From c753b8182c4e52089a99beaa687c9b5f10043d08 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sun, 23 Oct 2022 02:06:57 +0800 Subject: [PATCH] Improve and consolidate quaternion struct. Add more quaternion operators --- src/ai/steering/agent.hpp | 2 +- src/ai/steering/behavior/wander.cpp | 3 +- src/entity/commands.cpp | 4 +- src/game/ant/morphogenesis.cpp | 2 +- src/game/ant/swarm.cpp | 4 +- src/game/state/splash.cpp | 4 +- src/game/system/astronomy.cpp | 4 +- src/game/system/constraint.cpp | 10 +- src/game/system/steering.cpp | 2 +- src/game/system/terrain.cpp | 2 +- src/game/system/terrain.hpp | 2 +- src/math/linear-algebra.hpp | 27 + src/math/math.hpp | 7 +- src/math/matrix.hpp | 48 +- src/math/operators.hpp | 4 - src/math/polynomial.hpp | 33 - src/math/quaternion-functions.hpp | 510 ------------ src/math/quaternion-operators.hpp | 97 --- src/math/quaternion-type.hpp | 92 --- src/math/quaternion.hpp | 959 ++++++++++++++++++++++ src/math/se3.hpp | 4 +- src/math/stream-operators.hpp | 65 -- src/math/transform-functions.hpp | 2 +- src/math/transform-type.hpp | 8 +- src/math/vector.hpp | 41 +- src/render/passes/material-pass.cpp | 2 +- src/render/passes/shadow-map-pass.cpp | 2 +- src/render/passes/sky-pass.cpp | 4 +- src/render/passes/sky-pass.hpp | 2 +- src/render/renderer.cpp | 2 +- src/resources/entity-archetype-loader.cpp | 8 +- src/resources/model-loader.cpp | 8 +- src/scene/camera.cpp | 2 +- src/scene/directional-light.cpp | 2 +- src/scene/object.hpp | 2 +- src/scene/spot-light.cpp | 2 +- 36 files changed, 1108 insertions(+), 864 deletions(-) create mode 100644 src/math/linear-algebra.hpp delete mode 100644 src/math/quaternion-functions.hpp delete mode 100644 src/math/quaternion-operators.hpp delete mode 100644 src/math/quaternion-type.hpp create mode 100644 src/math/quaternion.hpp delete mode 100644 src/math/stream-operators.hpp diff --git a/src/ai/steering/agent.hpp b/src/ai/steering/agent.hpp index 9abe7f5..ca3f10d 100644 --- a/src/ai/steering/agent.hpp +++ b/src/ai/steering/agent.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_AI_STEERING_AGENT_HPP #include "utility/fundamental-types.hpp" -#include "math/quaternion-type.hpp" +#include "math/quaternion.hpp" namespace ai { namespace steering { diff --git a/src/ai/steering/behavior/wander.cpp b/src/ai/steering/behavior/wander.cpp index 6eb8592..d73a1f2 100644 --- a/src/ai/steering/behavior/wander.cpp +++ b/src/ai/steering/behavior/wander.cpp @@ -20,8 +20,7 @@ #include "ai/steering/behavior/wander.hpp" #include "ai/steering/behavior/seek.hpp" #include "math/random.hpp" -#include "math/quaternion-functions.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" namespace ai { namespace steering { diff --git a/src/entity/commands.cpp b/src/entity/commands.cpp index 2c141b1..db6d924 100644 --- a/src/entity/commands.cpp +++ b/src/entity/commands.cpp @@ -23,9 +23,7 @@ #include "game/component/parent.hpp" #include "game/component/celestial-body.hpp" #include "game/component/terrain.hpp" -#include "math/quaternion-type.hpp" -#include "math/quaternion-operators.hpp" -#include "math/quaternion-functions.hpp" +#include "math/quaternion.hpp" #include namespace entity { diff --git a/src/game/ant/morphogenesis.cpp b/src/game/ant/morphogenesis.cpp index e588a07..1c007e1 100644 --- a/src/game/ant/morphogenesis.cpp +++ b/src/game/ant/morphogenesis.cpp @@ -21,7 +21,7 @@ #include "render/material.hpp" #include "render/vertex-attribute.hpp" #include "math/transform-operators.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include #include diff --git a/src/game/ant/swarm.cpp b/src/game/ant/swarm.cpp index 680bcbd..2ffdfe5 100644 --- a/src/game/ant/swarm.cpp +++ b/src/game/ant/swarm.cpp @@ -23,7 +23,7 @@ #include "game/component/model.hpp" #include "game/component/picking.hpp" #include "resources/resource-manager.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "config.hpp" #include #include @@ -99,7 +99,7 @@ entity::id create_swarm(game::context& ctx) steering.agent.max_force = 4.0f; steering.agent.max_speed = 5.0f; steering.agent.max_speed_squared = steering.agent.max_speed * steering.agent.max_speed; - steering.agent.orientation = math::quaternion::identity; + steering.agent.orientation = math::quaternion::identity(); steering.agent.forward = steering.agent.orientation * config::global_forward; steering.agent.up = steering.agent.orientation * config::global_up; steering.wander_weight = 1.0f; diff --git a/src/game/state/splash.cpp b/src/game/state/splash.cpp index e69d9fc..6729405 100644 --- a/src/game/state/splash.cpp +++ b/src/game/state/splash.cpp @@ -29,7 +29,7 @@ #include "debug/logger.hpp" #include "resources/resource-manager.hpp" #include "render/material-flags.hpp" -#include "math/matrix.hpp" +#include "math/linear-algebra.hpp" #include namespace game { @@ -37,7 +37,7 @@ namespace state { splash::splash(game::context& ctx): game::state::base(ctx) -{ +{ ctx.logger->push_task("Entering splash state"); // Enable color buffer clearing in UI pass diff --git a/src/game/system/astronomy.cpp b/src/game/system/astronomy.cpp index 098a3dd..955fc60 100644 --- a/src/game/system/astronomy.cpp +++ b/src/game/system/astronomy.cpp @@ -158,7 +158,7 @@ void astronomy::update(double t, double dt) if (orbit.parent != entt::null) { transform.local.translation = math::normalize(float3(r_eus)); - transform.local.rotation = math::type_cast(rotation_eus); + transform.local.rotation = math::quaternion(rotation_eus); transform.local.scale = {1.0f, 1.0f, 1.0f}; } }); @@ -581,7 +581,7 @@ void astronomy::update_icrf_to_eus(const game::component::celestial_body& body, math::transformation::se3 { float3(icrf_to_eus.t), - math::type_cast(icrf_to_eus.r) + math::quaternion(icrf_to_eus.r) } ); } diff --git a/src/game/system/constraint.cpp b/src/game/system/constraint.cpp index c5334ed..c135081 100644 --- a/src/game/system/constraint.cpp +++ b/src/game/system/constraint.cpp @@ -19,7 +19,7 @@ #include "game/system/constraint.hpp" #include "game/component/constraint-stack.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/transform-operators.hpp" namespace game { @@ -311,13 +311,7 @@ void constraint::handle_spring_to_constraint(component::transform& transform, co if (constraint.spring_rotation) { // Update rotation spring target - constraint.rotation.x1 = - { - target_transform->world.rotation.w, - target_transform->world.rotation.x, - target_transform->world.rotation.y, - target_transform->world.rotation.z - }; + constraint.rotation.x1 = float4(target_transform->world.rotation); // Solve rotation spring solve_numeric_spring(constraint.rotation, dt); diff --git a/src/game/system/steering.cpp b/src/game/system/steering.cpp index 2a51f0c..071cc87 100644 --- a/src/game/system/steering.cpp +++ b/src/game/system/steering.cpp @@ -23,7 +23,7 @@ #include "entity/id.hpp" #include "ai/steering/behavior/wander.hpp" #include "ai/steering/behavior/seek.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "config.hpp" namespace game { diff --git a/src/game/system/terrain.cpp b/src/game/system/terrain.cpp index 878c05d..5e996e6 100644 --- a/src/game/system/terrain.cpp +++ b/src/game/system/terrain.cpp @@ -26,7 +26,7 @@ #include "geom/quadtree.hpp" #include "geom/primitive/ray.hpp" #include "gl/vertex-attribute.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "render/vertex-attribute.hpp" #include "utility/fundamental-types.hpp" #include diff --git a/src/game/system/terrain.hpp b/src/game/system/terrain.hpp index c65b930..fb32ed3 100644 --- a/src/game/system/terrain.hpp +++ b/src/game/system/terrain.hpp @@ -23,7 +23,7 @@ #include "game/system/updatable.hpp" #include "game/component/terrain.hpp" #include "entity/id.hpp" -#include "math/quaternion-type.hpp" +#include "math/quaternion.hpp" #include "geom/quadtree.hpp" #include "geom/mesh.hpp" #include "utility/fundamental-types.hpp" diff --git a/src/math/linear-algebra.hpp b/src/math/linear-algebra.hpp new file mode 100644 index 0000000..271c485 --- /dev/null +++ b/src/math/linear-algebra.hpp @@ -0,0 +1,27 @@ +/* + * 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_MATH_LINEAR_ALGEBRA_HPP +#define ANTKEEPER_MATH_LINEAR_ALGEBRA_HPP + +#include "math/matrix.hpp" +#include "math/quaternion.hpp" +#include "math/vector.hpp" + +#endif // ANTKEEPER_MATH_LINEAR_ALGEBRA_HPP diff --git a/src/math/math.hpp b/src/math/math.hpp index fd4d678..635231f 100644 --- a/src/math/math.hpp +++ b/src/math/math.hpp @@ -25,18 +25,13 @@ namespace math {} #include "math/vector.hpp" #include "math/matrix.hpp" - -#include "math/quaternion-type.hpp" -#include "math/quaternion-functions.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/se3.hpp" #include "math/transform-type.hpp" #include "math/transform-functions.hpp" #include "math/transform-operators.hpp" -#include "math/stream-operators.hpp" - #include "math/angles.hpp" #include "math/constants.hpp" #include "math/quadrature.hpp" diff --git a/src/math/matrix.hpp b/src/math/matrix.hpp index a6a98a2..4881e2d 100644 --- a/src/math/matrix.hpp +++ b/src/math/matrix.hpp @@ -365,7 +365,7 @@ constexpr T determinant(const matrix& m) noexcept; /** * Calculates the inverse of a square matrix. * - * @param m Matrix of which to take the inverse. + * @param m Square matrix. * * @return Inverse of matrix @p m. * @@ -379,6 +379,8 @@ constexpr matrix inverse(const matrix& m) noexcept; * * @param x First matrix multiplicand. * @param y Second matrix multiplicand. + * + * @return Product of the component-wise multiplcation. */ template constexpr matrix componentwise_mul(const matrix& a, const matrix& b) noexcept; @@ -388,6 +390,7 @@ constexpr matrix componentwise_mul(const matrix& a, const matr * * @param a First matrix. * @param b Second matrix. + * * @return Result of the division. */ template @@ -398,6 +401,7 @@ constexpr matrix div(const matrix& a, const matrix& b * * @param a Matrix. * @param b Scalar. + * * @return Result of the division. */ template @@ -408,6 +412,7 @@ constexpr matrix div(const matrix& a, T b) noexcept; * * @param a Scalar. * @param b Matrix. + * * @return Result of the division. */ template @@ -419,6 +424,7 @@ constexpr matrix div(T a, const matrix& b) noexcept; * @param position Position of the view point. * @param target Position of the target. * @param up Normalized direction of the up vector. + * * @return Viewing transformation matrix. */ template @@ -445,6 +451,7 @@ constexpr matrix mul(const matrix& a, const matrix& b * * @param a Matrix. * @param b Scalar. + * * @return Product of the matrix and the scalar. */ template @@ -476,7 +483,8 @@ constexpr typename matrix::row_vector_type mul(const typename matrix @@ -486,6 +494,7 @@ matrix rotate(T angle, const vector& axis); * Produces a matrix which rotates Cartesian coordinates about the x-axis by a given angle. * * @param angle Angle of rotation, in radians. + * * @return Rotation matrix. */ template @@ -495,6 +504,7 @@ matrix3 rotate_x(T angle); * Produces a matrix which rotates Cartesian coordinates about the y-axis by a given angle. * * @param angle Angle of rotation, in radians. + * * @return Rotation matrix. */ template @@ -504,6 +514,7 @@ matrix3 rotate_y(T angle); * Produces a matrix which rotates Cartesian coordinates about the z-axis by a given angle. * * @param angle Angle of rotation, in radians. + * * @return Rotation matrix. */ template @@ -514,6 +525,7 @@ matrix3 rotate_z(T angle); * * @param m Matrix to scale. * @param v Scale vector. + * * @return Scaled matrix. */ template @@ -552,11 +564,22 @@ constexpr matrix sub(const matrix& a, T b) noexcept; template constexpr matrix sub(T a, const matrix& b) noexcept; +/** + * Calculates the trace of a square matrix. + * + * @param m Square matrix. + * + * @return Sum of elements on the main diagonal. + */ +template +constexpr T trace(const matrix& m) noexcept; + /** * Translates a matrix. * * @param m Matrix to translate. * @param v Translation vector. + * * @return Translated matrix. */ template @@ -942,6 +965,19 @@ constexpr matrix sub(T a, const matrix& b) noexcept return sub(a, b, std::make_index_sequence{}); } +/// @private +template +constexpr inline T trace(const matrix& m, std::index_sequence) noexcept +{ + return ((m[I][I]) + ...); +} + +template +constexpr T trace(const matrix& m) noexcept +{ + return trace(m, std::make_index_sequence{}); +} + template constexpr matrix translate(const matrix& m, const vector& v) { @@ -1079,6 +1115,7 @@ constexpr inline matrix operator-(T a, const matrix& b) noexce * * @param a First value. * @param b Second value. + * * @return Reference to the first value. */ /// @{ @@ -1099,6 +1136,7 @@ constexpr inline matrix& operator+=(matrix& a, T b) noexcept * * @param a First value. * @param b Second value. + * * @return Reference to the first value. */ /// @{ @@ -1119,11 +1157,12 @@ constexpr inline matrix& operator-=(matrix& a, T b) noexcept * * @param a First value. * @param b Second value. + * * @return Reference to the first value. */ /// @{ template -constexpr inline matrix& operator*=(matrix& a, matrix& b) noexcept +constexpr inline matrix& operator*=(matrix& a, const matrix& b) noexcept { return (a = a * b); } @@ -1139,6 +1178,7 @@ constexpr inline matrix& operator*=(matrix& a, T b) noexcept * * @param a First value. * @param b Second value. + * * @return Reference to the first value. */ /// @{ @@ -1159,6 +1199,7 @@ constexpr inline matrix& operator/=(matrix& a, T b) noexcept * * @param os Output stream. * @param m Matrix. + * * @return Output stream. */ template @@ -1179,6 +1220,7 @@ std::ostream& operator<<(std::ostream& os, const matrix& m) * * @param is Input stream. * @param m Matrix. + * * @return Input stream. */ template diff --git a/src/math/operators.hpp b/src/math/operators.hpp index 0387520..fcc46a3 100644 --- a/src/math/operators.hpp +++ b/src/math/operators.hpp @@ -20,10 +20,6 @@ #ifndef ANTKEEPER_MATH_OPERATORS_HPP #define ANTKEEPER_MATH_OPERATORS_HPP -#include "math/quaternion-operators.hpp" -#include "math/transform-operators.hpp" -#include "math/stream-operators.hpp" - namespace math { /// Mathematical operators. diff --git a/src/math/polynomial.hpp b/src/math/polynomial.hpp index a489807..82579ea 100644 --- a/src/math/polynomial.hpp +++ b/src/math/polynomial.hpp @@ -52,39 +52,6 @@ T horner(InputIt first, InputIt last, T x) */ namespace chebyshev { - /** - * Generates a Chebyshev approximation of a function. - * - * @param[out] first,last Range of Chebyshev polynomial coefficients. - * @param[in] f Unary function to approximate. - * @param[in] min,max Domain of @p f. - */ - template - void approximate(OutputIt first, OutputIt last, UnaryOp f, T min, T max) - { - std::size_t n = last - first; - const T two_over_n = T(2) / static_cast(n); - const T pi_over_n = math::pi / static_cast(n); - - last = first; - for (std::size_t i = 0; i < n; ++i) - *(last++) = T(0); - - for (std::size_t i = 0; i < n; ++i) - { - const T y = pi_over_n * (static_cast(i) + T(0.5)); - - T x = f(math::map(std::cos(y), T(-1), T(1), min, max)) * two_over_n; - - *first += x; - last = first; - for (std::size_t j = 1; j < n; ++j) - { - *(++last) += x * std::cos(y * static_cast(j)); - } - } - } - /** * Evaluates a Chebyshev polynomial. * diff --git a/src/math/quaternion-functions.hpp b/src/math/quaternion-functions.hpp deleted file mode 100644 index c838f0e..0000000 --- a/src/math/quaternion-functions.hpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * 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_MATH_QUATERNION_FUNCTIONS_HPP -#define ANTKEEPER_MATH_QUATERNION_FUNCTIONS_HPP - -#include "math/constants.hpp" -#include "math/matrix.hpp" -#include "math/quaternion-type.hpp" -#include "math/vector.hpp" -#include - -namespace math { - -/** - * Adds two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @return Sum of the two quaternions. - */ -template -quaternion add(const quaternion& x, const quaternion& y); - -/** - * Calculates the conjugate of a quaternion. - * - * @param x Quaternion from which the conjugate will be calculated. - * @return Conjugate of the quaternion. - */ -template -quaternion conjugate(const quaternion& x); - -/** - * Calculates the dot product of two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @return Dot product of the two quaternions. - */ -template -T dot(const quaternion& x, const quaternion& y); - -/** - * Divides a quaternion by a scalar. - * - * @param q Quaternion. - * @param s Scalar. - * @return Result of the division. - */ -template -quaternion div(const quaternion& q, T s); - -/** - * Calculates the length of a quaternion. - * - * @param x Quaternion to calculate the length of. - * @return Length of the quaternion. - */ -template -T length(const quaternion& x); - -/** - * Calculates the squared length of a quaternion. The squared length can be calculated faster than the length because a call to `std::sqrt` is saved. - * - * @param x Quaternion to calculate the squared length of. - * @return Squared length of the quaternion. - */ -template -T length_squared(const quaternion& x); - -/** - * Performs linear interpolation between two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @param a Interpolation factor. - * @return Interpolated quaternion. - */ -template -quaternion lerp(const quaternion& x, const quaternion& y, T a); - -/** - * Creates a unit quaternion rotation using forward and up vectors. - * - * @param forward Unit forward vector. - * @param up Unit up vector. - * @return Unit rotation quaternion. - */ -template -quaternion look_rotation(const vector& forward, vector up); - -/** - * Converts a quaternion to a rotation matrix. - * - * @param q Unit quaternion. - * @return Matrix representing the rotation described by `q`. - */ -template -matrix matrix_cast(const quaternion& q); - -/** - * Multiplies two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @return Product of the two quaternions. - */ -template -quaternion mul(const quaternion& x, const quaternion& y); - -/** - * Multiplies a quaternion by a scalar. - * - * @param q Quaternion. - * @param s Scalar. - * @return Product of the quaternion and scalar. - */ -template -quaternion mul(const quaternion& q, T s); - -/** - * Rotates a 3-dimensional vector by a quaternion. - * - * @param q Unit quaternion. - * @param v Vector. - * @return Rotated vector. - */ -template -vector mul(const quaternion& q, const vector& v); - -/** - * Negates a quaternion. - */ -template -quaternion negate(const quaternion& x); - -/** - * Performs normalized linear interpolation between two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @param a Interpolation factor. - * @return Interpolated quaternion. - */ -template -quaternion nlerp(const quaternion& x, const quaternion& y, T a); - -/** - * Normalizes a quaternion. - */ -template -quaternion normalize(const quaternion& x); - -/** - * Creates a rotation from an angle and axis. - * - * @param angle Angle of rotation (in radians). - * @param axis Axis of rotation - * @return Quaternion representing the rotation. - */ -template -quaternion angle_axis(T angle, const vector& axis); - -/** - * Calculates the minimum rotation between two normalized direction vectors. - * - * @param source Normalized source direction. - * @param destination Normalized destination direction. - * @return Quaternion representing the minimum rotation between the source and destination vectors. - */ -template -quaternion rotation(const vector& source, const vector& destination); - -/** - * Performs spherical linear interpolation between two quaternions. - * - * @param x First quaternion. - * @param y Second quaternion. - * @param a Interpolation factor. - * @return Interpolated quaternion. - */ -template -quaternion slerp(const quaternion& x, const quaternion& y, T a); - -/** - * Subtracts a quaternion from another quaternion. - * - * @param x First quaternion. - * @param y Second quaternion. - * @return Difference between the quaternions. - */ -template -quaternion sub(const quaternion& x, const quaternion& y); - -/** - * Decomposes a quaternion into swing and twist rotation components. - * - * @param[in] q Quaternion to decompose. - * @param[in] a Axis of twist rotation. - * @param[out] swing Swing rotation component. - * @param[out] twist Twist rotation component. - * @param[in] epsilon Threshold at which a number is considered zero. - * - * @see https://www.euclideanspace.com/maths/geometry/rotations/for/decomposition/ - */ -template -void swing_twist(const quaternion& q, const vector& a, quaternion& qs, quaternion& qt, T epsilon = T(1e-6)); - -/** - * Converts a 3x3 rotation matrix to a quaternion. - * - * @param m Rotation matrix. - * @return Unit quaternion representing the rotation described by `m`. - */ -template -quaternion quaternion_cast(const matrix& m); - -/** - * Types casts each quaternion component and returns a quaternion of the casted type. - * - * @tparam T2 Target quaternion component type. - * @tparam T1 Source quaternion component type. - * @param q Quaternion to type cast. - * @return Type-casted quaternion. - */ -template -quaternion type_cast(const quaternion& q); - -template -inline quaternion add(const quaternion& x, const quaternion& y) -{ - return {x.w + y.w, x.x + y.x, x.y + y.y, x.z + y.z}; -} - -template -inline quaternion conjugate(const quaternion& x) -{ - return {x.w, -x.x, -x.y, -x.z}; -} - -template -inline T dot(const quaternion& x, const quaternion& y) -{ - return {x.w * y.w + x.x * y.x + x.y * y.y + x.z * y.z}; -} - -template -inline quaternion div(const quaternion& q, T s) -{ - return {q.w / s, q.x / s, q.y / s, q.z / s} -} - -template -inline T length(const quaternion& x) -{ - return std::sqrt(x.w * x.w + x.x * x.x + x.y * x.y + x.z * x.z); -} - -template -inline T length_squared(const quaternion& x) -{ - return x.w * x.w + x.x * x.x + x.y * x.y + x.z * x.z; -} - -template -inline quaternion lerp(const quaternion& x, const quaternion& y, T a) -{ - return - { - (y.w - x.w) * a + x.w, - (y.x - x.x) * a + x.x, - (y.y - x.y) * a + x.y, - (y.z - x.z) * a + x.z - }; -} - -template -quaternion look_rotation(const vector& forward, vector up) -{ - vector right = normalize(cross(forward, up)); - up = cross(right, forward); - - matrix m = - { - right, - up, - -forward - }; - - // Convert to quaternion - return normalize(quaternion_cast(m)); -} - -template -matrix matrix_cast(const quaternion& q) -{ - const T xx = q.x * q.x; - const T xy = q.x * q.y; - const T xz = q.x * q.z; - const T xw = q.x * q.w; - const T yy = q.y * q.y; - const T yz = q.y * q.z; - const T yw = q.y * q.w; - const T zz = q.z * q.z; - const T zw = q.z * q.w; - - return - { - T(1) - (yy + zz) * T(2), (xy + zw) * T(2), (xz - yw) * T(2), - (xy - zw) * T(2), T(1) - (xx + zz) * T(2), (yz + xw) * T(2), - (xz + yw) * T(2), (yz - xw) * T(2), T(1) - (xx + yy) * T(2) - }; -} - -template -quaternion mul(const quaternion& x, const quaternion& y) -{ - return - { - -x.x * y.x - x.y * y.y - x.z * y.z + x.w * y.w, - x.x * y.w + x.y * y.z - x.z * y.y + x.w * y.x, - -x.x * y.z + x.y * y.w + x.z * y.x + x.w * y.y, - x.x * y.y - x.y * y.x + x.z * y.w + x.w * y.z - }; -} - -template -inline quaternion mul(const quaternion& q, T s) -{ - return {q.w * s, q.x * s, q.y * s, q.z * s}; -} - -template -vector mul(const quaternion& q, const vector& v) -{ - const vector& i = reinterpret_cast&>(q.x); - return add(add(mul(i, dot(i, v) * T(2)), mul(v, (q.w * q.w - dot(i, i)))), mul(cross(i, v), q.w * T(2))); -} - -template -inline quaternion negate(const quaternion& x) -{ - return {-x.w, -x.x, -x.y, -x.z}; -} - -template -quaternion nlerp(const quaternion& x, const quaternion& y, T a) -{ - return normalize(add(mul(x, T(1) - a), mul(y, a * std::copysign(T(1), dot(x, y))))); -} - -template -inline quaternion normalize(const quaternion& x) -{ - return mul(x, T(1) / length(x)); -} - -template -quaternion angle_axis(T angle, const vector& axis) -{ - T s = std::sin(angle * T(0.5)); - return {static_cast(std::cos(angle * T(0.5))), axis.x() * s, axis.y() * s, axis.z() * s}; -} - -template -quaternion rotation(const vector& source, const vector& destination) -{ - quaternion q; - q.w = dot(source, destination); - reinterpret_cast&>(q.x) = cross(source, destination); - - q.w += length(q); - return normalize(q); -} - -template -quaternion slerp(const quaternion& x, const quaternion& y, T a) -{ - T cos_theta = dot(x, y); - - constexpr T epsilon = T(0.0005); - if (cos_theta > T(1) - epsilon) - { - return normalize(lerp(x, y, a)); - } - - cos_theta = std::max(T(-1), std::min(T(1), cos_theta)); - T theta = static_cast(std::acos(cos_theta)) * a; - - quaternion z = normalize(sub(y, mul(x, cos_theta))); - - return add(mul(x, static_cast(std::cos(theta))), mul(z, static_cast(std::sin(theta)))); -} - -template -inline quaternion sub(const quaternion& x, const quaternion& y) -{ - return {x.w - y.w, x.x - y.x, x.y - y.y, x.z - y.z}; -} - -template -void swing_twist(const quaternion& q, const vector& a, quaternion& qs, quaternion& qt, T epsilon) -{ - if (q.x * q.x + q.y * q.y + q.z * q.z > epsilon) - { - const vector pa = mul(a, (a.x() * q.x + a.y() * q.y + a.z() * q.z)); - qt = normalize(quaternion{q.w, pa.x(), pa.y(), pa.z()}); - qs = mul(q, conjugate(qt)); - } - else - { - qt = angle_axis(pi, a); - - const vector qa = mul(q, a); - const vector sa = cross(a, qa); - if (length_squared(sa) > epsilon) - qs = angle_axis(std::acos(dot(a, qa)), sa); - else - qs = quaternion::identity; - } -} - -template -quaternion quaternion_cast(const matrix& m) -{ - T trace = m[0][0] + m[1][1] + m[2][2]; - - if (trace > T(0)) - { - T s = T(0.5) / std::sqrt(trace + T(1)); - return - { - T(0.25) / s, - (m[1][2] - m[2][1]) * s, - (m[2][0] - m[0][2]) * s, - (m[0][1] - m[1][0]) * s - }; - } - else - { - if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) - { - T s = T(2) * std::sqrt(T(1) + m[0][0] - m[1][1] - m[2][2]); - - return - { - (m[1][2] - m[2][1]) / s, - T(0.25) * s, - (m[1][0] + m[0][1]) / s, - (m[2][0] + m[0][2]) / s - }; - } - else if (m[1][1] > m[2][2]) - { - T s = T(2) * std::sqrt(T(1) + m[1][1] - m[0][0] - m[2][2]); - return - { - (m[2][0] - m[0][2]) / s, - (m[1][0] + m[0][1]) / s, - T(0.25) * s, - (m[2][1] + m[1][2]) / s - }; - } - else - { - T s = T(2) * std::sqrt(T(1) + m[2][2] - m[0][0] - m[1][1]); - return - { - (m[0][1] - m[1][0]) / s, - (m[2][0] + m[0][2]) / s, - (m[2][1] + m[1][2]) / s, - T(0.25) * s - }; - } - } -} - -template -inline quaternion type_cast(const quaternion& q) -{ - return quaternion - { - static_cast(q.w), - static_cast(q.x), - static_cast(q.y), - static_cast(q.z) - }; -} - -} // namespace math - -#endif // ANTKEEPER_MATH_QUATERNION_FUNCTIONS_HPP - diff --git a/src/math/quaternion-operators.hpp b/src/math/quaternion-operators.hpp deleted file mode 100644 index c71b887..0000000 --- a/src/math/quaternion-operators.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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_MATH_QUATERNION_OPERATORS_HPP -#define ANTKEEPER_MATH_QUATERNION_OPERATORS_HPP - -#include "math/quaternion-type.hpp" -#include "math/quaternion-functions.hpp" - -/// @copydoc math::add(const math::quaternion&, const math::quaternion&) -template -math::quaternion operator+(const math::quaternion& x, const math::quaternion& y); - -/// @copydoc math::div(const math::quaternion&, T) -template -math::quaternion operator/(const math::quaternion& q, T s); - -/// @copydoc math::mul(const math::quaternion&, const math::quaternion&) -template -math::quaternion operator*(const math::quaternion& x, const math::quaternion& y); - -/// @copydoc math::mul(const math::quaternion&, T) -template -math::quaternion operator*(const math::quaternion& q, T s); - -/// @copydoc math::mul(const math::quaternion&, const math::vector&) -template -math::vector operator*(const math::quaternion& q, const math::vector& v); - -/// @copydoc math::sub(const math::quaternion&, const math::quaternion&) -template -math::quaternion operator-(const math::quaternion& x, const math::quaternion& y); - -/// @copydoc math::negate(const math::quaternion&) -template -math::quaternion operator-(const math::quaternion& x); - -template -inline math::quaternion operator+(const math::quaternion& x, const math::quaternion& y) -{ - return add(x, y); -} - -template -inline math::quaternion operator/(const math::quaternion& q, T s) -{ - return div(q, s); -} - -template -inline math::quaternion operator*(const math::quaternion& x, const math::quaternion& y) -{ - return mul(x, y); -} - -template -inline math::quaternion operator*(const math::quaternion& q, T s) -{ - return mul(q, s); -} - -template -inline math::vector operator*(const math::quaternion& q, const math::vector& v) -{ - return mul(q, v); -} - -template -inline math::quaternion operator-(const math::quaternion& x, const math::quaternion& y) -{ - return sub(x, y); -} - -template -inline math::quaternion operator-(const math::quaternion& x) -{ - return negate(x); -} - -#endif // ANTKEEPER_MATH_QUATERNION_OPERATORS_HPP - diff --git a/src/math/quaternion-type.hpp b/src/math/quaternion-type.hpp deleted file mode 100644 index 14eb95f..0000000 --- a/src/math/quaternion-type.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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_MATH_QUATERNION_TYPE_HPP -#define ANTKEEPER_MATH_QUATERNION_TYPE_HPP - -#include - -namespace math { - -/** - * A quaternion type is a tuple made of a scalar (real) part and vector (imaginary) part. - * - * @tparam T Scalar type. - */ -template -struct quaternion -{ - typedef T scalar_type; - scalar_type w; - scalar_type x; - scalar_type y; - scalar_type z; - - /// Rotation identity quaternion. - static const quaternion identity; - - /** - * Returns a quaternion representing a rotation about the x-axis. - * - * @param angle Angle of rotation, in radians. - * @return Quaternion representing an x-axis rotation. - */ - static quaternion rotate_x(scalar_type angle); - - /** - * Returns a quaternion representing a rotation about the y-axis. - * - * @param angle Angle of rotation, in radians. - * @return Quaternion representing an y-axis rotation. - */ - static quaternion rotate_y(scalar_type angle); - - /** - * Returns a quaternion representing a rotation about the z-axis. - * - * @param angle Angle of rotation, in radians. - * @return Quaternion representing an z-axis rotation. - */ - static quaternion rotate_z(scalar_type angle); -}; - -template -constexpr quaternion quaternion::identity = {T(1), T(0), T(0), T(0)}; - -template -quaternion quaternion::rotate_x(scalar_type angle) -{ - return {std::cos(angle * T(0.5)), std::sin(angle * T(0.5)), T(0), T(0)}; -} - -template -quaternion quaternion::rotate_y(scalar_type angle) -{ - return {std::cos(angle * T(0.5)), T(0), std::sin(angle * T(0.5)), T(0)}; -} - -template -quaternion quaternion::rotate_z(scalar_type angle) -{ - return {std::cos(angle * T(0.5)), T(0), T(0), std::sin(angle * T(0.5))}; -} - -} // namespace math - -#endif // ANTKEEPER_MATH_QUATERNION_TYPE_HPP diff --git a/src/math/quaternion.hpp b/src/math/quaternion.hpp new file mode 100644 index 0000000..bcefa78 --- /dev/null +++ b/src/math/quaternion.hpp @@ -0,0 +1,959 @@ +/* + * 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_MATH_QUATERNION_HPP +#define ANTKEEPER_MATH_QUATERNION_HPP + +#include "math/constants.hpp" +#include "math/matrix.hpp" +#include "math/vector.hpp" +#include +#include +#include + +namespace math { + +/** + * A quaternion type is a tuple made of a scalar (real) part and vector (imaginary) part. + * + * @tparam T Scalar type. + */ +template +struct quaternion +{ + /// Scalar type. + typedef T scalar_type; + + /// Vector type. + typedef vector vector_type; + + /// Rotation matrix type. + typedef matrix matrix_type; + + /// Quaternion real part. + scalar_type r; + + /// Quaternion imaginary part. + vector_type i; + + /// Returns a reference to the quaternion real part. + /// @{ + constexpr inline scalar_type& w() noexcept + { + return r; + } + constexpr inline const scalar_type& w() const noexcept + { + return r; + } + /// @} + + /// Returns a reference to the first element of the quaternion imaginary part. + /// @{ + constexpr inline scalar_type& x() noexcept + { + return i.x(); + } + constexpr inline const scalar_type& x() const noexcept + { + return i.x(); + } + /// @} + + /// Returns a reference to the second element of the quaternion imaginary part. + /// @{ + constexpr inline scalar_type& y() noexcept + { + return i.y(); + } + constexpr inline const scalar_type& y() const noexcept + { + return i.y(); + } + /// @} + + /// Returns a reference to the third element of the quaternion imaginary part. + /// @{ + constexpr inline scalar_type& z() noexcept + { + return i.z(); + } + constexpr inline const scalar_type& z() const noexcept + { + return i.z(); + } + /// @} + + /** + * Returns a quaternion representing a rotation about the x-axis. + * + * @param angle Angle of rotation, in radians. + * + * @return Quaternion representing an x-axis rotation. + */ + static quaternion rotate_x(scalar_type angle) + { + return {std::cos(angle * T(0.5)), std::sin(angle * T(0.5)), T(0), T(0)}; + } + + /** + * Returns a quaternion representing a rotation about the y-axis. + * + * @param angle Angle of rotation, in radians. + * + * @return Quaternion representing an y-axis rotation. + */ + static quaternion rotate_y(scalar_type angle) + { + return {std::cos(angle * T(0.5)), T(0), std::sin(angle * T(0.5)), T(0)}; + } + + /** + * Returns a quaternion representing a rotation about the z-axis. + * + * @param angle Angle of rotation, in radians. + * @return Quaternion representing an z-axis rotation. + */ + static quaternion rotate_z(scalar_type angle) + { + return {std::cos(angle * T(0.5)), T(0), T(0), std::sin(angle * T(0.5))}; + } + + /** + * Type-casts the quaternion scalars using `static_cast`. + * + * @tparam U Target scalar type. + * + * @return Type-casted quaternion. + */ + template + constexpr inline explicit operator quaternion() const noexcept + { + return {static_cast(r), vector(i)}; + } + + /** + * Casts the quaternion to a 4-element vector, with the real part as the first element and the imaginary part as the following three elements. + * + * @return Vector containing the real and imaginary parts of the quaternion. + */ + constexpr inline explicit operator vector() const noexcept + { + return {r, i[0], i[1], i[2]}; + } + + /// Returns a zero quaternion, where every scalar is equal to zero. + static constexpr quaternion zero() noexcept + { + return {}; + } + + /// Returns a rotation identity quaternion. + static constexpr quaternion identity() noexcept + { + return {T{1}, vector_type::zero()}; + } +}; + +/** + * Adds two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * + * @return Sum of the two quaternions. + */ +template +constexpr quaternion add(const quaternion& a, const quaternion& b) noexcept; + +/** + * Adds a quaternion and a scalar. + * + * @param a First value. + * @param b Second second value. + * + * @return Sum of the quaternion and scalar. + */ +template +constexpr quaternion add(const quaternion& a, T b) noexcept; + +/** + * Calculates the conjugate of a quaternion. + * + * @param q Quaternion from which the conjugate will be calculated. + * + * @return Conjugate of the quaternion. + */ +template +constexpr quaternion conjugate(const quaternion& q) noexcept; + +/** + * Calculates the dot product of two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * + * @return Dot product of the two quaternions. + */ +template +constexpr T dot(const quaternion& a, const quaternion& b) noexcept; + +/** + * Divides a quaternion by another quaternion. + * + * @param a First value. + * @param b Second value. + * + * @return Result of the division. + */ +template +constexpr quaternion div(const quaternion& a, const quaternion& b) noexcept; + +/** + * Divides a quaternion by a scalar. + * + * @param a Quaternion. + * @param b Scalar. + * + * @return Result of the division. + */ +template +constexpr quaternion div(const quaternion& a, T b) noexcept; + +/** + * Divides a scalar by a quaternion. + * + * @param a Scalar. + * @param b Quaternion. + * + * @return Result of the division. + */ +template +constexpr quaternion div(T a, const quaternion& b) noexcept; + +/** + * Calculates the length of a quaternion. + * + * @param q Quaternion to calculate the length of. + * + * @return Length of the quaternion. + */ +template +T length(const quaternion& q); + +/** + * Calculates the squared length of a quaternion. The squared length can be calculated faster than the length because a call to `std::sqrt` is saved. + * + * @param q Quaternion to calculate the squared length of. + * + * @return Squared length of the quaternion. + */ +template +constexpr T length_squared(const quaternion& q) noexcept; + +/** + * Performs linear interpolation between two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * @param t Interpolation factor. + * + * @return Interpolated quaternion. + */ +template +constexpr quaternion lerp(const quaternion& a, const quaternion& b, T t) noexcept; + +/** + * Creates a unit quaternion rotation using forward and up vectors. + * + * @param forward Unit forward vector. + * @param up Unit up vector. + * + * @return Unit rotation quaternion. + */ +template +quaternion look_rotation(const vector& forward, vector up); + +/** + * Converts a quaternion to a rotation matrix. + * + * @param q Unit quaternion. + * + * @return Matrix representing the rotation described by `q`. + */ +template +constexpr matrix matrix_cast(const quaternion& q) noexcept; + +/** + * Multiplies two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * + * @return Product of the two quaternions. + */ +template +constexpr quaternion mul(const quaternion& a, const quaternion& b) noexcept; + +/** + * Multiplies a quaternion by a scalar. + * + * @param a First value. + * @param b Second value. + * + * @return Product of the quaternion and scalar. + */ +template +constexpr quaternion mul(const quaternion& a, T b) noexcept; + +/** + * Calculates the product of a quaternion and a vector. + * + * @param a First value. + * @param b second value. + * + * @return Product of the quaternion and vector. + */ +/// @{ +template +constexpr vector mul(const quaternion& a, const vector& b) noexcept; +template +constexpr vector mul(const vector& a, const quaternion& b) noexcept; +/// @} + +/** + * Negates a quaternion. + * + * @param q Quaternion to negate. + * + * @return Negated quaternion. + */ +template +constexpr quaternion negate(const quaternion& q) noexcept; + +/** + * Performs normalized linear interpolation between two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * @param t Interpolation factor. + * + * @return Interpolated quaternion. + */ +template +quaternion nlerp(const quaternion& a, const quaternion& b, T t); + +/** + * Normalizes a quaternion. + * + * @param q Quaternion to normalize. + * + * @return Normalized quaternion. + */ +template +quaternion normalize(const quaternion& q); + +/** + * Creates a rotation from an angle and axis. + * + * @param angle Angle of rotation (in radians). + * @param axis Axis of rotation + * + * @return Quaternion representing the rotation. + */ +template +quaternion angle_axis(T angle, const vector& axis); + +/** + * Calculates the minimum rotation between two normalized direction vectors. + * + * @param source Normalized source direction. + * @param destination Normalized destination direction. + * + * @return Quaternion representing the minimum rotation between the source and destination vectors. + */ +template +quaternion rotation(const vector& source, const vector& destination); + +/** + * Performs spherical linear interpolation between two quaternions. + * + * @param a First quaternion. + * @param b Second quaternion. + * @param t Interpolation factor. + * + * @return Interpolated quaternion. + */ +template +quaternion slerp(const quaternion& a, const quaternion& b, T t, T error = T{1e-6}); + +/** + * Subtracts a quaternion from another quaternion. + * + * @param a First quaternion. + * @param b Second quaternion. + * + * @return Difference between the quaternions. + */ +template +constexpr quaternion sub(const quaternion& a, const quaternion& b) noexcept; + +/** + * Subtracts a quaternion and a scalar. + * + * @param a First value. + * @param b Second second. + * + * @return Difference between the quaternion and scalar. + */ +/// @{ +template +constexpr quaternion sub(const quaternion& a, T b) noexcept; +template +constexpr quaternion sub(T a, const quaternion& b) noexcept; +/// @} + +/** + * Decomposes a quaternion into swing and twist rotation components. + * + * @param[in] q Quaternion to decompose. + * @param[in] a Axis of twist rotation. + * @param[out] swing Swing rotation component. + * @param[out] twist Twist rotation component. + * @param[in] error Threshold at which a number is considered zero. + * + * @see https://www.euclideanspace.com/maths/geometry/rotations/for/decomposition/ + */ +template +void swing_twist(const quaternion& q, const vector& a, quaternion& qs, quaternion& qt, T error = T{1e-6}); + +/** + * Converts a 3x3 rotation matrix to a quaternion. + * + * @param m Rotation matrix. + * + * @return Unit quaternion representing the rotation described by @p m. + */ +template +quaternion quaternion_cast(const matrix& m); + +template +constexpr inline quaternion add(const quaternion& a, const quaternion& b) noexcept +{ + return {a.r + b.r, a.i + b.i}; +} + +template +constexpr inline quaternion add(const quaternion& a, T b) noexcept +{ + return {a.r + b, a.i + b}; +} + +template +constexpr inline quaternion conjugate(const quaternion& q) noexcept +{ + return {q.r, -q.i}; +} + +template +constexpr inline T dot(const quaternion& a, const quaternion& b) noexcept +{ + return a.r * b.r + dot(a.i, b.i); +} + +template +constexpr inline quaternion div(const quaternion& a, const quaternion& b) noexcept +{ + return {a.r / b.r, a.i / b.i}; +} + +template +constexpr inline quaternion div(const quaternion& a, T b) noexcept +{ + return {a.r / b, a.i / b}; +} + +template +constexpr inline quaternion div(T a, const quaternion& b) noexcept +{ + return {a / b.r, a / b.i}; +} + +template +inline T length(const quaternion& q) +{ + return std::sqrt(length_squared(q)); +} + +template +constexpr inline T length_squared(const quaternion& q) noexcept +{ + return q.r * q.r + length_squared(q.i); +} + +template +constexpr inline quaternion lerp(const quaternion& a, const quaternion& b, T t) noexcept +{ + return + { + (b.r - a.r) * t + a.r, + (b.i - a.i) * t + a.i + }; +} + +template +quaternion look_rotation(const vector& forward, vector up) +{ + vector right = normalize(cross(forward, up)); + up = cross(right, forward); + + matrix m = + { + right, + up, + -forward + }; + + // Convert to quaternion + return normalize(quaternion_cast(m)); +} + +template +constexpr matrix matrix_cast(const quaternion& q) noexcept +{ + const T xx = q.x() * q.x(); + const T xy = q.x() * q.y(); + const T xz = q.x() * q.z(); + const T xw = q.x() * q.w(); + const T yy = q.y() * q.y(); + const T yz = q.y() * q.z(); + const T yw = q.y() * q.w(); + const T zz = q.z() * q.z(); + const T zw = q.z() * q.w(); + + return + { + T(1) - (yy + zz) * T(2), (xy + zw) * T(2), (xz - yw) * T(2), + (xy - zw) * T(2), T(1) - (xx + zz) * T(2), (yz + xw) * T(2), + (xz + yw) * T(2), (yz - xw) * T(2), T(1) - (xx + yy) * T(2) + }; +} + +template +constexpr quaternion mul(const quaternion& a, const quaternion& b) noexcept +{ + return + { + -a.x() * b.x() - a.y() * b.y() - a.z() * b.z() + a.w() * b.w(), + a.x() * b.w() + a.y() * b.z() - a.z() * b.y() + a.w() * b.x(), + -a.x() * b.z() + a.y() * b.w() + a.z() * b.x() + a.w() * b.y(), + a.x() * b.y() - a.y() * b.x() + a.z() * b.w() + a.w() * b.z() + }; +} + +template +constexpr inline quaternion mul(const quaternion& a, T b) noexcept +{ + return {a.r * b, a.i * b}; +} + +template +constexpr vector mul(const quaternion& a, const vector& b) noexcept +{ + return a.i * dot(a.i, b) * T(2) + b * (a.r * a.r - length_squared(a.i)) + cross(a.i, b) * a.r * T(2); +} + +template +constexpr inline vector mul(const vector& a, const quaternion& b) noexcept +{ + return mul(conjugate(b), a); +} + +template +constexpr inline quaternion negate(const quaternion& q) noexcept +{ + return {-q.r, -q.i}; +} + +template +quaternion nlerp(const quaternion& a, const quaternion& b, T t) +{ + return normalize(add(mul(a, T(1) - t), mul(b, t * std::copysign(T(1), dot(a, b))))); +} + +template +inline quaternion normalize(const quaternion& q) +{ + return mul(q, T(1) / length(q)); +} + +template +quaternion angle_axis(T angle, const vector& axis) +{ + angle *= T{0.5}; + return {std::cos(angle), axis * std::sin(angle)}; +} + +template +quaternion rotation(const vector& source, const vector& destination) +{ + quaternion q = {dot(source, destination), cross(source, destination)}; + q.w() += length(q); + return normalize(q); +} + +template +quaternion slerp(const quaternion& a, const quaternion& b, T t, T error) +{ + T cos_theta = dot(a, b); + + if (cos_theta > T(1) - error) + return normalize(lerp(a, b, t)); + + cos_theta = std::max(T(-1), std::min(T(1), cos_theta)); + const T theta = std::acos(cos_theta) * t; + + quaternion c = normalize(sub(b, mul(a, cos_theta))); + + return add(mul(a, std::cos(theta)), mul(c, std::sin(theta))); +} + +template +constexpr inline quaternion sub(const quaternion& a, const quaternion& b) noexcept +{ + return {a.r - b.r, a.i - b.i}; +} + +template +constexpr inline quaternion sub(const quaternion& a, T b) noexcept +{ + return {a.r - b, a.i - b}; +} + +template +constexpr inline quaternion sub(T a, const quaternion& b) noexcept +{ + return {a - b.r, a - b.i}; +} + +template +void swing_twist(const quaternion& q, const vector& a, quaternion& qs, quaternion& qt, T error) +{ + if (length_squared(q.i) > error) + { + qt = normalize(quaternion{q.w(), a * dot(a, q.i)}); + qs = mul(q, conjugate(qt)); + } + else + { + qt = angle_axis(pi, a); + + const vector qa = mul(q, a); + const vector sa = cross(a, qa); + if (length_squared(sa) > error) + qs = angle_axis(std::acos(dot(a, qa)), sa); + else + qs = quaternion::identity(); + } +} + +template +quaternion quaternion_cast(const matrix& m) +{ + const T t = trace(m); + + if (t > T(0)) + { + T s = T(0.5) / std::sqrt(t + T(1)); + return + { + T(0.25) / s, + (m[1][2] - m[2][1]) * s, + (m[2][0] - m[0][2]) * s, + (m[0][1] - m[1][0]) * s + }; + } + else + { + if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) + { + T s = T(2) * std::sqrt(T(1) + m[0][0] - m[1][1] - m[2][2]); + + return + { + (m[1][2] - m[2][1]) / s, + T(0.25) * s, + (m[1][0] + m[0][1]) / s, + (m[2][0] + m[0][2]) / s + }; + } + else if (m[1][1] > m[2][2]) + { + T s = T(2) * std::sqrt(T(1) + m[1][1] - m[0][0] - m[2][2]); + return + { + (m[2][0] - m[0][2]) / s, + (m[1][0] + m[0][1]) / s, + T(0.25) * s, + (m[2][1] + m[1][2]) / s + }; + } + else + { + T s = T(2) * std::sqrt(T(1) + m[2][2] - m[0][0] - m[1][1]); + return + { + (m[0][1] - m[1][0]) / s, + (m[2][0] + m[0][2]) / s, + (m[2][1] + m[1][2]) / s, + T(0.25) * s + }; + } + } +} + +namespace operators { + +/// @copydoc add(const quaternion&, const quaternion&) +template +constexpr inline quaternion operator+(const quaternion& a, const quaternion& b) noexcept +{ + return add(a, b); +} + +/// @copydoc add(const quaternion&, T) +/// @{ +template +constexpr inline quaternion operator+(const quaternion& a, T b) noexcept +{ + return add(a, b); +} +template +constexpr inline quaternion operator+(T a, const quaternion& b) noexcept +{ + return add(b, a); +} +/// @} + +/// @copydoc div(const quaternion&, const quaternion&) +template +constexpr inline quaternion operator/(const quaternion& a, const quaternion& b) noexcept +{ + return div(a, b); +} + +/// @copydoc div(const quaternion&, T) +template +constexpr inline quaternion operator/(const quaternion& a, T b) noexcept +{ + return div(a, b); +} + +/// @copydoc div(T, const quaternion&) +template +constexpr inline quaternion operator/(T a, const quaternion& b) noexcept +{ + return div(a, b); +} + +/// @copydoc mul(const quaternion&, const quaternion&) +template +constexpr inline quaternion operator*(const quaternion& a, const quaternion& b) noexcept +{ + return mul(a, b); +} + +/// @copydoc mul(const quaternion&, T) +/// @{ +template +constexpr inline quaternion operator*(const quaternion& a, T b) noexcept +{ + return mul(a, b); +} +template +constexpr inline quaternion operator*(T a, const quaternion& b) noexcept +{ + return mul(b, a); +} +/// @} + +/// @copydoc mul(const quaternion&, const vector&) +template +constexpr inline vector operator*(const quaternion& a, const vector& b) noexcept +{ + return mul(a, b); +} + +/// @copydoc mul(const vector&, const quaternion&) +template +constexpr inline vector operator*(const vector& a, const quaternion& b) noexcept +{ + return mul(a, b); +} + +/// @copydoc sub(const quaternion&, const quaternion&) +template +constexpr inline quaternion operator-(const quaternion& a, const quaternion& b) noexcept +{ + return sub(a, b); +} + +/// @copydoc sub(const quaternion&, T) +/// @{ +template +constexpr inline quaternion operator-(const quaternion& a, T b) noexcept +{ + return sub(a, b); +} +template +constexpr inline quaternion operator-(T a, const quaternion& b) noexcept +{ + return sub(a, b); +} +/// @} + +/// @copydoc negate(const quaternion&) +template +constexpr inline quaternion operator-(const quaternion& q) noexcept +{ + return negate(q); +} + +/** + * Adds two values and stores the result in the first value. + * + * @param a First value. + * @param b Second value. + * + * @return Reference to the first value. + */ +/// @{ +template +constexpr inline quaternion& operator+=(quaternion& a, const quaternion& b) noexcept +{ + return (a = a + b); +} +template +constexpr inline quaternion& operator+=(quaternion& a, T b) noexcept +{ + return (a = a + b); +} +/// @} + +/** + * Subtracts the first value by the second value and stores the result in the first value. + * + * @param a First value. + * @param b Second value. + * + * @return Reference to the first value. + */ +/// @{ +template +constexpr inline quaternion& operator-=(quaternion& a, const quaternion& b) noexcept +{ + return (a = a - b); +} +template +constexpr inline quaternion& operator-=(quaternion& a, T b) noexcept +{ + return (a = a - b); +} +/// @} + +/** + * Multiplies two values and stores the result in the first value. + * + * @param a First value. + * @param b Second value. + * + * @return Reference to the first value. + */ +/// @{ +template +constexpr inline quaternion& operator*=(quaternion& a, const quaternion& b) noexcept +{ + return (a = a * b); +} +template +constexpr inline quaternion& operator*=(quaternion& a, T b) noexcept +{ + return (a = a * b); +} +/// @} + +/** + * Divides the first value by the second value and stores the result in the first value. + * + * @param a First value. + * @param b Second value. + * + * @return Reference to the first value. + */ +/// @{ +template +constexpr inline quaternion& operator/=(quaternion& a, const quaternion& b) noexcept +{ + return (a = a / b); +} +template +constexpr inline quaternion& operator/=(quaternion& a, T b) noexcept +{ + return (a = a / b); +} +/// @} + +/** + * Writes the real and imaginary parts of a quaternion to an output stream, with each number delimeted by a space. + * + * @param os Output stream. + * @param q Quaternion. + * + * @return Output stream. + */ +template +std::ostream& operator<<(std::ostream& os, const math::quaternion& q) +{ + os << q.r << ' ' << q.i; + return os; +} + +/** + * Reads the real and imaginary parts of a quaternion from an input stream, with each number delimeted by a space. + * + * @param is Input stream. + * @param q Quaternion. + * + * @return Input stream. + */ +template +std::istream& operator>>(std::istream& is, const math::quaternion& q) +{ + is >> q.r; + is >> q.i; + return is; +} + +} // namespace operators + +} // namespace math + +using namespace math::operators; + +#endif // ANTKEEPER_MATH_QUATERNION_HPP diff --git a/src/math/se3.hpp b/src/math/se3.hpp index 7b23c2d..c5ed2a6 100644 --- a/src/math/se3.hpp +++ b/src/math/se3.hpp @@ -21,9 +21,7 @@ #define ANTKEEPER_MATH_TRANSFORMATION_SE3_HPP #include "math/vector.hpp" -#include "math/quaternion-type.hpp" -#include "math/quaternion-operators.hpp" -#include "math/quaternion-functions.hpp" +#include "math/quaternion.hpp" namespace math { namespace transformation { diff --git a/src/math/stream-operators.hpp b/src/math/stream-operators.hpp deleted file mode 100644 index 4cb5677..0000000 --- a/src/math/stream-operators.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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_MATH_STREAM_OPERATORS_HPP -#define ANTKEEPER_MATH_STREAM_OPERATORS_HPP - -#include "math/quaternion-type.hpp" -#include -#include - -/** - * Writes the real and imaginary parts of a quaternion to an output stream, with each number delimeted by a space. - * - * @param os Output stream. - * @param q Quaternion. - * @return Output stream. - */ -template -std::ostream& operator<<(std::ostream& os, const math::quaternion& q); - -/** - * Reads the real and imaginary parts of a quaternion from an input stream, with each number delimeted by a space. - * - * @param is Input stream. - * @param q Quaternion. - * @return Input stream. - */ -template -std::istream& operator>>(std::istream& is, const math::quaternion& q); - -template -std::ostream& operator<<(std::ostream& os, const math::quaternion& q) -{ - os << q.w << ' ' << q.x() << ' ' << q.y() << ' ' << q.z(); - return os; -} - -template -std::istream& operator>>(std::istream& is, const math::quaternion& q) -{ - is >> q.w; - is >> q.x; - is >> q.y; - is >> q.z; - - return is; -} - -#endif // ANTKEEPER_MATH_STREAM_OPERATORS_HPP diff --git a/src/math/transform-functions.hpp b/src/math/transform-functions.hpp index 639f770..4546e66 100644 --- a/src/math/transform-functions.hpp +++ b/src/math/transform-functions.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_MATH_TRANSFORM_FUNCTIONS_HPP #include "math/transform-type.hpp" -#include "math/quaternion-functions.hpp" +#include "math/quaternion.hpp" namespace math { diff --git a/src/math/transform-type.hpp b/src/math/transform-type.hpp index 351f2a3..e6d00f9 100644 --- a/src/math/transform-type.hpp +++ b/src/math/transform-type.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_MATH_TRANSFORM_TYPE_HPP #include "math/vector.hpp" -#include "math/quaternion-type.hpp" +#include "math/quaternion.hpp" namespace math { @@ -49,9 +49,9 @@ struct transform template constexpr transform transform::identity = { - {T(0), T(0), T(0)}, - {T(1), T(0), T(0), T(0)}, - {T(1), T(1), T(1)} + vector::zero(), + quaternion::identity(), + vector::one() }; } // namespace math diff --git a/src/math/vector.hpp b/src/math/vector.hpp index e5ad5cb..3774a5a 100644 --- a/src/math/vector.hpp +++ b/src/math/vector.hpp @@ -293,7 +293,8 @@ using vector4 = vector; /** * Returns the absolute values of each element. * - * @param x Input vector + * @param x Input vector. + * * @return Absolute values of input vector elements. */ template @@ -304,6 +305,7 @@ constexpr vector abs(const vector& x); * * @param x First value. * @param y Second value. + * * @return Sum of the two values. */ /// @{ @@ -317,6 +319,7 @@ constexpr vector add(const vector& x, T y) noexcept; * Checks if all elements of a boolean vector are `true`. * * @param x Vector to be tested for truth. + * * @return `true` if all elements are `true`, `false` otherwise. */ template @@ -326,6 +329,7 @@ constexpr bool all(const vector& x) noexcept; * Checks if any elements of a boolean vector are `true`. * * @param x Vector to be tested for truth. + * * @return `true` if any elements are `true`, `false` otherwise. */ template @@ -334,7 +338,8 @@ constexpr bool any(const vector& x) noexcept; /** * Performs a element-wise ceil operation. * - * @param x Input vector + * @param x Input vector. + * * @return Component-wise ceil of input vector. */ template @@ -346,6 +351,7 @@ constexpr vector ceil(const vector& x); * @param x Vector to clamp. * @param min Minimum value. * @param max Maximum value. + * * @return Clamped vector. */ /// @{ @@ -360,6 +366,7 @@ constexpr vector clamp(const vector& x, T min, T max); * * @param x Vector to clamp. * @param max_length Maximum length. + * * @return Length-clamped vector. */ template @@ -370,6 +377,7 @@ vector clamp_length(const vector& x, T max_length); * * @param x First vector. * @param y Second vector. + * * @return Cross product of the two vectors. */ template @@ -380,6 +388,7 @@ constexpr vector cross(const vector& x, const vector& y) noexc * * @param p0 First of two points. * @param p1 Second of two points. + * * @return Distance between the two points. */ template @@ -390,6 +399,7 @@ T distance(const vector& p0, const vector& p1); * * @param p0 First of two points. * @param p1 Second of two points. + * * @return Squared distance between the two points. */ template @@ -400,6 +410,7 @@ constexpr T distance_squared(const vector& p0, const vector& p1) noe * * @param x First value. * @param y Second value. + * * @return Result of the division. */ /// @{ @@ -416,6 +427,7 @@ constexpr vector div(T x, const vector& y) noexcept; * * @param x First vector. * @param y Second vector. + * * @return Dot product of the two vectors. */ template @@ -426,6 +438,7 @@ constexpr T dot(const vector& x, const vector& y) noexcept; * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -434,7 +447,8 @@ constexpr vector equal(const vector& x, const vector& y) no /** * Performs a element-wise floor operation. * - * @param x Input vector + * @param x Input vector. + * * @return Component-wise floor of input vector. */ template @@ -459,7 +473,8 @@ constexpr vector fma(const vector& x, T y, T z); /** * Returns a vector containing the fractional part of each element. * - * @param x Input vector + * @param x Input vector. + * * @return Fractional parts of input vector. */ template @@ -470,6 +485,7 @@ constexpr vector fract(const vector& x); * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -480,6 +496,7 @@ constexpr vector greater_than(const vector& x, const vector * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -489,6 +506,7 @@ constexpr vector greater_than_equal(const vector& x, const vector * Calculates the length of a vector. * * @param x Vector of which to calculate the length. + * * @return Length of the vector. */ template @@ -498,6 +516,7 @@ T length(const vector& x); * Calculates the squared length of a vector. The squared length can be calculated faster than the length because a call to `std::sqrt` is saved. * * @param x Vector of which to calculate the squared length. + * * @return Squared length of the vector. */ template @@ -508,6 +527,7 @@ constexpr T length_squared(const vector& x) noexcept; * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -518,6 +538,7 @@ constexpr vector less_than(const vector& x, const vector& y * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -570,6 +591,7 @@ constexpr T min(const vector& x); * * @param x First vector. * @param y Second vector. + * * @return Remainders of `x / y`. */ /// @{ @@ -584,6 +606,7 @@ constexpr vector mod(const vector& x, T y); * * @param x First value. * @param y Second value. + * * @return Product of the two values. */ /// @{ @@ -597,6 +620,7 @@ constexpr vector mul(const vector& x, T y) noexcept; * Negates a vector. * * @param x Vector to negate. + * * @return Negated vector. */ template @@ -606,6 +630,7 @@ constexpr vector negate(const vector& x) noexcept; * Calculates the unit vector in the same direction as the original vector. * * @param x Vector to normalize. + * * @return Normalized vector. */ template @@ -615,6 +640,7 @@ vector normalize(const vector& x); * Logically inverts a boolean vector. * * @param x Vector to be inverted. + * * @return Logically inverted vector. */ template @@ -625,6 +651,7 @@ constexpr vector not(const vector& x) noexcept; * * @param x First vector. * @param y Second vector. + * * @return Boolean vector containing the result of the element comparisons. */ template @@ -649,6 +676,7 @@ vector pow(const vector& x, T y); * Performs a element-wise round operation. * * @param x Input vector + * * @return Component-wise round of input vector. */ template @@ -678,6 +706,7 @@ vector sqrt(const vector& x); * * @param x First value. * @param y Second value. + * * @return Difference between the two values. */ /// @{ @@ -1422,6 +1451,7 @@ constexpr inline vector operator-(T x, const vector& y) noexcept * * @param x First value. * @param y Second value. + * * @return Reference to the first value. */ /// @{ @@ -1442,6 +1472,7 @@ constexpr inline vector& operator+=(vector& x, T y) noexcept * * @param x First value. * @param y Second value. + * * @return Reference to the first value. */ /// @{ @@ -1462,6 +1493,7 @@ constexpr inline vector& operator-=(vector& x, T y) noexcept * * @param x First value. * @param y Second value. + * * @return Reference to the first value. */ /// @{ @@ -1482,6 +1514,7 @@ constexpr inline vector& operator*=(vector& x, T y) noexcept * * @param x First value. * @param y Second value. + * * @return Reference to the first value. */ /// @{ diff --git a/src/render/passes/material-pass.cpp b/src/render/passes/material-pass.cpp index 452b1c3..b3b20a5 100644 --- a/src/render/passes/material-pass.cpp +++ b/src/render/passes/material-pass.cpp @@ -42,7 +42,7 @@ #include "scene/point-light.hpp" #include "scene/spot-light.hpp" #include "config.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/projection.hpp" #include #include diff --git a/src/render/passes/shadow-map-pass.cpp b/src/render/passes/shadow-map-pass.cpp index 01f93fb..2797687 100644 --- a/src/render/passes/shadow-map-pass.cpp +++ b/src/render/passes/shadow-map-pass.cpp @@ -34,7 +34,7 @@ #include "config.hpp" #include "math/vector.hpp" #include "math/matrix.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/projection.hpp" #include #include diff --git a/src/render/passes/sky-pass.cpp b/src/render/passes/sky-pass.cpp index 8cdd733..03b6573 100644 --- a/src/render/passes/sky-pass.cpp +++ b/src/render/passes/sky-pass.cpp @@ -70,9 +70,9 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp), sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp), icrf_to_eus_translation({0, 0, 0}, math::lerp), - icrf_to_eus_rotation(math::quaternion::identity, math::nlerp), + icrf_to_eus_rotation(math::quaternion::identity(), math::nlerp), moon_position_tween(float3{0, 0, 0}, math::lerp), - moon_rotation_tween(math::quaternion::identity, math::nlerp), + moon_rotation_tween(math::quaternion::identity(), math::nlerp), moon_angular_radius_tween(0.0f, math::lerp), moon_sunlight_direction_tween(float3{0, 0, 0}, math::lerp), moon_sunlight_illuminance_tween(float3{0, 0, 0}, math::lerp), diff --git a/src/render/passes/sky-pass.hpp b/src/render/passes/sky-pass.hpp index d561ac0..dfc4f45 100644 --- a/src/render/passes/sky-pass.hpp +++ b/src/render/passes/sky-pass.hpp @@ -25,7 +25,7 @@ #include "event/event-handler.hpp" #include "event/input-events.hpp" #include "animation/tween.hpp" -#include "math/quaternion-type.hpp" +#include "math/quaternion.hpp" #include "gl/shader-program.hpp" #include "gl/shader-input.hpp" #include "gl/vertex-buffer.hpp" diff --git a/src/render/renderer.cpp b/src/render/renderer.cpp index cf0be48..13e4b47 100644 --- a/src/render/renderer.cpp +++ b/src/render/renderer.cpp @@ -31,7 +31,7 @@ #include "math/matrix.hpp" #include "geom/projection.hpp" #include "config.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include #include diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index fd86de2..131dc3e 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -275,10 +275,10 @@ static bool load_component_transform(entity::archetype& archetype, const json& e if (element.contains("rotation")) { auto translation = element["rotation"]; - component.local.rotation.w = translation[0].get(); - component.local.rotation.x = translation[1].get(); - component.local.rotation.y = translation[2].get(); - component.local.rotation.z = translation[3].get(); + component.local.rotation.w() = translation[0].get(); + component.local.rotation.x() = translation[1].get(); + component.local.rotation.y() = translation[2].get(); + component.local.rotation.z() = translation[3].get(); } if (element.contains("scale")) diff --git a/src/resources/model-loader.cpp b/src/resources/model-loader.cpp index 13d1fb1..26d8d3c 100644 --- a/src/resources/model-loader.cpp +++ b/src/resources/model-loader.cpp @@ -259,10 +259,10 @@ render::model* resource_loader::load(resource_manager* resource_m { if (rotation_node->size() == 4) { - bone_transform.rotation.w = (*rotation_node)[0].get(); - bone_transform.rotation.x = (*rotation_node)[1].get(); - bone_transform.rotation.y = (*rotation_node)[2].get(); - bone_transform.rotation.z = (*rotation_node)[3].get(); + bone_transform.rotation.w() = (*rotation_node)[0].get(); + bone_transform.rotation.x() = (*rotation_node)[1].get(); + bone_transform.rotation.y() = (*rotation_node)[2].get(); + bone_transform.rotation.z() = (*rotation_node)[3].get(); } } diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index 4c82fe1..6545825 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -21,7 +21,7 @@ #include "config.hpp" #include "math/constants.hpp" #include "math/interpolation.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/projection.hpp" namespace scene { diff --git a/src/scene/directional-light.cpp b/src/scene/directional-light.cpp index d75ffe6..24f180f 100644 --- a/src/scene/directional-light.cpp +++ b/src/scene/directional-light.cpp @@ -19,7 +19,7 @@ #include "directional-light.hpp" #include "config.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/interpolation.hpp" namespace scene { diff --git a/src/scene/object.hpp b/src/scene/object.hpp index e38b38a..4bcbfbc 100644 --- a/src/scene/object.hpp +++ b/src/scene/object.hpp @@ -23,7 +23,7 @@ #include "animation/tween.hpp" #include "geom/bounding-volume.hpp" #include "math/vector.hpp" -#include "math/quaternion-type.hpp" +#include "math/quaternion.hpp" #include "math/transform-type.hpp" #include "render/context.hpp" #include "render/queue.hpp" diff --git a/src/scene/spot-light.cpp b/src/scene/spot-light.cpp index 418176d..c36c50f 100644 --- a/src/scene/spot-light.cpp +++ b/src/scene/spot-light.cpp @@ -19,7 +19,7 @@ #include "spot-light.hpp" #include "config.hpp" -#include "math/quaternion-operators.hpp" +#include "math/quaternion.hpp" #include "math/interpolation.hpp" #include