Esempio n. 1
0
        protected override void OnUpdate()
        {
            var polygons = PolygonsFromRoadOutline(Parameters.extensionDistance);

            var clipper = new Clipper();

            foreach (var polygon in polygons)
            {
                if (!Clipper.Orientation(polygon))
                {
                    polygon.Reverse();
                }
                if (Clipper.Area(polygon) > 0)
                {
                    clipper.AddPath(polygon, PolyType.ptSubject, true);
                }
            }

            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            solution.RemoveAll(IsSmallerThanMinimumArea);

            if (solution.Count == 0 && polygons.Count != 0)
            {
                throw new Exception($"Unable to create a polygon from " +
                                    $"{Parameters.roadNetworkDescription.name}");
            }

            foreach (var polygon in solution)
            {
                var pathEntity = EntityManager.CreateEntity(m_SamplesArchetype);

                var orientation = Clipper.Orientation(polygon)
                    ? PolygonOrientation.Outside
                    : PolygonOrientation.Inside;

                var pathSamplesBuffer    = EntityManager.GetBuffer <PointSampleGlobal>(pathEntity).Reinterpret <RigidTransform>();
                var placementPathSamples = PlacementUtility.IntPointsToRigidTransforms(polygon, true, Allocator.TempJob);
                pathSamplesBuffer.AddRange(placementPathSamples);
                placementPathSamples.Dispose();

                EntityManager.SetComponentData(pathEntity, new PolygonOrientationComponent
                {
                    Orientation = orientation
                });
            }
        }
        List <List <IntPoint> > GeneratePlacementRegions()
        {
            var polygons = new List <List <IntPoint> >();

            Entities.ForEach((DynamicBuffer <PointSampleGlobal> vertices) =>
            {
                var pathSamples = vertices.Reinterpret <RigidTransform>().AsNativeArray();
                polygons.Add(PlacementUtility.FromSamplesToClipper(pathSamples));
            });

            return(PlacementUtility.GenerateOffsetRegionFromRoadPaths(
                       polygons,
                       Parameters.innerOffsetFromPath,
                       Parameters.outerOffsetFromPath));
        }
