camera.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "camera.h"
  6. #include "types.h"
  7. #include "math_utils.h"
  8. #include "quaternion.h"
  9. #include "unit.h"
  10. #include "scene_graph.h"
  11. #include "error.h"
  12. #include "vector4.h"
  13. #include "frustum.h"
  14. namespace crown
  15. {
  16. Camera::Camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far)
  17. : _scene_graph(sg)
  18. , _node(node)
  19. , _projection_type(type)
  20. , _near(near)
  21. , _far(far)
  22. {
  23. update_projection_matrix();
  24. }
  25. Vector3 Camera::local_position() const
  26. {
  27. return _scene_graph.local_position(_node);
  28. }
  29. Quaternion Camera::local_rotation() const
  30. {
  31. return _scene_graph.local_rotation(_node);
  32. }
  33. Matrix4x4 Camera::local_pose() const
  34. {
  35. return _scene_graph.local_pose(_node);
  36. }
  37. Vector3 Camera::world_position() const
  38. {
  39. return _scene_graph.world_position(_node);
  40. }
  41. Quaternion Camera::world_rotation() const
  42. {
  43. return _scene_graph.world_rotation(_node);
  44. }
  45. Matrix4x4 Camera::world_pose() const
  46. {
  47. return _scene_graph.world_pose(_node);
  48. }
  49. void Camera::set_local_position(Unit* unit, const Vector3& pos)
  50. {
  51. unit->set_local_position(_node, pos);
  52. }
  53. void Camera::set_local_rotation(Unit* unit, const Quaternion& rot)
  54. {
  55. unit->set_local_rotation(_node, rot);
  56. }
  57. void Camera::set_local_pose(Unit* unit, const Matrix4x4& pose)
  58. {
  59. unit->set_local_pose(_node, pose);
  60. }
  61. void Camera::set_projection_type(ProjectionType::Enum type)
  62. {
  63. _projection_type = type;
  64. update_projection_matrix();
  65. }
  66. ProjectionType::Enum Camera::projection_type() const
  67. {
  68. return _projection_type;
  69. }
  70. const Matrix4x4& Camera::projection_matrix() const
  71. {
  72. return _projection;
  73. }
  74. Matrix4x4 Camera::view_matrix() const
  75. {
  76. Matrix4x4 view = world_pose();
  77. matrix4x4::invert(view);
  78. return view;
  79. }
  80. float Camera::fov() const
  81. {
  82. return _FOV;
  83. }
  84. void Camera::set_fov(float fov)
  85. {
  86. _FOV = fov;
  87. update_projection_matrix();
  88. }
  89. float Camera::aspect() const
  90. {
  91. return _aspect;
  92. }
  93. void Camera::set_aspect(float aspect)
  94. {
  95. _aspect = aspect;
  96. update_projection_matrix();
  97. }
  98. float Camera::near_clip_distance() const
  99. {
  100. return _near;
  101. }
  102. void Camera::set_near_clip_distance(float near)
  103. {
  104. _near = near;
  105. update_projection_matrix();
  106. }
  107. float Camera::far_clip_distance() const
  108. {
  109. return _far;
  110. }
  111. void Camera::set_far_clip_distance(float far)
  112. {
  113. _far = far;
  114. update_projection_matrix();
  115. }
  116. void Camera::set_orthographic_metrics(float left, float right, float bottom, float top)
  117. {
  118. _left = left;
  119. _right = right;
  120. _bottom = bottom;
  121. _top = top;
  122. update_projection_matrix();
  123. }
  124. void Camera::set_viewport_metrics(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
  125. {
  126. _view_x = x;
  127. _view_y = y;
  128. _view_width = width;
  129. _view_height = height;
  130. }
  131. Vector3 Camera::screen_to_world(const Vector3& pos)
  132. {
  133. using namespace matrix4x4;
  134. Matrix4x4 world_inv = world_pose();
  135. invert(world_inv);
  136. Matrix4x4 mvp = world_inv * _projection;
  137. invert(mvp);
  138. Vector4 ndc( (2 * (pos.x - 0)) / _view_width - 1,
  139. (2 * (_view_height - pos.y)) / _view_height - 1,
  140. (2 * pos.z) - 1, 1);
  141. Vector4 tmp = ndc * mvp;
  142. tmp *= 1.0f / tmp.w;
  143. return Vector3(tmp.x, tmp.y, tmp.z);
  144. }
  145. Vector3 Camera::world_to_screen(const Vector3& pos)
  146. {
  147. using namespace matrix4x4;
  148. Matrix4x4 world_inv = world_pose();
  149. invert(world_inv);
  150. Vector3 ndc = pos * (world_inv * _projection);
  151. return Vector3( (_view_x + _view_width * (ndc.x + 1.0f)) / 2.0f,
  152. (_view_y + _view_height * (ndc.y + 1.0f)) / 2.0f,
  153. (ndc.z + 1.0f) / 2.0f);
  154. }
  155. void Camera::update_projection_matrix()
  156. {
  157. switch (_projection_type)
  158. {
  159. case ProjectionType::ORTHOGRAPHIC:
  160. {
  161. matrix4x4::set_orthographic(_projection, _left, _right, _bottom, _top, _near, _far);
  162. break;
  163. }
  164. case ProjectionType::PERSPECTIVE:
  165. {
  166. matrix4x4::set_perspective(_projection, _FOV, _aspect, _near, _far);
  167. break;
  168. }
  169. default:
  170. {
  171. CE_FATAL("Oops, unknown projection type");
  172. break;
  173. }
  174. }
  175. }
  176. void Camera::update_frustum()
  177. {
  178. // TODO
  179. //m_frustum.from_matrix(_projection * m_view);
  180. }
  181. } // namespace crown