public void TestRandomVsPoissonVisually() { Vector2 region = new Vector2(400, 400); var radius = 20; List <Vector2> poissonPoints = PoissonDiscSampler.GeneratePoints(radius, region, 30); foreach (var point in poissonPoints) { Assert.IsTrue(point.X >= 0 && point.X < region.X, $"Point {point.X} not in X region 0,{region.X}"); Assert.IsTrue(point.Y >= 0 && point.Y < region.Y, $"Point {point.Y} not in Y region 0,{region.Y}"); } List <Vector2> randomPoints = RandomSampler.GeneratePoints(poissonPoints.Count, region); { //draw poission samples ImageDrawing imageDrawing = new ImageDrawing((int)region.X, (int)region.Y); imageDrawing.Clear(Color.Transparent); imageDrawing.FillCircles(poissonPoints, radius, Color.Black); imageDrawing.SaveImage("comp_2_poisson_disc.png"); } { // draw random samples ImageDrawing imageDrawing = new ImageDrawing((int)region.X, (int)region.Y); imageDrawing.Clear(Color.Transparent); imageDrawing.FillCircles(randomPoints, radius, Color.Black); imageDrawing.SaveImage("comp_1_random.png"); } Console.WriteLine($"Generated {poissonPoints.Count} points."); }
public void PoissonGridTest() { Debug.Log("Calculate time of 500 grid samples"); const int sampleCount = 50; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < sampleCount; i++) { PoissonDiscSampler pds = new PoissonDiscSampler(20, 20, 1); List <Vector2> total = new List <Vector2>(); foreach (Vector2 sample in pds.Samples()) { total.Add(sample); } Debug.Log(total.Count + " grid verts"); } sw.Stop(); long time = sw.ElapsedMilliseconds; Debug.Log("Elapsed time: " + time + " ms. " + time / 1000 + "s."); Debug.Log("Approx " + ((float)(time / 1000)) / sampleCount + " seconds"); }
public void IslandPipelineTest() { Pipeline pipeline = PipelineUtility.CreateEmptyPipelineUsingGraph("World Graph"); Vector2 worldRegion = new Vector2(2000, 2000); float islandSize = 300; float voronoiRadius = islandSize * 0.15f; string zoneLayerName = "ZoneLayer"; pipeline.AddStep(new PoissonLocationsAsEntitiesPipelineStep(islandSize, new(islandSize / 2, islandSize / 2), worldRegion - new Vector2(islandSize, islandSize), null, 60)); pipeline.AddStep(SetupIslandVisualizationStep(worldRegion, islandSize)); pipeline.AddStep(new IslandTypeAssignment(worldRegion / 2)); pipeline.AddStep(SetupIslandTypeVisualizationStep(worldRegion, islandSize)); pipeline.AddStep(new IteratorPipelineStep <Entity>( graph => graph.Entities, node => { var(centerX, centerY) = ComponentUtility.GetPosition2DFromComponent(node); Vector2 islandMin = new(centerX - islandSize / 2, centerY - islandSize / 2); Vector2 islandMax = new(centerX + islandSize / 2, centerY + islandSize / 2); return(new VoronoiPipelineStep( () => PoissonDiscSampler.GeneratePoints(voronoiRadius, new(islandSize, islandSize), islandMin), zoneLayerName, islandMin, islandMax, node)); }));
// Update is called once per frame void Generate() { // Destroy all existing obejcts foreach (GameObject go in _SpawnedObjects) { Destroy(go); } // Clear spawned list _SpawnedObjects.Clear(); _Sampler = new PoissonDiscSampler(_Dimensions.x, _Dimensions.y, _Radius); Vector3 startPos = new Vector3(-_Dimensions.x * .5f, 0, -_Dimensions.y * .5f); foreach (Vector2 sample in _Sampler.Samples()) { float rand = Random.Range(0f, 1f); if (rand < _PercentageToSpawn) { GameObject go = Instantiate(_Prefab, new Vector3(startPos.x + sample.x, 0f, startPos.z + sample.y), Quaternion.identity); go.transform.SetParent(transform); go.transform.localScale = Vector3.one * _Radius * _ScaleMultiplyer; _SpawnedObjects.Add(go); } } }
public void Generate(Generation world, Vector2 worldSize) { Vector3 offset = new Vector3(worldSize.x * (1f - margins), 0f, worldSize.x * (1f - margins)); PoissonDiscSampler sampler = new PoissonDiscSampler(worldSize.x * margins, worldSize.y * margins, spacing); foreach (Vector2 sample in sampler.Samples()) { Instantiate(pointOfInterestPrefab, new Vector3(sample.x, 100, sample.y) + (offset / 2f), Quaternion.identity); } // Using a delaunay library, we find info for fences and paths GameObject[] allPointsOfInterest = GameObject.FindGameObjectsWithTag("PointOfInterest"); List <Vector2> pointPositions = new List <Vector2>(); List <uint> pointColors = new List <uint>(); foreach (GameObject point in allPointsOfInterest) { pointColors.Add(0); pointPositions.Add(new Vector2(point.transform.position.x, point.transform.position.z)); } Voronoi voronoi = new Voronoi(pointPositions, pointColors, new Rect(0, 0, world.worldSize.x, world.worldSize.y)); foreach (var item in allPointsOfInterest) { item.GetComponent <PointOfInterest>().Generate(voronoi, world); } }
// Start is called before the first frame update void StartGame() { var size = 30; width = size; height = size; //var radius = .85f; var radius = 1.085f; PoissonDiscSampler sampler = new PoissonDiscSampler(width, height, radius); foreach (Vector2 sample in sampler.Samples()) { Summon(sample); } Score = 0; Support = 100; gameStartTime = Time.time; //for (var i = 0; i < 100; i++) //Instantiate(PrefabProtester, new Vector3(i, i, 0), Quaternion.identity); state = GameState.Running; }
public virtual void Generate(int worldSeed) { int chunkSeed = Generator.GetPerIslandSeed(this); creatingChunkStopwatch = System.Diagnostics.Stopwatch.StartNew(); random = new Random(chunkSeed); elevations = new List <float>(); islandColors = new List <Color>(); CreatingPoolTask = delegate { PoissonDiscSampler sampler = new PoissonDiscSampler(Size, Size, minPointRadius); Polygon polygon = new Polygon(); //Add uniformly-spaced points foreach (Vector2 sample in sampler.Samples(chunkSeed)) { polygon.Add(new Vertex((double)sample.x, (double)sample.y)); } //add points at corners so chunk will be always square shaped polygon.Add(new Vertex(0, 0)); polygon.Add(new Vertex(0, Size)); polygon.Add(new Vertex(Size, 0)); polygon.Add(new Vertex(Size, Size)); //Add some randomly sampled points for (int i = 0; i < randomPoints - 4; i++) { polygon.Add(new Vertex(random.Range(0.0f, Size), random.Range(0.0f, Size))); } TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; mesh = (TriangleNet.Mesh)polygon.Triangulate(options); // Sample perlin noise to get elevations foreach (Vertex vert in mesh.Vertices) { float height = Generator.GetTerrainHeight((float)vert.x, (float)vert.y, this); Color color = Generator.GetTerrainColor((float)vert.x, (float)vert.y, height, this); elevations.Add(height); islandColors.Add(color); } CreateMeshRequest = true; //let this be always the last piece of code here try { bin = new TriangleBin(mesh, Size, Size, minPointRadius * 2.0f); } catch (Exception e) { Debug.Log("triangulation failed!"); } }; CustomThreadPool.AddTask(CreatingPoolTask); }
private void Awake() { if (ChunkRockGenerator.AssetPrefabs == null) { ChunkRockGenerator.LoadPrefabs(); } this.GameController = GameController.GetSharedInstance(); this.PlacedAssets = new List <GameObject>(); this.sampler = new PoissonDiscSampler(); }
/// Will use Poisson-Disc Sampling Algorithm to generate trees private void GenerateTrees() { PoissonDiscSampler sampler = new PoissonDiscSampler(xTiles - 3, yTiles - 3, treeMinDistance); foreach (Vector2 sample in sampler.Samples()) { int xPos = (int)sample.x; int yPos = (int)sample.y; Instantiate(tree, sample, Quaternion.identity, tiles[xPos, yPos].transform); } }
public Map GenerateMap(int seed) { Map map = new Map(); map.seed = seed; Random.InitState(seed); map.areaList = new Map.Area[mapLength]; map.mapLength = mapLength; map.mapHeight = mapHeight; // Generate lengths for each area here, so that we can generate the point list float[] areaLengths = new float[mapLength]; for (int i = 0; i < mapLength; i++) { areaLengths[i] = Random.Range(areaMinMaxLength.x, areaMinMaxLength.y); } map.totalMapLength = areaLengths.Sum(); List <Vector2> allPoints = new PoissonDiscSampler ( map.totalMapLength, mapHeight, distanceBetweenPoints ).Samples().Where ( p => p.y <= mapHeight - emptyDistanceFromTopAndBottom && p.y >= emptyDistanceFromTopAndBottom ).ToList(); float xDistance = 0f; for (int x = 0; x < mapLength; x++) { Vector2 areaSize = new Vector2(areaLengths[x], mapHeight); List <Vector2> areaPoints = allPoints.FindAll ( p => p.x > xDistance && p.x < xDistance + areaSize.x ); Map.Area area = new Map.Area(); area.areaSize = areaSize; area.xOffsetFromStart = xDistance + areaSize.x / 2f; GeneratePoints(area, areaPoints); map.areaList[x] = area; xDistance += areaSize.x; } return(map); }
/// <summary> /// Calculates a grid using the poisson disc sampling method. /// The 2D grid positions fall within the range of [0, 1]. /// /// Can be called off of Unity's main thread. /// </summary> /// <param name="opt">Object placement type to sample</param> /// <returns>List of vectors within the grid</returns> public List <Vector2> GetPoissonGrid(ObjectPlacementType opt) { PoissonDiscSampler pds = new PoissonDiscSampler(opt.GridSize, opt.GridSize, opt.Density); List <Vector2> total = new List <Vector2>(); foreach (Vector2 sample in pds.Samples()) { total.Add(sample); } return(total); }
/// <summary> /// Creates a list of positions in the range of [0, 1] by /// running the poisson disc sampling algorithm. /// </summary> /// <param name="density">Density of the placement of objects</param> /// <param name="gridSize">Size of the grid to sample</param> /// <param name="random">Random number generator to sample</param> private Vector2[] GetPoissonGridSamples(float density, int gridSize, System.Random random) { PoissonDiscSampler pds = new PoissonDiscSampler(gridSize, gridSize, density, random); List <Vector2> total = new List <Vector2>(); foreach (Vector2 sample in pds.Samples()) { total.Add(sample / gridSize); } return(total.ToArray()); }
/// <summary> /// Calculates a grid using the poisson disc sampling method. /// The 2D grid positions fall within the range of [0, 1]. /// /// Can be called off of Unity's main thread. /// </summary> /// <param name="opt">How dense should the samples be</param> /// <returns>List of vectors within the grid</returns> public List <Vector2> GetPoissonGrid(float density) { PoissonDiscSampler pds = new PoissonDiscSampler(GRID_SIZE, GRID_SIZE, density); List <Vector2> total = new List <Vector2>(); foreach (Vector2 sample in pds.Samples()) { //Normalize in range of [0, 1] before adding total.Add(sample / GRID_SIZE); } return(total); }
private static Polygon GeneratePoisonDisc() { Polygon polygon = new Polygon(); Random.InitState(seed); PoissonDiscSampler poissonDiscSampler = new PoissonDiscSampler(dimensions.x, dimensions.y, radius); foreach (var sample in poissonDiscSampler.Samples()) { polygon.Add(sample.ToVertex()); } return(polygon); }
private IEnumerable <Vector2> PoissonPoints() { var sampler = new PoissonDiscSampler(galaxyRadius * 2, galaxyRadius * 2, galaxyRadius * 0.07f); var samples = new List <Vector2>(); foreach (var sample in sampler.Samples()) { sample.Set(sample.x - galaxyRadius, sample.y - galaxyRadius); samples.Add(sample); } return(samples); }
// Calculate the points to show when the game starts private void Awake() { // Create a list of points from the sampler points = new List <Vector3>(); var sampler = new PoissonDiscSampler(size.x, size.y, cellSize); foreach (var point in sampler.Samples()) { points.Add( new Vector3(point.x, transform.position.y, point.y) ); } }
public void Initialize() { Vector3 oldPos = transform.localPosition; transform.localPosition = new Vector3(oldPos.x - fakeWidth / 2, oldPos.y - fakeHeight / 2, oldPos.z); Helper.StartTime = Helper.CurrentTime(); ClearState(); targets.Clear(); Random.InitState((int)System.DateTime.Now.Ticks); foreach (Transform child in transform) { GameObject.Destroy(child.gameObject); } PoissonDiscSampler sampler = new PoissonDiscSampler(fakeWidth, fakeHeight, radius); foreach (Vector2 sample in sampler.Samples()) { if (range(fakeWidth / 2 - width / 2, fakeWidth / 2 + width / 2, sample.x) && range(fakeHeight / 2 - height / 2, fakeHeight / 2 + height / 2, sample.y)) { GameObject target = Instantiate(prefab, new Vector3(sample.x, sample.y, 0), Quaternion.identity, transform); target.transform.localPosition = new Vector3(sample.x, sample.y, 0); targets.Add(target); } else { GameObject target = Instantiate(dummy, new Vector3(sample.x, sample.y, 0), Quaternion.identity, transform); target.transform.localPosition = new Vector3(sample.x, sample.y, 0); } } foreach (GameObject targ in targets) { Target target = targ.GetComponent <Target>(); target.GetNeighbours(radius); target.Condition = Condition; } Collider[] col = Physics.OverlapBox(transform.TransformPoint(new Vector3(width / 2, height / 2, 0)), new Vector3(1f, 1f, 0), Quaternion.identity, LayerMask.GetMask("Both Eyes")); currentTarget = col[Random.Range(0, col.Length)].gameObject; currentTarget.GetComponent <Target>().EnableEffect(); Helper.Log(SessionName + "_" + Condition.ToString() + "_ACTIONS", "CONDITION", Condition.ToString()); Helper.Log(SessionName + "_" + Condition.ToString() + "_ACTIONS", "STARTED"); }
private void PrepareSpawnLocations() { var sampler = new PoissonDiscSampler(2 * spawnRadius, 2 * spawnRadius, fishRadius); var half = Vector2.one * spawnRadius; var sqr = spawnRadius * spawnRadius; var locs = sampler.Samples() .Select(loc => loc - half) .Where(loc => loc.sqrMagnitude < sqr) .OrderBy(loc => loc.sqrMagnitude) .ToList(); _spawnLocations = new LinkedList <Vector2>(locs); maxFishSpawns = _spawnLocations.Count; }
private void Awake() { if (ChunkTreeGenerator.AssetPrefabs == null) { ChunkTreeGenerator.LoadPrefabs(); } this.GameController = GameController.GetSharedInstance(); this.PlacedAssets = new List <GameObject>(); this.sampler = new PoissonDiscSampler(); this.sparseMask = new Perlin() { OctaveCount = 8, Frequency = 1.7, Persistence = 0.6 }; }
// Update is called once per frame public List <Vector2> SamplePoints() { var Domain = bp.Domain; var offset = bp.Offset; var sampler = new PoissonDiscSampler(Domain.y - Domain.x - 0.1f, Domain.w - Domain.z - 0.1f, Radius); List <Vector2> l = new List <Vector2>(); foreach (Vector2 s in sampler.Samples()) { l.Add(s + new Vector2(Domain.x + 0.05f, Domain.z + 0.05f)); } return(l); }
void CalculateNewWaitLocations() // a nice way of doing this would be to store old locations generated and workaround them { PoissonDiscSampler sampler = new PoissonDiscSampler(waitAreaTriggerBounds.size.x - 2 * Person.nmAgentRadius, waitAreaTriggerBounds.size.z - 2 * Person.nmAgentRadius, waitSpacing); foreach (Vector2 sample in sampler.Samples()) { Vector3 waitLocation = waitAreaTriggerBounds.min; //place at the '0,0' location for the generated grid waitLocation.x += sample.x + Person.nmAgentRadius; waitLocation.z += sample.y + Person.nmAgentRadius; NavMeshHit hit; //using SamplePosition to make absolutely sure the wait location we have generated ends up on the navmesh if (NavMesh.SamplePosition(waitLocation, out hit, 0.5f, NavMesh.AllAreas)) { waitingPeople.Add(new WaitLocation(hit.position, null)); } } }
//Adds terrain obstacles within triangle based on biome void AddTerrainObstacles(TileData.Triangle triangle, Vector3[] points, GameObject parent) { float density = GetObstacleDensity(triangle); PoissonDiscSampler poisson = new PoissonDiscSampler(TileSize, TileSize, density); foreach (var sample in poisson.Samples()) { if (PointInTriangle(new Vector3(sample.x, 0, sample.y), points[0], points[1], points[2])) { var objectGameObject = Instantiate(GetTerrainObstacles(triangle.biome), parent.transform); objectGameObject.transform.Rotate(new Vector3(0, UnityEngine.Random.Range(0, 360), 0)); objectGameObject.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); objectGameObject.transform.position = new Vector3(sample.x - .5f, 0, sample.y - .5f); } } }
private void Spawn() { float width = rows * size - (2 * size); float height = cols * size - (2 * size); PoissonDiscSampler sampler = new PoissonDiscSampler(width, height, 2 * size); foreach (Vector2 sample in sampler.Samples()) { Collider[] hitColliders = Physics.OverlapSphere(new Vector3(sample.x + size, 0, sample.y + size), 2f); if (hitColliders.Length == 0) { Instantiate(item, new Vector3(sample.x + size, 0, sample.y + size), Quaternion.identity); } } }
private void GenerateTreasure() { CleanUpTreasure(); Vector2 offset = new Vector2(0.5f * fieldWidth, 0.5f * fieldHeight); // To Do : Making assumptions about the default position of the arena treasures.Clear(); poissonNoise = new PoissonDiscSampler(fieldWidth, fieldHeight, distanceBetweenTreasures); List <Vector2> locations = poissonNoise.Samples().ToList(); locations = locations.Select(obj => obj -= offset).ToList(); for (int i = 0; i < (maxTreasures >= locations.Count ? locations.Count : maxTreasures); i++) { treasures.Add(new KeyValuePair <Vector2, GameObject>(locations[i], PlaceTreasure(locations[i]))); } }
private void CreateSystems() { GameObject tmp = new GameObject("Solar Systems"); tmp.transform.parent = transform; m_systemContainer = tmp.transform; Vector2 totalArea = m_galaxyAttached.GetTotalArea(); PoissonDiscSampler sampler = new PoissonDiscSampler(totalArea.x, totalArea.y, m_distanceBetweenSystem); List <Vector2> samples = new List <Vector2>(); samples.AddRange(sampler.Samples()); for (uint i = 0; i < m_numberOfSolarSystem; ++i) { GameObject system = Instantiate(m_galaxyAttached.GetSystemPrefab(), m_systemContainer); system.name = "Solar System " + (i + 1); SolarSystem obj = system.GetComponent <SolarSystem>(); obj.SetSector(this); Vector3 position = samples[0] - m_galaxyAttached.GetOffset(); samples.RemoveAt(0); if (samples.Count == 0) { samples.AddRange(sampler.Samples()); } uint nbTry = 0; do { position = samples[0] - m_galaxyAttached.GetOffset(); samples.RemoveAt(0); if (samples.Count == 0) { samples.AddRange(sampler.Samples()); } nbTry++; if (nbTry % 100 == 0) { m_distanceBetweenSystem -= 0.1f; } }while (!IsAtAGoodDistance(position)); system.transform.position = position; m_systems.Add(obj); } }
// Initializes the background pattern public void Generate() { float width = size * mazeRows; float height = size * mazeColumns; PoissonDiscSampler sampler = new PoissonDiscSampler(width + (4 * size), height + (4 * size), 2 * size); foreach (Vector2 sample in sampler.Samples()) { float xPos = sample.x - size; float yPos = sample.y - size; if (xPos < size || yPos < size || xPos > width || yPos > height) { Instantiate(pattern, new Vector3(xPos, -5 * size, yPos), Quaternion.Euler(Random.Range(0, 90), Random.Range(0, 90), Random.Range(0, 90))); } } }
private void distributeObject(GameObject plane, GameObject o, Vector3 beginPoint, int number) { PoissonDiscSampler sampler = new PoissonDiscSampler(width, length, 15); int i = 0; Vector3 origin = new Vector3(beginPoint.x - width / 2, beginPoint.y, beginPoint.z); foreach (Vector2 sample in sampler.Samples()) { Instantiate(o, new Vector3(origin.x + sample.x, getYofPlane(origin.x + sample.x, origin.z + sample.y), origin.z + sample.y), randomYRotation(), plane.transform); i++; if (i == number) { break; } } }
public static IEnumerable <float2> Sample(float rectWidth, float rectHeight, float xOffset, float yOffset, float radius, int count, uint randomSeed) { if (count <= 0) { throw new ArgumentException("PoissonDisc sampling count must be positive!"); } var sampler = new PoissonDiscSampler(rectWidth, rectHeight, radius); foreach (var pos in sampler.Samples(randomSeed)) { if (count-- <= 0) { break; } yield return(new float2(pos.x + xOffset, pos.y + yOffset)); } }
public void TestPoissonVisually() { Vector2 region = new Vector2(400, 400); var radius = 80; List <Vector2> points = PoissonDiscSampler.GeneratePoints(radius, region, 30); foreach (var point in points) { Assert.IsTrue(point.X >= 0 && point.X < region.X, $"Point {point.X} not in X region 0,{region.X}"); Assert.IsTrue(point.Y >= 0 && point.Y < region.Y, $"Point {point.Y} not in Y region 0,{region.Y}"); } ImageDrawing imageDrawing = new ImageDrawing((int)region.X, (int)region.Y); imageDrawing.Clear(Color.Gray); imageDrawing.FillCircles(points, radius, Color.DarkRed); imageDrawing.SaveImage("poisson_disc_tmp.png"); }
// Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.F)) { Texture2D texture = new Texture2D((int)w, (int)h); sampler = new PoissonDiscSampler(w, h, r); texture.filterMode = FilterMode.Point; texture.wrapMode = TextureWrapMode.Clamp; int count = 0; foreach (Vector2 sample in sampler.Samples()) { texture.SetPixel((int)sample.x, (int)sample.y, Color.black); count++; } texture.Apply(); renderer.material.mainTexture = texture; } }