From 6aec7555cce58e19560dbc03d12c8aedd3a65208 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 4 Feb 2016 11:13:33 +0100 Subject: [PATCH] WIP Waiting for importer --- include/Engine/Rendering/Skeleton.h | 12 +- resources/Schema/Entities/AnimationTests2.xml | 5 +- src/Engine/Rendering/AnimationSystem.cpp | 5 +- src/Engine/Rendering/BoneAttachmentSystem.cpp | 3 +- src/Engine/Rendering/DrawFinalPass.cpp | 9 +- src/Engine/Rendering/PickingPass.cpp | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 7 + src/Engine/Rendering/Skeleton.cpp | 137 +++++++++++++++++- 8 files changed, 162 insertions(+), 18 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 8ae3d487..9c7242d3 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -55,19 +55,23 @@ public: struct BoneProperty { int ID; - glm::vec3 Position; - glm::quat Rotation; + glm::vec3 Position; + glm::quat Rotation; glm::vec3 Scale = glm::vec3(1); }; int Index = 0; double Time = 0.0; std::map BoneProperties; + //Keyframe::BoneProperty boneProperty; }; std::string Name; double Duration; + // unsigned int KeyFrameAmount; std::vector Keyframes; + //std::map> BoneKeyFrames; + }; Skeleton() { } @@ -86,6 +90,10 @@ public: const Animation* GetAnimation(std::string name); std::vector GetFrameBones(const Animation* animation, double time, bool noRootMotion = false); void AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + + void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 23fc0548..baff7413 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -10,6 +10,7 @@ Models/Core/UnitPlane.mesh + false @@ -34,8 +35,8 @@ - Run - + Ru + 1 diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 93d52787..517fbf5c 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -51,6 +51,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a +/* ImGui::SliderFloat("Angle", &angle, -180.f, 180.f); @@ -86,6 +87,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } +*/ /* @@ -117,7 +119,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if (it != skeleton->Bones.end()) { it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle/2.f), 0.f, 0.f))); } - }*/ + }* if (entity.HasComponent("Player")) { EntityWrapper cameraEntity = entity.FirstChildByName("Camera"); @@ -127,5 +129,6 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } } + */ } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 2a2e5c7d..1f98c28e 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -2,6 +2,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) { +/* if(!entity.HasComponent("Transform")) { return; @@ -67,5 +68,5 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } if ((bool)entity["BoneAttachment"]["InheritScale"]) { (glm::vec3&)entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"]; - } + }*/ } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 48ea4144..005249ed 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -130,7 +130,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { if (explosionEffectJob->Animation != nullptr) { - std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animation, explosionEffectJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } @@ -155,11 +155,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(modelJob); if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - - if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); - glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } //draw diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index d0518ee8..58723a43 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -134,7 +134,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { if (modelJob->Animation != nullptr) { - std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + std::vector frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 83c68e47..1f9e104d 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -332,6 +332,7 @@ void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileDat ReadAnimationKeyFrame(offset, fileData, fileByteSize, newAnimation); } m_Skeleton->Animations[newAnimation.Name] = newAnimation; + //m_Skeleton->Animations[newAnimation.Name].KeyFrameAmount = nrOfKeyframes; #else #endif } @@ -363,12 +364,18 @@ void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, } Skeleton::Animation::Keyframe::BoneProperty newBone; + for (unsigned int i = 0; i < nrOfJoints; i++) { memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty); newKeyFrame.BoneProperties[newBone.ID] = newBone; } animation.Keyframes.push_back(newKeyFrame); + // memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); + //newKeyFrame.boneProperty = newBone; + + // animation.BoneKeyFrames[newBone.ID].push_back(newKeyFrame); + } RawModelCustom::~RawModelCustom() diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 7fe36319..590cd9a4 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -66,7 +66,9 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms2(noRootMotion, animation, currentKeyframeIndex, time, frameBones, RootBone, glm::mat4(1)); + //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; for (auto &kv : frameBones) { @@ -81,7 +83,14 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf { glm::mat4 boneMatrix; - if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) { + + + float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + + if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() && nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) { + + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID); Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties.at(bone->ID); @@ -89,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + // Flag for no root motion if (bone == RootBone && noRootMotion) { positionInterp.x = 0; @@ -97,13 +107,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf - boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * bone->ModificationMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { if (bone->Parent) { boneMatrix = parentMatrix;// *glm::inverse(bone->OffsetMatrix); } - boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; + boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix; } for (auto &child : bone->Children) { @@ -113,6 +123,123 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf } + +void Skeleton::AccumulateBoneTransforms2(bool noRootMotion, const Animation* animation, int keyframeIndex, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix = glm::mat4(1); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + int currentFrameIndex = keyframeIndex; + + while (true) { + std::map boneProperties = animation->Keyframes[currentFrameIndex].BoneProperties; + if (boneProperties.find(bone->ID) != boneProperties.end()) { + currentFrame = animation->Keyframes[keyframeIndex]; + break; + } else { + + if(currentFrameIndex > 0) { + currentFrameIndex--; + } else { + break; + } + } + } + + + + if ( != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + for (auto frame : boneKeyFrames) { + if (frame.Time <= time) { + currentFrame = &frame; + } else if (frame.Time > time) { + nextFrame = &frame; + } + } + + //if(currentFrame == nullptr) cant happen + + if (nextFrame == nullptr) { + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + nextFrame = &boneKeyFrames.front(); + } + +} + + + + +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +{ + +/* + glm::mat4 boneMatrix = glm::mat4(1); + + Animation::Keyframe* currentFrame = nullptr; + Animation::Keyframe* nextFrame = nullptr; + + if(animation->BoneKeyFrames.find(bone->ID) != animation->BoneKeyFrames.end()) { // find the bone keyframes that surrounds the current frame + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + for (auto frame : boneKeyFrames) { + if(frame.Time <= time) { + currentFrame = &frame; + } else if (frame.Time > time) { + nextFrame = &frame; + } + } + + //if(currentFrame == nullptr) cant happen + + if (nextFrame == nullptr) { + std::list boneKeyFrames = animation->BoneKeyFrames.at(bone->ID); + nextFrame = &boneKeyFrames.front(); + } + + + + if (currentFrame != nextFrame) { + + float progress = (time - currentFrame->Time) / (nextFrame->Time - currentFrame->Time); + + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame->boneProperty; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame->boneProperty; + + glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + // Flag for no root motion + if (bone == RootBone && noRootMotion) { + positionInterp.x = 0; + positionInterp.z = 0; + } + + boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + + } else {// if (currentFrame == nextFrame) { + boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(currentFrame->boneProperty.Position) * glm::toMat4(currentFrame->boneProperty.Rotation) * glm::scale(currentFrame->boneProperty.Scale)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } + } else { +// if (bone->Parent) { // dont think this is needed +// boneMatrix = parentMatrix * bone->ModificationMatrix; +// } + + boneMatrix = parentMatrix * bone->ModificationMatrix; + boneMatrices[bone->ID] = boneMatrix;// *bone->OffsetMatrix; + // } + } + + for (auto &child : bone->Children) { + std::string name = child->Name; + AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); + }*/ +} + glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix) { glm::mat4 boneMatrix;