Mesh/MeshParams: Replace flipUVs by texCoordOffset and texCoordScale
This commit is contained in:
parent
3ae5bfad63
commit
0c8128b7e4
|
|
@ -156,9 +156,10 @@ namespace Nz
|
|||
|
||||
params->animated = instance.CheckField<bool>("Animated", params->animated);
|
||||
params->center = instance.CheckField<bool>("Center", params->center);
|
||||
params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs);
|
||||
params->matrix = instance.CheckField<Matrix4f>("Matrix", params->matrix);
|
||||
params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
|
||||
params->texCoordOffset = instance.CheckField<Vector2f>("TexCoordOffset", params->texCoordOffset);
|
||||
params->texCoordScale = instance.CheckField<Vector2f>("TexCoordScale", params->texCoordScale);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,25 +28,15 @@ namespace Nz
|
|||
{
|
||||
struct NAZARA_UTILITY_API MeshParams : ResourceParameters
|
||||
{
|
||||
MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement)
|
||||
MeshParams();
|
||||
|
||||
// La transformation appliquée à tous les sommets du mesh
|
||||
Matrix4f matrix = Matrix4f::Identity();
|
||||
|
||||
// Si ceci sera le stockage utilisé par les buffers
|
||||
UInt32 storage = DataStorage_Hardware;
|
||||
|
||||
// Charger une version animée du mesh si possible ?
|
||||
bool animated = true;
|
||||
|
||||
// Faut-il centrer le mesh autour de l'origine ?
|
||||
bool center = false;
|
||||
|
||||
// Faut-il retourner les UV ?
|
||||
bool flipUVs = false;
|
||||
|
||||
// Faut-il optimiser les index buffers ? (Rendu plus rapide, mais le chargement dure plus longtemps)
|
||||
bool optimizeIndexBuffers = true;
|
||||
Matrix4f matrix = Matrix4f::Identity(); ///< A matrix which will transform every vertex position
|
||||
UInt32 storage = DataStorage_Hardware; ///< The place where the buffers will be allocated
|
||||
Vector2f texCoordOffset = {0.f, 0.f}; ///< Offset to apply on the texture coordinates (not scaled)
|
||||
Vector2f texCoordScale = {1.f, 1.f}; ///< Scale to apply on the texture coordinates
|
||||
bool animated = true; ///< If true, will load an animated version of the model if possible
|
||||
bool center = false; ///< If true, will center the mesh vertices around the origin
|
||||
bool optimizeIndexBuffers = true; ///< Optimize the index buffers after loading, improve cache locality (and thus rendering speed) but increase loading time.
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -97,17 +97,14 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
|||
unsigned int postProcess = aiProcess_CalcTangentSpace | aiProcess_JoinIdenticalVertices
|
||||
| aiProcess_MakeLeftHanded | aiProcess_Triangulate
|
||||
| aiProcess_RemoveComponent | aiProcess_GenSmoothNormals
|
||||
| aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights
|
||||
| aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials
|
||||
| aiProcess_FixInfacingNormals | aiProcess_SortByPType
|
||||
| aiProcess_FindInvalidData | aiProcess_GenUVCoords
|
||||
| aiProcess_TransformUVCoords | aiProcess_OptimizeMeshes
|
||||
| aiProcess_OptimizeGraph | aiProcess_FlipWindingOrder
|
||||
| aiProcess_SplitLargeMeshes | aiProcess_LimitBoneWeights
|
||||
| aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials
|
||||
| aiProcess_FixInfacingNormals | aiProcess_SortByPType
|
||||
| aiProcess_FindInvalidData | aiProcess_GenUVCoords
|
||||
| aiProcess_TransformUVCoords | aiProcess_OptimizeMeshes
|
||||
| aiProcess_OptimizeGraph | aiProcess_FlipWindingOrder
|
||||
| aiProcess_Debone;
|
||||
|
||||
if (parameters.flipUVs)
|
||||
postProcess |= aiProcess_FlipUVs;
|
||||
|
||||
if (parameters.optimizeIndexBuffers)
|
||||
postProcess |= aiProcess_ImproveCacheLocality;
|
||||
|
||||
|
|
@ -157,7 +154,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
|||
if (animatedMesh)
|
||||
{
|
||||
mesh->CreateSkeletal(joints.size());
|
||||
|
||||
|
||||
Skeleton* skeleton = mesh->GetSkeleton();
|
||||
|
||||
// First, assign names
|
||||
|
|
@ -172,9 +169,9 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
|||
else
|
||||
{
|
||||
mesh->CreateStatic();
|
||||
|
||||
|
||||
// aiMaterial index in scene => Material index and data in Mesh
|
||||
std::unordered_map<unsigned int, std::pair<unsigned int, ParameterList>> materials;
|
||||
std::unordered_map<unsigned int, std::pair<std::size_t, ParameterList>> materials;
|
||||
|
||||
for (unsigned int i = 0; i < scene->mNumMeshes; ++i)
|
||||
{
|
||||
|
|
@ -219,7 +216,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
|||
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->uv.Set(uv.x, uv.y);
|
||||
vertex->uv.Set(parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale);
|
||||
vertex++;
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +308,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
|
|||
mesh->AddSubMesh(subMesh);
|
||||
}
|
||||
|
||||
mesh->SetMaterialCount(std::max<unsigned int>(materials.size(), 1));
|
||||
mesh->SetMaterialCount(std::max<UInt32>(materials.size(), 1));
|
||||
for (const auto& pair : materials)
|
||||
mesh->SetMaterialData(pair.second.first, pair.second.second);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,15 +81,14 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Création du mesh
|
||||
// Le moteur ne supporte plus les animations image-clé, nous ne pouvons charger qu'en statique
|
||||
if (!mesh->CreateStatic()) // Ne devrait jamais échouer
|
||||
// Since the engine no longer supports keyframe animations, let's make a static mesh
|
||||
if (!mesh->CreateStatic())
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des skins
|
||||
// Extract skins (texture name)
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
mesh->SetMaterialCount(header.num_skins);
|
||||
|
|
@ -109,16 +108,15 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, BufferUsage_Static);
|
||||
|
||||
/// Lecture des triangles
|
||||
// Extract triangles data
|
||||
std::vector<MD2_Triangle> triangles(header.num_tris);
|
||||
|
||||
stream.SetCursorPos(header.offset_tris);
|
||||
stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle));
|
||||
|
||||
// And convert them into an index buffer
|
||||
BufferMapper<IndexBuffer> indexMapper(indexBuffer, BufferAccess_DiscardAndWrite);
|
||||
UInt16* index = static_cast<UInt16*>(indexMapper.GetPointer());
|
||||
|
||||
|
|
@ -135,7 +133,7 @@ namespace Nz
|
|||
SwapBytes(&triangles[i].texCoords[2], sizeof(UInt16));
|
||||
#endif
|
||||
|
||||
// On respécifie le triangle dans l'ordre attendu
|
||||
// Reverse winding order
|
||||
*index++ = triangles[i].vertices[0];
|
||||
*index++ = triangles[i].vertices[2];
|
||||
*index++ = triangles[i].vertices[1];
|
||||
|
|
@ -143,10 +141,11 @@ namespace Nz
|
|||
|
||||
indexMapper.Unmap();
|
||||
|
||||
// Optimize if requested (improves cache locality)
|
||||
if (parameters.optimizeIndexBuffers)
|
||||
indexBuffer->Optimize();
|
||||
|
||||
/// Lecture des coordonnées de texture
|
||||
// Extracting texture coordinates
|
||||
std::vector<MD2_TexCoord> texCoords(header.num_st);
|
||||
|
||||
stream.SetCursorPos(header.offset_st);
|
||||
|
|
@ -168,15 +167,15 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des vertices
|
||||
// Extracting vertices
|
||||
stream.SetCursorPos(header.offset_frames);
|
||||
|
||||
std::unique_ptr<MD2_Vertex[]> vertices(new MD2_Vertex[header.num_vertices]);
|
||||
std::vector<MD2_Vertex> vertices(header.num_vertices);
|
||||
Vector3f scale, translate;
|
||||
stream.Read(scale, sizeof(Vector3f));
|
||||
stream.Read(translate, sizeof(Vector3f));
|
||||
stream.Read(nullptr, 16*sizeof(char)); // Nom de la frame, inutile ici
|
||||
stream.Read(vertices.get(), header.num_vertices*sizeof(MD2_Vertex));
|
||||
stream.Read(nullptr, 16*sizeof(char)); //< Frame name, unused
|
||||
stream.Read(vertices.data(), header.num_vertices*sizeof(MD2_Vertex));
|
||||
|
||||
#ifdef NAZARA_BIG_ENDIAN
|
||||
SwapBytes(&scale.x, sizeof(float));
|
||||
|
|
@ -196,23 +195,26 @@ namespace Nz
|
|||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
|
||||
/// Chargement des coordonnées de texture
|
||||
const unsigned int indexFix[3] = {0, 2, 1}; // Pour respécifier les indices dans le bon ordre
|
||||
// Loading texture coordinates
|
||||
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)
|
||||
{
|
||||
for (unsigned int j = 0; j < 3; ++j)
|
||||
{
|
||||
const unsigned int fixedIndex = indexFix[j];
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
float u = static_cast<float>(texC.u) / header.skinwidth;
|
||||
float v = static_cast<float>(texC.v) / header.skinheight;
|
||||
const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order
|
||||
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v);
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
Vector2f uv(texC.u, texC.v);
|
||||
uv *= invSkinSize;
|
||||
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des positions
|
||||
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
|
||||
// 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;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ namespace Nz
|
|||
}
|
||||
|
||||
vertices->position = finalPos;
|
||||
vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé
|
||||
vertices->uv.Set(parameters.texCoordOffset + vertex.uv * parameters.texCoordScale);
|
||||
vertices++;
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ namespace Nz
|
|||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage);
|
||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
||||
|
||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
MeshVertex* vertices = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
|
||||
{
|
||||
// Skinning MD5 (Formule d'Id Tech)
|
||||
|
|
@ -268,9 +268,9 @@ namespace Nz
|
|||
}
|
||||
|
||||
// On retourne le modèle dans le bon sens
|
||||
vertex->position = matrix * finalPos;
|
||||
vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé
|
||||
vertex++;
|
||||
vertices->position = matrix * finalPos;
|
||||
vertices->uv.Set(parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale);
|
||||
vertices++;
|
||||
}
|
||||
|
||||
vertexMapper.Unmap();
|
||||
|
|
|
|||
|
|
@ -265,8 +265,8 @@ namespace Nz
|
|||
|
||||
if (vertexIndices.texCoord > 0)
|
||||
{
|
||||
const Vector3f& uvw = texCoords[vertexIndices.texCoord-1];
|
||||
vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
|
||||
Vector2f uv = texCoords[vertexIndices.texCoord - 1];
|
||||
vertex.uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||
}
|
||||
else
|
||||
hasTexCoords = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue