This commit is contained in:
dags- 2020-01-16 21:33:41 +00:00
parent baeba9c98a
commit 93b7abff62
23 changed files with 120 additions and 136 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "Noise2D"]
path = Noise2D
url = https://github.com/TerraForged/Noise2D.git
[submodule "TerraForgedMod"]
path = TerraForgedMod
url = https://github.com/dags-/TerraForgedMod.git

@ -1 +1 @@
Subproject commit 1fd2cd9f133c861c613edfb2d49fe1a801fe3366
Subproject commit 4083d609c0023744eef091e3f74ac871806b5565

View File

@ -1,7 +1,3 @@
plugins {
id "java"
}
repositories {
mavenCentral()
jcenter()
@ -15,4 +11,5 @@ dependencies {
jar {
manifest { attributes "Main-Class": "com.terraforged.app.Main" }
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}

View File

@ -1,5 +1,3 @@
apply plugin: "java"
dependencies {
compile project(":Noise2D")
}

View File

@ -4,7 +4,5 @@ import com.terraforged.core.world.terrain.Terrain;
public interface Extent {
Cell<Terrain> getCell(int x, int z);
void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor);
}

View File

@ -1,8 +1,8 @@
package com.terraforged.core.cell;
import me.dags.noise.Module;
import com.terraforged.core.util.concurrent.ObjectPool;
import com.terraforged.core.world.terrain.Terrain;
import me.dags.noise.Module;
public interface Populator extends Module {
@ -10,14 +10,11 @@ public interface Populator extends Module {
void tag(Cell<Terrain> cell, float x, float y);
@Override
default float getValue(float x, float z) {
try (ObjectPool.Item<Cell<Terrain>> cell = Cell.pooled()) {
return getValue(cell.getValue(), x, z);
apply(cell.getValue(), x, z);
return cell.getValue().value;
}
}
default float getValue(Cell<Terrain> cell, float x, float z) {
apply(cell, x, z);
return cell.value;
}
}

View File

@ -1,21 +1,29 @@
package com.terraforged.core.module;
import me.dags.noise.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 Module {
public class CellLookup implements Populator {
private final int scale;
private final Module module;
private final Heightmap heightmap;
public CellLookup(Module module, int scale) {
this.module = module;
public CellLookup(Heightmap heightmap, int scale) {
this.heightmap = heightmap;
this.scale = scale;
}
@Override
public float getValue(float x, float y) {
public void apply(Cell<Terrain> cell, float x, float y) {
float px = x * scale;
float pz = y * scale;
return module.getValue(px, pz);
heightmap.getValue(px, pz);
}
@Override
public void tag(Cell<Terrain> cell, float x, float y) {
}
}

View File

@ -1,30 +1,39 @@
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 Module {
public class CellLookupOffset implements Populator {
private final int scale;
private final Module lookup;
private final Module direction;
private final Module strength;
private final Heightmap heightmap;
public CellLookupOffset(Module lookup, Module direction, Module strength, int scale) {
public CellLookupOffset(Heightmap heightmap, Module direction, Module strength, int scale) {
this.scale = scale;
this.lookup = lookup;
this.heightmap = heightmap;
this.direction = direction;
this.strength = strength;
}
@Override
public float getValue(float x, float y) {
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;
return lookup.getValue(px + dx, pz + dz);
heightmap.visit(cell, px + dx, pz + dz);
}
@Override
public void tag(Cell<Terrain> cell, float x, float y) {
}
}

View File

@ -77,7 +77,6 @@ public class Region implements Extent {
return new FilterRegion();
}
@Override
public Cell<Terrain> getCell(int blockX, int blockZ) {
int relBlockX = blockSize.border + blockSize.mask(blockX);
int relBlockZ = blockSize.border + blockSize.mask(blockZ);
@ -131,6 +130,26 @@ public class Region implements Extent {
}
}
public void check() {
for (int dz = 0; dz < chunkSize.total; dz++) {
for (int dx = 0; dx < chunkSize.total; dx++) {
int index = chunkSize.indexOf(dx, dz);
if (chunks[index] == null) {
throw new NullPointerException("Null chunk " + dx + ":" + dz);
}
}
}
for (int dz = 0; dz < blockSize.total; dz++) {
for (int dx = 0; dx < blockSize.total; dx++) {
int index = blockSize.indexOf(dx, dz);
if (blocks[index] == null) {
throw new NullPointerException("Null block " + dx + ":" + dz);
}
}
}
}
public void decorate(Collection<Decorator> decorators) {
for (int dz = 0; dz < blockSize.total; dz++) {
for (int dx = 0; dx < blockSize.total; dx++) {
@ -233,14 +252,18 @@ public class Region implements Extent {
private final int chunkZ;
private final int blockX;
private final int blockZ;
private final int relBlockX;
private final int relBlockZ;
private final int regionBlockX;
private final int regionBlockZ;
private GenChunk(int relChunkX, int relChunkZ) {
this.relBlockX = relChunkX << 4;
this.relBlockZ = relChunkZ << 4;
this.chunkX = Region.this.chunkX + relChunkX;
this.chunkZ = Region.this.chunkZ + relChunkZ;
// the coordinate of the chunk within this region (relative to 0,0)
private GenChunk(int regionChunkX, int regionChunkZ) {
// the block coordinate of this chunk within this region (relative 0,0)
this.regionBlockX = regionChunkX << 4;
this.regionBlockZ = regionChunkZ << 4;
// the real coordinate of this chunk within the world
this.chunkX = Region.this.chunkX + regionChunkX;
this.chunkZ = Region.this.chunkZ + regionChunkZ;
// the real block coordinate of this chunk within the world
this.blockX = chunkX << 4;
this.blockZ = chunkZ << 4;
}
@ -267,16 +290,16 @@ public class Region implements Extent {
@Override
public Cell<Terrain> getCell(int blockX, int blockZ) {
int relX = relBlockX + (blockX & 15);
int relZ = relBlockZ + (blockZ & 15);
int relX = regionBlockX + (blockX & 15);
int relZ = regionBlockZ + (blockZ & 15);
int index = blockSize.indexOf(relX, relZ);
return blocks[index];
}
@Override
public Cell<Terrain> genCell(int blockX, int blockZ) {
int relX = relBlockX + (blockX & 15);
int relZ = relBlockZ + (blockZ & 15);
int relX = regionBlockX + (blockX & 15);
int relZ = regionBlockZ + (blockZ & 15);
int index = blockSize.indexOf(relX, relZ);
return computeCell(index);
}

View File

@ -84,13 +84,13 @@ public class RegionGenerator implements RegionExtent {
try (ThreadPool.Batcher batcher = threadPool.batcher(region.getChunkCount())) {
region.generateZoom(generator.getHeightmap(), centerX, centerZ, zoom, batcher);
}
region.check();
postProcess(region, generator, centerX, centerZ, zoom, filter);
return region;
}
}
private void postProcess(Region region, WorldGenerator generator, float centerX, float centerZ, float zoom,
boolean filter) {
private void postProcess(Region region, WorldGenerator generator, float centerX, float centerZ, float zoom, boolean filter) {
Filterable<Terrain> filterable = region.filterable();
if (filter) {
generator.getFilters().setRegion(region.getRegionX(), region.getRegionZ());

View File

@ -19,7 +19,7 @@ public class Size {
}
public int indexOf(int x, int z) {
return z * total + x;
return (z * total) + x;
}
public static int chunkToBlock(int i) {

View File

@ -5,7 +5,6 @@ import com.terraforged.core.world.terrain.Terrain;
public interface ChunkReader extends ChunkHolder {
@Override
Cell<Terrain> getCell(int dx, int dz);
@Override

View File

@ -66,7 +66,6 @@ public class ThreadPool {
for (Future<?> future : tasks) {
if (!future.isDone()) {
hasMore = true;
break;
}
}
}

View File

@ -25,8 +25,6 @@ public class Climate {
private final Rand rand;
private final Module treeLine;
private final Module heightMap;
private final Module offsetHeightMap;
private final Module offsetX;
private final Module offsetY;
@ -40,31 +38,9 @@ public class Climate {
this.biomeNoise = new ClimateModule(context.seed, context.settings.generator);
Module warpX = Source.perlin(context.seed.next(), warpScale, 2);
Module warpZ = Source.perlin(context.seed.next(), warpScale, 2);
Module windDirection = Source.cubic(context.seed.next(), cellSize, 1);
Module windStrength = Source.perlin(context.seed.next(), cellSize, 1)
.scale(cellSize * 1.5)
.bias(cellSize * 0.5);
this.treeLine = Source.perlin(context.seed.next(), context.settings.generator.biome.biomeSize * 2, 1)
.scale(0.1).bias(0.4);
this.heightMap = Source.build(cellSeed, cellSize, 1)
.distFunc(DistanceFunc.NATURAL)
.cellFunc(CellFunc.NOISE_LOOKUP)
.source(new CellLookup(heightmap::getValue, cellSize))
.cell()
.warp(warpX, warpZ, warpStrength);
this.offsetHeightMap = Source.build(cellSeed, cellSize, 1)
.distFunc(DistanceFunc.NATURAL)
.cellFunc(CellFunc.NOISE_LOOKUP)
.source(new CellLookupOffset(heightmap::getValue, windDirection, windStrength, cellSize))
.cell()
.warp(warpX, warpZ, warpStrength);
this.rand = new Rand(Source.builder().seed(context.seed.next()));
this.offsetX = context.settings.generator.biomeEdgeNoise.build(context.seed.next());
this.offsetY = context.settings.generator.biomeEdgeNoise.build(context.seed.next());
@ -76,14 +52,6 @@ public class Climate {
return rand;
}
public float getCellHeight(float x, float z) {
return heightMap.getValue(x, z);
}
public float getOffsetCellHeight(float x, float z) {
return offsetHeightMap.getValue(x, z);
}
public float getOffsetX(float x, float z, int distance) {
return offsetX.getValue(x, z) * distance;
}
@ -98,26 +66,12 @@ public class Climate {
public void apply(Cell<Terrain> cell, float x, float z, boolean mask) {
biomeNoise.apply(cell, x, z, mask);
modify(cell, x, z);
modifyTemp(cell, x, z);
}
private void modify(Cell<Terrain> cell, float x, float z) {
float height = getCellHeight(x, z);
float height1 = getOffsetCellHeight(x, z);
float moistDelta = 0F;
if (height > seaLevel) {
if (height1 < seaLevel) {
moistDelta = 0.7F;
} else if (height - height1 > 0.2) {
moistDelta = height - height1;
} else if (height1 - height > 0.1) {
moistDelta = Math.max(-0.5F, height - height1) * 2F;
}
}
float moistChange = moistureModifier * moistDelta;
cell.moisture = NoiseUtil.clamp(cell.moisture + moistChange, 0, 1);
private void modifyTemp(Cell<Terrain> cell, float x, float z) {
float height = cell.value;
if (height > upperHeight) {
cell.temperature = Math.max(0, cell.temperature - temperatureModifier);
return;

View File

@ -15,7 +15,7 @@ public class ContinentBlender extends Blender {
}
@Override
public float getValue(Cell<Terrain> cell, float x, float z) {
public float getSelect(Cell<Terrain> cell, float x, float z) {
return cell.continentEdge;
}
}

View File

@ -16,7 +16,7 @@ public class ContinentMultiBlender extends MultiBlender {
}
@Override
public float getValue(Cell<Terrain> cell, float x, float z) {
public float getSelect(Cell<Terrain> cell, float x, float z) {
return cell.continentEdge;
}
}

View File

@ -52,11 +52,14 @@ public class VoronoiContinentModule implements Populator {
@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) {

View File

@ -1,26 +1,18 @@
package com.terraforged.core.world.heightmap;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.cell.Populator;
import com.terraforged.core.cell.Extent;
import com.terraforged.core.cell.Populator;
import com.terraforged.core.region.Size;
import com.terraforged.core.util.concurrent.ObjectPool;
import com.terraforged.core.world.climate.Climate;
import com.terraforged.core.world.river.RiverManager;
import com.terraforged.core.world.terrain.Terrain;
import java.rmi.UnexpectedException;
public interface Heightmap extends Populator, Extent {
Climate getClimate();
RiverManager getRiverManager();
@Override
default Cell<Terrain> getCell(int x, int z) {
throw new RuntimeException("Don't use this pls");
}
void visit(Cell<Terrain> cell, float x, float z);
@Override
default void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor) {

View File

@ -37,14 +37,6 @@ public interface RegionExtent extends Extent {
return regions;
}
@Override
default Cell<Terrain> getCell(int x, int z) {
int regionX = chunkToRegion(Size.blockToChunk(x));
int regionZ = chunkToRegion(Size.blockToChunk(z));
Region region = getRegion(regionX, regionZ);
return region.getCell(x, z);
}
@Override
default void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor) {
int minRegionX = chunkToRegion(Size.blockToChunk(minX));

View File

@ -1,9 +1,5 @@
package com.terraforged.core.world.heightmap;
import me.dags.noise.Module;
import me.dags.noise.Source;
import me.dags.noise.func.EdgeFunc;
import me.dags.noise.func.Interpolation;
import com.terraforged.core.cell.Cell;
import com.terraforged.core.cell.Populator;
import com.terraforged.core.module.Blender;
@ -23,6 +19,10 @@ import com.terraforged.core.world.terrain.Terrain;
import com.terraforged.core.world.terrain.TerrainPopulator;
import com.terraforged.core.world.terrain.Terrains;
import com.terraforged.core.world.terrain.provider.TerrainProvider;
import me.dags.noise.Module;
import me.dags.noise.Source;
import me.dags.noise.func.EdgeFunc;
import me.dags.noise.func.Interpolation;
public class WorldHeightmap implements Heightmap {
@ -144,8 +144,10 @@ public class WorldHeightmap implements Heightmap {
this.riverManager = new RiverManager(this, context);
}
public RiverManager getRiverManager() {
return riverManager;
@Override
public void visit(Cell<Terrain> cell, float x, float z) {
continent.apply(cell, x, z);
root.apply(cell, x, z);
}
@Override

View File

@ -67,8 +67,8 @@ public class PosGenerator {
int pz = z + dz;
int wx = (int) domain.getX(px, pz);
int wz = (int) domain.getY(px, pz);
float value1 = heightmap.getValue(lookup, px, pz);
float value2 = heightmap.getValue(lookup, wx, wz);
float value1 = getHeight(px, pz);
float value2 = getHeight(wx, wz);
RiverNode.Type type1 = RiverNode.getType(value1);
RiverNode.Type type2 = RiverNode.getType(value2);
if (type1 == type2 && type1 != RiverNode.Type.NONE) {
@ -91,8 +91,8 @@ public class PosGenerator {
}
int wx = (int) domain.getX(px, pz);
int wz = (int) domain.getY(px, pz);
float value1 = heightmap.getValue(lookup, px, pz);
float value2 = heightmap.getValue(lookup, wx, wz);
float value1 = getHeight(px, pz);
float value2 = getHeight(wx, wz);
RiverNode.Type type1 = RiverNode.getType(value1);
RiverNode.Type type2 = RiverNode.getType(value2);
if (type1 == type2 && type1 == point.type.opposite()) {
@ -112,8 +112,8 @@ public class PosGenerator {
int pz = z + dz;
int wx = (int) domain.getX(px, pz);
int wz = (int) domain.getY(px, pz);
float value1 = heightmap.getValue(lookup, px, pz);
float value2 = heightmap.getValue(lookup, wx, wz);
float value1 = getHeight(px, pz);
float value2 = getHeight(wx, wz);
RiverNode.Type type1 = RiverNode.getType(value1);
RiverNode.Type type2 = RiverNode.getType(value2);
if (type1 == type2 && type1 == match) {
@ -130,8 +130,8 @@ public class PosGenerator {
int pz = z + dz;
int wx = (int) domain.getX(px, pz);
int wz = (int) domain.getY(px, pz);
float value1 = heightmap.getValue(lookup, px, pz);
float value2 = heightmap.getValue(lookup, wx, wz);
float value1 = getHeight(px, pz);
float value2 = getHeight(wx, wz);
if (value1 > minHeight && value2 > minHeight) {
return new RiverNode(px, pz, RiverNode.Type.START);
}
@ -139,6 +139,11 @@ public class PosGenerator {
return null;
}
private float getHeight(int x, int z) {
heightmap.visit(lookup, x, z);
return lookup.value;
}
private static int index(int x, int z) {
return z * 2 + x;
}

1
TerraForgedMod Submodule

@ -0,0 +1 @@
Subproject commit 576c491d5a156d48b1bf1e17f95d1b8272f2e5b5

View File

@ -1,2 +1,6 @@
rootProject.name = "TerraForged"
include ":Noise2D", ":FeatureManager", ":TerraForgedCore", ":TerraForgedApp"
include ":Noise2D"
include ":FeatureManager"
include ":TerraForgedCore"
include ":TerraForgedApp"
include ":TerraForgedMod"