diff --git a/include/Engine/Rendering/BlendTree.h b/include/Engine/Rendering/BlendTree.h index 2c5f1aa8..aa06f1e6 100644 --- a/include/Engine/Rendering/BlendTree.h +++ b/include/Engine/Rendering/BlendTree.h @@ -29,7 +29,7 @@ public: Node* Child[2] = { nullptr, nullptr }; NodeType Type; std::map Pose; - //std::vector Pose; + bool SubTreeRoot = false; double Weight = 0.0; Node* Next() { @@ -61,6 +61,7 @@ public: std::string NodeName; double progress; bool Start; + bool SingleBlend; std::unordered_map StartWeights; }; diff --git a/include/Engine/Rendering/EAutoAnimationBlend.h b/include/Engine/Rendering/EAutoAnimationBlend.h index 08c49191..ebd29848 100644 --- a/include/Engine/Rendering/EAutoAnimationBlend.h +++ b/include/Engine/Rendering/EAutoAnimationBlend.h @@ -17,6 +17,7 @@ struct AutoAnimationBlend : Event bool Start = false; bool Reverse = false; bool Restart = false; + bool SingleLevelBlend = false; EntityWrapper AnimationEntity = EntityWrapper::Invalid; }; diff --git a/resources/Schema/Components/Blend.xml b/resources/Schema/Components/Blend.xml index f949a102..a4a328ca 100644 --- a/resources/Schema/Components/Blend.xml +++ b/resources/Schema/Components/Blend.xml @@ -3,4 +3,5 @@ 0.5 + false \ No newline at end of file diff --git a/resources/Schema/Components/Blend.xsd b/resources/Schema/Components/Blend.xsd index 95fc8f49..34d32385 100644 --- a/resources/Schema/Components/Blend.xsd +++ b/resources/Schema/Components/Blend.xsd @@ -8,6 +8,7 @@ + diff --git a/resources/Schema/Entities/BlendTreeTest.xml b/resources/Schema/Entities/BlendTreeTest.xml index d2c7ead9..a3188348 100644 --- a/resources/Schema/Entities/BlendTreeTest.xml +++ b/resources/Schema/Entities/BlendTreeTest.xml @@ -68,8 +68,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + @@ -81,15 +81,16 @@ AimPrimary AimSecondary 0 + true - + - AimSecWepA - + AimRifleA + false true @@ -97,11 +98,11 @@ - + - AimRifleA - + AimSecWepA + false true @@ -125,7 +126,8 @@ StandCrouchBlend JumpDashBlend - 1.055110346338068e-57 + 2.5146881298480398e-63 + true @@ -135,7 +137,8 @@ StandMovement CrouchMovement - 0.0069837930620454403 + 0.012867419418159054 + true @@ -174,7 +177,7 @@ WalkF - + 1 true @@ -186,7 +189,7 @@ RunF - + 1 true @@ -210,7 +213,7 @@ StrafeLeftF - + 1 true @@ -222,7 +225,7 @@ StrafeRightF - + 1 true @@ -281,7 +284,7 @@ CrouchStrafeLeftF - + 1 true @@ -293,7 +296,7 @@ CrouchStrafeRightF - + 1 true @@ -307,7 +310,7 @@ CrouchWalkF - + 1 true @@ -338,6 +341,7 @@ Jump DashBlend 1 + true @@ -448,6 +452,7 @@ ReloadSwitch WeaponActionBlend 1 + true diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 4434e80b..5c048fed 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -148,11 +148,11 @@ void AnimationSystem::UpdateWeights(double dt) bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) { - if(!e.RootNode.Valid()) { + if (!e.RootNode.Valid()) { return false; } - if(!e.RootNode.HasComponent("Model")) { + if (!e.RootNode.HasComponent("Model")) { return false; } @@ -179,7 +179,7 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) EntityWrapper subTreeRoot = blendTree->GetSubTreeRoot(e.NodeName); - if(!subTreeRoot.Valid()) { + if (!subTreeRoot.Valid()) { return false; } @@ -193,16 +193,18 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) abj.BlendInfo.NodeName = e.NodeName; abj.BlendInfo.progress = 0.0; abj.BlendInfo.Start = e.Start; + abj.BlendInfo.SingleBlend = e.SingleLevelBlend; - if (e.Restart) { - EntityWrapper nodeEntity = subTreeRoot.FirstChildByName(e.NodeName); - if (nodeEntity.Valid()) { - if (nodeEntity.HasComponent("Animation")) { - const Skeleton::Animation* animation = skeleton->GetAnimation(nodeEntity["Animation"]["AnimationName"]); + EntityWrapper nodeEntity = subTreeRoot.FirstChildByName(e.NodeName); // more than one + if (nodeEntity.Valid()) { + if (nodeEntity.HasComponent("Animation")) { + const Skeleton::Animation* animation = skeleton->GetAnimation(nodeEntity["Animation"]["AnimationName"]); + (bool&)nodeEntity["Animation"]["Reverse"] = e.Reverse; + + if (e.Restart) { if (animation != nullptr) { if (e.Restart) { - (bool&)nodeEntity["Animation"]["Reverse"] = e.Reverse; if (e.Reverse) { (double&)nodeEntity["Animation"]["Time"] = animation->Duration; } else { @@ -439,27 +441,7 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) aeb.RootNode = entity; aeb.Start = true; aeb.Restart = true; - m_EventBroker->Publish(aeb); - } - } - } - } else if (e.Command == "Stand") { - auto blendComponents = m_World->GetComponents("BlendAdditive"); - - if (blendComponents == nullptr) { - return false; - } - for (auto& bc : *blendComponents) { - EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); - - if (entity.Name() == "Assault") { - { - Events::AutoAnimationBlend aeb; - aeb.Duration = 0.3; - aeb.NodeName = "StandMovement"; - aeb.RootNode = entity; - aeb.Start = true; - aeb.Restart = true; + aeb.SingleLevelBlend = true; m_EventBroker->Publish(aeb); } } @@ -526,27 +508,15 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); if (entity.Name() == "Assault") { - /* { + { Events::AutoAnimationBlend aeb; aeb.Duration = 0.1; aeb.NodeName = "Right"; aeb.RootNode = entity; aeb.Start = true; m_EventBroker->Publish(aeb); - }*/ - - - { - Events::AutoAnimationBlend aeb; - aeb.Duration = 0.3; - aeb.NodeName = "Right"; - aeb.RootNode = entity; - aeb.Start = true; - aeb.Restart = false; - aeb.AnimationEntity = entity.FirstChildByName("DashRight"); - aeb.Delay = -0.3; - m_EventBroker->Publish(aeb); } + } } } else if (e.Command == "ForwardTest") { @@ -570,8 +540,51 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) } } } + } else if (e.Command == "BackwardTest") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Walk"; + aeb.RootNode = entity; + aeb.Start = true; + aeb.Reverse = true; + m_EventBroker->Publish(aeb); + } + } + } + } else if (e.Value == 0.f) { + if (e.Command == "Crouch") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "StandMovement"; + aeb.RootNode = entity; + aeb.Start = true; + aeb.Restart = true; + aeb.SingleLevelBlend = true; + m_EventBroker->Publish(aeb); + } + } + } + } } } diff --git a/src/Engine/Rendering/AutoBlendQueue.cpp b/src/Engine/Rendering/AutoBlendQueue.cpp index e75e33b5..7ea79383 100644 --- a/src/Engine/Rendering/AutoBlendQueue.cpp +++ b/src/Engine/Rendering/AutoBlendQueue.cpp @@ -54,6 +54,11 @@ void AutoBlendQueue::Insert(AutoBlendJob autoBlendJob) for (auto it = m_BlendQueue.begin(); it != m_BlendQueue.end(); it++) { auto next = std::next(it, 1); + + if (it->BlendJob.BlendInfo.NodeName == autoBlendJob.BlendInfo.NodeName) { + (*it) = blendNode; + } + if (next != m_BlendQueue.end()) { if (it->StartTime >= blendNode.StartTime && next->StartTime <= blendNode.StartTime) { LOG_INFO("Inserted %s between %s and %s", blendNode.BlendJob.BlendInfo.NodeName.c_str(), it->BlendJob.BlendInfo.NodeName.c_str(), next->BlendJob.BlendInfo.NodeName.c_str()); @@ -83,11 +88,11 @@ void AutoBlendQueue::Insert(AutoBlendJob autoBlendJob) void AutoBlendQueue::UpdateTime(double dt) { for (auto it = m_BlendQueue.begin(); it != m_BlendQueue.end();) { - it->EndTime -= dt; - it->StartTime -= dt; if (it->EndTime <= 0) { it = m_BlendQueue.erase(it); } else { + it->EndTime -= dt; + it->StartTime -= dt; it++; } } diff --git a/src/Engine/Rendering/BlendTree.cpp b/src/Engine/Rendering/BlendTree.cpp index 2f74b45e..60858f2a 100644 --- a/src/Engine/Rendering/BlendTree.cpp +++ b/src/Engine/Rendering/BlendTree.cpp @@ -27,6 +27,7 @@ BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton) m_Root->Parent = nullptr; m_Root->Type = NodeType::Blend; m_Root->Weight = (double)ModelEntity["Blend"]["Weight"]; + m_Root->SubTreeRoot = (bool)ModelEntity["Blend"]["SubTreeRoot"]; (double&)ModelEntity["Blend"]["Weight"] = glm::clamp((double)ModelEntity["Blend"]["Weight"], 0.0, 1.0); m_Root->Child[0] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose1"], ModelEntity); m_Root->Child[1] = FillTreeByName(m_Root, (std::string)ModelEntity["Blend"]["Pose2"], ModelEntity); @@ -132,6 +133,7 @@ BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, E node->Type = NodeType::Blend; (double&)childEntity["Blend"]["Weight"] = glm::clamp((double)childEntity["Blend"]["Weight"], 0.0, 1.0); node->Weight = (double)childEntity["Blend"]["Weight"]; + node->SubTreeRoot = (bool)childEntity["Blend"]["SubTreeRoot"]; //if (node->Weight < 1.f && node->Weight > 0.f) { node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity); node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity); @@ -251,6 +253,10 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo) lastNode = currentNode; currentNode = currentNode->Parent; + + if (blendInfo.SingleBlend) { + break; + } } } else if(goalNodes.size() >= 2) { std::vector sharedParents; @@ -380,8 +386,8 @@ EntityWrapper BlendTree::GetSubTreeRoot(std::string nodeName) std::vector subTreeRoots; for (auto it = nodes.begin(); it != nodes.end(); it++) { - Node* currentNode = (*it); - while (currentNode->Parent->Type == NodeType::Blend) { + Node* currentNode = (*it)->Parent; + while (!currentNode->SubTreeRoot) { currentNode = currentNode->Parent; } subTreeRoots.push_back(currentNode);