void CopyPoints(const IPath& p) { AllocPoints(p.NumPoints()); for (unsigned int n = 0; n < p.NumPoints(); n++) { points[n] = p.GetPoint(n); } }
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; }