Jump to content

  • Log In with Google      Sign In   
  • Create Account

Issue combining matrix components


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Telanor   Members   -  Reputation: 1358

Like
1Likes
Like

Posted 23 April 2014 - 07:59 PM

Previously I was multiplying 2 matrices together to do my bone transformations, but now I've broken the matrices down into scale, rotation, translation components. My goal is to work with the component parts so I can perform proper lerping and then combine the final result into a matrix to send off to the GPU. I'm having a problem combining things in this form though.

This is what I did previously: C = A * B. Where those are all matrices. That worked fine. Now what I'm doing is:
 
C.rotation = A.rotation * B.rotation;
C.translation = A.translation + B.translation;
C.scale = A.scale * B.scale;

Rotation is a quaternion, translation and scale are vector3s. When I combine these 3 components of C into a matrix again: Matrix.Scaling(Scale) * Matrix.RotationQuaternion(Rotation) * Matrix.Translation(Translation) the result is wrong, and my model looks like a collapsed blob.

I'm not sure if this matters, but the original info coming from the model file is a matrix, so I have to decompose the matrix into the 3 component parts on load, which I then store and use for these calculations.

Anyone know what I'm doing wrong here?

Sponsor:

#2 Buckeye   Crossbones+   -  Reputation: 6308

Like
3Likes
Like

Posted 23 April 2014 - 08:56 PM

Unfortunately, you can't make a simple combination of the components as the order of application is important.

 

Consider: multiplying 2 matrices together, each comprised of scale-rotation-translation components. That matrix multiplication becomes the following series of operations:

scale1 * rotation1 * translation1 * scale2 * rotation2 * translation2

In your implementation, you simply add the two translations. However, the second translation (translation2) does not simply follow on translation1. Translation2 is preceded by rotation2. Rotation2 changes the orientation of the axes before translation2 is applied. So translation2 applies to a different orientation than translation1.

 

As a very simple example, consider the situation where an object has a translation (1, 0, 0), a move 1 unit along the x-axis. The next operation is a rotation by pi/2 about the y-axis. The next operation is a translation of (1, 0, 0). Your implementation would place the object at (2, 0, 0). However, the rotation of pi/2 changes the object's axes and the second translation actually moves the object perpendicular to its original movement to a location (1, 0, 1) or (1, 0, -1) depending on the direction of the rotation.

 

Your approach of maintaining separate quats and vectors for each keyframe is a good one if your intent is to lerp/slerp between keyframes, combine animations, etc. If so, you may want to take a look at my article on an animation controller for a skinned mesh. Not all of the discussion may apply to your situation, but the bottom line is that you can lerp/slerp the animation components, but you'll still have to apply them in SRT order. That is, do your lerp/slerps on the animation keyframe components; calculate a matrix combining the SRT results; and multiply the bone offset matrices by the animation matrices, etc.


Edited by Buckeye, 23 April 2014 - 09:01 PM.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#3 Ashaman73   Crossbones+   -  Reputation: 7991

Like
1Likes
Like

Posted 24 April 2014 - 01:13 AM

It is just a matter of interpretation. Keeping the components isolated for bone animation to use slerp for the rotation is common. The interpretation of the 3 components should be: I have a bone at position X(=translation) which point in the direction of Y (=rotation) of size Z(=scale). This way you need to combine the matricies like this

// Order: first scale, then rotate, then move, applying from right to left:
final = translation * rotation * scale;

If you need the inverse, you need to reverse the order too:

// Order: first scale, then rotate, then move, applying from right to left:
inv(final) 
= inv(translation * rotation * scale) 
= inv(scale) * inv(rotation) * inv(translation)  


Edited by Ashaman73, 24 April 2014 - 01:15 AM.


#4 Telanor   Members   -  Reputation: 1358

Like
0Likes
Like

Posted 24 April 2014 - 01:17 PM

Ah ok, so basically I need to keep them separate for the interpolation and then after that's done, build the matrix and then do the hierarchy multiplication. I've got it working now, thanks for the help guys.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS