From c48d752ad4cea3093dcafea880681a5b01cefc55 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Aug 2017 15:58:19 +0200 Subject: [PATCH] Utility/MeshLoader: Fix pre-transformation matrix not affecting normal and tangents in some cases (Fix #131) --- plugins/Assimp/Plugin.cpp | 10 ++++++++-- src/Nazara/Utility/Formats/MD2Loader.cpp | 5 ++++- src/Nazara/Utility/Formats/OBJLoader.cpp | 8 +++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 744434137..7834e0019 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -202,6 +202,12 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) indexMapper.Unmap(); // Vertex buffer + + // Make sure the normal/tangent matrix won't rescale our vectors + Nz::Matrix4f normalTangentMatrix = parameters.matrix; + if (normalTangentMatrix.HasScale()) + normalTangentMatrix.ApplyScale(1.f / normalTangentMatrix.GetScale()); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -214,8 +220,8 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z); - vertex->normal.Set(normal.x, normal.y, normal.z); - vertex->tangent.Set(tangent.x, tangent.y, tangent.z); + vertex->normal = normalTangentMatrix.Transform({normal.x, normal.y, normal.z}, 0.f); + vertex->tangent = normalTangentMatrix.Transform({tangent.x, tangent.y, tangent.z}, 0.f); vertex->uv.Set(parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale); vertex++; } diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 76ee1c1ea..9008a22ad 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -219,13 +219,16 @@ namespace Nz Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale); matrix *= parameters.matrix; + Nz::Matrix4f normalMatrix = Matrix4f::Rotate(rotationQuat); + normalMatrix *= parameters.matrix; + for (unsigned int v = 0; v < header.num_vertices; ++v) { const MD2_Vertex& vert = vertices[v]; Vector3f position = matrix * Vector3f(vert.x, vert.y, vert.z); vertex->position = position; - vertex->normal = rotationQuat * md2Normals[vert.n]; + vertex->normal = normalMatrix.Transform(md2Normals[vert.n], 0.f); vertex++; } diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index d7dd15d14..b9573b5d5 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -244,6 +244,12 @@ namespace Nz indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer // Remplissage des vertices + + // Make sure the normal matrix won't rescale our normals + Nz::Matrix4f normalMatrix = parameters.matrix; + if (normalMatrix.HasScale()) + normalMatrix.ApplyScale(1.f / normalMatrix.GetScale()); + bool hasNormals = true; bool hasTexCoords = true; BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -259,7 +265,7 @@ namespace Nz vertex.position = Vector3f(parameters.matrix * vec); if (vertexIndices.normal > 0) - vertex.normal = normals[vertexIndices.normal-1]; + vertex.normal = normalMatrix.Transform(normals[vertexIndices.normal - 1], 0.f); else hasNormals = false;