moveManager.cpp
Engine/source/T3D/gameBase/moveManager.cpp
Public Defines
Public Variables
Public Functions
Detailed Description
Public Defines
FANG2IANG(x) (()(()(((0x10000) / ) * x)) & 0xFFFF)
IANG2FANG(x) ()(( / (0x10000)) * ()(()x))
Public Variables
MODULE_END
MODULE_INIT
const Move NullMove
Public Functions
clampAngleClamp(F32 angle)
clampFloatWrap(F32 val)
clampRangeClamp(F32 val)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "T3D/gameBase/moveManager.h" 25#include "core/stream/bitStream.h" 26#include "core/module.h" 27#include "console/consoleTypes.h" 28#include "core/strings/stringFunctions.h" 29#include "math/mConstants.h" 30 31 32MODULE_BEGIN( MoveManager ) 33 34 MODULE_INIT 35 { 36 MoveManager::init(); 37 } 38 39MODULE_END; 40 41 42bool MoveManager::mDeviceIsKeyboardMouse = false; 43F32 MoveManager::mForwardAction = 0; 44F32 MoveManager::mBackwardAction = 0; 45F32 MoveManager::mUpAction = 0; 46F32 MoveManager::mDownAction = 0; 47F32 MoveManager::mLeftAction = 0; 48F32 MoveManager::mRightAction = 0; 49 50bool MoveManager::mFreeLook = false; 51F32 MoveManager::mPitch = 0; 52F32 MoveManager::mYaw = 0; 53F32 MoveManager::mRoll = 0; 54 55F32 MoveManager::mPitchUpSpeed = 0; 56F32 MoveManager::mPitchDownSpeed = 0; 57F32 MoveManager::mYawLeftSpeed = 0; 58F32 MoveManager::mYawRightSpeed = 0; 59F32 MoveManager::mRollLeftSpeed = 0; 60F32 MoveManager::mRollRightSpeed = 0; 61 62F32 MoveManager::mXAxis_L = 0; 63F32 MoveManager::mYAxis_L = 0; 64F32 MoveManager::mXAxis_R = 0; 65F32 MoveManager::mYAxis_R = 0; 66 67U32 MoveManager::mTriggerCount[MaxTriggerKeys] = { 0, }; 68U32 MoveManager::mPrevTriggerCount[MaxTriggerKeys] = { 0, }; 69 70const Move NullMove; 71 72void MoveManager::init() 73{ 74 Con::addVariable("mvForwardAction", TypeF32, &mForwardAction, 75 "Forwards movement speed for the active player.\n" 76 "@ingroup Game"); 77 Con::addVariable("mvBackwardAction", TypeF32, &mBackwardAction, 78 "Backwards movement speed for the active player.\n" 79 "@ingroup Game"); 80 Con::addVariable("mvUpAction", TypeF32, &mUpAction, 81 "Upwards movement speed for the active player.\n" 82 "@ingroup Game"); 83 Con::addVariable("mvDownAction", TypeF32, &mDownAction, 84 "Downwards movement speed for the active player.\n" 85 "@ingroup Game"); 86 Con::addVariable("mvLeftAction", TypeF32, &mLeftAction, 87 "Left movement speed for the active player.\n" 88 "@ingroup Game"); 89 Con::addVariable("mvRightAction", TypeF32, &mRightAction, 90 "Right movement speed for the active player.\n" 91 "@ingroup Game"); 92 93 Con::addVariable("mvFreeLook", TypeBool, &mFreeLook, 94 "Boolean state for if freelook is active or not.\n" 95 "@ingroup Game"); 96 Con::addVariable("mvDeviceIsKeyboardMouse", TypeBool, &mDeviceIsKeyboardMouse, 97 "Boolean state for it the system is using a keyboard and mouse or not.\n" 98 "@ingroup Game"); 99 Con::addVariable("mvPitch", TypeF32, &mPitch, 100 "Current pitch value, typically applied through input devices, such as a mouse.\n" 101 "@ingroup Game"); 102 Con::addVariable("mvYaw", TypeF32, &mYaw, 103 "Current yaw value, typically applied through input devices, such as a mouse.\n" 104 "@ingroup Game"); 105 Con::addVariable("mvRoll", TypeF32, &mRoll, 106 "Current roll value, typically applied through input devices, such as a mouse.\n" 107 "@ingroup Game"); 108 Con::addVariable("mvPitchUpSpeed", TypeF32, &mPitchUpSpeed, 109 "Upwards pitch speed.\n" 110 "@ingroup Game"); 111 Con::addVariable("mvPitchDownSpeed", TypeF32, &mPitchDownSpeed, 112 "Downwards pitch speed.\n" 113 "@ingroup Game"); 114 Con::addVariable("mvYawLeftSpeed", TypeF32, &mYawLeftSpeed, 115 "Left Yaw speed.\n" 116 "@ingroup Game"); 117 Con::addVariable("mvYawRightSpeed", TypeF32, &mYawRightSpeed, 118 "Right Yaw speed.\n" 119 "@ingroup Game"); 120 Con::addVariable("mvRollLeftSpeed", TypeF32, &mRollLeftSpeed, 121 "Left roll speed.\n" 122 "@ingroup Game"); 123 Con::addVariable("mvRollRightSpeed", TypeF32, &mRollRightSpeed, 124 "Right roll speed.\n" 125 "@ingroup Game"); 126 127 // Dual-analog 128 Con::addVariable( "mvXAxis_L", TypeF32, &mXAxis_L, 129 "Left thumbstick X axis position on a dual-analog gamepad.\n" 130 "@ingroup Game" ); 131 Con::addVariable( "mvYAxis_L", TypeF32, &mYAxis_L, 132 "Left thumbstick Y axis position on a dual-analog gamepad.\n" 133 "@ingroup Game" ); 134 135 Con::addVariable( "mvXAxis_R", TypeF32, &mXAxis_R, 136 "Right thumbstick X axis position on a dual-analog gamepad.\n" 137 "@ingroup Game" ); 138 Con::addVariable( "mvYAxis_R", TypeF32, &mYAxis_R, 139 "Right thumbstick Y axis position on a dual-analog gamepad.\n" 140 "@ingroup Game"); 141 142 for(U32 i = 0; i < MaxTriggerKeys; i++) 143 { 144 char varName[256]; 145 dSprintf(varName, sizeof(varName), "mvTriggerCount%d", i); 146 Con::addVariable(varName, TypeS32, &mTriggerCount[i], 147 "Used to determine the trigger counts of buttons. Namely used for input actions such as jumping and weapons firing.\n" 148 "@ingroup Game"); 149 } 150} 151 152Move::Move() 153{ 154 px=16; py=16; pz=16; 155 pyaw=0; ppitch=0; proll=0; 156 x=0; y=0; z=0; 157 yaw=0; pitch=0; roll=0; 158 id=0; 159 sendCount=0; 160 161 checksum = false; 162 deviceIsKeyboardMouse = false; 163 freeLook = false; 164 for (S32 i = 0; i< MaxTriggerKeys; i++) 165 trigger[i] = false; 166} 167 168static inline F32 clampFloatWrap(F32 val) 169{ 170 return val - F32(S32(val)); 171} 172 173static inline S32 clampRangeClamp(F32 val) 174{ 175 if(val < -1) 176 return 0; 177 if(val > 1) 178 return 32; 179 180 // 0.5 / 16 = 0.03125 ... this forces a round up to 181 // make the precision near zero equal in the negative 182 // and positive directions. See... 183 // 184 // http://www.garagegames.com/community/forums/viewthread/49714 185 186 return (S32)((val + 1.03125) * 16); 187} 188 189 190#define FANG2IANG(x) ((U32)((S16)((F32(0x10000) / M_2PI) * x)) & 0xFFFF) 191#define IANG2FANG(x) (F32)((M_2PI / F32(0x10000)) * (F32)((S16)x)) 192 193void Move::unclamp() 194{ 195 yaw = IANG2FANG(pyaw); 196 pitch = IANG2FANG(ppitch); 197 roll = IANG2FANG(proll); 198 199 x = (px - 16) / F32(16); 200 y = (py - 16) / F32(16); 201 z = (pz - 16) / F32(16); 202} 203 204static inline F32 clampAngleClamp( F32 angle ) 205{ 206 const F32 limit = ( M_PI_F / 180.0f ) * 179.999f; 207 if ( angle < -limit ) 208 return -limit; 209 if ( angle > limit ) 210 return limit; 211 212 return angle; 213} 214 215void Move::clamp() 216{ 217 // If yaw/pitch/roll goes equal or greater than -PI/+PI it 218 // flips the direction of the rotation... we protect against 219 // that by clamping before the conversion. 220 221 yaw = clampAngleClamp( yaw ); 222 pitch = clampAngleClamp( pitch ); 223 roll = clampAngleClamp( roll ); 224 225 // angles are all 16 bit. 226 pyaw = FANG2IANG(yaw); 227 ppitch = FANG2IANG(pitch); 228 proll = FANG2IANG(roll); 229 230 px = clampRangeClamp(x); 231 py = clampRangeClamp(y); 232 pz = clampRangeClamp(z); 233 unclamp(); 234} 235 236void Move::pack(BitStream *stream, const Move * basemove) 237{ 238 bool alwaysWriteAll = basemove!=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; 239 if (!basemove) 240 basemove = &NullMove; 241 242 packMove(stream, basemove, alwaysWriteAll); 243} 244 245bool Move::packMove(BitStream *stream, const Move* basemove, bool alwaysWriteAll) 246{ 247 S32 i; 248 bool triggerDifferent = false; 249 for (i=0; i < MaxTriggerKeys; i++) 250 if (trigger[i] != basemove->trigger[i]) 251 triggerDifferent = true; 252 bool somethingDifferent = (pyaw!=basemove->pyaw) || 253 (ppitch!=basemove->ppitch) || 254 (proll!=basemove->proll) || 255 (px!=basemove->px) || 256 (py!=basemove->py) || 257 (pz!=basemove->pz) || 258 (deviceIsKeyboardMouse!=basemove->deviceIsKeyboardMouse) || 259 (freeLook!=basemove->freeLook) || 260 triggerDifferent; 261 262 if (alwaysWriteAll || stream->writeFlag(somethingDifferent)) 263 { 264 if(stream->writeFlag(pyaw != basemove->pyaw)) 265 stream->writeInt(pyaw, 16); 266 if(stream->writeFlag(ppitch != basemove->ppitch)) 267 stream->writeInt(ppitch, 16); 268 if(stream->writeFlag(proll != basemove->proll)) 269 stream->writeInt(proll, 16); 270 271 if (stream->writeFlag(px != basemove->px)) 272 stream->writeInt(px, 6); 273 if (stream->writeFlag(py != basemove->py)) 274 stream->writeInt(py, 6); 275 if (stream->writeFlag(pz != basemove->pz)) 276 stream->writeInt(pz, 6); 277 stream->writeFlag(freeLook); 278 stream->writeFlag(deviceIsKeyboardMouse); 279 280 if (stream->writeFlag(triggerDifferent)) 281 for(i = 0; i < MaxTriggerKeys; i++) 282 stream->writeFlag(trigger[i]); 283 } 284 285 return (triggerDifferent || somethingDifferent); 286} 287 288void Move::unpack(BitStream *stream, const Move * basemove) 289{ 290 bool alwaysReadAll = basemove!=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; 291 if (!basemove) 292 basemove=&<a href="/coding/file/movemanager_8cpp/#movemanager_8cpp_1af8b72304f40d7b276a7433bb2a9645d7">NullMove</a>; 293 294 bool readMove = unpackMove(stream, basemove, alwaysReadAll); 295 if(!readMove) 296 *this = *basemove; 297} 298 299bool Move::unpackMove(BitStream *stream, const Move* basemove, bool alwaysReadAll) 300{ 301 bool readMove = alwaysReadAll; 302 if(!readMove) 303 { 304 readMove = stream->readFlag(); 305 } 306 307 if (readMove) 308 { 309 pyaw = stream->readFlag() ? stream->readInt(16) : basemove->pyaw; 310 ppitch = stream->readFlag() ? stream->readInt(16) : basemove->ppitch; 311 proll = stream->readFlag() ? stream->readInt(16) : basemove->proll; 312 313 px = stream->readFlag() ? stream->readInt(6) : basemove->px; 314 py = stream->readFlag() ? stream->readInt(6) : basemove->py; 315 pz = stream->readFlag() ? stream->readInt(6) : basemove->pz; 316 freeLook = stream->readFlag(); 317 deviceIsKeyboardMouse = stream->readFlag(); 318 319 bool triggersDiffer = stream->readFlag(); 320 for (S32 i = 0; i< MaxTriggerKeys; i++) 321 trigger[i] = triggersDiffer ? stream->readFlag() : basemove->trigger[i]; 322 unclamp(); 323 } 324 325 return readMove; 326} 327