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

134 lines
3.4 KiB

  1. /*
  2. * Copyright (C) 2021 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. #ifndef ANTKEEPER_PHYSICS_FRAME_HPP
  20. #define ANTKEEPER_PHYSICS_FRAME_HPP
  21. #include "math/math.hpp"
  22. #include <cmath>
  23. namespace physics {
  24. /**
  25. * 3-dimensional frame of reference.
  26. *
  27. * @tparam T Scalar type.
  28. */
  29. template <class T>
  30. struct frame
  31. {
  32. public:
  33. /// Scalar type.
  34. typedef T scalar_type;
  35. /// Vector type.
  36. typedef math::vector3<T> vector_type;
  37. /// Quaternion type.
  38. typedef math::quaternion<T> quaternion_type;
  39. /// Transformation matrix type.
  40. typedef math::matrix<T, 4, 4> matrix_type;
  41. /// Vector representing a translation from the origin of this frame to the origin of the parent frame.
  42. vector_type translation;
  43. /// Quaternion representing a rotation from the orientation of this frame to the orientation of the parent frame.
  44. quaternion_type rotation;
  45. /// Returns the inverse of this frame.
  46. frame inverse() const;
  47. /// Returns a transformation matrix representation of this frame.
  48. matrix_type matrix() const;
  49. /**
  50. * Transforms a vector from the parent frame space to this frame's space.
  51. *
  52. * @param v Vector in parent frame space.
  53. * @return Vector in this frame's space.
  54. */
  55. vector_type transform(const vector_type& v) const;
  56. /**
  57. * Transforms a frame from the parent frame space to this frame's space.
  58. *
  59. * @param f Frame in parent frame space.
  60. * @return Frame in this frame's space.
  61. */
  62. frame transform(const frame& f) const;
  63. /// @copydoc frame::transform(const vector_type&) const
  64. vector_type operator*(const vector_type& v) const;
  65. /// @copydoc frame::transform(const frame&) const
  66. frame operator*(const frame& f) const;
  67. };
  68. template <class T>
  69. frame<T> frame<T>::inverse() const
  70. {
  71. const quaternion_type inverse_rotation = math::conjugate(rotation);
  72. const vector_type inverse_translation = -(inverse_rotation * translation);
  73. return frame{inverse_translation, inverse_rotation};
  74. }
  75. template <class T>
  76. typename frame<T>::matrix_type frame<T>::matrix() const
  77. {
  78. matrix_type m = math::resize<4, 4>(math::matrix_cast<T>(rotation));
  79. m[3].x = translation.x;
  80. m[3].y = translation.y;
  81. m[3].z = translation.z;
  82. return m;
  83. }
  84. template <class T>
  85. typename frame<T>::vector_type frame<T>::transform(const vector_type& v) const
  86. {
  87. return translation + rotation * v;
  88. }
  89. template <class T>
  90. frame<T> frame<T>::transform(const frame& f) const
  91. {
  92. return frame
  93. {
  94. f.transform(translation),
  95. math::normalize(f.rotation * rotation)
  96. };
  97. }
  98. template <class T>
  99. typename frame<T>::vector_type frame<T>::operator*(const vector_type& v) const
  100. {
  101. return transform(v);
  102. }
  103. template <class T>
  104. frame<T> frame<T>::operator*(const frame& f) const
  105. {
  106. return transform(f);
  107. }
  108. } // namespace physics
  109. #endif // ANTKEEPER_PHYSICS_FRAME_HPP