在矩阵滚动后,目标向量必须保持一致,因为目标只瞄准轴线。
实际上,你的目标不是vec3(0,150,150),而是vec3(0,0,150)。你旋转它,然后加上vec3(0,150,0)。所以想一想,如果你旋转z轴,vec3(0,0,150)始终是vec3(0,0,150)。
更新
是的,rotateM()将乘以之前设置的矩阵和现在设置的矩阵,所以逻辑上没有问题。
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;
}
}
这个 Android 函数 rotateM() 是以下三个矩阵的组合版本。
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