Matrix.multiplyMM(float[] result, int resultOffset, float[] lhs, int lhsOffset, float[] rhs, int rhsOffset)
Multiply two 4x4 matrices together and store the result in a third 4x4 matrix. In matrix notation: result = lhs x rhs. Due to the way matrix multiplication works, the result matrix will have the same effect as first multiplying by the rhs matrix, then multiplying by the lhs matrix. This is the opposite of what you might expect. The same float array may be passed for result, lhs, and/or rhs. However, the result element values are undefined if the result elements overlap either the lhs or rhs elements.
将两个4x4矩阵相乘,把结果存到第三个4x4矩阵里。用矩阵符号表示:result = lhs x rhs 。由于矩阵相乘的工作方式,结果矩阵的效果相当于先被右边的矩阵乘,再被左边的矩阵乘。这跟你期望的情况是相反的。同一个float数组可以作为结果矩阵、左边矩阵、右边矩阵。然而,如果结果矩阵的元素与右边矩阵或左边矩阵的元素重叠,结果矩阵的元素就会无法确定。
奇怪的是,在Android的官方例子中看到如下的代码:
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
结果矩阵和右边矩阵都是mMVPMatrix,offset都是0。
做如下的测试:
float[] lhs = new float[16];
float[] rhs = new float[16];
float[] res = new float[16];
Matrix.setRotateM(lhs, 0, 45, 1, 1, 0);
Matrix.setRotateM(rhs, 0, 30, 0, 1, 1);
System.out.println("lhs");
MatrixUtil.printMatrix(lhs);
System.out.println("rhs");
MatrixUtil.printMatrix(rhs);
Matrix.multiplyMM(res, 0, lhs, 0, rhs, 0);
System.out.println("res");
MatrixUtil.printMatrix(res);
Matrix.setRotateM(lhs, 0, 45, 1, 1, 0);
Matrix.setRotateM(rhs, 0, 30, 0, 1, 1);
Matrix.multiplyMM(rhs, 0, lhs, 0, rhs, 0);
System.out.println("overlap rhs res");
MatrixUtil.printMatrix(rhs);
Matrix.setRotateM(lhs, 0, 45, 1, 1, 0);
Matrix.setRotateM(rhs, 0, 30, 0, 1, 1);
Matrix.multiplyMM(lhs, 0, lhs, 0, rhs, 0);
System.out.println("overlap lhs res");
MatrixUtil.printMatrix(lhs);
运行结果:
lhs
0.8536 0.1464 0.5000 0.0000
0.1464 0.8536 -0.5000 0.0000
-0.5000 0.5000 0.7071 0.0000
0.0000 0.0000 0.0000 1.0000
rhs
0.8660 -0.3536 0.3536 0.0000
0.3536 0.9330 0.0670 0.0000
-0.3536 0.0670 0.9330 0.0000
0.0000 0.0000 0.0000 1.0000
res
0.6142 -0.1316 0.7781 0.0000
0.6054 0.7111 -0.3576 0.0000
-0.5062 0.6907 0.5165 0.0000
0.0000 0.0000 0.0000 1.0000
overlap rhs res
0.6142 -0.1316 0.7781 0.0000
0.6054 0.7111 -0.3576 0.0000
-0.5062 0.6907 0.5165 0.0000
0.0000 0.0000 0.0000 1.0000
overlap lhs res
0.6142 -0.0470 0.6805 0.0000
0.6054 0.5488 -0.2157 0.0000
-0.5062 0.6929 0.5272 0.0000
0.0000 0.0000 0.0000 1.0000
当结果矩阵与右边矩阵重叠时,运算结果是正确的。
当结果矩阵与左边矩阵重叠时,运算结果是不正确的。
这就可以理解为啥Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);工作正常了。当然为了避免出问题,最好还是不要重叠。
void android.opengl.Matrix.setRotateM(float[] rm, int rmOffset, float a, float x, float y, float z)
设置矩阵rm为绕axis (x, y, z)旋转角度a的旋转矩阵。
void android.opengl.Matrix.rotateM(float[] m, int mOffset, float a, float x, float y, float z)
Rotates matrix m in place by angle a (in degrees) around the axis (x, y, z)
让矩阵m右乘一个旋转矩阵。
作用到一个物体上时,效果是让物体先旋转,再被m作用。
void android.opengl.Matrix.translateM(float[] m, int mOffset, float x, float y, float z)
Translates matrix m by x, y, and z in place.
让矩阵m右乘一个平移矩阵。
作用到一个物体时,效果是让物体先平移,再被m作用。