-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathintegration_field.h
More file actions
236 lines (210 loc) Β· 7.6 KB
/
Copy pathintegration_field.h
File metadata and controls
236 lines (210 loc) Β· 7.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
#pragma once
#include <cstddef>
#include <deque>
#include <memory>
#include <unordered_set>
#include <vector>
#include "pathfinding/types.h"
namespace openage {
namespace coord {
struct tile_delta;
} // namespace coord
namespace path {
class CostField;
class Portal;
/**
* Integration field in the flow-field pathfinding algorithm.
*/
class IntegrationField {
public:
/**
* Create a square integration field with a specified size.
*
* @param size Side length of the field.
*/
IntegrationField(size_t size);
/**
* Get the size of the integration field.
*
* @return Size of the integration field.
*/
size_t get_size() const;
/**
* Get the integration value at a specified position.
*
* @param pos Coordinates of the cell (relative to field origin).
* @return Integration value at the specified position.
*/
const integrated_t &get_cell(const coord::tile_delta &pos) const;
/**
* Get the integration value at a specified position.
*
* @param x X-coordinate of the cell.
* @param y Y-coordinate of the cell.
* @return Integration value at the specified position.
*/
const integrated_t &get_cell(size_t x, size_t y) const;
/**
* Get the integration value at a specified position.
*
* @param idx Index of the cell.
* @return Integration value at the specified position.
*/
const integrated_t &get_cell(size_t idx) const;
/**
* Calculate the line-of-sight integration flags for a target cell.
*
* The target cell coordinates must lie within the field.
*
* Returns a list of cells that are flagged as "wavefront blocked". These cells
* can be used as a starting point for the cost integration.
*
* @param cost_field Cost field to integrate.
* @param target Coordinates of the target cell (relative to field origin).
*
* @return Cells flagged as "wavefront blocked".
*/
std::vector<size_t> integrate_los(const std::shared_ptr<CostField> &cost_field,
const coord::tile_delta &target);
/**
* Calculate the line-of-sight integration flags starting from a portal to another
* integration field.
*
* Returns a list of cells that are flagged as "wavefront blocked". These cells
* can be used as a starting point for the cost integration.
*
* @param cost_field Cost field to integrate.
* @param other Integration field of the other sector.
* @param other_sector_id Sector ID of the other integration field.
* @param portal Portal connecting the two fields.
* @param target Coordinates of the target cell (relative to field origin).
*
* @return Cells flagged as "wavefront blocked".
*/
std::vector<size_t> integrate_los(const std::shared_ptr<CostField> &cost_field,
const std::shared_ptr<IntegrationField> &other,
sector_id_t other_sector_id,
const std::shared_ptr<Portal> &portal,
const coord::tile_delta &target);
/**
* Calculate the line-of-sight integration flags for a target cell.
*
* Returns a list of cells that are flagged as "wavefront blocked". These cells
* can be used as a starting point for the cost integration.
*
* @param cost_field Cost field to integrate.
* @param target Coordinates of the target cell (relative to field origin).
* @param start_cost Integration cost for the start wave.
* @param start_wave Cells used for the first LOS integration wave. The wavefront
* expands outwards from these cells.
*
* @return Cells flagged as "wavefront blocked".
*/
std::vector<size_t> integrate_los(const std::shared_ptr<CostField> &cost_field,
const coord::tile_delta &target,
integrated_cost_t start_cost,
std::vector<size_t> &&start_wave);
/**
* Calculate the cost integration field starting from a target cell.
*
* @param cost_field Cost field to integrate.
* @param target Coordinates of the target cell.
*/
void integrate_cost(const std::shared_ptr<CostField> &cost_field,
const coord::tile_delta &target);
/**
* Calculate the cost integration field starting from a portal to another
* integration field.
*
* @param cost_field Cost field to integrate.
* @param other_sector_id Sector ID of the other integration field.
* @param portal Portal connecting the two fields.
*/
void integrate_cost(const std::shared_ptr<CostField> &cost_field,
sector_id_t other_sector_id,
const std::shared_ptr<Portal> &portal);
/**
* Calculate the cost integration field starting from a wavefront.
*
* @param cost_field Cost field to integrate.
* @param start_cells Cells flagged as "wavefront blocked" from a LOS pass.
*/
void integrate_cost(const std::shared_ptr<CostField> &cost_field,
std::vector<size_t> &&start_cells);
/**
* Get the integration field values.
*
* @return Integration field values.
*/
const std::vector<integrated_t> &get_cells() const;
/**
* Reset the integration field for a new integration.
*/
void reset();
/**
* Reset all flags that are dependent on the path target location. These
* flags should be removed when the field is cached and reused for
* other targets.
*
* Relevant flags are:
* - INTEGRATE_LOS_MASK
* - INTEGRATE_WAVEFRONT_BLOCKED_MASK
* - INTEGRATE_FOUND_MASK
*/
void reset_dynamic_flags();
private:
/**
* Update a neighbor cell during the cost integration process.
*
* @param idx Index of the neighbor cell that is updated.
* @param cell_cost Cost of the neighbor cell from the cost field.
* @param integrated_cost Current integrated cost of the updating cell in the integration field.
* @param wave List of cells that are part of the next wavefront.
*
* @return New integration value of the cell.
*/
void update_neighbor(size_t idx,
cost_t cell_cost,
integrated_cost_t integrated_cost,
std::vector<size_t> &wave);
/**
* Get the LOS corners around a cell.
*
* @param cost_field Cost field to integrate.
* @param target Cell coordinates of the target (relative to field origin).
* @param blocker Cell coordinates of the cell blocking LOS (relative to field origin).
*
* @return Field coordinates of the LOS corners.
*/
std::vector<std::pair<int, int>> get_los_corners(const std::shared_ptr<CostField> &cost_field,
const coord::tile_delta &target,
const coord::tile_delta &blocker);
/**
* Get the cells in a bresenham's line between the corner cell and the field edge.
*
* This function is a modified version of the bresenham's line algorithm that
* retrieves the cells between the corner point and the field's edge, rather than
* the cells between two arbitrary points. We do this because the intersection
* point with the field edge is unknown.
*
* @param target Cell coordinates of the target (relative to field origin).
* @param corner_x X field coordinate edge of the LOS corner.
* @param corner_y Y field coordinate edge of the LOS corner.
*
* @return Cell indices of the LOS line.
*/
std::vector<size_t> bresenhams_line(const coord::tile_delta &target,
int corner_x,
int corner_y);
/**
* Side length of the field.
*/
size_t size;
/**
* Integration field values.
*/
std::vector<integrated_t> cells;
};
} // namespace path
} // namespace openage