true terrain regen, gen algo tweaks
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-10-29 14:58:06 -04:00
parent 987165649f
commit d6c476b4a3
13 changed files with 214 additions and 22 deletions

View File

@ -22,7 +22,37 @@
] ]
} }
], ],
"heightGenerator": "plains" "surfaceGenerationParams": {
"surfaceGenTag": "plains",
"heightOffset": 10
}
},
{
"id": "hills",
"displayName": "Hills",
"isAerial": false,
"isSurface": true,
"isSubterranean": false,
"regions": [
{
"frequency": 1.0,
"baseFloorVoxel": 1,
"floorVariants": [
{
"voxelId": 2,
"frequency": 1.0,
"dispersion": 1.0,
"priority": 1.0
}
],
"foliageDescription": [
]
}
],
"surfaceGenerationParams": {
"surfaceGenTag": "hills",
"heightOffset": 10
}
}, },
{ {
"id": "sky", "id": "sky",
@ -38,7 +68,10 @@
"foliageDescription": [] "foliageDescription": []
} }
], ],
"heightGenerator": "empty" "surfaceGenerationParams": {
"surfaceGenTag": "empty",
"heightOffset": 0
}
} }
], ],
"files": [ "files": [

View File

@ -46,6 +46,15 @@ public class ClientTerrainCache {
cacheMap.remove(currentChunk); cacheMap.remove(currentChunk);
} }
} }
/**
* Evicts all chunks from the cache
*/
public void evictAll(){
this.cacheList.clear();
this.cacheMap.clear();
this.chunkPositionMap.clear();
}
/** /**

View File

@ -488,7 +488,7 @@ public class DrawCellManager {
requested.clear(); requested.clear();
drawable.clear(); drawable.clear();
undrawable.clear(); undrawable.clear();
updateable.clear(); updateable.clear();
} }

View File

@ -100,6 +100,13 @@ public class ClientTerrainManager {
messageQueue.add(message); messageQueue.add(message);
} }
} }
/**
* Evicts all cached terrain
*/
public void evictAll(){
this.terrainCache.evictAll();
}
/** /**
* Attaches a terrain message to the queue of messages that this manager needs to process * Attaches a terrain message to the queue of messages that this manager needs to process

View File

@ -4,7 +4,10 @@ import electrosphere.engine.Globals;
import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.datacell.GriddedDataCellManager; import electrosphere.server.datacell.GriddedDataCellManager;
import electrosphere.server.terrain.generation.TestGenerationChunkGenerator;
import electrosphere.server.terrain.models.TerrainModel;
import imgui.ImGui; import imgui.ImGui;
import imgui.type.ImInt;
/** /**
* Menu for altering parameters of the test terrain generator * Menu for altering parameters of the test terrain generator
@ -26,17 +29,56 @@ public class ImGuiTestGen {
*/ */
protected static void createTestGenDebugWindow(){ protected static void createTestGenDebugWindow(){
testGenWindow = new ImGuiWindow("Test Terrain Generation"); testGenWindow = new ImGuiWindow("Test Terrain Generation");
int[] macroDataScaleInput = new int[1];
int[] seedInput = new int[1];
ImInt biome00 = new ImInt(0);
ImInt biome10 = new ImInt(0);
ImInt biome01 = new ImInt(0);
ImInt biome11 = new ImInt(0);
testGenWindow.setCallback(new ImGuiWindowCallback() { testGenWindow.setCallback(new ImGuiWindowCallback() {
@Override @Override
public void exec() { public void exec() {
//ui framework text //ui framework text
ImGui.text("Test Terrain Generation"); ImGui.text("Test Terrain Generation");
TerrainModel terrainModel = Globals.realmManager.first().getServerWorldData().getServerTerrainManager().getModel();
//regenerate the test area //regenerate the test area
if(ImGui.button("Regenerate")){ if(ImGui.button("Regenerate")){
GriddedDataCellManager gridManager = (GriddedDataCellManager)Globals.realmManager.first().getDataCellManager(); GriddedDataCellManager gridManager = (GriddedDataCellManager)Globals.realmManager.first().getDataCellManager();
gridManager.evictAll(); gridManager.evictAll();
Globals.drawCellManager.evictAll(); Globals.drawCellManager.evictAll();
Globals.clientTerrainManager.evictAll();
}
//set macro data scale in terrain model
if(ImGui.sliderInt("Macro Data Scale", macroDataScaleInput, TestGenerationChunkGenerator.GENERATOR_REALM_SIZE / terrainModel.getBiome().length, TerrainModel.DEFAULT_MACRO_DATA_SCALE)){
terrainModel.setMacroDataScale(macroDataScaleInput[0]);
}
//set macro data scale in terrain model
if(ImGui.sliderInt("Seed", seedInput, 0, 100)){
terrainModel.setSeed(seedInput[0]);
}
//sets the (surface) biome[0][0] value
if(ImGui.inputInt("biome[0][0]", biome00)){
terrainModel.getBiome()[0][0] = biome00.shortValue();
}
//sets the (surface) biome[1][0] value
if(ImGui.inputInt("biome[1][0]", biome10)){
terrainModel.getBiome()[1][0] = biome10.shortValue();
}
//sets the (surface) biome[0][1] value
if(ImGui.inputInt("biome[0][1]", biome01)){
terrainModel.getBiome()[0][1] = biome01.shortValue();
}
//sets the (surface) biome[1][1] value
if(ImGui.inputInt("biome[1][1]", biome11)){
terrainModel.getBiome()[1][1] = biome11.shortValue();
} }
} }

View File

@ -38,9 +38,9 @@ public class BiomeData {
Boolean isSubterranean; Boolean isSubterranean;
/** /**
* Tag for the heightmap generator to source from * The surface generation params
*/ */
String heightGenerator; BiomeSurfaceGenerationParams surfaceGenerationParams;
@ -93,11 +93,11 @@ public class BiomeData {
} }
/** /**
* Gets the tag for the heightmap generator to source from * Gets the surface generation params
* @return The tag for the heightmap generator to source from * @return The surface generation params
*/ */
public String getHeightGenerator(){ public BiomeSurfaceGenerationParams getSurfaceGenerationParams(){
return heightGenerator; return surfaceGenerationParams;
} }
} }

View File

@ -0,0 +1,36 @@
package electrosphere.game.data.biome;
/**
* Params for the surface generation algorithm
*/
public class BiomeSurfaceGenerationParams {
/**
* The tag for the generation algorithm for generating the surface
*/
String surfaceGenTag;
/**
* The offset from baseline for height generation with this biome
*/
Float heightOffset;
/**
* Gets the tag for the generation algorithm for generating the surface
* @return The tag for the generation algorithm for generating the surface
*/
public String getSurfaceGenTag() {
return surfaceGenTag;
}
/**
* Gets the offset from baseline for height generation with this biome
* @return The offset from baseline for height generation with this biome
*/
public Float getHeightOffset() {
return heightOffset;
}
}

View File

@ -343,6 +343,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
ClientEntityUtils.destroyEntity(entity); ClientEntityUtils.destroyEntity(entity);
} }
} }
this.serverTerrainManager.evictAll();
toCleanQueue.clear(); toCleanQueue.clear();
} }

