x


Converting Matrix4x4 to Quaternion & Vector3

I'm attempting to convert a Matrix4x4 which is being currently being applied to a camera using camera.worldToCameraMatrix and works fine.

I'm able to get the position out with:

Vector4 newCameraPos = matrix.GetColumn(3);
Camera.main.transform.position = Vector3(newCameraPos.x,newCameraPos.y,newCameraPos.z);

But at the moment can't get the quaternion to come out. I've pulled some code from a matrix and quaternion FAQ I stumbled across and have partially implemented, but at the moment its not behaving.

Quaternion matrixToQuaternionx(Matrix4x4 m1){
	float T = 1 + m1[0] + m1[5] + m1[10];

	Quaternion q = Quaternion.identity;

	if ( T > 0.00000001f ){
		float S = Mathf.Sqrt(T) * 2;
		q.x = ( m1[9] - m1[6] ) / S;
		q.y = ( m1[2] - m1[8] ) / S;
		q.z = ( m1[4] - m1[1] ) / S;
		q.w = 0.25f * S;
	}else{
		Debug.Log("more to calculate here");
	}

	return q;
}

If I turn off the camera.worldToCameraMatrix, and rely on the Vector and Quaternion I get out (ignoring cases where it gets to the 'more to calculate here') the position of the camera looks fine, but its rotation is way off.

more ▼

asked Feb 11 '10 at 07:15 AM

Leigh gravatar image

Leigh
59 2 2 7

(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

For getting a quaternion from a Matrix4x4, this function works:

public static Quaternion QuaternionFromMatrix(Matrix4x4 m) {
	// Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
	Quaternion q = new Quaternion();
	q.w = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] + m[1,1] + m[2,2] ) ) / 2; 
	q.x = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] - m[1,1] - m[2,2] ) ) / 2; 
	q.y = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] + m[1,1] - m[2,2] ) ) / 2; 
	q.z = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] - m[1,1] + m[2,2] ) ) / 2; 
	q.x *= Mathf.Sign( q.x * ( m[2,1] - m[1,2] ) );
	q.y *= Mathf.Sign( q.y * ( m[0,2] - m[2,0] ) );
	q.z *= Mathf.Sign( q.z * ( m[1,0] - m[0,1] ) );
	return q;
}

For getting the position, GetColumn(3) works fine.

more ▼

answered Feb 11 '10 at 11:08 AM

runevision gravatar image

runevision ♦♦
8.1k 29 46 112

Thanks!

It should be noted that if you're attempting to convert a valid worldToCameraMatrix to a quaternion rotation you'll need to adjust for the reversed z on camera and call something like:

Camera.main.transform.rotation = Quaternion.QuaternionFromMatrix(matrixToSet.inverse * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1,1,-1)));

Feb 14 '10 at 11:29 PM Leigh

such a great solution, thank you Rune!

Jan 30 '11 at 06:12 PM 3Duaun

What about the inverse operation? Obtaining a 4x4 out of a quaternion. Is that possible?

Sep 15 '11 at 07:27 AM roamcel
(comments are locked)
10|3000 characters needed characters left

Here's a faster and easier solution:

public static Quaternion QuaternionFromMatrix(Matrix4x4 m) { return Quaternion.LookRotation(m.GetColumn(2), m.GetColumn(1)); }

more ▼

answered May 21 '12 at 09:50 AM

Leto gravatar image

Leto
30

(comments are locked)
10|3000 characters needed characters left

Actually I can confirm that the

"For getting a quaternion from a Matrix4x4, this function works: ..."

Doesn't work, and the

"Here's a faster and easier solution: ..."

Works.

I'm making a voxel engine that performs all sorts of transforms and the first method produces: alt text

While the second función produces alt text

And the control test uses Graphics.DrawMesh() with the matrix transform as a parameter

more ▼

answered Jul 25 '12 at 01:08 AM

peacefulshade gravatar image

peacefulshade
16

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2173
x212

asked: Feb 11 '10 at 07:15 AM

Seen: 6028 times

Last Updated: Feb 19 at 04:48 AM