From 96107d4356950cbdf9c093e37b95f63d45605455 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 30 Nov 2024 17:02:08 -0500 Subject: [PATCH] rearching ServerFluidManager --- .../datacell/GriddedDataCellManager.java | 17 +++++-- .../fluid/manager/ServerFluidManager.java | 48 ++++++++++++++----- .../simulator/FluidAcceleratedSimulator.java | 11 +++-- .../FluidCellularAutomataSimulator.java | 28 +++++++++-- .../fluid/simulator/ServerFluidSimulator.java | 14 ++---- 5 files changed, 85 insertions(+), 33 deletions(-) diff --git a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java index fe015d04..d3d171f8 100644 --- a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java +++ b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java @@ -538,13 +538,20 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager Globals.microSimulation.simulate(cell); } - //simulate fluid + //queue fluid simulation Vector3i cellPos = this.getCellWorldPosition(cell); - boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z); - if(update){ - this.rebroadcastFluidChunk(cellPos); - } + this.serverFluidManager.queue(cellPos.x, cellPos.y, cellPos.z); } + + //simulate fluids + this.serverFluidManager.simulate(); + + //rebroadcast updated chunks + for(ServerFluidChunk chunk : this.serverFluidManager.getBroadcastQueue()){ + this.rebroadcastFluidChunk(chunk.getWorldPosition()); + } + this.serverFluidManager.getBroadcastQueue().clear(); + loadedCellsLock.release(); this.unloadPlayerlessChunks(); this.updatePlayerPositions(); diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index 6cc4070e..3184af8d 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -8,7 +8,6 @@ import electrosphere.server.fluid.generation.FluidGenerator; import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.simulator.FluidCellularAutomataSimulator; import electrosphere.server.fluid.simulator.ServerFluidSimulator; -import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.util.FileUtils; import electrosphere.util.annotation.Exclude; @@ -41,9 +40,9 @@ public class ServerFluidManager { //offset regenerating the array every time we want a new one int cacheSize = 500; @Exclude - Map chunkCache; + Map chunkCache = new HashMap(); @Exclude - List chunkCacheContents; + List chunkCacheContents = new LinkedList(); //The map of chunk position <-> file on disk containing chunk data FluidDiskMap chunkDiskMap = null; @@ -74,6 +73,18 @@ public class ServerFluidManager { * Locks the fluid manager */ ReentrantLock lock = new ReentrantLock(); + + @Exclude + /** + * The queued of chunks to simulate + */ + List simulationQueue = new LinkedList(); + + @Exclude + /** + * The queue of chunks to broadcast + */ + List broadcastQueue = new LinkedList(); /** @@ -87,8 +98,6 @@ public class ServerFluidManager { ){ this.parent = parent; this.serverTerrainManager = serverTerrainManager; - this.chunkCache = new HashMap(); - this.chunkCacheContents = new LinkedList(); this.seed = seed; this.chunkGenerator = chunkGenerator; this.serverFluidSimulator = new FluidCellularAutomataSimulator(); @@ -291,23 +300,38 @@ public class ServerFluidManager { lock.unlock(); } + /** + * Adds a chunk to the queue to be simulated + * @param worldX The world x coordinate of the chunk + * @param worldY The world y coordinate of the chunk + * @param worldZ The world z coordinate of the chunk + */ + public void queue(int worldX, int worldY, int worldZ){ + this.simulationQueue.add(this.getChunk(worldX, worldY, worldZ)); + } + /** * Simulates a chunk */ - public boolean simulate(int worldX, int worldY, int worldZ){ - boolean rVal = false; + public void simulate(){ Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate"); lock.lock(); if(simulate){ - ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); - ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ); - if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){ - rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ); + if(this.serverFluidSimulator != null){ + this.serverFluidSimulator.simulate(this.simulationQueue,this.broadcastQueue); } + this.simulationQueue.clear(); } lock.unlock(); Globals.profiler.endCpuSample(); - return rVal; + } + + /** + * Gets the broadcast queue + * @return The broadcast queue + */ + public List getBroadcastQueue(){ + return this.broadcastQueue; } //getter for simulate diff --git a/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java b/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java index db33ef24..250832d9 100644 --- a/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java +++ b/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java @@ -4,13 +4,17 @@ import java.io.File; import java.util.List; import electrosphere.server.fluid.manager.ServerFluidChunk; -import electrosphere.server.terrain.manager.ServerTerrainChunk; /** * A c-accelerated fluid simulator */ public class FluidAcceleratedSimulator implements ServerFluidSimulator { + /** + * Timestep to simulate by + */ + public static final float SIMULATE_TIMESTEP = 0.01f; + /** * Load fluid sim library */ @@ -24,9 +28,8 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator { } @Override - public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ){ - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'simulate'"); + public void simulate(List fluidChunks, List broadcastQueue){ + FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP); } /** diff --git a/src/main/java/electrosphere/server/fluid/simulator/FluidCellularAutomataSimulator.java b/src/main/java/electrosphere/server/fluid/simulator/FluidCellularAutomataSimulator.java index 3e6393f2..c63c83c2 100644 --- a/src/main/java/electrosphere/server/fluid/simulator/FluidCellularAutomataSimulator.java +++ b/src/main/java/electrosphere/server/fluid/simulator/FluidCellularAutomataSimulator.java @@ -1,5 +1,7 @@ package electrosphere.server.fluid.simulator; +import java.util.List; + import electrosphere.server.fluid.manager.ServerFluidChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk; @@ -13,9 +15,23 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator { static final float GRAVITY_DIFF = 0.04f; @Override - public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ) { + public void simulate(List fluidChunks, List broadcastQueue) { + for(ServerFluidChunk chunk : fluidChunks){ + boolean updated = this.simulateChunk(chunk); + if(updated){ + broadcastQueue.add(chunk); + } + } + } + + /** + * Simulates a single chunk + * @param fluidChunk The fluid chunk + * @return true if the chunk was updated, false otherwise + */ + public boolean simulateChunk(ServerFluidChunk fluidChunk) { - float[][][] terrainWeights = terrainChunk.getWeights(); + float[][][] terrainWeights = null;//terrainChunk.getWeights(); //if true, alerts the server data cell to broadcast a new update message to all clients within it boolean update = false; @@ -42,7 +58,13 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator { ){ if( fluidChunk.getWeight(realX, y, realZ) < fluidChunk.getWeight(x, y, z) && - terrainWeights[realX][y][realZ] < MAX_WEIGHT + ( + terrainWeights == null || + ( + terrainWeights != null && + terrainWeights[realX][y][realZ] < MAX_WEIGHT + ) + ) ){ update = true; fluidChunk.setWeight(x, y, z, fluidChunk.getWeight(x, y, z) - GRAVITY_DIFF); diff --git a/src/main/java/electrosphere/server/fluid/simulator/ServerFluidSimulator.java b/src/main/java/electrosphere/server/fluid/simulator/ServerFluidSimulator.java index dfa3e36f..912423d7 100644 --- a/src/main/java/electrosphere/server/fluid/simulator/ServerFluidSimulator.java +++ b/src/main/java/electrosphere/server/fluid/simulator/ServerFluidSimulator.java @@ -1,7 +1,8 @@ package electrosphere.server.fluid.simulator; +import java.util.List; + import electrosphere.server.fluid.manager.ServerFluidChunk; -import electrosphere.server.terrain.manager.ServerTerrainChunk; /** * A system capable of simulating a server fluid chunk for a single frame @@ -9,14 +10,9 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk; public interface ServerFluidSimulator { /** - * Simulates the chunk for single step - * @param fluidChunk The fluid chunk - * @param terrainChunk The terrain chunk - * @param worldX the world x coordinate - * @param worldY the world y coordinate - * @param worldZ the world z coordinate - * @return True if the server data cell should update all players connected to it with new values, false otherwise + * Simulates the chunks for single step + * @param fluidChunks The list of fluid chunks to simulate */ - public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ); + public void simulate(List fluidChunks, List broadcastQueue); }