No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

248 líneas
5.7 KiB

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