camera.cpp 7.7 KB

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