From 69ea0c9ce8cf8032a849cedbc7225ba8fa841391 Mon Sep 17 00:00:00 2001
From: Artur Wasmut <awasmut@uni-koblenz.de>
Date: Tue, 27 Jul 2021 12:34:55 +0200
Subject: [PATCH] [#87] add general VertexCacheReorderResult struct. Adjust
 forsyth reordering accordingly.

---
 .../meshlet/include/vkcv/meshlet/Forsyth.hpp  |  2 +-
 .../meshlet/include/vkcv/meshlet/Meshlet.hpp  | 12 ++++++++++++
 .../meshlet/include/vkcv/meshlet/Tipsify.hpp  | 19 ++-----------------
 modules/meshlet/src/vkcv/meshlet/Forsyth.cpp  | 11 ++++++++---
 modules/meshlet/src/vkcv/meshlet/Tipsify.cpp  |  6 +++---
 projects/mesh_shader/src/main.cpp             | 10 +++++-----
 6 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/modules/meshlet/include/vkcv/meshlet/Forsyth.hpp b/modules/meshlet/include/vkcv/meshlet/Forsyth.hpp
index 7d917a64..43dc9a3b 100644
--- a/modules/meshlet/include/vkcv/meshlet/Forsyth.hpp
+++ b/modules/meshlet/include/vkcv/meshlet/Forsyth.hpp
@@ -14,5 +14,5 @@ namespace vkcv::meshlet
   * https://www.martin.st/thesis/efficient_triangle_reordering.pdf
   * https://github.com/vivkin/forsyth/blob/master/forsyth.h
   */
-    std::vector<uint32_t> forsythReorder(const std::vector<uint32_t> &idxBuf, const size_t vertexCount);
+ VertexCacheReorderResult forsythReorder(const std::vector<uint32_t> &idxBuf, const size_t vertexCount);
 }
diff --git a/modules/meshlet/include/vkcv/meshlet/Meshlet.hpp b/modules/meshlet/include/vkcv/meshlet/Meshlet.hpp
index 124639d8..9900dffa 100644
--- a/modules/meshlet/include/vkcv/meshlet/Meshlet.hpp
+++ b/modules/meshlet/include/vkcv/meshlet/Meshlet.hpp
@@ -23,6 +23,18 @@ namespace vkcv::meshlet {
         float       boundingSphereRadius;
     };
 
+    struct VertexCacheReorderResult {
+        /**
+         * @param indexBuffer new indexBuffer
+         * @param skippedIndices indices that have a spacial break
+         */
+        VertexCacheReorderResult(const std::vector<uint32_t> indexBuffer, const std::vector<uint32_t> skippedIndices)
+                :indexBuffer(indexBuffer), skippedIndices(skippedIndices) {}
+
+        std::vector<uint32_t> indexBuffer;
+        std::vector<uint32_t>  skippedIndices;
+    };
+
     struct MeshShaderModelData {
         std::vector<Vertex>     vertices;
         std::vector<uint32_t>   localIndices;
diff --git a/modules/meshlet/include/vkcv/meshlet/Tipsify.hpp b/modules/meshlet/include/vkcv/meshlet/Tipsify.hpp
index 70fbd39c..6fb4b37d 100644
--- a/modules/meshlet/include/vkcv/meshlet/Tipsify.hpp
+++ b/modules/meshlet/include/vkcv/meshlet/Tipsify.hpp
@@ -5,19 +5,6 @@
 #include <iostream>
 
 namespace vkcv::meshlet {
-    struct tipsifyResult{
-        /**
-         *
-         * @param indexBuffer new indexBuffer
-         * @param skippedIndices indices that have a spacial break
-         */
-        tipsifyResult(const std::vector<uint32_t> indexBuffer, const std::vector<uint32_t> skippedIndices)
-        :indexBuffer(indexBuffer), skippedIndices(skippedIndices) {}
-
-        std::vector<uint32_t> indexBuffer;
-        std::vector<uint32_t>  skippedIndices;
-    };
-
     /**
      * reorders the IndexBuffer, so all usages of vertices to triangle are as close as possible
      * @param indexBuffer32Bit current IndexBuffer
@@ -31,8 +18,6 @@ namespace vkcv::meshlet {
      * https://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/tipsy.pdf
      * https://www.martin.st/thesis/efficient_triangle_reordering.pdf
      */
-    tipsifyResult tipsifyMesh(
-            const std::vector<uint32_t> &indexBuffer32Bit,
-            const int vertexCount, const unsigned int cacheSize = 20);
-
+    VertexCacheReorderResult tipsifyMesh(const std::vector<uint32_t> &indexBuffer32Bit,
+                                         const int vertexCount, const unsigned int cacheSize = 20);
 }
\ No newline at end of file
diff --git a/modules/meshlet/src/vkcv/meshlet/Forsyth.cpp b/modules/meshlet/src/vkcv/meshlet/Forsyth.cpp
index 1f5ccc06..3ed77c6d 100644
--- a/modules/meshlet/src/vkcv/meshlet/Forsyth.cpp
+++ b/modules/meshlet/src/vkcv/meshlet/Forsyth.cpp
@@ -82,8 +82,10 @@ namespace vkcv::meshlet
         return score;
     }
 