Esempio n. 3
0
        public void Execute(int index)
        {
            var placementPathEntity = PathEntities[index];
            var offsetPathEntity    = OffsetPathEntities[index];

            var pathBuffer             = PathBuffers[placementPathEntity].Reinterpret <RigidTransform>().AsNativeArray();
            var offsetPathRangesBuffer = OffsetPathRangeBuffers[offsetPathEntity];
            var offsetPathBuffer       = OffsetPathSampleBuffers[offsetPathEntity].Reinterpret <RigidTransform>();

            var offsetPolygons = PlacementUtility.OffsetPolygon(pathBuffer, Offset, Allocator.Temp);

            foreach (var offsetPolygon in offsetPolygons)
            {
                offsetPathRangesBuffer.Add(new OffsetPlacementPathRange
                {
                    StartIndex  = offsetPathRangesBuffer.Length,
                    SampleCount = offsetPolygon.Length
                });
                offsetPathBuffer.AddRange(offsetPolygon);
            }
        }
        protected override void OnUpdate()
        {
            if (!ParametersValidationCheck())
            {
                return;
            }

            var parentObj = new GameObject(Parameters.category.name);

            parentObj.transform.parent = Parameters.parent;

            var spacing = Parameters.spacing;

            if (Parameters.spacing < k_MinimumSpacing)
            {
                Debug.LogWarning(
                    $"Spacing parameter is less than the minimum of { k_MinimumSpacing }. " +
                    "Proceeding with minimum spacing.");
                spacing = k_MinimumSpacing;
            }

            var offsetPolygons = GeneratePlacementRegions();

            var polygonEntities = PlacementUtility.ClipperPolygonsToPolygonEntities(
                EntityManager,
                m_PolygonArchetype,
                offsetPolygons);
            var poissonPointRegionEntities = new NativeList <Entity>(Allocator.TempJob);
            var outerMostPolygonCount      = new NativeArray <int>(1, Allocator.TempJob);
            var unfilteredPoissonPoints    = new NativeList <float2>(Allocator.TempJob);
            var insidePolygons             = new NativeList <bool>(Allocator.TempJob);
            var filteredPoissonPoints      = new NativeList <float2>(Allocator.TempJob);

            var transaction = EntityManager.BeginExclusiveEntityTransaction();

            var countOutermostPolygonsJob = new CountOutermostPolygonsJob
            {
                OuterMostPolygonCount = outerMostPolygonCount,
                PolygonEntities       = polygonEntities,
                PolygonPointBuffers   = GetBufferFromEntity <PolygonPoint>(true)
            }.Schedule();

            var createPoissonPointRegionEntitiesJob = new CreatePoissonPointRegionEntitiesJob
            {
                Transaction = transaction,
                PoissonPointRegionEntities  = poissonPointRegionEntities,
                OuterMostPolygonCount       = outerMostPolygonCount,
                PoissonPointRegionArchetype = m_PoissonPointRegionArchetype
            }.Schedule(countOutermostPolygonsJob);

            var calculatePathAreasJob = new CalculatePathAreasJob
            {
                PoissonPointRegionEntities   = poissonPointRegionEntities.AsDeferredJobArray(),
                PolygonEntities              = polygonEntities,
                PolygonPointBuffers          = GetBufferFromEntity <PolygonPoint>(true),
                PoissonPointRegionComponents = GetComponentDataFromEntity <PoissonPointRegion>()
            }.Schedule(poissonPointRegionEntities, 1, createPoissonPointRegionEntitiesJob);

            var generatePoissonPointsJob = new GeneratePoissonPointsJob
            {
                MinimumRadius = spacing,
                RandomSeed    = 12345u,
                PoissonPointRegionEntities = poissonPointRegionEntities.AsDeferredJobArray(),
                PoissonPointBuffers        = GetBufferFromEntity <PoissonPoint>(),
                PoissonPointRegions        = GetComponentDataFromEntity <PoissonPointRegion>(true)
            }.Schedule(poissonPointRegionEntities, 1, calculatePathAreasJob);

            var gatherPoissonPointsJob = new GatherPoissonPointsJob
            {
                PoissonPoints              = unfilteredPoissonPoints,
                InsidePolygons             = insidePolygons,
                PoissonPointRegionEntities = poissonPointRegionEntities,
                PoissonPointBuffers        = GetBufferFromEntity <PoissonPoint>(true)
            }.Schedule(generatePoissonPointsJob);

            var checkPointsAreInsidePolygonsJob = new CheckPointsAreInsidePolygonsJob
            {
                PoissonPoints       = unfilteredPoissonPoints.AsDeferredJobArray(),
                InsidePolygons      = insidePolygons.AsDeferredJobArray(),
                PolygonEntities     = polygonEntities,
                PolygonPointBuffers = GetBufferFromEntity <PolygonPoint>(true)
            }.Schedule(unfilteredPoissonPoints, 8, gatherPoissonPointsJob);

            var gatherFilteredPoissonPointsJob = new GatherFilteredPoissonPointsJob
            {
                UnfilteredPoissonPoints = unfilteredPoissonPoints.AsDeferredJobArray(),
                FilteredPoissonPoints   = filteredPoissonPoints,
                InsidePolygon           = insidePolygons.AsDeferredJobArray()
            }.Schedule(checkPointsAreInsidePolygonsJob);

            polygonEntities.Dispose(gatherFilteredPoissonPointsJob);
            poissonPointRegionEntities.Dispose(gatherFilteredPoissonPointsJob);
            outerMostPolygonCount.Dispose(gatherFilteredPoissonPointsJob);
            insidePolygons.Dispose(gatherFilteredPoissonPointsJob);
            unfilteredPoissonPoints.Dispose(gatherFilteredPoissonPointsJob);

            EntityManager.ExclusiveEntityTransactionDependency = gatherFilteredPoissonPointsJob;
            EntityManager.EndExclusiveEntityTransaction();

            PlaceObjectsAtPoissonPoints(filteredPoissonPoints, parentObj.transform);
            filteredPoissonPoints.Dispose(gatherFilteredPoissonPointsJob);
        }