@ -1,103 +0,0 @@ | |||||
/* | |||||
* Copyright (C) 2023 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_MATH_TRANSFORM_FUNCTIONS_HPP | |||||
#define ANTKEEPER_MATH_TRANSFORM_FUNCTIONS_HPP | |||||
#include <engine/math/transform-type.hpp> | |||||
#include <engine/math/quaternion.hpp> | |||||
namespace math { | |||||
/** | |||||
* Calculates the inverse of a transform. | |||||
* | |||||
* @param t Transform of which to take the inverse. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] transform<T> inverse(const transform<T>& t); | |||||
/** | |||||
* Converts a transform to a transformation matrix. | |||||
* | |||||
* @param t Transform. | |||||
* @return Matrix representing the transformation described by `t`. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] matrix<T, 4, 4> matrix_cast(const transform<T>& t); | |||||
/** | |||||
* Multiplies two transforms. | |||||
* | |||||
* @param x First transform. | |||||
* @param y Second transform. | |||||
* @return Product of the two transforms. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] transform<T> mul(const transform<T>& x, const transform<T>& y); | |||||
/** | |||||
* Multiplies a vector by a transform. | |||||
* | |||||
* @param t Transform. | |||||
* @param v Vector. | |||||
* @return Product of the transform and vector. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] vector<T, 3> mul(const transform<T>& t, const vector<T, 3>& v); | |||||
template <class T> | |||||
transform<T> inverse(const transform<T>& t) | |||||
{ | |||||
transform<T> inverse_t; | |||||
inverse_t.scale = {T(1) / t.scale.x(), T(1) / t.scale.y(), T(1) / t.scale.z()}; | |||||
inverse_t.rotation = conjugate(t.rotation); | |||||
inverse_t.translation = negate(mul(inverse_t.rotation, t.translation)); | |||||
return inverse_t; | |||||
} | |||||
template <class T> | |||||
matrix<T, 4, 4> matrix_cast(const transform<T>& t) | |||||
{ | |||||
matrix<T, 4, 4> transformation = matrix<T, 4, 4>(matrix<T, 3, 3>(t.rotation)); | |||||
transformation[3] = {t.translation[0], t.translation[1], t.translation[2], T(1)}; | |||||
return scale(transformation, t.scale); | |||||
} | |||||
template <class T> | |||||
transform<T> mul(const transform<T>& x, const transform<T>& y) | |||||
{ | |||||
return | |||||
{ | |||||
mul(x, y.translation), | |||||
normalize(mul(x.rotation, y.rotation)), | |||||
mul(x.scale, y.scale) | |||||
}; | |||||
} | |||||
template <class T> | |||||
vector<T, 3> mul(const transform<T>& t, const vector<T, 3>& v) | |||||
{ | |||||
return add(t.translation, (mul(t.rotation, mul(v, t.scale)))); | |||||
} | |||||
} // namespace math | |||||
#endif // ANTKEEPER_MATH_TRANSFORM_FUNCTIONS_HPP | |||||
@ -1,63 +0,0 @@ | |||||
/* | |||||
* Copyright (C) 2023 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_MATH_TRANSFORM_OPERATORS_HPP | |||||
#define ANTKEEPER_MATH_TRANSFORM_OPERATORS_HPP | |||||
#include <engine/math/transform-type.hpp> | |||||
#include <engine/math/transform-functions.hpp> | |||||
/// @copydoc math::mul(const math::transform<T>&, const math::transform<T>&) | |||||
template <class T> | |||||
[[nodiscard]] math::transform<T> operator*(const math::transform<T>& x, const math::transform<T>& y); | |||||
/// @copydoc math::mul(const math::transform<T>&, const math::vector<T, 3>&) | |||||
template <class T> | |||||
[[nodiscard]] math::vector<T, 3> operator*(const math::transform<T>& t, const math::vector<T, 3>& v); | |||||
/** | |||||
* Multiplies two transforms and stores the result in the first transform. | |||||
* | |||||
* @param x First transform. | |||||
* @param y Second transform. | |||||
* @return Reference to the first transform. | |||||
*/ | |||||
template <class T> | |||||
math::transform<T>& operator*=(math::transform<T>& x, const math::transform<T>& y); | |||||
template <class T> | |||||
inline math::transform<T> operator*(const math::transform<T>& x, const math::transform<T>& y) | |||||
{ | |||||
return mul(x, y); | |||||
} | |||||
template <class T> | |||||
inline math::vector<T, 3> operator*(const math::transform<T>& t, const math::vector<T, 3>& v) | |||||
{ | |||||
return mul(t, v); | |||||
} | |||||
template <class T> | |||||
inline math::transform<T>& operator*=(math::transform<T>& x, const math::vector<T, 3>& y) | |||||
{ | |||||
return (x = x * y); | |||||
} | |||||
#endif // ANTKEEPER_MATH_TRANSFORM_OPERATORS_HPP | |||||
@ -1,59 +0,0 @@ | |||||
/* | |||||
* Copyright (C) 2023 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_MATH_TRANSFORM_TYPE_HPP | |||||
#define ANTKEEPER_MATH_TRANSFORM_TYPE_HPP | |||||
#include <engine/math/vector.hpp> | |||||
#include <engine/math/quaternion.hpp> | |||||
namespace math { | |||||
/** | |||||
* Represents 3D TRS transformation. | |||||
* | |||||
* @tparam T Scalar type. | |||||
*/ | |||||
template <class T> | |||||
struct transform | |||||
{ | |||||
/// Translation vector | |||||
vector<T, 3> translation; | |||||
/// Rotation quaternion | |||||
quaternion<T> rotation; | |||||
/// Scale vector | |||||
vector<T, 3> scale; | |||||
/// Identity transform. | |||||
static const transform identity; | |||||
}; | |||||
template <class T> | |||||
const transform<T> transform<T>::identity = | |||||
{ | |||||
vector<T, 3>::zero(), | |||||
quaternion<T>::identity(), | |||||
vector<T, 3>::one() | |||||
}; | |||||
} // namespace math | |||||
#endif // ANTKEEPER_MATH_TRANSFORM_TYPE_HPP |
@ -0,0 +1,235 @@ | |||||
/* | |||||
* Copyright (C) 2023 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_MATH_TRANSFORM_HPP | |||||
#define ANTKEEPER_MATH_TRANSFORM_HPP | |||||
#include <engine/math/vector.hpp> | |||||
#include <engine/math/quaternion.hpp> | |||||
#include <engine/math/matrix.hpp> | |||||
namespace math { | |||||
/** | |||||
* 3D transformation. | |||||
* | |||||
* Transformations are applied in the following order: scale, rotation, translation. | |||||
* | |||||
* @tparam T Scalar type. | |||||
*/ | |||||
template <class T> | |||||
struct transform | |||||
{ | |||||
/// Scalar type. | |||||
using scalar_type = T; | |||||
/// Vector type. | |||||
using vector_type = vector<T, 3>; | |||||
/// Quaternion type. | |||||
using quaternion_type = quaternion<T>; | |||||
/// Transformation matrix type. | |||||
using matrix_type = matrix<T, 4, 4>; | |||||
/// Translation vector. | |||||
vector_type translation; | |||||
/// Rotation quaternion. | |||||
quaternion_type rotation; | |||||
/// Scale vector. | |||||
vector_type scale; | |||||
/** | |||||
* Constructs a matrix representing the transformation. | |||||
* | |||||
* @return Transformation matrix. | |||||
*/ | |||||
/// @{ | |||||
[[nodiscard]] constexpr explicit operator matrix_type() const noexcept | |||||
{ | |||||
matrix_type matrix = matrix_type(quaternion_type::matrix_type(rotation)); | |||||
matrix[0][0] *= scale[0]; | |||||
matrix[0][1] *= scale[0]; | |||||
matrix[0][2] *= scale[0]; | |||||
matrix[1][0] *= scale[1]; | |||||
matrix[1][1] *= scale[1]; | |||||
matrix[1][2] *= scale[1]; | |||||
matrix[2][0] *= scale[2]; | |||||
matrix[2][1] *= scale[2]; | |||||
matrix[2][2] *= scale[2]; | |||||
matrix[3][0] = translation[0]; | |||||
matrix[3][1] = translation[1]; | |||||
matrix[3][2] = translation[2]; | |||||
return matrix; | |||||
} | |||||
[[nodiscard]] inline constexpr matrix_type matrix() const noexcept | |||||
{ | |||||
return matrix_type(*this); | |||||
} | |||||
/// @} | |||||
/* | |||||
* Type-casts the transform scalars using `static_cast`. | |||||
* | |||||
* @tparam U Target scalar type. | |||||
* | |||||
* @return Type-casted transform. | |||||
*/ | |||||
template <class U> | |||||
[[nodiscard]] inline constexpr explicit operator transform<U>() const noexcept | |||||
{ | |||||
return {math::vector<U, 3>(translation), math::quaternion<U>(rotation), math::vector<U, 3>(scale)}; | |||||
} | |||||
/// Returns an identity transform. | |||||
[[nodiscard]] static inline constexpr transform identity() noexcept | |||||
{ | |||||
return {vector_type::zero(), quaternion_type::identity(), vector_type::one()}; | |||||
} | |||||
}; | |||||
/** | |||||
* Calculates the inverse of a transform. | |||||
* | |||||
* @param t Transform of which to take the inverse. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] transform<T> inverse(const transform<T>& t) noexcept; | |||||
/** | |||||
* Combines two transforms. | |||||
* | |||||
* @param x First transform. | |||||
* @param y Second transform. | |||||
* | |||||
* @return Product of the two transforms. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] transform<T> mul(const transform<T>& x, const transform<T>& y); | |||||
/** | |||||
* Transforms a vector by a transform. | |||||
* | |||||
* @param t Transform. | |||||
* @param v Vector. | |||||
* | |||||
* @return Transformed vector. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] constexpr vector<T, 3> mul(const transform<T>& t, const vector<T, 3>& v) noexcept; | |||||
/** | |||||
* Transforms a vector by the inverse of a transform. | |||||
* | |||||
* @param v Vector. | |||||
* @param t Transform. | |||||
* | |||||
* @return Transformed vector. | |||||
*/ | |||||
template <class T> | |||||
[[nodiscard]] constexpr vector<T, 3> mul(const vector<T, 3>& v, const transform<T>& t) noexcept; | |||||
template <class T> | |||||
transform<T> inverse(const transform<T>& t) noexcept | |||||
{ | |||||
transform<T> inverse_t; | |||||
inverse_t.scale = T{1} / t.scale; | |||||
inverse_t.rotation = conjugate(t.rotation); | |||||
inverse_t.translation = -(inverse_t.rotation * t.translation); | |||||
return inverse_t; | |||||
} | |||||
template <class T> | |||||
transform<T> mul(const transform<T>& x, const transform<T>& y) | |||||
{ | |||||
return | |||||
{ | |||||
mul(x, y.translation), | |||||
normalize(x.rotation * y.rotation), | |||||
x.scale * y.scale | |||||
}; | |||||
} | |||||
template <class T> | |||||
constexpr vector<T, 3> mul(const transform<T>& t, const vector<T, 3>& v) noexcept | |||||
{ | |||||
return t.translation + t.rotation * (t.scale * v); | |||||
} | |||||
template <class T> | |||||
inline constexpr vector<T, 3> mul(const vector<T, 3>& v, const transform<T>& t) noexcept | |||||
{ | |||||
return mul(inverse(t), v); | |||||
} | |||||
namespace operators { | |||||
/// @copydoc math::mul(const math::transform<T>&, const math::transform<T>&) | |||||
template <class T> | |||||
[[nodiscard]] inline math::transform<T> operator*(const math::transform<T>& x, const math::transform<T>& y) | |||||
{ | |||||
return mul(x, y); | |||||
} | |||||
/// @copydoc math::mul(const math::transform<T>&, const math::vector<T, 3>&) | |||||
template <class T> | |||||
[[nodiscard]] inline constexpr math::vector<T, 3> operator*(const math::transform<T>& t, const math::vector<T, 3>& v) noexcept | |||||
{ | |||||
return mul(t, v); | |||||
} | |||||
/// @copydoc math::mul(const math::vector<T, 3>&, const math::transform<T>&) | |||||
template <class T> | |||||
[[nodiscard]] inline constexpr math::vector<T, 3> operator*(const math::vector<T, 3>& v, const math::transform<T>& t) noexcept | |||||
{ | |||||
return mul(v, t); | |||||
} | |||||
/** | |||||
* Combines two transforms and stores the result in the first transform. | |||||
* | |||||
* @param x First transform. | |||||
* @param y Second transform. | |||||
* | |||||
* @return Reference to the first transform. | |||||
*/ | |||||
template <class T> | |||||
inline math::transform<T>& operator*=(math::transform<T>& x, const math::transform<T>& y) | |||||
{ | |||||
return (x = x * y); | |||||
} | |||||
} // namespace operators | |||||
} // namespace math | |||||
// Bring transform operators into global namespace | |||||
using namespace math::operators; | |||||
#endif // ANTKEEPER_MATH_TRANSFORM_HPP |