SRT from Matrix? - beginners question

Started by
4 comments, last by Buckeye 14 years, 1 month ago
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?
Advertisement
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.
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
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.

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

You don't forget how to play when you grow old; you grow old when you forget how to play.

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!
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;}

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

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement