mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
326 lines
10 KiB
C++
326 lines
10 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "T3D/gameBase/moveManager.h"
|
|
#include "core/stream/bitStream.h"
|
|
#include "core/module.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "core/strings/stringFunctions.h"
|
|
#include "math/mConstants.h"
|
|
|
|
|
|
MODULE_BEGIN( MoveManager )
|
|
|
|
MODULE_INIT
|
|
{
|
|
MoveManager::init();
|
|
}
|
|
|
|
MODULE_END;
|
|
|
|
|
|
bool MoveManager::mDeviceIsKeyboardMouse = false;
|
|
F32 MoveManager::mForwardAction = 0;
|
|
F32 MoveManager::mBackwardAction = 0;
|
|
F32 MoveManager::mUpAction = 0;
|
|
F32 MoveManager::mDownAction = 0;
|
|
F32 MoveManager::mLeftAction = 0;
|
|
F32 MoveManager::mRightAction = 0;
|
|
|
|
bool MoveManager::mFreeLook = false;
|
|
F32 MoveManager::mPitch = 0;
|
|
F32 MoveManager::mYaw = 0;
|
|
F32 MoveManager::mRoll = 0;
|
|
|
|
F32 MoveManager::mPitchUpSpeed = 0;
|
|
F32 MoveManager::mPitchDownSpeed = 0;
|
|
F32 MoveManager::mYawLeftSpeed = 0;
|
|
F32 MoveManager::mYawRightSpeed = 0;
|
|
F32 MoveManager::mRollLeftSpeed = 0;
|
|
F32 MoveManager::mRollRightSpeed = 0;
|
|
|
|
F32 MoveManager::mXAxis_L = 0;
|
|
F32 MoveManager::mYAxis_L = 0;
|
|
F32 MoveManager::mXAxis_R = 0;
|
|
F32 MoveManager::mYAxis_R = 0;
|
|
|
|
U32 MoveManager::mTriggerCount[MaxTriggerKeys] = { 0, };
|
|
U32 MoveManager::mPrevTriggerCount[MaxTriggerKeys] = { 0, };
|
|
|
|
const Move NullMove;
|
|
|
|
void MoveManager::init()
|
|
{
|
|
Con::addVariable("mvForwardAction", TypeF32, &mForwardAction,
|
|
"Forwards movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvBackwardAction", TypeF32, &mBackwardAction,
|
|
"Backwards movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvUpAction", TypeF32, &mUpAction,
|
|
"Upwards movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvDownAction", TypeF32, &mDownAction,
|
|
"Downwards movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvLeftAction", TypeF32, &mLeftAction,
|
|
"Left movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvRightAction", TypeF32, &mRightAction,
|
|
"Right movement speed for the active player.\n"
|
|
"@ingroup Game");
|
|
|
|
Con::addVariable("mvFreeLook", TypeBool, &mFreeLook,
|
|
"Boolean state for if freelook is active or not.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvDeviceIsKeyboardMouse", TypeBool, &mDeviceIsKeyboardMouse,
|
|
"Boolean state for it the system is using a keyboard and mouse or not.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvPitch", TypeF32, &mPitch,
|
|
"Current pitch value, typically applied through input devices, such as a mouse.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvYaw", TypeF32, &mYaw,
|
|
"Current yaw value, typically applied through input devices, such as a mouse.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvRoll", TypeF32, &mRoll,
|
|
"Current roll value, typically applied through input devices, such as a mouse.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvPitchUpSpeed", TypeF32, &mPitchUpSpeed,
|
|
"Upwards pitch speed.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvPitchDownSpeed", TypeF32, &mPitchDownSpeed,
|
|
"Downwards pitch speed.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvYawLeftSpeed", TypeF32, &mYawLeftSpeed,
|
|
"Left Yaw speed.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvYawRightSpeed", TypeF32, &mYawRightSpeed,
|
|
"Right Yaw speed.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvRollLeftSpeed", TypeF32, &mRollLeftSpeed,
|
|
"Left roll speed.\n"
|
|
"@ingroup Game");
|
|
Con::addVariable("mvRollRightSpeed", TypeF32, &mRollRightSpeed,
|
|
"Right roll speed.\n"
|
|
"@ingroup Game");
|
|
|
|
// Dual-analog
|
|
Con::addVariable( "mvXAxis_L", TypeF32, &mXAxis_L,
|
|
"Left thumbstick X axis position on a dual-analog gamepad.\n"
|
|
"@ingroup Game" );
|
|
Con::addVariable( "mvYAxis_L", TypeF32, &mYAxis_L,
|
|
"Left thumbstick Y axis position on a dual-analog gamepad.\n"
|
|
"@ingroup Game" );
|
|
|
|
Con::addVariable( "mvXAxis_R", TypeF32, &mXAxis_R,
|
|
"Right thumbstick X axis position on a dual-analog gamepad.\n"
|
|
"@ingroup Game" );
|
|
Con::addVariable( "mvYAxis_R", TypeF32, &mYAxis_R,
|
|
"Right thumbstick Y axis position on a dual-analog gamepad.\n"
|
|
"@ingroup Game");
|
|
|
|
for(U32 i = 0; i < MaxTriggerKeys; i++)
|
|
{
|
|
char varName[256];
|
|
dSprintf(varName, sizeof(varName), "mvTriggerCount%d", i);
|
|
Con::addVariable(varName, TypeS32, &mTriggerCount[i],
|
|
"Used to determine the trigger counts of buttons. Namely used for input actions such as jumping and weapons firing.\n"
|
|
"@ingroup Game");
|
|
}
|
|
}
|
|
|
|
Move::Move()
|
|
{
|
|
px=16; py=16; pz=16;
|
|
pyaw=0; ppitch=0; proll=0;
|
|
x=0; y=0; z=0;
|
|
yaw=0; pitch=0; roll=0;
|
|
id=0;
|
|
sendCount=0;
|
|
|
|
checksum = false;
|
|
deviceIsKeyboardMouse = false;
|
|
freeLook = false;
|
|
for (S32 i = 0; i< MaxTriggerKeys; i++)
|
|
trigger[i] = false;
|
|
}
|
|
|
|
static inline F32 clampFloatWrap(F32 val)
|
|
{
|
|
return val - F32(S32(val));
|
|
}
|
|
|
|
static inline S32 clampRangeClamp(F32 val)
|
|
{
|
|
if(val < -1)
|
|
return 0;
|
|
if(val > 1)
|
|
return 32;
|
|
|
|
// 0.5 / 16 = 0.03125 ... this forces a round up to
|
|
// make the precision near zero equal in the negative
|
|
// and positive directions. See...
|
|
//
|
|
// http://www.garagegames.com/community/forums/viewthread/49714
|
|
|
|
return (S32)((val + 1.03125) * 16);
|
|
}
|
|
|
|
|
|
#define FANG2IANG(x) ((U32)((S16)((F32(0x10000) / M_2PI) * x)) & 0xFFFF)
|
|
#define IANG2FANG(x) (F32)((M_2PI / F32(0x10000)) * (F32)((S16)x))
|
|
|
|
void Move::unclamp()
|
|
{
|
|
yaw = IANG2FANG(pyaw);
|
|
pitch = IANG2FANG(ppitch);
|
|
roll = IANG2FANG(proll);
|
|
|
|
x = (px - 16) / F32(16);
|
|
y = (py - 16) / F32(16);
|
|
z = (pz - 16) / F32(16);
|
|
}
|
|
|
|
static inline F32 clampAngleClamp( F32 angle )
|
|
{
|
|
const F32 limit = ( M_PI_F / 180.0f ) * 179.999f;
|
|
if ( angle < -limit )
|
|
return -limit;
|
|
if ( angle > limit )
|
|
return limit;
|
|
|
|
return angle;
|
|
}
|
|
|
|
void Move::clamp()
|
|
{
|
|
// If yaw/pitch/roll goes equal or greater than -PI/+PI it
|
|
// flips the direction of the rotation... we protect against
|
|
// that by clamping before the conversion.
|
|
|
|
yaw = clampAngleClamp( yaw );
|
|
pitch = clampAngleClamp( pitch );
|
|
roll = clampAngleClamp( roll );
|
|
|
|
// angles are all 16 bit.
|
|
pyaw = FANG2IANG(yaw);
|
|
ppitch = FANG2IANG(pitch);
|
|
proll = FANG2IANG(roll);
|
|
|
|
px = clampRangeClamp(x);
|
|
py = clampRangeClamp(y);
|
|
pz = clampRangeClamp(z);
|
|
unclamp();
|
|
}
|
|
|
|
void Move::pack(BitStream *stream, const Move * basemove)
|
|
{
|
|
bool alwaysWriteAll = basemove!=NULL;
|
|
if (!basemove)
|
|
basemove = &NullMove;
|
|
|
|
packMove(stream, basemove, alwaysWriteAll);
|
|
}
|
|
|
|
bool Move::packMove(BitStream *stream, const Move* basemove, bool alwaysWriteAll)
|
|
{
|
|
S32 i;
|
|
bool triggerDifferent = false;
|
|
for (i=0; i < MaxTriggerKeys; i++)
|
|
if (trigger[i] != basemove->trigger[i])
|
|
triggerDifferent = true;
|
|
bool somethingDifferent = (pyaw!=basemove->pyaw) ||
|
|
(ppitch!=basemove->ppitch) ||
|
|
(proll!=basemove->proll) ||
|
|
(px!=basemove->px) ||
|
|
(py!=basemove->py) ||
|
|
(pz!=basemove->pz) ||
|
|
(deviceIsKeyboardMouse!=basemove->deviceIsKeyboardMouse) ||
|
|
(freeLook!=basemove->freeLook) ||
|
|
triggerDifferent;
|
|
|
|
if (alwaysWriteAll || stream->writeFlag(somethingDifferent))
|
|
{
|
|
if(stream->writeFlag(pyaw != basemove->pyaw))
|
|
stream->writeInt(pyaw, 16);
|
|
if(stream->writeFlag(ppitch != basemove->ppitch))
|
|
stream->writeInt(ppitch, 16);
|
|
if(stream->writeFlag(proll != basemove->proll))
|
|
stream->writeInt(proll, 16);
|
|
|
|
if (stream->writeFlag(px != basemove->px))
|
|
stream->writeInt(px, 6);
|
|
if (stream->writeFlag(py != basemove->py))
|
|
stream->writeInt(py, 6);
|
|
if (stream->writeFlag(pz != basemove->pz))
|
|
stream->writeInt(pz, 6);
|
|
stream->writeFlag(freeLook);
|
|
stream->writeFlag(deviceIsKeyboardMouse);
|
|
|
|
if (stream->writeFlag(triggerDifferent))
|
|
for(i = 0; i < MaxTriggerKeys; i++)
|
|
stream->writeFlag(trigger[i]);
|
|
}
|
|
|
|
return (triggerDifferent || somethingDifferent);
|
|
}
|
|
|
|
void Move::unpack(BitStream *stream, const Move * basemove)
|
|
{
|
|
bool alwaysReadAll = basemove!=NULL;
|
|
if (!basemove)
|
|
basemove=&NullMove;
|
|
|
|
bool readMove = unpackMove(stream, basemove, alwaysReadAll);
|
|
if(!readMove)
|
|
*this = *basemove;
|
|
}
|
|
|
|
bool Move::unpackMove(BitStream *stream, const Move* basemove, bool alwaysReadAll)
|
|
{
|
|
bool readMove = alwaysReadAll;
|
|
if(!readMove)
|
|
{
|
|
readMove = stream->readFlag();
|
|
}
|
|
|
|
if (readMove)
|
|
{
|
|
pyaw = stream->readFlag() ? stream->readInt(16) : basemove->pyaw;
|
|
ppitch = stream->readFlag() ? stream->readInt(16) : basemove->ppitch;
|
|
proll = stream->readFlag() ? stream->readInt(16) : basemove->proll;
|
|
|
|
px = stream->readFlag() ? stream->readInt(6) : basemove->px;
|
|
py = stream->readFlag() ? stream->readInt(6) : basemove->py;
|
|
pz = stream->readFlag() ? stream->readInt(6) : basemove->pz;
|
|
freeLook = stream->readFlag();
|
|
deviceIsKeyboardMouse = stream->readFlag();
|
|
|
|
bool triggersDiffer = stream->readFlag();
|
|
for (S32 i = 0; i< MaxTriggerKeys; i++)
|
|
trigger[i] = triggersDiffer ? stream->readFlag() : basemove->trigger[i];
|
|
unclamp();
|
|
}
|
|
|
|
return readMove;
|
|
}
|