Tuesday, January 24, 2017

How to get RotationMatrix from yaw, pitch and roll

Leave a Comment

Hi I managed to find yaw, pitch and roll from acceleratoin and magnetic sensor in my Android app. I now want to rotate my Camera Target(min3d) around a point in my scene according to does angles. The result is to be able to look in a 3d scene by moving the android device around. I've been trying for days almost read all related answers in SO but I just can't have it work.

The movement I get has absolutely no sens. I verified that my yaw is between 0-360 and is correct, pitch is between -90 and 90 and is correct and finally the roll is between -180 and 180 and is consistent.

Basically I am doing matrix rotation and multiplication by my target and up vector.

float[] rotation = new float[16];    Matrix.setIdentityM(rotation, 0); Matrix.rotateM(rotation, 0, (float) Math.toDegrees(roll), 0, 0, 1);          Matrix.rotateM(rotation, 0, (float) Math.toDegrees(pitch)+90f, 1, 0, 0);         Matrix.rotateM(rotation, 0, (float) Math.toDegrees(-azimut), 0, 1, 0);        float[] target = new float[4]; float[] source = new float[]{0,0,150,0};     Matrix.multiplyMV(target, 0,rotation, 0, source, 0); float targetX = target[0] + 0; float targetY = target[1] + 150; float targetZ = -target[2] + 0;  target = new float[4]; source = new float[]{0,1,0,0}; Matrix.multiplyMV(target, 0,rotation, 0, source, 0); float upX = target[0]; float upY = target[1]; float upZ = target[2];  scene.camera().target.x = targetX;               scene.camera().target.y = targetY; scene.camera().target.z = targetZ;       scene.camera().upAxis.x = upX; scene.camera().upAxis.y = upY; scene.camera().upAxis.z = upZ; 

Initially my target is at (0,0,150) and my up vector is (0,1,0).

Thank you for any help.

1 Answers

Answers 1

After the roll matrix, the target vector must be consistent because the target only aim axis.

Actually, your target is not vec3(0,150,150) the target is vec3(0,0,150) indeed. You rotate it and then add vec3(0,150,0). So think about it, vec3(0,0,150) is always vec3(0,0,150) if you rotate z-axis.

Update

Yes, rotateM() multiplies the matrix you set before and a matrix you set now, so logically there is no problem there.

 public static void rotateM(float[] rm, int rmOffset,         float[] m, int mOffset,         float a, float x, float y, float z) {     synchronized(sTemp) {         setRotateM(sTemp, 0, a, x, y, z);         multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);     }  public static void setRotateM(float[] rm, int rmOffset,         float a, float x, float y, float z) {     rm[rmOffset + 3] = 0;     rm[rmOffset + 7] = 0;     rm[rmOffset + 11]= 0;     rm[rmOffset + 12]= 0;     rm[rmOffset + 13]= 0;     rm[rmOffset + 14]= 0;     rm[rmOffset + 15]= 1;     a *= (float) (Math.PI / 180.0f);     float s = (float) Math.sin(a);     float c = (float) Math.cos(a);     if (1.0f == x && 0.0f == y && 0.0f == z) {         rm[rmOffset + 5] = c;   rm[rmOffset + 10]= c;         rm[rmOffset + 6] = s;   rm[rmOffset + 9] = -s;         rm[rmOffset + 1] = 0;   rm[rmOffset + 2] = 0;         rm[rmOffset + 4] = 0;   rm[rmOffset + 8] = 0;         rm[rmOffset + 0] = 1;     } else if (0.0f == x && 1.0f == y && 0.0f == z) {         rm[rmOffset + 0] = c;   rm[rmOffset + 10]= c;         rm[rmOffset + 8] = s;   rm[rmOffset + 2] = -s;         rm[rmOffset + 1] = 0;   rm[rmOffset + 4] = 0;         rm[rmOffset + 6] = 0;   rm[rmOffset + 9] = 0;         rm[rmOffset + 5] = 1;     } else if (0.0f == x && 0.0f == y && 1.0f == z) {         rm[rmOffset + 0] = c;   rm[rmOffset + 5] = c;         rm[rmOffset + 1] = s;   rm[rmOffset + 4] = -s;         rm[rmOffset + 2] = 0;   rm[rmOffset + 6] = 0;         rm[rmOffset + 8] = 0;   rm[rmOffset + 9] = 0;         rm[rmOffset + 10]= 1;     } else {         float len = length(x, y, z);         if (1.0f != len) {             float recipLen = 1.0f / len;             x *= recipLen;             y *= recipLen;             z *= recipLen;         }         float nc = 1.0f - c;         float xy = x * y;         float yz = y * z;         float zx = z * x;         float xs = x * s;         float ys = y * s;         float zs = z * s;         rm[rmOffset +  0] = x*x*nc +  c;         rm[rmOffset +  4] =  xy*nc - zs;         rm[rmOffset +  8] =  zx*nc + ys;         rm[rmOffset +  1] =  xy*nc + zs;         rm[rmOffset +  5] = y*y*nc +  c;         rm[rmOffset +  9] =  yz*nc - xs;         rm[rmOffset +  2] =  zx*nc - ys;         rm[rmOffset +  6] =  yz*nc + xs;         rm[rmOffset + 10] = z*z*nc +  c;     } } 

