Working skeletal animations!!!
This commit is contained in:
@@ -50,6 +50,7 @@ source_group(Input FILES ${SOURCE_FILES_Input})
|
||||
|
||||
file(GLOB SOURCE_FILES_Rendering
|
||||
"${INCLUDE_PATH}/Rendering/*.h"
|
||||
"Rendering/*.cpp"
|
||||
)
|
||||
source_group(Rendering FILES ${SOURCE_FILES_Rendering})
|
||||
|
||||
|
||||
@@ -431,6 +431,20 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
|
||||
glBindTexture(GL_TEXTURE_2D, *m_StandardSpecular);
|
||||
}
|
||||
|
||||
if (modelJob->Skeleton != nullptr) {
|
||||
auto animation = modelJob->Skeleton->GetAnimation(modelJob->AnimationName);
|
||||
if (animation != nullptr) {
|
||||
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones(
|
||||
*animation,
|
||||
modelJob->AnimationTime,
|
||||
modelJob->NoRootMotion
|
||||
);
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
LOG_WARNING("Tried to play unknown animation \"%s\"", modelJob->AnimationName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(modelJob->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
||||
|
||||
@@ -65,7 +65,7 @@ void main()
|
||||
+ BoneWeights2[3] * Bones[int(BoneIndices2[3])];
|
||||
}
|
||||
|
||||
gl_Position = MVP * vec4(Position, 1.0);
|
||||
gl_Position = MVP * boneTransform * vec4(Position, 1.0);
|
||||
|
||||
Output.Position = (V * M * boneTransform * vec4(Position, 1.0)).xyz;
|
||||
Output.Normal = (inverse(transpose(V * M)) * boneTransform * vec4(Normal, 0.0)).xyz;
|
||||
|
||||
@@ -65,8 +65,8 @@ void main()
|
||||
+ BoneWeights2[3] * Bones[int(BoneIndices2[3])];
|
||||
}
|
||||
|
||||
//gl_Position = MVP * boneTransform * vec4(Position, 1.0);
|
||||
gl_Position = MVP * vec4(Position, 1.0);
|
||||
gl_Position = MVP * boneTransform * vec4(Position, 1.0);
|
||||
//gl_Position = MVP * vec4(Position, 1.0);
|
||||
|
||||
//TODO: Make sure that boneTransform works here.
|
||||
Output.Position = (V * M * boneTransform * vec4(Position, 1.0)).xyz;
|
||||
|
||||
@@ -48,10 +48,18 @@ dd::Skeleton::~Skeleton()
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> dd::Skeleton::GetFrameBones(std::string animationName, double time, bool noRootMotion /*= false*/)
|
||||
const dd::Skeleton::Animation* dd::Skeleton::GetAnimation(std::string name)
|
||||
{
|
||||
auto it = Animations.find(name);
|
||||
if (it != Animations.end()) {
|
||||
return const_cast<const Animation*>(&it->second);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> dd::Skeleton::GetFrameBones(const Animation& animation, double time, bool noRootMotion /*= false*/)
|
||||
{
|
||||
auto& animation = Animations.at(animationName);
|
||||
|
||||
// HACK: Animation wrap-around
|
||||
while (time < 0)
|
||||
time += animation.Duration;
|
||||
@@ -60,8 +68,8 @@ std::vector<glm::mat4> dd::Skeleton::GetFrameBones(std::string animationName, do
|
||||
|
||||
int currentKeyframeIndex = GetKeyframe(animation, time);
|
||||
|
||||
Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex];
|
||||
Animation::Keyframe& nextFrame = animation.Keyframes[currentKeyframeIndex + 1];
|
||||
const Animation::Keyframe& currentFrame = animation.Keyframes[currentKeyframeIndex];
|
||||
const Animation::Keyframe& nextFrame = animation.Keyframes[currentKeyframeIndex + 1];
|
||||
float alpha = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
//auto animationFrame = Animations[""].Keyframes[frame];
|
||||
@@ -75,7 +83,7 @@ std::vector<glm::mat4> dd::Skeleton::GetFrameBones(std::string animationName, do
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
void dd::Skeleton::AccumulateBoneTransforms(bool noRootMotion, Animation::Keyframe ¤tFrame, Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, Bone* bone, glm::mat4 parentMatrix)
|
||||
void dd::Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
@@ -120,7 +128,7 @@ void dd::Skeleton::PrintSkeleton()
|
||||
PrintSkeleton(RootBone, 0);
|
||||
}
|
||||
|
||||
void dd::Skeleton::PrintSkeleton(Bone* bone, int depthCount)
|
||||
void dd::Skeleton::PrintSkeleton(const Bone* bone, int depthCount)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::string(depthCount, ' ');
|
||||
@@ -134,7 +142,7 @@ void dd::Skeleton::PrintSkeleton(Bone* bone, int depthCount)
|
||||
}
|
||||
}
|
||||
|
||||
int dd::Skeleton::GetKeyframe(Animation& animation, double time)
|
||||
int dd::Skeleton::GetKeyframe(const Animation& animation, double time)
|
||||
{
|
||||
if (time < 0)
|
||||
time = 0;
|
||||
@@ -143,7 +151,7 @@ int dd::Skeleton::GetKeyframe(Animation& animation, double time)
|
||||
|
||||
for (int keyframe = 0; keyframe < animation.Keyframes.size(); ++keyframe) {
|
||||
if (animation.Keyframes[keyframe].Time > time)
|
||||
return keyframe - 1;
|
||||
return glm::max(0, keyframe - 1); // HACK: If the time is less than the first keyframe, don
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -35,7 +35,9 @@ void dd::Systems::BallSystem::Initialize()
|
||||
transform->Scale = glm::vec3(0.3f, 0.3f, 0.3f);
|
||||
transform->Velocity = glm::vec3(0.f, 0.f, 0.f);
|
||||
auto model = m_World->AddComponent<Components::Model>(ent);
|
||||
model->ModelFile = "Models/Test/Ball/Sid.obj";
|
||||
model->ModelFile = "Models/Sid/Sid.dae";
|
||||
auto animation = m_World->AddComponent<Components::Animation>(ent);
|
||||
animation->Speed = 1.0;
|
||||
std::shared_ptr<Components::CircleShape> circleShape = m_World->AddComponent<Components::CircleShape>(ent);
|
||||
circleShape->Radius = 0.4f;
|
||||
std::shared_ptr<Components::Ball> ball = m_World->AddComponent<Components::Ball>(ent);
|
||||
@@ -421,7 +423,7 @@ void dd::Systems::BallSystem::CreateLife(int number)
|
||||
lifeNr->Number = number;
|
||||
|
||||
auto model = m_World->AddComponent<Components::Model>(life);
|
||||
model->ModelFile = "Models/Test/Ball/Sid.obj";
|
||||
model->ModelFile = "Models/Sid/Sid.dae";
|
||||
|
||||
|
||||
m_World->CommitEntity(life);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Rendering/AnimationSystem.h"
|
||||
|
||||
void dd::Systems::AnimationSystem::RegisterComponents(ComponentFactory* cf)
|
||||
{
|
||||
cf->Register<Components::Animation>();
|
||||
}
|
||||
|
||||
void dd::Systems::AnimationSystem::Update(double dt)
|
||||
{
|
||||
auto animations = m_World->GetComponentsOfType<Components::Animation>();
|
||||
if (animations == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& component : *animations) {
|
||||
auto animation = static_cast<Components::Animation*>(component.get());
|
||||
animation->Time += animation->Speed * dt;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user