Sign in to follow this  
NovaBlack

roatation problem!

Recommended Posts

Hey there im currently struggling slightly with rotating my entities in a 3d world! basically i store my rotations as 3 floats, rotX, rotY, and rotZ. Each one represents a value in radians of the rotation around that particular world axis. I rebuild my World matrix per entity, only when a change has been made (for efficiency), and i choose to store rotations seperately as above and build the net rotation (same with translations) into the world matrix when rebuilt. This saves the world matrix being rebuilt EVERY time a rotation/translation in any direction is made (could be several per frame!) (my rationale is this..imagine if i moved Z 20, then Z -10, then Z -10 again.. the net effect would be a translation of 0 in z.. yet the world matrix would have been rebuilt 3 times) When i build my world matrix i end up with 5 matrices multiplied in this order: ScaleMtx * RotXMtx * RotYMtx * RotZMtx * Translation. Now it all works fine for what im doing at the moment... however ive come across a situation where i cant seem to figure out what to do.. Im essentially making an entity look at another entity. Now.. if i was storing the WorldMatrix directly rather than rebuilding from rotation and translation values this wouldnt be a problem. some simple cross product work and literally write the new X Y and Z axis into the world matrix. However, as im using arbitrary values.. i cant seem to make it work. If i JUST do the rotation around world Y OR world X everything is fine. However i know there is a problem with the fact that my rotation around World Y wont be calculated right.. as when the world matrix is rebuilt the order RotX * RotY * RotZ means that the rotation around Y wont be what i think it is, if there has been an X rotation already... (hope that makes sense!) Basically im looking for some kind of solution to this problem (short or long term!). I either need to know (if possible) how to calculate the correct Y rotation taking into account the previous World X rotation, OR wether I would just be better off persistently storing a world matrix for each entity, and every time a Rotation/translation is made , just apply it directly to the WMatrix, thus meaning i can use my cross product calcs to do a simpe look at. Thanks for any help!! EDIT: cant believe i spelt rotation wrong in my thread title lol [Edited by - NovaBlack on September 15, 2008 3:07:57 PM]

Share this post


Link to post
Share on other sites
The usual way (AFAIK) to solve this problem is actually to compute the matrix and then to decompose it w.r.t. the composition prescription you have chosen. In your case of "look at" you know a-priori that the scaling is identity; that makes things easier. So your composition prescription can be reduced to
RotXMtx * RotYMtx * RotZMtx * Translation

Translation can be isolated easily. Then you have to try to find a way to solve the 9 equations of
RotXMtx * RotYMtx * RotZMtx = M
where M denotes the "faked" rotation matrix you already mentioned in the OP. This can be done on paper or by using a good math software.

9 equations for 3 variables means an over-determined equation system. This is because rotation matrices have several constraints, like pairwise orthogonality and unit lenghtes. However, I expect that the rotation matrix product gives you one equation that depends on only a single angle. That will be the starting point.

There are for sure some sites on the Inet that handle this problem explicitely. Unfortunately I don't know one ATM.

Share this post


Link to post
Share on other sites
cheers for the suggestion!

Ill look into getting the Completed look-at matrix , and then trying to decompose backward from that to get the rotations i need.

hmm Is the approach ive taken (of storing 3 rotation values seperately) generally acceptable then ? Im pretty unsure of wether this is a common problem and the method ive chosen is common, or if this problem is entirely caused by a 'bad' choice in storing entity data :S

Share this post


Link to post
Share on other sites
What about using quaternions for storing your rotations?

They are little cryptic, but they could help you storing 3x3 rotation matrices in a compact manner (x,y,z,w) and they have the useful property of being easy to interpolate.

With a function like MatrixToQuaternion you could build the look at matrix of your object easily and obtain the right quaternion (and be able to smoothly rotate in the right orientation).

Share this post


Link to post
Share on other sites
Right.. For future reference for anyone else who finds themself with this annoying problem heres the code i used to build the look at matrix.. then extract the 3 Euler angles!

