From b518220576df7c9ef541a6baa5fdebd00e91c6e5 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 13 Apr 2022 11:14:29 +0200 Subject: [PATCH] Added test which creates skeleton and animation during runtime. --- CMakeLists.txt | 10 +++ tests/AnimGraphEvalTests.cc | 121 ++++++++++++++++++++++++++++++++++++ tests/data/run.anim.ozz | Bin 0 -> 18178 bytes tests/data/skeleton.ozz | Bin 0 -> 4429 bytes tests/data/walk.anim.ozz | Bin 0 -> 20205 bytes 5 files changed, 131 insertions(+) create mode 100644 tests/AnimGraphEvalTests.cc create mode 100644 tests/data/run.anim.ozz create mode 100644 tests/data/skeleton.ozz create mode 100644 tests/data/walk.anim.ozz diff --git a/CMakeLists.txt b/CMakeLists.txt index a959967..09baef8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,15 +92,25 @@ target_link_libraries(AnimTestbed AnimTestbedCode glfw ozz_base ozz_geometry ozz # Tests add_executable(runtests) +set(ozz_offline_test_objs + 3rdparty/ozz-animation/src/animation/offline/skeleton_builder.cc + 3rdparty/ozz-animation/src/animation/offline/raw_skeleton.cc + 3rdparty/ozz-animation/src/animation/offline/animation_builder.cc + 3rdparty/ozz-animation/src/animation/offline/raw_animation.cc + ) + target_sources(runtests PRIVATE tests/AnimGraphResourceTests.cc + tests/AnimGraphEvalTests.cc tests/SyncTrackTests.cc tests/main.cc + ${ozz_offline_test_objs} ) target_include_directories( runtests PUBLIC $ + PUBLIC $ ${ThirdPartyIncludeDeps} ) diff --git a/tests/AnimGraphEvalTests.cc b/tests/AnimGraphEvalTests.cc new file mode 100644 index 0000000..e9b47d8 --- /dev/null +++ b/tests/AnimGraphEvalTests.cc @@ -0,0 +1,121 @@ +// +// Created by martin on 04.02.22. +// + +#include "AnimGraph/AnimGraph.h" +#include "AnimGraph/AnimGraphEditor.h" +#include "AnimGraph/AnimGraphResource.h" +#include "catch.hpp" +#include "ozz/animation/offline/animation_builder.h" +#include "ozz/animation/offline/raw_animation.h" +#include "ozz/animation/offline/raw_skeleton.h" +#include "ozz/animation/offline/skeleton_builder.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/base/io/archive.h" +#include "ozz/base/io/stream.h" +#include "ozz/base/log.h" + +struct SimpleAnimFixture { + ozz::unique_ptr skeleton = nullptr; + ozz::animation::offline::RawAnimation raw_animation_translation_x; + ozz::unique_ptr animation_translate_x = nullptr; + ozz::animation::offline::RawAnimation raw_animation_translation_y; + ozz::unique_ptr animation_translate_y = nullptr; + ozz::vector animation_output; + ozz::animation::SamplingCache sampling_cache; + + SimpleAnimFixture() { + createSkeleton(); + createAnimations(); + + animation_output.resize(skeleton->num_soa_joints()); + sampling_cache.Resize(skeleton->num_joints()); + } + + void createSkeleton() { + using namespace ozz::animation::offline; + + RawSkeleton raw_skeleton; + RawSkeleton::Joint raw_joint; + + raw_joint.name = "Bone0"; + raw_joint.transform.translation.x = 1.f; + raw_joint.transform.translation.y = 2.f; + raw_joint.transform.translation.z = 3.f; + + raw_skeleton.roots.push_back(raw_joint); + + SkeletonBuilder skeleton_builder; + skeleton = skeleton_builder(raw_skeleton); + } + + void createAnimations() { + using namespace ozz::animation::offline; + + raw_animation_translation_x.name = "TranslationX"; + RawAnimation::JointTrack bone0_track; + RawAnimation::JointTrack::Translations bone0_translations; + + // animation_translate_x + RawAnimation::TranslationKey translation_key; + translation_key.time = 0.f; + translation_key.value = ozz::math::Float3(0.f, 0.f, 0.f); + bone0_translations.push_back(translation_key); + + translation_key.time = 1.f; + translation_key.value = ozz::math::Float3(1.f, 6.f, 9.f); + bone0_translations.push_back(translation_key); + + bone0_track.translations = bone0_translations; + raw_animation_translation_x.tracks.push_back(bone0_track); + raw_animation_translation_x.duration = 1.f; + REQUIRE(raw_animation_translation_x.Validate()); + + AnimationBuilder animation_builder; + animation_translate_x = animation_builder(raw_animation_translation_x); + + // animation_translate_y + raw_animation_translation_y.name = "TranslationY"; + bone0_translations.clear(); + + translation_key.time = 0.f; + translation_key.value = ozz::math::Float3(0.f, 0.f, 0.f); + bone0_translations.push_back(translation_key); + + translation_key.time = 1.f; + translation_key.value = ozz::math::Float3(0.f, 1.f, 0.f); + bone0_translations.push_back(translation_key); + + bone0_track.translations = bone0_translations; + raw_animation_translation_y.tracks.push_back(bone0_track); + raw_animation_translation_y.duration = 1.f; + REQUIRE(raw_animation_translation_y.Validate()); + + animation_translate_y = animation_builder(raw_animation_translation_y); + } +}; + +TEST_CASE_METHOD( + SimpleAnimFixture, + "Create Animations", + "[AnimGraphEvalTests]") { + using namespace ozz::animation::offline; + + ozz::animation::SamplingJob sampling_job; + sampling_job.animation = animation_translate_x.get(); + sampling_job.cache = &sampling_cache; + sampling_job.ratio = 1.f; + sampling_job.output = make_span(animation_output); + REQUIRE(sampling_job.Run()); + + RawAnimation::TranslationKey& translation_key = + raw_animation_translation_x.tracks[0].translations.back(); + + ozz::math::SoaFloat3& sampled_translation = animation_output[0].translation; + CHECK( + sampled_translation.x[0] == Approx(translation_key.value.x).margin(0.01)); + CHECK( + sampled_translation.y[0] == Approx(translation_key.value.y).margin(0.01)); + CHECK( + sampled_translation.z[0] == Approx(translation_key.value.z).margin(0.01)); +} diff --git a/tests/data/run.anim.ozz b/tests/data/run.anim.ozz new file mode 100644 index 0000000000000000000000000000000000000000..2bd1fc090062e316fe605f6f216817ab00cfac0f GIT binary patch literal 18178 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 F{~x5WfQJA8 literal 0 HcmV?d00001 diff --git a/tests/data/walk.anim.ozz b/tests/data/walk.anim.ozz new file mode 100644 index 0000000000000000000000000000000000000000..68af0c28ad151e0f552ac88e163a3ee38856fe33 GIT binary patch literal 20205 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

w!yaT09#zfX=;~xn#cc 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

;Kh?k=|wIM2eIl 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 Ee}Ej)rT_o{ literal 0 HcmV?d00001