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
Road macro data generation
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.RaceMap;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.server.macro.town.Town;
import electrosphere.util.FileUtils;
@ -292,6 +293,16 @@ public class MacroData {
public void addStructure(VirtualStructure 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

View File

@ -4,12 +4,13 @@ import org.joml.AABBd;
import org.joml.Vector3d;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.util.ds.Spline3d;
/**
* A road
*/
public class Road {
public class Road implements MacroAreaObject {
/**
* The default radius
@ -155,6 +156,37 @@ public class Road {
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;
import java.util.List;
import electrosphere.client.terrain.cache.ChunkData;
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.manager.ServerTerrainChunk;
import electrosphere.server.physics.terrain.models.TerrainModel;
@ -24,7 +26,7 @@ public class DefaultChunkGenerator implements ChunkGenerator {
}
@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.
//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];

View File

@ -1,6 +1,7 @@
package electrosphere.server.physics.terrain.generation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import electrosphere.client.terrain.cache.ChunkData;
@ -11,7 +12,7 @@ import org.graalvm.polyglot.Value;
import electrosphere.engine.Globals;
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.HeightmapGenerator;
import electrosphere.server.physics.terrain.generation.heightmap.HillsGen;
@ -113,7 +114,7 @@ public class JSChunkGenerator implements ChunkGenerator {
}
@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");
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];;

View File

@ -1,7 +1,9 @@
package electrosphere.server.physics.terrain.generation;
import java.util.List;
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.manager.ServerTerrainChunk;
import electrosphere.server.physics.terrain.models.TerrainModel;
@ -26,7 +28,7 @@ public class OverworldChunkGenerator implements ChunkGenerator {
}
@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;
//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

View File

@ -1,6 +1,7 @@
package electrosphere.server.physics.terrain.generation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import electrosphere.client.terrain.cache.ChunkData;
@ -9,7 +10,8 @@ import electrosphere.data.biome.BiomeSurfaceGenerationParams;
import electrosphere.data.voxel.sampler.SamplerFile;
import electrosphere.engine.Globals;
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.HeightmapGenerator;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapNoiseGen;
@ -129,7 +131,7 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
}
@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");
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];;
@ -172,6 +174,9 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
GenerationContext generationContext = new GenerationContext();
generationContext.setServerWorldData(serverWorldData);
//
// Generate the voxels directly
//
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
int finalWorldX = worldX + ((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;
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){
firstType = values[x][y][z];
} else if(
@ -222,6 +232,11 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
}
}
}
//
//Homogenous logic
//
if(homogenous){
rVal.setHomogenousValue(firstType);
} else {
@ -236,6 +251,33 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
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
* @param heightfield The heightfield to populate

View File

@ -1,6 +1,8 @@
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.models.TerrainModel;
@ -18,7 +20,7 @@ public interface ChunkGenerator {
* @param stride The stride of the data
* @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

View File

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

View File

@ -6,6 +6,7 @@ import electrosphere.engine.threads.ThreadCounts;
import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.physics.terrain.generation.ProceduralChunkGenerator;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
@ -20,6 +21,7 @@ import electrosphere.util.annotation.Exclude;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
@ -304,7 +306,8 @@ public class ServerTerrainManager {
}
//generate if it does not exist
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);
}
@ -351,7 +354,8 @@ public class ServerTerrainManager {
*/
public void getChunkAsync(int worldX, int worldY, int worldZ, int stride, Consumer<ServerTerrainChunk> onLoad){
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();
}