mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
The ExtendedMove class can optionally replace the standard Move class to allow the passing of absolute position and rotation information from the client's input device to the server. It is enabled by changing $TORQUE_EXTENDED_MOVE to true in buildFiles/config/project.conf and re-running the project generator.
259 lines
7.7 KiB
C++
259 lines
7.7 KiB
C++
#include "T3D/gameBase/extended/extendedMove.h"
|
|
#include "core/stream/bitStream.h"
|
|
#include "math/mathIO.h"
|
|
#include "core/module.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "core/strings/stringFunctions.h"
|
|
|
|
MODULE_BEGIN( ExtendedMoveManager )
|
|
|
|
MODULE_INIT_AFTER( MoveManager )
|
|
MODULE_INIT
|
|
{
|
|
ExtendedMoveManager::init();
|
|
}
|
|
|
|
MODULE_END;
|
|
|
|
S32 ExtendedMoveManager::mPosX[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
S32 ExtendedMoveManager::mPosY[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
S32 ExtendedMoveManager::mPosZ[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
F32 ExtendedMoveManager::mRotAX[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
F32 ExtendedMoveManager::mRotAY[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
F32 ExtendedMoveManager::mRotAZ[ExtendedMove::MaxPositionsRotations] = { 0, };
|
|
F32 ExtendedMoveManager::mRotAA[ExtendedMove::MaxPositionsRotations] = { 1, };
|
|
|
|
void ExtendedMoveManager::init()
|
|
{
|
|
for(U32 i = 0; i < ExtendedMove::MaxPositionsRotations; ++i)
|
|
{
|
|
char varName[256];
|
|
|
|
dSprintf(varName, sizeof(varName), "mvPosX%d", i);
|
|
Con::addVariable(varName, TypeS32, &mPosX[i],
|
|
"X position of controller in millimeters. Only 13 bits are networked.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvPosY%d", i);
|
|
Con::addVariable(varName, TypeS32, &mPosY[i],
|
|
"Y position of controller in millimeters. Only 13 bits are networked.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvPosZ%d", i);
|
|
Con::addVariable(varName, TypeS32, &mPosZ[i],
|
|
"Z position of controller in millimeters. Only 13 bits are networked.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvRotX%d", i);
|
|
Con::addVariable(varName, TypeF32, &mRotAX[i],
|
|
"X rotation vector component of controller.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvRotY%d", i);
|
|
Con::addVariable(varName, TypeF32, &mRotAY[i],
|
|
"Y rotation vector component of controller.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvRotZ%d", i);
|
|
Con::addVariable(varName, TypeF32, &mRotAZ[i],
|
|
"Z rotation vector component of controller.\n"
|
|
"@ingroup Game");
|
|
|
|
dSprintf(varName, sizeof(varName), "mvRotA%d", i);
|
|
Con::addVariable(varName, TypeF32, &mRotAA[i],
|
|
"Angle rotation (in degrees) component of controller.\n"
|
|
"@ingroup Game");
|
|
}
|
|
}
|
|
|
|
const ExtendedMove NullExtendedMove;
|
|
|
|
#define CLAMPPOS(x) (x<0 ? -((-x) & (1<<(MaxPositionBits-1))-1) : (x & (1<<(MaxPositionBits-1))-1))
|
|
#define CLAMPROT(f) ((S32)(((f + 1) * .5) * ((1 << MaxRotationBits) - 1)) & ((1<<MaxRotationBits)-1))
|
|
#define UNCLAMPROT(x) ((F32)(x * 2 / F32((1 << MaxRotationBits) - 1) - 1.0f))
|
|
|
|
ExtendedMove::ExtendedMove() : Move()
|
|
{
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
posX[i] = 0;
|
|
posY[i] = 0;
|
|
posZ[i] = 0;
|
|
rotX[i] = 0;
|
|
rotY[i] = 0;
|
|
rotZ[i] = 0;
|
|
rotW[i] = 1;
|
|
}
|
|
}
|
|
|
|
void ExtendedMove::pack(BitStream *stream, const Move * basemove)
|
|
{
|
|
bool alwaysWriteAll = basemove!=NULL;
|
|
if (!basemove)
|
|
basemove = &NullExtendedMove;
|
|
|
|
// Write the standard Move stuff
|
|
packMove(stream, basemove, alwaysWriteAll);
|
|
|
|
// Extended Move
|
|
const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove);
|
|
|
|
bool extendedDifferent = false;
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
bool check = (posX[i] != extBaseMove->posX[i]) ||
|
|
(posY[i] != extBaseMove->posY[i]) ||
|
|
(posZ[i] != extBaseMove->posZ[i]) ||
|
|
(rotX[i] != extBaseMove->rotX[i]) ||
|
|
(rotY[i] != extBaseMove->rotY[i]) ||
|
|
(rotZ[i] != extBaseMove->rotZ[i]) ||
|
|
(rotW[i] != extBaseMove->rotW[i]);
|
|
|
|
extendedDifferent = extendedDifferent || check;
|
|
}
|
|
|
|
if (alwaysWriteAll || stream->writeFlag(extendedDifferent))
|
|
{
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
// Position
|
|
if(stream->writeFlag(posX[i] != extBaseMove->posX[i]))
|
|
stream->writeSignedInt(posX[i], MaxPositionBits);
|
|
if(stream->writeFlag(posY[i] != extBaseMove->posY[i]))
|
|
stream->writeSignedInt(posY[i], MaxPositionBits);
|
|
if(stream->writeFlag(posZ[i] != extBaseMove->posZ[i]))
|
|
stream->writeSignedInt(posZ[i], MaxPositionBits);
|
|
|
|
// Rotation
|
|
if(stream->writeFlag(rotX[i] != extBaseMove->rotX[i]))
|
|
stream->writeInt(crotX[i], MaxRotationBits);
|
|
if(stream->writeFlag(rotY[i] != extBaseMove->rotY[i]))
|
|
stream->writeInt(crotY[i], MaxRotationBits);
|
|
if(stream->writeFlag(rotZ[i] != extBaseMove->rotZ[i]))
|
|
stream->writeInt(crotZ[i], MaxRotationBits);
|
|
if(stream->writeFlag(rotW[i] != extBaseMove->rotW[i]))
|
|
stream->writeInt(crotW[i], MaxRotationBits);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ExtendedMove::unpack(BitStream *stream, const Move * basemove)
|
|
{
|
|
bool alwaysReadAll = basemove!=NULL;
|
|
if (!basemove)
|
|
basemove=&NullExtendedMove;
|
|
|
|
// Standard Move stuff
|
|
bool isBaseMove = !unpackMove(stream, basemove, alwaysReadAll);
|
|
|
|
// ExtendedMove
|
|
const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove);
|
|
|
|
if (alwaysReadAll || stream->readFlag())
|
|
{
|
|
isBaseMove = false;
|
|
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
// Position
|
|
if(stream->readFlag())
|
|
posX[i] = stream->readSignedInt(MaxPositionBits);
|
|
else
|
|
posX[i] = extBaseMove->posX[i];
|
|
|
|
if(stream->readFlag())
|
|
posY[i] = stream->readSignedInt(MaxPositionBits);
|
|
else
|
|
posY[i] = extBaseMove->posY[i];
|
|
|
|
if(stream->readFlag())
|
|
posZ[i] = stream->readSignedInt(MaxPositionBits);
|
|
else
|
|
posZ[i] = extBaseMove->posZ[i];
|
|
|
|
// Rotation
|
|
if(stream->readFlag())
|
|
{
|
|
crotX[i] = stream->readInt(MaxRotationBits);
|
|
rotX[i] = UNCLAMPROT(crotX[i]);
|
|
}
|
|
else
|
|
{
|
|
rotX[i] = extBaseMove->rotX[i];
|
|
}
|
|
|
|
if(stream->readFlag())
|
|
{
|
|
crotY[i] = stream->readInt(MaxRotationBits);
|
|
rotY[i] = UNCLAMPROT(crotY[i]);
|
|
}
|
|
else
|
|
{
|
|
rotY[i] = extBaseMove->rotY[i];
|
|
}
|
|
|
|
if(stream->readFlag())
|
|
{
|
|
crotZ[i] = stream->readInt(MaxRotationBits);
|
|
rotZ[i] = UNCLAMPROT(crotZ[i]);
|
|
}
|
|
else
|
|
{
|
|
rotZ[i] = extBaseMove->rotZ[i];
|
|
}
|
|
|
|
if(stream->readFlag())
|
|
{
|
|
crotW[i] = stream->readInt(MaxRotationBits);
|
|
rotW[i] = UNCLAMPROT(crotW[i]);
|
|
}
|
|
else
|
|
{
|
|
rotW[i] = extBaseMove->rotW[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(isBaseMove)
|
|
{
|
|
*this = *extBaseMove;
|
|
}
|
|
}
|
|
|
|
void ExtendedMove::clamp()
|
|
{
|
|
// Clamp the values the same as for net traffic so the client matches the server
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
// Positions
|
|
posX[i] = CLAMPPOS(posX[i]);
|
|
posY[i] = CLAMPPOS(posY[i]);
|
|
posZ[i] = CLAMPPOS(posZ[i]);
|
|
|
|
// Rotations
|
|
crotX[i] = CLAMPROT(rotX[i]);
|
|
crotY[i] = CLAMPROT(rotY[i]);
|
|
crotZ[i] = CLAMPROT(rotZ[i]);
|
|
crotW[i] = CLAMPROT(rotW[i]);
|
|
}
|
|
|
|
// Perform the standard Move clamp
|
|
Parent::clamp();
|
|
}
|
|
|
|
void ExtendedMove::unclamp()
|
|
{
|
|
// Unclamp the values the same as for net traffic so the client matches the server
|
|
for(U32 i=0; i<MaxPositionsRotations; ++i)
|
|
{
|
|
// Rotations
|
|
rotX[i] = UNCLAMPROT(crotX[i]);
|
|
rotY[i] = UNCLAMPROT(crotY[i]);
|
|
rotZ[i] = UNCLAMPROT(crotZ[i]);
|
|
rotW[i] = UNCLAMPROT(crotW[i]);
|
|
}
|
|
|
|
// Perform the standard Move unclamp
|
|
Parent::unclamp();
|
|
}
|