diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index e1bf1f502..7c3291de8 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -69,6 +69,7 @@ enum nzPlugin enum nzPrimitiveType { nzPrimitiveType_Box, + nzPrimitiveType_Cone, nzPrimitiveType_Plane, nzPrimitiveType_Sphere, diff --git a/include/Nazara/Core/Primitive.hpp b/include/Nazara/Core/Primitive.hpp index b67b9026a..c7a47279b 100644 --- a/include/Nazara/Core/Primitive.hpp +++ b/include/Nazara/Core/Primitive.hpp @@ -18,6 +18,8 @@ struct NzPrimitive { void MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); void MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); + void MakeCone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); + void MakeCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); void MakeCubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); void MakeCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); void MakeIcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); @@ -30,6 +32,8 @@ struct NzPrimitive static NzPrimitive Box(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); static NzPrimitive Box(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); + static NzPrimitive Cone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); + static NzPrimitive Cone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); static NzPrimitive CubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); static NzPrimitive CubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); static NzPrimitive IcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); @@ -53,6 +57,14 @@ struct NzPrimitive } box; + struct + { + float length; + float radius; + unsigned int subdivision; + } + cone; + struct { NzVector2f size; diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index 19b729f43..e4757741a 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -18,6 +18,21 @@ inline void NzPrimitive::MakeBox(const NzVector3f& lengths, const NzVector3ui& s MakeBox(lengths, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); } +inline void NzPrimitive::MakeCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) +{ + matrix = transformMatrix; + textureCoords = uvCoords; + type = nzPrimitiveType_Cone; + cone.length = length; + cone.radius = radius; + cone.subdivision = subdivision; +} + +inline void NzPrimitive::MakeCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) +{ + MakeCone(length, radius, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); +} + inline void NzPrimitive::MakeCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) { matrix = transformMatrix; @@ -99,6 +114,22 @@ inline NzPrimitive NzPrimitive::Box(const NzVector3f& lengths, const NzVector3ui return primitive; } +inline NzPrimitive NzPrimitive::Cone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) +{ + NzPrimitive primitive; + primitive.MakeCone(length, radius, subdivision, transformMatrix, uvCoords); + + return primitive; +} + +inline NzPrimitive NzPrimitive::Cone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) +{ + NzPrimitive primitive; + primitive.MakeCone(length, radius, subdivision, position, rotation, uvCoords); + + return primitive; +} + inline NzPrimitive NzPrimitive::CubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) { NzPrimitive primitive; diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index 1f24681fc..deb1ee612 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -19,6 +19,8 @@ class NAZARA_API NzPrimitiveList void AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); void AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + void AddCone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); + void AddCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); void AddCubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); void AddCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); void AddIcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index a9e8c8a92..0757c028d 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -17,6 +17,7 @@ NAZARA_API void NzComputeBoxIndexVertexCount(const NzVector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); NAZARA_API unsigned int NzComputeCacheMissCount(NzIndexIterator indices, unsigned int indexCount); +NAZARA_API void NzComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); NAZARA_API void NzComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); NAZARA_API void NzComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, unsigned int* indexCount, unsigned int* vertexCount); NAZARA_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); @@ -24,6 +25,7 @@ NAZARA_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsig template NzBoxf NzComputeVerticesAABB(const T* vertices, unsigned int vertexCount); NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); +NAZARA_API void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 1c1ba1743..a457c324d 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -16,6 +16,16 @@ void NzPrimitiveList::AddBox(const NzVector3f& lengths, const NzVector3ui& subdi m_primitives.push_back(NzPrimitive::Box(lengths, subdivision, position, rotation)); } +void NzPrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix) +{ + m_primitives.push_back(NzPrimitive::Cone(length, radius, subdivision, transformMatrix)); +} + +void NzPrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation) +{ + m_primitives.push_back(NzPrimitive::Cone(length, radius, subdivision, position, rotation)); +} + void NzPrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix) { m_primitives.push_back(NzPrimitive::CubicSphere(size, subdivision, transformMatrix)); diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index b11149d31..de24d7609 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -659,6 +659,15 @@ unsigned int NzComputeCacheMissCount(NzIndexIterator indices, unsigned int index return cache.GetMissCount(); } +void NzComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) +{ + if (indexCount) + *indexCount = (subdivision-1)*6; + + if (vertexCount) + *vertexCount = subdivision + 2; +} + void NzComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) { // Comme tous nos plans sont identiques, on peut optimiser un peu @@ -768,7 +777,53 @@ void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, co if (aabb) { aabb->Set(-halfLengths, halfLengths); - aabb->Transform(matrix, 0.f); + aabb->Transform(matrix, false); + } +} + +void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) +{ + const float round = 2.f*static_cast(M_PI); + float delta = round/subdivision; + + vertices->position = matrix.GetTranslation(); // matrix.Transform(NzVector3f(0.f)); + vertices->normal = matrix.Transform(NzVector3f::Up(), 0.f); + vertices++; + + for (unsigned int i = 0; i < subdivision; ++i) + { + float angle = delta*i; + vertices->position = matrix.Transform(NzVector3f(radius*std::sin(angle), -length, radius*std::cos(angle))); + vertices++; + + *indices++ = indexOffset + 0; + *indices++ = indexOffset + i+1; + *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); + + if (i != 0 && i != subdivision-1) + { + *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); + *indices++ = indexOffset + i+1; + *indices++ = indexOffset + 1; + } + } + + if (aabb) + { + aabb->MakeZero(); + + // On calcule le reste des points + NzVector3f base(NzVector3f::Down()*length); + + NzVector3f lExtend = NzVector3f::Left()*radius; + NzVector3f fExtend = NzVector3f::Forward()*radius; + + // Et on ajoute ensuite les quatres extrémités de la pyramide + aabb->ExtendTo(base + lExtend + fExtend); + aabb->ExtendTo(base + lExtend - fExtend); + aabb->ExtendTo(base - lExtend + fExtend); + aabb->ExtendTo(base - lExtend - fExtend); + aabb->Transform(matrix, false); } } @@ -788,8 +843,8 @@ void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4 for (unsigned int i = 0; i < vertexCount; ++i) { + vertices->position = matrix.Transform(size * vertices->position.GetNormal()); vertices->normal = vertices->position.GetNormal(); - vertices->position = matrix.Transform(size * vertices->normal); //vertices->tangent = ??? vertices++; } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 70954abe3..f862166f4 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -195,6 +195,25 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams break; } + case nzPrimitiveType_Cone: + { + unsigned int indexCount; + unsigned int vertexCount; + NzComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); + + indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static)); + indexBuffer->SetPersistent(false); + + vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static)); + vertexBuffer->SetPersistent(false); + + NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); + NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); + + NzGenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + break; + } + case nzPrimitiveType_Plane: { unsigned int indexCount;