/* * 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 . */ #ifndef ANTKEEPER_PHYSICS_FRAME_HPP #define ANTKEEPER_PHYSICS_FRAME_HPP #include "math/math.hpp" #include namespace physics { /** * 3-dimensional frame of reference. * * @tparam T Scalar type. */ template struct frame { public: /// Scalar type. typedef T scalar_type; /// Vector type. typedef math::vector3 vector_type; /// Quaternion type. typedef math::quaternion quaternion_type; /// Transformation matrix type. typedef math::matrix 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 frame frame::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 typename frame::matrix_type frame::matrix() const { matrix_type m = math::resize<4, 4>(math::matrix_cast(rotation)); m[3].x = translation.x; m[3].y = translation.y; m[3].z = translation.z; return m; } template typename frame::vector_type frame::transform(const vector_type& v) const { return translation + rotation * v; } template frame frame::transform(const frame& f) const { return frame { f.transform(translation), math::normalize(f.rotation * rotation) }; } template typename frame::vector_type frame::operator*(const vector_type& v) const { return transform(v); } template frame frame::operator*(const frame& f) const { return transform(f); } } // namespace physics #endif // ANTKEEPER_PHYSICS_FRAME_HPP