481 lines
13 KiB
Java
481 lines
13 KiB
Java
package electrosphere.server.fluid.manager;
|
|
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.FloatBuffer;
|
|
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3i;
|
|
|
|
|
|
/**
|
|
* Is a single chunk of terrain on the server
|
|
*/
|
|
public class ServerFluidChunk {
|
|
|
|
|
|
/**
|
|
* Number of adjacent arrays
|
|
*/
|
|
static final int ARRAY_CT = 27;
|
|
|
|
/**
|
|
* Index of the center buffer
|
|
*/
|
|
static final int CENTER_BUFF = 13;
|
|
|
|
/**
|
|
* Size of the true data. This is the data that is for this world position in particular
|
|
*/
|
|
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
|
|
*/
|
|
public static final int BUFFER_SIZE = ServerFluidChunk.BUFFER_DIM * ServerFluidChunk.BUFFER_DIM * ServerFluidChunk.BUFFER_DIM;
|
|
|
|
|
|
/**
|
|
* The world x coordinate of this chunk
|
|
*/
|
|
int worldX;
|
|
|
|
/**
|
|
* The world y coordinate of this chunk
|
|
*/
|
|
int worldY;
|
|
|
|
/**
|
|
* The world z coordinate of this chunk
|
|
*/
|
|
int worldZ;
|
|
|
|
|
|
/**
|
|
* The float view of the center weight buffer
|
|
*/
|
|
FloatBuffer weights;
|
|
|
|
/**
|
|
* The float view of the center velocity x buffer
|
|
*/
|
|
FloatBuffer velocityX;
|
|
|
|
/**
|
|
* The float view of the center velocity y buffer
|
|
*/
|
|
FloatBuffer velocityY;
|
|
|
|
/**
|
|
* The float view of the center velocity z buffer
|
|
*/
|
|
FloatBuffer velocityZ;
|
|
|
|
/**
|
|
* The array of all adjacent weight buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] bWeights = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity x buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] bVelocityX = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity y buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] bVelocityY = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity z buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] bVelocityZ = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent weight buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] b0Weights = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity x buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] b0VelocityX = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity y buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] b0VelocityY = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The array of all adjacent velocity z buffers for the fluid sim
|
|
*/
|
|
public ByteBuffer[] b0VelocityZ = new ByteBuffer[ARRAY_CT];
|
|
|
|
/**
|
|
* The chunk mask -- Stores which adjacent chunks are populated and which aren't
|
|
*/
|
|
public int chunkMask;
|
|
|
|
/**
|
|
* Tracks whether this chunk was updated or not
|
|
*/
|
|
public boolean updated = false;
|
|
|
|
/**
|
|
* The total density of the chunk
|
|
*/
|
|
public float totalDensity = 0;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param worldX The world x coordinate
|
|
* @param worldY The world y coordinate
|
|
* @param worldZ The world z coordinate
|
|
*/
|
|
public ServerFluidChunk(int worldX, int worldY, int worldZ) {
|
|
this.worldX = worldX;
|
|
this.worldY = worldY;
|
|
this.worldZ = worldZ;
|
|
|
|
//allocate
|
|
this.allocate();
|
|
|
|
//order
|
|
this.bWeights[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.bVelocityX[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.bVelocityY[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.bVelocityZ[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.b0Weights[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.b0VelocityX[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.b0VelocityY[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
this.b0VelocityZ[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN);
|
|
|
|
//get float view
|
|
this.weights = this.bWeights[CENTER_BUFF].asFloatBuffer();
|
|
this.velocityX = this.bVelocityX[CENTER_BUFF].asFloatBuffer();
|
|
this.velocityY = this.bVelocityY[CENTER_BUFF].asFloatBuffer();
|
|
this.velocityZ = this.bVelocityZ[CENTER_BUFF].asFloatBuffer();
|
|
}
|
|
|
|
/**
|
|
* Gets the world x coordinate
|
|
* @return The world x coordinate
|
|
*/
|
|
public int getWorldX() {
|
|
return worldX;
|
|
}
|
|
|
|
/**
|
|
* Gets the world y coordinate
|
|
* @return The world y coordinate
|
|
*/
|
|
public int getWorldY() {
|
|
return worldY;
|
|
}
|
|
|
|
/**
|
|
* Gets the world z coordinate
|
|
* @return The world z coordinate
|
|
*/
|
|
public int getWorldZ() {
|
|
return worldZ;
|
|
}
|
|
|
|
/**
|
|
* Gets the world position of this terrain chunk as a joml Vector
|
|
* @return The vector
|
|
*/
|
|
public Vector3i getWorldPosition(){
|
|
return new Vector3i(worldX,worldY,worldZ);
|
|
}
|
|
|
|
/**
|
|
* Gets the weights buffer
|
|
* @return The weight buffer
|
|
*/
|
|
public FloatBuffer getWeights() {
|
|
return weights;
|
|
}
|
|
|
|
/**
|
|
* Gets the weight of a voxel at a poisiton
|
|
* @param localPosition The local position
|
|
* @return The weight of the specified voxel
|
|
*/
|
|
public float getWeight(Vector3i localPosition){
|
|
return getWeight(localPosition.x,localPosition.y,localPosition.z);
|
|
}
|
|
|
|
/**
|
|
* Gets the weight of a voxel at a poisiton
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The weight of the specified voxel
|
|
*/
|
|
public float getWeight(int x, int y, int z){
|
|
return weights.get(this.IX(x,y,z));
|
|
}
|
|
|
|
/**
|
|
* Sets a weight
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param weight The weight
|
|
*/
|
|
public void setWeight(int x, int y, int z, float weight){
|
|
weights.put(this.IX(x,y,z),weight);
|
|
}
|
|
|
|
/**
|
|
* Gets the velocity x buffer
|
|
* @return The velocity x buffer
|
|
*/
|
|
public FloatBuffer getVelocityX() {
|
|
return velocityX;
|
|
}
|
|
|
|
/**
|
|
* Gets the x velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The x velocity at the point
|
|
*/
|
|
public float getVelocityX(int x, int y, int z){
|
|
return velocityX.get(this.IX(x, y, z));
|
|
}
|
|
|
|
|
|
/**
|
|
* Sets the velocity x buffer
|
|
* @param velocityX The velocity x buffer
|
|
*/
|
|
public void setVelocityX(FloatBuffer velocityX) {
|
|
this.velocityX = velocityX;
|
|
}
|
|
|
|
/**
|
|
* Sets the x velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param velocity The x velocity
|
|
*/
|
|
public void setVelocityX(int x, int y, int z, float velocity){
|
|
this.velocityX.put(this.IX(x,y,z),velocity);
|
|
}
|
|
|
|
/**
|
|
* Gets the velocity y buffer
|
|
* @return The velocity y buffer
|
|
*/
|
|
public FloatBuffer getVelocityY() {
|
|
return velocityY;
|
|
}
|
|
|
|
/**
|
|
* Gets the y velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The y velocity at the point
|
|
*/
|
|
public float getVelocityY(int x, int y, int z){
|
|
return velocityY.get(this.IX(x, y, z));
|
|
}
|
|
|
|
/**
|
|
* Sets the velocity y buffer
|
|
* @param velocityY The velocity y buffer
|
|
*/
|
|
public void setVelocityY(FloatBuffer velocityY) {
|
|
this.velocityY = velocityY;
|
|
}
|
|
|
|
/**
|
|
* Sets the y velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param velocity The y velocity
|
|
*/
|
|
public void setVelocityY(int x, int y, int z, float velocity){
|
|
this.velocityY.put(this.IX(x,y,z),velocity);
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the velocity z buffer
|
|
* @return The velocity z buffer
|
|
*/
|
|
public FloatBuffer getVelocityZ() {
|
|
return velocityZ;
|
|
}
|
|
|
|
/**
|
|
* Gets the z velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The z velocity at the point
|
|
*/
|
|
public float getVelocityZ(int x, int y, int z){
|
|
return velocityZ.get(this.IX(x, y, z));
|
|
}
|
|
|
|
/**
|
|
* Sets the velocity z buffer
|
|
* @param velocityZ The velocity z buffer
|
|
*/
|
|
public void setVelocityZ(FloatBuffer velocityZ) {
|
|
this.velocityZ = velocityZ;
|
|
}
|
|
|
|
/**
|
|
* Sets the z velocity at the point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param velocity The z velocity
|
|
*/
|
|
public void setVelocityZ(int x, int y, int z, float velocity){
|
|
this.velocityZ.put(this.IX(x,y,z),velocity);
|
|
}
|
|
|
|
/**
|
|
* Gets the velocity at a given point as a vector3f
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The velocity
|
|
*/
|
|
public Vector3f getVelocity(int x, int y, int 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
|
|
/**
|
|
* Sets the full velocity at a given point
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param velX The x component of the velocity
|
|
* @param velY The y component of the velocity
|
|
* @param velZ The z component of the velocity
|
|
*/
|
|
public void setVelocity(int x, int y, int z, float velX, float velY, float 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 * ServerFluidChunk.BUFFER_DIM * ServerFluidChunk.BUFFER_DIM + y * ServerFluidChunk.BUFFER_DIM + z;
|
|
}
|
|
|
|
/**
|
|
* Gets the chunk mask for this chunk
|
|
* @return The chunk mask
|
|
*/
|
|
public int getChunkMask(){
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Gets the neighbor index given an offset in each dimension
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @return The neighbor index
|
|
*/
|
|
public static final int getNeighborIndex(int x, int y, int z){
|
|
return x + y * 3 + z * 3 * 3;
|
|
}
|
|
|
|
/**
|
|
* Sets the neighbor of this chunk
|
|
* @param x The x coordinate
|
|
* @param y The y coordinate
|
|
* @param z The z coordinate
|
|
* @param neighbor The neighbor ServerFluidChunk
|
|
*/
|
|
public void setNeighbor(int x, int y, int z, ServerFluidChunk neighbor){
|
|
if(neighbor == null){
|
|
bWeights[getNeighborIndex(x,y,z)] = null;
|
|
b0Weights[getNeighborIndex(x,y,z)] = null;
|
|
bVelocityX[getNeighborIndex(x,y,z)] = null;
|
|
bVelocityY[getNeighborIndex(x,y,z)] = null;
|
|
bVelocityZ[getNeighborIndex(x,y,z)] = null;
|
|
b0VelocityX[getNeighborIndex(x,y,z)] = null;
|
|
b0VelocityY[getNeighborIndex(x,y,z)] = null;
|
|
b0VelocityZ[getNeighborIndex(x,y,z)] = null;
|
|
} else {
|
|
bWeights[getNeighborIndex(x,y,z)] = neighbor.bWeights[CENTER_BUFF];
|
|
b0Weights[getNeighborIndex(x,y,z)] = neighbor.b0Weights[CENTER_BUFF];
|
|
bVelocityX[getNeighborIndex(x,y,z)] = neighbor.bVelocityX[CENTER_BUFF];
|
|
bVelocityY[getNeighborIndex(x,y,z)] = neighbor.bVelocityY[CENTER_BUFF];
|
|
bVelocityZ[getNeighborIndex(x,y,z)] = neighbor.bVelocityZ[CENTER_BUFF];
|
|
b0VelocityX[getNeighborIndex(x,y,z)] = neighbor.b0VelocityX[CENTER_BUFF];
|
|
b0VelocityY[getNeighborIndex(x,y,z)] = neighbor.b0VelocityY[CENTER_BUFF];
|
|
b0VelocityZ[getNeighborIndex(x,y,z)] = neighbor.b0VelocityZ[CENTER_BUFF];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allocates the central arrays for this chunk
|
|
*/
|
|
private native void allocate();
|
|
|
|
/**
|
|
* Frees all native memory
|
|
*/
|
|
private native void free();
|
|
|
|
/**
|
|
* Frees the buffers contained within this chunk
|
|
*/
|
|
public void freeBuffers(){
|
|
this.free();
|
|
}
|
|
|
|
}
|