// // Created by martin on 12.11.21. // #include "AnimationController.h" #include #include #include #include #include "AnimNodes/AnimSamplerNode.h" #include "AnimNodes/BlendNode.h" #include "AnimNodes/SpeedScaleNode.h" #include "SkinnedMesh.h" AnimationController::AnimationController(SkinnedMesh* skinned_mesh) : m_current_time(0.f), m_skinned_mesh(skinned_mesh) { const int num_soa_joints = skinned_mesh->m_skeleton.num_soa_joints(); const int num_joints = skinned_mesh->m_skeleton.num_joints(); skinned_mesh->m_local_matrices.resize(num_soa_joints); skinned_mesh->m_model_matrices.resize(num_joints); m_local_matrices.resize(num_soa_joints); assert(skinned_mesh->m_animations.size() > 1); SetBlendAnims(skinned_mesh->m_animations[1], skinned_mesh->m_animations[0]); ResetAnims(); AnimSamplerNode* sampler_node0 = new AnimSamplerNode(this); sampler_node0->m_name = "AnimSampler0"; sampler_node0->SetAnimation(skinned_mesh->m_animations[1]); m_anim_nodes.push_back(sampler_node0); AnimSamplerNode* sampler_node1 = new AnimSamplerNode(this); sampler_node1->m_name = "AnimSampler0"; sampler_node1->SetAnimation(skinned_mesh->m_animations[2]); m_anim_nodes.push_back(sampler_node1); SpeedScaleNode* speed_node = new SpeedScaleNode(this); speed_node->m_name = "SpeedNode0"; speed_node->m_input_node = sampler_node0; m_anim_nodes.push_back(speed_node); BlendNode* blend_node = new BlendNode(this); blend_node->m_name = "Blend0"; blend_node->m_input_A = speed_node; blend_node->m_input_B = sampler_node1; m_anim_nodes.push_back(blend_node); m_output_node = blend_node; m_output_node->CollectNodeOrdering(m_ordered_nodes); std::cout << "Have " << m_ordered_nodes.size() << " nodes in blend tree." << std::endl; m_output_node->Reset(); } AnimationController::~AnimationController() { while (m_anim_nodes.size() > 0) { delete m_anim_nodes[m_anim_nodes.size() - 1]; m_anim_nodes.pop_back(); } m_output_node = nullptr; } void AnimationController::Update(float dt) { if (m_output_node == nullptr) { return; } m_output_node->Update(dt); } void AnimationController::Evaluate() { if (m_output_node == nullptr) { return; } m_output_node->Evaluate(&m_local_matrices); // convert joint matrices from local to model space ozz::animation::LocalToModelJob ltm_job; ltm_job.skeleton = &m_skinned_mesh->m_skeleton; ltm_job.input = make_span(m_local_matrices); ltm_job.output = make_span(m_skinned_mesh->m_model_matrices); ltm_job.Run(); }; void AnimationController::DrawDebugUi() { ImGui::Begin("AnimationController"); if (m_output_node && ImGui::TreeNode("Output")) { m_output_node->DrawDebugUi(); ImGui::TreePop(); } if (m_output_node && ImGui::TreeNode("Nodes")) { for (int i = 0; i < m_ordered_nodes.size(); i++) { ImGui::Text(m_ordered_nodes[i]->m_name.c_str()); } ImGui::TreePop(); } ImGui::End(); }