💿🐜 Antkeeper source code https://antkeeper.com
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.

251 lines
5.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
  1. /*
  2. * Copyright (C) 2017-2019 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper Source Code.
  5. *
  6. * Antkeeper Source Code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper Source Code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "camera-rig.hpp"
  20. #include <algorithm>
  21. #include <cmath>
  22. CameraRig::CameraRig():
  23. camera(nullptr),
  24. translation(0.0f),
  25. rotation(1.0f, 0.0f, 0.0f, 0.0f),
  26. forward(0.0f, 0.0f, -1.0f),
  27. right(1.0f, 0.0f, 0.0f),
  28. up(0.0f, 1.0f, 0.0f)
  29. {}
  30. void CameraRig::attachCamera(Camera* camera)
  31. {
  32. this->camera = camera;
  33. if (camera != nullptr)
  34. {
  35. camera->lookAt(translation, translation + forward, up);
  36. }
  37. }
  38. void CameraRig::detachCamera()
  39. {
  40. camera = nullptr;
  41. }
  42. void CameraRig::setTranslation(const Vector3& translation)
  43. {
  44. this->translation = translation;
  45. }
  46. void CameraRig::setRotation(const Quaternion& rotation)
  47. {
  48. this->rotation = rotation;
  49. // Calculate orthonormal basis
  50. forward = glm::normalize(rotation * Vector3(0.0f, 0.0f, -1.0f));
  51. up = glm::normalize(rotation * Vector3(0.0f, 1.0f, 0.0f));
  52. right = glm::normalize(glm::cross(forward, up));
  53. }
  54. FreeCam::FreeCam():
  55. pitchRotation(1.0f, 0.0f, 0.0f, 0.0f),
  56. yawRotation(1.0f, 0.0f, 0.0f, 0.0f),
  57. pitch(0.0f),
  58. yaw(0.0f)
  59. {}
  60. FreeCam::~FreeCam()
  61. {}
  62. void FreeCam::update(float dt)
  63. {
  64. if (getCamera() != nullptr)
  65. {
  66. getCamera()->lookAt(getTranslation(), getTranslation() + getForward(), getUp());
  67. }
  68. }
  69. void FreeCam::move(const Vector2& velocity)
  70. {
  71. setTranslation(getTranslation() + getForward() * -velocity.y + getRight() * velocity.x);
  72. }
  73. float wrapAngle(float x)
  74. {
  75. x = std::fmod(x + glm::pi<float>(), glm::pi<float>() * 2.0f);
  76. if (x < 0.0f)
  77. {
  78. x += glm::pi<float>() * 2.0f;
  79. }
  80. return x - glm::pi<float>();
  81. }
  82. void FreeCam::rotate(float pan, float tilt)
  83. {
  84. pitch = wrapAngle(pitch + tilt);
  85. yaw = wrapAngle(yaw + pan);
  86. pitch = std::min<float>(std::max<float>(glm::radians(-89.0f), pitch), glm::radians(89.0f));
  87. // Form quaternions from pan and tilt angles
  88. pitchRotation = glm::angleAxis(pitch,Vector3(1.0f, 0.0f, 0.0f));
  89. yawRotation = glm::angleAxis(yaw, Vector3(0.0f, 1.0f, 0.0f));
  90. // Rotate camera
  91. setRotation(glm::normalize(yawRotation * pitchRotation));
  92. }
  93. OrbitCam::OrbitCam():
  94. elevationRotation(1, 0, 0, 0),
  95. azimuthRotation(1, 0, 0, 0),
  96. targetElevationRotation(1, 0, 0, 0),
  97. targetAzimuthRotation(1, 0, 0, 0),
  98. targetRotation(1, 0, 0, 0)
  99. {}
  100. OrbitCam::~OrbitCam()
  101. {}
  102. void OrbitCam::update(float dt)
  103. {
  104. float interpolationFactor = 0.25f / (1.0 / 60.0f) * dt;
  105. // Calculate rotation and target rotation quaternions
  106. //rotation = azimuthRotation * elevationRotation;
  107. targetRotation = targetAzimuthRotation * targetElevationRotation;
  108. // Calculate target translation
  109. targetTranslation = targetFocalPoint + targetRotation * Vector3(0.0f, 0.0f, targetFocalDistance);
  110. // Interpolate rotation
  111. //rotation = glm::mix(rotation, targetRotation, interpolationFactor);
  112. // Interpolate angles
  113. setElevation(glm::mix(elevation, targetElevation, interpolationFactor));
  114. setAzimuth(glm::mix(azimuth, targetAzimuth, interpolationFactor));
  115. // Calculate rotation
  116. setRotation(azimuthRotation * elevationRotation);
  117. // Interpolate focal point and focal distance
  118. focalPoint = glm::mix(focalPoint, targetFocalPoint, interpolationFactor);
  119. focalDistance = glm::mix(focalDistance, targetFocalDistance, interpolationFactor);
  120. // Caluclate translation
  121. setTranslation(focalPoint + getRotation() * Vector3(0.0f, 0.0f, focalDistance));
  122. /*
  123. // Recalculate azimuth
  124. azimuthRotation = rotation;
  125. azimuthRotation.x = 0.0f;
  126. azimuthRotation.z = 0.0f;
  127. azimuthRotation = glm::normalize(azimuthRotation);
  128. azimuth = 2.0f * std::acos(azimuthRotation.w);
  129. // Recalculate elevation
  130. elevationRotation = rotation;
  131. elevationRotation.y = 0.0f;
  132. elevationRotation.z = 0.0f;
  133. elevationRotation = glm::normalize(elevationRotation);
  134. elevation = 2.0f * std::acos(elevationRotation.w);
  135. */
  136. // Update camera
  137. if (getCamera() != nullptr)
  138. {
  139. getCamera()->lookAt(getTranslation(), getTranslation() + getForward(), getUp());
  140. }
  141. }
  142. void OrbitCam::move(Vector2 direction)
  143. {
  144. targetFocalPoint += azimuthRotation * Vector3(direction.x, 0.0f, direction.y);
  145. }
  146. void OrbitCam::rotate(float angle)
  147. {
  148. setTargetAzimuth(targetAzimuth + angle);
  149. }
  150. void OrbitCam::zoom(float distance)
  151. {
  152. setTargetFocalDistance(targetFocalDistance - distance);
  153. }
  154. void OrbitCam::setFocalPoint(const Vector3& point)
  155. {
  156. focalPoint = point;
  157. }
  158. void OrbitCam::setFocalDistance(float distance)
  159. {
  160. focalDistance = distance;
  161. }
  162. void OrbitCam::setElevation(float angle)
  163. {
  164. elevation = angle;
  165. elevationRotation = glm::angleAxis(elevation, Vector3(-1.0f, 0.0f, 0.0f));
  166. }
  167. void OrbitCam::setAzimuth(float angle)
  168. {
  169. azimuth = angle;
  170. azimuthRotation = glm::angleAxis(azimuth, Vector3(0.0f, 1.0f, 0.0f));
  171. }
  172. void OrbitCam::setTargetFocalPoint(const Vector3& point)
  173. {
  174. targetFocalPoint = point;
  175. }
  176. void OrbitCam::setTargetFocalDistance(float distance)
  177. {
  178. targetFocalDistance = distance;
  179. }
  180. void OrbitCam::setTargetElevation(float angle)
  181. {
  182. targetElevation = angle;
  183. targetElevationRotation = glm::angleAxis(targetElevation, Vector3(-1.0f, 0.0f, 0.0f));
  184. }
  185. void OrbitCam::setTargetAzimuth(float angle)
  186. {
  187. targetAzimuth = angle;
  188. targetAzimuthRotation = glm::angleAxis(targetAzimuth, Vector3(0.0f, 1.0f, 0.0f));
  189. }
  190. ShadowCam::ShadowCam():
  191. light(nullptr)
  192. {}
  193. ShadowCam::~ShadowCam()
  194. {}
  195. void ShadowCam::setLight(const PunctualLight* light)
  196. {
  197. this->light = light;
  198. if (light != nullptr)
  199. {
  200. }
  201. }
  202. void ShadowCam::update(float dt)
  203. {
  204. }