From 57ab3158fe3aeb19a6f468cb6deae848087529b0 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 30 Nov 2024 16:33:53 -0500 Subject: [PATCH] work on integrating c fluid sim --- buildNumber.properties | 4 +- src/fluid/compile.sh | 2 +- ...luid_simulator_FluidAcceleratedSimulator.h | 8 +++ src/fluid/src/javainterface.c | 38 ++++++++--- .../server/datacell/RealmManager.java | 11 +++ .../fluid/manager/ServerFluidChunk.java | 68 +++++++++++++++---- .../fluid/manager/ServerFluidManager.java | 8 +++ .../simulator/FluidAcceleratedSimulator.java | 22 +++--- 8 files changed, 126 insertions(+), 35 deletions(-) diff --git a/buildNumber.properties b/buildNumber.properties index 0821db72..1c8a8bfe 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Nov 30 14:46:42 EST 2024 -buildNumber=408 +#Sat Nov 30 16:32:02 EST 2024 +buildNumber=419 diff --git a/src/fluid/compile.sh b/src/fluid/compile.sh index 74ce0191..5d16647c 100644 --- a/src/fluid/compile.sh +++ b/src/fluid/compile.sh @@ -1,6 +1,6 @@ cd ./src/fluid -echo "SAVE STEPS $SAVE_STEPS" +echo "[Fluid Lib] SAVE STEPS $SAVE_STEPS" LIB_ENDING=".so" BASE_INCLUDE_DIR="" diff --git a/src/fluid/includes/electrosphere_server_fluid_simulator_FluidAcceleratedSimulator.h b/src/fluid/includes/electrosphere_server_fluid_simulator_FluidAcceleratedSimulator.h index 0e69f63d..3e3464be 100644 --- a/src/fluid/includes/electrosphere_server_fluid_simulator_FluidAcceleratedSimulator.h +++ b/src/fluid/includes/electrosphere_server_fluid_simulator_FluidAcceleratedSimulator.h @@ -15,6 +15,14 @@ extern "C" { JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_simulate (JNIEnv *, jclass, jobject, jfloat); +/* + * Class: electrosphere_server_fluid_simulator_FluidAcceleratedSimulator + * Method: free + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_free + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/src/fluid/src/javainterface.c b/src/fluid/src/javainterface.c index ef4e5581..a9658e4f 100644 --- a/src/fluid/src/javainterface.c +++ b/src/fluid/src/javainterface.c @@ -46,27 +46,47 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate( simulate(numChunks,javaChunkView,dt); } +/** + * Should clean up all native allocations and state + */ +JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_free( + JNIEnv * env, + jclass fluidSimClass + ){ + + //free the c view of the chunks + int storedChunks = stbds_arrlen(javaChunkView); + for(int i = 0; i < storedChunks; i++){ + free(javaChunkView[i]); + } + + //free the dynamic array + stbds_arrfree(javaChunkView); + javaChunkView = NULL; + numChunks = 0; +} + /** * Reads chunks into the dynamic array */ void readInChunks(JNIEnv * env, jobject chunkList){ jclass listClass = (*env)->FindClass(env,"java/util/List"); - jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/FluidSim"); + jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/FluidSim"); //JNIEnv *env, jclass clazz, const char *name, const char *sig jmethodID jListSize = (*env)->GetMethodID(env, listClass, "size", "()I"); jmethodID jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;"); jmethodID jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); //ByteBuffer[] - jfieldID dJId = (*env)->GetFieldID(env,fluidSimClass,"density","[Ljava/nio/ByteBuffer;"); - jfieldID d0JId = (*env)->GetFieldID(env,fluidSimClass,"densityAddition","[Ljava/nio/ByteBuffer;"); - jfieldID uJId = (*env)->GetFieldID(env,fluidSimClass,"uVector","[Ljava/nio/ByteBuffer;"); - jfieldID vJId = (*env)->GetFieldID(env,fluidSimClass,"vVector","[Ljava/nio/ByteBuffer;"); - jfieldID wJId = (*env)->GetFieldID(env,fluidSimClass,"wVector","[Ljava/nio/ByteBuffer;"); - jfieldID u0JId = (*env)->GetFieldID(env,fluidSimClass,"uAdditionVector","[Ljava/nio/ByteBuffer;"); - jfieldID v0JId = (*env)->GetFieldID(env,fluidSimClass,"vAdditionVector","[Ljava/nio/ByteBuffer;"); - jfieldID w0JId = (*env)->GetFieldID(env,fluidSimClass,"wAdditionVector","[Ljava/nio/ByteBuffer;"); + jfieldID dJId = (*env)->GetFieldID(env,fluidSimClass,"bWeights","[Ljava/nio/ByteBuffer;"); + jfieldID d0JId = (*env)->GetFieldID(env,fluidSimClass,"b0Weights","[Ljava/nio/ByteBuffer;"); + jfieldID uJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID vJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID wJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityZ","[Ljava/nio/ByteBuffer;"); + jfieldID u0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); + jfieldID v0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); + jfieldID w0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); jfieldID chunkmaskJId = (*env)->GetFieldID(env,fluidSimClass,"chunkMask","I"); //the number of chunks diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index 9a1114ac..77bfdfae 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -17,6 +17,7 @@ import electrosphere.net.server.player.Player; import electrosphere.server.chemistry.ServerChemistryCollisionCallback; import electrosphere.server.collision.ServerHitboxResolutionCallback; import electrosphere.server.content.ServerContentManager; +import electrosphere.server.fluid.simulator.FluidAcceleratedSimulator; /** * Manages all realms for the engine. Should be a singleton @@ -209,6 +210,16 @@ public class RealmManager { * Resets the realm manager */ public void reset(){ + for(Realm realm : this.realms){ + if( + realm.getServerWorldData() != null && + realm.getServerWorldData().getServerFluidManager() != null && + realm.getServerWorldData().getServerFluidManager().getSimulator() != null && + realm.getServerWorldData().getServerFluidManager().getSimulator() instanceof FluidAcceleratedSimulator + ){ + FluidAcceleratedSimulator.cleanup(); + } + } this.realms.clear(); this.entityToRealmMap.clear(); this.playerToRealmMap.clear(); diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index c7f9bc45..01fc8974 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -7,7 +7,6 @@ import java.nio.FloatBuffer; import org.joml.Vector3f; import org.joml.Vector3i; -import org.lwjgl.BufferUtils; import electrosphere.server.terrain.manager.ServerTerrainChunk; @@ -28,6 +27,11 @@ public class ServerFluidChunk { */ static final int CENTER_BUFF = 13; + /** + * Size of a fluid buffer + */ + static final int BUFFER_SIZE = ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION; + /** * The world x coordinate of this chunk @@ -68,22 +72,47 @@ public class ServerFluidChunk { /** * The array of all adjacent weight buffers for the fluid sim */ - ByteBuffer[] bWeights = new ByteBuffer[ARRAY_CT]; + public ByteBuffer[] bWeights = new ByteBuffer[ARRAY_CT]; /** * The array of all adjacent velocity x buffers for the fluid sim */ - ByteBuffer[] bVelocityX = new ByteBuffer[ARRAY_CT]; + public ByteBuffer[] bVelocityX = new ByteBuffer[ARRAY_CT]; /** * The array of all adjacent velocity y buffers for the fluid sim */ - ByteBuffer[] bVelocityY = new ByteBuffer[ARRAY_CT]; + public ByteBuffer[] bVelocityY = new ByteBuffer[ARRAY_CT]; /** * The array of all adjacent velocity z buffers for the fluid sim */ - ByteBuffer[] bVelocityZ = new ByteBuffer[ARRAY_CT]; + 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; /** * Constructor @@ -91,26 +120,30 @@ public class ServerFluidChunk { * @param worldY The world y coordinate * @param worldZ The world z coordinate */ - public ServerFluidChunk( - int worldX, - int worldY, - int worldZ - ) { + public ServerFluidChunk(int worldX, int worldY, int worldZ) { this.worldX = worldX; this.worldY = worldY; this.worldZ = worldZ; //allocate - this.bWeights[CENTER_BUFF] = BufferUtils.createByteBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 4); - this.bVelocityX[CENTER_BUFF] = BufferUtils.createByteBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 4); - this.bVelocityY[CENTER_BUFF] = BufferUtils.createByteBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 4); - this.bVelocityZ[CENTER_BUFF] = BufferUtils.createByteBuffer(ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 4); + 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); //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(); @@ -350,6 +383,13 @@ public class ServerFluidChunk { return x * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION + y * ServerTerrainChunk.CHUNK_DIMENSION + z; } + /** + * Gets the chunk mask for this chunk + * @return The chunk mask + */ + public int getChunkMask(){ + return this.chunkMask; + } } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index dd31e7a3..6cc4070e 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -327,6 +327,14 @@ public class ServerFluidManager { public void setParent(ServerWorldData serverWorldData){ this.parent = serverWorldData; } + + /** + * Gets the server fluid simulator for this manager + * @return The server fluid simulator + */ + public ServerFluidSimulator getSimulator(){ + return serverFluidSimulator; + } diff --git a/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java b/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java index fdb9bf33..db33ef24 100644 --- a/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java +++ b/src/main/java/electrosphere/server/fluid/simulator/FluidAcceleratedSimulator.java @@ -29,20 +29,24 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator { throw new UnsupportedOperationException("Unimplemented method 'simulate'"); } - /** - * Main simulation function - * @param chunks The list of chunks to simulate with - * @param timestep The timestep to simulate - */ - private static void simulateWrapper(List chunks, float timestep){ - FluidAcceleratedSimulator.simulate(chunks,timestep); - } - /** * Main native simulation function * @param chunks The list of chunks to simulate with * @param timestep The timestep to simulate */ private static native void simulate(List chunks, float timestep); + + + /** + * Cleans up the simulator's native state + */ + public static void cleanup(){ + FluidAcceleratedSimulator.free(); + } + + /** + * Frees all native memory + */ + private static native void free(); }