View Full Version : Transformation Matrices
Leebre 08 August 2005, 04:41 PM What is the proper way to construct the transformation matrix of an arbitrary point in 3d space? I was thinking that I need to do something like multiply the point into a translation matrix, then a xrotation matrix, then a yrotation, then a zrotation, then a scale matrix. Is that correct or incorrect? But I don't think that is the right way because multiplying the point, which is just a vector, with a matrix would give me another vector, and not a matrix.
Once I get done working with the point's transformation matrix how do I go about extracting the individual translation, rotation, and scale factors back out of it?
Thanks!


mummey
08 August 2005, 07:12 PM
Multiplying the point by the transformation matrix gives you the transformed point. So yes, that is correct.
arnecls
08 August 2005, 08:21 AM
Sounds like two different questions here. If I understand that correctly, the first question is which order should be used to transform your point if you have a scale, rotate and translate matrix.
Well. I personally do it this way  scale, rotate, translate. This way you would support  let's call it  innerobject rotations. This means the object rotates around it's own axis (if it's positioned at origin). You can also switch translate and rotate (scale, translate, rotate), but that would rotate the object around the center of the scene, leading to different results.
Examples: If you have a player who wants to turn around use the first way. If you've got a planet rotating around a sun use the second way.
The second question is how to extract rotation, scale and translation matrixes from a combined matrix. Well ... that's some kind of a problem. If you've just scale and translate it's quite easy, as scalevalues are on the diagonal and the translatevalues are on the side or bottom (depends on the system you're using). But if rotation comes in you're lost because rotations have their values placed all over the matrix. There are ways, but they are quite complicated and in most cases not 100% correct.
The best way to solve that problem is to store the values you're using and access them directly. Just imagine a gameobject class, which has a draw() function, which  every time it's called  calls the transformation functions (in the order described above) and draws you're object afterwards. In that case you would have to store your scale, transform and rotation information at that object anyway and simple get functions will do the trick.
Hope that helps.
Leebre
08 August 2005, 04:40 PM
Thanks guys. Just a little clarification on what I'm trying to do...I'm trying to dynamically parent one object to another in a 3d app. My understanding is that I need to transform it realtive to the parent object and this is the process I'm trying to follow:
Frame X:multiply child's transformation matrix by the inverse of the dynamic parent's transformation matrix to get the child's coordinates relative to the dynamic parent, M1.
Frame Y:
Multiply M1 by the dynamic parent's new transformation matrix to get the child object's new transformation matrix, M2 .
Multiply M2 by the inverse of the actual parent's (which I guess would be the world) transfromation matrix to create the transformation matrix of the real parent to the fake parent, M3.
Extract the rotation and position values of M3 to assign to the child object.
arnecls
08 August 2005, 12:28 AM
Or the easy way:
parent : draw()
pushMatrix() // if the parent has a parent :)
doTransforms() // do parents transforms
drawChildren() // process all children
drawSelf() // If there's something to show
popMatrix() // Undo changes to go on with the parent's parent
child : draw()
pushMatrix() // Same as above
doTransforms() // Do your own transforms, relative to the parent transforms
drawSelf() // draw your object
popMatrix() // Undo changes, as you maybe have another child to go on with
That assumes, that you're resetting your matrixstack to identity each frame or in other words the classic scenegraph behaviour.
Note: this kind of Hierarchie makes it quite hard to rotate the child object around it's own axis (see earlier post) if it's parented. In this case you'll have to do something like this
child : draw()
safeParentMatrix() // For later use
pushMatrix() // We want to undo changes later
loadIdentity() // clear all transforms
doTransforms() // do your own transforms
loadSafedMatrix() // do parent transforms
drawSelf() // draw object
popMatrix() // Undo changes, fall back to parent matrix
The key is  you don't need to know the earlier transforms if you redo all transforms each frame. This is really much faster, because calculating the inverse of a matrix is slow and furthermore  not accurate.
I would recommend you to read the OpenGL redbook's part about matrix stacks.
Leebre
08 August 2005, 02:33 PM
Thanks for the advice arnecls. The issue, originally, was that I couldn't use OpenGl...I was thinking I was stuck with what was exposed by the API. But I've found out that I can OpenGl...so that willmake life much, much easier.
CGTalk Moderation
08 August 2005, 02:33 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.