BlendTree now working but has some memory leaks
This commit is contained in:
@@ -26,7 +26,8 @@ public:
|
|||||||
Node* Parent = nullptr;
|
Node* Parent = nullptr;
|
||||||
Node* Child[2] = { nullptr, nullptr };
|
Node* Child[2] = { nullptr, nullptr };
|
||||||
NodeType Type;
|
NodeType Type;
|
||||||
std::vector<glm::mat4> Pose;
|
std::map<int, glm::mat4> Pose;
|
||||||
|
//std::vector<glm::mat4> Pose;
|
||||||
float Weight = 0.f;
|
float Weight = 0.f;
|
||||||
|
|
||||||
Node* Next() {
|
Node* Next() {
|
||||||
@@ -69,7 +70,7 @@ private:
|
|||||||
void FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton);
|
void FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton* skeleton);
|
||||||
BlendTree::Node* FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton);
|
BlendTree::Node* FillTreeByName(Node* parentNode, std::string name, EntityWrapper parentEntity, Skeleton* skeleton);
|
||||||
|
|
||||||
void Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose);
|
void Blend(Skeleton* skeleton, std::map<int, glm::mat4>& pose);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
|
|
||||||
std::vector<glm::mat4> GetFrameBones();
|
std::vector<glm::mat4> GetFrameBones();
|
||||||
|
|
||||||
std::vector<glm::mat4> GetFrameBones(const Animation* animation, double time, bool additive, bool noRootMotion = false);
|
std::map<int, glm::mat4> GetFrameBones(const Animation* animation, double time, bool additive, bool noRootMotion = false);
|
||||||
void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix);
|
void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix);
|
||||||
|
|
||||||
const Animation* GetAnimation(std::string name);
|
const Animation* GetAnimation(std::string name);
|
||||||
@@ -124,11 +124,17 @@ public:
|
|||||||
glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix);
|
glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix);
|
||||||
|
|
||||||
|
|
||||||
std::vector<glm::mat4> BlendPoses(std::vector<glm::mat4> pose1, std::vector<glm::mat4> pose2, float weight);
|
std::map<int, glm::mat4> BlendPoses(std::map<int, glm::mat4> pose1, std::map<int, glm::mat4> pose2, float weight);
|
||||||
std::vector<glm::mat4> OverridePose(std::vector<glm::mat4> overridePose, std::vector<glm::mat4> targetPose);
|
std::map<int, glm::mat4> OverridePose(std::map<int, glm::mat4> overridePose, std::map<int, glm::mat4> targetPose);
|
||||||
|
std::map<int, glm::mat4> BlendPoseAdditive(std::map<int, glm::mat4> additivePose, std::map<int, glm::mat4> targetPose);
|
||||||
|
|
||||||
|
std::vector<glm::mat4> GetFinalPose(std::map<int, glm::mat4>& boneMatrices);
|
||||||
|
void AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix);
|
||||||
|
|
||||||
|
void AdditiveBoneTransforms(const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, const Bone* bone);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset);
|
glm::mat4 GetAdditiveBonePose(const Bone* bone, const Animation* animation, double time);
|
||||||
glm::mat4 GetBonePose(const Bone* bone, const Animation* animation, double time, bool noRootMotion);
|
glm::mat4 GetBonePose(const Bone* bone, const Animation* animation, double time, bool noRootMotion);
|
||||||
|
|
||||||
std::map<std::string, Bone*> m_BonesByName;
|
std::map<std::string, Bone*> m_BonesByName;
|
||||||
|
|||||||
@@ -2,5 +2,4 @@
|
|||||||
<BlendOverride xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BlendOverride.xsd">
|
<BlendOverride xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BlendOverride.xsd">
|
||||||
<Master></Master>
|
<Master></Master>
|
||||||
<Slave></Slave>
|
<Slave></Slave>
|
||||||
<Weight>1.0</Weight>
|
|
||||||
</BlendOverride>
|
</BlendOverride>
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="Master" type="t:string" minOccurs="0"/>
|
<xs:element name="Master" type="t:string" minOccurs="0"/>
|
||||||
<xs:element name="Slave" type="t:string" minOccurs="0"/>
|
<xs:element name="Slave" type="t:string" minOccurs="0"/>
|
||||||
<xs:element name="Weight" type="t:double" minOccurs="0"/>
|
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -65,11 +65,10 @@
|
|||||||
</Entity>
|
</Entity>
|
||||||
<Entity name="Assault">
|
<Entity name="Assault">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Blend>
|
<c:BlendAdditive>
|
||||||
<Pose1>BlendOverride</Pose1>
|
<Adder>AimAdditive</Adder>
|
||||||
<Pose2>AimAdditive</Pose2>
|
<Receiver>BlendOverride</Receiver>
|
||||||
<Weight>1</Weight>
|
</c:BlendAdditive>
|
||||||
</c:Blend>
|
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
@@ -93,9 +92,8 @@
|
|||||||
<Entity name="AimAdditive">
|
<Entity name="AimAdditive">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName>AimRifle</AnimationName>
|
<AnimationName>AimRifleA</AnimationName>
|
||||||
<Time>0.13031392561420052</Time>
|
<Time>1</Time>
|
||||||
<Speed>0.5</Speed>
|
|
||||||
<Additive>true</Additive>
|
<Additive>true</Additive>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
@@ -106,57 +104,79 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:BlendOverride>
|
<c:BlendOverride>
|
||||||
<Master>ShootRifleAnimation</Master>
|
<Master>ShootRifleAnimation</Master>
|
||||||
<Slave>BlendWalkRun</Slave>
|
<Slave>MovementBlend</Slave>
|
||||||
<Weight>0</Weight>
|
|
||||||
</c:BlendOverride>
|
</c:BlendOverride>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
<Entity name="BlendWalkRun">
|
|
||||||
<Components>
|
|
||||||
<c:Blend>
|
|
||||||
<Pose1>RunAnimtaion</Pose1>
|
|
||||||
<Pose2>WalkAnimation</Pose2>
|
|
||||||
<Weight>1</Weight>
|
|
||||||
</c:Blend>
|
|
||||||
<c:Transform/>
|
|
||||||
</Components>
|
|
||||||
<Children>
|
|
||||||
<Entity name="RunAnimtaion">
|
|
||||||
<Components>
|
|
||||||
<c:Animation>
|
|
||||||
<AnimationName>Run</AnimationName>
|
|
||||||
<Time>0.26062785122840193</Time>
|
|
||||||
<Speed>1</Speed>
|
|
||||||
</c:Animation>
|
|
||||||
<c:Transform/>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
<Entity name="WalkAnimation">
|
|
||||||
<Components>
|
|
||||||
<c:Animation>
|
|
||||||
<AnimationName>Walk</AnimationName>
|
|
||||||
<Time>0.26101654028221088</Time>
|
|
||||||
<Speed>1</Speed>
|
|
||||||
</c:Animation>
|
|
||||||
<c:Transform/>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
</Children>
|
|
||||||
</Entity>
|
|
||||||
<Entity name="ShootRifleAnimation">
|
<Entity name="ShootRifleAnimation">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName>ShootFastRifle</AnimationName>
|
<AnimationName>ShootFastRifleU</AnimationName>
|
||||||
<Time>0.061012901418647347</Time>
|
<Time>0.10655260153188972</Time>
|
||||||
<Speed>1</Speed>
|
<Speed>1</Speed>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="MovementBlend">
|
||||||
|
<Components>
|
||||||
|
<c:Blend>
|
||||||
|
<Pose1>BlendWalkRun</Pose1>
|
||||||
|
<Pose2>StrafeAnimation</Pose2>
|
||||||
|
<Weight>1</Weight>
|
||||||
|
</c:Blend>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="StrafeAnimation">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName>StrafeRightF</AnimationName>
|
||||||
|
<Time>0.16490204151743337</Time>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BlendWalkRun">
|
||||||
|
<Components>
|
||||||
|
<c:Blend>
|
||||||
|
<Pose1>RunAnimtaion</Pose1>
|
||||||
|
<Pose2>WalkAnimation</Pose2>
|
||||||
|
<Weight>0.43000054359436035</Weight>
|
||||||
|
</c:Blend>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="RunAnimtaion">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName>RunF</AnimationName>
|
||||||
|
<Time>0.9239205116676299</Time>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="WalkAnimation">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName>WalkF</AnimationName>
|
||||||
|
<Time>0.15333325334317904</Time>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ void BlendTree::FillTree(Node* parentNode, EntityWrapper parentEntity, Skeleton*
|
|||||||
node->Name = childEntity.Name();
|
node->Name = childEntity.Name();
|
||||||
node->Parent = parentNode;
|
node->Parent = parentNode;
|
||||||
node->Type = NodeType::Blend;
|
node->Type = NodeType::Blend;
|
||||||
|
(double&)childEntity["Blend"]["Weight"] = glm::clamp((float)(double)childEntity["Blend"]["Weight"], 0.f, 1.f);
|
||||||
node->Weight = (double)childEntity["Blend"]["Weight"];
|
node->Weight = (double)childEntity["Blend"]["Weight"];
|
||||||
parentNode->Child[childIndex] = node;
|
parentNode->Child[childIndex] = node;
|
||||||
childIndex++;
|
childIndex++;
|
||||||
@@ -183,6 +184,7 @@ BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, E
|
|||||||
node->Name = childEntity.Name();
|
node->Name = childEntity.Name();
|
||||||
node->Parent = parentNode;
|
node->Parent = parentNode;
|
||||||
node->Type = NodeType::Blend;
|
node->Type = NodeType::Blend;
|
||||||
|
(double&)childEntity["Blend"]["Weight"] = glm::clamp((float)(double)childEntity["Blend"]["Weight"], 0.f, 1.f);
|
||||||
node->Weight = (double)childEntity["Blend"]["Weight"];
|
node->Weight = (double)childEntity["Blend"]["Weight"];
|
||||||
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity, skeleton);
|
node->Child[0] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose1"], childEntity, skeleton);
|
||||||
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity, skeleton);
|
node->Child[1] = FillTreeByName(node, (std::string)childEntity["Blend"]["Pose2"], childEntity, skeleton);
|
||||||
@@ -208,7 +210,7 @@ BlendTree::Node* BlendTree::FillTreeByName(Node* parentNode, std::string name, E
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlendTree::Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose)
|
void BlendTree::Blend(Skeleton* skeleton, std::map<int, glm::mat4>& pose)
|
||||||
{
|
{
|
||||||
Node* currentNode;
|
Node* currentNode;
|
||||||
Node* start = m_Root;
|
Node* start = m_Root;
|
||||||
@@ -220,30 +222,37 @@ void BlendTree::Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose)
|
|||||||
LOG_INFO("\n\n");
|
LOG_INFO("\n\n");
|
||||||
while (m_Root->Pose.size() == 0) {
|
while (m_Root->Pose.size() == 0) {
|
||||||
if(currentNode->Pose.size() == 0) {
|
if(currentNode->Pose.size() == 0) {
|
||||||
if(currentNode->Child[0]->Pose.size() != 0 && currentNode->Child[1]->Pose.size() != 0) {
|
if (currentNode->Child[0] != nullptr && currentNode->Child[1] != nullptr) {
|
||||||
|
if (currentNode->Child[0]->Pose.size() != 0 && currentNode->Child[1]->Pose.size() != 0) {
|
||||||
|
|
||||||
switch (currentNode->Type) {
|
switch (currentNode->Type) {
|
||||||
case BlendTree::NodeType::Additive:
|
case BlendTree::NodeType::Additive:
|
||||||
currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight);
|
currentNode->Pose = skeleton->BlendPoseAdditive(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose);
|
||||||
break;
|
break;
|
||||||
case BlendTree::NodeType::Blend:
|
case BlendTree::NodeType::Blend:
|
||||||
currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight);
|
currentNode->Pose = skeleton->BlendPoses(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose, currentNode->Weight);
|
||||||
break;
|
break;
|
||||||
case BlendTree::NodeType::Override:
|
case BlendTree::NodeType::Override:
|
||||||
currentNode->Pose = skeleton->OverridePose(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose);
|
currentNode->Pose = skeleton->OverridePose(currentNode->Child[0]->Pose, currentNode->Child[1]->Pose);
|
||||||
break;
|
break;
|
||||||
case BlendTree::NodeType::Animation:
|
case BlendTree::NodeType::Animation:
|
||||||
// do nothing
|
// do nothing
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Blending %s and %s", currentNode->Child[0]->Name.c_str(), currentNode->Child[1]->Name.c_str());
|
||||||
|
}
|
||||||
|
} else if (currentNode->Child[0] != nullptr) {
|
||||||
|
if (currentNode->Child[0]->Pose.size() != 0) {
|
||||||
|
currentNode->Pose = currentNode->Child[0]->Pose;
|
||||||
|
}
|
||||||
|
} else if (currentNode->Child[1] != nullptr) {
|
||||||
|
if (currentNode->Child[1]->Pose.size() != 0) {
|
||||||
|
currentNode->Pose = currentNode->Child[1]->Pose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LOG_INFO("Blending %s and %s", currentNode->Child[0]->Name.c_str(), currentNode->Child[1]->Name.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
currentNode = currentNode->Next();
|
currentNode = currentNode->Next();
|
||||||
|
|
||||||
if (currentNode == nullptr) {
|
if (currentNode == nullptr) {
|
||||||
@@ -257,17 +266,20 @@ void BlendTree::Blend(Skeleton* skeleton, std::vector<glm::mat4>& pose)
|
|||||||
|
|
||||||
std::vector<glm::mat4> BlendTree::GetBoneTransforms(Skeleton* skeleton)
|
std::vector<glm::mat4> BlendTree::GetBoneTransforms(Skeleton* skeleton)
|
||||||
{
|
{
|
||||||
|
std::vector<glm::mat4> finalPose;
|
||||||
if (skeleton == nullptr || m_Root == nullptr) {
|
if (skeleton == nullptr || m_Root == nullptr) {
|
||||||
std::vector<glm::mat4> pose;
|
|
||||||
for (auto& b : skeleton->Bones) {
|
for (int i = 0; i < skeleton->Bones.size(); i++) {
|
||||||
pose.push_back(glm::mat4(1));
|
finalPose.push_back(glm::mat4(1));
|
||||||
}
|
}
|
||||||
return pose;
|
return finalPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<glm::mat4> pose;
|
std::map<int, glm::mat4> pose;
|
||||||
Blend(skeleton, pose);
|
Blend(skeleton, pose);
|
||||||
|
|
||||||
return pose;
|
finalPose = skeleton->GetFinalPose(pose);
|
||||||
|
|
||||||
|
return finalPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,25 +49,26 @@ std::vector<glm::mat4> Skeleton::GetFrameBones()
|
|||||||
}
|
}
|
||||||
return finalMatrices;
|
return finalMatrices;
|
||||||
}
|
}
|
||||||
std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation* animation, const double time, bool additive, bool noRootMotion /*= false*/)
|
std::map<int, glm::mat4> Skeleton::GetFrameBones(const Animation* animation, const double time, bool additive, bool noRootMotion /*= false*/)
|
||||||
{
|
{
|
||||||
if (animation == nullptr) {
|
if (animation == nullptr) {
|
||||||
std::vector<glm::mat4> finalMatrices;
|
std::map<int, glm::mat4> finalMatrices;
|
||||||
for (auto& b : Bones) {
|
for (auto& b : Bones) {
|
||||||
finalMatrices.push_back(glm::mat4(1));
|
finalMatrices[b.second->ID] = glm::mat4(1);
|
||||||
}
|
}
|
||||||
return finalMatrices;
|
return finalMatrices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::map<int, glm::mat4> frameBones;
|
std::map<int, glm::mat4> frameBones;
|
||||||
AccumulateBoneTransforms(true, animation, time, frameBones, additive, RootBone, glm::mat4(1));
|
|
||||||
|
|
||||||
std::vector<glm::mat4> finalMatrices;
|
if(!additive) {
|
||||||
for (auto &kv : frameBones) {
|
AccumulateBoneTransforms(true, animation, time, frameBones, additive, RootBone, glm::mat4(1));
|
||||||
finalMatrices.push_back(kv.second);
|
} else {
|
||||||
|
AdditiveBoneTransforms(animation, time, frameBones, RootBone);
|
||||||
}
|
}
|
||||||
return finalMatrices;
|
|
||||||
|
return frameBones;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix)
|
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, bool additive, const Bone* bone, glm::mat4 parentMatrix)
|
||||||
@@ -77,7 +78,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
|
|
||||||
|
|
||||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||||
@@ -118,21 +119,21 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim
|
|||||||
position.z = 0;
|
position.z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boneMatrix = parentMatrix * (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
boneMatrix = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||||
boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix;
|
||||||
|
|
||||||
} else { // 1 keyframes for the current bone
|
} else { // 1 keyframes for the current bone
|
||||||
currentFrame = boneKeyFrames.at(0);
|
currentFrame = boneKeyFrames.at(0);
|
||||||
boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
boneMatrix = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||||
boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix;
|
||||||
}
|
}
|
||||||
} else { // 0 keyframes for the current bone
|
} else { // 0 keyframes for the current bone
|
||||||
if (bone->Parent) {
|
if (bone->Parent) {
|
||||||
boneMatrix = parentMatrix * (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
//boneMatrix = parentMatrix * (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||||
boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix;
|
//boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix;
|
||||||
} else {
|
} else {
|
||||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
//boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||||
boneMatrices[bone->ID] = parentMatrix;
|
//boneMatrices[bone->ID] = parentMatrix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,22 +143,36 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::mat4 Skeleton::AdditiveBlend(const Bone* bone, AnimationOffset animationOffset, glm::mat4 targetPose)
|
void Skeleton::AdditiveBoneTransforms(const Animation* animation, double time, std::map<int, glm::mat4>& boneMatrices, const Bone* bone)
|
||||||
{
|
{
|
||||||
AnimationOffset refOffset = animationOffset;
|
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||||
refOffset.time = 0.5f; // reference pose is at 0.5s for now
|
glm::mat4 refPose = GetAdditiveBonePose(bone, animation, 0.0);
|
||||||
glm::mat4 refPose = GetOffsetTransform(bone, refOffset);
|
glm::mat4 srcPose = GetAdditiveBonePose(bone, animation, time);
|
||||||
glm::mat4 srcPose = GetOffsetTransform(bone, animationOffset);
|
glm::mat4 boneMatrix = srcPose * glm::inverse(refPose);
|
||||||
glm::mat4 differencePose = srcPose * glm::inverse(refPose);
|
boneMatrices[bone->ID] = boneMatrix;
|
||||||
glm::mat4 finalPose = differencePose * targetPose;
|
}
|
||||||
return finalPose;
|
|
||||||
|
for (auto &child : bone->Children) {
|
||||||
|
AdditiveBoneTransforms(animation, time, boneMatrices, child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset)
|
|
||||||
{
|
|
||||||
const Animation* animation = animationOffset.animation;
|
|
||||||
float time = animationOffset.time;
|
|
||||||
|
|
||||||
|
|
||||||
|
glm::mat4 Skeleton::AdditiveBlend(const Bone* bone, AnimationOffset animationOffset, glm::mat4 targetPose)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
AnimationOffset refOffset = animationOffset;
|
||||||
|
refOffset.time = 0.5f; // reference pose is at 0.5s for now
|
||||||
|
glm::mat4 refPose = GetAdditiveBonePose(bone, refOffset);
|
||||||
|
glm::mat4 srcPose = GetAdditiveBonePose(bone, animationOffset);
|
||||||
|
glm::mat4 differencePose = srcPose * glm::inverse(refPose);
|
||||||
|
glm::mat4 finalPose = differencePose * targetPose;*/
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 Skeleton::GetAdditiveBonePose(const Bone* bone, const Animation* animation, double time)
|
||||||
|
{
|
||||||
glm::vec3 position = glm::vec3(0);
|
glm::vec3 position = glm::vec3(0);
|
||||||
glm::quat rotation = glm::quat();
|
glm::quat rotation = glm::quat();
|
||||||
glm::vec3 scale = glm::vec3(1);
|
glm::vec3 scale = glm::vec3(1);
|
||||||
@@ -559,51 +574,107 @@ return boneMatrix;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<glm::mat4> Skeleton::BlendPoses(std::vector<glm::mat4> pose1, std::vector<glm::mat4> pose2, float weight)
|
std::map<int, glm::mat4> Skeleton::BlendPoses(std::map<int, glm::mat4> pose1, std::map<int, glm::mat4> pose2, float weight)
|
||||||
{
|
{
|
||||||
std::vector<glm::mat4> finalPose;
|
std::map<int, glm::mat4> finalPose;
|
||||||
|
|
||||||
if(pose1.size() != pose2.size()) {
|
for (auto& b : Bones) {
|
||||||
LOG_ERROR("Number of bones does not match");
|
int boneID = b.second->ID;
|
||||||
return finalPose;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < pose1.size(); i++) {
|
|
||||||
glm::mat4 blendedPose = glm::mat4(0);
|
glm::mat4 blendedPose = glm::mat4(0);
|
||||||
|
|
||||||
blendedPose += pose1[i] * weight;
|
if(pose1.find(boneID) != pose1.end() && pose2.find(boneID) != pose2.end()) {
|
||||||
|
blendedPose += pose1.at(boneID) * weight;
|
||||||
blendedPose += pose2[i] * (1.f - weight);
|
blendedPose += pose2.at(boneID) * (1.f - weight);
|
||||||
|
finalPose[boneID] = blendedPose;
|
||||||
finalPose.push_back(blendedPose);
|
} else if(pose1.find(boneID) != pose1.end()) {
|
||||||
|
finalPose[boneID] = pose1.at(boneID);
|
||||||
|
} else if (pose2.find(boneID) != pose2.end()) {
|
||||||
|
finalPose[boneID] = pose2.at(boneID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalPose;
|
return finalPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<glm::mat4> Skeleton::OverridePose(std::vector<glm::mat4> overridePose, std::vector<glm::mat4> targetPose)
|
std::map<int, glm::mat4> Skeleton::OverridePose(std::map<int, glm::mat4> overridePose, std::map<int, glm::mat4> targetPose)
|
||||||
{
|
{
|
||||||
std::vector<glm::mat4> finalPose;
|
std::map<int, glm::mat4> finalPose;
|
||||||
|
|
||||||
if (overridePose.size() != targetPose.size()) {
|
for (auto& b : Bones) {
|
||||||
LOG_ERROR("Number of bones does not match");
|
int boneID = b.second->ID;
|
||||||
return finalPose;
|
if (overridePose.find(boneID) != overridePose.end()) {
|
||||||
}
|
finalPose[boneID] = overridePose.at(boneID);
|
||||||
|
} else if (targetPose.find(boneID) != targetPose.end()) {
|
||||||
for (int i = 0; i < targetPose.size(); i++) {
|
finalPose[boneID] = targetPose.at(boneID);
|
||||||
if(overridePose[i] != glm::mat4(1)) {
|
|
||||||
finalPose.push_back(overridePose[i]);
|
|
||||||
} else {
|
|
||||||
finalPose.push_back(targetPose[i]);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return finalPose;
|
||||||
|
}
|
||||||
|
|
||||||
//finalPose.push_back(overridePose[i]);
|
|
||||||
|
std::map<int, glm::mat4> Skeleton::BlendPoseAdditive(std::map<int, glm::mat4> additivePose, std::map<int, glm::mat4> targetPose)
|
||||||
|
{
|
||||||
|
std::map<int, glm::mat4> finalPose;
|
||||||
|
|
||||||
|
for (auto& b : Bones) {
|
||||||
|
int boneID = b.second->ID;
|
||||||
|
glm::mat4 blendedPose = glm::mat4(1);
|
||||||
|
|
||||||
|
if (additivePose.find(boneID) != additivePose.end() && targetPose.find(boneID) != targetPose.end()) {
|
||||||
|
blendedPose = additivePose.at(boneID) * targetPose.at(boneID);
|
||||||
|
finalPose[boneID] = blendedPose;
|
||||||
|
|
||||||
|
} else if (additivePose.find(boneID) != additivePose.end()) {
|
||||||
|
finalPose[boneID] = additivePose.at(boneID);
|
||||||
|
} else if (targetPose.find(boneID) != targetPose.end()) {
|
||||||
|
finalPose[boneID] = targetPose.at(boneID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalPose;
|
return finalPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<glm::mat4> Skeleton::GetFinalPose(std::map<int, glm::mat4>& boneMatrices)
|
||||||
|
{
|
||||||
|
std::vector<glm::mat4> finalPose;
|
||||||
|
|
||||||
|
AccumulateFinalPose(boneMatrices, RootBone, glm::mat4(1));
|
||||||
|
|
||||||
|
|
||||||
|
for(auto& b : boneMatrices) {
|
||||||
|
finalPose.push_back(b.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalPose;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skeleton::AccumulateFinalPose(std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||||
|
{
|
||||||
|
|
||||||
|
glm::mat4 boneMatrix;
|
||||||
|
|
||||||
|
|
||||||
|
if (boneMatrices.find(bone->ID) != boneMatrices.end()) {
|
||||||
|
|
||||||
|
boneMatrix = parentMatrix * boneMatrices.at(bone->ID);
|
||||||
|
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (bone->Parent) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &child : bone->Children) {
|
||||||
|
AccumulateFinalPose(boneMatrices, child, boneMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Skeleton::GetBoneID(std::string name)
|
int Skeleton::GetBoneID(std::string name)
|
||||||
{
|
{
|
||||||
if (m_BonesByName.find(name) == m_BonesByName.end()) {
|
if (m_BonesByName.find(name) == m_BonesByName.end()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user