mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-12 05:53:51 -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,
|
minHeight: i32,
|
||||||
maxHeight: i32,
|
maxHeight: i32,
|
||||||
interpolation: Interpolation,
|
interpolation: Interpolation,
|
||||||
|
interpolationWeight: f32,
|
||||||
roughness: f32,
|
roughness: f32,
|
||||||
hills: f32,
|
hills: f32,
|
||||||
mountains: f32,
|
mountains: f32,
|
||||||
@ -266,6 +267,7 @@ pub const Biome = struct {
|
|||||||
.hills = json.get(f32, "hills", 0),
|
.hills = json.get(f32, "hills", 0),
|
||||||
.mountains = json.get(f32, "mountains", 0),
|
.mountains = json.get(f32, "mountains", 0),
|
||||||
.interpolation = std.meta.stringToEnum(Interpolation, json.get([]const u8, "interpolation", "square")) orelse .square,
|
.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),
|
.caves = json.get(f32, "caves", -0.375),
|
||||||
.crystals = json.get(u32, "crystals", 0),
|
.crystals = json.get(u32, "crystals", 0),
|
||||||
.stalagmites = json.get(u32, "stalagmites", 0),
|
.stalagmites = json.get(u32, "stalagmites", 0),
|
||||||
|
@ -10,6 +10,8 @@ const noise = terrain.noise;
|
|||||||
const FractalNoise = noise.FractalNoise;
|
const FractalNoise = noise.FractalNoise;
|
||||||
const RandomlyWeightedFractalNoise = noise.RandomlyWeightedFractalNoise;
|
const RandomlyWeightedFractalNoise = noise.RandomlyWeightedFractalNoise;
|
||||||
const PerlinNoise = noise.PerlinNoise;
|
const PerlinNoise = noise.PerlinNoise;
|
||||||
|
const vec = main.vec;
|
||||||
|
const Vec2f = vec.Vec2f;
|
||||||
|
|
||||||
pub const id = "cubyz:mapgen_v1";
|
pub const id = "cubyz:mapgen_v1";
|
||||||
|
|
||||||
@ -22,25 +24,25 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Assumes the 2 points are at tᵢ = (0, 1)
|
/// 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) {
|
switch (interpolation) {
|
||||||
.none => {
|
.none => {
|
||||||
if(t < 0.5) {
|
if(t < 0.5) {
|
||||||
return [2]f32 {1, 0};
|
return .{1, 0};
|
||||||
} else {
|
} else {
|
||||||
return [2]f32 {0, 1};
|
return .{0, 1};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.linear => {
|
.linear => {
|
||||||
return [2]f32 {1 - t, t};
|
return .{1 - t, t};
|
||||||
},
|
},
|
||||||
.square => {
|
.square => {
|
||||||
if(t < 0.5) {
|
if(t < 0.5) {
|
||||||
const tSqr = 2*t*t;
|
const tSqr = 2*t*t;
|
||||||
return [2]f32 {1 - tSqr, tSqr};
|
return .{1 - tSqr, tSqr};
|
||||||
} else {
|
} else {
|
||||||
const tSqr = 2*(1 - t)*(1 - t);
|
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;
|
closestBiome = biomePositions.get(@intCast(xBiome + 1), @intCast(yBiome + 1)).biome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const coefficientsX = interpolationWeights(relXBiome, closestBiome.interpolation);
|
const interpolationCoefficientsX = interpolationWeights(relXBiome, .square);
|
||||||
const coefficientsY = interpolationWeights(relYBiome, closestBiome.interpolation);
|
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) |dx| {
|
||||||
for(0..2) |dy| {
|
for(0..2) |dy| {
|
||||||
const biomeMapX = @as(usize, @intCast(xBiome)) + dx;
|
const biomeMapX = @as(usize, @intCast(xBiome)) + dx;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user