extendedMove.cpp 11 KB

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