- ensure order that river regions are visited

- fix for tundra tree density
- tweaks to jungle tree densities
- increase gen region size
This commit is contained in:
dags- 2020-03-26 12:09:05 +00:00
parent bb6263dfb8
commit ed92a3ed6b
17 changed files with 255 additions and 78 deletions

View File

@ -27,7 +27,7 @@ package com.terraforged.app;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.region.Region; import com.terraforged.core.region.Region;
import com.terraforged.core.region.RegionGenerator; import com.terraforged.core.region.gen.RegionGenerator;
import com.terraforged.core.settings.Settings; import com.terraforged.core.settings.Settings;
import com.terraforged.core.util.concurrent.ThreadPool; import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.world.GeneratorContext; import com.terraforged.core.world.GeneratorContext;

View File

@ -0,0 +1,21 @@
package com.terraforged.core.region.gen;
import com.terraforged.core.world.WorldGenerator;
import com.terraforged.core.world.WorldGeneratorFactory;
import com.terraforged.core.world.rivermap.RiverRegionList;
import java.util.function.Supplier;
public class GenContext {
public final WorldGenerator generator;
public final RiverRegionList rivers = new RiverRegionList();
public GenContext(WorldGenerator generator) {
this.generator = generator;
}
public static Supplier<GenContext> supplier(WorldGeneratorFactory factory) {
return () -> new GenContext(factory.get());
}
}

View File

@ -23,8 +23,9 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.terraforged.core.region; package com.terraforged.core.region.gen;
import com.terraforged.core.region.Region;
import com.terraforged.core.region.chunk.ChunkReader; import com.terraforged.core.region.chunk.ChunkReader;
import com.terraforged.core.util.concurrent.Disposable; import com.terraforged.core.util.concurrent.Disposable;
import com.terraforged.core.util.concurrent.cache.Cache; import com.terraforged.core.util.concurrent.cache.Cache;

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.terraforged.core.region; package com.terraforged.core.region.gen;
import com.terraforged.core.world.WorldGeneratorFactory; import com.terraforged.core.world.WorldGeneratorFactory;

View File