This android function rotateM() is a combined version of these three matrices below

void Matrix_Rotation_X(Matrix   &out_M,const float angle) {     float COS = (float)cos(angle);     float SIN = (float)sin(angle);     out_M.s[_0x0_]=  1.f;       out_M.s[_0x1_]= 0.f;    out_M.s[_0x2_]= 0.f;    out_M.s[_0x3_]= 0.f;     out_M.s[_1x0_]=  0.f;       out_M.s[_1x1_]= COS;    out_M.s[_1x2_]= SIN;    out_M.s[_1x3_]= 0.f;     out_M.s[_2x0_]=  0.f;       out_M.s[_2x1_]=-SIN;    out_M.s[_2x2_]= COS;    out_M.s[_2x3_]= 0.f;     out_M.s[_3x0_]=  0.f;       out_M.s[_3x1_]= 0.f;    out_M.s[_3x2_]= 0.f;    out_M.s[_3x3_]= 1.f;  }  void Matrix_Rotation_Y(Matrix   &out_M, const float angle) {     float COS = (float)cos(angle);     float SIN = (float)sin(angle);     out_M.s[_0x0_]=  COS;       out_M.s[_0x1_]= 0.f;    out_M.s[_0x2_]=-SIN;    out_M.s[_0x3_]= 0.f;     out_M.s[_1x0_]=  0.f;       out_M.s[_1x1_]= 1.f;    out_M.s[_1x2_]= 0.f;    out_M.s[_1x3_]= 0.f;     out_M.s[_2x0_]=  SIN;       out_M.s[_2x1_]= 0.f;    out_M.s[_2x2_]= COS;    out_M.s[_2x3_]= 0.f;     out_M.s[_3x0_]=  0.f;       out_M.s[_3x1_]= 0.f;    out_M.s[_3x2_]= 0.f;    out_M.s[_3x3_]= 1.f; }  void Matrix_Rotation_Z( Matrix  &out_M, const float angle) {     float COS = (float)cos(angle);     float SIN = (float)sin(angle);     out_M.s[_0x0_]=  COS;       out_M.s[_0x1_]= SIN;    out_M.s[_0x2_]= 0.f;    out_M.s[_0x3_]= 0.f;     out_M.s[_1x0_]=  -SIN;      out_M.s[_1x1_]= COS;    out_M.s[_1x2_]= 0.f;    out_M.s[_1x3_]= 0.f;     out_M.s[_2x0_]=  0.f;       out_M.s[_2x1_]= 0.f;    out_M.s[_2x2_]= 1.f;    out_M.s[_2x3_]= 0.f;     out_M.s[_3x0_]=  0.f;       out_M.s[_3x1_]= 0.f;    out_M.s[_3x2_]= 0.f;    out_M.s[_3x3_]= 1.f; } 

https://github.com/sunglab/StarEngine/blob/master/math/Matrix.cpp

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment