📄 camera.java
字号:
package demos.nehe.lesson44;
import javax.media.opengl.GL;
/**
* I don't mind if you use this class in your own code. All I ask is
* that you give me credit for it if you do. And plug NeHe while your
* at it! :P Thanks go to David Steere, Cameron Tidwell, Bert Sammons,
* and Brannon Martindale for helping me test all the code! Enjoy.
* @author Vic Hollis
* @author Abdul Bezrati
*/
class Camera {
Tuple3f vLightSourceToIntersect;
Tuple3f vLightSourceToCamera;
Tuple3f m_DirectionVector;
Tuple3f m_LightSourcePos;
Tuple3f ptIntersect;
Tuple3f m_Position;
Tuple3f pt;
float m_MaxForwardVelocity;
float m_ForwardVelocity;
float m_MaxHeadingRate;
float m_HeadingDegrees;
float m_PitchDegrees;
float m_MaxPitchRate;
float m_MaxPointSize;
float[][] m_Frustum;
int[] m_BigGlowTexture;
int[] m_StreakTexture;
int[] m_HaloTexture;
int[] m_GlowTexture;
int m_WindowHeight;
int m_WindowWidth;
public Camera() {
// Initalize all our member varibles.
vLightSourceToIntersect = new Tuple3f();
vLightSourceToCamera = new Tuple3f();
m_DirectionVector = new Tuple3f();
m_LightSourcePos = new Tuple3f();
ptIntersect = new Tuple3f();
m_Position = new Tuple3f();
pt = new Tuple3f();
m_Frustum = new float[6][4];
m_MaxForwardVelocity = 0;
m_LightSourcePos.x = 0;
m_LightSourcePos.y = 0;
m_LightSourcePos.z = 0;
m_ForwardVelocity = 0;
m_MaxHeadingRate = 0;
m_HeadingDegrees = 0;
m_BigGlowTexture = new int[1];
m_StreakTexture = new int[1];
m_PitchDegrees = 0;
m_MaxPointSize = 0;
m_MaxPitchRate = 0;
m_GlowTexture = new int[1];
m_HaloTexture = new int[1];
}
public void setPrespective(GL gl) {
Tuple3f v = new Tuple3f(); // A vector to hold our cameras direction * the forward velocity
float Matrix[] = new float[16]; // A array to hold the model view matrix.
// we don't want to destory the Direction vector by using it instead.
// Going to use glRotate to calculate our direction vector
gl.glRotatef(m_HeadingDegrees, 0.0f, 1.0f, 0.0f);
gl.glRotatef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);
// Get the resulting matrix from OpenGL it will have our
// direction vector in the 3rd row.
gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, Matrix, 0);
// Get the direction vector from the matrix. Element 10 must
// be inverted!
m_DirectionVector.x = Matrix[8];
m_DirectionVector.y = Matrix[9];
m_DirectionVector.z = -Matrix[10];
// Ok erase the results of the last computation.
gl.glLoadIdentity();
// Rotate the scene to get the right orientation.
gl.glRotatef(m_PitchDegrees, 1.0f, 0.0f, 0.0f);
gl.glRotatef(m_HeadingDegrees, 0.0f, 1.0f, 0.0f);
// Scale the direction by our speed.
v.scale(m_ForwardVelocity, m_DirectionVector);
// Increment our position by the vector
m_Position.add(v);
// Translate to our new position.
gl.glTranslatef(-m_Position.x, -m_Position.y, -m_Position.z);
}
public void changePitch(float degrees) {
if (Math.abs(degrees) < Math.abs(m_MaxPitchRate)) {
// Our pitch is less than the max pitch rate that we
// defined so lets increment it.
m_PitchDegrees += degrees;
} else {
// Our pitch is greater than the max pitch rate that
// we defined so we can only increment our pitch by the
// maximum allowed value.
if (degrees < 0) {
// We are pitching down so decrement
m_PitchDegrees -= m_MaxPitchRate;
} else {
// We are pitching up so increment
m_PitchDegrees += m_MaxPitchRate;
}
}
// We don't want our pitch to run away from us. Although it
// really doesn't matter I prefer to have my pitch degrees
// within the range of -360.0f to 360.0f
if (m_PitchDegrees > 360.0f) {
m_PitchDegrees -= 360.0f;
} else if (m_PitchDegrees < -360.0f) {
m_PitchDegrees += 360.0f;
}
}
public void changeHeading(float degrees) {
if (Math.abs(degrees) < Math.abs(m_MaxHeadingRate)) {
// Our Heading is less than the max heading rate that we
// defined so lets increment it but first we must check
// to see if we are inverted so that our heading will not
// become inverted.
if (m_PitchDegrees > 90 && m_PitchDegrees < 270 || (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
m_HeadingDegrees -= degrees;
} else {
m_HeadingDegrees += degrees;
}
} else {
// Our heading is greater than the max heading rate that
// we defined so we can only increment our heading by the
// maximum allowed value.
if (degrees < 0) {
// Check to see if we are upside down.
if ((m_PitchDegrees > 90 && m_PitchDegrees < 270) || (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
// Ok we would normally decrement here but since we are upside
// down then we need to increment our heading
m_HeadingDegrees += m_MaxHeadingRate;
} else {
// We are not upside down so decrement as usual
m_HeadingDegrees -= m_MaxHeadingRate;
}
} else {
// Check to see if we are upside down.
if (m_PitchDegrees > 90 && m_PitchDegrees < 270 || (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
// Ok we would normally increment here but since we are upside
// down then we need to decrement our heading.
m_HeadingDegrees -= m_MaxHeadingRate;
} else {
// We are not upside down so increment as usual.
m_HeadingDegrees += m_MaxHeadingRate;
}
}
}
// We don't want our heading to run away from us either. Although it
// really doesn't matter I prefer to have my heading degrees
// within the range of -360.0f to 360.0f
if (m_HeadingDegrees > 360.0f) {
m_HeadingDegrees -= 360.0f;
} else if (m_HeadingDegrees < -360.0f) {
m_HeadingDegrees += 360.0f;
}
}
public void changeVelocity(float vel) {
if (Math.abs(vel) < Math.abs(m_MaxForwardVelocity)) {
// Our velocity is less than the max velocity increment that we
// defined so lets increment it.
m_ForwardVelocity += vel;
} else {
// Our velocity is greater than the max velocity increment that
// we defined so we can only increment our velocity by the
// maximum allowed value.
if (vel < 0) {
// We are slowing down so decrement
m_ForwardVelocity -= -m_MaxForwardVelocity;
} else {
// We are speeding up so increment
m_ForwardVelocity += m_MaxForwardVelocity;
}
}
}
// I found this code here: http://www.markmorley.com/opengl/frustumculling.html
// and decided to make it part of
// the camera class just in case I might want to rotate
// and translate the projection matrix. This code will
// make sure that the Frustum is updated correctly but
// this member is computational expensive with:
// 82 muliplications, 72 additions, 24 divisions, and
// 12 subtractions for a total of 190 operations. Ouch!
private void updateFrustum(GL gl) {
float clip[] = new float[16],
proj[] = new float[16],
modl[] = new float[16],
t;
/* Get the current PROJECTION matrix from OpenGL */
gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, proj, 0);
/* Get the current MODELVIEW matrix from OpenGL */
gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modl, 0);
/* Combine the two matrices (multiply projection by modelview) */
clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + modl[3] * proj[12];
clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + modl[3] * proj[13];
clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + modl[3] * proj[14];
clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15];
clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + modl[7] * proj[12];
clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + modl[7] * proj[13];
clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + modl[7] * proj[14];
clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15];
clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + modl[11] * proj[12];
clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + modl[11] * proj[13];
clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + modl[11] * proj[14];
clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + modl[11] * proj[15];
clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + modl[15] * proj[12];
clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + modl[15] * proj[13];
clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + modl[15] * proj[14];
clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + modl[15] * proj[15];
/* Extract the numbers for the RIGHT plane */
m_Frustum[0][0] = clip[3] - clip[0];
m_Frustum[0][1] = clip[7] - clip[4];
m_Frustum[0][2] = clip[11] - clip[8];
m_Frustum[0][3] = clip[15] - clip[12];
/* Normalize the result */
t = (float) (Math.sqrt(m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] * m_Frustum[0][1] + m_Frustum[0][2] * m_Frustum[0][2]));
m_Frustum[0][0] /= t;
m_Frustum[0][1] /= t;
m_Frustum[0][2] /= t;
m_Frustum[0][3] /= t;
/* Extract the numbers for the LEFT plane */
m_Frustum[1][0] = clip[3] + clip[0];
m_Frustum[1][1] = clip[7] + clip[4];
m_Frustum[1][2] = clip[11] + clip[8];
m_Frustum[1][3] = clip[15] + clip[12];
/* Normalize the result */
t = (float) (Math.sqrt(m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] * m_Frustum[1][1] + m_Frustum[1][2] * m_Frustum[1][2]));
m_Frustum[1][0] /= t;
m_Frustum[1][1] /= t;
m_Frustum[1][2] /= t;
m_Frustum[1][3] /= t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -