Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
CCmpPathfinder_Common.h
Go to the documentation of this file.
1/* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef INCLUDED_CCMPPATHFINDER_COMMON
19#define INCLUDED_CCMPPATHFINDER_COMMON
20
21/**
22 * @file
23 * Declares CCmpPathfinder. Its implementation is mainly done in CCmpPathfinder.cpp,
24 * but the short-range (vertex) pathfinding is done in CCmpPathfinder_Vertex.cpp.
25 * This file provides common code needed for both files.
26 *
27 * The long-range pathfinding is done by a LongPathfinder object.
28 */
29
31
32#include "ICmpPathfinder.h"
33
34#include "graphics/Overlay.h"
35#include "graphics/Terrain.h"
36#include "maths/MathUtil.h"
37#include "ps/CLogger.h"
38#include "ps/TaskManager.h"
42
43#include <vector>
44
46class LongPathfinder;
48
49class SceneCollector;
50class AtlasOverlay;
51
52#ifdef NDEBUG
53#define PATHFIND_DEBUG 0
54#else
55#define PATHFIND_DEBUG 1
56#endif
57
58/**
59 * Implementation of ICmpPathfinder
60 */
61class CCmpPathfinder final : public ICmpPathfinder
62{
63public:
64 static void ClassInit(CComponentManager& componentManager)
65 {
66 componentManager.SubscribeToMessageType(MT_Deserialized);
67 componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays
68 componentManager.SubscribeToMessageType(MT_TerrainChanged);
69 componentManager.SubscribeToMessageType(MT_WaterChanged);
70 componentManager.SubscribeToMessageType(MT_ObstructionMapShapeChanged);
71 }
72
74
76
77 // Template state:
78
81 u16 m_MaxSameTurnMoves; // Compute only this many paths when useMax is true in StartProcessingMoves.
82
83 // Dynamic state:
84
85 // Lazily-constructed dynamic state (not serialized):
86
87 u16 m_GridSize; // Navcells per side of the map.
88 Grid<NavcellData>* m_Grid; // terrain/passability information
89 Grid<NavcellData>* m_TerrainOnlyGrid; // same as m_Grid, but only with terrain, to avoid some recomputations
90
91 // Keep clever updates in memory to avoid memory fragmentation from the grid.
92 // This should be used only in UpdateGrid(), there is no guarantee the data is properly initialized anywhere else.
94 // The data from clever updates is stored for the AI manager
97
101
102 // One per live asynchronous path computing task.
103 std::vector<Future<void>> m_Futures;
104
105 template<typename T>
107 public:
108 std::vector<T> m_Requests;
109 std::vector<PathResult> m_Results;
110 // This is the array index of the next path to compute.
111 std::atomic<size_t> m_NextPathToCompute = 0;
112 // This is false until all scheduled paths have been computed.
113 std::atomic<bool> m_ComputeDone = true;
114
116 {
117 if (m_Results.size() == m_Requests.size())
118 m_Requests.clear();
119 else
120 m_Requests.erase(m_Requests.end() - m_Results.size(), m_Requests.end());
121 m_Results.clear();
122 }
123
124 /**
125 * @param max - if non-zero, how many paths to process.
126 */
128 {
129 size_t n = m_Requests.size();
130 if (max && n > max)
131 n = max;
132 m_NextPathToCompute = 0;
133 m_Results.resize(n);
134 m_ComputeDone = n == 0;
135 }
136
137 template<typename U>
138 void Compute(const CCmpPathfinder& cmpPathfinder, const U& pathfinder);
139 };
142
143 u32 m_NextAsyncTicket; // Unique IDs for asynchronous path requests.
144
146
147 static std::string GetSchema()
148 {
149 return "<a:component type='system'/><empty/>";
150 }
151
152 void Init(const CParamNode& paramNode) override;
153
154 void Deinit() override;
155
156 template<typename S>
157 void SerializeCommon(S& serialize);
158
159 void Serialize(ISerializer& serialize) override;
160
161 void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) override;
162
163 void HandleMessage(const CMessage& msg, bool global) override;
164
165 pass_class_t GetPassabilityClass(const std::string& name) const override;
166
167 void GetPassabilityClasses(std::map<std::string, pass_class_t>& passClasses) const override;
169 std::map<std::string, pass_class_t>& nonPathfindingPassClasses,
170 std::map<std::string, pass_class_t>& pathfindingPassClasses) const override;
171
173
174 entity_pos_t GetClearance(pass_class_t passClass) const override
175 {
176 const PathfinderPassability* passability = GetPassabilityFromMask(passClass);
177 if (!passability)
178 return fixed::Zero();
179
180 return passability->m_Clearance;
181 }
182
184 {
186
187 for (const PathfinderPassability& passability : m_PassClasses)
188 if (passability.m_Clearance > max)
189 max = passability.m_Clearance;
190
192 }
193
194 const Grid<NavcellData>& GetPassabilityGrid() override;
195
197 {
199 }
200
202 {
204 }
205
206 Grid<u16> ComputeShoreGrid(bool expandOnWater = false) override;
207
208 void ComputePathImmediate(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass, WaypointPath& ret) const override;
209
210 u32 ComputePathAsync(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass, entity_id_t notify) override;
211
212 WaypointPath ComputeShortPathImmediate(const ShortPathRequest& request) const override;
213
214 u32 ComputeShortPathAsync(entity_pos_t x0, entity_pos_t z0, entity_pos_t clearance, entity_pos_t range, const PathGoal& goal, pass_class_t passClass, bool avoidMovingUnits, entity_id_t controller, entity_id_t notify) override;
215
216 bool IsGoalReachable(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass) override;
217
218 void SetDebugPath(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass) override;
219
220 void SetDebugOverlay(bool enabled) override;
221
222 void SetHierDebugOverlay(bool enabled) override;
223
224 void GetDebugData(u32& steps, double& time, Grid<u8>& grid) const override;
225
226 void SetAtlasOverlay(bool enable, pass_class_t passClass = 0) override;
227
228 bool CheckMovement(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, pass_class_t passClass) const override;
229
230 ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint) const override;
231
233
235
236 void SendRequestedPaths() override;
237
238 void StartProcessingMoves(bool useMax) override;
239
240 template <typename T>
241 std::vector<T> GetMovesToProcess(std::vector<T>& requests, bool useMax = false, size_t maxMoves = 0);
242
243 template <typename T>
244 void PushRequestsToWorkers(std::vector<T>& from);
245
246 /**
247 * Regenerates the grid based on the current obstruction list, if necessary
248 */
249 void UpdateGrid() override;
250
251 /**
252 * Updates the terrain-only grid without updating the dirtiness informations.
253 * Useful for fast passability updates in Atlas.
254 */
255 void MinimalTerrainUpdate(int itile0, int jtile0, int itile1, int jtile1);
256
257 /**
258 * Regenerates the terrain-only grid.
259 * Atlas doesn't need to have passability cells expanded.
260 */
261 void TerrainUpdateHelper(bool expandPassability = true, int itile0 = -1, int jtile0 = -1, int itile1 = -1, int jtile1 = -1);
262
263 void RenderSubmit(SceneCollector& collector);
264};
265
267{
268public:
271
272 AtlasOverlay(const CCmpPathfinder* pathfinder, pass_class_t passClass) :
274 {
275 }
276
277 void BuildTextureRGBA(u8* data, size_t w, size_t h) override
278 {
279 // Render navcell passability, based on the terrain-only grid
280 u8* p = data;
281 for (size_t j = 0; j < h; ++j)
282 {
283 for (size_t i = 0; i < w; ++i)
284 {
285 SColor4ub color(0, 0, 0, 0);
287 color = SColor4ub(255, 0, 0, 127);
288
289 *p++ = color.R;
290 *p++ = color.G;
291 *p++ = color.B;
292 *p++ = color.A;
293 }
294 }
295 }
296};
297
298#endif // INCLUDED_CCMPPATHFINDER_COMMON
#define DEFAULT_COMPONENT_ALLOCATOR(cname)
Definition: Component.h:39
u16 NavcellData
Definition: ICmpObstructionManager.h:32
#define IS_PASSABLE(item, classmask)
Definition: Pathfinding.h:127
u16 pass_class_t
Definition: Pathfinding.h:29
Definition: CCmpPathfinder_Common.h:267
const CCmpPathfinder * m_Pathfinder
Definition: CCmpPathfinder_Common.h:269
pass_class_t m_PassClass
Definition: CCmpPathfinder_Common.h:270
void BuildTextureRGBA(u8 *data, size_t w, size_t h) override
Called each frame to generate the texture to render on the terrain.
Definition: CCmpPathfinder_Common.h:277
AtlasOverlay(const CCmpPathfinder *pathfinder, pass_class_t passClass)
Definition: CCmpPathfinder_Common.h:272
Definition: CCmpPathfinder_Common.h:106
void ClearComputed()
Definition: CCmpPathfinder_Common.h:115
void PrepareForComputation(u16 max)
Definition: CCmpPathfinder_Common.h:127
std::vector< T > m_Requests
Definition: CCmpPathfinder_Common.h:108
std::vector< PathResult > m_Results
Definition: CCmpPathfinder_Common.h:109
Implementation of ICmpPathfinder.
Definition: CCmpPathfinder_Common.h:62
bool CheckMovement(const IObstructionTestFilter &filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, pass_class_t passClass) const override
Check whether the given movement line is valid and doesn't hit any obstructions or impassable terrain...
Definition: CCmpPathfinder.cpp:857
GridUpdateInformation m_DirtinessInformation
Definition: CCmpPathfinder_Common.h:93
void StartProcessingMoves(bool useMax) override
Tell asynchronous pathfinder threads that they can begin computing paths.
Definition: CCmpPathfinder.cpp:823
void Deserialize(const CParamNode &paramNode, IDeserializer &deserialize) override
Definition: CCmpPathfinder.cpp:164
void HandleMessage(const CMessage &msg, bool global) override
Definition: CCmpPathfinder.cpp:171
void Serialize(ISerializer &serialize) override
Definition: CCmpPathfinder.cpp:159
static std::string GetSchema()
Definition: CCmpPathfinder_Common.h:147
u16 m_GridSize
Definition: CCmpPathfinder_Common.h:87
void MinimalTerrainUpdate(int itile0, int jtile0, int itile1, int jtile1)
Updates the terrain-only grid without updating the dirtiness informations.
Definition: CCmpPathfinder.cpp:574
GridUpdateInformation m_AIPathfinderDirtinessInformation
Definition: CCmpPathfinder_Common.h:95
AtlasOverlay * m_AtlasOverlay
Definition: CCmpPathfinder_Common.h:145
entity_pos_t GetMaximumClearance() const override
Get the larger clearance in all passability classes.
Definition: CCmpPathfinder_Common.h:183
const GridUpdateInformation & GetAIPathfinderDirtinessInformation() const override
Get the accumulated dirtiness information since the last time the AI accessed and flushed it.
Definition: CCmpPathfinder_Common.h:196
void SetDebugOverlay(bool enabled) override
Toggle the storage and rendering of debug info.
Definition: CCmpPathfinder.cpp:216
void GetPassabilityClasses(std::map< std::string, pass_class_t > &passClasses) const override
Get the list of all known passability classes.
Definition: CCmpPathfinder.cpp:256
void TerrainUpdateHelper(bool expandPassability=true, int itile0=-1, int jtile0=-1, int itile1=-1, int jtile1=-1)
Regenerates the terrain-only grid.
Definition: CCmpPathfinder.cpp:579
u16 m_MaxSameTurnMoves
Definition: CCmpPathfinder_Common.h:81
std::vector< Future< void > > m_Futures
Definition: CCmpPathfinder_Common.h:103
void UpdateGrid() override
Regenerates the grid based on the current obstruction list, if necessary.
Definition: CCmpPathfinder.cpp:481
void SetDebugPath(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass) override
If the debug overlay is enabled, render the path that will computed by ComputePath.
Definition: CCmpPathfinder.cpp:211
static void ClassInit(CComponentManager &componentManager)
Definition: CCmpPathfinder_Common.h:64
void SendRequestedPaths() override
Finish computing asynchronous path requests and send the CMessagePathResult messages.
Definition: CCmpPathfinder.cpp:790
void SetHierDebugOverlay(bool enabled) override
Toggle the storage and rendering of debug info for the hierarchical pathfinder.
Definition: CCmpPathfinder.cpp:222
std::vector< PathfinderPassability > m_PassClasses
Definition: CCmpPathfinder_Common.h:80
u32 ComputeShortPathAsync(entity_pos_t x0, entity_pos_t z0, entity_pos_t clearance, entity_pos_t range, const PathGoal &goal, pass_class_t passClass, bool avoidMovingUnits, entity_id_t controller, entity_id_t notify) override
Request a short path computation, asynchronously.
Definition: CCmpPathfinder.cpp:744
Grid< NavcellData > * m_TerrainOnlyGrid
Definition: CCmpPathfinder_Common.h:89
void SerializeCommon(S &serialize)
Definition: CCmpPathfinder.cpp:151
void SetAtlasOverlay(bool enable, pass_class_t passClass=0) override
Sets up the pathfinder passability overlay in Atlas.
Definition: CCmpPathfinder.cpp:232
void RenderSubmit(SceneCollector &collector)
Definition: CCmpPathfinder.cpp:205
ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter &filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint) const override
Check whether a unit placed here is valid and doesn't hit any obstructions or impassable terrain.
Definition: CCmpPathfinder.cpp:875
const PathfinderPassability * GetPassabilityFromMask(pass_class_t passClass) const
Definition: CCmpPathfinder.cpp:272
std::unique_ptr< LongPathfinder > m_LongPathfinder
Definition: CCmpPathfinder_Common.h:100
pass_class_t GetPassabilityClass(const std::string &name) const override
Get the tag for a given passability class name.
Definition: CCmpPathfinder.cpp:244
entity_pos_t GetClearance(pass_class_t passClass) const override
Definition: CCmpPathfinder_Common.h:174
void ComputePathImmediate(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass, WaypointPath &ret) const override
Definition: CCmpPathfinder.cpp:753
std::map< std::string, pass_class_t > m_PassClassMasks
Definition: CCmpPathfinder_Common.h:79
std::vector< T > GetMovesToProcess(std::vector< T > &requests, bool useMax=false, size_t maxMoves=0)
PathRequests< ShortPathRequest > m_ShortPathRequests
Definition: CCmpPathfinder_Common.h:141
bool IsGoalReachable(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass) override
Definition: CCmpPathfinder.cpp:845
ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter &filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) const override
Check whether a building placed here is valid and doesn't hit any obstructions or impassable terrain.
Definition: CCmpPathfinder.cpp:900
u32 ComputePathAsync(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass, entity_id_t notify) override
Asynchronous version of ComputePath.
Definition: CCmpPathfinder.cpp:737
void FlushAIPathfinderDirtinessInformation() override
Definition: CCmpPathfinder_Common.h:201
void Init(const CParamNode &paramNode) override
Definition: CCmpPathfinder.cpp:50
~CCmpPathfinder()
Definition: CCmpPathfinder.cpp:102
std::unique_ptr< HierarchicalPathfinder > m_PathfinderHier
Definition: CCmpPathfinder_Common.h:99
void GetDebugData(u32 &steps, double &time, Grid< u8 > &grid) const override
Returns some stats about the last ComputePath.
Definition: CCmpPathfinder.cpp:227
void PushRequestsToWorkers(std::vector< T > &from)
Grid< u16 > ComputeShoreGrid(bool expandOnWater=false) override
Get a grid representing the distance to the shore of the terrain tile.
Definition: CCmpPathfinder.cpp:364
std::vector< VertexPathfinder > m_VertexPathfinders
Definition: CCmpPathfinder_Common.h:98
u32 m_NextAsyncTicket
Definition: CCmpPathfinder_Common.h:143
bool m_TerrainDirty
Definition: CCmpPathfinder_Common.h:96
void Deinit() override
Definition: CCmpPathfinder.cpp:104
Grid< NavcellData > * m_Grid
Definition: CCmpPathfinder_Common.h:88
WaypointPath ComputeShortPathImmediate(const ShortPathRequest &request) const override
Definition: CCmpPathfinder.cpp:758
PathRequests< LongPathRequest > m_LongPathRequests
Definition: CCmpPathfinder_Common.h:140
const Grid< NavcellData > & GetPassabilityGrid() override
Definition: CCmpPathfinder.cpp:283
Definition: ComponentManager.h:40
void SubscribeToMessageType(MessageTypeId mtid)
Subscribe the current component type to the given message type.
Definition: ComponentManager.cpp:551
A simple fixed-point number class.
Definition: Fixed.h:120
static CFixed Zero()
Definition: Fixed.h:131
Definition: Message.h:26
An entity initialisation parameter node.
Definition: ParamNode.h:151
Corresponds to std::future.
Definition: Future.h:165
Basic 2D array, intended for storing tile data, plus support for lazy updates by ICmpObstructionManag...
Definition: Grid.h:38
T & get(std::pair< u16, u16 > coords)
Definition: Grid.h:222
Definition: HierarchicalPathfinder.h:61
EFoundationCheck
Definition: ICmpObstruction.h:33
Pathfinder algorithms.
Definition: ICmpPathfinder.h:60
Deserialization interface; see serialization overview.
Definition: IDeserializer.h:35
Interface for ICmpObstructionManager Test functions to filter out unwanted shapes.
Definition: ICmpObstructionManager.h:352
Serialization interface; see serialization overview.
Definition: ISerializer.h:121
Definition: LongPathfinder.h:165
Pathfinder goal.
Definition: PathGoal.h:33
Definition: Pathfinding.h:214
fixed m_Clearance
Definition: Pathfinding.h:225
This interface accepts renderable objects.
Definition: Scene.h:90
Base class for texture-based terrain overlays, with an arbitrary number of texels per terrain tile,...
Definition: TerrainOverlay.h:198
Definition: VertexPathfinder.h:76
Definition: Pathfinding.cpp:28
constexpr entity_pos_t CLEARANCE_EXTENSION_RADIUS
To make sure the long-range pathfinder is more strict than the short-range one, we need to slightly o...
Definition: Pathfinding.h:157
constexpr int NAVCELLS_PER_TERRAIN_TILE
The terrain grid is coarser, and it is often convenient to convert from one to the other.
Definition: Pathfinding.h:150
Definition: ShaderDefines.cpp:31
#define T(string_literal)
Definition: secure_crt.cpp:77
u32 entity_id_t
Entity ID type.
Definition: Entity.h:29
Structure holding grid dirtiness informations, for clever updates.
Definition: Grid.h:379
void Clean()
Mark everything as clean.
Definition: Grid.h:410
Definition: SColor.h:31
u8 R
Definition: SColor.h:32
u8 B
Definition: SColor.h:34
u8 G
Definition: SColor.h:33
u8 A
Definition: SColor.h:35
Definition: Pathfinding.h:44
Returned path.
Definition: Pathfinding.h:67
uint8_t u8
Definition: types.h:37
uint16_t u16
Definition: types.h:38
uint32_t u32
Definition: types.h:39