metadata calculation on c side of fluidsim
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
f2fc2d2dc4
commit
03d583ee85
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user