-    std::vector<uint32_t> forsythReorder(const std::vector<uint32_t> &idxBuf, const size_t vertexCount)
+    VertexCacheReorderResult forsythReorder(const std::vector<uint32_t> &idxBuf, const size_t vertexCount)
     {
+        std::vector<uint32_t> skippedIndices;
+
         initScoreTables();
 
         // get the total triangle count from the index buffer
@@ -98,7 +100,7 @@ namespace vkcv::meshlet
             {
                 vkcv_log(LogLevel::ERROR, "Unsupported mesh.");
                 vkcv_log(LogLevel::ERROR, "Vertex shared by too many triangles.");
-                return {};
+                return VertexCacheReorderResult({}, {});
             }
 
             numActiveTris[index]++;
@@ -287,6 +289,9 @@ namespace vkcv::meshlet
                     if(!triangleAdded[scanPos])
                     {
                         bestTriangle = scanPos;
+
+                        skippedIndices.push_back(3 * outPos);
+
                         break;
                     }
                 }
@@ -307,6 +312,6 @@ namespace vkcv::meshlet
             }
         }
 
-        return outIndices;
+        return VertexCacheReorderResult(outIndices, skippedIndices);
     }
 }
\ No newline at end of file
diff --git a/modules/meshlet/src/vkcv/meshlet/Tipsify.cpp b/modules/meshlet/src/vkcv/meshlet/Tipsify.cpp
index 48357b06..e00e7dce 100644
--- a/modules/meshlet/src/vkcv/meshlet/Tipsify.cpp
+++ b/modules/meshlet/src/vkcv/meshlet/Tipsify.cpp
@@ -118,14 +118,14 @@ namespace vkcv::meshlet {
         return nextVertexIndex;
     }
 
-    tipsifyResult tipsifyMesh(
+    VertexCacheReorderResult tipsifyMesh(
             const std::vector<uint32_t> &indexBuffer32Bit,
             const int vertexCount,
             const unsigned int cacheSize) {
 
         if (indexBuffer32Bit.empty() || vertexCount <= 0) {
             vkcv_log(LogLevel::ERROR, "Invalid Input.");
-            return tipsifyResult(indexBuffer32Bit ,skippedIndices );
+            return VertexCacheReorderResult(indexBuffer32Bit ,skippedIndices);
         }
         int triangleCount = indexBuffer32Bit.size() / 3;
 
@@ -271,6 +271,6 @@ namespace vkcv::meshlet {
             }
         }
 
-        return tipsifyResult(reorderedIndexBuffer, skippedIndices);
+        return VertexCacheReorderResult(reorderedIndexBuffer, skippedIndices);
     }
 }
\ No newline at end of file
diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp
index 1a596be0..ddfc96d9 100644
--- a/projects/mesh_shader/src/main.cpp
+++ b/projects/mesh_shader/src/main.cpp
@@ -138,12 +138,12 @@ int main(int argc, const char** argv) {
 	const auto& bunny = mesh.vertexGroups[0];
 	std::vector<vkcv::meshlet::Vertex> interleavedVertices = vkcv::meshlet::convertToVertices(bunny.vertexBuffer.data, bunny.numVertices, attributes[0], attributes[1]);
 	// mesh shader buffers
-	const auto& assetLoaderIndexBuffer              = mesh.vertexGroups[0].indexBuffer;
-	std::vector<uint32_t> indexBuffer32Bit          = vkcv::meshlet::assetLoaderIndicesTo32BitIndices(assetLoaderIndexBuffer.data, assetLoaderIndexBuffer.type);
-    vkcv::meshlet::tipsifyResult tipsifyResult      = vkcv::meshlet::tipsifyMesh(indexBuffer32Bit, interleavedVertices.size());
-    //std::vector<uint32_t> reorderedIndexBuffer32Bit = vkcv::meshlet::forsythReorder(indexBuffer32Bit, interleavedVertices.size());
+	const auto& assetLoaderIndexBuffer                    = mesh.vertexGroups[0].indexBuffer;
+	std::vector<uint32_t> indexBuffer32Bit                = vkcv::meshlet::assetLoaderIndicesTo32BitIndices(assetLoaderIndexBuffer.data, assetLoaderIndexBuffer.type);
+    vkcv::meshlet::VertexCacheReorderResult tipsifyResult = vkcv::meshlet::tipsifyMesh(indexBuffer32Bit, interleavedVertices.size());
+    vkcv::meshlet::VertexCacheReorderResult forsythResult = vkcv::meshlet::forsythReorder(indexBuffer32Bit, interleavedVertices.size());
 
-    const auto meshShaderModelData = createMeshShaderModelData(interleavedVertices, tipsifyResult.indexBuffer, tipsifyResult.skippedIndices);
+    const auto meshShaderModelData = createMeshShaderModelData(interleavedVertices, forsythResult.indexBuffer, forsythResult.skippedIndices);
 
 	auto meshShaderVertexBuffer = core.createBuffer<vkcv::meshlet::Vertex>(
 		vkcv::BufferType::STORAGE,
-- 
GitLab