diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a86cf9..dedcd1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ add_library(AnimTestbedCode OBJECT src/AnimNodes/BlendNode.cc src/AnimNodes/LockTranslationNode.cc src/AnimationController.cc + src/ozzutils.cc 3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui_draw.cpp 3rdparty/imgui/imgui_widgets.cpp @@ -60,6 +61,8 @@ add_library(AnimTestbedCode OBJECT target_include_directories( AnimTestbedCode + PUBLIC + src ${ThirdPartyIncludeDeps} ) @@ -67,6 +70,7 @@ target_include_directories( add_executable(AnimTestbed) target_include_directories( AnimTestbed + PUBLIC ${ThirdPartyIncludeDeps} ) diff --git a/src/AnimNodes/AnimSamplerNode.cc b/src/AnimNodes/AnimSamplerNode.cc index 70b424b..687f070 100644 --- a/src/AnimNodes/AnimSamplerNode.cc +++ b/src/AnimNodes/AnimSamplerNode.cc @@ -4,9 +4,12 @@ #include "AnimSamplerNode.h" +#include "ozzutils.h" + #include #include "../SkinnedMesh.h" +#include "../ozzutils.h" void AnimSamplerNode::SetAnimation(ozz::animation::Animation* animation, const SyncTrack& sync_track) { m_animation = animation; @@ -36,43 +39,13 @@ void AnimSamplerNode::Evaluate( return; } - ozz::vector root_bone_prev; - root_bone_prev.push_back(ozz::math::SoaTransform()); - sampling_job.ratio = m_anim_ratio_prev; - sampling_job.output = make_span (root_bone_prev); - if (!sampling_job.Run()) { - ozz::log::Err() << "Error sampling animation." << std::endl; - } + ozz::math::Transform root_trans_prev; + calc_bone_translation (m_anim_ratio_prev, 0, m_animation, root_trans_prev); - ozz::vector root_bone_cur; - root_bone_prev.push_back(ozz::math::SoaTransform()); - sampling_job.ratio = m_anim_ratio; - sampling_job.output = make_span (root_bone_cur); - if (!sampling_job.Run()) { - ozz::log::Err() << "Error sampling animation." << std::endl; - } - - ozz::math::SoaFloat3 translation = - root_bone_prev[m_root_bone_index].translation; - float root_prev_trans_x[4]; - float root_prev_trans_y[4]; - float root_prev_trans_z[4]; - _mm_store_ps(root_prev_trans_x, translation.x); - _mm_store_ps(root_prev_trans_y, translation.y); - _mm_store_ps(root_prev_trans_z, translation.z); - - translation = - (*local_matrices)[m_root_bone_index].translation; - float root_current_trans_x[4]; - float root_current_trans_y[4]; - float root_current_trans_z[4]; - _mm_store_ps(root_current_trans_x, translation.x); - _mm_store_ps(root_current_trans_y, translation.y); - _mm_store_ps(root_current_trans_z, translation.z); + ozz::math::Transform root_trans_cur; + calc_bone_translation (m_anim_ratio, 0, m_animation, root_trans_cur); - root_transform->translation.x = root_current_trans_x[0]; - root_transform->translation.y = root_current_trans_y[0]; - root_transform->translation.z = root_current_trans_z[0]; + root_transform->translation = root_trans_cur.translation - root_trans_prev.translation; } void AnimSamplerNode::DrawDebugUi() { diff --git a/src/ozzutils.cc b/src/ozzutils.cc new file mode 100644 index 0000000..d6181e8 --- /dev/null +++ b/src/ozzutils.cc @@ -0,0 +1,57 @@ +// +// Created by martin on 10.12.21. +// + +#include "ozzutils.h" + +#include +#define OZZ_INCLUDE_PRIVATE_HEADER +#include "../src/animation/runtime/animation_keyframe.h" +#undef OZZ_INCLUDE_PRIVATE_HEADER + +void calc_bone_translation( + float ratio, + int i_bone_idx, + const ozz::animation::Animation* i_animation, + ozz::math::Transform& o_transform) { + int key_idx = 1; + const ozz::span& translations = + i_animation->translations(); + + int key_idx_prev = 0; + int key_idx_next = 0; + while (key_idx < translations.size()) { + key_idx_next = key_idx; + if (translations[key_idx].track == i_bone_idx) { + if (translations[key_idx].ratio < ratio) { + key_idx_prev = key_idx; + } else { + break; + } + } + key_idx++; + } + + const ozz::animation::Float3Key& key_prev = translations[key_idx_prev]; + const ozz::animation::Float3Key& key_next = translations[key_idx_next]; + + float r = 0.f; + if (key_prev.ratio != key_next.ratio) { + r = (ratio - key_prev.ratio) / (key_next.ratio - key_prev.ratio); + } + o_transform.translation.x = + ozz::math::HalfToFloat(key_prev.value[0]) + + r + * (ozz::math::HalfToFloat(key_next.value[0]) + - ozz::math::HalfToFloat(key_prev.value[0])); + o_transform.translation.y = + ozz::math::HalfToFloat(key_prev.value[1]) + + r + * (ozz::math::HalfToFloat(key_next.value[1]) + - ozz::math::HalfToFloat(key_prev.value[1])); + o_transform.translation.z = + ozz::math::HalfToFloat(key_prev.value[2]) + + r + * (ozz::math::HalfToFloat(key_next.value[2]) + - ozz::math::HalfToFloat(key_prev.value[2])); +} diff --git a/src/ozzutils.h b/src/ozzutils.h new file mode 100644 index 0000000..4eb4853 --- /dev/null +++ b/src/ozzutils.h @@ -0,0 +1,17 @@ +// +// Created by martin on 10.12.21. +// + +#ifndef ANIMTESTBED_OZZUTILS_H +#define ANIMTESTBED_OZZUTILS_H + +#include +#include "ozz/animation/runtime/animation.h" + +void calc_bone_translation( + float ratio, + int i_bone_idx, + const ozz::animation::Animation* i_animation, + ozz::math::Transform& o_transform); + +#endif //ANIMTESTBED_OZZUTILS_H diff --git a/tests/AnimSampleNodeTests.cc b/tests/AnimSampleNodeTests.cc index daa2a7e..24bd28f 100644 --- a/tests/AnimSampleNodeTests.cc +++ b/tests/AnimSampleNodeTests.cc @@ -6,6 +6,7 @@ #define OZZ_INCLUDE_PRIVATE_HEADER #include "../src/animation/runtime/animation_keyframe.h" #include "catch.hpp" +#include "ozzutils.h" void get_bone_transform( int i_bone_idx, @@ -41,52 +42,6 @@ void sample_bone_transform( get_bone_transform(i_bone_idx, io_local_matrices, o_transform); } -void calc_bone_translation( - float ratio, - int i_bone_idx, - const ozz::animation::Animation* i_animation, - ozz::math::Transform& o_transform) { - int key_idx = 0; - const ozz::span& translations = - i_animation->translations(); - - int key_idx_prev = 0; - int key_idx_next = 0; - while (key_idx < translations.size()) { - key_idx_next = key_idx; - if (translations[key_idx].track == i_bone_idx) { - if (translations[key_idx].ratio < ratio) { - key_idx_prev = key_idx; - } else { - break; - } - } - key_idx++; - } - - const ozz::animation::Float3Key& key_prev = translations[key_idx_prev]; - const ozz::animation::Float3Key& key_next = translations[key_idx_next]; - - float r = 0.f; - if (key_prev.ratio != key_next.ratio) { - r = (ratio - key_prev.ratio) / (key_next.ratio - key_prev.ratio); - } - o_transform.translation.x = - ozz::math::HalfToFloat(key_prev.value[0]) - + r - * (ozz::math::HalfToFloat(key_next.value[0]) - - ozz::math::HalfToFloat(key_prev.value[0])); - o_transform.translation.y = - ozz::math::HalfToFloat(key_prev.value[1]) - + r - * (ozz::math::HalfToFloat(key_next.value[1]) - - ozz::math::HalfToFloat(key_prev.value[1])); - o_transform.translation.z = - ozz::math::HalfToFloat(key_prev.value[2]) - + r - * (ozz::math::HalfToFloat(key_next.value[2]) - - ozz::math::HalfToFloat(key_prev.value[2])); -} TEST_CASE("Sample single bone channel", "[AnimSamplerNode]") { SkinnedMesh skinned_mesh; @@ -167,5 +122,5 @@ TEST_CASE("Root Bone Sampling", "[AnimSamplerNode]") { test_node.UpdateTime(0.2f); ozz::math::Transform root_transform; - // test_node.Evaluate(&skinned_mesh.m_local_matrices, &root_transform); + test_node.Evaluate(&skinned_mesh.m_local_matrices, &root_transform); } \ No newline at end of file