[ODE] Mapping to OpenGL axis system
Ruud van Gaal
ruud at marketgraph.nl
Wed Nov 21 15:34:01 MST 2001
> no, ODE uses a right handed coord system, in both the dynamics and
> collision. the choice of the 'up' axis is arbitrary, but the
> handedness of the coordinate system is an important distinction.
Ok, I reverted all back to no negations, direct application. For positions,
this is ok (all is righthanded). For torque, it isn't. I started digging hard
and here are my results: (view in Courier)
I tested with a car in 2 simple orientations, 1 in the identity matrix
(dBodyGetRotation()=I), and 1 with the car rotated 90 degrees counterclockwise
(to the left) in yaw. Then, I applied just 1 torque, a relative torque around X
(which gives pitch rotation) for both orientations (using
dBodyAddRelTorque(body,1000,0,0). You'd expect (in OpenGL) the pitch to go
down.
Orientation 1 (I): after some integrations, the rotation matrix (ODE's) changes
from:
1 0 0 => 1 0 0
0 1 0 0 0.91 -0.4
0 0 1 0 0.41 0.9
Especially take a look at the Z vector (0,-0.4,0.9). The Y is down; the car
pitches downward. Now for orientation 2 (rotated 90 degrees in yaw):
0 0 1 => 0 -0.27 0.96
0 1 0 0 0.96 0.27
-1 0 0 -1 0 0
Here, although the same dBodyAddRelTorque(id,1000,0,0) was given, the car's Z
vector indicates the car is now pointing UPward (Y=0.27 which is >0).
I didn't think this could be right, no matter the orientation of the axes. So I
viewed the source code, and dBodyAddRel*() does a multiplication with the
body's R (rotation) member. But as I see it, this would convert World
coordinates into Body coordinates, right? Instead, it seems to be used to
calculate World coordinates *from* Body coordinates (which isn't right if I
understand correctly). As I see it, ODE stores all forces/torque in world
coordinates, probably because that makes a global contact resolve possible
(which needs all coordinates in the same reference frame). Wouldn't this
dBodyAddRel*() function need the inverse of R?
Not getting all this working for arbitrary orientations (and geez I tried), I
thus modified dBodyAddRelTorque() to multiple with the INVERTED R matrix
instead (where inverted is just transposed since we're dealing with rotations
only).
Here's my revised function:
void dBobyAddRelTorque(dBodyID b,dReal Fx,dReal Fy,dReal Fz)
{
dAASSERT(b);
dReal Rt[12];
Rt[0]=b->R[0];
Rt[1]=b->R[4];
Rt[2]=b->R[8];
Rt[3]=0;
Rt[4]=b->R[1];
Rt[5]=b->R[5];
Rt[6]=b->R[9];
Rt[7]=0;
Rt[8]=b->R[2];
Rt[9]=b->R[6];
Rt[10]=b->R[10];
Rt[11]=1;
dVector3 t1,t2;
t1[0]=fx;
t1[1]=fy;
t1[2]=fz;
dMULTIPLY1_331(t2,Rt,t1);
b->tacc[0]+=t2[0];
b->tacc[1]+=t2[1];
b->tacc[2]+=t2[2];
}
Now, both orientations mentioned above gave the right result; when applying
dBodyAddRelTorque(id,1000,0,0) for a body-relative torque around X, the pitch
went downward. I also tried an entirely different (not axis-aligned)
orientation which still gives me correct behavior.
Now I might be totally misinterpreting 'relative' in the dBodyAdd*() functions,
so please correct me how I *should* think about it then. I've got it working
for torque now though, and I'm ofcourse now convinced that the
transposed/inverted matrix should be used. I should modify dBodyAddRelForce()
as well ofcourse, but I've gotta sleep because I have to be up early tomorrow.
:) Just thought I'd run it by you.
Note that ofcourse calculating the transpose of R like that is highly
inefficient and should be done in some revised form with another
dMULTIPLY_Transposed() whatever. Couldn't dig through odemath.h hard enough to
see if dMULTIPLY1_331() isn't already doing a transpose (the code was quite
thick/recursively defined to trace with the naked eye).
Also note that you may not notice this at all if you're supplying ODE with all
world coordinates, so that's why everybody else's attempts probably work but
mine. ;-)
> i don't think you'll have to do any mapping - but remember to
> set the world gravity vector appropriately for your 'down' direction.
I didn't use gravity in the above examples btw. They would be done separately
from ODE's built in gravity anyway (for the time being, until I get this
resolved).
Sorry to go on about this in such length, but I found it weird that I could
solve it this way. Still don't understand why it works for forces though
(dBodyAddRelForce()).
Cheers,
Ruud
More information about the ODE
mailing list