Pyrogenesis  trunk
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 
46 class LongPathfinder;
47 class VertexPathfinder;
48 
49 class SceneCollector;
50 class 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  */
61 class CCmpPathfinder final : public ICmpPathfinder
62 {
63 public:
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);
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>
106  class PathRequests {
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  {
185  entity_pos_t max = fixed::Zero();
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 {
268 public:
271 
272  AtlasOverlay(const CCmpPathfinder* pathfinder, pass_class_t passClass) :
273  TerrainTextureOverlay(Pathfinding::NAVCELLS_PER_TERRAIN_TILE), m_Pathfinder(pathfinder), m_PassClass(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);
286  if (!IS_PASSABLE(m_Pathfinder->m_TerrainOnlyGrid->get((int)i, (int)j), m_PassClass))
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
PathRequests< ShortPathRequest > m_ShortPathRequests
Definition: CCmpPathfinder_Common.h:141
An entity initialisation parameter node.
Definition: ParamNode.h:150
void SerializeCommon(S &serialize)
Definition: CCmpPathfinder.cpp:154
void SubscribeToMessageType(MessageTypeId mtid)
Subscribe the current component type to the given message type.
Definition: ComponentManager.cpp:549
A simple fixed-point number class.
Definition: Fixed.h:119
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&#39;t hit any obstructions or impassable terrain...
Definition: CCmpPathfinder.cpp:860
entity_pos_t GetClearance(pass_class_t passClass) const override
Definition: CCmpPathfinder_Common.h:174
Interface for ICmpObstructionManager Test functions to filter out unwanted shapes.
Definition: ICmpObstructionManager.h:351
pass_class_t m_PassClass
Definition: CCmpPathfinder_Common.h:270
static void ClassInit(CComponentManager &componentManager)
Definition: CCmpPathfinder_Common.h:64
u8 G
Definition: SColor.h:33
Implementation of ICmpPathfinder.
Definition: CCmpPathfinder_Common.h:61
u16 pass_class_t
Definition: Pathfinding.h:27
T & get(std::pair< u16, u16 > coords)
Definition: Grid.h:222
void ClearComputed()
Definition: CCmpPathfinder_Common.h:115
static CFixed Zero()
Definition: Fixed.h:131
Definition: Pathfinding.cpp:27
static std::string GetSchema()
Definition: CCmpPathfinder_Common.h:147
Definition: Pathfinding.h:213
Returned path.
Definition: Pathfinding.h:66
std::vector< PathfinderPassability > m_PassClasses
Definition: CCmpPathfinder_Common.h:80
void GetDebugData(u32 &steps, double &time, Grid< u8 > &grid) const override
Returns some stats about the last ComputePath.
Definition: CCmpPathfinder.cpp:230
uint16_t u16
Definition: types.h:38
const CCmpPathfinder * m_Pathfinder
Definition: CCmpPathfinder_Common.h:269
std::vector< T > GetMovesToProcess(std::vector< T > &requests, bool useMax=false, size_t maxMoves=0)
Serialization interface; see serialization overview.
Definition: ISerializer.h:120
#define IS_PASSABLE(item, classmask)
Definition: Pathfinding.h:127
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&#39;t hit any obstructions or impassable terrain...
Definition: CCmpPathfinder.cpp:878
void StartProcessingMoves(bool useMax) override
Tell asynchronous pathfinder threads that they can begin computing paths.
Definition: CCmpPathfinder.cpp:826
pass_class_t GetPassabilityClass(const std::string &name) const override
Get the tag for a given passability class name.
Definition: CCmpPathfinder.cpp:247
void SetHierDebugOverlay(bool enabled) override
Toggle the storage and rendering of debug info for the hierarchical pathfinder.
Definition: CCmpPathfinder.cpp:225
std::vector< Future< void > > m_Futures
Definition: CCmpPathfinder_Common.h:103
Definition: ShaderDefines.cpp:30
Pathfinder goal.
Definition: PathGoal.h:32
Structure holding grid dirtiness informations, for clever updates.
Definition: Grid.h:378
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&#39;t hit any obstructions or impassable terrain...
Definition: CCmpPathfinder.cpp:903
Basic 2D array, intended for storing tile data, plus support for lazy updates by ICmpObstructionManag...
Definition: TerritoryBoundary.h:27
EFoundationCheck
Definition: ICmpObstruction.h:33
std::vector< T > m_Requests
Definition: CCmpPathfinder_Common.h:108
u8 B
Definition: SColor.h:34
void Init(const CParamNode &paramNode) override
Definition: CCmpPathfinder.cpp:50
Definition: Components.h:83
uint8_t u8
Definition: types.h:37
Pathfinder algorithms.
Definition: ICmpPathfinder.h:59
void FlushAIPathfinderDirtinessInformation() override
Definition: CCmpPathfinder_Common.h:201
GridUpdateInformation m_AIPathfinderDirtinessInformation
Definition: CCmpPathfinder_Common.h:95
void RenderSubmit(SceneCollector &collector)
Definition: CCmpPathfinder.cpp:208
void MinimalTerrainUpdate(int itile0, int jtile0, int itile1, int jtile1)
Updates the terrain-only grid without updating the dirtiness informations.
Definition: CCmpPathfinder.cpp:577
This interface accepts renderable objects.
Definition: Scene.h:89
u8 A
Definition: SColor.h:35
WaypointPath ComputeShortPathImmediate(const ShortPathRequest &request) const override
Definition: CCmpPathfinder.cpp:761
Definition: LongPathfinder.h:164
Grid< NavcellData > * m_Grid
Definition: CCmpPathfinder_Common.h:88
Definition: Components.h:70
uint32_t u32
Definition: types.h:39
Definition: Pathfinding.h:43
Definition: HierarchicalPathfinder.h:60
Definition: ComponentManager.h:39
Grid< NavcellData > * m_TerrainOnlyGrid
Definition: CCmpPathfinder_Common.h:89
std::unique_ptr< HierarchicalPathfinder > m_PathfinderHier
Definition: CCmpPathfinder_Common.h:99
u16 m_MaxSameTurnMoves
Definition: CCmpPathfinder_Common.h:81
fixed m_Clearance
Definition: Pathfinding.h:225
Definition: VertexPathfinder.h:75
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:214
Definition: Components.h:85
u16 m_GridSize
Definition: CCmpPathfinder_Common.h:87
Definition: Components.h:81
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:747
entity_pos_t GetMaximumClearance() const override
Get the larger clearance in all passability classes.
Definition: CCmpPathfinder_Common.h:183
Definition: SColor.h:30
void GetPassabilityClasses(std::map< std::string, pass_class_t > &passClasses) const override
Get the list of all known passability classes.
Definition: CCmpPathfinder.cpp:259
u16 NavcellData
Definition: ICmpObstructionManager.h:32
void SetDebugOverlay(bool enabled) override
Toggle the storage and rendering of debug info.
Definition: CCmpPathfinder.cpp:219
Corresponds to std::future.
Definition: Future.h:145
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
#define DEFAULT_COMPONENT_ALLOCATOR(cname)
Definition: Component.h:39
AtlasOverlay * m_AtlasOverlay
Definition: CCmpPathfinder_Common.h:145
u8 R
Definition: SColor.h:32
Definition: CCmpPathfinder_Common.h:266
void PushRequestsToWorkers(std::vector< T > &from)
#define T(string_literal)
Definition: secure_crt.cpp:77
std::map< std::string, pass_class_t > m_PassClassMasks
Definition: CCmpPathfinder_Common.h:79
~CCmpPathfinder()
Definition: CCmpPathfinder.cpp:102
bool IsGoalReachable(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass) override
Definition: CCmpPathfinder.cpp:848
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
void ComputePathImmediate(entity_pos_t x0, entity_pos_t z0, const PathGoal &goal, pass_class_t passClass, WaypointPath &ret) const override
Definition: CCmpPathfinder.cpp:756
const Grid< NavcellData > & GetPassabilityGrid() override
Definition: CCmpPathfinder.cpp:286
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
GridUpdateInformation m_DirtinessInformation
Definition: CCmpPathfinder_Common.h:93
std::unique_ptr< LongPathfinder > m_LongPathfinder
Definition: CCmpPathfinder_Common.h:100
void PrepareForComputation(u16 max)
Definition: CCmpPathfinder_Common.h:127
Definition: CCmpPathfinder_Common.h:106
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
PathRequests< LongPathRequest > m_LongPathRequests
Definition: CCmpPathfinder_Common.h:140
void Clean()
Mark everything as clean.
Definition: Grid.h:410
Base class for texture-based terrain overlays, with an arbitrary number of texels per terrain tile...
Definition: TerrainOverlay.h:197
void Deinit() override
Definition: CCmpPathfinder.cpp:104
void Deserialize(const CParamNode &paramNode, IDeserializer &deserialize) override
Definition: CCmpPathfinder.cpp:167
Definition: Components.h:72
void HandleMessage(const CMessage &msg, bool global) override
Definition: CCmpPathfinder.cpp:174
void SetAtlasOverlay(bool enable, pass_class_t passClass=0) override
Sets up the pathfinder passability overlay in Atlas.
Definition: CCmpPathfinder.cpp:235
std::vector< VertexPathfinder > m_VertexPathfinders
Definition: CCmpPathfinder_Common.h:98
void UpdateGrid() override
Regenerates the grid based on the current obstruction list, if necessary.
Definition: CCmpPathfinder.cpp:484
AtlasOverlay(const CCmpPathfinder *pathfinder, pass_class_t passClass)
Definition: CCmpPathfinder_Common.h:272
Grid< u16 > ComputeShoreGrid(bool expandOnWater=false) override
Get a grid representing the distance to the shore of the terrain tile.
Definition: CCmpPathfinder.cpp:367
const PathfinderPassability * GetPassabilityFromMask(pass_class_t passClass) const
Definition: CCmpPathfinder.cpp:275
std::vector< PathResult > m_Results
Definition: CCmpPathfinder_Common.h:109
u32 entity_id_t
Entity ID type.
Definition: Entity.h:23
bool m_TerrainDirty
Definition: CCmpPathfinder_Common.h:96
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:740
u32 m_NextAsyncTicket
Definition: CCmpPathfinder_Common.h:143
void Serialize(ISerializer &serialize) override
Definition: CCmpPathfinder.cpp:162
void SendRequestedPaths() override
Finish computing asynchronous path requests and send the CMessagePathResult messages.
Definition: CCmpPathfinder.cpp:793
Deserialization interface; see serialization overview.
Definition: IDeserializer.h:34
Definition: Message.h:23
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:582