First Person Camera problem

Hi

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 there are functions to create the ModelView matrix ( i.e. calculateModelViewMatrix() ),
rotate the camera along its X and Y axis
and Translate the camera along its Z-axis.

I think that my ModelViewMatrix calulation is correct and i can also translate the camera along the Z-axis.

Rotation along x-axis seems to work but along Y-axis it gives strange results.
Also another problem with the rotation seems to be that instead of the camera being rotated, my 3d model starts to rotate instead along its axis.

I have written another implementation based on the look at point and using the openGL ES’s GLU.gluLookAt( ) function to obtain the ModelView matrix but that too seems to suffer from the exactly the same problems.

Any help or ideas on the matter will be greatly appreciated.
Here is what the class looks like:

package com.droidnova.android.games.vortex;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

import com.surrealtech.math.util.Vector3;

public class Camera4 implements ICamera {
	
	Vector3 _X = new Vector3(1,0,0);	// x-axis of the camera frame
	Vector3 _Y = new Vector3(0,1,0);	// y-axis of the camera frame
	Vector3 _Z = new Vector3(0,0,1);	// z-axis of the camera frame
	Vector3 _T = new Vector3(0,1,2);	// translation vector representing the position of camera frame from the world
				// frame's origin.
	
	float[] _matrixModelView = new float[16]; 	// the model-view matrix that represents the 
												// coordinate transformation between 
												// camera's frame & world frame
	
	float[] _matrixRotation = new float[9]; 	// a temporary matrix to store the rotation 
												// matrix each time it is calculated
	float[] _vecTemp = new float[3]; 	// a temporary vector to store results 
	
	/**
	 * Constructor
	 */
	public Camera4(){
		
	}

	@Override
	public void applyModelViewTransform(GL10 gl) {
		this.calculateModelViewMatrix();
		gl.glMatrixMode(gl.GL_MODELVIEW);
		gl.glLoadMatrixf(_matrixModelView, 0);
	}

	@Override
	public void pitch(GL10 gl, float angle) {
		// calculate the 3-by-3 rotation matrix along the camera's x-axis
		_matrixRotation = getRotationMatrixAlong(_X, angle);
		
		// rotate the camera's y-axis
		float[] result = this.multiplyMV(_matrixRotation, _Y);
		_Y.setFloat(result);
		Log.e(""+this.getClass(), "|Y| = "+_Y.Magnitude());
				
		// rotate the camera's Z-axis
		result = this.multiplyMV(_matrixRotation, _Z);
		_Z.setFloat(result);	
		Log.e(""+this.getClass(), "|Z| = "+_Z.Magnitude());
		
		this.applyModelViewTransform(gl);
		Log.e(""+this.getClass(), "X,Y,Z axes: ("+_X.x + ","+_X.y + "," + _X.z+ ") , ("+_Y.x+","+_Y.y+","+_Y.z+"), (" +_Z.x+","+_Z.y+","+_Z.z+")"   );
	}


	@Override
	public void yaw(GL10 gl, float angle) {
		// calculate the 3-by-3 rotation matrix along the camera's Y-axis
		_matrixRotation = getRotationMatrixAlong(_Y, angle);
		
		// rotate the camera's x-axis
		float[] result = this.multiplyMV(_matrixRotation, _X);
		_X.setFloat(result);
		_X.Normalise();
		Log.e(""+this.getClass(), "|X| = "+_X.Magnitude());
		
		// rotate the camera's Z-axis
		result = this.multiplyMV(_matrixRotation, _Z);
		_Z.setFloat(result);
		_Z.Normalise();
		Log.e(""+this.getClass(), "|Z| = "+_Z.Magnitude());
		
		this.applyModelViewTransform(gl);
		Log.e(""+this.getClass(), "X,Y,Z axes: ("+_X.x + ","+_X.y + "," + _X.z+ ") , ("+_Y.x+","+_Y.y+","+_Y.z+"), (" +_Z.x+","+_Z.y+","+_Z.z+")"   );
	}

	@Override
	public void translateZ(GL10 gl, float dist) {			
		_T.z += dist;
		
		this.applyModelViewTransform(gl);
	}
	

	/**
	 * Private method to calculate the model-view matrix based on the camera's frame axes. 
	 */
	private void calculateModelViewMatrix(){
		
		// 1st column
		_matrixModelView[0] = _X.x;
		_matrixModelView[1] = _Y.x;
		_matrixModelView[2] = _Z.x;
		_matrixModelView[3] = 0;
		
		// 2nd column
		_matrixModelView[4] = _X.y;
		_matrixModelView[5] = _Y.y;
		_matrixModelView[6] = _Z.y;
		_matrixModelView[7] = 0;
		
		// 3rd column
		_matrixModelView[8] = _X.z;
		_matrixModelView[9] = _Y.z;
		_matrixModelView[10] = _Z.z;
		_matrixModelView[11] = 0;
		
		// 4th column
		_matrixModelView[12] = (_T.x);
		_matrixModelView[13] = (_T.y);
		_matrixModelView[14] = (_T.z);
		_matrixModelView[15] = 1;		
	}
	
	/**
	 * 
	 * @param r			An arbitrary vector in 3D space, representing the rotation axis.  
	 * @param angle		The angle in degrees. 
	 * @return
	 */
	private float[] getRotationMatrixAlong(Vector3 r, double angle){
		double cos = Math.cos(angle);	// argument should be in radians
		double sin = Math.sin(angle);	// argument should be in radians
		double t = (1-cos);
		
		// 1st column
		_matrixRotation[0] = (float)( cos+ t*(r.x)*(r.x) );			
		_matrixRotation[1] = (float)( t*(r.x)*(r.y) + r.z*sin );	
		_matrixRotation[2] = (float)( t*(r.x)*(r.z) - r.y*sin );	
		// 2nd column
		_matrixRotation[3] = (float)( t*(r.x)*(r.y) - r.z*sin );			
		_matrixRotation[4] = (float)( cos+ t*(r.y)*(r.y) );	
		_matrixRotation[5] = (float)( t*(r.y)*(r.z) + r.x*sin );	
		// 1st column
		_matrixRotation[6] = (float)( t*(r.x)*(r.z) + r.y*sin );			
		_matrixRotation[7] = (float)( t*(r.y)*(r.z) - r.x*sin );	
		_matrixRotation[8] = (float)( cos+ t*(r.z)*(r.z) );	
		
		return _matrixRotation;
	}
	
	/**
	 * Multiply a 3-by-3 matrix with a 3_by_1 vector and return the result 
	 * as a 3-by-1 column vector 
	 * @param matrix	A 3-by-3 matrix.
	 * @param v			A 3-by-1 column vector.
	 * @return
	 */
	private float[] multiplyMV(float[] matrix, Vector3 v){
		_vecTemp[0] = matrix[0]*v.x + matrix[3]*v.y +matrix[6]*v.z;
		_vecTemp[1] = matrix[1]*v.x + matrix[4]*v.y +matrix[7]*v.z;
		_vecTemp[2] = matrix[2]*v.x + matrix[5]*v.y +matrix[8]*v.z;
		return _vecTemp; 
	}
	
}

Not sure how to address your problem, humanitarian. But perhaps a bump will bring it to someone else’s attention who can help.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.