Jump to content
  • Advertisement
Sign in to follow this  
chris00

Orientation matrix

This topic is 3925 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'm representing the orientation of an object using two vectors: forward and up. This is similar to how you might represent a camera. In the case of a camera, I can use a "look at" matrix to rotate the world to the correct orientation. Such a matrix would look like this:
	f = forward
	u = up
	r = right = f x u

	[  r.x   r.y   r.z  0 ]
	[  u.x   u.y   u.z  0 ]
	[ -f.x  -f.y  -f.z  0 ]
	[   0     0     0   1 ]
Which works perfectly well. However, what I want to do is to be able to rotate an object in a similar way, but obviously with a slight difference because the look at matrix is a sort of inverse rotation matrix, as it were. If I try to use the look at matrix then although my object is rotated, it tends becomes transformed so that it's back to front and so on. I've tried to work out the matrix for correctly transforming an object but I can't get quite get it to work! I presume I can use something very similar to the look at matrix above, but can't work out what it is. Can anybody help me? Cheers, Chris. [Edited by - chris00 on September 25, 2007 5:15:43 AM]

Share this post


Link to post
Share on other sites
Advertisement
Just transpose the look-at matrix to get the rotation matrix. The inverse of a rotation matrix is its transpose. Although I'm not sure if you should be negating an axis like that...your problem could be from using reflection matrices instead of rotation matrices, but it's hard to tell, since different graphics APIs use different conventions for their matrices and handedness.

Share this post


Link to post
Share on other sites
Thanks. I'm not sure about negating the f axis either - I just read it somewhere (on this site I think), and it seemed to work!

So, I've now got:


[ r.x u.x -f.x 0 ]
[ r.y u.y -f.y 0 ]
[ r.z u.z -f.z 0 ]
[ 0 0 0 1 ]


This almost works. x and y rotations are correct, but my object is reflected in the z direction and z rotation is inverted. I think this may possibly be down to me using the OpenGL right hand co-ordinate system?? Is that it, and if so, do you know how I can fix it?

Thanks.

Share this post


Link to post
Share on other sites
OpenGL uses a right-handed coordinate system, so that last column should not be negated. However, if you were using directX, it would be.

What you should be doing is building your model-view matrices out of rotation matrices, not the other way around.

standard rotation matrix:

[ x.x y.x z.x ]
[ x.y y.y z.y ]
[ x.z y.z z.z ]


where the vectors x, y, and z are the local axes of the coordinate system given by the rotation. These should be unit vectors that orthogonal (are all perpendicular to each other), such that z = x cross y.

Now, in order to convert this matrix into a format that your rendering API can use, you need to switch things around. Technically this is unnecessary, but it depends on how you want the matrix to be represented.

both OpenGL and DirectX use row vectors instead of column vectors, so your 4x4 modelview matrix is given by the following:


[ m[0] = x.x | m[1] = x.y | m[2] = x.z | m[3] = 0 ]
[ m[4] = y.x | m[5] = y.y | m[6] = y.z | m[7] = 0 ]
[ m[8] = z.x | m[9] = z.y | m[10] = z.z | m[11] = 0 ]
[ m[12] = 0 | m[13] = 0 | m[14] = 0 | m[15] = 1 ]


or alternatively:

[ m[0] = x.x | m[4] = y.x | m[8] = z.x | m[12] = 0 ]
[ m[1] = x.y | m[5] = y.y | m[9] = z.y | m[13] = 0 ]
[ m[2] = x.z | m[6] = y.z | m[10] = z.z | m[14] = 0 ]
[ m[3] = 0 | m[7] = 0 | m[11] = 0 | m[15] = 1 ]


in DirectX, since it uses a left hand coordinates (this is abnormal), you need to negate the z vector.

Finally, if you want to encode a translation into the matrix as well, put the x, y, and z components of the position in indexes 12, 13, and 14.

Share this post


Link to post
Share on other sites
Thanks for the clarification. After messing around with it a bit myself I also came to the conclusion that the last column should not be negated.

Final question: Have I got the look at matrix right, ie. with the forward vector negated? It certainly "appears" to work correctly...


f = forward
u = up
r = right = f x u

[ r.x r.y r.z 0 ]
[ u.x u.y u.z 0 ]
[ -f.x -f.y -f.z 0 ]
[ 0 0 0 1 ]

Share this post


Link to post
Share on other sites
Yes, that seems correct, assuming you want the right vector to represent the x vector, up to represent the y, and forward to represent the z vector, which seems correct.

One last thing, your cross product is in the wrong order (it's not commutative). Your r = f x u should be r = u x f. This is why you have to negate the f vector.

the following should all be equivalent:

f = r x u
r = u x f
u = f x r

Share this post


Link to post
Share on other sites
If I have up x forward then in a RH system wouldn't that make the right vector go along the +ve x axis? If so, then this must be left, not right - correct? I just checked the gluLookAt() documentation and they also use forward x up, and -ve forward in the matrix:

http://pyopengl.sourceforge.net/documentation/manual/gluLookAt.3G.html

I did try it with up x forward and +ve forward in the matrix, but I ended up looking backwards!

Share this post


Link to post
Share on other sites
The things I said come from the right-hand rule and the definition of an orthogonal basis for coordinate systems.

geometrical interpretation for a cross product:

a = b x c

let vector b be your index finger, vector c be your middle finger perpendicular to your palm. Then vector a is given by the direction of your thumb sticking up in the air. This is the right-hand rule, and is used to determine the direction of the result of a cross product in a right-handed coordinate system.

Likewise, do the same thing with your left hand, and the result of the cross product will be opposite what it would be with your right hand. This is what left-handed coordinate systems use.

-------------------------------------------

Basically, depending on which two vectors you are given, you will use some permutation of the following:

f = r x u
r = u x f
u = f x r

to generate the other, where r = x, u = y, f = z.

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!