我已经找到了这个问题的解决方案,但似乎没有办法。
我正在使用JBullet库并检索对象方向,它以四元数形式给出。我如何从这个四元数中检索Euler值,以便我可以调用..?
glRotate(rotationX, 1, 0, 0);
glRotate(rotationY, 0, 1, 0);
glRotate(rotationZ, 0, 0, 1);
或许有更有效的方式?
编辑:
我试过quat - > VEC
public static Vector3f quatToVec(Quat4f q) {
float x = q.x;
float y = q.y;
float z = q.z;
float w = q.w;
float roll = (float) (Math.atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z) / Math.PI * 360);
float pitch = (float) (Math.atan2(2*x*w - 2*y*z, 1 - 2*x*x - 2*z*z) / Math.PI * 360);
float yaw = (float) (Math.asin(2*x*y + 2*z*w) / Math.PI * 720);
return new Vector3f(yaw, pitch, roll);
}
我试过quat - >旋转矩阵
public static FloatBuffer quatToMatrix(Quat4f q) {
float qx = q.x;
float qy = q.y;
float qz = q.z;
float qw = q.w;
FloatBuffer fb = BufferUtils.createFloatBuffer(16);
fb.put(new float[]{1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f});
fb.flip();
return fb;
}
然而,似乎没有任何工作
答案 0 :(得分:2)
你发布的第二个解决方案更可取,因为欧拉角在+/- 90度间距会受到奇点(在其他领域称为万向节锁定)的影响。
你现在面临的最大障碍是,无论出于何种原因,你的矩阵都是行主要的。由于这是一个通用FloatBuffer
而不是实际的矩阵类,因此当您执行fb.put (...)
时,您可能需要自己转置矩阵。
这应该可以解决问题:
fb.put(new float[] {1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy + 2.0f*qz*qw, 2.0f*qx*qz - 2.0f*qy*qw, 0.0f,
2.0f*qx*qy - 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz + 2.0f*qx*qw, 0.0f,
2.0f*qx*qz + 2.0f*qy*qw, 2.0f*qy*qz - 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f});
答案 1 :(得分:2)
您可以使用
进行1次轮换通话glRotation(Math.acos(q.w)*360/Math.PI, q.x, q.y, q.z);
然而矩阵提取是首选,因为它避免了acR,然后是glRotation调用中的cos
答案 2 :(得分:1)
之前我遇到过这个问题,这是我的(直接复制粘贴)代码:
static public void addBoneRotation(float[] quart){
//0 1 2 3 4 5 6
//x, y, z, qw, qx, qy, qz;
//rotate by (qw, qx, qy, qz)
tmp.m00=1 - 2*quart[5]*quart[5] - 2*quart[6]*quart[6];
tmp.m01=2*quart[4]*quart[5] - 2*quart[6]*quart[3];
tmp.m02=2*quart[4]*quart[6] + 2*quart[5]*quart[3];
tmp.m03=0;
tmp.m10=2*quart[4]*quart[5] + 2*quart[6]*quart[3];
tmp.m11=1 - 2*quart[4]*quart[4] - 2*quart[6]*quart[6];
tmp.m12=2*quart[5]*quart[6] - 2*quart[4]*quart[3];
tmp.m13=0;
tmp.m20=2*quart[4]*quart[6] - 2*quart[5]*quart[3];
tmp.m21=2*quart[5]*quart[6] + 2*quart[4]*quart[3];
tmp.m22=1 - 2*quart[4]*quart[4] - 2*quart[5]*quart[5];
tmp.m23=0;
tmp.m30=tmp.m31=tmp.m32=0;
tmp.m33=1;
//translate by (x,y,z)
tmp2.m30=quart[0];
tmp2.m31=quart[1];
tmp2.m32=quart[2];
Matrix4f.mul(tmp2,tmp,tmp);
//add to the current bone transformation
Matrix4f.mul(tmp, bone, bone);
}
这假设quart []包含骨骼转换和旋转。
您需要稍微更改一下以匹配您的应用程序。
允许连续对链骨进行这些调用。