I have written a first person camera class for android.
The class is really simple , the camera object has its three axes X,Y
and Z
And I am using an Eye and a LookAt point to create the ModelView
matrix, which seems to be working fine.
The problem comes when i try to rotate around the Y-axis ( or X-
axis) .
I am simply creating a rotation matrix around the Y-axis and
multiplying it with the Eye vector.
But after 45-degree my camera starts rotating in reverse direction.
I have taken measurements after every 1-degree rotation and it seems
that my Eye-vector although it rotates but it lags behind.
e.g. if i rotate 20-degrees it has rotated only 12.
But after 45-degree things really start to go out of control.
I though it must be a problem with the Rotation matrices that i create
to rotate the Eye-vector.
So i made two implementations, one using the functions in
android.opengl.Matrix package (e.g. setRoatetM)
and doing everything from scratch using (sin, cos ) functions.
But surprisingly the results are same.
Below is the code from the Camera class.
The three main functions involved in rotations are :
1. applyModelViewTransform( ) // this is where I use the setLookAtM()
2. yaw( ) // rotating LookAt around y-axis of the camera
3. reNormalizeAxes() // recalculating all the camera's Axes
-------------------------------------------------
package com.droidnova.android.games.vortex;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.Matrix;
import android.util.Log;
import com.surrealtech.math.util.Vector3;
public class Camera7 implements ICamera {
Vector3 _vecUp = new Vector3(0,1,0); // global UP vector
Vector3 _vecLookAt; // look-at point vector
Vector3 _vecEye; // eye position
Vector3 _X; // camera's x-axis
Vector3 _Y; // camera's y-axis
Vector3 _Z; // camera's z-axis
float[] _matModelView = new float[16];
float[] _matRotation = new float[16];
float[] _vecTemp4 = new float[4]; // a temporary vector to store
results
float angleYaw = 0;
float anglePitch = 0;
public Camera7() {
// Initialize all vectors
_vecEye = new Vector3(0.0f, 1.0f, 2.0f); // eye
_vecLookAt = new Vector3(0.0f, 1.0f, 1.0f); // look-at
// // normalize all axis
// reNormalizeAxes();
//
// // calculate the mdoel view matrix
// Matrix.setLookAtM (_matModelView, 0,
// _vecEye.x, _vecEye.y,
_vecEye.z,
// _vecLookAt.x,
_vecLookAt.y, _vecLookAt.z,
// _Y.x, _Y.y, _Y.z);
}
private void reNormalizeAxes(){
_Z = Vector3.Subtract(_vecLookAt, _vecEye);
_Z.Normalise();
// calculate the right vector from
_X = Vector3.Cross(_Z, _vecUp); // this should give the +ve
X-axis
of camera from right-hand rule
_X.Normalise();
_Y = Vector3.Cross(_X, _Z);
_Y.Normalise();
}
@Override
public void applyModelViewTransform(GL10 gl) {
// normalize all axis
reNormalizeAxes();
// calculate the mdoel view matrix
Matrix.setLookAtM (_matModelView, 0,
_vecEye.x, _vecEye.y,
_vecEye.z,
_vecLookAt.x,
_vecLookAt.y, _vecLookAt.z,
_Y.x, _Y.y, _Y.z);
// push the new openGL matrix
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadMatrixf(_matModelView, 0);
}
@Override
public void pitch(GL10 gl, float angle) {
// get the rotation matrix around X-Axis
Matrix.setIdentityM(_matRotation, 0);
Matrix.setRotateM(_matRotation, 0, (float)Math.toDegrees(angle),
_X.x, _X.y, _X.z);
// rotate the LookAt point
Matrix.multiplyMV(_vecTemp4, 0, _matRotation, 0,
_vecLookAt.getFloat(), 0);
_vecLookAt.setFloat(_vecTemp4);
// apply transform
this.applyModelViewTransform(gl);
}
@Override
public void yaw(GL10 gl, float angle) {
// initialise the lookat vector back to the start point
_vecLookAt = new Vector3(0.0f, 1.0f, 1.0f); // look-at
this.angleYaw += angle;
// get the rotation matrix around Y-Axis
Matrix.setIdentityM(_matRotation, 0);
// Matrix.setRotateM(_matRotation, 0, (float)Math.toDegrees(angle),
_Y.x, _Y.y, _Y.z);
Matrix.setRotateM(_matRotation, 0,
(float)Math.toDegrees(this.angleYaw), _Y.x, _Y.y, _Y.z);
// rotate the LookAt point
Matrix.multiplyMV(_vecTemp4, 0, _matRotation, 0,
_vecLookAt.getFloat(), 0);
// _vecLookAt.setFloat(_vecTemp4);
_vecLookAt.setFloatHomogenous(_vecTemp4);
// apply transform
this.applyModelViewTransform(gl);
Log.v(""+this, "angleYaw:"+angleYaw +" , in-degrees:"+
Math.toDegrees(angleYaw));
Log.v(""+this, "angle:"+angle +" , in-degrees:"+
Math.toDegrees(angle));
Log.v(""+this, "angle:"+angle +" , X-axis:"+ _X.x+","+ _X.y+","+
_X.z);
Log.v(""+this, "angle:"+angle +" , Y-axis:"+ _Y.x+","+ _Y.y+","+
_Y.z);
Log.v(""+this, "angle:"+angle +" , Z-axis:"+ _Z.x+","+ _Z.y+","+
_Z.z);
Log.v(""+this, "angle:"+angle +" , _vecLookAt:"+
_vecLookAt.x+","+
_vecLookAt.y+","+ _vecLookAt.z);
}
@Override
public void translateZ(GL10 gl, float dist) {
// translate the eye and look-at point
Vector3 temp = Vector3.multiply(_Z, dist);
_vecEye = Vector3.Add(_vecEye, temp);
_vecLookAt = Vector3.Add(_vecLookAt, temp);
// apply the transform
this.applyModelViewTransform(gl);
}
}
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en