137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
//
|
|
// Created by martin on 12.11.21.
|
|
//
|
|
|
|
#include "SkinnedMesh.h"
|
|
|
|
#include <HandmadeMath.h>
|
|
#include <imgui.h>
|
|
|
|
|
|
SkinnedMesh::~SkinnedMesh() {
|
|
while (m_animations.size() > 0) {
|
|
ozz::animation::Animation* animation_ptr =
|
|
m_animations[m_animations.size() - 1];
|
|
delete animation_ptr;
|
|
m_animations.pop_back();
|
|
}
|
|
}
|
|
|
|
bool SkinnedMesh::LoadSkeleton(const char* filename) {
|
|
// const char* skeleton_file = "../media/skeleton.ozz";
|
|
const char* skeleton_file = "../media/MixamoYBot-skeleton.ozz";
|
|
|
|
assert(filename);
|
|
ozz::log::Out() << "Loading skeleton archive " << filename << "."
|
|
<< std::endl;
|
|
ozz::io::File file(filename, "rb");
|
|
if (!file.opened()) {
|
|
ozz::log::Err() << "Failed to open skeleton file " << filename << "."
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
ozz::io::IArchive archive(&file);
|
|
if (!archive.TestTag<ozz::animation::Skeleton>()) {
|
|
ozz::log::Err() << "Failed to load skeleton instance from file " << filename
|
|
<< "." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Once the tag is validated, reading cannot fail.
|
|
archive >> m_skeleton;
|
|
|
|
const int num_soa_joints = m_skeleton.num_soa_joints();
|
|
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);
|
|
std::cout << "Successfully loaded " << skeleton_file
|
|
<< " (soa: " << num_soa_joints << ", joints: " << num_joints << ")"
|
|
<< std::endl;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SkinnedMesh::LoadAnimation(const char* filename) {
|
|
ozz::animation::Animation* animation_ptr = new ozz::animation::Animation();
|
|
|
|
assert(filename);
|
|
ozz::log::Out() << "Loading animation archive: " << filename << "."
|
|
<< std::endl;
|
|
ozz::io::File file(filename, "rb");
|
|
if (!file.opened()) {
|
|
ozz::log::Err() << "Failed to open animation file " << 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 "
|
|
<< filename << "." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Once the tag is validated, reading cannot fail.
|
|
archive >> *animation_ptr;
|
|
|
|
m_animations.push_back(animation_ptr);
|
|
m_animation_names.push_back(filename);
|
|
|
|
return true;
|
|
}
|
|
|
|
void SkinnedMesh::SetCurrentAnimation(int index) {
|
|
if (index < 0 || index >= m_animations.size()) {
|
|
ozz::log::Err() << "Invalid animation index " << index << " valid range: ["
|
|
<< 0 << ", " << m_animations.size() << "]'" << std::endl;
|
|
}
|
|
|
|
m_current_animation = m_animations[index];
|
|
}
|
|
|
|
//bool LoadMesh (const char* filename);
|
|
|
|
void SkinnedMesh::EvalAnimation(float in_time) {
|
|
const float anim_duration = m_current_animation->duration();
|
|
float anim_ratio = fmodf((float)in_time / anim_duration, 1.0f);
|
|
|
|
// sample animation
|
|
ozz::animation::SamplingJob sampling_job;
|
|
sampling_job.animation = m_current_animation;
|
|
sampling_job.cache = &m_cache;
|
|
sampling_job.ratio = anim_ratio;
|
|
sampling_job.output = make_span(m_local_matrices);
|
|
sampling_job.Run();
|
|
|
|
// convert joint matrices from local to model space
|
|
ozz::animation::LocalToModelJob ltm_job;
|
|
ltm_job.skeleton = &m_skeleton;
|
|
ltm_job.input = make_span(m_local_matrices);
|
|
ltm_job.output = make_span(m_model_matrices);
|
|
ltm_job.Run();
|
|
}
|
|
|
|
void SkinnedMesh::DrawSkeleton() {
|
|
|
|
}
|
|
|
|
void SkinnedMesh::DrawDebugUi() {
|
|
ImGui::Begin("SkinnedMesh");
|
|
|
|
// ImGui::Checkbox("Time override", &state.time.anim_ratio_ui_override);
|
|
|
|
// const float anim_duration = state.ozz->animation.duration();
|
|
// if (!state.time.anim_ratio_ui_override) {
|
|
// state.time.anim_ratio =
|
|
// fmodf((float)state.time.absolute / anim_duration, 1.0f);
|
|
// }
|
|
// ImGui::SliderFloat("Time", &state.time.anim_ratio, 0.f, 1.f);
|
|
|
|
// ImGui::Text(
|
|
// "Application average %.3f ms/frame (%.1f FPS)",
|
|
// 1000.0f / ImGui::GetIO().Framerate,
|
|
// ImGui::GetIO().Framerate);
|
|
|
|
ImGui::End();
|
|
|
|
} |