macro object injection
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-18 18:16:12 -04:00
parent 82bf65d4a2
commit 0321a9338b
10 changed files with 114 additions and 16 deletions

View File

@ -1879,6 +1879,7 @@ Fix character position not saving on creating a player's character for the first
Server utility to move entities scans to see if it needs to create macro data if moving a player's entity Server utility to move entities scans to see if it needs to create macro data if moving a player's entity
Road macro data generation Road macro data generation
Macro data is injected into voxel chunk generators Macro data is injected into voxel chunk generators
Close macro objects injected into voxel chunk gen instead of all data

View File

@ -14,6 +14,7 @@ import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.race.Race; import electrosphere.server.macro.race.Race;
import electrosphere.server.macro.race.RaceMap; import electrosphere.server.macro.race.RaceMap;
import electrosphere.server.macro.spatial.MacroAreaObject; import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.server.macro.town.Town; import electrosphere.server.macro.town.Town;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
@ -292,6 +293,16 @@ public class MacroData {
public void addStructure(VirtualStructure structure){ public void addStructure(VirtualStructure structure){
structures.add(structure); structures.add(structure);
} }
/**
* Gets the nearby objects
* @param position The position to search near
* @return The list of objects
*/
public List<MacroObject> getNearbyObjects(Vector3d position){
List<MacroObject> rVal = new LinkedList<MacroObject>();
return rVal;
}
/** /**
* Describes the world * Describes the world

View File

@ -4,12 +4,13 @@ import org.joml.AABBd;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.util.ds.Spline3d; import electrosphere.util.ds.Spline3d;
/** /**
* A road * A road
*/ */
public class Road { public class Road implements MacroAreaObject {
/** /**
* The default radius * The default radius
@ -155,6 +156,37 @@ public class Road {
this.aabb.maxZ = point.z; this.aabb.maxZ = point.z;
} }
} }
this.aabb.minX = this.aabb.minX - radius;
this.aabb.minY = this.aabb.minY - radius;
this.aabb.minZ = this.aabb.minZ - radius;
this.aabb.maxX = this.aabb.maxX + radius;
this.aabb.maxY = this.aabb.maxY + radius;
this.aabb.maxZ = this.aabb.maxZ + radius;
}
@Override
public Vector3d getPos() {
throw new UnsupportedOperationException("Unimplemented method 'getPos'");
}
@Override
public void setPos(Vector3d pos) {
throw new UnsupportedOperationException("Unimplemented method 'setPos'");
}
@Override
public Vector3d getStartPos() {
return new Vector3d(aabb.minX, aabb.minY, aabb.minZ);
}
@Override
public Vector3d getEndPos() {
return new Vector3d(aabb.maxX, aabb.maxY, aabb.maxZ);
}
@Override
public AABBd getAABB() {
return aabb;
} }

View File

@ -1,8 +1,10 @@
package electrosphere.server.physics.terrain.generation; package electrosphere.server.physics.terrain.generation;
import java.util.List;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.entity.scene.RealmDescriptor; import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
import electrosphere.server.physics.terrain.models.TerrainModel; import electrosphere.server.physics.terrain.models.TerrainModel;
@ -24,7 +26,7 @@ public class DefaultChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(MacroData macroData, int worldX, int worldY, int worldZ, int stride) { public ServerTerrainChunk generateChunk(List<MacroObject> macroData, int worldX, int worldY, int worldZ, int stride) {
//Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap. //Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap.
//Hence, width should actually be chunk dimension + 1 //Hence, width should actually be chunk dimension + 1
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];

View File

@ -1,6 +1,7 @@
package electrosphere.server.physics.terrain.generation; package electrosphere.server.physics.terrain.generation;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
@ -11,7 +12,7 @@ import org.graalvm.polyglot.Value;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen; import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator; import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator;
import electrosphere.server.physics.terrain.generation.heightmap.HillsGen; import electrosphere.server.physics.terrain.generation.heightmap.HillsGen;
@ -113,7 +114,7 @@ public class JSChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(MacroData macroData, int worldX, int worldY, int worldZ, int stride) { public ServerTerrainChunk generateChunk(List<MacroObject> macroData, int worldX, int worldY, int worldZ, int stride) {
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk"); Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk");
ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ); ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ);
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];;

View File

@ -1,7 +1,9 @@
package electrosphere.server.physics.terrain.generation; package electrosphere.server.physics.terrain.generation;
import java.util.List;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
import electrosphere.server.physics.terrain.models.TerrainModel; import electrosphere.server.physics.terrain.models.TerrainModel;
@ -26,7 +28,7 @@ public class OverworldChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(MacroData macroData, int worldX, int worldY, int worldZ, int stride) { public ServerTerrainChunk generateChunk(List<MacroObject> macroData, int worldX, int worldY, int worldZ, int stride) {
ServerTerrainChunk returnedChunk; ServerTerrainChunk returnedChunk;
//Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap. //Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap.
//Hence, width should actually be chunk dimension + 1 //Hence, width should actually be chunk dimension + 1

View File

@ -1,6 +1,7 @@
package electrosphere.server.physics.terrain.generation; package electrosphere.server.physics.terrain.generation;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
@ -9,7 +10,8 @@ import electrosphere.data.biome.BiomeSurfaceGenerationParams;
import electrosphere.data.voxel.sampler.SamplerFile; import electrosphere.data.voxel.sampler.SamplerFile;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen; import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator; import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapNoiseGen; import electrosphere.server.physics.terrain.generation.heightmap.HeightmapNoiseGen;
@ -129,7 +131,7 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(MacroData macroData, int worldX, int worldY, int worldZ, int stride) { public ServerTerrainChunk generateChunk(List<MacroObject> macroData, int worldX, int worldY, int worldZ, int stride) {
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk"); Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk");
ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ); ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ);
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];;
@ -172,6 +174,9 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
GenerationContext generationContext = new GenerationContext(); GenerationContext generationContext = new GenerationContext();
generationContext.setServerWorldData(serverWorldData); generationContext.setServerWorldData(serverWorldData);
//
// Generate the voxels directly
//
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
@ -208,6 +213,11 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
weights[x][y][z] = voxel.weight; weights[x][y][z] = voxel.weight;
values[x][y][z] = voxel.type; values[x][y][z] = voxel.type;
} }
//apply macro data
if(this.applyMacroData(macroData, realX, realY, realZ, voxel)){
weights[x][y][z] = voxel.weight;
values[x][y][z] = voxel.type;
}
if(firstType == -2){ if(firstType == -2){
firstType = values[x][y][z]; firstType = values[x][y][z];
} else if( } else if(
@ -222,6 +232,11 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
} }
} }
} }
//
//Homogenous logic
//
if(homogenous){ if(homogenous){
rVal.setHomogenousValue(firstType); rVal.setHomogenousValue(firstType);
} else { } else {
@ -236,6 +251,33 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
return rVal; return rVal;
} }
/**
* Applies macro data to the voxel
* @param objects The object
* @param realX The real x position
* @param realY The real y position
* @param realZ The real z position
* @param voxel The voxel
*/
private boolean applyMacroData(
List<MacroObject> objects,
double realX, double realY, double realZ,
GeneratedVoxel voxel
){
for(MacroObject object : objects){
if(object instanceof Road){
Road road = (Road)object;
//broad phase intersection
if(road.getAABB().testPoint(realX, realY, realZ)){
}
} else {
throw new Error("Unsupported object type " + object);
}
}
return false;
}
/** /**
* Populates the heightfield * Populates the heightfield
* @param heightfield The heightfield to populate * @param heightfield The heightfield to populate

View File

@ -1,6 +1,8 @@
package electrosphere.server.physics.terrain.generation.interfaces; package electrosphere.server.physics.terrain.generation.interfaces;
import electrosphere.server.macro.MacroData; import java.util.List;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
import electrosphere.server.physics.terrain.models.TerrainModel; import electrosphere.server.physics.terrain.models.TerrainModel;
@ -18,7 +20,7 @@ public interface ChunkGenerator {
* @param stride The stride of the data * @param stride The stride of the data
* @return The chunk * @return The chunk
*/ */
public ServerTerrainChunk generateChunk(MacroData macroData, int worldX, int worldY, int worldZ, int stride); public ServerTerrainChunk generateChunk(List<MacroObject> macroData, int worldX, int worldY, int worldZ, int stride);
/** /**
* Gets the elevation at a given 2d coordinate * Gets the elevation at a given 2d coordinate

View File

@ -1,11 +1,12 @@
package electrosphere.server.physics.terrain.manager; package electrosphere.server.physics.terrain.manager;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap; import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
@ -42,7 +43,7 @@ public class ChunkGenerationThread implements Runnable {
/** /**
* The macro data * The macro data
*/ */
MacroData macroData; List<MacroObject> macroData;
/** /**
* The world x coordinate * The world x coordinate
@ -82,7 +83,7 @@ public class ChunkGenerationThread implements Runnable {
* @param onLoad The work to do once the chunk is available * @param onLoad The work to do once the chunk is available
*/ */
public ChunkGenerationThread( public ChunkGenerationThread(
MacroData macroData, List<MacroObject> macroData,
ChunkDiskMap chunkDiskMap, ChunkDiskMap chunkDiskMap,
ServerChunkCache chunkCache, ServerChunkCache chunkCache,
ChunkGenerator chunkGenerator, ChunkGenerator chunkGenerator,

View File

@ -6,6 +6,7 @@ import electrosphere.engine.threads.ThreadCounts;
import electrosphere.entity.scene.RealmDescriptor; import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap; import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.physics.terrain.generation.ProceduralChunkGenerator; import electrosphere.server.physics.terrain.generation.ProceduralChunkGenerator;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
@ -20,6 +21,7 @@ import electrosphere.util.annotation.Exclude;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -304,7 +306,8 @@ public class ServerTerrainManager {
} }
//generate if it does not exist //generate if it does not exist
if(returnedChunk == null){ if(returnedChunk == null){
returnedChunk = chunkGenerator.generateChunk(this.macroData, worldX, worldY, worldZ, ChunkData.NO_STRIDE); List<MacroObject> objects = this.macroData.getNearbyObjects(ServerWorldData.convertChunkToRealSpace(worldX, worldY, worldZ));
returnedChunk = chunkGenerator.generateChunk(objects, worldX, worldY, worldZ, ChunkData.NO_STRIDE);
} }
this.chunkCache.add(worldX, worldY, worldZ, ChunkData.NO_STRIDE, returnedChunk); this.chunkCache.add(worldX, worldY, worldZ, ChunkData.NO_STRIDE, returnedChunk);
} }
@ -351,7 +354,8 @@ public class ServerTerrainManager {
*/ */
public void getChunkAsync(int worldX, int worldY, int worldZ, int stride, Consumer<ServerTerrainChunk> onLoad){ public void getChunkAsync(int worldX, int worldY, int worldZ, int stride, Consumer<ServerTerrainChunk> onLoad){
Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunkAsync"); Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunkAsync");
chunkExecutorService.submit(new ChunkGenerationThread(this.macroData, chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad)); List<MacroObject> objects = this.macroData.getNearbyObjects(ServerWorldData.convertChunkToRealSpace(worldX, worldY, worldZ));
chunkExecutorService.submit(new ChunkGenerationThread(objects, chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad));
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }