moveManager.cpp 10 KB

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