Optimization for Skeletal animations

This commit is contained in:
Antoine Pilote
2023-09-07 20:52:05 -04:00
parent fb9179dde2
commit 36646a0990
7 changed files with 75 additions and 27 deletions

View File

@@ -387,7 +387,7 @@ namespace Nuake
// Skinned Models
const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID");
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
auto skinnedModelView = scene.m_Registry.view<TransformComponent, SkinnedModelComponent, VisibilityComponent>();
for (auto e : skinnedModelView)
{
@@ -404,7 +404,6 @@ namespace Nuake
{
m->GetMaterial()->Bind(gBufferSkinnedMeshShader);
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
gBufferSkinnedMeshShader->SetUniform1i(entityIdUniformLocation, (uint32_t)e + 1);
m->Draw(gBufferSkinnedMeshShader, true);
}
@@ -482,10 +481,8 @@ namespace Nuake
{
if (auto entity = scene->GetEntity(child.Name); entity.GetHandle() != -1)
{
const Matrix4& globalBoneTransform = entity.GetComponent<TransformComponent>().GetGlobalTransform();
const Matrix4 bonespaceTransform = globalBoneTransform * child.Offset;
const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(child.Id) + "]";
shader->SetUniformMat4f(boneMatrixUniformName, bonespaceTransform);
shader->SetUniformMat4f(boneMatrixUniformName, child.FinalTransform);
}
SetSkeletonBoneTransformRecursive(child, shader);

View File

@@ -295,7 +295,7 @@ namespace Nuake
if (addr != -1)
{
SetUniformMat4f(addr, std::move(mat));
SetUniformMat4f(addr, mat);
}
}

View File

@@ -26,24 +26,35 @@ namespace Nuake
std::vector<Quat> m_Rotations = {};
std::vector<Vector3> m_Scales = {};
Matrix4 m_PositionTransform;
Matrix4 m_RotationTransform;
Matrix4 m_ScaleTransform;
Matrix4 m_FinalTransform;
bool m_IsEmpty = true;
public:
BoneTransformTrack();
~BoneTransformTrack() = default;
bool IsEmpty() const { return m_IsEmpty; }
void PushPositionKeyframe(float timestamp, const Vector3& position)
{
m_IsEmpty = false;
m_PositionTimestamps.push_back(timestamp);
m_Positions.push_back(position);
}
void PushRotationKeyframe(float timestamp, const Quat& rotation)
{
m_IsEmpty = false;
m_RotationTimestamps.push_back(timestamp);
m_Rotations.push_back(rotation);
}
void PushScaleKeyframe(float timestamp, const Vector3& scale)
{
m_IsEmpty = false;
m_ScaleTimestamps.push_back(timestamp);
m_Scales.push_back(scale);
}
@@ -65,6 +76,27 @@ namespace Nuake
assert(0);
}
void Update(float time)
{
const Matrix4 previousPos = m_PositionTransform;
const Matrix4 previousRot = m_RotationTransform;
const Matrix4 previousSca = m_ScaleTransform;
m_PositionTransform = InterpolatePosition(time);
m_RotationTransform = InterpolateRotation(time);
m_ScaleTransform = InterpolateScale(time);
bool hasChanged = previousPos != m_PositionTransform || previousRot != m_RotationTransform || previousSca != m_ScaleTransform;
if (hasChanged)
{
m_FinalTransform = m_PositionTransform * m_RotationTransform * m_ScaleTransform;
}
}
const Matrix4& GetFinalTransform() const
{
return m_FinalTransform;
}
/* Gets the current index on mKeyRotations to interpolate to based on the
current animation time*/
int GetRotationIndex(float animationTime)

View File

@@ -11,6 +11,7 @@ namespace Nuake
std::string Name;
int ChildrenCount;
std::vector<SkeletonNode> Children;
Matrix4 FinalTransform = Matrix4(1.0f);
int32_t Id = -1;
};
}

View File