View File

@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import electrosphere.game.data.biome.BiomeData; import electrosphere.game.data.biome.BiomeData;
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
import electrosphere.game.server.world.ServerWorldData; import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.terrain.generation.heightmap.EmptySkyGen; import electrosphere.server.terrain.generation.heightmap.EmptySkyGen;
import electrosphere.server.terrain.generation.heightmap.HeightmapGenerator; import electrosphere.server.terrain.generation.heightmap.HeightmapGenerator;
@ -22,7 +23,12 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
/** /**
* The size of the realm for testing generation * The size of the realm for testing generation
*/ */
public static final int GENERATOR_REALM_SIZE = 10; public static final int GENERATOR_REALM_SIZE = 32;
/**
* The default biome index
*/
public static final int DEFAULT_BIOME_INDEX = 1;
/** /**
* The terreain model for the generator * The terreain model for the generator
@ -47,7 +53,6 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
registerGenerator(new EmptySkyGen()); registerGenerator(new EmptySkyGen());
registerGenerator(new HillsGen()); registerGenerator(new HillsGen());
registerGenerator(new PlainsGen()); registerGenerator(new PlainsGen());
} }
/** /**
@ -130,9 +135,10 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
TerrainModel terrainModel, TerrainModel terrainModel,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
HeightmapGenerator heightmapGen = this.tagGeneratorMap.get(surfaceBiome.getHeightGenerator()); BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagGeneratorMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){ if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceBiome.getHeightGenerator()); throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
} }
double realX = this.serverWorldData.convertVoxelToRealSpace(chunkX,worldX); double realX = this.serverWorldData.convertVoxelToRealSpace(chunkX,worldX);
@ -165,9 +171,10 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
TerrainModel terrainModel, TerrainModel terrainModel,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
HeightmapGenerator heightmapGen = this.tagGeneratorMap.get(surfaceBiome.getHeightGenerator()); BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagGeneratorMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){ if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceBiome.getHeightGenerator()); throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
} }
double realX = this.serverWorldData.convertVoxelToRealSpace(chunkX,worldX); double realX = this.serverWorldData.convertVoxelToRealSpace(chunkX,worldX);

View File

@ -12,6 +12,16 @@ public class HillsGen implements HeightmapGenerator {
*/ */
static final float HEIGHT_OFFSET = 10; static final float HEIGHT_OFFSET = 10;
/**
* Scales the input positions
*/
static final float POSITION_SCALE = 0.005f;
/**
* Scales the output height
*/
static final float VERTICAL_SCALE = 200.0f;
/** /**
* The different scales of noise to sample from * The different scales of noise to sample from
*/ */
@ -38,7 +48,9 @@ public class HillsGen implements HeightmapGenerator {
* @return The height * @return The height
*/ */
public float getHeight(long SEED, double x, double y){ public float getHeight(long SEED, double x, double y){
return gradientHeight(SEED, x, y); double scaledX = x * POSITION_SCALE;
double scaledY = y * POSITION_SCALE;
return gradientHeight(SEED, scaledX, scaledY) * VERTICAL_SCALE + HEIGHT_OFFSET;
} }
@ -71,7 +83,6 @@ public class HillsGen implements HeightmapGenerator {
//add to height //add to height
rVal = rVal + (float)(OpenSimplex2S.noise2_ImproveX(SEED, x * GRAD_NOISE[n][0], y * GRAD_NOISE[n][0]) * GRAD_NOISE[n][1]) * influence; rVal = rVal + (float)(OpenSimplex2S.noise2_ImproveX(SEED, x * GRAD_NOISE[n][0], y * GRAD_NOISE[n][0]) * GRAD_NOISE[n][1]) * influence;
} }
rVal = rVal + HEIGHT_OFFSET;
return rVal; return rVal;
} }

