6 #include <unordered_map>
21 using std::unordered_map;
39 std::hash<uint64_t> hashVal;
40 return hashVal(get<0>(k) ^ get<1>(k));
54 for (
const auto& [cellId, cell]:
cells)
delete cell;
73 inline void addCell(
const tuple<int, int>&
id,
const Vector3& position,
bool walkable,
const Vector3& direction,
int pathIdx) {
81 inline bool hasCell(
const tuple<int, int>&
id)
const {
82 auto cellIt =
cells.find(
id);
83 return cellIt !=
cells.end();
93 inline const tuple<int, int>
toId(
float x,
float z)
const {
104 inline static const tuple<int, int>
toId(
float x,
float z,
float stepSize) {
105 return tuple<int, int> {
static_cast<int>(Math::ceil(x /
stepSize)),
static_cast<int>(Math::ceil(z /
stepSize)) };
150 inline static const tuple<int, int>
toIdInt(
int x,
int z) {
151 return tuple<int, int> { x, z };
192 inline const vector<Vector3>&
getPath()
const {
202 auto cellIt =
cells.find(
id);
203 if (cellIt ==
cells.end())
return nullptr;
204 return cellIt->second;
213 auto cellIt =
cells.find(
id);
214 if (cellIt ==
cells.end())
return nullptr;
215 return cellIt->second;
229 auto cellIt =
cells.find(
id);
230 if (cellIt ==
cells.end())
return nullptr;
231 return cellIt->second;
245 auto cellIt =
cells.find(cellId);
246 if (cellIt ==
cells.end())
return nullptr;
247 return cellIt->second;
262 if (f00 ==
nullptr)
return Vector3();
267 auto top = f10 !=
nullptr?f00->getDirection().clone().scale(1.0f - xWeight).add(f10->getDirection().clone().scale(xWeight)):f00->getDirection();
268 auto bottom = f01 !=
nullptr && f11 !=
nullptr?f01->getDirection().clone().scale(1.0f - xWeight).add(f11->getDirection().clone().scale(xWeight)):top;
270 auto direction = top.clone().scale(1.0f - yWeight).add(bottom.clone().scale(yWeight)).normalize();
287 auto cellIt =
cells.find(
id);
288 if (cellIt ==
cells.end())
return;
301 auto pathSize =
path.size();
302 for (
const auto& pathNode: flowMap->
path) {
303 path.push_back(pathNode);
307 for (
const auto& [cellId, cell]: flowMap->
cells) {
308 auto clonedCell = cell->clone();
309 clonedCell->pathNodeIdx+= pathSize;
310 cells[cellId] = clonedCell;
313 for (
const auto& [cellId, flowMapCell]: flowMap->
cells) {
315 cell->setMissingNeighborCell(
false);
318 auto hadMissingNeighborCell =
false;
319 for (
auto nZ = -1; nZ < 2 && hadMissingNeighborCell ==
false; nZ++) {
320 for (
auto nX = -1; nX < 2 && hadMissingNeighborCell ==
false; nX++) {
321 if (nZ == 0 && nX == 0)
continue;
326 auto neighbourCell =
getCell(neighbourCellId);
327 if (neighbourCell ==
nullptr) {
328 cell->setMissingNeighborCell(
true);
329 hadMissingNeighborCell =
true;
349 auto halfSteps = steps / 2;
352 for (
auto nZ = -halfSteps; nZ < halfSteps; nZ++) {
353 for (
auto nX = -halfSteps; nX < halfSteps; nX++) {
358 auto cellCandidate =
getCell(cellId);
359 if (cellCandidate ==
nullptr)
continue;
360 auto cellCandidateDistanceSquared = cellCandidate->getPosition().clone().sub(position).computeLengthSquared();
361 if (cellBestFit ==
nullptr || cellCandidateDistanceSquared < cellBestFitDistanceSquared) {
362 cellBestFit = cellCandidate;
363 cellBestFitDistanceSquared = cellCandidateDistanceSquared;
Vector3 class representing vector3 mathematical structure and operations with x, y,...
static constexpr float MAX_VALUE
FlowMapCell * getCell(const tuple< int, int > &id)
Get cell by id.
const unordered_map< tuple< int, int >, FlowMapCell *, FlowMapCellId_Hash > & getCellMap() const
Cell map getter.
const tuple< int, int > toId(float x, float z) const
Return string representation of given x,z for flow map cell id.
const vector< Vector3 > & getPath() const
Returns path flow map is generated on.
const Vector3 computeDirection(float x, float z) const
Compute direction also taking neighbour cells into account.
int getIntegerPositionComponent(float value) const
Returns integer position component.
FlowMapCell * getCell(float x, float z)
Get cell by position.
void addCell(const tuple< int, int > &id, const Vector3 &position, bool walkable, const Vector3 &direction, int pathIdx)
Adds a cell to flow map.
unordered_map< tuple< int, int >, FlowMapCell *, FlowMapCellId_Hash > cells
const FlowMapCell * getCell(float x, float z) const
Get cell by position.
void setComplete(bool complete)
Set flow map complete flag.
const FlowMapCell * getCell(const tuple< int, int > &id) const
Get cell by id.
FlowMapCell * findNearestCell(float x, float z, int steps=8)
Find nearest cell, which can be used if outside of flow map to find back in.
vector< Vector3 > endPositions
static int getIntegerPositionComponent(float value, float stepSize)
Returns integer position component.
const vector< Vector3 > & getEndPositions() const
Returns end positions.
void merge(const FlowMap *flowMap)
Merge given flow map into this flow map, please note that given flow map step size needs to match thi...
float getStepSize() const
bool hasCell(const tuple< int, int > &id) const
Checks if a cell exists in flow map.
static const tuple< int, int > toId(float x, float z, float stepSize)
Return string representation of given x,z for flow map cell id.
float alignPositionComponent(float value) const
Align position component.
~FlowMap()
Private destructor.
void removeCell(const tuple< int, int > &id)
Remove cell by id.
static const tuple< int, int > toIdInt(int x, int z)
Return string representation of given x,z integer flow map position representation for flow map cell ...
static float alignPositionComponent(float value, float stepSize)
Align position component.
Reference counter implementation to be used with inheritance.
std::size_t operator()(const tuple< int, int > &k) const
#define FORBID_CLASS_COPY(CLASS)