RegionIO/internal/worldgen/normal_noise.go
Master290 a7bb9496ae Initial commit: RegionIO Minecraft server core (26.1.2/protocol 775)
Vanilla-faithful overworld generator (final_density + multi-noise biomes),
full connection lifecycle (status/login/configuration/play), chunk streaming,
creative block editing, and the protocol/nbt/registry infrastructure.
2026-06-24 00:32:51 +03:00

49 lines
1.6 KiB
Go

package worldgen
// normalInputFactor is NormalNoise.INPUT_FACTOR, the frequency offset applied
// to the second Perlin field so the two octave stacks don't align.
const normalInputFactor = 1.0181268882175227
// NormalNoise combines two PerlinNoise fields, scaled so the result has a
// normalized deviation. This is the noise type referenced by density functions.
type NormalNoise struct {
first *PerlinNoise
second *PerlinNoise
valueFactor float64
maxValue float64
}
// NewNormalNoise builds a NormalNoise from the same parameters vanilla uses:
// two PerlinNoise stacks drawn sequentially from r, plus a value factor derived
// from the span of non-zero amplitudes.
func NewNormalNoise(r RandomSource, firstOctave int, amplitudes []float64) *NormalNoise {
n := &NormalNoise{
first: NewPerlinNoise(r, firstOctave, amplitudes),
second: NewPerlinNoise(r, firstOctave, amplitudes),
}
min, max := len(amplitudes), 0
for i, a := range amplitudes {
if a != 0 {
if i < min {
min = i
}
if i > max {
max = i
}
}
}
expectedDeviation := 0.1 * (1.0 + 1.0/float64(max-min+1))
n.valueFactor = (1.0 / 6.0) / expectedDeviation
n.maxValue = (n.first.MaxValue() + n.second.MaxValue()) * n.valueFactor
return n
}
// GetValue samples the combined noise at (x, y, z).
func (n *NormalNoise) GetValue(x, y, z float64) float64 {
return (n.first.GetValue(x, y, z) +
n.second.GetValue(x*normalInputFactor, y*normalInputFactor, z*normalInputFactor)) * n.valueFactor
}
// MaxValue returns the theoretical maximum magnitude.
func (n *NormalNoise) MaxValue() float64 { return n.maxValue }