Utility: Make mesh loader use the parameters vertex declaration
This commit is contained in:
parent
2951b7811e
commit
9daadb73bc
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
Nazara Engine:
|
Nazara Engine:
|
||||||
- VertexMapper:GetComponentPtr no longer throw an error if component is disabled or incompatible with template type, instead a null pointer is returned.
|
- VertexMapper:GetComponentPtr no longer throw an error if component is disabled or incompatible with template type, instead a null pointer is returned.
|
||||||
- MeshParams now hold a ConstRef to the VertexDeclaration (preventing it to be freed before usage)
|
- Bitset swap operation is now correctly marked as noexcept`
|
||||||
|
- Mesh loaders now takes MeshParams vertexDeclaration into account
|
||||||
|
|
||||||
# 0.4:
|
# 0.4:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ namespace Nz
|
||||||
* If the declaration has a Vector3f Normals component enabled, Normals are generated.
|
* If the declaration has a Vector3f Normals component enabled, Normals are generated.
|
||||||
* If the declaration has a Vector3f Tangents component enabled, Tangents are generated.
|
* If the declaration has a Vector3f Tangents component enabled, Tangents are generated.
|
||||||
*/
|
*/
|
||||||
VertexDeclarationConstRef vertexDeclaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent);
|
VertexDeclaration* vertexDeclaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent);
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ SOFTWARE.
|
||||||
#include <Nazara/Utility/MaterialData.hpp>
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Skeleton.hpp>
|
#include <Nazara/Utility/Skeleton.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
#include <assimp/cfileio.h>
|
#include <assimp/cfileio.h>
|
||||||
#include <assimp/cimport.h>
|
#include <assimp/cimport.h>
|
||||||
#include <assimp/config.h>
|
#include <assimp/config.h>
|
||||||
|
|
@ -119,13 +120,27 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
||||||
long long vertexLimit = 1'000'000;
|
long long vertexLimit = 1'000'000;
|
||||||
parameters.custom.GetIntegerParameter("AssimpLoader_VertexLimit", &vertexLimit);
|
parameters.custom.GetIntegerParameter("AssimpLoader_VertexLimit", &vertexLimit);
|
||||||
|
|
||||||
|
int excludedComponents = 0;
|
||||||
|
|
||||||
|
if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Color))
|
||||||
|
excludedComponents |= aiComponent_COLORS;
|
||||||
|
|
||||||
|
if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Normal))
|
||||||
|
excludedComponents |= aiComponent_NORMALS;
|
||||||
|
|
||||||
|
if (!parameters.vertexDeclaration->HasComponent(VertexComponent_Tangent))
|
||||||
|
excludedComponents |= aiComponent_TANGENTS_AND_BITANGENTS;
|
||||||
|
|
||||||
|
if (!parameters.vertexDeclaration->HasComponent(VertexComponent_TexCoord))
|
||||||
|
excludedComponents |= aiComponent_TEXCOORDS;
|
||||||
|
|
||||||
aiPropertyStore* properties = aiCreatePropertyStore();
|
aiPropertyStore* properties = aiCreatePropertyStore();
|
||||||
aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, float(smoothingAngle));
|
aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, float(smoothingAngle));
|
||||||
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4);
|
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4);
|
||||||
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SBP_REMOVE, ~aiPrimitiveType_TRIANGLE); //< We only want triangles
|
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SBP_REMOVE, ~aiPrimitiveType_TRIANGLE); //< We only want triangles
|
||||||
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, int(triangleLimit));
|
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, int(triangleLimit));
|
||||||
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, int(vertexLimit));
|
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, int(vertexLimit));
|
||||||
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS);
|
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, excludedComponents);
|
||||||
|
|
||||||
const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties);
|
const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties);
|
||||||
aiReleasePropertyStore(properties);
|
aiReleasePropertyStore(properties);
|
||||||
|
|
@ -210,22 +225,56 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
||||||
if (normalTangentMatrix.HasScale())
|
if (normalTangentMatrix.HasScale())
|
||||||
normalTangentMatrix.ApplyScale(1.f / normalTangentMatrix.GetScale());
|
normalTangentMatrix.ApplyScale(1.f / normalTangentMatrix.GetScale());
|
||||||
|
|
||||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, parameters.vertexBufferFlags);
|
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, vertexCount, parameters.storage, parameters.vertexBufferFlags);
|
||||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
|
||||||
|
|
||||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||||
|
|
||||||
|
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
for (unsigned int j = 0; j < vertexCount; ++j)
|
for (unsigned int j = 0; j < vertexCount; ++j)
|
||||||
{
|
{
|
||||||
aiVector3D position = iMesh->mVertices[j];
|
aiVector3D position = iMesh->mVertices[j];
|
||||||
aiVector3D normal = iMesh->mNormals[j];
|
*posPtr++ = parameters.matrix * Vector3f(position.x, position.y, position.z);
|
||||||
aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f);
|
}
|
||||||
aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f);
|
|
||||||
|
|
||||||
vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z);
|
if (auto normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal))
|
||||||
vertex->normal = normalTangentMatrix.Transform({normal.x, normal.y, normal.z}, 0.f);
|
{
|
||||||
vertex->tangent = normalTangentMatrix.Transform({tangent.x, tangent.y, tangent.z}, 0.f);
|
for (unsigned int j = 0; j < vertexCount; ++j)
|
||||||
vertex->uv.Set(parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale);
|
{
|
||||||
vertex++;
|
aiVector3D normal = iMesh->mNormals[j];
|
||||||
|
*normalPtr++ = normalTangentMatrix.Transform({normal.x, normal.y, normal.z}, 0.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool generateTangents = false;
|
||||||
|
if (auto tangentPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent))
|
||||||
|
{
|
||||||
|
if (iMesh->HasTangentsAndBitangents())
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < vertexCount; ++j)
|
||||||
|
{
|
||||||
|
aiVector3D tangent = iMesh->mTangents[j];
|
||||||
|
*tangentPtr++ = normalTangentMatrix.Transform({tangent.x, tangent.y, tangent.z}, 0.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
generateTangents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord))
|
||||||
|
{
|
||||||
|
if (iMesh->HasTextureCoords(0))
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < vertexCount; ++j)
|
||||||
|
{
|
||||||
|
aiVector3D uv = iMesh->mTextureCoords[0][j];
|
||||||
|
*uvPtr++ = parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < vertexCount; ++j)
|
||||||
|
*uvPtr++ = Vector2f::Zero();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexMapper.Unmap();
|
vertexMapper.Unmap();
|
||||||
|
|
@ -238,6 +287,9 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
||||||
subMesh->GenerateAABB();
|
subMesh->GenerateAABB();
|
||||||
subMesh->SetMaterialIndex(iMesh->mMaterialIndex);
|
subMesh->SetMaterialIndex(iMesh->mMaterialIndex);
|
||||||
|
|
||||||
|
if (generateTangents)
|
||||||
|
subMesh->GenerateTangents();
|
||||||
|
|
||||||
auto matIt = materials.find(iMesh->mMaterialIndex);
|
auto matIt = materials.find(iMesh->mMaterialIndex);
|
||||||
if (matIt == materials.end())
|
if (matIt == materials.end())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1164,6 +1164,6 @@ namespace Nz
|
||||||
|
|
||||||
if (vertexPointers.tangentPtr)
|
if (vertexPointers.tangentPtr)
|
||||||
*vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale;
|
*vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Stream.hpp>
|
#include <Nazara/Core/Stream.hpp>
|
||||||
#include <Nazara/Math/Quaternion.hpp>
|
#include <Nazara/Math/Quaternion.hpp>
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
|
||||||
#include <Nazara/Utility/MaterialData.hpp>
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
#include <Nazara/Utility/Formats/MD2Constants.hpp>
|
#include <Nazara/Utility/Formats/MD2Constants.hpp>
|
||||||
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
|
|
@ -156,7 +157,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, parameters.vertexBufferFlags);
|
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, header.num_vertices, parameters.storage, parameters.vertexBufferFlags);
|
||||||
StaticMeshRef subMesh = StaticMesh::New(mesh);
|
StaticMeshRef subMesh = StaticMesh::New(mesh);
|
||||||
if (!subMesh->Create(vertexBuffer))
|
if (!subMesh->Create(vertexBuffer))
|
||||||
{
|
{
|
||||||
|
|
@ -189,23 +190,26 @@ namespace Nz
|
||||||
scale *= ScaleAdjust;
|
scale *= ScaleAdjust;
|
||||||
translate *= ScaleAdjust;
|
translate *= ScaleAdjust;
|
||||||
|
|
||||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
|
||||||
|
|
||||||
// Loading texture coordinates
|
// Loading texture coordinates
|
||||||
const unsigned int indexFix[3] = {0, 2, 1};
|
if (auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord))
|
||||||
Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight);
|
|
||||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < 3; ++j)
|
const unsigned int indexFix[3] = {0, 2, 1};
|
||||||
|
|
||||||
|
Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight);
|
||||||
|
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||||
{
|
{
|
||||||
const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order
|
for (unsigned int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order
|
||||||
|
|
||||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||||
Vector2f uv(texC.u, texC.v);
|
Vector2f uv(texC.u, texC.v);
|
||||||
uv *= invSkinSize;
|
uv *= invSkinSize;
|
||||||
|
|
||||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
uvPtr[triangles[i].vertices[fixedIndex]].Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,18 +220,27 @@ namespace Nz
|
||||||
Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale);
|
Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale);
|
||||||
matrix *= parameters.matrix;
|
matrix *= parameters.matrix;
|
||||||
|
|
||||||
Nz::Matrix4f normalMatrix = Matrix4f::Rotate(rotationQuat);
|
if (auto normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal))
|
||||||
normalMatrix *= 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];
|
||||||
|
|
||||||
|
*normalPtr++ = normalMatrix.Transform(md2Normals[vert.n], 0.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
|
assert(posPtr);
|
||||||
|
|
||||||
for (unsigned int v = 0; v < header.num_vertices; ++v)
|
for (unsigned int v = 0; v < header.num_vertices; ++v)
|
||||||
{
|
{
|
||||||
const MD2_Vertex& vert = vertices[v];
|
const MD2_Vertex& vert = vertices[v];
|
||||||
Vector3f position = matrix * Vector3f(vert.x, vert.y, vert.z);
|
|
||||||
|
|
||||||
vertex->position = position;
|
*posPtr++ = matrix * Vector3f(vert.x, vert.y, vert.z);
|
||||||
vertex->normal = normalMatrix.Transform(md2Normals[vert.n], 0.f);
|
|
||||||
|
|
||||||
vertex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexMapper.Unmap();
|
vertexMapper.Unmap();
|
||||||
|
|
@ -236,7 +249,9 @@ namespace Nz
|
||||||
subMesh->SetMaterialIndex(0);
|
subMesh->SetMaterialIndex(0);
|
||||||
|
|
||||||
subMesh->GenerateAABB();
|
subMesh->GenerateAABB();
|
||||||
subMesh->GenerateTangents();
|
|
||||||
|
if (parameters.vertexDeclaration->HasComponentOfType<Vector3f>(VertexComponent_Tangent))
|
||||||
|
subMesh->GenerateTangents();
|
||||||
|
|
||||||
mesh->AddSubMesh(subMesh);
|
mesh->AddSubMesh(subMesh);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||||
#include <Nazara/Utility/Skeleton.hpp>
|
#include <Nazara/Utility/Skeleton.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
#include <Nazara/Utility/Formats/MD5MeshParser.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
@ -128,6 +129,7 @@ namespace Nz
|
||||||
|
|
||||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
||||||
SkeletalMeshVertex* vertices = static_cast<SkeletalMeshVertex*>(vertexMapper.GetPointer());
|
SkeletalMeshVertex* vertices = static_cast<SkeletalMeshVertex*>(vertexMapper.GetPointer());
|
||||||
|
|
||||||
for (const MD5MeshParser::Vertex& vertex : md5Mesh.vertices)
|
for (const MD5MeshParser::Vertex& vertex : md5Mesh.vertices)
|
||||||
{
|
{
|
||||||
// Skinning MD5 (Formule d'Id Tech)
|
// Skinning MD5 (Formule d'Id Tech)
|
||||||
|
|
@ -254,13 +256,15 @@ namespace Nz
|
||||||
indexMapper.Unmap();
|
indexMapper.Unmap();
|
||||||
|
|
||||||
// Vertex buffer
|
// Vertex buffer
|
||||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
||||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
|
||||||
|
VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||||
|
|
||||||
|
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
|
|
||||||
MeshVertex* vertices = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
|
||||||
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
|
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
|
||||||
{
|
{
|
||||||
// Skinning MD5 (Formule d'Id Tech)
|
// Id Tech MD5 skinning
|
||||||
Vector3f finalPos(Vector3f::Zero());
|
Vector3f finalPos(Vector3f::Zero());
|
||||||
for (unsigned int j = 0; j < md5Vertex.weightCount; ++j)
|
for (unsigned int j = 0; j < md5Vertex.weightCount; ++j)
|
||||||
{
|
{
|
||||||
|
|
@ -271,9 +275,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
// On retourne le modèle dans le bon sens
|
// On retourne le modèle dans le bon sens
|
||||||
vertices->position = matrix * finalPos;
|
*posPtr++ = matrix * finalPos;
|
||||||
vertices->uv.Set(parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale);
|
}
|
||||||
vertices++;
|
|
||||||
|
if (auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord))
|
||||||
|
{
|
||||||
|
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
|
||||||
|
*uvPtr++ = parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexMapper.Unmap();
|
vertexMapper.Unmap();
|
||||||
|
|
@ -287,9 +295,16 @@ namespace Nz
|
||||||
|
|
||||||
subMesh->SetIndexBuffer(indexBuffer);
|
subMesh->SetIndexBuffer(indexBuffer);
|
||||||
subMesh->GenerateAABB();
|
subMesh->GenerateAABB();
|
||||||
subMesh->GenerateNormalsAndTangents();
|
|
||||||
subMesh->SetMaterialIndex(i);
|
subMesh->SetMaterialIndex(i);
|
||||||
|
|
||||||
|
if (parameters.vertexDeclaration->HasComponentOfType<Vector3f>(VertexComponent_Normal))
|
||||||
|
{
|
||||||
|
if (parameters.vertexDeclaration->HasComponentOfType<Vector3f>(VertexComponent_Tangent))
|
||||||
|
subMesh->GenerateNormalsAndTangents();
|
||||||
|
else
|
||||||
|
subMesh->GenerateNormals();
|
||||||
|
}
|
||||||
|
|
||||||
mesh->AddSubMesh(subMesh);
|
mesh->AddSubMesh(subMesh);
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
#include <Nazara/Utility/Formats/OBJLoader.hpp>
|
||||||
#include <Nazara/Core/ErrorFlags.hpp>
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
|
||||||
#include <Nazara/Utility/IndexMapper.hpp>
|
#include <Nazara/Utility/IndexMapper.hpp>
|
||||||
#include <Nazara/Utility/MaterialData.hpp>
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Utility/VertexMapper.hpp>
|
||||||
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||||
#include <Nazara/Utility/Formats/OBJParser.hpp>
|
#include <Nazara/Utility/Formats/OBJParser.hpp>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
@ -232,7 +232,7 @@ namespace Nz
|
||||||
|
|
||||||
// Création des buffers
|
// Création des buffers
|
||||||
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), UInt32(indices.size()), parameters.storage, parameters.indexBufferFlags);
|
IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits<UInt16>::max(), UInt32(indices.size()), parameters.storage, parameters.indexBufferFlags);
|
||||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
VertexBufferRef vertexBuffer = VertexBuffer::New(parameters.vertexDeclaration, UInt32(vertexCount), parameters.storage, parameters.vertexBufferFlags);
|
||||||
|
|
||||||
// Remplissage des indices
|
// Remplissage des indices
|
||||||
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly);
|
||||||
|
|
@ -250,30 +250,45 @@ namespace Nz
|
||||||
|
|
||||||
bool hasNormals = true;
|
bool hasNormals = true;
|
||||||
bool hasTexCoords = true;
|
bool hasTexCoords = true;
|
||||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
|
||||||
MeshVertex* meshVertices = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||||
|
|
||||||
|
auto normalPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
||||||
|
auto posPtr = vertexMapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
|
auto uvPtr = vertexMapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
||||||
|
|
||||||
|
if (!normalPtr)
|
||||||
|
hasNormals = false;
|
||||||
|
|
||||||
|
if (!uvPtr)
|
||||||
|
hasTexCoords = false;
|
||||||
|
|
||||||
for (auto& vertexPair : vertices)
|
for (auto& vertexPair : vertices)
|
||||||
{
|
{
|
||||||
const OBJParser::FaceVertex& vertexIndices = vertexPair.first;
|
const OBJParser::FaceVertex& vertexIndices = vertexPair.first;
|
||||||
unsigned int index = vertexPair.second;
|
unsigned int index = vertexPair.second;
|
||||||
|
|
||||||
MeshVertex& vertex = meshVertices[index];
|
|
||||||
|
|
||||||
const Vector4f& vec = positions[vertexIndices.position-1];
|
const Vector4f& vec = positions[vertexIndices.position-1];
|
||||||
vertex.position = Vector3f(parameters.matrix * vec);
|
posPtr[index] = Vector3f(parameters.matrix * vec);
|
||||||
|
|
||||||
if (vertexIndices.normal > 0)
|
if (hasNormals)
|
||||||
vertex.normal = normalMatrix.Transform(normals[vertexIndices.normal - 1], 0.f);
|
|
||||||
else
|
|
||||||
hasNormals = false;
|
|
||||||
|
|
||||||
if (vertexIndices.texCoord > 0)
|
|
||||||
{
|
{
|
||||||
Vector2f uv = Vector2f(texCoords[vertexIndices.texCoord - 1]);
|
if (vertexIndices.normal > 0)
|
||||||
vertex.uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
normalPtr[index] = normalMatrix.Transform(normals[vertexIndices.normal - 1], 0.f);
|
||||||
|
else
|
||||||
|
hasNormals = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasTexCoords)
|
||||||
|
{
|
||||||
|
if (vertexIndices.texCoord > 0)
|
||||||
|
{
|
||||||
|
Vector2f uv = Vector2f(texCoords[vertexIndices.texCoord - 1]);
|
||||||
|
uvPtr[index] = Vector2f(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hasTexCoords = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
hasTexCoords = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexMapper.Unmap();
|
vertexMapper.Unmap();
|
||||||
|
|
@ -298,7 +313,7 @@ namespace Nz
|
||||||
subMesh->GenerateTangents();
|
subMesh->GenerateTangents();
|
||||||
else if (hasTexCoords)
|
else if (hasTexCoords)
|
||||||
subMesh->GenerateNormalsAndTangents();
|
subMesh->GenerateNormalsAndTangents();
|
||||||
else
|
else if (normalPtr)
|
||||||
subMesh->GenerateNormals();
|
subMesh->GenerateNormals();
|
||||||
|
|
||||||
mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh);
|
mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh);
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,12 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!vertexDeclaration->HasComponent(VertexComponent_Position))
|
||||||
|
{
|
||||||
|
NazaraError("Vertex declaration must contains a vertex position");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +60,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
MeshImpl()
|
MeshImpl()
|
||||||
{
|
{
|
||||||
materialData.resize(1); // Un matériau par défaut
|
materialData.resize(1); // One material by default
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<String, UInt32> subMeshMap;
|
std::unordered_map<String, UInt32> subMeshMap;
|
||||||
|
|
@ -62,10 +68,10 @@ namespace Nz
|
||||||
std::vector<SubMeshRef> subMeshes;
|
std::vector<SubMeshRef> subMeshes;
|
||||||
AnimationType animationType;
|
AnimationType animationType;
|
||||||
Boxf aabb;
|
Boxf aabb;
|
||||||
Skeleton skeleton; // Uniquement pour les meshs squelettiques
|
Skeleton skeleton; // Only used by skeletal meshes
|
||||||
String animationPath;
|
String animationPath;
|
||||||
bool aabbUpdated = false;
|
bool aabbUpdated = false;
|
||||||
UInt32 jointCount; // Uniquement pour les meshs squelettiques
|
UInt32 jointCount; // Only used by skeletal meshes
|
||||||
};
|
};
|
||||||
|
|
||||||
Mesh::~Mesh()
|
Mesh::~Mesh()
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,14 @@ namespace Nz
|
||||||
void SubMesh::GenerateNormals()
|
void SubMesh::GenerateNormals()
|
||||||
{
|
{
|
||||||
VertexMapper mapper(this);
|
VertexMapper mapper(this);
|
||||||
unsigned int vertexCount = GetVertexCount();
|
UInt32 vertexCount = mapper.GetVertexCount();
|
||||||
|
|
||||||
SparsePtr<Vector3f> normals = mapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
SparsePtr<Vector3f> normals = mapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
||||||
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
|
if (!normals || !positions)
|
||||||
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
for (UInt32 i = 0; i < vertexCount; ++i)
|
||||||
normals[i].MakeZero();
|
normals[i].MakeZero();
|
||||||
|
|
||||||
TriangleIterator iterator(this);
|
TriangleIterator iterator(this);
|
||||||
|
|
@ -52,21 +54,23 @@ namespace Nz
|
||||||
}
|
}
|
||||||
while (iterator.Advance());
|
while (iterator.Advance());
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
for (UInt32 i = 0; i < vertexCount; ++i)
|
||||||
normals[i].Normalize();
|
normals[i].Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubMesh::GenerateNormalsAndTangents()
|
void SubMesh::GenerateNormalsAndTangents()
|
||||||
{
|
{
|
||||||
VertexMapper mapper(this);
|
VertexMapper mapper(this);
|
||||||
unsigned int vertexCount = GetVertexCount();
|
UInt32 vertexCount = mapper.GetVertexCount();
|
||||||
|
|
||||||
SparsePtr<Vector3f> normals = mapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
SparsePtr<Vector3f> normals = mapper.GetComponentPtr<Vector3f>(VertexComponent_Normal);
|
||||||
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
SparsePtr<Vector3f> tangents = mapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
|
SparsePtr<Vector3f> tangents = mapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
|
||||||
SparsePtr<Vector2f> texCoords = mapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
SparsePtr<Vector2f> texCoords = mapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
||||||
|
if (!normals || !positions || !tangents || !texCoords)
|
||||||
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
for (UInt32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
normals[i].MakeZero();
|
normals[i].MakeZero();
|
||||||
tangents[i].MakeZero();
|
tangents[i].MakeZero();
|
||||||
|
|
@ -105,7 +109,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
while (iterator.Advance());
|
while (iterator.Advance());
|
||||||
|
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
for (UInt32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
normals[i].Normalize();
|
normals[i].Normalize();
|
||||||
tangents[i].Normalize();
|
tangents[i].Normalize();
|
||||||
|
|
@ -120,6 +124,8 @@ namespace Nz
|
||||||
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
SparsePtr<Vector3f> positions = mapper.GetComponentPtr<Vector3f>(VertexComponent_Position);
|
||||||
SparsePtr<Vector3f> tangents = mapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
|
SparsePtr<Vector3f> tangents = mapper.GetComponentPtr<Vector3f>(VertexComponent_Tangent);
|
||||||
SparsePtr<Vector2f> texCoords = mapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
SparsePtr<Vector2f> texCoords = mapper.GetComponentPtr<Vector2f>(VertexComponent_TexCoord);
|
||||||
|
if (!normals || !positions || !tangents || !texCoords)
|
||||||
|
return;
|
||||||
|
|
||||||
TriangleIterator iterator(this);
|
TriangleIterator iterator(this);
|
||||||
do
|
do
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue