💿🐜 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.

154 lines
4.4 KiB

  1. /*
  2. * Copyright (C) 2020 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 "orbit-cam.hpp"
  20. #include "scene/camera.hpp"
  21. #include "math/math.hpp"
  22. #include <algorithm>
  23. #include <cmath>
  24. orbit_cam::orbit_cam():
  25. elevation_rotation(math::identity_quaternion<float>),
  26. azimuth_rotation(math::identity_quaternion<float>),
  27. target_elevation_rotation(math::identity_quaternion<float>),
  28. target_azimuth_rotation(math::identity_quaternion<float>),
  29. target_rotation(math::identity_quaternion<float>)
  30. {}
  31. orbit_cam::~orbit_cam()
  32. {}
  33. void orbit_cam::update(float dt)
  34. {
  35. float interpolation_factor = 1.0f;
  36. // Calculate rotation and target rotation quaternions
  37. //rotation = azimuth_rotation * elevation_rotation;
  38. target_rotation = math::normalize(target_azimuth_rotation * target_elevation_rotation);
  39. // Calculate target translation
  40. target_translation = target_focal_point + target_rotation * float3{0.0f, 0.0f, target_focal_distance};
  41. // Interpolate rotation
  42. //rotation = glm::mix(rotation, target_rotation, interpolation_factor);
  43. // Interpolate angles
  44. set_elevation(math::lerp(elevation, target_elevation, interpolation_factor));
  45. set_azimuth(math::lerp(azimuth, target_azimuth, interpolation_factor));
  46. // Calculate rotation
  47. set_rotation(math::normalize(azimuth_rotation * elevation_rotation));
  48. // Interpolate focal point and focal distance
  49. focal_point = math::lerp(focal_point, target_focal_point, interpolation_factor);
  50. focal_distance = math::lerp(focal_distance, target_focal_distance, interpolation_factor);
  51. // Caluclate translation
  52. set_translation(focal_point + get_rotation() * float3{0.0f, 0.0f, focal_distance});
  53. /*
  54. // Recalculate azimuth
  55. azimuth_rotation = rotation;
  56. azimuth_rotation.x = 0.0f;
  57. azimuth_rotation.z = 0.0f;
  58. azimuth_rotation = glm::normalize(azimuth_rotation);
  59. azimuth = 2.0f * std::acos(azimuth_rotation.w);
  60. // Recalculate elevation
  61. elevation_rotation = rotation;
  62. elevation_rotation.y = 0.0f;
  63. elevation_rotation.z = 0.0f;
  64. elevation_rotation = glm::normalize(elevation_rotation);
  65. elevation = 2.0f * std::acos(elevation_rotation.w);
  66. */
  67. // Update camera
  68. if (get_camera() != nullptr)
  69. {
  70. transform_type transform = math::identity_transform<float>;
  71. transform.translation = get_translation();
  72. transform.rotation = get_rotation();
  73. get_camera()->set_transform(transform);
  74. //get_camera()->look_at(get_translation(), get_translation() + get_forward(), get_up());
  75. }
  76. }
  77. void orbit_cam::move(const float2& direction)
  78. {
  79. target_focal_point += azimuth_rotation * float3{direction[0], 0.0f, direction[1]};
  80. }
  81. void orbit_cam::rotate(float angle)
  82. {
  83. set_target_azimuth(target_azimuth + angle);
  84. }
  85. void orbit_cam::tilt(float angle)
  86. {
  87. set_target_elevation(target_elevation + angle);
  88. }
  89. void orbit_cam::zoom(float distance)
  90. {
  91. set_target_focal_distance(target_focal_distance - distance);
  92. }
  93. void orbit_cam::set_focal_point(const float3& point)
  94. {
  95. focal_point = point;
  96. }
  97. void orbit_cam::set_focal_distance(float distance)
  98. {
  99. focal_distance = distance;
  100. }
  101. void orbit_cam::set_elevation(float angle)
  102. {
  103. elevation = angle;
  104. elevation_rotation = math::angle_axis(elevation, float3{-1.0f, 0.0f, 0.0f});
  105. }
  106. void orbit_cam::set_azimuth(float angle)
  107. {
  108. azimuth = angle;
  109. azimuth_rotation = math::angle_axis(azimuth, float3{0.0f, 1.0f, 0.0f});
  110. }
  111. void orbit_cam::set_target_focal_point(const float3& point)
  112. {
  113. target_focal_point = point;
  114. }
  115. void orbit_cam::set_target_focal_distance(float distance)
  116. {
  117. target_focal_distance = distance;
  118. }
  119. void orbit_cam::set_target_elevation(float angle)
  120. {
  121. target_elevation = angle;
  122. target_elevation_rotation = math::angle_axis(target_elevation, float3{-1.0f, 0.0f, 0.0f});
  123. }
  124. void orbit_cam::set_target_azimuth(float angle)
  125. {
  126. target_azimuth = angle;
  127. target_azimuth_rotation = math::angle_axis(target_azimuth, float3{0.0f, 1.0f, 0.0f});
  128. }