From 15871f349cc0d4e547bf6bc8b004c36258891f47 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 26 Mar 2023 11:44:29 +0200 Subject: [PATCH] Updated ozz-animation to version 0.14.1 @35b2efd4 --- 3rdparty/ozz-animation/AUTHORS.md | 6 +- 3rdparty/ozz-animation/CHANGES.md | 23 +- 3rdparty/ozz-animation/CMakeLists.txt | 15 +- 3rdparty/ozz-animation/README.md | 6 +- .../build-utils/cmake/compiler_settings.cmake | 54 +- .../build-utils/cmake/fuse_target.cmake | 9 +- .../cmake/fuse_target_script.cmake | 21 +- .../build-utils/cmake/modules/FindFbx.cmake | 160 ++-- .../build-utils/cmake/shared_library.cmake | 48 ++ .../ozz-animation/extern/gtest/CMakeLists.txt | 3 +- .../extern/gtest/fused-src/gtest/gtest-all.cc | 4 +- .../extern/jsoncpp/CMakeLists.txt | 10 + .../extern/jsoncpp/dist/json/json.h | 2 +- 3rdparty/ozz-animation/howtos/CMakeLists.txt | 3 + .../howtos/custom_skeleton_importer.cc | 7 +- .../offline/additive_animation_builder.h | 3 +- .../ozz/animation/offline/animation_builder.h | 3 +- .../animation/offline/animation_optimizer.h | 5 +- .../include/ozz/animation/offline/export.h | 44 + .../ozz/animation/offline/fbx/export.h | 44 + .../include/ozz/animation/offline/fbx/fbx.h | 13 +- .../ozz/animation/offline/fbx/fbx_animation.h | 22 +- .../ozz/animation/offline/fbx/fbx_skeleton.h | 3 +- .../ozz/animation/offline/raw_animation.h | 5 +- .../animation/offline/raw_animation_utils.h | 17 +- .../ozz/animation/offline/raw_skeleton.h | 19 +- .../include/ozz/animation/offline/raw_track.h | 19 +- .../ozz/animation/offline/skeleton_builder.h | 3 +- .../ozz/animation/offline/tools/export.h | 44 + .../ozz/animation/offline/tools/import2ozz.h | 7 +- .../ozz/animation/offline/track_builder.h | 3 +- .../ozz/animation/offline/track_optimizer.h | 5 +- .../include/ozz/animation/runtime/animation.h | 20 +- .../ozz/animation/runtime/animation_utils.h | 10 +- .../ozz/animation/runtime/blending_job.h | 29 +- .../include/ozz/animation/runtime/export.h | 44 + .../ozz/animation/runtime/ik_aim_job.h | 3 +- .../ozz/animation/runtime/ik_two_bone_job.h | 3 +- .../animation/runtime/local_to_model_job.h | 3 +- .../ozz/animation/runtime/sampling_job.h | 74 +- .../include/ozz/animation/runtime/skeleton.h | 29 +- .../ozz/animation/runtime/skeleton_utils.h | 24 +- .../include/ozz/animation/runtime/track.h | 34 +- .../animation/runtime/track_sampling_job.h | 18 +- .../animation/runtime/track_triggering_job.h | 5 +- .../runtime/track_triggering_job_trait.h | 2 + .../include/ozz/base/containers/array.h | 73 ++ .../ozz/base/containers/array_archive.h | 63 ++ .../ozz/base/containers/std_allocator.h | 2 +- .../ozz/base/containers/string_archive.h | 2 +- .../ozz/base/containers/vector_archive.h | 4 +- .../include/ozz/base/endianness.h | 27 +- .../ozz-animation/include/ozz/base/export.h | 44 + .../include/ozz/base/io/archive.h | 20 +- .../include/ozz/base/io/stream.h | 12 +- 3rdparty/ozz-animation/include/ozz/base/log.h | 18 +- .../include/ozz/base/maths/box.h | 4 +- .../base/maths/internal/simd_math_config.h | 3 +- .../base/maths/internal/simd_math_ref-inl.h | 20 +- .../base/maths/internal/simd_math_sse-inl.h | 28 +- .../include/ozz/base/maths/math_archive.h | 16 +- .../include/ozz/base/maths/quaternion.h | 2 +- .../include/ozz/base/maths/rect.h | 6 +- .../include/ozz/base/maths/simd_math.h | 6 +- .../ozz/base/maths/simd_math_archive.h | 6 +- .../include/ozz/base/maths/soa_math_archive.h | 12 +- .../include/ozz/base/maths/transform.h | 2 +- .../include/ozz/base/maths/vec_float.h | 6 +- .../include/ozz/base/memory/allocator.h | 6 +- .../ozz-animation/include/ozz/base/platform.h | 7 +- .../ozz-animation/include/ozz/base/span.h | 44 +- .../include/ozz/geometry/runtime/export.h | 44 + .../ozz/geometry/runtime/skinning_job.h | 3 +- .../include/ozz/options/export.h | 44 + .../include/ozz/options/options.h | 28 +- .../samples/additive/CMakeLists.txt | 20 +- .../ozz-animation/samples/additive/README.md | 27 +- .../samples/additive/sample_additive.cc | 367 ++++---- .../samples/attach/CMakeLists.txt | 2 +- .../samples/attach/sample_attach.cc | 43 +- .../samples/baked/CMakeLists.txt | 1 + .../samples/baked/sample_baked.cc | 34 +- .../samples/blend/CMakeLists.txt | 1 + .../ozz-animation/samples/blend/README.md | 2 +- .../samples/blend/sample_blend.cc | 26 +- 3rdparty/ozz-animation/samples/demo.zip | Bin 0 -> 4884 bytes .../samples/foot_ik/CMakeLists.txt | 1 + .../samples/foot_ik/sample_foot_ik.cc | 40 +- .../samples/framework/CMakeLists.txt | 7 +- .../samples/framework/application.cc | 48 ++ .../samples/framework/application.h | 24 +- .../ozz-animation/samples/framework/imgui.h | 20 +- .../samples/framework/internal/imgui_impl.cc | 167 +++- .../samples/framework/internal/imgui_impl.h | 6 +- .../framework/internal/renderer_impl.cc | 305 +++++-- .../framework/internal/renderer_impl.h | 9 +- .../samples/framework/internal/shader.cc | 85 ++ .../samples/framework/internal/shader.h | 23 + .../ozz-animation/samples/framework/mesh.h | 7 +- .../samples/framework/renderer.h | 30 +- .../samples/framework/tools/CMakeLists.txt | 3 +- .../samples/framework/tools/fbx2mesh.cc | 39 +- .../ozz-animation/samples/framework/utils.cc | 28 +- .../samples/look_at/CMakeLists.txt | 1 + .../samples/look_at/sample_look_at.cc | 40 +- .../samples/millipede/CMakeLists.txt | 2 +- .../ozz-animation/samples/millipede/README.md | 2 +- .../samples/millipede/sample_millipede.cc | 37 +- .../samples/multithread/CMakeLists.txt | 2 +- .../samples/multithread/README.md | 2 +- .../samples/multithread/sample_multithread.cc | 73 +- .../samples/optimize/CMakeLists.txt | 2 +- .../ozz-animation/samples/optimize/README.md | 2 +- .../samples/optimize/sample_optimize.cc | 84 +- .../samples/partial_blend/CMakeLists.txt | 1 + .../samples/partial_blend/README.md | 2 +- .../partial_blend/sample_partial_blend.cc | 41 +- .../samples/playback/CMakeLists.txt | 1 + .../ozz-animation/samples/playback/README.md | 4 +- .../samples/playback/sample_playback.cc | 10 +- .../samples/skinning/CMakeLists.txt | 1 + .../samples/skinning/sample_skinning.cc | 55 +- .../samples/two_bone_ik/CMakeLists.txt | 1 + .../samples/two_bone_ik/README.md | 2 +- .../samples/two_bone_ik/sample_two_bone_ik.cc | 813 +++++++++--------- .../samples/user_channel/CMakeLists.txt | 1 + .../user_channel/sample_user_channel.cc | 10 +- 3rdparty/ozz-animation/src/CMakeLists.txt | 4 +- .../src/animation/CMakeLists.txt | 4 +- .../src/animation/offline/CMakeLists.txt | 12 +- .../offline/additive_animation_builder.cc | 2 + .../animation/offline/animation_builder.cc | 4 +- .../src/animation/offline/fbx/CMakeLists.txt | 16 +- .../animation/offline/fbx/fbx_animation.cc | 17 +- .../src/animation/offline/fbx/fbx_skeleton.cc | 8 +- .../src/animation/offline/gltf/CMakeLists.txt | 1 + .../animation/offline/gltf/extern/json.hpp | 2 +- .../src/animation/offline/gltf/gltf2ozz.cc | 72 +- .../src/animation/offline/skeleton_builder.cc | 6 +- .../animation/offline/tools/CMakeLists.txt | 9 +- .../offline/tools/import2ozz_anim.cc | 50 +- .../animation/offline/tools/import2ozz_anim.h | 6 +- .../offline/tools/import2ozz_config.cc | 13 +- .../offline/tools/import2ozz_config.h | 5 +- .../offline/tools/import2ozz_skel.cc | 3 +- .../animation/offline/tools/import2ozz_skel.h | 6 +- .../offline/tools/import2ozz_track.h | 16 +- .../animation/offline/tools/reference.json | 2 +- .../src/animation/runtime/CMakeLists.txt | 8 +- .../src/animation/runtime/animation.cc | 15 +- .../animation/runtime/animation_keyframe.h | 6 +- .../src/animation/runtime/blending_job.cc | 30 +- .../src/animation/runtime/sampling_job.cc | 76 +- .../src/animation/runtime/skeleton.cc | 35 +- .../src/animation/runtime/skeleton_utils.cc | 32 +- .../src/animation/runtime/track.cc | 26 +- .../ozz-animation/src/base/CMakeLists.txt | 12 +- 3rdparty/ozz-animation/src/base/io/stream.cc | 8 +- .../src/geometry/runtime/CMakeLists.txt | 13 +- .../ozz-animation/src/options/CMakeLists.txt | 12 +- 3rdparty/ozz-animation/src/options/options.cc | 20 +- .../test/animation/offline/CMakeLists.txt | 15 +- .../additive_animation_builder_tests.cc | 11 +- .../offline/animation_builder_tests.cc | 52 +- .../test/animation/offline/fbx/CMakeLists.txt | 14 +- .../offline/skeleton_builder_tests.cc | 61 +- .../animation/offline/tools/CMakeLists.txt | 13 +- .../test/animation/offline/tools/test2ozz.cc | 61 +- .../animation/offline/track_builder_tests.cc | 57 +- .../test/animation/runtime/CMakeLists.txt | 16 + .../runtime/animation_archive_tests.cc | 25 +- .../animation/runtime/blending_job_tests.cc | 116 +-- .../animation/runtime/sampling_job_tests.cc | 95 +- .../runtime/skeleton_archive_tests.cc | 26 +- .../animation/runtime/skeleton_utils_tests.cc | 61 +- .../runtime/track_triggering_job_tests.cc | 9 +- .../ozz-animation/test/base/CMakeLists.txt | 4 + .../test/base/containers/CMakeLists.txt | 3 + .../std_containers_archive_tests.cc | 51 +- .../base/containers/std_containers_tests.cc | 42 + .../ozz-animation/test/base/io/CMakeLists.txt | 2 + .../test/base/maths/CMakeLists.txt | 4 + .../test/base/maths/simd_float4x4_tests.cc | 28 +- .../test/base/memory/CMakeLists.txt | 2 + .../ozz-animation/test/base/platform_tests.cc | 2 + .../ozz-animation/test/base/span_tests.cc | 62 +- .../test/geometry/runtime/CMakeLists.txt | 3 + .../ozz-animation/test/options/CMakeLists.txt | 10 +- src/AnimGraph/AnimGraphNodes.cc | 6 +- src/AnimGraph/AnimGraphNodes.h | 2 +- src/SkinnedMesh.cc | 4 +- src/SkinnedMesh.h | 2 +- src/main.cc | 2 +- tests/AnimGraphEvalTests.cc | 6 +- 194 files changed, 3495 insertions(+), 1957 deletions(-) create mode 100644 3rdparty/ozz-animation/build-utils/cmake/shared_library.cmake create mode 100644 3rdparty/ozz-animation/include/ozz/animation/offline/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/animation/offline/fbx/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/animation/offline/tools/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/animation/runtime/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/base/containers/array.h create mode 100644 3rdparty/ozz-animation/include/ozz/base/containers/array_archive.h create mode 100644 3rdparty/ozz-animation/include/ozz/base/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/geometry/runtime/export.h create mode 100644 3rdparty/ozz-animation/include/ozz/options/export.h create mode 100644 3rdparty/ozz-animation/samples/demo.zip diff --git a/3rdparty/ozz-animation/AUTHORS.md b/3rdparty/ozz-animation/AUTHORS.md index f274552..cc59ee5 100644 --- a/3rdparty/ozz-animation/AUTHORS.md +++ b/3rdparty/ozz-animation/AUTHORS.md @@ -9,4 +9,8 @@ The following authors have all licensed their contributions to ozz-animation und - Kyle Rocha - Andreas Streichardt - Chen Junjie -- James W. Walker \ No newline at end of file +- James W. Walker +- James W. Fleming +- Kota Iguchi +- MikoĊ‚aj Siedlarek +- Paul Gruenbacher diff --git a/3rdparty/ozz-animation/CHANGES.md b/3rdparty/ozz-animation/CHANGES.md index d464a57..fcf2243 100644 --- a/3rdparty/ozz-animation/CHANGES.md +++ b/3rdparty/ozz-animation/CHANGES.md @@ -1,3 +1,24 @@ +Release version 0.14.0 +---------------------- + +* Samples + - [sample_fbx2mesh] Supports vertices part of a skinned mesh but with a weight of 0. + - [sample_fbx2mesh] Assigns non-influenced vertices to root joint. + +* Library + - [offline] #124 Fixes incorrect root joint detection bug in glTF importer. + - [offline] #129 #130 Copy animation name to output in ozz::animation::offline::AdditiveAnimationBuilder. + - [animation] #103 Allows move constructor and assignment for ozz::animation::Skeleton, ozz::animation::Animation and ozz::animation::Track. + - [animation] Renames SamplingCache to SamplingJob::Context. + - [animation] #110 Renames skeleton bind pose to rest pose, to avoid confusion with skinning bind pose. + - [base] Fixes Float4x4::FromEuler which was swapping pitch and roll. + +* Build pipeline + - Moves CI to github actions. + - #59 Adds support for shared libraries on Windows (dll), Linux and MacOS platforms. + - #111 Removes _GLIBCXX_DEBUG from default build settings as it can create incompatibilities when using prebuilt packages. + - #122 #137 Adds support for gcc 11 compiler. + Release version 0.13.0 ---------------------- @@ -52,7 +73,7 @@ Release version 0.11.0 * Library - [animation] Adds two-bone and aim inverse kinematic solvers. They can be used at runtime to procedurally affect joint local-space transforms. - - [animation] Allows resizing SamplingCache, meaning the can be allocated without knowing the number of joints the cache needs to support. + - [animation] Allows resizing SamplingJob::Context, meaning the can be allocated without knowing the number of joints the cache needs to support. - [animation] Allow ozz::animation::LocalToModelJob to partially update a hierarchy, aka all children of a joint. This is useful when changes to a local-space pose has been limited to part of the joint hierarchy, like when applying IK or modifying model-space matrices independently from local-space transform. - [animation] Changes ozz::animation::Skeleton joints from breadth-first to depth-first. This change breaks compatibility of previous ozz::animation::offline::RawAnimation, ozz::animation::Animation and ozz::animation::Skeleton archives. - [animation] Renames track_triggering_job_stl.h to track_triggering_job_trait.h. diff --git a/3rdparty/ozz-animation/CMakeLists.txt b/3rdparty/ozz-animation/CMakeLists.txt index 769c026..292cad1 100644 --- a/3rdparty/ozz-animation/CMakeLists.txt +++ b/3rdparty/ozz-animation/CMakeLists.txt @@ -5,11 +5,12 @@ project(ozz) # Current version set(OZZ_VERSION_MAJOR 0) -set(OZZ_VERSION_MINOR 13) +set(OZZ_VERSION_MINOR 14) set(OZZ_VERSION_PATCH 0) set(OZZ_VERSION ${OZZ_VERSION_MAJOR}.${OZZ_VERSION_MINOR}.${OZZ_VERSION_PATCH}) # Add project build options +option(BUILD_SHARED_LIBS "Build ozz as shared libraries" OFF) option(ozz_build_tools "Build tools" ON) option(ozz_build_fbx "Build Fbx pipeline (Requires Fbx SDK)" ON) option(ozz_build_gltf "Build glTF importer (Requires c++11)" ON) @@ -18,8 +19,14 @@ option(ozz_build_samples "Build samples" ON) option(ozz_build_howtos "Build howtos" ON) option(ozz_build_tests "Build unit tests" ON) option(ozz_build_simd_ref "Force SIMD math reference implementation" OFF) -option(ozz_build_msvc_rt_dll "Select msvc DLL runtime library" ON) option(ozz_build_postfix "Use per config postfix name" ON) +option(ozz_build_msvc_rt_dll "Select msvc DLL runtime library" OFF) + +# Checks DLL flags +if(WIN32 AND BUILD_SHARED_LIBS AND NOT ozz_build_msvc_rt_dll) + message("Forcing ozz_build_msvc_rt_dll to ON as ozz is being built as dll (BUILD_SHARED_LIBS is ON).") + set(ozz_build_msvc_rt_dll ON) +endif() # Include ozz cmake parameters and scripts include(CheckCXXCompilerFlag) @@ -27,6 +34,7 @@ include(${PROJECT_SOURCE_DIR}/build-utils/cmake/compiler_settings.cmake) include(${PROJECT_SOURCE_DIR}/build-utils/cmake/package_settings.cmake) include(${PROJECT_SOURCE_DIR}/build-utils/cmake/fuse_target.cmake) include(${PROJECT_SOURCE_DIR}/build-utils/cmake/clang_format.cmake) +include(${PROJECT_SOURCE_DIR}/build-utils/cmake/shared_library.cmake) # Add project execution options option(ozz_run_tests_headless "Run samples without rendering (used for unit tests)" ON) @@ -39,6 +47,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/build-utils/cm if(ozz_build_tools AND ozz_build_fbx) # Select a msvc runtime compatible with ozz_build_msvc_rt_dll + set(FBX_SHARED ${BUILD_SHARED_LIBS}) set(FBX_MSVC_RT_DLL ${ozz_build_msvc_rt_dll}) # Search for FBX sdk package @@ -49,6 +58,7 @@ if(ozz_build_tools AND ozz_build_fbx) message("Fbx SDK not found, FBX tools libraries and samples will be skipped.") set(ozz_build_fbx OFF) endif() + else() # Disables fbx if tools are disabled set(ozz_build_fbx OFF) @@ -75,6 +85,7 @@ file(MAKE_DIRECTORY ${ozz_temp_directory}) # Outputs selected options (can be modified by the command line) message("-- ---------------------------------------------------------") message("-- Selected options:") +message("-- - BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS}) message("-- - ozz_build_tools: " ${ozz_build_tools}) message("-- - ozz_build_fbx: " ${ozz_build_fbx}) message("-- - ozz_build_gltf: " ${ozz_build_gltf}) diff --git a/3rdparty/ozz-animation/README.md b/3rdparty/ozz-animation/README.md index bc52b34..98ef549 100644 --- a/3rdparty/ozz-animation/README.md +++ b/3rdparty/ozz-animation/README.md @@ -25,10 +25,10 @@ Samples, tools and tests depend on external libraries (glfw, tinygltf, Fbx SDK, Build status ------------ -| | Linux | Mac OS | Windows | +| | Linux | macOS | Windows | | ------- | ------ | ------ | ------- | -| master | [![Travis-CI](https://travis-ci.org/guillaumeblanc/ozz-animation.svg?branch=master)](http://travis-ci.org/guillaumeblanc/ozz-animation) | [![Travis-CI](https://travis-ci.org/guillaumeblanc/ozz-animation.svg?branch=master)](http://travis-ci.org/guillaumeblanc/ozz-animation) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/guillaumeblanc/ozz-animation?branch=master&svg=true)](http://ci.appveyor.com/project/guillaumeblanc/ozz-animation) | -| develop | [![Travis-CI](https://travis-ci.org/guillaumeblanc/ozz-animation.svg?branch=develop)](http://travis-ci.org/guillaumeblanc/ozz-animation) | [![Travis-CI](https://travis-ci.org/guillaumeblanc/ozz-animation.svg?branch=develop)](http://travis-ci.org/guillaumeblanc/ozz-animation) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/guillaumeblanc/ozz-animation?branch=develop&svg=true)](http://ci.appveyor.com/project/guillaumeblanc/ozz-animation) | +| master | [![Linux](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/linux.yml/badge.svg?branch=master)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/linux.yml) | [![macOS](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/macos.yml/badge.svg?branch=master)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/macos.yml) | [![Windows](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/windows.yml/badge.svg?branch=master)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/windows.yml) | +| develop | [![Linux](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/linux.yml/badge.svg?branch=develop)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/linux.yml) | [![macOS](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/macos.yml/badge.svg?branch=develop)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/macos.yml) | [![Windows](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/windows.yml/badge.svg?branch=develop)](https://github.com/guillaumeblanc/ozz-animation/actions/workflows/windows.yml) | The dashboard for all branches is available [here](http://guillaumeblanc.github.io/ozz-animation/documentation/dashboard/). diff --git a/3rdparty/ozz-animation/build-utils/cmake/compiler_settings.cmake b/3rdparty/ozz-animation/build-utils/cmake/compiler_settings.cmake index b1c3883..daa6f60 100644 --- a/3rdparty/ozz-animation/build-utils/cmake/compiler_settings.cmake +++ b/3rdparty/ozz-animation/build-utils/cmake/compiler_settings.cmake @@ -30,33 +30,34 @@ set(cxx_all_flags # Cross compiler compilation flags # Requires C++11 -set(CMAKE_CXX_STANDARD 11) +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Simd math force ref if(ozz_build_simd_ref) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS OZZ_BUILD_SIMD_REF) + add_compile_definitions(OZZ_BUILD_SIMD_REF) endif() + # Disables crt secure warnings + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + #-------------------------------------- # Modify default MSVC compilation flags -if(MSVC) - +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") #--------------------------- # For the common build flags - # Disables crt secure warnings - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS) - # Adds support for multiple processes builds - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "/MP") + add_compile_options(/MP) # Set the warning level to W4 - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "/W4") + add_compile_options(/W4) # Set warning as error - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "/WX") + add_compile_options(/WX) # Select whether to use the DLL version or the static library version of the Visual C++ runtime library. foreach(flag ${cxx_all_flags}) @@ -68,40 +69,35 @@ if(MSVC) endforeach() #-------------------------------------- -# else consider the compiler as GCC compatible -# Modify default GCC compilation flags +# else consider the compiler as GCC compatible (inc clang) else() # Set the warning level to Wall - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-Wall") + add_compile_options(-Wall) # Enable extra level of warning - #set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-Wextra") + #add_compile_options(-Wextra) # Set warning as error - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-Werror") + add_compile_options(-Werror) - # Disables warning: ignored-attributes reports issue when using _m128 as template argument + # ignored-attributes reports issue when using _m128 as template argument check_cxx_compiler_flag("-Wignored-attributes" W_IGNORED_ATTRIBUTES) if(W_IGNORED_ATTRIBUTES) - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-Wno-ignored-attributes") + add_compile_options(-Wno-ignored-attributes) + endif() + + # Disables c98 retrocompatibility warnings + check_cxx_compiler_flag("-Wc++98-compat-pedantic" W_98_COMPAT_PEDANTIC) + if(W_98_COMPAT_PEDANTIC) + add_compile_options(-Wno-c++98-compat-pedantic) endif() - # Enables warning: sign comparison warnings - check_cxx_compiler_flag("-Wsign-compare" W_SIGN_COMPARE) - if(W_SIGN_COMPARE) - set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-Wsign-compare") - endif() - # Check some more options availability for the targeted compiler + # Check some options availibity for the targetted compiler check_cxx_compiler_flag("-Wnull-dereference" W_NULL_DEREFERENCE) check_cxx_compiler_flag("-Wpragma-pack" W_PRAGMA_PACK) - # Enables debug glibcxx if NDebug isn't defined, not supported by APPLE - if(NOT APPLE) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "$<$:_GLIBCXX_DEBUG>") - endif() - #---------------------- # Sets emscripten output if(EMSCRIPTEN) @@ -157,4 +153,4 @@ if(ozz_build_postfix) set(CMAKE_RELEASE_POSTFIX "_r") set(CMAKE_MINSIZEREL_POSTFIX "_rs") set(CMAKE_RELWITHDEBINFO_POSTFIX "_rd") -endif() \ No newline at end of file +endif() diff --git a/3rdparty/ozz-animation/build-utils/cmake/fuse_target.cmake b/3rdparty/ozz-animation/build-utils/cmake/fuse_target.cmake index 75a9aa6..068f686 100644 --- a/3rdparty/ozz-animation/build-utils/cmake/fuse_target.cmake +++ b/3rdparty/ozz-animation/build-utils/cmake/fuse_target.cmake @@ -9,11 +9,18 @@ function(fuse_target _target_name) # Get all target sources. get_property(target_source_files TARGET ${_target_name} PROPERTY SOURCES) + foreach(src_file ${target_source_files}) + if(IS_ABSOLUTE ${src_file}) + file(RELATIVE_PATH src_file ${CMAKE_CURRENT_LIST_DIR} ${src_file}) + endif() + list(APPEND relative_target_source_files ${src_file}) + endforeach() + add_custom_command( OUTPUT ${output_file} DEPENDS ${target_source_files} ${PROJECT_SOURCE_DIR}/build-utils/cmake/fuse_target_script.cmake - COMMAND ${CMAKE_COMMAND} -Dozz_fuse_output_file="${output_file}" -Dozz_target_source_files="${target_source_files}" -Dozz_fuse_target_dir="${CMAKE_CURRENT_LIST_DIR}" -Dozz_fuse_src_dir="${PROJECT_SOURCE_DIR}" -P "${PROJECT_SOURCE_DIR}/build-utils/cmake/fuse_target_script.cmake") + COMMAND ${CMAKE_COMMAND} -Dozz_fuse_output_file="${output_file}" -Dozz_target_source_files="${relative_target_source_files}" -Dozz_fuse_target_dir="${CMAKE_CURRENT_LIST_DIR}" -Dozz_fuse_src_dir="${PROJECT_SOURCE_DIR}" -P "${PROJECT_SOURCE_DIR}/build-utils/cmake/fuse_target_script.cmake") add_custom_target(BUILD_FUSE_${_target_name} ALL DEPENDS ${output_file}) set_target_properties(BUILD_FUSE_${_target_name} PROPERTIES FOLDER "ozz/fuse") diff --git a/3rdparty/ozz-animation/build-utils/cmake/fuse_target_script.cmake b/3rdparty/ozz-animation/build-utils/cmake/fuse_target_script.cmake index b3d2745..e9b439e 100644 --- a/3rdparty/ozz-animation/build-utils/cmake/fuse_target_script.cmake +++ b/3rdparty/ozz-animation/build-utils/cmake/fuse_target_script.cmake @@ -2,18 +2,25 @@ #---------------------------------------------------------- # Start with new content -string(CONCAT output_content "" "// This file is autogenerated. Do not modify it.\n\n") +string(CONCAT output_content "" "// This file is autogenerated. Any modification might be lost.\n\n") -# Patches arguments so that cmake interprate it as a list. -string (REPLACE " " ";" ozz_target_source_files "${ozz_target_source_files}") +# Patches arguments so that cmake take them as a list. +separate_arguments(ozz_target_source_files) + +string(REPLACE "\\ " " " ozz_fuse_target_dir "${ozz_fuse_target_dir}") +string(REPLACE "\\ " " " ozz_fuse_src_dir "${ozz_fuse_src_dir}") +string(REPLACE "\\ " " " ozz_fuse_output_file "${ozz_fuse_output_file}") # Concat all sources to the output. foreach(src_file ${ozz_target_source_files}) - get_filename_component(src_file_ext ${src_file} EXT) + + get_filename_component(absolute_src_file ${src_file} ABSOLUTE BASE_DIR ${ozz_fuse_target_dir}) + get_filename_component(src_file_ext ${absolute_src_file} EXT) # Handle source files. if(src_file_ext STREQUAL ".cc") - file(READ "${ozz_fuse_target_dir}/${src_file}" src_file_content) + + file(READ "${absolute_src_file}" src_file_content) string(CONCAT output_content "${output_content}" "// Including ${src_file} file.\n\n") string(CONCAT output_content "${output_content}" "${src_file_content}\n") @@ -28,10 +35,12 @@ foreach(internal_include_line ${internal_include_lines}) STRING(REGEX REPLACE "#include \"([^\"]+)\"" "\\1" internal_include_file "${internal_include_line}" ) - file(READ "${ozz_fuse_src_dir}/src/${internal_include_file}" internal_src_file_content) + get_filename_component(internal_src_file src/${internal_include_file} ABSOLUTE BASE_DIR ${ozz_fuse_src_dir}) + file(READ "${internal_src_file}" internal_src_file_content) string(REPLACE "${internal_include_line}" "\n// Includes internal include file ${internal_include_file}\n\n${internal_src_file_content}" output_content "${output_content}") endforeach() +# Output new file file(WRITE "${ozz_fuse_output_file}" "${output_content}") \ No newline at end of file diff --git a/3rdparty/ozz-animation/build-utils/cmake/modules/FindFbx.cmake b/3rdparty/ozz-animation/build-utils/cmake/modules/FindFbx.cmake index a79bd4b..f3bebe0 100644 --- a/3rdparty/ozz-animation/build-utils/cmake/modules/FindFbx.cmake +++ b/3rdparty/ozz-animation/build-utils/cmake/modules/FindFbx.cmake @@ -9,9 +9,15 @@ # FBX_INCLUDE_DIRS - The Fbx SDK include directories # FBX_LIBRARIES - The libraries needed to use Fbx SDK # FBX_LIBRARIES_DEBUG - The libraries needed to use debug Fbx SDK +# FBX_SHARED_LIBRARIES - The shared library file (dll, so) to use Fbx +# FBX_SHARED_LIBRARIES_DEBUG - The shared library file (dll, so) to use debug +# Fbx SDK +# +# A cmake target named fbx::sdk is also created. Adding this target to your +# project via target_link_libraries will setup everything automatically. # # It accepts the following variables as input: -# +# FBX_SHARED - Optional. Select whether to use the shared version fbx sdk. # FBX_MSVC_RT_DLL - Optional. Select whether to use the DLL version or the # static library version of the Visual C++ runtime library. # Default is ON (aka, DLL version: /MD). @@ -52,7 +58,7 @@ ############################################################################### # Generic library search function definition ############################################################################### -function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRARIES_DEBUG) +function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRARIES_DEBUG _OUT_FBX_SHARED_LIBRARIES _OUT_FBX_SHARED_LIBRARIES_DEBUG) # Directory structure depends on the platform: # - Windows: \lib\\\ # - Mac OSX: \lib\\ub\\ @@ -61,7 +67,9 @@ function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRA # Figures out matching compiler/os directory. if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.20) + set(FBX_CP_PATH "vs2019") + elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) set(FBX_CP_PATH "vs2017") elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) set(FBX_CP_PATH "vs2015") @@ -90,19 +98,25 @@ function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRA endif() endif() - # Set libraries names to search, sorted by preference. - set(FBX_SEARCH_LIB_NAMES fbxsdk-static.a libfbxsdk.a fbxsdk.a) - - # Select whether to use the DLL version or the static library version of the Visual C++ runtime library. - # Default is "md", aka use the multithread DLL version of the run-time library. - if (NOT DEFINED FBX_MSVC_RT_DLL OR FBX_MSVC_RT_DLL) - set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk-md.lib) + # Select whether to use the DLL version or the static library version of fbx sdk. + if (FBX_SHARED) + # Dynamic libraries + set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk.lib libfbxsdk.dylib libfbxsdk.so) else() - set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk-mt.lib) - endif() + # static library names + set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk.a libfbxsdk-static.a) + + # Select whether to use the DLL version or the static library version of the Visual C++ runtime library. + # Default is "md", aka use the multithread DLL version of the run-time library. + if (NOT DEFINED FBX_MSVC_RT_DLL OR FBX_MSVC_RT_DLL) + set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk-md.lib) + else() + set(FBX_SEARCH_LIB_NAMES ${FBX_SEARCH_LIB_NAMES} libfbxsdk-mt.lib) + endif() + endif() # Set search path. - set(FBX_SEARCH_LIB_PATH "${_FBX_ROOT_DIR}/lib/${FBX_CP_PATH}/${FBX_PROCESSOR_PATH}") + set(FBX_SEARCH_LIB_PATH "${_FBX_ROOT_DIR}lib/${FBX_CP_PATH}/${FBX_PROCESSOR_PATH}") find_library(FBX_LIB ${FBX_SEARCH_LIB_NAMES} @@ -114,21 +128,42 @@ function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRA ${FBX_SEARCH_LIB_NAMES} HINTS "${FBX_SEARCH_LIB_PATH}/debug/") - if(UNIX) - if(APPLE) # APPLE requires to link with Carbon framework - find_library(CARBON_FRAMEWORK Carbon) - list(APPEND FBX_LIB ${CARBON_FRAMEWORK}) - list(APPEND FBX_LIB_DEBUG ${CARBON_FRAMEWORK}) - else() - find_package(Threads) - list(APPEND FBX_LIB ${CMAKE_THREAD_LIBS_INIT} dl) - list(APPEND FBX_LIB_DEBUG ${CMAKE_THREAD_LIBS_INIT} dl) - endif() + # Looks for shared libraries + if (FBX_SHARED) + set(FBX_SEARCH_SHARED_LIB_NAMES libfbxsdk.dll libfbxsdk.so libfbxsdk.dylib) + + find_file(FBX_SHARED_LIB + ${FBX_SEARCH_SHARED_LIB_NAMES} + HINTS "${FBX_SEARCH_LIB_PATH}/release/") + find_file(FBX_SHARED_LIB_DEBUG + ${FBX_SEARCH_SHARED_LIB_NAMES} + HINTS "${FBX_SEARCH_LIB_PATH}/debug/") + + set(${_OUT_FBX_SHARED_LIBRARIES} ${FBX_SHARED_LIB} PARENT_SCOPE) + set(${_OUT_FBX_SHARED_LIBRARIES_DEBUG} ${FBX_SHARED_LIB_DEBUG} PARENT_SCOPE) endif() + # Create a target for a convenient use of the sdk with cmake + if(FBX_SHARED) + add_library(fbx::sdk SHARED IMPORTED GLOBAL) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_LOCATION ${FBX_SHARED_LIB}) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_LOCATION_DEBUG ${FBX_SHARED_LIB_DEBUG}) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_IMPLIB ${FBX_LIB}) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_IMPLIB_DEBUG ${FBX_LIB_DEBUG}) + target_compile_definitions(fbx::sdk INTERFACE FBXSDK_SHARED) + else() + add_library(fbx::sdk STATIC IMPORTED GLOBAL) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_LOCATION ${FBX_LIB}) + set_property(TARGET fbx::sdk PROPERTY IMPORTED_LOCATION_DEBUG ${FBX_LIB_DEBUG}) + endif() + target_include_directories(fbx::sdk INTERFACE "${_FBX_ROOT_DIR}include/") + target_compile_options(fbx::sdk + INTERFACE $<$:-Wno-null-dereference> + INTERFACE $<$:-Wno-pragma-pack>) + FindFbxVersion(${FBX_ROOT_DIR} PATH_VERSION) - # 2019 SDK needs to link against bundled libxml and zlib + # 2019+ non-DLL SDK needs to link against bundled libxml and zlib if(PATH_VERSION GREATER_EQUAL "2019.1") if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") set(ADDITIONAL_LIB_SEARCH_PATH_RELEASE "${FBX_SEARCH_LIB_PATH}/release/") @@ -150,48 +185,71 @@ function(FindFbxLibrariesGeneric _FBX_ROOT_DIR _OUT_FBX_LIBRARIES _OUT_FBX_LIBRA find_library(XML_LIB ${XML_SEARCH_LIB_NAMES} HINTS ${ADDITIONAL_LIB_SEARCH_PATH_RELEASE}) - find_library(Z_LIB - ${Z_SEARCH_LIB_NAMES} - HINTS ${ADDITIONAL_LIB_SEARCH_PATH_RELEASE}) - - # Searches debug version also find_library(XML_LIB_DEBUG ${XML_SEARCH_LIB_NAMES} HINTS ${ADDITIONAL_LIB_SEARCH_PATH_DEBUG}) - find_library(Z_LIB_DEBUG - ${Z_SEARCH_LIB_NAMES} - HINTS ${ADDITIONAL_LIB_SEARCH_PATH_DEBUG}) - # for whatever reason on apple it will need iconv as well?! - if(APPLE) - find_library(ICONV_LIB - iconv) - - # no special debug search here as mac only anyway - - if(NOT ICONV_LIB) - message(WARNING "FBX found but required iconv was not found!") - endif() - list(APPEND FBX_LIB ${ICONV_LIB}) - list(APPEND FBX_LIB_DEBUG ${ICONV_LIB}) - endif() - - if(NOT XML_LIB) + if(XML_LIB AND XML_LIB_DEBUG) + target_link_libraries(fbx::sdk INTERFACE optimized ${XML_LIB}) + target_link_libraries(fbx::sdk INTERFACE debug ${XML_LIB_DEBUG}) + else() message(WARNING "FBX found but required libxml2 was not found!") endif() - if(NOT Z_LIB) + + find_library(Z_LIB + ${Z_SEARCH_LIB_NAMES} + HINTS ${ADDITIONAL_LIB_SEARCH_PATH_RELEASE}) + find_library(Z_LIB_DEBUG + ${Z_SEARCH_LIB_NAMES} + HINTS ${ADDITIONAL_LIB_SEARCH_PATH_DEBUG}) + + if(Z_LIB AND Z_LIB_DEBUG) + target_link_libraries(fbx::sdk INTERFACE optimized ${Z_LIB}) + target_link_libraries(fbx::sdk INTERFACE debug ${Z_LIB_DEBUG}) + else() message(WARNING "FBX found but required zlib was not found!") endif() list(APPEND FBX_LIB ${XML_LIB} ${Z_LIB}) list(APPEND FBX_LIB_DEBUG ${XML_LIB_DEBUG} ${Z_LIB_DEBUG}) endif() + + # Other dependencies. + if(APPLE) + find_library(ICONV_LIB iconv) + + if(ICONV_LIB) + target_link_libraries(fbx::sdk INTERFACE ${ICONV_LIB}) + list(APPEND FBX_LIB ${ICONV_LIB}) + list(APPEND FBX_LIB_DEBUG ${ICONV_LIB}) + else() + message(WARNING "FBX found but required iconv was not found!") + endif() + + find_library(CARBON_FRAMEWORK Carbon) + if(CARBON_FRAMEWORK) + target_link_libraries(fbx::sdk INTERFACE ${CARBON_FRAMEWORK}) + list(APPEND FBX_LIB ${CARBON_FRAMEWORK}) + list(APPEND FBX_LIB_DEBUG ${CARBON_FRAMEWORK}) + else() + message(WARNING "FBX found but required Carbon was not found!") + endif() + endif() + + if(UNIX) + find_package(Threads) + target_link_libraries(fbx::sdk INTERFACE ${CMAKE_THREAD_LIBS_INIT} dl) + list(APPEND FBX_LIB ${CMAKE_THREAD_LIBS_INIT} dl) + list(APPEND FBX_LIB_DEBUG ${CMAKE_THREAD_LIBS_INIT} dl) + endif() + set(${_OUT_FBX_LIBRARIES} ${FBX_LIB} PARENT_SCOPE) set(${_OUT_FBX_LIBRARIES_DEBUG} ${FBX_LIB_DEBUG} PARENT_SCOPE) + else() - message ("A Fbx SDK was found, but doesn't match your compiler settings.") + message("A Fbx installation was found, but couldn't be matched with current compiler settings.") endif() - # Deduce fbx sdk version + endfunction() ############################################################################### @@ -257,7 +315,7 @@ if(FBX_INCLUDE_DIR) set(FBX_INCLUDE_DIRS "${FBX_INCLUDE_DIR}/include") # Searches libraries according to the current compiler - FindFbxLibrariesGeneric(${FBX_ROOT_DIR} FBX_LIBRARIES FBX_LIBRARIES_DEBUG) + FindFbxLibrariesGeneric(${FBX_ROOT_DIR} FBX_LIBRARIES FBX_LIBRARIES_DEBUG FBX_SHARED_LIBRARIES FBX_SHARED_LIBRARIES_DEBUG) endif() # Handles find_package arguments and set FBX_FOUND to TRUE if all listed variables and version are valid. diff --git a/3rdparty/ozz-animation/build-utils/cmake/shared_library.cmake b/3rdparty/ozz-animation/build-utils/cmake/shared_library.cmake new file mode 100644 index 0000000..4f7a01d --- /dev/null +++ b/3rdparty/ozz-animation/build-utils/cmake/shared_library.cmake @@ -0,0 +1,48 @@ +# Finds target dependencies on shared libraries so they can +# be copied next to the exe. +#---------------------------------------------------------- + +# Finds all target dependencies +function(get_link_libraries OUTPUT_LIST _TARGET) + get_target_property(LIBS ${_TARGET} LINK_LIBRARIES) + + list(APPEND VISITED_TARGETS ${TARGET}) + + set(LIB_FILES "") + foreach(LIB ${LIBS}) + + if (TARGET ${LIB}) + list(FIND VISITED_TARGETS ${LIB} VISITED) + if (${VISITED} EQUAL -1) + get_link_libraries(LINK_LIBS ${LIB}) + list(APPEND LIB_FILES ${LIB} ${LINK_LIBS}) + endif() + endif() + endforeach() + set(VISITED_TARGETS ${VISITED_TARGETS} PARENT_SCOPE) + set(${OUTPUT_LIST} ${LIB_FILES} PARENT_SCOPE) +endfunction() + +# Copy dependent shared libraries next to executable target +function(target_copy_shared_libraries _TARGET) + get_link_libraries(LINKED_TARGETS ${_TARGET}) + + foreach(LINKED_TARGET ${LINKED_TARGETS}) + get_target_property(TARGET_TYPE ${LINKED_TARGET} TYPE) + if(TARGET_TYPE STREQUAL "SHARED_LIBRARY") + list(APPEND DLL_TARGETS "$") + endif() + endforeach() + + if(DLL_TARGETS) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_TARGET}_dll_copy" + DEPENDS ${DLL_TARGETS} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_TARGETS} "./" + COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/${_TARGET}_dll_copy" + VERBATIM) + + # This allows to create a dependency with the command above, so command is executed again when target is built AND a DLL changed + target_sources(${_TARGET} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/${_TARGET}_dll_copy") + endif() +endfunction() \ No newline at end of file diff --git a/3rdparty/ozz-animation/extern/gtest/CMakeLists.txt b/3rdparty/ozz-animation/extern/gtest/CMakeLists.txt index 080134b..ad2282a 100644 --- a/3rdparty/ozz-animation/extern/gtest/CMakeLists.txt +++ b/3rdparty/ozz-animation/extern/gtest/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(gtest +add_library(gtest STATIC fused-src/gtest/gtest_main.cc fused-src/gtest/gtest-all.cc fused-src/gtest/gtest.h) @@ -12,4 +12,3 @@ target_link_libraries(gtest target_include_directories(gtest PUBLIC $) - diff --git a/3rdparty/ozz-animation/extern/gtest/fused-src/gtest/gtest-all.cc b/3rdparty/ozz-animation/extern/gtest/fused-src/gtest/gtest-all.cc index 89867fc..f47f5da 100644 --- a/3rdparty/ozz-animation/extern/gtest/fused-src/gtest/gtest-all.cc +++ b/3rdparty/ozz-animation/extern/gtest/fused-src/gtest/gtest-all.cc @@ -7832,14 +7832,14 @@ static int ExecDeathTestChildMain(void* child_arg) { // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) { - int dummy; + int dummy = 0; *result = (&dummy < ptr); } // Make sure AddressSanitizer does not tamper with the stack here. GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ bool StackGrowsDown() { - int dummy; + int dummy = 0; bool result; StackLowerThanAddress(&dummy, &result); return result; diff --git a/3rdparty/ozz-animation/extern/jsoncpp/CMakeLists.txt b/3rdparty/ozz-animation/extern/jsoncpp/CMakeLists.txt index 68e6222..7a25489 100644 --- a/3rdparty/ozz-animation/extern/jsoncpp/CMakeLists.txt +++ b/3rdparty/ozz-animation/extern/jsoncpp/CMakeLists.txt @@ -6,8 +6,18 @@ add_library(json set_target_properties(json PROPERTIES FOLDER "extern") +target_compile_definitions(json + PUBLIC $<$:JSON_DLL> + PRIVATE $<$:JSON_DLL_BUILD>) + set_target_properties(json PROPERTIES COMPILE_OPTIONS $<$:/wd4702>) +set_target_properties(json + PROPERTIES COMPILE_OPTIONS $<$:/wd4275>) + +target_compile_options(json + PUBLIC $<$:/wd4702> + PUBLIC $<$:/wd4275>) target_include_directories(json PUBLIC $) diff --git a/3rdparty/ozz-animation/extern/jsoncpp/dist/json/json.h b/3rdparty/ozz-animation/extern/jsoncpp/dist/json/json.h index 52eeeb6..eb4095a 100644 --- a/3rdparty/ozz-animation/extern/jsoncpp/dist/json/json.h +++ b/3rdparty/ozz-animation/extern/jsoncpp/dist/json/json.h @@ -416,7 +416,7 @@ public: virtual ~Exception() throw(); virtual char const* what() const throw(); protected: - void operator = (const Exception&); + void operator = (const Exception&) = delete; std::string const msg_; }; diff --git a/3rdparty/ozz-animation/howtos/CMakeLists.txt b/3rdparty/ozz-animation/howtos/CMakeLists.txt index 0d74b4d..3857d4e 100644 --- a/3rdparty/ozz-animation/howtos/CMakeLists.txt +++ b/3rdparty/ozz-animation/howtos/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(load_from_file load_from_file.cc) target_link_libraries(load_from_file ozz_animation) +target_copy_shared_libraries(load_from_file) set_target_properties(load_from_file PROPERTIES FOLDER "howtos") add_test(NAME load_from_file COMMAND load_from_file "${ozz_media_directory}/bin/pab_skeleton.ozz") @@ -18,6 +19,7 @@ add_executable(custom_skeleton_importer custom_skeleton_importer.cc) target_link_libraries(custom_skeleton_importer ozz_animation_offline) +target_copy_shared_libraries(custom_skeleton_importer) set_target_properties(custom_skeleton_importer PROPERTIES FOLDER "howtos") add_test(NAME custom_skeleton_importer COMMAND custom_skeleton_importer) @@ -28,6 +30,7 @@ add_executable(custom_animation_importer custom_animation_importer.cc) target_link_libraries(custom_animation_importer ozz_animation_offline) +target_copy_shared_libraries(custom_animation_importer) set_target_properties(custom_animation_importer PROPERTIES FOLDER "howtos") add_test(NAME custom_animation_importer COMMAND custom_animation_importer) diff --git a/3rdparty/ozz-animation/howtos/custom_skeleton_importer.cc b/3rdparty/ozz-animation/howtos/custom_skeleton_importer.cc index 5a788f7..424b0cd 100644 --- a/3rdparty/ozz-animation/howtos/custom_skeleton_importer.cc +++ b/3rdparty/ozz-animation/howtos/custom_skeleton_importer.cc @@ -25,13 +25,12 @@ // // //----------------------------------------------------------------------------// +#include + #include "ozz/animation/offline/raw_skeleton.h" #include "ozz/animation/offline/skeleton_builder.h" - #include "ozz/animation/runtime/skeleton.h" -#include - // Code for ozz-animation HowTo: "How to write a custon skeleton importer?" int main(int argc, char const* argv[]) { @@ -52,7 +51,7 @@ int main(int argc, char const* argv[]) { // Setup root joints name. root.name = "root"; - // Setup root joints bind-pose/rest transformation, in joint local-space. + // Setup root joints rest pose transformation, in joint local-space. // This is the default skeleton posture (most of the time a T-pose). It's // used as a fallback when there's no animation for a joint. root.transform.translation = ozz::math::Float3(0.f, 1.f, 0.f); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/additive_animation_builder.h b/3rdparty/ozz-animation/include/ozz/animation/offline/additive_animation_builder.h index 1fa09c0..54b5ae9 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/additive_animation_builder.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/additive_animation_builder.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_ADDITIVE_ANIMATION_BUILDER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_ADDITIVE_ANIMATION_BUILDER_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" @@ -46,7 +47,7 @@ struct RawAnimation; // Defines the class responsible for building a delta animation from an offline // raw animation. This is used to create animations compatible with additive // blending. -class AdditiveAnimationBuilder { +class OZZ_ANIMOFFLINE_DLL AdditiveAnimationBuilder { public: // Initializes the builder. AdditiveAnimationBuilder(); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/animation_builder.h b/3rdparty/ozz-animation/include/ozz/animation/offline/animation_builder.h index 27c5657..977bd93 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/animation_builder.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/animation_builder.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_ANIMATION_BUILDER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_ANIMATION_BUILDER_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/memory/unique_ptr.h" namespace ozz { @@ -44,7 +45,7 @@ struct RawAnimation; // Defines the class responsible of building runtime animation instances from // offline raw animations. // No optimization at all is performed on the raw animation. -class AnimationBuilder { +class OZZ_ANIMOFFLINE_DLL AnimationBuilder { public: // Creates an Animation based on _raw_animation and *this builder parameters. // Returns a valid Animation on success. diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/animation_optimizer.h b/3rdparty/ozz-animation/include/ozz/animation/offline/animation_optimizer.h index 1b1cf27..9c60295 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/animation_optimizer.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/animation_optimizer.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_ANIMATION_OPTIMIZER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_ANIMATION_OPTIMIZER_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/containers/map.h" namespace ozz { @@ -54,7 +55,7 @@ struct RawAnimation; // that leads to the hand if user wants it to be precise. Default optimization // tolerances are set in order to favor quality over runtime performances and // memory footprint. -class AnimationOptimizer { +class OZZ_ANIMOFFLINE_DLL AnimationOptimizer { public: // Initializes the optimizer with default tolerances (favoring quality). AnimationOptimizer(); @@ -89,7 +90,7 @@ class AnimationOptimizer { float distance; }; - // Golbal optimization settings. These settings apply to all joints of the + // Global optimization settings. These settings apply to all joints of the // hierarchy, unless overriden by joint specific settings. Setting setting; diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/export.h b/3rdparty/ozz-animation/include/ozz/animation/offline/export.h new file mode 100644 index 0000000..68af6b3 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_ANIMATION_OFFLINE_EXPORT_H_ +#define OZZ_OZZ_ANIMATION_OFFLINE_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_ANIMOFFLINE_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_ANIMOFFLINE_DLL __declspec(dllexport) +#else +#define OZZ_ANIMOFFLINE_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_ANIMOFFLINE_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_ANIMATION_OFFLINE_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/export.h b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/export.h new file mode 100644 index 0000000..92e80f5 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_ANIMATION_OFFLINE_FBX_EXPORT_H_ +#define OZZ_OZZ_ANIMATION_OFFLINE_FBX_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_ANIMATIONFBX_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_ANIMFBX_DLL __declspec(dllexport) +#else +#define OZZ_ANIMFBX_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_ANIMFBX_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_ANIMATION_OFFLINE_FBX_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx.h b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx.h index 92f9a12..d39dd90 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx.h @@ -30,6 +30,7 @@ #include +#include "ozz/animation/offline/fbx/export.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/transform.h" @@ -42,7 +43,7 @@ namespace offline { namespace fbx { // Manages FbxManager instance. -class FbxManagerInstance { +class OZZ_ANIMFBX_DLL FbxManagerInstance { public: // Instantiates FbxManager. FbxManagerInstance(); @@ -58,7 +59,7 @@ class FbxManagerInstance { }; // Default io settings used to import a scene. -class FbxDefaultIOSettings { +class OZZ_ANIMFBX_DLL FbxDefaultIOSettings { public: // Instantiates default settings. explicit FbxDefaultIOSettings(const FbxManagerInstance& _manager); @@ -77,13 +78,13 @@ class FbxDefaultIOSettings { }; // Io settings used to import an animation from a scene. -class FbxAnimationIOSettings : public FbxDefaultIOSettings { +class OZZ_ANIMFBX_DLL FbxAnimationIOSettings : public FbxDefaultIOSettings { public: FbxAnimationIOSettings(const FbxManagerInstance& _manager); }; // Io settings used to import a skeleton from a scene. -class FbxSkeletonIOSettings : public FbxDefaultIOSettings { +class OZZ_ANIMFBX_DLL FbxSkeletonIOSettings : public FbxDefaultIOSettings { public: FbxSkeletonIOSettings(const FbxManagerInstance& _manager); }; @@ -94,7 +95,7 @@ class FbxSkeletonIOSettings : public FbxDefaultIOSettings { // While Fbx sdk FbxAxisSystem::ConvertScene and FbxSystem::ConvertScene only // affect scene root, this class functions can be used to bake nodes, vertices, // animations transformations... -class FbxSystemConverter { +class OZZ_ANIMFBX_DLL FbxSystemConverter { public: // Initialize converter with fbx scene systems. FbxSystemConverter(const FbxAxisSystem& _from_axis, @@ -133,7 +134,7 @@ class FbxSystemConverter { }; // Loads a scene from a Fbx file. -class FbxSceneLoader { +class OZZ_ANIMFBX_DLL FbxSceneLoader { public: // Loads the scene that can then be obtained with scene() function. FbxSceneLoader(const char* _filename, const char* _password, diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_animation.h b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_animation.h index ddcec9c..8dae914 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_animation.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_animation.h @@ -28,6 +28,8 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_FBX_FBX_ANIMATION_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_FBX_FBX_ANIMATION_H_ +#include "ozz/animation/offline/fbx/export.h" + #include "ozz/animation/offline/fbx/fbx.h" #include "ozz/animation/offline/tools/import2ozz.h" @@ -51,34 +53,40 @@ struct RawquaternionTrack; namespace fbx { -OzzImporter::AnimationNames GetAnimationNames(FbxSceneLoader& _scene_loader); +OZZ_ANIMFBX_DLL OzzImporter::AnimationNames GetAnimationNames( + FbxSceneLoader& _scene_loader); -bool ExtractAnimation(const char* _animation_name, +OZZ_ANIMFBX_DLL bool ExtractAnimation(const char* _animation_name, FbxSceneLoader& _scene_loader, const Skeleton& _skeleton, float _sampling_rate, RawAnimation* _animation); -OzzImporter::NodeProperties GetNodeProperties(FbxSceneLoader& _scene_loader, +OZZ_ANIMFBX_DLL OzzImporter::NodeProperties GetNodeProperties( + FbxSceneLoader& _scene_loader, const char* _node_name); -bool ExtractTrack(const char* _animation_name, const char* _node_name, +OZZ_ANIMFBX_DLL bool ExtractTrack(const char* _animation_name, + const char* _node_name, const char* _track_name, OzzImporter::NodeProperty::Type _type, FbxSceneLoader& _scene_loader, float _sampling_rate, RawFloatTrack* _track); -bool ExtractTrack(const char* _animation_name, const char* _node_name, +OZZ_ANIMFBX_DLL bool ExtractTrack(const char* _animation_name, + const char* _node_name, const char* _track_name, OzzImporter::NodeProperty::Type _type, FbxSceneLoader& _scene_loader, float _sampling_rate, RawFloat2Track* _track); -bool ExtractTrack(const char* _animation_name, const char* _node_name, +OZZ_ANIMFBX_DLL bool ExtractTrack(const char* _animation_name, + const char* _node_name, const char* _track_name, OzzImporter::NodeProperty::Type _type, FbxSceneLoader& _scene_loader, float _sampling_rate, RawFloat3Track* _track); -bool ExtractTrack(const char* _animation_name, const char* _node_name, +OZZ_ANIMFBX_DLL bool ExtractTrack(const char* _animation_name, + const char* _node_name, const char* _track_name, OzzImporter::NodeProperty::Type _type, FbxSceneLoader& _scene_loader, float _sampling_rate, diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_skeleton.h b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_skeleton.h index 79ca680..4fd8e28 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_skeleton.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/fbx/fbx_skeleton.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_FBX_FBX_SKELETON_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_FBX_FBX_SKELETON_H_ +#include "ozz/animation/offline/fbx/export.h" #include "ozz/animation/offline/fbx/fbx.h" #include "ozz/animation/offline/tools/import2ozz.h" @@ -39,7 +40,7 @@ struct RawSkeleton; namespace fbx { -bool ExtractSkeleton(FbxSceneLoader& _loader, +OZZ_ANIMFBX_DLL bool ExtractSkeleton(FbxSceneLoader& _loader, const OzzImporter::NodeType& _types, RawSkeleton* _skeleton); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation.h b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation.h index 767521c..3bb4e70 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_RAW_ANIMATION_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_RAW_ANIMATION_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/containers/string.h" #include "ozz/base/containers/vector.h" #include "ozz/base/io/archive_traits.h" @@ -55,7 +56,7 @@ namespace offline { // 3. Keyframes' time are all within [0,animation duration] range. // Animations that would fail this validation will fail to be converted by the // AnimationBuilder. -struct RawAnimation { +struct OZZ_ANIMOFFLINE_DLL RawAnimation { // Constructs a valid RawAnimation with a 1s default duration. RawAnimation(); @@ -146,7 +147,7 @@ OZZ_IO_TYPE_TAG("ozz-raw_animation", animation::offline::RawAnimation) // Should not be called directly but through io::Archive << and >> operators. template <> -struct Extern { +struct OZZ_ANIMOFFLINE_DLL Extern { static void Save(OArchive& _archive, const animation::offline::RawAnimation* _animations, size_t _count); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation_utils.h b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation_utils.h index db95900..e8b0551 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation_utils.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_animation_utils.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_RAW_ANIMATION_UTILS_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_RAW_ANIMATION_UTILS_H_ +#include "ozz/animation/offline/export.h" #include "ozz/animation/offline/raw_animation.h" #include "ozz/base/maths/transform.h" @@ -38,22 +39,25 @@ namespace animation { namespace offline { // Translation interpolation method. -math::Float3 LerpTranslation(const math::Float3& _a, const math::Float3& _b, +OZZ_ANIMOFFLINE_DLL math::Float3 LerpTranslation(const math::Float3& _a, + const math::Float3& _b, float _alpha); // Rotation interpolation method. -math::Quaternion LerpRotation(const math::Quaternion& _a, +OZZ_ANIMOFFLINE_DLL math::Quaternion LerpRotation(const math::Quaternion& _a, const math::Quaternion& _b, float _alpha); // Scale interpolation method. -math::Float3 LerpScale(const math::Float3& _a, const math::Float3& _b, +OZZ_ANIMOFFLINE_DLL math::Float3 LerpScale(const math::Float3& _a, + const math::Float3& _b, float _alpha); // Samples a RawAnimation track. This function shall be used for offline // purpose. Use ozz::animation::Animation and ozz::animation::SamplingJob for // runtime purpose. // Returns false if track is invalid. -bool SampleTrack(const RawAnimation::JointTrack& _track, float _time, +OZZ_ANIMOFFLINE_DLL bool SampleTrack(const RawAnimation::JointTrack& _track, + float _time, ozz::math::Transform* _transform); // Samples a RawAnimation. This function shall be used for offline @@ -61,7 +65,8 @@ bool SampleTrack(const RawAnimation::JointTrack& _track, float _time, // runtime purpose. // _animation must be valid. // Returns false output range is too small or animation is invalid. -bool SampleAnimation(const RawAnimation& _animation, float _time, +OZZ_ANIMOFFLINE_DLL bool SampleAnimation( + const RawAnimation& _animation, float _time, const span& _transforms); // Implement fixed rate keyframe time iteration. This utility purpose is to @@ -69,7 +74,7 @@ bool SampleAnimation(const RawAnimation& _animation, float _time, // between consecutive time samples have a fixed period. // This sounds trivial, but floating point error could occur if keyframe time // was accumulated for a long duration. -class FixedRateSamplingTime { +class OZZ_ANIMOFFLINE_DLL FixedRateSamplingTime { public: FixedRateSamplingTime(float _duration, float _frequency); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_skeleton.h b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_skeleton.h index 26b287d..6b5348d 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_skeleton.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_skeleton.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_RAW_SKELETON_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_RAW_SKELETON_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/containers/string.h" #include "ozz/base/containers/vector.h" #include "ozz/base/io/archive_traits.h" @@ -41,13 +42,13 @@ namespace offline { // This skeleton type is not intended to be used in run time. It is used to // define the offline skeleton object that can be converted to the runtime // skeleton using the SkeletonBuilder. This skeleton structure exposes joints' -// hierarchy. A joint is defined with a name, a transformation (its bind pose), -// and its children. Children are exposed as a public std::vector of joints. -// This same type is used for skeleton roots, also exposed from the public API. -// The public API exposed through std:vector's of joints can be used freely with -// the only restriction that the total number of joints does not exceed -// Skeleton::kMaxJoints. -struct RawSkeleton { +// hierarchy. A joint is defined with a name, a transformation (its rest_pose +// pose), and its children. Children are exposed as a public std::vector of +// joints. This same type is used for skeleton roots, also exposed from the +// public API. The public API exposed through std:vector's of joints can be used +// freely with the only restriction that the total number of joints does not +// exceed Skeleton::kMaxJoints. +struct OZZ_ANIMOFFLINE_DLL RawSkeleton { // Construct an empty skeleton. RawSkeleton(); @@ -65,7 +66,7 @@ struct RawSkeleton { // The name of the joint. ozz::string name; - // Joint bind pose transformation in local space. + // Joint rest pose transformation in local space. math::Transform transform; }; @@ -139,7 +140,7 @@ OZZ_IO_TYPE_TAG("ozz-raw_skeleton", animation::offline::RawSkeleton) // Should not be called directly but through io::Archive << and >> operators. template <> -struct Extern { +struct OZZ_ANIMOFFLINE_DLL Extern { static void Save(OArchive& _archive, const animation::offline::RawSkeleton* _skeletons, size_t _count); diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_track.h b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_track.h index 76f9752..d3eb6e6 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/raw_track.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/raw_track.h @@ -28,11 +28,10 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_RAW_TRACK_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_RAW_TRACK_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/containers/string.h" #include "ozz/base/containers/vector.h" - #include "ozz/base/io/archive_traits.h" - #include "ozz/base/maths/quaternion.h" #include "ozz/base/maths/vec_float.h" @@ -85,7 +84,7 @@ namespace internal { // RawTrack that would fail this validation will fail to be converted by // the RawTrackBuilder. template -struct RawTrack { +struct OZZ_ANIMOFFLINE_DLL RawTrack { typedef _ValueType ValueType; typedef RawTrackKeyframe Keyframe; @@ -109,11 +108,15 @@ struct RawTrack { } // namespace internal // Offline user-channel animation track type instantiation. -struct RawFloatTrack : public internal::RawTrack {}; -struct RawFloat2Track : public internal::RawTrack {}; -struct RawFloat3Track : public internal::RawTrack {}; -struct RawFloat4Track : public internal::RawTrack {}; -struct RawQuaternionTrack : public internal::RawTrack {}; +struct OZZ_ANIMOFFLINE_DLL RawFloatTrack : public internal::RawTrack {}; +struct OZZ_ANIMOFFLINE_DLL RawFloat2Track + : public internal::RawTrack {}; +struct OZZ_ANIMOFFLINE_DLL RawFloat3Track + : public internal::RawTrack {}; +struct OZZ_ANIMOFFLINE_DLL RawFloat4Track + : public internal::RawTrack {}; +struct OZZ_ANIMOFFLINE_DLL RawQuaternionTrack + : public internal::RawTrack {}; } // namespace offline } // namespace animation diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/skeleton_builder.h b/3rdparty/ozz-animation/include/ozz/animation/offline/skeleton_builder.h index c045d87..e31e81b 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/skeleton_builder.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/skeleton_builder.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_SKELETON_BUILDER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_SKELETON_BUILDER_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/maths/transform.h" #include "ozz/base/memory/unique_ptr.h" @@ -43,7 +44,7 @@ namespace offline { struct RawSkeleton; // Defines the class responsible of building Skeleton instances. -class SkeletonBuilder { +class OZZ_ANIMOFFLINE_DLL SkeletonBuilder { public: // Creates a Skeleton based on _raw_skeleton and *this builder parameters. // Returns a Skeleton instance on success, an empty unique_ptr on failure. See diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/tools/export.h b/3rdparty/ozz-animation/include/ozz/animation/offline/tools/export.h new file mode 100644 index 0000000..9dc8b7f --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/tools/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_ANIMATION_OFFLINE_TOOLS_EXPORT_H_ +#define OZZ_OZZ_ANIMATION_OFFLINE_TOOLS_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_ANIMATIONTOOLS_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_ANIMTOOLS_DLL __declspec(dllexport) +#else +#define OZZ_ANIMTOOLS_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_ANIMTOOLS_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_ANIMATION_OFFLINE_TOOLS_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/tools/import2ozz.h b/3rdparty/ozz-animation/include/ozz/animation/offline/tools/import2ozz.h index 1b02e43..6829dc0 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/tools/import2ozz.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/tools/import2ozz.h @@ -28,6 +28,8 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_H_ +#include "ozz/animation/offline/tools/export.h" + #include "ozz/base/containers/string.h" #include "ozz/base/containers/vector.h" @@ -35,6 +37,8 @@ #include "ozz/animation/offline/raw_skeleton.h" #include "ozz/animation/offline/raw_track.h" +#include "ozz/base/platform.h" + namespace ozz { namespace animation { @@ -51,7 +55,7 @@ namespace offline { // To import a new source data format, one will implement the pure virtual // functions of this interface. All the conversions end error processing are // done by the tool. -class OzzImporter { +class OZZ_ANIMTOOLS_DLL OzzImporter { public: virtual ~OzzImporter() {} @@ -72,6 +76,7 @@ class OzzImporter { bool camera : 1; // Uses camera nodes as skeleton joints. bool geometry : 1; // Uses geometry nodes as skeleton joints. bool light : 1; // Uses light nodes as skeleton joints. + bool null : 1; // Uses null nodes as skeleton joints. bool any : 1; // Uses any node type as skeleton joints, including those // listed above and any other. }; diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/track_builder.h b/3rdparty/ozz-animation/include/ozz/animation/offline/track_builder.h index 9011f83..39ba99b 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/track_builder.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/track_builder.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_TRACK_BUILDER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_TRACK_BUILDER_H_ +#include "ozz/animation/offline/export.h" #include "ozz/base/memory/unique_ptr.h" namespace ozz { @@ -53,7 +54,7 @@ struct RawQuaternionTrack; // offline tracks.The input raw track is first validated. Runtime conversion of // a validated raw track cannot fail. Note that no optimization is performed on // the data at all. -class TrackBuilder { +class OZZ_ANIMOFFLINE_DLL TrackBuilder { public: // Creates a Track based on _raw_track and *this builder parameters. // Returns a track instance on success, an empty unique_ptr on failure. See diff --git a/3rdparty/ozz-animation/include/ozz/animation/offline/track_optimizer.h b/3rdparty/ozz-animation/include/ozz/animation/offline/track_optimizer.h index 6fd09f1..d5c1dde 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/offline/track_optimizer.h +++ b/3rdparty/ozz-animation/include/ozz/animation/offline/track_optimizer.h @@ -28,6 +28,9 @@ #ifndef OZZ_OZZ_ANIMATION_OFFLINE_TRACK_OPTIMIZER_H_ #define OZZ_OZZ_ANIMATION_OFFLINE_TRACK_OPTIMIZER_H_ +#include "ozz/animation/offline/export.h" +#include "ozz/base/platform.h" + namespace ozz { namespace animation { namespace offline { @@ -44,7 +47,7 @@ struct RawQuaternionTrack; // keyframes (within a tolerance value) are removed from the track. Default // optimization tolerances are set in order to favor quality over runtime // performances and memory footprint. -class TrackOptimizer { +class OZZ_ANIMOFFLINE_DLL TrackOptimizer { public: // Initializes the optimizer with default tolerances (favoring quality). TrackOptimizer(); diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/animation.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/animation.h index 4b6d97a..755c5e3 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/animation.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/animation.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_ANIMATION_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_ANIMATION_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/io/archive_traits.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" @@ -58,11 +59,19 @@ struct QuaternionKey; // joints order of the runtime skeleton structure. In order to optimize cache // coherency when sampling the animation, Keyframes in this array are sorted by // time, then by track number. -class Animation { +class OZZ_ANIMATION_DLL Animation { public: // Builds a default animation. Animation(); + // Allow moves. + Animation(Animation&&); + Animation& operator=(Animation&&); + + // Delete copies. + Animation(Animation const&) = delete; + Animation& operator=(Animation const&) = delete; + // Declares the public non-virtual destructor. ~Animation(); @@ -80,9 +89,7 @@ class Animation { const char* name() const { return name_ ? name_ : ""; } // Gets the buffer of translations keys. - span translations() const { - return translations_; - } + span translations() const { return translations_; } // Gets the buffer of rotation keys. span rotations() const { return rotations_; } @@ -98,12 +105,7 @@ class Animation { void Save(ozz::io::OArchive& _archive) const; void Load(ozz::io::IArchive& _archive, uint32_t _version); - protected: private: - // Disables copy and assignation. - Animation(Animation const&); - void operator=(Animation const&); - // AnimationBuilder class is allowed to instantiate an Animation. friend class offline::AnimationBuilder; diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/animation_utils.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/animation_utils.h index 9bd3423..73ce031 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/animation_utils.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/animation_utils.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_ANIMATION_UTILS_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_ANIMATION_UTILS_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/animation/runtime/animation.h" namespace ozz { @@ -35,9 +36,12 @@ namespace animation { // Count translation, rotation or scale keyframes for a given track number. Use // a negative _track value to count all tracks. -int CountTranslationKeyframes(const Animation& _animation, int _track = -1); -int CountRotationKeyframes(const Animation& _animation, int _track = -1); -int CountScaleKeyframes(const Animation& _animation, int _track = -1); +OZZ_ANIMATION_DLL int CountTranslationKeyframes(const Animation& _animation, + int _track = -1); +OZZ_ANIMATION_DLL int CountRotationKeyframes(const Animation& _animation, + int _track = -1); +OZZ_ANIMATION_DLL int CountScaleKeyframes(const Animation& _animation, + int _track = -1); } // namespace animation } // namespace ozz #endif // OZZ_OZZ_ANIMATION_RUNTIME_ANIMATION_UTILS_H_ diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/blending_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/blending_job.h index f5ff0bd..12bcb6c 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/blending_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/blending_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_BLENDING_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_BLENDING_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/span.h" @@ -44,15 +45,15 @@ namespace animation { // (the result of a sampled animation) according to their respective weight, // into one output pose. // The number of transforms/joints blended by the job is defined by the number -// of transforms of the bind pose (note that this is a SoA format). This means -// that all buffers must be at least as big as the bind pose buffer. +// of transforms of the rest pose (note that this is a SoA format). This means +// that all buffers must be at least as big as the rest pose buffer. // Partial animation blending is supported through optional joint weights that // can be specified with layers joint_weights buffer. Unspecified joint weights // are considered as a unit weight of 1.f, allowing to mix full and partial // blend operations in a single pass. // The job does not owned any buffers (input/output) and will thus not delete // them during job's destruction. -struct BlendingJob { +struct OZZ_ANIMATION_DLL BlendingJob { // Default constructor, initializes default values. BlendingJob(); @@ -63,7 +64,7 @@ struct BlendingJob { // -if any layer is not valid. // -if output range is not valid. // -if any buffer (including layers' content : transform, joint weights...) is - // smaller than the bind pose buffer. + // smaller than the rest pose buffer. // -if the threshold value is less than or equal to 0.f. bool Validate() const; @@ -75,7 +76,7 @@ struct BlendingJob { // Defines a layer of blending input data (local space transforms) and // parameters (weights). - struct Layer { + struct OZZ_ANIMATION_DLL Layer { // Default constructor, initializes default values. Layer(); @@ -86,8 +87,8 @@ struct BlendingJob { // The range [begin,end[ of input layer posture. This buffer expect to store // local space transforms, that are usually outputted from a sampling job. - // This range must be at least as big as the bind pose buffer, even though - // only the number of transforms defined by the bind pose buffer will be + // This range must be at least as big as the rest pose buffer, even though + // only the number of transforms defined by the rest pose buffer will be // processed. span transform; @@ -95,8 +96,8 @@ struct BlendingJob { // layer. // If both pointers are nullptr (default case) then per joint weight // blending is disabled. A valid range is defined as being at least as big - // as the bind pose buffer, even though only the number of transforms - // defined by the bind pose buffer will be processed. When a layer doesn't + // as the rest pose buffer, even though only the number of transforms + // defined by the rest pose buffer will be processed. When a layer doesn't // specifies per joint weights, then it is implicitly considered as // being 1.f. This default value is a reference value for the normalization // process, which implies that the range of values for joint weights should @@ -106,7 +107,7 @@ struct BlendingJob { span joint_weights; }; - // The job blends the bind pose to the output when the accumulated weight of + // The job blends the rest pose to the output when the accumulated weight of // all layers is less than this threshold value. // Must be greater than 0.f. float threshold; @@ -119,18 +120,18 @@ struct BlendingJob { // The range of layers that must be added to the output. span additive_layers; - // The skeleton bind pose. The size of this buffer defines the number of + // The skeleton rest pose. The size of this buffer defines the number of // transforms to blend. This is the reference because this buffer is defined // by the skeleton that all the animations belongs to. // It is used when the accumulated weight for a bone on all layers is // less than the threshold value, in order to fall back on valid transforms. - span bind_pose; + span rest_pose; // Job output. // The range of output transforms to be filled with blended layer // transforms during job execution. - // Must be at least as big as the bind pose buffer, but only the number of - // transforms defined by the bind pose buffer size will be processed. + // Must be at least as big as the rest pose buffer, but only the number of + // transforms defined by the rest pose buffer size will be processed. span output; }; } // namespace animation diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/export.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/export.h new file mode 100644 index 0000000..3c97667 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_ANIMATION_RUNTIME_EXPORT_H_ +#define OZZ_OZZ_ANIMATION_RUNTIME_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_ANIMATION_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_ANIMATION_DLL __declspec(dllexport) +#else +#define OZZ_ANIMATION_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_ANIMATION_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_ANIMATION_RUNTIME_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_aim_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_aim_job.h index 858fbc1..298fffa 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_aim_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_aim_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_IK_AIM_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_IK_AIM_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" #include "ozz/base/maths/simd_math.h" @@ -50,7 +51,7 @@ namespace animation { // vector should aim the target. // Result is unstable if joint-to-target direction is parallel to pole vector, // or if target is too close to joint position. -struct IKAimJob { +struct OZZ_ANIMATION_DLL IKAimJob { // Default constructor, initializes default values. IKAimJob(); diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_two_bone_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_two_bone_job.h index fb5f93c..d642bd8 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_two_bone_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/ik_two_bone_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_IK_TWO_BONE_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_IK_TWO_BONE_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" #include "ozz/base/maths/simd_math.h" @@ -51,7 +52,7 @@ namespace animation { // ancestors (joints in-between will simply remain fixed). // Implementation is inspired by Autodesk Maya 2 bone IK, improved stability // wise and extended with Soften IK. -struct IKTwoBoneJob { +struct OZZ_ANIMATION_DLL IKTwoBoneJob { // Constructor, initializes default values. IKTwoBoneJob(); diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/local_to_model_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/local_to_model_job.h index 313f77b..510e1c4 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/local_to_model_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/local_to_model_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_LOCAL_TO_MODEL_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_LOCAL_TO_MODEL_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" @@ -55,7 +56,7 @@ class Skeleton; // ordered like skeleton's joints. Output are matrices, because the combination // of affine transformations can contain shearing or complex transformation // that cannot be represented as Transform object. -struct LocalToModelJob { +struct OZZ_ANIMATION_DLL LocalToModelJob { // Default constructor, initializes default values. LocalToModelJob(); diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/sampling_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/sampling_job.h index 3fe65a5..43086c0 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/sampling_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/sampling_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_SAMPLING_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_SAMPLING_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" @@ -43,19 +44,16 @@ namespace animation { // Forward declares the animation type to sample. class Animation; -// Forward declares the cache object used by the SamplingJob. -class SamplingCache; - // Samples an animation at a given time ratio in the unit interval [0,1] (where // 0 is the beginning of the animation, 1 is the end), to output the // corresponding posture in local-space. -// SamplingJob uses a cache (aka SamplingCache) to store intermediate values -// (decompressed animation keyframes...) while sampling. This cache also stores -// pre-computed values that allows drastic optimization while playing/sampling -// the animation forward. Backward sampling works, but isn't optimized through -// the cache. The job does not owned the buffers (in/output) and will thus not -// delete them during job's destruction. -struct SamplingJob { +// SamplingJob uses a context (aka SamplingJob::Context) to store intermediate +// values (decompressed animation keyframes...) while sampling. This context +// also stores pre-computed values that allows drastic optimization while +// playing/sampling the animation forward. Backward sampling works, but isn't +// optimized through the context. The job does not owned the buffers (in/output) +// and will thus not delete them during job's destruction. +struct OZZ_ANIMATION_DLL SamplingJob { // Default constructor, initializes default values. SamplingJob(); @@ -80,8 +78,11 @@ struct SamplingJob { // The animation to sample. const Animation* animation; - // A cache object that must be big enough to sample *this animation. - SamplingCache* cache; + // Forward declares the context object used by the SamplingJob. + class Context; + + // A context object that must be big enough to sample *this animation. + Context* context; // Job output. // The output range to be filled with sampled joints during job execution. @@ -98,61 +99,62 @@ struct InterpSoaFloat3; struct InterpSoaQuaternion; } // namespace internal -// Declares the cache object used by the workload to take advantage of the +// Declares the context object used by the workload to take advantage of the // frame coherency of animation sampling. -class SamplingCache { +class OZZ_ANIMATION_DLL SamplingJob::Context { public: - // Constructs an empty cache. The cache needs to be resized with the + // Constructs an empty context. The context needs to be resized with the // appropriate number of tracks before it can be used with a SamplingJob. - SamplingCache(); + Context(); - // Constructs a cache that can be used to sample any animation with at most + // Constructs a context that can be used to sample any animation with at most // _max_tracks tracks. _num_tracks is internally aligned to a multiple of // soa size, which means max_tracks() can return a different (but bigger) // value than _max_tracks. - explicit SamplingCache(int _max_tracks); + explicit Context(int _max_tracks); - // Deallocates cache. - ~SamplingCache(); + // Disables copy and assignation. + Context(Context const&) = delete; + Context& operator=(Context const&) = delete; - // Resize the number of joints that the cache can support. - // This also implicitly invalidate the cache. + // Deallocates context. + ~Context(); + + // Resize the number of joints that the context can support. + // This also implicitly invalidate the context. void Resize(int _max_tracks); - // Invalidate the cache. - // The SamplingJob automatically invalidates a cache when required + // Invalidate the context. + // The SamplingJob automatically invalidates a context when required // during sampling. This automatic mechanism is based on the animation // address and sampling time ratio. The weak point is that it can result in a // crash if ever the address of an animation is used again with another // animation (could be the result of successive call to delete / new). - // Therefore it is recommended to manually invalidate a cache when it is - // known that this cache will not be used for with an animation again. + // Therefore it is recommended to manually invalidate a context when it is + // known that this context will not be used for with an animation again. void Invalidate(); - // The maximum number of tracks that the cache can handle. + // The maximum number of tracks that the context can handle. int max_tracks() const { return max_soa_tracks_ * 4; } int max_soa_tracks() const { return max_soa_tracks_; } private: - // Disables copy and assignation. - SamplingCache(SamplingCache const&); - void operator=(SamplingCache const&); - friend struct SamplingJob; - // Steps the cache in order to use it for a potentially new animation and + // Steps the context in order to use it for a potentially new animation and // ratio. If the _animation is different from the animation currently cached, // or if the _ratio shows that the animation is played backward, then the - // cache is invalidated and reseted for the new _animation and _ratio. + // context is invalidated and reset for the new _animation and _ratio. void Step(const Animation& _animation, float _ratio); - // The animation this cache refers to. nullptr means that the cache is invalid. + // The animation this context refers to. nullptr means that the context is + // invalid. const Animation* animation_; // The current time ratio in the animation. float ratio_; - // The number of soa tracks that can store this cache. + // The number of soa tracks that can store this context. int max_soa_tracks_; // Soa hot data to interpolate. @@ -166,7 +168,7 @@ class SamplingCache { int* rotation_keys_; int* scale_keys_; - // Current cursors in the animation. 0 means that the cache is invalid. + // Current cursors in the animation. 0 means that the context is invalid. int translation_cursor_; int rotation_cursor_; int scale_cursor_; diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton.h index 23e53cb..4fdc22a 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_SKELETON_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_SKELETON_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/io/archive_traits.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" @@ -48,16 +49,16 @@ class SkeletonBuilder; } // This runtime skeleton data structure provides a const-only access to joint -// hierarchy, joint names and bind-pose. This structure is filled by the +// hierarchy, joint names and rest-pose. This structure is filled by the // SkeletonBuilder and can be serialize/deserialized. -// Joint names, bind-poses and hierarchy information are all stored in separate +// Joint names, rest-poses and hierarchy information are all stored in separate // arrays of data (as opposed to joint structures for the RawSkeleton), in order // to closely match with the way runtime algorithms use them. Joint hierarchy is // packed as an array of parent jont indices (16 bits), stored in depth-first // order. This is enough to traverse the whole joint hierarchy. See // IterateJointsDF() from skeleton_utils.h that implements a depth-first // traversal utility. -class Skeleton { +class OZZ_ANIMATION_DLL Skeleton { public: // Defines Skeleton constant values. enum Constants { @@ -81,6 +82,14 @@ class Skeleton { // Builds a default skeleton. Skeleton(); + // Allow move. + Skeleton(Skeleton&&); + Skeleton& operator=(Skeleton&&); + + // Disables copy and assignation. + Skeleton(Skeleton const&) = delete; + Skeleton& operator=(Skeleton const&) = delete; + // Declares the public non-virtual destructor. ~Skeleton(); @@ -91,9 +100,9 @@ class Skeleton { // skeleton. This value is useful to allocate SoA runtime data structures. int num_soa_joints() const { return (num_joints() + 3) / 4; } - // Returns joint's bind poses. Bind poses are stored in soa format. - span joint_bind_poses() const { - return joint_bind_poses_; + // Returns joint's rest poses. Rest poses are stored in soa format. + span joint_rest_poses() const { + return joint_rest_poses_; } // Returns joint's parent indices range. @@ -110,10 +119,6 @@ class Skeleton { void Load(ozz::io::IArchive& _archive, uint32_t _version); private: - // Disables copy and assignation. - Skeleton(Skeleton const&); - void operator=(Skeleton const&); - // Internal allocation/deallocation function. // Allocate returns the beginning of the contiguous buffer of names. char* Allocate(size_t _char_count, size_t _num_joints); @@ -125,8 +130,8 @@ class Skeleton { // Buffers below store joint informations in joing depth first order. Their // size is equal to the number of joints of the skeleton. - // Bind pose of every joint in local space. - span joint_bind_poses_; + // Rest pose of every joint in local space. + span joint_rest_poses_; // Array of joint parent indexes. span joint_parents_; diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton_utils.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton_utils.h index 30d68c3..2d01287 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton_utils.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/skeleton_utils.h @@ -28,17 +28,18 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_SKELETON_UTILS_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_SKELETON_UTILS_H_ +#include + +#include "ozz/animation/runtime/export.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/base/maths/transform.h" -#include - namespace ozz { namespace animation { -// Get bind-pose of a skeleton joint. -ozz::math::Transform GetJointLocalBindPose(const Skeleton& _skeleton, - int _joint); +// Get rest-pose of a skeleton joint. +OZZ_ANIMATION_DLL ozz::math::Transform GetJointLocalRestPose( + const Skeleton& _skeleton, int _joint); // Test if a joint is a leaf. _joint number must be in range [0, num joints]. // "_joint" is a leaf if it's the last joint, or next joint's parent isn't @@ -51,12 +52,15 @@ inline bool IsLeaf(const Skeleton& _skeleton, int _joint) { return next == num_joints || parents[next] != _joint; } +// Finds joint index by name. Uses a case sensitive comparison. +OZZ_ANIMATION_DLL int FindJoint(const Skeleton& _skeleton, const char* _name); + // Applies a specified functor to each joint in a depth-first order. -// _Fct is of type void(int _current, int _parent) where the first argument is -// the child of the second argument. _parent is kNoParent if the -// _current joint is a root. _from indicates the joint from which the joint -// hierarchy traversal begins. Use Skeleton::kNoParent to traverse the -// whole hierarchy, in case there are multiple roots. +// _Fct is of type void(int _current, int _parent) where the first argument +// is the child of the second argument. _parent is kNoParent if the _current +// joint is a root. _from indicates the joint from which the joint hierarchy +// traversal begins. Use Skeleton::kNoParent to traverse the whole +// hierarchy, in case there are multiple roots. template inline _Fct IterateJointsDF(const Skeleton& _skeleton, _Fct _fct, int _from = Skeleton::kNoParent) { diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/track.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/track.h index 424301d..1ec3213 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/track.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/track.h @@ -28,12 +28,12 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/io/archive_traits.h" -#include "ozz/base/platform.h" -#include "ozz/base/span.h" - #include "ozz/base/maths/quaternion.h" #include "ozz/base/maths/vec_float.h" +#include "ozz/base/platform.h" +#include "ozz/base/span.h" namespace ozz { namespace animation { @@ -54,11 +54,20 @@ namespace internal { // coherently. Ratios are usually accessed/read alone from the jobs that all // start by looking up the keyframes to interpolate indeed. template -class Track { +class OZZ_ANIMATION_DLL Track { public: typedef _ValueType ValueType; Track(); + + // Allow move. + Track(Track&& _other); + Track& operator=(Track&& _other); + + // Disables copy and assignation. + Track(Track const&) = delete; + void operator=(Track const&) = delete; + ~Track(); // Keyframe accessors. @@ -78,10 +87,6 @@ class Track { void Load(ozz::io::IArchive& _archive, uint32_t _version); private: - // Disables copy and assignation. - Track(Track const&); - void operator=(Track const&); - // TrackBuilder class is allowed to allocate a Track. friend class offline::TrackBuilder; @@ -99,7 +104,7 @@ class Track { span steps_; // Track name. - char* name_; + char* name_ = nullptr; }; // Definition of operations policies per track value type. @@ -146,11 +151,12 @@ inline math::Quaternion TrackPolicy::identity() { } // namespace internal // Runtime track data structure instantiation. -class FloatTrack : public internal::Track {}; -class Float2Track : public internal::Track {}; -class Float3Track : public internal::Track {}; -class Float4Track : public internal::Track {}; -class QuaternionTrack : public internal::Track {}; +class OZZ_ANIMATION_DLL FloatTrack : public internal::Track {}; +class OZZ_ANIMATION_DLL Float2Track : public internal::Track {}; +class OZZ_ANIMATION_DLL Float3Track : public internal::Track {}; +class OZZ_ANIMATION_DLL Float4Track : public internal::Track {}; +class OZZ_ANIMATION_DLL QuaternionTrack + : public internal::Track {}; } // namespace animation namespace io { diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_sampling_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_sampling_job.h index 8b1b336..0475f64 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_sampling_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_sampling_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_SAMPLING_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_SAMPLING_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/animation/runtime/track.h" namespace ozz { @@ -65,14 +66,15 @@ struct TrackSamplingJob { // Track sampling job implementation. Track sampling allows to query a track // value for a specified ratio. This is a ratio rather than a time because // tracks have no duration. -struct FloatTrackSamplingJob : public internal::TrackSamplingJob {}; -struct Float2TrackSamplingJob : public internal::TrackSamplingJob { -}; -struct Float3TrackSamplingJob : public internal::TrackSamplingJob { -}; -struct Float4TrackSamplingJob : public internal::TrackSamplingJob { -}; -struct QuaternionTrackSamplingJob +struct OZZ_ANIMATION_DLL FloatTrackSamplingJob + : public internal::TrackSamplingJob {}; +struct OZZ_ANIMATION_DLL Float2TrackSamplingJob + : public internal::TrackSamplingJob {}; +struct OZZ_ANIMATION_DLL Float3TrackSamplingJob + : public internal::TrackSamplingJob {}; +struct OZZ_ANIMATION_DLL Float4TrackSamplingJob + : public internal::TrackSamplingJob {}; +struct OZZ_ANIMATION_DLL QuaternionTrackSamplingJob : public internal::TrackSamplingJob {}; } // namespace animation diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job.h index 4d07afc..9a11c49 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job.h @@ -28,6 +28,7 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" namespace ozz { @@ -46,7 +47,7 @@ class FloatTrack; // track types isn't possible. // The job execution actually performs a lazy evaluation of edges. It builds an // iterator that will process the next edge on each call to ++ operator. -struct TrackTriggeringJob { +struct OZZ_ANIMATION_DLL TrackTriggeringJob { TrackTriggeringJob(); // Validates job parameters. @@ -95,7 +96,7 @@ struct TrackTriggeringJob { // Iterator implementation. Calls to ++ operator will compute the next edge. It // should be compared (using operator !=) to job's end iterator to test if the // last edge has been reached. -class TrackTriggeringJob::Iterator { +class OZZ_ANIMATION_DLL TrackTriggeringJob::Iterator { public: Iterator() : job_(nullptr), outer_(0.f), inner_(0) {} diff --git a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job_trait.h b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job_trait.h index 399ade9..4aeb063 100644 --- a/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job_trait.h +++ b/3rdparty/ozz-animation/include/ozz/animation/runtime/track_triggering_job_trait.h @@ -28,6 +28,8 @@ #ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_TRAIT_H_ #define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_TRAIT_H_ +#include "ozz/animation/runtime/export.h" + // Defines iterator traits required to use TrackTriggeringJob::Iterator // with stl algorithms. // This is a separate file from "track_triggering_job.h" to prevent everyone diff --git a/3rdparty/ozz-animation/include/ozz/base/containers/array.h b/3rdparty/ozz-animation/include/ozz/base/containers/array.h new file mode 100644 index 0000000..be5ee4a --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/base/containers/array.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_BASE_CONTAINERS_ARRAY_H_ +#define OZZ_OZZ_BASE_CONTAINERS_ARRAY_H_ + +#include + +#include "ozz/base/platform.h" + +namespace ozz { +// Redirects std::array to ozz::array . +template +using array = std::array<_Ty, _N>; + +// Extends std::array with two functions that gives access to the begin and the +// end of its array of elements. + +// Returns the mutable begin of the array of elements, or nullptr if +// array's empty. +template +inline _Ty* array_begin(std::array<_Ty, _N>& _array) { + return _array.data(); +} + +// Returns the non-mutable begin of the array of elements, or nullptr if +// array's empty. +template +inline const _Ty* array_begin(const std::array<_Ty, _N>& _array) { + return _array.data(); +} + +// Returns the mutable end of the array of elements, or nullptr if +// array's empty. Array end is one element past the last element of the +// array, it cannot be dereferenced. +template +inline _Ty* array_end(std::array<_Ty, _N>& _array) { + return _array.data() + _N; +} + +// Returns the non-mutable end of the array of elements, or nullptr if +// array's empty. Array end is one element past the last element of the +// array, it cannot be dereferenced. +template +inline const _Ty* array_end(const std::array<_Ty, _N>& _array) { + return _array.data() + _N; +} +} // namespace ozz +#endif // OZZ_OZZ_BASE_CONTAINERS_ARRAY_H_ diff --git a/3rdparty/ozz-animation/include/ozz/base/containers/array_archive.h b/3rdparty/ozz-animation/include/ozz/base/containers/array_archive.h new file mode 100644 index 0000000..a96e80e --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/base/containers/array_archive.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_BASE_CONTAINERS_ARRAY_ARCHIVE_H_ +#define OZZ_OZZ_BASE_CONTAINERS_ARRAY_ARCHIVE_H_ + +#include "ozz/base/containers/array.h" +#include "ozz/base/io/archive.h" + +namespace ozz { +namespace io { + +OZZ_IO_TYPE_NOT_VERSIONABLE_T2(class _Ty, size_t _N, std::array<_Ty, _N>) + +template +struct Extern> { + inline static void Save(OArchive& _archive, + const std::array<_Ty, _N>* _values, size_t _count) { + if (void(0), _N != 0) { + for (size_t i = 0; i < _count; i++) { + const std::array<_Ty, _N>& array = _values[i]; + _archive << ozz::io::MakeArray(array.data(), _N); + } + } + } + inline static void Load(IArchive& _archive, std::array<_Ty, _N>* _values, + size_t _count, uint32_t _version) { + (void)_version; + if (void(0), _N != 0) { + for (size_t i = 0; i < _count; i++) { + std::array<_Ty, _N>& array = _values[i]; + _archive >> ozz::io::MakeArray(array.data(), _N); + } + } + } +}; +} // namespace io +} // namespace ozz +#endif // OZZ_OZZ_BASE_CONTAINERS_ARRAY_ARCHIVE_H_ diff --git a/3rdparty/ozz-animation/include/ozz/base/containers/std_allocator.h b/3rdparty/ozz-animation/include/ozz/base/containers/std_allocator.h index 0211253..9355815 100644 --- a/3rdparty/ozz-animation/include/ozz/base/containers/std_allocator.h +++ b/3rdparty/ozz-animation/include/ozz/base/containers/std_allocator.h @@ -49,7 +49,7 @@ class StdAllocator { StdAllocator(const StdAllocator&) noexcept {} template - StdAllocator(const StdAllocator<_Other>&) noexcept {} + StdAllocator(const StdAllocator<_Other>&) noexcept {} template struct rebind { diff --git a/3rdparty/ozz-animation/include/ozz/base/containers/string_archive.h b/3rdparty/ozz-animation/include/ozz/base/containers/string_archive.h index c38d33f..e3099ec 100644 --- a/3rdparty/ozz-animation/include/ozz/base/containers/string_archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/containers/string_archive.h @@ -38,7 +38,7 @@ namespace io { OZZ_IO_TYPE_NOT_VERSIONABLE(ozz::string) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const ozz::string* _values, size_t _count); static void Load(IArchive& _archive, ozz::string* _values, size_t _count, diff --git a/3rdparty/ozz-animation/include/ozz/base/containers/vector_archive.h b/3rdparty/ozz-animation/include/ozz/base/containers/vector_archive.h index e42b848..b96b36b 100644 --- a/3rdparty/ozz-animation/include/ozz/base/containers/vector_archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/containers/vector_archive.h @@ -48,7 +48,7 @@ struct Extern> { const uint32_t size = static_cast(vector.size()); _archive << size; if (size > 0) { - _archive << ozz::io::MakeArray(&vector[0], size); + _archive << ozz::io::MakeArray(vector.data(), size); } } } @@ -62,7 +62,7 @@ struct Extern> { _archive >> size; vector.resize(size); if (size > 0) { - _archive >> ozz::io::MakeArray(&vector[0], size); + _archive >> ozz::io::MakeArray(vector.data(), size); } } } diff --git a/3rdparty/ozz-animation/include/ozz/base/endianness.h b/3rdparty/ozz-animation/include/ozz/base/endianness.h index de7f26d..97c66d8 100644 --- a/3rdparty/ozz-animation/include/ozz/base/endianness.h +++ b/3rdparty/ozz-animation/include/ozz/base/endianness.h @@ -66,20 +66,17 @@ template struct EndianSwapper; // Internal macro used to swap two bytes. -#define OZZ_BYTE_SWAP(_a, _b) \ - do { \ - const char temp = _a; \ - _a = _b; \ - _b = temp; \ +#define OZZ_BYTE_SWAP(_a, _b) \ + do { \ + const ozz::byte temp = (_a); \ + (_a) = (_b); \ + (_b) = temp; \ } while (0) // EndianSwapper specialization for 1 byte types. template struct EndianSwapper<_Ty, 1> { - OZZ_INLINE static void Swap(_Ty* _ty, size_t _count) { - (void)_ty; - (void)_count; - } + OZZ_INLINE static void Swap(_Ty*, size_t) {} OZZ_INLINE static _Ty Swap(_Ty _ty) { return _ty; } }; @@ -87,13 +84,13 @@ struct EndianSwapper<_Ty, 1> { template struct EndianSwapper<_Ty, 2> { OZZ_INLINE static void Swap(_Ty* _ty, size_t _count) { - char* alias = reinterpret_cast(_ty); + byte* alias = reinterpret_cast(_ty); for (size_t i = 0; i < _count * 2; i += 2) { OZZ_BYTE_SWAP(alias[i + 0], alias[i + 1]); } } OZZ_INLINE static _Ty Swap(_Ty _ty) { // Pass by copy to swap _ty in-place. - char* alias = reinterpret_cast(&_ty); + byte* alias = reinterpret_cast(&_ty); OZZ_BYTE_SWAP(alias[0], alias[1]); return _ty; } @@ -103,14 +100,14 @@ struct EndianSwapper<_Ty, 2> { template struct EndianSwapper<_Ty, 4> { OZZ_INLINE static void Swap(_Ty* _ty, size_t _count) { - char* alias = reinterpret_cast(_ty); + byte* alias = reinterpret_cast(_ty); for (size_t i = 0; i < _count * 4; i += 4) { OZZ_BYTE_SWAP(alias[i + 0], alias[i + 3]); OZZ_BYTE_SWAP(alias[i + 1], alias[i + 2]); } } OZZ_INLINE static _Ty Swap(_Ty _ty) { // Pass by copy to swap _ty in-place. - char* alias = reinterpret_cast(&_ty); + byte* alias = reinterpret_cast(&_ty); OZZ_BYTE_SWAP(alias[0], alias[3]); OZZ_BYTE_SWAP(alias[1], alias[2]); return _ty; @@ -121,7 +118,7 @@ struct EndianSwapper<_Ty, 4> { template struct EndianSwapper<_Ty, 8> { OZZ_INLINE static void Swap(_Ty* _ty, size_t _count) { - char* alias = reinterpret_cast(_ty); + byte* alias = reinterpret_cast(_ty); for (size_t i = 0; i < _count * 8; i += 8) { OZZ_BYTE_SWAP(alias[i + 0], alias[i + 7]); OZZ_BYTE_SWAP(alias[i + 1], alias[i + 6]); @@ -130,7 +127,7 @@ struct EndianSwapper<_Ty, 8> { } } OZZ_INLINE static _Ty Swap(_Ty _ty) { // Pass by copy to swap _ty in-place. - char* alias = reinterpret_cast(&_ty); + byte* alias = reinterpret_cast(&_ty); OZZ_BYTE_SWAP(alias[0], alias[7]); OZZ_BYTE_SWAP(alias[1], alias[6]); OZZ_BYTE_SWAP(alias[2], alias[5]); diff --git a/3rdparty/ozz-animation/include/ozz/base/export.h b/3rdparty/ozz-animation/include/ozz/base/export.h new file mode 100644 index 0000000..47b03e9 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/base/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_BASE_EXPORT_H_ +#define OZZ_OZZ_BASE_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_BASE_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_BASE_DLL __declspec(dllexport) +#else +#define OZZ_BASE_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_BASE_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_BASE_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/base/io/archive.h b/3rdparty/ozz-animation/include/ozz/base/io/archive.h index e33527d..ddf3a3b 100644 --- a/3rdparty/ozz-animation/include/ozz/base/io/archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/io/archive.h @@ -77,16 +77,16 @@ // integrity, like data corruption or file truncation, must also be validated on // the user side. +#include + +#include + #include "ozz/base/endianness.h" +#include "ozz/base/io/archive_traits.h" #include "ozz/base/io/stream.h" #include "ozz/base/platform.h" #include "ozz/base/span.h" -#include -#include - -#include "ozz/base/io/archive_traits.h" - namespace ozz { namespace io { namespace internal { @@ -102,7 +102,7 @@ struct Tagger; // The output endianness mode is set at construction time. It is written to the // stream to allow the IArchive to perform the required conversion to the native // endianness mode while reading. -class OArchive { +class OZZ_BASE_DLL OArchive { public: // Constructs an output archive from the Stream _stream that must be valid // and opened for writing. @@ -126,7 +126,7 @@ class OArchive { } // Primitive type saving. -#define OZZ_IO_PRIMITIVE_TYPE(_type) \ +#define OZZ_IO_PRIMITIVE_TYPE(_type) \ void operator<<(_type _v) { \ _type v = endian_swap_ ? EndianSwapper<_type>::Swap(_v) : _v; \ OZZ_IF_DEBUG(size_t size =) stream_->Write(&v, sizeof(v)); \ @@ -171,7 +171,7 @@ class OArchive { // Implements input archive concept used to load/de-serialize data to a Stream. // Endianness conversions are automatically performed according to the Archive // and the native formats. -class IArchive { +class OZZ_BASE_DLL IArchive { public: // Constructs an input archive from the Stream _stream that must be opened for // reading, at the same tell (position in the stream) as when it was passed to @@ -199,7 +199,7 @@ class IArchive { } // Primitive type loading. -#define OZZ_IO_PRIMITIVE_TYPE(_type) \ +#define OZZ_IO_PRIMITIVE_TYPE(_type) \ void operator>>(_type& _v) { \ _type v; \ OZZ_IF_DEBUG(size_t size =) stream_->Read(&v, sizeof(v)); \ @@ -314,7 +314,7 @@ struct Version> { }; // Specializes Array Save/Load for primitive types. -#define OZZ_IO_PRIMITIVE_TYPE(_type) \ +#define OZZ_IO_PRIMITIVE_TYPE(_type) \ template <> \ inline void Array::Save(OArchive& _archive) const { \ if (_archive.endian_swap()) { \ diff --git a/3rdparty/ozz-animation/include/ozz/base/io/stream.h b/3rdparty/ozz-animation/include/ozz/base/io/stream.h index ce26c79..faeba08 100644 --- a/3rdparty/ozz-animation/include/ozz/base/io/stream.h +++ b/3rdparty/ozz-animation/include/ozz/base/io/stream.h @@ -31,16 +31,16 @@ // Provides Stream interface used to read/write a memory buffer or a file with // Crt fread/fwrite/fseek/ftell like functions. -#include "ozz/base/platform.h" - #include +#include "ozz/base/platform.h" + namespace ozz { namespace io { // Declares a stream access interface that conforms with CRT FILE API. // This interface should be used to remap io operations. -class Stream { +class OZZ_BASE_DLL Stream { public: // Tests whether a file is opened. virtual bool opened() const = 0; @@ -86,7 +86,7 @@ class Stream { }; // Implements Stream of type File. -class File : public Stream { +class OZZ_BASE_DLL File : public Stream { public: // Test if a file at path _filename exists. // Note that this function is costly. If you aim to open the file right after, @@ -133,7 +133,7 @@ class File : public Stream { // Implements an in-memory Stream. Allows to use a memory buffer as a Stream. // The opening mode is equivalent to fopen w+b (binary read/write). -class MemoryStream : public Stream { +class OZZ_BASE_DLL MemoryStream : public Stream { public: // Construct an empty memory stream opened in w+b mode. MemoryStream(); @@ -172,7 +172,7 @@ class MemoryStream : public Stream { static const size_t kMaxSize; // Buffer of data. - char* buffer_; + byte* buffer_; // The size of the buffer, which is greater or equal to the size of the data // it contains (end_). diff --git a/3rdparty/ozz-animation/include/ozz/base/log.h b/3rdparty/ozz-animation/include/ozz/base/log.h index c5ffe80..99c0b77 100644 --- a/3rdparty/ozz-animation/include/ozz/base/log.h +++ b/3rdparty/ozz-animation/include/ozz/base/log.h @@ -34,6 +34,8 @@ // So it is included here to ensure a portable behavior. #include +#include "platform.h" + // Proposes a logging interface that redirects logs to std::cout, clog and cerr // output streams. This interface adds a logging level functionality (kSilent, // kStandard, kVerbose) to the std API, which can be set using @@ -50,17 +52,17 @@ enum Level { }; // Sets the global logging level. -Level SetLevel(Level _level); +OZZ_BASE_DLL Level SetLevel(Level _level); // Gets the global logging level. -Level GetLevel(); +OZZ_BASE_DLL Level GetLevel(); // Implements logging base class. // This class is not intended to be used publicly, it is derived by user // classes LogV, Log, Out, Err... // Forwards ostream::operator << to a standard ostream or a silent // ostringstream according to the logging level at construction time. -class Logger { +class OZZ_BASE_DLL Logger { public: // Forwards ostream::operator << for any type. template @@ -101,28 +103,28 @@ class Logger { // Logs verbose output to the standard error stream (std::clog). // Enabled if logging level is Verbose. -class LogV : public Logger { +class OZZ_BASE_DLL LogV : public Logger { public: LogV(); }; // Logs output to the standard error stream (std::clog). // Enabled if logging level is not Silent. -class Log : public Logger { +class OZZ_BASE_DLL Log : public Logger { public: Log(); }; // Logs output to the standard output (std::cout). // Enabled if logging level is not Silent. -class Out : public Logger { +class OZZ_BASE_DLL Out : public Logger { public: Out(); }; // Logs error to the standard error stream (std::cerr). // Enabled if logging level is not Silent. -class Err : public Logger { +class OZZ_BASE_DLL Err : public Logger { public: Err(); }; @@ -131,7 +133,7 @@ class Err : public Logger { // settings when exiting scope. // User is reponsible for making sure stream still exist upon RAII destruction. // See std::setprecision() for more details. -class FloatPrecision { +class OZZ_BASE_DLL FloatPrecision { public: FloatPrecision(const Logger& _logger, int _precision); ~FloatPrecision(); diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/box.h b/3rdparty/ozz-animation/include/ozz/base/maths/box.h index c631237..d4b3307 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/box.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/box.h @@ -39,7 +39,7 @@ namespace math { struct Float4x4; // Defines an axis aligned box. -struct Box { +struct OZZ_BASE_DLL Box { // Constructs an invalid box. Box(); @@ -78,7 +78,7 @@ OZZ_INLINE Box Merge(const Box& _a, const Box& _b) { } // Compute box transformation by a matrix. -Box TransformBox(const Float4x4& _matrix, const Box& _box); +OZZ_BASE_DLL Box TransformBox(const Float4x4& _matrix, const Box& _box); } // namespace math } // namespace ozz #endif // OZZ_OZZ_BASE_MATHS_BOX_H_ diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_config.h b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_config.h index 38c1c0f..71867ad 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_config.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_config.h @@ -152,7 +152,8 @@ typedef const SimdInt4& _SimdInt4; } // namespace ozz #endif // OZZ_SIMD_x -// Native SIMD operator already exist on some compilers, so they have to be disable from ozz implementation +// Native SIMD operator already exist on some compilers, so they have to be +// disable from ozz implementation #if !defined(OZZ_SIMD_REF) && (defined(__GNUC__) || defined(__llvm__)) #define OZZ_DISABLE_SSE_NATIVE_OPERATORS #endif diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_ref-inl.h b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_ref-inl.h index 0eb6cf3..711ad20 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_ref-inl.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_ref-inl.h @@ -31,6 +31,7 @@ // SIMD refence implementation, based on scalar floats. #include + #include #include #include @@ -1820,22 +1821,9 @@ OZZ_INLINE bool ToAffine(const Float4x4& _m, SimdFloat4* _translation, } OZZ_INLINE Float4x4 Float4x4::FromEuler(_SimdFloat4 _v) { - const float ch = std::cos(_v.x); - const float sh = std::sin(_v.x); - const float ca = std::cos(_v.y); - const float sa = std::sin(_v.y); - const float cb = std::cos(_v.z); - const float sb = std::sin(_v.z); - - const float sa_cb = sa * cb; - const float sa_sb = sa * sb; - - const Float4x4 ret = { - {{ch * ca, sh * sb - ch * sa_cb, ch * sa_sb + sh * cb, 0.f}, - {sa, ca * cb, -ca * sb, 0.f}, - {-sh * ca, sh * sa_cb + ch * sb, -sh * sa_sb + ch * cb, 0.f}, - {0.f, 0.f, 0.f, 1.f}}}; - return ret; + return Float4x4::FromAxisAngle(simd_float4::y_axis(), SplatX(_v)) * + Float4x4::FromAxisAngle(simd_float4::x_axis(), SplatY(_v)) * + Float4x4::FromAxisAngle(simd_float4::z_axis(), SplatZ(_v)); } OZZ_INLINE Float4x4 Float4x4::FromAxisAngle(_SimdFloat4 _axis, diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_sse-inl.h b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_sse-inl.h index 3ab9496..2545212 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_sse-inl.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/internal/simd_math_sse-inl.h @@ -31,6 +31,7 @@ // SIMD SSE2+ implementation, based on scalar floats. #include + #include // Temporarly needed while trigonometric functions aren't implemented. @@ -1294,7 +1295,7 @@ OZZ_INLINE SimdInt4 Sign(_SimdInt4 _v) { OZZ_INLINE SimdInt4 Min(_SimdInt4 _a, _SimdInt4 _b) { #ifdef OZZ_SIMD_SSE4_1 return _mm_min_epi32(_a, _b); -#else // OZZ_SIMD_SSE4_1 +#else // OZZ_SIMD_SSE4_1 return OZZ_SSE_SELECT_I(_mm_cmplt_epi32(_a, _b), _a, _b); #endif // OZZ_SIMD_SSE4_1 } @@ -1302,7 +1303,7 @@ OZZ_INLINE SimdInt4 Min(_SimdInt4 _a, _SimdInt4 _b) { OZZ_INLINE SimdInt4 Max(_SimdInt4 _a, _SimdInt4 _b) { #ifdef OZZ_SIMD_SSE4_1 return _mm_max_epi32(_a, _b); -#else // OZZ_SIMD_SSE4_1 +#else // OZZ_SIMD_SSE4_1 return OZZ_SSE_SELECT_I(_mm_cmpgt_epi32(_a, _b), _a, _b); #endif // OZZ_SIMD_SSE4_1 } @@ -1775,26 +1776,9 @@ inline bool ToAffine(const Float4x4& _m, SimdFloat4* _translation, } inline Float4x4 Float4x4::FromEuler(_SimdFloat4 _v) { - const __m128 cos = Cos(_v); - const __m128 sin = Sin(_v); - - const float cx = GetX(cos); - const float sx = GetX(sin); - const float cy = GetY(cos); - const float sy = GetY(sin); - const float cz = GetZ(cos); - const float sz = GetZ(sin); - - const float sycz = sy * cz; - const float sysz = sy * sz; - - const Float4x4 ret = {{simd_float4::Load(cx * cy, sx * sz - cx * sycz, - cx * sysz + sx * cz, 0.f), - simd_float4::Load(sy, cy * cz, -cy * sz, 0.f), - simd_float4::Load(-sx * cy, sx * sycz + cx * sz, - -sx * sysz + cx * cz, 0.f), - simd_float4::w_axis()}}; - return ret; + return Float4x4::FromAxisAngle(simd_float4::y_axis(), SplatX(_v)) * + Float4x4::FromAxisAngle(simd_float4::x_axis(), SplatY(_v)) * + Float4x4::FromAxisAngle(simd_float4::z_axis(), SplatZ(_v)); } inline Float4x4 Float4x4::FromAxisAngle(_SimdFloat4 _axis, _SimdFloat4 _angle) { diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/math_archive.h b/3rdparty/ozz-animation/include/ozz/base/maths/math_archive.h index ffc1da7..3ffeef1 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/math_archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/math_archive.h @@ -45,7 +45,7 @@ struct RectInt; namespace io { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Float2) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Float2* _values, size_t _count); static void Load(IArchive& _archive, math::Float2* _values, size_t _count, @@ -54,7 +54,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Float3) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Float3* _values, size_t _count); static void Load(IArchive& _archive, math::Float3* _values, size_t _count, @@ -63,7 +63,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Float4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Float4* _values, size_t _count); static void Load(IArchive& _archive, math::Float4* _values, size_t _count, @@ -72,7 +72,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Quaternion) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Quaternion* _values, size_t _count); static void Load(IArchive& _archive, math::Quaternion* _values, size_t _count, @@ -81,7 +81,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Transform) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Transform* _values, size_t _count); static void Load(IArchive& _archive, math::Transform* _values, size_t _count, @@ -90,7 +90,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Box) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Box* _values, size_t _count); static void Load(IArchive& _archive, math::Box* _values, size_t _count, uint32_t _version); @@ -98,7 +98,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::RectFloat) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::RectFloat* _values, size_t _count); static void Load(IArchive& _archive, math::RectFloat* _values, size_t _count, @@ -107,7 +107,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::RectInt) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::RectInt* _values, size_t _count); static void Load(IArchive& _archive, math::RectInt* _values, size_t _count, diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/quaternion.h b/3rdparty/ozz-animation/include/ozz/base/maths/quaternion.h index fceb536..825e033 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/quaternion.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/quaternion.h @@ -38,7 +38,7 @@ namespace ozz { namespace math { -struct Quaternion { +struct OZZ_BASE_DLL Quaternion { float x, y, z, w; // Constructs an uninitialized quaternion. diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/rect.h b/3rdparty/ozz-animation/include/ozz/base/maths/rect.h index 5c001fa..8c0605e 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/rect.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/rect.h @@ -28,12 +28,14 @@ #ifndef OZZ_OZZ_BASE_MATHS_RECT_H_ #define OZZ_OZZ_BASE_MATHS_RECT_H_ +#include "../platform.h" + namespace ozz { namespace math { // Defines a rectangle by the integer coordinates of its lower-left and // width-height. -struct RectInt { +struct OZZ_BASE_DLL RectInt { // Constructs a uninitialized rectangle. RectInt() {} @@ -65,7 +67,7 @@ struct RectInt { // Defines a rectangle by the floating point coordinates of its lower-left // and width-height. -struct RectFloat { +struct OZZ_BASE_DLL RectFloat { // Constructs a uninitialized rectangle. RectFloat() {} diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/simd_math.h b/3rdparty/ozz-animation/include/ozz/base/maths/simd_math.h index 31301ff..76e0ffe 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/simd_math.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/simd_math.h @@ -35,7 +35,7 @@ namespace ozz { namespace math { // Returns SIMDimplementation name has decided at library build time. -const char* SimdImplementationName(); +OZZ_BASE_DLL const char* SimdImplementationName(); namespace simd_float4 { // Returns a SimdFloat4 vector with all components set to 0. @@ -241,10 +241,6 @@ OZZ_INLINE void Transpose4x1(const SimdFloat4 _in[4], SimdFloat4 _out[1]); // Remaining y, z and w are set to 0. OZZ_INLINE void Transpose1x4(const SimdFloat4 _in[1], SimdFloat4 _out[4]); -// Transposes the 1 SimdFloat4 of _in into the x components of the 4 -// SimdFloat4 of _out. Remaining y, z and w are set to 0. -OZZ_INLINE void Transpose2x4(const SimdFloat4 _in[2], SimdFloat4 _out[4]); - // Transposes the x and y components of the 4 SimdFloat4 of _in into the 2 // SimdFloat4 of _out. OZZ_INLINE void Transpose4x2(const SimdFloat4 _in[4], SimdFloat4 _out[2]); diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/simd_math_archive.h b/3rdparty/ozz-animation/include/ozz/base/maths/simd_math_archive.h index b5ca974..ecb613e 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/simd_math_archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/simd_math_archive.h @@ -36,7 +36,7 @@ namespace ozz { namespace io { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SimdFloat4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SimdFloat4* _values, size_t _count); static void Load(IArchive& _archive, math::SimdFloat4* _values, size_t _count, @@ -45,7 +45,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SimdInt4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SimdInt4* _values, size_t _count); static void Load(IArchive& _archive, math::SimdInt4* _values, size_t _count, @@ -54,7 +54,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::Float4x4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::Float4x4* _values, size_t _count); static void Load(IArchive& _archive, math::Float4x4* _values, size_t _count, diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/soa_math_archive.h b/3rdparty/ozz-animation/include/ozz/base/maths/soa_math_archive.h index b5ebdfe..168ed29 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/soa_math_archive.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/soa_math_archive.h @@ -43,7 +43,7 @@ struct SoaTransform; namespace io { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaFloat2) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaFloat2* _values, size_t _count); static void Load(IArchive& _archive, math::SoaFloat2* _values, size_t _count, @@ -52,7 +52,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaFloat3) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaFloat3* _values, size_t _count); static void Load(IArchive& _archive, math::SoaFloat3* _values, size_t _count, @@ -61,7 +61,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaFloat4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaFloat4* _values, size_t _count); static void Load(IArchive& _archive, math::SoaFloat4* _values, size_t _count, @@ -70,7 +70,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaQuaternion) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaQuaternion* _values, size_t _count); static void Load(IArchive& _archive, math::SoaQuaternion* _values, @@ -79,7 +79,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaFloat4x4) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaFloat4x4* _values, size_t _count); static void Load(IArchive& _archive, math::SoaFloat4x4* _values, @@ -88,7 +88,7 @@ struct Extern { OZZ_IO_TYPE_NOT_VERSIONABLE(math::SoaTransform) template <> -struct Extern { +struct OZZ_BASE_DLL Extern { static void Save(OArchive& _archive, const math::SoaTransform* _values, size_t _count); static void Load(IArchive& _archive, math::SoaTransform* _values, diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/transform.h b/3rdparty/ozz-animation/include/ozz/base/maths/transform.h index 27da478..96908cc 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/transform.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/transform.h @@ -37,7 +37,7 @@ namespace math { // Stores an affine transformation with separate translation, rotation and scale // attributes. -struct Transform { +struct OZZ_BASE_DLL Transform { // Translation affine transformation component. Float3 translation; diff --git a/3rdparty/ozz-animation/include/ozz/base/maths/vec_float.h b/3rdparty/ozz-animation/include/ozz/base/maths/vec_float.h index 440f3b6..d005af9 100644 --- a/3rdparty/ozz-animation/include/ozz/base/maths/vec_float.h +++ b/3rdparty/ozz-animation/include/ozz/base/maths/vec_float.h @@ -38,7 +38,7 @@ namespace ozz { namespace math { // Declares a 2d float vector. -struct Float2 { +struct OZZ_BASE_DLL Float2 { float x, y; // Constructs an uninitialized vector. @@ -64,7 +64,7 @@ struct Float2 { }; // Declares a 3d float vector. -struct Float3 { +struct OZZ_BASE_DLL Float3 { float x, y, z; // Constructs an uninitialized vector. @@ -96,7 +96,7 @@ struct Float3 { }; // Declares a 4d float vector. -struct Float4 { +struct OZZ_BASE_DLL Float4 { float x, y, z, w; // Constructs an uninitialized vector. diff --git a/3rdparty/ozz-animation/include/ozz/base/memory/allocator.h b/3rdparty/ozz-animation/include/ozz/base/memory/allocator.h index 6264b4c..747679b 100644 --- a/3rdparty/ozz-animation/include/ozz/base/memory/allocator.h +++ b/3rdparty/ozz-animation/include/ozz/base/memory/allocator.h @@ -41,18 +41,18 @@ namespace memory { class Allocator; // Defines the default allocator accessor. -Allocator* default_allocator(); +OZZ_BASE_DLL Allocator* default_allocator(); // Set the default allocator, used for all dynamic allocation inside ozz. // Returns current memory allocator, such that in can be restored if needed. -Allocator* SetDefaulAllocator(Allocator* _allocator); +OZZ_BASE_DLL Allocator* SetDefaulAllocator(Allocator* _allocator); // Defines an abstract allocator class. // Implements helper methods to allocate/deallocate POD typed objects instead of // raw memory. // Implements New and Delete function to allocate C++ objects, as a replacement // of new and delete operators. -class Allocator { +class OZZ_BASE_DLL Allocator { public: // Default virtual destructor. virtual ~Allocator() {} diff --git a/3rdparty/ozz-animation/include/ozz/base/platform.h b/3rdparty/ozz-animation/include/ozz/base/platform.h index 043c469..78caeff 100644 --- a/3rdparty/ozz-animation/include/ozz/base/platform.h +++ b/3rdparty/ozz-animation/include/ozz/base/platform.h @@ -41,8 +41,13 @@ #include #include +#include "ozz/base/export.h" + namespace ozz { +// Defines a byte type, unsigned so right shift doesn't propagate sign bit. +typedef uint8_t byte; + // Finds the number of elements of a statically allocated array. #define OZZ_ARRAY_SIZE(_array) (sizeof(_array) / sizeof(_array[0])) @@ -80,7 +85,7 @@ namespace ozz { // Case sensitive wildcard string matching: // - a ? sign matches any character, except an empty string. // - a * sign matches any string, including an empty string. -bool strmatch(const char* _str, const char* _pattern); +OZZ_BASE_DLL bool strmatch(const char* _str, const char* _pattern); // Tests whether _block is aligned to _alignment boundary. template diff --git a/3rdparty/ozz-animation/include/ozz/base/span.h b/3rdparty/ozz-animation/include/ozz/base/span.h index c37850e..24a545b 100644 --- a/3rdparty/ozz-animation/include/ozz/base/span.h +++ b/3rdparty/ozz-animation/include/ozz/base/span.h @@ -52,7 +52,8 @@ struct span { span() : data_(nullptr), size_(0) {} // Constructs a range from its extreme values. - span(_Ty* _begin, _Ty* _end) : data_(_begin), size_(static_cast(_end - _begin)) { + span(_Ty* _begin, _Ty* _end) + : data_(_begin), size_(static_cast(_end - _begin)) { assert(_begin <= _end && "Invalid range."); } @@ -84,6 +85,25 @@ struct span { // Implement cast operator to allow conversions to span. operator span() const { return span(data_, size_); } + // Subspan + + span first(index_type _count) const { + assert(_count <= size_ && "Count out of range"); + return {data(), _count}; + } + + span last(index_type _count) const { + assert(_count <= size_ && "Count out of range"); + return {data() + size_ - _count, _count}; + } + + span subspan(index_type _offset, index_type _count) const { + assert(_offset <= size_ && "Offset out of range"); + assert(_count <= size_ && "Count out of range"); + assert(_offset <= size_ - _count && "Offset + count out of range"); + return {data_ + _offset, _count}; + } + // Returns a const reference to element _i of range [begin,end[. _Ty& operator[](size_t _i) const { assert(_i < size_ && "Index out of range."); @@ -135,35 +155,25 @@ inline span make_span( // As bytes template -inline span as_bytes(const span<_Ty>& _span) { - return {reinterpret_cast(_span.data()), _span.size_bytes()}; +inline span as_bytes(const span<_Ty>& _span) { + return {reinterpret_cast(_span.data()), _span.size_bytes()}; } template -inline span as_writable_bytes(const span<_Ty>& _span) { +inline span as_writable_bytes(const span<_Ty>& _span) { // Compilation will fail here if _Ty is const. This prevents from writing to // const data. - return {reinterpret_cast(_span.data()), _span.size_bytes()}; -} - -template <> -inline span as_bytes(const span& _span) { - return _span; -} - -template <> -inline span as_writable_bytes(const span& _span) { - return _span; + return {reinterpret_cast(_span.data()), _span.size_bytes()}; } // Fills a typed span from a byte source span. Source byte span is modified to // reflect remain size. template -inline span<_Ty> fill_span(span& _src, size_t _count) { +inline span<_Ty> fill_span(span& _src, size_t _count) { assert(ozz::IsAligned(_src.data(), alignof(_Ty)) && "Invalid alignment."); const span<_Ty> ret = {reinterpret_cast<_Ty*>(_src.data()), _count}; // Validity assertion is done by span constructor. - _src = {reinterpret_cast(ret.end()), _src.end()}; + _src = {reinterpret_cast(ret.end()), _src.end()}; return ret; } diff --git a/3rdparty/ozz-animation/include/ozz/geometry/runtime/export.h b/3rdparty/ozz-animation/include/ozz/geometry/runtime/export.h new file mode 100644 index 0000000..8704726 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/geometry/runtime/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_GEOMETRY_EXPORT_H_ +#define OZZ_OZZ_GEOMETRY_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_GEOMETRY_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_GEOMETRY_DLL __declspec(dllexport) +#else +#define OZZ_GEOMETRY_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_GEOMETRY_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_GEOMETRY_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/geometry/runtime/skinning_job.h b/3rdparty/ozz-animation/include/ozz/geometry/runtime/skinning_job.h index b95508d..9427bc6 100644 --- a/3rdparty/ozz-animation/include/ozz/geometry/runtime/skinning_job.h +++ b/3rdparty/ozz-animation/include/ozz/geometry/runtime/skinning_job.h @@ -30,6 +30,7 @@ #include "ozz/base/platform.h" #include "ozz/base/span.h" +#include "ozz/geometry/runtime/export.h" namespace ozz { namespace math { @@ -73,7 +74,7 @@ namespace geometry { // should only be used when input matrices have non uniform scaling or shearing. // The job does not owned the buffers (in/output) and will thus not delete them // during job's destruction. -struct SkinningJob { +struct OZZ_GEOMETRY_DLL SkinningJob { // Default constructor, initializes default values. SkinningJob(); diff --git a/3rdparty/ozz-animation/include/ozz/options/export.h b/3rdparty/ozz-animation/include/ozz/options/export.h new file mode 100644 index 0000000..7827947 --- /dev/null +++ b/3rdparty/ozz-animation/include/ozz/options/export.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------// +// // +// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // +// and distributed under the MIT License (MIT). // +// // +// Copyright (c) Guillaume Blanc // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software"), // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // +// DEALINGS IN THE SOFTWARE. // +// // +//----------------------------------------------------------------------------// + +#ifndef OZZ_OZZ_OPTIONS_EXPORT_H_ +#define OZZ_OZZ_OPTIONS_EXPORT_H_ + +#if defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#ifdef OZZ_BUILD_OPTIONS_LIB +// Import/Export for dynamic linking while building ozz +#define OZZ_OPTIONS_DLL __declspec(dllexport) +#else +#define OZZ_OPTIONS_DLL __declspec(dllimport) +#endif +#else // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) +// Static or non msvc linking +#define OZZ_OPTIONS_DLL +#endif // defined(_MSC_VER) && defined(OZZ_USE_DYNAMIC_LINKING) + +#endif // OZZ_OZZ_OPTIONS_EXPORT_H_ diff --git a/3rdparty/ozz-animation/include/ozz/options/options.h b/3rdparty/ozz-animation/include/ozz/options/options.h index 79df890..c1fa4e9 100644 --- a/3rdparty/ozz-animation/include/ozz/options/options.h +++ b/3rdparty/ozz-animation/include/ozz/options/options.h @@ -80,8 +80,8 @@ // registered options. // --version displays executable's version. -#include -#include +#include "ozz/options/export.h" +#include "ozz/base/containers/string.h" namespace ozz { namespace options { @@ -108,26 +108,28 @@ enum ParseResult { // _version and _usage are not copied, ParseCommandLine caller is in charge of // maintaining their allocation during application lifetime. // See ParseResult for more details about returned values. -ParseResult ParseCommandLine(int _argc, const char* const* _argv, - const char* _version, const char* _usage); +OZZ_OPTIONS_DLL ParseResult ParseCommandLine(int _argc, + const char* const* _argv, + const char* _version, + const char* _usage); // Get the executable path that was extracted from the last call to // ParseCommandLine. // If ParseCommandLine has never been called, then ParsedExecutablePath // returns a default empty string. -std::string ParsedExecutablePath(); +OZZ_OPTIONS_DLL ozz::string ParsedExecutablePath(); // Get the executable name that was extracted from the last call to // ParseCommandLine. // If ParseCommandLine has never been called, then ParsedExecutableName // returns a default empty string. -const char* ParsedExecutableName(); +OZZ_OPTIONS_DLL const char* ParsedExecutableName(); // Get the executable usage that was extracted from the last call to // ParseCommandLine. // If ParseCommandLine has never been called, then ParsedExecutableUsage // returns a default empty string. -const char* ParsedExecutableUsage(); +OZZ_OPTIONS_DLL const char* ParsedExecutableUsage(); #define OZZ_OPTIONS_DECLARE_BOOL(_name, _help, _default, _required) \ OZZ_OPTIONS_DECLARE_VARIABLE(ozz::options::BoolOption, _name, _help, \ @@ -168,7 +170,7 @@ const char* ParsedExecutableUsage(); #_name, _help, _default, _required, _fn); // Defines option interface. -class Option { +class OZZ_OPTIONS_DLL Option { public: // Returns option's name. const char* name() const { return name_; } @@ -196,7 +198,7 @@ class Option { void RestoreDefault(); // Outputs default value as a string. - virtual std::string FormatDefault() const = 0; + virtual ozz::string FormatDefault() const = 0; // Outputs type of value as a c string. virtual const char* FormatType() const = 0; @@ -246,7 +248,7 @@ class Option { // Defines a strongly typed option class template -class TypedOption : public Option { +class OZZ_OPTIONS_DLL TypedOption : public Option { public: // Lets the type be known. typedef _Type Type; @@ -277,7 +279,7 @@ class TypedOption : public Option { virtual void RestoreDefaultImpl() { value_ = default_; } // Outputs default value as a string. - virtual std::string FormatDefault() const; + virtual ozz::string FormatDefault() const; // Outputs type of value as a string. virtual const char* FormatType() const; @@ -298,7 +300,7 @@ typedef TypedOption StringOption; // Declares the option parser class. // Option are registered by the parser and updated when command line arguments // are parsed. -class Parser { +class OZZ_OPTIONS_DLL Parser { public: // Construct a parser with only built-in options. Parser(); @@ -354,7 +356,7 @@ class Parser { const char* version() const; // Returns the path of the executable that was extracted from argument 0. - std::string executable_path() const; + ozz::string executable_path() const; // Returns the name of the executable that was extracted from argument 0. const char* executable_name() const; diff --git a/3rdparty/ozz-animation/samples/additive/CMakeLists.txt b/3rdparty/ozz-animation/samples/additive/CMakeLists.txt index ff531c7..76a615f 100644 --- a/3rdparty/ozz-animation/samples/additive/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/additive/CMakeLists.txt @@ -5,16 +5,19 @@ add_custom_command( "${CMAKE_CURRENT_LIST_DIR}/README.md" "${ozz_media_directory}/bin/pab_skeleton.ozz" "${ozz_media_directory}/bin/pab_walk.ozz" - "${ozz_media_directory}/bin/pab_crackhead_additive.ozz" + "${ozz_media_directory}/bin/pab_curl_additive.ozz" + "${ozz_media_directory}/bin/pab_splay_additive.ozz" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/README.md" "${CMAKE_CURRENT_BINARY_DIR}/media/skeleton.ozz" "${CMAKE_CURRENT_BINARY_DIR}/media/animation_base.ozz" - "${CMAKE_CURRENT_BINARY_DIR}/media/animation_additive.ozz" + "${CMAKE_CURRENT_BINARY_DIR}/media/animation_curl_additive.ozz" + "${CMAKE_CURRENT_BINARY_DIR}/media/animation_splay_additive.ozz" COMMAND ${CMAKE_COMMAND} -E make_directory media COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_LIST_DIR}/README.md" . COMMAND ${CMAKE_COMMAND} -E copy "${ozz_media_directory}/bin/pab_skeleton.ozz" "./media/skeleton.ozz" COMMAND ${CMAKE_COMMAND} -E copy "${ozz_media_directory}/bin/pab_walk.ozz" "./media/animation_base.ozz" - COMMAND ${CMAKE_COMMAND} -E copy "${ozz_media_directory}/bin/pab_crackhead_additive.ozz" "./media/animation_additive.ozz" + COMMAND ${CMAKE_COMMAND} -E copy "${ozz_media_directory}/bin/pab_curl_additive.ozz" "./media/animation_curl_additive.ozz" + COMMAND ${CMAKE_COMMAND} -E copy "${ozz_media_directory}/bin/pab_splay_additive.ozz" "./media/animation_splay_additive.ozz" VERBATIM) add_executable(sample_additive @@ -22,10 +25,11 @@ add_executable(sample_additive "${CMAKE_CURRENT_BINARY_DIR}/README.md" "${CMAKE_CURRENT_BINARY_DIR}/media/skeleton.ozz" "${CMAKE_CURRENT_BINARY_DIR}/media/animation_base.ozz" - "${CMAKE_CURRENT_BINARY_DIR}/media/animation_additive.ozz") + "${CMAKE_CURRENT_BINARY_DIR}/media/animation_curl_additive.ozz" + "${CMAKE_CURRENT_BINARY_DIR}/media/animation_splay_additive.ozz") target_link_libraries(sample_additive sample_framework) - +target_copy_shared_libraries(sample_additive) set_target_properties(sample_additive PROPERTIES FOLDER "samples") @@ -46,10 +50,12 @@ else() endif(EMSCRIPTEN) add_test(NAME sample_additive COMMAND sample_additive "--max_idle_loops=${ozz_sample_testing_loops}" $<$:--norender>) -add_test(NAME sample_additive_path COMMAND sample_additive "--skeleton=media/skeleton.ozz" "--animation=media/animation_base.ozz" "--additive_animation=media/animation_additive.ozz" "--max_idle_loops=${ozz_sample_testing_loops}" $<$:--norender>) +add_test(NAME sample_additive_path COMMAND sample_additive "--skeleton=media/skeleton.ozz" "--animation=media/animation_base.ozz" "--splay_animation=media/animation_splay_additive.ozz" "--curl_animation=media/animation_curl_additive.ozz" "--max_idle_loops=${ozz_sample_testing_loops}" $<$:--norender>) add_test(NAME sample_additive_invalid_skeleton_path COMMAND sample_additive "--skeleton=media/bad_skeleton.ozz" $<$:--norender>) set_tests_properties(sample_additive_invalid_skeleton_path PROPERTIES WILL_FAIL true) add_test(NAME sample_additive_invalid_animation_path1 COMMAND sample_additive "--animation=media/bad_animation.ozz" $<$:--norender>) set_tests_properties(sample_additive_invalid_animation_path1 PROPERTIES WILL_FAIL true) -add_test(NAME sample_additive_invalid_animation_path2 COMMAND sample_additive "--additive_animation=media/bad_animation.ozz" $<$:--norender>) +add_test(NAME sample_additive_invalid_animation_path2 COMMAND sample_additive "--curl_animation=media/bad_animation.ozz" $<$:--norender>) set_tests_properties(sample_additive_invalid_animation_path2 PROPERTIES WILL_FAIL true) +add_test(NAME sample_additive_invalid_animation_path3 COMMAND sample_additive "--splay_animation=media/bad_animation.ozz" $<$:--norender>) +set_tests_properties(sample_additive_invalid_animation_path3 PROPERTIES WILL_FAIL true) \ No newline at end of file diff --git a/3rdparty/ozz-animation/samples/additive/README.md b/3rdparty/ozz-animation/samples/additive/README.md index 6145fda..2842a9d 100644 --- a/3rdparty/ozz-animation/samples/additive/README.md +++ b/3rdparty/ozz-animation/samples/additive/README.md @@ -2,32 +2,25 @@ ## Description -Additive blending is a key concept in run-time animation. By superimposing a movement on top of a playing animation, it allows to add variety while lessening animation count and complexity. -In this sample, a "cracking head" animation is added to a "walk" cycle. Note that no synchronization is required between the two animations. +Additive blending is a key concept in run-time animation. Superimposing a movement on top of a playing animation allows to add variety while lessening animation count and management complexity. In this sample, 2 *splay* and *curl* hand animations are a added to a *walk* cycle. A weight is associated to each additive layers independently, allowing to control fingers. ## Concept -Additive blending is different to normal blending because it does not interpolate from a pose to an other. Instead it combines poses, meaning you can see the two animations at the same time. In this example the walk cycle is never altered. The cracking head and shoulder movements from the additive animation are simply (visually speaking) added. +Additive blending is different from normal blending because it does not interpolate from a pose to an other. Instead it combines poses, meaning the two animations can be seen at the same time. In this example the walk cycle is never altered. Fingers curl and splay poses coming from the additive animation are simply added (visually speaking) to the base animation. For the purpose of this sample, only the first frames of the 2 additive animations are used, aka a fixed pose for each (curl and splay poses). -Additive blending is performed by ozz::animation::BlendingJob. ozz::animation::BlendingJob exposes additive layers with the same input as normal blending layers: per joint local transforms, a global layer weight and optional per-joint weights. The main differences are that additive blending is done at the end of the normal blending pass, with a different equation. +Additive blending is performed by ozz::animation::BlendingJob. BlendingJob exposes additive layers with the same input as normal blending layers: per joint local transforms, a global layer weight and optional per-joint weights. The main differences are that additive blending is done at the end of the normal blending pass, with a different equation. -The additive (or delta) animation is created by subtracting a reference pose from a source animation. ozz proposes a ozz::animation::offline::AdditiveAnimationBuilder utility to build additive animations. It uses the first frame of the animation as the reference pose. fbx2ozz supports additive configuration option to export delta animations from a source file. - -Additionally, the sample uses an optional mask to blend the additive animation on the character upper body only. See partial blending sample for more details. +The additive (or delta) animation is created by subtracting a reference pose from a source animation. ozz proposes a ozz::animation::offline::AdditiveAnimationBuilder utility to build additive animations. It uses the first frame of the animation as the reference pose. fbx2ozz and gltf2ozz support additive configuration option to export delta animations from a source file. ## Sample usage -The sample proposes to modify main and additive layers weights: -- Normal blending layer weight. -- Additive blending layer weight. -- Upper body masking activation and base joint selection. - -Both main and additive animation playback parameters are exposed. +The sample proposes to tune base and additive (curl & splay) layers weights. Additive layers weight are exposed via 2d slider to make it easier to control together. ## Implementation -1. Loads main, additive animations, and their skeleton. See "playback" sample for more details. -2. Samples each animation to get local-space transformations. Sampling an additive animation is not different from a standard one. -3. Setups ozz::animation::BlendingJob object. BlendingJob object takes as input two arrays of BlendingJob::Layer, one for standard blending, the other for additive blending. Each layer is setup with its weights and the local-space transforms outputted from the sampling stage. +1. Loads base, additive (curl and splay) animations, and their skeleton. See "playback" sample for more details. +2. At initialization time, the first frame of curl and splay animations are sampled in order to extract their respective local-space transformations. Sampling an additive animation is not different from a standard one. The 2 animations are deleted as only the extracted pose will be used further. +3. At runtime, base animation is sampled to get skeleton base local-space transformations. +3. Setups ozz::animation::BlendingJob object. BlendingJob takes as input two arrays of BlendingJob::Layer, one for standard blending (base animation sampling output), the other for additive blending (the 2 curl and splay poses). Each layer is setup with its weights and the local-space transforms. 4. Convert local-space transformations to model-space matrices using ozz::animation::LocalToModelJob. It takes as input the skeleton (to know about joint's hierarchy) and local-space transforms outputted from the blending pass. Output is model-space matrices array. -5. Model-space matrices array is then used for rendering skeleton posture. \ No newline at end of file +5. Model-space matrices array is then used for rendering the animated skeleton pose (or the skinned mesh in a real world example). diff --git a/3rdparty/ozz-animation/samples/additive/sample_additive.cc b/3rdparty/ozz-animation/samples/additive/sample_additive.cc index aed4764..2a646e1 100644 --- a/3rdparty/ozz-animation/samples/additive/sample_additive.cc +++ b/3rdparty/ozz-animation/samples/additive/sample_additive.cc @@ -39,6 +39,7 @@ #include "ozz/animation/runtime/skeleton_utils.h" #include "ozz/base/containers/vector.h" #include "ozz/base/log.h" +#include "ozz/base/maths/box.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" @@ -56,68 +57,65 @@ OZZ_OPTIONS_DECLARE_STRING(animation, // Additive animation archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING( - additive_animation, "Path to the additive animation (ozz archive format).", - "media/animation_additive.ozz", false) + splay_animation, + "Path to the additive splay animation (ozz archive format).", + "media/animation_splay_additive.ozz", false) +OZZ_OPTIONS_DECLARE_STRING( + curl_animation, "Path to the additive curl animation (ozz archive format).", + "media/animation_curl_additive.ozz", false) class AdditiveBlendSampleApplication : public ozz::sample::Application { public: AdditiveBlendSampleApplication() - : upper_body_root_(0), - upper_body_mask_enable_(true), - upper_body_joint_weight_setting_(1.f), - threshold_(ozz::animation::BlendingJob().threshold) {} + : base_weight_(0.f), + additive_weigths_{.3f, .9f}, + auto_animate_weights_(true) {} protected: // Updates current animation time and skeleton pose. virtual bool OnUpdate(float _dt, float) { - // Updates and samples both animations to their respective local space - // transform buffers. - for (int i = 0; i < kNumLayers; ++i) { - Sampler& sampler = samplers_[i]; - - // Updates animations time. - sampler.controller.Update(sampler.animation, _dt); - - // Setup sampling job. - ozz::animation::SamplingJob sampling_job; - sampling_job.animation = &sampler.animation; - sampling_job.cache = &sampler.cache; - sampling_job.ratio = sampler.controller.time_ratio(); - sampling_job.output = make_span(sampler.locals); - - // Samples animation. - if (!sampling_job.Run()) { - return false; - } + // For the sample purpose, animates additive weights automatically so the + // hand moves. + if (auto_animate_weights_) { + AnimateWeights(_dt); } - // Blends animations. - // Blends the local spaces transforms computed by sampling all animations - // (1st stage just above), and outputs the result to the local space - // transform buffer blended_locals_ + // Updates base animation time for main animation. + controller_.Update(base_animation_, _dt); - // Prepares standard blending layers. + // Setup sampling job. + ozz::animation::SamplingJob sampling_job; + sampling_job.animation = &base_animation_; + sampling_job.context = &context_; + sampling_job.ratio = controller_.time_ratio(); + sampling_job.output = make_span(locals_); + + // Samples animation. + if (!sampling_job.Run()) { + return false; + } + + // Setups blending job layers. + + // Main animation is used as-is. ozz::animation::BlendingJob::Layer layers[1]; - layers[0].transform = make_span(samplers_[kMainAnimation].locals); - layers[0].weight = samplers_[kMainAnimation].weight_setting; + layers[0].transform = make_span(locals_); + layers[0].weight = base_weight_; + layers[0].joint_weights = make_span(base_joint_weights_); - // Prepares additive blending layers. - ozz::animation::BlendingJob::Layer additive_layers[1]; - additive_layers[0].transform = - make_span(samplers_[kAdditiveAnimation].locals); - additive_layers[0].weight = samplers_[kAdditiveAnimation].weight_setting; - - // Set per-joint weights for the additive blended layer. - if (upper_body_mask_enable_) { - additive_layers[0].joint_weights = make_span(upper_body_joint_weights_); + // The two additive layers (curl and splay) are blended on top of the main + // layer. + ozz::animation::BlendingJob::Layer additive_layers[kNumLayers]; + for (size_t i = 0; i < kNumLayers; ++i) { + additive_layers[i].transform = make_span(additive_locals_[i]); + additive_layers[i].weight = additive_weigths_[i]; } // Setups blending job. ozz::animation::BlendingJob blend_job; - blend_job.threshold = threshold_; blend_job.layers = layers; blend_job.additive_layers = additive_layers; - blend_job.bind_pose = skeleton_.joint_bind_poses(); + blend_job.rest_pose = skeleton_.joint_rest_poses(); blend_job.output = make_span(blended_locals_); // Blends. @@ -141,12 +139,34 @@ class AdditiveBlendSampleApplication : public ozz::sample::Application { return true; } + void AnimateWeights(float _dt) { + static float t = 0.f; + t += _dt; + additive_weigths_[0] = .5f + std::cos(t * 1.7f) * .5f; + additive_weigths_[1] = .5f + std::cos(t * 2.5f) * .5f; + } + // Samples animation, transforms to model space and renders. virtual bool OnDisplay(ozz::sample::Renderer* _renderer) { return _renderer->DrawPosture(skeleton_, make_span(models_), ozz::math::Float4x4::identity()); } + bool SetJointWeights(const char* _name, float _weight) { + const auto set_joint = [this, _weight](int _joint, int) { + ozz::math::SimdFloat4& soa_weight = base_joint_weights_[_joint / 4]; + soa_weight = ozz::math::SetI( + soa_weight, ozz::math::simd_float4::Load1(_weight), _joint % 4); + }; + + const int joint = FindJoint(skeleton_, _name); + if (joint >= 0) { + ozz::animation::IterateJointsDF(skeleton_, set_joint, joint); + return true; + } + return false; + } + virtual bool OnInitialize() { // Reading skeleton. if (!ozz::sample::LoadSkeleton(OPTIONS_skeleton, &skeleton_)) { @@ -155,81 +175,70 @@ class AdditiveBlendSampleApplication : public ozz::sample::Application { const int num_soa_joints = skeleton_.num_soa_joints(); const int num_joints = skeleton_.num_joints(); - // Reading animations. - const char* filenames[] = {OPTIONS_animation, OPTIONS_additive_animation}; - for (int i = 0; i < kNumLayers; ++i) { - Sampler& sampler = samplers_[i]; - - if (!ozz::sample::LoadAnimation(filenames[i], &sampler.animation)) { - return false; - } - - // Allocates sampler runtime buffers. - sampler.locals.resize(num_soa_joints); - - // Allocates a cache that matches animation requirements. - sampler.cache.Resize(num_joints); + // Reads base animation. + if (!ozz::sample::LoadAnimation(OPTIONS_animation, &base_animation_)) { + return false; } - // Default weight settings. - samplers_[kMainAnimation].weight_setting = 1.f; + if (num_joints != base_animation_.num_tracks()) { + return false; + } - upper_body_joint_weight_setting_ = 1.f; - samplers_[kAdditiveAnimation].weight_setting = 1.f; + // Allocates sampling context. + context_.Resize(num_joints); - // Allocates local space runtime buffers of blended data. - blended_locals_.resize(num_soa_joints); + // Allocates local space runtime buffers for base animation. + locals_.resize(num_soa_joints); // Allocates model space runtime buffers of blended data. models_.resize(num_joints); - // Allocates per-joint weights used for the partial additive animation. - // Note that this is a Soa structure. - upper_body_joint_weights_.resize(num_soa_joints); + // Storage for blending stage output. + blended_locals_.resize(num_soa_joints); - // Finds the "Spine1" joint in the joint hierarchy. - for (int i = 0; i < num_joints; ++i) { - if (std::strstr(skeleton_.joint_names()[i], "Spine1")) { - upper_body_root_ = i; - break; + // Allocates and sets base animation mask weights to one. + base_joint_weights_.resize(num_soa_joints, ozz::math::simd_float4::one()); + SetJointWeights("Lefthand", 0.f); + SetJointWeights("RightHand", 0.f); + + // Reads and extract additive animations pose. + const char* filenames[] = {OPTIONS_splay_animation, OPTIONS_curl_animation}; + for (int i = 0; i < kNumLayers; ++i) { + // Reads animation on the stack as it won't need to be maintained in + // memory. Only the pose is needed. + ozz::animation::Animation animation; + if (!ozz::sample::LoadAnimation(filenames[i], &animation)) { + return false; } + + if (num_joints != animation.num_tracks()) { + return false; + } + + // Allocates additive poses, aka buffers of Soa tranforms. + additive_locals_[i].resize(num_soa_joints); + + // Samples the first frame pose. + ozz::animation::SamplingJob sampling_job; + sampling_job.animation = &animation; + sampling_job.context = &context_; + sampling_job.ratio = 0.f; // Only needs the first frame pose + sampling_job.output = make_span(additive_locals_[i]); + + // Samples animation. + if (!sampling_job.Run()) { + return false; + } + + // Invalidates context which will be re-used for another animation. + // This is usually not needed, animation address on the stack is the same + // each loop, hence creating an issue as animation content is changing. + context_.Invalidate(); } - SetupPerJointWeights(); return true; } - // Helper functor used to set weights while traversing joints hierarchy. - struct WeightSetupIterator { - WeightSetupIterator(ozz::vector* _weights, - float _weight_setting) - : weights(_weights), weight_setting(_weight_setting) {} - void operator()(int _joint, int) { - ozz::math::SimdFloat4& soa_weight = weights->at(_joint / 4); - soa_weight = ozz::math::SetI( - soa_weight, ozz::math::simd_float4::Load1(weight_setting), - _joint % 4); - } - ozz::vector* weights; - float weight_setting; - }; - - void SetupPerJointWeights() { - // Setup partial animation mask. This mask is defined by a weight_setting - // assigned to each joint of the hierarchy. Joint to disable are set to a - // weight_setting of 0.f, and enabled joints are set to 1.f. - - // Disables all joints: set all weights to 0. - for (int i = 0; i < skeleton_.num_soa_joints(); ++i) { - upper_body_joint_weights_[i] = ozz::math::simd_float4::zero(); - } - - // Extracts the list of children of the shoulder - WeightSetupIterator it(&upper_body_joint_weights_, - upper_body_joint_weight_setting_); - IterateJointsDF(skeleton_, it, upper_body_root_); - } - virtual void OnDestroy() {} virtual bool OnGui(ozz::sample::ImGui* _im_gui) { @@ -241,69 +250,31 @@ class AdditiveBlendSampleApplication : public ozz::sample::Application { ozz::sample::ImGui::OpenClose oc(_im_gui, "Blending parameters", &open); if (open) { _im_gui->DoLabel("Main layer:"); - std::sprintf(label, "Layer weight: %.2f", - samplers_[kMainAnimation].weight_setting); - _im_gui->DoSlider(label, 0.f, 1.f, - &samplers_[kMainAnimation].weight_setting, 1.f); + std::sprintf(label, "Layer weight: %.2f", base_weight_); + _im_gui->DoSlider(label, 0.f, 1.f, &base_weight_, 1.f); + _im_gui->DoLabel("Additive layer:"); - std::sprintf(label, "Layer weight: %.2f", - samplers_[kAdditiveAnimation].weight_setting); - _im_gui->DoSlider(label, -1.f, 1.f, - &samplers_[kAdditiveAnimation].weight_setting, 1.f); - _im_gui->DoLabel("Global settings:"); - std::sprintf(label, "Threshold: %.2f", threshold_); - _im_gui->DoSlider(label, .01f, 1.f, &threshold_); - } - } - // Exposes selection of the root of the partial blending hierarchy. - { - static bool open = true; - ozz::sample::ImGui::OpenClose oc(_im_gui, "Upper body masking", &open); + _im_gui->DoCheckBox("Animates weights", &auto_animate_weights_); + ozz::array weights; + std::memcpy(weights.data(), additive_weigths_, + sizeof(additive_weigths_)); - if (open) { - bool rebuild_joint_weights = false; - rebuild_joint_weights |= - _im_gui->DoCheckBox("Enable mask", &upper_body_mask_enable_); - - std::sprintf(label, "Joints weight: %.2f", - upper_body_joint_weight_setting_); - rebuild_joint_weights |= _im_gui->DoSlider( - label, 0.f, 1.f, &upper_body_joint_weight_setting_, 1.f, - upper_body_mask_enable_); - - if (skeleton_.num_joints() != 0) { - _im_gui->DoLabel("Root of the upper body hierarchy:", - ozz::sample::ImGui::kLeft, false); - std::sprintf(label, "%s (%d)", - skeleton_.joint_names()[upper_body_root_], - upper_body_root_); - - rebuild_joint_weights |= _im_gui->DoSlider( - label, 0, skeleton_.num_joints() - 1, &upper_body_root_, 1.f, - upper_body_mask_enable_); - } - - // Rebuilds per-joint weights if something has changed. - if (rebuild_joint_weights) { - SetupPerJointWeights(); + std::sprintf(label, "Weights\nCurl: %.2f\nSplay: %.2f", + additive_weigths_[kCurl], additive_weigths_[kSplay]); + if (_im_gui->DoSlider2D(label, {{0.f, 0.f}}, {{1.f, 1.f}}, &weights)) { + auto_animate_weights_ = false; // User interacted. + std::memcpy(additive_weigths_, weights.data(), + sizeof(additive_weigths_)); } } } - // Exposes animations runtime playback controls. + + // Exposes base animation runtime playback controls. { static bool oc_open = true; ozz::sample::ImGui::OpenClose oc(_im_gui, "Animation control", &oc_open); if (oc_open) { - static bool open[kNumLayers] = {true, true}; - const char* oc_names[kNumLayers] = {"Main animation", - "Additive animation"}; - for (int i = 0; i < kNumLayers; ++i) { - Sampler& sampler = samplers_[i]; - ozz::sample::ImGui::OpenClose loc(_im_gui, oc_names[i], nullptr); - if (open[i]) { - sampler.controller.OnGui(sampler.animation, _im_gui); - } - } + controller_.OnGui(base_animation_, _im_gui); } } @@ -311,62 +282,55 @@ class AdditiveBlendSampleApplication : public ozz::sample::Application { } virtual void GetSceneBounds(ozz::math::Box* _bound) const { - ozz::sample::ComputePostureBounds(make_span(models_), _bound); + // Finds the "hand" joint in the joint hierarchy. + const int hand = FindJoint(skeleton_, "Lefthand"); + + // Creates a bounding volume around the hand. + if (hand != -1) { + const ozz::math::Float4x4& hand_matrix = models_[hand]; + ozz::math::Float3 hand_position; + ozz::math::Store3PtrU(hand_matrix.cols[3], &hand_position.x); + const ozz::math::Float3 extent(.15f); + _bound->min = hand_position - extent; + _bound->max = hand_position + extent; + } else { + ozz::sample::ComputePostureBounds(make_span(models_), _bound); + } } private: // Runtime skeleton. ozz::animation::Skeleton skeleton_; - // The number of layers to blend. - enum { - kMainAnimation = 0, - kAdditiveAnimation = 1, - kNumLayers = 2, - }; + // The number of additive layers to blend. + enum { kSplay, kCurl, kNumLayers }; - // Sampler structure contains all the data required to sample a single - // animation. - struct Sampler { - // Constructor, default initialization. - Sampler() : weight_setting(1.f) {} + // Runtime animation. + ozz::animation::Animation base_animation_; - // Playback animation controller. This is a utility class that helps with - // controlling animation playback time. - ozz::sample::PlaybackController controller; + // Per-joint weights used to define the base animation mask. Allows to remove + // hands from base animations. + ozz::vector base_joint_weights_; - // Blending weight_setting for the layer. - float weight_setting; + // Main animation controller. This is a utility class that helps with + // controlling animation playback time. + ozz::sample::PlaybackController controller_; - // Runtime animation. - ozz::animation::Animation animation; + // Sampling context. + ozz::animation::SamplingJob::Context context_; - // Sampling cache. - ozz::animation::SamplingCache cache; + // Buffer of local transforms as sampled from main animation_. + ozz::vector locals_; - // Buffer of local transforms as sampled from animation_. - ozz::vector locals; + // Blending weight of the base animation layer. + float base_weight_; - } samplers_[kNumLayers]; // kNumLayers animations to blend. + // Poses of local transforms as sampled from curl and splay animations. + // They are sampled during initialization, as a single pose is used. + ozz::vector additive_locals_[kNumLayers]; - // Index of the joint at the base of the upper body hierarchy. - int upper_body_root_; - - // Enables upper boddy per-joint weights. - bool upper_body_mask_enable_; - - // Blending weight_setting setting of the joints of this layer that are - // affected - // by the masking. - float upper_body_joint_weight_setting_; - - // Per-joint weights used to define the partial animation mask. Allows to - // select which joints are considered during blending, and their individual - // weight_setting. - ozz::vector upper_body_joint_weights_; - - // Blending job bind pose threshold. - float threshold_; + // Blending weight of the additive animation layer. + float additive_weigths_[kNumLayers]; // Buffer of local transforms which stores the blending result. ozz::vector blended_locals_; @@ -374,7 +338,10 @@ class AdditiveBlendSampleApplication : public ozz::sample::Application { // Buffer of model space matrices. These are computed by the local-to-model // job after the blending stage. ozz::vector models_; - }; + + // Automatically animates additive weights. + bool auto_animate_weights_; +}; int main(int _argc, const char** _argv) { const char* title = "Ozz-animation sample: Additive animations blending"; diff --git a/3rdparty/ozz-animation/samples/attach/CMakeLists.txt b/3rdparty/ozz-animation/samples/attach/CMakeLists.txt index 8a0bf2a..1aba920 100644 --- a/3rdparty/ozz-animation/samples/attach/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/attach/CMakeLists.txt @@ -21,7 +21,7 @@ add_executable(sample_attach target_link_libraries(sample_attach sample_framework) - +target_copy_shared_libraries(sample_attach) set_target_properties(sample_attach PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/attach/sample_attach.cc b/3rdparty/ozz-animation/samples/attach/sample_attach.cc index d6a74ed..7cba010 100644 --- a/3rdparty/ozz-animation/samples/attach/sample_attach.cc +++ b/3rdparty/ozz-animation/samples/attach/sample_attach.cc @@ -25,24 +25,21 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/animation.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/sampling_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#include "ozz/base/log.h" - -#include "ozz/base/maths/box.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/maths/vec_float.h" - -#include "ozz/options/options.h" - #include "framework/application.h" #include "framework/imgui.h" #include "framework/renderer.h" #include "framework/utils.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/animation/runtime/skeleton_utils.h" +#include "ozz/base/log.h" +#include "ozz/base/maths/box.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/maths/vec_float.h" +#include "ozz/options/options.h" // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, @@ -67,7 +64,7 @@ class AttachSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -133,15 +130,13 @@ class AttachSampleApplication : public ozz::sample::Application { locals_.resize(num_soa_joints); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Finds the joint where the object should be attached. - for (int i = 0; i < num_joints; i++) { - if (std::strstr(skeleton_.joint_names()[i], "LeftHandMiddle")) { - attachment_ = i; - break; - } + attachment_ = FindJoint(skeleton_, "LeftHandMiddle1"); + if (attachment_ < 0) { + return false; } return true; @@ -198,8 +193,8 @@ class AttachSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; diff --git a/3rdparty/ozz-animation/samples/baked/CMakeLists.txt b/3rdparty/ozz-animation/samples/baked/CMakeLists.txt index fa32f44..995d1c9 100644 --- a/3rdparty/ozz-animation/samples/baked/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/baked/CMakeLists.txt @@ -23,6 +23,7 @@ add_executable(sample_baked target_link_libraries(sample_baked sample_framework) +target_copy_shared_libraries(sample_baked) set_target_properties(sample_baked PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/baked/sample_baked.cc b/3rdparty/ozz-animation/samples/baked/sample_baked.cc index 1e5ecf1..c70f220 100644 --- a/3rdparty/ozz-animation/samples/baked/sample_baked.cc +++ b/3rdparty/ozz-animation/samples/baked/sample_baked.cc @@ -25,24 +25,20 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/animation.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/sampling_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#include "ozz/base/log.h" - -#include "ozz/base/maths/box.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/maths/vec_float.h" - -#include "ozz/options/options.h" - #include "framework/application.h" #include "framework/imgui.h" #include "framework/renderer.h" #include "framework/utils.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/log.h" +#include "ozz/base/maths/box.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/maths/vec_float.h" +#include "ozz/options/options.h" // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, @@ -67,7 +63,7 @@ class BakedSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -103,8 +99,8 @@ class BakedSampleApplication : public ozz::sample::Application { locals_.resize(num_soa_joints); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Look for a "camera" joint. for (int i = 0; i < num_joints; i++) { @@ -167,8 +163,8 @@ class BakedSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; diff --git a/3rdparty/ozz-animation/samples/blend/CMakeLists.txt b/3rdparty/ozz-animation/samples/blend/CMakeLists.txt index ad7d42e..51d5656 100644 --- a/3rdparty/ozz-animation/samples/blend/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/blend/CMakeLists.txt @@ -31,6 +31,7 @@ add_executable(sample_blend target_link_libraries(sample_blend sample_framework) +target_copy_shared_libraries(sample_blend) set_target_properties(sample_blend PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/blend/README.md b/3rdparty/ozz-animation/samples/blend/README.md index 0358ad8..b691c9c 100644 --- a/3rdparty/ozz-animation/samples/blend/README.md +++ b/3rdparty/ozz-animation/samples/blend/README.md @@ -23,6 +23,6 @@ There are two ways to use the sample: 1. Load animations and skeleton. See "playback" sample for more details. 2. Compute each animation time (in order to sync their duration) and samples each of them to get local-space transformations. -3. Compute each animation (layer) blend weight and fills ozz::animation::BlendingJob object. BlendingJob object takes as input an array of BlendingJob::Layer representing each layer to blend: weight and local-space transformations (as outputed from the sampling stage). It also takes as input the skeleton bind-pose, which represents the default transformation of each joint. It is used by the blending algorithm as a fall-back when the accumulated layer weight is too small (under a threshold value which is also an input) to be used. The output of the blending job is a set of local-space transformations. +3. Compute each animation (layer) blend weight and fills ozz::animation::BlendingJob object. BlendingJob object takes as input an array of BlendingJob::Layer representing each layer to blend: weight and local-space transformations (as outputed from the sampling stage). It also takes as input the skeleton rest-pose, which represents the default transformation of each joint. It is used by the blending algorithm as a fall-back when the accumulated layer weight is too small (under a threshold value which is also an input) to be used. The output of the blending job is a set of local-space transformations. 4. Convert local-space transformations to model-space matrices using ozz::animation::LocalToModelJob. It takes as input the skeleton (to know about joint's hierarchy) and local-space transforms. Output is model-space matrices array. 5. Model-space matrices array can then be used for rendering (to skin a mesh) or updating the scene graph. \ No newline at end of file diff --git a/3rdparty/ozz-animation/samples/blend/sample_blend.cc b/3rdparty/ozz-animation/samples/blend/sample_blend.cc index e2ac3aa..0bda296 100644 --- a/3rdparty/ozz-animation/samples/blend/sample_blend.cc +++ b/3rdparty/ozz-animation/samples/blend/sample_blend.cc @@ -25,26 +25,22 @@ // // //----------------------------------------------------------------------------// +#include "framework/application.h" +#include "framework/imgui.h" +#include "framework/renderer.h" +#include "framework/utils.h" #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/blending_job.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" - #include "ozz/base/log.h" - #include "ozz/base/maths/math_ex.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" - #include "ozz/options/options.h" -#include "framework/application.h" -#include "framework/imgui.h" -#include "framework/renderer.h" -#include "framework/utils.h" - // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, "Path to the skeleton (ozz archive format).", @@ -97,7 +93,7 @@ class BlendSampleApplication : public ozz::sample::Application { // Setup sampling job. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &sampler.animation; - sampling_job.cache = &sampler.cache; + sampling_job.context = &sampler.context; sampling_job.ratio = sampler.controller.time_ratio(); sampling_job.output = make_span(sampler.locals); @@ -123,7 +119,7 @@ class BlendSampleApplication : public ozz::sample::Application { ozz::animation::BlendingJob blend_job; blend_job.threshold = threshold_; blend_job.layers = layers; - blend_job.bind_pose = skeleton_.joint_bind_poses(); + blend_job.rest_pose = skeleton_.joint_rest_poses(); blend_job.output = make_span(blended_locals_); // Blends. @@ -216,8 +212,8 @@ class BlendSampleApplication : public ozz::sample::Application { // Allocates sampler runtime buffers. sampler.locals.resize(num_soa_joints); - // Allocates a cache that matches animation requirements. - sampler.cache.Resize(num_joints); + // Allocates a context that matches animation requirements. + sampler.context.Resize(num_joints); } // Allocates local space runtime buffers of blended data. @@ -319,14 +315,14 @@ class BlendSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation; - // Sampling cache. - ozz::animation::SamplingCache cache; + // Sampling context. + ozz::animation::SamplingJob::Context context; // Buffer of local transforms as sampled from animation_. ozz::vector locals; } samplers_[kNumLayers]; // kNumLayers animations to blend. - // Blending job bind pose threshold. + // Blending job rest pose threshold. float threshold_; // Buffer of local transforms which stores the blending result. diff --git a/3rdparty/ozz-animation/samples/demo.zip b/3rdparty/ozz-animation/samples/demo.zip new file mode 100644 index 0000000000000000000000000000000000000000..c5a37bd50135cca2e00f2b0d626e32b667d395df GIT binary patch literal 4884 zcmZ{o1yodB*T;vHE=OmiTM6l*q?;KAhVBmO?nWs^KuVAt=|+(5MnW8V009B%5~M>v zAD`FndwkaWox9Hc-?P>}zkTmLYwfl69|6O{1_J&XoYs9RzaIW`!}+OJ)=n6xDV69^3;pxHU>FYVA3v-#1B5P+lq*D;M#dt^K1YD;C z%p77jvog{a*N^eJU4I_tJp;Gx3pv=ojQB7d#;Wb1WbrYO|Jw&kpKILm6r?&H;}buX zAfhyEax-Q!1WB5^z!`qzg#p37`YxdqbupqlC%mF7rt#~{f(_HS_uN>OX(ivXy+fto zonwu%iKZfn3%!`y@zJzE zu`SUFvCk%B{*W_*^z~{ILEVMeHc_1_sI-U}@vsAzVs^M*HkbeDnQE}aS!pWn>UU5N zO<{=oRdL-AXS6q-+;SIPGemQ^AYO|`JWtbOGQ$9WQar_(g2njq4 zjYVFm)>Ci|c^s|Y&0l%(YzQGm%TzzbgtyE7Hjofgol~b8MetRrPlnw! zek_IlO^usap@tTd$5CG!)rsWC$)<{%O$Ww%QV-gO93Gh78V4Kt*ec002F^f1LX_@d zfgM4Q<6h{m9O$ulVm*}mJfn5f^$y~?uJqc{;5LFdt5BPxuYyD6~b!LOnKDk2ldz ztcD;3x4zjISUK6&7WR2SMyUSc z$GpKc#-CMUU|OUvjR*jE%n1Pel)nqfU)6-m(z4B9$9Y8o_`PGiy(bxJsDxjueHCTI zEQ2O~7>1|RuxD>gd`ebWEj~%RF>b%qwlUIYX-S`-@zB7j(_{V7*)UPL- zeZwGOJ5lcW)qyPKw`eGrMYm=Ru*3@EO(JK3k=NWF6<6wP>sm~4P|_h!zJBjIL+p*W zolBh3YACi?3VzPx=;S^OShNwJyGU9B!~t_+`{!Z$)81{~Wg(dIcJR~d zuM20A2|hYP?vXPrL)MmOb)tsfG_RJI`9S+Or$HCr;ow1r<0eV|tEeoI4UW^40k1obg_OkyKEAH&;Loa{YV z9pAMBNIrg7Jn2BTgR_PiS0rtY4v(jdVpVM&=9^p3B?o>UfTBVVU?_S`jHbqA-{UFt za2p6Mi9OL%+UJPcA=6tUw@Dpm!QuGu`tT0nXSnmglN*Xj-W0MJ>edble0J?>hn|RR0dogAG9P%+*28xvbx^++!~^4zrYq)2^qZV+O-H2XOiOGinHlRIy4-oxls+i z_hK|7|Hu4PzGPP7VJ{;IS5@Rw2~J{#w&jxxv*WnTuG29vbQWL_Hv8EBeuk0cQnR;p zSIr;vwK_l$Ok&dkS~=V^6O^HK2~$or^1A;{`oJHZ^|EYdaLRY?mfI*shyb`P3()f2 zIz+$$BfwYTvZMPJU)v^0l!Jj!m2}m!#8#p9%OE~qA6_QV>arglZT5*YdVlt9yh=)Q zo4JqcEc3>~@P14C90V6w20?7NcXVv75)hywLfU4{#4vHfhHVAI;^C+ezG3o3(!v|o zEmd4i0d47>LGXFln%e<*naq4r*LR46Wdq~cWuW-p2Fjsb;=m`W(~QXGFQ`Xr>Y73Zga($Y~%PEaWU_MXpyhU0;0Jmyod5S zdm5w~V^k1oG83vG#%JCM?Cpz;K&^eV4~z+7^>)#5Xx4na5_`uVI<|N5W6^C&&hwr) z&WBE|j)lwQDnau)(n!xHFJ5!u%W5l*E`=zXD>P~~L({jkxx$V6&9ja#Xq4@XhwR3@ zIo!fMTM?a170x>+WruVjzN;MN9GVBMOH?xOuZ8^O1zuF_A7-k&nO*h>uFYE-7G$=~ z=8bTVSyN(l_VDwgaWb1-aq%{#2`LN9%_m!SWnv)GH+)daw~y`ajpYJ!-jsHsb2;RO zVYbogXGCk`hO`5nfQFzrDz^~%hmzsTuQO#Wyp07D;%E^;Vy0fArQfSnicp*E`V^g8u84&8l04{UW(n zw4Z23ZAWmDnzTSzs{*{%_H-S`(Hra)9bmIU;e#}ny(f|}r}ogeq89RPv00&KHF43o z&hc)t(+5r@=eQkPmh|VbcTVQhR*B1r`Y08x4dug;+?woyjNI>;MP)A~rePwYyzre+ z-}(@Jx8rt!Z$Y?hAuHh9oXq*zM;)*4D`Uf!Xx2Pk7CVzHnIdN}8Hrer_8JnpAa=<^ z?$wg_D;jt* z#+gX=oxD4}Lt>MPzMz)Mh^7ySGd;$g{(*|@P(PxJ9LMqkHrnH$k3}V7(~+W6-P{+% z#jJIh&8_Cxt$y!Fk~l&wbukB~KAIWS>S1ZNSS9f{5)x!~MX${;3rFC{ZSIiJtglb* zI7S$`=*)@2r80!Z$=V`d#n^r*5+N}6e`%pJf6YpLO!2lRO@*^*J;8P{3R zXFBCRH`Z(kEo9gwlL(5lsnmNUL$=kIBZ1Ed(zIzG?$`7LY2|9rL@n+%8|>?!jk+p1 z#j}Z`6%ve&m+g6H!rtMAKJZ+$D7!ga9#Du**Wa7xIe~zl8-j z-k_;vbVl=tpOvtB|@cN9?q9*JU#en%<8I25T(9)@Gjxi8J4fntjJQ&1KjfjizQ% zi^WZ;d0BPeBp;1ruTcueRs#XwjdY_C@GHEqtv&86p?YF_Q+H91X)N0LqO449+E=c+ zQ(MPL*tsX?X_HcRV(SZsowSx%UE}9eO@+)QdlCcFcMMVYpZ-|hH{Elttv`_2FCh}8 zdH){am$#h{_15X>B~eskmY+d1mAm@fyBKt?YDH6X>B-*A*YZ_Y47~V6W_fqaaWQ!f z_hVtKO(gB7Of`cT@vLmiAE1vj+Xk;r`4>#xzh~nLMF2;s)`MS-yz6_yQka3h%_QRH zb^3MEIURK#NdvlkuZ4Q;q*ip|PVPYMWCc4}rp=U#O?V#V8bIA$B^;}i9t_VVZ;@Q| zzCR}G&+@@p`FK#wSUsnL>Z$GYbE^;sbY=5sz&B50u(kxD_>AL&-U@bP^5n6T7W}?q zb$$213PzW7*M>_6gu#VhK^|mu*4@!OOm0kN`5B;$=@FDP=`U~;+&@sKQO#-k97ETn zSp8f0*u1@4sR@l%QRJg8tXBHYs;a(K5am4r36aO^SY;X4fEsr7_n}hq9OVa?W9BE= z>JSUcN30LdgXAu9t;o8V8d;VTZY_}kU5Kto?fboyQxzpm8b;nw%-a8 z=v(Q27~`+avgz3`HA5K2L>{~ljm3~8bbGiQR~(yH9R_-G&I}5^QP3UXttalN^~;aDjfC$)T$C5DMiNf^6nIO8l{zRsys(^^@pj7xV| zUCLwpY_S6~s3UyJN99yYo4V%>f7tSy_BZ`>WM>stvL74zunU#Xqh}1k>eW2jI#d2Z zNRv)%av*C?9bcdfNyn0h+#^@_#;X-lmezR10JeAtRZ31bX(;+0LE2r&Ey>Vvk3bVd zV`8LuBSyp$h4C|Bnm(9GXJViGttrbj$@7w%?X{u1!n#*R;&uu5zVG6GSASv})LoKR zTor#@USqY)u6Oyw4I<*X`^OZQE(0v?lxRBM_Nm4?FTDlKrs9C&Xs#3b|1nF2|TE~i;( zX)RK2YnzpDiYPUv?iPat8(2@>G_mYr`stF;}${5-L?e; zM!k?ou*Q>EgWwnvZ~ZbWjc=j}Ck*G5i(hI<%_(~PZV)gGOi951=fW`mO#as(`&<5Q zr3e7@zm^yPFyImk($RE1f$>|RI{d%Z|A+l=&dqP^UmT{N^Ox20r;qc`B-@_^enIEz z{?vab`Lpr+XA))XKij~6(tp4DzxChrKM&=fbVBm~(Es;{{u}@ISNv843 + +#include "framework/application.h" +#include "framework/imgui.h" +#include "framework/mesh.h" +#include "framework/renderer.h" +#include "framework/utils.h" #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/ik_aim_job.h" #include "ozz/animation/runtime/ik_two_bone_job.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" - #include "ozz/base/log.h" - #include "ozz/base/maths/box.h" #include "ozz/base/maths/math_ex.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/simd_quaternion.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" - #include "ozz/options/options.h" -#include "framework/application.h" -#include "framework/imgui.h" -#include "framework/mesh.h" -#include "framework/utils.h" - -#include "framework/renderer.h" -#include "framework/utils.h" - -#include - // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, "Path to the skeleton (ozz archive format).", @@ -107,7 +101,7 @@ class FootIKSampleApplication : public ozz::sample::Application { FootIKSampleApplication() : pelvis_offset_(0.f, 0.f, 0.f), root_translation_(2.17f, 2.f, -2.06f), - root_yaw_(2.f), + root_yaw_(-2.f), foot_heigh_(.12f), weight_(1.f), soften_(1.f), @@ -186,7 +180,7 @@ class FootIKSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -481,8 +475,8 @@ class FootIKSampleApplication : public ozz::sample::Application { } } else { // Renders skeleton only. - success &= _renderer->DrawPosture(skeleton_, make_span(models_), - offsetted_root); + success &= + _renderer->DrawPosture(skeleton_, make_span(models_), offsetted_root); } // Showing joints @@ -557,8 +551,8 @@ class FootIKSampleApplication : public ozz::sample::Application { const int num_joints = skeleton_.num_joints(); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Finds left and right joints. if (!SetupLeg(skeleton_, kLeftJointNames, &legs_setup_[kLeft]) || @@ -597,7 +591,7 @@ class FootIKSampleApplication : public ozz::sample::Application { bool SetupLeg(const ozz::animation::Skeleton& _skeleton, const char* _joint_names[3], LegSetup* _leg) { int found = 0; - int joints[3] = {0, 0, 0}; + int joints[3] = {0}; for (int i = 0; i < _skeleton.num_joints() && found != 3; i++) { const char* joint_name = _skeleton.joint_names()[i]; if (std::strcmp(joint_name, _joint_names[found]) == 0) { @@ -742,8 +736,8 @@ class FootIKSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; @@ -752,7 +746,7 @@ class FootIKSampleApplication : public ozz::sample::Application { ozz::vector models_; // Buffer of skinning matrices, result of the joint multiplication of the - // inverse bind pose with the model space matrix. + // inverse rest pose with the model space matrix. ozz::vector skinning_matrices_; // The mesh used by the sample. diff --git a/3rdparty/ozz-animation/samples/framework/CMakeLists.txt b/3rdparty/ozz-animation/samples/framework/CMakeLists.txt index a125ea6..4b8e2c0 100644 --- a/3rdparty/ozz-animation/samples/framework/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/framework/CMakeLists.txt @@ -29,9 +29,7 @@ add_library(sample_framework STATIC # Samples requires OpenGL package. if(NOT EMSCRIPTEN) add_subdirectory(${PROJECT_SOURCE_DIR}/extern/glfw glfw) - - target_link_libraries(sample_framework - glfw) + target_link_libraries(sample_framework glfw) endif() target_link_libraries(sample_framework @@ -43,7 +41,6 @@ if(TARGET BUILD_DATA_SAMPLE) add_dependencies(sample_framework BUILD_DATA_SAMPLE) endif() -set_target_properties(sample_framework - PROPERTIES FOLDER "samples") +set_target_properties(sample_framework PROPERTIES FOLDER "samples") add_subdirectory(tools) diff --git a/3rdparty/ozz-animation/samples/framework/application.cc b/3rdparty/ozz-animation/samples/framework/application.cc index b962769..b7778cb 100644 --- a/3rdparty/ozz-animation/samples/framework/application.cc +++ b/3rdparty/ozz-animation/samples/framework/application.cc @@ -476,6 +476,12 @@ bool Application::Gui() { // Downcast to public imgui. ImGui* im_gui = im_gui_.get(); + + // Do floating gui. + if (!show_help_) { + success = OnFloatingGui(im_gui); + } + // Help gui. { math::RectFloat rect(kGuiMargin, kGuiMargin, @@ -658,6 +664,31 @@ bool Application::FrameworkGui() { return true; } +bool Application::OnInitialize() { return true; } + +void Application::OnDestroy() {} + +bool Application::OnUpdate(float _dt, float _time) { + (void)_dt; + (void)_time; + return true; +} + +bool Application::OnGui(ImGui* _im_gui) { + (void)_im_gui; + return true; +} + +bool Application::OnFloatingGui(ImGui* _im_gui) { + (void)_im_gui; + return true; +} + +bool Application::OnDisplay(Renderer* _renderer) { + (void)_renderer; + return true; +} + bool Application::GetCameraInitialSetup(math::Float3* _center, math::Float2* _angles, float* _distance) const { @@ -674,6 +705,23 @@ bool Application::GetCameraOverride(math::Float4x4* _transform) const { return false; } +void Application::GetSceneBounds(math::Box* _bound) const { (void)_bound; } + +math::Float2 Application::WorldToScreen(const math::Float3& _world) const { + const math::SimdFloat4 ndc = + (camera_->projection() * camera_->view()) * + math::simd_float4::Load(_world.x, _world.y, _world.z, 1.f); + + const math::SimdFloat4 resolution = math::simd_float4::FromInt( + math::simd_int4::Load(resolution_.width, resolution_.height, 0, 0)); + const ozz::math::SimdFloat4 screen = + resolution * ((ndc / math::SplatW(ndc)) + math::simd_float4::one()) / + math::simd_float4::Load1(2.f); + math::Float2 ret; + math::Store2PtrU(screen, &ret.x); + return ret; +} + void Application::ResizeCbk(int _width, int _height) { // Stores new resolution settings. application_->resolution_.width = _width; diff --git a/3rdparty/ozz-animation/samples/framework/application.h b/3rdparty/ozz-animation/samples/framework/application.h index 12228cb..fb004cd 100644 --- a/3rdparty/ozz-animation/samples/framework/application.h +++ b/3rdparty/ozz-animation/samples/framework/application.h @@ -29,6 +29,7 @@ #define OZZ_SAMPLES_FRAMEWORK_APPLICATION_H_ #include + #include "ozz/base/containers/string.h" #include "ozz/base/memory/unique_ptr.h" @@ -78,36 +79,47 @@ class Application { int Run(int _argc, const char** _argv, const char* _version, const char* _title); + protected: + // Allows application to convert from world space to screen coordinates. + math::Float2 WorldToScreen(const math::Float3& _world) const; + private: // Provides initialization event to the inheriting application. Called while // the help screen is being displayed. // OnInitialize can return false which will in turn skip the display loop and // exit the application with EXIT_FAILURE. Note that OnDestroy is called in // any case. - virtual bool OnInitialize() = 0; + virtual bool OnInitialize(); // Provides de-initialization event to the inheriting application. // OnDestroy is called even if OnInitialize failed and returned an error. - virtual void OnDestroy() = 0; + virtual void OnDestroy(); // Provides update event to the inheriting application. // _dt is the elapsed time (in seconds) since the last update. // _time is application time including scaling (aka accumulated _dt). // OnUpdate can return false which will in turn stop the loop and exit the // application with EXIT_FAILURE. Note that OnDestroy is called in any case. - virtual bool OnUpdate(float _dt, float _time) = 0; + virtual bool OnUpdate(float _dt, float _time); // Provides immediate mode gui display event to the inheriting application. // This function is called in between the OnDisplay and swap functions. // OnGui can return false which will in turn stop the loop and exit the // application with EXIT_FAILURE. Note that OnDestroy is called in any case. - virtual bool OnGui(ImGui* _im_gui) = 0; + virtual bool OnGui(ImGui* _im_gui); + + // Provides immediate mode floating gui display event to the inheriting + // application. Floating gui allows to render a Gui anywere one screen. User + // must provide the form. OnFloatingGui can return false which will in turn + // stop the loop and exit the application with EXIT_FAILURE. Note that + // OnDestroy is called in any case. + virtual bool OnFloatingGui(ImGui* _im_gui); // Provides display event to the inheriting application. // This function is called in between the clear and swap functions. // OnDisplay can return false which will in turn stop the loop and exit the // application with EXIT_FAILURE. Note that OnDestroy is called in any case. - virtual bool OnDisplay(Renderer* _renderer) = 0; + virtual bool OnDisplay(Renderer* _renderer); // Initial camera values. These will only be considered if function returns // true; @@ -125,7 +137,7 @@ class Application { // the camera to frame all the scene. // This function is never called before a first OnUpdate. // If _bound is set to "invalid", then camera won't be updated. - virtual void GetSceneBounds(math::Box* _bound) const = 0; + virtual void GetSceneBounds(math::Box* _bound) const; // Implements framework internal loop function. bool Loop(); diff --git a/3rdparty/ozz-animation/samples/framework/imgui.h b/3rdparty/ozz-animation/samples/framework/imgui.h index 52fdb57..e18a5c6 100644 --- a/3rdparty/ozz-animation/samples/framework/imgui.h +++ b/3rdparty/ozz-animation/samples/framework/imgui.h @@ -28,12 +28,14 @@ #ifndef OZZ_SAMPLES_FRAMEWORK_IMGUI_H_ #define OZZ_SAMPLES_FRAMEWORK_IMGUI_H_ +#include + #include namespace ozz { namespace math { struct RectFloat; -} +} // namespace math namespace sample { // Interface for immediate mode graphical user interface rendering. @@ -54,8 +56,9 @@ class ImGui { // A form is a root in the frame's container stack. // The _rect argument is relative to the parent's rect and is automatically // shrunk to fit inside parent's rect and to the size of its widgets. - // Providing a non nullptr _title argument displays a title on top of the form. - // Providing a non nullptr _open argument enables the open/close mechanism. + // Providing a non nullptr _title argument displays a title on top of the + // form. Providing a non nullptr _open argument enables the open/close + // mechanism. class Form { public: Form(ImGui* _im_gui, const char* _title, const math::RectFloat& _rect, @@ -115,6 +118,11 @@ class ImGui { float* _value, float _pow = 1.f, bool _enabled = true) = 0; + virtual bool DoSlider2D(const char* _label, ozz::array _min, + ozz::array _max, + ozz::array* _value, + bool _enabled = true) = 0; + // Adds an integer slider to the current context and returns true if _value // was modified. // _value is the in-out parameter that stores slider value. It's clamped @@ -172,9 +180,9 @@ class ImGui { // container automatically shrinks to fit the size of the widgets it contains. // Providing a non nullptr _title argument displays a title on top of the // container. - // Providing a nullptr _rect argument means that the container will use all its - // parent size. - // Providing a non nullptr _open argument enables the open/close mechanism. + // Providing a nullptr _rect argument means that the container will use all + // its parent size. Providing a non nullptr _open argument enables the + // open/close mechanism. virtual void BeginContainer(const char* _title, const math::RectFloat* _rect, bool* _open, bool _constrain) = 0; diff --git a/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.cc b/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.cc index d06119e..e47e6d0 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.cc +++ b/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.cc @@ -34,11 +34,11 @@ #include #include +#include "immediate.h" #include "ozz/base/maths/math_constant.h" #include "ozz/base/maths/math_ex.h" +#include "ozz/base/maths/vec_float.h" #include "ozz/base/memory/allocator.h" - -#include "immediate.h" #include "renderer_impl.h" namespace ozz { @@ -211,6 +211,11 @@ bool ImGuiImpl::AddWidget(float _height, math::RectFloat* _rect) { // Get current container. Container& container = containers_.back(); + // Make it a square if height is negative. + if (_height < 0) { + _height = container.rect.width - kWidgetMarginX * 2.f; + } + // Early out if outside of the container. // But don't modify current container's state. if (container.offset_y < kWidgetMarginY + _height) { @@ -740,6 +745,33 @@ void ImGuiImpl::DoGraph(const char* _label, float _min, float _max, float _mean, } } +namespace { + +float SliderControl(float _value, float _min, float _max, float _pow, + int _mouse, int _mouse_max, bool _enabled, bool _active, + float* _cursor) { + const float pow_min = powf(_min, _pow); + const float pow_max = powf(_max, _pow); + const float clamped_value = ozz::math::Clamp(_min, _value, _max); + float pow_value = powf(clamped_value, _pow); + + // Finds cursor position and rect. + *_cursor = floorf((_mouse_max * (pow_value - pow_min)) / (pow_max - pow_min)); + + if (_enabled) { + if (_active) { + _mouse = ozz::math::Clamp(0, _mouse, _mouse_max); + pow_value = (_mouse * (pow_max - pow_min)) / _mouse_max + pow_min; + return ozz::math::Clamp(_min, powf(pow_value, 1.f / _pow), _max); + } else { + // Clamping is only applied if the widget is enabled. + return clamped_value; + } + } + return _value; +} +} // namespace + bool ImGuiImpl::DoSlider(const char* _label, float _min, float _max, float* _value, float _pow, bool _enabled) { math::RectFloat rect; @@ -751,7 +783,6 @@ bool ImGuiImpl::DoSlider(const char* _label, float _min, float _max, // Calculate mouse cursor's relative y offset. const float initial_value = *_value; - const float clamped_value = ozz::math::Clamp(_min, initial_value, _max); // Check for hotness. bool hot = false, active = false; @@ -795,24 +826,100 @@ bool ImGuiImpl::DoSlider(const char* _label, float _min, float _max, } // Update widget value. - const float pow_min = powf(_min, _pow); - const float pow_max = powf(_max, _pow); - float pow_value = powf(clamped_value, _pow); + float cursor; + *_value = + SliderControl(initial_value, _min, _max, _pow, + inputs_.mouse_x - static_cast(rect.left), + static_cast(rect.width), _enabled, active, &cursor); + + // Renders slider's rail. + const math::RectFloat rail_rect(rect.left, rect.bottom, rect.width, + rect.height); + FillRect(rail_rect, kSliderRoundRectRadius, background_color); + StrokeRect(rail_rect, kSliderRoundRectRadius, border_color); + + const math::RectFloat cursor_rect( + rect.left + cursor - kWidgetCursorWidth / 2.f, rect.bottom - 1.f, + kWidgetCursorWidth, rect.height + 2.f); + FillRect(cursor_rect, kSliderRoundRectRadius, slider_color); + StrokeRect(cursor_rect, kSliderRoundRectRadius, slider_border_color); + + const math::RectFloat text_rect( + rail_rect.left + kSliderRoundRectRadius, rail_rect.bottom, + rail_rect.width - kSliderRoundRectRadius * 2.f, rail_rect.height); + Print(_label, text_rect, kMiddle, text_color); + + // Returns true if the value has changed or if it was clamped in _min / _max + // bounds. + return initial_value != *_value; +} + +bool ImGuiImpl::DoSlider2D(const char* _label, ozz::array _min, + ozz::array _max, + ozz::array* _value, bool _enabled) { + math::RectFloat rect; + if (!AddWidget(-1.f, &rect)) { + return false; + } + + auto_gen_id_++; + + // Calculate mouse cursor's relative y offset. + const ozz::array initial_value = *_value; + + // Check for hotness. + bool hot = false, active = false; if (_enabled) { + // Includes the cursor size in the pick region. + math::RectFloat pick_rect = rect; + pick_rect.left -= kWidgetHeight / 2.f; + pick_rect.width += kWidgetHeight; + pick_rect.bottom -= kWidgetHeight / 2.f; + pick_rect.height += kWidgetHeight; + ButtonLogic(pick_rect, auto_gen_id_, &hot, &active); + + // A slider is active on lmb pressed, not released. It's different to the + // usual button behavior. + active &= inputs_.lmb_pressed; + } + + // Render the scrollbar + const GLubyte* background_color = kSliderBackgroundColor; + const GLubyte* border_color = kWidgetBorderColor; + const GLubyte* slider_color = kSliderCursorColor; + const GLubyte* slider_border_color = kWidgetBorderColor; + const GLubyte* text_color = kWidgetTextColor; + + if (!_enabled) { + background_color = kWidgetDisabledBackgroundColor; + border_color = kWidgetDisabledBorderColor; + slider_color = kSliderDisabledCursorColor; + slider_border_color = kWidgetDisabledBorderColor; + text_color = kWidgetDisabledTextColor; + } else if (hot) { if (active) { - int mousepos = inputs_.mouse_x - static_cast(rect.left); - if (mousepos < 0) { - mousepos = 0; - } - if (mousepos > rect.width) { - mousepos = static_cast(rect.width); - } - pow_value = (mousepos * (pow_max - pow_min)) / rect.width + pow_min; - *_value = ozz::math::Clamp(_min, powf(pow_value, 1.f / _pow), _max); + // Button is both 'hot' and 'active'. + slider_color = kWidgetActiveBackgroundColor; + slider_border_color = kWidgetActiveBorderColor; } else { - // Clamping is only applied if the widget is enabled. - *_value = clamped_value; + // Button is merely 'hot'. + slider_color = kSliderCursorHotColor; + slider_border_color = kWidgetHotBorderColor; } + } else { + // button is not hot, but it may be active. Use default colors. + } + + // Update widget value. + ozz::array cursor; + const int mouse[2] = {inputs_.mouse_x - static_cast(rect.left), + inputs_.mouse_y - static_cast(rect.bottom)}; + const int mouse_max[2] = {static_cast(rect.width), + static_cast(rect.height)}; + for (size_t i = 0; i < 2; ++i) { + _value->at(i) = + SliderControl(initial_value[i], _min[i], _max[i], 1.f, mouse[i], + mouse_max[i], _enabled, active, &cursor[i]); } // Renders slider's rail. @@ -822,14 +929,24 @@ bool ImGuiImpl::DoSlider(const char* _label, float _min, float _max, StrokeRect(rail_rect, kSliderRoundRectRadius, border_color); // Finds cursor position and rect. - const float cursor = - floorf((rect.width * (pow_value - pow_min)) / (pow_max - pow_min)); const math::RectFloat cursor_rect( - rect.left + cursor - kWidgetCursorWidth / 2.f, rect.bottom - 1.f, - kWidgetCursorWidth, rect.height + 2.f); + rect.left + cursor[0] - kWidgetHeight / 2.f, + rect.bottom + cursor[1] - kWidgetHeight / 2.f, kWidgetHeight, + kWidgetHeight); + + // Cursor cross + const math::RectFloat cross_hrect(rect.left, rect.bottom + cursor[1], + rect.width, 1); + StrokeRect(cross_hrect, 0.f, slider_color); + const math::RectFloat cross_vrect(rect.left + cursor[0], rect.bottom, 1, + rect.height); + StrokeRect(cross_vrect, 0.f, slider_color); + + // Draw slider FillRect(cursor_rect, kSliderRoundRectRadius, slider_color); StrokeRect(cursor_rect, kSliderRoundRectRadius, slider_border_color); + // Text const math::RectFloat text_rect( rail_rect.left + kSliderRoundRectRadius, rail_rect.bottom, rail_rect.width - kSliderRoundRectRadius * 2.f, rail_rect.height); @@ -1361,7 +1478,9 @@ float ImGuiImpl::Print(const char* _text, const math::RectFloat& _rect, ly = _rect.bottom + (line_count - 1) * (font_.glyph_height + interlign); break; } - default: { break; } + default: { + break; + } } GL(BindTexture(GL_TEXTURE_2D, glyph_texture_)); @@ -1385,7 +1504,9 @@ float ImGuiImpl::Print(const char* _text, const math::RectFloat& _rect, lx = _rect.right() - (line_char_count * font_.glyph_width); break; } - default: { break; } + default: { + break; + } } // Loops through all characters of the current line, and renders them using diff --git a/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.h b/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.h index b306188..8223024 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.h +++ b/3rdparty/ozz-animation/samples/framework/internal/imgui_impl.h @@ -36,10 +36,8 @@ // See imgui.h for details about function specifications. #include "framework/imgui.h" - #include "ozz/base/containers/vector.h" #include "ozz/base/maths/rect.h" - #include "renderer_impl.h" namespace ozz { @@ -90,6 +88,10 @@ class ImGuiImpl : public ImGui { virtual bool DoSlider(const char* _label, float _min, float _max, float* _value, float _pow, bool _enabled); + virtual bool DoSlider2D(const char* _label, ozz::array _min, + ozz::array _max, + ozz::array* _value, bool _enabled); + virtual bool DoSlider(const char* _label, int _min, int _max, int* _value, float _pow, bool _enabled); diff --git a/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.cc b/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.cc index 3749aa3..4235008 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.cc +++ b/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.cc @@ -132,6 +132,12 @@ bool RendererImpl::Initialize() { } } + // Instantiate instanced ambient rendering shader. + points_shader = PointsShader::Build(); + if (!points_shader) { + return false; + } + return true; } @@ -239,7 +245,7 @@ bool RendererImpl::DrawGrid(int _cell_count, float _cell_size) { return true; } -// Computes the model space bind pose and renders it. +// Computes the model space rest pose and renders it. bool RendererImpl::DrawSkeleton(const ozz::animation::Skeleton& _skeleton, const ozz::math::Float4x4& _transform, bool _draw_joints) { @@ -253,9 +259,9 @@ bool RendererImpl::DrawSkeleton(const ozz::animation::Skeleton& _skeleton, // Reallocate matrix array if necessary. prealloc_models_.resize(num_joints); - // Compute model space bind pose. + // Compute model space rest pose. ozz::animation::LocalToModelJob job; - job.input = _skeleton.joint_bind_poses(); + job.input = _skeleton.joint_rest_poses(); job.output = make_span(prealloc_models_); job.skeleton = &_skeleton; if (!job.Run()) { @@ -460,10 +466,7 @@ int DrawPosture_FillUniforms(const ozz::animation::Skeleton& _skeleton, // Copy parent joint's raw matrix, to render a bone between the parent // and current matrix. float* uniform = _uniforms + instances * 16; - math::StorePtr(parent.cols[0], uniform + 0); - math::StorePtr(parent.cols[1], uniform + 4); - math::StorePtr(parent.cols[2], uniform + 8); - math::StorePtr(parent.cols[3], uniform + 12); + std::memcpy(uniform, parent.cols, 16 * sizeof(float)); // Set bone direction (bone_dir). The shader expects to find it at index // [3,7,11] of the matrix. @@ -483,11 +486,7 @@ int DrawPosture_FillUniforms(const ozz::animation::Skeleton& _skeleton, // Only the joint is rendered for leaves, the bone model isn't. if (IsLeaf(_skeleton, i)) { // Copy current joint's raw matrix. - uniform = _uniforms + instances * 16; - math::StorePtr(current.cols[0], uniform + 0); - math::StorePtr(current.cols[1], uniform + 4); - math::StorePtr(current.cols[2], uniform + 8); - math::StorePtr(current.cols[3], uniform + 12); + std::memcpy(uniform, current.cols, 16 * sizeof(float)); // Re-use bone_dir to fix the size of the leaf (same as previous bone). // The shader expects to find it at index [3,7,11] of the matrix. @@ -621,6 +620,84 @@ bool RendererImpl::DrawPosture(const ozz::animation::Skeleton& _skeleton, return true; } +bool RendererImpl::DrawPoints(const ozz::span& _positions, + const ozz::span& _sizes, + const ozz::span& _colors, + const ozz::math::Float4x4& _transform, + bool _round, bool _screen_space) { + // Early out if no instance to render. + if (_positions.size() == 0) { + return true; + } + + // Sizes and colors must be of size 1 or equal to _positions' size. + if (_sizes.size() != 1 && _sizes.size() != _positions.size() / 3) { + return false; + } + if (_colors.size() != 1 && _colors.size() != _positions.size() / 3) { + return false; + } + + const GLsizei positions_size = static_cast(_positions.size_bytes()); + const GLsizei colors_size = + static_cast(_colors.size() == 1 ? 0 : _colors.size_bytes()); + const GLsizei sizes_size = + static_cast(_sizes.size() == 1 ? 0 : _sizes.size_bytes()); + const GLsizei buffer_size = positions_size + colors_size + sizes_size; + const GLsizei positions_offset = 0; + const GLsizei colors_offset = positions_offset + positions_size; + const GLsizei sizes_offset = colors_offset + colors_size; + + // Reallocate vertex buffer. + GL(BindBuffer(GL_ARRAY_BUFFER, dynamic_array_bo_)); + GL(BufferData(GL_ARRAY_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW)); + + GL(BufferSubData(GL_ARRAY_BUFFER, positions_offset, positions_size, + _positions.data())); + GL(BufferSubData(GL_ARRAY_BUFFER, colors_offset, colors_size, + _colors.data())); + GL(BufferSubData(GL_ARRAY_BUFFER, sizes_offset, sizes_size, _sizes.data())); + + // Square or round sprites. Beware msaa makes sprites round if GL_POINT_SPRITE + // isn't enabled + if (_round) { + GL(Enable(GL_POINT_SMOOTH)); + GL(Disable(GL_POINT_SPRITE)); + } else { + GL(Disable(GL_POINT_SMOOTH)); + GL(Enable(GL_POINT_SPRITE)); + } + + // Size is managed in vertex shader side. + GL(Enable(GL_PROGRAM_POINT_SIZE)); + + const PointsShader::GenericAttrib attrib = + points_shader->Bind(_transform, camera()->view_proj(), 12, + positions_offset, colors_size ? 4 : 0, colors_offset, + sizes_size ? 4 : 0, sizes_offset, _screen_space); + + GL(BindBuffer(GL_ARRAY_BUFFER, 0)); + + // Apply remaining general attributes + if (_colors.size() <= 1) { + const Color color = _colors.empty() ? kWhite : _colors[0]; + GL(VertexAttrib4f(attrib.color, color.r / 255.f, color.g / 255.f, + color.b / 255.f, color.a / 255.f)); + } + if (_sizes.size() <= 1) { + const float size = _sizes.empty() ? 1.f : _sizes[0]; + GL(VertexAttrib1f(attrib.size, size)); + } + + // Draws the mesh. + GL(DrawArrays(GL_POINTS, 0, static_cast(_positions.size() / 3))); + + // Unbinds. + points_shader->Unbind(); + + return true; +} + bool RendererImpl::DrawBoxIm(const ozz::math::Box& _box, const ozz::math::Float4x4& _transform, const Color _colors[2]) { @@ -1218,49 +1295,70 @@ bool RendererImpl::DrawMesh(const Mesh& _mesh, vertex_offset += part_vertex_count; } - // Binds shader with this array buffer, depending on rendering options. - Shader* shader = nullptr; - if (_options.texture) { - ambient_textured_shader->Bind(_transform, camera()->view_proj(), - positions_stride, positions_offset, - normals_stride, normals_offset, colors_stride, - colors_offset, uvs_stride, uvs_offset); - shader = ambient_textured_shader.get(); + if (_options.triangles) { + // Binds shader with this array buffer, depending on rendering options. + Shader* shader = nullptr; + if (_options.texture) { + ambient_textured_shader->Bind( + _transform, camera()->view_proj(), positions_stride, positions_offset, + normals_stride, normals_offset, colors_stride, colors_offset, + uvs_stride, uvs_offset); + shader = ambient_textured_shader.get(); - // Binds default texture - GL(BindTexture(GL_TEXTURE_2D, checkered_texture_)); - } else { - ambient_shader->Bind(_transform, camera()->view_proj(), positions_stride, - positions_offset, normals_stride, normals_offset, - colors_stride, colors_offset); - shader = ambient_shader.get(); + // Binds default texture + GL(BindTexture(GL_TEXTURE_2D, checkered_texture_)); + } else { + ambient_shader->Bind(_transform, camera()->view_proj(), positions_stride, + positions_offset, normals_stride, normals_offset, + colors_stride, colors_offset); + shader = ambient_shader.get(); + } + + // Maps the index dynamic buffer and update it. + GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, dynamic_index_bo_)); + const Mesh::TriangleIndices& indices = _mesh.triangle_indices; + GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, + indices.size() * sizeof(Mesh::TriangleIndices::value_type), + array_begin(indices), GL_STREAM_DRAW)); + + // Draws the mesh. + static_assert(sizeof(Mesh::TriangleIndices::value_type) == 2, + "Expects 2 bytes indices."); + GL(DrawElements(GL_TRIANGLES, static_cast(indices.size()), + GL_UNSIGNED_SHORT, 0)); + + // Unbinds. + GL(BindBuffer(GL_ARRAY_BUFFER, 0)); + GL(BindTexture(GL_TEXTURE_2D, 0)); + GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + shader->Unbind(); } - // Maps the index dynamic buffer and update it. - GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, dynamic_index_bo_)); - const Mesh::TriangleIndices& indices = _mesh.triangle_indices; - GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, - indices.size() * sizeof(Mesh::TriangleIndices::value_type), - array_begin(indices), GL_STREAM_DRAW)); - - // Draws the mesh. - static_assert(sizeof(Mesh::TriangleIndices::value_type) == 2, - "Expects 2 bytes indices."); - GL(DrawElements(GL_TRIANGLES, static_cast(indices.size()), - GL_UNSIGNED_SHORT, 0)); - - // Unbinds. - GL(BindBuffer(GL_ARRAY_BUFFER, 0)); - GL(BindTexture(GL_TEXTURE_2D, 0)); - GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - shader->Unbind(); - if (_options.wireframe) { #ifndef EMSCRIPTEN GL(PolygonMode(GL_FRONT_AND_BACK, GL_FILL)); #endif // EMSCRIPTEN } + // Renders debug vertices. + if (_options.vertices) { + for (size_t i = 0; i < _mesh.parts.size(); ++i) { + const Mesh::Part& part = _mesh.parts[i]; + ozz::sample::Color color = ozz::sample::kWhite; + span colors; + if (_options.colors && part.colors.size() == part.positions.size() / 3) { + colors = { + reinterpret_cast(part.colors.data()), + part.positions.size() / 3}; + } else { + colors = {&color, 1}; + } + const float size = 2.f; + DrawPoints({part.positions.data(), part.positions.size()}, {&size, 1}, + {&color, 1}, _transform, true, true); + } + } + // Renders debug normals. if (_options.normals) { for (size_t i = 0; i < _mesh.parts.size(); ++i) { @@ -1313,7 +1411,7 @@ bool RendererImpl::DrawSkinnedMesh( const Mesh& _mesh, const span _skinning_matrices, const ozz::math::Float4x4& _transform, const Options& _options) { // Forward to DrawMesh function is skinning is disabled. - if (_options.skip_skinning) { + if (_options.skip_skinning || !_mesh.skinned()) { return DrawMesh(_mesh, _transform, _options); } @@ -1327,13 +1425,16 @@ bool RendererImpl::DrawSkinnedMesh( // Positions and normals are interleaved to improve caching while executing // skinning job. + const GLsizei positions_offset = 0; - const GLsizei normals_offset = sizeof(float) * 3; - const GLsizei tangents_offset = sizeof(float) * 6; - const GLsizei positions_stride = sizeof(float) * 9; - const GLsizei normals_stride = positions_stride; - const GLsizei tangents_stride = positions_stride; - const GLsizei skinned_data_size = vertex_count * positions_stride; + const GLsizei positions_stride = sizeof(float) * 3; + const GLsizei normals_offset = vertex_count * positions_stride; + const GLsizei normals_stride = sizeof(float) * 3; + const GLsizei tangents_offset = + normals_offset + vertex_count * normals_stride; + const GLsizei tangents_stride = sizeof(float) * 3; + const GLsizei skinned_data_size = + tangents_offset + vertex_count * tangents_stride; // Colors and uvs are contiguous. They aren't transformed, so they can be // directly copied from source mesh which is non-interleaved as-well. @@ -1542,54 +1643,76 @@ bool RendererImpl::DrawSkinnedMesh( processed_vertex_count += part_vertex_count; } - // Updates dynamic vertex buffer with skinned data. - GL(BindBuffer(GL_ARRAY_BUFFER, dynamic_array_bo_)); - GL(BufferData(GL_ARRAY_BUFFER, vbo_size, nullptr, GL_STREAM_DRAW)); - GL(BufferSubData(GL_ARRAY_BUFFER, 0, vbo_size, vbo_map)); + if (_options.triangles) { + // Updates dynamic vertex buffer with skinned data. + GL(BindBuffer(GL_ARRAY_BUFFER, dynamic_array_bo_)); + GL(BufferData(GL_ARRAY_BUFFER, vbo_size, nullptr, GL_STREAM_DRAW)); + GL(BufferSubData(GL_ARRAY_BUFFER, 0, vbo_size, vbo_map)); - // Binds shader with this array buffer, depending on rendering options. - Shader* shader = nullptr; - if (_options.texture) { - ambient_textured_shader->Bind(_transform, camera()->view_proj(), - positions_stride, positions_offset, - normals_stride, normals_offset, colors_stride, - colors_offset, uvs_stride, uvs_offset); - shader = ambient_textured_shader.get(); + // Binds shader with this array buffer, depending on rendering options. + Shader* shader = nullptr; + if (_options.texture) { + ambient_textured_shader->Bind( + _transform, camera()->view_proj(), positions_stride, positions_offset, + normals_stride, normals_offset, colors_stride, colors_offset, + uvs_stride, uvs_offset); + shader = ambient_textured_shader.get(); - // Binds default texture - GL(BindTexture(GL_TEXTURE_2D, checkered_texture_)); - } else { - ambient_shader->Bind(_transform, camera()->view_proj(), positions_stride, - positions_offset, normals_stride, normals_offset, - colors_stride, colors_offset); - shader = ambient_shader.get(); + // Binds default texture + GL(BindTexture(GL_TEXTURE_2D, checkered_texture_)); + } else { + ambient_shader->Bind(_transform, camera()->view_proj(), positions_stride, + positions_offset, normals_stride, normals_offset, + colors_stride, colors_offset); + shader = ambient_shader.get(); + } + + // Maps the index dynamic buffer and update it. + GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, dynamic_index_bo_)); + const Mesh::TriangleIndices& indices = _mesh.triangle_indices; + GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, + indices.size() * sizeof(Mesh::TriangleIndices::value_type), + array_begin(indices), GL_STREAM_DRAW)); + + // Draws the mesh. + static_assert(sizeof(Mesh::TriangleIndices::value_type) == 2, + "Expects 2 bytes indices."); + GL(DrawElements(GL_TRIANGLES, static_cast(indices.size()), + GL_UNSIGNED_SHORT, 0)); + + // Unbinds. + GL(BindBuffer(GL_ARRAY_BUFFER, 0)); + GL(BindTexture(GL_TEXTURE_2D, 0)); + GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + shader->Unbind(); } - // Maps the index dynamic buffer and update it. - GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, dynamic_index_bo_)); - const Mesh::TriangleIndices& indices = _mesh.triangle_indices; - GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, - indices.size() * sizeof(Mesh::TriangleIndices::value_type), - array_begin(indices), GL_STREAM_DRAW)); - - // Draws the mesh. - static_assert(sizeof(Mesh::TriangleIndices::value_type) == 2, - "Expects 2 bytes indices."); - GL(DrawElements(GL_TRIANGLES, static_cast(indices.size()), - GL_UNSIGNED_SHORT, 0)); - - // Unbinds. - GL(BindBuffer(GL_ARRAY_BUFFER, 0)); - GL(BindTexture(GL_TEXTURE_2D, 0)); - GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - shader->Unbind(); - if (_options.wireframe) { #ifndef EMSCRIPTEN GL(PolygonMode(GL_FRONT_AND_BACK, GL_FILL)); #endif // EMSCRIPTEN } + // Renders debug vertices. + if (_options.vertices) { + ozz::sample::Color color = ozz::sample::kWhite; + span colors; + if (_options.colors) { + colors = {reinterpret_cast( + ozz::PointerStride(vbo_map, colors_offset)), + static_cast(vertex_count)}; + } else { + colors = {&color, 1}; + } + + const span vertices{ + reinterpret_cast( + ozz::PointerStride(vbo_map, positions_offset)), + static_cast(vertex_count * 3)}; + const float size = 2.f; + DrawPoints(vertices, {&size, 1}, colors, _transform, true, true); + } + return true; } diff --git a/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.h b/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.h index 668fdde..dce6880 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.h +++ b/3rdparty/ozz-animation/samples/framework/internal/renderer_impl.h @@ -59,7 +59,6 @@ // Include features as extentions #include "GL/glext.h" - #include "framework/renderer.h" #include "ozz/base/containers/vector.h" #include "ozz/base/memory/unique_ptr.h" @@ -91,6 +90,7 @@ namespace sample { namespace internal { class Camera; class Shader; +class PointsShader; class SkeletonShader; class AmbientShader; class AmbientTexturedShader; @@ -119,6 +119,12 @@ class RendererImpl : public Renderer { const ozz::math::Float4x4& _transform, bool _draw_joints); + virtual bool DrawPoints( + const ozz::span& _positions, + const ozz::span& _sizes, + const ozz::span& _colors, + const ozz::math::Float4x4& _transform, bool _round, bool _screen_space); + virtual bool DrawBoxIm(const ozz::math::Box& _box, const ozz::math::Float4x4& _transform, const Color _colors[2]); @@ -241,6 +247,7 @@ class RendererImpl : public Renderer { ozz::unique_ptr ambient_shader; ozz::unique_ptr ambient_textured_shader; ozz::unique_ptr ambient_shader_instanced; + ozz::unique_ptr points_shader; // Checkered texture unsigned int checkered_texture_; diff --git a/3rdparty/ozz-animation/samples/framework/internal/shader.cc b/3rdparty/ozz-animation/samples/framework/internal/shader.cc index ce84c2e..8908598 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/shader.cc +++ b/3rdparty/ozz-animation/samples/framework/internal/shader.cc @@ -326,6 +326,91 @@ void ImmediatePTCShader::Bind(const math::Float4x4& _model, GL(Uniform1i(texture, 0)); } +ozz::unique_ptr PointsShader::Build() { + bool success = true; + + const char* kSimplePointsVS = + "uniform mat4 u_mvp;\n" + "attribute vec3 a_position;\n" + "attribute vec4 a_color;\n" + "attribute float a_size;\n" + "attribute float a_screen_space;\n" + "varying vec4 v_vertex_color;\n" + "void main() {\n" + " vec4 vertex = vec4(a_position.xyz, 1.);\n" + " gl_Position = u_mvp * vertex;\n" + " gl_PointSize = a_screen_space == 0. ? a_size / gl_Position.w : a_size;\n" + " v_vertex_color = a_color;\n" + "}\n"; + const char* kSimplePointsPS = + "varying vec4 v_vertex_color;\n" + "void main() {\n" + " gl_FragColor = v_vertex_color;\n" + "}\n"; + + const char* vs[] = {kPlatformSpecivicVSHeader, kSimplePointsVS}; + const char* fs[] = {kPlatformSpecivicFSHeader, kSimplePointsPS}; + + ozz::unique_ptr shader = make_unique(); + success &= + shader->BuildFromSource(OZZ_ARRAY_SIZE(vs), vs, OZZ_ARRAY_SIZE(fs), fs); + + // Binds default attributes + success &= shader->FindAttrib("a_position"); + success &= shader->FindAttrib("a_color"); + success &= shader->FindAttrib("a_size"); + success &= shader->FindAttrib("a_screen_space"); + + // Binds default uniforms + success &= shader->BindUniform("u_mvp"); + + if (!success) { + shader.reset(); + } + + return shader; +} + +PointsShader::GenericAttrib PointsShader::Bind( + const math::Float4x4& _model, const math::Float4x4& _view_proj, + GLsizei _pos_stride, GLsizei _pos_offset, GLsizei _color_stride, + GLsizei _color_offset, GLsizei _size_stride, GLsizei _size_offset, + bool _screen_space) { + GL(UseProgram(program())); + + const GLint position_attrib = attrib(0); + GL(EnableVertexAttribArray(position_attrib)); + GL(VertexAttribPointer(position_attrib, 3, GL_FLOAT, GL_FALSE, _pos_stride, + GL_PTR_OFFSET(_pos_offset))); + + const GLint color_attrib = attrib(1); + if (_color_stride) { + GL(EnableVertexAttribArray(color_attrib)); + GL(VertexAttribPointer(color_attrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, + _color_stride, GL_PTR_OFFSET(_color_offset))); + } + const GLint size_attrib = attrib(2); + if (_size_stride) { + GL(EnableVertexAttribArray(size_attrib)); + GL(VertexAttribPointer(size_attrib, 1, GL_FLOAT, GL_TRUE, _size_stride, + GL_PTR_OFFSET(_size_offset))); + } + const GLint screen_space_attrib = attrib(3); + GL(VertexAttrib1f(screen_space_attrib, 1.f * _screen_space)); + + // Binds mvp uniform + const GLint mvp_uniform = uniform(0); + const ozz::math::Float4x4 mvp = _view_proj * _model; + float values[16]; + math::StorePtrU(mvp.cols[0], values + 0); + math::StorePtrU(mvp.cols[1], values + 4); + math::StorePtrU(mvp.cols[2], values + 8); + math::StorePtrU(mvp.cols[3], values + 12); + GL(UniformMatrix4fv(mvp_uniform, 1, false, values)); + + return {_color_stride ? -1 : color_attrib, _size_stride ? -1 : size_attrib}; +} + namespace { const char* kPassUv = "attribute vec2 a_uv;\n" diff --git a/3rdparty/ozz-animation/samples/framework/internal/shader.h b/3rdparty/ozz-animation/samples/framework/internal/shader.h index 4abf113..7be3e22 100644 --- a/3rdparty/ozz-animation/samples/framework/internal/shader.h +++ b/3rdparty/ozz-animation/samples/framework/internal/shader.h @@ -126,6 +126,29 @@ class ImmediatePTCShader : public Shader { GLsizei _tex_offset, GLsizei _color_stride, GLsizei _color_offset); }; +class PointsShader : public Shader { + public: + PointsShader() {} + virtual ~PointsShader() {} + + // Constructs the shader. + // Returns nullptr if shader compilation failed or a valid Shader pointer on + // success. The shader must then be deleted using default allocator Delete + // function. + static ozz::unique_ptr Build(); + + // Binds the shader. + struct GenericAttrib { + GLint color; + GLint size; + }; + GenericAttrib Bind(const math::Float4x4& _model, + const math::Float4x4& _view_proj, GLsizei _pos_stride, + GLsizei _pos_offset, GLsizei _color_stride, + GLsizei _color_offset, GLsizei _size_stride, + GLsizei _size_offset, bool _screen_space); +}; + class SkeletonShader : public Shader { public: SkeletonShader() {} diff --git a/3rdparty/ozz-animation/samples/framework/mesh.h b/3rdparty/ozz-animation/samples/framework/mesh.h index d62539e..b95dda1 100644 --- a/3rdparty/ozz-animation/samples/framework/mesh.h +++ b/3rdparty/ozz-animation/samples/framework/mesh.h @@ -69,12 +69,7 @@ struct Mesh { // Test if the mesh has skinning informations. bool skinned() const { - for (size_t i = 0; i < parts.size(); ++i) { - if (parts[i].influences_count() != 0) { - return true; - } - } - return false; + return !inverse_bind_poses.empty(); } // Returns the number of joints used to skin the mesh. diff --git a/3rdparty/ozz-animation/samples/framework/renderer.h b/3rdparty/ozz-animation/samples/framework/renderer.h index b4a1925..7417d9a 100644 --- a/3rdparty/ozz-animation/samples/framework/renderer.h +++ b/3rdparty/ozz-animation/samples/framework/renderer.h @@ -79,7 +79,7 @@ class Renderer { // has a size of _cell_size. virtual bool DrawGrid(int _cell_count, float _cell_size) = 0; - // Renders a skeleton in its bind pose posture. + // Renders a skeleton in its rest pose posture. virtual bool DrawSkeleton(const animation::Skeleton& _skeleton, const ozz::math::Float4x4& _transform, bool _draw_joints = true) = 0; @@ -93,6 +93,17 @@ class Renderer { const ozz::math::Float4x4& _transform, bool _draw_joints = true) = 0; + // Renders points. + // _sizes and _colors must be either of ize 1 or equal to _positions' size. + // If _screen_space is true, then points size is fixed in screen-space, + // otherwise it changes with screen depth. + virtual bool DrawPoints( + const ozz::span& _positions, + const ozz::span& _sizes, + const ozz::span& _colors, + const ozz::math::Float4x4& _transform, bool _round = true, + bool _screen_space = false) = 0; + // Renders a box at a specified location. // The 2 slots of _colors array respectively defines color of the filled // faces and color of the box outlines. @@ -116,16 +127,20 @@ class Renderer { Color _color) = 0; struct Options { + bool triangles; // Show triangles mesh. bool texture; // Show texture (default checkered texture). + bool vertices; // Show vertices as points. bool normals; // Show normals. bool tangents; // Show tangents. bool binormals; // Show binormals, computed from the normal and tangent. bool colors; // Show vertex colors. - bool wireframe; // Show vertex colors. + bool wireframe; // Show vertex colors. bool skip_skinning; // Show texture (default checkered texture). Options() - : texture(false), + : triangles(true), + texture(false), + vertices(false), normals(false), tangents(false), binormals(false), @@ -133,9 +148,12 @@ class Renderer { wireframe(false), skip_skinning(false) {} - Options(bool _texture, bool _normals, bool _tangents, bool _binormals, - bool _colors, bool _wireframe, bool _skip_skinning) - : texture(_texture), + Options(bool _triangles, bool _texture, bool _vertices, bool _normals, + bool _tangents, bool _binormals, bool _colors, bool _wireframe, + bool _skip_skinning) + : triangles(_triangles), + texture(_texture), + vertices(_vertices), normals(_normals), tangents(_tangents), binormals(_binormals), diff --git a/3rdparty/ozz-animation/samples/framework/tools/CMakeLists.txt b/3rdparty/ozz-animation/samples/framework/tools/CMakeLists.txt index 21e7309..10d5880 100644 --- a/3rdparty/ozz-animation/samples/framework/tools/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/framework/tools/CMakeLists.txt @@ -1,7 +1,7 @@ # Adds fbx2mesh utility target. if(ozz_build_fbx) - # share meshes with thte sample framework + # share meshes with the sample framework add_executable(sample_fbx2mesh fbx2mesh.cc ${PROJECT_SOURCE_DIR}/samples/framework/mesh.cc @@ -9,6 +9,7 @@ if(ozz_build_fbx) target_link_libraries(sample_fbx2mesh ozz_animation_fbx ozz_options) + target_copy_shared_libraries(sample_fbx2mesh) set_target_properties(sample_fbx2mesh PROPERTIES FOLDER "samples/tools") diff --git a/3rdparty/ozz-animation/samples/framework/tools/fbx2mesh.cc b/3rdparty/ozz-animation/samples/framework/tools/fbx2mesh.cc index 4765a11..2b0907c 100644 --- a/3rdparty/ozz-animation/samples/framework/tools/fbx2mesh.cc +++ b/3rdparty/ozz-animation/samples/framework/tools/fbx2mesh.cc @@ -25,12 +25,12 @@ // // //----------------------------------------------------------------------------// +#include +#include + #include "framework/mesh.h" - #include "ozz/animation/offline/fbx/fbx.h" - #include "ozz/animation/runtime/skeleton.h" - #include "ozz/base/containers/map.h" #include "ozz/base/containers/vector.h" #include "ozz/base/io/archive.h" @@ -39,14 +39,8 @@ #include "ozz/base/maths/math_ex.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/memory/allocator.h" - #include "ozz/options/options.h" -#include -#include - -#include "fbxsdk/utils/fbxgeometryconverter.h" - // Declares command line options. OZZ_OPTIONS_DECLARE_STRING(file, "Specifies input file.", "", true) OZZ_OPTIONS_DECLARE_STRING(skeleton, @@ -504,19 +498,18 @@ bool BuildSkin(FbxMesh* _fbx_mesh, const int* ctrl_point_indices = cluster->GetControlPointIndices(); const double* ctrl_point_weights = cluster->GetControlPointWeights(); for (int cpi = 0; cpi < ctrl_point_index_count; ++cpi) { - const SkinMapping mapping = {joint, - static_cast(ctrl_point_weights[cpi])}; - if (mapping.weight <= 0.f) { - continue; - } - - const int ctrl_point = ctrl_point_indices[cpi]; - assert(ctrl_point < static_cast(_remap.size())); + // It happens that weight is 0. In this case give the vertex a very small + // weight so normalization succeeds. + const float ctrl_point_weight = + static_cast(ctrl_point_weights[cpi]); + const SkinMapping mapping = { + joint, ctrl_point_weight == 0.f ? 1e-9f : ctrl_point_weight}; // remap.size() can be 0, skinned control point might not be used by any // polygon of the mesh. Sometimes, the mesh can have less points than at // the time of the skinning because a smooth operator was active when // skinning but has been deactivated during export. + const int ctrl_point = ctrl_point_indices[cpi]; const ControlPointRemap& remap = _remap[ctrl_point]; for (size_t v = 0; v < remap.size(); ++v) { vertex_skin_mappings[remap[v]].push_back(mapping); @@ -560,6 +553,11 @@ bool BuildSkin(FbxMesh* _fbx_mesh, // Stores joint's indices and weights. size_t influence_count = inv.size(); + if (influence_count == 0) { + vertex_skin_mappings[i].push_back({0,1.f}); + influence_count = 1; + } + if (influence_count > 0) { size_t j = 0; for (; j < influence_count; ++j) { @@ -579,11 +577,12 @@ bool BuildSkin(FbxMesh* _fbx_mesh, } if (vertex_isnt_influenced) { - ozz::log::Err() << "At least one vertex isn't influenced by any joints." - << std::endl; + ozz::log::LogV() << "At least one vertex isn't influenced by any joints. " + "It's been reassigned to root joint." + << std::endl; } - return !vertex_isnt_influenced; + return true; } // Limits the number of joints influencing a vertex. diff --git a/3rdparty/ozz-animation/samples/framework/utils.cc b/3rdparty/ozz-animation/samples/framework/utils.cc index 3d42d0b..af2c787 100644 --- a/3rdparty/ozz-animation/samples/framework/utils.cc +++ b/3rdparty/ozz-animation/samples/framework/utils.cc @@ -30,28 +30,22 @@ #include #include -#include "ozz/base/maths/box.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/simd_quaternion.h" -#include "ozz/base/maths/soa_transform.h" - -#include "ozz/base/memory/allocator.h" - +#include "framework/imgui.h" +#include "framework/mesh.h" +#include "ozz/animation/offline/raw_skeleton.h" #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/animation/runtime/track.h" - -#include "ozz/animation/offline/raw_skeleton.h" - -#include "ozz/geometry/runtime/skinning_job.h" - #include "ozz/base/io/archive.h" #include "ozz/base/io/stream.h" #include "ozz/base/log.h" - -#include "framework/imgui.h" -#include "framework/mesh.h" +#include "ozz/base/maths/box.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/simd_quaternion.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/memory/allocator.h" +#include "ozz/geometry/runtime/skinning_job.h" namespace ozz { namespace sample { @@ -224,9 +218,9 @@ void ComputeSkeletonBounds(const animation::Skeleton& _skeleton, // Allocate matrix array, out of memory is handled by the LocalToModelJob. ozz::vector models(num_joints); - // Compute model space bind pose. + // Compute model space rest pose. ozz::animation::LocalToModelJob job; - job.input = _skeleton.joint_bind_poses(); + job.input = _skeleton.joint_rest_poses(); job.output = make_span(models); job.skeleton = &_skeleton; if (job.Run()) { diff --git a/3rdparty/ozz-animation/samples/look_at/CMakeLists.txt b/3rdparty/ozz-animation/samples/look_at/CMakeLists.txt index 6f78c59..22e3486 100644 --- a/3rdparty/ozz-animation/samples/look_at/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/look_at/CMakeLists.txt @@ -25,6 +25,7 @@ add_executable(sample_look_at "${CMAKE_CURRENT_BINARY_DIR}/media/mesh.ozz") target_link_libraries(sample_look_at sample_framework) + target_copy_shared_libraries(sample_look_at) set_target_properties(sample_look_at PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/look_at/sample_look_at.cc b/3rdparty/ozz-animation/samples/look_at/sample_look_at.cc index 27987c7..4867534 100644 --- a/3rdparty/ozz-animation/samples/look_at/sample_look_at.cc +++ b/3rdparty/ozz-animation/samples/look_at/sample_look_at.cc @@ -25,27 +25,23 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/animation.h" -#include "ozz/animation/runtime/ik_aim_job.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/sampling_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#include "ozz/base/log.h" - -#include "ozz/base/maths/box.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/simd_quaternion.h" -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/maths/vec_float.h" - -#include "ozz/options/options.h" - #include "framework/application.h" #include "framework/imgui.h" #include "framework/mesh.h" #include "framework/renderer.h" #include "framework/utils.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/animation/runtime/ik_aim_job.h" +#include "ozz/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/log.h" +#include "ozz/base/maths/box.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/simd_quaternion.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/maths/vec_float.h" +#include "ozz/options/options.h" // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, @@ -106,7 +102,7 @@ class LookAtSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -339,8 +335,8 @@ class LookAtSampleApplication : public ozz::sample::Application { const int num_joints = skeleton_.num_joints(); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Reading animation. if (!ozz::sample::LoadAnimation(OPTIONS_animation, &animation_)) { @@ -472,8 +468,8 @@ class LookAtSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; @@ -482,7 +478,7 @@ class LookAtSampleApplication : public ozz::sample::Application { ozz::vector models_; // Buffer of skinning matrices, result of the joint multiplication of the - // inverse bind pose with the model-space matrix. + // inverse rest pose with the model-space matrix. ozz::vector skinning_matrices_; // The mesh used by the sample. diff --git a/3rdparty/ozz-animation/samples/millipede/CMakeLists.txt b/3rdparty/ozz-animation/samples/millipede/CMakeLists.txt index 50f67b9..bda2a01 100644 --- a/3rdparty/ozz-animation/samples/millipede/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/millipede/CMakeLists.txt @@ -7,10 +7,10 @@ add_custom_command( add_executable(sample_millipede sample_millipede.cc ${CMAKE_CURRENT_BINARY_DIR}/README.md) - target_link_libraries(sample_millipede ozz_animation_offline sample_framework) +target_copy_shared_libraries(sample_millipede) set_target_properties(sample_millipede PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/millipede/README.md b/3rdparty/ozz-animation/samples/millipede/README.md index 74a7f04..954d786 100644 --- a/3rdparty/ozz-animation/samples/millipede/README.md +++ b/3rdparty/ozz-animation/samples/millipede/README.md @@ -24,5 +24,5 @@ Some other playback parameters can be tuned: 2. Convert the RawSkeleton (aka offline) object to a runtime ozz::animation::offline::Skeleton, using ozz::animation::offline::SkeletonBuilder. This offline utility does the conversion to the runtime format, which can then be serialized or used by the runtime API. 2. Create the animation object: 1. Instantiates a ozz::animation::offline::RawAnimation object and fills it with keyframes for every joint of the skeleton, simulating walk cycles. The RawAnimation is an offline suitable format, meaning it is easily programmatically modified: Add/remove keys, add/remove tracks, change duration... - 2. Convert the offline animation to a runtime format, using ozz::animation::offline::AnimationBuilder. This utility takes as input a RawAnimation and outputs a runtime ozz::animation::Animation. The runtime format is the one used for sampling. In opposition with the offline one, it cannot be edited/modified. It is optimized for runtime usage in term of memory layout (cache coherence for sampling) and footprint (compression scheme). + 2. Convert the offline animation to a runtime format, using ozz::animation::offline::AnimationBuilder. This utility takes as input a RawAnimation and outputs a runtime ozz::animation::Animation. The runtime format is the one used for sampling. In opposition with the offline one, it cannot be edited/modified. It is optimized for runtime usage in term of memory layout (context coherence for sampling) and footprint (compression scheme). 3. The remaining code of the sample is to allocate runtime buffers and samples animation every frame. See playback sample for more details. diff --git a/3rdparty/ozz-animation/samples/millipede/sample_millipede.cc b/3rdparty/ozz-animation/samples/millipede/sample_millipede.cc index b626b46..d1f6123 100644 --- a/3rdparty/ozz-animation/samples/millipede/sample_millipede.cc +++ b/3rdparty/ozz-animation/samples/millipede/sample_millipede.cc @@ -30,25 +30,22 @@ #include #include -#include "ozz/animation/runtime/animation.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/sampling_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#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/base/maths/quaternion.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/maths/vec_float.h" - #include "framework/application.h" #include "framework/imgui.h" #include "framework/renderer.h" #include "framework/utils.h" +#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/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/maths/quaternion.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/maths/vec_float.h" using ozz::animation::offline::RawAnimation; using ozz::animation::offline::RawSkeleton; @@ -126,7 +123,7 @@ class MillipedeSampleApplication : public ozz::sample::Application { // Samples animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = animation_.get(); - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -208,8 +205,8 @@ class MillipedeSampleApplication : public ozz::sample::Application { locals_.resize(num_soa_joints); models_.resize(num_joints); - // Allocates a cache that matches new animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches new animation requirements. + context_.Resize(num_joints); return true; } @@ -423,8 +420,8 @@ class MillipedeSampleApplication : public ozz::sample::Application { // The millipede procedural walk animation. ozz::unique_ptr animation_; - // Sampling cache, as used by SamplingJob. - ozz::animation::SamplingCache cache_; + // Sampling context, as used by SamplingJob. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. // These are shared between sampling output and local-to-model input. diff --git a/3rdparty/ozz-animation/samples/multithread/CMakeLists.txt b/3rdparty/ozz-animation/samples/multithread/CMakeLists.txt index 8ff1d99..ee6eb8b 100644 --- a/3rdparty/ozz-animation/samples/multithread/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/multithread/CMakeLists.txt @@ -28,10 +28,10 @@ add_executable(sample_multithread "${CMAKE_CURRENT_BINARY_DIR}/README.md" "${CMAKE_CURRENT_BINARY_DIR}/media/skeleton.ozz" "${CMAKE_CURRENT_BINARY_DIR}/media/animation.ozz") - target_link_libraries(sample_multithread sample_framework ${CMAKE_THREAD_LIBS_INIT}) +target_copy_shared_libraries(sample_multithread) set_target_properties(sample_multithread PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/multithread/README.md b/3rdparty/ozz-animation/samples/multithread/README.md index 9bd7706..85f1303 100644 --- a/3rdparty/ozz-animation/samples/multithread/README.md +++ b/3rdparty/ozz-animation/samples/multithread/README.md @@ -20,5 +20,5 @@ The number of characters can also be set from the GUI. ## Implementation 1. This sample extends "playback" sample, and uses the same procedure to load skeleton and animation objects. -2. For each character, allocates runtime buffers (local-space transforms of type ozz::math::SoaTransform, model-space matrices of type ozz::math::Float4x4) with the number of elements required for the skeleton, and a sampling cache (ozz::animation::SamplingCache). Only the skeleton and the animation are shared amongst all characters, as they are read only objects, not modified during jobs execution. +2. For each character, allocates runtime buffers (local-space transforms of type ozz::math::SoaTransform, model-space matrices of type ozz::math::Float4x4) with the number of elements required for the skeleton, and a sampling context (ozz::animation::SamplingJob::Context). Only the skeleton and the animation are shared amongst all characters, as they are read only objects, not modified during jobs execution. 3. Update function uses a parallel-for loop to split up characters' update loop amongst std::async tasks (sampling and local-to-model jobs execution), allowing all characters' update to be executed in concurrent batches. \ No newline at end of file diff --git a/3rdparty/ozz-animation/samples/multithread/sample_multithread.cc b/3rdparty/ozz-animation/samples/multithread/sample_multithread.cc index 87fd8d8..d59d174 100644 --- a/3rdparty/ozz-animation/samples/multithread/sample_multithread.cc +++ b/3rdparty/ozz-animation/samples/multithread/sample_multithread.cc @@ -30,28 +30,23 @@ #include #include +#include "framework/application.h" +#include "framework/imgui.h" +#include "framework/renderer.h" +#include "framework/utils.h" #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" - -#include "ozz/base/log.h" - #include "ozz/base/containers/vector.h" - +#include "ozz/base/log.h" #include "ozz/base/maths/box.h" #include "ozz/base/maths/math_ex.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" - #include "ozz/options/options.h" -#include "framework/application.h" -#include "framework/imgui.h" -#include "framework/renderer.h" -#include "framework/utils.h" - #if EMSCRIPTEN #include #include @@ -118,7 +113,7 @@ class MultithreadSampleApplication : public ozz::sample::Application { // Setup sampling job. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &_animation; - sampling_job.cache = &_character->cache; + sampling_job.context = &_character->context; sampling_job.ratio = _character->controller.time_ratio(); sampling_job.output = make_span(_character->locals); @@ -150,7 +145,8 @@ class MultithreadSampleApplication : public ozz::sample::Application { // Data used to monitor and analyze threading. // Every task will push its thread id to an array. We can then process it to // find how many threads were used. - struct ParallelMonitor { + class ParallelMonitor { + public: ParallelMonitor() { // Finds the maximum possible number of tasks considering kMinGrain grain // size for kMaxCharacters characters. @@ -159,19 +155,39 @@ class MultithreadSampleApplication : public ozz::sample::Application { processed *= 2, max_tasks *= 2) { } thread_ids_.resize(max_tasks); - num_async_tasks.store(0); + num_async_tasks_.store(0); } - ozz::vector thread_ids_; - std::atomic_uint num_async_tasks; + + void Reset() { num_async_tasks_.store(0); } + + // Stores this thread identifier to a new task slot. + void PushTask() { + thread_ids_[num_async_tasks_++] = hasher_(std::this_thread::get_id()); + } + + // Finds number of threads, which is the number of unique thread ids + // found. + int ThreadCount() { + std::sort(thread_ids_.begin(), thread_ids_.begin() + num_async_tasks_); + auto end = std::unique(thread_ids_.begin(), + thread_ids_.begin() + num_async_tasks_); + + return static_cast(end - thread_ids_.begin()); + } + + int TaskCount() const { return num_async_tasks_; } + + private: + std::hash hasher_; + ozz::vector thread_ids_; + std::atomic_uint num_async_tasks_; }; static bool ParallelUpdate(const ParallelArgs& _args, Character* _characters, int _num, ParallelMonitor* _monitor) { bool success = true; if (_num <= _args.grain_size) { - // Stores this thread identifier to a new task slot. - _monitor->thread_ids_[_monitor->num_async_tasks++] = - std::this_thread::get_id(); + _monitor->PushTask(); for (int i = 0; i < _num; ++i) { success &= UpdateCharacter(*_args.animation, *_args.skeleton, _args.dt, @@ -197,7 +213,7 @@ class MultithreadSampleApplication : public ozz::sample::Application { bool success = true; if (enable_theading_) { // Initialize task counter. It's only used to monitor threading behavior. - monitor_.num_async_tasks.store(0); + monitor_.Reset(); const ParallelArgs args = {&animation_, &skeleton_, _dt, grain_size_}; success = ParallelUpdate(args, array_begin(characters_), num_characters_, @@ -256,7 +272,7 @@ class MultithreadSampleApplication : public ozz::sample::Application { character.locals.resize(skeleton_.num_soa_joints()); character.models.resize(skeleton_.num_joints()); - character.cache.Resize(animation_.num_tracks()); + character.context.Resize(animation_.num_tracks()); } return true; @@ -290,18 +306,9 @@ class MultithreadSampleApplication : public ozz::sample::Application { std::sprintf(label, "Grain size: %d", grain_size_); _im_gui->DoSlider(label, kMinGrainSize, kMaxCharacters, &grain_size_, .2f); - - // Finds number of threads, which is the number of unique thread ids - // found. - std::sort(monitor_.thread_ids_.begin(), - monitor_.thread_ids_.begin() + monitor_.num_async_tasks); - auto end = std::unique( - monitor_.thread_ids_.begin(), - monitor_.thread_ids_.begin() + monitor_.num_async_tasks); - const int num_threads = - static_cast(end - monitor_.thread_ids_.begin()); + const int num_threads = monitor_.ThreadCount(); std::sprintf(label, "Thread/task count: %d/%d", num_threads, - monitor_.num_async_tasks.load()); + monitor_.TaskCount()); _im_gui->DoLabel(label); } } @@ -334,8 +341,8 @@ class MultithreadSampleApplication : public ozz::sample::Application { // controlling animation playback time. ozz::sample::PlaybackController controller; - // Sampling cache. - ozz::animation::SamplingCache cache; + // Sampling context. + ozz::animation::SamplingJob::Context context; // Buffer of local transforms which stores the blending result. ozz::vector locals; diff --git a/3rdparty/ozz-animation/samples/optimize/CMakeLists.txt b/3rdparty/ozz-animation/samples/optimize/CMakeLists.txt index 0f46c6b..a0e48e3 100644 --- a/3rdparty/ozz-animation/samples/optimize/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/optimize/CMakeLists.txt @@ -17,10 +17,10 @@ add_executable(sample_optimize "${CMAKE_CURRENT_BINARY_DIR}/README.md" "${CMAKE_CURRENT_BINARY_DIR}/media/skeleton.ozz" "${CMAKE_CURRENT_BINARY_DIR}/media/animation_raw.ozz") - target_link_libraries(sample_optimize ozz_animation_offline sample_framework) +target_copy_shared_libraries(sample_optimize) set_target_properties(sample_optimize PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/optimize/README.md b/3rdparty/ozz-animation/samples/optimize/README.md index dfc6c9a..3a229f0 100644 --- a/3rdparty/ozz-animation/samples/optimize/README.md +++ b/3rdparty/ozz-animation/samples/optimize/README.md @@ -29,7 +29,7 @@ Some other parameters can be tuned from sample UI to affect animation playback. 1. Import the runtime skeleton and the unoptimized raw animation objects. These are imported from files as described in the "how to load an object from a file" section. Note that the animation is still in an offline format at this stage. 2. Optimizes animation by removing interpolable keyframes using `ozz::animation::offline::AnimationOptimizer` utility. It processes the source raw animation and outputs a new one. Optimization tolerance values like translation (meter), rotation (radian) and scale (percentage) are exposed to sample UI. -3. Convert the offline animation to the runtime format, using `ozz::animation::offline::AnimationBuilder`. This utility takes as input the optimized RawAnimation and outputs the runtime `ozz::animation::Animation`. The runtime format is the one used for sampling. In opposition with the offline one, it cannot be edited/modified. It is optimized for runtime usage in term of memory layout (cache coherence for sampling) and footprint (compression scheme). +3. Convert the offline animation to the runtime format, using `ozz::animation::offline::AnimationBuilder`. This utility takes as input the optimized RawAnimation and outputs the runtime `ozz::animation::Animation`. The runtime format is the one used for sampling. In opposition with the offline one, it cannot be edited/modified. It is optimized for runtime usage in term of memory layout (context coherence for sampling) and footprint (compression scheme). 4. Local-space transformations (in SoA format as required by the runtime pipeline) are computed from the runtime and the source raw animations according the selected rendering mode: - "Raw animation": Every track of the source raw animation is traversed in order to extract each relevant keyframes. Keyframes are interpolated to match the exact expected time. This implementation isn't part of the API but done by the sample, as raw animations aren't intended to be used this way in runtime. Even though it works, performance are quite low compared with sampling a runtime animation. On the other end the result is the closest to the input file, kind of lossless. - "Run time" (default): Samples optimized runtime animation as usual. diff --git a/3rdparty/ozz-animation/samples/optimize/sample_optimize.cc b/3rdparty/ozz-animation/samples/optimize/sample_optimize.cc index d21df5d..2bbd9b6 100644 --- a/3rdparty/ozz-animation/samples/optimize/sample_optimize.cc +++ b/3rdparty/ozz-animation/samples/optimize/sample_optimize.cc @@ -25,36 +25,30 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/animation.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/sampling_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#include "ozz/animation/offline/animation_builder.h" -#include "ozz/animation/offline/animation_optimizer.h" -#include "ozz/animation/offline/raw_animation.h" -#include "ozz/animation/offline/raw_animation_utils.h" - -#include "ozz/base/memory/unique_ptr.h" - -#include "ozz/base/io/archive.h" -#include "ozz/base/io/stream.h" -#include "ozz/base/log.h" - -#include "ozz/base/maths/math_ex.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/maths/vec_float.h" - -#include "ozz/options/options.h" +#include #include "framework/application.h" #include "framework/imgui.h" #include "framework/profile.h" #include "framework/renderer.h" #include "framework/utils.h" - -#include +#include "ozz/animation/offline/animation_builder.h" +#include "ozz/animation/offline/animation_optimizer.h" +#include "ozz/animation/offline/raw_animation.h" +#include "ozz/animation/offline/raw_animation_utils.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/io/archive.h" +#include "ozz/base/io/stream.h" +#include "ozz/base/log.h" +#include "ozz/base/maths/math_ex.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/maths/vec_float.h" +#include "ozz/base/memory/unique_ptr.h" +#include "ozz/options/options.h" // Skeleton and animation file can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, "Path to the runtime skeleton file.", @@ -111,7 +105,7 @@ class OptimizeSampleApplication : public ozz::sample::Application { // Prepares sampling job. ozz::animation::SamplingJob sampling_job; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); // Samples optimized animation (_according to the display mode). @@ -129,20 +123,20 @@ class OptimizeSampleApplication : public ozz::sample::Application { } // Computes difference between the optimized and non-optimized animations - // in local space, and rebinds it to the bind pose. + // in local space, and rebinds it to the rest pose. { - const ozz::span& bind_poses = - skeleton_.joint_bind_poses(); - const ozz::math::SoaTransform* bind_pose = bind_poses.begin(); + const ozz::span& rest_poses = + skeleton_.joint_rest_poses(); + const ozz::math::SoaTransform* rest_pose = rest_poses.begin(); const ozz::math::SoaTransform* locals_raw = locals_raw_.data(); const ozz::math::SoaTransform* locals_rt = locals_rt_.data(); ozz::math::SoaTransform* locals_diff = locals_diff_.data(); - for (; bind_pose < bind_poses.end(); - ++locals_raw, ++locals_rt, ++locals_diff, ++bind_pose) { + for (; rest_pose < rest_poses.end(); + ++locals_raw, ++locals_rt, ++locals_diff, ++rest_pose) { assert(locals_raw < array_end(locals_raw_) && locals_rt < array_end(locals_rt_) && locals_diff < array_end(locals_diff_) && - bind_pose < bind_poses.end()); + rest_pose < rest_poses.end()); // Computes difference. const ozz::math::SoaTransform diff = { @@ -150,10 +144,10 @@ class OptimizeSampleApplication : public ozz::sample::Application { locals_rt->rotation * Conjugate(locals_raw->rotation), locals_rt->scale / locals_raw->scale}; - // Rebinds to the bind pose in the diff buffer. - locals_diff->translation = bind_pose->translation + diff.translation; - locals_diff->rotation = bind_pose->rotation * diff.rotation; - locals_diff->scale = bind_pose->scale * diff.scale; + // Rebinds to the rest pose in the diff buffer. + locals_diff->translation = rest_pose->translation + diff.translation; + locals_diff->rotation = rest_pose->rotation * diff.rotation; + locals_diff->scale = rest_pose->scale * diff.scale; } } @@ -320,8 +314,8 @@ class OptimizeSampleApplication : public ozz::sample::Application { locals_diff_.resize(num_soa_joints); models_diff_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); return true; } @@ -374,11 +368,11 @@ class OptimizeSampleApplication : public ozz::sample::Application { .5f, joint_setting_enable_ && optimize_); if (rebuild) { - // Invalidates the cache in case the new animation has the same + // Invalidates the context in case the new animation has the same // address as the previous one. Other cases (like changing animation) - // are automatic handled by the cache. See SamplingCache::Invalidate - // for more details. - cache_.Invalidate(); + // are automatic handled by the context. See + // SamplingJob::Context::Invalidate for more details. + context_.Invalidate(); // Rebuilds a new runtime animation. if (!BuildAnimations()) { @@ -540,9 +534,9 @@ class OptimizeSampleApplication : public ozz::sample::Application { // Runtime skeleton. ozz::animation::Skeleton skeleton_; - // Sampling cache, shared across optimized and non-optimized animations. This - // is not optimal, but it's not an issue either. - ozz::animation::SamplingCache cache_; + // Sampling context, shared across optimized and non-optimized animations. + // This is not optimal, but it's not an issue either. + ozz::animation::SamplingJob::Context context_; // Runtime optimized animation. ozz::unique_ptr animation_rt_; diff --git a/3rdparty/ozz-animation/samples/partial_blend/CMakeLists.txt b/3rdparty/ozz-animation/samples/partial_blend/CMakeLists.txt index c09a658..af54656 100644 --- a/3rdparty/ozz-animation/samples/partial_blend/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/partial_blend/CMakeLists.txt @@ -23,6 +23,7 @@ add_executable(sample_partial_blend "${CMAKE_CURRENT_BINARY_DIR}/media/animation_partial.ozz") target_link_libraries(sample_partial_blend sample_framework) +target_copy_shared_libraries(sample_partial_blend) set_target_properties(sample_partial_blend PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/partial_blend/README.md b/3rdparty/ozz-animation/samples/partial_blend/README.md index fd44fd5..a02b79c 100644 --- a/3rdparty/ozz-animation/samples/partial_blend/README.md +++ b/3rdparty/ozz-animation/samples/partial_blend/README.md @@ -24,6 +24,6 @@ The GUI also proposes to select the "root" joint of the upper body hierarchy, wh 4. Uses ozz::animation::IterateJointsDF helper function to iterate all children of the upper body root joint, and set up per-joint weight masks as follows (note that weight coefficients are stored as SoA floats): - Upper body weight mask: Affects upper body weight coefficient to all the joints that are part of the upper body, all others are set to zero. - Lower body weight mask: Affects lower body weight coefficient to all the joints that are part of the lower body (ie: all the ones that are not part of the upper body), all others are set to one. -5. Sets ozz::animation::BlendingJob object with the two layers for the lower and upper body. Per-joint weight masks are provided as an input to each layer. All other arguments (bind-pose, input local-space transforms, weights, output) are the same as those used by the full skeleton hierarchy blending. See "blend" sample for more details. +5. Sets ozz::animation::BlendingJob object with the two layers for the lower and upper body. Per-joint weight masks are provided as an input to each layer. All other arguments (rest-pose, input local-space transforms, weights, output) are the same as those used by the full skeleton hierarchy blending. See "blend" sample for more details. 6. Converts local-space transformations, outputted from the blending stage, to model-space matrices using ozz::animation::LocalToModelJob. It also takes as input the skeleton (to know about joint's hierarchy). Output is model-space matrices array. 7. Model-space matrices array can then be used for rendering (to skin a mesh) or updating the scene graph. \ No newline at end of file diff --git a/3rdparty/ozz-animation/samples/partial_blend/sample_partial_blend.cc b/3rdparty/ozz-animation/samples/partial_blend/sample_partial_blend.cc index df912d1..03adbe2 100644 --- a/3rdparty/ozz-animation/samples/partial_blend/sample_partial_blend.cc +++ b/3rdparty/ozz-animation/samples/partial_blend/sample_partial_blend.cc @@ -25,30 +25,25 @@ // // //----------------------------------------------------------------------------// +#include + +#include "framework/application.h" +#include "framework/imgui.h" +#include "framework/renderer.h" +#include "framework/utils.h" #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/blending_job.h" #include "ozz/animation/runtime/local_to_model_job.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/animation/runtime/skeleton_utils.h" - -#include "ozz/base/log.h" - #include "ozz/base/containers/vector.h" - +#include "ozz/base/log.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/maths/vec_float.h" - #include "ozz/options/options.h" -#include "framework/application.h" -#include "framework/imgui.h" -#include "framework/renderer.h" -#include "framework/utils.h" - -#include - // Skeleton archive can be specified as an option. OZZ_OPTIONS_DECLARE_STRING(skeleton, "Path to the skeleton (ozz archive format).", @@ -86,7 +81,7 @@ class PartialBlendSampleApplication : public ozz::sample::Application { // Setup sampling job. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &sampler.animation; - sampling_job.cache = &sampler.cache; + sampling_job.context = &sampler.context; sampling_job.ratio = sampler.controller.time_ratio(); sampling_job.output = make_span(sampler.locals); @@ -115,7 +110,7 @@ class PartialBlendSampleApplication : public ozz::sample::Application { ozz::animation::BlendingJob blend_job; blend_job.threshold = threshold_; blend_job.layers = layers; - blend_job.bind_pose = skeleton_.joint_bind_poses(); + blend_job.rest_pose = skeleton_.joint_rest_poses(); blend_job.output = make_span(blended_locals_); // Blends. @@ -171,8 +166,8 @@ class PartialBlendSampleApplication : public ozz::sample::Application { // this is a Soa structure. sampler.joint_weights.resize(num_soa_joints); - // Allocates a cache that matches animation requirements. - sampler.cache.Resize(num_joints); + // Allocates a context that matches animation requirements. + sampler.context.Resize(num_joints); } // Default weight settings. @@ -191,11 +186,9 @@ class PartialBlendSampleApplication : public ozz::sample::Application { models_.resize(num_joints); // Finds the "Spine1" joint in the joint hierarchy. - for (int i = 0; i < num_joints; ++i) { - if (std::strstr(skeleton_.joint_names()[i], "Spine1")) { - upper_body_root_ = i; - break; - } + upper_body_root_ = FindJoint(skeleton_, "Spine1"); + if (upper_body_root_ < 0) { + return false; } SetupPerJointWeights(); @@ -373,8 +366,8 @@ class PartialBlendSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation; - // Sampling cache. - ozz::animation::SamplingCache cache; + // Sampling context. + ozz::animation::SamplingJob::Context context; // Buffer of local transforms as sampled from animation_. ozz::vector locals; @@ -388,7 +381,7 @@ class PartialBlendSampleApplication : public ozz::sample::Application { // Index of the joint at the base of the upper body hierarchy. int upper_body_root_; - // Blending job bind pose threshold. + // Blending job rest pose threshold. float threshold_; // Buffer of local transforms which stores the blending result. diff --git a/3rdparty/ozz-animation/samples/playback/CMakeLists.txt b/3rdparty/ozz-animation/samples/playback/CMakeLists.txt index d3bdf30..a78a72a 100644 --- a/3rdparty/ozz-animation/samples/playback/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/playback/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable(sample_playback "${CMAKE_CURRENT_BINARY_DIR}/media/animation.ozz") target_link_libraries(sample_playback sample_framework) +target_copy_shared_libraries(sample_playback) set_target_properties(sample_playback PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/playback/README.md b/3rdparty/ozz-animation/samples/playback/README.md index e390a20..3a6bac7 100644 --- a/3rdparty/ozz-animation/samples/playback/README.md +++ b/3rdparty/ozz-animation/samples/playback/README.md @@ -23,7 +23,7 @@ Some parameters can be tuned from sample UI: 2. Check that the stream stores the expected object using ozz::io::OArchive::TestTag() function. Object type is specified as a template argument. 3. De-serialize the object with >> operator. 2. Allocates runtime buffers (local-space transforms of type ozz::math::SoaTransform, model-space matrices of type ozz::math::Float4x4) with the number of elements required for the skeleton. Note that local-space transform are Soa objects, meaning that 1 ozz::math::SoaTransform can store multiple (4) joints. -3. Allocates sampling cache (ozz::animation::SamplingCache) with the number of joints required for the animation. This cache is used to store sampling local data as well as optimizing key-frame lookup while reading animation forward. -4. Sample animation to get local-space transformations using ozz::animation::SamplingJob. This job takes as input the animation, the cache and a time at which the animation should be sampled. Output is the local-space transformation array. +3. Allocates sampling context (ozz::animation::SamplingJob::Context) with the number of joints required for the animation. This context is used to store sampling local data as well as optimizing key-frame lookup while reading animation forward. +4. Sample animation to get local-space transformations using ozz::animation::SamplingJob. This job takes as input the animation, the context and a time at which the animation should be sampled. Output is the local-space transformation array. 5. Convert local-space transformations to model-space matrices using ozz::animation::LocalToModelJob. It takes as input the skeleton (to know about joint's hierarchy) and local-space transforms. Output is model-space matrices array. 6. Model-space matrices array can then be used for rendering (to skin a mesh) or updating the scene graph. \ No newline at end of file diff --git a/3rdparty/ozz-animation/samples/playback/sample_playback.cc b/3rdparty/ozz-animation/samples/playback/sample_playback.cc index 3cc2701..f5242f5 100644 --- a/3rdparty/ozz-animation/samples/playback/sample_playback.cc +++ b/3rdparty/ozz-animation/samples/playback/sample_playback.cc @@ -62,7 +62,7 @@ class PlaybackSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -109,8 +109,8 @@ class PlaybackSampleApplication : public ozz::sample::Application { const int num_joints = skeleton_.num_joints(); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); return true; } @@ -144,8 +144,8 @@ class PlaybackSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; diff --git a/3rdparty/ozz-animation/samples/skinning/CMakeLists.txt b/3rdparty/ozz-animation/samples/skinning/CMakeLists.txt index 3384705..a6477cb 100644 --- a/3rdparty/ozz-animation/samples/skinning/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/skinning/CMakeLists.txt @@ -25,6 +25,7 @@ add_executable(sample_skinning "${CMAKE_CURRENT_BINARY_DIR}/media/animation.ozz") target_link_libraries(sample_skinning sample_framework) +target_copy_shared_libraries(sample_skinning) set_target_properties(sample_skinning PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/skinning/sample_skinning.cc b/3rdparty/ozz-animation/samples/skinning/sample_skinning.cc index ecdee51..355c13c 100644 --- a/3rdparty/ozz-animation/samples/skinning/sample_skinning.cc +++ b/3rdparty/ozz-animation/samples/skinning/sample_skinning.cc @@ -68,7 +68,7 @@ class SkinningSampleApplication : public ozz::sample::Application { // Samples optimized animation at t = animation_time_. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = controller_.time_ratio(); sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -90,17 +90,18 @@ class SkinningSampleApplication : public ozz::sample::Application { // Samples animation, transforms to model space and renders. virtual bool OnDisplay(ozz::sample::Renderer* _renderer) { bool success = true; + const ozz::math::Float4x4 transform = ozz::math::Float4x4::identity(); if (draw_skeleton_) { - success &= _renderer->DrawPosture(skeleton_, make_span(models_), - ozz::math::Float4x4::identity()); + success &= + _renderer->DrawPosture(skeleton_, make_span(models_), transform); } if (draw_mesh_) { // Builds skinning matrices, based on the output of the animation stage. - // The mesh might not use (aka be skinned by) all skeleton joints. We use - // the joint remapping table (available from the mesh object) to reorder - // model-space matrices and build skinning ones. + // The mesh might not use (aka be skinned by) all skeleton joints. We + // use the joint remapping table (available from the mesh object) to + // reorder model-space matrices and build skinning ones. for (const ozz::sample::Mesh& mesh : meshes_) { for (size_t i = 0; i < mesh.joint_remaps.size(); ++i) { skinning_matrices_[i] = @@ -109,8 +110,7 @@ class SkinningSampleApplication : public ozz::sample::Application { // Renders skin. success &= _renderer->DrawSkinnedMesh( - mesh, make_span(skinning_matrices_), - ozz::math::Float4x4::identity(), render_options_); + mesh, make_span(skinning_matrices_), transform, render_options_); } } return success; @@ -141,8 +141,8 @@ class SkinningSampleApplication : public ozz::sample::Application { const int num_joints = skeleton_.num_joints(); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Reading skinned meshes. if (!ozz::sample::LoadMeshes(OPTIONS_mesh, &meshes_)) { @@ -152,8 +152,8 @@ class SkinningSampleApplication : public ozz::sample::Application { // Computes the number of skinning matrices required to skin all meshes. // A mesh is skinned by only a subset of joints, so the number of skinning // matrices might be less that the number of skeleton joints. - // Mesh::joint_remaps is used to know how to order skinning matrices. So the - // number of matrices required is the size of joint_remaps. + // Mesh::joint_remaps is used to know how to order skinning matrices. So + // the number of matrices required is the size of joint_remaps. size_t num_skinning_matrices = 0; for (const ozz::sample::Mesh& mesh : meshes_) { num_skinning_matrices = @@ -224,19 +224,26 @@ class SkinningSampleApplication : public ozz::sample::Application { // Expose mesh rendering options { // Rendering options. - static bool oc_open = false; - ozz::sample::ImGui::OpenClose oc(_im_gui, "Rendering options", &oc_open); - if (oc_open) { + static bool ocd_open = true; + ozz::sample::ImGui::OpenClose ocd(_im_gui, "Display options", &ocd_open); + if (ocd_open) { _im_gui->DoCheckBox("Draw skeleton", &draw_skeleton_); _im_gui->DoCheckBox("Draw mesh", &draw_mesh_); - _im_gui->DoCheckBox("Show texture", &render_options_.texture); - _im_gui->DoCheckBox("Show normals", &render_options_.normals); - _im_gui->DoCheckBox("Show tangents", &render_options_.tangents); - _im_gui->DoCheckBox("Show binormals", &render_options_.binormals); - _im_gui->DoCheckBox("Show colors", &render_options_.colors); - _im_gui->DoCheckBox("Wireframe", &render_options_.wireframe); - _im_gui->DoCheckBox("Skip skinning", &render_options_.skip_skinning); + static bool ocr_open = false; + ozz::sample::ImGui::OpenClose ocr(_im_gui, "Rendering options", + &ocr_open); + if (ocr_open) { + _im_gui->DoCheckBox("Show triangles", &render_options_.triangles); + _im_gui->DoCheckBox("Show texture", &render_options_.texture); + _im_gui->DoCheckBox("Show vertices", &render_options_.vertices); + _im_gui->DoCheckBox("Show normals", &render_options_.normals); + _im_gui->DoCheckBox("Show tangents", &render_options_.tangents); + _im_gui->DoCheckBox("Show binormals", &render_options_.binormals); + _im_gui->DoCheckBox("Show colors", &render_options_.colors); + _im_gui->DoCheckBox("Wireframe", &render_options_.wireframe); + _im_gui->DoCheckBox("Skip skinning", &render_options_.skip_skinning); + } } } return true; @@ -257,8 +264,8 @@ class SkinningSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; diff --git a/3rdparty/ozz-animation/samples/two_bone_ik/CMakeLists.txt b/3rdparty/ozz-animation/samples/two_bone_ik/CMakeLists.txt index b131551..3337961 100644 --- a/3rdparty/ozz-animation/samples/two_bone_ik/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/two_bone_ik/CMakeLists.txt @@ -17,6 +17,7 @@ target_link_libraries(sample_two_bone_ik sample_framework ozz_animation_offline ozz_animation) +target_copy_shared_libraries(sample_two_bone_ik) set_target_properties(sample_two_bone_ik PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/two_bone_ik/README.md b/3rdparty/ozz-animation/samples/two_bone_ik/README.md index f3c1254..71b56b4 100644 --- a/3rdparty/ozz-animation/samples/two_bone_ik/README.md +++ b/3rdparty/ozz-animation/samples/two_bone_ik/README.md @@ -18,7 +18,7 @@ The sample exposes IKTwoBoneJob parameters: - Weight given to the IK correction. This allows to blend / interpolate from zero to full IK. float weight; -Target position is animated by the sample, but can also be tweaked manually, as well as skeleton root transformation. Fix initial transform option select whether ik job is run from the skeleton bind pose or the last frame transforms. This allows to use IK job's weighting parameter, as well as stressing it with a wide range of input. +Target position is animated by the sample, but can also be tweaked manually, as well as skeleton root transformation. Fix initial transform option select whether ik job is run from the skeleton rest pose or the last frame transforms. This allows to use IK job's weighting parameter, as well as stressing it with a wide range of input. ## Implementation diff --git a/3rdparty/ozz-animation/samples/two_bone_ik/sample_two_bone_ik.cc b/3rdparty/ozz-animation/samples/two_bone_ik/sample_two_bone_ik.cc index d113905..f52a9d7 100644 --- a/3rdparty/ozz-animation/samples/two_bone_ik/sample_two_bone_ik.cc +++ b/3rdparty/ozz-animation/samples/two_bone_ik/sample_two_bone_ik.cc @@ -25,412 +25,407 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/ik_two_bone_job.h" -#include "ozz/animation/runtime/local_to_model_job.h" -#include "ozz/animation/runtime/skeleton.h" - -#include "ozz/base/log.h" - -#include "ozz/base/maths/box.h" -#include "ozz/base/maths/simd_math.h" -#include "ozz/base/maths/simd_quaternion.h" -#include "ozz/base/maths/soa_transform.h" - -#include "ozz/base/memory/allocator.h" - -#include "ozz/options/options.h" - -#include "framework/application.h" -#include "framework/imgui.h" -#include "framework/renderer.h" -#include "framework/utils.h" - -#include - -// Skeleton archive can be specified as an option. -OZZ_OPTIONS_DECLARE_STRING(skeleton, - "Path to the skeleton (ozz archive format).", - "media/skeleton.ozz", false) - -class TwoBoneIKSampleApplication : public ozz::sample::Application { - public: - TwoBoneIKSampleApplication() - : start_joint_(-1), - mid_joint_(-1), - end_joint_(-1), - pole_vector(0.f, 1.f, 0.f), - weight_(1.f), - soften_(.97f), - twist_angle_(0.f), - reached_(false), - fix_initial_transform_(true), - two_bone_ik_(true), - show_target_(true), - show_joints_(false), - show_pole_vector_(false), - root_translation_(0.f, 0.f, 0.f), - root_euler_(0.f, 0.f, 0.f), - root_scale_(1.f), - target_extent_(.5f), - target_offset_(0.f, .2f, .1f), - target_(0.f, 0.f, 0.f) {} - - protected: - bool ApplyTwoBoneIK() { - // Target and pole should be in model-space, so they must be converted from - // world-space using character inverse root matrix. - // IK jobs must support non invertible matrices (like 0 scale matrices). - ozz::math::SimdInt4 invertible; - const ozz::math::Float4x4 invert_root = - Invert(GetRootTransform(), &invertible); - - const ozz::math::SimdFloat4 target_ms = TransformPoint( - invert_root, ozz::math::simd_float4::Load3PtrU(&target_.x)); - const ozz::math::SimdFloat4 pole_vector_ms = TransformVector( - invert_root, ozz::math::simd_float4::Load3PtrU(&pole_vector.x)); - - // Setup IK job. - ozz::animation::IKTwoBoneJob ik_job; - ik_job.target = target_ms; - ik_job.pole_vector = pole_vector_ms; - ik_job.mid_axis = ozz::math::simd_float4::z_axis(); // Middle joint - // rotation axis is - // fixed, and depends - // on skeleton rig. - ik_job.weight = weight_; - ik_job.soften = soften_; - ik_job.twist_angle = twist_angle_; - - // Provides start, middle and end joints model space matrices. - ik_job.start_joint = &models_[start_joint_]; - ik_job.mid_joint = &models_[mid_joint_]; - ik_job.end_joint = &models_[end_joint_]; - - // Setup output pointers. - ozz::math::SimdQuaternion start_correction; - ik_job.start_joint_correction = &start_correction; - ozz::math::SimdQuaternion mid_correction; - ik_job.mid_joint_correction = &mid_correction; - ik_job.reached = &reached_; - - if (!ik_job.Run()) { - return false; - } - - // Apply IK quaternions to their respective local-space transforms. - ozz::sample::MultiplySoATransformQuaternion(start_joint_, start_correction, - make_span(locals_)); - ozz::sample::MultiplySoATransformQuaternion(mid_joint_, mid_correction, - make_span(locals_)); - - // Updates model-space matrices now IK has been applied to local transforms. - // All the ancestors of the start of the IK chain must be computed. - ozz::animation::LocalToModelJob ltm_job; - ltm_job.skeleton = &skeleton_; - ltm_job.input = make_span(locals_); - ltm_job.output = make_span(models_); - ltm_job.from = - start_joint_; // Local transforms haven't changed before start_joint_. - ltm_job.to = ozz::animation::Skeleton::kMaxJoints; - - if (!ltm_job.Run()) { - return false; - } - - return true; - } - - virtual bool OnUpdate(float, float _time) { - // Updates sample target position. - if (!MoveTarget(_time)) { - return false; - } - - // Reset locals to skeleton bind pose if option is true. - // This allows to always start IK from a fix position (required to test - // weighting), or do IK from the latest computed pose - if (fix_initial_transform_) { - for (size_t i = 0; i < locals_.size(); ++i) { - locals_[i] = skeleton_.joint_bind_poses()[i]; - } - } - - // Updates model-space matrices from current local-space setup. - // Model-space matrices needs to be updated up to the end joint. Any joint - // after that will need to be recomputed after IK indeed. - ozz::animation::LocalToModelJob ltm_job; - ltm_job.skeleton = &skeleton_; - ltm_job.input = make_span(locals_); - ltm_job.output = make_span(models_); - if (!ltm_job.Run()) { - return false; - } - - // Setup and run IK job. - if (two_bone_ik_ && !ApplyTwoBoneIK()) { - return false; - } - - return true; - } - - virtual bool OnDisplay(ozz::sample::Renderer* _renderer) { - bool success = true; - - // Get skeleton root transform. - const ozz::math::Float4x4 root = GetRootTransform(); - - if (show_target_ && two_bone_ik_) { - // Displays target - const ozz::sample::Color colors[2][2] = { - {ozz::sample::kRed, ozz::sample::kBlack}, - {ozz::sample::kGreen, ozz::sample::kBlack}}; - - const float kBoxHalfSize = .006f; - const ozz::math::Box box(ozz::math::Float3(-kBoxHalfSize), - ozz::math::Float3(kBoxHalfSize)); - success &= _renderer->DrawBoxIm( - box, - ozz::math::Float4x4::Translation( - ozz::math::simd_float4::Load3PtrU(&target_.x)), - colors[reached_]); - } - - // Displays pole vector - if (show_pole_vector_) { - ozz::math::Float3 begin; - ozz::math::Store3PtrU(TransformPoint(root, models_[mid_joint_].cols[3]), - &begin.x); - success &= _renderer->DrawSegment(begin, begin + pole_vector, - ozz::sample::kWhite, - ozz::math::Float4x4::identity()); - } - - // Showing joints - if (show_joints_) { - const float kAxeScale = .1f; - const float kSphereRadius = .009f; - const ozz::math::Float4x4 kAxesScale = ozz::math::Float4x4::Scaling( - ozz::math::simd_float4::Load1(kAxeScale)); - for (size_t i = 0; i < 3; ++i) { - const int joints[3] = {start_joint_, mid_joint_, end_joint_}; - const ozz::math::Float4x4& transform = root * models_[joints[i]]; - success &= _renderer->DrawAxes(transform * kAxesScale); - success &= _renderer->DrawSphereIm(kSphereRadius, transform, - ozz::sample::kWhite); - } - } - - // Draws the animated skeleton posture. - success &= _renderer->DrawPosture(skeleton_, make_span(models_), root); - - return success; - } - - virtual bool OnInitialize() { - // Loads skeleton. - if (!ozz::sample::LoadSkeleton(OPTIONS_skeleton, &skeleton_)) { - return false; - } - - // Allocates runtime buffers. - const int num_soa_joints = skeleton_.num_soa_joints(); - locals_.resize(num_soa_joints); - const int num_joints = skeleton_.num_joints(); - models_.resize(num_joints); - - // Find the 3 joints in skeleton hierarchy. - start_joint_ = mid_joint_ = end_joint_ = -1; - for (int i = 0; i < skeleton_.num_joints(); i++) { - const char* joint_name = skeleton_.joint_names()[i]; - if (std::strcmp(joint_name, "shoulder") == 0) { - start_joint_ = i; - } else if (std::strcmp(joint_name, "forearm") == 0) { - mid_joint_ = i; - } else if (std::strcmp(joint_name, "wrist") == 0) { - end_joint_ = i; - } - } - - // Fails if a joint is missing. - if (start_joint_ < 0 || mid_joint_ < 0 || end_joint_ < 0) { - ozz::log::Err() << "Failed to find required joints." << std::endl; - return false; - } - - // Initialize locals from skeleton bind pose - for (size_t i = 0; i < locals_.size(); ++i) { - locals_[i] = skeleton_.joint_bind_poses()[i]; - } - - return true; - } - - virtual void OnDestroy() {} - - virtual bool OnGui(ozz::sample::ImGui* _im_gui) { - char txt[32]; - - // IK parameters - _im_gui->DoCheckBox("Fix initial transform", &fix_initial_transform_); - _im_gui->DoCheckBox("Enable two bone ik", &two_bone_ik_); - { - static bool opened = true; - ozz::sample::ImGui::OpenClose oc(_im_gui, "IK parameters", &opened); - if (opened) { - sprintf(txt, "Soften: %.2g", soften_); - _im_gui->DoSlider(txt, 0.f, 1.f, &soften_, 2.f); - sprintf(txt, "Twist angle: %.0f", - twist_angle_ * ozz::math::kRadianToDegree); - _im_gui->DoSlider(txt, -ozz::math::kPi, ozz::math::kPi, &twist_angle_); - sprintf(txt, "Weight: %.2g", weight_); - _im_gui->DoSlider(txt, 0.f, 1.f, &weight_); - { - // Pole vector - static bool pole_opened = true; - ozz::sample::ImGui::OpenClose oc_pole(_im_gui, "Pole vector", - &pole_opened); - if (pole_opened) { - sprintf(txt, "x %.2g", pole_vector.x); - _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.x); - sprintf(txt, "y %.2g", pole_vector.y); - _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.y); - sprintf(txt, "z %.2g", pole_vector.z); - _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.z); - } - } - } - } - { // Target position - static bool opened = true; - ozz::sample::ImGui::OpenClose oc(_im_gui, "Target position", &opened); - if (opened) { - _im_gui->DoLabel("Target animation extent"); - sprintf(txt, "%.2g", target_extent_); - _im_gui->DoSlider(txt, 0.f, 1.f, &target_extent_); - - _im_gui->DoLabel("Target Offset"); - const float kOffsetRange = 1.f; - sprintf(txt, "x %.2g", target_offset_.x); - _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.x); - sprintf(txt, "y %.2g", target_offset_.y); - _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.y); - sprintf(txt, "z %.2g", target_offset_.z); - _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.z); - } - } - { // Root - static bool opened = false; - ozz::sample::ImGui::OpenClose oc(_im_gui, "Root transformation", &opened); - if (opened) { - // Translation - _im_gui->DoLabel("Translation"); - sprintf(txt, "x %.2g", root_translation_.x); - _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.x); - sprintf(txt, "y %.2g", root_translation_.y); - _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.y); - sprintf(txt, "z %.2g", root_translation_.z); - _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.z); - - // Rotation (in euler form) - _im_gui->DoLabel("Rotation"); - ozz::math::Float3 euler = root_euler_ * ozz::math::kRadianToDegree; - sprintf(txt, "yaw %.3g", euler.x); - _im_gui->DoSlider(txt, -180.f, 180.f, &euler.x); - sprintf(txt, "pitch %.3g", euler.y); - _im_gui->DoSlider(txt, -180.f, 180.f, &euler.y); - sprintf(txt, "roll %.3g", euler.z); - _im_gui->DoSlider(txt, -180.f, 180.f, &euler.z); - root_euler_ = euler * ozz::math::kDegreeToRadian; - - // Scale (must be uniform and not 0) - _im_gui->DoLabel("Scale"); - sprintf(txt, "%.2g", root_scale_); - _im_gui->DoSlider(txt, -1.f, 1.f, &root_scale_); - } - } - { // Display options - static bool opened = true; - ozz::sample::ImGui::OpenClose oc(_im_gui, "Display options", &opened); - if (opened) { - _im_gui->DoCheckBox("Show target", &show_target_); - _im_gui->DoCheckBox("Show joints", &show_joints_); - _im_gui->DoCheckBox("Show pole vector", &show_pole_vector_); - } - } - - return true; - } - - virtual void GetSceneBounds(ozz::math::Box* _bound) const { - const ozz::math::Float3 radius(target_extent_ * .5f); - _bound->min = target_offset_ - radius; - _bound->max = target_offset_ + radius; - } - - private: - bool MoveTarget(float _time) { - const float anim_extent = (1.f - std::cos(_time)) * .5f * target_extent_; - const int floor = static_cast(std::fabs(_time) / ozz::math::k2Pi); - - target_ = target_offset_; - (&target_.x)[floor % 3] += anim_extent; - return true; - } - - ozz::math::Float4x4 GetRootTransform() const { - return ozz::math::Float4x4::Translation( - ozz::math::simd_float4::Load3PtrU(&root_translation_.x)) * - ozz::math::Float4x4::FromEuler( - ozz::math::simd_float4::Load3PtrU(&root_euler_.x)) * - ozz::math::Float4x4::Scaling( - ozz::math::simd_float4::Load1(root_scale_)); - } - - // Runtime skeleton. - ozz::animation::Skeleton skeleton_; - - // Buffer of local transforms as sampled from animation_. - ozz::vector locals_; - - // Buffer of model space matrices. - ozz::vector models_; - - // Two bone IK setup. Indices of the relevant joints in the chain. - int start_joint_; - int mid_joint_; - int end_joint_; - - // Two bone IK parameters. - ozz::math::Float3 pole_vector; - float weight_; - float soften_; - float twist_angle_; - - // Two bone IK job "reched" output value. - bool reached_; - - // Sample options - bool fix_initial_transform_; - bool two_bone_ik_; - - // Sample display options - bool show_target_; - bool show_joints_; - bool show_pole_vector_; - - // Root transformation. - ozz::math::Float3 root_translation_; - ozz::math::Float3 root_euler_; - float root_scale_; - - // Target positioning and animation. - float target_extent_; - ozz::math::Float3 target_offset_; - ozz::math::Float3 target_; -}; - -int main(int _argc, const char** _argv) { - const char* title = "Ozz-animation sample: Two bone IK"; - return TwoBoneIKSampleApplication().Run(_argc, _argv, "1.0", title); -} +#include + +#include "framework/application.h" +#include "framework/imgui.h" +#include "framework/renderer.h" +#include "framework/utils.h" +#include "ozz/animation/runtime/ik_two_bone_job.h" +#include "ozz/animation/runtime/local_to_model_job.h" +#include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/log.h" +#include "ozz/base/maths/box.h" +#include "ozz/base/maths/simd_math.h" +#include "ozz/base/maths/simd_quaternion.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/memory/allocator.h" +#include "ozz/options/options.h" + +// Skeleton archive can be specified as an option. +OZZ_OPTIONS_DECLARE_STRING(skeleton, + "Path to the skeleton (ozz archive format).", + "media/skeleton.ozz", false) + +class TwoBoneIKSampleApplication : public ozz::sample::Application { + public: + TwoBoneIKSampleApplication() + : start_joint_(-1), + mid_joint_(-1), + end_joint_(-1), + pole_vector(0.f, 1.f, 0.f), + weight_(1.f), + soften_(.97f), + twist_angle_(0.f), + reached_(false), + fix_initial_transform_(true), + two_bone_ik_(true), + show_target_(true), + show_joints_(false), + show_pole_vector_(false), + root_translation_(0.f, 0.f, 0.f), + root_euler_(0.f, 0.f, 0.f), + root_scale_(1.f), + target_extent_(.5f), + target_offset_(0.f, .2f, .1f), + target_(0.f, 0.f, 0.f) {} + + protected: + bool ApplyTwoBoneIK() { + // Target and pole should be in model-space, so they must be converted from + // world-space using character inverse root matrix. + // IK jobs must support non invertible matrices (like 0 scale matrices). + ozz::math::SimdInt4 invertible; + const ozz::math::Float4x4 invert_root = + Invert(GetRootTransform(), &invertible); + + const ozz::math::SimdFloat4 target_ms = TransformPoint( + invert_root, ozz::math::simd_float4::Load3PtrU(&target_.x)); + const ozz::math::SimdFloat4 pole_vector_ms = TransformVector( + invert_root, ozz::math::simd_float4::Load3PtrU(&pole_vector.x)); + + // Setup IK job. + ozz::animation::IKTwoBoneJob ik_job; + ik_job.target = target_ms; + ik_job.pole_vector = pole_vector_ms; + ik_job.mid_axis = ozz::math::simd_float4::z_axis(); // Middle joint + // rotation axis is + // fixed, and depends + // on skeleton rig. + ik_job.weight = weight_; + ik_job.soften = soften_; + ik_job.twist_angle = twist_angle_; + + // Provides start, middle and end joints model space matrices. + ik_job.start_joint = &models_[start_joint_]; + ik_job.mid_joint = &models_[mid_joint_]; + ik_job.end_joint = &models_[end_joint_]; + + // Setup output pointers. + ozz::math::SimdQuaternion start_correction; + ik_job.start_joint_correction = &start_correction; + ozz::math::SimdQuaternion mid_correction; + ik_job.mid_joint_correction = &mid_correction; + ik_job.reached = &reached_; + + if (!ik_job.Run()) { + return false; + } + + // Apply IK quaternions to their respective local-space transforms. + ozz::sample::MultiplySoATransformQuaternion(start_joint_, start_correction, + make_span(locals_)); + ozz::sample::MultiplySoATransformQuaternion(mid_joint_, mid_correction, + make_span(locals_)); + + // Updates model-space matrices now IK has been applied to local transforms. + // All the ancestors of the start of the IK chain must be computed. + ozz::animation::LocalToModelJob ltm_job; + ltm_job.skeleton = &skeleton_; + ltm_job.input = make_span(locals_); + ltm_job.output = make_span(models_); + ltm_job.from = + start_joint_; // Local transforms haven't changed before start_joint_. + ltm_job.to = ozz::animation::Skeleton::kMaxJoints; + + if (!ltm_job.Run()) { + return false; + } + + return true; + } + + virtual bool OnUpdate(float, float _time) { + // Updates sample target position. + if (!MoveTarget(_time)) { + return false; + } + + // Reset locals to skeleton rest pose if option is true. + // This allows to always start IK from a fix position (required to test + // weighting), or do IK from the latest computed pose + if (fix_initial_transform_) { + for (size_t i = 0; i < locals_.size(); ++i) { + locals_[i] = skeleton_.joint_rest_poses()[i]; + } + } + + // Updates model-space matrices from current local-space setup. + // Model-space matrices needs to be updated up to the end joint. Any joint + // after that will need to be recomputed after IK indeed. + ozz::animation::LocalToModelJob ltm_job; + ltm_job.skeleton = &skeleton_; + ltm_job.input = make_span(locals_); + ltm_job.output = make_span(models_); + if (!ltm_job.Run()) { + return false; + } + + // Setup and run IK job. + if (two_bone_ik_ && !ApplyTwoBoneIK()) { + return false; + } + + return true; + } + + virtual bool OnDisplay(ozz::sample::Renderer* _renderer) { + bool success = true; + + // Get skeleton root transform. + const ozz::math::Float4x4 root = GetRootTransform(); + + if (show_target_ && two_bone_ik_) { + // Displays target + const ozz::sample::Color colors[2][2] = { + {ozz::sample::kRed, ozz::sample::kBlack}, + {ozz::sample::kGreen, ozz::sample::kBlack}}; + + const float kBoxHalfSize = .006f; + const ozz::math::Box box(ozz::math::Float3(-kBoxHalfSize), + ozz::math::Float3(kBoxHalfSize)); + success &= _renderer->DrawBoxIm( + box, + ozz::math::Float4x4::Translation( + ozz::math::simd_float4::Load3PtrU(&target_.x)), + colors[reached_]); + } + + // Displays pole vector + if (show_pole_vector_) { + ozz::math::Float3 begin; + ozz::math::Store3PtrU(TransformPoint(root, models_[mid_joint_].cols[3]), + &begin.x); + success &= _renderer->DrawSegment(begin, begin + pole_vector, + ozz::sample::kWhite, + ozz::math::Float4x4::identity()); + } + + // Showing joints + if (show_joints_) { + const float kAxeScale = .1f; + const float kSphereRadius = .009f; + const ozz::math::Float4x4 kAxesScale = ozz::math::Float4x4::Scaling( + ozz::math::simd_float4::Load1(kAxeScale)); + for (size_t i = 0; i < 3; ++i) { + const int joints[3] = {start_joint_, mid_joint_, end_joint_}; + const ozz::math::Float4x4& transform = root * models_[joints[i]]; + success &= _renderer->DrawAxes(transform * kAxesScale); + success &= _renderer->DrawSphereIm(kSphereRadius, transform, + ozz::sample::kWhite); + } + } + + // Draws the animated skeleton posture. + success &= _renderer->DrawPosture(skeleton_, make_span(models_), root); + + return success; + } + + virtual bool OnInitialize() { + // Loads skeleton. + if (!ozz::sample::LoadSkeleton(OPTIONS_skeleton, &skeleton_)) { + return false; + } + + // Allocates runtime buffers. + const int num_soa_joints = skeleton_.num_soa_joints(); + locals_.resize(num_soa_joints); + const int num_joints = skeleton_.num_joints(); + models_.resize(num_joints); + + // Find the 3 joints in skeleton hierarchy. + start_joint_ = mid_joint_ = end_joint_ = -1; + for (int i = 0; i < skeleton_.num_joints(); i++) { + const char* joint_name = skeleton_.joint_names()[i]; + if (std::strcmp(joint_name, "shoulder") == 0) { + start_joint_ = i; + } else if (std::strcmp(joint_name, "forearm") == 0) { + mid_joint_ = i; + } else if (std::strcmp(joint_name, "wrist") == 0) { + end_joint_ = i; + } + } + + // Fails if a joint is missing. + if (start_joint_ < 0 || mid_joint_ < 0 || end_joint_ < 0) { + ozz::log::Err() << "Failed to find required joints." << std::endl; + return false; + } + + // Initialize locals from skeleton rest pose + for (size_t i = 0; i < locals_.size(); ++i) { + locals_[i] = skeleton_.joint_rest_poses()[i]; + } + + return true; + } + + virtual void OnDestroy() {} + + virtual bool OnGui(ozz::sample::ImGui* _im_gui) { + char txt[32]; + + // IK parameters + _im_gui->DoCheckBox("Fix initial transform", &fix_initial_transform_); + _im_gui->DoCheckBox("Enable two bone ik", &two_bone_ik_); + { + static bool opened = true; + ozz::sample::ImGui::OpenClose oc(_im_gui, "IK parameters", &opened); + if (opened) { + sprintf(txt, "Soften: %.2g", soften_); + _im_gui->DoSlider(txt, 0.f, 1.f, &soften_, 2.f); + sprintf(txt, "Twist angle: %.0f", + twist_angle_ * ozz::math::kRadianToDegree); + _im_gui->DoSlider(txt, -ozz::math::kPi, ozz::math::kPi, &twist_angle_); + sprintf(txt, "Weight: %.2g", weight_); + _im_gui->DoSlider(txt, 0.f, 1.f, &weight_); + { + // Pole vector + static bool pole_opened = true; + ozz::sample::ImGui::OpenClose oc_pole(_im_gui, "Pole vector", + &pole_opened); + if (pole_opened) { + sprintf(txt, "x %.2g", pole_vector.x); + _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.x); + sprintf(txt, "y %.2g", pole_vector.y); + _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.y); + sprintf(txt, "z %.2g", pole_vector.z); + _im_gui->DoSlider(txt, -1.f, 1.f, &pole_vector.z); + } + } + } + } + { // Target position + static bool opened = true; + ozz::sample::ImGui::OpenClose oc(_im_gui, "Target position", &opened); + if (opened) { + _im_gui->DoLabel("Target animation extent"); + sprintf(txt, "%.2g", target_extent_); + _im_gui->DoSlider(txt, 0.f, 1.f, &target_extent_); + + _im_gui->DoLabel("Target Offset"); + const float kOffsetRange = 1.f; + sprintf(txt, "x %.2g", target_offset_.x); + _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.x); + sprintf(txt, "y %.2g", target_offset_.y); + _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.y); + sprintf(txt, "z %.2g", target_offset_.z); + _im_gui->DoSlider(txt, -kOffsetRange, kOffsetRange, &target_offset_.z); + } + } + { // Root + static bool opened = false; + ozz::sample::ImGui::OpenClose oc(_im_gui, "Root transformation", &opened); + if (opened) { + // Translation + _im_gui->DoLabel("Translation"); + sprintf(txt, "x %.2g", root_translation_.x); + _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.x); + sprintf(txt, "y %.2g", root_translation_.y); + _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.y); + sprintf(txt, "z %.2g", root_translation_.z); + _im_gui->DoSlider(txt, -1.f, 1.f, &root_translation_.z); + + // Rotation (in euler form) + _im_gui->DoLabel("Rotation"); + ozz::math::Float3 euler = root_euler_ * ozz::math::kRadianToDegree; + sprintf(txt, "yaw %.3g", euler.x); + _im_gui->DoSlider(txt, -180.f, 180.f, &euler.x); + sprintf(txt, "pitch %.3g", euler.y); + _im_gui->DoSlider(txt, -180.f, 180.f, &euler.y); + sprintf(txt, "roll %.3g", euler.z); + _im_gui->DoSlider(txt, -180.f, 180.f, &euler.z); + root_euler_ = euler * ozz::math::kDegreeToRadian; + + // Scale (must be uniform and not 0) + _im_gui->DoLabel("Scale"); + sprintf(txt, "%.2g", root_scale_); + _im_gui->DoSlider(txt, -1.f, 1.f, &root_scale_); + } + } + { // Display options + static bool opened = true; + ozz::sample::ImGui::OpenClose oc(_im_gui, "Display options", &opened); + if (opened) { + _im_gui->DoCheckBox("Show target", &show_target_); + _im_gui->DoCheckBox("Show joints", &show_joints_); + _im_gui->DoCheckBox("Show pole vector", &show_pole_vector_); + } + } + + return true; + } + + virtual void GetSceneBounds(ozz::math::Box* _bound) const { + const ozz::math::Float3 radius(target_extent_ * .5f); + _bound->min = target_offset_ - radius; + _bound->max = target_offset_ + radius; + } + + private: + bool MoveTarget(float _time) { + const float anim_extent = (1.f - std::cos(_time)) * .5f * target_extent_; + const int floor = static_cast(std::fabs(_time) / ozz::math::k2Pi); + + target_ = target_offset_; + (&target_.x)[floor % 3] += anim_extent; + return true; + } + + ozz::math::Float4x4 GetRootTransform() const { + return ozz::math::Float4x4::Translation( + ozz::math::simd_float4::Load3PtrU(&root_translation_.x)) * + ozz::math::Float4x4::FromEuler( + ozz::math::simd_float4::Load3PtrU(&root_euler_.x)) * + ozz::math::Float4x4::Scaling( + ozz::math::simd_float4::Load1(root_scale_)); + } + + // Runtime skeleton. + ozz::animation::Skeleton skeleton_; + + // Buffer of local transforms as sampled from animation_. + ozz::vector locals_; + + // Buffer of model space matrices. + ozz::vector models_; + + // Two bone IK setup. Indices of the relevant joints in the chain. + int start_joint_; + int mid_joint_; + int end_joint_; + + // Two bone IK parameters. + ozz::math::Float3 pole_vector; + float weight_; + float soften_; + float twist_angle_; + + // Two bone IK job "reched" output value. + bool reached_; + + // Sample options + bool fix_initial_transform_; + bool two_bone_ik_; + + // Sample display options + bool show_target_; + bool show_joints_; + bool show_pole_vector_; + + // Root transformation. + ozz::math::Float3 root_translation_; + ozz::math::Float3 root_euler_; + float root_scale_; + + // Target positioning and animation. + float target_extent_; + ozz::math::Float3 target_offset_; + ozz::math::Float3 target_; +}; + +int main(int _argc, const char** _argv) { + const char* title = "Ozz-animation sample: Two bone IK"; + return TwoBoneIKSampleApplication().Run(_argc, _argv, "1.0", title); +} diff --git a/3rdparty/ozz-animation/samples/user_channel/CMakeLists.txt b/3rdparty/ozz-animation/samples/user_channel/CMakeLists.txt index bee792e..8854cb2 100644 --- a/3rdparty/ozz-animation/samples/user_channel/CMakeLists.txt +++ b/3rdparty/ozz-animation/samples/user_channel/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable(sample_user_channel "${CMAKE_CURRENT_BINARY_DIR}/media/track.ozz") target_link_libraries(sample_user_channel sample_framework) +target_copy_shared_libraries(sample_user_channel) set_target_properties(sample_user_channel PROPERTIES FOLDER "samples") diff --git a/3rdparty/ozz-animation/samples/user_channel/sample_user_channel.cc b/3rdparty/ozz-animation/samples/user_channel/sample_user_channel.cc index e6f6624..59bfaf0 100644 --- a/3rdparty/ozz-animation/samples/user_channel/sample_user_channel.cc +++ b/3rdparty/ozz-animation/samples/user_channel/sample_user_channel.cc @@ -212,7 +212,7 @@ class UserChannelSampleApplication : public ozz::sample::Application { // Samples animation at r = _ratio. ozz::animation::SamplingJob sampling_job; sampling_job.animation = &animation_; - sampling_job.cache = &cache_; + sampling_job.context = &context_; sampling_job.ratio = _ratio; sampling_job.output = make_span(locals_); if (!sampling_job.Run()) { @@ -277,8 +277,8 @@ class UserChannelSampleApplication : public ozz::sample::Application { const int num_joints = skeleton_.num_joints(); models_.resize(num_joints); - // Allocates a cache that matches animation requirements. - cache_.Resize(num_joints); + // Allocates a context that matches animation requirements. + context_.Resize(num_joints); // Reading track. if (!ozz::sample::LoadTrack(OPTIONS_track, &track_)) { @@ -339,8 +339,8 @@ class UserChannelSampleApplication : public ozz::sample::Application { // Runtime animation. ozz::animation::Animation animation_; - // Sampling cache. - ozz::animation::SamplingCache cache_; + // Sampling context. + ozz::animation::SamplingJob::Context context_; // Buffer of local transforms as sampled from animation_. ozz::vector locals_; diff --git a/3rdparty/ozz-animation/src/CMakeLists.txt b/3rdparty/ozz-animation/src/CMakeLists.txt index 2ffa912..125da94 100644 --- a/3rdparty/ozz-animation/src/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/CMakeLists.txt @@ -1,7 +1,7 @@ # Directory src is available from the implementation files. include_directories(./) -add_subdirectory(animation) -add_subdirectory(geometry) add_subdirectory(base) add_subdirectory(options) +add_subdirectory(animation) +add_subdirectory(geometry) diff --git a/3rdparty/ozz-animation/src/animation/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/CMakeLists.txt index 4972c7e..ce31ae3 100644 --- a/3rdparty/ozz-animation/src/animation/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/CMakeLists.txt @@ -1,2 +1,2 @@ -add_subdirectory(offline) -add_subdirectory(runtime) \ No newline at end of file +add_subdirectory(runtime) +add_subdirectory(offline) \ No newline at end of file diff --git a/3rdparty/ozz-animation/src/animation/offline/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/offline/CMakeLists.txt index 6b23e03..7dc853f 100644 --- a/3rdparty/ozz-animation/src/animation/offline/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/offline/CMakeLists.txt @@ -1,4 +1,6 @@ -add_library(ozz_animation_offline STATIC + +add_library(ozz_animation_offline + ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/export.h decimate.h ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/raw_animation.h raw_animation.cc @@ -22,8 +24,10 @@ add_library(ozz_animation_offline STATIC track_builder.cc ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/track_optimizer.h track_optimizer.cc) -target_link_libraries(ozz_animation_offline - ozz_animation) + +target_compile_definitions(ozz_animation_offline PRIVATE $<$:OZZ_BUILD_ANIMOFFLINE_LIB>) + +target_link_libraries(ozz_animation_offline ozz_animation) set_target_properties(ozz_animation_offline PROPERTIES FOLDER "ozz") @@ -31,7 +35,7 @@ install(TARGETS ozz_animation_offline DESTINATION lib) fuse_target("ozz_animation_offline") +add_subdirectory(tools) # tools target need to be defined before other targets that uses them add_subdirectory(fbx) add_subdirectory(gltf) -add_subdirectory(tools) diff --git a/3rdparty/ozz-animation/src/animation/offline/additive_animation_builder.cc b/3rdparty/ozz-animation/src/animation/offline/additive_animation_builder.cc index 1e6980b..930b6fa 100644 --- a/3rdparty/ozz-animation/src/animation/offline/additive_animation_builder.cc +++ b/3rdparty/ozz-animation/src/animation/offline/additive_animation_builder.cc @@ -89,6 +89,7 @@ bool AdditiveAnimationBuilder::operator()(const RawAnimation& _input, } // Rebuilds output animation. + _output->name = _input.name; _output->duration = _input.duration; _output->tracks.resize(_input.tracks.size()); @@ -143,6 +144,7 @@ bool AdditiveAnimationBuilder::operator()( } // Rebuilds output animation. + _output->name = _input.name; _output->duration = _input.duration; _output->tracks.resize(_input.tracks.size()); diff --git a/3rdparty/ozz-animation/src/animation/offline/animation_builder.cc b/3rdparty/ozz-animation/src/animation/offline/animation_builder.cc index f788371..e06b015 100644 --- a/3rdparty/ozz-animation/src/animation/offline/animation_builder.cc +++ b/3rdparty/ozz-animation/src/animation/offline/animation_builder.cc @@ -163,7 +163,7 @@ void CompressQuat(const ozz::math::Quaternion& _src, ozz::animation::QuaternionKey* _dest) { // Finds the largest quaternion component. const float quat[4] = {_src.x, _src.y, _src.z, _src.w}; - const size_t largest = std::max_element(quat, quat + 4, LessAbs) - quat; + const ptrdiff_t largest = std::max_element(quat, quat + 4, LessAbs) - quat; assert(largest <= 3); _dest->largest = largest & 0x3; @@ -269,7 +269,7 @@ unique_ptr AnimationBuilder::operator()( // Declares and preallocates tracks to sort. size_t translations = 0, rotations = 0, scales = 0; - for (int i = 0; i < num_tracks; ++i) { + for (uint16_t i = 0; i < num_tracks; ++i) { const RawAnimation::JointTrack& raw_track = _input.tracks[i]; translations += raw_track.translations.size() + 2; // +2 because worst case rotations += raw_track.rotations.size() + 2; // needs to add the diff --git a/3rdparty/ozz-animation/src/animation/offline/fbx/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/offline/fbx/CMakeLists.txt index 456f21a..6ccb9ec 100644 --- a/3rdparty/ozz-animation/src/animation/offline/fbx/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/offline/fbx/CMakeLists.txt @@ -2,22 +2,20 @@ if(NOT ozz_build_fbx) return() endif() -add_library(ozz_animation_fbx STATIC +add_library(ozz_animation_fbx + ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/fbx/export.h ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/fbx/fbx.h fbx.cc ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/fbx/fbx_animation.h fbx_animation.cc ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/fbx/fbx_skeleton.h fbx_skeleton.cc) -target_include_directories(ozz_animation_fbx - PUBLIC $) + +target_compile_definitions(ozz_animation_fbx PRIVATE $<$:OZZ_BUILD_ANIMATIONFBX_LIB>) + target_link_libraries(ozz_animation_fbx ozz_animation_offline - debug ${FBX_LIBRARIES_DEBUG} - optimized ${FBX_LIBRARIES}) -target_compile_options(ozz_animation_fbx - PUBLIC $<$:-Wno-null-dereference> - PUBLIC $<$:-Wno-pragma-pack>) + fbx::sdk) set_target_properties(ozz_animation_fbx PROPERTIES FOLDER "ozz/tools") install(TARGETS ozz_animation_fbx DESTINATION lib) @@ -32,6 +30,7 @@ add_executable(fbx2ozz target_link_libraries(fbx2ozz ozz_animation_tools ozz_animation_fbx) +target_copy_shared_libraries(fbx2ozz) set_target_properties(fbx2ozz PROPERTIES FOLDER "ozz/tools") @@ -45,6 +44,7 @@ set(build_configurations "/fbx/pab/locomotions.fbx\;{\"skeleton\":{\"filename\":\"pab_skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"pab_*.ozz\"}]}\;output:pab_walk.ozz\;output:pab_jog.ozz\;output:pab_run.ozz\;depend:pab_skeleton.ozz" "/fbx/pab/crossarms.fbx\;{\"skeleton\":{\"filename\":\"pab_skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"pab_crossarms.ozz\"}]}\;output:pab_crossarms.ozz\;depend:pab_skeleton.ozz" "/fbx/pab/crackhead.fbx\;{\"skeleton\":{\"filename\":\"pab_skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"pab_crackhead.ozz\"},{\"filename\":\"pab_crackhead_additive.ozz\",\"additive\":true}]}\;output:pab_crackhead_additive.ozz\;output:pab_crackhead.ozz\;depend:pab_skeleton.ozz" + "/fbx/pab/hand.fbx\;{\"skeleton\":{\"filename\":\"pab_skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"clip\":\"curl\",\"filename\":\"pab_curl_additive.ozz\",\"additive\":true,\"additive_reference\":\"skeleton\"},{\"clip\":\"splay\",\"filename\":\"pab_splay_additive.ozz\",\"additive\":true,\"additive_reference\":\"skeleton\"}]}\;output:pab_curl_additive.ozz\;output:pab_splay_additive.ozz\;depend:pab_skeleton.ozz" # Robot user channels "/fbx/robot.fbx\;\;config_file:${PROJECT_SOURCE_DIR}/samples/user_channel/config.json\;output:robot_skeleton.ozz\;output:robot_animation.ozz\;output:robot_track_grasp.ozz" diff --git a/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_animation.cc b/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_animation.cc index fcebdde..cb16f93 100644 --- a/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_animation.cc +++ b/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_animation.cc @@ -28,15 +28,12 @@ #include "ozz/animation/offline/fbx/fbx_animation.h" #include "ozz/animation/offline/fbx/fbx.h" - #include "ozz/animation/offline/raw_animation.h" #include "ozz/animation/offline/raw_animation_utils.h" #include "ozz/animation/offline/raw_track.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/animation/runtime/skeleton_utils.h" - #include "ozz/base/log.h" - #include "ozz/base/maths/math_ex.h" #include "ozz/base/maths/transform.h" @@ -157,16 +154,16 @@ bool ExtractAnimation(FbxSceneLoader& _scene_loader, const SamplingInfo& _info, if (node == nullptr) { ozz::log::LogV() << "No animation track found for joint \"" << _skeleton.joint_names()[i] - << "\". Using skeleton bind pose instead." << std::endl; + << "\". Using skeleton rest pose instead." << std::endl; - const math::Transform& bind_pose = - ozz::animation::GetJointLocalBindPose(_skeleton, i); + const math::Transform& rest_pose = + ozz::animation::GetJointLocalRestPose(_skeleton, i); const math::SimdFloat4 t = - math::simd_float4::Load3PtrU(&bind_pose.translation.x); + math::simd_float4::Load3PtrU(&rest_pose.translation.x); const math::SimdFloat4 q = - math::simd_float4::LoadPtrU(&bind_pose.rotation.x); + math::simd_float4::LoadPtrU(&rest_pose.rotation.x); const math::SimdFloat4 s = - math::simd_float4::Load3PtrU(&bind_pose.scale.x); + math::simd_float4::Load3PtrU(&rest_pose.scale.x); const math::Float4x4 local_matrix = math::Float4x4::FromAffine(t, q, s); ozz::vector& node_matrices = world_matrices[i]; @@ -201,7 +198,7 @@ bool ExtractAnimation(FbxSceneLoader& _scene_loader, const SamplingInfo& _info, // Builds local space animation tracks. // Allocates all tracks with the same number of joints as the skeleton. - // Tracks that would not be found will be set to skeleton bind-pose + // Tracks that would not be found will be set to skeleton rest-pose // transformation. _animation->tracks.resize(_skeleton.num_joints()); for (int i = 0; i < _skeleton.num_joints(); i++) { diff --git a/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_skeleton.cc b/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_skeleton.cc index 0531bc4..73e1728 100644 --- a/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_skeleton.cc +++ b/3rdparty/ozz-animation/src/animation/offline/fbx/fbx_skeleton.cc @@ -28,7 +28,6 @@ #include "ozz/animation/offline/fbx/fbx_skeleton.h" #include "ozz/animation/offline/raw_skeleton.h" - #include "ozz/base/log.h" namespace ozz { @@ -78,9 +77,12 @@ bool IsTypeSelected(const OzzImporter::NodeType& _types, case FbxNodeAttribute::eLight: return _types.light; + // Null + case FbxNodeAttribute::eNull: + return _types.null; + // Others case FbxNodeAttribute::eUnknown: - case FbxNodeAttribute::eNull: case FbxNodeAttribute::eCameraSwitcher: case FbxNodeAttribute::eOpticalReference: case FbxNodeAttribute::eOpticalMarker: @@ -116,7 +118,7 @@ RecurseReturn RecurseNode(FbxNode* _node, FbxSystemConverter* _converter, this_joint = &sibling->back(); // Will not be resized inside recursion. this_joint->name = _node->GetName(); - // Extract bind pose. + // Extract rest pose. const FbxAMatrix node_global = _node->EvaluateGlobalTransform(); const FbxAMatrix node_local = _parent_global_inv * node_global; diff --git a/3rdparty/ozz-animation/src/animation/offline/gltf/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/offline/gltf/CMakeLists.txt index 9389011..73aeb50 100644 --- a/3rdparty/ozz-animation/src/animation/offline/gltf/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/offline/gltf/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(gltf2ozz target_link_libraries(gltf2ozz PRIVATE ozz_animation_tools) +target_copy_shared_libraries(gltf2ozz) set_target_properties(gltf2ozz PROPERTIES FOLDER "ozz/tools") diff --git a/3rdparty/ozz-animation/src/animation/offline/gltf/extern/json.hpp b/3rdparty/ozz-animation/src/animation/offline/gltf/extern/json.hpp index c9af0be..7e1aea4 100644 --- a/3rdparty/ozz-animation/src/animation/offline/gltf/extern/json.hpp +++ b/3rdparty/ozz-animation/src/animation/offline/gltf/extern/json.hpp @@ -9745,7 +9745,7 @@ class binary_writer static CharType to_char_type(std::uint8_t x) noexcept { static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t"); - static_assert(std::is_pod::value, "CharType must be POD"); + static_assert(std::is_standard_layout::value && std::is_trivial::value, "CharType must be POD"); CharType result; std::memcpy(&result, &x, sizeof(x)); return result; diff --git a/3rdparty/ozz-animation/src/animation/offline/gltf/gltf2ozz.cc b/3rdparty/ozz-animation/src/animation/offline/gltf/gltf2ozz.cc index 99acdc2..2fa4bc2 100644 --- a/3rdparty/ozz-animation/src/animation/offline/gltf/gltf2ozz.cc +++ b/3rdparty/ozz-animation/src/animation/offline/gltf/gltf2ozz.cc @@ -358,7 +358,7 @@ bool SampleChannel(const tinygltf::Model& _model, } ozz::animation::offline::RawAnimation::TranslationKey -CreateTranslationBindPoseKey(const tinygltf::Node& _node) { +CreateTranslationRestPoseKey(const tinygltf::Node& _node) { ozz::animation::offline::RawAnimation::TranslationKey key; key.time = 0.0f; @@ -373,7 +373,7 @@ CreateTranslationBindPoseKey(const tinygltf::Node& _node) { return key; } -ozz::animation::offline::RawAnimation::RotationKey CreateRotationBindPoseKey( +ozz::animation::offline::RawAnimation::RotationKey CreateRotationRestPoseKey( const tinygltf::Node& _node) { ozz::animation::offline::RawAnimation::RotationKey key; key.time = 0.0f; @@ -389,7 +389,7 @@ ozz::animation::offline::RawAnimation::RotationKey CreateRotationBindPoseKey( return key; } -ozz::animation::offline::RawAnimation::ScaleKey CreateScaleBindPoseKey( +ozz::animation::offline::RawAnimation::ScaleKey CreateScaleRestPoseKey( const tinygltf::Node& _node) { ozz::animation::offline::RawAnimation::ScaleKey key; key.time = 0.0f; @@ -430,8 +430,8 @@ bool CreateNodeTransform(const tinygltf::Node& _node, ozz::math::SimdFloat4 translation, rotation, scale; if (ToAffine(matrix, &translation, &rotation, &scale)) { ozz::math::Store3PtrU(translation, &_transform->translation.x); - ozz::math::StorePtrU(translation, &_transform->rotation.x); - ozz::math::Store3PtrU(translation, &_transform->scale.x); + ozz::math::StorePtrU(rotation, &_transform->rotation.x); + ozz::math::Store3PtrU(scale, &_transform->scale.x); return true; } @@ -521,30 +521,38 @@ class GltfImporter : public ozz::animation::offline::OzzImporter { return success; } - // Given a skin find which of its joints is the skeleton root and return it - // returns -1 if the skin has no associated joints - int FindSkinRootJointIndex(const tinygltf::Skin& skin) { - if (skin.joints.empty()) { - return -1; - } - - if (skin.skeleton != -1) { - return skin.skeleton; - } - - ozz::map parents; - for (int node : skin.joints) { + // Find all unique root joints of skeletons used by given skins and add them + // to `roots` + void FindSkinRootJointIndices(const ozz::vector& skins, + ozz::vector& roots) { + static constexpr int no_parent = -1; + static constexpr int visited = -2; + ozz::vector parents(m_model.nodes.size(), no_parent); + for (int node = 0; node < static_cast(m_model.nodes.size()); node++) { for (int child : m_model.nodes[node].children) { parents[child] = node; } } - int root = skin.joints[0]; - while (parents.find(root) != parents.end()) { - root = parents[root]; - } + for (const tinygltf::Skin& skin : skins) { + if (skin.joints.empty()) { + continue; + } - return root; + if (skin.skeleton != -1) { + parents[skin.skeleton] = visited; + roots.push_back(skin.skeleton); + continue; + } + + int root = skin.joints[0]; + while (root != visited && parents[root] != no_parent) { + root = parents[root]; + } + if (root != visited) { + roots.push_back(root); + } + } } bool Import(ozz::animation::offline::RawSkeleton* _skeleton, @@ -591,14 +599,8 @@ class GltfImporter : public ozz::animation::offline::OzzImporter { << std::endl; } - // Uses all skins root - for (auto& skin : skins) { - const int root = FindSkinRootJointIndex(skin); - if (root == -1) { - continue; - } - roots.push_back(root); - } + // Uses all skins roots. + FindSkinRootJointIndices(skins, roots); } // Remove nodes listed multiple times. @@ -745,16 +747,16 @@ class GltfImporter : public ozz::animation::offline::OzzImporter { const tinygltf::Node* node = FindNodeByName(joint_names[i]); assert(node != nullptr); - // Pads the bind pose transform for any joints which do not have an + // Pads the rest pose transform for any joints which do not have an // associated channel for this animation if (track.translations.empty()) { - track.translations.push_back(CreateTranslationBindPoseKey(*node)); + track.translations.push_back(CreateTranslationRestPoseKey(*node)); } if (track.rotations.empty()) { - track.rotations.push_back(CreateRotationBindPoseKey(*node)); + track.rotations.push_back(CreateRotationRestPoseKey(*node)); } if (track.scales.empty()) { - track.scales.push_back(CreateScaleBindPoseKey(*node)); + track.scales.push_back(CreateScaleRestPoseKey(*node)); } } diff --git a/3rdparty/ozz-animation/src/animation/offline/skeleton_builder.cc b/3rdparty/ozz-animation/src/animation/offline/skeleton_builder.cc index 5072b8f..79f8b77 100644 --- a/3rdparty/ozz-animation/src/animation/offline/skeleton_builder.cc +++ b/3rdparty/ozz-animation/src/animation/offline/skeleton_builder.cc @@ -144,9 +144,9 @@ unique_ptr SkeletonBuilder::operator()( } // Fills the SoaTransform structure. math::Transpose4x3(translations, - &skeleton->joint_bind_poses_[i].translation.x); - math::Transpose4x4(rotations, &skeleton->joint_bind_poses_[i].rotation.x); - math::Transpose4x3(scales, &skeleton->joint_bind_poses_[i].scale.x); + &skeleton->joint_rest_poses_[i].translation.x); + math::Transpose4x4(rotations, &skeleton->joint_rest_poses_[i].rotation.x); + math::Transpose4x3(scales, &skeleton->joint_rest_poses_[i].scale.x); } return skeleton; // Success. diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/offline/tools/CMakeLists.txt index 5959b81..905c6f4 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/offline/tools/CMakeLists.txt @@ -4,7 +4,8 @@ endif() add_subdirectory(${PROJECT_SOURCE_DIR}/extern/jsoncpp json) -add_library(ozz_animation_tools STATIC +add_library(ozz_animation_tools + ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/tools/export.h ${PROJECT_SOURCE_DIR}/include/ozz/animation/offline/tools/import2ozz.h import2ozz.cc import2ozz_anim.h @@ -15,10 +16,14 @@ add_library(ozz_animation_tools STATIC import2ozz_skel.cc import2ozz_track.h import2ozz_track.cc) + +target_compile_definitions(ozz_animation_tools PRIVATE $<$:OZZ_BUILD_ANIMATIONTOOLS_LIB>) + target_link_libraries(ozz_animation_tools ozz_animation_offline ozz_options json) + set_target_properties(ozz_animation_tools PROPERTIES FOLDER "ozz/tools") @@ -32,6 +37,7 @@ if(NOT EMSCRIPTEN) target_link_libraries(dump2ozz ozz_animation_tools ozz_options) + target_copy_shared_libraries(dump2ozz) # Uses a fake import file to dump reference and default configurations. add_custom_command(TARGET dump2ozz POST_BUILD @@ -39,4 +45,5 @@ if(NOT EMSCRIPTEN) set_target_properties(dump2ozz PROPERTIES FOLDER "ozz/tools") + endif() \ No newline at end of file diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.cc b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.cc index b7e37ad..18329de 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.cc +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.cc @@ -137,11 +137,11 @@ unique_ptr LoadSkeleton(const char* _path) { return skeleton; } -vector SkeletonBindPoseSoAToAoS(const Skeleton& _skeleton) { - // Copy skeleton bind pose to AoS form. +vector SkeletonRestPoseSoAToAoS(const Skeleton& _skeleton) { + // Copy skeleton rest pose to AoS form. vector transforms(_skeleton.num_joints()); for (int i = 0; i < _skeleton.num_soa_joints(); ++i) { - const math::SoaTransform& soa_transform = _skeleton.joint_bind_poses()[i]; + const math::SoaTransform& soa_transform = _skeleton.joint_rest_poses()[i]; math::SimdFloat4 translation[4]; math::SimdFloat4 rotation[4]; math::SimdFloat4 scale[4]; @@ -248,7 +248,7 @@ bool Export(OzzImporter& _importer, const RawAnimation& _input_animation, bool succeeded = false; if (enum_found && reference == AdditiveReferenceEnum::kSkeleton) { const vector transforms = - SkeletonBindPoseSoAToAoS(_skeleton); + SkeletonRestPoseSoAToAoS(_skeleton); succeeded = additive_builder(raw_animation, make_span(transforms), &raw_additive); } else { @@ -371,9 +371,12 @@ bool ImportAnimations(const Json::Value& _config, OzzImporter* _importer, LoadSkeleton(skeleton_config["filename"].asCString())); success &= skeleton.get() != nullptr; + if (!success) + return false; + // Loop though all existing animations, and export those who match // configuration. - for (Json::ArrayIndex i = 0; success && i < animations_config.size(); ++i) { + for (Json::ArrayIndex i = 0; i < animations_config.size(); ++i) { const Json::Value& animation_config = animations_config[i]; const char* clip_match = animation_config["clip"].asCString(); @@ -384,28 +387,45 @@ bool ImportAnimations(const Json::Value& _config, OzzImporter* _importer, continue; } - bool matched = false; - for (size_t j = 0; success && j < import_animation_names.size(); ++j) { + size_t num_not_clip_animation = 0, num_valid_animation = 0; + for (size_t j = 0; j < import_animation_names.size(); ++j) { const char* animation_name = import_animation_names[j].c_str(); if (!strmatch(animation_name, clip_match)) { continue; } + ++num_not_clip_animation; + const bool anisuccess = ProcessAnimation(*_importer, animation_name, *skeleton, + animation_config, _endianness); + if(anisuccess){ + ++num_valid_animation; + } - matched = true; - success = ProcessAnimation(*_importer, animation_name, *skeleton, - animation_config, _endianness); - + size_t num_valid_track = 0; const Json::Value& tracks_config = animation_config["tracks"]; - for (Json::ArrayIndex t = 0; success && t < tracks_config.size(); ++t) { - success = ProcessTracks(*_importer, animation_name, *skeleton, - tracks_config[t], _endianness); + for (Json::ArrayIndex t = 0; t < tracks_config.size(); ++t) { + if (ProcessTracks(*_importer, animation_name, *skeleton, + tracks_config[t], _endianness)){ + ++num_valid_track; + } + } + + if (num_valid_track != tracks_config.size()){ + ozz::log::Log() << "One of track failed when import: \"" << animation_name + << "\"" << std::endl; + success = false; } } // Don't display any message if no animation is supposed to be imported. - if (!matched && *clip_match != 0) { + if (0 == num_not_clip_animation && *clip_match != 0) { ozz::log::Log() << "No matching animation found for \"" << clip_match << "\"." << std::endl; } + + if (num_valid_animation != num_not_clip_animation){ + ozz::log::Log() << "One of animation failed when import, animation index: \"" << i + << "\"" << std::endl; + success = false; + } } return success; diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.h b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.h index 97f09c7..67cc8e2 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.h +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_anim.h @@ -28,6 +28,7 @@ #ifndef OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_ANIM_H_ #define OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_ANIM_H_ +#include "ozz/animation/offline/tools/export.h" #include "ozz/base/endianness.h" #include "ozz/base/platform.h" @@ -43,14 +44,15 @@ namespace animation { namespace offline { class OzzImporter; -bool ImportAnimations(const Json::Value& _config, OzzImporter* _importer, +OZZ_ANIMTOOLS_DLL bool ImportAnimations(const Json::Value& _config, + OzzImporter* _importer, const ozz::Endianness _endianness); // Additive reference enum to config string conversions. struct AdditiveReferenceEnum { enum Value { kAnimation, kSkeleton }; }; -struct AdditiveReference +struct OZZ_ANIMTOOLS_DLL AdditiveReference : JsonEnum { static EnumNames GetNames(); }; diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.cc b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.cc index c5b6a59..85f62e1 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.cc +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.cc @@ -27,24 +27,21 @@ #include "animation/offline/tools/import2ozz_config.h" +#include + #include #include #include #include "animation/offline/tools/import2ozz_anim.h" #include "animation/offline/tools/import2ozz_track.h" -#include "ozz/animation/offline/tools/import2ozz.h" - #include "ozz/animation/offline/animation_optimizer.h" +#include "ozz/animation/offline/tools/import2ozz.h" #include "ozz/animation/offline/track_optimizer.h" - #include "ozz/base/containers/string.h" #include "ozz/base/log.h" - #include "ozz/options/options.h" -#include - bool ValidateExclusiveConfigOption(const ozz::options::Option& _option, int _argc); OZZ_OPTIONS_DECLARE_STRING_FN( @@ -365,14 +362,14 @@ bool SanitizeAnimation(Json::Value& _root, bool _all_options) { MakeDefault(_root, "additive_reference", "animation", "Select reference pose to use to build additive/delta animation. " "Can be \"animation\" to use the 1st animation keyframe as " - "reference, or \"skeleton\" to use skeleton bind pose."); + "reference, or \"skeleton\" to use skeleton rest pose."); if (!AdditiveReference::IsValidEnumName( _root["additive_reference"].asCString())) { ozz::log::Err() << "Invalid additive reference pose \"" << _root["additive_reference"].asCString() << "\". \"" << "Can be \"animation\" to use the 1st animation keyframe " - "as reference, or \"skeleton\" to use skeleton bind " + "as reference, or \"skeleton\" to use skeleton rest " "pose." << std::endl; return false; diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.h b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.h index 217d269..09cfb4e 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.h +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_config.h @@ -28,6 +28,7 @@ #ifndef OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_CONFIG_H_ #define OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_CONFIG_H_ +#include "ozz/animation/offline/tools/export.h" #include "ozz/base/platform.h" #include @@ -37,10 +38,10 @@ namespace animation { namespace offline { // Get the sanitized (all members are set, with the right types) configuration. -bool ProcessConfiguration(Json::Value* _config); +OZZ_ANIMTOOLS_DLL bool ProcessConfiguration(Json::Value* _config); // Internal function used to compare enum names. -bool CompareName(const char* _a, const char* _b); +OZZ_ANIMTOOLS_DLL bool CompareName(const char* _a, const char* _b); // Struct allowing inheriting class to provide enum names. template diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.cc b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.cc index 859a3b0..7ac8ae9 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.cc +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.cc @@ -122,12 +122,13 @@ bool ImportSkeleton(const Json::Value& _config, OzzImporter* _importer, // Setup node types import properties. const Json::Value& types_config = import_config["types"]; - OzzImporter::NodeType types = {0}; + OzzImporter::NodeType types = {}; types.skeleton = types_config["skeleton"].asBool(); types.marker = types_config["marker"].asBool(); types.camera = types_config["camera"].asBool(); types.geometry = types_config["geometry"].asBool(); types.light = types_config["light"].asBool(); + types.null = types_config["null"].asBool(); types.any = types_config["any"].asBool(); RawSkeleton raw_skeleton; diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.h b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.h index 6cfab4c..0d28f2d 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.h +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_skel.h @@ -28,6 +28,7 @@ #ifndef OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_SKEL_H_ #define OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_SKEL_H_ +#include "ozz/animation/offline/tools/export.h" #include "ozz/base/endianness.h" #include "ozz/base/platform.h" @@ -41,8 +42,9 @@ namespace offline { class OzzImporter; -bool ImportSkeleton(const Json::Value& _config, OzzImporter* _importer, - const ozz::Endianness _endianness); +OZZ_ANIMTOOLS_DLL bool ImportSkeleton(const Json::Value& _config, + OzzImporter* _importer, + const ozz::Endianness _endianness); } // namespace offline } // namespace animation diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_track.h b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_track.h index 405e0a6..9c0f1be 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_track.h +++ b/3rdparty/ozz-animation/src/animation/offline/tools/import2ozz_track.h @@ -28,12 +28,12 @@ #ifndef OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_TRACK_H_ #define OZZ_ANIMATION_OFFLINE_TOOLS_IMPORT2OZZ_TRACK_H_ +#include "animation/offline/tools/import2ozz_config.h" +#include "ozz/animation/offline/tools/export.h" +#include "ozz/animation/offline/tools/import2ozz.h" #include "ozz/base/endianness.h" #include "ozz/base/platform.h" -#include "animation/offline/tools/import2ozz_config.h" -#include "ozz/animation/offline/tools/import2ozz.h" - namespace Json { class Value; } @@ -44,12 +44,14 @@ class Skeleton; namespace offline { class OzzImporter; -bool ProcessTracks(OzzImporter& _importer, const char* _animation_name, - const Skeleton& _skeleton, const Json::Value& _config, - const ozz::Endianness _endianness); +OZZ_ANIMTOOLS_DLL bool ProcessTracks(OzzImporter& _importer, + const char* _animation_name, + const Skeleton& _skeleton, + const Json::Value& _config, + const ozz::Endianness _endianness); // Property type enum to config string conversions. -struct PropertyTypeConfig +struct OZZ_ANIMTOOLS_DLL PropertyTypeConfig : JsonEnum { static EnumNames GetNames(); }; diff --git a/3rdparty/ozz-animation/src/animation/offline/tools/reference.json b/3rdparty/ozz-animation/src/animation/offline/tools/reference.json index aefd48e..6da283c 100644 --- a/3rdparty/ozz-animation/src/animation/offline/tools/reference.json +++ b/3rdparty/ozz-animation/src/animation/offline/tools/reference.json @@ -29,7 +29,7 @@ "filename" : "*.ozz", // Specifies animation output filename. Use a '*' character to specify part(s) of the filename that should be replaced by the clip name. "raw" : false, // Outputs raw animation. "additive" : false, // Creates a delta animation that can be used for additive blending. - "additive_reference" : "animation", // Select reference pose to use to build additive/delta animation. Can be "animation" to use the 1st animation keyframe as reference, or "skeleton" to use skeleton bind pose. + "additive_reference" : "animation", // Select reference pose to use to build additive/delta animation. Can be "animation" to use the 1st animation keyframe as reference, or "skeleton" to use skeleton rest pose. "sampling_rate" : 0, // Selects animation sampling rate in hertz. Set a value <= 0 to use imported scene default frame rate. "optimize" : true, // Activates keyframes reduction optimization. "optimization_settings" : diff --git a/3rdparty/ozz-animation/src/animation/runtime/CMakeLists.txt b/3rdparty/ozz-animation/src/animation/runtime/CMakeLists.txt index e9b5da5..06b129e 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/animation/runtime/CMakeLists.txt @@ -1,4 +1,6 @@ -add_library(ozz_animation STATIC + +add_library(ozz_animation + ${PROJECT_SOURCE_DIR}/include/ozz/animation/runtime/export.h ${PROJECT_SOURCE_DIR}/include/ozz/animation/runtime/animation.h animation.cc animation_keyframe.h @@ -25,7 +27,11 @@ add_library(ozz_animation STATIC ${PROJECT_SOURCE_DIR}/include/ozz/animation/runtime/track_triggering_job.h ${PROJECT_SOURCE_DIR}/include/ozz/animation/runtime/track_triggering_job_trait.h track_triggering_job.cc) + +target_compile_definitions(ozz_animation PRIVATE $<$:OZZ_BUILD_ANIMATION_LIB>) + target_link_libraries(ozz_animation + PUBLIC ozz_base) set_target_properties(ozz_animation diff --git a/3rdparty/ozz-animation/src/animation/runtime/animation.cc b/3rdparty/ozz-animation/src/animation/runtime/animation.cc index 9963c13..26f7835 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/animation.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/animation.cc @@ -46,6 +46,19 @@ namespace animation { Animation::Animation() : duration_(0.f), num_tracks_(0), name_(nullptr) {} +Animation::Animation(Animation&& _other) { *this = std::move(_other); } + +Animation& Animation::operator=(Animation&& _other) { + std::swap(duration_, _other.duration_); + std::swap(num_tracks_, _other.num_tracks_); + std::swap(name_, _other.name_); + std::swap(translations_, _other.translations_); + std::swap(rotations_, _other.rotations_); + std::swap(scales_, _other.scales_); + + return *this; +} + Animation::~Animation() { Deallocate(); } void Animation::Allocate(size_t _name_len, size_t _translation_count, @@ -65,7 +78,7 @@ void Animation::Allocate(size_t _name_len, size_t _translation_count, _translation_count * sizeof(Float3Key) + _rotation_count * sizeof(QuaternionKey) + _scale_count * sizeof(Float3Key); - span buffer = {static_cast(memory::default_allocator()->Allocate( + span buffer = {static_cast(memory::default_allocator()->Allocate( buffer_size, alignof(Float3Key))), buffer_size}; diff --git a/3rdparty/ozz-animation/src/animation/runtime/animation_keyframe.h b/3rdparty/ozz-animation/src/animation/runtime/animation_keyframe.h index 56f9167..a5af047 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/animation_keyframe.h +++ b/3rdparty/ozz-animation/src/animation/runtime/animation_keyframe.h @@ -28,7 +28,9 @@ #ifndef OZZ_ANIMATION_RUNTIME_ANIMATION_KEYFRAME_H_ #define OZZ_ANIMATION_RUNTIME_ANIMATION_KEYFRAME_H_ +#include "ozz/animation/runtime/export.h" #include "ozz/base/platform.h" + #ifndef OZZ_INCLUDE_PRIVATE_HEADER #error "This header is private, it cannot be included from public headers." #endif // OZZ_INCLUDE_PRIVATE_HEADER @@ -46,7 +48,7 @@ namespace animation { // Defines the float3 key frame type, used for translations and scales. // Translation values are stored as half precision floats with 16 bits per // component. -struct Float3Key { +struct OZZ_ANIMATION_DLL Float3Key { float ratio; uint16_t track; uint16_t value[3]; @@ -67,7 +69,7 @@ struct Float3Key { // Quantization could be reduced to 11-11-10 bits as often used for animation // key frames, but in this case RotationKey structure would induce 16 bits of // padding. -struct QuaternionKey { +struct OZZ_ANIMATION_DLL QuaternionKey { float ratio; uint16_t track : 13; // The track this key frame belongs to. uint16_t largest : 2; // The largest component of the quaternion. diff --git a/3rdparty/ozz-animation/src/animation/runtime/blending_job.cc b/3rdparty/ozz-animation/src/animation/runtime/blending_job.cc index 082648c..e9990f7 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/blending_job.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/blending_job.cc @@ -69,12 +69,12 @@ bool BlendingJob::Validate() const { // Test for nullptr begin pointers. // Blending layers are mandatory, additive aren't. - valid &= !bind_pose.empty(); + valid &= !rest_pose.empty(); valid &= !output.empty(); - // The bind pose size defines the ranges of transforms to blend, so all + // The rest pose size defines the ranges of transforms to blend, so all // other buffers should be bigger. - const size_t min_range = bind_pose.size(); + const size_t min_range = rest_pose.size(); valid &= output.size() >= min_range; // Validates layers. @@ -160,7 +160,7 @@ namespace { struct ProcessArgs { ProcessArgs(const BlendingJob& _job) : job(_job), - num_soa_joints(_job.bind_pose.size()), + num_soa_joints(_job.rest_pose.size()), num_passes(0), num_partial_passes(0), accumulated_weight(0.f) { @@ -182,7 +182,7 @@ struct ProcessArgs { // The job to process. const BlendingJob& job; - // The number of transforms to process as defined by the size of the bind + // The number of transforms to process as defined by the size of the rest // pose. size_t num_soa_joints; @@ -271,24 +271,24 @@ void BlendLayers(ProcessArgs* _args) { } } -// Blends bind pose to the output if accumulated weight is less than the +// Blends rest pose to the output if accumulated weight is less than the // threshold value. -void BlendBindPose(ProcessArgs* _args) { +void BlendRestPose(ProcessArgs* _args) { assert(_args); // Asserts buffer sizes, which must never fail as it has been validated. - assert(_args->job.bind_pose.size() >= _args->num_soa_joints); + assert(_args->job.rest_pose.size() >= _args->num_soa_joints); if (_args->num_partial_passes == 0) { // No partial blending pass detected, threshold can be tested globally. const float bp_weight = _args->job.threshold - _args->accumulated_weight; - if (bp_weight > 0.f) { // The bind-pose is needed if it has a weight. + if (bp_weight > 0.f) { // The rest-pose is needed if it has a weight. if (_args->num_passes == 0) { - // Strictly copying bind-pose. + // Strictly copying rest-pose. _args->accumulated_weight = 1.f; for (size_t i = 0; i < _args->num_soa_joints; ++i) { - _args->job.output[i] = _args->job.bind_pose[i]; + _args->job.output[i] = _args->job.rest_pose[i]; } } else { // Updates global accumulated weight, but not per-joint weight any more @@ -299,7 +299,7 @@ void BlendBindPose(ProcessArgs* _args) { math::simd_float4::Load1(bp_weight); for (size_t i = 0; i < _args->num_soa_joints; ++i) { - const math::SoaTransform& src = _args->job.bind_pose[i]; + const math::SoaTransform& src = _args->job.rest_pose[i]; math::SoaTransform* dest = _args->job.output.begin() + i; OZZ_BLEND_N_PASS(src, simd_bp_weight, dest); } @@ -315,7 +315,7 @@ void BlendBindPose(ProcessArgs* _args) { assert(_args->num_passes != 0); for (size_t i = 0; i < _args->num_soa_joints; ++i) { - const math::SoaTransform& src = _args->job.bind_pose[i]; + const math::SoaTransform& src = _args->job.rest_pose[i]; math::SoaTransform* dest = _args->job.output.begin() + i; const math::SimdFloat4 bp_weight = math::Max0(threshold - _args->accumulated_weights[i]); @@ -442,8 +442,8 @@ bool BlendingJob::Run() const { // Blends all layers to the job output buffers. BlendLayers(&process_args); - // Applies bind pose. - BlendBindPose(&process_args); + // Applies rest pose. + BlendRestPose(&process_args); // Normalizes output. Normalize(&process_args); diff --git a/3rdparty/ozz-animation/src/animation/runtime/sampling_job.cc b/3rdparty/ozz-animation/src/animation/runtime/sampling_job.cc index 75ac1b4..070141c 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/sampling_job.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/sampling_job.cc @@ -60,22 +60,21 @@ bool SamplingJob::Validate() const { bool valid = true; // Test for nullptr pointers. - if (!animation || !cache) { + if (!animation || !context) { return false; } valid &= !output.empty(); const int num_soa_tracks = animation->num_soa_tracks(); - valid &= output.size() >= static_cast(num_soa_tracks); - // Tests cache size. - valid &= cache->max_soa_tracks() >= num_soa_tracks; + // Tests context size. + valid &= context->max_soa_tracks() >= num_soa_tracks; return valid; } namespace { -// Loops through the sorted key frames and update cache structure. +// Loops through the sorted key frames and update context structure. template void UpdateCacheCursor(float _ratio, int _num_soa_tracks, const ozz::span& _keys, int* _cursor, @@ -118,16 +117,16 @@ void UpdateCacheCursor(float _ratio, int _num_soa_tracks, } // Search for the keys that matches _ratio. - // Iterates while the cache is not updated with left and right keys required + // Iterates while the context is not updated with left and right keys required // for interpolation at time ratio _ratio, for all tracks. Thanks to the // keyframe sorting, the loop can end as soon as it finds a key greater that // _ratio. It will mean that all the keys lower than _ratio have been - // processed, meaning all cache entries are up to date. + // processed, meaning all context entries are up to date. while (cursor < _keys.end() && _keys[_cache[cursor->track * 2 + 1]].ratio <= _ratio) { // Flag this soa entry as outdated. _outdated[cursor->track / 32] |= (1 << ((cursor->track & 0x1f) / 4)); - // Updates cache. + // Updates context. const int base = cursor->track * 2; _cache[base] = _cache[base + 1]; _cache[base + 1] = static_cast(cursor - _keys.begin()); @@ -293,7 +292,7 @@ void Interpolates(float _anim_ratio, int _num_soa_tracks, } } // namespace -SamplingJob::SamplingJob() : ratio(0.f), animation(nullptr), cache(nullptr) {} +SamplingJob::SamplingJob() : ratio(0.f), animation(nullptr), context(nullptr) {} bool SamplingJob::Run() const { if (!Validate()) { @@ -308,60 +307,64 @@ bool SamplingJob::Run() const { // Clamps ratio in range [0,duration]. const float anim_ratio = math::Clamp(0.f, ratio, 1.f); - // Step the cache to this potentially new animation and ratio. - assert(cache->max_soa_tracks() >= num_soa_tracks); - cache->Step(*animation, anim_ratio); + // Step the context to this potentially new animation and ratio. + assert(context->max_soa_tracks() >= num_soa_tracks); + context->Step(*animation, anim_ratio); - // Fetch key frames from the animation to the cache a r = anim_ratio. + // Fetch key frames from the animation to the context at r = anim_ratio. // Then updates outdated soa hot values. UpdateCacheCursor(anim_ratio, num_soa_tracks, animation->translations(), - &cache->translation_cursor_, cache->translation_keys_, - cache->outdated_translations_); + &context->translation_cursor_, context->translation_keys_, + context->outdated_translations_); UpdateInterpKeyframes(num_soa_tracks, animation->translations(), - cache->translation_keys_, cache->outdated_translations_, - cache->soa_translations_, &DecompressFloat3); + context->translation_keys_, + context->outdated_translations_, + context->soa_translations_, &DecompressFloat3); UpdateCacheCursor(anim_ratio, num_soa_tracks, animation->rotations(), - &cache->rotation_cursor_, cache->rotation_keys_, - cache->outdated_rotations_); + &context->rotation_cursor_, context->rotation_keys_, + context->outdated_rotations_); UpdateInterpKeyframes(num_soa_tracks, animation->rotations(), - cache->rotation_keys_, cache->outdated_rotations_, - cache->soa_rotations_, &DecompressQuaternion); + context->rotation_keys_, context->outdated_rotations_, + context->soa_rotations_, &DecompressQuaternion); UpdateCacheCursor(anim_ratio, num_soa_tracks, animation->scales(), - &cache->scale_cursor_, cache->scale_keys_, - cache->outdated_scales_); - UpdateInterpKeyframes(num_soa_tracks, animation->scales(), cache->scale_keys_, - cache->outdated_scales_, cache->soa_scales_, - &DecompressFloat3); + &context->scale_cursor_, context->scale_keys_, + context->outdated_scales_); + UpdateInterpKeyframes(num_soa_tracks, animation->scales(), + context->scale_keys_, context->outdated_scales_, + context->soa_scales_, &DecompressFloat3); + + // only interp as much as we have output for. + const int num_soa_interp_tracks = math::Min(static_cast< int >(output.size()), num_soa_tracks); // Interpolates soa hot data. - Interpolates(anim_ratio, num_soa_tracks, cache->soa_translations_, - cache->soa_rotations_, cache->soa_scales_, output.begin()); + Interpolates(anim_ratio, num_soa_interp_tracks, context->soa_translations_, + context->soa_rotations_, context->soa_scales_, output.begin()); return true; } -SamplingCache::SamplingCache() +SamplingJob::Context::Context() : max_soa_tracks_(0), soa_translations_( nullptr) { // soa_translations_ is the allocation pointer. Invalidate(); } -SamplingCache::SamplingCache(int _max_tracks) +SamplingJob::Context::Context(int _max_tracks) : max_soa_tracks_(0), soa_translations_( nullptr) { // soa_translations_ is the allocation pointer. Resize(_max_tracks); } -SamplingCache::~SamplingCache() { +SamplingJob::Context::~Context() { // Deallocates everything at once. memory::default_allocator()->Deallocate(soa_translations_); } -void SamplingCache::Resize(int _max_tracks) { +void SamplingJob::Context::Resize(int _max_tracks) { using internal::InterpSoaFloat3; using internal::InterpSoaQuaternion; @@ -372,7 +375,7 @@ void SamplingCache::Resize(int _max_tracks) { // Updates maximum supported soa tracks. max_soa_tracks_ = (_max_tracks + 3) / 4; - // Allocate all cache data at once in a single allocation. + // Allocate all context data at once in a single allocation. // Alignment is guaranteed because memory is dispatch from the highest // alignment requirement (Soa data: SimdFloat4) to the lowest (outdated // flag: unsigned char). @@ -430,8 +433,9 @@ void SamplingCache::Resize(int _max_tracks) { assert(alloc_cursor == alloc_begin + size); } -void SamplingCache::Step(const Animation& _animation, float _ratio) { - // The cache is invalidated if animation has changed or if it is being rewind. +void SamplingJob::Context::Step(const Animation& _animation, float _ratio) { + // The context is invalidated if animation has changed or if it is being + // rewind. if (animation_ != &_animation || _ratio < ratio_) { animation_ = &_animation; translation_cursor_ = 0; @@ -441,7 +445,7 @@ void SamplingCache::Step(const Animation& _animation, float _ratio) { ratio_ = _ratio; } -void SamplingCache::Invalidate() { +void SamplingJob::Context::Invalidate() { animation_ = nullptr; ratio_ = 0.f; translation_cursor_ = 0; diff --git a/3rdparty/ozz-animation/src/animation/runtime/skeleton.cc b/3rdparty/ozz-animation/src/animation/runtime/skeleton.cc index 56a87b6..94db603 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/skeleton.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/skeleton.cc @@ -41,6 +41,16 @@ namespace animation { Skeleton::Skeleton() {} +Skeleton::Skeleton(Skeleton&& _other) { *this = std::move(_other); } + +Skeleton& Skeleton::operator=(Skeleton&& _other) { + std::swap(joint_rest_poses_, _other.joint_rest_poses_); + std::swap(joint_parents_, _other.joint_parents_); + std::swap(joint_names_, _other.joint_names_); + + return *this; +} + Skeleton::~Skeleton() { Deallocate(); } char* Skeleton::Allocate(size_t _chars_size, size_t _num_joints) { @@ -51,7 +61,7 @@ char* Skeleton::Allocate(size_t _chars_size, size_t _num_joints) { alignof(int16_t) >= alignof(char), "Must serve larger alignment values first)"); - assert(joint_bind_poses_.size() == 0 && joint_names_.size() == 0 && + assert(joint_rest_poses_.size() == 0 && joint_names_.size() == 0 && joint_parents_.size() == 0); // Early out if no joint. @@ -59,23 +69,23 @@ char* Skeleton::Allocate(size_t _chars_size, size_t _num_joints) { return nullptr; } - // Bind poses have SoA format + // Rest poses have SoA format const size_t num_soa_joints = (_num_joints + 3) / 4; - const size_t joint_bind_poses_size = + const size_t joint_rest_poses_size = num_soa_joints * sizeof(math::SoaTransform); const size_t names_size = _num_joints * sizeof(char*); const size_t joint_parents_size = _num_joints * sizeof(int16_t); const size_t buffer_size = - names_size + _chars_size + joint_parents_size + joint_bind_poses_size; + names_size + _chars_size + joint_parents_size + joint_rest_poses_size; // Allocates whole buffer. - span buffer = {static_cast(memory::default_allocator()->Allocate( + span buffer = {static_cast(memory::default_allocator()->Allocate( buffer_size, alignof(math::SoaTransform))), buffer_size}; // Serves larger alignment values first. - // Bind pose first, biggest alignment. - joint_bind_poses_ = fill_span(buffer, num_soa_joints); + // Rest pose first, biggest alignment. + joint_rest_poses_ = fill_span(buffer, num_soa_joints); // Then names array, second biggest alignment. joint_names_ = fill_span(buffer, _num_joints); @@ -86,12 +96,13 @@ char* Skeleton::Allocate(size_t _chars_size, size_t _num_joints) { // Remaning buffer will be used to store joint names. assert(buffer.size_bytes() == _chars_size && "Whole buffer should be consumned"); - return buffer.data(); + return reinterpret_cast(buffer.data()); } void Skeleton::Deallocate() { - memory::default_allocator()->Deallocate(as_writable_bytes(joint_bind_poses_).data()); - joint_bind_poses_ = {}; + memory::default_allocator()->Deallocate( + as_writable_bytes(joint_rest_poses_).data()); + joint_rest_poses_ = {}; joint_names_ = {}; joint_parents_ = {}; } @@ -114,7 +125,7 @@ void Skeleton::Save(ozz::io::OArchive& _archive) const { _archive << static_cast(chars_count); _archive << ozz::io::MakeArray(joint_names_[0], chars_count); _archive << ozz::io::MakeArray(joint_parents_); - _archive << ozz::io::MakeArray(joint_bind_poses_); + _archive << ozz::io::MakeArray(joint_rest_poses_); } void Skeleton::Load(ozz::io::IArchive& _archive, uint32_t _version) { @@ -155,7 +166,7 @@ void Skeleton::Load(ozz::io::IArchive& _archive, uint32_t _version) { joint_names_[num_joints - 1] = cursor; _archive >> ozz::io::MakeArray(joint_parents_); - _archive >> ozz::io::MakeArray(joint_bind_poses_); + _archive >> ozz::io::MakeArray(joint_rest_poses_); } } // namespace animation } // namespace ozz diff --git a/3rdparty/ozz-animation/src/animation/runtime/skeleton_utils.cc b/3rdparty/ozz-animation/src/animation/runtime/skeleton_utils.cc index 3440a13..2e8a556 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/skeleton_utils.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/skeleton_utils.cc @@ -27,21 +27,33 @@ #include "ozz/animation/runtime/skeleton_utils.h" -#include "ozz/base/maths/soa_transform.h" - #include +#include + +#include "ozz/base/maths/soa_transform.h" + namespace ozz { namespace animation { -// Unpacks skeleton bind pose stored in soa format by the skeleton. -ozz::math::Transform GetJointLocalBindPose(const Skeleton& _skeleton, +int FindJoint(const Skeleton& _skeleton, const char* _name) { + const auto& names = _skeleton.joint_names(); + for (size_t i = 0; i < names.size(); ++i) { + if (std::strcmp(names[i], _name) == 0) { + return static_cast(i); + } + } + return -1; +} + +// Unpacks skeleton rest pose stored in soa format by the skeleton. +ozz::math::Transform GetJointLocalRestPose(const Skeleton& _skeleton, int _joint) { assert(_joint >= 0 && _joint < _skeleton.num_joints() && "Joint index out of range."); const ozz::math::SoaTransform& soa_transform = - _skeleton.joint_bind_poses()[_joint / 4]; + _skeleton.joint_rest_poses()[_joint / 4]; // Transpose SoA data to AoS. ozz::math::SimdFloat4 translations[4]; @@ -52,13 +64,13 @@ ozz::math::Transform GetJointLocalBindPose(const Skeleton& _skeleton, ozz::math::Transpose3x4(&soa_transform.scale.x, scales); // Stores to the Transform object. - math::Transform bind_pose; + math::Transform rest_pose; const int offset = _joint % 4; - ozz::math::Store3PtrU(translations[offset], &bind_pose.translation.x); - ozz::math::StorePtrU(rotations[offset], &bind_pose.rotation.x); - ozz::math::Store3PtrU(scales[offset], &bind_pose.scale.x); + ozz::math::Store3PtrU(translations[offset], &rest_pose.translation.x); + ozz::math::StorePtrU(rotations[offset], &rest_pose.rotation.x); + ozz::math::Store3PtrU(scales[offset], &rest_pose.scale.x); - return bind_pose; + return rest_pose; } } // namespace animation } // namespace ozz diff --git a/3rdparty/ozz-animation/src/animation/runtime/track.cc b/3rdparty/ozz-animation/src/animation/runtime/track.cc index 6d43ee9..e91838d 100644 --- a/3rdparty/ozz-animation/src/animation/runtime/track.cc +++ b/3rdparty/ozz-animation/src/animation/runtime/track.cc @@ -43,6 +43,20 @@ namespace internal { template Track<_ValueType>::Track() : name_(nullptr) {} +template +Track<_ValueType>::Track(Track<_ValueType>&& _other) { + *this = std::move(_other); +} + +template +Track<_ValueType>& Track<_ValueType>::operator=(Track<_ValueType>&& _other) { + std::swap(ratios_, _other.ratios_); + std::swap(values_, _other.values_); + std::swap(steps_, _other.steps_); + std::swap(name_, _other.name_); + return *this; +} + template Track<_ValueType>::~Track() { Deallocate(); @@ -63,7 +77,7 @@ void Track<_ValueType>::Allocate(size_t _keys_count, size_t _name_len) { _keys_count * sizeof(float) + // ratios (_keys_count + 7) * sizeof(uint8_t) / 8 + // steps (_name_len > 0 ? _name_len + 1 : 0); - span buffer = {static_cast(memory::default_allocator()->Allocate( + span buffer = {static_cast(memory::default_allocator()->Allocate( buffer_size, alignof(_ValueType))), buffer_size}; @@ -142,11 +156,11 @@ void Track<_ValueType>::Load(ozz::io::IArchive& _archive, uint32_t _version) { } // Explicitly instantiate supported tracks. -template class Track; -template class Track; -template class Track; -template class Track; -template class Track; +template class OZZ_ANIMATION_DLL Track; +template class OZZ_ANIMATION_DLL Track; +template class OZZ_ANIMATION_DLL Track; +template class OZZ_ANIMATION_DLL Track; +template class OZZ_ANIMATION_DLL Track; } // namespace internal } // namespace animation diff --git a/3rdparty/ozz-animation/src/base/CMakeLists.txt b/3rdparty/ozz-animation/src/base/CMakeLists.txt index 1e6bbc3..97b069e 100644 --- a/3rdparty/ozz-animation/src/base/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/base/CMakeLists.txt @@ -1,4 +1,6 @@ -add_library(ozz_base STATIC + +add_library(ozz_base + ${PROJECT_SOURCE_DIR}/include/ozz/base/export.h ${PROJECT_SOURCE_DIR}/include/ozz/base/endianness.h ${PROJECT_SOURCE_DIR}/include/ozz/base/gtest_helper.h ${PROJECT_SOURCE_DIR}/include/ozz/base/memory/allocator.h @@ -54,11 +56,19 @@ add_library(ozz_base STATIC maths/soa_math_archive.cc ${PROJECT_SOURCE_DIR}/include/ozz/base/maths/simd_math_archive.h maths/simd_math_archive.cc) + +target_compile_definitions(ozz_base + PUBLIC $<$:OZZ_USE_DYNAMIC_LINKING> + PRIVATE $<$:OZZ_BUILD_BASE_LIB>) + +target_compile_options(ozz_base PUBLIC $<$:/wd4251>) target_include_directories(ozz_base PUBLIC $ $/include>) + set_target_properties(ozz_base PROPERTIES FOLDER "ozz") install(TARGETS ozz_base DESTINATION lib) fuse_target("ozz_base") + diff --git a/3rdparty/ozz-animation/src/base/io/stream.cc b/3rdparty/ozz-animation/src/base/io/stream.cc index caf3ad2..414b0a4 100644 --- a/3rdparty/ozz-animation/src/base/io/stream.cc +++ b/3rdparty/ozz-animation/src/base/io/stream.cc @@ -182,7 +182,7 @@ int MemoryStream::Seek(int _offset, Origin _origin) { // Exit if seeking before file begin or beyond max file size. if (origin < -_offset || - (_offset > 0 && origin > static_cast(kMaxSize - _offset))) { + (_offset > 0 && origin > static_cast(kMaxSize) - _offset)) { return -1; } @@ -204,9 +204,11 @@ bool MemoryStream::Resize(size_t _size) { (MemoryStream::kBufferSizeIncrement & (kBufferSizeIncrement - 1)) == 0, "kBufferSizeIncrement must be a power of 2"); const size_t new_size = ozz::Align(_size, kBufferSizeIncrement); - char* new_buffer = reinterpret_cast( + byte* new_buffer = reinterpret_cast( ozz::memory::default_allocator()->Allocate(new_size, 16)); - std::memcpy(new_buffer, buffer_, alloc_size_); + if (buffer_ != nullptr) { + std::memcpy(new_buffer, buffer_, alloc_size_); + } ozz::memory::default_allocator()->Deallocate(buffer_); buffer_ = new_buffer; alloc_size_ = new_size; diff --git a/3rdparty/ozz-animation/src/geometry/runtime/CMakeLists.txt b/3rdparty/ozz-animation/src/geometry/runtime/CMakeLists.txt index d1320e6..92376d0 100644 --- a/3rdparty/ozz-animation/src/geometry/runtime/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/geometry/runtime/CMakeLists.txt @@ -1,10 +1,11 @@ -add_library(ozz_geometry STATIC +add_library(ozz_geometry + ${PROJECT_SOURCE_DIR}/include/ozz/geometry/runtime/export.h ${PROJECT_SOURCE_DIR}/include/ozz/geometry/runtime/skinning_job.h - skinning_job.cc) -target_link_libraries(ozz_geometry - ozz_base) -set_target_properties(ozz_geometry - PROPERTIES FOLDER "ozz") +skinning_job.cc) +target_compile_definitions(ozz_geometry PRIVATE $<$:OZZ_BUILD_GEOMETRY_LIB>) + +target_link_libraries(ozz_geometry ozz_base) +set_target_properties(ozz_geometry PROPERTIES FOLDER "ozz") install(TARGETS ozz_geometry DESTINATION lib) diff --git a/3rdparty/ozz-animation/src/options/CMakeLists.txt b/3rdparty/ozz-animation/src/options/CMakeLists.txt index 7666459..a477b19 100644 --- a/3rdparty/ozz-animation/src/options/CMakeLists.txt +++ b/3rdparty/ozz-animation/src/options/CMakeLists.txt @@ -1,9 +1,11 @@ -add_library(ozz_options STATIC - ../../include/ozz/options/options.h +add_library(ozz_options + ${PROJECT_SOURCE_DIR}/include/ozz/options/export.h + ${PROJECT_SOURCE_DIR}/include/ozz/options/options.h options.cc) -target_include_directories(ozz_options PUBLIC - $ - $/include>) +target_link_libraries(ozz_options ozz_base) + +target_compile_definitions(ozz_options PRIVATE $<$:OZZ_BUILD_OPTIONS_LIB>) + set_target_properties(ozz_options PROPERTIES FOLDER "ozz") install(TARGETS ozz_options DESTINATION lib) diff --git a/3rdparty/ozz-animation/src/options/options.cc b/3rdparty/ozz-animation/src/options/options.cc index 34681cc..446e5f3 100644 --- a/3rdparty/ozz-animation/src/options/options.cc +++ b/3rdparty/ozz-animation/src/options/options.cc @@ -107,10 +107,10 @@ Registrer<_Option>::~Registrer() { } // Explicit instantiation of all supported types of Registrer. -template class Registrer>; -template class Registrer>; -template class Registrer>; -template class Registrer>; +template class OZZ_OPTIONS_DLL Registrer>; +template class OZZ_OPTIONS_DLL Registrer>; +template class OZZ_OPTIONS_DLL Registrer>; +template class OZZ_OPTIONS_DLL Registrer>; } // namespace internal // Construct the parser if no option is registered. @@ -130,10 +130,10 @@ ParseResult ParseCommandLine(int _argc, const char* const* _argv, // A nullptr parser means that no option is registered and that ParseCommandLine // has not been called. -std::string ParsedExecutablePath() { +ozz::string ParsedExecutablePath() { Parser* parser = internal::g_global_registrer.parser(); if (!parser) { - return std::string(); + return {}; } return parser->executable_path(); } @@ -368,10 +368,10 @@ bool TypedOption<_Type>::ParseImpl(const char* _argv) { } template -std::string TypedOption<_Type>::FormatDefault() const { +ozz::string TypedOption<_Type>::FormatDefault() const { std::stringstream str; str << "\"" << std::boolalpha << default_ << "\""; - return str.str(); + return str.str().c_str(); } template @@ -648,8 +648,8 @@ const char* Parser::usage() const { return usage_; } const char* Parser::version() const { return version_; } -std::string Parser::executable_path() const { - return std::string(executable_path_begin_, executable_path_end_); +ozz::string Parser::executable_path() const { + return ozz::string(executable_path_begin_, executable_path_end_); } const char* Parser::executable_name() const { return executable_name_; } diff --git a/3rdparty/ozz-animation/test/animation/offline/CMakeLists.txt b/3rdparty/ozz-animation/test/animation/offline/CMakeLists.txt index d7eb5bd..d1a6330 100644 --- a/3rdparty/ozz-animation/test/animation/offline/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/animation/offline/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(test_animation_builder target_link_libraries(test_animation_builder ozz_animation_offline gtest) +target_copy_shared_libraries(test_animation_builder) set_target_properties(test_animation_builder PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_animation_builder COMMAND test_animation_builder) @@ -11,6 +12,7 @@ add_executable(test_animation_optimizer target_link_libraries(test_animation_optimizer ozz_animation_offline gtest) +target_copy_shared_libraries(test_animation_optimizer) set_target_properties(test_animation_optimizer PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_animation_optimizer COMMAND test_animation_optimizer) @@ -19,6 +21,7 @@ add_executable(test_raw_animation_utils target_link_libraries(test_raw_animation_utils ozz_animation_offline gtest) +target_copy_shared_libraries(test_raw_animation_utils) set_target_properties(test_raw_animation_utils PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_animation_utils COMMAND test_raw_animation_utils) @@ -27,6 +30,7 @@ add_executable(test_additive_animation_builder target_link_libraries(test_additive_animation_builder ozz_animation_offline gtest) +target_copy_shared_libraries(test_additive_animation_builder) set_target_properties(test_additive_animation_builder PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_additive_animation_builder COMMAND test_additive_animation_builder) @@ -35,6 +39,7 @@ add_executable(test_skeleton_builder target_link_libraries(test_skeleton_builder ozz_animation_offline gtest) +target_copy_shared_libraries(test_skeleton_builder) set_target_properties(test_skeleton_builder PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_skeleton_builder COMMAND test_skeleton_builder) @@ -43,6 +48,7 @@ add_executable(test_raw_skeleton_archive target_link_libraries(test_raw_skeleton_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_raw_skeleton_archive) set_target_properties(test_raw_skeleton_archive PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_skeleton_archive COMMAND test_raw_skeleton_archive) @@ -53,6 +59,7 @@ target_link_libraries(test_track_builder ozz_animation ozz_base gtest) +target_copy_shared_libraries(test_track_builder) set_target_properties(test_track_builder PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_track_builder COMMAND test_track_builder) @@ -63,16 +70,17 @@ target_link_libraries(test_track_optimizer ozz_animation ozz_base gtest) +target_copy_shared_libraries(test_track_optimizer) set_target_properties(test_track_optimizer PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_track_optimizer COMMAND test_track_optimizer) add_executable(test_raw_skeleton_archive_versioning raw_skeleton_archive_versioning_tests.cc) - target_link_libraries(test_raw_skeleton_archive_versioning ozz_animation_offline ozz_options gtest) +target_copy_shared_libraries(test_raw_skeleton_archive_versioning) set_target_properties(test_raw_skeleton_archive_versioning PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_skeleton_archive_versioning_le COMMAND test_raw_skeleton_archive_versioning "--file=${ozz_media_directory}/bin/versioning/raw_skeleton_v1_le.ozz" "--joints=67" "--root_name=Hips") @@ -83,6 +91,7 @@ add_executable(test_raw_animation_archive target_link_libraries(test_raw_animation_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_raw_animation_archive) set_target_properties(test_raw_animation_archive PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_animation_archive COMMAND test_raw_animation_archive) @@ -92,6 +101,7 @@ target_link_libraries(test_raw_animation_archive_versioning ozz_animation_offline ozz_options gtest) +target_copy_shared_libraries(test_raw_animation_archive_versioning) set_target_properties(test_raw_animation_archive_versioning PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_animation_archive_versioning_le COMMAND test_raw_animation_archive_versioning "--file=${ozz_media_directory}/bin/versioning/raw_animation_v3_le.ozz" "--tracks=67" "--duration=.66666667" "--name=run") @@ -107,6 +117,7 @@ add_executable(test_raw_track_archive target_link_libraries(test_raw_track_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_raw_track_archive) set_target_properties(test_raw_track_archive PROPERTIES FOLDER "ozz/tests/animation_offline") add_test(NAME test_raw_track_archive COMMAND test_raw_track_archive) @@ -119,8 +130,10 @@ add_dependencies(test_fuse_animation_offline BUILD_FUSE_ozz_animation_offline) target_link_libraries(test_fuse_animation_offline ozz_animation gtest) +#target_copy_shared_libraries(test_fuse_animation_offline) add_test(NAME test_fuse_animation_offline COMMAND test_fuse_animation_offline) set_target_properties(test_fuse_animation_offline PROPERTIES FOLDER "ozz/tests/animation_offline") +target_compile_definitions(test_fuse_animation_offline PRIVATE $<$:OZZ_BUILD_ANIMOFFLINE_LIB>) add_subdirectory(fbx) add_subdirectory(gltf) diff --git a/3rdparty/ozz-animation/test/animation/offline/additive_animation_builder_tests.cc b/3rdparty/ozz-animation/test/animation/offline/additive_animation_builder_tests.cc index 03a0db3..aed86e6 100644 --- a/3rdparty/ozz-animation/test/animation/offline/additive_animation_builder_tests.cc +++ b/3rdparty/ozz-animation/test/animation/offline/additive_animation_builder_tests.cc @@ -25,16 +25,13 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/offline/additive_animation_builder.h" - #include "gtest/gtest.h" - +#include "ozz/animation/offline/additive_animation_builder.h" +#include "ozz/animation/offline/raw_animation.h" #include "ozz/base/maths/gtest_math_helper.h" #include "ozz/base/maths/math_constant.h" #include "ozz/base/maths/transform.h" -#include "ozz/animation/offline/raw_animation.h" - using ozz::animation::offline::AdditiveAnimationBuilder; using ozz::animation::offline::RawAnimation; @@ -85,6 +82,7 @@ TEST(Build, AdditiveAnimationBuilder) { AdditiveAnimationBuilder builder; RawAnimation input; + input.name = "test"; input.duration = 1.f; input.tracks.resize(3); @@ -140,6 +138,7 @@ TEST(Build, AdditiveAnimationBuilder) { { RawAnimation output; ASSERT_TRUE(builder(input, &output)); + EXPECT_STREQ(output.name.c_str(), input.name.c_str()); EXPECT_EQ(output.num_tracks(), 3); // 1st track. @@ -199,6 +198,7 @@ TEST(BuildRefPose, AdditiveAnimationBuilder) { RawAnimation input; input.duration = 1.f; input.tracks.resize(3); + input.name = "test"; // First track is empty { @@ -263,6 +263,7 @@ TEST(BuildRefPose, AdditiveAnimationBuilder) { RawAnimation output; ASSERT_TRUE( builder(input, ozz::span(ref_pose), &output)); + EXPECT_STREQ(output.name.c_str(), input.name.c_str()); EXPECT_EQ(output.num_tracks(), 3); // 1st track. diff --git a/3rdparty/ozz-animation/test/animation/offline/animation_builder_tests.cc b/3rdparty/ozz-animation/test/animation/offline/animation_builder_tests.cc index c0f6bcc..2fd4d64 100644 --- a/3rdparty/ozz-animation/test/animation/offline/animation_builder_tests.cc +++ b/3rdparty/ozz-animation/test/animation/offline/animation_builder_tests.cc @@ -25,19 +25,15 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/offline/animation_builder.h" - #include "gtest/gtest.h" -#include "ozz/base/maths/gtest_math_helper.h" - -#include "ozz/base/maths/soa_transform.h" -#include "ozz/base/memory/unique_ptr.h" - +#include "ozz/animation/offline/animation_builder.h" #include "ozz/animation/offline/raw_animation.h" - #include "ozz/animation/runtime/animation.h" #include "ozz/animation/runtime/sampling_job.h" #include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/maths/gtest_math_helper.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/memory/unique_ptr.h" using ozz::animation::Animation; using ozz::animation::offline::AnimationBuilder; @@ -220,6 +216,42 @@ TEST(Name, AnimationBuilder) { } } +TEST(Move, AnimationBuilder) { + AnimationBuilder builder; + RawAnimation raw_animation; + + { // Move constructor + raw_animation.name = "anim1"; + raw_animation.duration = 46.f; + raw_animation.tracks.resize(46); + ozz::unique_ptr anim1(builder(raw_animation)); + const Animation canim(std::move(*anim1)); + EXPECT_FLOAT_EQ(canim.duration(), 46.f); + EXPECT_STREQ(canim.name(), "anim1"); + } + + { // Move assignment + raw_animation.name = "anim1"; + raw_animation.duration = 46.f; + raw_animation.tracks.resize(46); + ozz::unique_ptr anim1(builder(raw_animation)); + EXPECT_STREQ(anim1->name(), "anim1"); + EXPECT_EQ(anim1->num_tracks(), 46); + + raw_animation.name = "anim2"; + raw_animation.duration = 93.f; + raw_animation.tracks.resize(93); + ozz::unique_ptr anim2(builder(raw_animation)); + EXPECT_STREQ(anim2->name(), "anim2"); + EXPECT_EQ(anim2->num_tracks(), 93); + + *anim2 = std::move(*anim1); + EXPECT_FLOAT_EQ(anim2->duration(), 46.f); + EXPECT_EQ(anim2->num_tracks(), 46); + EXPECT_STREQ(anim2->name(), "anim1"); + } +} + TEST(Sort, AnimationBuilder) { // Instantiates a builder objects with default parameters. AnimationBuilder builder; @@ -300,10 +332,10 @@ TEST(Sort, AnimationBuilder) { // Needs to sample to test the animation. ozz::animation::SamplingJob job; - ozz::animation::SamplingCache cache(1); + ozz::animation::SamplingJob::Context context(1); ozz::math::SoaTransform output[1]; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; // Samples and compares the two animations diff --git a/3rdparty/ozz-animation/test/animation/offline/fbx/CMakeLists.txt b/3rdparty/ozz-animation/test/animation/offline/fbx/CMakeLists.txt index e103d83..8d4f80a 100644 --- a/3rdparty/ozz-animation/test/animation/offline/fbx/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/animation/offline/fbx/CMakeLists.txt @@ -152,18 +152,14 @@ endif() # ozz_animation_fbx fuse tests set_source_files_properties(${PROJECT_BINARY_DIR}/src_fused/ozz_animation_fbx.cc PROPERTIES GENERATED 1) add_executable(test_fuse_ozz_animation_fbx - fuse_ozz_animation_fbx_tests + fuse_ozz_animation_fbx_tests.cc ${PROJECT_BINARY_DIR}/src_fused/ozz_animation_fbx.cc) add_dependencies(test_fuse_ozz_animation_fbx BUILD_FUSE_ozz_animation_fbx) -target_include_directories(test_fuse_ozz_animation_fbx - PUBLIC ${FBX_INCLUDE_DIRS}) -target_compile_options(test_fuse_ozz_animation_fbx - PUBLIC $<$:-Wno-null-dereference> - PUBLIC $<$:-Wno-pragma-pack>) target_link_libraries(test_fuse_ozz_animation_fbx - debug ${FBX_LIBRARIES_DEBUG} - optimized ${FBX_LIBRARIES} - ozz_animation_offline) + ozz_animation_offline + fbx::sdk) +target_copy_shared_libraries(test_fuse_ozz_animation_fbx) set_target_properties(test_fuse_ozz_animation_fbx PROPERTIES FOLDER "ozz/tests/animation_offline") +target_compile_definitions(test_fuse_ozz_animation_fbx PRIVATE $<$:OZZ_BUILD_ANIMATIONFBX_LIB>) add_test(NAME test_fuse_ozz_animation_fbx COMMAND test_fuse_ozz_animation_fbx) diff --git a/3rdparty/ozz-animation/test/animation/offline/skeleton_builder_tests.cc b/3rdparty/ozz-animation/test/animation/offline/skeleton_builder_tests.cc index 115570a..8e2440c 100644 --- a/3rdparty/ozz-animation/test/animation/offline/skeleton_builder_tests.cc +++ b/3rdparty/ozz-animation/test/animation/offline/skeleton_builder_tests.cc @@ -25,20 +25,17 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/offline/raw_skeleton.h" -#include "ozz/animation/offline/skeleton_builder.h" - #include #include "gtest/gtest.h" - +#include "ozz/animation/offline/raw_skeleton.h" +#include "ozz/animation/offline/skeleton_builder.h" #include "ozz/animation/runtime/skeleton.h" +#include "ozz/base/maths/gtest_math_helper.h" #include "ozz/base/maths/simd_math.h" #include "ozz/base/maths/soa_transform.h" #include "ozz/base/memory/unique_ptr.h" -#include "ozz/base/maths/gtest_math_helper.h" - using ozz::animation::Skeleton; using ozz::animation::offline::RawSkeleton; using ozz::animation::offline::SkeletonBuilder; @@ -606,7 +603,7 @@ TEST(MultiRoots, SkeletonBuilder) { } } -TEST(BindPose, SkeletonBuilder) { +TEST(RestPose, SkeletonBuilder) { using ozz::math::Float3; using ozz::math::Float4; using ozz::math::Quaternion; @@ -649,14 +646,14 @@ TEST(BindPose, SkeletonBuilder) { ozz::unique_ptr skeleton(builder(raw_skeleton)); ASSERT_TRUE(skeleton); - // Convert bind pose back to aos. + // Convert rest pose back to aos. ozz::math::SimdFloat4 translations[4]; ozz::math::SimdFloat4 scales[4]; ozz::math::SimdFloat4 rotations[4]; - const ozz::math::SoaTransform& bind_pose = skeleton->joint_bind_poses()[0]; - ozz::math::Transpose3x4(&bind_pose.translation.x, translations); - ozz::math::Transpose4x4(&bind_pose.rotation.x, rotations); - ozz::math::Transpose3x4(&bind_pose.scale.x, scales); + const ozz::math::SoaTransform& rest_pose = skeleton->joint_rest_poses()[0]; + ozz::math::Transpose3x4(&rest_pose.translation.x, translations); + ozz::math::Transpose4x4(&rest_pose.rotation.x, rotations); + ozz::math::Transpose3x4(&rest_pose.scale.x, scales); for (int i = 0; i < skeleton->num_joints(); ++i) { if (std::strcmp(skeleton->joint_names()[i], "j0") == 0) { @@ -707,3 +704,43 @@ TEST(MaxJoints, SkeletonBuilder) { EXPECT_TRUE(!builder(raw_skeleton)); } } + +TEST(Move, SkeletonBuilder) { + SkeletonBuilder builder; + RawSkeleton raw_skeleton; + + raw_skeleton.roots.resize(1); + RawSkeleton::Joint& root = raw_skeleton.roots[0]; + root.name = "j0"; + + root.children.resize(2); + root.children[0].name = "j1"; + root.children[1].name = "j2"; + + ozz::unique_ptr skeleton(builder(raw_skeleton)); + + { // Move constructor + root.name = "root1"; + ozz::unique_ptr skeleton1(builder(raw_skeleton)); + const Skeleton cskeleton(std::move(*skeleton1)); + EXPECT_STREQ(cskeleton.joint_names()[0], "root1"); + } + + { // Move assignment + root.name = "root1"; + root.children.resize(45); + ozz::unique_ptr skeleton1(builder(raw_skeleton)); + EXPECT_STREQ(skeleton1->joint_names()[0], "root1"); + EXPECT_EQ(skeleton1->num_joints(), 46); + + root.name = "root2"; + root.children.resize(92); + ozz::unique_ptr skeleton2(builder(raw_skeleton)); + EXPECT_STREQ(skeleton2->joint_names()[0], "root2"); + EXPECT_EQ(skeleton2->num_joints(), 93); + + *skeleton2 = std::move(*skeleton1); + EXPECT_STREQ(skeleton2->joint_names()[0], "root1"); + EXPECT_EQ(skeleton2->num_joints(), 46); + } +} diff --git a/3rdparty/ozz-animation/test/animation/offline/tools/CMakeLists.txt b/3rdparty/ozz-animation/test/animation/offline/tools/CMakeLists.txt index ab9f7ad..60ad851 100644 --- a/3rdparty/ozz-animation/test/animation/offline/tools/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/animation/offline/tools/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(test2ozz target_link_libraries(test2ozz ozz_animation_tools ozz_options) +target_copy_shared_libraries(test2ozz) set_target_properties(test2ozz PROPERTIES FOLDER "ozz/tests/animation_offline") @@ -18,6 +19,7 @@ file(WRITE "${ozz_temp_directory}/good.content1" "good content 1") file(WRITE "${ozz_temp_directory}/good.content2" "good content 2") file(WRITE "${ozz_temp_directory}/good.content_renamed" "good content renamed") file(WRITE "${ozz_temp_directory}/non_unique_names.content" "good content but not unique joint names") +file(WRITE "${ozz_temp_directory}/partial.good.content0" "partial good content") # Creates config test files. file(WRITE "${ozz_temp_directory}/valid_config.json" "{\"skeleton\":{\"filename\":\"${ozz_temp_directory}/skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"${ozz_temp_directory}/animation_valid_config.ozz\"}]}") @@ -179,6 +181,9 @@ set_tests_properties(test2ozz_anim_no_match PROPERTIES PASS_REGULAR_EXPRESSION " add_test(NAME test2ozz_anim_additive_wrong_ref COMMAND test2ozz "--file=${ozz_temp_directory}/good.content1" "--config={\"skeleton\":{\"filename\":\"${ozz_temp_directory}/skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"${ozz_temp_directory}/animation_${CMAKE_CURRENT_LIST_LINE}.ozz\",\"additive\":true,\"additive_reference\":\"anim\"}]}") set_tests_properties(test2ozz_anim_additive_wrong_ref PROPERTIES PASS_REGULAR_EXPRESSION "Invalid additive reference pose \"anim\"." DEPENDS test2ozz_skel_simple) +add_test(NAME test2ozz_anim_partial_good_content COMMAND test2ozz "--file=${ozz_temp_directory}/partial.good.content0" "--config={\"skeleton\":{\"filename\":\"${ozz_temp_directory}/skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"${ozz_temp_directory}/anim_good_part_content.ozz\"}]}") +set_tests_properties(test2ozz_anim_partial_good_content PROPERTIES PASS_REGULAR_EXPRESSION "One of animation failed when import" DEPENDS test2ozz_skel_simple) + # Run test2ozz track import failing tests #---------------------------- @@ -194,6 +199,9 @@ set_tests_properties(test2ozz_anim_track_bad_type PROPERTIES PASS_REGULAR_EXPRES add_test(NAME test2ozz_anim_track_invalid_type COMMAND test2ozz "--file=${ozz_temp_directory}/good.content1" "--config={\"skeleton\":{\"filename\":\"${ozz_temp_directory}/skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"${ozz_temp_directory}/animation_${CMAKE_CURRENT_LIST_LINE}.ozz\",\"tracks\":[{\"properties\":[{\"joint_name\":\"joint1\",\"property_name\":\"property2\",\"type\":\"1\",\"filename\":\"${ozz_temp_directory}/anim_should_not_exist.ozz\"}]}]}]}") set_tests_properties(test2ozz_anim_track_invalid_type PROPERTIES PASS_REGULAR_EXPRESSION "Invalid value \"1\" for import track type property." DEPENDS test2ozz_skel_simple) +add_test(NAME test2ozz_anim_track_import_failed COMMAND test2ozz "--file=${ozz_temp_directory}/partial.good.content0" "--config={\"skeleton\":{\"filename\":\"${ozz_temp_directory}/skeleton.ozz\",\"import\":{\"enable\":false}},\"animations\":[{\"filename\":\"${ozz_temp_directory}/anim_good_part_content.ozz\",\"tracks\":[{\"properties\":[{\"joint_name\":\"joint0\",\"property_name\":\"property0\",\"type\":\"float1\",\"filename\":\"${ozz_temp_directory}/anim_should_not_exist.ozz\"}]}]}]}") +set_tests_properties(test2ozz_anim_track_import_failed PROPERTIES PASS_REGULAR_EXPRESSION "One of track failed when import" DEPENDS test2ozz_skel_simple) + # Ensures nothing was outputted. add_test(NAME test2ozz_anim_output COMMAND ${CMAKE_COMMAND} -E copy "${ozz_temp_directory}/anim_should_not_exist.ozz" "${ozz_temp_directory}/anim_should_not_exist_too.ozz") set_tests_properties(test2ozz_anim_output PROPERTIES WILL_FAIL true) @@ -208,7 +216,8 @@ set_tests_properties(test2ozz_anim_output PROPERTIES test2ozz_anim_track_bad_joint_name test2ozz_anim_track_bad_ppt_name test2ozz_anim_track_bad_type - test2ozz_anim_track_invalid_type") + test2ozz_anim_track_invalid_type + test2ozz_anim_track_import_failed") # Run test2ozz animation import passing tests #---------------------------- @@ -391,8 +400,10 @@ target_link_libraries(test_fuse_ozz_animation_tools ozz_options json gtest) +#target_copy_shared_libraries(test_fuse_ozz_animation_tools) set_target_properties(test_fuse_ozz_animation_tools PROPERTIES FOLDER "ozz/tests/animation_offline") +target_compile_definitions(test_fuse_ozz_animation_tools PRIVATE $<$:OZZ_BUILD_ANIMATIONTOOLS_LIB>) add_test(NAME test_fuse_ozz_animation_tools_no_arg COMMAND test_fuse_ozz_animation_tools) set_tests_properties(test_fuse_ozz_animation_tools_no_arg PROPERTIES PASS_REGULAR_EXPRESSION "Required option \"file\" is not specified.") diff --git a/3rdparty/ozz-animation/test/animation/offline/tools/test2ozz.cc b/3rdparty/ozz-animation/test/animation/offline/tools/test2ozz.cc index 60aa029..07ee80a 100644 --- a/3rdparty/ozz-animation/test/animation/offline/tools/test2ozz.cc +++ b/3rdparty/ozz-animation/test/animation/offline/tools/test2ozz.cc @@ -45,12 +45,22 @@ class TestConverter : public ozz::animation::offline::OzzImporter { return false; } - const char good_content[] = "good content"; + char buffer[256]; - bool valid = - file_->Read(buffer, sizeof(buffer)) >= sizeof(good_content) - 1 && - memcmp(buffer, good_content, sizeof(good_content) - 1) == 0; - file_->Seek(0, ozz::io::File::kSet); + bool valid = true; + { + const char good_content[] = "good content"; + valid = file_->Read(buffer, sizeof(buffer)) >= sizeof(good_content) - 1 && + memcmp(buffer, good_content, sizeof(good_content) - 1) == 0; + file_->Seek(0, ozz::io::File::kSet); + } + + if (!valid) { + const char partial_good_content[] = "partial good content"; + valid = file_->Read(buffer, sizeof(buffer)) >= sizeof(partial_good_content) - 1 && + memcmp(buffer, partial_good_content, sizeof(partial_good_content) - 1) == 0; + file_->Seek(0, ozz::io::File::kSet); + } return valid; } @@ -172,6 +182,18 @@ class TestConverter : public ozz::animation::offline::OzzImporter { return names; } } + + // Handles one of animation is good + { + file_->Seek(0, ozz::io::File::kSet); + const char content[] = "partial good content"; + if (file_->Read(buffer, sizeof(buffer)) >= sizeof(content) - 1 && + memcmp(buffer, content, sizeof(content) - 1) == 0) { + names.push_back("bad"); + names.push_back("good"); + return names; + } + } } return names; @@ -223,6 +245,20 @@ class TestConverter : public ozz::animation::offline::OzzImporter { return true; } } + { // Handles one of animation is good + file_->Seek(0, ozz::io::File::kSet); + const char content[] = "partial good content"; + if (file_->Read(buffer, sizeof(buffer)) >= sizeof(content) - 1 && + memcmp(buffer, content, sizeof(content) - 1) == 0){ + + if (strcmp(_animation_name, "good") == 0){ + _animation->tracks.resize(_skeleton.num_joints()); + return true; + } + + return false; + } + } } return false; } @@ -254,6 +290,21 @@ class TestConverter : public ozz::animation::offline::OzzImporter { (void)_sampling_rate; (void)_track; + { + char buffer[256]; + const char content[] = "partial good content"; + if (strcmp(_animation_name, "good") == 0 || + strcmp(_animation_name, "bad") == 0) { + file_->Seek(0, ozz::io::File::kSet); + bool valid = file_->Read(buffer, sizeof(buffer)) >= sizeof(content) - 1; + valid &= memcmp(buffer, content, sizeof(content) - 1) == 0; + if (valid){ + return !((strcmp(_node_name, "joint0") == 0) && + (strcmp(_track_name, "property0") == 0)); + } + } + } + // joint2 doesn't have the property bool found = (strcmp(_node_name, "joint0") == 0 || strcmp(_node_name, "joint1") == 0) && diff --git a/3rdparty/ozz-animation/test/animation/offline/track_builder_tests.cc b/3rdparty/ozz-animation/test/animation/offline/track_builder_tests.cc index bd21ff7..04749a2 100644 --- a/3rdparty/ozz-animation/test/animation/offline/track_builder_tests.cc +++ b/3rdparty/ozz-animation/test/animation/offline/track_builder_tests.cc @@ -25,25 +25,22 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/offline/track_builder.h" - -#include "gtest/gtest.h" -#include "ozz/base/maths/gtest_math_helper.h" - -#include "ozz/base/memory/unique_ptr.h" - -#include "ozz/animation/offline/raw_track.h" -#include "ozz/animation/runtime/track.h" -#include "ozz/animation/runtime/track_sampling_job.h" - #include -using ozz::animation::FloatTrack; +#include "gtest/gtest.h" +#include "ozz/animation/offline/raw_track.h" +#include "ozz/animation/offline/track_builder.h" +#include "ozz/animation/runtime/track.h" +#include "ozz/animation/runtime/track_sampling_job.h" +#include "ozz/base/maths/gtest_math_helper.h" +#include "ozz/base/memory/unique_ptr.h" + using ozz::animation::Float2Track; using ozz::animation::Float3Track; using ozz::animation::Float4Track; -using ozz::animation::QuaternionTrack; +using ozz::animation::FloatTrack; using ozz::animation::FloatTrackSamplingJob; +using ozz::animation::QuaternionTrack; using ozz::animation::offline::RawFloatTrack; using ozz::animation::offline::RawTrackInterpolation; using ozz::animation::offline::TrackBuilder; @@ -731,6 +728,40 @@ TEST(BuildMixed, TrackBuilder) { ASSERT_TRUE(sampling.Run()); EXPECT_FLOAT_EQ(result, 0.f); } +TEST(Move, TrackBuilder) { + TrackBuilder builder; + RawFloatTrack raw_float_track; + + const RawFloatTrack::Keyframe key0 = {RawTrackInterpolation::kLinear, 0.f, + 0.f}; + raw_float_track.keyframes.push_back(key0); + const RawFloatTrack::Keyframe key1 = {RawTrackInterpolation::kStep, .5f, + 46.f}; + raw_float_track.keyframes.push_back(key1); + const RawFloatTrack::Keyframe key2 = {RawTrackInterpolation::kLinear, .7f, + 0.f}; + raw_float_track.keyframes.push_back(key2); + + { // Move constructor + raw_float_track.name = "track1"; + ozz::unique_ptr track(builder(raw_float_track)); + const FloatTrack ctrack(std::move(*track)); + EXPECT_STREQ(ctrack.name(), "track1"); + } + + { // Move assignment + raw_float_track.name = "track1"; + ozz::unique_ptr track1(builder(raw_float_track)); + EXPECT_STREQ(track1->name(), "track1"); + + raw_float_track.name = "track2"; + ozz::unique_ptr track2(builder(raw_float_track)); + EXPECT_STREQ(track2->name(), "track2"); + + *track2 = std::move(*track1); + EXPECT_STREQ(track2->name(), "track1"); + } +} TEST(Float, TrackBuilder) { TrackBuilder builder; diff --git a/3rdparty/ozz-animation/test/animation/runtime/CMakeLists.txt b/3rdparty/ozz-animation/test/animation/runtime/CMakeLists.txt index af21d46..d660354 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/animation/runtime/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(test_sampling_job target_link_libraries(test_sampling_job ozz_animation_offline gtest) +target_copy_shared_libraries(test_sampling_job) set_target_properties(test_sampling_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_sampling_job COMMAND test_sampling_job) @@ -13,6 +14,7 @@ add_executable(test_blending_job target_link_libraries(test_blending_job ozz_animation_offline gtest) +target_copy_shared_libraries(test_blending_job) set_target_properties(test_blending_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_blending_job COMMAND test_blending_job) @@ -22,6 +24,7 @@ add_executable(test_local_to_model_job target_link_libraries(test_local_to_model_job ozz_animation_offline gtest) +target_copy_shared_libraries(test_local_to_model_job) set_target_properties(test_local_to_model_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_local_to_model_job COMMAND test_local_to_model_job) @@ -30,6 +33,7 @@ add_executable(test_animation_archive target_link_libraries(test_animation_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_animation_archive) set_target_properties(test_animation_archive PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_animation_archive COMMAND test_animation_archive) @@ -39,6 +43,7 @@ target_link_libraries(test_animation_archive_versioning ozz_animation ozz_options gtest) +target_copy_shared_libraries(test_animation_archive_versioning) set_target_properties(test_animation_archive_versioning PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_animation_archive_versioning_le COMMAND test_animation_archive_versioning "--file=${ozz_media_directory}/bin/versioning/animation_v6_le.ozz" "--tracks=67" "--duration=.66666667" "--name=run") add_test(NAME test_animation_archive_versioning_be COMMAND test_animation_archive_versioning "--file=${ozz_media_directory}/bin/versioning/animation_v6_be.ozz" "--tracks=67" "--duration=.66666667" "--name=run") @@ -60,6 +65,7 @@ add_executable(test_skeleton_archive target_link_libraries(test_skeleton_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_skeleton_archive) set_target_properties(test_skeleton_archive PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_skeleton_archive COMMAND test_skeleton_archive) @@ -69,6 +75,7 @@ target_link_libraries(test_skeleton_archive_versioning ozz_animation ozz_options gtest) +target_copy_shared_libraries(test_skeleton_archive_versioning) set_target_properties(test_skeleton_archive_versioning PROPERTIES FOLDER "ozz/tests/animation") # Previous skeleton versions. @@ -84,6 +91,7 @@ add_executable(test_skeleton_utils target_link_libraries(test_skeleton_utils ozz_animation_offline gtest) +target_copy_shared_libraries(test_skeleton_utils) set_target_properties(test_skeleton_utils PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_skeleton_utils COMMAND test_skeleton_utils) @@ -92,6 +100,7 @@ add_executable(test_animation_utils target_link_libraries(test_animation_utils ozz_animation_offline gtest) +target_copy_shared_libraries(test_animation_utils) set_target_properties(test_animation_utils PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_animation_utils COMMAND test_skeleton_utils) @@ -103,6 +112,7 @@ target_link_libraries(test_track_sampling_job ozz_animation ozz_base gtest) +target_copy_shared_libraries(test_track_sampling_job) set_target_properties(test_track_sampling_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_track_sampling_job COMMAND test_track_sampling_job) @@ -115,6 +125,7 @@ target_link_libraries(test_track_triggering_job ozz_animation ozz_base gtest) +target_copy_shared_libraries(test_track_triggering_job) set_target_properties(test_track_triggering_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_track_triggering_job COMMAND test_track_triggering_job) @@ -123,6 +134,7 @@ add_executable(test_track_archive target_link_libraries(test_track_archive ozz_animation_offline gtest) +target_copy_shared_libraries(test_track_archive) set_target_properties(test_track_archive PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_track_archive COMMAND test_track_archive) @@ -131,6 +143,7 @@ add_executable(test_ik_aim_job target_link_libraries(test_ik_aim_job ozz_animation gtest) +target_copy_shared_libraries(test_ik_aim_job) set_target_properties(test_ik_aim_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_ik_aim_job COMMAND test_ik_aim_job) @@ -139,6 +152,7 @@ add_executable(test_ik_two_bone_job target_link_libraries(test_ik_two_bone_job ozz_animation gtest) +target_copy_shared_libraries(test_ik_two_bone_job) set_target_properties(test_ik_two_bone_job PROPERTIES FOLDER "ozz/tests/animation") add_test(NAME test_ik_two_bone_job COMMAND test_ik_two_bone_job) @@ -148,8 +162,10 @@ add_executable(test_fuse_animation sampling_job_tests.cc ${PROJECT_BINARY_DIR}/src_fused/ozz_animation.cc) add_dependencies(test_fuse_animation BUILD_FUSE_ozz_animation) +target_compile_definitions(test_fuse_animation PRIVATE $<$:OZZ_BUILD_ANIMATION_LIB>) target_link_libraries(test_fuse_animation ozz_animation_offline gtest) +#target_copy_shared_libraries(test_fuse_animation) add_test(NAME test_fuse_animation COMMAND test_fuse_animation) set_target_properties(test_fuse_animation PROPERTIES FOLDER "ozz/tests/animation") diff --git a/3rdparty/ozz-animation/test/animation/runtime/animation_archive_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/animation_archive_tests.cc index 418908c..4469152 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/animation_archive_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/animation_archive_tests.cc @@ -25,25 +25,20 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/animation.h" - #include "gtest/gtest.h" -#include "ozz/base/maths/gtest_math_helper.h" - -#include "ozz/base/io/archive.h" -#include "ozz/base/io/stream.h" -#include "ozz/base/memory/unique_ptr.h" - -#include "ozz/base/maths/soa_transform.h" - -#include "ozz/animation/runtime/sampling_job.h" - #include "ozz/animation/offline/animation_builder.h" #include "ozz/animation/offline/raw_animation.h" +#include "ozz/animation/runtime/animation.h" +#include "ozz/animation/runtime/sampling_job.h" +#include "ozz/base/io/archive.h" +#include "ozz/base/io/stream.h" +#include "ozz/base/maths/gtest_math_helper.h" +#include "ozz/base/maths/soa_transform.h" +#include "ozz/base/memory/unique_ptr.h" using ozz::animation::Animation; -using ozz::animation::offline::RawAnimation; using ozz::animation::offline::AnimationBuilder; +using ozz::animation::offline::RawAnimation; TEST(Empty, AnimationSerialize) { ozz::io::MemoryStream stream; @@ -112,10 +107,10 @@ TEST(Filled, AnimationSerialize) { // Needs to sample to test the animation. ozz::animation::SamplingJob job; - ozz::animation::SamplingCache cache(1); + ozz::animation::SamplingJob::Context context(1); ozz::math::SoaTransform output[1]; job.animation = o_animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; // Samples and compares the two animations diff --git a/3rdparty/ozz-animation/test/animation/runtime/blending_job_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/blending_job_tests.cc index 561cc30..f7df160 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/blending_job_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/blending_job_tests.cc @@ -36,7 +36,7 @@ TEST(JobValidity, BlendingJob) { const ozz::math::SoaTransform identity = ozz::math::SoaTransform::identity(); const ozz::math::SimdFloat4 zero = ozz::math::simd_float4::zero(); BlendingJob::Layer layers[2]; - const ozz::math::SoaTransform bind_poses[3] = {identity, identity, identity}; + const ozz::math::SoaTransform rest_poses[3] = {identity, identity, identity}; const ozz::math::SoaTransform input_transforms[3] = {identity, identity, identity}; ozz::math::SoaTransform output_transforms[3] = {identity, identity, identity}; @@ -54,18 +54,18 @@ TEST(JobValidity, BlendingJob) { { // Invalid output. BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); } { // Layers are optional. BlendingJob job; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); } - { // Invalid bind pose. + { // Invalid rest pose. BlendingJob job; job.layers = {layers, layers + 2}; job.output = {output_transforms, output_transforms + 2}; @@ -79,7 +79,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.layers = invalid_layers; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -87,7 +87,7 @@ TEST(JobValidity, BlendingJob) { { // Invalid output range, smaller output. BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 1}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -96,7 +96,7 @@ TEST(JobValidity, BlendingJob) { { // Invalid smaller input. BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 3}; + job.rest_pose = {rest_poses, rest_poses + 3}; job.output = {output_transforms, output_transforms + 3}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -106,7 +106,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.threshold = 0.f; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -117,7 +117,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -128,7 +128,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -139,7 +139,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -150,7 +150,7 @@ TEST(JobValidity, BlendingJob) { BlendingJob job; job.layers = {layers, layers + 2}; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 3}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -158,7 +158,7 @@ TEST(JobValidity, BlendingJob) { { // Valid no layers. BlendingJob job; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -171,7 +171,7 @@ TEST(JobValidityAdditive, BlendingJob) { BlendingJob::Layer layers[2]; BlendingJob::Layer additive_layers[2]; - const ozz::math::SoaTransform bind_poses[3] = {identity, identity, identity}; + const ozz::math::SoaTransform rest_poses[3] = {identity, identity, identity}; const ozz::math::SoaTransform input_transforms[3] = {identity, identity, identity}; ozz::math::SoaTransform output_transforms[3] = {identity, identity, identity}; @@ -186,7 +186,7 @@ TEST(JobValidityAdditive, BlendingJob) { { // Valid additive job, no normal blending. BlendingJob job; job.additive_layers = additive_layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -197,7 +197,7 @@ TEST(JobValidityAdditive, BlendingJob) { BlendingJob job; job.layers = layers; job.additive_layers = additive_layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -211,7 +211,7 @@ TEST(JobValidityAdditive, BlendingJob) { BlendingJob job; job.layers = layers; job.additive_layers = invalid_layers; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); @@ -222,7 +222,7 @@ TEST(JobValidityAdditive, BlendingJob) { BlendingJob job; job.additive_layers = additive_layers; - job.bind_pose = {bind_poses, bind_poses + 2}; + job.rest_pose = {rest_poses, rest_poses + 2}; job.output = {output_transforms, output_transforms + 2}; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -232,23 +232,23 @@ TEST(JobValidityAdditive, BlendingJob) { TEST(Empty, BlendingJob) { const ozz::math::SoaTransform identity = ozz::math::SoaTransform::identity(); - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[2] = {identity, identity}; - bind_poses[0].translation = ozz::math::SoaFloat3::Load( + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[2] = {identity, identity}; + rest_poses[0].translation = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f), ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f), ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)); - bind_poses[0].scale = ozz::math::SoaFloat3::Load( + rest_poses[0].scale = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 10.f, 20.f, 30.f), ozz::math::simd_float4::Load(40.f, 50.f, 60.f, 70.f), ozz::math::simd_float4::Load(80.f, 90.f, 100.f, 110.f)); - bind_poses[1].translation = bind_poses[0].translation * + rest_poses[1].translation = rest_poses[0].translation * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); - bind_poses[1].scale = - bind_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); + rest_poses[1].scale = + rest_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); BlendingJob job; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; ozz::math::SoaTransform output_transforms[2]; job.output = output_transforms; @@ -282,14 +282,14 @@ TEST(Weight, BlendingJob) { input_transforms[1][0].translation = -input_transforms[0][0].translation; input_transforms[1][1].translation = -input_transforms[0][1].translation; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[2] = {identity, identity}; - bind_poses[0].scale = ozz::math::SoaFloat3::Load( + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[2] = {identity, identity}; + rest_poses[0].scale = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f), ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f), ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)); - bind_poses[1].scale = - bind_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); + rest_poses[1].scale = + rest_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); { BlendingJob::Layer layers[2]; @@ -300,7 +300,7 @@ TEST(Weight, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; // Weight 0 (a bit less must give the same result) for the first layer, @@ -373,18 +373,18 @@ TEST(JointWeights, BlendingJob) { ozz::math::simd_float4::Load(1.f, 0.f, 1.f, 1.f)}, {ozz::math::simd_float4::Load(1.f, 1.f, 1.f, 0.f), ozz::math::simd_float4::Load(0.f, 1.f, 1.f, 1.f)}}; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[2] = {identity, identity}; - bind_poses[0].translation = ozz::math::SoaFloat3::Load( + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[2] = {identity, identity}; + rest_poses[0].translation = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(10.f, 11.f, 12.f, 13.f), ozz::math::simd_float4::Load(14.f, 15.f, 16.f, 17.f), ozz::math::simd_float4::Load(18.f, 19.f, 20.f, 21.f)); - bind_poses[0].scale = ozz::math::SoaFloat3::Load( + rest_poses[0].scale = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f), ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f), ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)); - bind_poses[1].scale = - bind_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); + rest_poses[1].scale = + rest_poses[0].scale * ozz::math::simd_float4::Load(2.f, 2.f, 2.f, 2.f); BlendingJob::Layer layers[2]; layers[0].transform = input_transforms[0]; @@ -397,7 +397,7 @@ TEST(JointWeights, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; layers[0].weight = .5f; @@ -419,7 +419,7 @@ TEST(JointWeights, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; layers[0].weight = 0.f; @@ -445,9 +445,9 @@ TEST(Normalize, BlendingJob) { // Initialize inputs. ozz::math::SoaTransform input_transforms[2][1] = {{identity}, {identity}}; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[1] = {identity}; - bind_poses[0].scale = ozz::math::SoaFloat3::Load( + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[1] = {identity}; + rest_poses[0].scale = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f), ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f), ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)); @@ -483,7 +483,7 @@ TEST(Normalize, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Run()); @@ -520,7 +520,7 @@ TEST(Normalize, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Run()); @@ -559,7 +559,7 @@ TEST(Normalize, BlendingJob) { BlendingJob job; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Run()); @@ -578,9 +578,9 @@ TEST(Threshold, BlendingJob) { // Initialize inputs. ozz::math::SoaTransform input_transforms[2][1] = {{identity}, {identity}}; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[1] = {identity}; - bind_poses[0].scale = ozz::math::SoaFloat3::Load( + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[1] = {identity}; + rest_poses[0].scale = ozz::math::SoaFloat3::Load( ozz::math::simd_float4::Load(0.f, 1.f, 2.f, 3.f), ozz::math::simd_float4::Load(4.f, 5.f, 6.f, 7.f), ozz::math::simd_float4::Load(8.f, 9.f, 10.f, 11.f)); @@ -606,7 +606,7 @@ TEST(Threshold, BlendingJob) { BlendingJob job; job.threshold = .1f; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Run()); @@ -632,7 +632,7 @@ TEST(Threshold, BlendingJob) { BlendingJob job; job.threshold = .1f; job.layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; EXPECT_TRUE(job.Run()); @@ -669,8 +669,8 @@ TEST(AdditiveWeight, BlendingJob) { input_transforms[1][0].rotation = Conjugate(input_transforms[0][0].rotation); input_transforms[1][0].scale = -input_transforms[0][0].scale; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[1] = {identity}; + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[1] = {identity}; { BlendingJob::Layer layers[1]; @@ -680,7 +680,7 @@ TEST(AdditiveWeight, BlendingJob) { BlendingJob job; job.additive_layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; // No weight for the 1st layer. @@ -731,7 +731,7 @@ TEST(AdditiveWeight, BlendingJob) { BlendingJob job; job.additive_layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; // No weight for the 1st layer. @@ -803,8 +803,8 @@ TEST(AdditiveJointWeight, BlendingJob) { ozz::math::SimdFloat4 joint_weights[1] = { ozz::math::simd_float4::Load(1.f, .5f, 0.f, -1.f)}; - // Initialize bind pose. - ozz::math::SoaTransform bind_poses[1] = {identity}; + // Initialize rest pose. + ozz::math::SoaTransform rest_poses[1] = {identity}; { BlendingJob::Layer layers[1]; @@ -815,7 +815,7 @@ TEST(AdditiveJointWeight, BlendingJob) { BlendingJob job; job.additive_layers = layers; - job.bind_pose = bind_poses; + job.rest_pose = rest_poses; job.output = output_transforms; // No weight for the 1st layer. diff --git a/3rdparty/ozz-animation/test/animation/runtime/sampling_job_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/sampling_job_tests.cc index 0ba8ab7..ed0d85d 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/sampling_job_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/sampling_job_tests.cc @@ -35,7 +35,6 @@ #include "ozz/base/memory/unique_ptr.h" using ozz::animation::Animation; -using ozz::animation::SamplingCache; using ozz::animation::SamplingJob; using ozz::animation::offline::AnimationBuilder; using ozz::animation::offline::RawAnimation; @@ -49,8 +48,8 @@ TEST(JobValidity, SamplingJob) { ozz::unique_ptr animation(builder(raw_animation)); ASSERT_TRUE(animation); - // Allocates cache. - SamplingCache cache(1); + // Allocates context. + SamplingJob::Context context(1); { // Empty/default job SamplingJob job; @@ -61,7 +60,7 @@ TEST(JobValidity, SamplingJob) { { // Invalid output SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); } @@ -70,13 +69,13 @@ TEST(JobValidity, SamplingJob) { ozz::math::SoaTransform output[1]; SamplingJob job; - job.cache = &cache; + job.context = &context; job.output = output; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); } - { // Invalid cache. + { // Invalid context. ozz::math::SoaTransform output[1]; SamplingJob job; @@ -86,48 +85,66 @@ TEST(JobValidity, SamplingJob) { EXPECT_FALSE(job.Run()); } - { // Invalid cache size. - SamplingCache zero_cache(0); + { // Invalid context size. + SamplingJob::Context zero_cache(0); ozz::math::SoaTransform output[1]; SamplingJob job; job.animation = animation.get(); - job.cache = &zero_cache; + job.context = &zero_cache; job.output = output; EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); } - { // Invalid job with smaller output. + { // Invalid job with empty output. ozz::math::SoaTransform* output = nullptr; SamplingJob job; job.ratio = 2155.f; // Any time ratio can be set, it's clamped in unit interval. job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = ozz::span(output, size_t(0)); EXPECT_FALSE(job.Validate()); EXPECT_FALSE(job.Run()); } + { // valid job with output smaller than animation, but not empty. + RawAnimation big_raw_animation; + big_raw_animation.duration = 1.f; + big_raw_animation.tracks.resize(2); + ozz::unique_ptr big_animation(builder(big_raw_animation)); + ASSERT_TRUE(big_animation); + + ozz::math::SoaTransform output[1]; + SamplingJob job; + job.ratio = + 2155.f; // Any time ratio can be set, it's clamped in unit interval. + job.animation = big_animation.get(); + job.context = &context; + job.output = output; + EXPECT_TRUE(job.Validate()); + EXPECT_TRUE(job.Run()); + } + { // Valid job. ozz::math::SoaTransform output[1]; SamplingJob job; job.ratio = 2155.f; // Any time can be set. job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); } - { // Valid job with bigger cache. - SamplingCache big_cache(2); + { // Valid job with bigger context. + SamplingJob::Context big_cache(2); ozz::math::SoaTransform output[1]; SamplingJob job; job.ratio = 2155.f; // Any time can be set. job.animation = animation.get(); - job.cache = &big_cache; + job.context = &big_cache; job.output = output; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -138,7 +155,7 @@ TEST(JobValidity, SamplingJob) { SamplingJob job; job.ratio = 2155.f; // Any time can be set. job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -149,7 +166,7 @@ TEST(JobValidity, SamplingJob) { Animation default_animation; SamplingJob job; job.animation = &default_animation; - job.cache = &cache; + job.context = &context; job.output = output; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -165,7 +182,7 @@ TEST(Sampling, SamplingJob) { raw_animation.duration = 1.f; raw_animation.tracks.resize(4); - SamplingCache cache(4); + SamplingJob::Context context(4); // Raw animation inputs. // 0 1 @@ -239,7 +256,7 @@ TEST(Sampling, SamplingJob) { SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; for (size_t i = 0; i < OZZ_ARRAY_SIZE(result); ++i) { @@ -266,7 +283,7 @@ TEST(SamplingNoTrack, SamplingJob) { RawAnimation raw_animation; raw_animation.duration = 46.f; - SamplingCache cache(1); + SamplingJob::Context context(1); AnimationBuilder builder; ozz::unique_ptr animation(builder(raw_animation)); @@ -280,7 +297,7 @@ TEST(SamplingNoTrack, SamplingJob) { SamplingJob job; job.ratio = 0.f; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -294,7 +311,7 @@ TEST(Sampling1Track0Key, SamplingJob) { raw_animation.duration = 46.f; raw_animation.tracks.resize(1); // Adds a joint. - SamplingCache cache(1); + SamplingJob::Context context(1); AnimationBuilder builder; ozz::unique_ptr animation(builder(raw_animation)); @@ -304,7 +321,7 @@ TEST(Sampling1Track0Key, SamplingJob) { SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; for (float t = -.2f; t < 1.2f; t += .1f) { @@ -327,7 +344,7 @@ TEST(Sampling1Track1Key, SamplingJob) { raw_animation.duration = 46.f; raw_animation.tracks.resize(1); // Adds a joint. - SamplingCache cache(1); + SamplingJob::Context context(1); const RawAnimation::TranslationKey tkey = {.3f, ozz::math::Float3(1.f, -1.f, 5.f)}; @@ -341,7 +358,7 @@ TEST(Sampling1Track1Key, SamplingJob) { SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; for (float t = -.2f; t < 1.2f; t += .1f) { @@ -364,7 +381,7 @@ TEST(Sampling1Track2Keys, SamplingJob) { raw_animation.duration = 46.f; raw_animation.tracks.resize(1); // Adds a joint. - SamplingCache cache(1); + SamplingJob::Context context(1); const RawAnimation::TranslationKey tkey0 = {.5f, ozz::math::Float3(1.f, 2.f, 4.f)}; @@ -382,7 +399,7 @@ TEST(Sampling1Track2Keys, SamplingJob) { SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; // Samples at t = 0. @@ -448,7 +465,7 @@ TEST(Sampling4Track2Keys, SamplingJob) { raw_animation.duration = 1.f; raw_animation.tracks.resize(4); // Adds a joint. - SamplingCache cache(1); + SamplingJob::Context context(1); const RawAnimation::TranslationKey tkey00 = { .5f, ozz::math::Float3(1.f, 2.f, 4.f)}; @@ -488,7 +505,7 @@ TEST(Sampling4Track2Keys, SamplingJob) { SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.output = output; // Samples at t = 0. @@ -534,7 +551,7 @@ TEST(Cache, SamplingJob) { 0.f, RawAnimation::TranslationKey::identity()}; raw_animation.tracks[0].translations.push_back(empty_key); - SamplingCache cache(1); + SamplingJob::Context context(1); ozz::unique_ptr animations[2]; { @@ -560,7 +577,7 @@ TEST(Cache, SamplingJob) { SamplingJob job; job.animation = animations[0].get(); - job.cache = &cache; + job.context = &context; job.ratio = 0.f; job.output = output; @@ -573,14 +590,14 @@ TEST(Cache, SamplingJob) { EXPECT_SOAFLOAT3_EQ_EST(output[0].scale, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f); - // Re-uses cache. + // Re-uses context. EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); EXPECT_SOAFLOAT3_EQ_EST(output[0].translation, 1.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 5.f, 0.f, 0.f, 0.f); - // Invalidates cache. - cache.Invalidate(); + // Invalidates context. + context.Invalidate(); EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); @@ -615,14 +632,14 @@ TEST(CacheResize, SamplingJob) { ozz::unique_ptr animation(builder(raw_animation)); ASSERT_TRUE(animation); - // Empty cache by default - SamplingCache cache; + // Empty context by default + SamplingJob::Context context; ozz::math::SoaTransform output[7]; SamplingJob job; job.animation = animation.get(); - job.cache = &cache; + job.context = &context; job.ratio = 0.f; job.output = output; @@ -630,11 +647,11 @@ TEST(CacheResize, SamplingJob) { EXPECT_FALSE(job.Validate()); // Cache is ok. - cache.Resize(7); + context.Resize(7); EXPECT_TRUE(job.Validate()); EXPECT_TRUE(job.Run()); // Cache is too small - cache.Resize(1); + context.Resize(1); EXPECT_FALSE(job.Validate()); } diff --git a/3rdparty/ozz-animation/test/animation/runtime/skeleton_archive_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/skeleton_archive_tests.cc index 5e53916..23349bb 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/skeleton_archive_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/skeleton_archive_tests.cc @@ -25,18 +25,13 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/runtime/skeleton.h" - #include "gtest/gtest.h" - #include "ozz/animation/offline/raw_skeleton.h" #include "ozz/animation/offline/skeleton_builder.h" - +#include "ozz/animation/runtime/skeleton.h" #include "ozz/base/io/archive.h" #include "ozz/base/io/stream.h" - #include "ozz/base/maths/soa_transform.h" - #include "ozz/base/memory/unique_ptr.h" using ozz::animation::Skeleton; @@ -109,20 +104,19 @@ TEST(Filled, SkeletonSerialize) { // Compares skeletons. EXPECT_EQ(o_skeleton->num_joints(), i_skeleton.num_joints()); for (int i = 0; i < i_skeleton.num_joints(); ++i) { - EXPECT_EQ(i_skeleton.joint_parents()[i], - o_skeleton->joint_parents()[i]); + EXPECT_EQ(i_skeleton.joint_parents()[i], o_skeleton->joint_parents()[i]); EXPECT_STREQ(i_skeleton.joint_names()[i], o_skeleton->joint_names()[i]); } for (int i = 0; i < (i_skeleton.num_joints() + 3) / 4; ++i) { - EXPECT_TRUE(ozz::math::AreAllTrue( - i_skeleton.joint_bind_poses()[i].translation == - o_skeleton->joint_bind_poses()[i].translation)); - EXPECT_TRUE(ozz::math::AreAllTrue( - i_skeleton.joint_bind_poses()[i].rotation == - o_skeleton->joint_bind_poses()[i].rotation)); EXPECT_TRUE( - ozz::math::AreAllTrue(i_skeleton.joint_bind_poses()[i].scale == - o_skeleton->joint_bind_poses()[i].scale)); + ozz::math::AreAllTrue(i_skeleton.joint_rest_poses()[i].translation == + o_skeleton->joint_rest_poses()[i].translation)); + EXPECT_TRUE( + ozz::math::AreAllTrue(i_skeleton.joint_rest_poses()[i].rotation == + o_skeleton->joint_rest_poses()[i].rotation)); + EXPECT_TRUE( + ozz::math::AreAllTrue(i_skeleton.joint_rest_poses()[i].scale == + o_skeleton->joint_rest_poses()[i].scale)); } } } diff --git a/3rdparty/ozz-animation/test/animation/runtime/skeleton_utils_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/skeleton_utils_tests.cc index d6e2356..723aae8 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/skeleton_utils_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/skeleton_utils_tests.cc @@ -25,25 +25,23 @@ // // //----------------------------------------------------------------------------// -#include "ozz/animation/offline/raw_skeleton.h" -#include "ozz/animation/offline/skeleton_builder.h" - #include #include #include "gtest/gtest.h" -#include "ozz/base/gtest_helper.h" -#include "ozz/base/maths/gtest_math_helper.h" - +#include "ozz/animation/offline/raw_skeleton.h" +#include "ozz/animation/offline/skeleton_builder.h" #include "ozz/animation/runtime/skeleton.h" #include "ozz/animation/runtime/skeleton_utils.h" +#include "ozz/base/gtest_helper.h" +#include "ozz/base/maths/gtest_math_helper.h" #include "ozz/base/memory/unique_ptr.h" using ozz::animation::Skeleton; using ozz::animation::offline::RawSkeleton; using ozz::animation::offline::SkeletonBuilder; -TEST(JointBindPose, SkeletonUtils) { +TEST(JointRestPose, SkeletonUtils) { // Instantiates a builder objects with default parameters. SkeletonBuilder builder; @@ -76,23 +74,23 @@ TEST(JointBindPose, SkeletonUtils) { EXPECT_EQ(skeleton->num_joints(), 3); // Out of range. - EXPECT_ASSERTION(GetJointLocalBindPose(*skeleton, 3), + EXPECT_ASSERTION(GetJointLocalRestPose(*skeleton, 3), "Joint index out of range."); - const ozz::math::Transform bind_pose0 = GetJointLocalBindPose(*skeleton, 0); - EXPECT_FLOAT3_EQ(bind_pose0.translation, 1.f, 0.f, 0.f); - EXPECT_QUATERNION_EQ(bind_pose0.rotation, 0.f, 0.f, 0.f, 1.f); - EXPECT_FLOAT3_EQ(bind_pose0.scale, 0.f, 0.f, 0.f); + const ozz::math::Transform rest_pose0 = GetJointLocalRestPose(*skeleton, 0); + EXPECT_FLOAT3_EQ(rest_pose0.translation, 1.f, 0.f, 0.f); + EXPECT_QUATERNION_EQ(rest_pose0.rotation, 0.f, 0.f, 0.f, 1.f); + EXPECT_FLOAT3_EQ(rest_pose0.scale, 0.f, 0.f, 0.f); - const ozz::math::Transform bind_pose1 = GetJointLocalBindPose(*skeleton, 1); - EXPECT_FLOAT3_EQ(bind_pose1.translation, 0.f, 1.f, 0.f); - EXPECT_QUATERNION_EQ(bind_pose1.rotation, 0.f, 0.f, 0.f, -1.f); - EXPECT_FLOAT3_EQ(bind_pose1.scale, -1.f, -1.f, -1.f); + const ozz::math::Transform rest_pose1 = GetJointLocalRestPose(*skeleton, 1); + EXPECT_FLOAT3_EQ(rest_pose1.translation, 0.f, 1.f, 0.f); + EXPECT_QUATERNION_EQ(rest_pose1.rotation, 0.f, 0.f, 0.f, -1.f); + EXPECT_FLOAT3_EQ(rest_pose1.scale, -1.f, -1.f, -1.f); - const ozz::math::Transform bind_pose2 = GetJointLocalBindPose(*skeleton, 2); - EXPECT_FLOAT3_EQ(bind_pose2.translation, 0.f, 0.f, 1.f); - EXPECT_QUATERNION_EQ(bind_pose2.rotation, -0.f, -0.f, -0.f, 1.f); - EXPECT_FLOAT3_EQ(bind_pose2.scale, 1.f, 1.f, 1.f); + const ozz::math::Transform rest_pose2 = GetJointLocalRestPose(*skeleton, 2); + EXPECT_FLOAT3_EQ(rest_pose2.translation, 0.f, 0.f, 1.f); + EXPECT_QUATERNION_EQ(rest_pose2.rotation, -0.f, -0.f, -0.f, 1.f); + EXPECT_FLOAT3_EQ(rest_pose2.scale, 1.f, 1.f, 1.f); } /* Definition of the skeleton used by the tests. @@ -415,3 +413,26 @@ TEST(IsLeaf, SkeletonUtils) { EXPECT_FALSE(IsLeaf(*skeleton, 8)); EXPECT_TRUE(IsLeaf(*skeleton, 9)); } + +TEST(Name, SkeletonUtils) { + // Instantiates a builder objects with default parameters. + SkeletonBuilder builder; + + RawSkeleton raw_skeleton; + raw_skeleton.roots.resize(4); + raw_skeleton.roots[0].name = "j0"; + raw_skeleton.roots[1].name = "j10"; + raw_skeleton.roots[2].name = "j1"; + raw_skeleton.roots[3].name = "J0"; + + ozz::unique_ptr skeleton(builder(raw_skeleton)); + ASSERT_TRUE(skeleton); + + EXPECT_EQ(FindJoint(*skeleton, "j0"), 0); + EXPECT_EQ(FindJoint(*skeleton, "j10"), 1); + EXPECT_EQ(FindJoint(*skeleton, "j1"), 2); + EXPECT_EQ(FindJoint(*skeleton, "J0"), 3); + + EXPECT_TRUE(FindJoint(*skeleton, "aj0") < 0); + EXPECT_TRUE(FindJoint(*skeleton, "j0a") < 0); +} \ No newline at end of file diff --git a/3rdparty/ozz-animation/test/animation/runtime/track_triggering_job_tests.cc b/3rdparty/ozz-animation/test/animation/runtime/track_triggering_job_tests.cc index 5533654..070a036 100644 --- a/3rdparty/ozz-animation/test/animation/runtime/track_triggering_job_tests.cc +++ b/3rdparty/ozz-animation/test/animation/runtime/track_triggering_job_tests.cc @@ -852,8 +852,10 @@ void TestEdgesExpectation( const size_t kMaxIterations = 1000; for (size_t i = 0; i < kMaxIterations; ++i) { job.from = - kMaxRange * (1.f - 2.f * static_cast(rand()) / RAND_MAX); - job.to = kMaxRange * (1.f - 2.f * static_cast(rand()) / RAND_MAX); + kMaxRange * (1.f - 2.f * static_cast(rand()) / + static_cast(RAND_MAX)); + job.to = kMaxRange * (1.f - 2.f * static_cast(rand()) / + static_cast(RAND_MAX)); TrackTriggeringJob::Iterator iterator; job.iterator = &iterator; ASSERT_TRUE(job.Run()); @@ -870,7 +872,8 @@ void TestEdgesExpectation( // Finds new evaluation range float new_time = ratio + - kMaxRange * (1.f - 2.f * static_cast(rand()) / RAND_MAX); + kMaxRange * (1.f - 2.f * static_cast(rand()) / + static_cast(RAND_MAX)); switch (rand() % 20) { case 0: { diff --git a/3rdparty/ozz-animation/test/base/CMakeLists.txt b/3rdparty/ozz-animation/test/base/CMakeLists.txt index 3bd890b..a84b3fe 100644 --- a/3rdparty/ozz-animation/test/base/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/base/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(test_endianness endianness_tests.cc) target_link_libraries(test_endianness ozz_base gtest) +target_copy_shared_libraries(test_endianness) add_test(NAME test_endianness COMMAND test_endianness) set_target_properties(test_endianness PROPERTIES FOLDER "ozz/tests/base") @@ -14,6 +15,7 @@ add_executable(test_log log_tests.cc) target_link_libraries(test_log ozz_base gtest) +target_copy_shared_libraries(test_log) add_test(NAME test_log COMMAND test_log) set_target_properties(test_log PROPERTIES FOLDER "ozz/tests/base") @@ -23,6 +25,7 @@ add_executable(test_platform target_link_libraries(test_platform ozz_base gtest) +target_copy_shared_libraries(test_platform) add_test(NAME test_platform COMMAND test_platform) set_target_properties(test_platform PROPERTIES FOLDER "ozz/tests/base") @@ -37,5 +40,6 @@ target_include_directories(test_fuse_base PUBLIC "${PROJECT_SOURCE_DIR}/include") target_link_libraries(test_fuse_base gtest) +#target_copy_shared_libraries(test_fuse_base) add_test(NAME test_fuse_base COMMAND test_fuse_base) set_target_properties(test_fuse_base PROPERTIES FOLDER "ozz/tests/base") diff --git a/3rdparty/ozz-animation/test/base/containers/CMakeLists.txt b/3rdparty/ozz-animation/test/base/containers/CMakeLists.txt index 8d4098a..6efbbe5 100644 --- a/3rdparty/ozz-animation/test/base/containers/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/base/containers/CMakeLists.txt @@ -3,6 +3,7 @@ target_include_directories(test_intrusive_list PUBLIC "${PROJECT_SOURCE_DIR}/include") target_link_libraries(test_intrusive_list gtest) +target_copy_shared_libraries(test_intrusive_list) add_test(NAME test_intrusive_list COMMAND test_intrusive_list) set_target_properties(test_intrusive_list PROPERTIES FOLDER "ozz/tests/base") @@ -10,6 +11,7 @@ add_executable(test_std_containers std_containers_tests.cc) target_link_libraries(test_std_containers ozz_base gtest) +target_copy_shared_libraries(test_std_containers) add_test(NAME test_std_containers COMMAND test_std_containers) set_target_properties(test_std_containers PROPERTIES FOLDER "ozz/tests/base") @@ -18,5 +20,6 @@ add_executable(test_std_containers_archive target_link_libraries(test_std_containers_archive ozz_base gtest) +target_copy_shared_libraries(test_std_containers_archive) add_test(NAME test_std_containers_archive COMMAND test_std_containers_archive) set_target_properties(test_std_containers_archive PROPERTIES FOLDER "ozz/tests/base") diff --git a/3rdparty/ozz-animation/test/base/containers/std_containers_archive_tests.cc b/3rdparty/ozz-animation/test/base/containers/std_containers_archive_tests.cc index 439beb6..c2b0729 100644 --- a/3rdparty/ozz-animation/test/base/containers/std_containers_archive_tests.cc +++ b/3rdparty/ozz-animation/test/base/containers/std_containers_archive_tests.cc @@ -25,13 +25,12 @@ // // //----------------------------------------------------------------------------// -#include "ozz/base/containers/string_archive.h" -#include "ozz/base/containers/vector_archive.h" - #include #include "gtest/gtest.h" - +#include "ozz/base/containers/array_archive.h" +#include "ozz/base/containers/string_archive.h" +#include "ozz/base/containers/vector_archive.h" #include "ozz/base/io/archive.h" TEST(string, Archive) { @@ -123,7 +122,7 @@ TEST(Vector, Archive) { ozz::vector small_i; i >> small_i; EXPECT_EQ(small_o.size(), small_i.size()); - for (size_t j = 0; j < empty_i.size(); ++j) { + for (size_t j = 0; j < small_i.size(); ++j) { EXPECT_EQ(small_o[j], small_i[j]); } @@ -143,3 +142,45 @@ TEST(Vector, Archive) { } } } + +TEST(Array, Archive) { + for (int e = 0; e < 2; ++e) { + ozz::Endianness endianess = e == 0 ? ozz::kBigEndian : ozz::kLittleEndian; + + ozz::io::MemoryStream stream; + ASSERT_TRUE(stream.opened()); + + // Writes. + ozz::io::OArchive o(&stream, endianess); + ozz::array empty_o; + o << empty_o; + + ozz::array array_o{{0, 1, 2, 3, 4}}; + o << array_o; + + // Rewrite for the Vector reuse test. + ozz::array reuse_o{{5, 6, 7, 8, 9}}; + o << reuse_o; + + // Reads. + stream.Seek(0, ozz::io::Stream::kSet); + ozz::io::IArchive i(&stream); + + ozz::array empty_i; + i >> empty_i; + EXPECT_EQ(empty_i.size(), 0u); + + ozz::array array_i; + i >> array_i; + EXPECT_EQ(array_o.size(), array_i.size()); + for (size_t j = 0; j < array_i.size(); ++j) { + EXPECT_EQ(array_o[j], array_i[j]); + } + + i >> array_i; + EXPECT_EQ(reuse_o.size(), array_i.size()); + for (size_t j = 0; j < array_i.size(); ++j) { + EXPECT_EQ(reuse_o[j], array_i[j]); + } + } +} diff --git a/3rdparty/ozz-animation/test/base/containers/std_containers_tests.cc b/3rdparty/ozz-animation/test/base/containers/std_containers_tests.cc index 6e87012..82e6289 100644 --- a/3rdparty/ozz-animation/test/base/containers/std_containers_tests.cc +++ b/3rdparty/ozz-animation/test/base/containers/std_containers_tests.cc @@ -26,6 +26,7 @@ //----------------------------------------------------------------------------// #include "gtest/gtest.h" +#include "ozz/base/containers/array.h" #include "ozz/base/containers/deque.h" #include "ozz/base/containers/list.h" #include "ozz/base/containers/map.h" @@ -39,6 +40,35 @@ #include "ozz/base/gtest_helper.h" #include "ozz/base/span.h" +TEST(Allocator, Containers) { + ozz::StdAllocator int_allocator; + int_allocator.deallocate(int_allocator.allocate(46), 46); + ozz::StdAllocator other_allocator(int_allocator); + + class Object { + public: + Object(int& _counter) : counter_(_counter) { ++counter_; } + ~Object() { --counter_; } + + private: + int& counter_; + }; + + int counter = 0; + ozz::StdAllocator ObjectAllocator; + Object* pointer = ObjectAllocator.allocate(1); + int_allocator.construct(pointer, counter); + EXPECT_EQ(counter, 1); + + int_allocator.destroy(pointer); + EXPECT_EQ(counter, 0); + + ObjectAllocator.deallocate(pointer, 1); + + EXPECT_TRUE(int_allocator == other_allocator); + EXPECT_FALSE(int_allocator != other_allocator); +} + TEST(Vector, Containers) { typedef ozz::vector Container; Container container; @@ -54,6 +84,18 @@ TEST(Vector, Containers) { Container container2 = std::move(container); } +TEST(Array, Containers) { + typedef ozz::array Container; + Container container{{0, 1, 2, 3}}; + EXPECT_EQ(container[0], 0); + EXPECT_EQ(container[1], 1); + EXPECT_EQ(container[2], 2); + EXPECT_EQ(container[3], 3); + + Container container2 = std::move(container); + (void)container2; +} + TEST(VectorExtensions, Containers) { typedef ozz::vector Container; Container container; diff --git a/3rdparty/ozz-animation/test/base/io/CMakeLists.txt b/3rdparty/ozz-animation/test/base/io/CMakeLists.txt index 1e705d9..4744328 100644 --- a/3rdparty/ozz-animation/test/base/io/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/base/io/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(test_archive target_link_libraries(test_archive ozz_base gtest) +target_copy_shared_libraries(test_archive) add_test(NAME test_archive COMMAND test_archive) set_target_properties(test_archive PROPERTIES FOLDER "ozz/tests/base") @@ -13,5 +14,6 @@ add_executable(test_stream target_link_libraries(test_stream ozz_base gtest) +target_copy_shared_libraries(test_stream) add_test(NAME test_stream COMMAND test_stream) set_target_properties(test_stream PROPERTIES FOLDER "ozz/tests/base") diff --git a/3rdparty/ozz-animation/test/base/maths/CMakeLists.txt b/3rdparty/ozz-animation/test/base/maths/CMakeLists.txt index 7130ad6..8cf0774 100644 --- a/3rdparty/ozz-animation/test/base/maths/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/base/maths/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(test_math target_link_libraries(test_math ozz_base gtest) +target_copy_shared_libraries(test_math) add_test(NAME test_math COMMAND test_math) set_target_properties(test_math PROPERTIES FOLDER "ozz/tests/base") @@ -20,6 +21,7 @@ add_executable(test_simd_math target_link_libraries(test_simd_math ozz_base gtest) +target_copy_shared_libraries(test_simd_math) add_test(NAME test_simd_math COMMAND test_simd_math) set_target_properties(test_simd_math PROPERTIES FOLDER "ozz/tests/base") @@ -31,6 +33,7 @@ add_executable(test_soa_math target_link_libraries(test_soa_math ozz_base gtest) +target_copy_shared_libraries(test_soa_math) add_test(NAME test_soa_math COMMAND test_soa_math) set_target_properties(test_soa_math PROPERTIES FOLDER "ozz/tests/base") @@ -41,5 +44,6 @@ add_executable(test_archive_maths target_link_libraries(test_archive_maths ozz_base gtest) +target_copy_shared_libraries(test_archive_maths) add_test(NAME test_archive_maths COMMAND test_archive_maths) set_target_properties(test_archive_maths PROPERTIES FOLDER "ozz/tests/base") \ No newline at end of file diff --git a/3rdparty/ozz-animation/test/base/maths/simd_float4x4_tests.cc b/3rdparty/ozz-animation/test/base/maths/simd_float4x4_tests.cc index ccf0fc6..30e9f9b 100644 --- a/3rdparty/ozz-animation/test/base/maths/simd_float4x4_tests.cc +++ b/3rdparty/ozz-animation/test/base/maths/simd_float4x4_tests.cc @@ -25,14 +25,12 @@ // // //----------------------------------------------------------------------------// -#include "ozz/base/maths/simd_math.h" - #include "gtest/gtest.h" - #include "ozz/base/gtest_helper.h" #include "ozz/base/maths/gtest_math_helper.h" #include "ozz/base/maths/math_constant.h" #include "ozz/base/maths/math_ex.h" +#include "ozz/base/maths/simd_math.h" using ozz::math::Float4x4; using ozz::math::SimdFloat4; @@ -236,12 +234,26 @@ TEST(Float4x4Rotate, ozz_simd_math) { EXPECT_FLOAT4x4_EQ(euler_identity, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); - const Float4x4 euler = Float4x4::FromEuler( + const Float4x4 euler_yaw = Float4x4::FromEuler( ozz::math::simd_float4::Load(ozz::math::kPi_2, 0.f, 0.f, 0.f)); - EXPECT_FLOAT4x4_EQ(euler, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, - 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); - EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(euler))); - EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(euler))); + EXPECT_FLOAT4x4_EQ(euler_yaw, 0.f, 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(euler_yaw))); + EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(euler_yaw))); + + const Float4x4 euler_pitch = Float4x4::FromEuler( + ozz::math::simd_float4::Load(0.f, ozz::math::kPi_2, 0.f, 0.f)); + EXPECT_FLOAT4x4_EQ(euler_pitch, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, + -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(euler_pitch))); + EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(euler_pitch))); + + const Float4x4 euler_roll = Float4x4::FromEuler( + ozz::math::simd_float4::Load(0.f, 0.f, ozz::math::kPi_2, 0.f)); + EXPECT_FLOAT4x4_EQ(euler_roll, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 00.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); + EXPECT_TRUE(ozz::math::AreAllTrue3(IsNormalized(euler_roll))); + EXPECT_TRUE(ozz::math::AreAllTrue1(IsOrthogonal(euler_roll))); EXPECT_ASSERTION(Float4x4::FromQuaternion( ozz::math::simd_float4::Load(1.f, 0.f, 0.f, 1.f)), diff --git a/3rdparty/ozz-animation/test/base/memory/CMakeLists.txt b/3rdparty/ozz-animation/test/base/memory/CMakeLists.txt index 26153d6..dfe9e05 100644 --- a/3rdparty/ozz-animation/test/base/memory/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/base/memory/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(test_memory target_link_libraries(test_memory ozz_base gtest) +target_copy_shared_libraries(test_memory) add_test(NAME test_memory COMMAND test_memory) set_target_properties(test_memory PROPERTIES FOLDER "ozz/tests/base") @@ -11,5 +12,6 @@ add_executable(test_unique_ptr target_link_libraries(test_unique_ptr ozz_base gtest) +target_copy_shared_libraries(test_unique_ptr) add_test(NAME test_unique_ptr COMMAND test_unique_ptr) set_target_properties(test_unique_ptr PROPERTIES FOLDER "ozz/tests/base") diff --git a/3rdparty/ozz-animation/test/base/platform_tests.cc b/3rdparty/ozz-animation/test/base/platform_tests.cc index 54efeb9..a3ee995 100644 --- a/3rdparty/ozz-animation/test/base/platform_tests.cc +++ b/3rdparty/ozz-animation/test/base/platform_tests.cc @@ -89,6 +89,7 @@ TEST(PointerAlignment, Platform) { TEST(TypeSize, Platform) { // Checks sizes. static_assert(CHAR_BIT == 8, "Unexpected type size"); + static_assert(sizeof(ozz::byte) == 1, "Unexpected type size"); static_assert(sizeof(int8_t) == 1, "Unexpected type size"); static_assert(sizeof(uint8_t) == 1, "Unexpected type size"); static_assert(sizeof(int16_t) == 2, "Unexpected type size"); @@ -107,6 +108,7 @@ TEST(TypeSize, Platform) { static_assert((int16_t(-1) >> 1) == -1, "Unexpected type sign"); static_assert((int32_t(-1) >> 1) == -1, "Unexpected type sign"); static_assert((int64_t(-1) >> 1) == -1, "Unexpected type sign"); + static_assert((ozz::byte(-1) >> 1) == 0x7f, "Unexpected type sign"); static_assert((uint8_t(-1) >> 1) == 0x7f, "Unexpected type sign"); static_assert((uint16_t(-1) >> 1) == 0x7fff, "Unexpected type sign"); static_assert((uint32_t(-1) >> 1) == 0x7fffffff, "Unexpected type sign"); diff --git a/3rdparty/ozz-animation/test/base/span_tests.cc b/3rdparty/ozz-animation/test/base/span_tests.cc index 49f0b4f..32be2a5 100644 --- a/3rdparty/ozz-animation/test/base/span_tests.cc +++ b/3rdparty/ozz-animation/test/base/span_tests.cc @@ -104,10 +104,10 @@ TEST(SpanAsBytes, Platform) { ozz::span si(ai); EXPECT_EQ(si.size(), kSize); - ozz::span ab = as_bytes(si); + ozz::span ab = as_bytes(si); EXPECT_EQ(ab.size(), kSize * sizeof(int)); - ozz::span awb = as_writable_bytes(si); + ozz::span awb = as_writable_bytes(si); EXPECT_EQ(awb.size(), kSize * sizeof(int)); } @@ -116,17 +116,17 @@ TEST(SpanAsBytes, Platform) { ozz::span sc(ac); EXPECT_EQ(sc.size(), kSize); - ozz::span ab = as_bytes(sc); + ozz::span ab = as_bytes(sc); EXPECT_EQ(ab.size(), sc.size()); - ozz::span awbc = as_writable_bytes(sc); + ozz::span awbc = as_writable_bytes(sc); EXPECT_EQ(awbc.size(), sc.size()); } { // const ozz::span si(ai); EXPECT_EQ(si.size(), kSize); - ozz::span ab = as_bytes(si); + ozz::span ab = as_bytes(si); EXPECT_EQ(ab.size(), kSize * sizeof(int)); } @@ -136,14 +136,14 @@ TEST(SpanAsBytes, Platform) { ozz::span sc(ac); EXPECT_EQ(sc.size(), kSize); - ozz::span ab = as_bytes(sc); + ozz::span ab = as_bytes(sc); EXPECT_EQ(ab.size(), sc.size()); } } TEST(SpanFill, Platform) { - alignas(alignof(int)) char abuffer[16]; - ozz::span src(abuffer); + alignas(alignof(int)) ozz::byte abuffer[16]; + ozz::span src(abuffer); ozz::span ispan1 = ozz::fill_span(src, 3); EXPECT_EQ(ispan1.size(), 3u); @@ -152,7 +152,7 @@ TEST(SpanFill, Platform) { EXPECT_TRUE(src.empty()); EXPECT_ASSERTION(ozz::fill_span(src, 1), "Invalid range."); - // Bad aligment + // Bad alignment src = ozz::make_span(abuffer); ozz::span cspan = ozz::fill_span(src, 1); @@ -181,3 +181,47 @@ TEST(SpanRangeLoop, Platform) { i++; } } + +TEST(SpanSubSpan, Platform) { + const size_t kSize = 46; + size_t ai[kSize]; + for (size_t i = 0; i < kSize; ++i) { + ai[i] = i; + } + + { // empty + ozz::span eai; + ozz::span seai = eai.subspan(0, 0); + EXPECT_EQ(seai.size(), 0u); + } + + { // subspan + ozz::span ncai(ai); + + EXPECT_ASSERTION(ncai.subspan(kSize, 1), " count out of range"); + EXPECT_ASSERTION(ncai.subspan(1, kSize), " count out of range"); + EXPECT_ASSERTION(ncai.subspan(kSize + 1, 0), "Offset out of range"); + EXPECT_ASSERTION(ncai.subspan(0, kSize + 1), "Count out of range"); + + EXPECT_EQ(ncai.subspan(0, 0).size(), 0u); + EXPECT_EQ(ncai.subspan(0, kSize).size(), kSize); + EXPECT_EQ(ncai.subspan(0, kSize - 10)[0], 0u); + EXPECT_EQ(ncai.subspan(10, kSize - 10).size(), kSize - 10); + EXPECT_EQ(ncai.subspan(10, kSize - 10)[0], 10u); + EXPECT_EQ(ncai.subspan(0, kSize - 10).size(), kSize - 10); + } + + { // first - last + ozz::span ncai(ai); + + EXPECT_ASSERTION(ncai.first(kSize + 1), "Count out of range"); + EXPECT_EQ(ncai.first(0).size(), 0u); + EXPECT_EQ(ncai.first(10).size(), 10u); + EXPECT_EQ(ncai.first(10)[0], 0u); + + EXPECT_ASSERTION(ncai.last(kSize + 1), "Count out of range"); + EXPECT_EQ(ncai.last(0).size(), 0u); + EXPECT_EQ(ncai.last(10).size(), 10u); + EXPECT_EQ(ncai.last(10)[0], kSize - 10); + } +} diff --git a/3rdparty/ozz-animation/test/geometry/runtime/CMakeLists.txt b/3rdparty/ozz-animation/test/geometry/runtime/CMakeLists.txt index c596f3b..107a67b 100644 --- a/3rdparty/ozz-animation/test/geometry/runtime/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/geometry/runtime/CMakeLists.txt @@ -5,6 +5,7 @@ target_link_libraries(test_skinning_job ozz_geometry ozz_base gtest) +target_copy_shared_libraries(test_skinning_job) set_target_properties(test_skinning_job PROPERTIES FOLDER "ozz/tests/geometry") add_test(NAME test_skinning_job COMMAND test_skinning_job) @@ -17,5 +18,7 @@ add_dependencies(test_fuse_geometry BUILD_FUSE_ozz_geometry) target_link_libraries(test_fuse_geometry ozz_base gtest) +#target_copy_shared_libraries(test_fuse_geometry) add_test(NAME test_fuse_geometry COMMAND test_fuse_geometry) set_target_properties(test_fuse_geometry PROPERTIES FOLDER "ozz/tests/geometry") +target_compile_definitions(test_fuse_geometry PRIVATE $<$:OZZ_BUILD_GEOMETRY_LIB>) \ No newline at end of file diff --git a/3rdparty/ozz-animation/test/options/CMakeLists.txt b/3rdparty/ozz-animation/test/options/CMakeLists.txt index fe96192..4df7cfc 100644 --- a/3rdparty/ozz-animation/test/options/CMakeLists.txt +++ b/3rdparty/ozz-animation/test/options/CMakeLists.txt @@ -1,8 +1,8 @@ add_executable(test_options options_tests.cc) target_link_libraries(test_options ozz_options - ozz_base gtest) +target_copy_shared_libraries(test_options) add_test(NAME test_options COMMAND test_options) set_target_properties(test_options PROPERTIES FOLDER "ozz/tests/options") @@ -10,6 +10,7 @@ add_executable(test_options_registration options_registration_tests.cc) target_link_libraries(test_options_registration ozz_options gtest) +target_copy_shared_libraries(test_options_registration) add_test(NAME test_options_registration COMMAND test_options_registration) set_target_properties(test_options_registration PROPERTIES FOLDER "ozz/tests/options") @@ -17,6 +18,7 @@ add_executable(test_options_registration_empty options_registration_empty_tests. target_link_libraries(test_options_registration_empty ozz_options gtest) +target_copy_shared_libraries(test_options_registration_empty) add_test(NAME test_options_registration_empty COMMAND test_options_registration_empty) set_target_properties(test_options_registration_empty PROPERTIES FOLDER "ozz/tests/options") @@ -26,10 +28,12 @@ add_executable(test_fuse_options options_registration_tests.cc ${PROJECT_BINARY_DIR}/src_fused/ozz_options.cc) add_dependencies(test_fuse_options BUILD_FUSE_ozz_options) -target_include_directories(test_fuse_options - PUBLIC "${PROJECT_SOURCE_DIR}/include") target_link_libraries(test_fuse_options + ozz_base gtest) +target_compile_definitions(test_fuse_options PRIVATE $<$:OZZ_BUILD_OPTIONS_LIB>) + +#target_copy_shared_libraries(test_fuse_options) add_test(NAME test_fuse_options COMMAND test_fuse_options) set_target_properties(test_fuse_options PROPERTIES FOLDER "ozz/tests/options") diff --git a/src/AnimGraph/AnimGraphNodes.cc b/src/AnimGraph/AnimGraphNodes.cc index bc0be18..a81d23b 100644 --- a/src/AnimGraph/AnimGraphNodes.cc +++ b/src/AnimGraph/AnimGraphNodes.cc @@ -27,7 +27,7 @@ void Blend2Node::Evaluate(AnimGraphContext& context) { ozz::animation::BlendingJob blend_job; blend_job.threshold = ozz::animation::BlendingJob().threshold; blend_job.layers = layers; - blend_job.bind_pose = context.m_skeleton->joint_bind_poses(); + blend_job.rest_pose = context.m_skeleton->joint_rest_poses(); blend_job.output = make_span(o_output->m_local_matrices); if (!blend_job.Run()) { @@ -69,7 +69,7 @@ bool AnimSamplerNode::Init(AnimGraphContext& context) { } assert (context.m_skeleton != nullptr); - m_sampling_cache.Resize(context.m_skeleton->num_joints()); + m_sampling_context.Resize(context.m_skeleton->num_joints()); return true; } @@ -79,7 +79,7 @@ void AnimSamplerNode::Evaluate(AnimGraphContext& context) { ozz::animation::SamplingJob sampling_job; sampling_job.animation = m_animation; - sampling_job.cache = &m_sampling_cache; + sampling_job.context = &m_sampling_context; sampling_job.ratio = m_time_now; sampling_job.output = make_span(o_output->m_local_matrices); diff --git a/src/AnimGraph/AnimGraphNodes.h b/src/AnimGraph/AnimGraphNodes.h index 697e253..470061b 100644 --- a/src/AnimGraph/AnimGraphNodes.h +++ b/src/AnimGraph/AnimGraphNodes.h @@ -192,7 +192,7 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { struct AnimSamplerNode : public AnimNode { AnimData* o_output = nullptr; std::string m_filename; - ozz::animation::SamplingCache m_sampling_cache; + ozz::animation::SamplingJob::Context m_sampling_context; ozz::animation::Animation* m_animation = nullptr; virtual ~AnimSamplerNode(); diff --git a/src/SkinnedMesh.cc b/src/SkinnedMesh.cc index 10c39ab..5f6ec03 100644 --- a/src/SkinnedMesh.cc +++ b/src/SkinnedMesh.cc @@ -43,7 +43,7 @@ bool SkinnedMesh::LoadSkeleton(const char* filename) { const int num_joints = m_skeleton.num_joints(); m_local_matrices.resize(num_soa_joints); m_model_matrices.resize(num_joints); - m_cache.Resize(num_joints); + m_sampling_context.Resize(num_joints); std::cout << "Successfully loaded " << skeleton_file << " (soa: " << num_soa_joints << ", joints: " << num_joints << ")" << std::endl; @@ -129,7 +129,7 @@ void SkinnedMesh::DrawDebugUi() { ozz::animation::SamplingJob sampling_job; sampling_job.animation = m_animations[selected]; - sampling_job.cache = &m_cache; + sampling_job.context = &m_sampling_context; sampling_job.ratio = m_override_ratio; sampling_job.output = make_span(m_local_matrices); if (!sampling_job.Run()) { diff --git a/src/SkinnedMesh.h b/src/SkinnedMesh.h index c86fff9..db20900 100644 --- a/src/SkinnedMesh.h +++ b/src/SkinnedMesh.h @@ -49,7 +49,7 @@ struct SkinnedMesh { std::vector m_animation_sync_track; ozz::animation::Skeleton m_skeleton; ozz::animation::Animation* m_current_animation; - ozz::animation::SamplingCache m_cache; + ozz::animation::SamplingJob::Context m_sampling_context; ozz::vector m_local_matrices; ozz::vector m_model_matrices; diff --git a/src/main.cc b/src/main.cc index 40ede66..2a3a3ea 100644 --- a/src/main.cc +++ b/src/main.cc @@ -65,7 +65,7 @@ static void draw_imgui(ImDrawData*); typedef struct { ozz::animation::Skeleton skeleton; ozz::animation::Animation animation; - ozz::animation::SamplingCache cache; + ozz::animation::SamplingJob::Context sampling_context; ozz::vector local_matrices; ozz::vector model_matrices; } ozz_t; diff --git a/tests/AnimGraphEvalTests.cc b/tests/AnimGraphEvalTests.cc index 6ac2968..b438019 100644 --- a/tests/AnimGraphEvalTests.cc +++ b/tests/AnimGraphEvalTests.cc @@ -22,14 +22,14 @@ struct SimpleAnimFixture { ozz::animation::offline::RawAnimation raw_animation_translation_y; ozz::unique_ptr animation_translate_y = nullptr; ozz::vector animation_output; - ozz::animation::SamplingCache sampling_cache; + ozz::animation::SamplingJob::Context sampling_context; SimpleAnimFixture() { createSkeleton(); createAnimations(); animation_output.resize(skeleton->num_soa_joints()); - sampling_cache.Resize(skeleton->num_joints()); + sampling_context.Resize(skeleton->num_joints()); } void createSkeleton() { @@ -103,7 +103,7 @@ TEST_CASE_METHOD( ozz::animation::SamplingJob sampling_job; sampling_job.animation = animation_translate_x.get(); - sampling_job.cache = &sampling_cache; + sampling_job.context = &sampling_context; sampling_job.ratio = 1.f; sampling_job.output = make_span(animation_output); REQUIRE(sampling_job.Run());