diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 11c7ef3ca..7fba22b4a 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include NAZARA_API void NzComputeBoxIndexVertexCount(const NzVector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); @@ -20,12 +21,11 @@ NAZARA_API void NzComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, NAZARA_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); NAZARA_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount); -///TODO: Itérateur sur les indices -NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_API void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_API void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_API void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); inline void NzTransformVertex(NzMeshVertex* vertex, const NzMatrix4f& matrix); inline void NzTransformVertices(NzMeshVertex* vertices, unsigned int vertexCount, const NzMatrix4f& matrix); diff --git a/include/Nazara/Utility/IndexIterator.hpp b/include/Nazara/Utility/IndexIterator.hpp new file mode 100644 index 000000000..557782c12 --- /dev/null +++ b/include/Nazara/Utility/IndexIterator.hpp @@ -0,0 +1,79 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_INDEXITERATOR_HPP +#define NAZARA_INDEXITERATOR_HPP + +#include + +class NzIndexMapper; + +class NzIndexIterator +{ + friend NzIndexMapper; + + public: + class Reference; + + NzIndexIterator(); + NzIndexIterator(const NzIndexIterator& iterator); + ~NzIndexIterator() = default; + + Reference operator*() const; + + Reference operator[](unsigned int index) const; + + NzIndexIterator& operator=(const NzIndexIterator& iterator); + + NzIndexIterator operator+(unsigned int indexCount); + NzIndexIterator operator-(unsigned int indexCount); + + NzIndexIterator& operator+=(unsigned int indexCount); + NzIndexIterator& operator-=(unsigned int indexCount); + + NzIndexIterator& operator++(); + NzIndexIterator operator++(int); + + NzIndexIterator& operator--(); + NzIndexIterator operator--(int); + + friend bool operator==(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + friend bool operator!=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + friend bool operator<(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + friend bool operator<=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + friend bool operator>(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + friend bool operator>=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + + private: + NzIndexIterator(NzIndexMapper* mapper, unsigned int index); + + NzIndexMapper* m_mapper; + unsigned int m_index; +}; + +class NzIndexIterator::Reference +{ + friend NzIndexIterator; + + public: + Reference(const Reference& reference) = default; + ~Reference() = default; + + Reference& operator=(nzUInt32 value); + Reference& operator=(const Reference& reference); + + operator nzUInt32() const; + + private: + Reference(NzIndexMapper* mapper, unsigned int index); + + NzIndexMapper* m_mapper; + unsigned int m_index; +}; + +#include + +#endif // NAZARA_INDEXITERATOR_HPP diff --git a/include/Nazara/Utility/IndexIterator.inl b/include/Nazara/Utility/IndexIterator.inl new file mode 100644 index 000000000..3be73858a --- /dev/null +++ b/include/Nazara/Utility/IndexIterator.inl @@ -0,0 +1,158 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +inline NzIndexIterator::NzIndexIterator() : +m_mapper(nullptr), +m_index(0) +{ +} + +inline NzIndexIterator::NzIndexIterator(const NzIndexIterator& iterator) : +m_mapper(iterator.m_mapper), +m_index(iterator.m_index) +{ +} + +inline NzIndexIterator::NzIndexIterator(NzIndexMapper* mapper, unsigned int index) : +m_mapper(mapper), +m_index(index) +{ +} + +inline NzIndexIterator::Reference NzIndexIterator::operator*() const +{ + return Reference(m_mapper, m_index); +} + +inline NzIndexIterator::Reference NzIndexIterator::operator[](unsigned int index) const +{ + return Reference(m_mapper, m_index+index); +} + +inline NzIndexIterator& NzIndexIterator::operator=(const NzIndexIterator& iterator) +{ + m_mapper = iterator.m_mapper; + m_index = iterator.m_index; + + return *this; +} + +inline NzIndexIterator NzIndexIterator::operator+(unsigned int indexCount) +{ + return NzIndexIterator(m_mapper, m_index + indexCount); +} + +inline NzIndexIterator NzIndexIterator::operator-(unsigned int indexCount) +{ + return NzIndexIterator(m_mapper, m_index - indexCount); +} + +inline NzIndexIterator& NzIndexIterator::operator+=(unsigned int indexCount) +{ + m_index += indexCount; + + return *this; +} + +inline NzIndexIterator& NzIndexIterator::operator-=(unsigned int indexCount) +{ + m_index += indexCount; + + return *this; +} + +inline NzIndexIterator& NzIndexIterator::operator++() +{ + m_index++; + + return *this; +} + +inline NzIndexIterator NzIndexIterator::operator++(int) +{ + NzIndexIterator iterator(*this); + operator++(); + + return iterator; +} + +inline NzIndexIterator& NzIndexIterator::operator--() +{ + m_index--; + + return *this; +} + +inline NzIndexIterator NzIndexIterator::operator--(int) +{ + NzIndexIterator iterator(*this); + operator--(); + + return iterator; +} + +inline bool operator==(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + return lhs.m_mapper == rhs.m_mapper && lhs.m_index == rhs.m_index; +} + +inline bool operator!=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + return !operator==(lhs, rhs); +} + +inline bool operator<(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + if (lhs.m_mapper == rhs.m_mapper) + return lhs.m_index < rhs.m_index; + else + return lhs.m_mapper < rhs.m_mapper; +} + +inline bool operator<=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + return !operator<(rhs, lhs); +} + +inline bool operator>(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + return operator<(rhs, lhs); +} + +inline bool operator>=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) +{ + return !operator<(lhs, rhs); +} + +/**************************NzIndexIterator::Reference*************************/ + +inline NzIndexIterator::Reference::Reference(NzIndexMapper* mapper, unsigned int index) : +m_mapper(mapper), +m_index(index) +{ +} + +inline NzIndexIterator::Reference& NzIndexIterator::Reference::operator=(nzUInt32 value) +{ + m_mapper->Set(m_index, value); + + return *this; +} + +inline NzIndexIterator::Reference& NzIndexIterator::Reference::operator=(const NzIndexIterator::Reference& reference) +{ + m_mapper->Set(m_index, reference); // Conversion implicite en UInt32 + + return *this; +} + +inline NzIndexIterator::Reference::operator nzUInt32() const +{ + return m_mapper->Get(m_index); +} + +#include diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index 1adceee43..d831e1566 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -11,6 +11,7 @@ #include class NzIndexBuffer; +class NzIndexIterator; class NzSubMesh; using NzIndexMapperGetter = nzUInt32 (*)(const void* buffer, unsigned int i); @@ -26,15 +27,24 @@ class NAZARA_API NzIndexMapper nzUInt32 Get(unsigned int i) const; const NzIndexBuffer* GetBuffer() const; + unsigned int GetIndexCount() const; void Set(unsigned int i, nzUInt32 value); void Unmap(); + // Méthodes STD + NzIndexIterator begin(); + //NzIndexConstIterator begin() const; + NzIndexIterator end(); + //NzIndexIterator end() const; + // Méthodes STD + private: NzBufferMapper m_mapper; NzIndexMapperGetter m_getter; NzIndexMapperSetter m_setter; + unsigned int m_indexCount; }; #endif // NAZARA_INDEXMAPPER_HPP diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index 7c97ae20f..3cd43fa75 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -17,7 +17,7 @@ namespace { } - void Generate(float size, unsigned int recursionLevel, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) + void Generate(float size, unsigned int recursionLevel, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { // Grandement inspiré de http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html const float t = (1.f + 2.236067f)/2.f; @@ -202,7 +202,7 @@ void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int sta *vertexCount = sliceCount * stackCount; } -void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { unsigned int xIndexCount, yIndexCount, zIndexCount; unsigned int xVertexCount, yVertexCount, zVertexCount; @@ -258,7 +258,7 @@ void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, co } } -void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { unsigned int vertexCount; NzComputeBoxIndexVertexCount(NzVector3ui(subdivision), nullptr, &vertexCount); @@ -281,13 +281,13 @@ void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4 } } -void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { IcoSphereBuilder builder(matrix); builder.Generate(size, recursionLevel, vertices, indices, aabb, indexOffset); } -void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { // Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...) unsigned int horizontalFaceCount = (1 << subdivision.x); @@ -344,7 +344,7 @@ void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, aabb->Set(rotation * NzVector3f(-halfSizeX, 0.f, -halfSizeY), rotation * NzVector3f(halfSizeX, 0.f, halfSizeY)); } -void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, NzMeshVertex* vertices, nzUInt32* indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { // http://stackoverflow.com/questions/14080932/implementing-opengl-sphere-example-code float invSliceCount = 1.f / (sliceCount-1); diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index 402810d55..942feff76 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -101,6 +102,14 @@ NzIndexMapper(subMesh->GetIndexBuffer()) nzUInt32 NzIndexMapper::Get(unsigned int i) const { + #if NAZARA_UTILITY_SAFE + if (i >= m_indexCount) + { + NazaraError("Index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_indexCount) + ')'); + return 0; + } + #endif + return m_getter(m_mapper.GetPointer(), i); } @@ -109,8 +118,21 @@ const NzIndexBuffer* NzIndexMapper::GetBuffer() const return m_mapper.GetBuffer(); } +unsigned int NzIndexMapper::GetIndexCount() const +{ + return m_indexCount; +} + void NzIndexMapper::Set(unsigned int i, nzUInt32 value) { + #if NAZARA_UTILITY_SAFE + if (i >= m_indexCount) + { + NazaraError("Index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_indexCount) + ')'); + return; + } + #endif + m_setter(m_mapper.GetPointer(), i, value); } @@ -118,3 +140,13 @@ void NzIndexMapper::Unmap() { m_mapper.Unmap(); } + +NzIndexIterator NzIndexMapper::begin() +{ + return NzIndexIterator(this, 0); +} + +NzIndexIterator NzIndexMapper::end() +{ + return NzIndexIterator(this, m_indexCount); // Post-end +} diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index cce70e0e8..a68fea8c1 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -188,20 +188,10 @@ void NzMesh::Build(const NzPrimitiveList& list, const NzMeshParams& params) vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); - ///TODO: Remplacer par un itérateur sur les indices - std::vector indices; - indices.resize(indexCount); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, primitive.box.matrix, static_cast(vertexMapper.GetPointer()), &indices[0], &aabb); - vertexMapper.Unmap(); - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - for (unsigned int i = 0; i < indexCount; ++i) - indexMapper.Set(i, indices[i]); - - indexMapper.Unmap(); + NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, primitive.box.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -217,20 +207,10 @@ void NzMesh::Build(const NzPrimitiveList& list, const NzMeshParams& params) vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); - ///TODO: Remplacer par un itérateur sur les indices - std::vector indices; - indices.resize(indexCount); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzGeneratePlane(primitive.plane.subdivision, primitive.plane.position, primitive.plane.normal, primitive.plane.size, static_cast(vertexMapper.GetPointer()), &indices[0], &aabb); - vertexMapper.Unmap(); - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - for (unsigned int i = 0; i < indexCount; ++i) - indexMapper.Set(i, indices[i]); - - indexMapper.Unmap(); + NzGeneratePlane(primitive.plane.subdivision, primitive.plane.position, primitive.plane.normal, primitive.plane.size, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -250,20 +230,10 @@ void NzMesh::Build(const NzPrimitiveList& list, const NzMeshParams& params) vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); - ///TODO: Remplacer par un itérateur sur les indices - std::vector indices; - indices.resize(indexCount); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), &indices[0], &aabb); - vertexMapper.Unmap(); - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - for (unsigned int i = 0; i < indexCount; ++i) - indexMapper.Set(i, indices[i]); - - indexMapper.Unmap(); + NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -279,20 +249,10 @@ void NzMesh::Build(const NzPrimitiveList& list, const NzMeshParams& params) vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); - ///TODO: Remplacer par un itérateur sur les indices - std::vector indices; - indices.resize(indexCount); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), &indices[0], &aabb); - vertexMapper.Unmap(); - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - for (unsigned int i = 0; i < indexCount; ++i) - indexMapper.Set(i, indices[i]); - - indexMapper.Unmap(); + NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -308,20 +268,11 @@ void NzMesh::Build(const NzPrimitiveList& list, const NzMeshParams& params) vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); - ///TODO: Remplacer par un itérateur sur les indices - std::vector indices; - indices.resize(indexCount); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.slices, primitive.sphere.uv.stacks, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), &indices[0], &aabb); - vertexMapper.Unmap(); - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - for (unsigned int i = 0; i < indexCount; ++i) - indexMapper.Set(i, indices[i]); - - indexMapper.Unmap(); + NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.slices, primitive.sphere.uv.stacks, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + break; } } break;