Properly transform bones

This commit is contained in:
Antoine Pilote
2023-09-06 17:48:50 -04:00
parent 290f0e03b5
commit fb5069ba5e
5 changed files with 57 additions and 39 deletions

View File

@@ -359,6 +359,8 @@ namespace Nuake
gBufferSkinnedMeshShader->SetUniformMat4f("u_Projection", mProjection);
gBufferSkinnedMeshShader->SetUniformMat4f("u_View", mView);
RenderCommand::Disable(RendererEnum::FACE_CULL);
// Skinned Models
const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID");
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
@@ -367,22 +369,19 @@ namespace Nuake
for (auto e : skinnedModelView)
{
auto [transform, mesh, visibility] = skinnedModelView.get<TransformComponent, SkinnedModelComponent, VisibilityComponent>(e);
auto& meshResource = mesh.ModelResource;
if (mesh.ModelResource && visibility.Visible)
if (meshResource && visibility.Visible)
{
auto& rootBoneNode = meshResource->GetSkeletonRootNode();
SetSkeletonBoneTransformRecursive(rootBoneNode, gBufferSkinnedMeshShader);
for (auto& m : mesh.ModelResource->GetMeshes())
{
m->GetMaterial()->Bind(gBufferSkinnedMeshShader);
uint32_t boneId = 0;
for (auto& b : m->GetBones())
{
const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(boneId) + "]";
gBufferSkinnedMeshShader->SetUniformMat4f(boneMatrixUniformName, b.Offset);
boneId++;
}
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, transform.GetGlobalTransform());
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
gBufferSkinnedMeshShader->SetUniform1i(entityIdUniformLocation, (uint32_t)e + 1);
m->Draw(gBufferSkinnedMeshShader, true);
}
@@ -452,4 +451,22 @@ namespace Nuake
void SceneRenderer::PostProcessPass(const Scene& scene)
{
}
void SceneRenderer::SetSkeletonBoneTransformRecursive(SkeletonNode& skeletonNode, Shader* shader)
{
auto scene = Engine::GetCurrentScene();
for (auto& child : skeletonNode.Children)
{
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);
}
SetSkeletonBoneTransformRecursive(child, shader);
}
}
}

View File

@@ -39,5 +39,7 @@ namespace Nuake
void GBufferPass(Scene& scene);
void ShadingPass(Scene& scene);
void PostProcessPass(const Scene& scene);
void SetSkeletonBoneTransformRecursive(SkeletonNode& skeletonNode, Shader* shader);
};
}

View File

