server fluid storage conversion
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 13:23:20 -05:00
parent 2d8b172f16
commit 72e6a6d0cb
6 changed files with 117 additions and 73 deletions

View File

@ -1195,6 +1195,7 @@ Fix viewport loading
(11/30/2024)
Water spawner firing on repeat
Convert server side fluid storage to using buffers

View File

@ -399,41 +399,39 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
//The length along each access of the chunk data. Typically, should be at least 17.
//Because CHUNK_SIZE is 16, 17 adds the necessary extra value. Each chunk needs the value of the immediately following position to generate
//chunk data that connects seamlessly to the next chunk.
int xWidth = chunk.getWeights().length;
int yWidth = chunk.getWeights()[0].length;
int zWidth = chunk.getWeights()[0][0].length;
int dataLength = chunk.getWeights().limit();
ByteBuffer buffer = ByteBuffer.allocate(xWidth*yWidth*zWidth*(4+4+4+4));
ByteBuffer buffer = ByteBuffer.allocate(dataLength*(4+4+4+4));
FloatBuffer floatView = buffer.asFloatBuffer();
for(int x = 0; x < xWidth; x++){
for(int y = 0; y < yWidth; y++){
for(int z = 0; z < zWidth; z++){
floatView.put(chunk.getWeights()[x][y][z]);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
floatView.put(chunk.getWeight(x, y, z));
}
}
}
for(int x = 0; x < xWidth; x++){
for(int y = 0; y < yWidth; y++){
for(int z = 0; z < zWidth; z++){
floatView.put(chunk.getVelocityX()[x][y][z]);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
floatView.put(chunk.getVelocityX(x, y, z));
}
}
}
for(int x = 0; x < xWidth; x++){
for(int y = 0; y < yWidth; y++){
for(int z = 0; z < zWidth; z++){
floatView.put(chunk.getVelocityY()[x][y][z]);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
floatView.put(chunk.getVelocityY(x, y, z));
}
}
}
for(int x = 0; x < xWidth; x++){
for(int y = 0; y < yWidth; y++){
for(int z = 0; z < zWidth; z++){
floatView.put(chunk.getVelocityZ()[x][y][z]);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
floatView.put(chunk.getVelocityZ(x, y, z));
}
}
}

View File

@ -105,39 +105,35 @@ public class FluidDiskMap {
ByteBuffer buffer = ByteBuffer.wrap(rawData);
FloatBuffer floatView = buffer.asFloatBuffer();
int DIM = ServerTerrainChunk.CHUNK_DIMENSION;
float[][][] weights = new float[DIM][DIM][DIM];
float[][][] velocityX = new float[DIM][DIM][DIM];
float[][][] velocityY = new float[DIM][DIM][DIM];
float[][][] velocityZ = new float[DIM][DIM][DIM];
rVal = new ServerFluidChunk(worldX, worldY, worldZ);
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
weights[x][y][z] = floatView.get();
rVal.setWeight(x, y, z, floatView.get());
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
velocityX[x][y][z] = floatView.get();
rVal.setVelocityX(x, y, z, floatView.get());
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
velocityY[x][y][z] = floatView.get();
rVal.setVelocityY(x, y, z, floatView.get());
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
velocityZ[x][y][z] = floatView.get();
rVal.setVelocityZ(x, y, z, floatView.get());
}
}
}
rVal = new ServerFluidChunk(worldX, worldY, worldZ, weights, velocityX, velocityY, velocityZ);
}
}
return rVal;
@ -158,38 +154,34 @@ public class FluidDiskMap {
fileName = chunkKey + ".dat";
}
//generate binary for the file
float[][][] weights = fluidChunk.getWeights();
float[][][] velocityX = fluidChunk.getVelocityX();
float[][][] velocityY = fluidChunk.getVelocityY();
float[][][] velocityZ = fluidChunk.getVelocityZ();
int DIM = ServerTerrainChunk.CHUNK_DIMENSION;
ByteBuffer buffer = ByteBuffer.allocate(DIM * DIM * DIM * 4 + DIM * DIM * DIM * 4 + DIM * DIM * DIM * 4 + DIM * DIM * DIM * 4);
FloatBuffer floatView = buffer.asFloatBuffer();
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
floatView.put(weights[x][y][z]);
floatView.put(fluidChunk.getWeight(x, y, z));
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
floatView.put(velocityX[x][y][z]);
floatView.put(fluidChunk.getVelocityX(x,y,z));
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
floatView.put(velocityY[x][y][z]);
floatView.put(fluidChunk.getVelocityY(x,y,z));
}
}
}
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
floatView.put(velocityZ[x][y][z]);
floatView.put(fluidChunk.getVelocityZ(x,y,z));
}
}
}

