metadata calculation on c side of fluidsim
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 19:52:10 -05:00
parent f2fc2d2dc4
commit 03d583ee85
10 changed files with 142 additions and 34 deletions

View File

@ -15,6 +15,8 @@
"simulation.h": "c", "simulation.h": "c",
"chunk.h": "c", "chunk.h": "c",
"chunkmask.h": "c", "chunkmask.h": "c",
"metadatacalc.h": "c" "metadatacalc.h": "c",
"immintrin.h": "c",
"stdint.h": "c"
} }
} }

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Sat Nov 30 19:02:40 EST 2024 #Sat Nov 30 19:48:02 EST 2024
buildNumber=435 buildNumber=441

View File

@ -1,6 +1,8 @@
#ifndef CHUNK_H #ifndef CHUNK_H
#define CHUNK_H #define CHUNK_H
#include <jni.h>
/** /**
* A chunk * A chunk
*/ */
@ -14,6 +16,9 @@ typedef struct {
float * v0[27]; float * v0[27];
float * w0[27]; float * w0[27];
int chunkMask; int chunkMask;
jobject chunkJRaw;
} Chunk; } Chunk;
#define DIM 18
#endif #endif

View File

@ -1,10 +1,45 @@
#ifndef ENVIRONMENT_H #ifndef ENVIRONMENT_H
#define 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 * Stores data about the simulation environment
*/ */
typedef struct { typedef struct {
JNILookupTable lookupTable;
float gravity; float gravity;
} Environment; } Environment;

View File

@ -7,11 +7,12 @@
/** /**
* Updates the metadata for all chunks * Updates the metadata for all chunks
* @param env The java environment variable
* @param numChunks The number of chunks * @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in * @param passedInChunks The chunks that were passed in
* @param environment The environment data * @param environment The environment data
*/ */
void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment); void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Environment * environment);

View File

@ -25,14 +25,14 @@
//declarations //declarations
void readInChunks(JNIEnv * env, jobject chunkList); void readInChunks(JNIEnv * env, jobject chunkList, Environment * environment);
int calculateChunkMask(JNIEnv * env, jobjectArray jrx); int calculateChunkMask(JNIEnv * env, jobjectArray jrx);
uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx); uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx);
//the list of chunks //the list of chunks
Chunk ** javaChunkView = NULL; Chunk ** chunkViewC = NULL;
//the number of chunks //the number of chunks
int numChunks = 0; int numChunks = 0;
@ -46,9 +46,9 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jobject chunkList, jobject chunkList,
jfloat dt jfloat dt
){ ){
readInChunks(env,chunkList); readInChunks(env,chunkList,environment);
simulate(numChunks,javaChunkView,environment,dt); simulate(numChunks,chunkViewC,environment,dt);
updateMetadata(numChunks,javaChunkView,environment); 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 //free the c view of the chunks
int storedChunks = stbds_arrlen(javaChunkView); int storedChunks = stbds_arrlen(chunkViewC);
for(int i = 0; i < storedChunks; i++){ for(int i = 0; i < storedChunks; i++){
free(javaChunkView[i]); free(chunkViewC[i]);
} }
//free the dynamic array //free the dynamic array
stbds_arrfree(javaChunkView); stbds_arrfree(chunkViewC);
javaChunkView = NULL; chunkViewC = NULL;
numChunks = 0; numChunks = 0;
} }
@ -79,33 +79,57 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jclass fluidSimClass, jclass fluidSimClass,
jfloat gravity jfloat gravity
){ ){
//allocate if unallocated
if(environment == NULL){ if(environment == NULL){
environment = (Environment *)malloc(sizeof(Environment)); environment = (Environment *)malloc(sizeof(Environment));
} }
//store variables from java side
environment->gravity = gravity; 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 * 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 listClass = (*env)->FindClass(env,"java/util/List");
jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk"); jclass fluidSimClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk");
//JNIEnv *env, jclass clazz, const char *name, const char *sig //JNIEnv *env, jclass clazz, const char *name, const char *sig
jmethodID jListSize = (*env)->GetMethodID(env, listClass, "size", "()I"); jmethodID jListSize = environment->lookupTable.listTable.jListSize;
jmethodID jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;"); jmethodID jListGet = environment->lookupTable.listTable.jListGet;
jmethodID jListAdd = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); jmethodID jListAdd = environment->lookupTable.listTable.jListAdd;
//ByteBuffer[] //ByteBuffer[]
jfieldID dJId = (*env)->GetFieldID(env,fluidSimClass,"bWeights","[Ljava/nio/ByteBuffer;"); jfieldID dJId = environment->lookupTable.serverFluidChunkTable.dJId;
jfieldID d0JId = (*env)->GetFieldID(env,fluidSimClass,"b0Weights","[Ljava/nio/ByteBuffer;"); jfieldID d0JId = environment->lookupTable.serverFluidChunkTable.d0JId;
jfieldID uJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityX","[Ljava/nio/ByteBuffer;"); jfieldID uJId = environment->lookupTable.serverFluidChunkTable.uJId;
jfieldID vJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityY","[Ljava/nio/ByteBuffer;"); jfieldID vJId = environment->lookupTable.serverFluidChunkTable.vJId;
jfieldID wJId = (*env)->GetFieldID(env,fluidSimClass,"bVelocityZ","[Ljava/nio/ByteBuffer;"); jfieldID wJId = environment->lookupTable.serverFluidChunkTable.wJId;
jfieldID u0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); jfieldID u0JId = environment->lookupTable.serverFluidChunkTable.u0JId;
jfieldID v0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); jfieldID v0JId = environment->lookupTable.serverFluidChunkTable.v0JId;
jfieldID w0JId = (*env)->GetFieldID(env,fluidSimClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); jfieldID w0JId = environment->lookupTable.serverFluidChunkTable.w0JId;
jfieldID chunkmaskJId = (*env)->GetFieldID(env,fluidSimClass,"chunkMask","I"); jfieldID chunkmaskJId = environment->lookupTable.serverFluidChunkTable.chunkmaskJId;
//the number of chunks //the number of chunks
numChunks = (*env)->CallIntMethod(env,chunkList,jListSize); numChunks = (*env)->CallIntMethod(env,chunkList,jListSize);
@ -130,17 +154,17 @@ void readInChunks(JNIEnv * env, jobject chunkList){
(*env)->SetIntField(env,chunkJRaw,chunkmaskJId,chunkMask); (*env)->SetIntField(env,chunkJRaw,chunkmaskJId,chunkMask);
Chunk * newChunk; Chunk * newChunk;
if(i >= stbds_arrlen(javaChunkView)){ if(i >= stbds_arrlen(chunkViewC)){
// printf("allocate chunk %d\n",i); // printf("allocate chunk %d\n",i);
// fflush(stdout); // fflush(stdout);
newChunk = (Chunk *)malloc(sizeof(Chunk)); newChunk = (Chunk *)malloc(sizeof(Chunk));
// printf("new chunk %p\n",newChunk); // printf("new chunk %p\n",newChunk);
// fflush(stdout); // fflush(stdout);
stbds_arrput(javaChunkView,newChunk); stbds_arrput(chunkViewC,newChunk);
// printf("new chunk %p\n",chunks[i]); // printf("new chunk %p\n",chunks[i]);
// fflush(stdout); // fflush(stdout);
} else { } else {
newChunk = javaChunkView[i]; newChunk = chunkViewC[i];
// printf("get chunk %d: %p\n",i,newChunk); // printf("get chunk %d: %p\n",i,newChunk);
// fflush(stdout); // fflush(stdout);
} }
@ -153,6 +177,7 @@ void readInChunks(JNIEnv * env, jobject chunkList){
v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId); v0 = (*env)->GetObjectField(env,chunkJRaw,v0JId);
w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId); w0 = (*env)->GetObjectField(env,chunkJRaw,w0JId);
newChunk->chunkMask = chunkMask; newChunk->chunkMask = chunkMask;
newChunk->chunkJRaw = chunkJRaw;
for(int j = 0; j < 27; j++){ for(int j = 0; j < 27; j++){
if((chunkMask & CHUNK_INDEX_ARR[j]) > 0){ if((chunkMask & CHUNK_INDEX_ARR[j]) > 0){
newChunk->d[j] = GET_ARR(env,jd,j); newChunk->d[j] = GET_ARR(env,jd,j);

View File

@ -1,18 +1,55 @@
#include <stdio.h>
#include <immintrin.h> #include <immintrin.h>
#include <stdint.h> #include <stdint.h>
#include <math.h>
#include "../includes/utilities.h" #include "../includes/utilities.h"
#include "../includes/chunkmask.h" #include "../includes/chunkmask.h"
#include "../includes/metadatacalc.h" #include "../includes/metadatacalc.h"
#define UPDATE_THRESHOLD 0.1
/** /**
* Updates the metadata for all chunks * Updates the metadata for all chunks
* @param env The java environment variable
* @param numChunks The number of chunks * @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in * @param passedInChunks The chunks that were passed in
* @param environment The environment data * @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; y<N-1; y++){
for(z=1; z<N-1; z++){
int n = 0;
//solve as much as possible vectorized
for(x = 1; x < N-1; x=x+8){
sum = sum + GET_ARR_RAW(currentChunk->d,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);
}
}
} }

View File

@ -4,6 +4,7 @@
#include "../includes/utilities.h" #include "../includes/utilities.h"
#include "../includes/chunkmask.h" #include "../includes/chunkmask.h"
#include "../includes/chunk.h"
#define BOUND_NO_DIR 0 #define BOUND_NO_DIR 0
@ -653,7 +654,6 @@ static inline void setBoundsToNeighborsRaw(
int vector_dir, int vector_dir,
float ** neighborArray float ** neighborArray
){ ){
int DIM = N;
float * target = GET_ARR_RAW(neighborArray,CENTER_LOC); float * target = GET_ARR_RAW(neighborArray,CENTER_LOC);
float * source; float * source;
//set the faces bounds //set the faces bounds
@ -709,7 +709,6 @@ static inline void copyNeighborsRaw(
int vector_dir, int vector_dir,
float ** neighborArray float ** neighborArray
){ ){
int DIM = N;
float * target = GET_ARR_RAW(neighborArray,CENTER_LOC); float * target = GET_ARR_RAW(neighborArray,CENTER_LOC);
float * source; float * source;

View File

@ -137,6 +137,11 @@ public class ServerFluidChunk {
*/ */
public boolean updated = false; public boolean updated = false;
/**
* The total density of the chunk
*/
public float totalDensity = 0;
/** /**
* Constructor * Constructor
* @param worldX The world x coordinate * @param worldX The world x coordinate

View File

@ -280,7 +280,6 @@ public class ServerFluidManager {
*/ */
public void queue(int worldX, int worldY, int worldZ){ public void queue(int worldX, int worldY, int worldZ){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
fluidChunk.updated = true;
this.simulationQueue.add(fluidChunk); this.simulationQueue.add(fluidChunk);
} }