# "accumulating" world transformations

12 replies to this topic

### #1starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 01:31 AM

Ugh, I feel like one of those things "I should just know". Anyway, I have a parent-child system set up for a simple (very simple) animation system I'm putting together. The main idea being I can animate simpler parts of the world without having to wait on an artist.

For getting the world matrix of a child, that's easy, I simply multiply by each parent nodes' world matrix in the correct order. This works and I have it down. What I can't seem to do is correctly update the actual vectors held like:
vec3 worldPosition
vec3 worldRotation
vec3 worldScale
I've tried many things, such as multiplying (transforming) by their parent matricies, adding to position/rotation, multiplying by scale, ect, but it isn't coming out right. So how do I transform the "node space" (or model space) positions, rotations and scales to world space while correctly staying aligned with the parent?

Any help is much appreciated.
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #2Reedbeta

DevMaster Staff

• 5305 posts
• LocationBellevue, WA

Posted 09 June 2009 - 02:15 AM

Well, if you can already calculate the matrix then it should be simple to extract this info from it. The world position is just the translation part of the world matrix (4th row or 4th column depending on convention - also known as the point you get out if you multiply (0, 0, 0, 1) by the world matrix). The rotation and scale may not be easily separable if you have non-uniform scaling somewhere between the node and the root, but assuming you do not, you can calculate the overall scaling factor by looking at the length of the X axis of the world matrix (first row/column), then get the rotation part by taking the 3x3 upper-left submatrix and dividing out the scale factor.

That being said you should also be able to calculate this information directly if you want. The world position, for instance, should be equal to taking the origin point (0, 0, 0, 1) and multiplying up the hierarchy by all the child-to-parent matrices. The scale factor (again assuming uniform scaling only) should be the product of all the scaling factors at each node from child to root, and the rotation should similarly be the product of all the rotations from child to root.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #3starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 02:29 AM

hmmm... well I already tried doing that, but perhaps I missed something. Thanks a lot, I'll tell if I got the correct results or not :)
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #4starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 05:36 AM

Hey, the scaling and transformations work perfectly, but I can't get the manual computation of the rotation to work at all. Can you clarify what you mean? You cant possibly be talking about just multiplying the 3 component degree vectors together for each node 0_o
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #5.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 09 June 2009 - 12:11 PM

Reedbeta said:

The scale factor (again assuming uniform scaling only) should be the product of all the scaling factors at each node from child to root, and the rotation should similarly be the product of all the rotations from child to root.
Well no, not quite. If a certain node was to rotate 90 degrees on the z-axis, a scale in the x-axis from thereon would actually mean a scale in the y-axis of the original object. Furthermore, naturally if one would not rotate in multiples of 90 degrees around unit axes, you would get non-unit-axis scales, which implies shearing.

My question for starstutter is: why do you need to have euler rotations and unit-axis scales represented in the nodes? Why not simply work with matrices?
-
Currently working on: the 3D engine for Tomb Raider.

### #6Reedbeta

DevMaster Staff

• 5305 posts
• LocationBellevue, WA

Posted 09 June 2009 - 04:08 PM

.oisyn said:

Well no, not quite. If a certain node was to rotate 90 degrees on the z-axis, a scale in the x-axis from thereon would actually mean a scale in the y-axis of the original object. Furthermore, naturally if one would not rotate in multiples of 90 degrees around unit axes, you would get non-unit-axis scales, which implies shearing.

Note I said: assuming uniform (same in all 3 axes) scaling only. Of course things get hairy if you allow for non-uniform scaling.

starstutter said:

You cant possibly be talking about just multiplying the 3 component degree vectors together for each node

Haha, no. Sorry, when I said product I really meant composition. That would be the product if you use matrices or quaternions, but is more complicated for Euler angles (pretty much you have to convert them to matrices or quats, multiply, then convert back to Euler angles).
reedbeta.com - developer blog, OpenGL demos, and other projects

