算法:
- 从 ModelMatrix * playerCentre 获取当前模型位置 (x,y,z)
- 将 ModelMatrix 设置为 IdentityMatrix
- 将对象转换为 0,0,0
- 将 z 轴旋转到 0
- 沿 y 轴平移 ds
- 旋转到 zAngle 的总旋转
- 使用步骤 3、4、5、6 设置 ModelMatrix
- 重复步骤 1
- 重复步骤 2
- 将对象转换为 0,0,0
- 将 z 轴旋转到 zAngle
- 将对象平移到步骤 1 中的模型位置 + 步骤 8 中的模型位置
代码:
private static void updateModel(int upDown, float xAngle, float yAngle, float zAngle) {
Matrix.setIdentityM(GLES20Renderer._RMatrix, 0);
//Matrix.rotateM(GLES20Renderer.RMatrix, 0, xAngle, 0, 1, 0);
//Matrix.rotateM(GLES20Renderer.RMatrix, 0, yAngle, 1, 0, 0);
Matrix.rotateM(GLES20Renderer._RMatrix, 0, zAngle, 0, 0, 1);
_ds = upDown - GLES20Renderer._upDown;
float[] RMatrix = new float[16];
float[] TMatrix = new float[16];
float objX = 0.0f;
float objY = 0.0f;
float objZ = 0.0f;
float objTempTranslateX = 0.0f;
float objTempTranslateY = 0.0f;
float objTempTranslateZ = 0.0f;
//////////////////////////////////////
// transformations for nozzle start //
//////////////////////////////////////
Matrix.multiplyMV(GLES20Renderer._uNozzleCentreMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentre, 0);
//collision parameter
objX = GLES20Renderer._uNozzleCentreMatrix[0];
objY = GLES20Renderer._uNozzleCentreMatrix[1];
objZ = GLES20Renderer._uNozzleCentreMatrix[2];
Log.d("ZAXIS", "OBJY: " + GLES20Renderer._uNozzleCentreMatrix[1]);
Matrix.setIdentityM(GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.setIdentityM(TMatrix, 0);
Matrix.translateM(TMatrix, 0, 0, (float)GLES20Renderer._ds/10, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixNozzle, 0, TMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._RMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.multiplyMV(GLES20Renderer._uNozzleCentreMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentre, 0);
objTempTranslateX = GLES20Renderer._uNozzleCentreMatrix[0];
objTempTranslateY = GLES20Renderer._uNozzleCentreMatrix[1];
objTempTranslateZ = GLES20Renderer._uNozzleCentreMatrix[2];
Matrix.setIdentityM(GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.setIdentityM(TMatrix, 0);
Matrix.setIdentityM(RMatrix, 0);
Matrix.translateM(TMatrix, 0, 0, 0, 0);
Matrix.rotateM(RMatrix, 0, 0, 0, 0, 1);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixNozzle, 0, RMatrix, 0, TMatrix, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._RMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.setIdentityM(TMatrix, 0);
if( Math.abs(GLES20Renderer._ds) > 0 ) {
Matrix.translateM(TMatrix, 0, (objX + objTempTranslateX), (objY + objTempTranslateY), (objZ + objTempTranslateZ));
}
Matrix.multiplyMM(GLES20Renderer._ModelMatrixNozzle, 0, TMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ViewMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0);
Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ProjectionMatrix, 0, GLES20Renderer._MVPMatrixNozzle, 0);
/////////////////////////////////////
// transformations for nozzle end //
/////////////////////////////////////
////////////////////////////////////
// transformations for body start //
////////////////////////////////////
Matrix.multiplyMV(GLES20Renderer._uBodyCentreMatrix, 0, GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._uBodyCentre, 0);
//collision parameter
objX = GLES20Renderer._uBodyCentreMatrix[0];
objY = GLES20Renderer._uBodyCentreMatrix[1];
objZ = GLES20Renderer._uBodyCentreMatrix[2];
Matrix.setIdentityM(GLES20Renderer._ModelMatrixBody, 0);
Matrix.setIdentityM(TMatrix, 0);
Matrix.setIdentityM(RMatrix, 0);
Matrix.translateM(TMatrix, 0, 0, 0, 0);
Matrix.rotateM(RMatrix, 0, 0, 0, 0, 1);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, RMatrix, 0, TMatrix, 0);
Matrix.setIdentityM(TMatrix, 0);
Matrix.translateM(TMatrix, 0, 0, (float)GLES20Renderer._ds/10, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, TMatrix, 0, GLES20Renderer._ModelMatrixBody, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._RMatrix, 0, GLES20Renderer._ModelMatrixBody, 0);
Matrix.multiplyMV(GLES20Renderer._uBodyCentreMatrix, 0, GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._uBodyCentre, 0);
objTempTranslateX = GLES20Renderer._uBodyCentreMatrix[0];
objTempTranslateY = GLES20Renderer._uBodyCentreMatrix[1];
objTempTranslateZ = GLES20Renderer._uBodyCentreMatrix[2];
Matrix.setIdentityM(GLES20Renderer._ModelMatrixBody, 0);
Matrix.setIdentityM(TMatrix, 0);
Matrix.setIdentityM(RMatrix, 0);
Matrix.translateM(TMatrix, 0, 0, 0, 0);
Matrix.rotateM(RMatrix, 0, 0, 0, 0, 1);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, RMatrix, 0, TMatrix, 0);
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, GLES20Renderer._RMatrix, 0, GLES20Renderer._ModelMatrixBody, 0);
Matrix.setIdentityM(TMatrix, 0);
if( Math.abs(GLES20Renderer._ds) > 0 ) {
Matrix.translateM(TMatrix, 0, (objX + objTempTranslateX), (objY + objTempTranslateY), (objZ + objTempTranslateZ));
}
Matrix.multiplyMM(GLES20Renderer._ModelMatrixBody, 0, TMatrix, 0, GLES20Renderer._ModelMatrixBody, 0);
Matrix.multiplyMM(GLES20Renderer._MVPMatrixBody, 0, GLES20Renderer._ViewMatrix, 0, GLES20Renderer._ModelMatrixBody, 0);
Matrix.multiplyMM(GLES20Renderer._MVPMatrixBody, 0, GLES20Renderer._ProjectionMatrix, 0, GLES20Renderer._MVPMatrixBody, 0);
///////////////////////////////////
// transformations for body end //
///////////////////////////////////
GLES20Renderer._upDown = upDown;
//collision parameter
Matrix.multiplyMV(GLES20Renderer._uPlayerCentreMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uPlayerCentre, 0);
}
这里 upDown 是按下可点击 ui 视图(例如 ui 按钮)沿头部指向的位置移动立方体的次数的当前值,实际上有两个按钮,一个用于向上,另一个用于向下,在上面的代码中我有两个立方体喷嘴和主体
请尝试自己实现该算法,因为给出的代码有一个错误导致 objY 自动递增
我有更少的时间,所以不会编辑代码以供您随时使用,即来自我的应用程序。
我已经发布了同样的问题,但我正在等待回复,算法是绝对正确的,只有代码有错误。
这是我的问题:
https ://stackoverflow.com/questions/11817450/rotation-about-local-z-axis