Implement Tipsify
This commit is contained in:
+163
-50
@@ -5,12 +5,159 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
|
struct AdjacencyInfo
|
||||||
|
{
|
||||||
|
Array<uint32> trianglesPerVertex;
|
||||||
|
Array<uint32> indexBufferOffset;
|
||||||
|
Array<uint32> triangleData;
|
||||||
|
};
|
||||||
|
|
||||||
|
void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, AdjacencyInfo& info)
|
||||||
|
{
|
||||||
|
info.trianglesPerVertex.resize(numVerts, 0);
|
||||||
|
for (int i = 0; i < indices.size(); ++i)
|
||||||
|
{
|
||||||
|
info.trianglesPerVertex[indices[i]]++;
|
||||||
|
}
|
||||||
|
uint32 triangleOffset = 0;
|
||||||
|
info.indexBufferOffset.resize(numVerts, 0);
|
||||||
|
for (int j = 0; j < numVerts; ++j)
|
||||||
|
{
|
||||||
|
info.indexBufferOffset[j] = triangleOffset;
|
||||||
|
triangleOffset += info.trianglesPerVertex[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 numTriangles = indices.size() / 3;
|
||||||
|
info.triangleData.resize(triangleOffset);
|
||||||
|
Array<uint32> offsets = info.indexBufferOffset;
|
||||||
|
for (uint32 k = 0; k < numTriangles; ++k)
|
||||||
|
{
|
||||||
|
int a = indices[k * 3];
|
||||||
|
int b = indices[k * 3 + 1];
|
||||||
|
int c = indices[k * 3 + 2];
|
||||||
|
|
||||||
|
info.triangleData[offsets[a]++] = k;
|
||||||
|
info.triangleData[offsets[b]++] = k;
|
||||||
|
info.triangleData[offsets[c]++] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||||
|
{
|
||||||
|
while (!deadEndStack.empty())
|
||||||
|
{
|
||||||
|
uint32 vertIdx = deadEndStack.front();
|
||||||
|
deadEndStack.popFront();
|
||||||
|
if (liveTriCount[vertIdx] > 0)
|
||||||
|
{
|
||||||
|
return vertIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (cursor < liveTriCount.size())
|
||||||
|
{
|
||||||
|
if (liveTriCount[cursor] > 0)
|
||||||
|
{
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
++cursor;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getNextVertex(const int cacheSize, const Array<uint32>& oneRing, const Array<uint32>& cacheTimeStamps, const uint32 timeStamp, const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||||
|
{
|
||||||
|
uint32 bestCandidate = std::numeric_limits<uint32>::max();
|
||||||
|
int highestPriority = -1;
|
||||||
|
for (const uint32& vertIdx : oneRing)
|
||||||
|
{
|
||||||
|
if (liveTriCount[vertIdx] > 0)
|
||||||
|
{
|
||||||
|
int priority = 0;
|
||||||
|
if (timeStamp - cacheTimeStamps[vertIdx] + 2 * liveTriCount[vertIdx] <= cacheSize)
|
||||||
|
{
|
||||||
|
priority = timeStamp - cacheTimeStamps[vertIdx];
|
||||||
|
}
|
||||||
|
if (priority > highestPriority)
|
||||||
|
{
|
||||||
|
highestPriority = priority;
|
||||||
|
bestCandidate = vertIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bestCandidate == std::numeric_limits<uint32>::max())
|
||||||
|
{
|
||||||
|
bestCandidate = skipDeadEnd(liveTriCount, deadEndStack, cursor);
|
||||||
|
}
|
||||||
|
return bestCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, const int cacheSize, Array<uint32>& outIndices)
|
||||||
|
{
|
||||||
|
AdjacencyInfo adjacencyStruct;
|
||||||
|
buildAdjacency(numVerts, indices, adjacencyStruct);
|
||||||
|
|
||||||
|
Array<uint32> liveTriCount = adjacencyStruct.trianglesPerVertex;
|
||||||
|
|
||||||
|
Array<uint32> cacheTimeStamps(numVerts);
|
||||||
|
|
||||||
|
List<uint32> deadEndStack;
|
||||||
|
|
||||||
|
Array<bool> emittedTriangles(indices.size() / 3);
|
||||||
|
|
||||||
|
uint32 curVert = 0;
|
||||||
|
uint32 timeStamp = cacheSize + 1;
|
||||||
|
uint32 cursor = 1;
|
||||||
|
while (curVert != -1)
|
||||||
|
{
|
||||||
|
Array<uint32> oneRing;
|
||||||
|
const uint32* startTriPointer = &adjacencyStruct.triangleData[0] + adjacencyStruct.indexBufferOffset[curVert];
|
||||||
|
const uint32* endTriPointer = startTriPointer + adjacencyStruct.trianglesPerVertex[curVert];
|
||||||
|
|
||||||
|
for (const uint32* it = startTriPointer; it != endTriPointer; ++it)
|
||||||
|
{
|
||||||
|
uint32 triangle = *it;
|
||||||
|
|
||||||
|
if (emittedTriangles[triangle])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 a = indices[triangle * 3 + 0];
|
||||||
|
uint32 b = indices[triangle * 3 + 1];
|
||||||
|
uint32 c = indices[triangle * 3 + 2];
|
||||||
|
|
||||||
|
outIndices.add(a);
|
||||||
|
outIndices.add(b);
|
||||||
|
outIndices.add(c);
|
||||||
|
|
||||||
|
deadEndStack.add(a);
|
||||||
|
deadEndStack.add(b);
|
||||||
|
deadEndStack.add(c);
|
||||||
|
|
||||||
|
oneRing.add(a);
|
||||||
|
oneRing.add(b);
|
||||||
|
oneRing.add(c);
|
||||||
|
|
||||||
|
liveTriCount[a]--;
|
||||||
|
liveTriCount[b]--;
|
||||||
|
liveTriCount[c]--;
|
||||||
|
|
||||||
|
if (timeStamp - cacheTimeStamps[a] > cacheSize) {
|
||||||
|
cacheTimeStamps[a] = timeStamp;
|
||||||
|
}
|
||||||
|
if (timeStamp - cacheTimeStamps[b] > cacheSize) {
|
||||||
|
cacheTimeStamps[b] = timeStamp;
|
||||||
|
}
|
||||||
|
if (timeStamp - cacheTimeStamps[c] > cacheSize) {
|
||||||
|
cacheTimeStamps[c] = timeStamp;
|
||||||
|
}
|
||||||
|
emittedTriangles[triangle] = true;
|
||||||
|
}
|
||||||
|
curVert = getNextVertex(cacheSize, oneRing, cacheTimeStamps, timeStamp, liveTriCount, deadEndStack, cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Triangle
|
struct Triangle
|
||||||
{
|
{
|
||||||
StaticArray<uint32, 3> indices;
|
StaticArray<uint32, 3> indices;
|
||||||
Array<uint32> twoAdjacent;
|
|
||||||
Array<uint32> oneAdjacent;
|
|
||||||
int32 meshletId = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int findIndex(Meshlet ¤t, uint32 index)
|
int findIndex(Meshlet ¤t, uint32 index)
|
||||||
@@ -41,7 +188,7 @@ void completeMeshlet(Array<Meshlet> &meshlets, Meshlet ¤t)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addTriangle(const Array<Vector>& positions, Array<Meshlet> &meshlets, Meshlet ¤t, Triangle tri)
|
bool addTriangle(const Array<Vector>& positions, Meshlet ¤t, Triangle& tri)
|
||||||
{
|
{
|
||||||
int f1 = findIndex(current, tri.indices[0]);
|
int f1 = findIndex(current, tri.indices[0]);
|
||||||
int f2 = findIndex(current, tri.indices[1]);
|
int f2 = findIndex(current, tri.indices[1]);
|
||||||
@@ -67,61 +214,27 @@ void Meshlet::build(const Array<Vector> &positions, const Array<uint32> &indices
|
|||||||
.numVertices = 0,
|
.numVertices = 0,
|
||||||
.numPrimitives = 0,
|
.numPrimitives = 0,
|
||||||
};
|
};
|
||||||
Array<Triangle> triangles(indices.size() / 3);
|
Array<uint32> optimizedIndices;
|
||||||
|
tipsifyIndexBuffer(indices, positions.size(), 25, optimizedIndices);
|
||||||
|
Array<Triangle> triangles(optimizedIndices.size() / 3);
|
||||||
for (size_t i = 0; i < triangles.size(); ++i)
|
for (size_t i = 0; i < triangles.size(); ++i)
|
||||||
{
|
{
|
||||||
triangles[i] = Triangle{
|
triangles[i] = Triangle{
|
||||||
.indices = {
|
.indices = {
|
||||||
indices[i * 3 + 0],
|
optimizedIndices[i * 3 + 0],
|
||||||
indices[i * 3 + 1],
|
optimizedIndices[i * 3 + 1],
|
||||||
indices[i * 3 + 2],
|
optimizedIndices[i * 3 + 2],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < triangles.size(); i++)
|
|
||||||
{
|
|
||||||
for (size_t j = 0; j < triangles.size(); j++)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
uint32 adjacency = 0;
|
|
||||||
if (triangles[i].indices[0] == triangles[j].indices[0]
|
|
||||||
|| triangles[i].indices[0] == triangles[j].indices[1]
|
|
||||||
|| triangles[i].indices[0] == triangles[j].indices[2])
|
|
||||||
{
|
|
||||||
adjacency++;
|
|
||||||
}
|
|
||||||
if (triangles[i].indices[1] == triangles[j].indices[0]
|
|
||||||
|| triangles[i].indices[1] == triangles[j].indices[1]
|
|
||||||
|| triangles[i].indices[1] == triangles[j].indices[2])
|
|
||||||
{
|
|
||||||
adjacency++;
|
|
||||||
}
|
|
||||||
if (triangles[i].indices[1] == triangles[j].indices[0]
|
|
||||||
|| triangles[i].indices[1] == triangles[j].indices[1]
|
|
||||||
|| triangles[i].indices[1] == triangles[j].indices[2])
|
|
||||||
{
|
|
||||||
adjacency++;
|
|
||||||
}
|
|
||||||
if(adjacency == 2)
|
|
||||||
{
|
|
||||||
triangles[i].twoAdjacent.add(j);
|
|
||||||
triangles[j].twoAdjacent.add(i);
|
|
||||||
}
|
|
||||||
if(adjacency == 1)
|
|
||||||
{
|
|
||||||
triangles[i].oneAdjacent.add(j);
|
|
||||||
triangles[j].oneAdjacent.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addTriangle(positions, meshlets, current, triangles.back());
|
|
||||||
triangles.pop();
|
|
||||||
while(!triangles.empty())
|
while(!triangles.empty())
|
||||||
{
|
{
|
||||||
AABB boundingBox;
|
if (!addTriangle(positions, current, triangles.back()))
|
||||||
|
{
|
||||||
|
completeMeshlet(meshlets, current);
|
||||||
|
addTriangle(positions, current, triangles.back());
|
||||||
|
}
|
||||||
|
triangles.pop();
|
||||||
}
|
}
|
||||||
if (current.numVertices > 0)
|
if (current.numVertices > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,43 +44,43 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
|
|||||||
},
|
},
|
||||||
.data = data,
|
.data = data,
|
||||||
});
|
});
|
||||||
for (size_t i = 0; i < data.numMeshlets; ++i)
|
//for (size_t i = 0; i < data.numMeshlets; ++i)
|
||||||
{
|
//{
|
||||||
auto bounding = meshlets[data.meshletOffset + i].bounding;
|
// auto bounding = meshlets[data.meshletOffset + i].bounding;
|
||||||
StaticArray<Vector, 8> corners;
|
// StaticArray<Vector, 8> corners;
|
||||||
corners[0] = transform.toMatrix() * Vector4(bounding.min.x, bounding.min.y, bounding.min.z, 1);
|
// corners[0] = transform.toMatrix() * Vector4(bounding.min.x, bounding.min.y, bounding.min.z, 1);
|
||||||
corners[1] = transform.toMatrix() * Vector4(bounding.min.x, bounding.min.y, bounding.max.z, 1);
|
// corners[1] = transform.toMatrix() * Vector4(bounding.min.x, bounding.min.y, bounding.max.z, 1);
|
||||||
corners[2] = transform.toMatrix() * Vector4(bounding.min.x, bounding.max.y, bounding.min.z, 1);
|
// corners[2] = transform.toMatrix() * Vector4(bounding.min.x, bounding.max.y, bounding.min.z, 1);
|
||||||
corners[3] = transform.toMatrix() * Vector4(bounding.min.x, bounding.max.y, bounding.max.z, 1);
|
// corners[3] = transform.toMatrix() * Vector4(bounding.min.x, bounding.max.y, bounding.max.z, 1);
|
||||||
corners[4] = transform.toMatrix() * Vector4(bounding.max.x, bounding.min.y, bounding.min.z, 1);
|
// corners[4] = transform.toMatrix() * Vector4(bounding.max.x, bounding.min.y, bounding.min.z, 1);
|
||||||
corners[5] = transform.toMatrix() * Vector4(bounding.max.x, bounding.min.y, bounding.max.z, 1);
|
// corners[5] = transform.toMatrix() * Vector4(bounding.max.x, bounding.min.y, bounding.max.z, 1);
|
||||||
corners[6] = transform.toMatrix() * Vector4(bounding.max.x, bounding.max.y, bounding.min.z, 1);
|
// corners[6] = transform.toMatrix() * Vector4(bounding.max.x, bounding.max.y, bounding.min.z, 1);
|
||||||
corners[7] = transform.toMatrix() * Vector4(bounding.max.x, bounding.max.y, bounding.max.z, 1);
|
// corners[7] = transform.toMatrix() * Vector4(bounding.max.x, bounding.max.y, bounding.max.z, 1);
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[0], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[1], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[2], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[3], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[4], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[6], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[5], .color = meshlets[data.meshletOffset + i].color });
|
||||||
addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
// addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color });
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
matInstanceData.materialInstance = referencedInstance;
|
matInstanceData.materialInstance = referencedInstance;
|
||||||
referencedInstance->updateDescriptor();
|
referencedInstance->updateDescriptor();
|
||||||
|
|||||||
Reference in New Issue
Block a user