From 5dc8d2ff781865f6dda46bacda5c528ee5c7d2a1 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Tue, 10 Aug 2021 12:42:33 +0200 Subject: [PATCH] Rewrote surface grouping method to be iterative instead of tail-recursive. Fixes potential stack overflow issues when loading particularly large and complex maps. --- Assets/Scripts/Support/BrushModel.cs | 39 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Assets/Scripts/Support/BrushModel.cs b/Assets/Scripts/Support/BrushModel.cs index b810c33..4f982be 100644 --- a/Assets/Scripts/Support/BrushModel.cs +++ b/Assets/Scripts/Support/BrushModel.cs @@ -66,27 +66,34 @@ public class BrushModel private void GroupSurfaces(QNode node, QSurface[] surfaces, Dictionary<(IntPtr, int, QSurfaceFlags), List> surfaceGroups) { - if (node.contents < 0) // Leaf node - return; + var nodeQueue = new Queue(); + nodeQueue.Enqueue(node); - for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx) + while (nodeQueue.Count > 0) { - var surface = surfaces[node.firstSurface + surfIdx]; + node = nodeQueue.Dequeue(); + if (node.contents < 0) // Leaf node + continue; - IntPtr texPtr = surface.TextureInfo.texture; - int lightNum = surface.lightmapTextureNum; - QSurfaceFlags flags = surface.flags; - var key = (texPtr, lightNum, flags); + for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx) + { + var surface = surfaces[node.firstSurface + surfIdx]; - if (!surfaceGroups.ContainsKey(key)) - surfaceGroups[key] = new List(); - - surfaceGroups[key].Add(surface); - } + IntPtr texPtr = surface.TextureInfo.texture; + int lightNum = surface.lightmapTextureNum; + QSurfaceFlags flags = surface.flags; + var key = (texPtr, lightNum, flags); - foreach (var childNode in node.Children) - { - GroupSurfaces(childNode, surfaces, surfaceGroups); + if (!surfaceGroups.ContainsKey(key)) + surfaceGroups[key] = new List(); + + surfaceGroups[key].Add(surface); + } + + foreach (var childNode in node.Children) + { + nodeQueue.Enqueue(childNode); + } } }