You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 12 година
пре 11 година
пре 11 година
пре 11 година
пре 12 година
пре 11 година
пре 12 година
пре 11 година
пре 11 година
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 */