Пример #1
0
        public static IEnumerable<(PolyNode, double)> X(IntLineSegment2 seg, LocalGeometryView lgv)
        {
            var punchedLand = lgv.PunchedLand;
             punchedLand.AssertIsContourlessRootHolePunchResult();

             var allBreakpoints = new SortedList<double, List<(PolyNode, double)>>();

             foreach (var polyNode in punchedLand.EnumerateLandNodes()) {
            XVisitLandPolyNode(seg, polyNode, allBreakpoints);
             }

             var res = new List<(PolyNode, double)>();
             foreach (var x in allBreakpoints.Values) {
            res.AddRange(x);
             }
            //            allBreakpoints.SelectMany(kvp => kvp.Value.Item2.Select(t => (kvp.Value.Item1, t))).ToList();
             return res;

            //         // TODO: Fix this hack. Eventually. Maybe never. Possibly.
            //
            //
            //         Trace.Assert(breakpoints.Count % 2 == 0);
            //         return breakpoints.Select(kvp => (kvp.Value, kvp.Key));
             //
             //         var it = breakpoints.GetEnumerator();
             //         while (it.MoveNext()) {
             //            var bp0 = it.Current;
             //            Trace.Assert(it.MoveNext());
             //            var bp1 = it.Current;
             //            yield return (landPolyNodeBoundedByPolyNodeContour[bp0.Value], bp0.Key, bp1.Key);
             //         }
        }
        public TerrainOverlayNetworkNode(SectorNodeDescription sectorNodeDescription, LocalGeometryView localGeometryView, PolyNode landPolyNode)
        {
            SectorNodeDescription = sectorNodeDescription;
            LocalGeometryView     = localGeometryView;
            LandPolyNode          = landPolyNode;

            CrossoverPointManager = new PolyNodeCrossoverPointManager(landPolyNode);
        }
Пример #3
0
 public static void DrawWallPushGrid(this IDebugCanvas canvas, LocalGeometryView lgv, double holeDilationRadius, double xlow = -50, double xhigh = 1100, double xstep = 100, double ylow = -50, double yhigh = 1100, double ystep = 100)
 {
     for (double x = xlow; x < xhigh; x += xstep)
     {
         for (double y = ylow; y < yhigh; y += ystep)
         {
             throw new NotImplementedException();
             //               var query = new DoubleVector2(x, y);
             //               DoubleVector2 nearestLandPoint;
             //               var isInHole = lgv.FindNearestLandPointAndIsInHole(query, out nearestLandPoint);
             //               canvas.DrawPoint(new DoubleVector3(query), isInHole ? InHoleStrokeStyle : InLandStrokeStyle);
             //               if (isInHole) {
             //                  canvas.DrawLine(new DoubleVector3(query), new DoubleVector3(nearestLandPoint), NearestLandStrokeStyle);
             //               }
         }
     }
 }
Пример #4
0
        // public static bool TryFindSector(this TerrainSnapshot terrainSnapshot, IntVector3 queryWorld, out SectorSnapshot result) {
        //    return TryFindSector(terrainSnapshot, queryWorld.ToDoubleVector3(), out result);
        // }

        // public static bool TryFindSector(this TerrainSnapshot terrainSnapshot, DoubleVector3 queryWorld, out SectorSnapshot result) {
        //    return terrainSnapshot.SectorSnapshots.TryFindFirst(sectorSnapshot => {
        //       var queryLocal = sectorSnapshot.WorldToLocal(queryWorld);
        //       var localBoundary = sectorSnapshot.StaticMetadata.LocalBoundary;
        //       return localBoundary.X <= queryLocal.X && queryLocal.X <= localBoundary.Right &&
        //              localBoundary.Y <= queryLocal.Y && queryLocal.Y <= localBoundary.Bottom;
        //    }, out result);
        // }

        // public static bool IsInHole(this SectorSnapshotGeometryContext sectorSnapshotGeometryContext, IntVector3 query) {
        //    var punchedLandPolytree = sectorSnapshotGeometryContext.PunchedLand;
        //    punchedLandPolytree.AssertIsContourlessRootHolePunchResult();
        //
        //    PolyNode pickedNode;
        //    bool isHole;
        //    punchedLandPolytree.PickDeepestPolynode(query.XY, out pickedNode, out isHole);
        //
        //    return isHole;
        // }

        /// <summary>
        /// Note: Containment definition varies by hole vs terrain: Containment for holes
        /// does not include the hole edge, containment for terrain includes the terrain edge.
        /// This is important, else e.g. knockback + terrain push placing an entity on an edge
        /// would potentially infinite loop.
        /// </summary>
        public static bool FindNearestLandPointAndIsInHole(this LocalGeometryView localGeometryView, DoubleVector2 query, out DoubleVector2 nearestLandPoint)
        {
            var punchedLandPolytree = localGeometryView.PunchedLand;

            punchedLandPolytree.AssertIsContourlessRootHolePunchResult();

            PolyNode pickedNode;
            bool     isHole;

            punchedLandPolytree.PickDeepestPolynode(query.LossyToIntVector2(), out pickedNode, out isHole);

            // If query point not in a hole, nearest land point is query point
            if (!isHole)
            {
                nearestLandPoint = query;
                return(false);
            }

            // Else, two cases to consider: nearest point is on an island inside this hole, alternatively
            // and (only if the hole has a contour), nearest point is on the hole contour.
            nearestLandPoint = DoubleVector2.Zero;
            double bestDistance = double.PositiveInfinity;

            if (pickedNode.Contour.Any())
            {
                // the hole has a contour; that is, it's a hole inside of a landmass
                var result = GeometryOperations.FindNearestPointOnContour(pickedNode.Contour, query);
                bestDistance     = result.Distance;
                nearestLandPoint = result.NearestPoint;
            }

            foreach (var childLandNode in pickedNode.Childs)
            {
                var result = GeometryOperations.FindNearestPointOnContour(childLandNode.Contour, query);
                if (result.Distance < bestDistance)
                {
                    bestDistance     = result.Distance;
                    nearestLandPoint = result.NearestPoint;
                }
            }
            return(true);
        }