View File

@ -2,17 +2,12 @@ package electrosphere.server.fluid.generation;
import electrosphere.server.fluid.manager.ServerFluidChunk;
import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
public class DefaultFluidGenerator implements FluidGenerator {
@Override
public ServerFluidChunk generateChunk(int worldX, int worldY, int worldZ) {
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
float[][][] velocityX = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
float[][][] velocityY = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
float[][][] velocityZ = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
ServerFluidChunk chunk = new ServerFluidChunk(worldX, worldY, worldZ, weights, velocityX, velocityY, velocityZ);
ServerFluidChunk chunk = new ServerFluidChunk(worldX, worldY, worldZ);
return chunk;
}

View File

@ -1,8 +1,13 @@
package electrosphere.server.fluid.manager;
import java.nio.FloatBuffer;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.lwjgl.BufferUtils;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/**
@ -12,19 +17,19 @@ public class ServerFluidChunk {
int worldX, worldY, worldZ;
float[][][] weights;
float[][][] velocityX;
float[][][] velocityY;
float[][][] velocityZ;
FloatBuffer weights;
FloatBuffer velocityX;
FloatBuffer velocityY;
FloatBuffer velocityZ;
public ServerFluidChunk(
int worldX,
int worldY,
int worldZ,
float[][][] weights,
float[][][] velocityX,
float[][][] velocityY,
float[][][] velocityZ
FloatBuffer weights,
FloatBuffer velocityX,
FloatBuffer velocityY,
FloatBuffer velocityZ
) {
this.worldX = worldX;
this.worldY = worldY;
@ -35,6 +40,20 @@ public class ServerFluidChunk {
this.velocityZ = velocityZ;
}
public ServerFluidChunk(
int worldX,
int worldY,
int worldZ
) {
this.worldX = worldX;
this.worldY = worldY;
this.worldZ = worldZ;
this.weights = BufferUtils.createFloatBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION);
this.velocityX = BufferUtils.createFloatBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION);
this.velocityY = BufferUtils.createFloatBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION);
this.velocityZ = BufferUtils.createFloatBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION);
}
public int getWorldX() {
return worldX;
}
@ -55,7 +74,7 @@ public class ServerFluidChunk {
return new Vector3i(worldX,worldY,worldZ);
}
public float[][][] getWeights() {
public FloatBuffer getWeights() {
return weights;
}
@ -76,7 +95,7 @@ public class ServerFluidChunk {
* @return The weight of the specified voxel
*/
public float getWeight(int x, int y, int z){
return weights[x][y][z];
return weights.get(this.IX(x,y,z));
}
/**
@ -87,54 +106,94 @@ public class ServerFluidChunk {
* @param weight The weight
*/
public void setWeight(int x, int y, int z, float weight){
weights[x][y][z] = weight;
weights.put(this.IX(x,y,z),weight);
}
//get velocity x
public float[][][] getVelocityX() {
public FloatBuffer getVelocityX() {
return velocityX;
}
public float getVelocityX(int x, int y, int z){
return velocityX.get(this.IX(x, y, z));
}
//set velocity x
public void setVelocityX(float[][][] velocityX) {
public void setVelocityX(FloatBuffer velocityX) {
this.velocityX = velocityX;
}
public void setVelocityX(int x, int y, int z, float velocity){
this.velocityX.put(this.IX(x,y,z),velocity);
}
//get velocity y
public float[][][] getVelocityY() {
public FloatBuffer getVelocityY() {
return velocityY;
}
public float getVelocityY(int x, int y, int z){
return velocityY.get(this.IX(x, y, z));
}
//set velocity y
public void setVelocityY(float[][][] velocityY) {
public void setVelocityY(FloatBuffer velocityY) {
this.velocityY = velocityY;
}
public void setVelocityY(int x, int y, int z, float velocity){
this.velocityY.put(this.IX(x,y,z),velocity);
}
//get velocity z
public float[][][] getVelocityZ() {
public FloatBuffer getVelocityZ() {
return velocityZ;
}
public float getVelocityZ(int x, int y, int z){
return velocityZ.get(this.IX(x, y, z));
}
//set velocity z
public void setVelocityZ(float[][][] velocityZ) {
public void setVelocityZ(FloatBuffer velocityZ) {
this.velocityZ = velocityZ;
}
public void setVelocityZ(int x, int y, int z, float velocity){
this.velocityZ.put(this.IX(x,y,z),velocity);
}
//get a velocity at a given x, y and z as a Vector3f
public Vector3f getVelocity(int x, int y, int z){
return new Vector3f(velocityX[x][y][z],velocityY[x][y][z],velocityZ[x][y][z]);
int index = this.IX(x,y,z);
return new Vector3f(
velocityX.get(index),
velocityY.get(index),
velocityZ.get(index)
);
}
//set a velocity at a given x, y, and z given three ints
public void setVelocity(int x, int y, int z, float velX, float velY, float velZ){
velocityX[x][y][z] = velX;
velocityY[x][y][z] = velY;
velocityZ[x][y][z] = velZ;
int index = this.IX(x,y,z);
velocityX.put(index, velX);
velocityY.put(index, velY);
velocityZ.put(index, velZ);
}
/**
* Gets the inddex into the buffer
* @param x The x position
* @param y The y position
* @param z The z position
* @return The index
*/
public int IX(int x, int y, int z){
return x * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION + y * ServerTerrainChunk.CHUNK_DIMENSION + z;
}
}

View File

@ -16,7 +16,6 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
@Override
public boolean simulate(ServerFluidChunk fluidChunk, ServerTerrainChunk terrainChunk, int worldX, int worldY, int worldZ) {
float[][][] weights = fluidChunk.getWeights();
float[][][] terrainWeights = terrainChunk.getWeights();
//if true, alerts the server data cell to broadcast a new update message to all clients within it
@ -25,13 +24,13 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
if(weights[x][y][z] <= 0){
if(fluidChunk.getWeight(x, y, z) <= 0){
continue;
} else {
if(y > 0 && weights[x][y-1][z] < MAX_WEIGHT){
if(y > 0 && fluidChunk.getWeight(x, y - 1, z) < MAX_WEIGHT){
update = true;
weights[x][y][z] -= GRAVITY_DIFF;
weights[x][y-1][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);
} else {
//propagate sideways
int[] offsetX = new int[]{-1,1,0,0};
@ -43,12 +42,12 @@ public class FluidCellularAutomataSimulator implements ServerFluidSimulator {
realZ > 0 && realZ < ServerTerrainChunk.CHUNK_DIMENSION - 1
){
if(
weights[realX][y][realZ] < weights[x][y][z] &&
fluidChunk.getWeight(realX, y, realZ) < fluidChunk.getWeight(x, y, z) &&
terrainWeights[realX][y][realZ] < MAX_WEIGHT
){
update = true;
weights[x][y][z] -= GRAVITY_DIFF;
weights[realX][y][realZ] += GRAVITY_DIFF;
fluidChunk.setWeight(x, y, z, fluidChunk.getWeight(x, y, z) - GRAVITY_DIFF);
fluidChunk.setWeight(realX, y, realZ, fluidChunk.getWeight(realX, y, realZ) + GRAVITY_DIFF);
}
}
}