Add math::trs class & use it in gltf animations
This commit is contained in:
parent
d826940b4c
commit
a7cbe69712
3 changed files with 92 additions and 8 deletions
|
|
@ -1,9 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/gfx/gltf_parser.hpp>
|
||||
#include <psemek/math/scale.hpp>
|
||||
#include <psemek/math/rotation.hpp>
|
||||
#include <psemek/math/translation.hpp>
|
||||
#include <psemek/math/trs.hpp>
|
||||
#include <psemek/util/exception.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
|
@ -147,7 +145,7 @@ namespace psemek::gfx
|
|||
|
||||
math::interval<float> range() const;
|
||||
|
||||
math::affine_transform<float, 3, 3> operator()(float time) const;
|
||||
math::trs<float, 3> operator()(float time) const;
|
||||
|
||||
gltf_scale_animation const & scale() const { return scale_; }
|
||||
gltf_rotation_animation const & rotation() const { return rotation_; }
|
||||
|
|
|
|||
|
|
@ -90,11 +90,9 @@ namespace psemek::gfx
|
|||
return scale_.range() | rotation_.range() | translation_.range();
|
||||
}
|
||||
|
||||
math::affine_transform<float, 3, 3> gltf_animation::operator()(float time) const
|
||||
math::trs<float, 3> 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)};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
88
libs/math/include/psemek/math/trs.hpp
Normal file
88
libs/math/include/psemek/math/trs.hpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/math/scale.hpp>
|
||||
#include <psemek/math/rotation.hpp>
|
||||
#include <psemek/math/translation.hpp>
|
||||
|
||||
namespace psemek::math
|
||||
{
|
||||
|
||||
// NB: composition of TRS triplets is not defined as the result
|
||||
// might not be expressible in TRS form
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct trs;
|
||||
|
||||
template <typename T>
|
||||
struct trs<T, 3>
|
||||
{
|
||||
vector<T, 3> translation;
|
||||
quaternion<T> rotation;
|
||||
vector<T, 3> scale;
|
||||
|
||||
static trs<T, 3> identity()
|
||||
{
|
||||
return {vector<T, 3>::zero(), quaternion<T>::identity(), vector{T{1}, T{1}, T{1}}};
|
||||
}
|
||||
|
||||
static trs<T, 3> from(matrix<T, 3, 4> const & m)
|
||||
{
|
||||
trs<T, 3> 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<T, 3, 3> 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<T>::rotation(r);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
matrix<T, 3, 4> affine_matrix() const
|
||||
{
|
||||
return transform().affine_matrix();
|
||||
}
|
||||
|
||||
matrix<T, 3, 3> linear_matrix() const
|
||||
{
|
||||
return transform().linear_matrix();
|
||||
}
|
||||
|
||||
vector<T, 3> translation_vector() const
|
||||
{
|
||||
return translation;
|
||||
}
|
||||
|
||||
matrix<T, 4, 4> homogeneous_matrix() const
|
||||
{
|
||||
return transform().homogeneous_matrix();
|
||||
}
|
||||
|
||||
vector<T, 3> operator()(vector<T, 3> const & v) const
|
||||
{
|
||||
return rotate(rotation, pointwise_mult(v, scale));
|
||||
}
|
||||
|
||||
point<T, 3> operator()(point<T, 3> const & p) const
|
||||
{
|
||||
return p.zero() + rotate(rotation, pointwise_mult(p - p.zero(), scale)) + translation;
|
||||
}
|
||||
|
||||
affine_transform<T, 3, 3> transform() const
|
||||
{
|
||||
return math::translation(translation).transform()
|
||||
* quaternion_rotation(rotation).transform()
|
||||
* math::scale(scale).transform();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue