Initial works for sampling root node transforms.

AnimGraphEditor
Martin Felis 2022-01-22 09:25:50 +01:00
parent b8d863c8e1
commit fd4785afcd
5 changed files with 88 additions and 82 deletions

View File

@ -53,6 +53,7 @@ add_library(AnimTestbedCode OBJECT
src/AnimNodes/BlendNode.cc src/AnimNodes/BlendNode.cc
src/AnimNodes/LockTranslationNode.cc src/AnimNodes/LockTranslationNode.cc
src/AnimationController.cc src/AnimationController.cc
src/ozzutils.cc
3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui.cpp
3rdparty/imgui/imgui_draw.cpp 3rdparty/imgui/imgui_draw.cpp
3rdparty/imgui/imgui_widgets.cpp 3rdparty/imgui/imgui_widgets.cpp
@ -60,6 +61,8 @@ add_library(AnimTestbedCode OBJECT
target_include_directories( target_include_directories(
AnimTestbedCode AnimTestbedCode
PUBLIC
src
${ThirdPartyIncludeDeps} ${ThirdPartyIncludeDeps}
) )
@ -67,6 +70,7 @@ target_include_directories(
add_executable(AnimTestbed) add_executable(AnimTestbed)
target_include_directories( target_include_directories(
AnimTestbed AnimTestbed
PUBLIC
${ThirdPartyIncludeDeps} ${ThirdPartyIncludeDeps}
) )

View File

@ -4,9 +4,12 @@
#include "AnimSamplerNode.h" #include "AnimSamplerNode.h"
#include "ozzutils.h"
#include <imgui.h> #include <imgui.h>
#include "../SkinnedMesh.h" #include "../SkinnedMesh.h"
#include "../ozzutils.h"
void AnimSamplerNode::SetAnimation(ozz::animation::Animation* animation, const SyncTrack& sync_track) { void AnimSamplerNode::SetAnimation(ozz::animation::Animation* animation, const SyncTrack& sync_track) {
m_animation = animation; m_animation = animation;
@ -36,43 +39,13 @@ void AnimSamplerNode::Evaluate(
return; return;
} }
ozz::vector<ozz::math::SoaTransform> root_bone_prev; ozz::math::Transform root_trans_prev;
root_bone_prev.push_back(ozz::math::SoaTransform()); calc_bone_translation (m_anim_ratio_prev, 0, m_animation, root_trans_prev);
sampling_job.ratio = m_anim_ratio_prev;
sampling_job.output = make_span (root_bone_prev);
if (!sampling_job.Run()) {
ozz::log::Err() << "Error sampling animation." << std::endl;
}
ozz::vector<ozz::math::SoaTransform> root_bone_cur; ozz::math::Transform root_trans_cur;
root_bone_prev.push_back(ozz::math::SoaTransform()); calc_bone_translation (m_anim_ratio, 0, m_animation, root_trans_cur);
sampling_job.ratio = m_anim_ratio;
sampling_job.output = make_span (root_bone_cur);
if (!sampling_job.Run()) {
ozz::log::Err() << "Error sampling animation." << std::endl;
}
ozz::math::SoaFloat3 translation =
root_bone_prev[m_root_bone_index].translation;
float root_prev_trans_x[4];
float root_prev_trans_y[4];
float root_prev_trans_z[4];
_mm_store_ps(root_prev_trans_x, translation.x);
_mm_store_ps(root_prev_trans_y, translation.y);
_mm_store_ps(root_prev_trans_z, translation.z);
translation =
(*local_matrices)[m_root_bone_index].translation;
float root_current_trans_x[4];
float root_current_trans_y[4];
float root_current_trans_z[4];
_mm_store_ps(root_current_trans_x, translation.x);
_mm_store_ps(root_current_trans_y, translation.y);
_mm_store_ps(root_current_trans_z, translation.z);
root_transform->translation.x = root_current_trans_x[0]; root_transform->translation = root_trans_cur.translation - root_trans_prev.translation;
root_transform->translation.y = root_current_trans_y[0];
root_transform->translation.z = root_current_trans_z[0];
} }
void AnimSamplerNode::DrawDebugUi() { void AnimSamplerNode::DrawDebugUi() {

57
src/ozzutils.cc Normal file
View File

@ -0,0 +1,57 @@
//
// Created by martin on 10.12.21.
//
#include "ozzutils.h"
#include <ozz/base/maths/simd_math.h>
#define OZZ_INCLUDE_PRIVATE_HEADER
#include "../src/animation/runtime/animation_keyframe.h"
#undef OZZ_INCLUDE_PRIVATE_HEADER
void calc_bone_translation(
float ratio,
int i_bone_idx,
const ozz::animation::Animation* i_animation,
ozz::math::Transform& o_transform) {
int key_idx = 1;
const ozz::span<const ozz::animation::Float3Key>& translations =
i_animation->translations();
int key_idx_prev = 0;
int key_idx_next = 0;
while (key_idx < translations.size()) {
key_idx_next = key_idx;
if (translations[key_idx].track == i_bone_idx) {
if (translations[key_idx].ratio < ratio) {
key_idx_prev = key_idx;
} else {
break;
}
}
key_idx++;
}
const ozz::animation::Float3Key& key_prev = translations[key_idx_prev];
const ozz::animation::Float3Key& key_next = translations[key_idx_next];
float r = 0.f;
if (key_prev.ratio != key_next.ratio) {
r = (ratio - key_prev.ratio) / (key_next.ratio - key_prev.ratio);
}
o_transform.translation.x =
ozz::math::HalfToFloat(key_prev.value[0])
+ r
* (ozz::math::HalfToFloat(key_next.value[0])
- ozz::math::HalfToFloat(key_prev.value[0]));
o_transform.translation.y =
ozz::math::HalfToFloat(key_prev.value[1])
+ r
* (ozz::math::HalfToFloat(key_next.value[1])
- ozz::math::HalfToFloat(key_prev.value[1]));
o_transform.translation.z =
ozz::math::HalfToFloat(key_prev.value[2])
+ r
* (ozz::math::HalfToFloat(key_next.value[2])
- ozz::math::HalfToFloat(key_prev.value[2]));
}

17
src/ozzutils.h Normal file
View File

@ -0,0 +1,17 @@
//
// Created by martin on 10.12.21.
//
#ifndef ANIMTESTBED_OZZUTILS_H
#define ANIMTESTBED_OZZUTILS_H
#include <ozz/base/maths/transform.h>
#include "ozz/animation/runtime/animation.h"
void calc_bone_translation(
float ratio,
int i_bone_idx,
const ozz::animation::Animation* i_animation,
ozz::math::Transform& o_transform);
#endif //ANIMTESTBED_OZZUTILS_H

View File

@ -6,6 +6,7 @@
#define OZZ_INCLUDE_PRIVATE_HEADER #define OZZ_INCLUDE_PRIVATE_HEADER
#include "../src/animation/runtime/animation_keyframe.h" #include "../src/animation/runtime/animation_keyframe.h"
#include "catch.hpp" #include "catch.hpp"
#include "ozzutils.h"
void get_bone_transform( void get_bone_transform(
int i_bone_idx, int i_bone_idx,
@ -41,52 +42,6 @@ void sample_bone_transform(
get_bone_transform(i_bone_idx, io_local_matrices, o_transform); get_bone_transform(i_bone_idx, io_local_matrices, o_transform);
} }
void calc_bone_translation(
float ratio,
int i_bone_idx,
const ozz::animation::Animation* i_animation,
ozz::math::Transform& o_transform) {
int key_idx = 0;
const ozz::span<const ozz::animation::Float3Key>& translations =
i_animation->translations();
int key_idx_prev = 0;
int key_idx_next = 0;
while (key_idx < translations.size()) {
key_idx_next = key_idx;
if (translations[key_idx].track == i_bone_idx) {
if (translations[key_idx].ratio < ratio) {
key_idx_prev = key_idx;
} else {
break;
}
}
key_idx++;
}
const ozz::animation::Float3Key& key_prev = translations[key_idx_prev];
const ozz::animation::Float3Key& key_next = translations[key_idx_next];
float r = 0.f;
if (key_prev.ratio != key_next.ratio) {
r = (ratio - key_prev.ratio) / (key_next.ratio - key_prev.ratio);
}
o_transform.translation.x =
ozz::math::HalfToFloat(key_prev.value[0])
+ r
* (ozz::math::HalfToFloat(key_next.value[0])
- ozz::math::HalfToFloat(key_prev.value[0]));
o_transform.translation.y =
ozz::math::HalfToFloat(key_prev.value[1])
+ r
* (ozz::math::HalfToFloat(key_next.value[1])
- ozz::math::HalfToFloat(key_prev.value[1]));
o_transform.translation.z =
ozz::math::HalfToFloat(key_prev.value[2])
+ r
* (ozz::math::HalfToFloat(key_next.value[2])
- ozz::math::HalfToFloat(key_prev.value[2]));
}
TEST_CASE("Sample single bone channel", "[AnimSamplerNode]") { TEST_CASE("Sample single bone channel", "[AnimSamplerNode]") {
SkinnedMesh skinned_mesh; SkinnedMesh skinned_mesh;
@ -167,5 +122,5 @@ TEST_CASE("Root Bone Sampling", "[AnimSamplerNode]") {
test_node.UpdateTime(0.2f); test_node.UpdateTime(0.2f);
ozz::math::Transform root_transform; ozz::math::Transform root_transform;
// test_node.Evaluate(&skinned_mesh.m_local_matrices, &root_transform); test_node.Evaluate(&skinned_mesh.m_local_matrices, &root_transform);
} }