diff --git a/.vscode/settings.json b/.vscode/settings.json index 5a02e9dc..25cd09f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,6 +17,8 @@ "chunkmask.h": "c", "metadatacalc.h": "c", "immintrin.h": "c", - "stdint.h": "c" + "stdint.h": "c", + "electrosphere_server_fluid_manager_serverfluidchunk.h": "c", + "stdio.h": "c" } } \ No newline at end of file diff --git a/buildNumber.properties b/buildNumber.properties index d8297665..36f6d424 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sun Dec 01 11:59:35 EST 2024 -buildNumber=449 +#Sun Dec 01 12:58:18 EST 2024 +buildNumber=462 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 9690ea2b..4cb21ffc 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1205,6 +1205,7 @@ Break out solver consts Move header file generation location Add more debugging tools for fluids Remove conditional update check in fluid sim +Explicit memory management of fluid chunk cache buffers diff --git a/src/fluid/compile.sh b/src/fluid/compile.sh index 419d345a..a4bbb593 100644 --- a/src/fluid/compile.sh +++ b/src/fluid/compile.sh @@ -69,16 +69,21 @@ OUTPUT_FILE="./fluidsim.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -DSAVE_STEPS=$SAVE_STEPS" -INPUT_FILES="./src/metadatacalc.c" +INPUT_FILES="./src/metadata/metadatacalc.c" OUTPUT_FILE="./metadatacalc.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE +COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -DSAVE_STEPS=$SAVE_STEPS" +INPUT_FILES="./src/mem/fluidmem.c" +OUTPUT_FILE="./fluidmem.o" +gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE + #compile shared object file OUTPUT_FILE="libfluidsim$LIB_ENDING" COMPILE_FLAGS="-shared" -INPUT_FILES="fluidsim.o javainterface.o metadatacalc.o" +INPUT_FILES="fluidsim.o javainterface.o metadatacalc.o fluidmem.o" gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE #move to resources diff --git a/src/fluid/src/mem/fluidmem.c b/src/fluid/src/mem/fluidmem.c new file mode 100644 index 00000000..3285f12b --- /dev/null +++ b/src/fluid/src/mem/fluidmem.c @@ -0,0 +1,234 @@ +#include +#include + +#include "../../../main/c/includes/electrosphere_server_fluid_manager_ServerFluidChunk.h" +#include "../../../main/c/includes/electrosphere_client_fluid_cache_FluidChunkData.h" + +/** + * Size of a single buffer + */ +#define BUFF_SIZE 18 *18 * 18 * 4 + +/** + * The center position of the buffer array + */ +#define CENTER_POS 13 + + +/** + * Allocates the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to allocate + */ +void allocateCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId); + +/** + * Frees the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to free + */ +void freeCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId); + +/** + * Allocates the buffer of an object + * @param env The JNI env + * @param fluidObj The object containing the buffer field + * @param arrFieldId The specific field to allocate + */ +void allocateField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId); + +/** + * Frees the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to free + */ +void freeField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId); + +/** + * Allocates the buffers for the fluid chunk + * @param env The JNI env + * @param fluidObj The fluid object + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_allocate( + JNIEnv * env, + jobject fluidObj + ){ + jclass serverFluidChunkClass = (*env)->GetObjectClass(env,fluidObj); + jfieldID dId = (*env)->GetFieldID(env,serverFluidChunkClass,"bWeights","[Ljava/nio/ByteBuffer;"); + jfieldID d0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0Weights","[Ljava/nio/ByteBuffer;"); + jfieldID uId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID vId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID wId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityZ","[Ljava/nio/ByteBuffer;"); + jfieldID u0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID v0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID w0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); + allocateCenterField(env,fluidObj,dId); + allocateCenterField(env,fluidObj,d0Id); + allocateCenterField(env,fluidObj,uId); + allocateCenterField(env,fluidObj,vId); + allocateCenterField(env,fluidObj,wId); + allocateCenterField(env,fluidObj,u0Id); + allocateCenterField(env,fluidObj,v0Id); + allocateCenterField(env,fluidObj,w0Id); +} + +/** + * Allocates the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to allocate + */ +void allocateCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + //actually allocate + void *buffer = calloc(1,BUFF_SIZE); + if (buffer == NULL) { + // Handle allocation failure + return; + } + // Create a direct ByteBuffer + jobject byteBuffer = (*env)->NewDirectByteBuffer(env, buffer, BUFF_SIZE); + if (byteBuffer == NULL) { + // Handle ByteBuffer creation failure + free(buffer); + return; + } + + //assign to array + jobject jd = (*env)->GetObjectField(env,fluidObj,arrFieldId); + (*env)->SetObjectArrayElement(env,jd,CENTER_POS,byteBuffer); +} + +/** + * Frees the buffers for the fluid chunk + * @param env The JNI env + * @param fluidObj The fluid object + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_free( + JNIEnv * env, + jobject fluidObj + ){ + jclass serverFluidChunkClass = (*env)->GetObjectClass(env,fluidObj); + jfieldID dId = (*env)->GetFieldID(env,serverFluidChunkClass,"bWeights","[Ljava/nio/ByteBuffer;"); + jfieldID d0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0Weights","[Ljava/nio/ByteBuffer;"); + jfieldID uId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID vId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID wId = (*env)->GetFieldID(env,serverFluidChunkClass,"bVelocityZ","[Ljava/nio/ByteBuffer;"); + jfieldID u0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID v0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID w0Id = (*env)->GetFieldID(env,serverFluidChunkClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); + freeCenterField(env,fluidObj,dId); + freeCenterField(env,fluidObj,d0Id); + freeCenterField(env,fluidObj,uId); + freeCenterField(env,fluidObj,vId); + freeCenterField(env,fluidObj,wId); + freeCenterField(env,fluidObj,u0Id); + freeCenterField(env,fluidObj,v0Id); + freeCenterField(env,fluidObj,w0Id); +} + +/** + * Frees the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to free + */ +void freeCenterField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + //grab the buffer + jobject jd = (*env)->GetObjectField(env,fluidObj,arrFieldId); + jobject buff = (*env)->GetObjectArrayElement(env,jd,CENTER_POS); + + //actually free + void *buffer = (*env)->GetDirectBufferAddress(env, buff); + if (buffer != NULL) { + // Free the allocated memory + free(buffer); + } + + //null the array element + (*env)->SetObjectArrayElement(env,jd,CENTER_POS,NULL); +} + +/** + * Allocates a fluid chunk's data + */ +JNIEXPORT void JNICALL Java_electrosphere_client_fluid_cache_FluidChunkData_allocate( + JNIEnv * env, + jobject fluidObj + ){ + jclass fluidChunkDataClass = (*env)->GetObjectClass(env,fluidObj); + jfieldID dId = (*env)->GetFieldID(env,fluidChunkDataClass,"bWeights","Ljava/nio/ByteBuffer;"); + jfieldID uId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityX","Ljava/nio/ByteBuffer;"); + jfieldID vId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityY","Ljava/nio/ByteBuffer;"); + jfieldID wId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityZ","Ljava/nio/ByteBuffer;"); + allocateField(env,fluidObj,dId); + allocateField(env,fluidObj,uId); + allocateField(env,fluidObj,vId); + allocateField(env,fluidObj,wId); +} + +/** + * Allocates the buffer of an object + * @param env The JNI env + * @param fluidObj The object containing the buffer field + * @param arrFieldId The specific field to allocate + */ +void allocateField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + //actually allocate + void *buffer = calloc(1,BUFF_SIZE); + if (buffer == NULL) { + // Handle allocation failure + return; + } + // Create a direct ByteBuffer + jobject byteBuffer = (*env)->NewDirectByteBuffer(env, buffer, BUFF_SIZE); + if (byteBuffer == NULL) { + // Handle ByteBuffer creation failure + free(buffer); + return; + } + + //assign to array + (*env)->SetObjectField(env,fluidObj,arrFieldId,byteBuffer); +} + +/** + * Frees a fluid chunk's data + */ +JNIEXPORT void JNICALL Java_electrosphere_client_fluid_cache_FluidChunkData_free( + JNIEnv * env, + jobject fluidObj + ){ + jclass fluidChunkDataClass = (*env)->GetObjectClass(env,fluidObj); + jfieldID dId = (*env)->GetFieldID(env,fluidChunkDataClass,"bWeights","Ljava/nio/ByteBuffer;"); + jfieldID uId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityX","Ljava/nio/ByteBuffer;"); + jfieldID vId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityY","Ljava/nio/ByteBuffer;"); + jfieldID wId = (*env)->GetFieldID(env,fluidChunkDataClass,"bVelocityZ","Ljava/nio/ByteBuffer;"); + freeField(env,fluidObj,dId); + freeField(env,fluidObj,uId); + freeField(env,fluidObj,vId); + freeField(env,fluidObj,wId); +} + +/** + * Frees the center buffer of a buffer array + * @param env The JNI env + * @param fluidObj The object containing the buffer arrays + * @param arrFieldId The specific field to free + */ +void freeField(JNIEnv * env, jobject fluidObj, jfieldID arrFieldId){ + //grab the buffer + jobject buff = (*env)->GetObjectField(env,fluidObj,arrFieldId); + + //actually free + void *buffer = (*env)->GetDirectBufferAddress(env, buff); + if (buffer != NULL) { + // Free the allocated memory + free(buffer); + } + + //null the array element + (*env)->SetObjectField(env,fluidObj,arrFieldId,NULL); +} \ No newline at end of file diff --git a/src/fluid/src/metadatacalc.c b/src/fluid/src/metadata/metadatacalc.c similarity index 92% rename from src/fluid/src/metadatacalc.c rename to src/fluid/src/metadata/metadatacalc.c index 84edb88f..d32c439c 100644 --- a/src/fluid/src/metadatacalc.c +++ b/src/fluid/src/metadata/metadatacalc.c @@ -2,9 +2,9 @@ #include #include -#include "../includes/utilities.h" -#include "../includes/chunkmask.h" -#include "../includes/metadatacalc.h" +#include "../../includes/utilities.h" +#include "../../includes/chunkmask.h" +#include "../../includes/metadatacalc.h" #define UPDATE_THRESHOLD 0.1 diff --git a/src/main/c/includes/electrosphere_client_fluid_cache_FluidChunkData.h b/src/main/c/includes/electrosphere_client_fluid_cache_FluidChunkData.h new file mode 100644 index 00000000..409bfa98 --- /dev/null +++ b/src/main/c/includes/electrosphere_client_fluid_cache_FluidChunkData.h @@ -0,0 +1,33 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class electrosphere_client_fluid_cache_FluidChunkData */ + +#ifndef _Included_electrosphere_client_fluid_cache_FluidChunkData +#define _Included_electrosphere_client_fluid_cache_FluidChunkData +#ifdef __cplusplus +extern "C" { +#endif +#undef electrosphere_client_fluid_cache_FluidChunkData_CHUNK_SIZE +#define electrosphere_client_fluid_cache_FluidChunkData_CHUNK_SIZE 18L +#undef electrosphere_client_fluid_cache_FluidChunkData_CHUNK_DATA_GENERATOR_SIZE +#define electrosphere_client_fluid_cache_FluidChunkData_CHUNK_DATA_GENERATOR_SIZE 17L +/* + * Class: electrosphere_client_fluid_cache_FluidChunkData + * Method: allocate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_client_fluid_cache_FluidChunkData_allocate + (JNIEnv *, jobject); + +/* + * Class: electrosphere_client_fluid_cache_FluidChunkData + * Method: free + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_client_fluid_cache_FluidChunkData_free + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/main/c/includes/electrosphere_server_fluid_manager_ServerFluidChunk.h b/src/main/c/includes/electrosphere_server_fluid_manager_ServerFluidChunk.h new file mode 100644 index 00000000..b711d93b --- /dev/null +++ b/src/main/c/includes/electrosphere_server_fluid_manager_ServerFluidChunk.h @@ -0,0 +1,43 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class electrosphere_server_fluid_manager_ServerFluidChunk */ + +#ifndef _Included_electrosphere_server_fluid_manager_ServerFluidChunk +#define _Included_electrosphere_server_fluid_manager_ServerFluidChunk +#ifdef __cplusplus +extern "C" { +#endif +#undef electrosphere_server_fluid_manager_ServerFluidChunk_ARRAY_CT +#define electrosphere_server_fluid_manager_ServerFluidChunk_ARRAY_CT 27L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_CENTER_BUFF +#define electrosphere_server_fluid_manager_ServerFluidChunk_CENTER_BUFF 13L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_DIM +#define electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_DIM 16L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_GENERATOR_SIZE +#define electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_GENERATOR_SIZE 17L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_OFFSET +#define electrosphere_server_fluid_manager_ServerFluidChunk_TRUE_DATA_OFFSET 1L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_BUFFER_DIM +#define electrosphere_server_fluid_manager_ServerFluidChunk_BUFFER_DIM 18L +#undef electrosphere_server_fluid_manager_ServerFluidChunk_BUFFER_SIZE +#define electrosphere_server_fluid_manager_ServerFluidChunk_BUFFER_SIZE 5832L +/* + * Class: electrosphere_server_fluid_manager_ServerFluidChunk + * Method: allocate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_allocate + (JNIEnv *, jobject); + +/* + * Class: electrosphere_server_fluid_manager_ServerFluidChunk + * Method: free + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_manager_ServerFluidChunk_free + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java b/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java index 9878c047..94ba847c 100644 --- a/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java +++ b/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java @@ -36,8 +36,9 @@ public class ClientFluidCache { public void addChunkDataToCache(int worldX, int worldY, int worldZ, FluidChunkData chunkData){ cacheMap.put(getKey(worldX,worldY,worldZ),chunkData); while(cacheList.size() > cacheSize){ - String currentChunk = cacheList.remove(0); - cacheMap.remove(currentChunk); + String currentKey = cacheList.remove(0); + FluidChunkData currentChunk = cacheMap.remove(currentKey); + currentChunk.freeBuffers(); } } diff --git a/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java b/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java index 25a3ccc0..e94cf8a5 100644 --- a/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java +++ b/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java @@ -1,5 +1,9 @@ package electrosphere.client.fluid.cache; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + import org.joml.Vector3i; import electrosphere.server.fluid.manager.ServerFluidChunk; @@ -13,31 +17,77 @@ public class FluidChunkData { 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 public static final int CHUNK_DATA_GENERATOR_SIZE = ServerFluidChunk.TRUE_DATA_GENERATOR_SIZE; - - //How much of that fluid type is in this voxel - float[][][] voxelWeight; - //The velocities - float[][][] velocityX; - float[][][] velocityY; - float[][][] velocityZ; + /** + * The float view of the center weight buffer + */ + FloatBuffer weights = null; + + /** + * The float view of the center velocity x buffer + */ + FloatBuffer velocityX = null; + + /** + * The float view of the center velocity y buffer + */ + FloatBuffer velocityY = null; + + /** + * The float view of the center velocity z buffer + */ + FloatBuffer velocityZ = null; + + /** + * The array of all adjacent weight buffers for the fluid sim + */ + public ByteBuffer bWeights = null; + + /** + * The array of all adjacent velocity x buffers for the fluid sim + */ + public ByteBuffer bVelocityX = null; + + /** + * The array of all adjacent velocity y buffers for the fluid sim + */ + public ByteBuffer bVelocityY = null; + + /** + * The array of all adjacent velocity z buffers for the fluid sim + */ + public ByteBuffer bVelocityZ = null; /** - * Gets the voxel weight array in this container - * @return The voxel weight array + * Constructor */ - public float[][][] getVoxelWeight(){ - return voxelWeight; + public FluidChunkData(){ + //allocate buffers + this.allocate(); + + //reorder + this.bWeights.order(ByteOrder.LITTLE_ENDIAN); + this.bVelocityX.order(ByteOrder.LITTLE_ENDIAN); + this.bVelocityY.order(ByteOrder.LITTLE_ENDIAN); + this.bVelocityZ.order(ByteOrder.LITTLE_ENDIAN); + + //get float view + this.weights = this.bWeights.asFloatBuffer(); + this.velocityX = this.bVelocityX.asFloatBuffer(); + this.velocityY = this.bVelocityY.asFloatBuffer(); + this.velocityZ = this.bVelocityZ.asFloatBuffer(); } /** - * Sets the voxel weight array in this container - * @param voxelWeight The voxel weight array + * 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 void setVoxelWeight(float[][][] voxelWeight){ - //update data - this.voxelWeight = voxelWeight; + public int IX(int x, int y, int z){ + return x * ServerFluidChunk.BUFFER_DIM * ServerFluidChunk.BUFFER_DIM + y * ServerFluidChunk.BUFFER_DIM + z; } /** @@ -46,7 +96,7 @@ public class FluidChunkData { * @return The weight of the specified voxel */ public float getWeight(Vector3i localPosition){ - return voxelWeight[localPosition.x][localPosition.y][localPosition.z]; + return weights.get(this.IX(localPosition.x,localPosition.y,localPosition.z)); } /** @@ -54,7 +104,92 @@ public class FluidChunkData { * @return The weight of the specified voxel */ public float getWeight(int x, int y, int z){ - return voxelWeight[x][y][z]; + return weights.get(this.IX(x,y,z)); + } + + /** + * Sets the weight at a given position + * @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 x velocity of a voxel at a poisiton + * @return The x velocity of the specified voxel + */ + public float getVelocityX(int x, int y, int z){ + return velocityX.get(this.IX(x,y,z)); + } + + /** + * Sets the x velocity at a given position + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @param vel The x velocity + */ + public void setVelocityX(int x, int y, int z, float vel){ + velocityX.put(this.IX(x,y,z),vel); + } + + /** + * Gets the y velocity of a voxel at a poisiton + * @return The y velocity of the specified voxel + */ + public float getVelocityY(int x, int y, int z){ + return velocityY.get(this.IX(x,y,z)); + } + + /** + * Sets the y velocity at a given position + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @param vel The y velocity + */ + public void setVelocityY(int x, int y, int z, float vel){ + velocityY.put(this.IX(x,y,z),vel); + } + + /** + * Gets the z velocity of a voxel at a poisiton + * @return The z velocity of the specified voxel + */ + public float getVelocityZ(int x, int y, int z){ + return velocityZ.get(this.IX(x,y,z)); + } + + /** + * Sets the z velocity at a given position + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @param vel The z velocity + */ + public void setVelocityZ(int x, int y, int z, float vel){ + velocityZ.put(this.IX(x,y,z),vel); + } + + /** + * Allocates the buffers 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(); } } diff --git a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java index d9e9c717..22209587 100644 --- a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java +++ b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java @@ -177,17 +177,14 @@ public class ClientFluidManager { * @return the object */ private FluidChunkData parseFluidDataBuffer(ByteBuffer buffer){ - float[][][] weights = new float[FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE]; - float[][][] velocityX = new float[FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE]; - float[][][] velocityY = new float[FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE]; - float[][][] velocityZ = new float[FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE][FluidChunkData.CHUNK_SIZE]; + FluidChunkData data = new FluidChunkData(); FloatBuffer floatBuffer = buffer.asFloatBuffer(); for(int x = 0; x < FluidChunkData.CHUNK_SIZE; x++){ for(int y = 0; y < FluidChunkData.CHUNK_SIZE; y++){ for(int z = 0; z < FluidChunkData.CHUNK_SIZE; z++){ - weights[x][y][z] = floatBuffer.get(); - if(weights[x][y][z] <= 0){ - weights[x][y][z] = FluidCell.ISO_SURFACE_EMPTY; + data.setWeight(x,y,z,floatBuffer.get()); + if(data.getWeight(x, y, z) <= 0){ + data.setWeight(x, y, z, FluidCell.ISO_SURFACE_EMPTY); } } } @@ -195,26 +192,25 @@ public class ClientFluidManager { for(int x = 0; x < FluidChunkData.CHUNK_SIZE; x++){ for(int y = 0; y < FluidChunkData.CHUNK_SIZE; y++){ for(int z = 0; z < FluidChunkData.CHUNK_SIZE; z++){ - velocityX[x][y][z] = floatBuffer.get(); + data.setVelocityX(x, y, z, floatBuffer.get()); } } } for(int x = 0; x < FluidChunkData.CHUNK_SIZE; x++){ for(int y = 0; y < FluidChunkData.CHUNK_SIZE; y++){ for(int z = 0; z < FluidChunkData.CHUNK_SIZE; z++){ - velocityY[x][y][z] = floatBuffer.get(); + data.setVelocityY(x, y, z, floatBuffer.get()); } } } for(int x = 0; x < FluidChunkData.CHUNK_SIZE; x++){ for(int y = 0; y < FluidChunkData.CHUNK_SIZE; y++){ for(int z = 0; z < FluidChunkData.CHUNK_SIZE; z++){ - velocityZ[x][y][z] = floatBuffer.get(); + data.setVelocityZ(x, y, z, floatBuffer.get()); } } } - FluidChunkData data = new FluidChunkData(); - data.setVoxelWeight(weights); + // data.setVoxelWeight(weights); return data; } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index 3d01b16a..e53b46a0 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -154,14 +154,7 @@ public class ServerFluidChunk { this.worldZ = worldZ; //allocate - this.bWeights[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.bVelocityX[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.bVelocityY[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.bVelocityZ[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.b0Weights[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.b0VelocityX[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.b0VelocityY[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); - this.b0VelocityZ[CENTER_BUFF] = ByteBuffer.allocateDirect(BUFFER_SIZE * 4); + this.allocate(); //order this.bWeights[CENTER_BUFF].order(ByteOrder.LITTLE_ENDIAN); @@ -467,4 +460,21 @@ public class ServerFluidChunk { } } + /** + * 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(); + } + } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index 1b620cbc..c0a28306 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -70,7 +70,7 @@ public class ServerFluidManager { ServerTerrainManager serverTerrainManager; //controls whether fluid simulation should actually happen or not - boolean simulate = true; + boolean simulate = false; @Exclude /** @@ -217,8 +217,10 @@ public class ServerFluidManager { returnedChunk = chunkCache.get(key); } else { if(chunkCacheContents.size() > cacheSize){ - String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1); - chunkCache.remove(oldChunk); + String oldChunkKey = chunkCacheContents.remove(chunkCacheContents.size() - 1); + ServerFluidChunk oldChunk = chunkCache.remove(oldChunkKey); + oldChunk.freeBuffers(); + this.linkNeighbors(null, oldChunk.getWorldX(), oldChunk.getWorldY(), oldChunk.getWorldZ()); } //pull from disk if it exists if(chunkDiskMap != null){ @@ -351,7 +353,9 @@ public class ServerFluidManager { ){ key = this.getKey(worldX + i,worldY +j,worldZ + k); ServerFluidChunk neighbor = this.chunkCache.get(key); - current.setNeighbor(i+1,j+1,k+1,neighbor); + if(current != null){ + current.setNeighbor(i+1,j+1,k+1,neighbor); + } if(neighbor != null){ neighbor.setNeighbor(1-i,1-j,1-k,current); }