Search code examples
matrixviewopengl-esrotationgles20

Android: Camera rotation issues with GLES 20


I've moved my Camera (mViewMatrix) in the 3D Space, 15° to each angle x,y,z (with all angles 0° I have no issues with the camera rotation!)

All Objects in the 3D Space are fine (shown at the right bottom of the screen).

Ok, now I want to rotate the Camera around the X axis. The Objects in the bottom right corner should move from down to up on the right side.

But... because of the changed 15° camera angles ... the objects are moving not only down to up on the right side... they are moving also a little bit from right to left.

I think I have to change the vector from:

Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);

to:

Matrix.setRotateM(mViewMatrix, 0, 15, cameraVector.x, cameraVector.y, cameraVector.z);

... or something.

This is what I did (I know I have to use a rotate matrix, but here I've posted the simple code, only for easy read reasons):

Matrix.setIdentityM(mViewMatrix, 0);
Matrix.translateM(mViewMatrix, 0, 0, 0, -8);
Matrix.setRotateM(mViewMatrix, 0, 15 + angle, 1, 0, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 0, 1);

It would be nice if someone can post a working simple demo code, because I've tried 5 days, and I don't know how to fix it (I've tested a lot).


Solution

  • Actualy you can't rotate a camera in OpenGL. Instead, you should move/rotate the objects around. You need to apply model/view/projection matrices to each object being rendered. You don't have to calcalute them all by yourself, you can use the android.graphics.matrix. You used it in your code but with the wrong method. To rotate your camera you should use method.

    Matrix.setLookAtM(float rm[], int rmOffset, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
    

    However, you need to supply the coordinates of the point where your camera should be centered. Fortunately, finding coordinates of such a point is easy, you just need a little bit of trigonometry and 3 lines of code:

    centerX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );  
    centerY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );  
    centerZ =eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );  
    

    Math.cos( double angle ) and Math.sin( double angle ) accept angles in radians, so you should convert them to radians using Math.toRadians( double angle ). These functions return values of type double, so you need to cast them to float because Matrix class functions accept floats as coordinates.