2012-08-30 181 views
1

在一個應用程序中,在嘗試使用觸摸旋轉一個對象時,我注意到有時候物體的位置漂移(沒有應用任何平移!!)。旋轉只是圍繞z軸進行的,並且完美地工作,但是漂移只發生在幾次旋轉之後。圍繞z軸旋轉漂移

ds將被用於翻譯(使用上下按鈕)

_uNozzleCentreMatrix_ModelMatrixNozzle將使用ds如果我糾正。

private static final float[] _uNozzleCentre  = new float[]{0.0f, 0.333605f, 0.0f, 1.0f}; 
protected static float[] _uNozzleCentreMatrix = new float[4]; 

public void onSurfaceChanged(GL10 gl, int width, int height) { 
    gl.glViewport(0, 0, width, height); 
    float ratio = (float) width/height; 
    Matrix.setLookAtM(GLES20Renderer._ViewMatrix, 0, 0, 0, 7f, 0, 0, 0, 0, 1, 0); 
    Matrix.frustumM(GLES20Renderer._ProjectionMatrix, 0, -ratio, ratio, -1, 1, 2, 8); 
    Matrix.setIdentityM(GLES20Renderer._ModelMatrixNozzle, 0); 
} 
private static void updateModel(int upDown, float xAngle, float yAngle, float zAngle) { 
    //ds    = GLES20Renderer._upDown - GLES20Renderer._lastUpDown; 
    ds = 0; // ds changes with button up-down, but now it is made 0, so button up-down will not affect it 
    Matrix.multiplyMV(GLES20Renderer._uNozzleCentreMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentre, 0); 
    if(Math.abs(ds) > 0) { 
    } else { 
     if(GLES20Renderer._zAngle >= 360) { 
      GLES20Renderer._zAngle = GLES20Renderer._zAngle - 360; 
     } 
     if(GLES20Renderer._zAngle <= -360) { 
      GLES20Renderer._zAngle = GLES20Renderer._zAngle + 360; 
     } 
     Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentreMatrix[0], GLES20Renderer._uNozzleCentreMatrix[1], 0); 
     Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._zAngle, 0, 0, 1); 
     Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._lastZAngle, 0, 0, 1); 
     Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._uNozzleCentreMatrix[0], -GLES20Renderer._uNozzleCentreMatrix[1], 0); 
    } 
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ViewMatrix, 0, GLES20Renderer._ModelMatrixNozzle, 0); 
    Matrix.multiplyMM(GLES20Renderer._MVPMatrixNozzle, 0, GLES20Renderer._ProjectionMatrix, 0, GLES20Renderer._MVPMatrixNozzle, 0); 

    GLES20Renderer._lastZAngle = zAngle; 
} 

的.apk下載:

http://www.pixdip.com/opengles/rotation/rotation.apk

(嘗試滑動極端更長的水平面積左至右早期觀察漂移,請耐心等待漂移可能需要20秒發生! )

對於那些誰沒有發生,這裏是自動化的apk: http://www.pixdip.com/opengles/rotation/automatic.apk

和代碼編輯的部分:

 Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._uNozzleCentreMatrix[0], GLES20Renderer._uNozzleCentreMatrix[1], 0); 
     Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, GLES20Renderer._zAngle, 0, 0, 1); 
     //Matrix.rotateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._lastZAngle, 0, 0, 1); 
     Matrix.translateM(GLES20Renderer._ModelMatrixNozzle, 0, -GLES20Renderer._uNozzleCentreMatrix[0], -GLES20Renderer._uNozzleCentreMatrix[1], 0); 
+0

什麼的線程和方法是調用「的UpdateModel」:

這可以通過使用不同的矩陣對於一些關鍵的轉變被刪除?如果這是連接到任何東西,但「繪製」的方法可能會出現你描述的問題。 –

+0

ondrawframe正在調用updatemodel。所有這些都在渲染器線程中。 – user1622689

回答

0

有時浮點錯誤得到積累,因爲矩陣堆棧。

private static float[] _TMatrix = new float[16]; 
private static float[] _ModelMatrix = new float[16]; 
Matrix.setIdentity(Renderer._ModelMatrix); 
Matrix.setIdentity(Renderer._TMatrix); 
Matrix.translate(Renderer._ModelMatrix, xmov,ymov,0); 
Matrix.translate(Renderer._TMatrix, -xmov,-ymov,0); 
Matrix.multiply(Renderer._ModelMatrix, Renderer._TMatrix, Renderer._ModelMatrix); 
// will result in an identity model matrix, without any floating point errors