camera.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * Copyright 2013 Dario Manesku. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <bx/timer.h>
  6. #include <bx/fpumath.h>
  7. #include "camera.h"
  8. #include "entry/cmd.h"
  9. #include "entry/input.h"
  10. int cmdMove(CmdContext* /*_context*/, void* /*_userData*/, int _argc, char const* const* _argv)
  11. {
  12. if (_argc > 1)
  13. {
  14. if (0 == strcmp(_argv[1], "forward") )
  15. {
  16. cameraSetKeyState(CAMERA_KEY_FORWARD, true);
  17. return 0;
  18. }
  19. else if (0 == strcmp(_argv[1], "left") )
  20. {
  21. cameraSetKeyState(CAMERA_KEY_LEFT, true);
  22. return 0;
  23. }
  24. else if (0 == strcmp(_argv[1], "right") )
  25. {
  26. cameraSetKeyState(CAMERA_KEY_RIGHT, true);
  27. return 0;
  28. }
  29. else if (0 == strcmp(_argv[1], "backward") )
  30. {
  31. cameraSetKeyState(CAMERA_KEY_BACKWARD, true);
  32. return 0;
  33. }
  34. else if (0 == strcmp(_argv[1], "up") )
  35. {
  36. cameraSetKeyState(CAMERA_KEY_UP, true);
  37. return 0;
  38. }
  39. else if (0 == strcmp(_argv[1], "down") )
  40. {
  41. cameraSetKeyState(CAMERA_KEY_DOWN, true);
  42. return 0;
  43. }
  44. }
  45. return 1;
  46. }
  47. static void cmd(const void* _userData)
  48. {
  49. cmdExec( (const char*)_userData);
  50. }
  51. static const InputBinding s_camBindings[] =
  52. {
  53. { entry::Key::KeyW, entry::Modifier::None, 0, cmd, "move forward" },
  54. { entry::Key::GamepadUp, entry::Modifier::None, 0, cmd, "move forward" },
  55. { entry::Key::KeyA, entry::Modifier::None, 0, cmd, "move left" },
  56. { entry::Key::GamepadLeft, entry::Modifier::None, 0, cmd, "move left" },
  57. { entry::Key::KeyS, entry::Modifier::None, 0, cmd, "move backward" },
  58. { entry::Key::GamepadDown, entry::Modifier::None, 0, cmd, "move backward" },
  59. { entry::Key::KeyD, entry::Modifier::None, 0, cmd, "move right" },
  60. { entry::Key::GamepadRight, entry::Modifier::None, 0, cmd, "move right" },
  61. { entry::Key::GamepadShoulderL, entry::Modifier::None, 0, cmd, "move down" },
  62. { entry::Key::GamepadShoulderR, entry::Modifier::None, 0, cmd, "move up" },
  63. INPUT_BINDING_END
  64. };
  65. struct Camera
  66. {
  67. struct MouseCoords
  68. {
  69. int32_t m_mx;
  70. int32_t m_my;
  71. };
  72. Camera()
  73. {
  74. reset();
  75. entry::MouseState mouseState;
  76. update(0.0f, mouseState);
  77. cmdAdd("move", cmdMove);
  78. inputAddBindings("camBindings", s_camBindings);
  79. }
  80. ~Camera()
  81. {
  82. inputRemoveBindings("camBindings");
  83. }
  84. void reset()
  85. {
  86. m_mouseNow.m_mx = 0;
  87. m_mouseNow.m_my = 0;
  88. m_mouseLast.m_mx = 0;
  89. m_mouseLast.m_my = 0;
  90. m_eye[0] = 0.0f;
  91. m_eye[1] = 0.0f;
  92. m_eye[2] = -35.0f;
  93. m_at[0] = 0.0f;
  94. m_at[1] = 0.0f;
  95. m_at[2] = -1.0f;
  96. m_up[0] = 0.0f;
  97. m_up[1] = 1.0f;
  98. m_up[2] = 0.0f;
  99. m_horizontalAngle = 0.01f;
  100. m_verticalAngle = 0.0f;
  101. m_mouseSpeed = 0.0020f;
  102. m_gamepadSpeed = 0.04f;
  103. m_moveSpeed = 30.0f;
  104. m_keys = 0;
  105. m_mouseDown = false;
  106. }
  107. void setKeyState(uint8_t _key, bool _down)
  108. {
  109. m_keys &= ~_key;
  110. m_keys |= _down ? _key : 0;
  111. }
  112. void update(float _deltaTime, const entry::MouseState& _mouseState)
  113. {
  114. if (!m_mouseDown)
  115. {
  116. m_mouseLast.m_mx = _mouseState.m_mx;
  117. m_mouseLast.m_my = _mouseState.m_my;
  118. }
  119. m_mouseDown = !!_mouseState.m_buttons[entry::MouseButton::Right];
  120. if (m_mouseDown)
  121. {
  122. m_mouseNow.m_mx = _mouseState.m_mx;
  123. m_mouseNow.m_my = _mouseState.m_my;
  124. }
  125. if (m_mouseDown)
  126. {
  127. int32_t deltaX = m_mouseNow.m_mx - m_mouseLast.m_mx;
  128. int32_t deltaY = m_mouseNow.m_my - m_mouseLast.m_my;
  129. m_horizontalAngle += m_mouseSpeed * float(deltaX);
  130. m_verticalAngle -= m_mouseSpeed * float(deltaY);
  131. m_mouseLast.m_mx = m_mouseNow.m_mx;
  132. m_mouseLast.m_my = m_mouseNow.m_my;
  133. }
  134. entry::GamepadHandle handle = { 0 };
  135. m_horizontalAngle += m_gamepadSpeed * inputGetGamepadAxis(handle, entry::GamepadAxis::RightX)/32768.0f;
  136. m_verticalAngle -= m_gamepadSpeed * inputGetGamepadAxis(handle, entry::GamepadAxis::RightY)/32768.0f;
  137. const int32_t gpx = inputGetGamepadAxis(handle, entry::GamepadAxis::LeftX);
  138. const int32_t gpy = inputGetGamepadAxis(handle, entry::GamepadAxis::LeftY);
  139. m_keys |= gpx < -16834 ? CAMERA_KEY_LEFT : 0;
  140. m_keys |= gpx > 16834 ? CAMERA_KEY_RIGHT : 0;
  141. m_keys |= gpy < -16834 ? CAMERA_KEY_FORWARD : 0;
  142. m_keys |= gpy > 16834 ? CAMERA_KEY_BACKWARD : 0;
  143. float direction[3] =
  144. {
  145. cosf(m_verticalAngle) * sinf(m_horizontalAngle),
  146. sinf(m_verticalAngle),
  147. cosf(m_verticalAngle) * cosf(m_horizontalAngle),
  148. };
  149. float right[3] =
  150. {
  151. sinf(m_horizontalAngle - bx::piHalf),
  152. 0,
  153. cosf(m_horizontalAngle - bx::piHalf),
  154. };
  155. float up[3];
  156. bx::vec3Cross(up, right, direction);
  157. if (m_keys & CAMERA_KEY_FORWARD)
  158. {
  159. float pos[3];
  160. bx::vec3Move(pos, m_eye);
  161. float tmp[3];
  162. bx::vec3Mul(tmp, direction, _deltaTime * m_moveSpeed);
  163. bx::vec3Add(m_eye, pos, tmp);
  164. setKeyState(CAMERA_KEY_FORWARD, false);
  165. }
  166. if (m_keys & CAMERA_KEY_BACKWARD)
  167. {
  168. float pos[3];
  169. bx::vec3Move(pos, m_eye);
  170. float tmp[3];
  171. bx::vec3Mul(tmp, direction, _deltaTime * m_moveSpeed);
  172. bx::vec3Sub(m_eye, pos, tmp);
  173. setKeyState(CAMERA_KEY_BACKWARD, false);
  174. }
  175. if (m_keys & CAMERA_KEY_LEFT)
  176. {
  177. float pos[3];
  178. bx::vec3Move(pos, m_eye);
  179. float tmp[3];
  180. bx::vec3Mul(tmp, right, _deltaTime * m_moveSpeed);
  181. bx::vec3Add(m_eye, pos, tmp);
  182. setKeyState(CAMERA_KEY_LEFT, false);
  183. }
  184. if (m_keys & CAMERA_KEY_RIGHT)
  185. {
  186. float pos[3];
  187. bx::vec3Move(pos, m_eye);
  188. float tmp[3];
  189. bx::vec3Mul(tmp, right, _deltaTime * m_moveSpeed);
  190. bx::vec3Sub(m_eye, pos, tmp);
  191. setKeyState(CAMERA_KEY_RIGHT, false);
  192. }
  193. if (m_keys & CAMERA_KEY_UP)
  194. {
  195. float pos[3];
  196. bx::vec3Move(pos, m_eye);
  197. float tmp[3];
  198. bx::vec3Mul(tmp, up, _deltaTime * m_moveSpeed);
  199. bx::vec3Add(m_eye, pos, tmp);
  200. setKeyState(CAMERA_KEY_UP, false);
  201. }
  202. if (m_keys & CAMERA_KEY_DOWN)
  203. {
  204. float pos[3];
  205. bx::vec3Move(pos, m_eye);
  206. float tmp[3];
  207. bx::vec3Mul(tmp, up, _deltaTime * m_moveSpeed);
  208. bx::vec3Sub(m_eye, pos, tmp);
  209. setKeyState(CAMERA_KEY_DOWN, false);
  210. }
  211. bx::vec3Add(m_at, m_eye, direction);
  212. bx::vec3Cross(m_up, right, direction);
  213. }
  214. void getViewMtx(float* _viewMtx)
  215. {
  216. bx::mtxLookAt(_viewMtx, m_eye, m_at, m_up);
  217. }
  218. void setPosition(float* _pos)
  219. {
  220. memcpy(m_eye, _pos, sizeof(float)*3);
  221. }
  222. void setVerticalAngle(float _verticalAngle)
  223. {
  224. m_verticalAngle = _verticalAngle;
  225. }
  226. void setHorizontalAngle(float _horizontalAngle)
  227. {
  228. m_horizontalAngle = _horizontalAngle;
  229. }
  230. MouseCoords m_mouseNow;
  231. MouseCoords m_mouseLast;
  232. float m_eye[3];
  233. float m_at[3];
  234. float m_up[3];
  235. float m_horizontalAngle;
  236. float m_verticalAngle;
  237. float m_mouseSpeed;
  238. float m_gamepadSpeed;
  239. float m_moveSpeed;
  240. uint8_t m_keys;
  241. bool m_mouseDown;
  242. };
  243. static Camera* s_camera = NULL;
  244. void cameraCreate()
  245. {
  246. s_camera = new Camera;
  247. }
  248. void cameraDestroy()
  249. {
  250. delete s_camera;
  251. s_camera = NULL;
  252. }
  253. void cameraSetPosition(float* _pos)
  254. {
  255. s_camera->setPosition(_pos);
  256. }
  257. void cameraSetHorizontalAngle(float _horizontalAngle)
  258. {
  259. s_camera->setHorizontalAngle(_horizontalAngle);
  260. }
  261. void cameraSetVerticalAngle(float _verticalAngle)
  262. {
  263. s_camera->setVerticalAngle(_verticalAngle);
  264. }
  265. void cameraSetKeyState(uint8_t _key, bool _down)
  266. {
  267. s_camera->setKeyState(_key, _down);
  268. }
  269. void cameraGetViewMtx(float* _viewMtx)
  270. {
  271. s_camera->getViewMtx(_viewMtx);
  272. }
  273. void cameraGetPosition(float* _pos)
  274. {
  275. memcpy(_pos, s_camera->m_eye, 3*sizeof(float) );
  276. }
  277. void cameraGetAt(float* _at)
  278. {
  279. memcpy(_at, s_camera->m_at, 3*sizeof(float) );
  280. }
  281. void cameraUpdate(float _deltaTime, const entry::MouseState& _mouseState)
  282. {
  283. s_camera->update(_deltaTime, _mouseState);
  284. }