View File

@ -35,7 +35,7 @@ public class PlainsGen implements HeightmapGenerator {
* @return The height * @return The height
*/ */
public float getHeight(long SEED, double x, double y){ public float getHeight(long SEED, double x, double y){
return sampleAllNoise(SEED, x, y); return sampleAllNoise(SEED, x, y) + HEIGHT_OFFSET;
} }
@ -53,7 +53,6 @@ public class PlainsGen implements HeightmapGenerator {
for(int n = 0; n < NOISE_SCALES.length; n++){ for(int n = 0; n < NOISE_SCALES.length; n++){
rVal = rVal + (float)(OpenSimplex2S.noise2_ImproveX(SEED, scaledX * NOISE_SCALES[n][0], scaledY * NOISE_SCALES[n][0]) * NOISE_SCALES[n][1]); rVal = rVal + (float)(OpenSimplex2S.noise2_ImproveX(SEED, scaledX * NOISE_SCALES[n][0], scaledY * NOISE_SCALES[n][0]) * NOISE_SCALES[n][1]);
} }
rVal = rVal + HEIGHT_OFFSET;
return rVal; return rVal;
} }

View File

@ -161,6 +161,14 @@ public class ServerTerrainManager {
this.model = TerrainModel.generateTestModel(); this.model = TerrainModel.generateTestModel();
chunkGen.setModel(model); chunkGen.setModel(model);
} }
/**
* Evicts all cached terrain
*/
public void evictAll(){
this.chunkCache.clear();
this.chunkCacheContents.clear();
}
public float[][] getTerrainAtChunk(int x, int y){ public float[][] getTerrainAtChunk(int x, int y){
return model.getElevationForChunk(x, y); return model.getElevationForChunk(x, y);

View File

@ -17,7 +17,7 @@ public class TerrainModel {
/** /**
* The scale of the macro data * The scale of the macro data
*/ */
static final int MACRO_DATA_SCALE = 32; public static final int DEFAULT_MACRO_DATA_SCALE = 32;
/** /**
@ -66,6 +66,14 @@ public class TerrainModel {
* The seed of the terrain * The seed of the terrain
*/ */
long seed = 0; long seed = 0;
/**
* The macro data scale
* <p>
* !!NOTE!!: macroDataScale * biome.length must be greater than or equal to the number of chunks that are generateable
* </p>
*/
int macroDataScale = DEFAULT_MACRO_DATA_SCALE;
/** /**
* Private constructor * Private constructor
@ -120,6 +128,10 @@ public class TerrainModel {
rVal.discreteArrayDimension = TestGenerationChunkGenerator.GENERATOR_REALM_SIZE; rVal.discreteArrayDimension = TestGenerationChunkGenerator.GENERATOR_REALM_SIZE;
rVal.dynamicInterpolationRatio = 1; rVal.dynamicInterpolationRatio = 1;
rVal.biome = new short[2][2]; rVal.biome = new short[2][2];
rVal.biome[0][0] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX;
rVal.biome[1][0] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX;
rVal.biome[0][1] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX;
rVal.biome[1][1] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX;
return rVal; return rVal;
} }
@ -130,6 +142,14 @@ public class TerrainModel {
public float[][] getElevation(){ public float[][] getElevation(){
return elevation; return elevation;
} }
/**
* Gets the macro biome data for the terrain model
* @return The macro biome data
*/
public short[][] getBiome(){
return biome;
}
/** /**
* Gets the interpolation random dampener * Gets the interpolation random dampener
@ -497,8 +517,8 @@ public class TerrainModel {
* @return The biome * @return The biome
*/ */
public BiomeData getSurfaceBiome(int worldX, int worldY, int worldZ){ public BiomeData getSurfaceBiome(int worldX, int worldY, int worldZ){
int macroX = worldX / MACRO_DATA_SCALE; int macroX = worldX / macroDataScale;
int macroZ = worldZ / MACRO_DATA_SCALE; int macroZ = worldZ / macroDataScale;
int surfaceBiomeIndex = this.biome[macroX][macroZ]; int surfaceBiomeIndex = this.biome[macroX][macroZ];
BiomeData biome = Globals.gameConfigCurrent.getBiomeMap().getBiomeByIndex(surfaceBiomeIndex); BiomeData biome = Globals.gameConfigCurrent.getBiomeMap().getBiomeByIndex(surfaceBiomeIndex);
return biome; return biome;
@ -511,5 +531,24 @@ public class TerrainModel {
public long getSeed(){ public long getSeed(){
return seed; return seed;
} }
/**
* Sets the seed of the terrain model
* @param seed The seed
*/
public void setSeed(long seed){
this.seed = seed;
}
/**
* Sets the scale of the macro data
* <p>
* !!NOTE!!: macroDataScale * biome.length must be greater than or equal to the number of chunks that are generateable
* </p>
* @param scale The scale
*/
public void setMacroDataScale(int scale){
this.macroDataScale = scale;
}
} }