Commit 660250cc authored by DavidWyand-GG's avatar DavidWyand-GG

Game cam and eye banking, control schemes

- ShapeBaseData has two new properties.  cameraCanBank indicates that
the game object may bank its eye/camera, if supported by the object.
mountedImagesBank indicates that mounted images should bank with the
eye/camera in first person view.  Both default to false.
- Player supports 1st person eye and 3rd person camera banking when
making use of the new ExtendedMove class.
- Camera class supports banking when making use of the new ExtendedMove
class.
- GameConnection now has an idea of a control scheme.  This determines
how game objects should respond to input events.  A control scheme may
be set by either the server or client.  Current control schemes are:
-- Absolute rotation (likely though the ExtendedMove class)
-- Add relative yaw (from mouse or gamepad) to absolute rotation.
-- Add relative pitch (from mouse or gamepad) to absolute rotation.
- Player class supports the new control schemes when using the
ExtendedMove class.
- Camera class supports the new control scheme when using the
ExtendedMove class.
parent 2805ec81
This diff is collapsed.
......@@ -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();
......
This diff is collapsed.
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment