diff --git a/.vscode/settings.json b/.vscode/settings.json index b0d0d099..5a02e9dc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,8 @@ "simulation.h": "c", "chunk.h": "c", "chunkmask.h": "c", - "metadatacalc.h": "c" + "metadatacalc.h": "c", + "immintrin.h": "c", + "stdint.h": "c" } } \ No newline at end of file diff --git a/buildNumber.properties b/buildNumber.properties index 8adc26f9..998e7151 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Nov 30 19:02:40 EST 2024 -buildNumber=435 +#Sat Nov 30 19:48:02 EST 2024 +buildNumber=441 diff --git a/src/fluid/includes/chunk.h b/src/fluid/includes/chunk.h index 586f37ee..5a2f21b6 100644 --- a/src/fluid/includes/chunk.h +++ b/src/fluid/includes/chunk.h @@ -1,6 +1,8 @@ #ifndef CHUNK_H #define CHUNK_H +#include + /** * A chunk */ @@ -14,6 +16,9 @@ typedef struct { float * v0[27]; float * w0[27]; int chunkMask; + jobject chunkJRaw; } Chunk; +#define DIM 18 + #endif \ No newline at end of file diff --git a/src/fluid/includes/environment.h b/src/fluid/includes/environment.h index d4fc6916..dc628966 100644 --- a/src/fluid/includes/environment.h +++ b/src/fluid/includes/environment.h @@ -1,10 +1,45 @@ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H +/** + * The List lookup table + */ +typedef struct { + jmethodID jListSize; + jmethodID jListGet; + jmethodID jListAdd; +} ListLookupTable; + +/** + * The ServerFluidChunk lookup table + */ +typedef struct { + jfieldID dJId; + jfieldID d0JId; + jfieldID uJId; + jfieldID vJId; + jfieldID wJId; + jfieldID u0JId; + jfieldID v0JId; + jfieldID w0JId; + jfieldID chunkmaskJId; + jfieldID updatedId; + jfieldID totalDensityId; +} ServerFluidChunkLookupTable; + +/** + * Lookup table for various java fields, methods, etc + */ +typedef struct { + ListLookupTable listTable; + ServerFluidChunkLookupTable serverFluidChunkTable; +} JNILookupTable; + /** * Stores data about the simulation environment */ typedef struct { + JNILookupTable lookupTable; float gravity; } Environment; diff --git a/src/fluid/includes/metadatacalc.h b/src/fluid/includes/metadatacalc.h index 9d584ec1..749b8ca2 100644 --- a/src/fluid/includes/metadatacalc.h +++ b/src/fluid/includes/metadatacalc.h @@ -7,11 +7,12 @@ /** * Updates the metadata for all chunks + * @param env The java environment variable * @param numChunks The number of chunks * @param passedInChunks The chunks that were passed in * @param environment The environment data */ -void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment); +void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Environment * environment); diff --git a/src/fluid/src/javainterface.c b/src/fluid/src/javainterface.c index 9ed4de2c..a11dddad 100644 --- a/src/fluid/src/javainterface.c +++ b/src/fluid/src/javainterface.c @@ -25,14 +25,14 @@ //declarations -void readInChunks(JNIEnv * env, jobject chunkList); +void readInChunks(JNIEnv * env, jobject chunkList, Environment * environment); int calculateChunkMask(JNIEnv * env, jobjectArray jrx); uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx); //the list of chunks -Chunk ** javaChunkView = NULL; +Chunk ** chunkViewC = NULL; //the number of chunks int numChunks = 0; @@ -46,9 +46,9 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate jobject chunkList, jfloat dt ){ - readInChunks(env,chunkList); - simulate(numChunks,javaChunkView,environment,dt); - updateMetadata(numChunks,javaChunkView,environment); + readInChunks(env,chunkList,environment); + simulate(numChunks,chunkViewC,environment,dt); + updateMetadata(env,numChunks,chunkViewC,environment); } /** @@ -60,14 +60,14 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate ){ //free the c view of the chunks - int storedChunks = stbds_arrlen(javaChunkView); + int storedChunks = stbds_arrlen(chunkViewC); for(int i = 0; i < storedChunks; i++){ - free(javaChunkView[i]); + free(chunkViewC[i]); } //free the dynamic array - stbds_arrfree(javaChunkView); - javaChunkView = NULL; + stbds_arrfree(chunkViewC); + chunkViewC = NULL; numChunks = 0; } @@ -79,33 +79,57 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate jclass fluidSimClass, jfloat gravity ){ + + //allocate if unallocated if(environment == NULL){ environment = (Environment *)malloc(sizeof(Environment)); } + + //store variables from java side environment->gravity = gravity; + + //store jni lookup tables + jclass listClass = (*env)->FindClass(env,"java/util/List"); + jclass fluidSimStorageClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk"); + //JNIEnv *env, jclass clazz, const char *name, const char *sig + environment->lookupTable.listTable.jListSize = (*env)->GetMethodID(env, listClass, "size", "()I"); + environment->lookupTable.listTable.jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;"); + environment->lookupTable.listTable.jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); + //ByteBuffer[] + environment->lookupTable.serverFluidChunkTable.dJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bWeights","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.d0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0Weights","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.uJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityX","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.vJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityY","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.wJId = (*env)->GetFieldID(env,fluidSimStorageClass,"bVelocityZ","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.u0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.v0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.w0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.chunkmaskJId = (*env)->GetFieldID(env,fluidSimStorageClass,"chunkMask","I"); + environment->lookupTable.serverFluidChunkTable.totalDensityId = (*env)->GetFieldID(env,fluidSimStorageClass,"totalDensity","F"); + environment->lookupTable.serverFluidChunkTable.updatedId = (*env)->GetFieldID(env,fluidSimStorageClass,"updated","Z"); } /** * Reads chunks into the dynamic array */ -void readInChunks(JNIEnv * env, jobject chunkList){ +void readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){ jclass listClass = (*env)->FindClass(env,"java/util/List"); jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk"); //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"); + jmethodID jListSize = environment->lookupTable.listTable.jListSize; + jmethodID jListGet = environment->lookupTable.listTable.jListGet; + jmethodID jListAdd = environment->lookupTable.listTable.jListAdd; //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"); + jfieldID dJId = environment->lookupTable.serverFluidChunkTable.dJId; + jfieldID d0JId = environment->lookupTable.serverFluidChunkTable.d0JId; + jfieldID uJId = environment->lookupTable.serverFluidChunkTable.uJId; + jfieldID vJId = environment->lookupTable.serverFluidChunkTable.vJId; + jfieldID wJId = environment->lookupTable.serverFluidChunkTable.wJId; + jfieldID u0JId = environment->lookupTable.serverFluidChunkTable.u0JId; + jfieldID v0JId = environment->lookupTable.serverFluidChunkTable.v0JId; + jfieldID w0JId = environment->lookupTable.serverFluidChunkTable.w0JId; + jfieldID chunkmaskJId = environment->lookupTable.serverFluidChunkTable.chunkmaskJId; //the number of chunks numChunks = (*env)->CallIntMethod(env,chunkList,jListSize); @@ -130,17 +154,17 @@ void readInChunks(JNIEnv * env, jobject chunkList){ (*env)->SetIntField(env,chunkJRaw,chunkmaskJId,chunkMask); Chunk * newChunk; - if(i >= stbds_arrlen(javaChunkView)){ + if(i >= stbds_arrlen(chunkViewC)){ // printf("allocate chunk %d\n",i); // fflush(stdout); newChunk = (Chunk *)malloc(sizeof(Chunk)); // printf("new chunk %p\n",newChunk); // fflush(stdout); - stbds_arrput(javaChunkView,newChunk); + stbds_arrput(chunkViewC,newChunk); // printf("new chunk %p\n",chunks[i]); // fflush(stdout); } else { - newChunk = javaChunkView[i]; + newChunk = chunkViewC[i]; // printf("get chunk %d: %p\n",i,newChunk); // fflush(stdout); } @@ -153,6 +177,7 @@ void readInChunks(JNIEnv * env, jobject chunkList){ v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId); w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId); newChunk->chunkMask = chunkMask; + newChunk->chunkJRaw = chunkJRaw; for(int j = 0; j < 27; j++){ if((chunkMask & CHUNK_INDEX_ARR[j]) > 0){ newChunk->d[j] = GET_ARR(env,jd,j); diff --git a/src/fluid/src/metadatacalc.c b/src/fluid/src/metadatacalc.c index 2363734f..bf2ef29d 100644 --- a/src/fluid/src/metadatacalc.c +++ b/src/fluid/src/metadatacalc.c @@ -1,18 +1,55 @@ -#include #include #include +#include #include "../includes/utilities.h" #include "../includes/chunkmask.h" #include "../includes/metadatacalc.h" +#define UPDATE_THRESHOLD 0.1 + /** * Updates the metadata for all chunks + * @param env The java environment variable * @param numChunks The number of chunks * @param passedInChunks The chunks that were passed in * @param environment The environment data */ -void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment){ +void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Environment * environment){ + jfieldID totalDensityId = environment->lookupTable.serverFluidChunkTable.totalDensityId; + jfieldID updatedId = environment->lookupTable.serverFluidChunkTable.updatedId; + int N = DIM; + int i; + int x, y, z; + for(i = 0; i < numChunks; i++){ + + //get previous total density + Chunk * currentChunk = passedInChunks[i]; + jobject jObj = currentChunk->chunkJRaw; + float prevDensity = (*env)->GetFloatField(env,jObj,totalDensityId); + + //calculate new total density + //transform u direction + float sum = 0; + for(y=1; yd,CENTER_LOC)[IX(x,y,z)]; + } + } + } + + //update total density + if(fabs(sum - prevDensity) > UPDATE_THRESHOLD){ + (*env)->SetBooleanField(env,jObj,updatedId,JNI_TRUE); + (*env)->SetFloatField(env,jObj,totalDensityId,sum); + } else { + (*env)->SetBooleanField(env,jObj,updatedId,JNI_FALSE); + } + + } } diff --git a/src/fluid/src/velocitystep.c b/src/fluid/src/velocitystep.c index 66665347..cc93df15 100644 --- a/src/fluid/src/velocitystep.c +++ b/src/fluid/src/velocitystep.c @@ -4,6 +4,7 @@ #include "../includes/utilities.h" #include "../includes/chunkmask.h" +#include "../includes/chunk.h" #define BOUND_NO_DIR 0 @@ -653,7 +654,6 @@ static inline void setBoundsToNeighborsRaw( int vector_dir, float ** neighborArray ){ - int DIM = N; float * target = GET_ARR_RAW(neighborArray,CENTER_LOC); float * source; //set the faces bounds @@ -709,7 +709,6 @@ static inline void copyNeighborsRaw( int vector_dir, float ** neighborArray ){ - int DIM = N; float * target = GET_ARR_RAW(neighborArray,CENTER_LOC); float * source; diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index 1097af7a..766b6cbd 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -137,6 +137,11 @@ public class ServerFluidChunk { */ public boolean updated = false; + /** + * The total density of the chunk + */ + public float totalDensity = 0; + /** * Constructor * @param worldX The world x coordinate diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index 6da820c3..78de3e9c 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -280,7 +280,6 @@ public class ServerFluidManager { */ public void queue(int worldX, int worldY, int worldZ){ ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); - fluidChunk.updated = true; this.simulationQueue.add(fluidChunk); }