2012-08-30 142 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