⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.java

📁 NeHe用java与OpenGL结合教程源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
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 + -