From 44c6a667e9cd6586e7a9be13a615b240ebeb0834 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 2 Apr 2025 14:09:22 -0400 Subject: [PATCH] surface selection work --- docs/src/progress/renderertodo.md | 1 + .../TestGenerationChunkGenerator.java | 44 ++++++++++++++++++- .../voxelphase/AnimeMountainsGen.java | 2 +- .../generation/voxelphase/HillsVoxelGen.java | 2 +- .../voxelphase/MountainVoxelGen.java | 2 +- .../generation/voxelphase/NoiseVoxelGen.java | 6 +-- .../generation/voxelphase/VoxelGenerator.java | 3 +- 7 files changed, 51 insertions(+), 9 deletions(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 1b744e2d..4e3b79ca 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1415,6 +1415,7 @@ Fix rock2 texture biome floor elements controlling noise generator's voxel selection Plains (rock) biome Lore message resend from client on failure +More surface selection work diff --git a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java index 97545591..fd05a38b 100644 --- a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java @@ -26,6 +26,8 @@ import electrosphere.server.terrain.generation.voxelphase.NoiseVoxelGen; import electrosphere.server.terrain.generation.voxelphase.VoxelGenerator; import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.models.TerrainModel; +import electrosphere.util.noise.OpenSimplex2S; +import io.github.studiorailgun.MathUtils; /** * A generator for testing terrain generation @@ -142,7 +144,10 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { double[][] heightfield = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; BiomeData[][] surfaceBiomeMap = new BiomeData[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; this.populateElevation(heightfield,surfaceBiomeMap,worldX,worldZ,strideValue); - + + //presolve surface selection noise + double[][] surfaceSelectionField = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; + this.surfaceSelectionNoise(surfaceSelectionField,worldX,worldZ,strideValue,this.terrainModel.getSeed()); double[][] gradientField = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ @@ -182,6 +187,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ); double surfaceHeight = heightfield[x][z]; double gradient = gradientField[x][z]; + double surfaceSelection = surfaceSelectionField[x][z]; BiomeData surfaceBiome = surfaceBiomeMap[x][z]; BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); @@ -196,7 +202,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { finalChunkX, finalChunkY, finalChunkZ, realX, realY, realZ, stride, - surfaceHeight, gradient, + surfaceHeight, gradient, surfaceSelection, surfaceBiome, surfaceParams, generationContext ); @@ -284,6 +290,40 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { } } + /** + * Populates the surface selection noise field + * @param surfaceNoiseField The surface selection noise field + * @param worldX The world x position + * @param worldZ The world z position + * @param strideValue The stride value + */ + private void surfaceSelectionNoise(double[][] surfaceNoiseField, int worldX, int worldZ, int strideValue, long seed){ + for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ + for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ + int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); + int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); + int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; + int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; + + if(finalWorldX > this.serverWorldData.getWorldSizeDiscrete() || finalWorldZ > this.serverWorldData.getWorldSizeDiscrete()){ + throw new Error("Invalid world dim! " + finalWorldX + " " + finalWorldZ); + } + + double realX = serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX); + double realZ = serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ); + + double warpX = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 0); + double warpZ = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 1); + double valueRaw = OpenSimplex2S.noise2(seed, realX + warpX, realZ + warpZ); + double fixed = (MathUtils.clamp(valueRaw, -1, 1) + 1) / 2.0; + if(fixed < 0){ + throw new Error("Failed to clamp value properly! " + valueRaw + " " + fixed); + } + surfaceNoiseField[x][z] = fixed; + } + } + } + /** * Gets the elevation of a given position by sampling all four surrounding biome generators * @param finalWorldX The world x coordinate diff --git a/src/main/java/electrosphere/server/terrain/generation/voxelphase/AnimeMountainsGen.java b/src/main/java/electrosphere/server/terrain/generation/voxelphase/AnimeMountainsGen.java index 086fa929..568de91f 100644 --- a/src/main/java/electrosphere/server/terrain/generation/voxelphase/AnimeMountainsGen.java +++ b/src/main/java/electrosphere/server/terrain/generation/voxelphase/AnimeMountainsGen.java @@ -79,7 +79,7 @@ public class AnimeMountainsGen implements VoxelGenerator { int worldX, int worldY, int worldZ, int chunkX, int chunkY, int chunkZ, double realX, double realY, double realZ, - int stride, double surfaceHeight, double surfaceGradient, + int stride, double surfaceHeight, double surfaceGradient, double surfaceSelectionNoise, BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams, GenerationContext generationContext ) { diff --git a/src/main/java/electrosphere/server/terrain/generation/voxelphase/HillsVoxelGen.java b/src/main/java/electrosphere/server/terrain/generation/voxelphase/HillsVoxelGen.java index d96ce779..6186ba56 100644 --- a/src/main/java/electrosphere/server/terrain/generation/voxelphase/HillsVoxelGen.java +++ b/src/main/java/electrosphere/server/terrain/generation/voxelphase/HillsVoxelGen.java @@ -39,7 +39,7 @@ public class HillsVoxelGen implements VoxelGenerator { int chunkX, int chunkY, int chunkZ, double realX, double realY, double realZ, int stride, - double surfaceHeight, double surfaceGradient, + double surfaceHeight, double surfaceGradient, double surfaceSelectionNoise, BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams, GenerationContext generationContext ){ diff --git a/src/main/java/electrosphere/server/terrain/generation/voxelphase/MountainVoxelGen.java b/src/main/java/electrosphere/server/terrain/generation/voxelphase/MountainVoxelGen.java index a7052267..e15a4188 100644 --- a/src/main/java/electrosphere/server/terrain/generation/voxelphase/MountainVoxelGen.java +++ b/src/main/java/electrosphere/server/terrain/generation/voxelphase/MountainVoxelGen.java @@ -45,7 +45,7 @@ public class MountainVoxelGen implements VoxelGenerator { int chunkX, int chunkY, int chunkZ, double realX, double realY, double realZ, int stride, - double surfaceHeight, double surfaceGradient, + double surfaceHeight, double surfaceGradient, double surfaceSelectionNoise, BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams, GenerationContext generationContext ){ diff --git a/src/main/java/electrosphere/server/terrain/generation/voxelphase/NoiseVoxelGen.java b/src/main/java/electrosphere/server/terrain/generation/voxelphase/NoiseVoxelGen.java index 25cfdffe..2d9de93a 100644 --- a/src/main/java/electrosphere/server/terrain/generation/voxelphase/NoiseVoxelGen.java +++ b/src/main/java/electrosphere/server/terrain/generation/voxelphase/NoiseVoxelGen.java @@ -63,7 +63,7 @@ public class NoiseVoxelGen implements VoxelGenerator { int worldX, int worldY, int worldZ, int chunkX, int chunkY, int chunkZ, double realX, double realY, double realZ, - int stride, double surfaceHeight, double surfaceGradient, + int stride, double surfaceHeight, double surfaceGradient, double surfaceSelectionNoise, BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams, GenerationContext generationContext ) { @@ -94,13 +94,13 @@ public class NoiseVoxelGen implements VoxelGenerator { voxel.weight = -1.0f; voxel.type = 0; } else if(heightDiff < -strideMultiplier){ - BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceGradient); + BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceSelectionNoise); //generate full-size surface-type voxel double finalHeight = sample; voxel.weight = (float)finalHeight; voxel.type = floorEl.getVoxelId(); } else { - BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceGradient); + BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceSelectionNoise); //surface double surfacePercent = -heightDiff / strideMultiplier; if(surfacePercent > 1.0 || surfacePercent < 0){ diff --git a/src/main/java/electrosphere/server/terrain/generation/voxelphase/VoxelGenerator.java b/src/main/java/electrosphere/server/terrain/generation/voxelphase/VoxelGenerator.java index 9547da59..758c7c26 100644 --- a/src/main/java/electrosphere/server/terrain/generation/voxelphase/VoxelGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/voxelphase/VoxelGenerator.java @@ -37,6 +37,7 @@ public interface VoxelGenerator { * @param stride The stride of the data * @param surfaceHeight The height of the surface at x,z * @param surfaceGradient The rate of change in the surface at this point + * @param surfaceSelectionNoise The noise value to select surface variants * @param surfaceBiome The surface biome of the chunk * @param surfaceGenPArams Extra parameters for generating surface voxel values * @param generationContext The generation context @@ -47,7 +48,7 @@ public interface VoxelGenerator { int chunkX, int chunkY, int chunkZ, double realX, double realY, double realZ, int stride, - double surfaceHeight, double surfaceGradient, + double surfaceHeight, double surfaceGradient, double surfaceSelectionNoise, BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceGenParams, GenerationContext generationContext );