From b087e2554f6091cb222ae1462ebb927b19b6414b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Tue, 24 Dec 2024 15:25:07 +0100 Subject: [PATCH] Add glTF STEP interpolation support (#15525) --- doc/lua_api.md | 2 +- games/devtest/mods/gltf/init.lua | 14 +++++++++ .../gltf/models/gltf_simple_skin_step.gltf | Bin 0 -> 2710 bytes irr/src/CGLTFMeshFileLoader.cpp | 27 ++++++++++++++---- 4 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 games/devtest/mods/gltf/models/gltf_simple_skin_step.gltf diff --git a/doc/lua_api.md b/doc/lua_api.md index 91d8f314a..f46c9eb28 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -318,7 +318,7 @@ Many glTF features are not supported *yet*, including: * Animations * Only a single animation is supported, use frame ranges within this animation. - * Only linear interpolation is supported. + * `CUBICSPLINE` interpolation is not supported. * Cameras * Materials * Only base color textures are supported diff --git a/games/devtest/mods/gltf/init.lua b/games/devtest/mods/gltf/init.lua index fd4d13bee..f6a8f9bdf 100644 --- a/games/devtest/mods/gltf/init.lua +++ b/games/devtest/mods/gltf/init.lua @@ -55,6 +55,20 @@ core.register_entity("gltf:simple_skin", { end }) +core.register_entity("gltf:simple_skin_step", { + initial_properties = { + infotext = "Simple skin, but using STEP interpolation", + visual = "mesh", + visual_size = vector.new(5, 5, 5), + mesh = "gltf_simple_skin_step.gltf", + textures = {}, + backface_culling = false + }, + on_activate = function(self) + self.object:set_animation({x = 0, y = 5.5}, 1) + end +}) + -- The claws rendering incorrectly from one side is expected behavior: -- They use an unsupported double-sided material. core.register_entity("gltf:frog", { diff --git a/games/devtest/mods/gltf/models/gltf_simple_skin_step.gltf b/games/devtest/mods/gltf/models/gltf_simple_skin_step.gltf new file mode 100644 index 0000000000000000000000000000000000000000..f26c0c8b1101fee094d67aa4ce0ecbf03b5b8f5c GIT binary patch literal 2710 zcmcguS#R1v5Pt8^*w;E>n$|L@YjPK}&V9oCVBz9U*Nlh5gOq zCTu*KS~F{O%Q}X}u1D7GZ2CiI9aCf92G-{*Ni_}{^ZbS9ppJeZ01Q9|>G^v%irp?q z+}L27q?#Ig3Orw+h@n9^;Ii#|Tk=`zIghsQyBkTw_BPzO5v4@f(aII*9p;am32gyc z%7Z?jy;SGuMYsc<7J4e&C=8ByW7FAS%rqA41WB}||MT5)32uXX3EM>;7+=`J?$}|t z@f`B9zS@Z8nUwo5w_~^6)Hvr|&TnAhea<=>YobXc`@-%-H?$GsDm~f+gfqnR< z{N#rJxKo_SWg&GH&!pmv|37^-znLc%uV?#g)1`c_`pxVFHxsOf#oreWxzsP$pJ=6i zs6+M!B|Nex@k(|J{gCmB{(dagx?$2s=qQ|_Fp|RskXf!X|FpiQ`HqpeEAP*kPUCOSIZD00&fZ3o6-9HfIL511Txf^8W1t}kYX-=G;lZQHJ}1p`-QF%EzQiX5nH^5+@I;S7F{3k zZc)a8uupMvM~gVk6F1YW9SdZ%!LL($zw-Ok9wC?Wma79?8ubmIooYi?e+!::make(m_gltf_model, sampler.input); const auto n_frames = inputAccessor.getCount(); @@ -686,32 +695,38 @@ void SelfType::MeshExtractor::loadAnimation(const std::size_t animIdx) if (!channel.target.node.has_value()) throw std::runtime_error("no animated node"); - const auto &joint = m_loaded_nodes.at(*channel.target.node); + auto *joint = m_loaded_nodes.at(*channel.target.node); switch (channel.target.path) { case tiniergltf::AnimationChannelTarget::Path::TRANSLATION: { const auto outputAccessor = Accessor::make(m_gltf_model, sampler.output); + auto &channel = joint->keys.position; + channel.interpolate = interpolate; for (std::size_t i = 0; i < n_frames; ++i) { f32 frame = inputAccessor.get(i); core::vector3df position = outputAccessor.get(i); - m_irr_model->addPositionKey(joint, frame, convertHandedness(position)); + channel.pushBack(frame, convertHandedness(position)); } break; } case tiniergltf::AnimationChannelTarget::Path::ROTATION: { const auto outputAccessor = Accessor::make(m_gltf_model, sampler.output); + auto &channel = joint->keys.rotation; + channel.interpolate = interpolate; for (std::size_t i = 0; i < n_frames; ++i) { f32 frame = inputAccessor.get(i); core::quaternion rotation = outputAccessor.get(i); - m_irr_model->addRotationKey(joint, frame, convertHandedness(rotation)); + channel.pushBack(frame, convertHandedness(rotation)); } break; } case tiniergltf::AnimationChannelTarget::Path::SCALE: { const auto outputAccessor = Accessor::make(m_gltf_model, sampler.output); + auto &channel = joint->keys.scale; + channel.interpolate = interpolate; for (std::size_t i = 0; i < n_frames; ++i) { f32 frame = inputAccessor.get(i); core::vector3df scale = outputAccessor.get(i); - m_irr_model->addScaleKey(joint, frame, scale); + channel.pushBack(frame, scale); } break; }