|
|
- /*
- * Copyright (C) 2021 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #ifndef ANTKEEPER_PHYSICS_FRAME_HPP
- #define ANTKEEPER_PHYSICS_FRAME_HPP
-
- #include "math/math.hpp"
- #include <cmath>
-
- namespace physics {
-
- /**
- * 3-dimensional frame of reference.
- *
- * @tparam T Scalar type.
- */
- template <class T>
- struct frame
- {
- public:
- /// Scalar type.
- typedef T scalar_type;
-
- /// Vector type.
- typedef math::vector3<T> vector_type;
-
- /// Quaternion type.
- typedef math::quaternion<T> quaternion_type;
-
- /// Transformation matrix type.
- typedef math::matrix<T, 4, 4> matrix_type;
-
- /// Vector representing a translation from the origin of this frame to the origin of the parent frame.
- vector_type translation;
-
- /// Quaternion representing a rotation from the orientation of this frame to the orientation of the parent frame.
- quaternion_type rotation;
-
- /// Returns the inverse of this frame.
- frame inverse() const;
-
- /// Returns a transformation matrix representation of this frame.
- matrix_type matrix() const;
-
- /**
- * Transforms a vector from the parent frame space to this frame's space.
- *
- * @param v Vector in parent frame space.
- * @return Vector in this frame's space.
- */
- vector_type transform(const vector_type& v) const;
-
- /**
- * Transforms a frame from the parent frame space to this frame's space.
- *
- * @param f Frame in parent frame space.
- * @return Frame in this frame's space.
- */
- frame transform(const frame& f) const;
-
- /// @copydoc frame::transform(const vector_type&) const
- vector_type operator*(const vector_type& v) const;
-
- /// @copydoc frame::transform(const frame&) const
- frame operator*(const frame& f) const;
- };
-
- template <class T>
- frame<T> frame<T>::inverse() const
- {
- const quaternion_type inverse_rotation = math::conjugate(rotation);
- const vector_type inverse_translation = -(inverse_rotation * translation);
- return frame{inverse_translation, inverse_rotation};
- }
-
- template <class T>
- typename frame<T>::matrix_type frame<T>::matrix() const
- {
- matrix_type m = math::resize<4, 4>(math::matrix_cast<T>(rotation));
-
- m[3].x = translation.x;
- m[3].y = translation.y;
- m[3].z = translation.z;
-
- return m;
- }
-
- template <class T>
- typename frame<T>::vector_type frame<T>::transform(const vector_type& v) const
- {
- return translation + rotation * v;
- }
-
- template <class T>
- frame<T> frame<T>::transform(const frame& f) const
- {
- return frame
- {
- f.transform(translation),
- math::normalize(f.rotation * rotation)
- };
- }
-
- template <class T>
- typename frame<T>::vector_type frame<T>::operator*(const vector_type& v) const
- {
- return transform(v);
- }
-
- template <class T>
- frame<T> frame<T>::operator*(const frame& f) const
- {
- return transform(f);
- }
-
- } // namespace physics
-
- #endif // ANTKEEPER_PHYSICS_FRAME_HPP
|