I basically have this problem:
Generic Simple 3D Matrix Rotation Issue
and it is driving me mad. I have been on Google for hours but cannot find any posts about
Thanks for all your help. I have found the answer here:
http://www.learnopengles.com/tag/rotation/
The solution is: "One easy way to work around this problem is to keep a second matrix around that will store all of the accumulated rotations." :-)
If I get it right you want to rotate direct object transform matrix around its own axises.
M0
is original object matrixR
is transformation you want to apply (rotation)M1
is the result new object matrixM1 = Inverse(Inverse(M0)*R)
That is all. you just have to add 4x4 inverse matrix routine to your code for example here is mine
void matrix_subdet (double *c,double *a)
{
double q[16];
int i,j;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
q[j+(i<<2)]=matrix_subdet(a,i,j);
for (i=0;i<16;i++) c[i]=q[i];
}
double matrix_subdet ( double *a,int r,int s)
{
double c,q[9];
int i,j,k;
k=0; // q = sub matrix
for (j=0;j<4;j++)
if (j!=s)
for (i=0;i<4;i++)
if (i!=r)
{
q[k]=a[i+(j<<2)];
k++;
}
c=0;
c+=q[0]*q[4]*q[8];
c+=q[1]*q[5]*q[6];
c+=q[2]*q[3]*q[7];
c-=q[0]*q[5]*q[7];
c-=q[1]*q[3]*q[8];
c-=q[2]*q[4]*q[6];
if (int((r+s)&1)) c=-c; // add signum
return c;
}
double matrix_det ( double *a)
{
double c=0;
c+=a[ 0]*matrix_subdet(a,0,0);
c+=a[ 4]*matrix_subdet(a,0,1);
c+=a[ 8]*matrix_subdet(a,0,2);
c+=a[12]*matrix_subdet(a,0,3);
return c;
}
double matrix_det ( double *a,double *b)
{
double c=0;
c+=a[ 0]*b[ 0];
c+=a[ 4]*b[ 1];
c+=a[ 8]*b[ 2];
c+=a[12]*b[ 3];
return c;
}
void matrix_inv (double *c,double *a)
{
double d[16],D;
matrix_subdet(d,a);
D=matrix_det(a,d);
if (D) D=1.0/D;
for (int i=0;i<16;i++) c[i]=d[i]*D;
}
matrix_inv(dst,src)
src
to dst
src
and dst
are double[16]
linear arrays representing 4x4 transform matrix [Edit1] 3x3 matrix
Mine matrix layout is this (OpenGL like):
double M[16];
a00 a04 a08 a12
a01 a05 a09 a13
a02 a06 a10 a14
a03 a07 a11 a15
a??
is ??-th value from M[]
Now if you want to use 4x4 inverse of 3x3 matrix just do this
double m[9];
b00 b03 b06 0
b01 b04 b07 0
b02 b05 b08 0
0 0 0 1
b??
is ??-th value from your 3x3 m[]
just to be sure you get it right m[3*3] -> M[4*4] will be like this:
M[ 0]=m[0];
M[ 1]=m[1];
M[ 2]=m[2];
M[ 3]=0.0;
M[ 4]=m[3];
M[ 5]=m[4];
M[ 6]=m[5];
M[ 7]=0.0;
M[ 8]=m[6];
M[ 9]=m[7];
M[10]=m[8];
M[11]=0.0;
M[12]=0.0;
M[13]=0.0;
M[14]=0.0;
M[15]=1.0;
And backwards m[3*3] <- M[4*4] will be like this:
m[0]=M[ 0];
m[1]=M[ 1];
m[2]=M[ 2];
m[3]=M[ 4];
m[4]=M[ 5];
m[5]=M[ 6];
m[6]=M[ 8];
m[7]=M[ 9];
m[8]=M[10];
The solution/workaraound is to apply the rotations in the correct order.
If you have rotation matrices A, B and C and want to apply them to matrix M in order A, B, C then the solution is:
First apply A:
A * M
Then B:
B * A * M
And finally C:
C * B * A * M
If you want to apply ABC frequently you can precalculate the combined rotation matrix R:
R = C * B * A
and then you can apply R to M:
R * M