Archived

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

atreyu

Rotation Troubles...why can't I get this...

Recommended Posts

When rotating an object in D3D8 I''ve been doing a---> WorldMat = z_rotation_mat * y_rotation_mat * x_rotation_mat * translation_mat; I know that SetTransform(D3DTS_WORLDMATRIX, &WorldMat) with a call to DrawPrimitive() will first rotate about z, then y, then x, and finally translate. This is great, but it doesn''t allow me to rotate an object about its local axis correctly, regardless of the rotation order. If I have an airplane object it can rotate about its length, but rotation about the other two axis is wrong. Games always seem to do rotations correctly, and I can''t seem to figure it out. Does anyone know how to get it right? Thanks a lot. --Ben d e e p s k y . s 5 . c o m "If builders made buildings the way programmers write programs, then the first woodpecker to come along would destroy civilization." -Weinberg''s Law

Share this post


Link to post
Share on other sites
quote:
Original post by atreyu

When rotating an object in D3D8 I''ve been doing a--->

WorldMat = z_rotation_mat * y_rotation_mat * x_rotation_mat * translation_mat;

I know that SetTransform(D3DTS_WORLDMATRIX, &WorldMat) with a call to DrawPrimitive() will first rotate about z, then y, then x, and finally translate.



Actually, according to the multiplication order you specified, there would be a translation, followed by an x-axis rotation, then y, then z. So M = R * T means a translation follwed by a rotation. Its the reverse order you would think, kind of weird...

quote:

This is great, but it doesn''t allow me to rotate an object about its local axis correctly, regardless of the rotation order. If I have an airplane object it can rotate about its length, but rotation about the other two axis is wrong. Games always seem to do rotations correctly, and I can''t seem to figure it out. Does anyone know how to get it right?


I had problems with this when I first started too. When you apply a rotation to an object, you have to understand that the rotation is applied around an AXIS. The rotations don''t mean the object will rotate this way or that, they mean the object will rotate around an axis. I had missed that part too. So if you place the center of your object at 5,5,0 in world coordinates, rotations about the z-axis will work properly, but the other ones will end up moving the object quite a bit around the respective axis. So, in order for an object to rotate about its center, the center must be at 0,0,0. For that matter, to rotate an object by any point, that point must be at 0,0,0.

What you need to do is in your coordinates for your object, make 0,0,0 the center of the object. Then, when you apply the rotations, the object will rotate in place.

If you want to rotate an object whos center is at some position, say 5,5,5, you first need to translate the object so the center is at 0,0,0. In this case, that would be a translation of T(-5,-5,-5). Once you''ve done this, you apply your rotations, and then translate the object back to its original position. So your matrix would be (where T(-1) is the inverse of the first translation, in this case T(-1)(5, 5, 5))
M = T(-1)* Rz() * Ry() * Rx() * T.

Hope that helps,
IceGod

Share this post


Link to post
Share on other sites
I''m an idiot. I can''t believe wrote my matrix code wrong in the post. In my game all my objects are centered about(0,0,0) in the vertex buffer. I do do my rotations first and then translations.

Specifically, whichever rotation is done last is the one that *always* works correctly. Initially everything begins rotation fine. Z-axis rotation is always correct. X and Y are only correct when done independantly. If I rotate 90 degrees about Y and then try rotating about X the object instead rotates about its Z axis. It almost seems like the X and Y axis rotations are conflicting. I read an article about this problem a long time ago, before I started 3D so I''m pretty sure I''m not just messing up something dumb. Correct me if I''m wrong though.

Thanks in advance.
--Ben

d e e p s k y . s 5 . c o m



"If builders made buildings the way programmers write
programs, then the first woodpecker to come along would
destroy civilization." -Weinberg''s Law

Share this post


Link to post
Share on other sites
Hi,

The problem is called Gimbal lock, where when you rotate 90 degrees about an axis you can end up not being able to rotate about another one. If you are doing this, the only fixes I know of are to use quaternions, or seperate out the rotations.

GL,
IceGod

Edited by - IceGod on April 22, 2001 6:48:22 AM

Share this post


Link to post
Share on other sites
Are you talking about gimbal lock?

Goddamnit I hate it when someone beats me to the punch!

-Mezz

Edited by - Mezz on April 22, 2001 6:48:51 AM

Share this post


Link to post
Share on other sites
Ahh crap, I was hoping I would never need quaternions.
Thanks a lot for answering that. If I''m going to do this,
do the vertices in my vbuffer have to be 4-dimensional, or
is there a way to transform 3D vertices by a 4D matrix?

--Ben


d e e p s k y . s 5 . c o m



"If builders made buildings the way programmers write
programs, then the first woodpecker to come along would
destroy civilization." -Weinberg''s Law

Share this post


Link to post
Share on other sites
quote:
Original post by atreyu

Ahh crap, I was hoping I would never need quaternions.
Thanks a lot for answering that. If I''m going to do this,
do the vertices in my vbuffer have to be 4-dimensional, or
is there a way to transform 3D vertices by a 4D matrix?

--Ben



No probs, D3DXVec3TransformCoord() should do the job.

Tom

Share this post


Link to post
Share on other sites
You don''t need quaternions to fix gimbal lock. Use matrices to accumulate your rotations. Don''t rotate 90deg then another 90deg instead rotate from 89 to 90deg in this frame. You can also pass your vertex through RotationX() then through rotationY() then through rotationZ() and you won''t have gimbal lock. This is slow though. Gimbal lock happens when you multiply matrices together made of non-relative rotations and then you transform your vertex through the concatenated 3x3 or 4x4 matrix. As far as rotations go if you need to rotate around object''s axis and the object is way in the world then bring the object to model space, do your rotation and then translate back into world space. If your matrix is made of rotations and translation then transpose and reverse multiplication order to get to model space. You can also envision the rotation matrix to be as 3 axis in d3d your rows of upper 3x3 matrix are x,y and z axis in opengl just transpose matrix. Oh, when you use relative rotations once every couple of frames orthonormalize your matrix otherwise it might get out of wack and your object will become skewed.

Share this post


Link to post
Share on other sites
Thanks a lot everyone. You''ve got me started...just before
finals week too. No clue how I''m going to make the time.
Thanks again.
--Ben

d e e p s k y . s 5 . c o m



"If builders made buildings the way programmers write
programs, then the first woodpecker to come along would
destroy civilization." -Weinberg''s Law

Share this post


Link to post
Share on other sites
Quaternions are not that hard to use.
Besides, they should give a slight speed increase.

Go buy Begining Direct3D Game Programming.
Chapter 4(?) gives an example of how to do it with and without quaternions.
It''s a good book.

Share this post


Link to post
Share on other sites
I have seen this question a few times, and answers are always wide and varied.

1. Gimbal lock is due to using euler angles (rotation about x,y,z). This is basically what you are doing at the moment.

Your problem, if i understand the question, is not gimbal lock but is that you are rotating in World Coordinates, when you want to rotate about Object Coordinates.

2. To achieve this you can keep your viewing matrix and multiply it by the rotation you want to do. This is not a good idea because rounding errors will distort the matrix.

3. Quaternions can be converted to a viewing matrix. this way you avoid the rounding errors. but, this is also not a good idea IMO. quaternions are almost impossible to visualize.

4. You can store an axis/angle combination. this is what i do. you can generate the viewing matrix from this combination, and it is easy to visualize.


for maths and code examples of all 4 methods:
www.cs.ualberta.ca/~andreas/math/matrfaq_latest.html

- zenic

Share this post


Link to post
Share on other sites