diff --git a/source/simulation2/helpers/HierarchicalPathfinder.cpp b/source/simulation2/helpers/HierarchicalPathfinder.cpp
index 8ccbb02..ad1b3e9 100644
a
|
b
|
|
1 | | /* Copyright (C) 2015 Wildfire Games. |
| 1 | /* Copyright (C) 2016 Wildfire Games. |
2 | 2 | * This file is part of 0 A.D. |
3 | 3 | * |
4 | 4 | * 0 A.D. is free software: you can redistribute it and/or modify |
… |
… |
|
25 | 25 | // Find the root ID of a region, used by InitRegions |
26 | 26 | inline u16 RootID(u16 x, const std::vector<u16>& v) |
27 | 27 | { |
28 | | // Just add a basic check for infinite loops |
29 | | int checkLoop = 0; |
30 | 28 | while (v[x] < x) |
31 | | { |
32 | | ++checkLoop; |
33 | | ENSURE(checkLoop < 1000 && "Long loop (probably infinite), unable to find an invariant point"); |
34 | 29 | x = v[x]; |
35 | | } |
36 | 30 | |
37 | 31 | return x; |
38 | 32 | } |
… |
… |
void HierarchicalPathfinder::Chunk::InitRegions(int ci, int cj, Grid<NavcellData
|
58 | 52 | u16* pCurrentID = NULL; |
59 | 53 | u16 LeftID = 0; |
60 | 54 | u16 DownID = 0; |
| 55 | bool Checked = false; // prevent some unneccessary RootID calls |
61 | 56 | |
62 | 57 | connect.reserve(32); // TODO: What's a sensible number? |
63 | 58 | connect.push_back(0); // connect[0] = 0 |
… |
… |
void HierarchicalPathfinder::Chunk::InitRegions(int ci, int cj, Grid<NavcellData
|
86 | 81 | if (LeftID > 0) |
87 | 82 | { |
88 | 83 | *pCurrentID = LeftID; |
89 | | if (*pCurrentID != DownID && DownID > 0) |
| 84 | if (*pCurrentID != DownID && DownID > 0 && !Checked) |
90 | 85 | { |
91 | 86 | u16 id0 = RootID(DownID, connect); |
92 | 87 | u16 id1 = RootID(LeftID, connect); |
| 88 | Checked = true; // this avoids repeatedly connecting the same IDs |
93 | 89 | |
94 | 90 | if (id0 < id1) |
95 | 91 | connect[id1] = id0; |
96 | 92 | else if (id0 > id1) |
97 | 93 | connect[id0] = id1; |
98 | 94 | } |
| 95 | else if (DownID == 0) |
| 96 | Checked = false; |
99 | 97 | } |
100 | 98 | else if (DownID > 0) |
| 99 | { |
101 | 100 | *pCurrentID = DownID; |
| 101 | Checked = false; |
| 102 | } |
102 | 103 | else |
103 | 104 | { |
104 | 105 | // New ID |
105 | 106 | *pCurrentID = ++regionID; |
106 | 107 | connect.push_back(regionID); |
| 108 | Checked = false; |
107 | 109 | } |
108 | 110 | } |
109 | 111 | } |
110 | 112 | |
111 | 113 | // Directly point the root ID |
112 | 114 | m_NumRegions = 0; |
113 | | for (u16 i = regionID; i > 0; --i) |
| 115 | for (u16 i = 1; i <= regionID; ++i) |
114 | 116 | { |
115 | 117 | if (connect[i] == i) |
116 | 118 | ++m_NumRegions; |
117 | 119 | else |
118 | | connect[i] = RootID(i,connect); |
| 120 | connect[i] = connect[connect[i]]; // = RootID(i,connect) by induction |
119 | 121 | } |
120 | 122 | |
121 | 123 | // Replace IDs by the root ID |