Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 固定3D摄像头,使其沿';他面对什么? 短版本(TL;DR)_Java_3d_Opengl 4 - Fatal编程技术网

Java 固定3D摄像头,使其沿';他面对什么? 短版本(TL;DR)

Java 固定3D摄像头,使其沿';他面对什么? 短版本(TL;DR),java,3d,opengl-4,Java,3d,Opengl 4,我有一个摄像头连接到场景节点,只要场景节点的旋转/轴与世界的旋转/轴对齐,运动就可以正常工作。但是,当一个对象旋转到另一个方向“看”,并被告知“向前”移动时,它不会沿着新的“向前”方向移动。相反,它将继续沿应用旋转之前的方向移动 细节和例子 我有一个场景图来管理3D场景。该图是一个由场景节点对象组成的树,这些对象知道它们相对于其父对象和世界的变换 根据TL;博士在代码片段中,假设您有一个旋转为零的cameraNode,然后将cameraNode绕+Y“向上”轴向左旋转90度,即使其看起来向西。到

我有一个
摄像头
连接到
场景节点
,只要
场景节点
的旋转/轴与世界的旋转/轴对齐,运动就可以正常工作。但是,当一个对象旋转到另一个方向“看”,并被告知“向前”移动时,它不会沿着新的“向前”方向移动。相反,它将继续沿应用旋转之前的方向移动

细节和例子 我有一个场景图来管理3D场景。该图是一个由
场景节点
对象组成的树,这些对象知道它们相对于其父对象和世界的变换

根据TL;博士在代码片段中,假设您有一个旋转为零的
cameraNode
,然后将
cameraNode
绕+Y“向上”轴向左旋转90度,即使其看起来向西。到目前为止一切正常。如果您现在尝试将
cameraNode
向前移动(现在是向西移动),则
cameraNode
会移动,就好像“向前”仍然面向北方一样

简言之,它的运动就好像它一开始从未旋转过一样

下面的代码显示了我最近的尝试和我(当前)对缩小最可能与问题相关的区域的最佳猜测

相关
SceneNode
成员
SceneNode
实现具有以下字段(仅显示与此问题相关的字段):

摄影机
添加到场景只意味着它将附加到图形中的
场景节点
。由于
摄像头
本身没有位置/旋转信息,因此客户端只需处理
摄像头
所连接的
场景节点
,就这样

除了这个问题中提到的问题外,其他一切似乎都在按预期进行

SceneNode
翻译 在特定方向上平移节点的数学很简单,基本上可以归结为:

currentPosition = currentPosition + normalizedDirectionVector * offset;
SceneNode
实现如下:

@Override
public void moveForward(float offset) {
    translate(getDerivedForwardAxis().mult(-offset));
}

@Override
public void moveBackward(float offset) {
    translate(getDerivedForwardAxis().mult(offset));
}

@Override
public void moveLeft(float offset) {
    translate(getDerivedRightAxis().mult(-offset));
}

@Override
public void moveRight(float offset) {
    translate(getDerivedRightAxis().mult(offset));
}

@Override
public void moveUp(float offset) {
    translate(getDerivedUpAxis().mult(offset));
}

@Override
public void moveDown(float offset) {
    translate(getDerivedUpAxis().mult(-offset));
}

@Override
public void translate(Vector3 tv) {
    relativePosition = relativePosition.add(tv);
    isOutOfDate = true;
}
除了这个问题中提到的问题之外,一切都如预期的那样

场景节点
旋转 客户端应用程序按如下方式旋转
cameraNode

final Angle rotationAngle = new Degreef(-90f);
// ...
cameraNode.yaw(rotationAngle);
SceneNode
的实现也相当简单:

@Override
public void yaw(Angle angle) {
    // FIXME?: rotate(angle, getDerivedUpAxis()) accumulates other rotations
    rotate(angle, Vector3f.createUnitVectorY());
}

@Override
public void rotate(Angle angle, Vector3 axis) {
    relativeRotation = relativeRotation.rotate(angle, axis);
    isOutOfDate = true;
}
旋转的数学/代码封装在3x3矩阵对象中。请注意,在测试过程中,您可以看到场景围绕摄影机旋转,因此确实应用了旋转,这使得这个问题对我来说更加困惑

方向向量 方向向量只是从导出的3x3旋转矩阵中获取的列,相对于世界:

@Override
public Vector3 getDerivedRightAxis() {
    return derivedRotation.column(0);
}

