コード例 #1
0
ファイル: PathManager.cpp プロジェクト: nixtux/spring
/*
Request a new multipath, store the result and return a handle-id to it.
*/
unsigned int CPathManager::RequestPath(
	CSolidObject* caller,
	const MoveDef* moveDef,
	float3 startPos,
	float3 goalPos,
	float goalRadius,
	bool synced
) {
	if (!IsFinalized())
		return 0;

	// in misc since it is called from many points
	SCOPED_TIMER("Misc::Path::RequestPath");
	startPos.ClampInBounds();
	goalPos.ClampInBounds();

	// Create an estimator definition.
	goalRadius = std::max<float>(goalRadius, PATH_NODE_SPACING * SQUARE_SIZE); //FIXME do on a per PE & PF level?
	assert(moveDef == moveDefHandler->GetMoveDefByPathType(moveDef->pathType));

	MultiPath newPath = MultiPath(moveDef, startPos, goalPos, goalRadius);
	newPath.finalGoal = goalPos;
	newPath.caller = caller;
	newPath.peDef.synced = synced;

	if (caller != nullptr)
		caller->UnBlock();

	const IPath::SearchResult result = ArrangePath(&newPath, moveDef, startPos, goalPos, caller);

	unsigned int pathID = 0;

	if (result != IPath::Error) {
		if (newPath.maxResPath.path.empty()) {
			if (result != IPath::CantGetCloser) {
				LowRes2MedRes(newPath, startPos, caller, synced);
				MedRes2MaxRes(newPath, startPos, caller, synced);
			} else {
				// add one dummy waypoint so that the calling MoveType
				// does not consider this request a failure, which can
				// happen when startPos is very close to goalPos
				//
				// otherwise, code relying on MoveType::progressState
				// (eg. BuilderCAI::MoveInBuildRange) would misbehave
				// (eg. reject build orders)
				newPath.maxResPath.path.push_back(startPos);
				newPath.maxResPath.squares.push_back(int2(startPos.x / SQUARE_SIZE, startPos.z / SQUARE_SIZE));
			}
		}

		FinalizePath(&newPath, startPos, goalPos, result == IPath::CantGetCloser);
		newPath.searchResult = result;
		pathID = Store(newPath);
	}

	if (caller != nullptr)
		caller->Block();

	return pathID;
}
コード例 #2
0
ファイル: JPSPlus.cpp プロジェクト: maxrenke/gppc-2015
bool JPSPlus::GetPath(void *data, xyLocJPS& s, xyLocJPS& g, std::vector<xyLocJPS> &path)
{
	JPSPlus* Search = (JPSPlus*)data;

	if (path.size() > 0)
	{
		path.push_back(g);
		return true;
	}

	{
		// Initialize map
		int startRow = s.y;
		int startCol = s.x;
		m_goalRow = g.y;
		m_goalCol = g.x;

		path.clear();

		m_goalNode = &m_mapNodes[m_goalRow][m_goalCol];
		m_currentIteration++;

		m_openList.reset();
		m_openList.reserve(3000);

		// Push the starting node onto the Open list
		PathfindingNode* startNode = &m_mapNodes[startRow][startCol];
		startNode->m_parent = NULL;
		startNode->m_givenCost = 0;
		startNode->m_finalCost = 0;
		startNode->m_listStatus = PathfindingNode::OnOpen;
		startNode->m_iteration = m_currentIteration;
		m_openList.add(&m_mapNodes[startRow][startCol]);
	}

	PathStatus status = SearchLoop();

	if (status == PathFound)
	{
		FinalizePath(path);
		if (path.size() > 0)
		{
			path.pop_back();
			return false;
		}
		return true;
	}
	else
	{
		// No path
		return true;
	}
}
コード例 #3
0
ファイル: PathManager.cpp プロジェクト: nixtux/spring
/*
Removes and return the next waypoint in the multipath corresponding to given id.
*/
float3 CPathManager::NextWayPoint(
	const CSolidObject* owner,
	unsigned int pathID,
	unsigned int numRetries,
	float3 callerPos,
	float radius,
	bool synced
) {
	// in misc since it is called from many points
	SCOPED_TIMER("Misc::Path::NextWayPoint");

	const float3 noPathPoint = -XZVector;

	if (!IsFinalized())
		return noPathPoint;

	// 0 indicates the null-path ID
	if (pathID == 0)
		return noPathPoint;

	// find corresponding multipath entry
	MultiPath* multiPath = GetMultiPath(pathID);

	if (multiPath == nullptr)
		return noPathPoint;

	if (numRetries > MAX_PATH_REFINEMENT_DEPTH)
		return (multiPath->finalGoal);

	IPath::Path& maxResPath = multiPath->maxResPath;
	IPath::Path& medResPath = multiPath->medResPath;
	IPath::Path& lowResPath = multiPath->lowResPath;

	if ((callerPos == ZeroVector) && !maxResPath.path.empty())
		callerPos = maxResPath.path.back();

	assert(multiPath->peDef.synced == synced);

	#define EXTEND_PATH_POINTS(curResPts, nxtResPts, dist) ((!curResPts.empty() && (curResPts.back()).SqDistance2D(callerPos) < Square((dist))) || nxtResPts.size() <= 2)
	const bool extendMaxResPath = EXTEND_PATH_POINTS(medResPath.path, maxResPath.path, MAXRES_SEARCH_DISTANCE_EXT);
	const bool extendMedResPath = EXTEND_PATH_POINTS(lowResPath.path, medResPath.path, MEDRES_SEARCH_DISTANCE_EXT);
	#undef EXTEND_PATH_POINTS

	// check whether the max-res path needs extending through
	// recursive refinement of its lower-resolution segments
	// if so, check if the med-res path also needs extending
	if (extendMaxResPath) {
		if (multiPath->caller != nullptr)
			multiPath->caller->UnBlock();

		if (extendMedResPath)
			LowRes2MedRes(*multiPath, callerPos, owner, synced);

		MedRes2MaxRes(*multiPath, callerPos, owner, synced);

		if (multiPath->caller != nullptr)
			multiPath->caller->Block();

		FinalizePath(multiPath, callerPos, multiPath->finalGoal, multiPath->searchResult == IPath::CantGetCloser);
	}

	float3 waypoint = noPathPoint;

	do {
		// eat waypoints from the max-res path until we
		// find one that lies outside the search-radius
		// or equals the goal
		//
		// if this is not possible, then either we are
		// at the goal OR the path could not reach all
		// the way to it (ie. a GoalOutOfRange result)
		// OR we are stuck on an impassable square
		if (maxResPath.path.empty()) {
			if (lowResPath.path.empty() && medResPath.path.empty()) {
				if (multiPath->searchResult == IPath::Ok) {
					waypoint = multiPath->finalGoal; break;
				} else {
					// reached in the CantGetCloser case for any max-res searches
					// that start within their goal radius (ie. have no waypoints)
					// RequestPath always puts startPos into maxResPath to handle
					// this so waypoint will have been set to it (during previous
					// iteration) if we end up here
					break;
				}
			} else {
				waypoint = NextWayPoint(owner, pathID, numRetries + 1, callerPos, radius, synced);
				break;
			}
		} else {
			waypoint = maxResPath.path.back();
			maxResPath.path.pop_back();
		}
	} while ((callerPos.SqDistance2D(waypoint) < Square(radius)) && (waypoint != maxResPath.pathGoal));

	// y=0 indicates this is not a temporary waypoint
	// (the default PFS does not queue path-requests)
	return (waypoint * XZVector);
}