Archived

This topic is now archived and is closed to further replies.

atreyu

I need advice on D3DTS_WORLD transforms

Recommended Posts

I finally got some freetime to mess around and after coding for two days I ran into a wall. A while back I managed to get my camera rotating correctly (no gimbal lock). I ended up storing an UP, RIGHT, and LOOK vector and rotating those as necessary (ie: two of the vectors would be rotated around the third). Then I''d fill in my rotation matrix with...agg too hard to explain, I''ll just paste it...the algorithm is pretty straightforward:
  
//X, Y, Z are the coordinates of the camera


	D3DXMATRIX YawMat, PitchMat, RollMat;
	D3DXMATRIX ViewMat;

	Up_Vector = D3DXVECTOR3(0,1,0);
	Right_Vector = D3DXVECTOR3(1,0,0);
	Look_Vector = D3DXVECTOR3(0,0,1);

	D3DXMatrixRotationAxis(&YawMat, &Up_Vector, Yaw);
	D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &YawMat);
	D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &YawMat);

	D3DXMatrixRotationAxis(&PitchMat, &Right_Vector, Pitch);
	D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &PitchMat);
	D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &PitchMat);

	D3DXMatrixRotationAxis(&RollMat, &Look_Vector, Roll);
	D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &RollMat);
	D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &RollMat);

	D3DXMatrixIdentity(&ViewMat);
	ViewMat._11 = Right_Vector.x;	ViewMat._12 = Up_Vector.x;	ViewMat._13 = Look_Vector.x;
	ViewMat._21 = Right_Vector.y;	ViewMat._22 = Up_Vector.y;	ViewMat._23 = Look_Vector.y;
	ViewMat._31 = Right_Vector.z;	ViewMat._32 = Up_Vector.z;	ViewMat._33 = Look_Vector.z;
	ViewMat._41 = - ((X * Right_Vector.x) + (Y * Right_Vector.y) + (Z * Right_Vector.z));	
	ViewMat._42 = - ((X * Up_Vector.x)    + (Y * Up_Vector.y)    + (Z * Up_Vector.z));
	ViewMat._43 = - ((X * Look_Vector.x)  + (Y * Look_Vector.y)  + (Z * Look_Vector.z));

	D3DDevice->SetTransform(D3DTS_VIEW, &ViewMat);

  
Hopefully that formats out ok. Anyway, the camera works great. Rotation and translation are perfect. Now I want to use this same technique for transforming objects within the world. I made the necessary adjustments...the big change was from D3DDevice->SetTransform(D3DTS_VIEW, &ViewMat); to D3DDevice->SetTransform(D3DTS_WORLD, &WorldMat); It doesn''t work at all though. The objects all rotate relative to the world''s origin (not their own) and they don''t translate along their LOOK, UP, RIGHT vectors (move forward, jump, strafe) but instead translate along the world''s axis. I''m totally confused as to why this is happening? If it works for the camera why doesn''t it work for objects in the world? Thanks a lot. --Ben

Share this post


Link to post
Share on other sites
hmm. I was hoping someone could help me. The algorithm I''m using is pretty common. Hopefully this makes more sense:

1) create an UP, RIGHT, and LOOK vector
2) create a rotation matrix for the desired operation (yaw pitch or roll)
3) transform two of the vectors around the third (the operation determines which vector to rotate around).
4) manually build a WorldMat (ViewMat for the camera case).
5) apply using SetTransform(D3DTS_WORLD, &WorldMat)


Movement through the world is done by
//forward and reverse movement
object_x += speed * LOOK.x;
object_y += speed * LOOK.y;
object_z += speed * LOOK.z;

It seems logical. It works for the camera (with D3DTS_VIEW) but everything behaves as if being transformed relative to the worlds axis when using D3DTS_WORLD with some object in the vertex buffer.

I''m really stuck on this one. Please help.

--Ben


| particlefield.com |

Share this post


Link to post
Share on other sites
Ben,

Don''t know if this will help but the world matrices elements :

WorldMat._41 = (X * Right_Vector.x) + (Y * Right_Vector.y) + (Z * Right_Vector.z);

