diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index 03cf1ea3..62760762 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -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(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().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); + } + } + } \ No newline at end of file diff --git a/Nuake/src/Rendering/SceneRenderer.h b/Nuake/src/Rendering/SceneRenderer.h index 1e4d9d72..267359ad 100644 --- a/Nuake/src/Rendering/SceneRenderer.h +++ b/Nuake/src/Rendering/SceneRenderer.h @@ -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); }; } \ No newline at end of file diff --git a/Nuake/src/Resource/ModelLoader.cpp b/Nuake/src/Resource/ModelLoader.cpp index 157ac835..57cfe60d 100644 --- a/Nuake/src/Resource/ModelLoader.cpp +++ b/Nuake/src/Resource/ModelLoader.cpp @@ -50,8 +50,13 @@ namespace Nuake return model; } + + std::unordered_map bonesNameIDMap; Ref ModelLoader::LoadSkinnedModel(const std::string& path, bool absolute) { + bonesNameIDMap = std::unordered_map(); + m_BoneMap = std::unordered_map(); + m_SkinnedMeshes.clear(); Ref model = CreateRef(path); @@ -137,7 +142,6 @@ namespace Nuake auto& indices = ProcessIndices(node); auto& material = ProcessMaterials(scene, node); auto& bones = std::vector(); - auto& bonesMap = std::unordered_map(); 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(); 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); diff --git a/Nuake/src/Resource/ModelLoader.h b/Nuake/src/Resource/ModelLoader.h index 6c2cba9e..598be588 100644 --- a/Nuake/src/Resource/ModelLoader.h +++ b/Nuake/src/Resource/ModelLoader.h @@ -33,6 +33,8 @@ namespace Nuake std::string modelDir; std::vector> m_Meshes; std::vector> m_SkinnedMeshes; + std::unordered_map m_BoneIDMap; + std::unordered_map m_BoneMap; void ProcessNode(aiNode* node, const aiScene* scene); Ref 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; } }; } \ No newline at end of file diff --git a/Nuake/src/Resource/SkeletonNode.h b/Nuake/src/Resource/SkeletonNode.h index 7c8e2277..90bc5fa2 100644 --- a/Nuake/src/Resource/SkeletonNode.h +++ b/Nuake/src/Resource/SkeletonNode.h @@ -7,8 +7,10 @@ namespace Nuake struct SkeletonNode { Matrix4 Transform; + Matrix4 Offset; std::string Name; int ChildrenCount; std::vector Children; + int32_t Id = -1; }; } \ No newline at end of file