btMatrix3x3::getEulerZYX () degenerate case

attente
Posts: 1
Joined: Thu Oct 07, 2010 3:30 am

btMatrix3x3::getEulerZYX () degenerate case

Post by attente »

Hi,

I looked around, but didn't notice any prior topic about this, and am hoping that I'm putting this in the right place. It's a very very minor thing, but when I call it on a matrix that triggers the degenerate case in this function, the angles I get back are incorrect. The typical case works perfectly though.

The degenerate matrix is (a simple pi/2 pitch rotation):

0 0 1
0 1 0
-1 0 0

If I'm not asking too much, could someone take a look at the diff? I've tested it and believe it's correct according to this: http://www.gregslabaugh.name/publications/euler.pdf.

Thanks! :D

Code: Select all

Index: btMatrix3x3.h
===================================================================
--- btMatrix3x3.h	(revision 2225)
+++ btMatrix3x3.h	(working copy)
@@ -291,7 +291,7 @@
 
 
 	/**@brief Get the matrix represented as euler angles around ZYX
-	* @param yaw Yaw around X axis
+	* @param yaw Yaw around Z axis
 	* @param pitch Pitch around Y axis
 	* @param roll around X axis 
 	* @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/	
@@ -315,20 +315,20 @@
 			euler_out2.yaw = 0;
 
 			// From difference of angles formula
-			btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
-			if (m_el[2].x() > 0)  //gimbal locked up
+			btScalar delta = btAtan2(m_el[0].y(),m_el[0].z());
+			if (m_el[2].x() < 0)  //gimbal locked down
 			{
 				euler_out.pitch = SIMD_PI / btScalar(2.0);
 				euler_out2.pitch = SIMD_PI / btScalar(2.0);
-				euler_out.roll = euler_out.pitch + delta;
-				euler_out2.roll = euler_out.pitch + delta;
+				euler_out.roll = euler_out.yaw + delta;
+				euler_out2.roll = euler_out.yaw + delta;
 			}
-			else // gimbal locked down
+			else // gimbal locked up
 			{
 				euler_out.pitch = -SIMD_PI / btScalar(2.0);
 				euler_out2.pitch = -SIMD_PI / btScalar(2.0);
-				euler_out.roll = -euler_out.pitch + delta;
-				euler_out2.roll = -euler_out.pitch + delta;
+				euler_out.roll = -euler_out.yaw + delta + SIMD_PI;
+				euler_out2.roll = -euler_out.yaw + delta + SIMD_PI;
 			}
 		}
 		else