@ -23,10 +23,13 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.terraforged.core.region; package com.terraforged.core.region.gen;
import com.terraforged.core.region.Region;
import com.terraforged.core.region.RegionFactory;
import com.terraforged.core.region.legacy.LegacyRegion; import com.terraforged.core.region.legacy.LegacyRegion;
import com.terraforged.core.util.concurrent.Disposable; import com.terraforged.core.util.concurrent.Disposable;
import com.terraforged.core.util.concurrent.ObjectPool;
import com.terraforged.core.util.concurrent.ThreadPool; import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.util.concurrent.cache.CacheEntry; import com.terraforged.core.util.concurrent.cache.CacheEntry;
import com.terraforged.core.world.WorldGenerator; import com.terraforged.core.world.WorldGenerator;
@ -42,7 +45,7 @@ public class RegionGenerator implements RegionExtent {
private final int border; private final int border;
private final RegionFactory regions; private final RegionFactory regions;
private final ThreadPool threadPool; private final ThreadPool threadPool;
private final ThreadLocal<WorldGenerator> genPool; private final ObjectPool<GenContext> genPool;
private final Disposable.Listener<Region> disposalListener; private final Disposable.Listener<Region> disposalListener;
private RegionGenerator(Builder builder) { private RegionGenerator(Builder builder) {
@ -50,7 +53,7 @@ public class RegionGenerator implements RegionExtent {
this.border = builder.border; this.border = builder.border;
this.threadPool = builder.threadPool; this.threadPool = builder.threadPool;
this.regions = builder.regionFactory; this.regions = builder.regionFactory;
this.genPool = ThreadLocal.withInitial(builder.factory); this.genPool = new ObjectPool<>(6, GenContext.supplier(builder.factory));
this.disposalListener = region -> {}; this.disposalListener = region -> {};
} }
@ -99,13 +102,17 @@ public class RegionGenerator implements RegionExtent {
} }
public Region generateRegion(int regionX, int regionZ) { public Region generateRegion(int regionX, int regionZ) {
WorldGenerator generator = genPool.get(); try (ObjectPool.Item<GenContext> item = genPool.get()) {
Region region = regions.create(regionX, regionZ, factor, border, disposalListener); RiverRegionList rivers = item.getValue().rivers;
RiverRegionList rivers = generator.getHeightmap().getRiverMap().getRivers(region); WorldGenerator generator = item.getValue().generator;
region.generateBase(generator.getHeightmap()); Region region = regions.create(regionX, regionZ, factor, border, disposalListener);
region.generateRivers(generator.getHeightmap(), rivers); generator.getHeightmap().getRiverMap().getRivers(region, rivers);
postProcess(region, generator); region.generateBase(generator.getHeightmap());
return region; region.generateRivers(generator.getHeightmap(), rivers);
postProcess(region, generator);
rivers.clear();
return region;
}
} }
private void postProcess(Region region, WorldGenerator generator) { private void postProcess(Region region, WorldGenerator generator) {
@ -114,11 +121,13 @@ public class RegionGenerator implements RegionExtent {
} }
public Region generateRegion(float centerX, float centerZ, float zoom, boolean filter) { public Region generateRegion(float centerX, float centerZ, float zoom, boolean filter) {
WorldGenerator generator = genPool.get(); try (ObjectPool.Item<GenContext> item = genPool.get()) {
Region region = regions.create(0, 0, factor, border, disposalListener); WorldGenerator generator = item.getValue().generator;
region.generateZoom(generator.getHeightmap(), centerX, centerZ, zoom); Region region = regions.create(0, 0, factor, border, disposalListener);
postProcess(region, generator, centerX, centerZ, zoom, filter); region.generateZoom(generator.getHeightmap(), centerX, centerZ, zoom);
return region; 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) {

View File

@ -85,10 +85,22 @@ public class RiverMap {
} }
public RiverRegionList getRivers(Region region) { public RiverRegionList getRivers(Region region) {
return getRivers(region.getBlockX(), region.getBlockZ()); RiverRegionList rivers = new RiverRegionList();
getRivers(region.getBlockX(), region.getBlockZ(), rivers);
return rivers;
} }
public RiverRegionList getRivers(int blockX, int blockZ) { public RiverRegionList getRivers(int blockX, int blockZ) {
RiverRegionList rivers = new RiverRegionList();
getRivers(blockX, blockZ, rivers);
return rivers;
}
public void getRivers(Region region, RiverRegionList rivers) {
getRivers(region.getBlockX(), region.getBlockZ(), rivers);
}
public void getRivers(int blockX, int blockZ, RiverRegionList rivers) {
int rx = RiverRegion.blockToRegion(blockX); int rx = RiverRegion.blockToRegion(blockX);
int rz = RiverRegion.blockToRegion(blockZ); int rz = RiverRegion.blockToRegion(blockZ);
@ -102,48 +114,18 @@ public class RiverMap {
int maxX = Math.max(0, qx); int maxX = Math.max(0, qx);
int maxZ = Math.max(0, qz); int maxZ = Math.max(0, qz);
RiverRegionList list = new RiverRegionList(); rivers.reset();
for (int dz = minZ; dz <= maxZ; dz++) { for (int dz = minZ; dz <= maxZ; dz++) {
for (int dx = minX; dx <= maxX; dx++) { for (int dx = minX; dx <= maxX; dx++) {
list.add(getRegion(rx + dx, rz + dz)); rivers.add(getRegion(rx + dx, rz + dz));
} }
} }
return list;
} }
public void apply(Cell<Terrain> cell, float x, float z) { public void apply(Cell<Terrain> cell, float x, float z) {
int rx = RiverRegion.blockToRegion((int) x); RiverRegionList rivers = new RiverRegionList();
int rz = RiverRegion.blockToRegion((int) z); getRivers((int) x, (int) z, rivers);
rivers.apply(cell, x, z);
// check which quarter of the region pos (x,y) is in & get the neighbouring regions' relative coords
int qx = x < RiverRegion.regionToBlock(rx) + QUAD_SIZE ? -1 : 1;
int qz = z < RiverRegion.regionToBlock(rz) + QUAD_SIZE ? -1 : 1;
// relative positions of neighbouring regions
int minX = Math.min(0, qx);
int minZ = Math.min(0, qz);
int maxX = Math.max(0, qx);
int maxZ = Math.max(0, qz);
// queue up the 4 nearest reiver regions
int index = 0;
CacheEntry<RiverRegion>[] entries = new CacheEntry[4];
for (int dz = minZ; dz <= maxZ; dz++) {
for (int dx = minX; dx <= maxX; dx++) {
entries[index++] = getRegion(rx + dx, rz + dz);
}
}
int count = 0;
while (count < index) {
for (CacheEntry<RiverRegion> entry : entries) {
if (entry.isDone()) {
count++;
entry.get().apply(cell, x, z);
}
}
}
} }
private CacheEntry<RiverRegion> getRegion(int rx, int rz) { private CacheEntry<RiverRegion> getRegion(int rx, int rz) {

View File

@ -5,6 +5,8 @@ import com.terraforged.core.util.concurrent.cache.CacheEntry;
import com.terraforged.core.world.rivermap.river.RiverRegion; import com.terraforged.core.world.rivermap.river.RiverRegion;
import com.terraforged.core.world.terrain.Terrain; import com.terraforged.core.world.terrain.Terrain;
import java.util.Arrays;
public class RiverRegionList { public class RiverRegionList {
private int index = 0; private int index = 0;
@ -17,15 +19,17 @@ public class RiverRegionList {
} }
} }
protected void reset() {
index = 0;
}
public void clear() {
Arrays.fill(regions, null);
}
public void apply(Cell<Terrain> cell, float x, float z) { public void apply(Cell<Terrain> cell, float x, float z) {
int complete = 0; for (CacheEntry<RiverRegion> entry : regions) {
while (complete < regions.length) { entry.get().apply(cell, x, z);
for (CacheEntry<RiverRegion> entry : regions) {
if (entry.isDone()) {
complete++;
entry.get().apply(cell, x, z);
}
}
} }
} }
} }

View File

@ -32,10 +32,10 @@ import com.terraforged.api.chunk.surface.SurfaceContext;
import com.terraforged.api.chunk.surface.SurfaceManager; import com.terraforged.api.chunk.surface.SurfaceManager;
import com.terraforged.api.material.layer.LayerManager; import com.terraforged.api.material.layer.LayerManager;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.region.RegionCache;
import com.terraforged.core.region.RegionGenerator;
import com.terraforged.core.region.Size; import com.terraforged.core.region.Size;
import com.terraforged.core.region.chunk.ChunkReader; import com.terraforged.core.region.chunk.ChunkReader;
import com.terraforged.core.region.gen.RegionCache;
import com.terraforged.core.region.gen.RegionGenerator;
import com.terraforged.core.util.concurrent.ThreadPool; import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.world.decorator.Decorator; import com.terraforged.core.world.decorator.Decorator;
import com.terraforged.feature.FeatureManager; import com.terraforged.feature.FeatureManager;
@ -390,7 +390,7 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSetti
.legacy(context.terraSettings.version == 0) .legacy(context.terraSettings.version == 0)
.pool(ThreadPool.getPool()) .pool(ThreadPool.getPool())
.factory(context.factory) .factory(context.factory)
.size(3, 2) .size(4, 2)
.build() .build()
.toCache(false); .toCache(false);
} }

View File

@ -27,8 +27,8 @@ package com.terraforged.mod.chunk.test;
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.region.RegionCache; import com.terraforged.core.region.gen.RegionCache;
import com.terraforged.core.region.RegionGenerator; import com.terraforged.core.region.gen.RegionGenerator;
import com.terraforged.core.util.concurrent.ThreadPool; import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.world.GeneratorContext; import com.terraforged.core.world.GeneratorContext;
import com.terraforged.core.world.WorldGeneratorFactory; import com.terraforged.core.world.WorldGeneratorFactory;

View File

@ -83,10 +83,7 @@ public class ErosionDecorator implements ColumnDecorator {
return; return;
} }
int topY = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, x, z); y = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, x, z);
if (topY < y) {
y = topY;
}
ISurfaceBuilderConfig config = context.biome.getSurfaceBuilderConfig(); ISurfaceBuilderConfig config = context.biome.getSurfaceBuilderConfig();
BlockState top = config.getTop(); BlockState top = config.getTop();

