Trying new meshlet gen approach
This commit is contained in:
@@ -5,62 +5,95 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
struct Triangle
|
||||
{
|
||||
StaticArray<uint32, 3> indices;
|
||||
};
|
||||
|
||||
int findIndex(Meshlet& current, uint32 index)
|
||||
{
|
||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||
{
|
||||
if (current.uniqueVertices[i] == index)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
current.uniqueVertices[current.numVertices] = index;
|
||||
|
||||
return current.numVertices++;
|
||||
}
|
||||
|
||||
void completeMeshlet(Array<Meshlet>& meshlets, Meshlet& current)
|
||||
{
|
||||
meshlets.add(current);
|
||||
current = {
|
||||
.numVertices = 0,
|
||||
.numPrimitives = 0,
|
||||
};
|
||||
}
|
||||
|
||||
void addTriangle(Array<Meshlet>& meshlets, Meshlet& current, Triangle tri)
|
||||
{
|
||||
int f1 = findIndex(current, tri.indices[0]);
|
||||
int f2 = findIndex(current, tri.indices[1]);
|
||||
int f3 = findIndex(current, tri.indices[2]);
|
||||
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1)
|
||||
{
|
||||
completeMeshlet(meshlets, current);
|
||||
f1 = findIndex(current, tri.indices[0]);
|
||||
f2 = findIndex(current, tri.indices[1]);
|
||||
f3 = findIndex(current, tri.indices[2]);
|
||||
}
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 0] = uint8(f1);
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 1] = uint8(f2);
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 2] = uint8(f3);
|
||||
current.numPrimitives++;
|
||||
if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
||||
{
|
||||
completeMeshlet(meshlets, current);
|
||||
}
|
||||
}
|
||||
|
||||
void Meshlet::build(const Array<Vector>& positions, const Array<uint32>& indices, Array<Meshlet>& meshlets)
|
||||
{
|
||||
Meshlet current = {
|
||||
.numVertices = 0,
|
||||
.numPrimitives = 0,
|
||||
};
|
||||
auto findIndex = [¤t](uint32 index) -> int {
|
||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||
Array<Triangle> triangles(indices.size() / 3);
|
||||
for (size_t i = 0; i < triangles.size(); ++i)
|
||||
{
|
||||
triangles[i].indices[0] = indices[i * 3 + 0];
|
||||
triangles[i].indices[1] = indices[i * 3 + 1];
|
||||
triangles[i].indices[2] = indices[i * 3 + 2];
|
||||
}
|
||||
while (!triangles.empty())
|
||||
{
|
||||
uint32 best = 0;
|
||||
float lowestSurface = std::numeric_limits<float>::max();
|
||||
AABB newAABB;
|
||||
for (uint32 i = 0; i < triangles.size(); ++i)
|
||||
{
|
||||
if (current.uniqueVertices[i] == index)
|
||||
AABB adjusted = current.boundingBox;
|
||||
adjusted.adjust(positions[triangles[i].indices[0]]);
|
||||
adjusted.adjust(positions[triangles[i].indices[1]]);
|
||||
adjusted.adjust(positions[triangles[i].indices[2]]);
|
||||
float surface = adjusted.surfaceArea();
|
||||
if (surface < lowestSurface)
|
||||
{
|
||||
return i;
|
||||
lowestSurface = surface;
|
||||
best = i;
|
||||
newAABB = adjusted;
|
||||
}
|
||||
}
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
current.uniqueVertices[current.numVertices] = index;
|
||||
return current.numVertices++;
|
||||
};
|
||||
auto completeMeshlet = [&positions, &meshlets, ¤t]() {
|
||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||
{
|
||||
current.boundingBox.adjust(positions[current.uniqueVertices[i]]);
|
||||
}
|
||||
meshlets.add(current);
|
||||
current = {
|
||||
.numVertices = 0,
|
||||
.numPrimitives = 0,
|
||||
};
|
||||
};
|
||||
for (size_t faceIndex = 0; faceIndex < indices.size() / 3; ++faceIndex)
|
||||
{
|
||||
int f1 = findIndex(indices[faceIndex * 3 + 0]);
|
||||
int f2 = findIndex(indices[faceIndex * 3 + 1]);
|
||||
int f3 = findIndex(indices[faceIndex * 3 + 2]);
|
||||
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1)
|
||||
{
|
||||
completeMeshlet();
|
||||
f1 = findIndex(indices[faceIndex * 3 + 0]);
|
||||
f2 = findIndex(indices[faceIndex * 3 + 1]);
|
||||
f3 = findIndex(indices[faceIndex * 3 + 2]);
|
||||
}
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 0] = uint8(f1);
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 1] = uint8(f2);
|
||||
current.primitiveLayout[current.numPrimitives * 3 + 2] = uint8(f3);
|
||||
current.numPrimitives++;
|
||||
if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
||||
{
|
||||
completeMeshlet();
|
||||
}
|
||||
}
|
||||
if (current.numVertices > 0)
|
||||
{
|
||||
completeMeshlet();
|
||||
current.boundingBox = newAABB;
|
||||
addTriangle(meshlets, current, triangles[best]);
|
||||
triangles.removeAt(best);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user