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操作符重载)。你可能仍然能够注意到我错过的东西(例如数学或其他东西)。如果您想让我添加更多信息,请让我知道它将是什么。您是否尝试单独渲染摄影机,而不是将其节点嵌套在场景节点下?您的计算将移动