Merge remote-tracking branch 'origin/Animations' into TCPConnections
This commit is contained in:
@@ -120,6 +120,32 @@ struct ModelJob : RenderJob
|
||||
|
||||
if (model->IsSkinned()) {
|
||||
Skeleton = Model->m_RawModel->m_Skeleton;
|
||||
|
||||
if (Skeleton != nullptr) {
|
||||
if (world->HasComponent(Entity, "Animation")) {
|
||||
auto animationComponent = world->GetComponent(Entity, "Animation");
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
::Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)animationComponent["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)animationComponent["Weight" + std::to_string(i)];
|
||||
|
||||
Animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (world->HasComponent(Entity, "AnimationOffset")) {
|
||||
auto animationOffsetComponent = world->GetComponent(Entity, "AnimationOffset");
|
||||
AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationOffsetComponent["AnimationName"]);
|
||||
AnimationOffset.time = (double)animationOffsetComponent["Time"];
|
||||
} else {
|
||||
AnimationOffset.animation = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -140,8 +166,8 @@ struct ModelJob : RenderJob
|
||||
glm::vec4 Color;
|
||||
const ::Model* Model = nullptr;
|
||||
::Skeleton* Skeleton = nullptr;
|
||||
// const ::Skeleton::Animation* Animation = nullptr;
|
||||
|
||||
std::vector<::Skeleton::AnimationData> Animations;
|
||||
::Skeleton::AnimationOffset AnimationOffset;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -100,50 +100,29 @@ public:
|
||||
|
||||
int GetBoneID(std::string name);
|
||||
|
||||
void CalculateFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion = false);
|
||||
void CalculateFrameBones(std::vector<AnimationData> animations, bool noRootMotion = false);
|
||||
std::vector<glm::mat4> GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion = false);
|
||||
std::vector<glm::mat4> GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion = false);
|
||||
|
||||
const Animation* GetAnimation(std::string name);
|
||||
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, const Bone* bone, glm::mat4 parentMatrix);
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix);
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& frameBones, const Bone* bone, glm::mat4 parentMatrix);
|
||||
void AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& frameBones, const Bone* bone, glm::mat4 parentMatrix);
|
||||
|
||||
void PrintSkeleton();
|
||||
void PrintSkeleton(const Bone* parent, int depthCount);
|
||||
std::map<std::string, Animation> Animations;
|
||||
|
||||
glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix);
|
||||
glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, AnimationOffset animationOffset, 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);
|
||||
|
||||
|
||||
std::vector<glm::mat4> GetBones()
|
||||
{
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : m_BoneLocalTransforms) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;;
|
||||
}
|
||||
|
||||
glm::mat4 GetBoneTransformSuper(int boneID)
|
||||
{
|
||||
if(m_BoneTransforms.find(boneID) != m_BoneTransforms.end()) {
|
||||
return m_BoneTransforms.at(boneID);
|
||||
} else {
|
||||
return glm::mat4(1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset);
|
||||
|
||||
std::map<std::string, Bone*> m_BonesByName;
|
||||
float aim = 0.f;
|
||||
|
||||
|
||||
std::map<int, glm::mat4> m_BoneLocalTransforms;
|
||||
std::map<int, glm::mat4> m_BoneTransforms;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,29 +26,25 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="Wave">
|
||||
<Entity name="Running">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>Run</AnimationName1>
|
||||
<Weight1>0.5</Weight1>
|
||||
<Time1>0.78014858943309839</Time1>
|
||||
<Speed1>1</Speed1>
|
||||
<Time1>0.60188997954429357</Time1>
|
||||
<Speed1>-1</Speed1>
|
||||
<Speed2>1</Speed2>
|
||||
<AnimationName2>StrafeRight</AnimationName2>
|
||||
<Weight2>0.5</Weight2>
|
||||
<Time2>0.78620929522779459</Time2>
|
||||
<AnimationName3>ShootFastRifle</AnimationName3>
|
||||
<Time3>0.13809128482706701</Time3>
|
||||
<Time2>0.96957233017255007</Time2>
|
||||
<Time3>0.093923612201312068</Time3>
|
||||
<Speed3>1</Speed3>
|
||||
</c:Animation>
|
||||
<c:AnimationOffset>
|
||||
<AnimationName>AimRifle</AnimationName>
|
||||
<Time>0.040000014007091522</Time>
|
||||
<Time>0.5</Time>
|
||||
</c:AnimationOffset>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
<Color A="0.627451003" B="19.6078434" G="1" R="3.92156863"/>
|
||||
<Transparent>true</Transparent>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="-0.690088332" Y="0" Z="0"/>
|
||||
@@ -62,13 +58,11 @@
|
||||
<ScaleOffset X="0.200000003" Y="0.200000003" Z="0.200000003"/>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Blue/AssaultWeapon.mesh</Resource>
|
||||
<Color A="1" B="1" G="1" R="19.6078434"/>
|
||||
<Transparent>true</Transparent>
|
||||
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0.144055843" Y="0.970111489" Z="-0.126199633"/>
|
||||
<Orientation X="-0.535831392" Y="0.0691146553" Z="-0.0608282126"/>
|
||||
<Position X="0.161975682" Y="1.06281972" Z="-0.216630161"/>
|
||||
<Orientation X="-0.064812161" Y="-0.0739696771" Z="0.143780142"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
@@ -78,13 +72,27 @@
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:PointLight>
|
||||
<Color A="1" B="0.70588237" G="0.70588237" R="1"/>
|
||||
<Radius>10</Radius>
|
||||
</c:PointLight>
|
||||
<c:Transform>
|
||||
<Position X="0" Y="1.0823108" Z="0.738871336"/>
|
||||
<Position X="-0.375567257" Y="2.13093901" Z="-0.718547285"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:PointLight>
|
||||
<Color A="1" B="1" G="0.70588237" R="0.70588237"/>
|
||||
<Radius>10</Radius>
|
||||
</c:PointLight>
|
||||
<c:Transform>
|
||||
<Position X="-1.96873236" Y="0" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
@@ -97,6 +105,43 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>ShootFastRifle</AnimationName1>
|
||||
<Time1>0.056234247235838808</Time1>
|
||||
<Speed1>1</Speed1>
|
||||
<Speed2>1</Speed2>
|
||||
<AnimationName2>Idl</AnimationName2>
|
||||
<Weight2>0.5</Weight2>
|
||||
<Time2>1.8308673495784191</Time2>
|
||||
<AnimationName3>StrafeRigh</AnimationName3>
|
||||
<Weight3>0.5</Weight3>
|
||||
<Time3>0.32167823998061529</Time3>
|
||||
<Speed3>1</Speed3>
|
||||
</c:Animation>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0" Y="0.803468645" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
@@ -26,57 +26,48 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity name="Wave">
|
||||
<Entity name="Running">
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>Run</AnimationName1>
|
||||
<Weight1>0.5</Weight1>
|
||||
<Time1>0.97312056690160276</Time1>
|
||||
<Speed1>1</Speed1>
|
||||
<Time1>0.14873348341666759</Time1>
|
||||
<Speed1>-1</Speed1>
|
||||
<Speed2>1</Speed2>
|
||||
<AnimationName2>ReloadSwitch</AnimationName2>
|
||||
<Time2>0.91310356788604263</Time2>
|
||||
<AnimationName3>LeftRight</AnimationName3>
|
||||
<Weight3>0</Weight3>
|
||||
<Time3>0.040207288496060478</Time3>
|
||||
<AnimationName2></AnimationName2>
|
||||
<Weight2>0.5</Weight2>
|
||||
<Time2>0.96957233017255007</Time2>
|
||||
<AnimationName3></AnimationName3>
|
||||
<Time3>0.093923612201312068</Time3>
|
||||
<Speed3>1</Speed3>
|
||||
</c:Animation>
|
||||
<c:AnimationOffset>
|
||||
<AnimationName>DownUp</AnimationName>
|
||||
<Time>0.77999961376190186</Time>
|
||||
<AnimationName>AimRifle</AnimationName>
|
||||
</c:AnimationOffset>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
|
||||
<Color A="0.627451003" B="19.6078434" G="1" R="3.92156863"/>
|
||||
<Transparent>true</Transparent>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="-0.690088332" Y="1.00491476" Z="0"/>
|
||||
<Position X="-0.690088332" Y="0" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Entity name="R_Arm_Weapon_Joint">
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
<ScaleOffset X="0.200000003" Y="0.200000003" Z="0.200000003"/>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Blue/AssaultWeapon.mesh</Resource>
|
||||
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0.120548911" Y="-0.223148599" Z="-0.151705116"/>
|
||||
<Orientation X="0.09407565" Y="0.0181003436" Z="0.0279055703"/>
|
||||
<Position X="0.106085993" Y="1.24281573" Z="-0.198514819"/>
|
||||
<Orientation X="0.466044426" Y="0.284358948" Z="-0.0190349482"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Camera/>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity>
|
||||
@@ -101,6 +92,40 @@
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Animation>
|
||||
<AnimationName1>ShootFastRifle</AnimationName1>
|
||||
<Time1>0.11093210511546658</Time1>
|
||||
<Speed1>1</Speed1>
|
||||
</c:Animation>
|
||||
<c:AnimationOffset>
|
||||
<AnimationName>AimRifle</AnimationName>
|
||||
<Time>1</Time>
|
||||
</c:AnimationOffset>
|
||||
<c:Model>
|
||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:BoneAttachment>
|
||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||
</c:BoneAttachment>
|
||||
<c:Model>
|
||||
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0.106085993" Y="1.24281573" Z="-0.198514819"/>
|
||||
<Orientation X="0.466044426" Y="0.284358948" Z="-0.0190349482"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
@@ -54,32 +54,5 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = nextTime;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate bone transforms
|
||||
if (skeleton != nullptr) {
|
||||
std::vector<Skeleton::AnimationData> animations;
|
||||
if (entity.HasComponent("Animation")) {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(entity["Animation"]["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)entity["Animation"]["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)entity["Animation"]["Weight" + std::to_string(i)];
|
||||
|
||||
animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent("AnimationOffset")) {
|
||||
Skeleton::AnimationOffset animationOffset;
|
||||
animationOffset.animation = skeleton->GetAnimation(entity["AnimationOffset"]["AnimationName"]);
|
||||
animationOffset.time = (double)entity["AnimationOffset"]["Time"];
|
||||
skeleton->CalculateFrameBones(animations, animationOffset);
|
||||
} else {
|
||||
skeleton->CalculateFrameBones(animations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
return;
|
||||
}
|
||||
|
||||
if (!model->IsSkinned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
|
||||
|
||||
@@ -26,21 +29,45 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
return;
|
||||
}
|
||||
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName1"]);
|
||||
|
||||
if (!animation) {
|
||||
return;
|
||||
}
|
||||
|
||||
int id = skeleton->GetBoneID(entity["BoneAttachment"]["BoneName"]);
|
||||
|
||||
if(id == -1) {
|
||||
if (id == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<::Skeleton::AnimationData> Animations;
|
||||
::Skeleton::AnimationOffset AnimationOffset;
|
||||
glm::mat4 boneTransform;
|
||||
|
||||
glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id);
|
||||
//glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1));
|
||||
if (parent.HasComponent("Animation")) {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
::Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)parent["Animation"]["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)parent["Animation"]["Weight" + std::to_string(i)];
|
||||
|
||||
Animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent.HasComponent("AnimationOffset")) {
|
||||
AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["AnimationOffset"]["AnimationName"]);
|
||||
AnimationOffset.time = (double)parent["AnimationOffset"]["Time"];
|
||||
|
||||
if(AnimationOffset.animation != nullptr) {
|
||||
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, AnimationOffset, glm::mat4(1));
|
||||
} else {
|
||||
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1));
|
||||
}
|
||||
|
||||
} else {
|
||||
boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
glm::vec3 scale;
|
||||
glm::quat rotation;
|
||||
|
||||
@@ -338,7 +338,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
@@ -361,7 +365,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -402,7 +410,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindModelTextures(forwardSkinnedHandle, modelJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -426,7 +438,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindModelTextures(forwardSplatMapSkinnedHandle, modelJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -470,7 +486,11 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::list<std::shared_ptr<RenderJo
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ShieldToStencilProgram->Bind();
|
||||
@@ -524,7 +544,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
if (GLERROR("Animation")) {
|
||||
@@ -559,7 +583,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
BindModelTextures(forwardHandle ,modelJob);
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
|
||||
@@ -591,7 +619,11 @@ void DrawFinalPass::DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& job
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -102,7 +102,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
} else {
|
||||
@@ -154,7 +158,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
@@ -205,7 +213,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -262,7 +274,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
|
||||
+412
-157
@@ -30,30 +30,6 @@ Skeleton::~Skeleton()
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
{
|
||||
@@ -65,7 +41,167 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix)
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
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) {
|
||||
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.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (JointTransforms.size() <= 0) {
|
||||
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;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -105,6 +241,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
|
||||
|
||||
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;
|
||||
@@ -147,12 +284,10 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
boneMatrix = parentMatrix *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix));
|
||||
|
||||
}
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = offset * glm::inverse(bone->OffsetMatrix);
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -181,140 +316,18 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (offset != glm::mat4(1)) {
|
||||
boneMatrix = parentMatrix * ((glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) + offset);
|
||||
} else {
|
||||
boneMatrix = parentMatrix * (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
}
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
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;
|
||||
|
||||
jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, child, boneMatrix);
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,9 +365,8 @@ glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animati
|
||||
|
||||
}
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
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 nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
@@ -436,6 +448,249 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, AnimationOffset animationOffset, glm::mat4 childMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
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) {
|
||||
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.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 offset = GetOffsetTransform(bone, animationOffset);
|
||||
|
||||
if (JointTransforms.size() == 0) {
|
||||
if (bone->Parent) {
|
||||
if (offset != glm::mat4(1)) {
|
||||
boneMatrix = offset * childMatrix;// *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix));
|
||||
} else {
|
||||
boneMatrix = ((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix)) * childMatrix;
|
||||
}
|
||||
} else {
|
||||
boneMatrix = offset * glm::inverse(bone->OffsetMatrix);
|
||||
}
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (offset != glm::mat4(1)) {
|
||||
boneMatrix = ((glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) + offset) * childMatrix;
|
||||
} else {
|
||||
boneMatrix = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
if (bone->Parent != nullptr) {
|
||||
return GetBoneTransform(noRootMotion, bone->Parent, animations, animationOffset, boneMatrix);
|
||||
} else {
|
||||
return boneMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector<AnimationData> animations, glm::mat4 childMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
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) {
|
||||
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.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix * childMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix) * childMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = (glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp)) * childMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
}
|
||||
|
||||
boneMatrix = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bone->Parent != nullptr) {
|
||||
return GetBoneTransform(noRootMotion, bone->Parent, animations, boneMatrix);
|
||||
} else {
|
||||
return boneMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
int Skeleton::GetBoneID(std::string name)
|
||||
{
|
||||
if (m_BonesByName.find(name) == m_BonesByName.end()) {
|
||||
|
||||
Reference in New Issue
Block a user