Add MrGameEng.WorldGen: deterministic procedural world generation
CI / build-test (push) Successful in 1m14s
CI / build-test (push) Successful in 1m14s
Introduce a WorldGen module under Simulation with reusable helpers for seed-based terrain heightmaps: PerlinNoise (deterministic 2D gradient noise), FractalNoise (fBm over octaves), Falloff (island edge masks), Heightmap (row-major grid with min-max normalize) and HeightmapGenerator (settings to normalized heightmap). All deterministic from an integer seed, allocation-free per sample, covered by xUnit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ef1111bcb6
commit
53659450a6
@@ -0,0 +1,64 @@
|
||||
namespace MrGameEng.WorldGen;
|
||||
|
||||
/// <summary>
|
||||
/// A dense row-major grid of height values. Plain data with indexed access — fill it from a
|
||||
/// <see cref="HeightmapGenerator"/> and read it from worldgen code. Values are arbitrary until
|
||||
/// <see cref="Normalize"/> rescales them into <c>[0, 1]</c>.
|
||||
/// </summary>
|
||||
public sealed class Heightmap
|
||||
{
|
||||
/// <summary>Grid width in cells.</summary>
|
||||
public int Width { get; }
|
||||
|
||||
/// <summary>Grid height in cells.</summary>
|
||||
public int Height { get; }
|
||||
|
||||
/// <summary>Row-major values, length <see cref="Width"/>×<see cref="Height"/>.</summary>
|
||||
public float[] Values { get; }
|
||||
|
||||
/// <summary>Creates an all-zero map of the given size.</summary>
|
||||
public Heightmap(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Values = new float[width * height];
|
||||
}
|
||||
|
||||
/// <summary>Height at (<paramref name="x"/>, <paramref name="y"/>).</summary>
|
||||
public float this[int x, int y]
|
||||
{
|
||||
get => Values[y * Width + x];
|
||||
set => Values[y * Width + x] = value;
|
||||
}
|
||||
|
||||
/// <summary>Rescales all values into <c>[0, 1]</c> by min–max; a flat map becomes all zeros.</summary>
|
||||
public void Normalize()
|
||||
{
|
||||
var min = float.MaxValue;
|
||||
var max = float.MinValue;
|
||||
foreach (var v in Values)
|
||||
{
|
||||
if (v < min)
|
||||
{
|
||||
min = v;
|
||||
}
|
||||
|
||||
if (v > max)
|
||||
{
|
||||
max = v;
|
||||
}
|
||||
}
|
||||
|
||||
var range = max - min;
|
||||
if (range <= float.Epsilon)
|
||||
{
|
||||
Array.Clear(Values);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Values.Length; i++)
|
||||
{
|
||||
Values[i] = (Values[i] - min) / range;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user