// Todo: Can we support DV2s? public int[] AddMany(DoubleLineSegment2 edgeSegment, IntVector2[] points) { Interlocked.Increment(ref AddManyInvocationCount); // return points.Map(p => 0); var segmentSeeingWaypoints = landPolyNode.ComputeSegmentSeeingWaypoints(edgeSegment); // It's safe to assume <some> point in points will be new, so preprocess which segments are betwen us and other edge segments var barriers = landPolyNode.FindContourAndChildHoleBarriers(); Dictionary <DoubleLineSegment2, IntLineSegment2[]> barriersBySegment = indicesBySegment.Map((s, _) => { Interlocked.Increment(ref AddManyConvexHullsComputed); var hull = GeometryOperations.ConvexHull4(s.First, s.Second, edgeSegment.First, edgeSegment.Second); return(barriers.Where(b => { var barrierDv2 = new DoubleLineSegment2(b.First.ToDoubleVector2(), b.Second.ToDoubleVector2()); return GeometryOperations.SegmentIntersectsConvexPolygonInterior(barrierDv2, hull); }).ToArray()); }); return(indicesBySegment[edgeSegment] = points.Map(p => { if (TryAdd(p, out var cpi)) { Interlocked.Increment(ref CrossoverPointsAdded); segmentByCrossoverPoint[p] = edgeSegment; } return cpi; })); bool TryAdd(IntVector2 crossoverPoint, out int crossoverPointIndex) { if (!crossoverPoints.TryAdd(crossoverPoint, out crossoverPointIndex)) { return(false); } var(visibleWaypointLinks, visibleWaypointLinksLength, optimalLinkToWaypoints, optimalLinkToCrossovers) = FindOptimalLinksToCrossovers(crossoverPoint, segmentSeeingWaypoints, barriersBySegment); // visibleWaypointLinksByCrossoverPointIndex.Add(visibleWaypointLinks); optimalLinkToWaypointsByCrossoverPointIndex.Add(optimalLinkToWaypoints); optimalLinkToOtherCrossoversByCrossoverPointIndex.Add(optimalLinkToCrossovers); Trace.Assert(optimalLinkToOtherCrossoversByCrossoverPointIndex.Count == optimalLinkToCrossovers.Count); for (var otherCpi = 0; otherCpi < crossoverPoints.Count - 1; otherCpi++) { var linkToOther = optimalLinkToCrossovers[otherCpi]; var linkFromOther = linkToOther.PriorIndex < 0 ? new PathLink { PriorIndex = linkToOther.PriorIndex, TotalCost = linkToOther.TotalCost } : new PathLink { PriorIndex = optimalLinkToWaypointsByCrossoverPointIndex[otherCpi][linkToOther.PriorIndex].PriorIndex, TotalCost = linkToOther.TotalCost }; optimalLinkToOtherCrossoversByCrossoverPointIndex[otherCpi].Add(linkFromOther); } return(true); } }
public static BvhILS2 FindContourAndChildHoleBarriersBvh(this PolyNode node) { if (node.visibilityGraphNodeData.ContourAndChildHoleBarriersBvh != null) { return(node.visibilityGraphNodeData.ContourAndChildHoleBarriersBvh); } return(node.visibilityGraphNodeData.ContourAndChildHoleBarriersBvh = BvhILS2.Build(node.FindContourAndChildHoleBarriers())); }