@@ -194,14 +194,20 @@ namespace Nuake
Entity Scene::GetEntity(const std::string& name)
{
std::vector<Entity> allEntities;
const auto& view = m_Registry.view<NameComponent>();
if (m_EntitiesNameMap.find(name) != m_EntitiesNameMap.end())
{
return m_EntitiesNameMap[name];
}
const auto& view = m_Registry.view<const NameComponent>();
for (auto e : view)
{
const auto& namec = view.get<NameComponent>(e);
const auto& [namec] = view.get(e);
if (namec.Name == name)
{
return Entity{ e, this };
auto entity = Entity{ e, this };
m_EntitiesNameMap[name] = entity;
return entity;
}
}
@@ -260,6 +266,7 @@ namespace Nuake
nameComponent.ID = id;
m_EntitiesIDMap[id] = entity;
m_EntitiesNameMap[entityName] = entity;
Logger::Log("Entity created with name: " + nameComponent.Name, "scene", LOG_TYPE::VERBOSE);
return entity;
@@ -288,6 +295,11 @@ namespace Nuake
m_EntitiesIDMap.erase(entity.GetComponent<NameComponent>().ID);
}
if (m_EntitiesNameMap.find(entity.GetComponent<NameComponent>().Name) != m_EntitiesNameMap.end())
{
m_EntitiesNameMap.erase(entity.GetComponent<NameComponent>().Name);
}
entity.Destroy();
m_Registry.shrink_to_fit();
}

View File

@@ -38,7 +38,8 @@ namespace Nuake
public:
Ref<EditorCamera> m_EditorCamera;
entt::registry m_Registry;
std::map<uint32_t, Entity> m_EntitiesIDMap;
std::unordered_map<uint32_t, Entity> m_EntitiesIDMap;
std::unordered_map<std::string, Entity> m_EntitiesNameMap;
std::string Path = "";
SceneRenderer* m_SceneRenderer;

View File

@@ -3,6 +3,8 @@
#include "src/Scene/Scene.h"
#include "src/Scene/Entities/Entity.h"
#include "src/Scene/Components/SkinnedModelComponent.h"
#include <src/Scene/Components/BoneComponent.h>
#include <future>
namespace Nuake
{
@@ -45,37 +47,40 @@ namespace Nuake
{
const std::string& boneName = bone.Name;
auto& animationTrack = animation->GetTrack(boneName);
Entity& boneEntity = m_Scene->GetEntity(boneName);
if (boneEntity.GetHandle() != -1)
{
auto& animationTrack = animation->GetTrack(boneName);
auto& transformComponent = boneEntity.GetComponent<TransformComponent>();
bone.FinalTransform = transformComponent.GetGlobalTransform() * bone.Offset;
// Get Update transform
const Matrix4 newPosition = animationTrack.InterpolatePosition(time);
const Matrix4 newRotation = animationTrack.InterpolateRotation(time);
const Matrix4 newScale = animationTrack.InterpolateScale(time);
const Matrix4 finalTransform = newPosition * newRotation * newScale;
if (!animationTrack.IsEmpty())
{
// Get Update transform
animationTrack.Update(time);
Vector3 localPosition;
Quat localRotation;
Vector3 localScale;
Decompose(finalTransform, localPosition, localRotation, localScale);
const Matrix4& finalTransform = animationTrack.GetFinalTransform();
transformComponent.SetLocalPosition(localPosition);
transformComponent.SetLocalRotation(localRotation);
transformComponent.SetLocalScale(localScale);
transformComponent.SetLocalTransform(finalTransform);
transformComponent.Dirty = false;
Vector3 localPosition;
Quat localRotation;
Vector3 localScale;
Decompose(finalTransform, localPosition, localRotation, localScale);
transformComponent.SetLocalPosition(localPosition);
transformComponent.SetLocalRotation(localRotation);
transformComponent.SetLocalScale(localScale);
transformComponent.SetLocalTransform(finalTransform);
transformComponent.Dirty = false;
}
}
for (auto& childBone : bone.Children)
{
UpdateBonePositionTraversal(childBone, animation, time);
}
}
void AnimationSystem::FixedUpdate(Timestep ts)
{