### #7starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 04:19 PM

.oisyn said:

My question for starstutter is: why do you need to have euler rotations and unit-axis scales represented in the nodes? Why not simply work with matrices?
that's starting to seem like a better option I suppose.

So, that said, how precisley do I extract the rotation? I can get the translation portion just fine, but can you show the math operation to extract the rotation from the world matrix?

Reedbeta said:

then get the rotation part by taking the 3x3 upper-left submatrix and dividing out the scale factor.

1. Extract all the 9 (3x3) components from the upper left corner of the matrix:
_11 _12 _13
_21 _22 _23
_31 _32 _33

2. Divide out the scale factor? Can you show this please.

Psh, why do I only have to be the only one on this site who's not a mathematician? -_- Oh well, thanks for the help so far.
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #8Reedbeta

DevMaster Staff

• 5305 posts
• LocationBellevue, WA

Posted 09 June 2009 - 05:09 PM

Divide each of the 9 components by the scale factor.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #9starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 05:20 PM

I found this:
D3DXMatrixDecompose()

and this:
float Quaternion::getPitch(){ return atan2(2*(y*z + w*x), w*w - x*x - y*y + z*z);}
float Quaternion::getYaw(){ return asin(-2*(x*z - w*y));}
float Quaternion::getRoll(){ return atan2(2*(x*y + w*z), w*w + x*x - y*y - z*z);}

So I guess I'll make use of the d3dx library this time. Thanks anyway, but I think we're having a horrendous miscommunication (you'll have to excuse my complete lack of math terminology). I was talking about extracting the roll, pitch and yaw degrees from the matrix. Were you talking about just getting the actual rotation matrix?

EDIT: oh wow, I made a post at the exact same time as you 2 posts above this one 0_o. Thats why I didn't get the clarification. Yes, big misunderstanding :)
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #10Reedbeta

DevMaster Staff

• 5305 posts
• LocationBellevue, WA

Posted 09 June 2009 - 05:24 PM

Yes, I was describing how to get the rotation matrix - which I assumed you could then have your way with, including converting it into Euler angles if you like. (But, I generally don't touch Euler angles unless it's a restricted situation where I'm only using yaw and pitch, such as for an FPS-style camera. They are just too much trouble for general rotations - quaternions FTW.)
reedbeta.com - developer blog, OpenGL demos, and other projects

### #11starstutter

Senior Member

• Members
• 1039 posts

Posted 09 June 2009 - 05:30 PM

Ok, now I see. Thanks much :D I'll try this out and see if it works. Reguardless of weather I want to use roll pitch and yaw or not, my entire current system is built around them (only for rotations of course). What are the advantages of quarternions over this system? I've found them to be fairly easy to work with so far.
(\__/)
(='.'=)
This is Bunny. Copy and paste bunny into
(")_(") your signature to help him gain world domination.
bunny also wants to fight spam: Click Here Bots!

### #12Reedbeta

DevMaster Staff

• 5305 posts
• LocationBellevue, WA

Posted 09 June 2009 - 05:54 PM

The main problems with Euler angles (aka roll, pitch, yaw) are (1) gimbal lock, (2) difficulty of composition, and (3) difficulty of interpolation (linearly interpolating Euler angles between two rotations doesn't necessarily produce a natural-looking movement of the object). Here is some discussion of the issue and here is another (BTW...the authors of those two articles are Steve Baker and Martin Baker...related?)

The advantages of quaternions are (1) no singularities such as gimbal lock, (2) they are more compact and easier to keep normalized than a rotation matrix, (3) easy to compose, (4) easy to interpolate. The main disadvantage is that their numeric values are not easy for humans to interpret. The euclideanspace.com site I linked to earlier has tons more information about quats.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #13.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 09 June 2009 - 08:12 PM

Reedbeta said:

Note I said: assuming uniform (same in all 3 axes) scaling only.
d'Oh, I read "assuming unit axis scaling only". In that case, disregard my post