Jump to content
  • Advertisement
Sign in to follow this  
LowRad

[XNA] Orientation & Rotation using matrices and quaternion

This topic is 3032 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I am writing an Asteroid clone and i got few problems and questions. So i though i would ask here for advices and comments.

Firstly, even if im planning on using quaternion to rotate my objets, im storing their orientation as a matrix. Im doing so since it seems easier to do lots of stuff, like transforming coordinates from world to local or simply getting a forward vector. Any thoughts about this, is this practice common or should i store the orientation as a quaternion?

Secondly, even if all seems to work as they should, i've got some kind of error in my rotation code. Im using this code snippet to turn the ship.

// Orientation is the Ship's Orientation store as a Matrix
Quaternion q1 = Quaternion.CreateFromRotationMatrix(Orientation);
Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Up, 0.2f);
Quaternion final = q1 * rot;

Orientation = Matrix.CreateFromQuaternion(final);


Question: result seems the same if im swapping quaternion multiplication order (seems odd to me). Is this a normal behavior? From what ive red, no!

// in the above code, either of theses line are giving me the same result.
// as if: q1 * rot = rot * q1
final = q1 * rot;
final2 = rot * q1;


Problem: I got a bug and it's really hard to reproduce it. Very rarely as im moving around the screen and turning the ship around. The ship go out of control and seems to zoom in/out or being tranlated up/down (instead of turning normally). I cant track the problem down, but im sure its has to do with the way im using thoses quaternion to rotate my objects.

Any comments or ideas are welcome...
Thanks you!

Share this post


Link to post
Share on other sites
Advertisement
Successive rotations around the same axis commute; this is why changing the multiplication order isn't having any noticeable effect.

Regarding the quaternions, my advice is to drop them completely unless you have a clear, definite understanding of what their use will gain you in the given context. In other words, if you're not sure why you're using them, don't use them (just stick with matrices).

As for your bug, I don't know, but one thing I noticed is that you don't appear to be normalizing your quaternion after applying the relative rotation. Whether you're using quaternions or matrices, you should normalize the orientation after applying a relative rotation in order to prevent numerical drift.

Also, if your object will really only ever rotate about a single axis, you could simply track the angle of rotation about that axis and build the orientation from scratch each update. This would solve any potential numerical issues that might come up. (Even with normalization, successive relative rotations could theoretically cause the orientation to drift out of alignment with the up vector. That's probably unlikely to happen in this particular scenario, but building the orientation from scratch will eliminate the possibility entirely.)

Share this post


Link to post
Share on other sites
Thanks for answering me. Im using quaternion since i want to turn the tradional asteroid game into a "3d" version (meaning you can rotate in any direction and chase asteroids in a 3d space rather then a 2d world). Im using them to avoid the famous gimbal lock problem. Can i achieve the same with matrices only?

About your comment on normalization, do you mean something like this? And can you explain what you mean about normalizing a matrice? i dont see how i can do this (i cant find nothing in xna documentation).

Quaternion ori = Quaternion.CreateFromRotationMatrix(Orientation);
Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Up, 0.2f);

// i'm assuming this is the right order (or is it ori * rot)
Quaternion final = rot * ori;
final.Normalize();

Orientation = Matrix.CreateFromQuaternion(final);


You are also talking about the multiplication order. From what i understand this should be the right way to do it? am i right? (Transformations are applied from right to left).

Quaternion ori = Quaternion.CreateFromRotationMatrix(Orientation);
Quaternion rotPitch = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), GetPitchInput());
Quaternion rotRoll = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), GetRollInput());
Quaternion rotYaw = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), GetYawInput());

// Is this correct?
// Should i normalize before, between each transforms or only after
Quaternion final = rotPitch * rotRoll * rotYaw * ori;
final.Normalize();

Orientation = Matrix.CreateFromQuaternion(final);


Would an implementation like this suffer from numerical error?

Share this post


Link to post
Share on other sites
Quote:
Im using quaternion since i want to turn the tradional asteroid game into a "3d" version (meaning you can rotate in any direction and chase asteroids in a 3d space rather then a 2d world).
My earlier comments regarding quaternions still apply - whether it's 2-d or 3-d doesn't matter.
Quote:
Im using them to avoid the famous gimbal lock problem. Can i achieve the same with matrices only?
Yup. Whether or not you use quaternions has nothing to do with whether your rotations will be susceptible to gimbal lock.
Quote:
About your comment on normalization, do you mean something like this?
Yes, that looks right. (Note that all that converting back and forth between quaternions and matrices is probably unnecessary. Either just use matrices, or use quaternions consistently throughout and only convert to matrix form as needed.)
Quote:
And can you explain what you mean about normalizing a matrice?
With matrices the process is called 'orthogonalization'.

Note earlier that I suggested not using quaternions unless you can articulate how using them would be advantageous. Here's one way using them can be advantageous: normalizing a rotation in quaternion form is easier than doing so in matrix form. (I don't know if XNA has a matrix orthogonalization function already - if it does, then it doesn't really matter which you use, since it's just a matter of calling the appropriate function.)
Quote:
// Is this correct?
// Should i normalize before, between each transforms or only after
Quaternion final = rotPitch * rotRoll * rotYaw * ori;
final.Normalize();

Orientation = Matrix.CreateFromQuaternion(final);


Would an implementation like this suffer from numerical error?
Assuming I'm understanding the context of your code correctly, that should be fine; normalizing the quaternion before re-building the orientation matrix will correct for any accumulated numerical error.

As for the order, which order is correct depends on the desired effect and how quaternion multiplication is defined. (I can't remember if XNA uses standard or 'reverse' quaternion multiplication order - I think it's standard, but I'm not sure.)

Share this post


Link to post
Share on other sites
Thanks for quick response, my code looks like it performing correctly: no more weird zooming in and out even after playing a few levels.

About making normalizing matrices in XNA, ive not found anything in the documentation. However, this shouldnt be too hard, its just a bit of cross-product and vectorial maths to make sure the vector are orthogonal to each other.

About quaternion, after re-reading a few references i had. Would their only usefull quality is their ability to be easily interpolated? Or can you tell me or descripe me where quaternion are best used.

Thanks again!

Share this post


Link to post
Share on other sites
Quote:
Or can you tell me or descripe me where quaternion are best used.
There's really nothing that quaternions can do that rotation matrices can't. However, here are some things that are commonly cited as advantages with respect to quaternions:

1. Lower storage requirements than matrices.
2. More efficient concatenation.
3. More efficient normalization of orientations.
4. More efficient and (arguably) more elegant NLERP, SLERP, SQUAD, etc.
5. There's a couple of nice quaternion-specific algorithms for rotating over the shortest arc from one vector to another.
6. Numerical error can accumulate more slowly (theoretically, at least). If you're re-normalizing every update anyway though, this doesn't really matter.
7. Probably some other things I'm forgetting.

Possible disadvantages:

1. Will generally need to be converted to matrix form (explicitly or implicitly) at some point or other (e.g. for rendering, extraction of direction vectors, transforming of points, etc.). Depending on the context, this can offset some of the gains described above.
2. Probably some other things I'm forgetting.

So, seems like a pretty good deal, right? The reason I usually recommend avoiding quaternions unless one knows why they're advantageous is that it seems that, quite often, folks use quaternions just because they think they 'should', without really knowing why they're using them. As a result, they end up using them in ways that are pointless and that don't benefit from any of the advantages listed above. (IMX, at least :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!