diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index e30f9c58..373df375 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -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 diff --git a/src/main/java/electrosphere/server/macro/MacroData.java b/src/main/java/electrosphere/server/macro/MacroData.java index 462ab110..663981db 100644 --- a/src/main/java/electrosphere/server/macro/MacroData.java +++ b/src/main/java/electrosphere/server/macro/MacroData.java @@ -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 getNearbyObjects(Vector3d position){ + List rVal = new LinkedList(); + return rVal; + } /** * Describes the world diff --git a/src/main/java/electrosphere/server/macro/civilization/road/Road.java b/src/main/java/electrosphere/server/macro/civilization/road/Road.java index 5c068378..65859568 100644 --- a/src/main/java/electrosphere/server/macro/civilization/road/Road.java +++ b/src/main/java/electrosphere/server/macro/civilization/road/Road.java @@ -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; } diff --git a/src/main/java/electrosphere/server/physics/terrain/generation/DefaultChunkGenerator.java b/src/main/java/electrosphere/server/physics/terrain/generation/DefaultChunkGenerator.java index 05fc6d5a..c743d09f 100644 --- a/src/main/java/electrosphere/server/physics/terrain/generation/DefaultChunkGenerator.java +++ b/src/main/java/electrosphere/server/physics/terrain/generation/DefaultChunkGenerator.java @@ -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 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]; diff --git a/src/main/java/electrosphere/server/physics/terrain/generation/JSChunkGenerator.java b/src/main/java/electrosphere/server/physics/terrain/generation/JSChunkGenerator.java index cad34dcf..3edcbf1c 100644 --- a/src/main/java/electrosphere/server/physics/terrain/generation/JSChunkGenerator.java +++ b/src/main/java/electrosphere/server/physics/terrain/generation/JSChunkGenerator.java @@ -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 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];; diff --git a/src/main/java/electrosphere/server/physics/terrain/generation/OverworldChunkGenerator.java b/src/main/java/electrosphere/server/physics/terrain/generation/OverworldChunkGenerator.java index bb539b99..92b5ebb0 100644 --- a/src/main/java/electrosphere/server/physics/terrain/generation/OverworldChunkGenerator.java +++ b/src/main/java/electrosphere/server/physics/terrain/generation/OverworldChunkGenerator.java @@ -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 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 diff --git a/src/main/java/electrosphere/server/physics/terrain/generation/ProceduralChunkGenerator.java b/src/main/java/electrosphere/server/physics/terrain/generation/ProceduralChunkGenerator.java index b32e11c4..c7198671 100644 --- a/src/main/java/electrosphere/server/physics/terrain/generation/ProceduralChunkGenerator.java +++ b/src/main/java/electrosphere/server/physics/terrain/generation/ProceduralChunkGenerator.java @@ -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 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 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 diff --git a/src/main/java/electrosphere/server/physics/terrain/generation/interfaces/ChunkGenerator.java b/src/main/java/electrosphere/server/physics/terrain/generation/interfaces/ChunkGenerator.java index d4f27d29..e94c3297 100644 --- a/src/main/java/electrosphere/server/physics/terrain/generation/interfaces/ChunkGenerator.java +++ b/src/main/java/electrosphere/server/physics/terrain/generation/interfaces/ChunkGenerator.java @@ -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 macroData, int worldX, int worldY, int worldZ, int stride); /** * Gets the elevation at a given 2d coordinate diff --git a/src/main/java/electrosphere/server/physics/terrain/manager/ChunkGenerationThread.java b/src/main/java/electrosphere/server/physics/terrain/manager/ChunkGenerationThread.java index e9ade87e..02933272 100644 --- a/src/main/java/electrosphere/server/physics/terrain/manager/ChunkGenerationThread.java +++ b/src/main/java/electrosphere/server/physics/terrain/manager/ChunkGenerationThread.java @@ -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 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 macroData, ChunkDiskMap chunkDiskMap, ServerChunkCache chunkCache, ChunkGenerator chunkGenerator, diff --git a/src/main/java/electrosphere/server/physics/terrain/manager/ServerTerrainManager.java b/src/main/java/electrosphere/server/physics/terrain/manager/ServerTerrainManager.java index 147cb931..b27ecdec 100644 --- a/src/main/java/electrosphere/server/physics/terrain/manager/ServerTerrainManager.java +++ b/src/main/java/electrosphere/server/physics/terrain/manager/ServerTerrainManager.java @@ -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 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 onLoad){ Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunkAsync"); - chunkExecutorService.submit(new ChunkGenerationThread(this.macroData, chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad)); + List 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(); }