// calculate all the obstacles which will be used in multiple nav mesh IsVisible tests (optimization to avoid doing multiple sim.KDTree.GetObstacles()) // if all the from points are the same in the 'theInput' list, set 'areFromPointsEqual' to true for an optimization public static bool CalculateNavMeshQueryObstacles(ref List <NavMeshQueryInput> theInput, ref List <ObstacleVertex> obstacles, Simulator sim, bool areFromPointsEqual) { if (null == AstarPath.active) { return(false); } CreateAllPointsList(); _allPoints.Clear(); for (int inputIndex = 0; inputIndex < theInput.Count; ++inputIndex) { NavMeshQueryInput query = theInput[inputIndex]; query.isInputValid = true; _allPoints.Add(query.from); _allPoints.Add(query.to); if (!areFromPointsEqual || 0 == inputIndex) // if from points are not equal or this is the first in the list { query.fromInfo = AstarPath.active.GetNearest(query.from); } else // (areFromPointsEqual && inputIndex > 0) // from points are equal and we've already calculated one GetNearest() { query.fromInfo = theInput[0].fromInfo; } if (null == query.fromInfo.node) { query.isInputValid = false; continue; } query.fromNodePos = (Vector3)query.fromInfo.node.position; _allPoints.Add(query.fromNodePos); } Bounds bounds = GameUtils.CalculateBounds(_allPoints); // calculate the bounding box to encapsulate all points we need to consider // sim.GetObstacles() is an alternative - this may be faster const float SearchPadding = 0.1f; sim.GetStaticAndDynamicObstacles(obstacles, bounds.center, (bounds.max - bounds.center).sqrMagnitude + SearchPadding); // get all obstacles near our line return(true); }
// will return false if any part of the line is off the nav mesh // if 'clampFromInNavMesh' is true, we make sure the from position is on the nav mesh before doing checks (this is an optimization to avoid checks) // (done in 2d, does not currently support nav meshes on top of one and other) public static bool IsVisible(NavMeshQueryInput input, List <ObstacleVertex> obstacles, Simulator sim) { if (!input.isInputValid) { return(false); } if (input.clampFromInNavMesh) { input.from = CalculatePointOnNavMesh(input.from, sim, 0.1f, input.fromInfo, obstacles); int obstaclesCount = obstacles.Count; for (int i = 0; i < obstaclesCount; i++) { // do a 2d line intersection check to see if the line extends off the nav mesh if (VectorMath.SegmentsIntersectXZ(input.from, input.to, obstacles[i].position, obstacles[i].next.position)) { return(false); // the line extends off the nav mesh } } } else { int obstaclesCount = obstacles.Count; for (int i = 0; i < obstaclesCount; i++) { // do a 2d line intersection check to see if the start point is off the nav mesh if (VectorMath.SegmentsIntersectXZ(input.fromNodePos, input.from, obstacles[i].position, obstacles[i].next.position)) { return(false); // the start point is off the nav mesh } // do a 2d line intersection check to see if the line extends off the nav mesh if (VectorMath.SegmentsIntersectXZ(input.from, input.to, obstacles[i].position, obstacles[i].next.position)) { return(false); // the line extends off the nav mesh } } } return(true); // the line is fully on the nav mesh }