@Override
public Vector3 getDerivedUpAxis() {
    return derivedRotation.column(1);
}

@Override
public Vector3 getDerivedForwardAxis() {
    return derivedRotation.column(2);
}
计算派生变换 如果相关,这就是如何组合
parentNode
变换来计算
实例的派生变换:

private void updateDerivedTransforms() {
    if (parentNode != null) {
        /**
         * derivedRotation = parent.derivedRotation * relativeRotation
         * derivedScale    = parent.derivedScale    * relativeScale
         * derivedPosition = parent.derivedPosition + parent.derivedRotation * (parent.derivedScale * relativePosition)
         */
        derivedRotation = parentNode.getDerivedRotation().mult(relativeRotation);
        derivedScale = parentNode.getDerivedScale().mult(relativeScale);

        Vector3 scaledPosition = parentNode.getDerivedScale().mult(relativePosition);
        derivedPosition = parentNode.getDerivedPosition().add(parentNode.getDerivedRotation().mult(scaledPosition));
    } else {
        derivedPosition = relativePosition;
        derivedRotation = relativeRotation;
        derivedScale = relativeScale;
    }

    Matrix4 t, r, s;

    t = Matrix4f.createTranslationFrom(relativePosition);
    r = Matrix4f.createFrom(relativeRotation);
    s = Matrix4f.createScalingFrom(relativeScale);
    relativeTransform = t.mult(r).mult(s);

    t = Matrix4f.createTranslationFrom(derivedPosition);
    r = Matrix4f.createFrom(derivedRotation);
    s = Matrix4f.createScalingFrom(derivedScale);
    derivedTransform = t.mult(r).mult(s);
}
这用于通过场景图传播变换,以便子
sceneode
s可以考虑其父级的变换


其他/相关问题 在发布此问题之前的最后3周内,我已经阅读了SO内外的几个答案(例如,、和等)。很明显,虽然有关联,但对我来说,它们真的没有帮助


对评论中问题的回答 您确定在计算
derivedTransform
时已计算父级的
derivedTransform

是的,父级
场景节点总是在更新子级之前更新。
更新
逻辑为:

@Override
public void update(boolean updateChildren, boolean parentHasChanged) {
    boolean updateRequired = parentHasChanged || isOutOfDate;

    // update this node's transforms before updating children
    if (updateRequired)
        updateFromParent();

    if (updateChildren)
        for (Node n : childNodesMap.values())
            n.update(updateChildren, updateRequired);

    emitNodeUpdated(this);
}

@Override
public void updateFromParent() {
    updateDerivedTransforms();  // implementation above
    isOutOfDate = false;
}

这篇文章调用了上一节中的私有方法。

这不是一个直接的回答,而是在OP的要求下作为参考

OpenGL v1.0使用旧API调用:在场景类的场景图之外的场景类中使用摄影机类对象时实现该对象。这是用C写的++

Camera.h

#ifndef CAMERA_H
#define CAMERA_H

#include "Core.h"

class Camera {    
private:
    Vector3 _v3EyePosition;
    Vector3 _v3LookCenter;
    Vector3 _v3Up;

public:
    Camera();
    ~Camera();    

    void Get3rdPersonLocation( Vector3 &v3Position, float &fAngle );
    void Set( Vector3 v3EyePosition, Vector3 v3LookCenter, Vector3 v3Up = Vector3( 0.0f, 1.0f, 0.0f ) );
    void Render();    
}; 

#endif
#ifndef PLAYER_H
#define PLAYER_H

#include "Core.h"

class Weapon;
class NodeTransform;

class Player {
private:
    enum MouseLook {
        ML_NORMAL = 1,
        ML_INVERT = -1,
    } _MouseLookState; // MouseLook

    Vector3 _v3Position;
    Vector3 _v3LookCenter;

    float _fLookDistance;
    float _fMaxUp;
    float _fMaxDown;

    float _fLinearSpeed;
    float _fAngularSpeed;

public:
    Player( float fLookDistance );
    ~Player();

    void    SetSpeed( float fLinear, float fAngular );

    void    SetMouseY( bool bInvert );
    void    SetLocation( Vector3 v3Position, Vector3 v3Direction = Vector3( 0.0f, 0.0f, -1.0f ) );
    void    Move( Action action, float fDeltaTime );

    bool    Update();   

    inline void     SetPosition( Vector3 v3Position );
    inline Vector3  GetPosition();
    inline Vector3  GetLookCenter();
    inline Vector3  GetLookDirection();         
};

