extendedMove.cpp 9.3 KB

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