Animation blending improved and Animation Override added
This commit is contained in:
+1
-1
Submodule assets updated: 4d36fdced7...1e7adc749e
@@ -133,7 +133,16 @@ struct ModelJob : RenderJob
|
|||||||
}
|
}
|
||||||
animationData.time = (double)animationComponent["Time" + std::to_string(i)];
|
animationData.time = (double)animationComponent["Time" + std::to_string(i)];
|
||||||
animationData.weight = (double)animationComponent["Weight" + 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);
|
Animations.push_back(animationData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,18 +68,26 @@ public:
|
|||||||
std::map<int, std::vector<Keyframe>> JointAnimations;
|
std::map<int, std::vector<Keyframe>> JointAnimations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class BlendType
|
||||||
|
{
|
||||||
|
Additive,
|
||||||
|
Blend,
|
||||||
|
Override,
|
||||||
|
};
|
||||||
struct AnimationData
|
struct AnimationData
|
||||||
{
|
{
|
||||||
const Animation* animation;
|
const Animation* animation;
|
||||||
|
BlendType blendType;
|
||||||
float time;
|
float time;
|
||||||
|
int level;
|
||||||
float weight;
|
float weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JointFrameTransform {
|
struct JointFramePose {
|
||||||
glm::vec3 Position = glm::vec3(0);
|
BlendType Type;
|
||||||
glm::quat Rotation = glm::quat();
|
int Level = 0;
|
||||||
glm::vec3 Scale = glm::vec3(0);
|
glm::mat4 Pose = glm::mat4(0);
|
||||||
float Weight;
|
float Weight = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnimationOffset {
|
struct AnimationOffset {
|
||||||
@@ -119,8 +127,10 @@ 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);
|
||||||
int GetKeyframe(const Animation& animation, double time);
|
int GetKeyframe(const Animation& animation, double time);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JointFrameTransform GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset);
|
glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset);
|
||||||
|
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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
|
||||||
<AnimationName1></AnimationName1>
|
<AnimationName1></AnimationName1>
|
||||||
|
<BlendType1><Blend/></BlendType1>
|
||||||
|
<Level1>0</Level1>
|
||||||
<Weight1>1.0</Weight1>
|
<Weight1>1.0</Weight1>
|
||||||
<Time1>0</Time1>
|
<Time1>0</Time1>
|
||||||
<Speed1>0</Speed1>
|
<Speed1>0</Speed1>
|
||||||
<Loop1>true</Loop1>
|
<Loop1>true</Loop1>
|
||||||
<AnimationName2></AnimationName2>
|
<AnimationName2></AnimationName2>
|
||||||
|
<BlendType2><Blend/></BlendType2>
|
||||||
|
<Level2>0</Level2>
|
||||||
<Weight2>1.0</Weight2>
|
<Weight2>1.0</Weight2>
|
||||||
<Time2>0</Time2>
|
<Time2>0</Time2>
|
||||||
<Speed2>0</Speed2>
|
<Speed2>0</Speed2>
|
||||||
<Loop2>true</Loop2>
|
<Loop2>true</Loop2>
|
||||||
<AnimationName3></AnimationName3>
|
<AnimationName3></AnimationName3>
|
||||||
|
<BlendType3><Blend/></BlendType3>
|
||||||
|
<Level3>0</Level3>
|
||||||
<Weight3>1.0</Weight3>
|
<Weight3>1.0</Weight3>
|
||||||
<Time3>0</Time3>
|
<Time3>0</Time3>
|
||||||
<Speed3>0</Speed3>
|
<Speed3>0</Speed3>
|
||||||
|
|||||||
@@ -3,20 +3,41 @@
|
|||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:complexType name="BlendEnum" mixed="true">
|
||||||
|
<xs:complexContent>
|
||||||
|
<xs:extension base="t:enum">
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element name="Additive" type="xs:integer" fixed="0" minOccurs="0"/>
|
||||||
|
<xs:element name="Blend" type="xs:integer" fixed="1" minOccurs="0"/>
|
||||||
|
<xs:element name="Override" type="xs:integer" fixed="2" minOccurs="0"/>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:complexContent>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
|
||||||
<xs:element name="Animation">
|
<xs:element name="Animation">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="AnimationName1" type="t:string" minOccurs="0"/>
|
<xs:element name="AnimationName1" type="t:string" minOccurs="0"/>
|
||||||
|
<xs:element name="BlendType1" type="BlendEnum" minOccurs="0"/>
|
||||||
|
<xs:element name="Level1" type="t:int" minOccurs="0"/>
|
||||||
<xs:element name="Weight1" type="t:double" minOccurs="0"/>
|
<xs:element name="Weight1" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Time1" type="t:double" minOccurs="0"/>
|
<xs:element name="Time1" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Speed1" type="t:double" minOccurs="0"/>
|
<xs:element name="Speed1" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Loop1" type="t:bool" minOccurs="0"/>
|
<xs:element name="Loop1" type="t:bool" minOccurs="0"/>
|
||||||
|
|
||||||
<xs:element name="AnimationName2" type="t:string" minOccurs="0"/>
|
<xs:element name="AnimationName2" type="t:string" minOccurs="0"/>
|
||||||
|
<xs:element name="BlendType2" type="BlendEnum" minOccurs="0"/>
|
||||||
|
<xs:element name="Level2" type="t:int" minOccurs="0"/>
|
||||||
<xs:element name="Weight2" type="t:double" minOccurs="0"/>
|
<xs:element name="Weight2" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Time2" type="t:double" minOccurs="0"/>
|
<xs:element name="Time2" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Speed2" type="t:double" minOccurs="0"/>
|
<xs:element name="Speed2" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Loop2" type="t:bool" minOccurs="0"/>
|
<xs:element name="Loop2" type="t:bool" minOccurs="0"/>
|
||||||
|
|
||||||
<xs:element name="AnimationName3" type="t:string" minOccurs="0"/>
|
<xs:element name="AnimationName3" type="t:string" minOccurs="0"/>
|
||||||
|
<xs:element name="BlendType3" type="BlendEnum" minOccurs="0"/>
|
||||||
|
<xs:element name="Level3" type="t:int" minOccurs="0"/>
|
||||||
<xs:element name="Weight3" type="t:double" minOccurs="0"/>
|
<xs:element name="Weight3" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Time3" type="t:double" minOccurs="0"/>
|
<xs:element name="Time3" type="t:double" minOccurs="0"/>
|
||||||
<xs:element name="Speed3" type="t:double" minOccurs="0"/>
|
<xs:element name="Speed3" type="t:double" minOccurs="0"/>
|
||||||
|
|||||||
@@ -29,11 +29,14 @@
|
|||||||
<Entity name="Running">
|
<Entity name="Running">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName1>Idle</AnimationName1>
|
<AnimationName1>Run</AnimationName1>
|
||||||
<Time1>1.1429797894322036</Time1>
|
|
||||||
<Speed1>1</Speed1>
|
<Speed1>1</Speed1>
|
||||||
|
<AnimationName2>StrafeRight</AnimationName2>
|
||||||
|
<Weight1>0.5</Weight1>
|
||||||
|
<Time1>0.98334510030765165</Time1>
|
||||||
|
<Weight2>0.5</Weight2>
|
||||||
|
<Time2>0.97153983043137671</Time2>
|
||||||
<Speed2>1</Speed2>
|
<Speed2>1</Speed2>
|
||||||
<Time2>0.032904333143131348</Time2>
|
|
||||||
<Time3>0.093923612201312068</Time3>
|
<Time3>0.093923612201312068</Time3>
|
||||||
<Speed3>1</Speed3>
|
<Speed3>1</Speed3>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
@@ -44,7 +47,20 @@
|
|||||||
<Position X="-1" Y="0" Z="0"/>
|
<Position X="-1" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
@@ -75,6 +91,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitPlane.mesh</Resource>
|
<Resource>Models/Core/UnitPlane.mesh</Resource>
|
||||||
|
<Color A="1" B="0.137254909" G="0.121568628" R="0.160784319"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Scale X="10" Y="1" Z="10"/>
|
<Scale X="10" Y="1" Z="10"/>
|
||||||
@@ -85,42 +102,80 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName1>Idle</AnimationName1>
|
<AnimationName1>Run</AnimationName1>
|
||||||
<Time1>1.1429797894322036</Time1>
|
|
||||||
<Speed1>1</Speed1>
|
<Speed1>1</Speed1>
|
||||||
<Speed2>0.10000000149011612</Speed2>
|
<AnimationName2>StrafeRight</AnimationName2>
|
||||||
<AnimationName2>StrafeRigh</AnimationName2>
|
<Weight1>0.5</Weight1>
|
||||||
|
<Time1>0.98334510030765165</Time1>
|
||||||
<Weight2>0.5</Weight2>
|
<Weight2>0.5</Weight2>
|
||||||
<Time2>0.67154243305829331</Time2>
|
<Time2>0.89665639003541542</Time2>
|
||||||
<Weight3>0.5</Weight3>
|
<Speed2>1</Speed2>
|
||||||
<Time3>0.32167823998061529</Time3>
|
<AnimationName3>ShootFastRifle</AnimationName3>
|
||||||
|
<BlendType3>
|
||||||
|
<Override/>
|
||||||
|
</BlendType3>
|
||||||
|
<Time3>0.099759525382621339</Time3>
|
||||||
<Speed3>1</Speed3>
|
<Speed3>1</Speed3>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:AnimationOffset>
|
<c:AnimationOffset>
|
||||||
<AnimationName>AimRifle</AnimationName>
|
<AnimationName>AimRifle</AnimationName>
|
||||||
<Time>0.15999999642372131</Time>
|
<Time>0.68999981880187988</Time>
|
||||||
</c:AnimationOffset>
|
</c:AnimationOffset>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.146727413" Y="1.15066242" Z="-0.195905238"/>
|
||||||
|
<Scale X="1.00000012" Y="1" Z="1.00000012"/>
|
||||||
|
<Orientation X="0.38856402" Y="0.017387826" Z="0.0776973143"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName1>AimRifle</AnimationName1>
|
<AnimationName1>AimRifle</AnimationName1>
|
||||||
<Time1>0.5</Time1>
|
<Speed1>0.5</Speed1>
|
||||||
|
<AnimationName2>Ru</AnimationName2>
|
||||||
|
<Time1>0.57926159055711501</Time1>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="1" Y="0" Z="0"/>
|
<Position X="1" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -54,13 +54,19 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
|||||||
e.Entity = entity;
|
e.Entity = entity;
|
||||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
nextTime -= animation->Duration;
|
|
||||||
|
while(nextTime > animation->Duration) {
|
||||||
|
nextTime -= animation->Duration;
|
||||||
|
}
|
||||||
} else if (nextTime < 0) {
|
} else if (nextTime < 0) {
|
||||||
Events::AnimationComplete e;
|
Events::AnimationComplete e;
|
||||||
e.Entity = entity;
|
e.Entity = entity;
|
||||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
nextTime += animation->Duration;
|
|
||||||
|
while (nextTime < 0) {
|
||||||
|
nextTime += animation->Duration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ void Renderer::Draw(RenderFrame& frame)
|
|||||||
|
|
||||||
}
|
}
|
||||||
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
|
m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture());
|
||||||
|
|
||||||
if (m_DebugTextureToDraw == 0) {
|
if (m_DebugTextureToDraw == 0) {
|
||||||
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure);
|
m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure);
|
||||||
}
|
}
|
||||||
|
|||||||
+147
-176
@@ -66,7 +66,7 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animat
|
|||||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||||
std::vector<glm::mat4> finalMatrices;
|
std::vector<glm::mat4> finalMatrices;
|
||||||
for (auto& b : Bones) {
|
for (auto& b : Bones) {
|
||||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
finalMatrices.push_back(glm::mat4(1));
|
||||||
}
|
}
|
||||||
return finalMatrices;
|
return finalMatrices;
|
||||||
}
|
}
|
||||||
@@ -85,14 +85,15 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animat
|
|||||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||||
{
|
{
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
std::vector<JointFrameTransform> JointTransforms;
|
|
||||||
|
std::vector<JointFramePose> JointPoses;
|
||||||
|
|
||||||
for (const AnimationData animationData : animations) {
|
for (const AnimationData animationData : animations) {
|
||||||
const Animation* animation = animationData.animation;
|
const Animation* animation = animationData.animation;
|
||||||
const float time = animationData.time;
|
const float time = animationData.time;
|
||||||
|
|
||||||
JointFrameTransform jointTransform;
|
JointFramePose jointPose;
|
||||||
jointTransform.Weight = animationData.weight;;
|
jointPose.Weight = animationData.weight;;
|
||||||
|
|
||||||
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);
|
||||||
@@ -121,31 +122,28 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
|||||||
|
|
||||||
|
|
||||||
if (progress > 1.0f || progress < 0.0f) {
|
if (progress > 1.0f || progress < 0.0f) {
|
||||||
LOG_INFO("Progress: %f", progress);
|
|
||||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||||
|
|
||||||
jointTransform.Position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||||
jointTransform.Rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||||
jointTransform.Scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||||
|
|
||||||
// Flag for no root motion
|
// Flag for no root motion
|
||||||
if (bone == RootBone && noRootMotion) {
|
if (bone == RootBone && noRootMotion) {
|
||||||
jointTransform.Position.x = 0;
|
position.x = 0;
|
||||||
jointTransform.Position.z = 0;
|
position.z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JointTransforms.push_back(jointTransform);
|
jointPose.Pose = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||||
|
JointPoses.push_back(jointPose);
|
||||||
|
|
||||||
} else { // 1 keyframes for the current bone
|
} else { // 1 keyframes for the current bone
|
||||||
currentFrame = boneKeyFrames.at(0);
|
currentFrame = boneKeyFrames.at(0);
|
||||||
jointTransform.Position = currentFrame.BoneProperties.Position;
|
jointPose.Pose = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||||
jointTransform.Rotation = currentFrame.BoneProperties.Rotation;
|
JointPoses.push_back(jointPose);
|
||||||
jointTransform.Scale = currentFrame.BoneProperties.Scale;
|
|
||||||
JointTransforms.push_back(jointTransform);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else { // 0 keyframes for the current bone
|
} else { // 0 keyframes for the current bone
|
||||||
|
|
||||||
@@ -153,49 +151,41 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JointTransforms.size() <= 0) {
|
|
||||||
|
if (JointPoses.size() == 0) {
|
||||||
if (bone->Parent) {
|
if (bone->Parent) {
|
||||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
|
||||||
|
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||||
|
|
||||||
|
boneMatrix = parentMatrix * jointPose;
|
||||||
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;
|
||||||
}
|
}
|
||||||
} else if (JointTransforms.size() == 1) {
|
|
||||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).Position) * glm::toMat4(JointTransforms.at(0).Rotation) * glm::scale(JointTransforms.at(0).Scale));
|
|
||||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
glm::vec3 finalPosInterp;
|
|
||||||
glm::quat finalRotInterp;
|
|
||||||
glm::vec3 finalScaleInterp;
|
|
||||||
float totalWeight = 0;
|
float totalWeight = 0;
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
for (JointFramePose jointFramePose : JointPoses) {
|
||||||
totalWeight += jointTransform.Weight;
|
totalWeight += jointFramePose.Weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 finalBlend = glm::mat4(0);
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
for (JointFramePose jointFramePose : JointPoses) {
|
||||||
if (jointTransform.Weight == 1.0f) {
|
if (jointFramePose.Weight == 1.0f) {
|
||||||
finalPosInterp = jointTransform.Position;
|
finalBlend = jointFramePose.Pose;
|
||||||
finalRotInterp = jointTransform.Rotation;
|
|
||||||
finalScaleInterp = jointTransform.Scale;
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
finalPosInterp += jointTransform.Position * (jointTransform.Weight/totalWeight);
|
finalBlend += jointFramePose.Pose * (jointFramePose.Weight / totalWeight);
|
||||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.Rotation, (jointTransform.Weight/totalWeight));
|
|
||||||
finalScaleInterp += jointTransform.Scale * (jointTransform.Weight/totalWeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
|
||||||
|
boneMatrix = parentMatrix * finalBlend;
|
||||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (auto &child : bone->Children) {
|
for (auto &child : bone->Children) {
|
||||||
AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix);
|
AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix);
|
||||||
}
|
}
|
||||||
@@ -204,83 +194,25 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
|||||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||||
{
|
{
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
|
std::vector<JointFramePose> JointPoses;
|
||||||
std::vector<JointFrameTransform> JointTransforms;
|
|
||||||
|
|
||||||
for (const AnimationData animationData : animations) {
|
for (const AnimationData animationData : animations) {
|
||||||
const Animation* animation = animationData.animation;
|
if (animationData.animation->JointAnimations.find(bone->ID) != animationData.animation->JointAnimations.end()) { // Does the bone have any keyframes in this animation?
|
||||||
const float time = animationData.time;
|
JointFramePose jointPose;
|
||||||
|
jointPose.Weight = animationData.weight;
|
||||||
JointFrameTransform jointTransform;
|
jointPose.Type = animationData.blendType;
|
||||||
jointTransform.Weight = animationData.weight;;
|
jointPose.Level = animationData.level;
|
||||||
|
jointPose.Pose = GetBonePose(bone, animationData.animation, animationData.time, noRootMotion);
|
||||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
JointPoses.push_back(jointPose);
|
||||||
std::vector<Animation::Keyframe> 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) {
|
|
||||||
LOG_INFO("Progress: %f", progress);
|
|
||||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
|
||||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
|
||||||
|
|
||||||
jointTransform.Position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
|
||||||
jointTransform.Rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
|
||||||
jointTransform.Scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
|
||||||
|
|
||||||
// Flag for no root motion
|
|
||||||
if (bone == RootBone && noRootMotion) {
|
|
||||||
jointTransform.Position.x = 0;
|
|
||||||
jointTransform.Position.z = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
JointTransforms.push_back(jointTransform);
|
|
||||||
|
|
||||||
} else { // 1 keyframes for the current bone
|
|
||||||
currentFrame = boneKeyFrames.at(0);
|
|
||||||
jointTransform.Position = currentFrame.BoneProperties.Position;
|
|
||||||
jointTransform.Rotation = currentFrame.BoneProperties.Rotation;
|
|
||||||
jointTransform.Scale = currentFrame.BoneProperties.Scale;
|
|
||||||
JointTransforms.push_back(jointTransform);
|
|
||||||
|
|
||||||
}
|
|
||||||
} else { // 0 keyframes for the current bone
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (JointTransforms.size() == 0) {
|
if (JointPoses.size() == 0) { // No keyframes for the current bone
|
||||||
if (bone->Parent) {
|
if (bone->Parent) {
|
||||||
|
|
||||||
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||||
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose);
|
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose);
|
||||||
|
boneMatrix = parentMatrix * boneTransform;
|
||||||
boneMatrix = parentMatrix * boneTransform;
|
|
||||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||||
} else {
|
} else {
|
||||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||||
@@ -288,33 +220,31 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
JointFrameTransform jointFinalTransform;
|
|
||||||
|
|
||||||
float totalWeight = 0;
|
glm::mat4 finalBlend = glm::mat4(0);
|
||||||
|
glm::mat4 finalOverride = glm::mat4(0);
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
int maxLevel = 0;
|
||||||
totalWeight += jointTransform.Weight;
|
for (JointFramePose jointPose : JointPoses) {
|
||||||
|
maxLevel = jointPose.Level > maxLevel ? jointPose.Level : maxLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
for (JointFramePose jointPose : JointPoses) {
|
||||||
if (jointTransform.Weight == 1.0f) {
|
if (jointPose.Type == BlendType::Override) {
|
||||||
jointFinalTransform.Position = jointTransform.Position;
|
finalOverride += jointPose.Pose * jointPose.Weight; //Blend Overrides then apply to final blend
|
||||||
jointFinalTransform.Rotation = jointTransform.Rotation;
|
} else if(jointPose.Type == BlendType::Blend) {
|
||||||
jointFinalTransform.Scale = jointTransform.Scale;
|
finalBlend += jointPose.Pose * jointPose.Weight;
|
||||||
break;
|
} else if (jointPose.Type == BlendType::Additive) {
|
||||||
} else {
|
//Soon
|
||||||
jointFinalTransform.Position += jointTransform.Position * (jointTransform.Weight/totalWeight);
|
|
||||||
jointFinalTransform.Rotation *= glm::slerp(glm::quat(), jointTransform.Rotation, (jointTransform.Weight/totalWeight));
|
|
||||||
jointFinalTransform.Scale += jointTransform.Scale * (jointTransform.Weight/totalWeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(finalOverride != glm::mat4(0)) {
|
||||||
|
finalBlend = finalOverride;
|
||||||
|
}
|
||||||
|
|
||||||
glm::mat4 jointPose = (glm::translate(jointFinalTransform.Position) * glm::toMat4(jointFinalTransform.Rotation) * glm::scale(jointFinalTransform.Scale));
|
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, finalBlend);
|
||||||
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose);
|
|
||||||
|
|
||||||
boneMatrix = parentMatrix * boneTransform;
|
boneMatrix = parentMatrix * boneTransform;
|
||||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||||
}
|
}
|
||||||
@@ -329,18 +259,14 @@ glm::mat4 Skeleton::AdditiveBlend(const Bone* bone, AnimationOffset animationOff
|
|||||||
{
|
{
|
||||||
AnimationOffset refOffset = animationOffset;
|
AnimationOffset refOffset = animationOffset;
|
||||||
refOffset.time = 0.5f; // reference pose is at 0.5s for now
|
refOffset.time = 0.5f; // reference pose is at 0.5s for now
|
||||||
JointFrameTransform refOffsetTransform = GetOffsetTransform(bone, refOffset);
|
glm::mat4 refPose = GetOffsetTransform(bone, refOffset);
|
||||||
JointFrameTransform srcOffsetTransform = GetOffsetTransform(bone, animationOffset);
|
glm::mat4 srcPose = GetOffsetTransform(bone, animationOffset);
|
||||||
|
|
||||||
glm::mat4 srcPose = (glm::translate(srcOffsetTransform.Position) * glm::toMat4(srcOffsetTransform.Rotation) * glm::scale(srcOffsetTransform.Scale));
|
|
||||||
glm::mat4 refPose = (glm::translate(refOffsetTransform.Position) * glm::toMat4(refOffsetTransform.Rotation) * glm::scale(refOffsetTransform.Scale));
|
|
||||||
|
|
||||||
glm::mat4 differencePose = srcPose * glm::inverse(refPose);
|
glm::mat4 differencePose = srcPose * glm::inverse(refPose);
|
||||||
glm::mat4 finalPose = differencePose * targetPose;
|
glm::mat4 finalPose = differencePose * targetPose;
|
||||||
return finalPose;
|
return finalPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
Skeleton::JointFrameTransform Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset)
|
glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset)
|
||||||
{
|
{
|
||||||
const Animation* animation = animationOffset.animation;
|
const Animation* animation = animationOffset.animation;
|
||||||
float time = animationOffset.time;
|
float time = animationOffset.time;
|
||||||
@@ -371,7 +297,6 @@ Skeleton::JointFrameTransform Skeleton::GetOffsetTransform(const Bone* bone, Ani
|
|||||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||||
} else {
|
} else {
|
||||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||||
@@ -392,13 +317,70 @@ Skeleton::JointFrameTransform Skeleton::GetOffsetTransform(const Bone* bone, Ani
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));;
|
||||||
|
}
|
||||||
|
|
||||||
JointFrameTransform jointTransform;
|
|
||||||
jointTransform.Position = position;
|
|
||||||
jointTransform.Rotation = rotation;
|
|
||||||
jointTransform.Scale = scale;
|
|
||||||
|
|
||||||
return jointTransform;
|
glm::mat4 Skeleton::GetBonePose(const Bone* bone, const Animation* animation, double time, bool noRootMotion)
|
||||||
|
{
|
||||||
|
glm::mat4 boneMatrix;
|
||||||
|
|
||||||
|
std::vector<JointFramePose> JointPoses;
|
||||||
|
|
||||||
|
|
||||||
|
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||||
|
std::vector<Animation::Keyframe> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
boneMatrix = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||||
|
|
||||||
|
} else { // 1 keyframes for the current bone
|
||||||
|
currentFrame = boneKeyFrames.at(0);
|
||||||
|
boneMatrix = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||||
|
}
|
||||||
|
} //else { // 0 keyframes for the current bone
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
return boneMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix)
|
glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix)
|
||||||
@@ -467,14 +449,14 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
{
|
{
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
|
|
||||||
std::vector<JointFrameTransform> JointTransforms;
|
std::vector<JointFramePose> JointPoses;
|
||||||
|
|
||||||
for (const AnimationData animationData : animations) {
|
for (const AnimationData animationData : animations) {
|
||||||
const Animation* animation = animationData.animation;
|
const Animation* animation = animationData.animation;
|
||||||
const float time = animationData.time;
|
const float time = animationData.time;
|
||||||
|
|
||||||
JointFrameTransform jointTransform;
|
JointFramePose jointPose;
|
||||||
jointTransform.Weight = animationData.weight;;
|
jointPose.Weight = animationData.weight;;
|
||||||
|
|
||||||
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);
|
||||||
@@ -503,31 +485,28 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
|
|
||||||
|
|
||||||
if (progress > 1.0f || progress < 0.0f) {
|
if (progress > 1.0f || progress < 0.0f) {
|
||||||
LOG_INFO("Progress: %f", progress);
|
|
||||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||||
|
|
||||||
jointTransform.Position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
glm::vec3 position = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||||
jointTransform.Rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
glm::quat rotation = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||||
jointTransform.Scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
glm::vec3 scale = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||||
|
|
||||||
// Flag for no root motion
|
// Flag for no root motion
|
||||||
if (bone == RootBone && noRootMotion) {
|
if (bone == RootBone && noRootMotion) {
|
||||||
jointTransform.Position.x = 0;
|
position.x = 0;
|
||||||
jointTransform.Position.z = 0;
|
position.z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JointTransforms.push_back(jointTransform);
|
jointPose.Pose = (glm::translate(position) * glm::toMat4(rotation) * glm::scale(scale));
|
||||||
|
JointPoses.push_back(jointPose);
|
||||||
|
|
||||||
} else { // 1 keyframes for the current bone
|
} else { // 1 keyframes for the current bone
|
||||||
currentFrame = boneKeyFrames.at(0);
|
currentFrame = boneKeyFrames.at(0);
|
||||||
jointTransform.Position = currentFrame.BoneProperties.Position;
|
jointPose.Pose = (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||||
jointTransform.Rotation = currentFrame.BoneProperties.Rotation;
|
JointPoses.push_back(jointPose);
|
||||||
jointTransform.Scale = currentFrame.BoneProperties.Scale;
|
|
||||||
JointTransforms.push_back(jointTransform);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else { // 0 keyframes for the current bone
|
} else { // 0 keyframes for the current bone
|
||||||
|
|
||||||
@@ -536,7 +515,7 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (JointTransforms.size() == 0) {
|
if (JointPoses.size() == 0) {
|
||||||
if (bone->Parent) {
|
if (bone->Parent) {
|
||||||
|
|
||||||
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
glm::mat4 jointPose = (glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix);
|
||||||
@@ -548,33 +527,24 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
JointFrameTransform jointFinalTransform;
|
|
||||||
|
|
||||||
float totalWeight = 0;
|
float totalWeight = 0;
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
for (JointFramePose jointFramePose : JointPoses) {
|
||||||
totalWeight += jointTransform.Weight;
|
totalWeight += jointFramePose.Weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 finalBlend = glm::mat4(0);
|
||||||
|
|
||||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
for (JointFramePose jointFramePose : JointPoses) {
|
||||||
if (jointTransform.Weight == 1.0f) {
|
if (jointFramePose.Weight == 1.0f) {
|
||||||
jointFinalTransform.Position = jointTransform.Position;
|
finalBlend = jointFramePose.Pose;
|
||||||
jointFinalTransform.Rotation = jointTransform.Rotation;
|
|
||||||
jointFinalTransform.Scale = jointTransform.Scale;
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
jointFinalTransform.Position += jointTransform.Position * (jointTransform.Weight/totalWeight);
|
finalBlend += jointFramePose.Pose * (jointFramePose.Weight / totalWeight);
|
||||||
jointFinalTransform.Rotation *= glm::slerp(glm::quat(), jointTransform.Rotation, (jointTransform.Weight/totalWeight));
|
|
||||||
jointFinalTransform.Scale += jointTransform.Scale * (jointTransform.Weight/totalWeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::mat4 jointPose = (glm::translate(jointFinalTransform.Position) * glm::toMat4(jointFinalTransform.Rotation) * glm::scale(jointFinalTransform.Scale));
|
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, finalBlend);
|
||||||
glm::mat4 boneTransform = AdditiveBlend(bone, animationOffset, jointPose);
|
|
||||||
|
|
||||||
boneMatrix = boneTransform * childMatrix;
|
boneMatrix = boneTransform * childMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,7 +559,7 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix)
|
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix)
|
||||||
{
|
{
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
std::vector<JointFrameTransform> JointTransforms;
|
/* std::vector<JointFrameTransform> JointTransforms;
|
||||||
|
|
||||||
for (const AnimationData animationData : animations) {
|
for (const AnimationData animationData : animations) {
|
||||||
const Animation* animation = animationData.animation;
|
const Animation* animation = animationData.animation;
|
||||||
@@ -625,7 +595,6 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
|
|
||||||
|
|
||||||
if (progress > 1.0f || progress < 0.0f) {
|
if (progress > 1.0f || progress < 0.0f) {
|
||||||
LOG_INFO("Progress: %f", progress);
|
|
||||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||||
@@ -688,18 +657,20 @@ glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::v
|
|||||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.Rotation, (jointTransform.Weight/totalWeight));
|
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.Rotation, (jointTransform.Weight/totalWeight));
|
||||||
finalScaleInterp += jointTransform.Scale * (jointTransform.Weight/totalWeight);
|
finalScaleInterp += jointTransform.Scale * (jointTransform.Weight/totalWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boneMatrix = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix;
|
boneMatrix = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (bone->Parent != nullptr) {
|
if (bone->Parent != nullptr) {
|
||||||
return GetBoneTransform(noRootMotion, bone->Parent, animations, boneMatrix);
|
return GetBoneTransform(noRootMotion, bone->Parent, animations, boneMatrix);
|
||||||
} else {
|
} else {
|
||||||
return boneMatrix;
|
return boneMatrix;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
return boneMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Skeleton::GetBoneID(std::string name)
|
int Skeleton::GetBoneID(std::string name)
|
||||||
|
|||||||
Reference in New Issue
Block a user