From a1a1a3da0c1ce8f043d373c2a54aa710066b04e0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 27 Nov 2012 21:45:00 +0100 Subject: [PATCH] Replaced mesh material system Former-commit-id: 1a3f2e0a80211a17838f29e5c0b0fc9def89d30a --- include/Nazara/Utility/Mesh.hpp | 5 +- src/Nazara/Utility/Loaders/MD2/Loader.cpp | 3 +- src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp | 43 +++---- src/Nazara/Utility/Mesh.cpp | 116 +++++++----------- 4 files changed, 62 insertions(+), 105 deletions(-) diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 7134ff1a6..5832d848c 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -46,7 +46,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener NzMesh() = default; ~NzMesh(); - bool AddMaterial(const NzString& matPath, unsigned int* matIndex = nullptr); bool AddSubMesh(NzSubMesh* subMesh); bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh); @@ -75,7 +74,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener unsigned int GetVertexCount() const; bool HasAnimation() const; - bool HasMaterial(unsigned int index) const; bool HasSubMesh(const NzString& identifier) const; bool HasSubMesh(unsigned int index = 0) const; @@ -88,11 +86,12 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams()); bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams()); - void RemoveMaterial(unsigned int index); void RemoveSubMesh(const NzString& identifier); void RemoveSubMesh(unsigned int index); bool SetAnimation(const NzAnimation* animation); + void SetMaterial(unsigned int matIndex, const NzString& materialPath); + void SetMaterialCount(unsigned int matCount); void Skin(const NzSkeleton* skeleton) const; diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index a6f246d39..fca60d4b0 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -87,6 +87,7 @@ namespace /// Chargement des skins if (header.num_skins > 0) { + mesh->SetMaterialCount(header.num_skins); stream.SetCursorPos(header.offset_skins); { NzString baseDir = stream.GetDirectory(); @@ -94,7 +95,7 @@ namespace for (unsigned int i = 0; i < header.num_skins; ++i) { stream.Read(skin, 68*sizeof(char)); - mesh->AddMaterial(baseDir + skin); + mesh->SetMaterial(i, baseDir + skin); } } } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index e6c8e3f41..b8afa6fe2 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -175,8 +175,11 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) joint->SetInverseBindMatrix(bindMatrix.InverseAffine()); } - for (const Mesh& md5Mesh : m_meshes) + mesh->SetMaterialCount(m_meshes.size()); + for (unsigned int i = 0; i < m_meshes.size(); ++i) { + const Mesh& md5Mesh = m_meshes[i]; + void* ptr; unsigned int indexCount = md5Mesh.triangles.size()*3; unsigned int vertexCount = md5Mesh.vertices.size(); @@ -270,10 +273,10 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) vertexBuffer.release(); NzWeight* weights = subMesh->GetWeight(); - for (unsigned int i = 0; i < weightCount; ++i) + for (unsigned int j = 0; j < weightCount; ++j) { - weights->jointIndex = md5Mesh.weights[i].joint; - weights->weight = md5Mesh.weights[i].bias; + weights->jointIndex = md5Mesh.weights[j].joint; + weights->weight = md5Mesh.weights[j].bias; weights++; } @@ -301,14 +304,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) } // Material - if (!md5Mesh.shader.IsEmpty()) - { - unsigned int skinIndex; - if (mesh->AddMaterial(baseDir + md5Mesh.shader, &skinIndex)) - subMesh->SetMaterialIndex(skinIndex); - else - NazaraWarning("Failed to add mesh shader"); - } + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + subMesh->SetMaterialIndex(i); if (!mesh->AddSubMesh(subMesh.get())) { @@ -320,14 +317,13 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) // Animation // Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle. - NzString animationPath = m_stream.GetPath(); - if (!animationPath.IsEmpty()) + if (!baseDir.IsEmpty()) { - animationPath.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive); - if (NzFile::Exists(animationPath)) + baseDir.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive); + if (NzFile::Exists(baseDir)) { std::unique_ptr animation(new NzAnimation); - if (animation->LoadFromFile(animationPath) && mesh->SetAnimation(animation.get())) + if (animation->LoadFromFile(baseDir) && mesh->SetAnimation(animation.get())) animation.release(); else NazaraWarning("Failed to load mesh's animation"); @@ -343,8 +339,9 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) return false; } - for (const Mesh& md5Mesh : m_meshes) + for (unsigned int i = 0; i < m_meshes.size(); ++i) { + const Mesh& md5Mesh = m_meshes[i]; void* ptr; unsigned int indexCount = md5Mesh.triangles.size()*3; unsigned int vertexCount = md5Mesh.vertices.size(); @@ -479,14 +476,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) indexBuffer.release(); // Material - if (!md5Mesh.shader.IsEmpty()) - { - unsigned int skinIndex; - if (mesh->AddMaterial(baseDir + md5Mesh.shader, &skinIndex)) - subMesh->SetMaterialIndex(skinIndex); - else - NazaraWarning("Failed to add mesh shader"); - } + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + subMesh->SetMaterialIndex(i); if (!mesh->AddSubMesh(subMesh.get())) { diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index daa0ac94d..d62f83105 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -55,45 +55,6 @@ NzMesh::~NzMesh() Destroy(); } -bool NzMesh::AddMaterial(const NzString& matPath, unsigned int* matIndex) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - - if (matPath.IsEmpty()) - { - NazaraError("Material path is empty"); - return false; - } - #endif - - NzString path = NzFile::NormalizeSeparators(matPath); - - for (unsigned int i = 0; i < m_impl->materials.size(); ++i) - { - if (m_impl->materials[i] == path) // Ce skin est-il déjà présent ? - { - if (matIndex) - *matIndex = i; - - return true; - } - } - - // Sinon on l'ajoute - - if (matIndex) - *matIndex = m_impl->materials.size(); - - m_impl->materials.push_back(matPath); - - return true; -} - bool NzMesh::AddSubMesh(NzSubMesh* subMesh) { #if NAZARA_UTILITY_SAFE @@ -609,19 +570,6 @@ bool NzMesh::HasAnimation() const return m_impl->animation != nullptr; } -bool NzMesh::HasMaterial(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif - - return index < m_impl->materials.size(); -} - bool NzMesh::HasSubMesh(const NzString& identifier) const { #if NAZARA_UTILITY_SAFE @@ -681,29 +629,6 @@ bool NzMesh::LoadFromStream(NzInputStream& stream, const NzMeshParams& params) return NzMeshLoader::LoadFromStream(this, stream, params); } -void NzMesh::RemoveMaterial(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (index >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->materials.size()) + ')'); - return; - } - #endif - - // On accède à l'itérateur correspondant à l'entrée #index - auto it = m_impl->materials.begin(); - std::advance(it, index); - - m_impl->materials.erase(it); -} - void NzMesh::RemoveSubMesh(const NzString& identifier) { #if NAZARA_UTILITY_SAFE @@ -805,6 +730,47 @@ bool NzMesh::SetAnimation(const NzAnimation* animation) return true; } +void NzMesh::SetMaterial(unsigned int matIndex, const NzString& materialPath) +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (matIndex >= m_impl->materials.size()) + { + NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_impl->materials.size())); + return; + } + #endif + + m_impl->materials[matIndex] = materialPath; +} + +void NzMesh::SetMaterialCount(unsigned int matCount) +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + m_impl->materials.resize(matCount); + + #ifdef NAZARA_DEBUG + for (NzSubMesh* subMesh : m_impl->subMeshes) + { + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= matCount) + NazaraWarning("SubMesh " + NzString::Pointer(subMesh) + " material index is over mesh new material count (" + NzString::Number(matIndex) + " >= " + NzString::Number(matCount)); + } + #endif +} + void NzMesh::Skin(const NzSkeleton* skeleton) const { #if NAZARA_UTILITY_SAFE