biome surface blending
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-29 16:19:39 -05:00
parent 471df1c6b1
commit aa34ea4db6
12 changed files with 251 additions and 62 deletions

View File

@ -1173,6 +1173,9 @@ Allow variable collision bits for collidable entities
Autodisable terrain colliders Autodisable terrain colliders
Lower grass radius Lower grass radius
Work on diagnosing data cell misalignment with entities Work on diagnosing data cell misalignment with entities
Fix gridded data cell manager loops iterating incorrectly
Implement multi-biome sampling for surface heightmap
Nearest biome sampling for content generation
# TODO # TODO

View File

@ -270,6 +270,37 @@ public class ServerWorldData {
convertRealToChunkSpace(position.z) convertRealToChunkSpace(position.z)
); );
} }
/**
* Converts a world coordinate to a macro scale coordinate
* @param worldPos The world position
* @return The macro scale position
*/
public Vector3i convertWorldToMacroScale(Vector3i worldPos){
return new Vector3i(
worldPos.x / this.serverTerrainManager.getModel().getMacroDataScale(),
worldPos.y / this.serverTerrainManager.getModel().getMacroDataScale(),
worldPos.z / this.serverTerrainManager.getModel().getMacroDataScale()
);
}
/**
* Converts a world coordinate to a macro scale coordinate
* @param worldPos The world position
* @return The macro scale position
*/
public int convertWorldToMacroScale(int worldPos){
return worldPos / this.serverTerrainManager.getModel().getMacroDataScale();
}
/**
* Clamps the world position to the floored macro value in world pos
* @param worldPos The world position
* @return The floor macro value in world pos
*/
public int clampWorldToMacro(int worldPos){
return (worldPos / this.serverTerrainManager.getModel().getMacroDataScale()) * this.serverTerrainManager.getModel().getMacroDataScale();
}
/** /**
* Gets the terrain manager for this world * Gets the terrain manager for this world

View File

@ -55,7 +55,7 @@ public class ServerContentGenerator {
//generate foliage //generate foliage
BiomeData biome = null; BiomeData biome = null;
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null && realm.getServerWorldData().getServerTerrainManager().getModel() != null){ if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null && realm.getServerWorldData().getServerTerrainManager().getModel() != null){
biome = realm.getServerWorldData().getServerTerrainManager().getModel().getSurfaceBiome(worldPos.x, worldPos.z); biome = realm.getServerWorldData().getServerTerrainManager().getModel().getClosestSurfaceBiome(worldPos.x, worldPos.z);
} }
List<BiomeFoliageDescription> foliageDescriptions = biome.getSurfaceGenerationParams().getFoliageDescriptions(); List<BiomeFoliageDescription> foliageDescriptions = biome.getSurfaceGenerationParams().getFoliageDescriptions();
if(foliageDescriptions != null){ if(foliageDescriptions != null){

View File

@ -332,7 +332,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
//Add to cells that are in range //Add to cells that are in range
for(int x = newPosition.x - playerSimulationRadius + 1; x < newPosition.x + playerSimulationRadius; x++){ for(int x = newPosition.x - playerSimulationRadius + 1; x < newPosition.x + playerSimulationRadius; x++){
for(int y = newPosition.y - playerSimulationRadius + 1; y < newPosition.y + playerSimulationRadius; y++){ for(int y = newPosition.y - playerSimulationRadius + 1; y < newPosition.y + playerSimulationRadius; y++){
for(int z = newPosition.x - playerSimulationRadius + 1; z < newPosition.z + playerSimulationRadius; z++){ for(int z = newPosition.z - playerSimulationRadius + 1; z < newPosition.z + playerSimulationRadius; z++){
if(this.canCreateCell(x,y,z) && this.shouldContainPlayer(new Vector3i(x,y,z), newPosition, playerSimulationRadius)){ if(this.canCreateCell(x,y,z) && this.shouldContainPlayer(new Vector3i(x,y,z), newPosition, playerSimulationRadius)){
Vector3i targetPos = new Vector3i(x,y,z); Vector3i targetPos = new Vector3i(x,y,z);
if(groundDataCells.get(this.getServerDataCellKey(targetPos)) != null){ if(groundDataCells.get(this.getServerDataCellKey(targetPos)) != null){

View File

@ -120,7 +120,7 @@ public class JSChunkGenerator implements ChunkGenerator {
try { try {
//biome of the current chunk //biome of the current chunk
BiomeData surfaceBiome = this.terrainModel.getSurfaceBiome(worldX, worldZ); BiomeData surfaceBiome = this.terrainModel.getClosestSurfaceBiome(worldX, worldZ);
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag()); HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
@ -218,7 +218,7 @@ public class JSChunkGenerator implements ChunkGenerator {
@Override @Override
public double getElevation(int worldX, int worldZ, int chunkX, int chunkZ){ public double getElevation(int worldX, int worldZ, int chunkX, int chunkZ){
BiomeData surfaceBiome = this.terrainModel.getSurfaceBiome(worldX, worldZ); BiomeData surfaceBiome = this.terrainModel.getClosestSurfaceBiome(worldX, worldZ);
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag()); HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());

View File

@ -134,40 +134,21 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
int[][][] values = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; int[][][] values = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
try { try {
//biome of the current chunk
BiomeData surfaceBiome = this.terrainModel.getSurfaceBiome(worldX, worldZ);
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
heightmapGen = this.tagHeightmapMap.get("hills");
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
//stride value //stride value
int strideValue = (int)Math.pow(2,stride); int strideValue = (int)Math.pow(2,stride);
//presolve heightfield //presolve heightfield
float[][] heightfield = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; double[][] heightfield = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ BiomeData[][] surfaceBiomeMap = new BiomeData[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ this.populateElevation(heightfield,surfaceBiomeMap,worldX,worldZ,strideValue);
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;
heightfield[x][z] = heightmapGen.getHeight(
this.terrainModel.getSeed(),
this.serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX),
this.serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ)
);
}
}
float[][] gradientField = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; 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++){ for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){
float deltaX = 0; double deltaX = 0;
float deltaZ = 0; double deltaZ = 0;
if(x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1){ if(x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1){
deltaX = Math.abs(heightfield[x][z] - heightfield[x+1][z]); deltaX = Math.abs(heightfield[x][z] - heightfield[x+1][z]);
} else { } else {
@ -199,8 +180,9 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ); double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ);
float surfaceHeight = heightfield[x][z]; double surfaceHeight = heightfield[x][z];
float gradient = gradientField[x][z]; double gradient = gradientField[x][z];
BiomeData surfaceBiome = surfaceBiomeMap[x][z];
for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){ for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){
int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
@ -249,21 +231,158 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
return rVal; return rVal;
} }
/**
* Populates the heightfield
* @param heightfield The heightfield to populate
* @param surfaceBiomeMap The surface biome map
* @param worldX The world x position
* @param worldZ The world z position
* @param strideValue The stride value
*/
private void populateElevation(double[][] heightfield, BiomeData[][] surfaceBiomeMap, int worldX, int worldZ, int strideValue){
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;
heightfield[x][z] = this.getMultisampleElevation(finalWorldX, finalWorldZ, finalChunkX, finalChunkZ);
//calculate real pos
double realX = serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX);
double realZ = serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ);
//clamped macro pos
int macroDataScale = terrainModel.getMacroDataScale();
double macroWorldPosX = serverWorldData.convertWorldToReal(serverWorldData.clampWorldToMacro(finalWorldX));
double macroWorldPosZ = serverWorldData.convertWorldToReal(serverWorldData.clampWorldToMacro(finalWorldZ));
double macroWidth = this.terrainModel.getMacroWidthInRealTerms();
double percent1 = (realX - macroWorldPosX) / macroWidth;
double percent2 = (realZ - macroWorldPosZ) / macroWidth;
//solve dominant surface biome
if(percent1 > 0.5){
if(percent2 > 0.5){
surfaceBiomeMap[x][z] = this.terrainModel.getMacroData(finalWorldX / macroDataScale + 1, finalWorldZ / macroDataScale + 1);
} else {
surfaceBiomeMap[x][z] = this.terrainModel.getMacroData(finalWorldX / macroDataScale + 1, finalWorldZ / macroDataScale);
}
} else {
if(percent2 > 0.5){
surfaceBiomeMap[x][z] = this.terrainModel.getMacroData(finalWorldX / macroDataScale, finalWorldZ / macroDataScale + 1);
} else {
surfaceBiomeMap[x][z] = this.terrainModel.getMacroData(finalWorldX / macroDataScale, finalWorldZ / macroDataScale);
}
}
}
}
}
/**
* Gets the elevation of a given position by sampling all four surrounding biome generators
* @param finalWorldX The world x coordinate
* @param finalWorldZ The world z coordinate
* @param finalChunkX The chunk x coordinate
* @param finalChunkZ The chunk z coordinate
* @return The elevation of the world at that position
*/
private double getMultisampleElevation(int finalWorldX, int finalWorldZ, int finalChunkX, int finalChunkZ){
double rVal = 0;
//biome of the current chunk
double weight = 0;
BiomeData surfaceBiome = null;
BiomeSurfaceGenerationParams surfaceParams = null;
HeightmapGenerator heightmapGen = null;
//calculate real pos
double realX = serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX);
double realZ = serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ);
//clamped macro pos
int macroDataScale = terrainModel.getMacroDataScale();
double macroWorldPosX = serverWorldData.convertWorldToReal(serverWorldData.clampWorldToMacro(finalWorldX));
double macroWorldPosZ = serverWorldData.convertWorldToReal(serverWorldData.clampWorldToMacro(finalWorldZ));
double macroWidth = this.terrainModel.getMacroWidthInRealTerms();
double percent1 = (realX - macroWorldPosX) / macroWidth;
double percent2 = (realZ - macroWorldPosZ) / macroWidth;
//sample 1
{
weight = (1.0 - percent1) * (1.0 - percent2);
surfaceBiome = this.terrainModel.getMacroData(finalWorldX / macroDataScale, finalWorldZ / macroDataScale);
surfaceParams = surfaceBiome.getSurfaceGenerationParams();
heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
rVal = rVal + heightmapGen.getHeight(
this.terrainModel.getSeed(),
realX,
realZ
) * weight;
}
//sample 2
{
weight = percent1 * (1.0 - percent2);
surfaceBiome = this.terrainModel.getMacroData(finalWorldX / macroDataScale + 1, finalWorldZ / macroDataScale);
surfaceParams = surfaceBiome.getSurfaceGenerationParams();
heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
rVal = rVal + heightmapGen.getHeight(
this.terrainModel.getSeed(),
realX,
realZ
) * weight;
}
//sample 3
{
weight = (1.0 - percent1) * percent2;
surfaceBiome = this.terrainModel.getMacroData(finalWorldX / macroDataScale, finalWorldZ / macroDataScale + 1);
surfaceParams = surfaceBiome.getSurfaceGenerationParams();
heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
rVal = rVal + heightmapGen.getHeight(
this.terrainModel.getSeed(),
realX,
realZ
) * weight;
}
//sample 4
{
weight = percent1 * percent2;
surfaceBiome = this.terrainModel.getMacroData(finalWorldX / macroDataScale + 1, finalWorldZ / macroDataScale + 1);
surfaceParams = surfaceBiome.getSurfaceGenerationParams();
heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
rVal = rVal+ heightmapGen.getHeight(
this.terrainModel.getSeed(),
realX,
realZ
) * weight;
}
return rVal;
}
@Override @Override
public double getElevation(int worldX, int worldZ, int chunkX, int chunkZ){ public double getElevation(int worldX, int worldZ, int chunkX, int chunkZ){
BiomeData surfaceBiome = this.terrainModel.getSurfaceBiome(worldX, worldZ); return this.getMultisampleElevation(worldX,worldZ,chunkX,chunkZ);
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
}
double rVal = heightmapGen.getHeight(
this.terrainModel.getSeed(),
this.serverWorldData.convertVoxelToRealSpace(chunkX, worldX),
this.serverWorldData.convertVoxelToRealSpace(chunkZ, worldZ)
);
return rVal;
} }
@Override @Override

