# 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 on other sites
Quote:
 Original post by jmgunn87i 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 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 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 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 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;}