rearching ServerFluidManager
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 17:02:08 -05:00
parent 57ab3158fe
commit 96107d4356
5 changed files with 85 additions and 33 deletions

View File

@ -538,13 +538,20 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Globals.microSimulation.simulate(cell); Globals.microSimulation.simulate(cell);
} }
//simulate fluid //queue fluid simulation
Vector3i cellPos = this.getCellWorldPosition(cell); Vector3i cellPos = this.getCellWorldPosition(cell);
boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z); this.serverFluidManager.queue(cellPos.x, cellPos.y, cellPos.z);
if(update){
this.rebroadcastFluidChunk(cellPos);
}
} }
//simulate fluids
this.serverFluidManager.simulate();
//rebroadcast updated chunks
for(ServerFluidChunk chunk : this.serverFluidManager.getBroadcastQueue()){
this.rebroadcastFluidChunk(chunk.getWorldPosition());
}
this.serverFluidManager.getBroadcastQueue().clear();
loadedCellsLock.release(); loadedCellsLock.release();
this.unloadPlayerlessChunks(); this.unloadPlayerlessChunks();
this.updatePlayerPositions(); this.updatePlayerPositions();

View File

@ -8,7 +8,6 @@ import electrosphere.server.fluid.generation.FluidGenerator;
import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.fluid.simulator.FluidCellularAutomataSimulator; import electrosphere.server.fluid.simulator.FluidCellularAutomataSimulator;
import electrosphere.server.fluid.simulator.ServerFluidSimulator; import electrosphere.server.fluid.simulator.ServerFluidSimulator;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
import electrosphere.util.annotation.Exclude; import electrosphere.util.annotation.Exclude;
@ -41,9 +40,9 @@ public class ServerFluidManager {
//offset regenerating the array every time we want a new one //offset regenerating the array every time we want a new one
int cacheSize = 500; int cacheSize = 500;
@Exclude @Exclude
Map<String, ServerFluidChunk> chunkCache; Map<String, ServerFluidChunk> chunkCache = new HashMap<String, ServerFluidChunk>();
@Exclude @Exclude
List<String> chunkCacheContents; List<String> chunkCacheContents = new LinkedList<String>();
//The map of chunk position <-> file on disk containing chunk data //The map of chunk position <-> file on disk containing chunk data
FluidDiskMap chunkDiskMap = null; FluidDiskMap chunkDiskMap = null;
@ -74,6 +73,18 @@ public class ServerFluidManager {
* Locks the fluid manager * Locks the fluid manager
*/ */
ReentrantLock lock = new ReentrantLock(); ReentrantLock lock = new ReentrantLock();
@Exclude
/**
* The queued of chunks to simulate
*/
List<ServerFluidChunk> simulationQueue = new LinkedList<ServerFluidChunk>();
@Exclude
/**
* The queue of chunks to broadcast
*/
List<ServerFluidChunk> broadcastQueue = new LinkedList<ServerFluidChunk>();
/** /**
@ -87,8 +98,6 @@ public class ServerFluidManager {
){ ){
this.parent = parent; this.parent = parent;
this.serverTerrainManager = serverTerrainManager; this.serverTerrainManager = serverTerrainManager;
this.chunkCache = new HashMap<String, ServerFluidChunk>();
this.chunkCacheContents = new LinkedList<String>();
this.seed = seed; this.seed = seed;
this.chunkGenerator = chunkGenerator; this.chunkGenerator = chunkGenerator;
this.serverFluidSimulator = new FluidCellularAutomataSimulator(); this.serverFluidSimulator = new FluidCellularAutomataSimulator();
@ -291,23 +300,38 @@ public class ServerFluidManager {
lock.unlock(); 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 * Simulates a chunk
*/ */
public boolean simulate(int worldX, int worldY, int worldZ){ public void simulate(){
boolean rVal = false;
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate"); Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
lock.lock(); lock.lock();
if(simulate){ if(simulate){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); if(this.serverFluidSimulator != null){
ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ); this.serverFluidSimulator.simulate(this.simulationQueue,this.broadcastQueue);
if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
} }
this.simulationQueue.clear();
} }
lock.unlock(); lock.unlock();
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
return rVal; }
/**
* Gets the broadcast queue
* @return The broadcast queue
*/
public List<ServerFluidChunk> getBroadcastQueue(){
return this.broadcastQueue;
} }
//getter for simulate //getter for simulate

View File

@ -4,13 +4,17 @@ import java.io.File;
import java.util.List; import java.util.List;
import electrosphere.server.fluid.manager.ServerFluidChunk; import electrosphere.server.fluid.manager.ServerFluidChunk;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/** /**
* A c-accelerated fluid simulator * A c-accelerated fluid simulator
*/ */
public class FluidAcceleratedSimulator implements ServerFluidSimulator { public class FluidAcceleratedSimulator implements ServerFluidSimulator {
/**
* Timestep to simulate by
*/
public static final float SIMULATE_TIMESTEP = 0.01f;
/** /**
* Load fluid sim library * Load fluid sim library
*/ */
@ -24,9 +28,8 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
} }
@Override @Override
public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ){ public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){
// TODO Auto-generated method stub FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP);
throw new UnsupportedOperationException("Unimplemented method 'simulate'");
} }
/** /**

View File

@ -1,5 +1,7 @@
package electrosphere.server.fluid.simulator; package electrosphere.server.fluid.simulator;
import java.util.List;
import electrosphere.server.fluid.manager.ServerFluidChunk; import electrosphere.server.fluid.manager.ServerFluidChunk;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
@ -13,9 +15,23 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
static final float GRAVITY_DIFF = 0.04f; static final float GRAVITY_DIFF = 0.04f;
@Override @Override
public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ) { public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> 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 //if true, alerts the server data cell to broadcast a new update message to all clients within it
boolean update = false; boolean update = false;
@ -42,7 +58,13 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
){ ){
if( if(
fluidChunk.getWeight(realX, y, realZ) < fluidChunk.getWeight(x, y, z) && 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; update = true;
fluidChunk.setWeight(x, y, z, fluidChunk.getWeight(x, y, z) - GRAVITY_DIFF); fluidChunk.setWeight(x, y, z, fluidChunk.getWeight(x, y, z) - GRAVITY_DIFF);

View File

@ -1,7 +1,8 @@
package electrosphere.server.fluid.simulator; package electrosphere.server.fluid.simulator;
import java.util.List;
import electrosphere.server.fluid.manager.ServerFluidChunk; 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 * 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 { public interface ServerFluidSimulator {
/** /**
* Simulates the chunk for single step * Simulates the chunks for single step
* @param fluidChunk The fluid chunk * @param fluidChunks The list of fluid chunks to simulate
* @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
*/ */
public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ); public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue);
} }