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)); }
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); }