From 75f927b4144df05c024e9461720e23141cda155f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 8 Sep 2021 19:07:59 +0200 Subject: [PATCH] Utility: Handle vertex color loading --- plugins/Assimp/Plugin.cpp | 32 +++++++++++++++--- src/Nazara/Utility/Formats/MD2Loader.cpp | 32 +++++++++++------- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 34 +++++++++++++------- src/Nazara/Utility/Formats/OBJLoader.cpp | 14 ++++++-- 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 62c35a6f0..926703869 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -493,13 +493,17 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) VertexMapper vertexMapper(*vertexBuffer, BufferAccess::DiscardAndWrite); - auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position); - for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) + // Vertex positions + if (auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position)) { - aiVector3D position = iMesh->mVertices[vertexIdx]; - *posPtr++ = parameters.matrix * Vector3f(position.x, position.y, position.z); + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) + { + aiVector3D position = iMesh->mVertices[vertexIdx]; + *posPtr++ = parameters.matrix * Vector3f(position.x, position.y, position.z); + } } + // Vertex normals if (auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent::Normal)) { for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) @@ -509,6 +513,7 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) } } + // Vertex tangents bool generateTangents = false; if (auto tangentPtr = vertexMapper.GetComponentPtr(VertexComponent::Tangent)) { @@ -524,6 +529,7 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) generateTangents = true; } + // Vertex UVs if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent::TexCoord)) { if (iMesh->HasTextureCoords(0)) @@ -541,6 +547,24 @@ std::shared_ptr LoadMesh(Stream& stream, const MeshParams& parameters) } } + // Vertex colors + if (auto colorPtr = vertexMapper.GetComponentPtr(VertexComponent::Color)) + { + if (iMesh->HasVertexColors(0)) + { + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) + { + aiColor4D color = iMesh->mColors[0][vertexIdx]; + *colorPtr++ = Color(UInt8(color.r * 255.f), UInt8(color.g * 255.f), UInt8(color.b * 255.f), UInt8(color.a * 255.f)); + } + } + else + { + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) + *colorPtr++ = Color::White; + } + } + vertexMapper.Unmap(); // Submesh diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 395007750..2c43b9edb 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -191,12 +192,12 @@ namespace Nz // Loading texture coordinates if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent::TexCoord)) { - const unsigned int indexFix[3] = {0, 2, 1}; + constexpr std::array indexFix = {0, 2, 1}; Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight); - for (unsigned int i = 0; i < header.num_tris; ++i) + for (UInt32 i = 0; i < header.num_tris; ++i) { - for (unsigned int fixedIndex : indexFix) //< Reverse winding order + for (UInt32 fixedIndex : indexFix) //< Reverse winding order { const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; Vector2f uv(texC.u, texC.v); @@ -207,19 +208,18 @@ namespace Nz } } - // Loading vertex position - // Align the model to our coordinates system Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f); Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale); matrix *= parameters.matrix; + // Vertex normals if (auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent::Normal)) { Nz::Matrix4f normalMatrix = Matrix4f::Rotate(rotationQuat); normalMatrix *= parameters.matrix; - for (unsigned int v = 0; v < header.num_vertices; ++v) + for (UInt32 v = 0; v < header.num_vertices; ++v) { const MD2_Vertex& vert = vertices[v]; @@ -227,14 +227,22 @@ namespace Nz } } - auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position); - assert(posPtr); - - for (unsigned int v = 0; v < header.num_vertices; ++v) + // Vertex positions + if (auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position)) { - const MD2_Vertex& vert = vertices[v]; + for (UInt32 v = 0; v < header.num_vertices; ++v) + { + const MD2_Vertex& vert = vertices[v]; - *posPtr++ = matrix * Vector3f(vert.x, vert.y, vert.z); + *posPtr++ = matrix * Vector3f(vert.x, vert.y, vert.z); + } + } + + // Vertex colors (.md2 files have no vertex color) + if (auto colorPtr = vertexMapper.GetComponentPtr(VertexComponent::Color)) + { + for (UInt32 v = 0; v < header.num_vertices; ++v) + *colorPtr++ = Color::White; } vertexMapper.Unmap(); diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 7a6ba60e1..b981d07cd 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -263,30 +263,40 @@ namespace Nz VertexMapper vertexMapper(*vertexBuffer, BufferAccess::DiscardAndWrite); - auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position); - - for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) + // Vertex positions + if (auto posPtr = vertexMapper.GetComponentPtr(VertexComponent::Position)) { - // Id Tech MD5 skinning - Vector3f finalPos(Vector3f::Zero()); - for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) + for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) { - const MD5MeshParser::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; - const MD5MeshParser::Joint& joint = joints[weight.joint]; + // Id Tech MD5 skinning + Vector3f finalPos(Vector3f::Zero()); + for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) + { + const MD5MeshParser::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; + const MD5MeshParser::Joint& joint = joints[weight.joint]; - finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + finalPos += (joint.bindPos + joint.bindOrient * weight.pos) * weight.bias; + } + + // On retourne le modèle dans le bon sens + *posPtr++ = matrix * finalPos; } - - // On retourne le modèle dans le bon sens - *posPtr++ = matrix * finalPos; } + // Vertex UVs if (auto uvPtr = vertexMapper.GetComponentPtr(VertexComponent::TexCoord)) { for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) *uvPtr++ = parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale; } + // Vertex colors (.md5mesh files have no vertex color) + if (auto colorPtr = vertexMapper.GetComponentPtr(VertexComponent::Color)) + { + for (std::size_t i = 0; i < md5Mesh.vertices.size(); ++i) + *colorPtr++ = Color::White; + } + vertexMapper.Unmap(); // Submesh diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 9b14409c9..cd8a51502 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -294,8 +294,11 @@ namespace Nz const OBJParser::FaceVertex& vertexIndices = vertexPair.first; unsigned int index = vertexPair.second; - const Vector4f& vec = positions[vertexIndices.position-1]; - posPtr[index] = Vector3f(parameters.matrix * vec); + if (posPtr) + { + const Vector4f& vec = positions[vertexIndices.position - 1]; + posPtr[index] = Vector3f(parameters.matrix * vec); + } if (hasNormals) { @@ -319,6 +322,13 @@ namespace Nz } } + // Official .obj files have no vertex color, fill it with white + if (auto colorPtr = vertexMapper.GetComponentPtr(VertexComponent::Color)) + { + for (unsigned int i = 0; i < vertexCount; ++i) + colorPtr[i] = Nz::Color::White; + } + vertexMapper.Unmap(); std::shared_ptr subMesh = std::make_shared(std::move(vertexBuffer), indexBuffer);