From 933a32aa8db98ff5391637447f7b59835579ceef Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sat, 6 Feb 2016 18:09:51 +0100 Subject: [PATCH] Animations kind of working --- include/Engine/Rendering/Skeleton.h | 2 +- resources/Schema/Entities/AnimationTests2.xml | 112 ++++++++--------- resources/Schema/Entities/RenderingWorld.xml | 17 ++- resources/Shaders/Sprite.frag.glsl | 41 +++++++ resources/Shaders/Sprite.vert.glsl | 24 ++++ src/Engine/Rendering/AnimationSystem.cpp | 2 + src/Engine/Rendering/BoneAttachmentSystem.cpp | 11 +- src/Engine/Rendering/Skeleton.cpp | 115 ++++++++++++------ 8 files changed, 224 insertions(+), 100 deletions(-) create mode 100644 resources/Shaders/Sprite.frag.glsl create mode 100644 resources/Shaders/Sprite.vert.glsl diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index f1ef22c7..90e24578 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -92,7 +92,7 @@ public: void PrintSkeleton(const Bone* parent, int depthCount); std::map Animations; - glm::mat4 GetBoneTransform(const Bone* bone, const Animation::Keyframe& currentFrame, const Animation::Keyframe& nextFrame, float progress, glm::mat4 parentMatrix); + glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix); int GetKeyframe(const Animation& animation, double time); private: diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index a116803f..21a899f5 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -13,7 +13,6 @@ - @@ -32,39 +31,21 @@ - + - Run - - 1 + Wave + + 0.099999986588954926 - Models/Asstest.mesh + Models/finaltest.mesh - + - - - - R_Leg_Top - - - - Models/Core/UnitCube.mesh - - - - - - - - - - @@ -76,9 +57,8 @@ - + - @@ -94,9 +74,8 @@ - + - @@ -112,9 +91,8 @@ - + - @@ -130,9 +108,8 @@ - + - @@ -148,9 +125,8 @@ - + - @@ -166,9 +142,8 @@ - + - @@ -184,9 +159,8 @@ - + - @@ -202,9 +176,8 @@ - + - @@ -220,9 +193,8 @@ - + - @@ -238,9 +210,8 @@ - + - @@ -256,9 +227,8 @@ - + - @@ -274,9 +244,8 @@ - + - @@ -292,9 +261,8 @@ - + - @@ -310,9 +278,8 @@ - + - @@ -328,9 +295,44 @@ - + - + + + + + + + + + + Run + + 0.099999986588954926 + + + Models/Supertest2.mesh + + + + + + + + + + R_Leg_Top + + + + + Models/Core/UnitCube.mesh + + + + + + diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 1ac95a3b..4564b3f5 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -60,6 +60,7 @@ Models/Core/UnitHexagon.mesh + true @@ -161,7 +162,7 @@ - + @@ -346,6 +347,20 @@ + + + + Run + + 0.004999999888241291 + + + Models/SuperTest.mesh + + + + + diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl new file mode 100644 index 00000000..c391322d --- /dev/null +++ b/resources/Shaders/Sprite.frag.glsl @@ -0,0 +1,41 @@ +#version 430 + +uniform vec4 Color; +uniform vec4 FillColor; +uniform float FillPercentage; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout (binding = 0) uniform sampler2D DiffuseTexture; +layout (binding = 1) uniform sampler2D GlowMapTexture; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Input; + + +out vec4 sceneColor; +out vec4 bloomColor; + +void main() +{ + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); + + vec4 color_result = Color * diffuseTexel; + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + color_result += glowTexel*3; + + bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); +} + + diff --git a/resources/Shaders/Sprite.vert.glsl b/resources/Shaders/Sprite.vert.glsl new file mode 100644 index 00000000..e910a26a --- /dev/null +++ b/resources/Shaders/Sprite.vert.glsl @@ -0,0 +1,24 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 4) in vec2 TextureCoords; + +out VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Output; + +void main() +{ + gl_Position = P * M * vec4(Position, 1.0); + + Output.Position = Position; + Output.TextureCoordinate = TextureCoords; + Output.Normal = Normal; +} \ No newline at end of file diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index c78aafd9..ef035dca 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -19,6 +19,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if(skeleton == nullptr) { return; } +/* ImGui::SliderFloat("Angle", &angle, -100.f, 100.f); { @@ -28,6 +29,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a it->second->ModificationMatrix = glm::mat4(glm::quat(glm::vec3(glm::radians(angle), 0.f, 0.f))); } } +*/ const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName"]); diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index 1f98c28e..f172d0ab 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -2,7 +2,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& BoneAttachmentComponent, double dt) { -/* + if(!entity.HasComponent("Transform")) { return; @@ -33,13 +33,8 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - int currentKeyframeIndex = skeleton->GetKeyframe(*animation, parent["Animation"]["Time"]); - const Skeleton::Animation::Keyframe& currentFrame = animation->Keyframes[currentKeyframeIndex]; - const Skeleton::Animation::Keyframe& nextFrame = animation->Keyframes[(currentKeyframeIndex + 1) % animation->Keyframes.size()]; - float alpha = ((double)parent["Animation"]["Time"] - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], currentFrame, nextFrame, alpha, glm::mat4(1)); + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time"], glm::mat4(1)); @@ -68,5 +63,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/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 5ae6a264..d857fa5d 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -61,7 +61,7 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl //auto animationFrame = Animations[""].Keyframes[frame]; std::map frameBones; - AccumulateBoneTransforms(noRootMotion, animation, time, frameBones, RootBone, glm::mat4(1)); + AccumulateBoneTransforms(true, animation, time, frameBones, RootBone, glm::mat4(1)); //AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, alpha, frameBones, RootBone, glm::mat4(1)); std::vector finalMatrices; @@ -71,21 +71,18 @@ std::vector Skeleton::GetFrameBones(const Animation* animation, doubl return finalMatrices; } - - - 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); + glm::mat4 boneMatrix; Animation::Keyframe currentFrame; Animation::Keyframe nextFrame; - if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { // find the bone keyframes that surrounds the current frame + if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - + if(boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone - for (int index = boneKeyFrames.size()-1; index >= 0; index--) { + 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()); @@ -93,10 +90,18 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim } } - float progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + float progress; + + if(nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + + } + + if(progress > 1.0f || progress < 0.0f) { - LOG_INFO("Progress %f", progress); - progress = 0.f; + progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; @@ -111,53 +116,93 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* anim positionInterp.z = 0; } - boneMatrix = parentMatrix * bone->ModificationMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { // 1 keyframes for the current bone currentFrame = boneKeyFrames.at(0); - boneMatrix = parentMatrix * bone->ModificationMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - boneMatrices[bone->ID] = boneMatrix *bone->OffsetMatrix; + boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); + + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } } else { // 0 keyframes for the current bone - boneMatrix = parentMatrix * bone->ModificationMatrix; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - + // LOG_INFO("%s Has no keyframe", bone->Name.c_str()); + if (bone->Parent) { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + } else { + boneMatrix = glm::inverse(bone->OffsetMatrix); + boneMatrices[bone->ID] = parentMatrix; + } + } for (auto &child : bone->Children) { - 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 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 parentMatrix) { - /* glm::mat4 boneMatrix; + glm::mat4 boneMatrix; - 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); + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; - 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; + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + 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) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); // fix loopinguuuu + + } + + 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; + + 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; + + boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + boneMatrix = parentMatrix * (glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - boneMatrix = (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)) * bone->ModificationMatrix * parentMatrix; - } else { - if (bone->Parent) { - boneMatrix = parentMatrix; } + } else { // 0 keyframes for the current bone + if (bone->Parent) { + boneMatrix = glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix * parentMatrix; + } else { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix); + } + } - if(bone->Parent) { - return GetBoneTransform(bone->Parent, currentFrame, nextFrame, progress, boneMatrix); + if (bone->Parent) { + return GetBoneTransform(bone->Parent, animation, time, boneMatrix); } else { return boneMatrix; - }*/ - return parentMatrix; + } } int Skeleton::GetBoneID(std::string name)