From 23fb74466586798c6ac8013a4df8762a964760a3 Mon Sep 17 00:00:00 2001
From: Xian55 <367101+Xian55@users.noreply.github.com>
Date: Sun, 8 Sep 2024 12:26:50 +0200
Subject: [PATCH] PPather: MPQTrinagleSupplier: optimize code around reading
 triangles and vertices - flat out loop

---
 PPather/Triangles/MPQTriangleSupplier.cs | 90 ++++++++++++++----------
 1 file changed, 51 insertions(+), 39 deletions(-)

diff --git a/PPather/Triangles/MPQTriangleSupplier.cs b/PPather/Triangles/MPQTriangleSupplier.cs
index ac8da845..38aaa974 100644
--- a/PPather/Triangles/MPQTriangleSupplier.cs
+++ b/PPather/Triangles/MPQTriangleSupplier.cs
@@ -168,60 +168,72 @@ private static void AddTriangles(TriangleCollection tc, MapChunk c)
             }
         }
 
-        for (int row = 0; row < 8; row++)
+        const int totalCells = 8 * 8;
+
+        for (int cell = 0; cell < totalCells; cell++)
         {
-            for (int col = 0; col < 8; col++)
+            int row = cell / 8;
+            int col = cell % 8;
+
+            if (c.IsHole(col, row))
             {
-                if (!c.isHole(col, row))
-                {
-                    int v0 = vertices[row * 9 + col];
-                    int v1 = vertices[(row + 1) * 9 + col];
-                    int v2 = vertices[(row + 1) * 9 + col + 1];
-                    int v3 = vertices[row * 9 + col + 1];
-                    int vMid = verticesMid[row * 8 + col];
-
-                    tc.AddTriangle(v0, v1, vMid, TriangleType.Terrain);
-                    tc.AddTriangle(v1, v2, vMid, TriangleType.Terrain);
-                    tc.AddTriangle(v2, v3, vMid, TriangleType.Terrain);
-                    tc.AddTriangle(v3, v0, vMid, TriangleType.Terrain);
-                }
+                continue;
             }
+
+            int rowIndex9 = row * 9;
+            int rowIndexMid = row * 8;
+
+            // Precompute indices for vertices
+            int v0 = vertices[rowIndex9 + col];
+            int v1 = vertices[(row + 1) * 9 + col];
+            int v2 = vertices[(row + 1) * 9 + col + 1];
+            int v3 = vertices[rowIndex9 + col + 1];
+            int vMid = verticesMid[rowIndexMid + col];
+
+            // Add triangles using precomputed indices
+            tc.AddTriangle(v0, v1, vMid, TriangleType.Terrain);
+            tc.AddTriangle(v1, v2, vMid, TriangleType.Terrain);
+            tc.AddTriangle(v2, v3, vMid, TriangleType.Terrain);
+            tc.AddTriangle(v3, v0, vMid, TriangleType.Terrain);
         }
 
-        if (c.haswater)
+
+        if (!c.haswater)
         {
-            // paint the water
-            for (int row = 0; row < LiquidData.HEIGHT_SIZE; row++)
+            return;
+        }
+
+        // paint the water
+        for (int row = 0; row < LiquidData.HEIGHT_SIZE; row++)
+        {
+            for (int col = 0; col < LiquidData.HEIGHT_SIZE; col++)
             {
-                for (int col = 0; col < LiquidData.HEIGHT_SIZE; col++)
-                {
-                    int ii = row * LiquidData.HEIGHT_SIZE + col;
+                int ii = row * LiquidData.HEIGHT_SIZE + col;
 
-                    ChunkGetCoordForPoint(c, row, col, out float x, out float y, out float z);
-                    float height = c.water_height[ii]; // - 1.5f //why this here
-                    int index = tc.AddVertex(x, y, height);
+                ChunkGetCoordForPoint(c, row, col, out float x, out float y, out float z);
+                float height = c.water_height[ii]; // - 1.5f //why this here
+                int index = tc.AddVertex(x, y, height);
 
-                    vertices[row * LiquidData.HEIGHT_SIZE + col] = index;
-                }
+                vertices[row * LiquidData.HEIGHT_SIZE + col] = index;
             }
+        }
 
-            for (int row = 0; row < LiquidData.FLAG_SIZE; row++)
+        for (int row = 0; row < LiquidData.FLAG_SIZE; row++)
+        {
+            for (int col = 0; col < LiquidData.FLAG_SIZE; col++)
             {
-                for (int col = 0; col < LiquidData.FLAG_SIZE; col++)
-                {
-                    int ii = row * LiquidData.FLAG_SIZE + col;
+                int ii = row * LiquidData.FLAG_SIZE + col;
 
-                    if (c.water_flags[ii] == 0xf)
-                        continue;
+                if (c.water_flags[ii] == 0xf)
+                    continue;
 
-                    int v0 = vertices[row * LiquidData.HEIGHT_SIZE + col];
-                    int v1 = vertices[(row + 1) * LiquidData.HEIGHT_SIZE + col];
-                    int v2 = vertices[(row + 1) * LiquidData.HEIGHT_SIZE + col + 1];
-                    int v3 = vertices[row * LiquidData.HEIGHT_SIZE + col + 1];
+                int v0 = vertices[row * LiquidData.HEIGHT_SIZE + col];
+                int v1 = vertices[(row + 1) * LiquidData.HEIGHT_SIZE + col];
+                int v2 = vertices[(row + 1) * LiquidData.HEIGHT_SIZE + col + 1];
+                int v3 = vertices[row * LiquidData.HEIGHT_SIZE + col + 1];
 
-                    tc.AddTriangle(v0, v1, v3, TriangleType.Water);
-                    tc.AddTriangle(v1, v2, v3, TriangleType.Water);
-                }
+                tc.AddTriangle(v0, v1, v3, TriangleType.Water);
+                tc.AddTriangle(v1, v2, v3, TriangleType.Water);
             }
         }
     }