extendedMove.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "T3D/gameBase/extended/extendedMove.h"
  2. #include "core/stream/bitStream.h"
  3. #include "math/mathIO.h"
  4. #include "math/mAngAxis.h"
  5. #include "core/module.h"
  6. #include "console/consoleTypes.h"
  7. #include "core/strings/stringFunctions.h"
  8. MODULE_BEGIN( ExtendedMoveManager )
  9. MODULE_INIT_AFTER( MoveManager )
  10. MODULE_INIT
  11. {
  12. ExtendedMoveManager::init();
  13. }
  14. MODULE_END;
  15. S32 ExtendedMoveManager::mPosX[ExtendedMove::MaxPositionsRotations] = { 0, };
  16. S32 ExtendedMoveManager::mPosY[ExtendedMove::MaxPositionsRotations] = { 0, };
  17. S32 ExtendedMoveManager::mPosZ[ExtendedMove::MaxPositionsRotations] = { 0, };
  18. bool ExtendedMoveManager::mRotIsEuler[ExtendedMove::MaxPositionsRotations] = { 0, };
  19. F32 ExtendedMoveManager::mRotAX[ExtendedMove::MaxPositionsRotations] = { 0, };
  20. F32 ExtendedMoveManager::mRotAY[ExtendedMove::MaxPositionsRotations] = { 0, };
  21. F32 ExtendedMoveManager::mRotAZ[ExtendedMove::MaxPositionsRotations] = { 0, };
  22. F32 ExtendedMoveManager::mRotAA[ExtendedMove::MaxPositionsRotations] = { 1, };
  23. void ExtendedMoveManager::init()
  24. {
  25. for(U32 i = 0; i < ExtendedMove::MaxPositionsRotations; ++i)
  26. {
  27. char varName[256];
  28. dSprintf(varName, sizeof(varName), "mvPosX%d", i);
  29. Con::addVariable(varName, TypeS32, &mPosX[i],
  30. "X position of controller in millimeters. Only 13 bits are networked.\n"
  31. "@ingroup Game");
  32. dSprintf(varName, sizeof(varName), "mvPosY%d", i);
  33. Con::addVariable(varName, TypeS32, &mPosY[i],
  34. "Y position of controller in millimeters. Only 13 bits are networked.\n"
  35. "@ingroup Game");
  36. dSprintf(varName, sizeof(varName), "mvPosZ%d", i);
  37. Con::addVariable(varName, TypeS32, &mPosZ[i],
  38. "Z position of controller in millimeters. Only 13 bits are networked.\n"
  39. "@ingroup Game");
  40. dSprintf(varName, sizeof(varName), "mvRotIsEuler%d", i);
  41. Con::addVariable(varName, TypeBool, &mRotIsEuler[i],
  42. "@brief Indicates that the given rotation is Euler angles.\n\n"
  43. "When false (the default) the given rotation is a four component angled axis "
  44. "(a vector and angle). When true, the given rotation is a three component "
  45. "Euler angle. When using Euler angles, the $mvRotA component of the ExtendedMove "
  46. "is ignored for this set of rotations.\n"
  47. "@ingroup Game");
  48. dSprintf(varName, sizeof(varName), "mvRotX%d", i);
  49. Con::addVariable(varName, TypeF32, &mRotAX[i],
  50. "X rotation vector component of controller.\n"
  51. "@ingroup Game");
  52. dSprintf(varName, sizeof(varName), "mvRotY%d", i);
  53. Con::addVariable(varName, TypeF32, &mRotAY[i],
  54. "Y rotation vector component of controller.\n"
  55. "@ingroup Game");
  56. dSprintf(varName, sizeof(varName), "mvRotZ%d", i);
  57. Con::addVariable(varName, TypeF32, &mRotAZ[i],
  58. "Z rotation vector component of controller.\n"
  59. "@ingroup Game");
  60. dSprintf(varName, sizeof(varName), "mvRotA%d", i);
  61. Con::addVariable(varName, TypeF32, &mRotAA[i],
  62. "Angle rotation (in degrees) component of controller.\n"
  63. "@ingroup Game");
  64. }
  65. }
  66. const ExtendedMove NullExtendedMove;
  67. #define CLAMPPOS(x) (x<0 ? -((-x) & (1<<(MaxPositionBits-1))-1) : (x & (1<<(MaxPositionBits-1))-1))
  68. #define CLAMPROT(f) ((S32)(((f + 1) * .5) * ((1 << MaxRotationBits) - 1)) & ((1<<MaxRotationBits)-1))
  69. #define UNCLAMPROT(x) ((F32)(x * 2 / F32((1 << MaxRotationBits) - 1) - 1.0f))
  70. ExtendedMove::ExtendedMove() : Move()
  71. {
  72. for(U32 i=0; i<MaxPositionsRotations; ++i)
  73. {
  74. posX[i] = 0;
  75. posY[i] = 0;
  76. posZ[i] = 0;
  77. rotX[i] = 0;
  78. rotY[i] = 0;
  79. rotZ[i] = 0;
  80. rotW[i] = 1;
  81. EulerBasedRotation[i] = false;
  82. }
  83. }
  84. void ExtendedMove::pack(BitStream *stream, const Move * basemove)
  85. {
  86. bool alwaysWriteAll = basemove!=NULL;
  87. if (!basemove)
  88. basemove = &NullExtendedMove;
  89. // Write the standard Move stuff
  90. packMove(stream, basemove, alwaysWriteAll);
  91. // Extended Move
  92. const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove);
  93. bool extendedDifferent = false;
  94. for(U32 i=0; i<MaxPositionsRotations; ++i)
  95. {
  96. bool check = (posX[i] != extBaseMove->posX[i]) ||
  97. (posY[i] != extBaseMove->posY[i]) ||
  98. (posZ[i] != extBaseMove->posZ[i]) ||
  99. (rotX[i] != extBaseMove->rotX[i]) ||
  100. (rotY[i] != extBaseMove->rotY[i]) ||
  101. (rotZ[i] != extBaseMove->rotZ[i]);
  102. if(!EulerBasedRotation[i])
  103. {
  104. check = check || (rotW[i] != extBaseMove->rotW[i]);
  105. }
  106. extendedDifferent = extendedDifferent || check;
  107. }
  108. if (alwaysWriteAll || stream->writeFlag(extendedDifferent))
  109. {
  110. for(U32 i=0; i<MaxPositionsRotations; ++i)
  111. {
  112. // Position
  113. if(stream->writeFlag(posX[i] != extBaseMove->posX[i]))
  114. stream->writeSignedInt(posX[i], MaxPositionBits);
  115. if(stream->writeFlag(posY[i] != extBaseMove->posY[i]))
  116. stream->writeSignedInt(posY[i], MaxPositionBits);
  117. if(stream->writeFlag(posZ[i] != extBaseMove->posZ[i]))
  118. stream->writeSignedInt(posZ[i], MaxPositionBits);
  119. // Rotation
  120. stream->writeFlag(EulerBasedRotation[i]);
  121. if(stream->writeFlag(rotX[i] != extBaseMove->rotX[i]))
  122. stream->writeInt(crotX[i], MaxRotationBits);
  123. if(stream->writeFlag(rotY[i] != extBaseMove->rotY[i]))
  124. stream->writeInt(crotY[i], MaxRotationBits);
  125. if(stream->writeFlag(rotZ[i] != extBaseMove->rotZ[i]))
  126. stream->writeInt(crotZ[i], MaxRotationBits);
  127. if(!EulerBasedRotation[i])
  128. {
  129. if(stream->writeFlag(rotW[i] != extBaseMove->rotW[i]))
  130. stream->writeInt(crotW[i], MaxRotationBits);
  131. }
  132. }
  133. }
  134. }
  135. void ExtendedMove::unpack(BitStream *stream, const Move * basemove)
  136. {
  137. bool alwaysReadAll = basemove!=NULL;
  138. if (!basemove)
  139. basemove=&NullExtendedMove;
  140. // Standard Move stuff
  141. bool isBaseMove = !unpackMove(stream, basemove, alwaysReadAll);
  142. // ExtendedMove
  143. const ExtendedMove* extBaseMove = static_cast<const ExtendedMove*>(basemove);
  144. if (alwaysReadAll || stream->readFlag())
  145. {
  146. isBaseMove = false;
  147. for(U32 i=0; i<MaxPositionsRotations; ++i)
  148. {
  149. // Position
  150. if(stream->readFlag())
  151. posX[i] = stream->readSignedInt(MaxPositionBits);
  152. else
  153. posX[i] = extBaseMove->posX[i];
  154. if(stream->readFlag())
  155. posY[i] = stream->readSignedInt(MaxPositionBits);
  156. else
  157. posY[i] = extBaseMove->posY[i];
  158. if(stream->readFlag())
  159. posZ[i] = stream->readSignedInt(MaxPositionBits);
  160. else
  161. posZ[i] = extBaseMove->posZ[i];
  162. // Rotation
  163. EulerBasedRotation[i] = stream->readFlag();
  164. F32 scale = 1.0f;
  165. if(EulerBasedRotation[i])
  166. scale = M_2PI_F;
  167. if(stream->readFlag())
  168. {
  169. crotX[i] = stream->readInt(MaxRotationBits);
  170. rotX[i] = UNCLAMPROT(crotX[i]) * scale;
  171. }
  172. else
  173. {
  174. rotX[i] = extBaseMove->rotX[i];
  175. }
  176. if(stream->readFlag())
  177. {
  178. crotY[i] = stream->readInt(MaxRotationBits);
  179. rotY[i] = UNCLAMPROT(crotY[i]) * scale;
  180. }
  181. else
  182. {
  183. rotY[i] = extBaseMove->rotY[i];
  184. }
  185. if(stream->readFlag())
  186. {
  187. crotZ[i] = stream->readInt(MaxRotationBits);
  188. rotZ[i] = UNCLAMPROT(crotZ[i]) * scale;
  189. }
  190. else
  191. {
  192. rotZ[i] = extBaseMove->rotZ[i];
  193. }
  194. if(!EulerBasedRotation[i])
  195. {
  196. if(stream->readFlag())
  197. {
  198. crotW[i] = stream->readInt(MaxRotationBits);
  199. rotW[i] = UNCLAMPROT(crotW[i]);
  200. }
  201. else
  202. {
  203. rotW[i] = extBaseMove->rotW[i];
  204. }
  205. }
  206. }
  207. }
  208. if(isBaseMove)
  209. {
  210. *this = *extBaseMove;
  211. }
  212. }
  213. void ExtendedMove::clamp()
  214. {
  215. // Clamp the values the same as for net traffic so the client matches the server
  216. for(U32 i=0; i<MaxPositionsRotations; ++i)
  217. {
  218. // Positions
  219. posX[i] = CLAMPPOS(posX[i]);
  220. posY[i] = CLAMPPOS(posY[i]);
  221. posZ[i] = CLAMPPOS(posZ[i]);
  222. // Rotations
  223. if(EulerBasedRotation[i])
  224. {
  225. crotX[i] = CLAMPROT(rotX[i] / M_2PI_F);
  226. crotY[i] = CLAMPROT(rotY[i] / M_2PI_F);
  227. crotZ[i] = CLAMPROT(rotZ[i] / M_2PI_F);
  228. }
  229. else
  230. {
  231. crotX[i] = CLAMPROT(rotX[i]);
  232. crotY[i] = CLAMPROT(rotY[i]);
  233. crotZ[i] = CLAMPROT(rotZ[i]);
  234. crotW[i] = CLAMPROT(rotW[i] / M_2PI_F);
  235. }
  236. }
  237. // Perform the standard Move clamp
  238. Parent::clamp();
  239. }
  240. void ExtendedMove::unclamp()
  241. {
  242. // Unclamp the values the same as for net traffic so the client matches the server
  243. for(U32 i=0; i<MaxPositionsRotations; ++i)
  244. {
  245. // Rotations
  246. if(EulerBasedRotation[i])
  247. {
  248. rotX[i] = UNCLAMPROT(crotX[i]) * M_2PI_F;
  249. rotY[i] = UNCLAMPROT(crotY[i]) * M_2PI_F;
  250. rotZ[i] = UNCLAMPROT(crotZ[i]) * M_2PI_F;
  251. }
  252. else
  253. {
  254. rotX[i] = UNCLAMPROT(crotX[i]);
  255. rotY[i] = UNCLAMPROT(crotY[i]);
  256. rotZ[i] = UNCLAMPROT(crotZ[i]);
  257. rotW[i] = UNCLAMPROT(crotW[i]) * M_2PI_F;
  258. }
  259. }
  260. // Perform the standard Move unclamp
  261. Parent::unclamp();
  262. }