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
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include "PathFinderDef.h"
#include "Map/ReadMap.h"
#include "Sim/MoveTypes/MoveInfo.h"
#include "Sim/Misc/GlobalSynced.h"
CPathFinderDef::CPathFinderDef(const float3& goalCenter, float goalRadius, float sqGoalDistance):
goal(goalCenter),
sqGoalRadius(goalRadius * goalRadius)
{
// make sure that the goal can be reached with 2-square resolution
if (sqGoalRadius < (SQUARE_SIZE * SQUARE_SIZE * 2))
sqGoalRadius = (SQUARE_SIZE * SQUARE_SIZE * 2);
startInGoalRadius = sqGoalRadius >= sqGoalDistance;
goalSquareX = int(goalCenter.x / SQUARE_SIZE);
goalSquareZ = int(goalCenter.z / SQUARE_SIZE);
}
// returns true when the goal is within our defined range
bool CPathFinderDef::IsGoal(int xSquare, int zSquare) const {
return (SquareToFloat3(xSquare, zSquare).SqDistance2D(goal) <= sqGoalRadius);
}
// returns distance to goal center in mapsquares
float CPathFinderDef::Heuristic(int xSquare, int zSquare) const
{
const int x = abs(xSquare - goalSquareX);
const int z = abs(zSquare - goalSquareZ);
return std::max(x, z) * 0.5f + std::min(x, z) * 0.2f;
}
// returns if the goal is inaccessable: this is
// true if the goal area is "small" and blocked
bool CPathFinderDef::GoalIsBlocked(const MoveData& moveData, const CMoveMath::BlockType& moveMathOptions) const {
const float r0 = SQUARE_SIZE * SQUARE_SIZE * 4;
const float r1 = ((moveData.xsize * SQUARE_SIZE) >> 1) * ((moveData.zsize * SQUARE_SIZE) >> 1) * 1.5f;
return
((sqGoalRadius < r0 || sqGoalRadius <= r1) &&
(moveData.moveMath->IsBlocked(moveData, goal) & moveMathOptions));
}
int2 CPathFinderDef::GoalSquareOffset(int blockSize) const {
const int blockPixelSize = blockSize * SQUARE_SIZE;
int2 offset;
offset.x = ((int) goal.x % blockPixelSize) / SQUARE_SIZE;
offset.y = ((int) goal.z % blockPixelSize) / SQUARE_SIZE;
return offset;
}
CRangedGoalWithCircularConstraint::CRangedGoalWithCircularConstraint(const float3& start, const float3& goal, float goalRadius, float searchSize, int extraSize):
CPathFinderDef(goal, goalRadius, start.SqDistance2D(goal))
{
disabled = false;
// calculate the center and radius of the constrained area
const int startX = int(start.x / SQUARE_SIZE);
const int startZ = int(start.z / SQUARE_SIZE);
float3 halfWay = (start + goal) * 0.5f;
halfWayX = int(halfWay.x/SQUARE_SIZE);
halfWayZ = int(halfWay.z/SQUARE_SIZE);
const int dx = startX - halfWayX;
const int dz = startZ - halfWayZ;
searchRadiusSq = dx * dx + dz * dz;
searchRadiusSq *= int(searchSize * searchSize);
searchRadiusSq += extraSize;
}
// tests if a square is inside is the circular constrained area
// defined by the start and goal positions (disabled: this only
// saves CPU under certain conditions and destroys admissibility)
bool CRangedGoalWithCircularConstraint::WithinConstraints(int xSquare, int zSquare) const
{
const int dx = halfWayX - xSquare;
const int dz = halfWayZ - zSquare;
return (disabled || ((dx * dx + dz * dz) <= searchRadiusSq));
}
|