Imagination PowerVR SDK Blog

Building matrices from quats, trans and rot




I am exporting an animation from 3dmax, first by matrices and then by quaternions, rotations and scaling.
Using matrices the animation works fine, but using quats, rotations and scaling the model deforms horribly. The first frame looks good, but the following frames start to get deformed.
However, there are some models that work well using quaternions, rotations and scaling.
I can only presume there is bug in my code when converting from translation/rotation/scale to matrices ( although there are models that work with the entire animation ), so I would like to ask:
- why is the pfAnimScale written at 7-floats boundary? Are there other relevant information beside pfAnimScale[0], pfAnimScale[1], pfAnimScale [2] that are supposed to be the scaling on x, y, z?
- can a pfAnimRotation be treated like a normal quaternion, with the w ( cos(alfa) ) being the last element in the 4 floats read?
- have other people encountered this kind of problems?


Nobody knows? Are the pfAnimMatrix coming from TranslationRotationScaling ( OpenGL model, vectors are columns, multiplication at right side )?


Sometimes the position, quaternion and scale isn't sufficient to represent the required transformations needed so in some cases only exporting the transformations as matrices will work. From your description, it sounds like you may have hit one of these cases.
If you want to rule out whether the problem is with your code or not, try viewing the scene in our PVRShaman utility.
pfAnimMatrix contains the matrices provided by 3dsmax before they're decomposed into position, quaternion and scale. So they aren't actually constructed from the position, quaternion and scale that get exported.
The last 4 values of each scale contains information on the axis system the scaling is performed in. The POD file format specification has details on them but in our code we tend to only use the first three values.


Hello Scott,

just thanks for the answer. So, my basic question now is - how can I export an animated model so that I can interpolate between animation frames ( typically to create animation blending )? Is there anything more I can expect from POD or I need to use some special settings from 3dsmax? Or should I move the question to a 3dmax forum :slight_smile: ?


Also, Shaman is viewing correctly the animated scene, when exported via Rotations, Translations and Scaling. Does Shaman use additional things, beside the T R S info, when computing the matrices?

wtherapy wrote:
Also, Shaman is viewing correctly the animated scene, when exported via Rotations, Translations and Scaling. Does Shaman use additional things, beside the T R S info, when computing the matrices?
PVRShaman uses the PVRTModelPOD code that is included in the SDK's tools, so nope, nothing additional.


For animation blending you don’t really need anything else but transformations ( Vec3,Vec3,Quat) and frame timing which is what you get from POD files.

Beyond that you will need to write some custom code for blending.

In general , a typical flow for blending would be.

1. Interpolate transforms for the first animation.
2. Interpolate transforms for the second animation
3. Blend 1 and 2 based on some factor.

You will need to make sure that both animations are designed in such way that interpolation actually makes sense (visually) - for instance if you want to blend between walking and running you will have to make sure that both animations have their equivalent poses ( left foot down etc) at the same position in the normalized time scale.

In other words, you can’t blend random animations and expect good results - you need to create animations with blending in mind.



I have already created the code for blending and worked well until I’ve encountered some ‘strange’ POD files. Those first animations was converting just fine from matrix to TRS ( I wasn’t aware, at that time, that powervr can export TRS, the importer was written by other developers ).
In the current case, we encounter matrices that cannot be converted to TRS ( when the model is exported with matrices ) or the TRS exported ( when the model is exported with TRS ) does not expand to the matrices found when exported with matrices. 

Just one last question: are the matrices read from file always Line-ordered?


Using this code:

PVRTMatrixTranslation( m0, node->pfAnimPosition[j * 3], node->pfAnimPosition[j * 3 + 1], node->pfAnimPosition[j * 3 + 2] );

q1.x = node->pfAnimRotation[j * 4 + 0];
q1.y = node->pfAnimRotation[j * 4 + 1];
q1.z = node->pfAnimRotation[j * 4 + 2];
q1.w = node->pfAnimRotation[j * 4 + 3];
PVRTMatrixRotationQuaternion(m1, q1);

PVRTMatrixScaling(m2, node->pfAnimScale[j * 7], node->pfAnimScale[j * 7 + 1], node->pfAnimScale[j * 7 + 2]);

PVRTMatrixMultiply(m2, m2, m1);
PVRTMatrixMultiply(m2, m2, m0);

yields, in m2 the same matrix computed by me.

What I have noticed is that the first 3x3 components are the same with the original matrix ( as exported with matrices ), but multiplied by -1.

Also, this code:

PVRTMat4 m40 = ((CPVRTModelPOD*)sc)->GetTranslationMatrix(*node);
PVRTMat4 m41 = ((CPVRTModelPOD*)sc)->GetRotationMatrix(*node);
PVRTMat4 m42 = ((CPVRTModelPOD*)sc)->GetScalingMatrix(*node);

m40 *= m41;
m40 *= m42;

yields the same matrix as computed by me; the original matrix ( as exported with matrices ) is the same matrix, but with scaling of (-1, -1, -1 ). If there is a mirror, can I get this info from somewhere? Any help appreciated