Files
mrgameeng/src/MrGameEng.Simulation/WorldGen/Heightmap.cs
T
Leonid PershinandClaude Opus 4.8 53659450a6
CI / build-test (push) Successful in 1m14s
Add MrGameEng.WorldGen: deterministic procedural world generation
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>
2026-06-12 09:23:45 +03:00

65 lines
1.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 minmax; 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;
}
}
}