View File

@ -68,7 +68,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
int stride, float surfaceHeight, float surfaceGradient, int stride, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
) { ) {
@ -122,7 +122,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
voxel.weight = (float)surfacePercent * 2 - 1; voxel.weight = (float)surfacePercent * 2 - 1;
@ -139,7 +139,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
if(realY < surfaceHeight - 5){ if(realY < surfaceHeight - 5){
@ -161,7 +161,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
//default voxel value //default voxel value

View File

@ -28,7 +28,7 @@ public class HillsVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
int stride, int stride,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
){ ){
@ -81,7 +81,7 @@ public class HillsVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
voxel.weight = (float)surfacePercent * 2 - 1; voxel.weight = (float)surfacePercent * 2 - 1;
@ -98,7 +98,7 @@ public class HillsVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
if(realY < surfaceHeight - 5){ if(realY < surfaceHeight - 5){
@ -120,7 +120,7 @@ public class HillsVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, double surfaceHeight,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
voxel.weight = -1; voxel.weight = -1;

View File

@ -35,7 +35,7 @@ public class MountainVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
int stride, int stride,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
){ ){
@ -88,7 +88,7 @@ public class MountainVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
voxel.weight = (float)surfacePercent * 2 - 1; voxel.weight = (float)surfacePercent * 2 - 1;
@ -112,7 +112,7 @@ public class MountainVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
if(realY < surfaceHeight - 5){ if(realY < surfaceHeight - 5){
@ -134,7 +134,7 @@ public class MountainVoxelGen implements VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
double surfacePercent, double surfacePercent,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome BiomeData surfaceBiome
){ ){
voxel.weight = -1; voxel.weight = -1;

View File

@ -46,7 +46,7 @@ public class NoiseVoxelGen implements VoxelGenerator {
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
int stride, float surfaceHeight, float surfaceGradient, int stride, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome, GenerationContext generationContext BiomeData surfaceBiome, GenerationContext generationContext
) { ) {
double strideMultiplier = Math.pow(2,stride); double strideMultiplier = Math.pow(2,stride);

View File

@ -39,7 +39,7 @@ public interface VoxelGenerator {
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ, double realX, double realY, double realZ,
int stride, int stride,
float surfaceHeight, float surfaceGradient, double surfaceHeight, double surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
); );

View File

@ -3,6 +3,7 @@ package electrosphere.server.terrain.models;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.game.data.biome.BiomeData; import electrosphere.game.data.biome.BiomeData;
import electrosphere.server.terrain.generation.TestGenerationChunkGenerator; import electrosphere.server.terrain.generation.TestGenerationChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.util.annotation.Exclude; import electrosphere.util.annotation.Exclude;
/** /**
@ -129,6 +130,7 @@ public class TerrainModel {
rVal.biome[x][z] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX; rVal.biome[x][z] = TestGenerationChunkGenerator.DEFAULT_BIOME_INDEX;
} }
} }
rVal.biome[1][0] = 0;
return rVal; return rVal;
} }
@ -463,9 +465,26 @@ public class TerrainModel {
* @param worldZ The world Z * @param worldZ The world Z
* @return The biome * @return The biome
*/ */
public BiomeData getSurfaceBiome(int worldX, int worldZ){ public BiomeData getClosestSurfaceBiome(int worldX, int worldZ){
int macroX = worldX / macroDataScale; //essentially, select the closest macro data point, not just floor
int macroZ = worldZ / macroDataScale; int offsetX = worldX % macroDataScale > (macroDataScale / 2.0) ? 1 : 0;
int offsetZ = worldZ % macroDataScale > (macroDataScale / 2.0) ? 1 : 0;
int macroX = worldX / macroDataScale + offsetX;
int macroZ = worldZ / macroDataScale + offsetZ;
int surfaceBiomeIndex = this.biome[macroX][macroZ];
BiomeData biome = Globals.gameConfigCurrent.getBiomeMap().getBiomeByIndex(surfaceBiomeIndex);
return biome;
}
/**
* Gets the surface biome for a given macro position
* @param worldX The macro X
* @param worldZ The macro Z
* @return The biome
*/
public BiomeData getMacroData(int macroX, int macroZ){
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;
@ -497,5 +516,22 @@ public class TerrainModel {
public void setMacroDataScale(int scale){ public void setMacroDataScale(int scale){
this.macroDataScale = scale; this.macroDataScale = scale;
} }
/**
* Gets the scale of the macro data
* @return The scale
*/
public int getMacroDataScale(){
return this.macroDataScale;
}
/**
* Gets the width of the macro data in real terms
* @return The width of the macro data in real terms
*/
public double getMacroWidthInRealTerms(){
return this.macroDataScale * ServerTerrainChunk.CHUNK_DIMENSION;
}
} }