From a7cbe697124f12b24924b3d7f5e73a993e33509b Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 9 Jul 2025 21:02:22 +0300 Subject: [PATCH] Add math::trs class & use it in gltf animations --- .../gfx/include/psemek/gfx/gltf_animation.hpp | 6 +- libs/gfx/source/gltf_animation.cpp | 6 +- libs/math/include/psemek/math/trs.hpp | 88 +++++++++++++++++++ 3 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 libs/math/include/psemek/math/trs.hpp diff --git a/libs/gfx/include/psemek/gfx/gltf_animation.hpp b/libs/gfx/include/psemek/gfx/gltf_animation.hpp index ac5f95b7..df3e8491 100644 --- a/libs/gfx/include/psemek/gfx/gltf_animation.hpp +++ b/libs/gfx/include/psemek/gfx/gltf_animation.hpp @@ -1,9 +1,7 @@ #pragma once #include -#include -#include -#include +#include #include #include @@ -147,7 +145,7 @@ namespace psemek::gfx math::interval range() const; - math::affine_transform operator()(float time) const; + math::trs operator()(float time) const; gltf_scale_animation const & scale() const { return scale_; } gltf_rotation_animation const & rotation() const { return rotation_; } diff --git a/libs/gfx/source/gltf_animation.cpp b/libs/gfx/source/gltf_animation.cpp index bfd28800..efb2f351 100644 --- a/libs/gfx/source/gltf_animation.cpp +++ b/libs/gfx/source/gltf_animation.cpp @@ -90,11 +90,9 @@ namespace psemek::gfx return scale_.range() | rotation_.range() | translation_.range(); } - math::affine_transform gltf_animation::operator()(float time) const + math::trs gltf_animation::operator()(float time) const { - return math::translation(translation_(time)).transform() - * math::quaternion_rotation(rotation_(time)).transform() - * math::scale(scale_(time)).transform(); + return {translation_(time), rotation_(time), scale_(time)}; } } diff --git a/libs/math/include/psemek/math/trs.hpp b/libs/math/include/psemek/math/trs.hpp new file mode 100644 index 00000000..20593728 --- /dev/null +++ b/libs/math/include/psemek/math/trs.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include +#include +#include + +namespace psemek::math +{ + + // NB: composition of TRS triplets is not defined as the result + // might not be expressible in TRS form + + template + struct trs; + + template + struct trs + { + vector translation; + quaternion rotation; + vector scale; + + static trs identity() + { + return {vector::zero(), quaternion::identity(), vector{T{1}, T{1}, T{1}}}; + } + + static trs from(matrix const & m) + { + trs result; + + result.translation[0] = m[0][3]; + result.translation[1] = m[1][3]; + result.translation[2] = m[2][3]; + + result.scale[0] = length(vector{m[0][0], m[1][0], m[2][0]}); + result.scale[1] = length(vector{m[0][1], m[1][1], m[2][1]}); + result.scale[2] = length(vector{m[0][2], m[1][2], m[2][2]}); + + matrix r; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + r[i][j] = m[i][j] / result.scale[j]; + + result.rotation = quaternion::rotation(r); + + return result; + } + + matrix affine_matrix() const + { + return transform().affine_matrix(); + } + + matrix linear_matrix() const + { + return transform().linear_matrix(); + } + + vector translation_vector() const + { + return translation; + } + + matrix homogeneous_matrix() const + { + return transform().homogeneous_matrix(); + } + + vector operator()(vector const & v) const + { + return rotate(rotation, pointwise_mult(v, scale)); + } + + point operator()(point const & p) const + { + return p.zero() + rotate(rotation, pointwise_mult(p - p.zero(), scale)) + translation; + } + + affine_transform transform() const + { + return math::translation(translation).transform() + * quaternion_rotation(rotation).transform() + * math::scale(scale).transform(); + } + }; + +}