|
9 | 9 | #include "stdafx.h"
|
10 | 10 | #include "xrAICore/Navigation/level_graph.h"
|
11 | 11 |
|
12 |
| -CLevelGraph::CVertex** stack_storage; |
13 |
| - |
14 | 12 | #define PUSH(a) *stack_iterator++ = (a)
|
15 | 13 | #define POP() vertex = *--stack_iterator
|
16 | 14 |
|
17 |
| -void floodfill(const CLevelGraph& level_graph, xr_vector<bool>& marks, u32 start_vertex_id) |
| 15 | +void floodfill(const CLevelGraph& level_graph, CLevelGraph::CVertex** stack_storage, xr_vector<bool>& marks, const u32 start_vertex_id) |
18 | 16 | {
|
19 | 17 | CLevelGraph::CVertex** stack_iterator = stack_storage;
|
20 |
| - CLevelGraph::CVertex* vertex = 0; |
21 |
| - CLevelGraph::const_iterator I, E; |
22 |
| - u32 vertex_id; |
| 18 | + CLevelGraph::CVertex* vertex = nullptr; |
23 | 19 | PUSH(level_graph.vertex(start_vertex_id));
|
24 | 20 | while (stack_iterator != stack_storage)
|
25 | 21 | {
|
26 | 22 | POP();
|
27 |
| - vertex_id = level_graph.vertex_id(vertex); |
| 23 | + auto vertex_id = level_graph.vertex_id(vertex); |
28 | 24 | if (marks[vertex_id])
|
29 | 25 | continue;
|
30 | 26 | marks[vertex_id] = true;
|
31 |
| - level_graph.begin(vertex, I, E); |
32 |
| - for (; I != E; ++I) |
| 27 | + for (const auto j : { 0, 1, 2, 3 }) |
33 | 28 | {
|
34 |
| - u32 neighbour_vertex_id = level_graph.value(vertex, I); |
| 29 | + auto neighbour_vertex_id = vertex->link(j); |
35 | 30 | if (level_graph.valid_vertex_id(neighbour_vertex_id) && !marks[neighbour_vertex_id])
|
36 | 31 | PUSH(level_graph.vertex(neighbour_vertex_id));
|
37 | 32 | }
|
38 | 33 | }
|
39 | 34 | }
|
40 | 35 |
|
41 |
| -IC bool single_link(const CLevelGraph& level_graph, u32 i1, u32 i2, u32 link_index) |
42 |
| -{ |
43 |
| - return (level_graph.value(level_graph.vertex(i1), link_index) != i2); |
44 |
| -} |
45 |
| - |
46 | 36 | bool verify_invalid_links(const CLevelGraph& graph)
|
47 | 37 | {
|
48 | 38 | bool result = true;
|
49 |
| - CLevelGraph::const_vertex_iterator I = graph.begin(); |
50 |
| - CLevelGraph::const_vertex_iterator E = graph.end(); |
51 |
| - for (; I != E; ++I) |
| 39 | + for (const auto &vertex : graph) |
52 | 40 | {
|
53 |
| - u32 vertex_id = graph.vertex_id(I); |
54 |
| - CLevelGraph::const_iterator i, e; |
55 |
| - graph.begin(I, i, e); |
56 |
| - for (; i != e; ++i) |
| 41 | + auto vertex_id = graph.vertex_id(&vertex); |
| 42 | + for (const auto j : { 0, 1, 2, 3 }) |
57 | 43 | {
|
58 |
| - u32 link_vertex_id = graph.value(I, i); |
| 44 | + auto link_vertex_id = vertex.link(j); |
59 | 45 | if (!graph.valid_vertex_id(link_vertex_id))
|
60 | 46 | continue;
|
61 | 47 |
|
62 | 48 | if (vertex_id == link_vertex_id)
|
63 | 49 | {
|
64 |
| - Msg("Vertex [%d][%f][%f][%f] has link to itself", vertex_id, VPUSH(graph.vertex_position(I))); |
| 50 | + Msg("Vertex %d[%f][%f][%f] has link to itself", vertex_id, VPUSH(graph.vertex_position(vertex))); |
65 | 51 | result = false;
|
66 | 52 | continue;
|
67 | 53 | }
|
68 | 54 | }
|
69 |
| - }; |
70 |
| - return (result); |
| 55 | + } |
| 56 | + return result; |
71 | 57 | }
|
72 | 58 |
|
73 | 59 | void verify_level_graph(LPCSTR name, bool verbose)
|
74 | 60 | {
|
75 | 61 | Msg("Verifying level %s", name);
|
76 | 62 | Logger.Phase("Verifying level graph");
|
77 | 63 | Logger.Progress(0.f);
|
78 |
| - CLevelGraph* level_graph = new CLevelGraph(name); |
79 |
| - if (!level_graph->header().vertex_count()) |
| 64 | + CLevelGraph level_graph(name); |
| 65 | + |
| 66 | + if (!level_graph.header().vertex_count()) |
80 | 67 | {
|
81 | 68 | Logger.Progress(1.f);
|
82 | 69 | Msg("Level graph is empty!");
|
83 |
| - xr_delete(level_graph); |
84 | 70 | return;
|
85 | 71 | }
|
86 | 72 |
|
87 |
| - if (!verify_invalid_links(*level_graph)) |
| 73 | + if (!verify_invalid_links(level_graph)) |
88 | 74 | {
|
89 | 75 | Logger.Progress(1.f);
|
90 | 76 | Msg("AI map is CORRUPTED : REGENERATE AI-MAP");
|
91 |
| - xr_delete(level_graph); |
92 | 77 | return;
|
93 | 78 | }
|
94 | 79 |
|
95 |
| - stack_storage = |
96 |
| - (CLevelGraph::CVertex**)xr_malloc(level_graph->header().vertex_count() * sizeof(CLevelGraph::CVertex*)); |
97 |
| - |
98 |
| - xr_vector<bool> marks; |
99 |
| - |
100 | 80 | xr_vector<u32> single_links;
|
101 |
| - single_links.reserve(level_graph->header().vertex_count()); |
| 81 | + single_links.reserve(level_graph.header().vertex_count()); |
102 | 82 | Logger.Progress(0.05f);
|
103 | 83 |
|
104 |
| - for (u32 i = 0, n = level_graph->header().vertex_count(); i < n; ++i) |
| 84 | + for (const auto &vertex : level_graph) |
105 | 85 | {
|
106 |
| - CLevelGraph::const_iterator I, E; |
107 |
| - CLevelGraph::CVertex* vertex = level_graph->vertex(i); |
108 |
| - level_graph->begin(vertex, I, E); |
109 |
| - for (; I != E; ++I) |
| 86 | + for (const auto j : {0, 1, 2, 3}) |
110 | 87 | {
|
111 |
| - u32 neighbour_vertex_id = level_graph->value(vertex, I); |
112 |
| - if (level_graph->valid_vertex_id(neighbour_vertex_id) && |
113 |
| - single_link(*level_graph, neighbour_vertex_id, i, (I + 2) % 4)) |
| 88 | + auto neighbour_vertex_id = vertex.link(j); |
| 89 | + if (level_graph.valid_vertex_id(neighbour_vertex_id) && // Valid vertex |
| 90 | + level_graph.vertex(neighbour_vertex_id)->link((j + 2) % 4) != level_graph.vertex_id(&vertex)) // Single vertex |
114 | 91 | {
|
115 | 92 | single_links.push_back(neighbour_vertex_id);
|
116 | 93 | }
|
117 | 94 | }
|
118 |
| - Logger.Progress(0.05f + 0.05f * float(i) / float(n)); |
| 95 | + Logger.Progress(0.05f + 0.05f * float(level_graph.vertex_id(&vertex)) / float(level_graph.header().vertex_count())); |
119 | 96 | }
|
120 | 97 |
|
121 | 98 | bool no_single_links = single_links.empty();
|
122 | 99 | Logger.Progress(0.1f);
|
123 | 100 | if (single_links.empty())
|
124 | 101 | single_links.push_back(0);
|
125 | 102 |
|
126 |
| - { |
127 |
| - std::sort(single_links.begin(), single_links.end()); |
128 |
| - xr_vector<u32>::iterator I = std::unique(single_links.begin(), single_links.end()); |
129 |
| - single_links.erase(I, single_links.end()); |
130 |
| - } |
| 103 | + std::sort(single_links.begin(), single_links.end()); |
| 104 | + auto I = std::unique(single_links.begin(), single_links.end()); |
| 105 | + single_links.erase(I, single_links.end()); |
131 | 106 |
|
132 | 107 | if (!no_single_links)
|
133 | 108 | {
|
134 | 109 | if (verbose)
|
135 |
| - { |
136 |
| - xr_vector<u32>::const_iterator I = single_links.begin(); |
137 |
| - xr_vector<u32>::const_iterator E = single_links.end(); |
138 |
| - for (; I != E; ++I) |
139 |
| - Msg("Vertex %d[%f][%f][%f] is single linked!", *I, VPUSH(level_graph->vertex_position(*I))); |
140 |
| - } |
| 110 | + for (const auto &i : single_links) |
| 111 | + Msg("Vertex %d[%f][%f][%f] is single linked!", i, VPUSH(level_graph.vertex_position(i))); |
141 | 112 | Msg("There are %d single linked nodes!", single_links.size());
|
142 | 113 | }
|
143 | 114 |
|
144 | 115 | Logger.Progress(0.15f);
|
| 116 | + CLevelGraph::CVertex** stack_storage = (CLevelGraph::CVertex**)xr_malloc(level_graph.header().vertex_count() * sizeof(CLevelGraph::CVertex*)); |
| 117 | + xr_vector<bool> marks; |
145 | 118 | bool valid = true;
|
146 |
| - xr_vector<u32>::const_iterator I = single_links.begin(); |
147 |
| - xr_vector<u32>::const_iterator E = single_links.end(); |
148 |
| - for (u32 i = 0, n = single_links.size(); I != E; ++I, ++i) |
| 119 | + for (auto &i : single_links) |
149 | 120 | {
|
150 |
| - marks.assign(level_graph->header().vertex_count(), false); |
151 |
| - floodfill(*level_graph, marks, *I); |
152 |
| - xr_vector<bool>::const_iterator II = marks.begin(), BB = II; |
153 |
| - xr_vector<bool>::const_iterator EE = marks.end(); |
154 |
| - for (; II != EE; ++II) |
155 |
| - if (!*II) |
| 121 | + marks.assign(level_graph.header().vertex_count(), false); |
| 122 | + floodfill(level_graph, stack_storage, marks, i); |
| 123 | + for (auto &j : marks) |
| 124 | + { |
| 125 | + if (!j) |
156 | 126 | {
|
157 | 127 | valid = false;
|
| 128 | + auto J = std::distance(&marks.front(), &j); |
158 | 129 | Msg("AI-map is NOT valid :\nNode \n%6d[%f][%f][%f]\ncannot be reached from the node\n%6d[%f][%f][%f]\n",
|
159 |
| - u32(II - BB), VPUSH(level_graph->vertex_position(u32(II - BB))), *I, |
160 |
| - VPUSH(level_graph->vertex_position(*I))); |
| 130 | + J, VPUSH(level_graph.vertex_position(J)), |
| 131 | + i, VPUSH(level_graph.vertex_position(i))); |
161 | 132 | break;
|
162 | 133 | }
|
| 134 | + } |
163 | 135 |
|
164 | 136 | if (!valid)
|
165 | 137 | break;
|
166 |
| - Logger.Progress(0.15f + 0.85f * float(i) / float(n)); |
| 138 | + Logger.Progress(0.15f + 0.85f * float(std::distance(&single_links.front(), &i)) / float(single_links.size())); |
167 | 139 | }
|
168 | 140 |
|
169 | 141 | xr_free(stack_storage);
|
170 |
| - xr_delete(level_graph); |
171 | 142 | Logger.Progress(1.f);
|
| 143 | + |
172 | 144 | if (valid)
|
173 | 145 | Msg("AI-map is valid!");
|
174 | 146 |
|
|
0 commit comments