more fluid dimensions work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 17:25:26 -05:00
parent 40ae429417
commit 888cc254f3
7 changed files with 102 additions and 71 deletions

View File

@ -1197,6 +1197,7 @@ Fix viewport loading
Water spawner firing on repeat Water spawner firing on repeat
Convert server side fluid storage to using buffers Convert server side fluid storage to using buffers
Move cellular automata simulator package Move cellular automata simulator package
Update fluid chunk dimensions to correspond with C code

View File

@ -3,7 +3,6 @@ package electrosphere.client.fluid.cache;
import org.joml.Vector3i; import org.joml.Vector3i;
import electrosphere.server.fluid.manager.ServerFluidChunk; import electrosphere.server.fluid.manager.ServerFluidChunk;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/** /**
* A container of data about a chunk of fluid * A container of data about a chunk of fluid
@ -13,7 +12,7 @@ public class FluidChunkData {
//The size of a chunk in virtual data //The size of a chunk in virtual data
public static final int CHUNK_SIZE = ServerFluidChunk.BUFFER_DIM; public static final int CHUNK_SIZE = ServerFluidChunk.BUFFER_DIM;
//The size of the data passed into marching cubes/transvoxel algorithm to get a fully connected and seamless chunk //The size of the data passed into marching cubes/transvoxel algorithm to get a fully connected and seamless chunk
public static final int CHUNK_DATA_GENERATOR_SIZE = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; public static final int CHUNK_DATA_GENERATOR_SIZE = ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE;
//How much of that fluid type is in this voxel //How much of that fluid type is in this voxel
float[][][] voxelWeight; float[][][] voxelWeight;

View File

@ -13,7 +13,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.types.fluid.FluidChunk; import electrosphere.entity.types.fluid.FluidChunk;
import electrosphere.renderer.shader.VisualShader; import electrosphere.renderer.shader.VisualShader;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.fluid.manager.ServerFluidChunk;
/** /**
* *
@ -31,7 +31,7 @@ public class FluidCell {
DBody physicsObject; DBody physicsObject;
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; float[][][] weights = new float[ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE][ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE][ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE];
//the value of an empty fluid cell weight that is not neighbored by a fluid value //the value of an empty fluid cell weight that is not neighbored by a fluid value
public static final float ISO_SURFACE_EMPTY = -1; public static final float ISO_SURFACE_EMPTY = -1;
@ -109,9 +109,9 @@ public class FluidCell {
// //
//main chunk //main chunk
FluidChunkData currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos); FluidChunkData currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ for(int x = ServerFluidChunk.TRUE_DATA_OFFSET; x < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ for(int y = ServerFluidChunk.TRUE_DATA_OFFSET; y < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ for(int z = ServerFluidChunk.TRUE_DATA_OFFSET; z < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; z++){
weights[x][y][z] = currentChunk.getWeight(x,y,z); weights[x][y][z] = currentChunk.getWeight(x,y,z);
} }
} }
@ -120,22 +120,22 @@ public class FluidCell {
if(worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize()){ if(worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][j] = currentChunk.getWeight(0, i, j); weights[ServerFluidChunk.TRUE_DATA_DIM][i][j] = currentChunk.getWeight(0, i, j);
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][j] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][i][j] = ISO_SURFACE_EMPTY;
} }
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][j] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][i][j] = ISO_SURFACE_EMPTY;
} }
} }
} }
@ -143,22 +143,22 @@ public class FluidCell {
if(worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize()){ if(worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][j] = currentChunk.getWeight(i, 0, j); weights[i][ServerFluidChunk.TRUE_DATA_DIM][j] = currentChunk.getWeight(i, 0, j);
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][j] = ISO_SURFACE_EMPTY; weights[i][ServerFluidChunk.TRUE_DATA_DIM][j] = ISO_SURFACE_EMPTY;
} }
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][j] = ISO_SURFACE_EMPTY; weights[i][ServerFluidChunk.TRUE_DATA_DIM][j] = ISO_SURFACE_EMPTY;
} }
} }
} }
@ -166,22 +166,22 @@ public class FluidCell {
if(worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()){ if(worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z + 1); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z + 1);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][j][ServerTerrainChunk.CHUNK_DIMENSION] = currentChunk.getWeight(i, j, 0); weights[i][j][ServerFluidChunk.TRUE_DATA_DIM] = currentChunk.getWeight(i, j, 0);
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][j][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[i][j][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
for(int j = 0; j < ServerTerrainChunk.CHUNK_DIMENSION; j++){ for(int j = ServerFluidChunk.TRUE_DATA_OFFSET; j < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; j++){
weights[i][j][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[i][j][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
} }
@ -192,17 +192,17 @@ public class FluidCell {
){ ){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][i] = currentChunk.getWeight(0, 0, i); weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][i] = currentChunk.getWeight(0, 0, i);
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][i] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][i] = ISO_SURFACE_EMPTY;
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][i] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][i] = ISO_SURFACE_EMPTY;
} }
} }
//edge X-Z //edge X-Z
@ -212,17 +212,17 @@ public class FluidCell {
){ ){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z + 1); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z + 1);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][ServerTerrainChunk.CHUNK_DIMENSION] = currentChunk.getWeight(0, i, 0); weights[ServerFluidChunk.TRUE_DATA_DIM][i][ServerFluidChunk.TRUE_DATA_DIM] = currentChunk.getWeight(0, i, 0);
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][i][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[ServerTerrainChunk.CHUNK_DIMENSION][i][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][i][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
//edge Y-Z //edge Y-Z
@ -232,17 +232,17 @@ public class FluidCell {
){ ){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z + 1); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z + 1);
if(currentChunk != null){ if(currentChunk != null){
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = currentChunk.getWeight(i, 0, 0); weights[i][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = currentChunk.getWeight(i, 0, 0);
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[i][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
} else { } else {
for(int i = 0; i < ServerTerrainChunk.CHUNK_DIMENSION; i++){ for(int i = ServerFluidChunk.TRUE_DATA_OFFSET; i < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; i++){
weights[i][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[i][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} }
if( if(
@ -252,12 +252,12 @@ public class FluidCell {
){ ){
currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1); currentChunk = Globals.clientFluidManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
if(currentChunk != null){ if(currentChunk != null){
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = currentChunk.getWeight(0, 0, 0); weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = currentChunk.getWeight(0, 0, 0);
} else { } else {
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
} else { } else {
weights[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION] = ISO_SURFACE_EMPTY; weights[ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM][ServerFluidChunk.TRUE_DATA_DIM] = ISO_SURFACE_EMPTY;
} }
//now set neighboring air weights based on nearby fluid count //now set neighboring air weights based on nearby fluid count
@ -265,9 +265,9 @@ public class FluidCell {
int[] neighborIndexX = new int[]{-1,1,0,0,0,0}; int[] neighborIndexX = new int[]{-1,1,0,0,0,0};
int[] neighborIndexY = new int[]{0,0,-1,1,0,0}; int[] neighborIndexY = new int[]{0,0,-1,1,0,0};
int[] neighborIndexZ = new int[]{0,0,0,0,-1,1}; int[] neighborIndexZ = new int[]{0,0,0,0,-1,1};
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ for(int x = 0; x < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){ for(int y = 0; y < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ for(int z = 0; z < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; z++){
if(weights[x][y][z] > 0){ if(weights[x][y][z] > 0){
continue; continue;
} }
@ -276,9 +276,9 @@ public class FluidCell {
int currY = y + neighborIndexY[i]; int currY = y + neighborIndexY[i];
int currZ = z + neighborIndexZ[i]; int currZ = z + neighborIndexZ[i];
if( if(
currX >= 0 && currX < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE && currX >= 0 && currX < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE &&
currY >= 0 && currY < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE && currY >= 0 && currY < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE &&
currZ >= 0 && currZ < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE && currZ >= 0 && currZ < ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE &&
(1 + weights[x][y][z]) < weights[currX][currY][currZ] (1 + weights[x][y][z]) < weights[currX][currY][currZ]
){ ){
weights[x][y][z] = -(1 - weights[currX][currY][currZ]); weights[x][y][z] = -(1 - weights[currX][currY][currZ]);

View File

@ -28,9 +28,24 @@ public class ServerFluidChunk {
static final int CENTER_BUFF = 13; static final int CENTER_BUFF = 13;
/** /**
* Dimension of a fluid buffer * Size of the true data. This is the data that is for this world position in particular
*/ */
public static final int BUFFER_DIM = 18; public static final int TRUE_DATA_DIM = 16;
/**
* Size of the true data generator for meshing
*/
public static final int TRUE_DATA_GENERATOR_SIZE = TRUE_DATA_DIM + 1;
/**
* Number of positions to offset into the buffer before you will access the true data
*/
public static final int TRUE_DATA_OFFSET = 1;
/**
* Dimension of a fluid buffer. This includes positions that just store neighbor values
*/
public static final int BUFFER_DIM = TRUE_DATA_DIM + 2;
/** /**
* Size of a fluid buffer * Size of a fluid buffer
@ -119,6 +134,11 @@ public class ServerFluidChunk {
*/ */
public int chunkMask; public int chunkMask;
/**
* Tracks whether this chunk was updated or not
*/
public boolean updated = false;
/** /**
* Constructor * Constructor
* @param worldX The world x coordinate * @param worldX The world x coordinate
@ -396,5 +416,12 @@ public class ServerFluidChunk {
return this.chunkMask; return this.chunkMask;
} }
/**
* Gets whether this chunk updated in its most recent frame or not
* @return true if it updated, false otherwise
*/
public boolean getUpdated(){
return updated;
}
} }