[SOURCE]


D3DXVECTOR3 targetPos = mTarget->getPosition();
D3DXVECTOR3 viewerPos = mViewer->getPosition();

D3DXMATRIX lookAtWorld;
D3DXMatrixIdentity(&lookAtWorld);
D3DXMatrixLookAtLH(&lookAtWorld,&viewerPos,&targetPos,&D3DXVECTOR3(0.0f,1.0f,0.0f));

// Now invert it..(DLookAtLH builds opposite transformation than we want!)
D3DXMatrixInverse(&lookAtWorld,0,&lookAtWorld);

// Now we hav the Wmatrix that looks at the target..
// But need to store 3 angles that, when built, will orientate the viewer
// This problem isnt simple considering the order the rotation matrices
// Are multiplied has a massive effect.
// However.. it can be done...
// According to 3D MathPrimer for Graphics and game development: Fletcher Dunn
// && Ian Parberry p203...

// Note : watch out for gimbel lock at the 90degree angles...

float newXRot = 0.0f;
float newYRot = 0.0f;
float newZRot = 0.0f;


// Extract Pitch from m._32 ( World X Rotation )
float sp = -lookAtWorld._32;

// Check for Gimbel Lock
if(fabs(sp) > 9.99999f)
{
// Either looking straight down or up
newXRot = (3.141592654f * 0.5f) * sp;

// Compute Heading (World Y Rotation)
// and set bank (World Z Rotation) to 0.

newYRot = atan2(-lookAtWorld._23, lookAtWorld._11);
newZRot = 0.0f;

}
else
{
// Just compute angles (no range errors since we have already
// checked for gimbel lock

newYRot = atan2(lookAtWorld._31,lookAtWorld._33);
newXRot = asin(sp);
newZRot = atan2(lookAtWorld._12,lookAtWorld._22);
}

mViewer->setRotation(D3DXVECTOR3(newXRot,newYRot,newZRot));


Share this post


Link to post
Share on other sites
Quote:
Original post by Txkun
What about using quaternions for storing your rotations?

They are little cryptic, but they could help you storing 3x3 rotation matrices in a compact manner (x,y,z,w) and they have the useful property of being easy to interpolate.

With a function like MatrixToQuaternion you could build the look at matrix of your object easily and obtain the right quaternion (and be able to smoothly rotate in the right orientation).




Yeah i thought somebody would suggest that!! :)

you are totally right i DEFINITELY need to start looking more at quaternions, i just havent had ANY experience as of yet and im not the most mathematical of people! ( i have to work HARD to grasp stuff.. although once i get it im totally fine ). I also know that quaternions are vital fore certain animation code ( i vagely recall something to do with slerping rotation keyframes is pretty essential using quaternions )

I Think ill start reading up on them ASAP.. whilst i leave my code for now until ive grasped them correctly. Any good articles/books/blogs to read up on them? Im one of those people who needs things explained kinda simply (usually visually) before i can kinda get the mathematica gist behind things.

cheers for the reply.

Share this post


Link to post
Share on other sites
Quote:
Original post by NovaBlack
hmm Is the approach ive taken (of storing 3 rotation values seperately) generally acceptable then ? Im pretty unsure of wether this is a common problem and the method ive chosen is common, or if this problem is entirely caused by a 'bad' choice in storing entity data :S

That depends on the circumstances. E.g. how the user input controls the orientation. And mainly whether you need to feedback Euler angles to the user (e.g. in an editor).

You may look into euclideanspace.com for geometrical stuff in general, and various rotation representations in special. If is IMHO no site to actually learn the math backgrounds, but it is a good source for formulas (e.g. conversion quaternion -> matrix).

If you actually go the road of quaternions, don't see them as a sanctum. I suggest you to see them as a mathematical tool, nothing else. Even don't try to interpret them geometrically. And don't get blended by slerp. See e.g. here about its pros and cons in comparison with nlerp.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this