From 446b036414529d19b723430404ed227b918097d3 Mon Sep 17 00:00:00 2001 From: dags- Date: Sun, 9 Feb 2020 01:48:40 +0000 Subject: [PATCH] added /find command & reworked some of the back-end stuff in Core --- .../terraforged/app/renderer/Renderer.java | 4 +- .../java/com/terraforged/core/cell/Cell.java | 46 +++--- .../terraforged/core/decorator/Decorator.java | 2 +- .../core/decorator/DesertDunes.java | 53 +++++++ .../core/decorator/DesertStacks.java | 12 +- .../core/decorator/SwampPools.java | 11 +- .../com/terraforged/core/module/Blender.java | 11 -- .../terraforged/core/module/CellLookup.java | 29 ---- .../core/module/CellLookupOffset.java | 39 ----- .../terraforged/core/module/MultiBlender.java | 11 -- .../com/terraforged/core/region/Region.java | 4 +- .../core/region/RegionGenerator.java | 2 +- .../core/settings/GeneratorSettings.java | 12 +- .../core/world/WorldDecorators.java | 1 + .../core/world/climate/Climate.java | 4 +- .../core/world/climate/ClimateModule.java | 4 +- .../world/continent/ContinentBlender.java | 21 --- .../world/continent/ContinentLerper2.java | 78 ++++++++++ .../world/continent/ContinentLerper3.java | 96 +++++++++++++ .../core/world/continent/ContinentModule.java | 136 +++++++++++++++++- .../continent/ContinentMultiBlender.java | 22 --- .../core/world/heightmap/Levels.java | 3 + .../core/world/heightmap/WorldHeightmap.java | 73 ++++------ .../core/world/river/PosGenerator.java | 6 +- .../core/world/river/RiverManager.java | 6 +- .../core/world/river/RiverRegion.java | 4 +- .../core/world/terrain/VolcanoPopulator.java | 4 +- .../terrain/region/RegionLerper.java} | 18 +-- .../region/RegionModule.java} | 71 +++------ .../terrain/region/RegionSelector.java} | 20 ++- TerraForgedMod | 2 +- 31 files changed, 498 insertions(+), 307 deletions(-) create mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertDunes.java delete mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookup.java delete mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookupOffset.java delete mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentBlender.java create mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper2.java create mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper3.java delete mode 100644 TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentMultiBlender.java rename TerraForgedCore/src/main/java/com/terraforged/core/{module/Lerp.java => world/terrain/region/RegionLerper.java} (71%) rename TerraForgedCore/src/main/java/com/terraforged/core/world/{continent/VoronoiContinentModule.java => terrain/region/RegionModule.java} (57%) rename TerraForgedCore/src/main/java/com/terraforged/core/{module/Selector.java => world/terrain/region/RegionSelector.java} (76%) diff --git a/TerraForgedApp/src/main/java/com/terraforged/app/renderer/Renderer.java b/TerraForgedApp/src/main/java/com/terraforged/app/renderer/Renderer.java index e9eebbc..15d277f 100644 --- a/TerraForgedApp/src/main/java/com/terraforged/app/renderer/Renderer.java +++ b/TerraForgedApp/src/main/java/com/terraforged/app/renderer/Renderer.java @@ -58,13 +58,13 @@ public abstract class Renderer { if (cell.tag == applet.getCache().getTerrain().coast) { hue = 15; } - float modifier = cell.mask; + float modifier = cell.mask(0.4F, 0.5F, 0F, 1F); float modAlpha = 0.1F; float mod = (1 - modAlpha) + (modifier * modAlpha); float sat = 70; float bri = 70; applet.fill(hue, 65, 70); - return height * el; + return cell.regionEdge * el; } else if(applet.controller.getColorMode() == Applet.EROSION) { float change = cell.sediment + cell.erosion; float value = Math.abs(cell.sediment * 250); diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/cell/Cell.java b/TerraForgedCore/src/main/java/com/terraforged/core/cell/Cell.java index 8ee2815..143d1f8 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/cell/Cell.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/cell/Cell.java @@ -18,9 +18,13 @@ public class Cell { public float continent; public float continentEdge; + public float region; + public float regionEdge; + public float biome; + public float biomeEdge = 1F; + public float riverMask = 1F; public float value; - public float biome; public float biomeMoisture; public float biomeTemperature; public float moisture; @@ -28,49 +32,53 @@ public class Cell { public float steepness; public float erosion; public float sediment; - - public float mask = 1F; - public float biomeMask = 1F; public float biomeTypeMask = 1F; - public float regionMask = 1F; - public float riverMask = 1F; public BiomeType biomeType = BiomeType.GRASSLAND; public T tag = null; public void copy(Cell other) { + value = other.value; + continent = other.continent; continentEdge = other.continentEdge; - value = other.value; - biome = other.biome; + region = other.region; + regionEdge = other.regionEdge; + + biome = other.biome; + biomeEdge = other.biomeEdge; - biomeMask = other.biomeMask; riverMask = other.riverMask; - biomeMoisture = other.biomeMoisture; - biomeTemperature = other.biomeTemperature; - mask = other.mask; - regionMask = other.regionMask; + moisture = other.moisture; temperature = other.temperature; + biomeMoisture = other.biomeMoisture; + biomeTemperature = other.biomeTemperature; + steepness = other.steepness; erosion = other.erosion; sediment = other.sediment; biomeType = other.biomeType; biomeTypeMask = other.biomeTypeMask; + tag = other.tag; } - public float combinedMask(float clamp) { - return NoiseUtil.map(biomeMask * regionMask, 0, clamp, clamp); + public float continentMask(float min, float max) { + return NoiseUtil.map(continentEdge, min, max, max - min); } - public float biomeMask(float clamp) { - return NoiseUtil.map(biomeMask, 0, clamp, clamp); + public float regionMask(float min, float max) { + return NoiseUtil.map(regionEdge, min, max, max - min); } - public float regionMask(float clamp) { - return NoiseUtil.map(regionMask, 0, clamp, clamp); + public float biomeMask(float min, float max) { + return NoiseUtil.map(biomeEdge, min, max, max - min); + } + + public float mask(float cmin, float cmax, float rmin, float rmax) { + return riverMask * continentMask(cmin, cmax) * regionMask(rmin, rmax); } public boolean isAbsent() { diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/Decorator.java b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/Decorator.java index bbdb2c1..cd6040d 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/Decorator.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/Decorator.java @@ -5,5 +5,5 @@ import com.terraforged.core.world.terrain.Terrain; public interface Decorator { - void apply(Cell cell, float x, float y); + boolean apply(Cell cell, float x, float y); } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertDunes.java b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertDunes.java new file mode 100644 index 0000000..7364d69 --- /dev/null +++ b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertDunes.java @@ -0,0 +1,53 @@ +package com.terraforged.core.decorator; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.func.CellFunc; + +public class DesertDunes implements Decorator { + + private final Module module; + private final float climateMin; + private final float climateMax; + private final float climateRange; + + private final Levels levels; + private final Terrains terrains; + private final Terrain dunes = new Terrain("dunes", 100); + + public DesertDunes(GeneratorContext context) { + this.climateMin = 0.6F; + this.climateMax = 0.85F; + this.climateRange = climateMax - climateMin; + this.levels = context.levels; + this.terrains = context.terrain; + this.module = Source.cell(context.seed.next(), 80, CellFunc.DISTANCE) + .warp(context.seed.next(), 70, 1, 70) + .scale(30 / 255D); + } + + @Override + public boolean apply(Cell cell, float x, float y) { + float temp = cell.temperature; + float moisture = 1 - cell.moisture; + float climate = temp * moisture; + if (climate < climateMin) { + return false; + } + + float duneHeight = module.getValue(x, y); + float climateMask = climate > climateMax ? 1F : (climate - climateMin) / climateRange; + float regionMask = cell.mask(0.4F, 0.5F, 0,0.8F); + + float height = duneHeight * climateMask * regionMask; + cell.value += height; + cell.tag = dunes; + + return height >= levels.unit; + } +} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertStacks.java b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertStacks.java index 70eeadd..935ed31 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertStacks.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/DesertStacks.java @@ -12,6 +12,7 @@ public class DesertStacks implements Decorator { private final float minY; private final float maxY; + private final Levels levels; private final Module module; public DesertStacks(Seed seed, Levels levels) { @@ -35,21 +36,24 @@ public class DesertStacks implements Decorator { this.minY = levels.water(0); this.maxY = levels.water(50); + this.levels = levels; this.module = stack.scale(scale).mult(mask); } @Override - public void apply(Cell cell, float x, float y) { + public boolean apply(Cell cell, float x, float y) { if (BiomeType.DESERT != cell.biomeType) { - return; + return false; } if (cell.value <= minY || cell.value > maxY) { - return; + return false; } float value = module.getValue(x, y); - value *= cell.biomeMask; + value *= cell.biomeEdge; cell.value += value; + + return value > levels.unit; } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/SwampPools.java b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/SwampPools.java index 5850f64..3ee7909 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/decorator/SwampPools.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/decorator/SwampPools.java @@ -30,21 +30,21 @@ public class SwampPools implements Decorator { } @Override - public void apply(Cell cell, float x, float y) { + public boolean apply(Cell cell, float x, float y) { if (cell.tag == terrains.ocean) { - return; + return false; } if (cell.moisture < 0.7 || cell.temperature < 0.3) { - return; + return false; } if (cell.value <= minY) { - return; + return false; } if (cell.value > blendY) { - return; + return false; } float alpha = module.getValue(x, y); @@ -55,5 +55,6 @@ public class SwampPools implements Decorator { } cell.value = NoiseUtil.lerp(cell.value, minY, alpha); + return true; } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/Blender.java b/TerraForgedCore/src/main/java/com/terraforged/core/module/Blender.java index fdb03c2..f9947d0 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/Blender.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/module/Blender.java @@ -18,8 +18,6 @@ public class Blender extends Select implements Populator { private final float midpoint; private final float tagThreshold; - private boolean mask = false; - public Blender(Module control, Populator lower, Populator upper, float min, float max, float split) { super(control); this.lower = lower; @@ -42,11 +40,6 @@ public class Blender extends Select implements Populator { this.tagThreshold = tagThreshold; } - public Blender mask() { - mask = true; - return this; - } - @Override public void apply(Cell cell, float x, float y) { float select = getSelect(cell, x, y); @@ -74,10 +67,6 @@ public class Blender extends Select implements Populator { if (select < midpoint) { cell.tag = lowerType; } - - if (mask) { - cell.mask *= alpha; - } } @Override diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookup.java b/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookup.java deleted file mode 100644 index 6bc9f16..0000000 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookup.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.terraforged.core.module; - -import com.terraforged.core.cell.Cell; -import com.terraforged.core.cell.Populator; -import com.terraforged.core.world.heightmap.Heightmap; -import com.terraforged.core.world.terrain.Terrain; - -public class CellLookup implements Populator { - - private final int scale; - private final Heightmap heightmap; - - public CellLookup(Heightmap heightmap, int scale) { - this.heightmap = heightmap; - this.scale = scale; - } - - @Override - public void apply(Cell cell, float x, float y) { - float px = x * scale; - float pz = y * scale; - heightmap.getValue(px, pz); - } - - @Override - public void tag(Cell cell, float x, float y) { - - } -} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookupOffset.java b/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookupOffset.java deleted file mode 100644 index 76e50f0..0000000 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/CellLookupOffset.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.terraforged.core.module; - -import com.terraforged.core.cell.Cell; -import com.terraforged.core.cell.Populator; -import com.terraforged.core.world.heightmap.Heightmap; -import com.terraforged.core.world.terrain.Terrain; -import me.dags.noise.Module; -import me.dags.noise.util.NoiseUtil; - -public class CellLookupOffset implements Populator { - - private final int scale; - private final Module direction; - private final Module strength; - private final Heightmap heightmap; - - public CellLookupOffset(Heightmap heightmap, Module direction, Module strength, int scale) { - this.scale = scale; - this.heightmap = heightmap; - this.direction = direction; - this.strength = strength; - } - - @Override - public void apply(Cell cell, float x, float y) { - float px = x * scale; - float pz = y * scale; - float str = strength.getValue(x, y); - float dir = direction.getValue(x, y) * NoiseUtil.PI2; - float dx = NoiseUtil.sin(dir) * str; - float dz = NoiseUtil.cos(dir) * str; - heightmap.visit(cell, px + dx, pz + dz); - } - - @Override - public void tag(Cell cell, float x, float y) { - - } -} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/MultiBlender.java b/TerraForgedCore/src/main/java/com/terraforged/core/module/MultiBlender.java index 2260cbf..f39dd79 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/MultiBlender.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/module/MultiBlender.java @@ -21,8 +21,6 @@ public class MultiBlender extends Select implements Populator { private final float lowerRange; private final float upperRange; - private boolean mask = false; - public MultiBlender(Climate climate, Populator control, Populator lower, Populator middle, Populator upper, float min, float mid, float max) { super(control); this.climate = climate; @@ -62,11 +60,6 @@ public class MultiBlender extends Select implements Populator { float upperVal = cell.value; cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha); -// cell.tag = lowerType; - - if (mask) { - cell.mask *= alpha; - } } else { float alpha = Interpolation.CURVE3.apply((select - midpoint) / upperRange); @@ -75,10 +68,6 @@ public class MultiBlender extends Select implements Populator { upper.apply(cell, x, y); cell.value = NoiseUtil.lerp(lowerVal, cell.value, alpha); - - if (mask) { - cell.mask *= alpha; - } } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/region/Region.java b/TerraForgedCore/src/main/java/com/terraforged/core/region/Region.java index 6446780..9084088 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/region/Region.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/region/Region.java @@ -156,7 +156,9 @@ public class Region implements Extent { int index = blockSize.indexOf(dx, dz); GenCell cell = blocks[index]; for (Decorator decorator : decorators) { - decorator.apply(cell, getBlockX() + dx, getBlockZ() + dz); + if (decorator.apply(cell, getBlockX() + dx, getBlockZ() + dz)) { + break; + } } } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/region/RegionGenerator.java b/TerraForgedCore/src/main/java/com/terraforged/core/region/RegionGenerator.java index 182cd75..4113fd5 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/region/RegionGenerator.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/region/RegionGenerator.java @@ -88,7 +88,7 @@ public class RegionGenerator implements RegionExtent { if (filter) { generator.getFilters().apply(region); } -// region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom); + region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom); } public static Builder builder() { diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/settings/GeneratorSettings.java b/TerraForgedCore/src/main/java/com/terraforged/core/settings/GeneratorSettings.java index e2b7452..fb033c0 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/settings/GeneratorSettings.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/settings/GeneratorSettings.java @@ -80,11 +80,11 @@ public class GeneratorSettings { @Range(min = 1, max = 200) @Comment("Controls the scale of shape distortion for biomes") - public int biomeWarpScale = 30; + public int biomeWarpScale = 35; @Range(min = 1, max = 200) @Comment("Controls the strength of shape distortion for biomes") - public int biomeWarpStrength = 30; + public int biomeWarpStrength = 70; } @Serializable @@ -95,11 +95,11 @@ public class GeneratorSettings { @Range(min = 1, max = 100) @Comment("Controls the scale of the noise") - public int scale = 4; + public int scale = 8; @Range(min = 1, max = 5) @Comment("Controls the number of noise octaves") - public int octaves = 1; + public int octaves = 2; @Range(min = 0F, max = 5.5F) @Comment("Controls the gain subsequent noise octaves") @@ -107,11 +107,11 @@ public class GeneratorSettings { @Range(min = 0F, max = 10.5F) @Comment("Controls the lacunarity of subsequent noise octaves") - public float lacunarity = 2F; + public float lacunarity = 2.5F; @Range(min = 1, max = 100) @Comment("Controls the strength of the noise") - public int strength = 12; + public int strength = 24; public Module build(int seed) { return Source.build(seed, scale, octaves).gain(gain).lacunarity(lacunarity).build(type).bias(-0.5); diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/WorldDecorators.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/WorldDecorators.java index f9ea02a..0f2dab5 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/WorldDecorators.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/WorldDecorators.java @@ -1,6 +1,7 @@ package com.terraforged.core.world; import com.terraforged.core.decorator.Decorator; +import com.terraforged.core.decorator.DesertDunes; import com.terraforged.core.decorator.DesertStacks; import com.terraforged.core.decorator.SwampPools; diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/Climate.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/Climate.java index 4604907..312c195 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/Climate.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/Climate.java @@ -2,8 +2,6 @@ package com.terraforged.core.world.climate; import com.terraforged.core.cell.Cell; import com.terraforged.core.world.GeneratorContext; -import com.terraforged.core.world.biome.BiomeType; -import com.terraforged.core.world.heightmap.WorldHeightmap; import com.terraforged.core.world.terrain.Terrain; import me.dags.noise.Module; import me.dags.noise.Source; @@ -26,7 +24,7 @@ public class Climate { private final ClimateModule biomeNoise; - public Climate(GeneratorContext context, WorldHeightmap heightmap) { + public Climate(GeneratorContext context) { this.biomeNoise = new ClimateModule(context.seed, context.settings.generator); this.treeLine = Source.perlin(context.seed.next(), context.settings.generator.biome.biomeSize * 2, 1) diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/ClimateModule.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/ClimateModule.java index 5828e4b..48414d2 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/ClimateModule.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/climate/ClimateModule.java @@ -104,10 +104,10 @@ public class ClimateModule { } if (mask) { - cell.biomeMask = edgeValue(edgeDistance, edgeDistance2); + cell.biomeEdge = edgeValue(edgeDistance, edgeDistance2); } else { cell.biome = cellValue(seed, cellX, cellY); - cell.biomeMask = edgeValue(edgeDistance, edgeDistance2); + cell.biomeEdge = edgeValue(edgeDistance, edgeDistance2); cell.biomeMoisture = moisture.getValue(cellX + vec2f.x, cellY + vec2f.y); cell.biomeTemperature = temperature.getValue(cellX + vec2f.x, cellY + vec2f.y); cell.moisture = moisture.getValue(x, y); diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentBlender.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentBlender.java deleted file mode 100644 index 5eb9459..0000000 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentBlender.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.terraforged.core.world.continent; - -import com.terraforged.core.cell.Cell; -import com.terraforged.core.cell.Populator; -import com.terraforged.core.module.Blender; -import com.terraforged.core.world.terrain.Terrain; - -public class ContinentBlender extends Blender { - - private final Populator control; - - public ContinentBlender(Populator continent, Populator lower, Populator upper, float min, float max, float split, float tagThreshold) { - super(continent, lower, upper, min, max, split, tagThreshold); - this.control = continent; - } - - @Override - public float getSelect(Cell cell, float x, float z) { - return cell.continentEdge; - } -} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper2.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper2.java new file mode 100644 index 0000000..7829f81 --- /dev/null +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper2.java @@ -0,0 +1,78 @@ +package com.terraforged.core.world.continent; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.cell.Populator; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.func.Interpolation; +import me.dags.noise.util.NoiseUtil; + +public class ContinentLerper2 implements Populator { + + private final Populator lower; + private final Populator upper; + + private final float blendLower; + private final float blendUpper; + private final float blendRange; + private final float midpoint; + private final float tagThreshold; + + public ContinentLerper2(Populator lower, Populator upper, float min, float max, float split, float tagThreshold) { + this.lower = lower; + this.upper = upper; + this.blendLower = min; + this.blendUpper = max; + this.blendRange = blendUpper - blendLower; + this.midpoint = blendLower + (blendRange * split); + this.tagThreshold = tagThreshold; + } + + @Override + public void apply(Cell cell, float x, float y) { + float select = cell.continentEdge; + + if (select < blendLower) { + lower.apply(cell, x, y); + return; + } + + if (select > blendUpper) { + upper.apply(cell, x, y); + return; + } + + float alpha = Interpolation.LINEAR.apply((select - blendLower) / blendRange); + lower.apply(cell, x, y); + + float lowerVal = cell.value; + Terrain lowerType = cell.tag; + + upper.apply(cell, x, y); + float upperVal = cell.value; + + cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha); + if (select < midpoint) { + cell.tag = lowerType; + } + } + + @Override + public void tag(Cell cell, float x, float y) { + float select = cell.continentEdge; + if (select < blendLower) { + lower.tag(cell, x, y); + return; + } + + if (select > blendUpper) { + upper.tag(cell, x, y); + return; + } + + if (select < tagThreshold) { + lower.tag(cell, x, y); + } else { + upper.tag(cell, x, y); + } + } +} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper3.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper3.java new file mode 100644 index 0000000..ba2cab7 --- /dev/null +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentLerper3.java @@ -0,0 +1,96 @@ +package com.terraforged.core.world.continent; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.cell.Populator; +import com.terraforged.core.module.MultiBlender; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.func.Interpolation; +import me.dags.noise.util.NoiseUtil; + +public class ContinentLerper3 implements Populator { + + private final Climate climate; + private final Populator lower; + private final Populator middle; + private final Populator upper; + private final float midpoint; + + private final float blendLower; + private final float blendUpper; + + private final float lowerRange; + private final float upperRange; + + public ContinentLerper3(Climate climate, Populator lower, Populator middle, Populator upper, float min, float mid, float max) { + this.climate = climate; + this.lower = lower; + this.upper = upper; + this.middle = middle; + + this.midpoint = mid; + this.blendLower = min; + this.blendUpper = max; + + this.lowerRange = midpoint - blendLower; + this.upperRange = blendUpper - midpoint; + } + + @Override + public void apply(Cell cell, float x, float y) { + float select = cell.continentEdge; + if (select < blendLower) { + lower.apply(cell, x, y); + return; + } + + if (select > blendUpper) { + upper.apply(cell, x, y); + return; + } + + if (select < midpoint) { + float alpha = Interpolation.CURVE3.apply((select - blendLower) / lowerRange); + + lower.apply(cell, x, y); + float lowerVal = cell.value; + Terrain lowerType = cell.tag; + + middle.apply(cell, x, y); + float upperVal = cell.value; + + cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha); + } else { + float alpha = Interpolation.CURVE3.apply((select - midpoint) / upperRange); + + middle.apply(cell, x, y); + float lowerVal = cell.value; + + upper.apply(cell, x, y); + cell.value = NoiseUtil.lerp(lowerVal, cell.value, alpha); + } + } + + @Override + public void tag(Cell cell, float x, float y) { + float select = cell.continentEdge; + if (select < blendLower) { + lower.tag(cell, x, y); + return; + } + + if (select > blendUpper) { + upper.tag(cell, x, y); + return; + } + + if (select < midpoint) { + lower.tag(cell, x, y); + if (cell.value > cell.tag.getMax(climate.getRand().getValue(x, y))) { + upper.tag(cell, x, y); + } + } else { + upper.tag(cell, x, y); + } + } +} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentModule.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentModule.java index 6d19e67..cd20374 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentModule.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentModule.java @@ -1,7 +1,141 @@ package com.terraforged.core.world.continent; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.domain.Domain; +import me.dags.noise.func.DistanceFunc; +import me.dags.noise.func.EdgeFunc; +import me.dags.noise.util.NoiseUtil; +import me.dags.noise.util.Vec2f; +import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Populator; +import com.terraforged.core.settings.GeneratorSettings; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.terrain.Terrain; -public interface ContinentModule extends Populator { +public class ContinentModule implements Populator { + private static final float edgeClampMin = 0.05F; + private static final float edgeClampMax = 0.50F; + private static final float edgeClampRange = edgeClampMax - edgeClampMin; + + private final int seed; + private final float frequency; + + private final float edgeMin; + private final float edgeMax; + private final float edgeRange; + + private final Domain warp; + private final Module shape; + + public ContinentModule(Seed seed, GeneratorSettings settings) { + int tectonicScale = settings.land.continentScale * 4; + int continentScale = settings.land.continentScale / 2; + double oceans = Math.min(Math.max(settings.world.oceanSize, 0.01), 0.99); + double shapeMin = 0.15 + (oceans * 0.35); + this.seed = seed.next(); + + this.frequency = 1F / tectonicScale; + this.edgeMin = edgeClampMin; + this.edgeMax = (float) oceans; + this.edgeRange = edgeMax - edgeMin; + + this.warp = Domain.warp(Source.SIMPLEX, seed.next(), continentScale, 3, continentScale); + + this.shape = Source.perlin(seed.next(), settings.land.continentScale, 2) + .clamp(shapeMin, 0.7) + .map(0, 1) + .warp(Source.SIMPLEX, seed.next(), continentScale / 2, 1, continentScale / 4D) + .warp(seed.next(), 50, 1, 20D); + } + + @Override + public float getValue(float x, float y) { + if (true) { + throw new RuntimeException("no pls!"); + } else { + Cell cell = new Cell<>(); + apply(cell, x, y); + return cell.continentEdge; + } + } + + @Override + public void apply(Cell cell, final float x, final float y) { + float ox = warp.getOffsetX(x, y); + float oz = warp.getOffsetY(x, y); + + float px = x + ox; + float py = y + oz; + + px *= frequency; + py *= frequency; + + int cellX = 0; + int cellY = 0; + + int xr = NoiseUtil.round(px); + int yr = NoiseUtil.round(py); + float edgeDistance = 999999.0F; + float edgeDistance2 = 999999.0F; + float valueDistance = 3.4028235E38F; + DistanceFunc dist = DistanceFunc.NATURAL; + + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int xi = xr + dx; + int yi = yr + dy; + Vec2f vec = NoiseUtil.CELL_2D[NoiseUtil.hash2D(seed, xi, yi) & 255]; + + float vecX = xi - px + vec.x; + float vecY = yi - py + vec.y; + float distance = dist.apply(vecX, vecY); + + if (distance < valueDistance) { + valueDistance = distance; + cellX = xi; + cellY = yi; + } + + if (distance < edgeDistance2) { + edgeDistance2 = Math.max(edgeDistance, distance); + } else { + edgeDistance2 = Math.max(edgeDistance, edgeDistance2); + } + + edgeDistance = Math.min(edgeDistance, distance); + } + } + + + float shapeNoise = shape.getValue(x, y); + float continentNoise = edgeValue(edgeDistance, edgeDistance2); + + cell.continent = cellValue(seed, cellX, cellY); + cell.continentEdge = shapeNoise * continentNoise; + } + + @Override + public void tag(Cell cell, float x, float y) { + + } + + private float cellValue(int seed, int cellX, int cellY) { + float value = NoiseUtil.valCoord2D(seed, cellX, cellY); + return NoiseUtil.map(value, -1, 1, 2); + } + + private float edgeValue(float distance, float distance2) { + EdgeFunc edge = EdgeFunc.DISTANCE_2_DIV; + float value = edge.apply(distance, distance2); + float edgeValue = 1 - NoiseUtil.map(value, edge.min(), edge.max(), edge.range()); + if (edgeValue < edgeMin) { + return 0F; + } + if (edgeValue > edgeMax) { + return 1F; + } + return (edgeValue - edgeMin) / edgeRange; + } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentMultiBlender.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentMultiBlender.java deleted file mode 100644 index 61cf63d..0000000 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/ContinentMultiBlender.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.terraforged.core.world.continent; - -import com.terraforged.core.cell.Cell; -import com.terraforged.core.cell.Populator; -import com.terraforged.core.module.MultiBlender; -import com.terraforged.core.world.climate.Climate; -import com.terraforged.core.world.terrain.Terrain; - -public class ContinentMultiBlender extends MultiBlender { - - private final Populator control; - - public ContinentMultiBlender(Climate climate, Populator continent, Populator lower, Populator middle, Populator upper, float min, float mid, float max) { - super(climate, continent, lower, middle, upper, min, mid, max); - this.control = continent; - } - - @Override - public float getSelect(Cell cell, float x, float z) { - return cell.continentEdge; - } -} diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/Levels.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/Levels.java index c09155f..b2f1391 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/Levels.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/Levels.java @@ -7,6 +7,8 @@ public class Levels { public final int worldHeight; + public final float unit; + // y index of the top-most water block public final int waterY; private final int groundY; @@ -23,6 +25,7 @@ public class Levels { public Levels(GeneratorSettings settings) { worldHeight = Math.max(1, settings.world.worldHeight); + unit = NoiseUtil.div(1, worldHeight); waterLevel = settings.world.seaLevel; groundLevel = waterLevel + 1; diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/WorldHeightmap.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/WorldHeightmap.java index 53e6634..863d607 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/WorldHeightmap.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/heightmap/WorldHeightmap.java @@ -3,17 +3,17 @@ package com.terraforged.core.world.heightmap; import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Populator; import com.terraforged.core.module.Blender; -import com.terraforged.core.module.Lerp; -import com.terraforged.core.module.MultiBlender; -import com.terraforged.core.module.Selector; import com.terraforged.core.settings.GeneratorSettings; import com.terraforged.core.settings.Settings; import com.terraforged.core.util.Seed; import com.terraforged.core.world.GeneratorContext; import com.terraforged.core.world.climate.Climate; -import com.terraforged.core.world.continent.ContinentBlender; -import com.terraforged.core.world.continent.ContinentMultiBlender; -import com.terraforged.core.world.continent.VoronoiContinentModule; +import com.terraforged.core.world.continent.ContinentLerper2; +import com.terraforged.core.world.continent.ContinentLerper3; +import com.terraforged.core.world.continent.ContinentModule; +import com.terraforged.core.world.terrain.region.RegionLerper; +import com.terraforged.core.world.terrain.region.RegionModule; +import com.terraforged.core.world.terrain.region.RegionSelector; import com.terraforged.core.world.river.RiverManager; import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.TerrainPopulator; @@ -36,9 +36,11 @@ public class WorldHeightmap implements Heightmap { private final Terrains terrain; private final Settings settings; + private final Populator continentModule; + private final Populator regionModule; + private final Climate climate; private final Populator root; - private final Populator continent; private final RiverManager riverManager; private final TerrainProvider terrainProvider; @@ -48,7 +50,7 @@ public class WorldHeightmap implements Heightmap { this.levels = context.levels; this.terrain = context.terrain; this.settings = context.settings; - this.climate = new Climate(context, this); + this.climate = new Climate(context); Seed seed = context.seed; Levels levels = context.levels; @@ -62,11 +64,13 @@ public class WorldHeightmap implements Heightmap { RegionConfig regionConfig = new RegionConfig( regionSeed.get(), context.settings.generator.land.regionSize, - Source.simplex(regionWarp.next(), regionWarpScale, 2), - Source.simplex(regionWarp.next(), regionWarpScale, 2), + Source.simplex(regionWarp.next(), regionWarpScale, 1), + Source.simplex(regionWarp.next(), regionWarpScale, 1), regionWarpStrength ); + regionModule = new RegionModule(regionConfig); + // controls where mountain chains form in the world Module mountainShapeBase = Source.cellEdge(seed.next(), genSettings.land.mountainScale, EdgeFunc.DISTANCE_2_ADD) .add(Source.cubic(seed.next(), genSettings.land.mountainScale, 1).scale(-0.05)); @@ -77,36 +81,21 @@ public class WorldHeightmap implements Heightmap { .clamp(0, 0.9) .map(0, 1); - // controls the shape of terrain regions - Module regionShape = Source.cell(regionConfig.seed, regionConfig.scale) - .warp(regionConfig.warpX, regionConfig.warpZ, regionConfig.warpStrength); - - // the corresponding edges of terrain regions so we can fade out towards borders - Module regionEdge = Source.cellEdge(regionConfig.seed, regionConfig.scale, EdgeFunc.DISTANCE_2_DIV).invert() - .warp(regionConfig.warpX, regionConfig.warpZ, regionConfig.warpStrength) - .pow(1.5) - .clamp(0, 0.75) - .map(0, 1); - - this.terrainProvider = context.terrainFactory.create(context, regionConfig, this); + terrainProvider = context.terrainFactory.create(context, regionConfig, this); // the voronoi controlled terrain regions - Populator terrainRegions = new Selector(regionShape, terrainProvider.getPopulators()); + Populator terrainRegions = new RegionSelector(terrainProvider.getPopulators()); // the terrain type at region edges Populator terrainRegionBorders = new TerrainPopulator(terrainProvider.getLandforms().plains(seed), context.terrain.steppe); // transitions between the unique terrain regions and the common border terrain - Populator terrain = new Lerp( - regionEdge, - terrainRegionBorders, - terrainRegions - ); + Populator terrain = new RegionLerper(terrainRegionBorders, terrainRegions); // mountain populator Populator mountains = register(terrainProvider.getLandforms().mountains(seed), context.terrain.mountains); // controls what's ocean and what's land - this.continent = createContinent(context); + continentModule = new ContinentModule(seed, settings.generator); // blends between normal terrain and mountain chains Populator land = new Blender( @@ -119,9 +108,8 @@ public class WorldHeightmap implements Heightmap { ); // uses the continent noise to blend between deep ocean, to ocean, to coast - MultiBlender oceans = new ContinentMultiBlender( + ContinentLerper3 oceans = new ContinentLerper3( climate, - continent, register(terrainProvider.getLandforms().deepOcean(seed.next()), context.terrain.deepOcean), register(Source.constant(levels.water(-7)), context.terrain.ocean), register(Source.constant(levels.water), context.terrain.coast), @@ -131,22 +119,23 @@ public class WorldHeightmap implements Heightmap { ); // blends between the ocean/coast terrain and land terrains - root = new ContinentBlender( - continent, + root = new ContinentLerper2( oceans, land, OCEAN_VALUE, // below == pure ocean INLAND_VALUE, // above == pure land COAST_VALUE, // split point COAST_VALUE - 0.05F - ).mask(); + ); - this.riverManager = new RiverManager(this, context); + riverManager = new RiverManager(this, context); } @Override public void visit(Cell cell, float x, float z) { - continent.apply(cell, x, z); + continentModule.apply(cell, x, z); + regionModule.apply(cell, x, z); + root.apply(cell, x, z); } @@ -155,8 +144,9 @@ public class WorldHeightmap implements Heightmap { // initial type cell.tag = terrain.steppe; - // apply continent value/edge noise - continent.apply(cell, x, z); + // basic shapes + continentModule.apply(cell, x, z); + regionModule.apply(cell, x, z); // apply actuall heightmap root.apply(cell, x, z); @@ -184,7 +174,8 @@ public class WorldHeightmap implements Heightmap { @Override public void tag(Cell cell, float x, float z) { - continent.apply(cell, x, z); + continentModule.apply(cell, x, z); + regionModule.apply(cell, x, z); root.tag(cell, x, z); } @@ -201,8 +192,4 @@ public class WorldHeightmap implements Heightmap { terrainProvider.registerMixable(populator); return populator; } - - private Populator createContinent(GeneratorContext context) { - return new VoronoiContinentModule(context.seed, context.settings.generator); - } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/PosGenerator.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/PosGenerator.java index 16da003..926c84e 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/PosGenerator.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/PosGenerator.java @@ -1,9 +1,9 @@ package com.terraforged.core.world.river; +import com.terraforged.core.world.heightmap.Heightmap; import me.dags.noise.domain.Domain; import me.dags.noise.util.Vec2i; import com.terraforged.core.cell.Cell; -import com.terraforged.core.world.heightmap.WorldHeightmap; import com.terraforged.core.world.terrain.Terrain; import java.util.Random; @@ -21,13 +21,13 @@ public class PosGenerator { private final int padding; private final Domain domain; private final Cell lookup; - private final WorldHeightmap heightmap; + private final Heightmap heightmap; private int i; private int dx; private int dz; - public PosGenerator(WorldHeightmap heightmap, Domain domain, Cell lookup, int size, int padding) { + public PosGenerator(Heightmap heightmap, Domain domain, Cell lookup, int size, int padding) { this.domain = domain; this.lookup = lookup; this.padding = padding; diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverManager.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverManager.java index da3cf79..c0c954f 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverManager.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverManager.java @@ -1,10 +1,10 @@ package com.terraforged.core.world.river; +import com.terraforged.core.world.heightmap.Heightmap; import me.dags.noise.util.NoiseUtil; import com.terraforged.core.cell.Cell; import com.terraforged.core.util.Cache; import com.terraforged.core.world.GeneratorContext; -import com.terraforged.core.world.heightmap.WorldHeightmap; import com.terraforged.core.world.terrain.Terrain; import java.util.concurrent.ConcurrentHashMap; @@ -18,11 +18,11 @@ public class RiverManager { private final RiverConfig primary; private final RiverConfig secondary; private final RiverConfig tertiary; - private final WorldHeightmap heightmap; + private final Heightmap heightmap; private final GeneratorContext context; private final Cache cache = new Cache<>(60, 60, TimeUnit.SECONDS, () -> new ConcurrentHashMap<>()); - public RiverManager(WorldHeightmap heightmap, GeneratorContext context) { + public RiverManager(Heightmap heightmap, GeneratorContext context) { this.heightmap = heightmap; this.context = context; this.primary = RiverConfig.builder(context.levels) diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverRegion.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverRegion.java index 0298b32..ec6078d 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverRegion.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/river/RiverRegion.java @@ -1,5 +1,6 @@ package com.terraforged.core.world.river; +import com.terraforged.core.world.heightmap.Heightmap; import me.dags.noise.domain.Domain; import me.dags.noise.util.NoiseUtil; import me.dags.noise.util.Vec2f; @@ -7,7 +8,6 @@ import me.dags.noise.util.Vec2i; import com.terraforged.core.cell.Cell; import com.terraforged.core.util.concurrent.ObjectPool; import com.terraforged.core.world.GeneratorContext; -import com.terraforged.core.world.heightmap.WorldHeightmap; import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.Terrains; @@ -35,7 +35,7 @@ public class RiverRegion { private final List rivers; private final List lakes = new LinkedList<>(); - public RiverRegion(int regionX, int regionZ, WorldHeightmap heightmap, GeneratorContext context, RiverConfig primary, RiverConfig secondary, RiverConfig tertiary, LakeConfig lake) { + public RiverRegion(int regionX, int regionZ, Heightmap heightmap, GeneratorContext context, RiverConfig primary, RiverConfig secondary, RiverConfig tertiary, LakeConfig lake) { int seed = new Random(NoiseUtil.seed(regionX, regionZ)).nextInt(); this.lake = lake; this.primary = primary; diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/VolcanoPopulator.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/VolcanoPopulator.java index ecf9752..3ecea92 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/VolcanoPopulator.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/VolcanoPopulator.java @@ -36,7 +36,7 @@ public class VolcanoPopulator extends TerrainPopulator { this.cone = Source.cellEdge(region.seed, region.scale, EdgeFunc.DISTANCE_2_DIV).invert() .warp(region.warpX, region.warpZ, region.warpStrength) - .powCurve(14) + .powCurve(10) .clamp(0.475, 1) .map(0, 1) .grad(0, 0.5, 0.5) @@ -47,7 +47,7 @@ public class VolcanoPopulator extends TerrainPopulator { .warp(seed.next(), 30, 1, 30) .scale(0.1); - this.inversionPoint = 0.95F; + this.inversionPoint = 0.93F; this.blendLower = midpoint - (range / 2F); this.blendUpper = blendLower + range; this.blendRange = blendUpper - blendLower; diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/Lerp.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionLerper.java similarity index 71% rename from TerraForgedCore/src/main/java/com/terraforged/core/module/Lerp.java rename to TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionLerper.java index 1b37e34..daaeea7 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/Lerp.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionLerper.java @@ -1,28 +1,23 @@ -package com.terraforged.core.module; +package com.terraforged.core.world.terrain.region; -import me.dags.noise.Module; -import me.dags.noise.util.NoiseUtil; import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Populator; import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.util.NoiseUtil; -public class Lerp implements Populator { +public class RegionLerper implements Populator { - private final Module control; private final Populator lower; private final Populator upper; - public Lerp(Module control, Populator lower, Populator upper) { - this.control = control; + public RegionLerper(Populator lower, Populator upper) { this.lower = lower; this.upper = upper; } @Override public void apply(Cell cell, float x, float y) { - float alpha = control.getValue(x, y); - cell.regionMask = alpha; - + float alpha = cell.regionEdge; if (alpha == 0) { lower.apply(cell, x, y); return; @@ -44,8 +39,7 @@ public class Lerp implements Populator { @Override public void tag(Cell cell, float x, float y) { - float alpha = control.getValue(x, y); - if (alpha == 0) { + if (cell.regionEdge == 0) { lower.tag(cell, x, y); return; } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/VoronoiContinentModule.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionModule.java similarity index 57% rename from TerraForgedCore/src/main/java/com/terraforged/core/world/continent/VoronoiContinentModule.java rename to TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionModule.java index 34ed53c..48f193a 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/world/continent/VoronoiContinentModule.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionModule.java @@ -1,23 +1,17 @@ -package com.terraforged.core.world.continent; +package com.terraforged.core.world.terrain.region; -import me.dags.noise.Module; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.cell.Populator; +import com.terraforged.core.world.heightmap.RegionConfig; +import com.terraforged.core.world.terrain.Terrain; import me.dags.noise.Source; import me.dags.noise.domain.Domain; import me.dags.noise.func.DistanceFunc; import me.dags.noise.func.EdgeFunc; import me.dags.noise.util.NoiseUtil; import me.dags.noise.util.Vec2f; -import com.terraforged.core.cell.Cell; -import com.terraforged.core.cell.Populator; -import com.terraforged.core.settings.GeneratorSettings; -import com.terraforged.core.util.Seed; -import com.terraforged.core.world.terrain.Terrain; -public class VoronoiContinentModule implements Populator { - - private static final float edgeClampMin = 0.05F; - private static final float edgeClampMax = 0.50F; - private static final float edgeClampRange = edgeClampMax - edgeClampMin; +public class RegionModule implements Populator { private final int seed; private final float frequency; @@ -25,44 +19,19 @@ public class VoronoiContinentModule implements Populator { private final float edgeMin; private final float edgeMax; private final float edgeRange; - private final Domain warp; - private final Module shape; - public VoronoiContinentModule(Seed seed, GeneratorSettings settings) { - int tectonicScale = settings.land.continentScale * 4; - int continentScale = settings.land.continentScale / 2; - double oceans = Math.min(Math.max(settings.world.oceanSize, 0.01), 0.99); - double shapeMin = 0.15 + (oceans * 0.35); - this.seed = seed.next(); - - this.frequency = 1F / tectonicScale; - this.edgeMin = edgeClampMin; - this.edgeMax = (float) oceans; - this.edgeRange = edgeMax - edgeMin; - - this.warp = Domain.warp(Source.SIMPLEX, seed.next(), continentScale, 3, continentScale); - - this.shape = Source.perlin(seed.next(), settings.land.continentScale, 2) - .clamp(shapeMin, 0.7) - .map(0, 1) - .warp(Source.SIMPLEX, seed.next(), continentScale / 2, 1, continentScale / 4D) - .warp(seed.next(), 50, 1, 20D); + public RegionModule(RegionConfig regionConfig) { + seed = regionConfig.seed; + edgeMin = 0F; + edgeMax = 0.5F; + edgeRange = edgeMax - edgeMin; + frequency = 1F / regionConfig.scale; + warp = Domain.warp(regionConfig.warpX, regionConfig.warpZ, Source.constant(regionConfig.warpStrength)); } @Override - public float getValue(float x, float y) { - if (true) { - throw new RuntimeException("no pls!"); - } else { - Cell cell = new Cell<>(); - apply(cell, x, y); - return cell.continentEdge; - } - } - - @Override - public void apply(Cell cell, final float x, final float y) { + public void apply(Cell cell, float x, float y) { float ox = warp.getOffsetX(x, y); float oz = warp.getOffsetY(x, y); @@ -108,12 +77,8 @@ public class VoronoiContinentModule implements Populator { } } - - float shapeNoise = shape.getValue(x, y); - float continentNoise = edgeValue(edgeDistance, edgeDistance2); - - cell.continent = cellValue(seed, cellX, cellY); - cell.continentEdge = shapeNoise * continentNoise; + cell.region = cellValue(seed, cellX, cellY); + cell.regionEdge = edgeValue(edgeDistance, edgeDistance2); } @Override @@ -130,12 +95,16 @@ public class VoronoiContinentModule implements Populator { EdgeFunc edge = EdgeFunc.DISTANCE_2_DIV; float value = edge.apply(distance, distance2); float edgeValue = 1 - NoiseUtil.map(value, edge.min(), edge.max(), edge.range()); + + edgeValue = NoiseUtil.pow(edgeValue, 1.5F); + if (edgeValue < edgeMin) { return 0F; } if (edgeValue > edgeMax) { return 1F; } + return (edgeValue - edgeMin) / edgeRange; } } diff --git a/TerraForgedCore/src/main/java/com/terraforged/core/module/Selector.java b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionSelector.java similarity index 76% rename from TerraForgedCore/src/main/java/com/terraforged/core/module/Selector.java rename to TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionSelector.java index 5f8f6cd..9f1d08b 100644 --- a/TerraForgedCore/src/main/java/com/terraforged/core/module/Selector.java +++ b/TerraForgedCore/src/main/java/com/terraforged/core/world/terrain/region/RegionSelector.java @@ -1,40 +1,36 @@ -package com.terraforged.core.module; +package com.terraforged.core.world.terrain.region; -import me.dags.noise.Module; -import me.dags.noise.util.NoiseUtil; import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Populator; import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.TerrainPopulator; +import me.dags.noise.util.NoiseUtil; import java.util.LinkedList; import java.util.List; -public class Selector implements Populator { +public class RegionSelector implements Populator { private final int maxIndex; - private final Module control; private final Populator[] nodes; - public Selector(Module control, List populators) { - this.control = control; + public RegionSelector(List populators) { this.nodes = getWeightedArray(populators); this.maxIndex = nodes.length - 1; } @Override public void apply(Cell cell, float x, float y) { - get(x, y).apply(cell, x, y); + get(cell.region).apply(cell, x, y); } @Override public void tag(Cell cell, float x, float y) { - get(x, y).tag(cell, x, y); + get(cell.region).tag(cell, x, y); } - public Populator get(float x, float y) { - float selector = control.getValue(x, y); - int index = NoiseUtil.round(selector * maxIndex); + public Populator get(float identity) { + int index = NoiseUtil.round(identity * maxIndex); return nodes[index]; } diff --git a/TerraForgedMod b/TerraForgedMod index 5f7d2c8..5d1604a 160000 --- a/TerraForgedMod +++ b/TerraForgedMod @@ -1 +1 @@ -Subproject commit 5f7d2c8ec864f6dcd1c977013c3c8377d33c4547 +Subproject commit 5d1604ab29ae129f133c34fdd72bc207f21364aa