BlendQueues fully working
This commit is contained in:
@@ -29,7 +29,7 @@ public:
|
||||
Node* Child[2] = { nullptr, nullptr };
|
||||
NodeType Type;
|
||||
std::map<int, Skeleton::PoseData> Pose;
|
||||
//std::vector<glm::mat4> 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<EntityWrapper, double> StartWeights;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ struct AutoAnimationBlend : Event
|
||||
bool Start = false;
|
||||
bool Reverse = false;
|
||||
bool Restart = false;
|
||||
bool SingleLevelBlend = false;
|
||||
|
||||
EntityWrapper AnimationEntity = EntityWrapper::Invalid;
|
||||
};
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
<Pose1></Pose1>
|
||||
<Pose2></Pose2>
|
||||
<Weight>0.5</Weight>
|
||||
<SubTreeRoot>false</SubTreeRoot>
|
||||
</Blend>
|
||||
@@ -8,6 +8,7 @@
|
||||
<xs:element name="Pose1" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Pose2" type="t:string" minOccurs="0"/>
|
||||
<xs:element name="Weight" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="SubTreeRoot" type="t:bool" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0.11611557" Y="1.09652853" Z="-0.231708765"/>
|
||||
<Orientation X="-0.0518394187" Y="-0.00663758488" Z="0.23004289"/>
|
||||
<Position X="0.11860811" Y="1.0820415" Z="-0.239292726"/>
|
||||
<Orientation X="-0.0479474887" Y="0.0671224222" Z="0.17587325"/>
|
||||
<Scale X="1.00000012" Y="1" Z="1.00000012"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
@@ -81,15 +81,16 @@
|
||||
<Pose1>AimPrimary</Pose1>
|
||||
<Pose2>AimSecondary</Pose2>
|
||||
<Weight>0</Weight>
|
||||
<SubTreeRoot>true</SubTreeRoot>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity name="AimSecondary">
|
||||
<Entity name="AimPrimary">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>AimSecWepA</AnimationName>
|
||||
<Time>0.5</Time>
|
||||
<AnimationName>AimRifleA</AnimationName>
|
||||
<Time>0.49999979138374329</Time>
|
||||
<Loop>false</Loop>
|
||||
<Additive>true</Additive>
|
||||
</c:Animation>
|
||||
@@ -97,11 +98,11 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="AimPrimary">
|
||||
<Entity name="AimSecondary">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>AimRifleA</AnimationName>
|
||||
<Time>0.49999979138374329</Time>
|
||||
<AnimationName>AimSecWepA</AnimationName>
|
||||
<Time>0.5</Time>
|
||||
<Loop>false</Loop>
|
||||
<Additive>true</Additive>
|
||||
</c:Animation>
|
||||
@@ -125,7 +126,8 @@
|
||||
<c:Blend>
|
||||
<Pose1>StandCrouchBlend</Pose1>
|
||||
<Pose2>JumpDashBlend</Pose2>
|
||||
<Weight>1.055110346338068e-57</Weight>
|
||||
<Weight>2.5146881298480398e-63</Weight>
|
||||
<SubTreeRoot>true</SubTreeRoot>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
@@ -135,7 +137,8 @@
|
||||
<c:Blend>
|
||||
<Pose1>StandMovement</Pose1>
|
||||
<Pose2>CrouchMovement</Pose2>
|
||||
<Weight>0.0069837930620454403</Weight>
|
||||
<Weight>0.012867419418159054</Weight>
|
||||
<SubTreeRoot>true</SubTreeRoot>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
@@ -174,7 +177,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>WalkF</AnimationName>
|
||||
<Time>0.27508859963322152</Time>
|
||||
<Time>0.62248157279189154</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -186,7 +189,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>RunF</AnimationName>
|
||||
<Time>0.5471021036571253</Time>
|
||||
<Time>0.89449507681579532</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -210,7 +213,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>StrafeLeftF</AnimationName>
|
||||
<Time>0.45668122066676009</Time>
|
||||
<Time>0.80407419382543011</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -222,7 +225,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>StrafeRightF</AnimationName>
|
||||
<Time>0.48019675054687472</Time>
|
||||
<Time>0.82758972370554473</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -281,7 +284,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>CrouchStrafeLeftF</AnimationName>
|
||||
<Time>0.064238523095263123</Time>
|
||||
<Time>0.41163149625393314</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -293,7 +296,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>CrouchStrafeRightF</AnimationName>
|
||||
<Time>0.99155998504604614</Time>
|
||||
<Time>0.33895295820471616</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -307,7 +310,7 @@
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName>CrouchWalkF</AnimationName>
|
||||
<Time>0.76993397022344823</Time>
|
||||
<Time>0.11732694338211824</Time>
|
||||
<Speed>1</Speed>
|
||||
<Play>true</Play>
|
||||
</c:Animation>
|
||||
@@ -338,6 +341,7 @@
|
||||
<Pose1>Jump</Pose1>
|
||||
<Pose2>DashBlend</Pose2>
|
||||
<Weight>1</Weight>
|
||||
<SubTreeRoot>true</SubTreeRoot>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
@@ -448,6 +452,7 @@
|
||||
<Pose1>ReloadSwitch</Pose1>
|
||||
<Pose2>WeaponActionBlend</Pose2>
|
||||
<Weight>1</Weight>
|
||||
<SubTreeRoot>true</SubTreeRoot>
|
||||
</c:Blend>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Node*> sharedParents;
|
||||
@@ -380,8 +386,8 @@ EntityWrapper BlendTree::GetSubTreeRoot(std::string nodeName)
|
||||
std::vector<Node*> 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);
|
||||
|
||||
Reference in New Issue
Block a user