25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

camera.cpp 5.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the Do What The Fuck You Want To
  8. // Public License, Version 2, as published by Sam Hocevar. See
  9. // http://www.wtfpl.net/ for more details.
  10. //
  11. #if defined HAVE_CONFIG_H
  12. # include "config.h"
  13. #endif
  14. #include <cstring>
  15. #include <cstdlib>
  16. #include <lol/main.h>
  17. #if defined _WIN32 || defined _XBOX
  18. # define strcasecmp _stricmp
  19. # undef near
  20. # undef far
  21. #endif
  22. namespace lol
  23. {
  24. Camera::Camera()
  25. {
  26. m_gamegroup = GAMEGROUP_BEFORE;
  27. m_drawgroup = DRAWGROUP_CAMERA;
  28. //Arbitrary values when g_renderer is not ready.
  29. ivec2 screen_size = (g_renderer)?(Video::GetSize()):(ivec2(800, 600));
  30. m_fov = 45.f;
  31. m_near = -1000.f;
  32. m_far = 1000.f;
  33. m_screen_size = (float)screen_size.x;
  34. m_screen_ratio = (float)screen_size.y / (float)screen_size.x;
  35. m_is_shifted = false;
  36. m_screen_scale = vec2(1.f);
  37. m_target_distance = .0f;
  38. /* Create a default perspective */
  39. SetProjection(m_fov, m_near, m_far, m_screen_size, m_screen_ratio);
  40. SetView(mat4::lookat(vec3(0.f, 50.f, 50.f), vec3::zero, vec3::axis_y));
  41. }
  42. Camera::~Camera()
  43. {
  44. }
  45. //-----------------------------------------------------------------------------
  46. //View functions
  47. //--
  48. //WARNING : Don't forget the position
  49. void Camera::SetView(mat4 const &view)
  50. {
  51. m_view_matrix = view;
  52. m_position = inverse(view)[3].xyz;
  53. }
  54. void Camera::SetView(vec3 eye, vec3 target, vec3 up)
  55. {
  56. m_view_matrix = mat4::lookat(eye, target, up);
  57. m_position = eye;
  58. m_target_distance = length(target - m_position);
  59. }
  60. void Camera::SetView(vec3 pos, vec3 rot)
  61. {
  62. SetView(pos, quat::fromeuler_zyx(rot));
  63. }
  64. void Camera::SetView(vec3 pos, quat rot)
  65. {
  66. m_view_matrix = inverse(mat4(rot)) * mat4::translate(-pos);
  67. m_position = pos;
  68. }
  69. mat4 Camera::GetView() const
  70. {
  71. return m_view_matrix;
  72. }
  73. //-----------------------------------------------------------------------------
  74. //Projections functions
  75. //--
  76. void Camera::SetProjection(mat4 const &proj)
  77. {
  78. m_proj_matrix = proj;
  79. }
  80. void Camera::SetProjection(float fov, float near, float far)
  81. {
  82. SetProjection(fov, near, far, m_screen_size, m_screen_ratio);
  83. }
  84. void Camera::SetProjection(float fov, float near, float far, float screen_size, float screen_ratio)
  85. {
  86. m_fov = fov;
  87. m_near = near;
  88. m_far = far;
  89. m_screen_size = screen_size;
  90. m_screen_ratio = screen_ratio;
  91. mat4 screen_scale = mat4::scale(vec3(m_screen_scale.xy, 1.f));
  92. if (m_fov > .001f)
  93. {
  94. if (m_is_shifted)
  95. SetProjection(screen_scale * mat4::shifted_perspective(m_fov, screen_size, screen_ratio, m_near, m_far));
  96. else
  97. SetProjection(screen_scale * mat4::perspective(m_fov, screen_size, screen_size * screen_ratio, m_near, m_far));
  98. }
  99. else
  100. SetProjection(screen_scale * mat4::ortho(screen_size, screen_size * screen_ratio, m_near, m_far));
  101. }
  102. mat4 Camera::GetProjection() const
  103. {
  104. return m_proj_matrix;
  105. }
  106. //-----------------------------------------------------------------------------
  107. //Projections manipulation functions
  108. //--
  109. void Camera::SetFov(float fov)
  110. {
  111. SetProjection(fov, m_near, m_far, m_screen_size, m_screen_ratio);
  112. }
  113. void Camera::SetScreenInfos(float screen_size)
  114. {
  115. SetScreenInfos(screen_size, m_screen_ratio);
  116. }
  117. void Camera::SetScreenInfos(float screen_size, float screen_ratio)
  118. {
  119. SetProjection(m_fov, m_near, m_far, screen_size, screen_ratio);
  120. }
  121. void Camera::SetDrawInfos(float far)
  122. {
  123. SetDrawInfos(m_near, far);
  124. }
  125. void Camera::SetDrawInfos(float near, float far)
  126. {
  127. SetProjection(m_fov, near, far, m_screen_size, m_screen_ratio);
  128. }
  129. void Camera::SetScreenScale(vec2 screen_scale)
  130. {
  131. m_screen_scale = screen_scale;
  132. SetProjection(m_fov, m_near, m_far, m_screen_size, m_screen_ratio);
  133. }
  134. void Camera::UseShift(bool should_shift)
  135. {
  136. m_is_shifted = should_shift;
  137. SetProjection(m_fov, m_near, m_far, m_screen_size, m_screen_ratio);
  138. }
  139. void Camera::UseTarget(bool use_target)
  140. {
  141. m_target_distance = ((use_target)?(max(m_target_distance, 1.f)):(.0f));
  142. }
  143. //-----------------------------------------------------------------------------
  144. //camera manipulation Functions
  145. //--
  146. void Camera::SetPosition(vec3 pos, bool keep_target)
  147. {
  148. if (keep_target)
  149. SetView(pos, GetTarget(), GetUp());
  150. else
  151. SetView(GetView() * mat4::translate(pos - m_position));
  152. m_position = pos;
  153. }
  154. void Camera::SetTarget(vec3 target, vec3 up)
  155. {
  156. SetView(m_position, target, up);
  157. }
  158. void Camera::SetRotation(vec3 rot)
  159. {
  160. SetView(m_position, rot);
  161. }
  162. void Camera::SetRotation(quat rot)
  163. {
  164. SetView(m_position, rot);
  165. }
  166. //--
  167. vec3 Camera::GetPosition() const
  168. {
  169. return m_position;
  170. }
  171. vec3 Camera::GetTarget() const
  172. {
  173. return m_position + (inverse(m_view_matrix) * vec4(0.f, 0.f, -max(m_target_distance, 1.f), 0.f)).xyz;
  174. }
  175. vec3 Camera::GetUp() const
  176. {
  177. return (inverse(m_view_matrix) * vec4(0.f, 1.f, 0.f, 0.f)).xyz;
  178. }
  179. vec3 Camera::GetRotationEuler() const
  180. {
  181. return vec3::toeuler_zyx(GetRotation());
  182. }
  183. quat Camera::GetRotation() const
  184. {
  185. return quat(inverse(m_view_matrix));
  186. }
  187. // Calculate the frustum height at a given distance from the camera.
  188. float Camera::GetFrustumHeightAtDistance(float distance, float fov) const
  189. {
  190. return 2.f * distance * lol::tan(radians(fov * .5f));
  191. }
  192. // Calculate the FOV needed to get a given frustum height at a given distance.
  193. float Camera::GetFOVForHeightAndDistance(float distance, float height) const
  194. {
  195. return 2.f * radians(lol::atan(height * .5f / distance));
  196. }
  197. void Camera::TickGame(float seconds)
  198. {
  199. WorldEntity::TickGame(seconds);
  200. }
  201. void Camera::TickDraw(float seconds, Scene &scene)
  202. {
  203. WorldEntity::TickDraw(seconds, scene);
  204. }
  205. } /* namespace lol */