Sign in to follow this  
jmgunn87

SRT from Matrix? - beginners question

Recommended Posts

i know that _41,_42,_43 from a 16*16 matrix will give me an absolute position but where do i get the scale and rotate values? Unable to find this out?

Share this post


Link to post
Share on other sites
Quote:
Original post by jmgunn87
i know that _41,_42,_43 from a 16*16 matrix will give me an absolute position but where do i get the scale and rotate values? Unable to find this out?
The XYZ scale values are in _11, _22 and _33, but the rotation is a bit more awkward. Google has plenty of links on matrices, they're not DirectX specific. The direction (+Z), up (+Y) and right (+X) vectors are in (_11, _21, _31), (_12, _22, _32) and (_13, _23, _33) (Although I may have got the row and column the wrong way around there). Matrices don't store rotation directly.

Share this post


Link to post
Share on other sites
In a 4x4 matrix there are separate scales on each of the 3 axes that form the matrix. So, assuming row-major ordering, the length of the first row vector is the scale on the x axis, the length of the 2nd is the scale of y, and the 3rd is the scale of z. Evil S is right [smile]

Extracting rotation is more complicated and you shouldn't really need to do it. Assuming it's an orthogonal matrix (all 3 axes are perpendicular to each other) then the matrix will store the sum total of rotations by how much the coordinate system it represents is rotated from the default axes: (1,0,0) (0,1,0) (0,0,1). If you really need to extract a set of angles, google "Matrix to Euler". It's important to note that there are many possible ways you can rotate one coordinate system to become another, so there is not a single correct answer to this problem.

-me

Share this post


Link to post
Share on other sites
You can use D3DXMatrixDecompose(), though the dx9.0 version has a bug.

I can't remember where it is, but there's substitute code for D3DXMatrixDecompose somewhere on the web. It's only about 40 lines of code and quite fast.

Share this post


Link to post
Share on other sites
yea, i was using MatrixDecompose. Didn't realise there was an actual bug in it but stopped using it due to its unreliability.
I'll have a look at extracting rotation a bit further.

Cheers!

Share this post


Link to post
Share on other sites
Found a copy. I believe this is the corrected version.

HRESULT XAD3DXMatrixDecompose(D3DXVECTOR3 *poutscale, D3DXQUATERNION *poutrotation, D3DXVECTOR3 *pouttranslation, D3DXMATRIX *pm)
{
D3DXMATRIX normalized;
D3DXVECTOR3 vec;
/*Compute the scaling part.*/
//vec.x=(*pm)(0,0);
//vec.y=(*pm)(0,1);
//vec.z=(*pm)(0,2);
vec.x=pm->_11;
vec.y=pm->_12;
vec.z=pm->_13;
poutscale->x=D3DXVec3Length(&vec);
vec.x=pm->_21;
vec.y=pm->_22;
vec.z=pm->_23;
poutscale->y=D3DXVec3Length(&vec);
vec.x=pm->_31;
vec.y=pm->_32;
vec.z=pm->_33;
poutscale->z=D3DXVec3Length(&vec);
/*Compute the translation part.*/
pouttranslation->x=pm->_41;
pouttranslation->y=pm->_42;
pouttranslation->z=pm->_43;
/*Let's calculate the rotation now*/
if ( (poutscale->x == 0.0f) || (poutscale->y == 0.0f) || (poutscale->z == 0.0f) ) return D3DERR_INVALIDCALL;
if( D3DXMatrixDeterminant(pm) < 0 ) poutscale->z *= -1; normalized._11=pm->_11/poutscale->x;
normalized._12=pm->_12/poutscale->x;
normalized._13=pm->_13/poutscale->x;
normalized._21=pm->_21/poutscale->y;
normalized._22=pm->_22/poutscale->y;
normalized._23=pm->_23/poutscale->y;
normalized._31=pm->_31/poutscale->z;
normalized._32=pm->_32/poutscale->z;
normalized._33=pm->_33/poutscale->z;

D3DXQuaternionRotationMatrix(poutrotation,&normalized);
return S_OK;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this