From 3777a9a37ca8bb0fd8fdcd0450d6c97fc1d0b104 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 23 Nov 2024 21:46:13 -0500 Subject: [PATCH] server side terrain management refactoring --- docs/src/progress/renderertodo.md | 2 + .../client/block/BlockChunkData.java | 28 ++++++++- .../assetmanager/queue/QueuedModel.java | 4 +- .../assetmanager/queue/QueuedTexture.java | 12 +++- .../engine/loadingthreads/ClientLoading.java | 30 +++++----- .../server/terrain/diskmap/ChunkDiskMap.java | 28 ++++++--- .../terrain/manager/ServerTerrainManager.java | 9 +-- .../terrain/models/ModificationList.java | 21 ------- .../server/terrain/models/TerrainModel.java | 59 ------------------- .../terrain/models/TerrainModification.java | 41 ++++++++++++- 10 files changed, 118 insertions(+), 116 deletions(-) delete mode 100644 src/main/java/electrosphere/server/terrain/models/ModificationList.java diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 2dff8b48..4b345dd4 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1144,6 +1144,8 @@ Fix script entity spawn utils not spawning on max cursor distance Block mesh generation Add asset manager support for queueing models asynchronously w/ promised path Add promised path support to queued textures +Code formatting on queued asset classes +Refactoring server side of terrain management # TODO diff --git a/src/main/java/electrosphere/client/block/BlockChunkData.java b/src/main/java/electrosphere/client/block/BlockChunkData.java index 44e2c85c..e4b07904 100644 --- a/src/main/java/electrosphere/client/block/BlockChunkData.java +++ b/src/main/java/electrosphere/client/block/BlockChunkData.java @@ -22,6 +22,11 @@ public class BlockChunkData { */ public static final float BLOCK_SIZE_MULTIPLIER = 1.0f / BLOCKS_PER_UNIT_DISTANCE; + /** + * Set if this chunk is not homogenous + */ + public static final short NOT_HOMOGENOUS = -1; + /** * The type of block at a given position @@ -34,6 +39,11 @@ public class BlockChunkData { */ short[] metadata; + /** + * If this block chunk is homogenously a single value, it will be the value of this short. Otherwise is + */ + short homogenousValue = NOT_HOMOGENOUS; + /** * Constructor */ @@ -41,7 +51,7 @@ public class BlockChunkData { } /** - * Constructor + * Allocates a BlockChunkData with empty values */ public static BlockChunkData allocate(){ BlockChunkData rVal = new BlockChunkData(); @@ -50,6 +60,15 @@ public class BlockChunkData { return rVal; } + /** + * Allocates a BlockChunkData with a homogenous value + */ + public static BlockChunkData allocate(short homogenousValue){ + BlockChunkData rVal = new BlockChunkData(); + rVal.homogenousValue = homogenousValue; + return rVal; + } + /** * Gets the type data for the chunk * @return The type data @@ -147,5 +166,12 @@ public class BlockChunkData { return empty; } + /** + * Checks if this block chunk is homogenous or not + * @return true if it is homogenous, false otherwise + */ + public boolean isHomogenous(){ + return this.homogenousValue != NOT_HOMOGENOUS; + } } diff --git a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedModel.java b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedModel.java index 87932d22..77d63fc9 100644 --- a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedModel.java +++ b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedModel.java @@ -10,7 +10,9 @@ import electrosphere.renderer.model.Model; */ public class QueuedModel implements QueuedAsset { - //true if loaded + /** + * true if loaded + */ boolean hasLoaded = false; /** diff --git a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java index a3f8923c..e1834f03 100644 --- a/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java +++ b/src/main/java/electrosphere/engine/assetmanager/queue/QueuedTexture.java @@ -11,13 +11,19 @@ import electrosphere.renderer.texture.Texture; */ public class QueuedTexture implements QueuedAsset { - //true if loaded + /** + * True if loaded + */ boolean hasLoaded = false; - //the resulting texture object + /** + * The resuling texture object + */ Texture texture = null; - //data to be loaded + /** + * The data to be loaded + */ BufferedImage data; /** diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 00ae5d43..408aef8e 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -278,21 +278,21 @@ public class ClientLoading { EntityUtils.getScale(Globals.playerCursor).set(0.2f); //block test - // Entity blockEntity = EntityCreationUtils.createClientSpatialEntity(); - // BlockChunkData blockChunkData = BlockChunkData.allocate(); - // blockChunkData.setType(0, 0, 0, 1); - // blockChunkData.setType(1, 0, 0, 1); - // blockChunkData.setType(0, 1, 0, 1); - // blockChunkData.setType(1, 1, 0, 1); - // blockChunkData.setType(0, 0, 1, 1); - // blockChunkData.setType(1, 0, 1, 1); - // blockChunkData.setType(0, 1, 1, 1); - // blockChunkData.setType(1, 1, 1, 1); - // BlockMeshData meshData = BlockMeshgen.rasterize(blockChunkData); - // String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> { - // return BlockMeshgen.generateBlockModel(meshData); - // })); - // EntityCreationUtils.makeEntityDrawablePreexistingModel(blockEntity, modelPath); + Entity blockEntity = EntityCreationUtils.createClientSpatialEntity(); + BlockChunkData blockChunkData = BlockChunkData.allocate(); + blockChunkData.setType(0, 0, 0, 1); + blockChunkData.setType(1, 0, 0, 1); + blockChunkData.setType(0, 1, 0, 1); + blockChunkData.setType(1, 1, 0, 1); + blockChunkData.setType(0, 0, 1, 1); + blockChunkData.setType(1, 0, 1, 1); + blockChunkData.setType(0, 1, 1, 1); + blockChunkData.setType(1, 1, 1, 1); + BlockMeshData meshData = BlockMeshgen.rasterize(blockChunkData); + String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> { + return BlockMeshgen.generateBlockModel(meshData); + })); + EntityCreationUtils.makeEntityDrawablePreexistingModel(blockEntity, modelPath); } static final int MAX_DRAW_CELL_WAIT = 1000; diff --git a/src/main/java/electrosphere/server/terrain/diskmap/ChunkDiskMap.java b/src/main/java/electrosphere/server/terrain/diskmap/ChunkDiskMap.java index 30238840..b7250570 100644 --- a/src/main/java/electrosphere/server/terrain/diskmap/ChunkDiskMap.java +++ b/src/main/java/electrosphere/server/terrain/diskmap/ChunkDiskMap.java @@ -23,8 +23,10 @@ import electrosphere.util.annotation.Exclude; */ public class ChunkDiskMap { - //The map of world position+chunk type to the file that actually houses that information - Map worldPosFileMap = new HashMap(); + /** + * The map of world position+chunk type to the file that actually houses that information + */ + Map worldPosFileMap; /** * Locks the chunk disk map for thread safety @@ -35,8 +37,8 @@ public class ChunkDiskMap { /** * Constructor */ - public ChunkDiskMap(){ - + private ChunkDiskMap(){ + worldPosFileMap = new HashMap(); } /** @@ -65,14 +67,24 @@ public class ChunkDiskMap { * Initializes a diskmap based on a given save name * @param saveName The save name */ - public void init(String saveName){ + public static ChunkDiskMap init(String saveName){ + ChunkDiskMap rVal = null; LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName); if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){ - worldPosFileMap = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", Map.class); - LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + worldPosFileMap.keySet()); + rVal = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", ChunkDiskMap.class); + LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet()); } else { - worldPosFileMap = new HashMap(); + rVal = new ChunkDiskMap(); } + return rVal; + } + + /** + * Initializes a diskmap based on a given save name + * @param saveName The save name + */ + public static ChunkDiskMap init(){ + return new ChunkDiskMap(); } /** diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java index 662e63dd..40b7ebdd 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java @@ -106,7 +106,7 @@ public class ServerTerrainManager { model = terrainGen.generateModel(); this.chunkGenerator.setModel(model); model.setInterpolationRandomDampener(SERVER_TERRAIN_MANAGER_DAMPENER); - this.chunkDiskMap = new ChunkDiskMap(); + this.chunkDiskMap = ChunkDiskMap.init(); } /** @@ -157,8 +157,7 @@ public class ServerTerrainManager { model.setElevationArray(elevation); } //load chunk disk map - chunkDiskMap = new ChunkDiskMap(); - chunkDiskMap.init(saveName); + chunkDiskMap = ChunkDiskMap.init(saveName); } /** @@ -296,10 +295,6 @@ public class ServerTerrainManager { */ public void deformTerrainAtLocationToValue(Vector3i worldPos, Vector3i voxelPos, float weight, int value){ TerrainModification modification = new TerrainModification(worldPos,voxelPos,weight,value); - //could be null if, for instance, arena mode - if(model != null){ - model.addModification(modification); - } if(chunkCache.containsChunk(worldPos.x,worldPos.y,worldPos.z,ChunkData.NO_STRIDE)){ ServerTerrainChunk chunk = chunkCache.get(worldPos.x,worldPos.y,worldPos.z, ChunkData.NO_STRIDE); chunk.addModification(modification); diff --git a/src/main/java/electrosphere/server/terrain/models/ModificationList.java b/src/main/java/electrosphere/server/terrain/models/ModificationList.java deleted file mode 100644 index 7f247361..00000000 --- a/src/main/java/electrosphere/server/terrain/models/ModificationList.java +++ /dev/null @@ -1,21 +0,0 @@ -package electrosphere.server.terrain.models; - -import java.util.ArrayList; -import java.util.List; - -/** - * Modifications made to terrain - */ -public class ModificationList { - - List modifications = new ArrayList(); - - public List getModifications() { - return modifications; - } - - public void addModification(TerrainModification modification){ - modifications.add(modification); - } - -} diff --git a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java index c473539e..12beadab 100644 --- a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java +++ b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java @@ -1,8 +1,5 @@ package electrosphere.server.terrain.models; -import java.util.HashMap; -import java.util.Map; - import electrosphere.engine.Globals; import electrosphere.game.data.biome.BiomeData; import electrosphere.server.terrain.generation.TestGenerationChunkGenerator; @@ -61,11 +58,6 @@ public class TerrainModel { * The real coordinate ocean threshold */ float realOceanThreshold; - - /** - * The map of modifications applied to the model - */ - Map modifications; /** * The seed of the terrain @@ -84,7 +76,6 @@ public class TerrainModel { * Private constructor */ TerrainModel() { - this.modifications = new HashMap(); } /** @@ -108,7 +99,6 @@ public class TerrainModel { this.elevation = elevation; this.realMountainThreshold = realMountainThreshold; this.realOceanThreshold = realOceanThreshold; - this.modifications = new HashMap(); } /** @@ -458,55 +448,6 @@ public class TerrainModel { public float getRealOceanThreshold() { return realOceanThreshold; } - - /** - * Gets a modification key - * @param x The world x position - * @param y The world y position - * @param z The world z position - * @return The key - */ - public String getModificationKey(int x, int y, int z){ - return x + "_" + y + "_" + z; - } - - /** - * Adds a terrain modification to the model - * @param modification The modification - */ - public void addModification(TerrainModification modification){ - String key = getModificationKey(modification.getWorldPos().x,modification.getWorldPos().y,modification.getWorldPos().z); - ModificationList list; - if(!modifications.containsKey(key)){ - list = new ModificationList(); - modifications.put(key, list); - } else { - list = modifications.get(key); - } - list.addModification(modification); - } - - /** - * Checks if a modification has been applied at a world position - * @param worldX The x coordinate of the world position - * @param worldY The y coordinate of the world position - * @param worldZ The z coordinate of the world position - * @return true if there is a modification, false otherwise - */ - public boolean containsModificationsAtCoord(int worldX, int worldY, int worldZ){ - return modifications.containsKey(getModificationKey(worldX, worldY, worldZ)); - } - - /** - * Gets the terrain modification at the world position - * @param worldX The x coordinate of the world position - * @param worldY The y coordinate of the world position - * @param worldZ The z coordinate of the world position - * @return The modification if there is one at the position, null otherwise - */ - public ModificationList getModifications(int worldX, int worldY, int worldZ){ - return modifications.get(getModificationKey(worldX, worldY, worldZ)); - } /** * Sets the elevation array (For instance when read from save file on loading a save) diff --git a/src/main/java/electrosphere/server/terrain/models/TerrainModification.java b/src/main/java/electrosphere/server/terrain/models/TerrainModification.java index 9760640b..57005c19 100644 --- a/src/main/java/electrosphere/server/terrain/models/TerrainModification.java +++ b/src/main/java/electrosphere/server/terrain/models/TerrainModification.java @@ -3,14 +3,37 @@ package electrosphere.server.terrain.models; import org.joml.Vector3i; /** - * A modification made to terrain + * A modification made to a terrain chunk */ public class TerrainModification { + + /** + * The world position of the modification + */ Vector3i worldPos; + + /** + * The voxel position within the chunk that was modified + */ Vector3i voxelPos; + + /** + * The new weight + */ float weight; + + /** + * The new type of voxel + */ int value; + /** + * Constructor + * @param worldPos The world position of the modification + * @param voxelPos The voxel position within the chunk that was modified + * @param weight The new weight + * @param value The new type of voxel + */ public TerrainModification(Vector3i worldPos, Vector3i voxelPos, float weight, int value) { this.worldPos = worldPos; this.voxelPos = voxelPos; @@ -18,18 +41,34 @@ public class TerrainModification { this.value = value; } + /** + * Gets the world position of the modification + * @return The world position + */ public Vector3i getWorldPos() { return worldPos; } + /** + * Gets the new relative voxel position of the modification + * @return The relative voxel position + */ public Vector3i getVoxelPos() { return voxelPos; } + /** + * Gets the new weight + * @return The new weight + */ public float getWeight(){ return weight; } + /** + * Gets the new type of voxel + * @return The new type of voxel + */ public int getValue() { return value; }