Plane primitives no longer rely on normal vector

Former-commit-id: 66e1e2a83799055ad773f7b145e569469f68279a
This commit is contained in:
Lynix 2013-06-18 16:39:46 +02:00
parent 433c36f176
commit 880c2aa32c
6 changed files with 51 additions and 42 deletions

View File

@ -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

View File

@ -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());

View File

@ -26,7 +26,7 @@ template<typename T> 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);

View File

@ -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;

View File

@ -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)

View File

@ -166,6 +166,9 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
std::unique_ptr<NzIndexBuffer> indexBuffer;
std::unique_ptr<NzVertexBuffer> 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<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);
NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, primitive.box.matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
break;
}
@ -202,7 +205,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
NzBufferMapper<NzVertexBuffer> 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<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
NzGeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
break;
}
@ -225,7 +228,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);
NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, primitive.sphere.matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
break;
}
@ -244,7 +247,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);
NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, primitive.sphere.matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
break;
}
@ -263,7 +266,7 @@ void NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& para
NzBufferMapper<NzVertexBuffer> 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<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.slices, primitive.sphere.uv.stacks, matrix, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
break;
}
}