From 607150189c7a4717b0be98b167bab6ccf1ffaab1 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 10:51:11 +0100 Subject: [PATCH 1/3] Different animations can now be played on multiple meshes, AnimationOffset seems to make the lighting buggy --- include/Engine/Rendering/ModelJob.h | 30 +- include/Engine/Rendering/Skeleton.h | 33 +- resources/Schema/Entities/AnimationTests2.xml | 87 ++++- resources/Schema/Entities/AnimationTests3.xml | 75 ++-- src/Engine/Rendering/AnimationSystem.cpp | 27 -- src/Engine/Rendering/BoneAttachmentSystem.cpp | 5 +- src/Engine/Rendering/DrawFinalPass.cpp | 48 ++- src/Engine/Rendering/PickingPass.cpp | 24 +- src/Engine/Rendering/Skeleton.cpp | 328 +++++++++--------- 9 files changed, 380 insertions(+), 277 deletions(-) diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 4bb1b51f..ba801f60 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -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; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index a8dd982d..ccf3e2b4 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -100,13 +100,13 @@ public: int GetBoneID(std::string name); - void CalculateFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); - void CalculateFrameBones(std::vector animations, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); const Animation* GetAnimation(std::string name); - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); @@ -115,35 +115,12 @@ public: glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix); int GetKeyframe(const Animation& animation, double time); - - std::vector GetBones() - { - std::vector 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 m_BonesByName; - float aim = 0.f; - - - std::map m_BoneLocalTransforms; - std::map m_BoneTransforms; + }; #endif diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 6536a839..f027dd1d 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -15,7 +15,9 @@ - + + + Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -26,29 +28,24 @@ - + Run 0.5 - 0.78014858943309839 - 1 + 0.99150007800799234 + -1 1 - StrafeRight 0.5 - 0.78620929522779459 - ShootFastRifle - 0.13809128482706701 + 0.96957233017255007 + 0.093923612201312068 1 AimRifle - Models/Characters/Assault/AssaultAnimations.mesh - - true @@ -62,13 +59,11 @@ - Models/Weapons/Blue/AssaultWeapon.mesh - - true + Models/Weapons/Red/AssaultWeaponRed.mesh - - + + @@ -78,13 +73,27 @@ + 10 - + - + + + + + + 10 + + + + + + + + @@ -97,6 +106,48 @@ + + + + ShootFastRifle + 0.068159934509623099 + 1 + 1 + Run + 0.5 + 0.19240865965109588 + StrafeRight + 0.5 + 0.12533627444542628 + 1 + + + AimRifle + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + + + + diff --git a/resources/Schema/Entities/AnimationTests3.xml b/resources/Schema/Entities/AnimationTests3.xml index bd985b2d..39043231 100644 --- a/resources/Schema/Entities/AnimationTests3.xml +++ b/resources/Schema/Entities/AnimationTests3.xml @@ -26,57 +26,48 @@ - + Run 0.5 - 0.97312056690160276 - 1 + 0.14873348341666759 + -1 1 - ReloadSwitch - 0.91310356788604263 - LeftRight - 0 - 0.040207288496060478 + + 0.5 + 0.96957233017255007 + + 0.093923612201312068 1 - DownUp - + AimRifle - Models/Characters/Assault/FirstPerson.mesh - - true + Models/Characters/Assault/AssaultAnimations.mesh - + - + R_Arm_Weapon_Joint + - Models/Weapons/Blue/AssaultWeapon.mesh + Models/Weapons/Red/AssaultWeaponRed.mesh - - + + - - - - - - - @@ -101,6 +92,40 @@ + + + + ShootFastRifle + 0.11093210511546658 + 1 + + + AimRifle + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 48681e6e..55edffe2 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -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 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); - } - } } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index a9588a16..c0c2b8de 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -38,10 +38,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - - glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id); - //glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); - + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); glm::vec3 scale; glm::quat rotation; glm::vec3 translation; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 00b85528..c3381632 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -328,7 +328,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); std::vector 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(); @@ -351,7 +355,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); GLERROR("asdasd"); std::vector 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 { @@ -392,7 +400,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(forwardSkinnedHandle, modelJob); std::vector 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 { @@ -416,7 +428,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); GLERROR("asdasd"); std::vector 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 { @@ -460,7 +476,11 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::listViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); std::vector 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(); @@ -514,7 +534,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list 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")) { @@ -549,7 +573,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list 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])); @@ -581,7 +609,11 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); std::vector 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 { diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index cc9837ff..fa1b3ca3 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -103,7 +103,11 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector 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])); } @@ -156,7 +160,11 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector 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(); @@ -207,7 +215,11 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector 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 { @@ -264,7 +276,11 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector 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])); } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 5da95558..f85efd17 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -30,30 +30,6 @@ Skeleton::~Skeleton() } -void Skeleton::CalculateFrameBones(std::vector 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 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 animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix) +std::vector Skeleton::GetFrameBones(std::vector animations, bool noRootMotion /*= false*/) +{ + if (animations.size() <= 0) { + std::vector finalMatrices; + for (auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); + } + return finalMatrices; + } + + std::map frameBones; + AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1)); + + std::vector finalMatrices; + for (auto &kv : frameBones) { + finalMatrices.push_back(kv.second); + } + return finalMatrices; +} + +std::vector Skeleton::GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/) +{ + if (animations.size() <= 0 || animationOffset.animation == nullptr) { + std::vector finalMatrices; + for (auto& b : Bones) { + finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); + } + return finalMatrices; + } + + + std::map frameBones; + AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1)); + + std::vector finalMatrices; + for (auto &kv : frameBones) { + finalMatrices.push_back(kv.second); + } + return finalMatrices; +} + +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix; + std::vector 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 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 animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { glm::mat4 boneMatrix; @@ -148,12 +284,10 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorOffsetMatrix) * 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 { @@ -189,136 +323,11 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorID] = 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 animations, const Bone* bone, glm::mat4 parentMatrix) -{ - glm::mat4 boneMatrix; - std::vector 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 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; - 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); } } @@ -356,11 +365,8 @@ glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animati } - - 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 nextBoneProperty = nextFrame.BoneProperties; From 97de31be65e4bc32ef9461f0cc6dd19716d025d1 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 13:36:27 +0100 Subject: [PATCH 2/3] Fixed BoneAttachment component --- include/Engine/Rendering/Skeleton.h | 2 + resources/Schema/Entities/AnimationTests2.xml | 28 +- src/Engine/Rendering/BoneAttachmentSystem.cpp | 46 +++- src/Engine/Rendering/Skeleton.cpp | 243 ++++++++++++++++++ 4 files changed, 294 insertions(+), 25 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index ccf3e2b4..28a5ef6a 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -113,6 +113,8 @@ public: std::map 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 animations, AnimationOffset animationOffset, glm::mat4 childMatrix); + glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, glm::mat4 childMatrix); int GetKeyframe(const Animation& animation, double time); private: diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index f027dd1d..413c7e67 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -15,9 +15,7 @@ - - - + Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -33,7 +31,7 @@ Run 0.5 - 0.99150007800799234 + 0.60188997954429357 -1 1 0.5 @@ -43,6 +41,7 @@ AimRifle + Models/Characters/Assault/AssaultAnimations.mesh @@ -62,8 +61,8 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + + @@ -110,21 +109,17 @@ ShootFastRifle - 0.068159934509623099 + 0.056234247235838808 1 1 - Run + Idl 0.5 - 0.19240865965109588 - StrafeRight + 1.8308673495784191 + StrafeRigh 0.5 - 0.12533627444542628 + 0.32167823998061529 1 - - AimRifle - - Models/Characters/Assault/AssaultAnimations.mesh @@ -140,8 +135,7 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index c0c2b8de..3effaf2c 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -19,6 +19,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } + if (!model->IsSkinned()) { + return; + } Skeleton* skeleton = model->m_RawModel->m_Skeleton; @@ -26,19 +29,46 @@ 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; } - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); + std::vector<::Skeleton::AnimationData> Animations; + ::Skeleton::AnimationOffset AnimationOffset; + glm::mat4 boneTransform; + + 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; glm::vec3 translation; diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index f85efd17..e390d694 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -448,6 +448,249 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio } } + +glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, AnimationOffset animationOffset, glm::mat4 childMatrix) +{ + glm::mat4 boneMatrix; + + std::vector 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 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 animations, glm::mat4 childMatrix) +{ + glm::mat4 boneMatrix; + std::vector 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 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()) { From bd385a0d59a90edec4aca9beb5de614e59a4b17b Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 20:15:56 +0100 Subject: [PATCH 3/3] new assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index c56f6380..01df0799 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c56f6380ab05c23419beafe14190013d1432e32c +Subproject commit 01df07998ba0d7ddc2e32168bd88b6adf502e094