Initial works for sampling root node transforms.
parent
b8d863c8e1
commit
fd4785afcd
|
@ -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}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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]));
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
}
|
}
|
Loading…
Reference in New Issue