Esempio n. 1
0
bool QTPFS::PathCache::MarkDeadPaths(const SRectangle& r) {
	#ifdef QTPFS_IGNORE_DEAD_PATHS
	return false;
	#endif

	if (livePaths.empty())
		return false;

	// NOTE: not static, we run in multiple threads
	CollisionVolume rv;
	float3 rm;

	GetRectangleCollisionVolume(r, rv, rm);

	// "mark" any live path crossing the area of a terrain
	// deformation, for which some or all of its waypoints
	// might now be invalid and need to be recomputed
	//
	std::list<PathMapIt> livePathIts;

	for (PathMapIt it = livePaths.begin(); it != livePaths.end(); ++it) {
		IPath* path = it->second;

		const float3& pathMins = path->GetBoundingBoxMins();
		const float3& pathMaxs = path->GetBoundingBoxMaxs();

		// if rectangle does not overlap bounding-box, skip this path
		if (WS(r.x2) < pathMins.x) { continue; }
		if (WS(r.z2) < pathMins.z) { continue; }
		if (WS(r.x1) > pathMaxs.x) { continue; }
		if (WS(r.z1) > pathMaxs.z) { continue; }

		// figure out if <path> has at least one edge crossing <r>
		// we only care about the segments we have not yet visited
		for (unsigned int i = path->GetPointID(); i < (path->NumPoints() - 1); i++) {
			const float3& p0 = path->GetPoint(i    );
			const float3& p1 = path->GetPoint(i + 1);

			const bool pointInRect0 =
				((p0.x >= WS(r.x1) && p0.x < WS(r.x2)) &&
				 (p0.z >= WS(r.z1) && p0.z < WS(r.z2)));
			const bool pointInRect1 =
				((p1.x >= WS(r.x1) && p1.x < WS(r.x2)) &&
				 (p1.z >= WS(r.z1) && p1.z < WS(r.z2)));
			const bool havePointInRect = (pointInRect0 || pointInRect1);
			// NOTE:
			//     box-volume tests in its own space, but points are
			//     in world-space so we must inv-transform them first
			//     (p0 --> p0 - rm, p1 --> p1 - rm)
			const bool edgeCrossesRect =
				((p0.x < WS(r.x1) && p1.x >= WS(r.x2)) && (p0.z >= WS(r.z1) && p1.z < WS(r.z2))) ||  // H
				((p0.z < WS(r.z1) && p1.z >= WS(r.z2)) && (p0.x >= WS(r.x1) && p1.x < WS(r.x2))) ||  // V
				CCollisionHandler::IntersectBox(&rv, p0 - rm, p1 - rm, NULL);

			// remember the ID of each path affected by the deformation
			if (havePointInRect || edgeCrossesRect) {
				assert(tempPaths.find(path->GetID()) == tempPaths.end());
				deadPaths.insert(std::make_pair<unsigned int, IPath*>(path->GetID(), path));
				livePathIts.push_back(it);
				break;
			}
		}
	}

	for (std::list<PathMapIt>::const_iterator it = livePathIts.begin(); it != livePathIts.end(); ++it) {
		livePaths.erase(*it);
	}

	return true;
}