File: PathFinderDef.cpp

package info (click to toggle)
spring 88.0%2Bdfsg1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 41,524 kB
  • sloc: cpp: 343,114; ansic: 38,414; python: 12,257; java: 12,203; awk: 5,748; sh: 1,204; xml: 997; perl: 405; objc: 192; makefile: 181; php: 134; sed: 2
file content (91 lines) | stat: -rwxr-xr-x 3,051 bytes parent folder | download
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));
}