AnimTestbed/src/AnimGraph/AnimGraphNodes.cc
2023-04-21 10:04:04 +02:00

121 lines
3.3 KiB
C++

//
// Created by martin on 25.03.22.
//
#include "AnimGraphNodes.h"
#include "ozz/base/log.h"
#include "ozz/animation/runtime/blending_job.h"
#include "ozz/animation/runtime/animation.h"
#include "ozz/base/io/archive.h"
#include "ozz/base/io/stream.h"
void Blend2Node::Evaluate(AnimGraphContext& context) {
assert (i_input0 != nullptr);
assert (i_input1 != nullptr);
assert (i_blend_weight != nullptr);
assert (o_output != nullptr);
// perform blend
ozz::animation::BlendingJob::Layer layers[2];
layers[0].transform = make_span(i_input0->m_local_matrices);
layers[0].weight = (1.0f - *i_blend_weight);
layers[1].transform = make_span(i_input1->m_local_matrices);
layers[1].weight = (*i_blend_weight);
ozz::animation::BlendingJob blend_job;
blend_job.threshold = ozz::animation::BlendingJob().threshold;
blend_job.layers = layers;
blend_job.rest_pose = context.m_skeleton->joint_rest_poses();
blend_job.output = make_span(o_output->m_local_matrices);
if (!blend_job.Run()) {
ozz::log::Err() << "Error blending animations." << std::endl;
}
}
//
// AnimSamplerNode
//
AnimSamplerNode::~AnimSamplerNode() noexcept {
m_animation = nullptr;
}
bool AnimSamplerNode::Init(AnimGraphContext& context) {
assert (m_animation == nullptr);
assert(!m_filename.empty());
AnimGraphContext::AnimationFileMap::const_iterator animation_map_iter;
animation_map_iter = context.m_animation_map.find(m_filename);
if (animation_map_iter != context.m_animation_map.end()) {
m_animation = animation_map_iter->second;
} else {
m_animation = new ozz::animation::Animation();
ozz::io::File file(m_filename.c_str(), "rb");
if (!file.opened()) {
ozz::log::Err() << "Failed to open animation file " << m_filename << "."
<< std::endl;
return false;
}
ozz::io::IArchive archive(&file);
if (!archive.TestTag<ozz::animation::Animation>()) {
ozz::log::Err() << "Failed to load animation instance from file "
<< m_filename << "." << std::endl;
return false;
}
archive >> *m_animation;
context.m_animation_map[m_filename] = m_animation;
}
assert (context.m_skeleton != nullptr);
m_sampling_context.Resize(context.m_skeleton->num_joints());
return true;
}
void AnimSamplerNode::Evaluate(AnimGraphContext& context) {
assert (o_output != nullptr);
ozz::animation::SamplingJob sampling_job;
sampling_job.animation = m_animation;
sampling_job.context = &m_sampling_context;
sampling_job.ratio = fmodf(m_time_now, m_animation->duration());
sampling_job.output = make_span(o_output->m_local_matrices);
if (!sampling_job.Run()) {
ozz::log::Err() << "Error sampling animation." << std::endl;
}
}
void LockTranslationNode::Evaluate(AnimGraphContext& context) {
o_output->m_local_matrices = i_input->m_local_matrices;
ozz::math::SoaFloat3 translation =
o_output->m_local_matrices[m_locked_bone_index].translation;
float x[4];
float y[4];
float z[4];
_mm_store_ps(x, translation.x);
_mm_store_ps(y, translation.y);
_mm_store_ps(z, translation.z);
if (m_lock_x) {
x[0] = 0.f;
}
if (m_lock_y) {
y[0] = 0.f;
}
if (m_lock_z) {
z[0] = 0.f;
}
translation.x = _mm_load_ps(x);
translation.y = _mm_load_ps(y);
translation.z = _mm_load_ps(z);
o_output->m_local_matrices[m_locked_bone_index].translation = translation;
}