From 880c2aa32c85bc0b3d4078501027ba2d320703ed Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 18 Jun 2013 16:39:46 +0200 Subject: [PATCH] Plane primitives no longer rely on normal vector Former-commit-id: 66e1e2a83799055ad773f7b145e569469f68279a --- include/Nazara/Core/Primitive.hpp | 5 +-- include/Nazara/Core/PrimitiveList.hpp | 5 +-- include/Nazara/Utility/Algorithm.hpp | 2 +- src/Nazara/Core/PrimitiveList.cpp | 23 ++++++++------ src/Nazara/Utility/Algorithm.cpp | 45 +++++++++++++++------------ src/Nazara/Utility/Mesh.cpp | 13 +++++--- 6 files changed, 51 insertions(+), 42 deletions(-) diff --git a/include/Nazara/Core/Primitive.hpp b/include/Nazara/Core/Primitive.hpp index 9bc3d7bac..06a04e7d8 100644 --- a/include/Nazara/Core/Primitive.hpp +++ b/include/Nazara/Core/Primitive.hpp @@ -15,13 +15,13 @@ struct NzPrimitive { + NzMatrix4f matrix; nzPrimitiveType type; union { struct { - NzMatrix4f matrix; NzVector3f lengths; NzVector3ui subdivision; } @@ -31,15 +31,12 @@ struct NzPrimitive { NzVector2f size; NzVector2ui subdivision; - NzVector3f normal; - NzVector3f position; } plane; struct { nzSphereType type; - NzMatrix4f matrix; float size; union diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index feb026a32..3feeb1b51 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -23,8 +23,9 @@ class NAZARA_API NzPrimitiveList 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& matrix = NzMatrix4f::Identity()); void AddIcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddPlane(const NzPlanef& plane, const NzVector2f& size, const NzVector2ui& subdivision = NzVector2ui(0U)); - void AddPlane(const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, const NzVector2ui& subdivision = NzVector2ui(0U)); + void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& matrix = NzMatrix4f::Identity()); + void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& plane); + void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); void AddUVSphere(float size, unsigned int slices = 4, unsigned int stacks = 4, const NzMatrix4f& matrix = NzMatrix4f::Identity()); void AddUVSphere(float size, unsigned int slices, unsigned int stacks, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 01e6f2960..bab7732b9 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -26,7 +26,7 @@ template NzBoxf NzComputeVerticesAABB(const T* vertices, unsigned in 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 NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, 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); NAZARA_API void NzOptimizeIndices(NzIndexIterator indices, unsigned int indexCount); diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 65da5775c..446ed026c 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -9,9 +9,9 @@ void NzPrimitiveList::AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix) { NzPrimitive primitive; + primitive.matrix = matrix; primitive.type = nzPrimitiveType_Box; primitive.box.lengths = lengths; - primitive.box.matrix = matrix; primitive.box.subdivision = subdivision; m_primitives.push_back(primitive); @@ -25,8 +25,8 @@ void NzPrimitiveList::AddBox(const NzVector3f& lengths, const NzVector3ui& subdi void NzPrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix) { NzPrimitive primitive; + primitive.matrix = matrix; primitive.type = nzPrimitiveType_Sphere; - primitive.sphere.matrix = matrix; primitive.sphere.size = size; primitive.sphere.type = nzSphereType_Cubic; primitive.sphere.cubic.subdivision = subdivision; @@ -42,8 +42,8 @@ void NzPrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const void NzPrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix) { NzPrimitive primitive; + primitive.matrix = matrix; primitive.type = nzPrimitiveType_Sphere; - primitive.sphere.matrix = matrix; primitive.sphere.size = size; primitive.sphere.type = nzSphereType_Ico; primitive.sphere.ico.recursionLevel = recursionLevel; @@ -56,35 +56,38 @@ void NzPrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, cons AddIcoSphere(size, recursionLevel, NzMatrix4f::Transform(position, rotation)); } -void NzPrimitiveList::AddPlane(const NzPlanef& plane, const NzVector2f& size, const NzVector2ui& subdivision) +void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& matrix) { NzPrimitive primitive; + primitive.matrix = matrix; primitive.type = nzPrimitiveType_Plane; - primitive.plane.normal = plane.normal; - primitive.plane.position = plane.distance * plane.normal; primitive.plane.size = size; primitive.plane.subdivision = subdivision; m_primitives.push_back(primitive); } -void NzPrimitiveList::AddPlane(const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, const NzVector2ui& subdivision) +void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& plane) { NzPrimitive primitive; + primitive.matrix = NzMatrix4f::Transform(plane.distance * plane.normal, NzQuaternionf::RotationBetween(NzVector3f::Up(), plane.normal)); primitive.type = nzPrimitiveType_Plane; - primitive.plane.normal = normal; - primitive.plane.position = position; primitive.plane.size = size; primitive.plane.subdivision = subdivision; m_primitives.push_back(primitive); } +void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation) +{ + AddPlane(size, subdivision, NzMatrix4f::Transform(position, rotation)); +} + void NzPrimitiveList::AddUVSphere(float size, unsigned int slices, unsigned int stacks, const NzMatrix4f& matrix) { NzPrimitive primitive; + primitive.matrix = matrix; primitive.type = nzPrimitiveType_Sphere; - primitive.sphere.matrix = matrix; primitive.sphere.size = size; primitive.sphere.type = nzSphereType_UV; primitive.sphere.uv.slices = slices; diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index 131449292..53f9c57f5 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -718,39 +718,47 @@ void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, co NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.x, subdivision.y), &zIndexCount, &zVertexCount); NzMeshVertex* oldVertices = vertices; + NzMatrix4f transform; + NzVector3f halfLengths = lengths/2.f; // Face +X - NzGeneratePlane(NzVector2ui(subdivision.y, subdivision.z), NzVector3f::UnitX() * lengths.x/2.f, NzVector3f::UnitX(), NzVector2f(lengths.y, lengths.z), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(NzVector3f::UnitX() * halfLengths.x, NzEulerAnglesf(-90.f, 0.f, -90.f)); + NzGeneratePlane(NzVector2ui(subdivision.y, subdivision.z), NzVector2f(lengths.y, lengths.z), transform, vertices, indices, nullptr, indexOffset); indexOffset += xVertexCount; indices += xIndexCount; vertices += xVertexCount; // Face +Y - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), NzVector3f::UnitY() * lengths.y/2.f, NzVector3f::UnitY(), NzVector2f(lengths.x, lengths.z), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(NzVector3f::UnitY() * halfLengths.y, NzEulerAnglesf(0.f, 0.f, 0.f)); + NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), NzVector2f(lengths.x, lengths.z), transform, vertices, indices, nullptr, indexOffset); indexOffset += yVertexCount; indices += yIndexCount; vertices += yVertexCount; // Face +Z - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), NzVector3f::UnitZ() * lengths.z/2.f, NzVector3f::UnitZ(), NzVector2f(lengths.x, lengths.y), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(NzVector3f::UnitZ() * halfLengths.z, NzEulerAnglesf(-90.f, 90.f, 90.f)); + NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), NzVector2f(lengths.x, lengths.y), transform, vertices, indices, nullptr, indexOffset); indexOffset += zVertexCount; indices += zIndexCount; vertices += zVertexCount; // Face -X - NzGeneratePlane(NzVector2ui(subdivision.y, subdivision.z), -NzVector3f::UnitX() * lengths.x/2.f, -NzVector3f::UnitX(), NzVector2f(lengths.y, lengths.z), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(-NzVector3f::UnitX() * halfLengths.x, NzEulerAnglesf(-90.f, 0.f, 90.f)); + NzGeneratePlane(NzVector2ui(subdivision.y, subdivision.z), NzVector2f(lengths.y, lengths.z), transform, vertices, indices, nullptr, indexOffset); indexOffset += xVertexCount; indices += xIndexCount; vertices += xVertexCount; // Face -Y - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), -NzVector3f::UnitY() * lengths.y/2.f, -NzVector3f::UnitY(), NzVector2f(lengths.x, lengths.z), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(-NzVector3f::UnitY() * halfLengths.y, NzEulerAnglesf(0.f, 0.f, 180.f)); + NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), NzVector2f(lengths.x, lengths.z), transform, vertices, indices, nullptr, indexOffset); indexOffset += yVertexCount; indices += yIndexCount; vertices += yVertexCount; // Face -Z - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), -NzVector3f::UnitZ() * lengths.z/2.f, -NzVector3f::UnitZ(), NzVector2f(lengths.x, lengths.y), vertices, indices, nullptr, indexOffset); + transform.MakeTransform(-NzVector3f::UnitZ() * halfLengths.z, NzEulerAnglesf(-90.f, -90.f, 90.f)); + NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), NzVector2f(lengths.x, lengths.y), transform, vertices, indices, nullptr, indexOffset); indexOffset += zVertexCount; indices += zIndexCount; vertices += zVertexCount; @@ -759,7 +767,7 @@ void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, co if (aabb) { - aabb->Set(lengths); + aabb->Set(-halfLengths, halfLengths); aabb->Transform(matrix, 0.f); } } @@ -793,8 +801,11 @@ void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix builder.Generate(size, recursionLevel, vertices, indices, aabb, indexOffset); } -void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, const NzVector3f& normal, const NzVector2f& size, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) +void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) { + // Pour plus de facilité, on va construire notre plan en considérant que la normale est de 0,1,0 + // Et appliquer ensuite une matrice "finissant le travail" + // 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); unsigned int verticalFaceCount = (1 << subdivision.y); @@ -803,18 +814,12 @@ void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, unsigned int horizontalVertexCount = horizontalFaceCount + 1; unsigned int verticalVertexCount = verticalFaceCount + 1; - // Pour plus de facilité, on va construire notre plan en considérant que la normale est de 0,1,0 - // et on va construire un quaternion représentant la rotation de cette normale à la normale demandée par l'utilisateur. - // Celui-ci, combiné avec la position, va former une transformation qu'il suffira d'appliquer aux sommets - NzQuaternionf rotation; - rotation.MakeRotationBetween(NzVector3f::UnitY(), normal); + NzVector3f normal(NzVector3f::UnitY()); + normal = matrix.Transform(normal, 0.f); + normal.Normalize(); - NzMatrix4f transform; - transform.MakeTransform(position, rotation); - - ///FIXME: Vérifier les tangentes NzVector3f tangent(1.f, 1.f, 0.f); - tangent = rotation * tangent; + tangent = matrix.Transform(tangent, 0.f); tangent.Normalize(); float halfSizeX = size.x / 2.f; @@ -827,7 +832,7 @@ void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, for (unsigned int y = 0; y < verticalVertexCount; ++y) { NzVector3f localPos((2.f*x*invHorizontalVertexCount - 1.f) * halfSizeX, 0.f, (2.f*y*invVerticalVertexCount - 1.f) * halfSizeY); - vertices->position = transform * localPos; + vertices->position = matrix * localPos; vertices->uv.Set(x*invHorizontalVertexCount, y*invVerticalVertexCount); vertices->normal = normal; vertices->tangent = tangent; @@ -847,7 +852,7 @@ void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector3f& position, } if (aabb) - aabb->Set(rotation * NzVector3f(-halfSizeX, 0.f, -halfSizeY), rotation * NzVector3f(halfSizeX, 0.f, halfSizeY)); + aabb->Set(matrix.Transform(NzVector3f(-halfSizeX, 0.f, -halfSizeY), 0.f), matrix.Transform(NzVector3f(halfSizeX, 0.f, halfSizeY), 0.f)); } void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index ce412f202..4d54ec2c1 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -166,6 +166,9 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para std::unique_ptr indexBuffer; std::unique_ptr vertexBuffer; + NzMatrix4f matrix(primitive.matrix); + matrix.ApplyScale(params.scale); + switch (primitive.type) { case nzPrimitiveType_Box: @@ -183,7 +186,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, primitive.box.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -202,7 +205,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - NzGeneratePlane(primitive.plane.subdivision, primitive.plane.position, primitive.plane.normal, primitive.plane.size, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + NzGeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -225,7 +228,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -244,7 +247,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } @@ -263,7 +266,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.slices, primitive.sphere.uv.stacks, primitive.sphere.matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); + NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.slices, primitive.sphere.uv.stacks, matrix, static_cast(vertexMapper.GetPointer()), indexMapper.begin(), &aabb); break; } }