added /find command & reworked some of the back-end stuff in Core
This commit is contained in:
parent
e853f3d347
commit
446b036414
@ -58,13 +58,13 @@ public abstract class Renderer {
|
|||||||
if (cell.tag == applet.getCache().getTerrain().coast) {
|
if (cell.tag == applet.getCache().getTerrain().coast) {
|
||||||
hue = 15;
|
hue = 15;
|
||||||
}
|
}
|
||||||
float modifier = cell.mask;
|
float modifier = cell.mask(0.4F, 0.5F, 0F, 1F);
|
||||||
float modAlpha = 0.1F;
|
float modAlpha = 0.1F;
|
||||||
float mod = (1 - modAlpha) + (modifier * modAlpha);
|
float mod = (1 - modAlpha) + (modifier * modAlpha);
|
||||||
float sat = 70;
|
float sat = 70;
|
||||||
float bri = 70;
|
float bri = 70;
|
||||||
applet.fill(hue, 65, 70);
|
applet.fill(hue, 65, 70);
|
||||||
return height * el;
|
return cell.regionEdge * el;
|
||||||
} else if(applet.controller.getColorMode() == Applet.EROSION) {
|
} else if(applet.controller.getColorMode() == Applet.EROSION) {
|
||||||
float change = cell.sediment + cell.erosion;
|
float change = cell.sediment + cell.erosion;
|
||||||
float value = Math.abs(cell.sediment * 250);
|
float value = Math.abs(cell.sediment * 250);
|
||||||
|
@ -18,9 +18,13 @@ public class Cell<T extends Tag> {
|
|||||||
|
|
||||||
public float continent;
|
public float continent;
|
||||||
public float continentEdge;
|
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 value;
|
||||||
public float biome;
|
|
||||||
public float biomeMoisture;
|
public float biomeMoisture;
|
||||||
public float biomeTemperature;
|
public float biomeTemperature;
|
||||||
public float moisture;
|
public float moisture;
|
||||||
@ -28,49 +32,53 @@ public class Cell<T extends Tag> {
|
|||||||
public float steepness;
|
public float steepness;
|
||||||
public float erosion;
|
public float erosion;
|
||||||
public float sediment;
|
public float sediment;
|
||||||
|
|
||||||
public float mask = 1F;
|
|
||||||
public float biomeMask = 1F;
|
|
||||||
public float biomeTypeMask = 1F;
|
public float biomeTypeMask = 1F;
|
||||||
public float regionMask = 1F;
|
|
||||||
public float riverMask = 1F;
|
|
||||||
public BiomeType biomeType = BiomeType.GRASSLAND;
|
public BiomeType biomeType = BiomeType.GRASSLAND;
|
||||||
|
|
||||||
public T tag = null;
|
public T tag = null;
|
||||||
|
|
||||||
public void copy(Cell<T> other) {
|
public void copy(Cell<T> other) {
|
||||||
|
value = other.value;
|
||||||
|
|
||||||
continent = other.continent;
|
continent = other.continent;
|
||||||
continentEdge = other.continentEdge;
|
continentEdge = other.continentEdge;
|
||||||
|
|
||||||
value = other.value;
|
region = other.region;
|
||||||
biome = other.biome;
|
regionEdge = other.regionEdge;
|
||||||
|
|
||||||
|
biome = other.biome;
|
||||||
|
biomeEdge = other.biomeEdge;
|
||||||
|
|
||||||
biomeMask = other.biomeMask;
|
|
||||||
riverMask = other.riverMask;
|
riverMask = other.riverMask;
|
||||||
biomeMoisture = other.biomeMoisture;
|
|
||||||
biomeTemperature = other.biomeTemperature;
|
|
||||||
mask = other.mask;
|
|
||||||
regionMask = other.regionMask;
|
|
||||||
moisture = other.moisture;
|
moisture = other.moisture;
|
||||||
temperature = other.temperature;
|
temperature = other.temperature;
|
||||||
|
biomeMoisture = other.biomeMoisture;
|
||||||
|
biomeTemperature = other.biomeTemperature;
|
||||||
|
|
||||||
steepness = other.steepness;
|
steepness = other.steepness;
|
||||||
erosion = other.erosion;
|
erosion = other.erosion;
|
||||||
sediment = other.sediment;
|
sediment = other.sediment;
|
||||||
biomeType = other.biomeType;
|
biomeType = other.biomeType;
|
||||||
biomeTypeMask = other.biomeTypeMask;
|
biomeTypeMask = other.biomeTypeMask;
|
||||||
|
|
||||||
tag = other.tag;
|
tag = other.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float combinedMask(float clamp) {
|
public float continentMask(float min, float max) {
|
||||||
return NoiseUtil.map(biomeMask * regionMask, 0, clamp, clamp);
|
return NoiseUtil.map(continentEdge, min, max, max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float biomeMask(float clamp) {
|
public float regionMask(float min, float max) {
|
||||||
return NoiseUtil.map(biomeMask, 0, clamp, clamp);
|
return NoiseUtil.map(regionEdge, min, max, max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float regionMask(float clamp) {
|
public float biomeMask(float min, float max) {
|
||||||
return NoiseUtil.map(regionMask, 0, clamp, clamp);
|
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() {
|
public boolean isAbsent() {
|
||||||
|
@ -5,5 +5,5 @@ import com.terraforged.core.world.terrain.Terrain;
|
|||||||
|
|
||||||
public interface Decorator {
|
public interface Decorator {
|
||||||
|
|
||||||
void apply(Cell<Terrain> cell, float x, float y);
|
boolean apply(Cell<Terrain> cell, float x, float y);
|
||||||
}
|
}
|
||||||
|
@ -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<Terrain> 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;
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ public class DesertStacks implements Decorator {
|
|||||||
|
|
||||||
private final float minY;
|
private final float minY;
|
||||||
private final float maxY;
|
private final float maxY;
|
||||||
|
private final Levels levels;
|
||||||
private final Module module;
|
private final Module module;
|
||||||
|
|
||||||
public DesertStacks(Seed seed, Levels levels) {
|
public DesertStacks(Seed seed, Levels levels) {
|
||||||
@ -35,21 +36,24 @@ public class DesertStacks implements Decorator {
|
|||||||
|
|
||||||
this.minY = levels.water(0);
|
this.minY = levels.water(0);
|
||||||
this.maxY = levels.water(50);
|
this.maxY = levels.water(50);
|
||||||
|
this.levels = levels;
|
||||||
this.module = stack.scale(scale).mult(mask);
|
this.module = stack.scale(scale).mult(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
public boolean apply(Cell<Terrain> cell, float x, float y) {
|
||||||
if (BiomeType.DESERT != cell.biomeType) {
|
if (BiomeType.DESERT != cell.biomeType) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell.value <= minY || cell.value > maxY) {
|
if (cell.value <= minY || cell.value > maxY) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float value = module.getValue(x, y);
|
float value = module.getValue(x, y);
|
||||||
value *= cell.biomeMask;
|
value *= cell.biomeEdge;
|
||||||
cell.value += value;
|
cell.value += value;
|
||||||
|
|
||||||
|
return value > levels.unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,21 @@ public class SwampPools implements Decorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
public boolean apply(Cell<Terrain> cell, float x, float y) {
|
||||||
if (cell.tag == terrains.ocean) {
|
if (cell.tag == terrains.ocean) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell.moisture < 0.7 || cell.temperature < 0.3) {
|
if (cell.moisture < 0.7 || cell.temperature < 0.3) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell.value <= minY) {
|
if (cell.value <= minY) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell.value > blendY) {
|
if (cell.value > blendY) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = module.getValue(x, y);
|
float alpha = module.getValue(x, y);
|
||||||
@ -55,5 +55,6 @@ public class SwampPools implements Decorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell.value = NoiseUtil.lerp(cell.value, minY, alpha);
|
cell.value = NoiseUtil.lerp(cell.value, minY, alpha);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@ public class Blender extends Select implements Populator {
|
|||||||
private final float midpoint;
|
private final float midpoint;
|
||||||
private final float tagThreshold;
|
private final float tagThreshold;
|
||||||
|
|
||||||
private boolean mask = false;
|
|
||||||
|
|
||||||
public Blender(Module control, Populator lower, Populator upper, float min, float max, float split) {
|
public Blender(Module control, Populator lower, Populator upper, float min, float max, float split) {
|
||||||
super(control);
|
super(control);
|
||||||
this.lower = lower;
|
this.lower = lower;
|
||||||
@ -42,11 +40,6 @@ public class Blender extends Select implements Populator {
|
|||||||
this.tagThreshold = tagThreshold;
|
this.tagThreshold = tagThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Blender mask() {
|
|
||||||
mask = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||||
float select = getSelect(cell, x, y);
|
float select = getSelect(cell, x, y);
|
||||||
@ -74,10 +67,6 @@ public class Blender extends Select implements Populator {
|
|||||||
if (select < midpoint) {
|
if (select < midpoint) {
|
||||||
cell.tag = lowerType;
|
cell.tag = lowerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask) {
|
|
||||||
cell.mask *= alpha;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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<Terrain> cell, float x, float y) {
|
|
||||||
float px = x * scale;
|
|
||||||
float pz = y * scale;
|
|
||||||
heightmap.getValue(px, pz);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tag(Cell<Terrain> cell, float x, float y) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<Terrain> 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<Terrain> cell, float x, float y) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,8 +21,6 @@ public class MultiBlender extends Select implements Populator {
|
|||||||
private final float lowerRange;
|
private final float lowerRange;
|
||||||
private final float upperRange;
|
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) {
|
public MultiBlender(Climate climate, Populator control, Populator lower, Populator middle, Populator upper, float min, float mid, float max) {
|
||||||
super(control);
|
super(control);
|
||||||
this.climate = climate;
|
this.climate = climate;
|
||||||
@ -62,11 +60,6 @@ public class MultiBlender extends Select implements Populator {
|
|||||||
float upperVal = cell.value;
|
float upperVal = cell.value;
|
||||||
|
|
||||||
cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha);
|
cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha);
|
||||||
// cell.tag = lowerType;
|
|
||||||
|
|
||||||
if (mask) {
|
|
||||||
cell.mask *= alpha;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
float alpha = Interpolation.CURVE3.apply((select - midpoint) / upperRange);
|
float alpha = Interpolation.CURVE3.apply((select - midpoint) / upperRange);
|
||||||
|
|
||||||
@ -75,10 +68,6 @@ public class MultiBlender extends Select implements Populator {
|
|||||||
|
|
||||||
upper.apply(cell, x, y);
|
upper.apply(cell, x, y);
|
||||||
cell.value = NoiseUtil.lerp(lowerVal, cell.value, alpha);
|
cell.value = NoiseUtil.lerp(lowerVal, cell.value, alpha);
|
||||||
|
|
||||||
if (mask) {
|
|
||||||
cell.mask *= alpha;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,9 @@ public class Region implements Extent {
|
|||||||
int index = blockSize.indexOf(dx, dz);
|
int index = blockSize.indexOf(dx, dz);
|
||||||
GenCell cell = blocks[index];
|
GenCell cell = blocks[index];
|
||||||
for (Decorator decorator : decorators) {
|
for (Decorator decorator : decorators) {
|
||||||
decorator.apply(cell, getBlockX() + dx, getBlockZ() + dz);
|
if (decorator.apply(cell, getBlockX() + dx, getBlockZ() + dz)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class RegionGenerator implements RegionExtent {
|
|||||||
if (filter) {
|
if (filter) {
|
||||||
generator.getFilters().apply(region);
|
generator.getFilters().apply(region);
|
||||||
}
|
}
|
||||||
// region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom);
|
region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -80,11 +80,11 @@ public class GeneratorSettings {
|
|||||||
|
|
||||||
@Range(min = 1, max = 200)
|
@Range(min = 1, max = 200)
|
||||||
@Comment("Controls the scale of shape distortion for biomes")
|
@Comment("Controls the scale of shape distortion for biomes")
|
||||||
public int biomeWarpScale = 30;
|
public int biomeWarpScale = 35;
|
||||||
|
|
||||||
@Range(min = 1, max = 200)
|
@Range(min = 1, max = 200)
|
||||||
@Comment("Controls the strength of shape distortion for biomes")
|
@Comment("Controls the strength of shape distortion for biomes")
|
||||||
public int biomeWarpStrength = 30;
|
public int biomeWarpStrength = 70;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -95,11 +95,11 @@ public class GeneratorSettings {
|
|||||||
|
|
||||||
@Range(min = 1, max = 100)
|
@Range(min = 1, max = 100)
|
||||||
@Comment("Controls the scale of the noise")
|
@Comment("Controls the scale of the noise")
|
||||||
public int scale = 4;
|
public int scale = 8;
|
||||||
|
|
||||||
@Range(min = 1, max = 5)
|
@Range(min = 1, max = 5)
|
||||||
@Comment("Controls the number of noise octaves")
|
@Comment("Controls the number of noise octaves")
|
||||||
public int octaves = 1;
|
public int octaves = 2;
|
||||||
|
|
||||||
@Range(min = 0F, max = 5.5F)
|
@Range(min = 0F, max = 5.5F)
|
||||||
@Comment("Controls the gain subsequent noise octaves")
|
@Comment("Controls the gain subsequent noise octaves")
|
||||||
@ -107,11 +107,11 @@ public class GeneratorSettings {
|
|||||||
|
|
||||||
@Range(min = 0F, max = 10.5F)
|
@Range(min = 0F, max = 10.5F)
|
||||||
@Comment("Controls the lacunarity of subsequent noise octaves")
|
@Comment("Controls the lacunarity of subsequent noise octaves")
|
||||||
public float lacunarity = 2F;
|
public float lacunarity = 2.5F;
|
||||||
|
|
||||||
@Range(min = 1, max = 100)
|
@Range(min = 1, max = 100)
|
||||||
@Comment("Controls the strength of the noise")
|
@Comment("Controls the strength of the noise")
|
||||||
public int strength = 12;
|
public int strength = 24;
|
||||||
|
|
||||||
public Module build(int seed) {
|
public Module build(int seed) {
|
||||||
return Source.build(seed, scale, octaves).gain(gain).lacunarity(lacunarity).build(type).bias(-0.5);
|
return Source.build(seed, scale, octaves).gain(gain).lacunarity(lacunarity).build(type).bias(-0.5);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.terraforged.core.world;
|
package com.terraforged.core.world;
|
||||||
|
|
||||||
import com.terraforged.core.decorator.Decorator;
|
import com.terraforged.core.decorator.Decorator;
|
||||||
|
import com.terraforged.core.decorator.DesertDunes;
|
||||||
import com.terraforged.core.decorator.DesertStacks;
|
import com.terraforged.core.decorator.DesertStacks;
|
||||||
import com.terraforged.core.decorator.SwampPools;
|
import com.terraforged.core.decorator.SwampPools;
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package com.terraforged.core.world.climate;
|
|||||||
|
|
||||||
import com.terraforged.core.cell.Cell;
|
import com.terraforged.core.cell.Cell;
|
||||||
import com.terraforged.core.world.GeneratorContext;
|
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 com.terraforged.core.world.terrain.Terrain;
|
||||||
import me.dags.noise.Module;
|
import me.dags.noise.Module;
|
||||||
import me.dags.noise.Source;
|
import me.dags.noise.Source;
|
||||||
@ -26,7 +24,7 @@ public class Climate {
|
|||||||
|
|
||||||
private final ClimateModule biomeNoise;
|
private final ClimateModule biomeNoise;
|
||||||
|
|
||||||
public Climate(GeneratorContext context, WorldHeightmap heightmap) {
|
public Climate(GeneratorContext context) {
|
||||||
this.biomeNoise = new ClimateModule(context.seed, context.settings.generator);
|
this.biomeNoise = new ClimateModule(context.seed, context.settings.generator);
|
||||||
|
|
||||||
this.treeLine = Source.perlin(context.seed.next(), context.settings.generator.biome.biomeSize * 2, 1)
|
this.treeLine = Source.perlin(context.seed.next(), context.settings.generator.biome.biomeSize * 2, 1)
|
||||||
|
@ -104,10 +104,10 @@ public class ClimateModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
cell.biomeMask = edgeValue(edgeDistance, edgeDistance2);
|
cell.biomeEdge = edgeValue(edgeDistance, edgeDistance2);
|
||||||
} else {
|
} else {
|
||||||
cell.biome = cellValue(seed, cellX, cellY);
|
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.biomeMoisture = moisture.getValue(cellX + vec2f.x, cellY + vec2f.y);
|
||||||
cell.biomeTemperature = temperature.getValue(cellX + vec2f.x, cellY + vec2f.y);
|
cell.biomeTemperature = temperature.getValue(cellX + vec2f.x, cellY + vec2f.y);
|
||||||
cell.moisture = moisture.getValue(x, y);
|
cell.moisture = moisture.getValue(x, y);
|
||||||
|
@ -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<Terrain> cell, float x, float z) {
|
|
||||||
return cell.continentEdge;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<Terrain> 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<Terrain> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<Terrain> 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<Terrain> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,141 @@
|
|||||||
package com.terraforged.core.world.continent;
|
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.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<Terrain> cell = new Cell<>();
|
||||||
|
apply(cell, x, y);
|
||||||
|
return cell.continentEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Cell<Terrain> 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<Terrain> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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<Terrain> cell, float x, float z) {
|
|
||||||
return cell.continentEdge;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,6 +7,8 @@ public class Levels {
|
|||||||
|
|
||||||
public final int worldHeight;
|
public final int worldHeight;
|
||||||
|
|
||||||
|
public final float unit;
|
||||||
|
|
||||||
// y index of the top-most water block
|
// y index of the top-most water block
|
||||||
public final int waterY;
|
public final int waterY;
|
||||||
private final int groundY;
|
private final int groundY;
|
||||||
@ -23,6 +25,7 @@ public class Levels {
|
|||||||
|
|
||||||
public Levels(GeneratorSettings settings) {
|
public Levels(GeneratorSettings settings) {
|
||||||
worldHeight = Math.max(1, settings.world.worldHeight);
|
worldHeight = Math.max(1, settings.world.worldHeight);
|
||||||
|
unit = NoiseUtil.div(1, worldHeight);
|
||||||
|
|
||||||
waterLevel = settings.world.seaLevel;
|
waterLevel = settings.world.seaLevel;
|
||||||
groundLevel = waterLevel + 1;
|
groundLevel = waterLevel + 1;
|
||||||
|
@ -3,17 +3,17 @@ package com.terraforged.core.world.heightmap;
|
|||||||
import com.terraforged.core.cell.Cell;
|
import com.terraforged.core.cell.Cell;
|
||||||
import com.terraforged.core.cell.Populator;
|
import com.terraforged.core.cell.Populator;
|
||||||
import com.terraforged.core.module.Blender;
|
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.GeneratorSettings;
|
||||||
import com.terraforged.core.settings.Settings;
|
import com.terraforged.core.settings.Settings;
|
||||||
import com.terraforged.core.util.Seed;
|
import com.terraforged.core.util.Seed;
|
||||||
import com.terraforged.core.world.GeneratorContext;
|
import com.terraforged.core.world.GeneratorContext;
|
||||||
import com.terraforged.core.world.climate.Climate;
|
import com.terraforged.core.world.climate.Climate;
|
||||||
import com.terraforged.core.world.continent.ContinentBlender;
|
import com.terraforged.core.world.continent.ContinentLerper2;
|
||||||
import com.terraforged.core.world.continent.ContinentMultiBlender;
|
import com.terraforged.core.world.continent.ContinentLerper3;
|
||||||
import com.terraforged.core.world.continent.VoronoiContinentModule;
|
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.river.RiverManager;
|
||||||
import com.terraforged.core.world.terrain.Terrain;
|
import com.terraforged.core.world.terrain.Terrain;
|
||||||
import com.terraforged.core.world.terrain.TerrainPopulator;
|
import com.terraforged.core.world.terrain.TerrainPopulator;
|
||||||
@ -36,9 +36,11 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
private final Terrains terrain;
|
private final Terrains terrain;
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
|
|
||||||
|
private final Populator continentModule;
|
||||||
|
private final Populator regionModule;
|
||||||
|
|
||||||
private final Climate climate;
|
private final Climate climate;
|
||||||
private final Populator root;
|
private final Populator root;
|
||||||
private final Populator continent;
|
|
||||||
private final RiverManager riverManager;
|
private final RiverManager riverManager;
|
||||||
private final TerrainProvider terrainProvider;
|
private final TerrainProvider terrainProvider;
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
this.levels = context.levels;
|
this.levels = context.levels;
|
||||||
this.terrain = context.terrain;
|
this.terrain = context.terrain;
|
||||||
this.settings = context.settings;
|
this.settings = context.settings;
|
||||||
this.climate = new Climate(context, this);
|
this.climate = new Climate(context);
|
||||||
|
|
||||||
Seed seed = context.seed;
|
Seed seed = context.seed;
|
||||||
Levels levels = context.levels;
|
Levels levels = context.levels;
|
||||||
@ -62,11 +64,13 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
RegionConfig regionConfig = new RegionConfig(
|
RegionConfig regionConfig = new RegionConfig(
|
||||||
regionSeed.get(),
|
regionSeed.get(),
|
||||||
context.settings.generator.land.regionSize,
|
context.settings.generator.land.regionSize,
|
||||||
Source.simplex(regionWarp.next(), regionWarpScale, 2),
|
Source.simplex(regionWarp.next(), regionWarpScale, 1),
|
||||||
Source.simplex(regionWarp.next(), regionWarpScale, 2),
|
Source.simplex(regionWarp.next(), regionWarpScale, 1),
|
||||||
regionWarpStrength
|
regionWarpStrength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
regionModule = new RegionModule(regionConfig);
|
||||||
|
|
||||||
// controls where mountain chains form in the world
|
// controls where mountain chains form in the world
|
||||||
Module mountainShapeBase = Source.cellEdge(seed.next(), genSettings.land.mountainScale, EdgeFunc.DISTANCE_2_ADD)
|
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));
|
.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)
|
.clamp(0, 0.9)
|
||||||
.map(0, 1);
|
.map(0, 1);
|
||||||
|
|
||||||
// controls the shape of terrain regions
|
terrainProvider = context.terrainFactory.create(context, regionConfig, this);
|
||||||
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);
|
|
||||||
|
|
||||||
// the voronoi controlled terrain regions
|
// the voronoi controlled terrain regions
|
||||||
Populator terrainRegions = new Selector(regionShape, terrainProvider.getPopulators());
|
Populator terrainRegions = new RegionSelector(terrainProvider.getPopulators());
|
||||||
// the terrain type at region edges
|
// the terrain type at region edges
|
||||||
Populator terrainRegionBorders = new TerrainPopulator(terrainProvider.getLandforms().plains(seed), context.terrain.steppe);
|
Populator terrainRegionBorders = new TerrainPopulator(terrainProvider.getLandforms().plains(seed), context.terrain.steppe);
|
||||||
|
|
||||||
// transitions between the unique terrain regions and the common border terrain
|
// transitions between the unique terrain regions and the common border terrain
|
||||||
Populator terrain = new Lerp(
|
Populator terrain = new RegionLerper(terrainRegionBorders, terrainRegions);
|
||||||
regionEdge,
|
|
||||||
terrainRegionBorders,
|
|
||||||
terrainRegions
|
|
||||||
);
|
|
||||||
|
|
||||||
// mountain populator
|
// mountain populator
|
||||||
Populator mountains = register(terrainProvider.getLandforms().mountains(seed), context.terrain.mountains);
|
Populator mountains = register(terrainProvider.getLandforms().mountains(seed), context.terrain.mountains);
|
||||||
|
|
||||||
// controls what's ocean and what's land
|
// 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
|
// blends between normal terrain and mountain chains
|
||||||
Populator land = new Blender(
|
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
|
// uses the continent noise to blend between deep ocean, to ocean, to coast
|
||||||
MultiBlender oceans = new ContinentMultiBlender(
|
ContinentLerper3 oceans = new ContinentLerper3(
|
||||||
climate,
|
climate,
|
||||||
continent,
|
|
||||||
register(terrainProvider.getLandforms().deepOcean(seed.next()), context.terrain.deepOcean),
|
register(terrainProvider.getLandforms().deepOcean(seed.next()), context.terrain.deepOcean),
|
||||||
register(Source.constant(levels.water(-7)), context.terrain.ocean),
|
register(Source.constant(levels.water(-7)), context.terrain.ocean),
|
||||||
register(Source.constant(levels.water), context.terrain.coast),
|
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
|
// blends between the ocean/coast terrain and land terrains
|
||||||
root = new ContinentBlender(
|
root = new ContinentLerper2(
|
||||||
continent,
|
|
||||||
oceans,
|
oceans,
|
||||||
land,
|
land,
|
||||||
OCEAN_VALUE, // below == pure ocean
|
OCEAN_VALUE, // below == pure ocean
|
||||||
INLAND_VALUE, // above == pure land
|
INLAND_VALUE, // above == pure land
|
||||||
COAST_VALUE, // split point
|
COAST_VALUE, // split point
|
||||||
COAST_VALUE - 0.05F
|
COAST_VALUE - 0.05F
|
||||||
).mask();
|
);
|
||||||
|
|
||||||
this.riverManager = new RiverManager(this, context);
|
riverManager = new RiverManager(this, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Cell<Terrain> cell, float x, float z) {
|
public void visit(Cell<Terrain> 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);
|
root.apply(cell, x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,8 +144,9 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
// initial type
|
// initial type
|
||||||
cell.tag = terrain.steppe;
|
cell.tag = terrain.steppe;
|
||||||
|
|
||||||
// apply continent value/edge noise
|
// basic shapes
|
||||||
continent.apply(cell, x, z);
|
continentModule.apply(cell, x, z);
|
||||||
|
regionModule.apply(cell, x, z);
|
||||||
|
|
||||||
// apply actuall heightmap
|
// apply actuall heightmap
|
||||||
root.apply(cell, x, z);
|
root.apply(cell, x, z);
|
||||||
@ -184,7 +174,8 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tag(Cell<Terrain> cell, float x, float z) {
|
public void tag(Cell<Terrain> 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);
|
root.tag(cell, x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,8 +192,4 @@ public class WorldHeightmap implements Heightmap {
|
|||||||
terrainProvider.registerMixable(populator);
|
terrainProvider.registerMixable(populator);
|
||||||
return populator;
|
return populator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Populator createContinent(GeneratorContext context) {
|
|
||||||
return new VoronoiContinentModule(context.seed, context.settings.generator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.terraforged.core.world.river;
|
package com.terraforged.core.world.river;
|
||||||
|
|
||||||
|
import com.terraforged.core.world.heightmap.Heightmap;
|
||||||
import me.dags.noise.domain.Domain;
|
import me.dags.noise.domain.Domain;
|
||||||
import me.dags.noise.util.Vec2i;
|
import me.dags.noise.util.Vec2i;
|
||||||
import com.terraforged.core.cell.Cell;
|
import com.terraforged.core.cell.Cell;
|
||||||
import com.terraforged.core.world.heightmap.WorldHeightmap;
|
|
||||||
import com.terraforged.core.world.terrain.Terrain;
|
import com.terraforged.core.world.terrain.Terrain;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@ -21,13 +21,13 @@ public class PosGenerator {
|
|||||||
private final int padding;
|
private final int padding;
|
||||||
private final Domain domain;
|
private final Domain domain;
|
||||||
private final Cell<Terrain> lookup;
|
private final Cell<Terrain> lookup;
|
||||||
private final WorldHeightmap heightmap;
|
private final Heightmap heightmap;
|
||||||
|
|
||||||
private int i;
|
private int i;
|
||||||
private int dx;
|
private int dx;
|
||||||
private int dz;
|
private int dz;
|
||||||
|
|
||||||
public PosGenerator(WorldHeightmap heightmap, Domain domain, Cell<Terrain> lookup, int size, int padding) {
|
public PosGenerator(Heightmap heightmap, Domain domain, Cell<Terrain> lookup, int size, int padding) {
|
||||||
this.domain = domain;
|
this.domain = domain;
|
||||||
this.lookup = lookup;
|
this.lookup = lookup;
|
||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.terraforged.core.world.river;
|
package com.terraforged.core.world.river;
|
||||||
|
|
||||||
|
import com.terraforged.core.world.heightmap.Heightmap;
|
||||||
import me.dags.noise.util.NoiseUtil;
|
import me.dags.noise.util.NoiseUtil;
|
||||||
import com.terraforged.core.cell.Cell;
|
import com.terraforged.core.cell.Cell;
|
||||||
import com.terraforged.core.util.Cache;
|
import com.terraforged.core.util.Cache;
|
||||||
import com.terraforged.core.world.GeneratorContext;
|
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.Terrain;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -18,11 +18,11 @@ public class RiverManager {
|
|||||||
private final RiverConfig primary;
|
private final RiverConfig primary;
|
||||||
private final RiverConfig secondary;
|
private final RiverConfig secondary;
|
||||||
private final RiverConfig tertiary;
|
private final RiverConfig tertiary;
|
||||||
private final WorldHeightmap heightmap;
|
private final Heightmap heightmap;
|
||||||
private final GeneratorContext context;
|
private final GeneratorContext context;
|
||||||
private final Cache<Long, RiverRegion> cache = new Cache<>(60, 60, TimeUnit.SECONDS, () -> new ConcurrentHashMap<>());
|
private final Cache<Long, RiverRegion> 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.heightmap = heightmap;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.primary = RiverConfig.builder(context.levels)
|
this.primary = RiverConfig.builder(context.levels)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.terraforged.core.world.river;
|
package com.terraforged.core.world.river;
|
||||||
|
|
||||||
|
import com.terraforged.core.world.heightmap.Heightmap;
|
||||||
import me.dags.noise.domain.Domain;
|
import me.dags.noise.domain.Domain;
|
||||||
import me.dags.noise.util.NoiseUtil;
|
import me.dags.noise.util.NoiseUtil;
|
||||||
import me.dags.noise.util.Vec2f;
|
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.cell.Cell;
|
||||||
import com.terraforged.core.util.concurrent.ObjectPool;
|
import com.terraforged.core.util.concurrent.ObjectPool;
|
||||||
import com.terraforged.core.world.GeneratorContext;
|
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.Terrain;
|
||||||
import com.terraforged.core.world.terrain.Terrains;
|
import com.terraforged.core.world.terrain.Terrains;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ public class RiverRegion {
|
|||||||
private final List<River> rivers;
|
private final List<River> rivers;
|
||||||
private final List<Lake> lakes = new LinkedList<>();
|
private final List<Lake> 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();
|
int seed = new Random(NoiseUtil.seed(regionX, regionZ)).nextInt();
|
||||||
this.lake = lake;
|
this.lake = lake;
|
||||||
this.primary = primary;
|
this.primary = primary;
|
||||||
|
@ -36,7 +36,7 @@ public class VolcanoPopulator extends TerrainPopulator {
|
|||||||
|
|
||||||
this.cone = Source.cellEdge(region.seed, region.scale, EdgeFunc.DISTANCE_2_DIV).invert()
|
this.cone = Source.cellEdge(region.seed, region.scale, EdgeFunc.DISTANCE_2_DIV).invert()
|
||||||
.warp(region.warpX, region.warpZ, region.warpStrength)
|
.warp(region.warpX, region.warpZ, region.warpStrength)
|
||||||
.powCurve(14)
|
.powCurve(10)
|
||||||
.clamp(0.475, 1)
|
.clamp(0.475, 1)
|
||||||
.map(0, 1)
|
.map(0, 1)
|
||||||
.grad(0, 0.5, 0.5)
|
.grad(0, 0.5, 0.5)
|
||||||
@ -47,7 +47,7 @@ public class VolcanoPopulator extends TerrainPopulator {
|
|||||||
.warp(seed.next(), 30, 1, 30)
|
.warp(seed.next(), 30, 1, 30)
|
||||||
.scale(0.1);
|
.scale(0.1);
|
||||||
|
|
||||||
this.inversionPoint = 0.95F;
|
this.inversionPoint = 0.93F;
|
||||||
this.blendLower = midpoint - (range / 2F);
|
this.blendLower = midpoint - (range / 2F);
|
||||||
this.blendUpper = blendLower + range;
|
this.blendUpper = blendLower + range;
|
||||||
this.blendRange = blendUpper - blendLower;
|
this.blendRange = blendUpper - blendLower;
|
||||||
|
@ -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.Cell;
|
||||||
import com.terraforged.core.cell.Populator;
|
import com.terraforged.core.cell.Populator;
|
||||||
import com.terraforged.core.world.terrain.Terrain;
|
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 lower;
|
||||||
private final Populator upper;
|
private final Populator upper;
|
||||||
|
|
||||||
public Lerp(Module control, Populator lower, Populator upper) {
|
public RegionLerper(Populator lower, Populator upper) {
|
||||||
this.control = control;
|
|
||||||
this.lower = lower;
|
this.lower = lower;
|
||||||
this.upper = upper;
|
this.upper = upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||||
float alpha = control.getValue(x, y);
|
float alpha = cell.regionEdge;
|
||||||
cell.regionMask = alpha;
|
|
||||||
|
|
||||||
if (alpha == 0) {
|
if (alpha == 0) {
|
||||||
lower.apply(cell, x, y);
|
lower.apply(cell, x, y);
|
||||||
return;
|
return;
|
||||||
@ -44,8 +39,7 @@ public class Lerp implements Populator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tag(Cell<Terrain> cell, float x, float y) {
|
public void tag(Cell<Terrain> cell, float x, float y) {
|
||||||
float alpha = control.getValue(x, y);
|
if (cell.regionEdge == 0) {
|
||||||
if (alpha == 0) {
|
|
||||||
lower.tag(cell, x, y);
|
lower.tag(cell, x, y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -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.Source;
|
||||||
import me.dags.noise.domain.Domain;
|
import me.dags.noise.domain.Domain;
|
||||||
import me.dags.noise.func.DistanceFunc;
|
import me.dags.noise.func.DistanceFunc;
|
||||||
import me.dags.noise.func.EdgeFunc;
|
import me.dags.noise.func.EdgeFunc;
|
||||||
import me.dags.noise.util.NoiseUtil;
|
import me.dags.noise.util.NoiseUtil;
|
||||||
import me.dags.noise.util.Vec2f;
|
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 {
|
public class RegionModule 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 int seed;
|
||||||
private final float frequency;
|
private final float frequency;
|
||||||
@ -25,44 +19,19 @@ public class VoronoiContinentModule implements Populator {
|
|||||||
private final float edgeMin;
|
private final float edgeMin;
|
||||||
private final float edgeMax;
|
private final float edgeMax;
|
||||||
private final float edgeRange;
|
private final float edgeRange;
|
||||||
|
|
||||||
private final Domain warp;
|
private final Domain warp;
|
||||||
private final Module shape;
|
|
||||||
|
|
||||||
public VoronoiContinentModule(Seed seed, GeneratorSettings settings) {
|
public RegionModule(RegionConfig regionConfig) {
|
||||||
int tectonicScale = settings.land.continentScale * 4;
|
seed = regionConfig.seed;
|
||||||
int continentScale = settings.land.continentScale / 2;
|
edgeMin = 0F;
|
||||||
double oceans = Math.min(Math.max(settings.world.oceanSize, 0.01), 0.99);
|
edgeMax = 0.5F;
|
||||||
double shapeMin = 0.15 + (oceans * 0.35);
|
edgeRange = edgeMax - edgeMin;
|
||||||
this.seed = seed.next();
|
frequency = 1F / regionConfig.scale;
|
||||||
|
warp = Domain.warp(regionConfig.warpX, regionConfig.warpZ, Source.constant(regionConfig.warpStrength));
|
||||||
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
|
@Override
|
||||||
public float getValue(float x, float y) {
|
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||||
if (true) {
|
|
||||||
throw new RuntimeException("no pls!");
|
|
||||||
} else {
|
|
||||||
Cell<Terrain> cell = new Cell<>();
|
|
||||||
apply(cell, x, y);
|
|
||||||
return cell.continentEdge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void apply(Cell<Terrain> cell, final float x, final float y) {
|
|
||||||
float ox = warp.getOffsetX(x, y);
|
float ox = warp.getOffsetX(x, y);
|
||||||
float oz = warp.getOffsetY(x, y);
|
float oz = warp.getOffsetY(x, y);
|
||||||
|
|
||||||
@ -108,12 +77,8 @@ public class VoronoiContinentModule implements Populator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell.region = cellValue(seed, cellX, cellY);
|
||||||
float shapeNoise = shape.getValue(x, y);
|
cell.regionEdge = edgeValue(edgeDistance, edgeDistance2);
|
||||||
float continentNoise = edgeValue(edgeDistance, edgeDistance2);
|
|
||||||
|
|
||||||
cell.continent = cellValue(seed, cellX, cellY);
|
|
||||||
cell.continentEdge = shapeNoise * continentNoise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,12 +95,16 @@ public class VoronoiContinentModule implements Populator {
|
|||||||
EdgeFunc edge = EdgeFunc.DISTANCE_2_DIV;
|
EdgeFunc edge = EdgeFunc.DISTANCE_2_DIV;
|
||||||
float value = edge.apply(distance, distance2);
|
float value = edge.apply(distance, distance2);
|
||||||
float edgeValue = 1 - NoiseUtil.map(value, edge.min(), edge.max(), edge.range());
|
float edgeValue = 1 - NoiseUtil.map(value, edge.min(), edge.max(), edge.range());
|
||||||
|
|
||||||
|
edgeValue = NoiseUtil.pow(edgeValue, 1.5F);
|
||||||
|
|
||||||
if (edgeValue < edgeMin) {
|
if (edgeValue < edgeMin) {
|
||||||
return 0F;
|
return 0F;
|
||||||
}
|
}
|
||||||
if (edgeValue > edgeMax) {
|
if (edgeValue > edgeMax) {
|
||||||
return 1F;
|
return 1F;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (edgeValue - edgeMin) / edgeRange;
|
return (edgeValue - edgeMin) / edgeRange;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.Cell;
|
||||||
import com.terraforged.core.cell.Populator;
|
import com.terraforged.core.cell.Populator;
|
||||||
import com.terraforged.core.world.terrain.Terrain;
|
import com.terraforged.core.world.terrain.Terrain;
|
||||||
import com.terraforged.core.world.terrain.TerrainPopulator;
|
import com.terraforged.core.world.terrain.TerrainPopulator;
|
||||||
|
import me.dags.noise.util.NoiseUtil;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Selector implements Populator {
|
public class RegionSelector implements Populator {
|
||||||
|
|
||||||
private final int maxIndex;
|
private final int maxIndex;
|
||||||
private final Module control;
|
|
||||||
private final Populator[] nodes;
|
private final Populator[] nodes;
|
||||||
|
|
||||||
public Selector(Module control, List<Populator> populators) {
|
public RegionSelector(List<Populator> populators) {
|
||||||
this.control = control;
|
|
||||||
this.nodes = getWeightedArray(populators);
|
this.nodes = getWeightedArray(populators);
|
||||||
this.maxIndex = nodes.length - 1;
|
this.maxIndex = nodes.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||||
get(x, y).apply(cell, x, y);
|
get(cell.region).apply(cell, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tag(Cell<Terrain> cell, float x, float y) {
|
public void tag(Cell<Terrain> 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) {
|
public Populator get(float identity) {
|
||||||
float selector = control.getValue(x, y);
|
int index = NoiseUtil.round(identity * maxIndex);
|
||||||
int index = NoiseUtil.round(selector * maxIndex);
|
|
||||||
return nodes[index];
|
return nodes[index];
|
||||||
}
|
}
|
||||||
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 5f7d2c8ec864f6dcd1c977013c3c8377d33c4547
|
Subproject commit 5d1604ab29ae129f133c34fdd72bc207f21364aa
|
Loading…
Reference in New Issue
Block a user