CameraScript.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #pragma once
  2. #include "BaseScriptObject.h"
  3. #include "Math.h"
  4. #include "WindowLocator.h"
  5. class Camera : public BaseScriptObject
  6. {
  7. friend class ScriptingScene;
  8. public:
  9. Camera(SystemScene *p_systemScene, std::string p_name, Properties::PropertyID p_objectType)
  10. : BaseScriptObject(p_systemScene, p_name, p_objectType)
  11. {
  12. m_speed = 0.0f;
  13. m_fasterSpeed = 0.0f;
  14. m_verticalAngle = 0.0f;
  15. m_horizontalAngle = 0.0f;
  16. }
  17. const virtual Math::Vec3f &getVec3(const Observer *p_observer, BitMask p_changedBits) const
  18. {
  19. switch(p_changedBits)
  20. {
  21. case Systems::Changes::Spacial::Position:
  22. return m_positionVec;
  23. break;
  24. case Systems::Changes::Spacial::Rotation:
  25. return m_targetVec;
  26. break;
  27. }
  28. return ObservedSubject::getVec3(p_observer, p_changedBits);
  29. }
  30. const virtual Math::Mat4f &getMat4(const Observer *p_observer, BitMask p_changedBits) const
  31. {
  32. switch(p_changedBits)
  33. {
  34. case Systems::Changes::Spacial::ModelMatrix:
  35. return m_modelMatrix;
  36. break;
  37. }
  38. return ObservedSubject::getMat4(p_observer, p_changedBits);
  39. }
  40. // Setters
  41. const inline void setPosition(const Math::Vec3f &p_position) { m_positionVec = p_position; }
  42. const inline void setFasterSpeed(const float p_speed) { m_fasterSpeed = p_speed; }
  43. const inline void setSpeed(const float p_speed) { m_speed = p_speed; }
  44. const inline void setAngles(const Math::Vec2f &p_angles)
  45. {
  46. m_horizontalAngle = p_angles.x;
  47. m_verticalAngle = p_angles.y;
  48. }
  49. protected:
  50. float m_speed,
  51. m_fasterSpeed,
  52. m_verticalAngle,
  53. m_horizontalAngle;
  54. Math::Mat4f m_modelMatrix;
  55. Math::Vec3f m_positionVec,
  56. m_targetVec,
  57. m_upVector,
  58. m_horizontalVec;
  59. };
  60. class FreeCamera : public Camera
  61. {
  62. public:
  63. FreeCamera(SystemScene *p_systemScene, std::string p_name) : Camera(p_systemScene, p_name, Properties::FreeCamera)
  64. {
  65. m_enableLowerLimit = false;
  66. m_enableUpperLimit = false;
  67. m_lowerLimit = 0.0f;
  68. m_upperLimit = 0.0f;
  69. }
  70. virtual ErrorCode init()
  71. {
  72. return ErrorCode::Success;
  73. }
  74. void loadToMemory()
  75. {
  76. // Nothing to load
  77. }
  78. // Exports all the data of the object as a PropertySet
  79. virtual PropertySet exportObject()
  80. {
  81. // Create the root property set
  82. PropertySet propertySet(Properties::ArrayEntry);
  83. // Add variables
  84. propertySet.addProperty(Properties::Type, Properties::FreeCamera);
  85. propertySet.addProperty(Properties::Name, m_name);
  86. propertySet.addProperty(Properties::Position, m_positionVec);
  87. propertySet.addProperty(Properties::Angle, Math::Vec2f(m_horizontalAngle, m_verticalAngle));
  88. propertySet.addProperty(Properties::Speed, m_speed);
  89. propertySet.addProperty(Properties::SprintSpeed, m_fasterSpeed);
  90. if(m_enableLowerLimit)
  91. propertySet.addProperty(Properties::LowerLimit, m_lowerLimit);
  92. if(m_enableUpperLimit)
  93. propertySet.addProperty(Properties::UpperLimit, m_upperLimit);
  94. // Add root key-binding property set
  95. auto &keyBinds = propertySet.addPropertySet(Properties::Keybindings);
  96. // Add individual key-bindings
  97. keyBinds.addProperty(Properties::ForwardKey, (int)m_forwardKey.getFirstBinding());
  98. keyBinds.addProperty(Properties::BackwardKey, (int)m_backwardKey.getFirstBinding());
  99. keyBinds.addProperty(Properties::LeftStrafeKey, (int)m_strafeLeftKey.getFirstBinding());
  100. keyBinds.addProperty(Properties::RightStrafeKey, (int)m_strafeRightKey.getFirstBinding());
  101. keyBinds.addProperty(Properties::SprintKey, (int)m_sprintKey.getFirstBinding());
  102. return propertySet;
  103. }
  104. virtual void update(const float p_deltaTime)
  105. {
  106. // Only move the camera if the mouse is captured by the window
  107. if(Config::windowVar().mouse_captured)
  108. {
  109. const auto &mouseInfo = WindowLocator::get().getMouseInfo();
  110. m_horizontalAngle -= Config::inputVar().mouse_jaw * mouseInfo.m_movementX * (Config::inputVar().mouse_sensitivity * 0.01f);
  111. m_verticalAngle -= Config::inputVar().mouse_pitch * mouseInfo.m_movementY * (Config::inputVar().mouse_sensitivity * 0.01f);
  112. m_verticalAngle = Math::clamp(m_verticalAngle, -Config::inputVar().mouse_pitch_clip, Config::inputVar().mouse_pitch_clip);
  113. }
  114. // Calculate camera's rotation
  115. m_targetVec.target(m_verticalAngle, m_horizontalAngle);
  116. m_horizontalVec.horizontal(m_horizontalAngle);
  117. // Set speed for movement
  118. float speed = m_speed;
  119. // If sprint key is pressed, increase the movement speed
  120. if(m_sprintKey.isActivated())
  121. speed = m_fasterSpeed;
  122. // Check the status of all the movement keys
  123. if(m_forwardKey.isActivated())
  124. m_positionVec += m_targetVec * speed * p_deltaTime;
  125. if(m_backwardKey.isActivated())
  126. m_positionVec -= m_targetVec * speed * p_deltaTime;
  127. if(m_strafeLeftKey.isActivated())
  128. m_positionVec -= m_horizontalVec * speed * p_deltaTime;
  129. if(m_strafeRightKey.isActivated())
  130. m_positionVec += m_horizontalVec * speed * p_deltaTime;
  131. if(m_enableLowerLimit && m_positionVec.y < m_lowerLimit)
  132. m_positionVec.y = m_lowerLimit;
  133. if(m_enableUpperLimit && m_positionVec.y > m_upperLimit)
  134. m_positionVec.y = m_upperLimit;
  135. // Calculate camera's position based on the pressed movement keys
  136. m_upVector = Math::cross(m_horizontalVec, m_targetVec);
  137. m_modelMatrix.initCamera(m_positionVec, m_targetVec + m_positionVec, m_upVector);
  138. // Set the target vector variable, so it can be retrieved later by listeners
  139. m_targetVec = Math::Vec3f(0.0f);
  140. m_targetVec.y = m_verticalAngle;
  141. m_targetVec.z = m_horizontalAngle;
  142. // Notify listeners
  143. postChanges(Systems::Changes::Spacial::Position |
  144. Systems::Changes::Spacial::Rotation |
  145. Systems::Changes::Spacial::ModelMatrix);
  146. }
  147. // Setters for the movement keys:
  148. inline void setForwardKey(Scancode p_key)
  149. {
  150. m_forwardKey.unbindAll();
  151. m_forwardKey.bind(p_key);
  152. }
  153. inline void setForwardKey(std::string &p_string)
  154. {
  155. m_forwardKey.unbindAll();
  156. m_forwardKey.bind(p_string);
  157. }
  158. inline void setBackwardKey(Scancode p_key)
  159. {
  160. m_backwardKey.unbindAll();
  161. m_backwardKey.bind(p_key);
  162. }
  163. inline void setBackwardKey(std::string &p_string)
  164. {
  165. m_backwardKey.unbindAll();
  166. m_backwardKey.bind(p_string);
  167. }
  168. inline void setStrafeLeftKey(Scancode p_key)
  169. {
  170. m_strafeLeftKey.unbindAll();
  171. m_strafeLeftKey.bind(p_key);
  172. }
  173. inline void setStrafeLeftKey(std::string &p_string)
  174. {
  175. m_strafeLeftKey.unbindAll();
  176. m_strafeLeftKey.bind(p_string);
  177. }
  178. inline void setStrafeRightKey(Scancode p_key)
  179. {
  180. m_strafeRightKey.unbindAll();
  181. m_strafeRightKey.bind(p_key);
  182. }
  183. inline void setStrafeRightKey(std::string &p_string)
  184. {
  185. m_strafeRightKey.unbindAll();
  186. m_strafeRightKey.bind(p_string);
  187. }
  188. inline void setSprintKey(Scancode p_key)
  189. {
  190. m_sprintKey.unbindAll();
  191. m_sprintKey.bind(p_key);
  192. }
  193. inline void setSprintKey(std::string &p_string)
  194. {
  195. m_sprintKey.unbindAll();
  196. m_sprintKey.bind(p_string);
  197. }
  198. inline void setLowerLimit(const float p_limit)
  199. {
  200. m_enableLowerLimit = true;
  201. m_lowerLimit = p_limit;
  202. }
  203. inline void setUpperLimit(const float p_limit)
  204. {
  205. m_enableUpperLimit = true;
  206. m_upperLimit = p_limit;
  207. }
  208. private:
  209. KeyCommand m_forwardKey,
  210. m_backwardKey,
  211. m_strafeLeftKey,
  212. m_strafeRightKey,
  213. m_sprintKey;
  214. float m_lowerLimit,
  215. m_upperLimit;
  216. bool m_enableLowerLimit,
  217. m_enableUpperLimit;
  218. };