@@ -50,8 +50,13 @@ namespace Nuake
return model;
}
std::unordered_map<std::string, uint32_t> bonesNameIDMap;
Ref<SkinnedModel> ModelLoader::LoadSkinnedModel(const std::string& path, bool absolute)
{
bonesNameIDMap = std::unordered_map<std::string, uint32_t>();
m_BoneMap = std::unordered_map<std::string, Bone>();
m_SkinnedMeshes.clear();
Ref<SkinnedModel> model = CreateRef<SkinnedModel>(path);
@@ -137,7 +142,6 @@ namespace Nuake
auto& indices = ProcessIndices(node);
auto& material = ProcessMaterials(scene, node);
auto& bones = std::vector<Bone>();
auto& bonesMap = std::unordered_map<std::string, Bone>();
if (node->HasBones())
{
@@ -148,7 +152,7 @@ namespace Nuake
const std::string& boneName = bone->mName.C_Str();
int32_t boneId = -1;
if (bonesMap.find(boneName) == bonesMap.end())
if (m_BoneMap.find(boneName) == m_BoneMap.end())
{
boneId = boneCounter;
boneCounter++;
@@ -157,11 +161,12 @@ namespace Nuake
newBone.Offset = ConvertMatrixToGLMFormat(bone->mOffsetMatrix);
bones.push_back(newBone);
bonesMap[boneName] = newBone;
bonesNameIDMap[boneName] = boneId;
m_BoneMap[boneName] = newBone;
}
else
{
boneId = bonesMap[boneName].Id;
boneId = m_BoneMap[boneName].Id;
}
assert(boneId != -1);
@@ -171,7 +176,7 @@ namespace Nuake
{
aiVertexWeight vertexWeight = bone->mWeights[j];
const uint32_t vertexWeightVertexId = vertexWeight.mVertexId;
SetVertexBoneData(vertices[vertexWeightVertexId], boneId, vertexWeight.mWeight);
//BoneVertexWeight boneVertexWeight
@@ -215,20 +220,20 @@ namespace Nuake
auto vertices = std::vector<Vertex>();
for (uint32_t i = 0; i < mesh->mNumVertices; i++)
{
Vertex vertex;
Vertex vertex {};
Vector3 current;
// Position
current.x = mesh->mVertices[i].x;
current.y = mesh->mVertices[i].z;
current.z = mesh->mVertices[i].y;
current.y = mesh->mVertices[i].y;
current.z = mesh->mVertices[i].z;
vertex.position = current;
// Normals
current.x = mesh->mNormals[i].x;
current.y = mesh->mNormals[i].z;
current.z = mesh->mNormals[i].y;
current.y = mesh->mNormals[i].y;
current.z = mesh->mNormals[i].z;
vertex.normal = current;
// Tangents
@@ -343,6 +348,8 @@ namespace Nuake
dest.Name = src->mName.data;
dest.Transform = ConvertMatrixToGLMFormat(src->mTransformation);
dest.ChildrenCount = src->mNumChildren;
dest.Id = bonesNameIDMap[dest.Name];
dest.Offset = m_BoneMap[dest.Name].Offset;
for (uint32_t i = 0; i < dest.ChildrenCount; i++)
{
@@ -358,6 +365,7 @@ namespace Nuake
SkeletonNode bone;
bone.Name = src->mName.C_Str();
bone.Transform = ConvertMatrixToGLMFormat(src->mTransformation);
bone.Id = bonesNameIDMap[bone.Name];
des.ChildrenCount++;
des.Children.push_back(bone);

View File

@@ -33,6 +33,8 @@ namespace Nuake
std::string modelDir;
std::vector<Ref<Mesh>> m_Meshes;
std::vector<Ref<SkinnedMesh>> m_SkinnedMeshes;
std::unordered_map<std::string, uint32_t> m_BoneIDMap;
std::unordered_map<std::string, Bone> m_BoneMap;
void ProcessNode(aiNode* node, const aiScene* scene);
Ref<Mesh> ProcessMesh(aiMesh* node, const aiScene* scene);
@@ -52,27 +54,14 @@ namespace Nuake
static inline Matrix4 ConvertMatrixToGLMFormat(const aiMatrix4x4& from)
{
Matrix4 result;
for (auto i = 0; i < 3; i++)
{
for (auto j = 0; j < 3; j++)
{
result[i][j] = from[i][j];
}
}
Matrix4 to;
// The rest would be zero, other than the 4,4.
result[0][3] = 0.0f;
result[1][3] = 0.0f;
result[2][3] = 0.0f;
to[0][0] = from.a1; to[0][1] = from.b1; to[0][2] = from.c1; to[0][3] = from.d1;
to[1][0] = from.a2; to[1][1] = from.b2; to[1][2] = from.c2; to[1][3] = from.d2;
to[2][0] = from.a3; to[2][1] = from.b3; to[2][2] = from.c3; to[2][3] = from.d3;
to[3][0] = from.a4; to[3][1] = from.b4; to[3][2] = from.c4; to[3][3] = from.d4;
result[3][0] = 0.0f;
result[3][1] = 0.0f;
result[3][2] = 0.0f;
result[3][3] = 1.0f;
return result;
return to;
}
};
}

View File

@@ -7,8 +7,10 @@ namespace Nuake
struct SkeletonNode
{
Matrix4 Transform;
Matrix4 Offset;
std::string Name;
int ChildrenCount;
std::vector<SkeletonNode> Children;
int32_t Id = -1;
};
}