extendedMove.cpp
Engine/source/T3D/gameBase/extended/extendedMove.cpp
Public Defines
define
CLAMPPOS(x) (()(((x + 1) * .5) * ((1 << MaxPositionBits) - 1)) & ((1<<MaxPositionBits)-1))
define
CLAMPROT(f) (()(((f + 1) * .5) * ((1 << MaxRotationBits) - 1)) & ((1<<MaxRotationBits)-1))
define
UNCLAMPPOS(x) (()(x * 2 / ((1 << MaxPositionBits) - 1) - 1.0f))
define
UNCLAMPROT(x) (()(x * 2 / ((1 << MaxRotationBits) - 1) - 1.0f))
Public Variables
Detailed Description
Public Defines
CLAMPPOS(x) (()(((x + 1) * .5) * ((1 << MaxPositionBits) - 1)) & ((1<<MaxPositionBits)-1))
CLAMPROT(f) (()(((f + 1) * .5) * ((1 << MaxRotationBits) - 1)) & ((1<<MaxRotationBits)-1))
UNCLAMPPOS(x) (()(x * 2 / ((1 << MaxPositionBits) - 1) - 1.0f))
UNCLAMPROT(x) (()(x * 2 / ((1 << MaxRotationBits) - 1) - 1.0f))
Public Variables
MODULE_END
MODULE_INIT
const ExtendedMove NullExtendedMove
1 2#include "T3D/gameBase/extended/extendedMove.h" 3#include "core/stream/bitStream.h" 4#include "math/mathIO.h" 5#include "math/mAngAxis.h" 6#include "core/module.h" 7#include "console/consoleTypes.h" 8#include "core/strings/stringFunctions.h" 9 10MODULE_BEGIN( ExtendedMoveManager ) 11 12 MODULE_INIT_AFTER( MoveManager ) 13 MODULE_INIT 14 { 15 ExtendedMoveManager::init(); 16 } 17 18MODULE_END; 19 20F32 ExtendedMoveManager::mPosX[ExtendedMove::MaxPositionsRotations] = { 0, }; 21F32 ExtendedMoveManager::mPosY[ExtendedMove::MaxPositionsRotations] = { 0, }; 22F32 ExtendedMoveManager::mPosZ[ExtendedMove::MaxPositionsRotations] = { 0, }; 23bool ExtendedMoveManager::mRotIsEuler[ExtendedMove::MaxPositionsRotations] = { 0, }; 24F32 ExtendedMoveManager::mRotAX[ExtendedMove::MaxPositionsRotations] = { 0, }; 25F32 ExtendedMoveManager::mRotAY[ExtendedMove::MaxPositionsRotations] = { 0, }; 26F32 ExtendedMoveManager::mRotAZ[ExtendedMove::MaxPositionsRotations] = { 0, }; 27F32 ExtendedMoveManager::mRotAA[ExtendedMove::MaxPositionsRotations] = { 1, }; 28 29F32 ExtendedMoveManager::mPosScale = 2.0f; 30 31void ExtendedMoveManager::init() 32{ 33 for(U32 i = 0; i < ExtendedMove::MaxPositionsRotations; ++i) 34 { 35 char varName[256]; 36 37 dSprintf(varName, sizeof(varName), "mvPosX%d", i); 38 Con::addVariable(varName, TypeF32, &mPosX[i], 39 "X position of controller in millimeters. Only 13 bits are networked.\n" 40 "@ingroup Game"); 41 42 dSprintf(varName, sizeof(varName), "mvPosY%d", i); 43 Con::addVariable(varName, TypeF32, &mPosY[i], 44 "Y position of controller in millimeters. Only 13 bits are networked.\n" 45 "@ingroup Game"); 46 47 dSprintf(varName, sizeof(varName), "mvPosZ%d", i); 48 Con::addVariable(varName, TypeF32, &mPosZ[i], 49 "Z position of controller in millimeters. Only 13 bits are networked.\n" 50 "@ingroup Game"); 51 52 dSprintf(varName, sizeof(varName), "mvRotIsEuler%d", i); 53 Con::addVariable(varName, TypeBool, &mRotIsEuler[i], 54 "@brief Indicates that the given rotation is Euler angles.\n\n" 55 "When false (the default) the given rotation is a four component angled axis " 56 "(a vector and angle). When true, the given rotation is a three component " 57 "Euler angle. When using Euler angles, the $mvRotA component of the ExtendedMove " 58 "is ignored for this set of rotations.\n" 59 "@ingroup Game"); 60 61 dSprintf(varName, sizeof(varName), "mvRotX%d", i); 62 Con::addVariable(varName, TypeF32, &mRotAX[i], 63 "X rotation vector component of controller.\n" 64 "@ingroup Game"); 65 66 dSprintf(varName, sizeof(varName), "mvRotY%d", i); 67 Con::addVariable(varName, TypeF32, &mRotAY[i], 68 "Y rotation vector component of controller.\n" 69 "@ingroup Game"); 70 71 dSprintf(varName, sizeof(varName), "mvRotZ%d", i); 72 Con::addVariable(varName, TypeF32, &mRotAZ[i], 73 "Z rotation vector component of controller.\n" 74 "@ingroup Game"); 75 76 dSprintf(varName, sizeof(varName), "mvRotA%d", i); 77 Con::addVariable(varName, TypeF32, &mRotAA[i], 78 "Angle rotation (in degrees) component of controller.\n" 79 "@ingroup Game"); 80 } 81 82 Con::addVariable("mvPosScale", TypeF32, &mPosScale, 83 "@brief Indicates the scale to be given to mvPos values.\n\n" 84 "" 85 "@ingroup Game"); 86} 87 88const ExtendedMove NullExtendedMove; 89 90#define CLAMPPOS(x) ((S32)(((x + 1) * .5) * ((1 << MaxPositionBits) - 1)) & ((1<<MaxPositionBits)-1)) 91#define UNCLAMPPOS(x) ((F32)(x * 2 / F32((1 << MaxPositionBits) - 1) - 1.0f)) 92#define CLAMPROT(f) ((S32)(((f + 1) * .5) * ((1 << MaxRotationBits) - 1)) & ((1<<MaxRotationBits)-1)) 93#define UNCLAMPROT(x) ((F32)(x * 2 / F32((1 << MaxRotationBits) - 1) - 1.0f)) 94 95ExtendedMove::ExtendedMove() : Move() 96{ 97 for(U32 i=0; i<MaxPositionsRotations; ++i) 98 { 99 posX[i] = 0; 100 posY[i] = 0; 101 posZ[i] = 0; 102 rotX[i] = 0; 103 rotY[i] = 0; 104 rotZ[i] = 0; 105 rotW[i] = 1; 106 107 cposX[i] = 0; 108 cposY[i] = 0; 109 cposZ[i] = 0; 110 111 EulerBasedRotation[i] = false; 112 } 113} 114 115void ExtendedMove::pack(BitStream *stream, const Move * basemove) 116{ 117 bool alwaysWriteAll = basemove!=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; 118 if (!basemove) 119 basemove = &NullExtendedMove; 120 121 // Write the standard Move stuff 122 packMove(stream, basemove, alwaysWriteAll); 123 124 // Extended Move 125 const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove); 126 127 bool extendedDifferent = false; 128 for(U32 i=0; i<MaxPositionsRotations; ++i) 129 { 130 bool check = (posX[i] != extBaseMove->posX[i]) || 131 (posY[i] != extBaseMove->posY[i]) || 132 (posZ[i] != extBaseMove->posZ[i]) || 133 (rotX[i] != extBaseMove->rotX[i]) || 134 (rotY[i] != extBaseMove->rotY[i]) || 135 (rotZ[i] != extBaseMove->rotZ[i]); 136 if(!EulerBasedRotation[i]) 137 { 138 check = check || (rotW[i] != extBaseMove->rotW[i]); 139 } 140 141 extendedDifferent = extendedDifferent || check; 142 } 143 144 if (alwaysWriteAll || stream->writeFlag(extendedDifferent)) 145 { 146 for(U32 i=0; i<MaxPositionsRotations; ++i) 147 { 148 // Position 149 if(stream->writeFlag(posX[i] != extBaseMove->posX[i])) 150 stream->writeInt(cposX[i], MaxPositionBits); 151 if(stream->writeFlag(posY[i] != extBaseMove->posY[i])) 152 stream->writeInt(cposY[i], MaxPositionBits); 153 if(stream->writeFlag(posZ[i] != extBaseMove->posZ[i])) 154 stream->writeInt(cposZ[i], MaxPositionBits); 155 156 // Rotation 157 stream->writeFlag(EulerBasedRotation[i]); 158 if(stream->writeFlag(rotX[i] != extBaseMove->rotX[i])) 159 stream->writeInt(crotX[i], EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 160 if(stream->writeFlag(rotY[i] != extBaseMove->rotY[i])) 161 stream->writeInt(crotY[i], EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 162 if(stream->writeFlag(rotZ[i] != extBaseMove->rotZ[i])) 163 stream->writeInt(crotZ[i], EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 164 if(!EulerBasedRotation[i]) 165 { 166 if(stream->writeFlag(rotW[i] != extBaseMove->rotW[i])) 167 stream->writeInt(crotW[i], MaxRotationBits); 168 } 169 } 170 } 171} 172 173void ExtendedMove::unpack(BitStream *stream, const Move * basemove) 174{ 175 bool alwaysReadAll = basemove!=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; 176 if (!basemove) 177 basemove=&<a href="/coding/file/extendedmove_8cpp/#extendedmove_8cpp_1a7bece84e9b668a95cbcdfbbca061f857">NullExtendedMove</a>; 178 179 // Standard Move stuff 180 bool isBaseMove = !unpackMove(stream, basemove, alwaysReadAll); 181 182 // ExtendedMove 183 const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove); 184 185 if (alwaysReadAll || stream->readFlag()) 186 { 187 isBaseMove = false; 188 189 for(U32 i=0; i<MaxPositionsRotations; ++i) 190 { 191 // Position 192 if (stream->readFlag()) 193 { 194 cposX[i] = stream->readInt(MaxPositionBits); 195 posX[i] = UNCLAMPPOS(cposX[i]) * ExtendedMoveManager::mPosScale; 196 } 197 else 198 posX[i] = extBaseMove->posX[i]; 199 200 if (stream->readFlag()) 201 { 202 cposY[i] = stream->readInt(MaxPositionBits); 203 posY[i] = UNCLAMPPOS(cposY[i]) * ExtendedMoveManager::mPosScale; 204 } 205 else 206 posY[i] = extBaseMove->posY[i]; 207 208 if (stream->readFlag()) 209 { 210 cposZ[i] = stream->readInt(MaxPositionBits); 211 posZ[i] = UNCLAMPPOS(cposZ[i]) * ExtendedMoveManager::mPosScale; 212 } 213 else 214 posZ[i] = extBaseMove->posZ[i]; 215 216 // Rotation 217 EulerBasedRotation[i] = stream->readFlag(); 218 F32 scale = 1.0f; 219 if(EulerBasedRotation[i]) 220 scale = M_2PI_F; 221 if(stream->readFlag()) 222 { 223 crotX[i] = stream->readInt(EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 224 rotX[i] = EulerBasedRotation[i] ? (UNCLAMPROT(crotX[i]) * scale) : UNCLAMPPOS(crotX[i]); 225 } 226 else 227 { 228 rotX[i] = extBaseMove->rotX[i]; 229 } 230 231 if(stream->readFlag()) 232 { 233 crotY[i] = stream->readInt(EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 234 rotY[i] = EulerBasedRotation[i] ? (UNCLAMPROT(crotY[i]) * scale) : UNCLAMPPOS(crotY[i]); 235 } 236 else 237 { 238 rotY[i] = extBaseMove->rotY[i]; 239 } 240 241 if(stream->readFlag()) 242 { 243 crotZ[i] = stream->readInt(EulerBasedRotation[i] ? MaxRotationBits : MaxPositionBits); 244 rotZ[i] = EulerBasedRotation[i] ? (UNCLAMPROT(crotZ[i]) * scale) : UNCLAMPPOS(crotZ[i]); 245 } 246 else 247 { 248 rotZ[i] = extBaseMove->rotZ[i]; 249 } 250 251 if(!EulerBasedRotation[i]) 252 { 253 if(stream->readFlag()) 254 { 255 crotW[i] = stream->readInt(MaxRotationBits); 256 rotW[i] = UNCLAMPROT(crotW[i]) * M_2PI_F; 257 } 258 else 259 { 260 rotW[i] = extBaseMove->rotW[i]; 261 } 262 } 263 } 264 } 265 266 if(isBaseMove) 267 { 268 *this = *extBaseMove; 269 } 270} 271 272void ExtendedMove::clamp() 273{ 274 // Clamp the values the same as for net traffic so the client matches the server 275 for(U32 i=0; i<MaxPositionsRotations; ++i) 276 { 277 // Positions 278 cposX[i] = CLAMPPOS(posX[i] / ExtendedMoveManager::mPosScale); 279 cposY[i] = CLAMPPOS(posY[i] / ExtendedMoveManager::mPosScale); 280 cposZ[i] = CLAMPPOS(posZ[i] / ExtendedMoveManager::mPosScale); 281 282 // Rotations 283 if(EulerBasedRotation[i]) 284 { 285 crotX[i] = CLAMPROT(rotX[i] / M_2PI_F); 286 crotY[i] = CLAMPROT(rotY[i] / M_2PI_F); 287 crotZ[i] = CLAMPROT(rotZ[i] / M_2PI_F); 288 } 289 else 290 { 291 crotX[i] = CLAMPPOS(rotX[i]); 292 crotY[i] = CLAMPPOS(rotY[i]); 293 crotZ[i] = CLAMPPOS(rotZ[i]); 294 crotW[i] = CLAMPROT(rotW[i] / M_2PI_F); 295 } 296 297 #ifdef DEBUG_CONTROLLER_MOVE 298 if (i == 1) 299 { 300 F32 x, y, z, a; 301 x = UNCLAMPPOS(crotX[i]); 302 y = UNCLAMPPOS(crotY[i]); 303 z = UNCLAMPPOS(crotZ[i]); 304 a = UNCLAMPROT(crotW[i]) * M_2PI_F; 305 306 Con::printf("INPUT POS == %f,%f,%f", ExtendedMoveManager::mPosX[i], ExtendedMoveManager::mPosY[i], ExtendedMoveManager::mPosZ[i]); 307 Con::printf("rot %f,%f,%f,%f clamped to %f,%f,%f,%f", rotX[i], rotY[i], rotZ[i], rotW[i], x,y,z,a); 308 x = UNCLAMPPOS(cposX[i]) * ExtendedMoveManager::mPosScale; 309 y = UNCLAMPPOS(cposX[i]) * ExtendedMoveManager::mPosScale; 310 z = UNCLAMPPOS(cposX[i]) * ExtendedMoveManager::mPosScale; 311 Con::printf("pos %f,%f,%f clamped to %f,%f,%f", posX[i], posY[i], posZ[i], x, y, z); 312 } 313 #endif 314 } 315 316 // Perform the standard Move clamp 317 Parent::clamp(); 318} 319 320void ExtendedMove::unclamp() 321{ 322 // Unclamp the values the same as for net traffic so the client matches the server 323 for(U32 i=0; i<MaxPositionsRotations; ++i) 324 { 325 posX[i] = UNCLAMPPOS(cposX[i]) * ExtendedMoveManager::mPosScale; 326 posY[i] = UNCLAMPPOS(cposY[i]) * ExtendedMoveManager::mPosScale; 327 posZ[i] = UNCLAMPPOS(cposZ[i]) * ExtendedMoveManager::mPosScale; 328 329 // Rotations 330 if(EulerBasedRotation[i]) 331 { 332 rotX[i] = UNCLAMPROT(crotX[i]) * M_2PI_F; 333 rotY[i] = UNCLAMPROT(crotY[i]) * M_2PI_F; 334 rotZ[i] = UNCLAMPROT(crotZ[i]) * M_2PI_F; 335 } 336 else 337 { 338 rotX[i] = UNCLAMPPOS(crotX[i]); 339 rotY[i] = UNCLAMPPOS(crotY[i]); 340 rotZ[i] = UNCLAMPPOS(crotZ[i]); 341 rotW[i] = UNCLAMPROT(crotW[i]) * M_2PI_F; 342 } 343 } 344 345 // Perform the standard Move unclamp 346 Parent::unclamp(); 347} 348