View File

@ -60,7 +60,7 @@ public class ServerFluidManager {
ServerTerrainManager serverTerrainManager; ServerTerrainManager serverTerrainManager;
//controls whether fluid simulation should actually happen or not //controls whether fluid simulation should actually happen or not
boolean simulate = false; boolean simulate = true;
@Exclude @Exclude
/** /**

View File

@ -30,6 +30,11 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
@Override @Override
public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){ public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){
FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP); FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP);
for(ServerFluidChunk fluidChunk : fluidChunks){
if(fluidChunk.getUpdated()){
broadcastQueue.add(fluidChunk);
}
}
} }
/** /**

View File

@ -3,7 +3,6 @@ package electrosphere.server.fluid.simulator;
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;
/** /**
* Simulates server fluid chunks via cellular automata * Simulates server fluid chunks via cellular automata
@ -36,13 +35,13 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
//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;
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ for(int x = ServerFluidChunk.TRUE_DATA_OFFSET; x < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ for(int y = ServerFluidChunk.TRUE_DATA_OFFSET; y < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ for(int z = ServerFluidChunk.TRUE_DATA_OFFSET; z < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; z++){
if(fluidChunk.getWeight(x, y, z) <= 0){ if(fluidChunk.getWeight(x, y, z) <= 0){
continue; continue;
} else { } else {
if(y > 0 && fluidChunk.getWeight(x, y - 1, z) < MAX_WEIGHT){ if(y > ServerFluidChunk.TRUE_DATA_OFFSET && fluidChunk.getWeight(x, y - 1, z) < 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);
fluidChunk.setWeight(x, y - 1, z, fluidChunk.getWeight(x, y - 1, z) + GRAVITY_DIFF); fluidChunk.setWeight(x, y - 1, z, fluidChunk.getWeight(x, y - 1, z) + GRAVITY_DIFF);
@ -53,8 +52,8 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
int realX = x + offsetX[i]; int realX = x + offsetX[i];
int realZ = z + offsetZ[i]; int realZ = z + offsetZ[i];
if(realX > 0 && realX < ServerTerrainChunk.CHUNK_DIMENSION - 1 && if(realX > ServerFluidChunk.TRUE_DATA_OFFSET && realX < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET - 1 &&
realZ > 0 && realZ < ServerTerrainChunk.CHUNK_DIMENSION - 1 realZ > ServerFluidChunk.TRUE_DATA_OFFSET && realZ < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET - 1
){ ){
if( if(
fluidChunk.getWeight(realX, y, realZ) < fluidChunk.getWeight(x, y, z) && fluidChunk.getWeight(realX, y, realZ) < fluidChunk.getWeight(x, y, z) &&