WorldMat._42 = (X * Up_Vector.x) + (Y * Up_Vector.y) + (Z * Up_Vector.z);

WorldMat._43 = (X * Look_Vector.x) + (Y * Look_Vector.y) + (Z * Look_Vector.z);

Should not be the negative dotproduct for the world as with the view matrices, maybe you have changed this already as shown above ?

Regards,
sTeVe

Share this post


Link to post
Share on other sites
Thanks Steg. I found that one a while back. I'm thinking about going with another method since this one is looking like too much trouble. The one below is pretty common (I think). Can someone tell me if it has any problems with gimbal lock? Also, with the previous method I could use my UP, LOOK, RIGHT vectors for moving an object in the direction it's pointing, strafing, etc. Without those vectors how am I supposed to move correctly? I guess I could recalculate them from scratch but it seems like a waste of the CPU. Is there a better way?

  
D3DXMATRIX TranslationMatrix;
D3DXMATRIX RotationMatrix;

D3DXMatrixIdentity(&WorldMat);

D3DXMatrixRotationYawPitchRoll(&RotationMatrix, Yaw, Pitch, Roll);
D3DXMatrixTranslation(&TranslationMatrix, X, Y, Z);

D3DXMatrixMultiply(&WorldMat, &RotationMatrix, &TranslationMatrix);


Thanks a lot,
--Ben


| particlefield.com |

Edited by - atreyu on January 10, 2002 2:25:17 PM

Share this post


Link to post
Share on other sites
Did you try to translate the object to the origin then rotate and then translate back to the original position?

Arcus

Share this post


Link to post
Share on other sites
In the vertex buffer the object is stored with its center at the origin. When using my original method for object transforms this is certainly how the object behaves but I think for other reasons. if I use the other method:

D3DXMatrixRotationYawPitchRoll(&RotationMatrix, Yaw, Pitch, Roll);D3DXMatrixTranslation(&TranslationMatrix, X, Y, Z);D3DXMatrixMultiply(&WorldMat, &RotationMatrix, &TranslationMatrix);

It rotates and translates as it should. I just don''t know how to move the object in the direction it''s facing anymore (since I don''t have the UP, LOOK, and RIGHT vectors).

I''m thinking the problem lies in my matrix step, where I assemble the matrix manually. I would have thought it would be the same as for the camera but apparently not.

Thanks,
--Ben


| particlefield.com |

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
just looking at this old post quickly -
have you tried reversing the order or rotation/translation.
what i mean is for the camera you do it one way ( I can''t
remember the order but lets say it is ) translation then rotations but for the world its reversed - rotations first then translations.

see if that makes some sense

Share this post


Link to post
Share on other sites
Use quaternioin for rotation, no more gimbal lock

I use this:

    
D3DXQUATERNION qRot;
D3DXMATRIX matR;

D3DXMatrixTranslation(&m_MatSrc,0.0f,fCamPosY,0.0f);
D3DXQuaternionRotationYawPitchRoll(&qRot,D3DXToRadian(D3DXToRadian(fCamRotX),D3DXToRadian(fCamRotY),D3DXToRadian(fCamRotZ));
D3DXMatrixRotationQuaternion(&matR,&qRot);
D3DXMatrixMultiply(&m_MatSrc,&matR,&m_MatSrc);
D3DXMatrixInverse(&m_MatDest,NULL,&m_MatSrc);
m_MatBillboard=m_MatSrc;


m_MatDest is your wanted matrix
m_MatSrc is the bilboard matrix

I don't move in the world appart Y (it's the world that move around) but it proved to work well even when moving.


Oups ! I thought it was for the camera sorry...
One must turn 7 time the finger over the keyboard...



Edited by - dansteph on January 14, 2002 5:37:41 PM

Share this post


Link to post
Share on other sites
Thanks a lot everyone. Things are working great now. I guess Arcus was mainly correct, I messed around with the transform order and now it works. (even if it doesn''t make COMPLETE sense ) Your other suggestions look good too. It''s nice to see different methods for doing something so you can pick and choose. I really appreciate the help.

Thanks again,
--Ben


| particlefield.com |

Share this post


Link to post
Share on other sites