I've been working on it for a long time, but I don't have a working solution: how can I convert ODE rotation matrices to Irr rotation vectors?
I've tried these so far:
(Where it seems that indices 1 and 2 are in the wrong order, it is because ODE's y vector is Irr's z and vv.)
http://www.euclideanspace.com/maths/geo ... /index.htm
To this, I first convert the dMatrix3d to dQuaternion first
The code derived from this:
Code: Select all
float test=q[0]*q[2]+q[1]*q[3];
if(test>0.449) { //singularity @ N pole
res[2]=2*atan2(q[0],q[3]);
res[1]=-M_PI/2.0;
res[0]=0.0;
} else {
if(test<-0.449) { //singularity @ S pole
res[2]=-2*atan2(q[0],q[3]);
res[1]=M_PI/2.0;
res[0]=0.0;
} else { //no singularity
float sqx=q[0]*q[0];
float sqy=q[2]*q[2];
float sqz=q[1]*q[1];
res[2]=atan2((float)(2*q[2]*q[3]-2*q[0]*q[1]),(float)(1-2*sqy-2*sqz));
res[1]=asin(2*test);
res[0]=atan2((float)(2*q[0]*q[3]-2*q[1]*q[2]),(float)(1-2*sqx-2*sqz));
}
}
res[0]+=M_PI;
float RD=180.0/M_PI;
res[0]*=RD;res[1]*=RD;res[2]*=RD;
A 'bit' simplified version:
Code: Select all
float sqx=q[0]*q[0];
float sqy=q[2]*q[2];
float sqz=q[1]*q[1];
float test=q[0]*q[2]+q[1]*q[3];
res[0]=atan2((float)(2*q[2]*q[3]-2*q[0]*q[1]),(float)(1-2*sqy-2*sqz));
res[1]=atan2((float)(2*q[0]*q[3]-2*q[1]*q[2]),(float)(1-2*sqx-2*sqz));
res[2]=asin(2*test);
res[1]+=M_PI;
float RD=180.0/M_PI;
res[0]*=RD;res[1]*=RD;res[2]*=RD;
This doesn't use quaternions, the algorythm is taken from
http://web.archive.org/web/200410290038 ... t.html#Q37
Code: Select all
flatd[1]=asin(ode_par[2]); /* Calculate Y-axis angle */
float C=cos(flatd[2]);
flatd[1]=(C/M_PI)*180.0;
if(fabs(C)>0.005) { //Gimball lock?
float tr_x=ode_par[10]/C; // No, so get X-axis angle
float tr_y=-ode_par[6]/C;
flatd[0]=(atan2(tr_y,tr_x)/M_PI)*180.0;
tr_x=ode_par[0]/C; // Get Z-axis angle
tr_y=-ode_par[1]/C;
flatd[2]=(atan2(tr_y,tr_x)/M_PI)*180.0;
} else { // Gimball lock has occurred
flatd[0]=0; // Set X-axis angle to zero
float tr_x=ode_par[5]; // And calculate Z-axis angle
float tr_y=ode_par[4];
flatd[2]=(atan2(tr_y,tr_x)/M_PI)*180.0;
}
The last thing I tried was to convert ODE quaternions to irr quaternions
Code: Select all
core::vector3df ode_rot_2_v3df(const dReal* ode_par) {
float RD=180.0/M_PI;
dQuaternion ode_q;
dRtoQ(ode_par,ode_q);
core::quaternion irr_q(ode_q[0]*RD,ode_q[2]*RD,ode_q[1]*RD,ode_q[3]*RD);
core::vector3df res;
irr_q.toEuler(res);
return res;
}
So: what's the correct way to do this? Or what's wrong with these codes?
Thx
Toma