inline void Player::SetPosition( Vector3 v3Position ) {
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;

    _v3Position   = v3Position;
    _v3LookCenter = v3Position + v3LookDirection;
}

inline Vector3 Player::GetPosition() {  
    return _v3Position;
} 

inline Vector3 Player::GetLookCenter() {
    return _v3LookCenter;
} 

inline Vector3 Player::GetLookDirection() {    
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;    
    v3LookDirection.Normalize();    
    return v3LookDirection;    
}

#endif
Camera.cpp

#include "stdafx.h"
#include "Camera.h"

Camera::Camera() {    
    _v3EyePosition = Vector3( 0.0f, 0.0f,  0.0f );
    _v3LookCenter  = Vector3( 0.0f, 0.0f, -1.0f );
    _v3Up          = Vector3( 0.0f, 1.0f,  0.0f );    
} 

Camera::~Camera() {
} 

void Camera::Get3rdPersonLocation( Vector3 &v3Position, float &fAngle ) {   
    v3Position._fX = _v3LookCenter._fX;
    v3Position._fY = _v3EyePosition._fY;
    v3Position._fZ = _v3LookCenter._fZ;

    // Find Angle
    float fX = _v3LookCenter._fX - _v3EyePosition._fX;
    float fZ = _v3LookCenter._fZ - _v3EyePosition._fZ;

    // Angle In Degrees
    fAngle = Math::Radian2Degree( atan2( fX, fZ ) );    
}     

void Camera::Set( Vector3 v3EyePosition, Vector3 v3LookCenter, Vector3 v3Up ) {    
    _v3EyePosition = v3EyePosition;
    _v3LookCenter  = v3LookCenter;
    _v3Up          = v3Up;    
}

void Camera::Render() {     
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    gluLookAt( _v3EyePosition._fX, _v3EyePosition._fY, _v3EyePosition._fZ,
               _v3LookCenter._fX,  _v3LookCenter._fY,  _v3LookCenter._fZ,
               _v3Up._fX,          _v3Up._fY,          _v3Up._fZ );     
}
#include "stdafx.h"
#include "Player.h"
#include "UserSettings.h"
#include "NodeTransform.h"

Player::Player( float fLookDistance ) {    
    _fLookDistance  = fLookDistance;    
    // Calculate Maximum Limits For Looking Up And Down
    _fMaxUp         = _fLookDistance * tan( Math::Degree2Radian( 50 ) );
    _fMaxDown       = _fLookDistance * tan( Math::Degree2Radian( 40 ) );

    _v3Position     = Vector3( 0.0f, 0.5f, 0.0f );
    _v3LookCenter   = Vector3( 0.0f, 0.5f, -fLookDistance );

    _fLinearSpeed   = 15.0f; // Units Per Second
    _fAngularSpeed  = 3.0f; // Radians Per Second

    SetMouseY( UserSettings::Get()->GetMouseInvert() );    
} 

Player::~Player() {
} // ~Player

void Player::SetMouseY( bool bInvert ) {    
    if ( bInvert ) {
        _MouseLookState = ML_INVERT;
    } else {
        _MouseLookState = ML_NORMAL;
    }       
} 

void Player::SetLocation( Vector3 v3Position, Vector3 v3Direction ) {    
    _v3Position   = v3Position;
    _v3LookCenter = v3Position + _fLookDistance*v3Direction;    
}

