Camera.java
package com.Diamond.gl07;
import android.opengl.Matrix;
import android.renderscript.Matrix4f;
import android.renderscript.Float3;
public class Camera {
private Float3 mPosition;
private Float3 mCenter;
private Float3 mUp;
private Matrix4f mProjection;
private float mYaw;
private float mPitch;
private float mRoll;
private float mFovy;
private float mAspect;
private float mNear;
private float mFar;
public final static Float3 XY = new Float3(1,1,0);
public final static Float3 XZ = new Float3(1,0,1);
public final static Float3 YZ = new Float3(0,1,1);
public Camera(Float3 position,Float3 center,Float3 up) {
mPosition = position;
mCenter = center;
mUp = up;
mProjection = new Matrix4f();
mYaw = 0;
mPitch = 0;
mRoll = 0;
mFovy = 120;
mAspect = 1;
mNear = 1;
mFar = 100;
}
public Camera setPosition(Float3 position) {
mPosition = position;
return this;
}
public Float3 getPosition() {
return mPosition;
}
public Camera move(Float3 distance) {
mPosition.x += distance.x;
mPosition.y += distance.y;
mPosition.z += distance.z;
return this;
}
public Camera moveX(float distance) {
mPosition.x += distance;
return this;
}
public Camera setX(float x) {
mPosition.x = x;
return this;
}
public Camera moveY(float distance) {
mPosition.y += distance;
return this;
}
public Camera setY(float y) {
mPosition.y = y;
return this;
}
public Camera moveZ(float distance) {
mPosition.z += distance;
return this;
}
public Camera setZ(float z) {
mPosition.z = z;
return this;
}
public Camera setCenter(Float3 center) {
mCenter = center;
return this;
}
public Camera setUp(Float3 up) {
mUp = up;
return this;
}
public Camera setPerspective(float fovy,float aspect,float near,float far) {
mFovy = fovy;
mAspect = aspect;
mNear = near;
mFar = far;
updatePerspective();
return this;
}
public Camera updatePerspective() {
mProjection.loadIdentity();
mProjection.loadPerspective(mFovy,mAspect,mNear,mFar);
return this;
}
public Camera setFovy(float fovy) {
mFovy = fovy;
updatePerspective();
return this;
}
public float getFovy() {
return mFovy;
}
public Camera fovy(float angle) {
mFovy += angle;
updatePerspective();
return this;
}
public Camera setAspect(float aspect) {
mAspect = aspect;
updatePerspective();
return this;
}
public float getAspect() {
return mAspect;
}
public Camera setNear(float near) {
mNear = near;
updatePerspective();
return this;
}
public float getNear() {
return mNear;
}
public Camera setFar(float far) {
mFar = far;
updatePerspective();
return this;
}
public float getFar() {
return mFar;
}
public Camera setOrtho(float l,float r,float b,float t,float n,float f) {
mProjection.loadOrtho(l,r,b,t,n,f);
return this;
}
public float[] getProjectionMatrix() {
return mProjection.getArray();
}
public float[] getViewMatrix() {
float[] view = new float[16];
Matrix.setLookAtM(
view,0,
mPosition.x,mPosition.y,mPosition.z,
mCenter.x,mCenter.y,mCenter.z,
mUp.x,mUp.y,mUp.z
);
return view;
}
//这个函数有问题,明明和LearnOpenGL的一样,但是就是有问题
public Camera updatePose() {
if(mYaw >= 360) {
mYaw -= 360;
} else if(mYaw < 0) {
mYaw += 360;
}
if(mPitch >= 90) {
mPitch = 89.9f;
} else if(mPitch <= -90) {
mPitch = -89.9f;
}
if(mRoll >= 360) {
mRoll -= 360;
} else if(mRoll < 0) {
mRoll += 360;
}
float x = (float)Math.cos(Math.toRadians(mYaw)) * (float)Math.cos(Math.toRadians(mPitch));
float y = (float)Math.sin(Math.toRadians(mPitch));
float z = (float)Math.sin(Math.toRadians(mYaw)) * (float)Math.cos(Math.toRadians(mPitch));
//标准化,相当于normalize()
float mod = (float)Math.sqrt(x * x + y * y + z * z);
x /= mod;
y /= mod;
z /= mod;
mCenter = new Float3(x,y,z);
//roll的计算其实有问题,默认是朝向Z轴负半轴的
float rx = (float)Math.sin(Math.toRadians(mRoll));
float ry = (float)Math.cos(Math.toRadians(mRoll));
mUp = new Float3(rx,ry,0);
return this;
}
public Camera setOrbit(Float3 plane,float angle,float distance) {
float x = (float)Math.sin(Math.toRadians(angle)) * distance;
float y = (float)Math.cos(Math.toRadians(angle)) * distance;
boolean isFirst = true;
if(plane.x == 1) {
mPosition.x = x;
isFirst = false;
}
if(plane.y == 1) {
if(isFirst) {
mPosition.y = x;
mPosition.z = y;
} else {
mPosition.y = y;
}
}
if(plane.z == 1) {
mPosition.z = y;
}
return this;
}
public Camera setYaw(float yaw) {
mYaw = yaw;
updatePose();
return this;
}
public float getYaw() {
return mYaw;
}
public Camera yaw(float angle) {
mYaw += angle;
updatePose();
return this;
}
public Camera setPitch(float pitch) {
mPitch = pitch;
updatePose();
return this;
}
public float getPitch() {
return mPitch;
}
public Camera pitch(float angle) {
mPitch += angle;
updatePose();
return this;
}
public Camera setRoll(float roll) {
mRoll = roll;
updatePose();
return this;
}
public float getRoll() {
return mRoll;
}
public Camera roll(float angle) {
mRoll += angle;
updatePose();
return this;
}
}
更新内容
增加了缩放(通过调整fovy)和环绕(绕着一个点让摄像机环绕)
分别对应setFovy(float),fovy(float)以及setOrbit(Float3,float,float)函数
在看setOrbit()之前建议先了解三角函数和[Java] [OpenGL ES3.2] 正多边形,其实是差不多的


![[Java] [OpenGL ES3.2] Camera2.0 [Java] [OpenGL ES3.2] Camera2.0](http://www.mshxw.com/aiimages/31/712035.png)
