From 88e6641b171a2988e59cff8381061c7ef40bdd87 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 3 May 2014 22:02:25 +0100 Subject: [PATCH] Fixed|World|SectorCluster: Crash with sci2.wad (Doom2) upon triggering the exit crusher The crash was the result of an incorrect assumption that all sector clusters will have at least one outer boundary edge. While this is logically true there are some special cases in which no boundary is recorded (e.g., the one unique outer halfedge is twined with an egde originating from a degenerate BSP leaf). In this case, the trigger is a so-called "control sector" outside the map attempting to update surface light decorations when it's ceiling plane moved. Todo for later: There is no need for such a cluster to be observing plane movement at all. To address this properly we need two things; 1) BSP building algorithm that guarantees topologically sound and geometrically correct data, 2) more intelligent SectorCluster. IssueID #1791 --- doomsday/client/src/world/sectorcluster.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/doomsday/client/src/world/sectorcluster.cpp b/doomsday/client/src/world/sectorcluster.cpp index cfa1f9cd0a..511e75b699 100644 --- a/doomsday/client/src/world/sectorcluster.cpp +++ b/doomsday/client/src/world/sectorcluster.cpp @@ -624,15 +624,19 @@ DENG2_PIMPL(SectorCluster) initBoundaryInfoIfNeeded(); // Mark surfaces of the outer edge loop. - HEdge *base = boundaryInfo->uniqueOuterEdges.first(); - SectorClusterCirculator it(base); - do + /// @todo What about the special case of a cluster with no outer neighbors? -ds + if(!boundaryData->uniqueOuterEdges.isEmpty()) { - if(it->hasMapElement()) // BSP errors may fool the circulator wrt interior edges -ds + HEdge *base = boundaryInfo->uniqueOuterEdges.first(); + SectorClusterCirculator it(base); + do { - markAllSurfacesForDecorationUpdate(it->mapElementAs().line()); - } - } while(&it.next() != base); + if(it->hasMapElement()) // BSP errors may fool the circulator wrt interior edges -ds + { + markAllSurfacesForDecorationUpdate(it->mapElementAs().line()); + } + } while(&it.next() != base); + } // Mark surfaces of the inner edge loop(s). foreach(HEdge *base, boundaryInfo->uniqueInnerEdges)