mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Merge pull request #325 from DavidWyand-GG/GameObjectBanking
Game cam and eye banking, control schemes
This commit is contained in:
commit
2123365d4d
|
|
@ -35,6 +35,12 @@
|
|||
#include "math/mathUtils.h"
|
||||
#include "math/mTransform.h"
|
||||
|
||||
#ifdef TORQUE_EXTENDED_MOVE
|
||||
#include "T3D/gameBase/extended/extendedMove.h"
|
||||
#endif
|
||||
|
||||
S32 Camera::smExtendedMovePosRotIndex = 0; // The ExtendedMove position/rotation index used for camera movements
|
||||
|
||||
#define MaxPitch 1.5706f
|
||||
#define CameraRadius 0.05f;
|
||||
|
||||
|
|
@ -254,6 +260,7 @@ Camera::Camera()
|
|||
{
|
||||
mNetFlags.clear(Ghostable);
|
||||
mTypeMask |= CameraObjectType;
|
||||
mDataBlock = 0;
|
||||
mDelta.pos = Point3F(0.0f, 0.0f, 100.0f);
|
||||
mDelta.rot = Point3F(0.0f, 0.0f, 0.0f);
|
||||
mDelta.posVec = mDelta.rotVec = VectorF(0.0f, 0.0f, 0.0f);
|
||||
|
|
@ -270,6 +277,9 @@ Camera::Camera()
|
|||
mObservingClientObject = false;
|
||||
mMode = FlyMode;
|
||||
|
||||
mLastAbsoluteYaw = 0.0f;
|
||||
mLastAbsolutePitch = 0.0f;
|
||||
|
||||
// For NewtonFlyMode
|
||||
mNewtonRotation = false;
|
||||
mAngularVelocity.set(0.0f, 0.0f, 0.0f);
|
||||
|
|
@ -301,7 +311,7 @@ Camera::~Camera()
|
|||
|
||||
bool Camera::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
if(!Parent::onAdd() || !mDataBlock)
|
||||
return false;
|
||||
|
||||
mObjBox.maxExtents = mObjScale;
|
||||
|
|
@ -310,6 +320,31 @@ bool Camera::onAdd()
|
|||
resetWorldBox();
|
||||
|
||||
addToScene();
|
||||
|
||||
scriptOnAdd();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void Camera::onRemove()
|
||||
{
|
||||
scriptOnRemove();
|
||||
removeFromScene();
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool Camera::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||
{
|
||||
mDataBlock = dynamic_cast<CameraData*>(dptr);
|
||||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -329,14 +364,6 @@ void Camera::onEditorDisable()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void Camera::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// check if the object needs to be observed through its own camera...
|
||||
void Camera::getCameraTransform(F32* pos, MatrixF* mat)
|
||||
{
|
||||
|
|
@ -460,79 +487,154 @@ void Camera::processTick(const Move* move)
|
|||
|
||||
VectorF rotVec(0, 0, 0);
|
||||
|
||||
// process input/determine rotation vector
|
||||
if(virtualMode != StationaryMode &&
|
||||
virtualMode != TrackObjectMode &&
|
||||
(!mLocked || virtualMode != OrbitObjectMode && virtualMode != OrbitPointMode))
|
||||
bool doStandardMove = true;
|
||||
|
||||
#ifdef TORQUE_EXTENDED_MOVE
|
||||
GameConnection* con = getControllingClient();
|
||||
|
||||
// Work with an absolute rotation from the ExtendedMove class?
|
||||
if(con && con->getControlSchemeAbsoluteRotation())
|
||||
{
|
||||
if(!strafeMode)
|
||||
doStandardMove = false;
|
||||
const ExtendedMove* emove = dynamic_cast<const ExtendedMove*>(move);
|
||||
U32 emoveIndex = smExtendedMovePosRotIndex;
|
||||
if(emoveIndex >= ExtendedMove::MaxPositionsRotations)
|
||||
emoveIndex = 0;
|
||||
|
||||
if(emove->EulerBasedRotation[emoveIndex])
|
||||
{
|
||||
rotVec.x = move->pitch;
|
||||
rotVec.z = move->yaw;
|
||||
if(virtualMode != StationaryMode &&
|
||||
virtualMode != TrackObjectMode &&
|
||||
(!mLocked || virtualMode != OrbitObjectMode && virtualMode != OrbitPointMode))
|
||||
{
|
||||
// Pitch
|
||||
mRot.x += (emove->rotX[emoveIndex] - mLastAbsolutePitch);
|
||||
|
||||
// Do we also include the relative pitch value?
|
||||
if(con->getControlSchemeAddPitchToAbsRot() && !strafeMode)
|
||||
{
|
||||
F32 x = move->pitch;
|
||||
if (x > M_PI_F)
|
||||
x -= M_2PI_F;
|
||||
|
||||
mRot.x += x;
|
||||
}
|
||||
|
||||
// Constrain the range of mRot.x
|
||||
while (mRot.x < -M_PI_F)
|
||||
mRot.x += M_2PI_F;
|
||||
while (mRot.x > M_PI_F)
|
||||
mRot.x -= M_2PI_F;
|
||||
|
||||
// Yaw
|
||||
mRot.z += (emove->rotZ[emoveIndex] - mLastAbsoluteYaw);
|
||||
|
||||
// Do we also include the relative yaw value?
|
||||
if(con->getControlSchemeAddYawToAbsRot() && !strafeMode)
|
||||
{
|
||||
F32 z = move->yaw;
|
||||
if (z > M_PI_F)
|
||||
z -= M_2PI_F;
|
||||
|
||||
mRot.z += z;
|
||||
}
|
||||
|
||||
// Constrain the range of mRot.z
|
||||
while (mRot.z < -M_PI_F)
|
||||
mRot.z += M_2PI_F;
|
||||
while (mRot.z > M_PI_F)
|
||||
mRot.z -= M_2PI_F;
|
||||
|
||||
mLastAbsoluteYaw = emove->rotZ[emoveIndex];
|
||||
mLastAbsolutePitch = emove->rotX[emoveIndex];
|
||||
|
||||
// Bank
|
||||
mRot.y = emove->rotY[emoveIndex];
|
||||
|
||||
// Constrain the range of mRot.y
|
||||
while (mRot.y > M_PI_F)
|
||||
mRot.y -= M_2PI_F;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(virtualMode == TrackObjectMode && bool(mOrbitObject))
|
||||
#endif
|
||||
|
||||
if(doStandardMove)
|
||||
{
|
||||
// orient the camera to face the object
|
||||
Point3F objPos;
|
||||
// If this is a shapebase, use its render eye transform
|
||||
// to avoid jittering.
|
||||
ShapeBase *shape = dynamic_cast<ShapeBase*>((GameBase*)mOrbitObject);
|
||||
if( shape != NULL )
|
||||
// process input/determine rotation vector
|
||||
if(virtualMode != StationaryMode &&
|
||||
virtualMode != TrackObjectMode &&
|
||||
(!mLocked || virtualMode != OrbitObjectMode && virtualMode != OrbitPointMode))
|
||||
{
|
||||
MatrixF ret;
|
||||
shape->getRenderEyeTransform( &ret );
|
||||
objPos = ret.getPosition();
|
||||
if(!strafeMode)
|
||||
{
|
||||
rotVec.x = move->pitch;
|
||||
rotVec.z = move->yaw;
|
||||
}
|
||||
}
|
||||
else if(virtualMode == TrackObjectMode && bool(mOrbitObject))
|
||||
{
|
||||
// orient the camera to face the object
|
||||
Point3F objPos;
|
||||
// If this is a shapebase, use its render eye transform
|
||||
// to avoid jittering.
|
||||
ShapeBase *shape = dynamic_cast<ShapeBase*>((GameBase*)mOrbitObject);
|
||||
if( shape != NULL )
|
||||
{
|
||||
MatrixF ret;
|
||||
shape->getRenderEyeTransform( &ret );
|
||||
objPos = ret.getPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
mOrbitObject->getWorldBox().getCenter(&objPos);
|
||||
}
|
||||
mObjToWorld.getColumn(3,&pos);
|
||||
vec = objPos - pos;
|
||||
vec.normalizeSafe();
|
||||
F32 pitch, yaw;
|
||||
MathUtils::getAnglesFromVector(vec, yaw, pitch);
|
||||
rotVec.x = -pitch - mRot.x;
|
||||
rotVec.z = yaw - mRot.z;
|
||||
if(rotVec.z > M_PI_F)
|
||||
rotVec.z -= M_2PI_F;
|
||||
else if(rotVec.z < -M_PI_F)
|
||||
rotVec.z += M_2PI_F;
|
||||
}
|
||||
|
||||
// apply rotation vector according to physics rules
|
||||
if(mNewtonRotation)
|
||||
{
|
||||
const F32 force = mAngularForce;
|
||||
const F32 drag = mAngularDrag;
|
||||
|
||||
VectorF acc(0.0f, 0.0f, 0.0f);
|
||||
|
||||
rotVec.x *= 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script
|
||||
rotVec.z *= 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script
|
||||
|
||||
F32 rotVecL = rotVec.len();
|
||||
if(rotVecL > 0)
|
||||
{
|
||||
acc = (rotVec * force / mMass) * TickSec;
|
||||
}
|
||||
|
||||
// Accelerate
|
||||
mAngularVelocity += acc;
|
||||
|
||||
// Drag
|
||||
mAngularVelocity -= mAngularVelocity * drag * TickSec;
|
||||
|
||||
// Rotate
|
||||
mRot += mAngularVelocity * TickSec;
|
||||
clampPitchAngle(mRot.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOrbitObject->getWorldBox().getCenter(&objPos);
|
||||
mRot.x += rotVec.x;
|
||||
mRot.z += rotVec.z;
|
||||
clampPitchAngle(mRot.x);
|
||||
}
|
||||
mObjToWorld.getColumn(3,&pos);
|
||||
vec = objPos - pos;
|
||||
vec.normalizeSafe();
|
||||
F32 pitch, yaw;
|
||||
MathUtils::getAnglesFromVector(vec, yaw, pitch);
|
||||
rotVec.x = -pitch - mRot.x;
|
||||
rotVec.z = yaw - mRot.z;
|
||||
if(rotVec.z > M_PI_F)
|
||||
rotVec.z -= M_2PI_F;
|
||||
else if(rotVec.z < -M_PI_F)
|
||||
rotVec.z += M_2PI_F;
|
||||
}
|
||||
|
||||
// apply rotation vector according to physics rules
|
||||
if(mNewtonRotation)
|
||||
{
|
||||
const F32 force = mAngularForce;
|
||||
const F32 drag = mAngularDrag;
|
||||
|
||||
VectorF acc(0.0f, 0.0f, 0.0f);
|
||||
|
||||
rotVec.x *= 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script
|
||||
rotVec.z *= 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script
|
||||
|
||||
F32 rotVecL = rotVec.len();
|
||||
if(rotVecL > 0)
|
||||
{
|
||||
acc = (rotVec * force / mMass) * TickSec;
|
||||
}
|
||||
|
||||
// Accelerate
|
||||
mAngularVelocity += acc;
|
||||
|
||||
// Drag
|
||||
mAngularVelocity -= mAngularVelocity * drag * TickSec;
|
||||
|
||||
// Rotate
|
||||
mRot += mAngularVelocity * TickSec;
|
||||
clampPitchAngle(mRot.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRot.x += rotVec.x;
|
||||
mRot.z += rotVec.z;
|
||||
clampPitchAngle(mRot.x);
|
||||
}
|
||||
|
||||
// Update position
|
||||
|
|
@ -667,6 +769,13 @@ void Camera::processTick(const Move* move)
|
|||
mDelta.rot = mRot;
|
||||
mDelta.posVec = mDelta.posVec - mDelta.pos;
|
||||
mDelta.rotVec = mDelta.rotVec - mDelta.rot;
|
||||
for(U32 i=0; i<3; ++i)
|
||||
{
|
||||
if (mDelta.rotVec[i] > M_PI_F)
|
||||
mDelta.rotVec[i] -= M_2PI_F;
|
||||
else if (mDelta.rotVec[i] < -M_PI_F)
|
||||
mDelta.rotVec[i] += M_2PI_F;
|
||||
}
|
||||
}
|
||||
|
||||
if(mustValidateEyePoint)
|
||||
|
|
@ -793,7 +902,21 @@ void Camera::_setPosition(const Point3F& pos, const Point3F& rot)
|
|||
zRot.set(EulerF(0.0f, 0.0f, rot.z));
|
||||
|
||||
MatrixF temp;
|
||||
temp.mul(zRot, xRot);
|
||||
|
||||
if(mDataBlock->cameraCanBank)
|
||||
{
|
||||
// Take rot.y into account to bank the camera
|
||||
MatrixF imat;
|
||||
imat.mul(zRot, xRot);
|
||||
MatrixF ymat;
|
||||
ymat.set(EulerF(0.0f, rot.y, 0.0f));
|
||||
temp.mul(imat, ymat);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.mul(zRot, xRot);
|
||||
}
|
||||
|
||||
temp.setColumn(3, pos);
|
||||
Parent::setTransform(temp);
|
||||
mRot = rot;
|
||||
|
|
@ -808,7 +931,21 @@ void Camera::setRotation(const Point3F& rot)
|
|||
zRot.set(EulerF(0.0f, 0.0f, rot.z));
|
||||
|
||||
MatrixF temp;
|
||||
temp.mul(zRot, xRot);
|
||||
|
||||
if(mDataBlock->cameraCanBank)
|
||||
{
|
||||
// Take rot.y into account to bank the camera
|
||||
MatrixF imat;
|
||||
imat.mul(zRot, xRot);
|
||||
MatrixF ymat;
|
||||
ymat.set(EulerF(0.0f, rot.y, 0.0f));
|
||||
temp.mul(imat, ymat);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.mul(zRot, xRot);
|
||||
}
|
||||
|
||||
temp.setColumn(3, getPosition());
|
||||
Parent::setTransform(temp);
|
||||
mRot = rot;
|
||||
|
|
@ -821,8 +958,25 @@ void Camera::_setRenderPosition(const Point3F& pos,const Point3F& rot)
|
|||
MatrixF xRot, zRot;
|
||||
xRot.set(EulerF(rot.x, 0, 0));
|
||||
zRot.set(EulerF(0, 0, rot.z));
|
||||
|
||||
MatrixF temp;
|
||||
temp.mul(zRot, xRot);
|
||||
|
||||
// mDataBlock may not be defined yet as this method is called during
|
||||
// SceneObject::onAdd().
|
||||
if(mDataBlock && mDataBlock->cameraCanBank)
|
||||
{
|
||||
// Take rot.y into account to bank the camera
|
||||
MatrixF imat;
|
||||
imat.mul(zRot, xRot);
|
||||
MatrixF ymat;
|
||||
ymat.set(EulerF(0.0f, rot.y, 0.0f));
|
||||
temp.mul(imat, ymat);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.mul(zRot, xRot);
|
||||
}
|
||||
|
||||
temp.setColumn(3, pos);
|
||||
Parent::setRenderTransform(temp);
|
||||
}
|
||||
|
|
@ -839,6 +993,11 @@ void Camera::writePacketData(GameConnection *connection, BitStream *bstream)
|
|||
bstream->setCompressionPoint(pos);
|
||||
mathWrite(*bstream, pos);
|
||||
bstream->write(mRot.x);
|
||||
if(bstream->writeFlag(mDataBlock->cameraCanBank))
|
||||
{
|
||||
// Include mRot.y to allow for camera banking
|
||||
bstream->write(mRot.y);
|
||||
}
|
||||
bstream->write(mRot.z);
|
||||
|
||||
U32 writeMode = mMode;
|
||||
|
|
@ -912,6 +1071,11 @@ void Camera::readPacketData(GameConnection *connection, BitStream *bstream)
|
|||
mathRead(*bstream, &pos);
|
||||
bstream->setCompressionPoint(pos);
|
||||
bstream->read(&rot.x);
|
||||
if(bstream->readFlag())
|
||||
{
|
||||
// Include rot.y to allow for camera banking
|
||||
bstream->read(&rot.y);
|
||||
}
|
||||
bstream->read(&rot.z);
|
||||
|
||||
GameBase* obj = 0;
|
||||
|
|
@ -1184,6 +1348,11 @@ void Camera::consoleInit()
|
|||
"- Fly Mode\n"
|
||||
"- Overhead Mode\n"
|
||||
"@ingroup BaseCamera\n");
|
||||
|
||||
// ExtendedMove support
|
||||
Con::addVariable("$camera::extendedMovePosRotIndex", TypeS32, &smExtendedMovePosRotIndex,
|
||||
"@brief The ExtendedMove position/rotation index used for camera movements.\n\n"
|
||||
"@ingroup BaseCamera\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ class Camera: public ShapeBase
|
|||
CameraLastMode = EditOrbitMode
|
||||
};
|
||||
|
||||
/// The ExtendedMove position/rotation index used for camera movements
|
||||
static S32 smExtendedMovePosRotIndex;
|
||||
|
||||
protected:
|
||||
|
||||
enum MaskBits
|
||||
|
|
@ -92,6 +95,8 @@ class Camera: public ShapeBase
|
|||
VectorF rotVec;
|
||||
};
|
||||
|
||||
CameraData* mDataBlock;
|
||||
|
||||
Point3F mRot;
|
||||
StateDelta mDelta;
|
||||
|
||||
|
|
@ -106,6 +111,9 @@ class Camera: public ShapeBase
|
|||
Point3F mPosition;
|
||||
bool mObservingClientObject;
|
||||
|
||||
F32 mLastAbsoluteYaw; ///< Stores that last absolute yaw value as passed in by ExtendedMove
|
||||
F32 mLastAbsolutePitch; ///< Stores that last absolute pitch value as passed in by ExtendedMove
|
||||
|
||||
/// @name NewtonFlyMode
|
||||
/// @{
|
||||
|
||||
|
|
@ -223,6 +231,7 @@ class Camera: public ShapeBase
|
|||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual bool onNewDataBlock( GameBaseData *dptr, bool reload );
|
||||
virtual void processTick( const Move* move );
|
||||
virtual void interpolateTick( F32 delta);
|
||||
virtual void getCameraTransform( F32* pos,MatrixF* mat );
|
||||
|
|
|
|||
|
|
@ -219,6 +219,13 @@ GameConnection::GameConnection()
|
|||
// first person
|
||||
mFirstPerson = true;
|
||||
mUpdateFirstPerson = false;
|
||||
|
||||
// Control scheme
|
||||
mUpdateControlScheme = false;
|
||||
mAbsoluteRotation = false;
|
||||
mAddYawToAbsRot = false;
|
||||
mAddPitchToAbsRot = false;
|
||||
|
||||
clearDisplayDevice();
|
||||
}
|
||||
|
||||
|
|
@ -743,7 +750,15 @@ void GameConnection::setFirstPerson(bool firstPerson)
|
|||
mUpdateFirstPerson = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void GameConnection::setControlSchemeParameters(bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot)
|
||||
{
|
||||
mAbsoluteRotation = absoluteRotation;
|
||||
mAddYawToAbsRot = addYawToAbsRot;
|
||||
mAddPitchToAbsRot = addPitchToAbsRot;
|
||||
mUpdateControlScheme = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -826,6 +841,11 @@ void GameConnection::writeDemoStartBlock(ResizeBitStream *stream)
|
|||
stream->write(mCameraPos);
|
||||
stream->write(mCameraSpeed);
|
||||
|
||||
// Control scheme
|
||||
stream->write(mAbsoluteRotation);
|
||||
stream->write(mAddYawToAbsRot);
|
||||
stream->write(mAddPitchToAbsRot);
|
||||
|
||||
stream->writeString(Con::getVariable("$Client::MissionFile"));
|
||||
|
||||
mMoveList->writeDemoStartBlock(stream);
|
||||
|
|
@ -902,6 +922,11 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
|
|||
stream->read(&mCameraPos);
|
||||
stream->read(&mCameraSpeed);
|
||||
|
||||
// Control scheme
|
||||
stream->read(&mAbsoluteRotation);
|
||||
stream->read(&mAddYawToAbsRot);
|
||||
stream->read(&mAddPitchToAbsRot);
|
||||
|
||||
char buf[256];
|
||||
stream->readString(buf);
|
||||
Con::setVariable("$Client::MissionFile",buf);
|
||||
|
|
@ -1078,6 +1103,16 @@ void GameConnection::readPacket(BitStream *bstream)
|
|||
else
|
||||
setCameraObject(0);
|
||||
|
||||
// server changed control scheme
|
||||
if(bstream->readFlag())
|
||||
{
|
||||
bool absoluteRotation = bstream->readFlag();
|
||||
bool addYawToAbsRot = bstream->readFlag();
|
||||
bool addPitchToAbsRot = bstream->readFlag();
|
||||
setControlSchemeParameters(absoluteRotation, addYawToAbsRot, addPitchToAbsRot);
|
||||
mUpdateControlScheme = false;
|
||||
}
|
||||
|
||||
// server changed first person
|
||||
if(bstream->readFlag())
|
||||
{
|
||||
|
|
@ -1108,6 +1143,16 @@ void GameConnection::readPacket(BitStream *bstream)
|
|||
if (bstream->readFlag())
|
||||
mControlForceMismatch = true;
|
||||
|
||||
// client changed control scheme
|
||||
if(bstream->readFlag())
|
||||
{
|
||||
bool absoluteRotation = bstream->readFlag();
|
||||
bool addYawToAbsRot = bstream->readFlag();
|
||||
bool addPitchToAbsRot = bstream->readFlag();
|
||||
setControlSchemeParameters(absoluteRotation, addYawToAbsRot, addPitchToAbsRot);
|
||||
mUpdateControlScheme = false;
|
||||
}
|
||||
|
||||
// client changed first person
|
||||
if(bstream->readFlag())
|
||||
{
|
||||
|
|
@ -1170,6 +1215,15 @@ void GameConnection::writePacket(BitStream *bstream, PacketNotify *note)
|
|||
}
|
||||
bstream->writeFlag(forceUpdate);
|
||||
|
||||
// Control scheme changed?
|
||||
if(bstream->writeFlag(mUpdateControlScheme))
|
||||
{
|
||||
bstream->writeFlag(mAbsoluteRotation);
|
||||
bstream->writeFlag(mAddYawToAbsRot);
|
||||
bstream->writeFlag(mAddPitchToAbsRot);
|
||||
mUpdateControlScheme = false;
|
||||
}
|
||||
|
||||
// first person changed?
|
||||
if(bstream->writeFlag(mUpdateFirstPerson))
|
||||
{
|
||||
|
|
@ -1258,6 +1312,15 @@ void GameConnection::writePacket(BitStream *bstream, PacketNotify *note)
|
|||
else
|
||||
bstream->writeFlag( false );
|
||||
|
||||
// Control scheme changed?
|
||||
if(bstream->writeFlag(mUpdateControlScheme))
|
||||
{
|
||||
bstream->writeFlag(mAbsoluteRotation);
|
||||
bstream->writeFlag(mAddYawToAbsRot);
|
||||
bstream->writeFlag(mAddPitchToAbsRot);
|
||||
mUpdateControlScheme = false;
|
||||
}
|
||||
|
||||
// first person changed?
|
||||
if(bstream->writeFlag(mUpdateFirstPerson))
|
||||
{
|
||||
|
|
@ -2115,3 +2178,21 @@ DefineEngineMethod( GameConnection, setFirstPerson, void, (bool firstPerson),,
|
|||
{
|
||||
object->setFirstPerson(firstPerson);
|
||||
}
|
||||
|
||||
DefineEngineMethod( GameConnection, setControlSchemeParameters, void, (bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot),,
|
||||
"@brief Set the control scheme that may be used by a connection's control object.\n\n"
|
||||
|
||||
"@param absoluteRotation Use absolute rotation values from client, likely through ExtendedMove.\n"
|
||||
"@param addYawToAbsRot Add relative yaw control to the absolute rotation calculation. Only useful when absoluteRotation is true.\n\n" )
|
||||
{
|
||||
object->setControlSchemeParameters(absoluteRotation, addYawToAbsRot, addPitchToAbsRot);
|
||||
}
|
||||
|
||||
DefineEngineMethod( GameConnection, getControlSchemeAbsoluteRotation, bool, (),,
|
||||
"@brief Get the connection's control scheme absolute rotation property.\n\n"
|
||||
|
||||
"@return True if the connection's control object should use an absolute rotation control scheme.\n\n"
|
||||
"@see GameConnection::setControlSchemeParameters()\n\n")
|
||||
{
|
||||
return object->getControlSchemeAbsoluteRotation();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,14 @@ private:
|
|||
IDisplayDevice* mDisplayDevice; ///< Optional client display device that imposes rendering properties.
|
||||
/// @}
|
||||
|
||||
/// @name Client side control scheme that may be referenced by control objects
|
||||
/// @{
|
||||
bool mUpdateControlScheme; ///< Set to notify client or server of control scheme change
|
||||
bool mAbsoluteRotation; ///< Use absolute rotation values from client, likely through ExtendedMove
|
||||
bool mAddYawToAbsRot; ///< Add relative yaw control to the absolute rotation calculation. Only useful with mAbsoluteRotation.
|
||||
bool mAddPitchToAbsRot; ///< Add relative pitch control to the absolute rotation calculation. Only useful with mAbsoluteRotation.
|
||||
/// @}
|
||||
|
||||
public:
|
||||
|
||||
/// @name Protocol Versions
|
||||
|
|
@ -270,6 +278,12 @@ public:
|
|||
const IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
|
||||
void setDisplayDevice(IDisplayDevice* display) { mDisplayDevice = display; }
|
||||
void clearDisplayDevice() { mDisplayDevice = NULL; }
|
||||
|
||||
void setControlSchemeParameters(bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot);
|
||||
bool getControlSchemeAbsoluteRotation() {return mAbsoluteRotation;}
|
||||
bool getControlSchemeAddYawToAbsRot() {return mAddYawToAbsRot;}
|
||||
bool getControlSchemeAddPitchToAbsRot() {return mAddPitchToAbsRot;}
|
||||
|
||||
/// @}
|
||||
|
||||
void detectLag();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@
|
|||
#include "T3D/decal/decalData.h"
|
||||
#include "materials/baseMatInstance.h"
|
||||
|
||||
#ifdef TORQUE_EXTENDED_MOVE
|
||||
#include "T3D/gameBase/extended/extendedMove.h"
|
||||
#endif
|
||||
|
||||
// Amount of time if takes to transition to a new action sequence.
|
||||
static F32 sAnimationTransitionTime = 0.25f;
|
||||
static bool sUseAnimationTransitions = true;
|
||||
|
|
@ -96,6 +100,8 @@ static F32 sMinWarpTicks = 0.5f; // Fraction of tick at which instant warp
|
|||
static S32 sMaxWarpTicks = 3; // Max warp duration in ticks
|
||||
static S32 sMaxPredictionTicks = 30; // Number of ticks to predict
|
||||
|
||||
S32 Player::smExtendedMoveHeadPosRotIndex = 0; // The ExtendedMove position/rotation index used for head movements
|
||||
|
||||
// Anchor point compression
|
||||
const F32 sAnchorMaxDistance = 32.0f;
|
||||
|
||||
|
|
@ -1650,6 +1656,9 @@ Player::Player()
|
|||
mShapeFPFlashThread[i] = 0;
|
||||
mShapeFPSpinThread[i] = 0;
|
||||
}
|
||||
|
||||
mLastAbsoluteYaw = 0.0f;
|
||||
mLastAbsolutePitch = 0.0f;
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
|
|
@ -2523,38 +2532,130 @@ void Player::updateMove(const Move* move)
|
|||
F32 prevZRot = mRot.z;
|
||||
delta.headVec = mHead;
|
||||
|
||||
F32 p = move->pitch * (mPose == SprintPose ? mDataBlock->sprintPitchScale : 1.0f);
|
||||
if (p > M_PI_F)
|
||||
p -= M_2PI_F;
|
||||
mHead.x = mClampF(mHead.x + p,mDataBlock->minLookAngle,
|
||||
mDataBlock->maxLookAngle);
|
||||
|
||||
F32 y = move->yaw * (mPose == SprintPose ? mDataBlock->sprintYawScale : 1.0f);
|
||||
if (y > M_PI_F)
|
||||
y -= M_2PI_F;
|
||||
|
||||
bool doStandardMove = true;
|
||||
GameConnection* con = getControllingClient();
|
||||
if (move->freeLook && ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson())))
|
||||
{
|
||||
mHead.z = mClampF(mHead.z + y,
|
||||
-mDataBlock->maxFreelookAngle,
|
||||
mDataBlock->maxFreelookAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRot.z += y;
|
||||
// Rotate the head back to the front, center horizontal
|
||||
// as well if we're controlling another object.
|
||||
mHead.z *= 0.5f;
|
||||
if (mControlObject)
|
||||
mHead.x *= 0.5f;
|
||||
}
|
||||
|
||||
// constrain the range of mRot.z
|
||||
while (mRot.z < 0.0f)
|
||||
mRot.z += M_2PI_F;
|
||||
while (mRot.z > M_2PI_F)
|
||||
mRot.z -= M_2PI_F;
|
||||
#ifdef TORQUE_EXTENDED_MOVE
|
||||
// Work with an absolute rotation from the ExtendedMove class?
|
||||
if(con && con->getControlSchemeAbsoluteRotation())
|
||||
{
|
||||
doStandardMove = false;
|
||||
const ExtendedMove* emove = dynamic_cast<const ExtendedMove*>(move);
|
||||
U32 emoveIndex = smExtendedMoveHeadPosRotIndex;
|
||||
if(emoveIndex >= ExtendedMove::MaxPositionsRotations)
|
||||
emoveIndex = 0;
|
||||
|
||||
if(emove->EulerBasedRotation[emoveIndex])
|
||||
{
|
||||
// Head pitch
|
||||
mHead.x += (emove->rotX[emoveIndex] - mLastAbsolutePitch);
|
||||
|
||||
// Do we also include the relative yaw value?
|
||||
if(con->getControlSchemeAddPitchToAbsRot())
|
||||
{
|
||||
F32 x = move->pitch;
|
||||
if (x > M_PI_F)
|
||||
x -= M_2PI_F;
|
||||
|
||||
mHead.x += x;
|
||||
}
|
||||
|
||||
// Constrain the range of mHead.x
|
||||
while (mHead.x < -M_PI_F)
|
||||
mHead.x += M_2PI_F;
|
||||
while (mHead.x > M_PI_F)
|
||||
mHead.x -= M_2PI_F;
|
||||
|
||||
// Rotate (heading) head or body?
|
||||
if (move->freeLook && ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson())))
|
||||
{
|
||||
// Rotate head
|
||||
mHead.z += (emove->rotZ[emoveIndex] - mLastAbsoluteYaw);
|
||||
|
||||
// Do we also include the relative yaw value?
|
||||
if(con->getControlSchemeAddYawToAbsRot())
|
||||
{
|
||||
F32 z = move->yaw;
|
||||
if (z > M_PI_F)
|
||||
z -= M_2PI_F;
|
||||
|
||||
mHead.z += z;
|
||||
}
|
||||
|
||||
// Constrain the range of mHead.z
|
||||
while (mHead.z < 0.0f)
|
||||
mHead.z += M_2PI_F;
|
||||
while (mHead.z > M_2PI_F)
|
||||
mHead.z -= M_2PI_F;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rotate body
|
||||
mRot.z += (emove->rotZ[emoveIndex] - mLastAbsoluteYaw);
|
||||
|
||||
// Do we also include the relative yaw value?
|
||||
if(con->getControlSchemeAddYawToAbsRot())
|
||||
{
|
||||
F32 z = move->yaw;
|
||||
if (z > M_PI_F)
|
||||
z -= M_2PI_F;
|
||||
|
||||
mRot.z += z;
|
||||
}
|
||||
|
||||
// Constrain the range of mRot.z
|
||||
while (mRot.z < 0.0f)
|
||||
mRot.z += M_2PI_F;
|
||||
while (mRot.z > M_2PI_F)
|
||||
mRot.z -= M_2PI_F;
|
||||
}
|
||||
mLastAbsoluteYaw = emove->rotZ[emoveIndex];
|
||||
mLastAbsolutePitch = emove->rotX[emoveIndex];
|
||||
|
||||
// Head bank
|
||||
mHead.y = emove->rotY[emoveIndex];
|
||||
|
||||
// Constrain the range of mHead.y
|
||||
while (mHead.y > M_PI_F)
|
||||
mHead.y -= M_2PI_F;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(doStandardMove)
|
||||
{
|
||||
F32 p = move->pitch * (mPose == SprintPose ? mDataBlock->sprintPitchScale : 1.0f);
|
||||
if (p > M_PI_F)
|
||||
p -= M_2PI_F;
|
||||
mHead.x = mClampF(mHead.x + p,mDataBlock->minLookAngle,
|
||||
mDataBlock->maxLookAngle);
|
||||
|
||||
F32 y = move->yaw * (mPose == SprintPose ? mDataBlock->sprintYawScale : 1.0f);
|
||||
if (y > M_PI_F)
|
||||
y -= M_2PI_F;
|
||||
|
||||
if (move->freeLook && ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson())))
|
||||
{
|
||||
mHead.z = mClampF(mHead.z + y,
|
||||
-mDataBlock->maxFreelookAngle,
|
||||
mDataBlock->maxFreelookAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRot.z += y;
|
||||
// Rotate the head back to the front, center horizontal
|
||||
// as well if we're controlling another object.
|
||||
mHead.z *= 0.5f;
|
||||
if (mControlObject)
|
||||
mHead.x *= 0.5f;
|
||||
}
|
||||
|
||||
// constrain the range of mRot.z
|
||||
while (mRot.z < 0.0f)
|
||||
mRot.z += M_2PI_F;
|
||||
while (mRot.z > M_2PI_F)
|
||||
mRot.z -= M_2PI_F;
|
||||
}
|
||||
|
||||
delta.rot = mRot;
|
||||
delta.rotVec.x = delta.rotVec.y = 0.0f;
|
||||
|
|
@ -2566,6 +2667,13 @@ void Player::updateMove(const Move* move)
|
|||
|
||||
delta.head = mHead;
|
||||
delta.headVec -= mHead;
|
||||
for(U32 i=0; i<3; ++i)
|
||||
{
|
||||
if (delta.headVec[i] > M_PI_F)
|
||||
delta.headVec[i] -= M_2PI_F;
|
||||
else if (delta.headVec[i] < -M_PI_F)
|
||||
delta.headVec[i] += M_2PI_F;
|
||||
}
|
||||
}
|
||||
MatrixF zRot;
|
||||
zRot.set(EulerF(0.0f, 0.0f, mRot.z));
|
||||
|
|
@ -5259,7 +5367,7 @@ void Player::setTransform(const MatrixF& mat)
|
|||
|
||||
void Player::getEyeTransform(MatrixF* mat)
|
||||
{
|
||||
getEyeBaseTransform(mat);
|
||||
getEyeBaseTransform(mat, true);
|
||||
|
||||
// The shape instance is animated in getEyeBaseTransform() so we're
|
||||
// good here when attempting to get the eye node position on the server.
|
||||
|
|
@ -5297,7 +5405,7 @@ void Player::getEyeTransform(MatrixF* mat)
|
|||
}
|
||||
}
|
||||
|
||||
void Player::getEyeBaseTransform(MatrixF* mat)
|
||||
void Player::getEyeBaseTransform(MatrixF* mat, bool includeBank)
|
||||
{
|
||||
// Eye transform in world space. We only use the eye position
|
||||
// from the animation and supply our own rotation.
|
||||
|
|
@ -5313,7 +5421,19 @@ void Player::getEyeBaseTransform(MatrixF* mat)
|
|||
else
|
||||
zmat.identity();
|
||||
|
||||
pmat.mul(zmat,xmat);
|
||||
if(includeBank && mDataBlock->cameraCanBank)
|
||||
{
|
||||
// Take mHead.y into account to bank the camera
|
||||
MatrixF imat;
|
||||
imat.mul(zmat, xmat);
|
||||
MatrixF ymat;
|
||||
ymat.set(EulerF(0.0f, mHead.y, 0.0f));
|
||||
pmat.mul(imat, ymat);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmat.mul(zmat,xmat);
|
||||
}
|
||||
|
||||
F32 *dp = pmat;
|
||||
|
||||
|
|
@ -5340,7 +5460,7 @@ void Player::getEyeBaseTransform(MatrixF* mat)
|
|||
|
||||
void Player::getRenderEyeTransform(MatrixF* mat)
|
||||
{
|
||||
getRenderEyeBaseTransform(mat);
|
||||
getRenderEyeBaseTransform(mat, true);
|
||||
|
||||
// Use the first image that is set to use the eye node
|
||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||
|
|
@ -5369,7 +5489,7 @@ void Player::getRenderEyeTransform(MatrixF* mat)
|
|||
}
|
||||
}
|
||||
|
||||
void Player::getRenderEyeBaseTransform(MatrixF* mat)
|
||||
void Player::getRenderEyeBaseTransform(MatrixF* mat, bool includeBank)
|
||||
{
|
||||
// Eye transform in world space. We only use the eye position
|
||||
// from the animation and supply our own rotation.
|
||||
|
|
@ -5381,7 +5501,19 @@ void Player::getRenderEyeBaseTransform(MatrixF* mat)
|
|||
else
|
||||
zmat.identity();
|
||||
|
||||
pmat.mul(zmat,xmat);
|
||||
if(includeBank && mDataBlock->cameraCanBank)
|
||||
{
|
||||
// Take mHead.y delta into account to bank the camera
|
||||
MatrixF imat;
|
||||
imat.mul(zmat, xmat);
|
||||
MatrixF ymat;
|
||||
ymat.set(EulerF(0.0f, delta.head.y + delta.headVec.y * delta.dt, 0.0f));
|
||||
pmat.mul(imat, ymat);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmat.mul(zmat,xmat);
|
||||
}
|
||||
|
||||
F32 *dp = pmat;
|
||||
|
||||
|
|
@ -5539,7 +5671,7 @@ void Player::renderMountedImage( U32 imageSlot, TSRenderState &rstate, SceneRend
|
|||
if (data.useEyeNode && data.eyeMountNode[imageShapeIndex] != -1)
|
||||
{
|
||||
MatrixF nmat;
|
||||
getRenderEyeBaseTransform(&nmat);
|
||||
getRenderEyeBaseTransform(&nmat, mDataBlock->mountedImagesBank);
|
||||
MatrixF offsetMat = image.shapeInstance[imageShapeIndex]->mNodeTransforms[data.eyeMountNode[imageShapeIndex]];
|
||||
offsetMat.affineInverse();
|
||||
world.mul(nmat,offsetMat);
|
||||
|
|
@ -5547,7 +5679,7 @@ void Player::renderMountedImage( U32 imageSlot, TSRenderState &rstate, SceneRend
|
|||
else
|
||||
{
|
||||
MatrixF nmat;
|
||||
getRenderEyeBaseTransform(&nmat);
|
||||
getRenderEyeBaseTransform(&nmat, mDataBlock->mountedImagesBank);
|
||||
world.mul(nmat,data.eyeOffset);
|
||||
}
|
||||
|
||||
|
|
@ -5866,6 +5998,11 @@ void Player::writePacketData(GameConnection *connection, BitStream *stream)
|
|||
}
|
||||
}
|
||||
stream->write(mHead.x);
|
||||
if(stream->writeFlag(mDataBlock->cameraCanBank))
|
||||
{
|
||||
// Include mHead.y to allow for camera banking
|
||||
stream->write(mHead.y);
|
||||
}
|
||||
stream->write(mHead.z);
|
||||
stream->write(mRot.z);
|
||||
|
||||
|
|
@ -5928,6 +6065,11 @@ void Player::readPacketData(GameConnection *connection, BitStream *stream)
|
|||
else
|
||||
pos = delta.pos;
|
||||
stream->read(&mHead.x);
|
||||
if(stream->readFlag())
|
||||
{
|
||||
// Include mHead.y to allow for camera banking
|
||||
stream->read(&mHead.y);
|
||||
}
|
||||
stream->read(&mHead.z);
|
||||
stream->read(&rot.z);
|
||||
rot.x = rot.y = 0;
|
||||
|
|
@ -6587,6 +6729,11 @@ void Player::consoleInit()
|
|||
Con::addVariable("$player::vehicleDismountTrigger", TypeS32, &sVehicleDismountTrigger,
|
||||
"@brief The move trigger index used to dismount player.\n\n"
|
||||
"@ingroup GameObjects\n");
|
||||
|
||||
// ExtendedMove support
|
||||
Con::addVariable("$player::extendedMoveHeadPosRotIndex", TypeS32, &smExtendedMoveHeadPosRotIndex,
|
||||
"@brief The ExtendedMove position/rotation index used for head movements.\n\n"
|
||||
"@ingroup GameObjects\n");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -385,6 +385,9 @@ public:
|
|||
NumPoseBits = 3
|
||||
};
|
||||
|
||||
/// The ExtendedMove position/rotation index used for head movements
|
||||
static S32 smExtendedMoveHeadPosRotIndex;
|
||||
|
||||
protected:
|
||||
|
||||
/// Bit masks for different types of events
|
||||
|
|
@ -444,6 +447,9 @@ protected:
|
|||
|
||||
bool mUseHeadZCalc; ///< Including mHead.z in transform calculations
|
||||
|
||||
F32 mLastAbsoluteYaw; ///< Stores that last absolute yaw value as passed in by ExtendedMove
|
||||
F32 mLastAbsolutePitch; ///< Stores that last absolute pitch value as passed in by ExtendedMove
|
||||
|
||||
S32 mMountPending; ///< mMountPending suppresses tickDelay countdown so players will sit until
|
||||
///< their mount, or another animation, comes through (or 13 seconds elapses).
|
||||
|
||||
|
|
@ -687,9 +693,9 @@ public:
|
|||
|
||||
void setTransform(const MatrixF &mat);
|
||||
void getEyeTransform(MatrixF* mat);
|
||||
void getEyeBaseTransform(MatrixF* mat);
|
||||
void getEyeBaseTransform(MatrixF* mat, bool includeBank);
|
||||
void getRenderEyeTransform(MatrixF* mat);
|
||||
void getRenderEyeBaseTransform(MatrixF* mat);
|
||||
void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
|
||||
void getCameraParameters(F32 *min, F32 *max, Point3F *offset, MatrixF *rot);
|
||||
void getMuzzleTransform(U32 imageSlot,MatrixF* mat);
|
||||
void getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat);
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ ShapeBaseData::ShapeBaseData()
|
|||
cameraDefaultFov( 75.0f ),
|
||||
cameraMinFov( 5.0f ),
|
||||
cameraMaxFov( 120.f ),
|
||||
cameraCanBank( false ),
|
||||
mountedImagesBank( false ),
|
||||
isInvincible( false ),
|
||||
renderWhenDestroyed( true ),
|
||||
debris( NULL ),
|
||||
|
|
@ -544,6 +546,10 @@ void ShapeBaseData::initPersistFields()
|
|||
"The minimum camera vertical FOV allowed in degrees." );
|
||||
addField( "cameraMaxFov", TypeF32, Offset(cameraMaxFov, ShapeBaseData),
|
||||
"The maximum camera vertical FOV allowed in degrees." );
|
||||
addField( "cameraCanBank", TypeBool, Offset(cameraCanBank, ShapeBaseData),
|
||||
"If the derrived class supports it, allow the camera to bank." );
|
||||
addField( "mountedImagesBank", TypeBool, Offset(mountedImagesBank, ShapeBaseData),
|
||||
"Do mounted images bank along with the camera?" );
|
||||
addField( "firstPersonOnly", TypeBool, Offset(firstPersonOnly, ShapeBaseData),
|
||||
"Flag controlling whether the view from this object is first person "
|
||||
"only." );
|
||||
|
|
@ -689,6 +695,8 @@ void ShapeBaseData::packData(BitStream* stream)
|
|||
stream->write(cameraMinFov);
|
||||
if(stream->writeFlag(cameraMaxFov != gShapeBaseDataProto.cameraMaxFov))
|
||||
stream->write(cameraMaxFov);
|
||||
stream->writeFlag(cameraCanBank);
|
||||
stream->writeFlag(mountedImagesBank);
|
||||
stream->writeString( debrisShapeName );
|
||||
|
||||
stream->writeFlag(observeThroughObject);
|
||||
|
|
@ -788,6 +796,9 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
|||
else
|
||||
cameraMaxFov = gShapeBaseDataProto.cameraMaxFov;
|
||||
|
||||
cameraCanBank = stream->readFlag();
|
||||
mountedImagesBank = stream->readFlag();
|
||||
|
||||
debrisShapeName = stream->readSTString();
|
||||
|
||||
observeThroughObject = stream->readFlag();
|
||||
|
|
@ -1872,10 +1883,10 @@ Point3F ShapeBase::getAIRepairPoint()
|
|||
|
||||
void ShapeBase::getEyeTransform(MatrixF* mat)
|
||||
{
|
||||
getEyeBaseTransform(mat);
|
||||
getEyeBaseTransform(mat, true);
|
||||
}
|
||||
|
||||
void ShapeBase::getEyeBaseTransform(MatrixF* mat)
|
||||
void ShapeBase::getEyeBaseTransform(MatrixF* mat, bool includeBank)
|
||||
{
|
||||
// Returns eye to world space transform
|
||||
S32 eyeNode = mDataBlock->eyeNode;
|
||||
|
|
@ -1887,10 +1898,10 @@ void ShapeBase::getEyeBaseTransform(MatrixF* mat)
|
|||
|
||||
void ShapeBase::getRenderEyeTransform(MatrixF* mat)
|
||||
{
|
||||
getRenderEyeBaseTransform(mat);
|
||||
getRenderEyeBaseTransform(mat, true);
|
||||
}
|
||||
|
||||
void ShapeBase::getRenderEyeBaseTransform(MatrixF* mat)
|
||||
void ShapeBase::getRenderEyeBaseTransform(MatrixF* mat, bool includeBank)
|
||||
{
|
||||
// Returns eye to world space transform
|
||||
S32 eyeNode = mDataBlock->eyeNode;
|
||||
|
|
|
|||
|
|
@ -578,6 +578,12 @@ public:
|
|||
F32 cameraMaxFov; ///< Max vertical FOV allowed in degrees.
|
||||
/// @}
|
||||
|
||||
/// @name Camera Misc
|
||||
/// @{
|
||||
bool cameraCanBank; ///< If the derrived class supports it, allow the camera to bank
|
||||
bool mountedImagesBank; ///< Do mounted images bank along with the camera?
|
||||
/// @}
|
||||
|
||||
/// @name Data initialized on preload
|
||||
/// @{
|
||||
|
||||
|
|
@ -1618,7 +1624,7 @@ public:
|
|||
|
||||
/// Returns the eye transform of this shape without including mounted images, IE the eyes of a player
|
||||
/// @param mat Eye transform (out)
|
||||
virtual void getEyeBaseTransform(MatrixF* mat);
|
||||
virtual void getEyeBaseTransform(MatrixF* mat, bool includeBank);
|
||||
|
||||
/// The retraction transform is the muzzle transform in world space.
|
||||
///
|
||||
|
|
@ -1671,7 +1677,7 @@ public:
|
|||
virtual void getRenderMuzzleVector(U32 imageSlot,VectorF* vec);
|
||||
virtual void getRenderMuzzlePoint(U32 imageSlot,Point3F* pos);
|
||||
virtual void getRenderEyeTransform(MatrixF* mat);
|
||||
virtual void getRenderEyeBaseTransform(MatrixF* mat);
|
||||
virtual void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
|
||||
/// @}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1861,7 +1861,7 @@ void ShapeBase::getImageTransform(U32 imageSlot,MatrixF* mat)
|
|||
// We need to animate, even on the server, to make sure the nodes are in the correct location.
|
||||
image.shapeInstance[shapeIndex]->animate();
|
||||
|
||||
getEyeBaseTransform(&nmat);
|
||||
getEyeBaseTransform(&nmat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
|
||||
|
|
@ -1900,7 +1900,7 @@ void ShapeBase::getImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
|
|||
image.shapeInstance[shapeIndex]->animate();
|
||||
|
||||
MatrixF emat;
|
||||
getEyeBaseTransform(&emat);
|
||||
getEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
mountTransform.affineInverse();
|
||||
|
|
@ -1985,7 +1985,7 @@ void ShapeBase::getRenderImageTransform( U32 imageSlot, MatrixF* mat, bool noEye
|
|||
|
||||
MatrixF nmat;
|
||||
if ( data.useEyeNode && isFirstPerson() && data.eyeMountNode[shapeIndex] != -1 ) {
|
||||
getRenderEyeBaseTransform(&nmat);
|
||||
getRenderEyeBaseTransform(&nmat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
|
||||
|
|
@ -2023,7 +2023,7 @@ void ShapeBase::getRenderImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
|
|||
if ( data.useEyeNode && isFirstPerson() && data.eyeMountNode[shapeIndex] != -1 )
|
||||
{
|
||||
MatrixF emat;
|
||||
getRenderEyeBaseTransform(&emat);
|
||||
getRenderEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
mountTransform.affineInverse();
|
||||
|
|
|
|||
|
|
@ -1270,7 +1270,7 @@ void TurretShape::getImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
|
|||
image.shapeInstance[shapeIndex]->animate();
|
||||
|
||||
MatrixF emat;
|
||||
getEyeBaseTransform(&emat);
|
||||
getEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
mountTransform.affineInverse();
|
||||
|
|
@ -1318,7 +1318,7 @@ void TurretShape::getRenderImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
|
|||
if ( data.useEyeNode && isFirstPerson() && data.eyeMountNode[shapeIndex] != -1 )
|
||||
{
|
||||
MatrixF emat;
|
||||
getRenderEyeBaseTransform(&emat);
|
||||
getRenderEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);
|
||||
|
||||
MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
|
||||
mountTransform.affineInverse();
|
||||
|
|
|
|||
Loading…
Reference in a new issue