Пример #5
0
        private void DebugRenderLocalGeometryView(LocalGeometryView localGeometryView, params IntLineSegment2[] segs)
        {
            if (!kEnableDebugRender)
            {
                return;
            }

            Size bounds      = new Size(1280, 720);
            var  renderScale = 1.0f;

            PerspectiveProjector CreateCanvasProjector()
            {
                var rotation    = 95 * Math.PI / 180.0;
                var displaySize = new Size((int)(bounds.Width * renderScale), (int)(bounds.Height * renderScale));
                var center      = new DoubleVector3(0, 0, 0);
                var projector   = new PerspectiveProjector(
                    center + DoubleVector3.FromRadiusAngleAroundXAxis(1000, rotation),
                    center,
                    DoubleVector3.FromRadiusAngleAroundXAxis(1, rotation - Math.PI / 2),
                    displaySize.Width,
                    displaySize.Height);

                return(projector);
            }

            DebugMultiCanvasHost host = DebugMultiCanvasHost.CreateAndShowCanvas(bounds, new Point(0, 0), CreateCanvasProjector());
            var canvas = host.CreateAndAddCanvas(0);

            canvas.DrawPolyNode(localGeometryView.PunchedLand);
            foreach (var hole in localGeometryView.Job.DynamicHoles)
            {
                canvas.DrawPolygonContours(hole.Value.holeExcludedContours, StrokeStyle.OrangeHairLineSolid);
                canvas.DrawPolygonContours(hole.Value.holeIncludedContours, StrokeStyle.RedHairLineSolid);
            }
            foreach (var seg in segs)
            {
                canvas.DrawLine(seg, StrokeStyle.CyanHairLineSolid);
            }
        }
Пример #6
0
        public override List<EdgeJob> EmitCrossoverJobs(double crossoverPointSpacing, LocalGeometryView sourceLgv, LocalGeometryView destinationLgv)
        {
            //         return new List<EdgeJob>();

             var sourceSegmentVector = SourceSegment.First.To(SourceSegment.Second).ToDoubleVector2();
             var destinationSegmentVector = DestinationSegment.First.To(DestinationSegment.Second).ToDoubleVector2();

             var edgeJobs = new List<EdgeJob>();
             var streamSource = X(SourceSegment, sourceLgv).ToArray();
             var streamDest = X(DestinationSegment, destinationLgv).ToArray();
             var crossResult = CrossTheStreams(streamSource, streamDest).ToArray();
             foreach (var (source, dest, tStart, tEnd) in crossResult) {
            var sourceSubSegment = new DoubleLineSegment2(
               SourceSegment.First.ToDoubleVector2() + tStart * sourceSegmentVector,
               SourceSegment.First.ToDoubleVector2() + tEnd * sourceSegmentVector);

            var destinationSubSegment = new DoubleLineSegment2(
               DestinationSegment.First.ToDoubleVector2() + tStart * destinationSegmentVector,
               DestinationSegment.First.ToDoubleVector2() + tEnd * destinationSegmentVector);

            edgeJobs.Add(new EdgeJob {
               EdgeDescription = this,
               SourcePolyNode = source,
               SourceSegment = sourceSubSegment,
               DestinationPolyNode = dest,
               DestinationSegment = destinationSubSegment
            });
             }
             return edgeJobs;
        }