View File

@ -29,7 +29,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.terraforged.core.cell.Cell; import com.terraforged.core.cell.Cell;
import com.terraforged.core.region.Region; import com.terraforged.core.region.Region;
import com.terraforged.core.region.RegionGenerator; import com.terraforged.core.region.gen.RegionGenerator;
import com.terraforged.core.settings.Settings; import com.terraforged.core.settings.Settings;
import com.terraforged.core.util.concurrent.ThreadPool; import com.terraforged.core.util.concurrent.ThreadPool;
import com.terraforged.core.world.GeneratorContext; import com.terraforged.core.world.GeneratorContext;

View File

@ -1,4 +1,8 @@
{ {
"biomes": [
"minecraft:jungle",
"minecraft:bamboo_jungle"
],
"match": [ "match": [
[ [
"minecraft:mega_jungle_tree" "minecraft:mega_jungle_tree"

View File

@ -0,0 +1,44 @@
{
"biomes": [
"minecraft:jungle_edge"
],
"match": [
[
"minecraft:fancy_tree"
]
],
"replace": {
"name": "minecraft:decorated",
"config": {
"feature": {
"name": "minecraft:random_selector",
"config": {
"features": [
{
"name": "terraforged:jungle_small",
"config": {},
"chance": 0.2
},
{
"name": "terraforged:jungle_large",
"config": {},
"chance": 0.3
}
],
"default": {
"name": "terraforged:jungle_small",
"config": {}
}
}
},
"decorator": {
"name": "minecraft:count_extra_heightmap",
"config": {
"count": 3,
"extra_chance": 0.25,
"extra_count": 1
}
}
}
}
}

View File

@ -0,0 +1,77 @@
{
"biomes": [
"minecraft:jungle_hills",
"minecraft:bamboo_jungle_hills"
],
"match": [
[
"minecraft:fancy_tree"
]
],
"replace": {
"name": "minecraft:decorated",
"config": {
"feature": {
"name": "minecraft:random_selector",
"config": {
"features": [
{
"name": "terraforged:jungle_small",
"config": {},
"chance": 0.4
},
{
"name": "terraforged:jungle_large",
"config": {},
"chance": 0.2
},
{
"name": "terraforged:jungle_huge",
"config": {},
"chance": 0.05
},
{
"name": "minecraft:jungle_ground_bush",
"config": {
"trunk_provider": {
"type": "minecraft:simple_state_provider",
"state": {
"Name": "minecraft:jungle_log",
"Properties": {
"axis": "y"
}
}
},
"leaves_provider": {
"type": "minecraft:simple_state_provider",
"state": {
"Name": "minecraft:oak_leaves",
"Properties": {
"distance": "7",
"persistent": "false"
}
}
},
"decorators": [],
"base_height": 4
},
"chance": 0.3
}
],
"default": {
"name": "terraforged:jungle_small",
"config": {}
}
}
},
"decorator": {
"name": "minecraft:count_extra_heightmap",
"config": {
"count": 6,
"extra_chance": 0.25,
"extra_count": 1
}
}
}
}
}

View File

@ -2,8 +2,7 @@
"biomes": [ "biomes": [
"minecraft:taiga", "minecraft:taiga",
"minecraft:taiga_hills", "minecraft:taiga_hills",
"minecraft:taiga_mountains", "minecraft:taiga_mountains"
"minecraft:taiga_scrub"
], ],
"match": [ "match": [
[ [

View File

@ -2,10 +2,7 @@
"biomes": [ "biomes": [
"minecraft:snowy_taiga", "minecraft:snowy_taiga",
"minecraft:snowy_taiga_hills", "minecraft:snowy_taiga_hills",
"minecraft:snowy_taiga_mountains", "minecraft:snowy_taiga_mountains"
"minecraft:snowy_taiga_scrub",
"minecraft:snowy_tundra",
"minecraft:wooded_mountains"
], ],
"match": [ "match": [
[ [

View File

@ -0,0 +1,42 @@
{
"biomes": [
"minecraft:snowy_tundra",
"minecraft:wooded_mountains"
],
"match": [
[
"minecraft:normal_tree",
"minecraft:spruce_log",
"minecraft:spruce_leaves"
]
],
"replace": {
"name": "minecraft:decorated",
"config": {
"feature": {
"name": "minecraft:random_selector",
"config": {
"features": [
{
"name": "terraforged:pine",
"config": {},
"chance": 0.3
}
],
"default": {
"name": "terraforged:pine",
"config": {}
}
}
},
"decorator": {
"name": "minecraft:count_extra_heightmap",
"config": {
"count": 0,
"extra_chance": 0.02,
"extra_count": 1
}
}
}
}
}