void Player::Move( Action action, float fDeltaTime ) {    
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;

    switch ( action ) {
        case MOVING_FORWARD: {
            // Prevent Vertical Motion
            v3LookDirection._fY = 0.0f;
            _v3Position   += v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter += v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_BACK: {
            // Prevent Vertical Motion
            v3LookDirection._fY = 0.0f;
            _v3Position   -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_LEFT: {
            // Get "Side" Direction & Prevent Vertical Motion
            v3LookDirection._fY = v3LookDirection._fX;
            v3LookDirection._fX = -v3LookDirection._fZ;
            v3LookDirection._fZ = v3LookDirection._fY;
            v3LookDirection._fY = 0.0f;

            _v3Position   -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_RIGHT: {
            // Get "Side" Direction & Prevent Vertical Motion
            v3LookDirection._fY = v3LookDirection._fX;
            v3LookDirection._fX = -v3LookDirection._fZ;
            v3LookDirection._fZ = v3LookDirection._fY;
            v3LookDirection._fY = 0.0f;

            _v3Position   += v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter += v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case LOOKING_LEFT: {

            /*float fSin = -sin( fDeltaTime*_fAngularSpeed );
            float fCos =  cos( fDeltaTime*_fAngularSpeed );

            _v3LookCenter._fX = _v3Position._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3LookCenter._fZ = _v3Position._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;*/

            // Third Person
            float fSin = sin( fDeltaTime*_fAngularSpeed );
            float fCos = -cos( fDeltaTime*_fAngularSpeed );

            _v3Position._fX = _v3LookCenter._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3Position._fZ = _v3LookCenter._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;
        }
        case LOOKING_RIGHT: {
            /*float fSin = sin( fDeltaTime*_fAngularSpeed );
            float fCos = cos( fDeltaTime*_fAngularSpeed );

            _v3LookCenter._fX = _v3Position._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3LookCenter._fZ = _v3Position._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;*/

            // Third Person
            float fSin = -sin( fDeltaTime*_fAngularSpeed );
            float fCos = -cos( fDeltaTime*_fAngularSpeed );

            _v3Position._fX = _v3LookCenter._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3Position._fZ = _v3LookCenter._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;
        }
        case LOOKING_UP: {
            _v3LookCenter._fY -= fDeltaTime*_fAngularSpeed*_MouseLookState;

            // Check Maximum Values
            if ( _v3LookCenter._fY > (_v3Position._fY + _fMaxUp ) ) {
                _v3LookCenter._fY = _v3Position._fY + _fMaxUp;
            } else if ( _v3LookCenter._fY < (_v3Position._fY - _fMaxDown) ) {
                _v3LookCenter._fY = _v3Position._fY - _fMaxDown;
            }
            break;
        }
    }    
}

bool Player::Update() {     
    // Stripped Down This Deals With Player's Weapons    
} 

void Player::SetSpeed( float fLinear, float fAngular ) {        
    _fLinearSpeed  = fLinear;
    _fAngularSpeed = fAngular;    
} 
Camera
Render
函数中,使用旧的OpenGL API调用,我们首先加载Modelview矩阵,然后加载标识矩阵;然后我们最终使用glu的gluLookAt(…)方法来设置所需向量的位置

Scene.h-有许多成员和功能;但是对于
摄影机
对象,它有一个摄影机作为成员,而不是指向摄影机的指针

场景.cpp-Render()

Player.h

#ifndef CAMERA_H
#define CAMERA_H

#include "Core.h"

class Camera {    
private:
    Vector3 _v3EyePosition;
    Vector3 _v3LookCenter;
    Vector3 _v3Up;

public:
    Camera();
    ~Camera();    

    void Get3rdPersonLocation( Vector3 &v3Position, float &fAngle );
    void Set( Vector3 v3EyePosition, Vector3 v3LookCenter, Vector3 v3Up = Vector3( 0.0f, 1.0f, 0.0f ) );
    void Render();    
}; 

#endif
#ifndef PLAYER_H
#define PLAYER_H

#include "Core.h"

class Weapon;
class NodeTransform;

class Player {
private:
    enum MouseLook {
        ML_NORMAL = 1,
        ML_INVERT = -1,
    } _MouseLookState; // MouseLook

    Vector3 _v3Position;
    Vector3 _v3LookCenter;

    float _fLookDistance;
    float _fMaxUp;
    float _fMaxDown;

    float _fLinearSpeed;
    float _fAngularSpeed;

public:
    Player( float fLookDistance );
    ~Player();

    void    SetSpeed( float fLinear, float fAngular );

    void    SetMouseY( bool bInvert );
    void    SetLocation( Vector3 v3Position, Vector3 v3Direction = Vector3( 0.0f, 0.0f, -1.0f ) );
    void    Move( Action action, float fDeltaTime );

    bool    Update();   

    inline void     SetPosition( Vector3 v3Position );
    inline Vector3  GetPosition();
    inline Vector3  GetLookCenter();
    inline Vector3  GetLookDirection();         
};

inline void Player::SetPosition( Vector3 v3Position ) {
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;

    _v3Position   = v3Position;
    _v3LookCenter = v3Position + v3LookDirection;
}

inline Vector3 Player::GetPosition() {  
    return _v3Position;
} 

inline Vector3 Player::GetLookCenter() {
    return _v3LookCenter;
} 

inline Vector3 Player::GetLookDirection() {    
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;    
    v3LookDirection.Normalize();    
    return v3LookDirection;    
}

#endif
Player.cpp

#include "stdafx.h"
#include "Camera.h"

Camera::Camera() {    
    _v3EyePosition = Vector3( 0.0f, 0.0f,  0.0f );
    _v3LookCenter  = Vector3( 0.0f, 0.0f, -1.0f );
    _v3Up          = Vector3( 0.0f, 1.0f,  0.0f );    
} 

Camera::~Camera() {
} 

void Camera::Get3rdPersonLocation( Vector3 &v3Position, float &fAngle ) {   
    v3Position._fX = _v3LookCenter._fX;
    v3Position._fY = _v3EyePosition._fY;
    v3Position._fZ = _v3LookCenter._fZ;

    // Find Angle
    float fX = _v3LookCenter._fX - _v3EyePosition._fX;
    float fZ = _v3LookCenter._fZ - _v3EyePosition._fZ;

    // Angle In Degrees
    fAngle = Math::Radian2Degree( atan2( fX, fZ ) );    
}     

void Camera::Set( Vector3 v3EyePosition, Vector3 v3LookCenter, Vector3 v3Up ) {    
    _v3EyePosition = v3EyePosition;
    _v3LookCenter  = v3LookCenter;
    _v3Up          = v3Up;    
}

void Camera::Render() {     
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    gluLookAt( _v3EyePosition._fX, _v3EyePosition._fY, _v3EyePosition._fZ,
               _v3LookCenter._fX,  _v3LookCenter._fY,  _v3LookCenter._fZ,
               _v3Up._fX,          _v3Up._fY,          _v3Up._fZ );     
}
#include "stdafx.h"
#include "Player.h"
#include "UserSettings.h"
#include "NodeTransform.h"

Player::Player( float fLookDistance ) {    
    _fLookDistance  = fLookDistance;    
    // Calculate Maximum Limits For Looking Up And Down
    _fMaxUp         = _fLookDistance * tan( Math::Degree2Radian( 50 ) );
    _fMaxDown       = _fLookDistance * tan( Math::Degree2Radian( 40 ) );

    _v3Position     = Vector3( 0.0f, 0.5f, 0.0f );
    _v3LookCenter   = Vector3( 0.0f, 0.5f, -fLookDistance );

    _fLinearSpeed   = 15.0f; // Units Per Second
    _fAngularSpeed  = 3.0f; // Radians Per Second

    SetMouseY( UserSettings::Get()->GetMouseInvert() );    
} 

Player::~Player() {
} // ~Player

void Player::SetMouseY( bool bInvert ) {    
    if ( bInvert ) {
        _MouseLookState = ML_INVERT;
    } else {
        _MouseLookState = ML_NORMAL;
    }       
} 

void Player::SetLocation( Vector3 v3Position, Vector3 v3Direction ) {    
    _v3Position   = v3Position;
    _v3LookCenter = v3Position + _fLookDistance*v3Direction;    
}

void Player::Move( Action action, float fDeltaTime ) {    
    Vector3 v3LookDirection;
    v3LookDirection = _v3LookCenter - _v3Position;

    switch ( action ) {
        case MOVING_FORWARD: {
            // Prevent Vertical Motion
            v3LookDirection._fY = 0.0f;
            _v3Position   += v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter += v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_BACK: {
            // Prevent Vertical Motion
            v3LookDirection._fY = 0.0f;
            _v3Position   -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_LEFT: {
            // Get "Side" Direction & Prevent Vertical Motion
            v3LookDirection._fY = v3LookDirection._fX;
            v3LookDirection._fX = -v3LookDirection._fZ;
            v3LookDirection._fZ = v3LookDirection._fY;
            v3LookDirection._fY = 0.0f;

            _v3Position   -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter -= v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case MOVING_RIGHT: {
            // Get "Side" Direction & Prevent Vertical Motion
            v3LookDirection._fY = v3LookDirection._fX;
            v3LookDirection._fX = -v3LookDirection._fZ;
            v3LookDirection._fZ = v3LookDirection._fY;
            v3LookDirection._fY = 0.0f;

            _v3Position   += v3LookDirection*fDeltaTime*_fLinearSpeed;
            _v3LookCenter += v3LookDirection*fDeltaTime*_fLinearSpeed;
            break;
        }
        case LOOKING_LEFT: {

            /*float fSin = -sin( fDeltaTime*_fAngularSpeed );
            float fCos =  cos( fDeltaTime*_fAngularSpeed );

            _v3LookCenter._fX = _v3Position._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3LookCenter._fZ = _v3Position._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;*/

            // Third Person
            float fSin = sin( fDeltaTime*_fAngularSpeed );
            float fCos = -cos( fDeltaTime*_fAngularSpeed );

            _v3Position._fX = _v3LookCenter._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3Position._fZ = _v3LookCenter._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;
        }
        case LOOKING_RIGHT: {
            /*float fSin = sin( fDeltaTime*_fAngularSpeed );
            float fCos = cos( fDeltaTime*_fAngularSpeed );

            _v3LookCenter._fX = _v3Position._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3LookCenter._fZ = _v3Position._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;*/

            // Third Person
            float fSin = -sin( fDeltaTime*_fAngularSpeed );
            float fCos = -cos( fDeltaTime*_fAngularSpeed );

            _v3Position._fX = _v3LookCenter._fX + (-fSin * v3LookDirection._fZ + fCos * v3LookDirection._fX );
            _v3Position._fZ = _v3LookCenter._fZ + ( fCos * v3LookDirection._fZ + fSin * v3LookDirection._fX );
            break;
        }
        case LOOKING_UP: {
            _v3LookCenter._fY -= fDeltaTime*_fAngularSpeed*_MouseLookState;

            // Check Maximum Values
            if ( _v3LookCenter._fY > (_v3Position._fY + _fMaxUp ) ) {
                _v3LookCenter._fY = _v3Position._fY + _fMaxUp;
            } else if ( _v3LookCenter._fY < (_v3Position._fY - _fMaxDown) ) {
                _v3LookCenter._fY = _v3Position._fY - _fMaxDown;
            }
            break;
        }
    }    
}

bool Player::Update() {     
    // Stripped Down This Deals With Player's Weapons    
} 

void Player::SetSpeed( float fLinear, float fAngular ) {        
    _fLinearSpeed  = fLinear;
    _fAngularSpeed = fAngular;    
} 
编辑-添加NodeTransform::Render()-显示MVP的操作顺序

// Move Model View Matrix M = (T C R S C^)
void NodeTransform::RenderOGL( bool bSecondPass, bool bRenderNext ) {    
    if ( _pIn && _bVisible ) {
        // Put Matrix Onto Stack For Later Retrieval
        glMatrixMode( GL_MODELVIEW );
        glPushMatrix();

        if ( _bHaveMatrix ) {
            // Use Transformation Matrix
            glMultMatrixf( &_f16Matrix[0] );
        }

        // Transalate
        glTranslatef( _v3Translate._fX, _v3Translate._fY, _v3Translate._fZ );

        // Move Back To Center
        glTranslatef( _v3Center._fX, _v3Center._fY, _v3Center._fZ );

        // Rotate
        glRotatef( _fRotateAngle, _v3RotateAxis._fX, _v3RotateAxis._fY, _v3RotateAxis._fZ );

        // Scale
        glScalef( _v3Scale._fX, _v3Scale._fY, _v3Scale._fZ );

        // Offset By -ve Center Value
        glTranslatef( -_v3Center._fX, -_v3Center._fY, -_v3Center._fZ );

        // Move Down The Tree
        _pIn->RenderOGL( bSecondPass, true );

        // Get Old Matrix
        glMatrixMode( GL_MODELVIEW );
        glPopMatrix();
    }

    if ( _pNext && bRenderNext ) {
        _pNext->RenderOGL( bSecondPass, true );
    }    
} // RenderOGL

你用的是哪个版本的OpenGL?@FrancisCugler我用的是OpenGL 4.5。你需要我发布着色器吗?不需要;只是想知道您是在使用现代OpenGL还是旧的1.0API调用。我不熟悉java,但我一直在C++中使用OpenGL。我知道OpenGL没有摄影机对象,您必须创建一个并将其附加到场景中。然后,渲染后,其移动和旋转取决于定义坐标系的惯用手。MVP(模型视图投影)矩阵计算非常重要;旋转、平移和缩放的顺序也很重要。@FrancisCugler我理解。
Camera
sceneode
对象由我定义。即使你不熟悉java,你也熟悉C++和OpenGL,所以你可能已经理解上面代码的语义(SANS操作符重载)。你可能仍然能够注意到我错过的东西(例如数学或其他东西)。如果您想让我添加更多信息,请让我知道它将是什么。您是否尝试单独渲染摄影机,而不是将其节点嵌套在场景节点下?您的计算将移动