diff --git a/include/Engine/Rendering/BlendTree.h b/include/Engine/Rendering/BlendTree.h new file mode 100644 index 00000000..431cb8b2 --- /dev/null +++ b/include/Engine/Rendering/BlendTree.h @@ -0,0 +1,75 @@ +#ifndef BlendTree_h__ +#define BlendTree_h__ + +#include "Common.h" +#include "../GLM.h" +#include "Skeleton.h" +#include "../Core/EntityWrapper.h" +#include "../Core/World.h" +#include + +class BlendTree +{ +public: + enum class NodeType + { + Additive, + Blend, + Override, + Animation, + }; + + + struct Node + { + std::string Name; + Node* Parent = nullptr; + Node* Child[2] = { nullptr, nullptr }; + NodeType Type; + std::vector Pose; + float Weight = 0.f; + + Node* Next() { + Node* next = this; + + if (next->Child[1] == nullptr) { + // Node has no right child + next = this; + while (next->Parent != nullptr && next == next->Parent->Child[1]) { + next = next->Parent; + } + next = next->Parent; + } else { + // Find the leftmost node in the right subtree + next = next->Child[1]; + while (next->Child[0] != nullptr) { + next = next->Child[0]; + } + } + + return next; + + } + }; + + + + + + BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton); + ~BlendTree(); + + std::vector GetBoneTransforms(Skeleton* skeleton); + + void PrintTree(); + +private: + Node* m_Root = nullptr; + + void FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton); + BlendTree::Node* FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton); + + void Blend(Skeleton* skeleton, std::vector& pose); +}; + +#endif diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 773e002e..212a3888 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -15,6 +15,7 @@ #include "../Core/Transform.h" #include "Skeleton.h" #include "ShaderProgram.h" +#include "BlendTree.h" struct ModelJob : RenderJob { @@ -122,41 +123,11 @@ struct ModelJob : RenderJob Skeleton = Model->m_RawModel->m_Skeleton; if (Skeleton != nullptr) { - if (world->HasComponent(Entity, "Animation")) { - auto animationComponent = world->GetComponent(Entity, "Animation"); - - for (int i = 1; i <= 3; i++) { - ::Skeleton::AnimationData animationData; - animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); - if (animationData.animation == nullptr) { - continue; - } - animationData.time = (double)animationComponent["Time" + std::to_string(i)]; - animationData.weight = (double)animationComponent["Weight" + std::to_string(i)]; - - if((int)animationComponent["BlendType" + std::to_string(i)].Enum("Additive") == (int)animationComponent["BlendType" + std::to_string(i)]) { - animationData.blendType = Skeleton::BlendType::Additive; - } else if ((int)animationComponent["BlendType" + std::to_string(i)].Enum("Blend") == (int)animationComponent["BlendType" + std::to_string(i)]) { - animationData.blendType = Skeleton::BlendType::Blend; - } else if ((int)animationComponent["BlendType" + std::to_string(i)].Enum("Override") == (int)animationComponent["BlendType" + std::to_string(i)]) { - animationData.blendType = Skeleton::BlendType::Override; - } - - animationData.level = (int)animationComponent["Level" + std::to_string(i)]; - Animations.push_back(animationData); - } - } - - if (world->HasComponent(Entity, "AnimationOffset")) { - auto animationOffsetComponent = world->GetComponent(Entity, "AnimationOffset"); - AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationOffsetComponent["AnimationName"]); - AnimationOffset.time = (double)animationOffsetComponent["Time"]; - } else { - AnimationOffset.animation = nullptr; - } + + EntityWrapper entityWrapper = EntityWrapper(world, modelComponent.EntityID); + BlendTree = new ::BlendTree(entityWrapper, Skeleton); } } - }; unsigned int TextureID; @@ -178,7 +149,7 @@ struct ModelJob : RenderJob std::vector<::Skeleton::AnimationData> Animations; ::Skeleton::AnimationOffset AnimationOffset; - + ::BlendTree* BlendTree = nullptr; glm::vec4 DiffuseColor; glm::vec4 SpecularColor; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index f064cc3c..58021416 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -74,6 +74,7 @@ public: Blend, Override, }; + struct AnimationData { const Animation* animation; @@ -108,26 +109,24 @@ public: int GetBoneID(std::string name); - std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); - std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); + std::vector GetFrameBones(); + + std::vector GetFrameBones(const Animation* animation, double time, bool additive, bool noRootMotion = false); + void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix); const Animation* GetAnimation(std::string name); - - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); - glm::mat4 AdditiveBlend(const Bone* bone, AnimationOffset animationOffset, glm::mat4 targetPose); - void PrintSkeleton(); - void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix); glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, AnimationOffset animationOffset, glm::mat4 childMatrix); glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, glm::mat4 childMatrix); - int GetKeyframe(const Animation& animation, double time); + std::vector BlendPoses(std::vector pose1, std::vector pose2, float weight); + std::vector OverridePose(std::vector overridePose, std::vector targetPose); + private: glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset); glm::mat4 GetBonePose(const Bone* bone, const Animation* animation, double time, bool noRootMotion); diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index f950e8c8..d81c3852 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -39,4 +39,7 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xml b/resources/Schema/Components/Animation.xml index 6f49edb4..45ee8428 100644 --- a/resources/Schema/Components/Animation.xml +++ b/resources/Schema/Components/Animation.xml @@ -1,24 +1,8 @@ - - - 0 - 1.0 - 0 - 0 - true - - - 0 - 1.0 - 0 - 0 - true - - - 0 - 1.0 - 0 - 0 - true + + + 0 + true + false \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xsd b/resources/Schema/Components/Animation.xsd index e765f8e8..5e82c333 100644 --- a/resources/Schema/Components/Animation.xsd +++ b/resources/Schema/Components/Animation.xsd @@ -2,48 +2,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - \ No newline at end of file diff --git a/resources/Schema/Components/Blend.xml b/resources/Schema/Components/Blend.xml new file mode 100644 index 00000000..f949a102 --- /dev/null +++ b/resources/Schema/Components/Blend.xml @@ -0,0 +1,6 @@ + + + + + 0.5 + \ No newline at end of file diff --git a/resources/Schema/Components/Blend.xsd b/resources/Schema/Components/Blend.xsd new file mode 100644 index 00000000..95fc8f49 --- /dev/null +++ b/resources/Schema/Components/Blend.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/BlendAdditive.xml b/resources/Schema/Components/BlendAdditive.xml new file mode 100644 index 00000000..758917f9 --- /dev/null +++ b/resources/Schema/Components/BlendAdditive.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/BlendAdditive.xsd b/resources/Schema/Components/BlendAdditive.xsd new file mode 100644 index 00000000..ab931d52 --- /dev/null +++ b/resources/Schema/Components/BlendAdditive.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/BlendOverride.xml b/resources/Schema/Components/BlendOverride.xml new file mode 100644 index 00000000..a9f2095a --- /dev/null +++ b/resources/Schema/Components/BlendOverride.xml @@ -0,0 +1,6 @@ + + + + + 1.0 + \ No newline at end of file diff --git a/resources/Schema/Components/BlendOverride.xsd b/resources/Schema/Components/BlendOverride.xsd new file mode 100644 index 00000000..27fc01ed --- /dev/null +++ b/resources/Schema/Components/BlendOverride.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 8cc3f812..ace71800 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -26,42 +26,6 @@ - - - - Run - 1 - StrafeRight - 0.5 - 0.98334510030765165 - 0.5 - 0.97153983043137671 - 1 - 0.093923612201312068 - 1 - - - Models/Characters/Assault/AssaultAnimations.mesh - - - - - - - - - - R_Arm_Weapon_Joint - - - Models/Weapons/Blue/AssaultWeaponBlue.mesh - - - - - - - @@ -99,35 +63,19 @@ - + - - Run - 1 - StrafeRight - 0.5 - 0.98334510030765165 - 0.5 - 0.89665639003541542 - 1 - ShootFastRifle - - - - 0.099759525382621339 - 1 - - - AimRifle - - + + BlendOverride + AimAdditive + Models/Characters/Assault/AssaultAnimations.mesh - + R_Arm_Weapon_Joint @@ -136,45 +84,79 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - - - - - - - AimRifle - 0.5 - Ru - 0.57926159055711501 - - - Models/Characters/Assault/AssaultAnimations.mesh - true - - - - - - - + - - R_Arm_Weapon_Joint - - - Models/Weapons/Red/AssaultWeaponRed.mesh - true - + + AimRifle + + 0.5 + true + + + + + ShootRifleAnimation + BlendWalkRun + + + + + + + + RunAnimtaion + WalkAnimation + 1 + + + + + + + + Run + + 1 + + + + + + + + + Walk + + 1 + + + + + + + + + + + ShootFastRifle + + 1 + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index ffe3421a..19eded09 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -43,6 +43,9 @@ + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index e70c4f36..1b260b08 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -2,57 +2,56 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) { - if(!entity.HasComponent("Model")) { - return; - } + + EntityWrapper parent = entity.FirstParentWithComponent("Model"); Model* model; try { - model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]); + model = ResourceManager::Load<::Model, true>(parent["Model"]["Resource"]); } catch (const std::exception&) { return; } - + Skeleton* skeleton = model->m_RawModel->m_Skeleton; - if(skeleton == nullptr) { + if (skeleton == nullptr) { return; } - for (int i = 1; i <= 3; i++) { - const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); + for (int i = 1; i <= 1; i++) { + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); if (animation == nullptr) { continue;; } - double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)]; + double animationSpeed = (double)animationComponent["Speed"]; if (animationSpeed != 0.0) { - double nextTime = (double)animationComponent["Time" + std::to_string(i)] + animationSpeed * dt; + double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; - if (!(bool)animationComponent["Loop" + std::to_string(i)]) { + if (!(bool)animationComponent["Loop"]) { if (nextTime > animation->Duration) { nextTime = animation->Duration; Events::AnimationComplete e; e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + e.Name = (std::string)animationComponent["AnimationName"]; m_EventBroker->Publish(e); } else if (nextTime < 0) { Events::AnimationComplete e; e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + e.Name = (std::string)animationComponent["AnimationName"]; m_EventBroker->Publish(e); nextTime = 0; } - (double&)animationComponent["Speed" + std::to_string(i)] = 0.0; + (double&)animationComponent["Speed"] = 0.0; } else { if (nextTime > animation->Duration) { Events::AnimationComplete e; e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + e.Name = (std::string)animationComponent["AnimationName"]; m_EventBroker->Publish(e); while(nextTime > animation->Duration) { @@ -61,7 +60,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } else if (nextTime < 0) { Events::AnimationComplete e; e.Entity = entity; - e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + e.Name = (std::string)animationComponent["AnimationName"]; m_EventBroker->Publish(e); while (nextTime < 0) { @@ -70,7 +69,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } } - (double&)animationComponent["Time" + std::to_string(i)] = nextTime; + (double&)animationComponent["Time"] = nextTime; } } } diff --git a/src/Engine/Rendering/BlendTree.cpp b/src/Engine/Rendering/BlendTree.cpp new file mode 100644 index 00000000..43d1d5fd --- /dev/null +++ b/src/Engine/Rendering/BlendTree.cpp @@ -0,0 +1,255 @@ +#include "Rendering/BlendTree.h" + +BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton) +{ + auto itPair = ModelEntity.World->GetChildren(ModelEntity.ID); + if (itPair.first == itPair.second) { + return; + } + + + if (ModelEntity.HasComponent("Animation")) { + const Skeleton::Animation* animation = skeleton->GetAnimation(ModelEntity["Animation"]["AnimationName"]); + if (animation == nullptr) { + return; + } + + m_Root = new Node(); + m_Root->Name = ModelEntity.Name(); + m_Root->Pose = skeleton->GetFrameBones(animation, (double)ModelEntity["Animation"]["Time"], (bool)ModelEntity["Animation"]["Additive"]); + m_Root->Parent = nullptr; + m_Root->Type = NodeType::Animation; + + } else if (ModelEntity.HasComponent("Blend")) { + m_Root = new Node(); + m_Root->Name = ModelEntity.Name(); + m_Root->Parent = nullptr; + m_Root->Type = NodeType::Blend; + m_Root->Weight = (double)ModelEntity["Blend"]["Weight"]; + m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose1"], ModelEntity, skeleton); + m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose2"], ModelEntity, skeleton); + + } else if (ModelEntity.HasComponent("BlendOverride")) { + m_Root = new Node(); + m_Root->Name = ModelEntity.Name(); + m_Root->Parent = nullptr; + m_Root->Type = NodeType::Override; + m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendOverride"]["Master"], ModelEntity, skeleton); + m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendOverride"]["Slave"], ModelEntity, skeleton); + + } else if (ModelEntity.HasComponent("BlendAdditive")) { + m_Root = new Node(); + m_Root->Name = ModelEntity.Name(); + m_Root->Parent = nullptr; + m_Root->Type = NodeType::Additive; + m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendAdditive"]["Adder"], ModelEntity, skeleton); + m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["BlendAdditive"]["Receiver"], ModelEntity, skeleton); + } + + + + // PrintTree(); +} + +BlendTree::~BlendTree() +{ + +} + +void BlendTree::PrintTree() +{ + Node* currentNode = m_Root; + LOG_INFO("\n\n"); + + while(currentNode->Child[0] != nullptr) { + currentNode = currentNode->Child[0]; + } + + while (currentNode != nullptr) + { + LOG_INFO("%s", currentNode->Name.c_str()); + currentNode = currentNode->Next(); + } + + +} + + + +void BlendTree::FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton) +{ + auto itPair = parentEntity.World->GetChildren(parentEntity.ID); + if (itPair.first == itPair.second) { + return; // no children + } + + unsigned int childIndex = 0; + for (auto it = itPair.first; it != itPair.second; ++it) { + + EntityWrapper childEntity = EntityWrapper(parentEntity.World, it->second); + + if(!childEntity.Valid()) { + continue; + } + + if (childEntity.HasComponent("Animation")) { + const Skeleton::Animation* animation = skeleton->GetAnimation(childEntity["Animation"]["AnimationName"]); + if(animation == nullptr) { + continue; + } + + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Pose = skeleton->GetFrameBones(animation, (double)childEntity["Animation"]["Time"], (bool)childEntity["Animation"]["Additive"]); + node->Parent = parentNode; + node->Type = NodeType::Animation; + parentNode->Child[childIndex] = node; + childIndex++; + FillTree(node, childEntity, skeleton); + + } else if (childEntity.HasComponent("Blend")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Blend; + node->Weight = (double)childEntity["Blend"]["Weight"]; + parentNode->Child[childIndex] = node; + childIndex++; + FillTree(node, childEntity, skeleton); + + } else if (childEntity.HasComponent("BlendOverride")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Override; + parentNode->Child[childIndex] = node; + childIndex++; + FillTree(node, childEntity, skeleton); + + } else if (childEntity.HasComponent("BlendAdditive")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Additive; + parentNode->Child[childIndex] = node; + childIndex++; + FillTree(node, childEntity, skeleton); + } + } +} + + +BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton) +{ + EntityWrapper childEntity = parentEntity.FirstChildByName(name); + + if (!childEntity.Valid()) { + return nullptr; + } + + if (childEntity.HasComponent("Animation")) { + const Skeleton::Animation* animation = skeleton->GetAnimation(childEntity["Animation"]["AnimationName"]); + if (animation == nullptr) { + return nullptr; + } + + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Pose = skeleton->GetFrameBones(animation, (double)childEntity["Animation"]["Time"], (bool)childEntity["Animation"]["Additive"]); + node->Parent = parentNode; + node->Type = NodeType::Animation; + return node; + + } else if (childEntity.HasComponent("Blend")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Blend; + node->Weight = (double)childEntity["Blend"]["Weight"]; + node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity, skeleton); + node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity, skeleton); + return node; + } else if (childEntity.HasComponent("BlendOverride")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Override; + node->Child[0] = FillTreeByName(node, (std::string)childEntity["BlendOverride"]["Master"], childEntity, skeleton); + node->Child[1] = FillTreeByName(node, (std::string)childEntity["BlendOverride"]["Slave"], childEntity, skeleton); + return node; + } else if (childEntity.HasComponent("BlendAdditive")) { + Node* node = new Node(); + node->Name = childEntity.Name(); + node->Parent = parentNode; + node->Type = NodeType::Additive; + node->Child[0] = FillTreeByName(node, (std::string)childEntity["BlendAdditive"]["Adder"], childEntity, skeleton); + node->Child[1] = FillTreeByName(node, (std::string)childEntity["BlendAdditive"]["Receiver"], childEntity, skeleton); + return node; + } + + return nullptr; +} + +void BlendTree::Blend(Skeleton* skeleton, std::vector& pose) +{ + Node* currentNode; + Node* start = m_Root; + while (start->Child[0] != nullptr) { + start = start->Child[0]; + } + + currentNode = start; + LOG_INFO("\n\n"); + while (m_Root->Pose.size() == 0) { + if(currentNode->Pose.size() == 0) { + if(currentNode->Child[0]->Pose.size() != 0 && currentNode->Child[1]->Pose.size() != 0) { + + switch (currentNode->Type) { + case BlendTree::NodeType::Additive: + currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight); + break; + case BlendTree::NodeType::Blend: + currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight); + break; + case BlendTree::NodeType::Override: + currentNode->Pose = skeleton->OverridePose(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose); + break; + case BlendTree::NodeType::Animation: + // do nothing + break; + } + + + LOG_INFO("Blending %s and %s", currentNode->Child[0]->Name.c_str(), currentNode->Child[1]->Name.c_str()); + } + } + + + + currentNode = currentNode->Next(); + + if (currentNode == nullptr) { + currentNode = start; + } + + } + + pose = m_Root->Pose; +} + +std::vector BlendTree::GetBoneTransforms(Skeleton* skeleton) +{ + if (skeleton == nullptr || m_Root == nullptr) { + std::vector pose; + for (auto& b : skeleton->Bones) { + pose.push_back(glm::mat4(1)); + } + return pose; + } + + std::vector pose; + Blend(skeleton, pose); + + return pose; +} + diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 3effaf2c..a4d381d1 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -40,15 +40,10 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp glm::mat4 boneTransform; if (parent.HasComponent("Animation")) { - for (int i = 1; i <= 3; i++) { - ::Skeleton::AnimationData animationData; - animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName" + std::to_string(i)]); - if (animationData.animation == nullptr) { - continue; - } - animationData.time = (double)parent["Animation"]["Time" + std::to_string(i)]; - animationData.weight = (double)parent["Animation"]["Weight" + std::to_string(i)]; - + ::Skeleton::AnimationData animationData; + animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName"]); + if (animationData.animation != nullptr) { + animationData.time = (double)parent["Animation"]["Time"]; Animations.push_back(animationData); } } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 11db71f0..43722a61 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -338,11 +338,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { + /*if (explosionEffectJob->AnimationOffset.animation != nullptr) { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); } else { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + }*/ + frameBones = explosionEffectJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ExplosionEffectProgram->Bind(); @@ -365,11 +366,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); GLERROR("asdasd"); std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { + /*if (explosionEffectJob->AnimationOffset.animation != nullptr) { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); } else { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + }*/ + frameBones = explosionEffectJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -410,11 +412,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(forwardSkinnedHandle, modelJob); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /* if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->BlendTree->GetBoneTransforms(modelJob->Skeleton); glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -438,11 +441,12 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); GLERROR("asdasd"); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /* if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->BlendTree->GetBoneTransforms(modelJob->Skeleton); glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -486,11 +490,12 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::listViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /*if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ShieldToStencilProgram->Bind(); @@ -544,11 +549,12 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { + /* if (explosionEffectJob->AnimationOffset.animation != nullptr) { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); } else { frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + }*/ + frameBones = explosionEffectJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); if (GLERROR("Animation")) { @@ -583,11 +589,12 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /* if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); @@ -619,11 +626,12 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /*if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index fa1b3ca3..479cb762 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -103,11 +103,12 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /*if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } @@ -160,11 +161,12 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /* if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_PickingProgram->Bind(); @@ -215,11 +217,12 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /* if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -276,11 +279,12 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { + /*if (modelJob->AnimationOffset.animation != nullptr) { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); } else { frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + }*/ + frameBones = modelJob->Skeleton->GetFrameBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 94656848..4745b36d 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -41,29 +41,17 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) } } -std::vector Skeleton::GetFrameBones(std::vector animations, bool noRootMotion /*= false*/) +std::vector Skeleton::GetFrameBones() { - if (animations.size() <= 0) { - std::vector finalMatrices; - for (auto& b : Bones) { - finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); - } - return finalMatrices; - } - - std::map frameBones; - AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1)); - std::vector finalMatrices; - for (auto &kv : frameBones) { - finalMatrices.push_back(kv.second); + for (auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1)); } return finalMatrices; } - -std::vector Skeleton::GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/) +std::vector Skeleton::GetFrameBones(const Animation* animation, const double time, bool additive, bool noRootMotion /*= false*/) { - if (animations.size() <= 0 || animationOffset.animation == nullptr) { + if (animation == nullptr) { std::vector finalMatrices; for (auto& b : Bones) { finalMatrices.push_back(glm::mat4(1)); @@ -71,9 +59,9 @@ std::vector Skeleton::GetFrameBones(std::vector animat return finalMatrices; } - + std::map frameBones; - AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms(true, animation, time, frameBones, additive, RootBone, glm::mat4(1)); std::vector finalMatrices; for (auto &kv : frameBones) { @@ -82,175 +70,74 @@ std::vector Skeleton::GetFrameBones(std::vector animat return finalMatrices; } -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix; - - std::vector JointPoses; - - for (const AnimationData animationData : animations) { - const Animation* animation = animationData.animation; - const float time = animationData.time; - - JointFramePose jointPose; - jointPose.Weight = animationData.weight;; - - if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { - std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - - Animation::Keyframe currentFrame; - Animation::Keyframe nextFrame; - - if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone - for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame - if (time >= boneKeyFrames.at(index).Time) { - currentFrame = boneKeyFrames.at(index); - nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); - break; - } - } - - float progress; - - if (nextFrame.Index == 0) { - nextFrame = currentFrame; - progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); - } else { - progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - } - - - if (progress > 1.0f || progress < 0.0f) { - progress = glm::clamp(progress, 0.0f, 1.0f); - } - Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; - Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; - - glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; - glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); - glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; - - // Flag for no root motion - if (bone == RootBone && noRootMotion) { - position.x = 0; - position.z = 0; - } - - jointPose.Pose = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale)); - JointPoses.push_back(jointPose); - - } else { // 1 keyframes for the current bone - currentFrame = boneKeyFrames.at(0); - jointPose.Pose = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - JointPoses.push_back(jointPose); - } - } else { // 0 keyframes for the current bone - - } - + if (additive) { + time += 1.0/60.0; // first frame is a reference frame } + glm::mat4 boneMatrix; - if (JointPoses.size() == 0) { - if (bone->Parent) { - glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix); + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - boneMatrix = parentMatrix * jointPose; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } else { - boneMatrix = glm::inverse(bone->OffsetMatrix); - boneMatrices[bone->ID] = parentMatrix; - } - } else { + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; - float totalWeight = 0; + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } - for (JointFramePose jointFramePose : JointPoses) { - totalWeight += jointFramePose.Weight; - } + float progress; - glm::mat4 finalBlend = glm::mat4(0); - - for (JointFramePose jointFramePose : JointPoses) { - if (jointFramePose.Weight == 1.0f) { - finalBlend = jointFramePose.Pose; + if (nextFrame.Index == 0) { + nextFrame = currentFrame; + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); } else { - finalBlend += jointFramePose.Pose * (jointFramePose.Weight / totalWeight); + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + } + + progress = glm::clamp(progress, 0.0f, 1.0f); + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + // Flag for no root motion + if (bone == RootBone && noRootMotion) { + position.x = 0; + position.z = 0; + } + + boneMatrix = parentMatrix * (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale)); + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; } - - - boneMatrix = parentMatrix * finalBlend; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } - - for (auto &child : bone->Children) { - AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix); - } -} - -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) -{ - glm::mat4 boneMatrix; - std::vector JointPoses; - - for (const AnimationData animationData : animations) { - if (animationData.animation->JointAnimations.find(bone->ID) != animationData.animation->JointAnimations.end()) { // Does the bone have any keyframes in this animation? - JointFramePose jointPose; - jointPose.Weight = animationData.weight; - jointPose.Type = animationData.blendType; - jointPose.Level = animationData.level; - jointPose.Pose = GetBonePose(bone, animationData.animation, animationData.time, noRootMotion); - JointPoses.push_back(jointPose); - } - } - - - if (JointPoses.size() == 0) { // No keyframes for the current bone + } else { // 0 keyframes for the current bone if (bone->Parent) { - glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix); - glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose); - boneMatrix = parentMatrix * boneTransform; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + boneMatrix = parentMatrix * (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix); + boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; } else { boneMatrix = glm::inverse(bone->OffsetMatrix); boneMatrices[bone->ID] = parentMatrix; } - } else { - - - glm::mat4 finalBlend = glm::mat4(0); - glm::mat4 finalOverride = glm::mat4(0); - - int maxLevel = 0; - for (JointFramePose jointPose : JointPoses) { - maxLevel = jointPose.Level > maxLevel ? jointPose.Level : maxLevel; - } - - - for (JointFramePose jointPose : JointPoses) { - if (jointPose.Type == BlendType::Override) { - finalOverride += jointPose.Pose * jointPose.Weight; //Blend Overrides then apply to final blend - } else if(jointPose.Type == BlendType::Blend) { - finalBlend += jointPose.Pose * jointPose.Weight; - } else if (jointPose.Type == BlendType::Additive) { - //Soon - } - } - - if(finalOverride != glm::mat4(0)) { - finalBlend = finalOverride; - } - - glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, finalBlend); - boneMatrix = parentMatrix * boneTransform; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } for (auto &child : bone->Children) { - AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix); + AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, additive, child, boneMatrix); } } @@ -444,7 +331,6 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio } } - glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, AnimationOffset animationOffset, glm::mat4 childMatrix) { glm::mat4 boneMatrix; @@ -555,7 +441,6 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v } } - glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, glm::mat4 childMatrix) { glm::mat4 boneMatrix; @@ -673,6 +558,50 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v return boneMatrix; } + +std::vector Skeleton::BlendPoses(std::vector pose1, std::vector pose2, float weight) +{ + std::vector finalPose; + + if(pose1.size() != pose2.size()) { + LOG_ERROR("Number of bones does not match"); + return finalPose; + } + + for (int i = 0; i < pose1.size(); i++) { + glm::mat4 blendedPose = glm::mat4(0); + + blendedPose += pose1[i] * weight; + + blendedPose += pose2[i] * (1.f - weight); + + finalPose.push_back(blendedPose); + } + + return finalPose; +} + + +std::vector Skeleton::OverridePose(std::vector overridePose, std::vector targetPose) +{ + std::vector finalPose; + + if (overridePose.size() != targetPose.size()) { + LOG_ERROR("Number of bones does not match"); + return finalPose; + } + + for (int i = 0; i < overridePose.size(); i++) { + if(overridePose[i] != glm::mat4(1)) { + finalPose.push_back(overridePose[i]); + } else { + finalPose.push_back(targetPose[i]); + } + } + + return finalPose; +} + int Skeleton::GetBoneID(std::string name) { if (m_BonesByName.find(name) == m_BonesByName.end()) { @@ -681,47 +610,3 @@ int Skeleton::GetBoneID(std::string name) return m_BonesByName.at(name)->ID; } } - -void Skeleton::PrintSkeleton() -{ - if (LOG_LEVEL < LOG_LEVEL_DEBUG) { - return; - } - PrintSkeleton(RootBone, 0); -} - -void Skeleton::PrintSkeleton(const Bone* bone, int depthCount) -{ - std::stringstream ss; - ss << std::string(depthCount, ' '); - ss << bone->ID << ": " << bone->Name; - std::cout << ss.str() << std::endl; - - depthCount++; - - for (auto &child : bone->Children) { - PrintSkeleton(child, depthCount); - } -} - -int Skeleton::GetKeyframe(const Animation& animation, double time) -{ - -/* - if (time < 0) { - time = 0; - } - if (time >= animation.Duration) { - return animation..size() - 1; - } - - for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) { - if (animation.Keyframes[keyframe].Time > time) { - return (keyframe - 1) % animation.Keyframes.size(); - } - } -*/ - - - return 0; -}