ODE dBodyGetRotation results in shear

Started by
3 comments, last by gb_programmer 16 years, 3 months ago
Hello everyone, I've been trying to do some stuff with ODE (Tao.Ode, ode version 0.6 I think) and have been having some problems with it. dBodyGetRotation returns a 3x4 (or 4x3?) matrix which somehow results in me getting a shear on the model I am rendering (a box) instead of a rotation. For debug I printed out the output of dBodyGetRotation so here it is: 0.7642459 0.01327106 0 0 -0.01014324 0.999912 0 0 0.6448452 -9.313226E-10 -1 0 in the order 0 1 2 3 4 5 6 7 8 9 10 11 - is this all right as a pure rotation matrix for the 3x3 part? - if it is I guess I am messing up how I make a model matrix from it. I am using OpenGL and Cg and I just put those floats as the first 12 elements of the matrix, add translation to elements 3,7 and 11 and then give it to Cg as a row major cgGLSetMatrixParameterfr matrix. I would appreciate any help, thanks!
Advertisement
Quote:Original post by deavik
- is this all right as a pure rotation matrix for the 3x3 part?


No. A matrix that contains only rotation is orthogonal, that is, if we interpret it's rows (and columns) as 3D vectors, those vectors are orthogonal to each and have unit length. It's easy to see the the third row of your matrix is not a vector of unit length, because it's third element is -1 (so the other two should be zero).

Note that I'm referring to the upper left 3x3 part.

I'm not familiar with ODE, but it seems a bit strange to me that a function that's supposed to return a rotation matrix returns a 3x4 (or 4x3) matrix, as you only need a 3x3 matrix for that.

Either way, remember that OpenGL uses column vectors, and make sure you know what ODE uses. If it returns a 3x4 matrix, it uses column vectors. If it's 4x3, it uses row vectors (although if the matrix only contains rotation, then it's orthogonal and it's inverse is equal to it's transpose so transposing it shouldn't make a difference).

Hope this helps you somehow.
Interesting...I've had problems with the quaternion version of ODE object orientations becoming inconsistent, but the dBodyGetRotation results always seemed fine. So, let me show you a code snippet from my ODE integration code, which works (or did last time I ran it, which was not very recently). This shows you how I build the 3x3 rotation matrix part:

// Now for the rotations. ODE keeps body orientation// stored as both a matrix and a quaternion. Hmmmm.// So, it seems due to a bug in the ODE utility function// dQfromR, the quaternion version can become out-of-date,// and just plain wrong. Therefore, we grab the rotation// version.const dReal *pODEMat = dBodyGetRotation(BodyID);RotMat.Set(	float(pODEMat[0]), float(pODEMat[4]), float(pODEMat[8]),		float(pODEMat[1]), float(pODEMat[5]), float(pODEMat[9]),		float(pODEMat[2]), float(pODEMat[6]), float(pODEMat[10]));


That should tell you the appropriate elements from the ODE result to use to build your 3x3. You may still need to transpose the 3x3 depending on which math/graphics library you are using for display.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Quote:Original post by grhodes_at_work
Interesting...I've had problems with the quaternion version of ODE object orientations becoming inconsistent, but the dBodyGetRotation results always seemed fine.

What you said gave me an idea, so I instead used dBodyGetQuaternion, converted to a matrix with my own code and now it works. I know that doesn't really address the problem... and unless I've done something incredibly stupid I think there may be a bug in the runtime somewhere. I'll keep looking.
Dude, ODE uses 4x3 matrices for rotation.
You clearly need THIS CODE:
void renderer::setTransform (const float pos[3], const float R[12])//convert 4x3 rotation matrix and 4d vector into transform matrix//taken from ODE's renderer "drawstuff"{  GLfloat matrix[16];  matrix[0]=R[0];  matrix[1]=R[4];  matrix[2]=R[8];  matrix[3]=0;  matrix[4]=R[1];  matrix[5]=R[5];  matrix[6]=R[9];  matrix[7]=0;  matrix[8]=R[2];  matrix[9]=R[6];  matrix[10]=R[10];  matrix[11]=0;  matrix[12]=pos[0];  matrix[13]=pos[1];  matrix[14]=pos[2];  matrix[15]=1;  glMultMatrixf (matrix);}


It's a cleaner version of the one the included drawstuff renderer. Use it thusly:

T = dBodyGetPosition(mBodyID);R = dBodyGetRotation(mBodyID);ren->setTransform(T,R);


Works just fine for me, I tested it so far on trimeshes, cubes, and boxes. To quote the ODE use guide, "Hmm, dBodyGetRotation() returns a 4x3 matrix". The shear you are getting could be junk data.

This topic is closed to new replies.

Advertisement