camera.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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, UnitId id, ProjectionType::Enum type, float near, float far)
  17. : _scene_graph(sg)
  18. , _unit_id(id)
  19. , _projection_type(type)
  20. , _near(near)
  21. , _far(far)
  22. {
  23. update_projection_matrix();
  24. }
  25. void Camera::set_projection_type(ProjectionType::Enum type)
  26. {
  27. _projection_type = type;
  28. update_projection_matrix();
  29. }
  30. ProjectionType::Enum Camera::projection_type() const
  31. {
  32. return _projection_type;
  33. }
  34. const Matrix4x4& Camera::projection_matrix() const
  35. {
  36. return _projection;
  37. }
  38. Matrix4x4 Camera::view_matrix() const
  39. {
  40. Matrix4x4 view = _scene_graph.world_pose(_scene_graph.get(_unit_id));
  41. matrix4x4::invert(view);
  42. return view;
  43. }
  44. float Camera::fov() const
  45. {
  46. return _FOV;
  47. }
  48. void Camera::set_fov(float fov)
  49. {
  50. _FOV = fov;
  51. update_projection_matrix();
  52. }
  53. float Camera::aspect() const
  54. {
  55. return _aspect;
  56. }
  57. void Camera::set_aspect(float aspect)
  58. {
  59. _aspect = aspect;
  60. update_projection_matrix();
  61. }
  62. float Camera::near_clip_distance() const
  63. {
  64. return _near;
  65. }
  66. void Camera::set_near_clip_distance(float near)
  67. {
  68. _near = near;
  69. update_projection_matrix();
  70. }
  71. float Camera::far_clip_distance() const
  72. {
  73. return _far;
  74. }
  75. void Camera::set_far_clip_distance(float far)
  76. {
  77. _far = far;
  78. update_projection_matrix();
  79. }
  80. void Camera::set_orthographic_metrics(float left, float right, float bottom, float top)
  81. {
  82. _left = left;
  83. _right = right;
  84. _bottom = bottom;
  85. _top = top;
  86. update_projection_matrix();
  87. }
  88. void Camera::set_viewport_metrics(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
  89. {
  90. _view_x = x;
  91. _view_y = y;
  92. _view_width = width;
  93. _view_height = height;
  94. }
  95. Vector3 Camera::screen_to_world(const Vector3& pos)
  96. {
  97. using namespace matrix4x4;
  98. Matrix4x4 mvp = view_matrix() * _projection;
  99. invert(mvp);
  100. Vector4 ndc( (2 * (pos.x - 0)) / _view_width - 1,
  101. (2 * (_view_height - pos.y)) / _view_height - 1,
  102. (2 * pos.z) - 1, 1);
  103. Vector4 tmp = ndc * mvp;
  104. tmp *= 1.0f / tmp.w;
  105. return Vector3(tmp.x, tmp.y, tmp.z);
  106. }
  107. Vector3 Camera::world_to_screen(const Vector3& pos)
  108. {
  109. using namespace matrix4x4;
  110. Vector3 ndc = pos * (view_matrix() * _projection);
  111. return Vector3( (_view_x + _view_width * (ndc.x + 1.0f)) / 2.0f,
  112. (_view_y + _view_height * (ndc.y + 1.0f)) / 2.0f,
  113. (ndc.z + 1.0f) / 2.0f);
  114. }
  115. void Camera::update_projection_matrix()
  116. {
  117. switch (_projection_type)
  118. {
  119. case ProjectionType::ORTHOGRAPHIC:
  120. {
  121. matrix4x4::set_orthographic(_projection, _left, _right, _bottom, _top, _near, _far);
  122. break;
  123. }
  124. case ProjectionType::PERSPECTIVE:
  125. {
  126. matrix4x4::set_perspective(_projection, _FOV, _aspect, _near, _far);
  127. break;
  128. }
  129. default:
  130. {
  131. CE_FATAL("Oops, unknown projection type");
  132. break;
  133. }
  134. }
  135. }
  136. void Camera::update_frustum()
  137. {
  138. // TODO
  139. //m_frustum.from_matrix(_projection * m_view);
  140. }
  141. } // namespace crown