mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 19:50:23 -04:00
Interpolate the biome interpolation based on some weights, instead of choosing the closest one.
This allows making plateaus without having a ramp (from the other biome interpolation) leading up to it.
This commit is contained in:
parent
4343f6eb18
commit
78db8f0839
@ -227,6 +227,7 @@ pub const Biome = struct {
|
||||
minHeight: i32,
|
||||
maxHeight: i32,
|
||||
interpolation: Interpolation,
|
||||
interpolationWeight: f32,
|
||||
roughness: f32,
|
||||
hills: f32,
|
||||
mountains: f32,
|
||||
@ -266,6 +267,7 @@ pub const Biome = struct {
|
||||
.hills = json.get(f32, "hills", 0),
|
||||
.mountains = json.get(f32, "mountains", 0),
|
||||
.interpolation = std.meta.stringToEnum(Interpolation, json.get([]const u8, "interpolation", "square")) orelse .square,
|
||||
.interpolationWeight = @max(json.get(f32, "interpolationWeight", 1), std.math.floatMin(f32)),
|
||||
.caves = json.get(f32, "caves", -0.375),
|
||||
.crystals = json.get(u32, "crystals", 0),
|
||||
.stalagmites = json.get(u32, "stalagmites", 0),
|
||||
|
@ -10,6 +10,8 @@ const noise = terrain.noise;
|
||||
const FractalNoise = noise.FractalNoise;
|
||||
const RandomlyWeightedFractalNoise = noise.RandomlyWeightedFractalNoise;
|
||||
const PerlinNoise = noise.PerlinNoise;
|
||||
const vec = main.vec;
|
||||
const Vec2f = vec.Vec2f;
|
||||
|
||||
pub const id = "cubyz:mapgen_v1";
|
||||
|
||||
@ -22,25 +24,25 @@ pub fn deinit() void {
|
||||
}
|
||||
|
||||
/// Assumes the 2 points are at tᵢ = (0, 1)
|
||||
fn interpolationWeights(t: f32, interpolation: terrain.biomes.Interpolation) [2]f32 {
|
||||
fn interpolationWeights(t: f32, interpolation: terrain.biomes.Interpolation) Vec2f {
|
||||
switch (interpolation) {
|
||||
.none => {
|
||||
if(t < 0.5) {
|
||||
return [2]f32 {1, 0};
|
||||
return .{1, 0};
|
||||
} else {
|
||||
return [2]f32 {0, 1};
|
||||
return .{0, 1};
|
||||
}
|
||||
},
|
||||
.linear => {
|
||||
return [2]f32 {1 - t, t};
|
||||
return .{1 - t, t};
|
||||
},
|
||||
.square => {
|
||||
if(t < 0.5) {
|
||||
const tSqr = 2*t*t;
|
||||
return [2]f32 {1 - tSqr, tSqr};
|
||||
return .{1 - tSqr, tSqr};
|
||||
} else {
|
||||
const tSqr = 2*(1 - t)*(1 - t);
|
||||
return [2]f32 {tSqr, 1 - tSqr};
|
||||
return .{tSqr, 1 - tSqr};
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -113,8 +115,24 @@ pub fn generateMapFragment(map: *MapFragment, worldSeed: u64) void {
|
||||
closestBiome = biomePositions.get(@intCast(xBiome + 1), @intCast(yBiome + 1)).biome;
|
||||
}
|
||||
}
|
||||
const coefficientsX = interpolationWeights(relXBiome, closestBiome.interpolation);
|
||||
const coefficientsY = interpolationWeights(relYBiome, closestBiome.interpolation);
|
||||
const interpolationCoefficientsX = interpolationWeights(relXBiome, .square);
|
||||
const interpolationCoefficientsY = interpolationWeights(relYBiome, .square);
|
||||
var coefficientsX: vec.Vec2f = .{0, 0};
|
||||
var coefficientsY: vec.Vec2f = .{0, 0};
|
||||
var totalWeight: f32 = 0;
|
||||
for(0..2) |dx| {
|
||||
for(0..2) |dy| {
|
||||
const biomeMapX = @as(usize, @intCast(xBiome)) + dx;
|
||||
const biomeMapY = @as(usize, @intCast(yBiome)) + dy;
|
||||
const biomeSample = biomePositions.get(biomeMapX, biomeMapY);
|
||||
const weight = interpolationCoefficientsX[dx]*interpolationCoefficientsY[dy]*biomeSample.biome.interpolationWeight;
|
||||
coefficientsX += interpolationWeights(relXBiome, biomeSample.biome.interpolation)*@as(Vec2f, @splat(weight));
|
||||
coefficientsY += interpolationWeights(relYBiome, biomeSample.biome.interpolation)*@as(Vec2f, @splat(weight));
|
||||
totalWeight += weight;
|
||||
}
|
||||
}
|
||||
coefficientsX /= @splat(totalWeight);
|
||||
coefficientsY /= @splat(totalWeight);
|
||||
for(0..2) |dx| {
|
||||
for(0..2) |dy| {
|
||||
const biomeMapX = @as(usize, @intCast(xBiome)) + dx;
|
||||
|
Loading…
x
Reference in New Issue
Block a user