Preprocess glTF rotation animations to force shortest-arc interpolation

This commit is contained in:
Nikita Lisitsa 2024-10-15 21:42:00 +03:00
parent b5d556d06f
commit ce8547c8d3

View file

@ -98,7 +98,33 @@ namespace psemek::gfx
: input_(std::move(input))
, output_(std::move(output))
, interpolation_(interpolation)
{}
{
if constexpr (path == gltf_asset::animation::channel::rotation)
{
if (interpolation == geom::easing_type::linear)
{
for (std::size_t i = 1; i < input_.size(); ++i)
{
if (geom::dot(output_[i - 1].coords, output_[i].coords) < 0.f)
{
output_[i] = - output_[i];
}
}
}
else if (interpolation == geom::easing_type::cubic)
{
for (std::size_t i = 1; i < input_.size(); ++i)
{
if (geom::dot(output_[3 * (i - 1) + 1].coords, output_[3 * i + 1].coords) < 0.f)
{
output_[3 * i + 0] = - output_[3 * i + 0];
output_[3 * i + 1] = - output_[3 * i + 1];
output_[3 * i + 2] = - output_[3 * i + 2];
}
}
}
}
}
gltf_animation_channel(gltf_animation_channel &&) = default;