3
\$\begingroup\$

I'm new to 3D-game programming and I'm having some trouble making objects rotate the way I want them to. I just read Glenn Fiedler's tutorials on game physics, awesome stuff by the way! (http://gafferongames.com/game-physics/physics-in-3d/)

Now, I'm trying to make a simple space sim. If you imagine a spaceship that is not yet rotated in any way (up = Vector3.Up etc..). If I apply some yaw-input (which would increase the angular velocity) I'd then expect the ship to rotate around the up-vector of the ship (which is also the world y-axis at the moment). That works fine. If I would then roll the ship a little bit, I'd expect the ship to roll around its forward axis, but it should also continue to spin around the world y-axis.

At the moment with my implementation instead of keeping it's momentum around the y-axis, it continues to spin around its local up-vector - which is obviously wrong.

I think I understand why this happens with my current implementation, I'm just not sure how to fix it.

This is what I have at the moment, with some minor simplifications (runs every update):

Vector3 addedRotation = new Vector3(pitchInput, yawInput, rollInput);
addedRotation = Vector3.Transform(addedRotation, rotation);
rotationVelocity += addedRotation;

rotation.Normalize();

Quaternion w = new Quaternion(rotationVelocity, 0);
rotation += Quaternion.Multiply(w * rotation, 0.5f);

I'd be very happy if someone could point me in the right direction here. If anything needs clarification, please tell me and I'll try explain it better.

Thanks for taking the time!

\$\endgroup\$
  • \$\begingroup\$ Will have to take a closer look at this, but one thing I can say is that 'rotationVelocity += addedRotation' almost certainly isn't what you want; you can't simply add Y/P/R values to add rotations, but instead need to properly compose them (via something like quaternion or matrix multiplication). \$\endgroup\$ – Steven Stadnicki Sep 11 '13 at 23:48
  • \$\begingroup\$ Hm, yes. I don't even think what I want is possible with a rotation around a single axis. After yawing and rolling a little bit, I think I basically want one rotation around the up vector (up vector at the time of adding yaw rotation that is - so world y-axis in my example above) and one around the forward axis simultaneously and independently from each other. \$\endgroup\$ – user31091 Sep 12 '13 at 0:21
  • \$\begingroup\$ Note that every rotation can be expressed as a rotation around a single axis (this is actually a fairly deep theorem, and related to quaternion representations) - but that's only true for static rotations, and when you're animating you can certainly expect some 'tumble'. \$\endgroup\$ – Steven Stadnicki Sep 12 '13 at 0:27
5
\$\begingroup\$

rotationVelocity += addedRotation is actually fine. Angular velocity is a vector and adds in the usual way.

The part you may be missing is that in your description of the desired motion, you have a rotation around a constant axis (the global up-vector) combined with a rotation about a rotating axis (the ship's roll axis, which is rotating because of the ship's yaw angular velocity).

This does not correspond to a constant angular velocity, which would be the combination of several rotations about constant axes - e.g. the global up-vector and the ship's roll axis at the moment of adding the roll.

Also note that the quaternion renormalization, rotation.Normalize(), should probably be done after you add 0.5 * w * rotation, not before. (Also, you seem to be missing the delta time, which should be multiplied in there as well - your angular velocities are in radians per frame instead of radians per second.)

(Finally, as a side note I should mention that in general, angular velocity doesn't remain constant over time, even if no torques are acting on an object. Angular momentum remains constant, but for a non-trivial inertia tensor, this results in time-varying angular velocity because the inertia tensor is rotating with the object.)

\$\endgroup\$
  • \$\begingroup\$ I think we're both right - angular velocity is a vector, but the OP's conversion of YPR to an angular velocity vector (and the transformation thereof) still looks awfully suspicious to me. \$\endgroup\$ – Steven Stadnicki Sep 12 '13 at 4:23
  • \$\begingroup\$ Thanks for the response, I will take a closer look a bit later today. I actually do take time into account in my actual code, I'm also aware that angular velocity does not remain constant. I was just simplifying this a lot because I just want to get the actual rotation right. \$\endgroup\$ – user31091 Sep 12 '13 at 11:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.