Utility: Handle vertex color loading

This commit is contained in:
Jérôme Leclercq 2021-09-08 19:07:59 +02:00
parent 0961baa5ac
commit 75f927b414
4 changed files with 82 additions and 30 deletions

View File

@ -493,13 +493,17 @@ std::shared_ptr<Mesh> LoadMesh(Stream& stream, const MeshParams& parameters)
VertexMapper vertexMapper(*vertexBuffer, BufferAccess::DiscardAndWrite);
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent::Position);
for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx)
// Vertex positions
if (auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(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<Vector3f>(VertexComponent::Normal))
{
for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx)
@ -509,6 +513,7 @@ std::shared_ptr<Mesh> LoadMesh(Stream& stream, const MeshParams& parameters)
}
}
// Vertex tangents
bool generateTangents = false;
if (auto tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent::Tangent))
{
@ -524,6 +529,7 @@ std::shared_ptr<Mesh> LoadMesh(Stream& stream, const MeshParams& parameters)
generateTangents = true;
}
// Vertex UVs
if (auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent::TexCoord))
{
if (iMesh->HasTextureCoords(0))
@ -541,6 +547,24 @@ std::shared_ptr<Mesh> LoadMesh(Stream& stream, const MeshParams& parameters)
}
}
// Vertex colors
if (auto colorPtr = vertexMapper.GetComponentPtr<Color>(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

View File

@ -12,6 +12,7 @@
#include <Nazara/Utility/StaticMesh.hpp>
#include <Nazara/Utility/VertexMapper.hpp>
#include <Nazara/Utility/Formats/MD2Constants.hpp>
#include <array>
#include <cassert>
#include <memory>
#include <Nazara/Utility/Debug.hpp>
@ -191,12 +192,12 @@ namespace Nz
// Loading texture coordinates
if (auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent::TexCoord))
{
const unsigned int indexFix[3] = {0, 2, 1};
constexpr std::array<UInt32, 3> 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<Vector3f>(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<Vector3f>(VertexComponent::Position);
assert(posPtr);
for (unsigned int v = 0; v < header.num_vertices; ++v)
// Vertex positions
if (auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(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<Color>(VertexComponent::Color))
{
for (UInt32 v = 0; v < header.num_vertices; ++v)
*colorPtr++ = Color::White;
}
vertexMapper.Unmap();

View File

@ -263,30 +263,40 @@ namespace Nz
VertexMapper vertexMapper(*vertexBuffer, BufferAccess::DiscardAndWrite);
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent::Position);
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
// Vertex positions
if (auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(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<Vector2f>(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<Color>(VertexComponent::Color))
{
for (std::size_t i = 0; i < md5Mesh.vertices.size(); ++i)
*colorPtr++ = Color::White;
}
vertexMapper.Unmap();
// Submesh

View File

@ -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<Color>(VertexComponent::Color))
{
for (unsigned int i = 0; i < vertexCount; ++i)
colorPtr[i] = Nz::Color::White;
}
vertexMapper.Unmap();
std::shared_ptr<StaticMesh> subMesh = std::make_shared<StaticMesh>(std::move(vertexBuffer), indexBuffer);