Jump to content
  • Advertisement
Sign in to follow this  
Cacks

Translation & Rotation Matrix

This topic is 4491 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 guys, I'm having trouble with my object rotations. When I rotate my objects a few times they become increasingly more deformed out of shape. I store a single 4x4 matrix for each of my objects objects, called "transformationMatrix". This matrix describes their position & orientation. I'm using OpenGL, So the matrix indexes are: 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15 I render each object like this:
glPushMatrix();
    //multiply the current matrix by my transformation matrix
    glMultMatrixf(transformationMatrix.matrix);
    RenderObject...
glPopMatrix();

Translate like this:
void Brick::translateBrick(float _x, float _y, float _z)
{
    Matrix4x4 multMatrix;
    multMatrix.matrix[12] = _x;	//x-axis
    multMatrix.matrix[13] = _y;	//y axis
    multMatrix.matrix[14] = _z;	
    transformationMatrix = transformationMatrix * multMatrix;
}

Rotate like this:
//I pass a normalised vector which is 1 of my camera axis
void Brick::rotate(BrickRotation rotationType, SceneVector3 axis)
{
    float x = axis.x;
    float y = axis.y;
    float z = axis.z;
	
    float r = 1.0f-cos(rotationAng);    //rotationAng = rotation Angle
    float c = cos(rotationAng);
    float s = sin(rotationAng);
    float t = 1.0f - c;

    Matrix4x4 rotationMarix(t*x*x+c,   t*x*y-s*z, t*x*z+s*y, 0,
			    t*x*y+s*z, t*y*y+c,   t*y*z-s*x, 0,
			    t*x*z-s*y, t*y*z+s*x, t*z*z+c,   0,
			    0        ,	0       , 0      ,   1);

    transformationMatrix = transformationMatrix*rotationMarix;
}

Can any1 see where Im going wrong? Thanks for any help given!

Share this post


Link to post
Share on other sites
Advertisement
I can't understand some openGL syntax, however the effect you describe (objects being skewed) comes from the fact that the axes in the final model/world matrix are not exactly unit vectors. Try normalizing all axes before plugging them in matrices, even those that should obviously be unit vectors. (e.g. cross products of already normalized vectors) Even do it each frame, for each object, if you have to...

Another thing I noticed (2nd snippet) is that, you use an un-initialized matrix to multiply by the current one... this will be catastrophic in the release build.
Furthermore, you don't even set the major diagonal to "1"s. This way, you don't "pass" the translation into the matrix, you just set its first three columns to zero.

I don't think I see any other potential problems, but as I said I can only make assumptions about the openGL syntax...

edit:
Quote:
This way, you don't "pass" the translation into the matrix, you just set its first three columns to zero.

Ignore this. This is the case with DX multiplication. Still, though, you won't get the desired result

Share this post


Link to post
Share on other sites
Hi someusername,

when I declare my transformationMatrix, I get it's constructor to intialise it all to zero then make it an identity matrix by adding 1's in the correct place. Should I be re-initialising it somewhere else? or is that what u meant?

Thanks for the help!

Share this post


Link to post
Share on other sites
oops... I didn't realize it was your own class... :)
I'm sorry, I don't see anything weird...

Quote:
When I rotate my objects a few times they become increasingly more deformed out of shape

As I said, I can only interpret this as vectors passed for axes into matrices, that are not either precisely mutually perpendicular, or precisely unit vectors...
I'm afraid I can't help you with this...

Share this post


Link to post
Share on other sites
Don't mention it... To begin with, make sure that the determinants of all world matrices are as equal to 1.f as they can get, and most importantly, that there is no numerical error accumulating in the matrices, from repeated calculations that result to loss of precision.

Share this post


Link to post
Share on other sites
Please notice that the limited numerical resolution will in general prevent you from passing a perfect rotation basis. Importantly, you concatenate the partial transformation matrices to the global one over and over again. That will introduce errors into the global matrix in two ways: The basis vectors may become scaled (say no longer being of unit length) and they may become non-orthogonal. As soon as one or both of this happens the matrix will no longer provide a proper rotation but a rotation/scaling/shearing combination. It is not a question whether this happens but when.

So, if you follow this way, you have to do 2 things from time to time: Re-normalize the basis column vectors of transformationMatrix.matrix and re-orthogonalize them.


EDIT: someusername has written it ~40 seconds earlier ;)

Share this post


Link to post
Share on other sites
So to Re-normalize the basis column vectors I would just normalise each of them like I would a vector?


Then to re-orthogonalize them take their cross products once more?

Share this post


Link to post
Share on other sites
Quote:
Original post by Cacks
So to Re-normalize the basis column vectors I would just normalise each of them like I would a vector?


Then to re-orthogonalize them take their cross products once more?
Here's a quick and easy way to orthogonalize:
// Extract the basis vectors intro three vector objects, x, y and z
normalize(z);
x = normalize(cross(y,z));
y = cross(z,x);
// Load the basis vectors back into the matrix
If numerical drift is the only problem you're having, this should take care of it. (There are other ways to orthogonalize that have different characteristics, but the above should suffice.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Cacks
So to Re-normalize the basis column vectors I would just normalise each of them like I would a vector?

Yep. The vectors denotes by the indices {0,1,2}, {4,5,6}, and {8,9,10} when following your above index scheme. Notice that this is good only if you actually don't use scaling/shearing, or course.

Quote:
Original post by Cacks
Then to re-orthogonalize them take their cross products once more?

You could assume that the basis is close to orthogonality. So, computing the new z basis vector as the cross product of the old x and y, and then the new y vector as the cross product of the new z and old x basis vector should do the job.

There are more complex methods out there, but perhaps the above one is sufficient.


EDIT: Damned. It seems I'm too late a second time in this thread :/

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!