如何在自己的对象空间上进行旋转?

时间:2012-08-06 10:22:39

标签: android rotation opengl-es-2.0

我正在绘制一个立方体。我希望它在对象空间中旋转。下面的代码使立方体围绕某个轴移动而不是它自己的轴。所以任何建议都要提前感谢。

    public void onSurfaceCreated(GL10 unused, EGLConfig config){
    // Set the background frame color
    GLES20.glClearColor(0.5f, 0.2f, 0.1f, 1.0f);

    Matrix.setLookAtM(viewMatrix, 0, 0.0f, 0.0f, -5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    cube = new Cube();     
}           

//  @Override
public void onSurfaceChanged(GL10 unused, int width, int height){
    GLES20.glViewport(0, 0, width, height);        
    float ratio = (float) width / height;
    float angle, near, far, bottom, top,left, right;
    angle = 45.0f;
    near = 1.0f;
    far = 10.0f;

    top = near * (float)Math.tan(angle*(Math.PI/360.0));
    bottom = -top;
    left = bottom * ratio;
    right = top * ratio;

    Matrix.frustumM(projectionMatrix, 0, left, right, bottom, top, near, far);
}

//@Override 
public void onDrawFrame(GL10 unused) {        
    // Draw background color
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    Matrix.setRotateM(rotationXMatrix, 0, mAngleX, 1.0f, 0.0f, 0.0f);
    Matrix.setRotateM(rotationYMatrix, 0, mAngleY, 0.0f, 1.0f, 0.0f);
    Matrix.multiplyMM(rotationMatrix, 0, rotationXMatrix, 0, rotationYMatrix, 0);
    Matrix.multiplyMM(modelViewMatrix, 0, rotationMatrix, 0, viewMatrix, 0);
    Matrix.multiplyMM(ModelViewProjectionMatrix, 0, projectionMatrix, 0, modelViewMatrix, 0);

    cube.draw(ModelViewProjectionMatrix, modelViewMatrix);      
}

1 个答案:

答案 0 :(得分:1)

算法:

  1. 从ModelMatrix * playerCentre
  2. 获取当前模型位置(x,y,z)
  3. 将ModelMatrix设置为IdentityMatrix
  4. 将对象翻译为0,0,0
  5. 将z轴旋转为0
  6. 通过ds
  7. 沿y轴平移
  8. 旋转到zAngle的总旋转
  9. 使用步骤3,4,5,6
  10. 设置ModelMatrix
  11. 重复步骤1
  12. 重复步骤2
  13. 将对象翻译为0,0,0
  14. 将z轴旋转到zAngle
  15. 将对象转换为步骤1中的模型位置+步骤8中的模型位置
  16. 代码:

    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