Skip to content

Commit efb4cd0

Browse files
author
Cory Leach
committed
Renamed NoiseRng. PoissonDiskSampling now using Noise rng.
1 parent 8333ca6 commit efb4cd0

File tree

6 files changed

+154
-34
lines changed

6 files changed

+154
-34
lines changed

Runtime/Utility/PoissonDiskSampling.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
namespace Gameframe.Procgen
66
{
7-
7+
88
public static class PoissonDiskSampling
99
{
1010
public static List<Vector2> GeneratePoints(float radius, Vector2 size, int seed, int maxSamplesPerPoint = 30,
1111
Func<Vector2, bool> validate = null)
1212
{
13-
var rng = new System.Random(seed);
13+
var rng = new RandomGeneratorStruct((uint)seed);
1414
var points = new List<Vector2>();
1515
var cellSize = radius / Mathf.Sqrt(2);
1616
var gridWidth = Mathf.CeilToInt(size.x / cellSize);
@@ -24,17 +24,17 @@ public static List<Vector2> GeneratePoints(float radius, Vector2 size, int seed,
2424
while (spawnPoints.Count > 0)
2525
{
2626
//Get a random spawn point from the list
27-
var spawnIndex = rng.Next(0, spawnPoints.Count);
27+
var spawnIndex = rng.NextIntRange(0, spawnPoints.Count-1);
2828
var spawnCenter = spawnPoints[spawnIndex];
2929
var accepted = false;
3030

3131
for (int i = 0; i < maxSamplesPerPoint; i++)
3232
{
3333
//Get a random direction vector
34-
var angle = (float) (rng.NextDouble() * Mathf.PI * 2);
34+
var angle = (float) (rng.NextFloatZeroToOne() * Mathf.PI * 2);
3535
var dir = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
3636
//Get point along that direction vector between radius and 2radius distance away
37-
var distance = (float) (radius + rng.NextDouble() * radius * 2);
37+
var distance = (float) (radius + rng.NextFloatZeroToOne() * radius * 2);
3838
var candidate = spawnCenter + dir * distance;
3939

4040
//If point is valid we can accept it stop sampling
@@ -60,14 +60,14 @@ public static List<Vector2> GeneratePoints(float radius, Vector2 size, int seed,
6060
return points;
6161
}
6262

63-
public static List<Vector2Int> GenerateIntPoints(float radius, Vector2Int size, int seed,
64-
int maxSamplesPerPoint = 30, Func<Vector2Int, bool> validate = null)
63+
public static List<Vector2Int> GenerateIntPoints(float radius, Vector2Int size, int seed, int maxSamplesPerPoint = 30, Func<Vector2Int, bool> validate = null)
6564
{
66-
var rng = new System.Random(seed);
65+
var rng = new RandomGeneratorStruct((uint)seed);
6766
var points = new List<Vector2Int>();
6867
var cellSize = radius / Mathf.Sqrt(2);
6968
var gridWidth = Mathf.CeilToInt(size.x / cellSize);
7069
var gridHeight = Mathf.CeilToInt(size.y / cellSize);
70+
7171
//Grid values equal to zero mean there is no point in that grid cell
7272
var grid = new int[gridWidth, gridHeight];
7373
var spawnPoints = new List<Vector2Int>();
@@ -77,17 +77,17 @@ public static List<Vector2Int> GenerateIntPoints(float radius, Vector2Int size,
7777
while (spawnPoints.Count > 0)
7878
{
7979
//Get a random spawn point from the list
80-
var spawnIndex = rng.Next(0, spawnPoints.Count);
80+
var spawnIndex = rng.NextIntRange(0, spawnPoints.Count - 1);
8181
var spawnCenter = spawnPoints[spawnIndex];
8282
var accepted = false;
8383

8484
for (int i = 0; i < maxSamplesPerPoint; i++)
8585
{
8686
//Get a random direction vector
87-
var angle = (float) (rng.NextDouble() * Mathf.PI * 2);
87+
var angle = (float) (rng.NextFloatZeroToOne() * Mathf.PI * 2);
8888
var dir = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
8989
//Get point along that direction vector between radius and 2radius distance away
90-
var distance = (float) (radius + rng.NextDouble() * radius * 2);
90+
var distance = (float) (radius + rng.NextFloatZeroToOne() * radius * 2);
9191
var pt = spawnCenter + dir * distance;
9292
var candidate = new Vector2Int((int) pt.x, (int) pt.y);
9393

@@ -200,4 +200,4 @@ private static bool IsValid(Vector2 pt, Vector2 sampleRegionSize, float cellSize
200200

201201
}
202202

203-
}
203+
}
Lines changed: 133 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
namespace Gameframe.Procgen
55
{
66
/// <summary>
7-
/// Noise based random number generator
7+
/// Noise based random number generator (Struct version)
88
/// Allows for fast random-access within a sequence of generated numbers
99
/// Based on GDC 2017 talk and code by Squirrel Eiserloh
1010
/// </summary>
11-
public class NoiseRng : IRandomAccessRandomNumberGenerator
11+
public struct RandomGeneratorStruct : IRandomAccessRandomNumberGenerator
1212
{
1313
private uint seed;
1414
private int position;
@@ -17,21 +17,12 @@ public class NoiseRng : IRandomAccessRandomNumberGenerator
1717
/// Initialize random number generator with a given seed
1818
/// </summary>
1919
/// <param name="seed">see for the random number generator</param>
20-
public NoiseRng(uint seed)
20+
public RandomGeneratorStruct(uint seed)
2121
{
2222
this.seed = seed;
2323
position = 0;
2424
}
2525

26-
/// <summary>
27-
/// Seeds using DateTime.UtcNow.Ticks
28-
/// </summary>
29-
public NoiseRng()
30-
{
31-
this.seed = (uint)DateTime.UtcNow.Ticks;
32-
position = 0;
33-
}
34-
3526
/// <summary>
3627
/// Current position in the number generator sequence
3728
/// </summary>
@@ -194,4 +185,134 @@ public Vector3 NextDirection3D()
194185
#endregion
195186

196187
}
188+
189+
/// <summary>
190+
/// Noise based random number generator
191+
/// Allows for fast random-access within a sequence of generated numbers
192+
/// Based on GDC 2017 talk and code by Squirrel Eiserloh
193+
/// </summary>
194+
public class RandomGenerator : IRandomAccessRandomNumberGenerator
195+
{
196+
private RandomGeneratorStruct _randomGeneratorStruct;
197+
198+
/// <summary>
199+
/// Initialize random number generator with a given seed
200+
/// </summary>
201+
/// <param name="seed">see for the random number generator</param>
202+
public RandomGenerator(uint seed)
203+
{
204+
_randomGeneratorStruct = new RandomGeneratorStruct(seed);
205+
}
206+
207+
/// <summary>
208+
/// Seeds using DateTime.UtcNow.Ticks
209+
/// </summary>
210+
public RandomGenerator()
211+
{
212+
_randomGeneratorStruct = new RandomGeneratorStruct((uint)DateTime.UtcNow.Ticks);
213+
}
214+
215+
/// <summary>
216+
/// Current position in the number generator sequence
217+
/// </summary>
218+
public int Position
219+
{
220+
get => _randomGeneratorStruct.Position;
221+
set => _randomGeneratorStruct.Position = value;
222+
}
223+
224+
/// <summary>
225+
/// Current Seed
226+
/// </summary>
227+
public uint Seed => _randomGeneratorStruct.Seed;
228+
229+
/// <summary>
230+
/// Reseed the number generator with a new seed and position
231+
/// </summary>
232+
/// <param name="seed">seed</param>
233+
/// <param name="position">position in number generation sequence</param>
234+
public void ReSeed(uint seed, int position = 0) => _randomGeneratorStruct.ReSeed(seed, position);
235+
236+
#region Rand Methods
237+
238+
/// <summary>
239+
/// Next random unsigned integer
240+
/// </summary>
241+
/// <returns>next random unsigned integer in the current sequence</returns>
242+
public uint NextUint() => _randomGeneratorStruct.NextUint();
243+
244+
/// <summary>
245+
/// Next random unsigned short
246+
/// </summary>
247+
/// <returns>next random unsigned short in the current sequence</returns>
248+
public ushort NextUshort() => _randomGeneratorStruct.NextUshort();
249+
250+
/// <summary>
251+
/// Next random byte
252+
/// </summary>
253+
/// <returns>next random byte in the current sequence</returns>
254+
public byte NextByte() => _randomGeneratorStruct.NextByte();
255+
256+
/// <summary>
257+
/// Next random integer
258+
/// </summary>
259+
/// <returns>next random integer in the current sequence</returns>
260+
public int NextInt() => _randomGeneratorStruct.NextInt();
261+
262+
/// <summary>
263+
/// Next random short
264+
/// </summary>
265+
/// <returns>next random short in the current sequence</returns>
266+
public short NextShort() => _randomGeneratorStruct.NextShort();
267+
268+
/// <summary>
269+
/// Next random float in the range 0 to 1
270+
/// </summary>
271+
/// <returns>Next random float in the range 0 to 1 (inclusive, inclusive)</returns>
272+
public float NextFloatZeroToOne() => _randomGeneratorStruct.NextFloatZeroToOne();
273+
274+
/// <summary>
275+
/// Next random float in the range -1 to 1
276+
/// </summary>
277+
/// <returns>Next random float in the range -1 to 1 (inclusive, inclusive)</returns>
278+
public float NextFloatNegOneToOne() => _randomGeneratorStruct.NextFloatNegOneToOne();
279+
280+
/// <summary>
281+
/// Next random float in the range min to max
282+
/// </summary>
283+
/// <param name="min">min return value</param>
284+
/// <param name="max">max return value</param>
285+
/// <returns>Next random float in the range min to max (inclusive, inclusive)</returns>
286+
public float NextFloatRange(float min, float max) => _randomGeneratorStruct.NextFloatRange(min,max);
287+
288+
/// <summary>
289+
/// Next random integer in the range min to max
290+
/// </summary>
291+
/// <param name="min">min return value</param>
292+
/// <param name="max">max return value</param>
293+
/// <returns>Next random int in the range min to max (inclusive, inclusive)</returns>
294+
public int NextIntRange(int min, int max) => _randomGeneratorStruct.NextIntRange(min,max);
295+
296+
/// <summary>
297+
/// Rolls for a true for false with the given probability
298+
/// </summary>
299+
/// <param name="probabilityOfReturningTrue">probably that this function will return true</param>
300+
/// <returns>true or false</returns>
301+
public bool RollChance(float probabilityOfReturningTrue) =>
302+
_randomGeneratorStruct.RollChance(probabilityOfReturningTrue);
303+
304+
/// <summary>
305+
/// Next uniformly distributed randomized 2d direction
306+
/// </summary>
307+
/// <returns>Random Normalized Vector2</returns>
308+
public Vector2 NextDirection2D() => _randomGeneratorStruct.NextDirection2D();
309+
310+
/// <summary>
311+
/// Next uniformly distributed randomized 3d direction
312+
/// </summary>
313+
/// <returns>Random Normalized Vector3</returns>
314+
public Vector3 NextDirection3D() => _randomGeneratorStruct.NextDirection3D();
315+
316+
#endregion
317+
}
197318
}

Runtime/Visualizers/RandomDirectionVisualizer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class RandomDirectionVisualizer : MonoBehaviour
1919
public Color sphereColor = Color.white;
2020
public Color pointColor = Color.white;
2121

22-
private NoiseRng rand;
22+
private RandomGenerator rand;
2323

2424
public enum DirectionDimensions
2525
{
@@ -31,7 +31,7 @@ private void OnDrawGizmos()
3131
{
3232
if (rand == null)
3333
{
34-
rand = new NoiseRng(seed);
34+
rand = new RandomGenerator(seed);
3535
}
3636

3737
rand.ReSeed(seed, 0);

Runtime/WorldMap/Layers/PoissonMapLayerGenerator.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ public class PoissonMapLayerGenerator : WorldMapLayerGenerator
77
{
88
[SerializeField]
99
private float radius = 10;
10-
10+
1111
[SerializeField]
1212
private int maxSamplesPerPoint = 30;
13-
13+
1414
[SerializeField]
1515
private bool useRegions = true;
16-
16+
1717
[SerializeField]
1818
private int edgeAvoidance;
1919

@@ -81,13 +81,12 @@ private void AddToWorldUsingRegions(WorldMapData mapData)
8181

8282
private void AddToWorldDefault(WorldMapData mapData)
8383
{
84-
var points = PoissonDiskSampling.GenerateIntPoints(radius, new Vector2Int(mapData.width, mapData.height),
85-
mapData.seed, maxSamplesPerPoint);
84+
var points = PoissonDiskSampling.GenerateIntPoints(radius, new Vector2Int(mapData.width, mapData.height), mapData.seed, maxSamplesPerPoint);
8685
var layer = new PoissonMapLayerData
8786
{
8887
points = points
8988
};
9089
mapData.layers.Add(layer);
9190
}
9291
}
93-
}
92+
}

Tests/Runtime/RuntimeTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class RuntimeTests
99
[Test]
1010
public void NoiseRNG_IntRange()
1111
{
12-
var noiseRng = new NoiseRng((uint)DateTime.UtcNow.Ticks);
12+
var noiseRng = new RandomGenerator((uint)DateTime.UtcNow.Ticks);
1313

1414
const int maxRange = 2;
1515
var totals = new int[maxRange+1];
@@ -35,7 +35,7 @@ public void NoiseRNG_IntRange()
3535
[Test]
3636
public void NoiseRNG_RollChance_33percent()
3737
{
38-
var noiseRng = new NoiseRng((uint)DateTime.UtcNow.Ticks);
38+
var noiseRng = new RandomGenerator((uint)DateTime.UtcNow.Ticks);
3939

4040
const float probability = 0.33f;
4141
var totals = new int[2];

0 commit comments

Comments
 (0)