normalization ratio for fluid simulation
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-12-01 19:23:08 -05:00
parent 6b3a07cbc1
commit 83b8227b68
11 changed files with 121 additions and 17 deletions

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Sun Dec 01 18:25:39 EST 2024 #Sun Dec 01 19:21:24 EST 2024
buildNumber=485 buildNumber=502

View File

@ -1216,6 +1216,7 @@ Unsleeping fluid chunks on edit
Conditionally rasterize fluid chunks based on homogeneity Conditionally rasterize fluid chunks based on homogeneity
Awake fluid chunks based on neighbor state Awake fluid chunks based on neighbor state
Fluid chunk conditionally send update based on sleep status Fluid chunk conditionally send update based on sleep status
Fluid simulation normalization ratio

View File

@ -3,6 +3,9 @@
#include <jni.h> #include <jni.h>
#define MIN_VALUE 0
#define MAX_VALUE 1
/** /**
* A chunk * A chunk
*/ */

View File

@ -28,6 +28,7 @@ typedef struct {
jfieldID totalDensityId; jfieldID totalDensityId;
jfieldID asleepId; jfieldID asleepId;
jfieldID homogenousId; jfieldID homogenousId;
jfieldID normalizationRatioId;
} ServerFluidChunkLookupTable; } ServerFluidChunkLookupTable;
/** /**
@ -36,6 +37,7 @@ typedef struct {
typedef struct { typedef struct {
ListLookupTable listTable; ListLookupTable listTable;
ServerFluidChunkLookupTable serverFluidChunkTable; ServerFluidChunkLookupTable serverFluidChunkTable;
jclass serverFluidChunkClass;
} JNILookupTable; } JNILookupTable;
/** /**
@ -44,6 +46,9 @@ typedef struct {
typedef struct { typedef struct {
JNILookupTable lookupTable; JNILookupTable lookupTable;
float gravity; float gravity;
double existingDensity;
double newDensity;
float normalizationRatio;
} Environment; } Environment;
#endif #endif

View File

@ -1,3 +1,5 @@
#include "environment.h"
#ifndef MAINFUNC #ifndef MAINFUNC
#define MAINFUNC #define MAINFUNC
@ -60,13 +62,11 @@ static inline void finalizeProjection
static inline void advectVectors static inline void advectVectors
(int, int, float **, float **, float **, float **, float **, float **, float, float, float); (int, int, float **, float **, float **, float **, float **, float **, float, float, float);
/* /**
* Class: electrosphere_FluidSim * Adds density to the density array
* Method: addDensity * @return The change in density within this chunk for this frame
* Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;F)V */
*/ static inline void addDensity(Environment * environment, int, int, float **, float **, float);
static inline void addDensity
(int, int, float **, float **, float);
/* /*
* Class: electrosphere_FluidSim * Class: electrosphere_FluidSim
@ -83,6 +83,17 @@ static inline void solveDiffuseDensity
*/ */
static inline void advectDensity(uint32_t chunk_mask, int N, float ** d, float ** d0, float ** ur, float ** vr, float ** wr, float dt); static inline void advectDensity(uint32_t chunk_mask, int N, float ** d, float ** d0, float ** ur, float ** vr, float ** wr, float dt);
/**
* Sums the density of the chunk
*/
double calculateSum(uint32_t chunk_mask, int N, float ** d);
/**
* Normalizes the density array with a given ratio
*/
static inline void normalizeDensity(int N, float ** d, float ratio);
static inline void setBoundsToNeighborsRaw static inline void setBoundsToNeighborsRaw
( (
int N, int N,

View File

@ -8,20 +8,29 @@
/** /**
* Adds density to the density array * Adds density to the density array
* @return The change in density within this chunk for this frame
*/ */
static inline void addDensity( static inline void addDensity(
int N, Environment * environment,
int chunk_mask, int N,
float ** d, int chunk_mask,
float ** d0, float ** d,
float dt float ** d0,
float dt
){ ){
int i; int i;
int size=N*N*N; int size=N*N*N;
float * x = GET_ARR_RAW(d,CENTER_LOC); float * x = GET_ARR_RAW(d,CENTER_LOC);
float * s = GET_ARR_RAW(d0,CENTER_LOC); float * s = GET_ARR_RAW(d0,CENTER_LOC);
for(i=0; i<size; i++){ for(i=0; i<size; i++){
environment->newDensity = environment->newDensity + dt * s[i];
environment->existingDensity = environment->existingDensity + x[i];
x[i] += dt*s[i]; x[i] += dt*s[i];
if(x[i] < MIN_VALUE){
x[i] = MIN_VALUE;
} else if(x[i] > MAX_VALUE){
x[i] = MAX_VALUE;
}
} }
} }
@ -227,4 +236,33 @@ static inline void advectDensity(uint32_t chunk_mask, int N, float ** d, float *
} }
} }
} }
} }
/**
* Sums the density of the chunk
*/
double calculateSum(uint32_t chunk_mask, int N, float ** d){
int j;
int size=N*N*N;
float * x = GET_ARR_RAW(d,CENTER_LOC);
double rVal = 0;
for(j=0; j<size; j++){
rVal = rVal + x[j];
}
return rVal;
}
/**
* Normalizes the density array with a given ratio
*/
void normalizeDensity(int N, float ** d, float ratio){
int j;
int size=N*N*N;
float * x = GET_ARR_RAW(d,CENTER_LOC);
for(j=0; j<size; j++){
float value = x[j];
value = value * ratio;
x[j] = value;
}
}

View File

@ -443,9 +443,12 @@ void simulate(
//add density //add density
{ {
double deltaDensity = 0;
environment->existingDensity = 0;
environment->newDensity = 0;
for(int i = 0; i < numChunks; i++){ for(int i = 0; i < numChunks; i++){
Chunk * currentChunk = chunks[i]; Chunk * currentChunk = chunks[i];
addDensity(DIM,currentChunk->chunkMask,currentChunk->d,currentChunk->d0,timestep); addDensity(environment,DIM,currentChunk->chunkMask,currentChunk->d,currentChunk->d0,timestep);
} }
} }
//swap all density arrays //swap all density arrays
@ -512,6 +515,23 @@ void simulate(
setBoundsToNeighborsRaw(DIM,currentChunk->chunkMask,0,currentChunk->d); setBoundsToNeighborsRaw(DIM,currentChunk->chunkMask,0,currentChunk->d);
} }
} }
//normalize densities
{
double transformedDensity = 0;
for(int i = 0; i < numChunks; i++){
Chunk * currentChunk = chunks[i];
transformedDensity = transformedDensity + calculateSum(currentChunk->chunkMask,DIM,currentChunk->d);
}
float normalizationRatio = 0;
if(transformedDensity != 0){
normalizationRatio = transformedDensity / (environment->existingDensity + environment->newDensity);
environment->normalizationRatio = normalizationRatio;
}
for(int i = 0; i < numChunks; i++){
Chunk * currentChunk = chunks[i];
normalizeDensity(DIM,currentChunk->d,normalizationRatio);
}
}
} }
@ -553,7 +573,7 @@ static inline void applyGravity(Chunk * currentChunk, Environment * environment)
for(int x = 0; x < DIM; x++){ for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){ for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){ for(int z = 0; z < DIM; z++){
GET_ARR_RAW(currentChunk->v0,CENTER_LOC)[IX(x,y,z)] = GET_ARR_RAW(currentChunk->d,CENTER_LOC)[IX(x,y,z)] * environment->gravity; GET_ARR_RAW(currentChunk->v0,CENTER_LOC)[IX(x,y,z)] = GET_ARR_RAW(currentChunk->v0,CENTER_LOC)[IX(x,y,z)] + GET_ARR_RAW(currentChunk->d,CENTER_LOC)[IX(x,y,z)] * environment->gravity;
} }
} }
} }

View File

@ -93,10 +93,14 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
//store variables from java side //store variables from java side
environment->gravity = gravity; environment->gravity = gravity;
environment->existingDensity = 0;
environment->newDensity = 0;
environment->normalizationRatio = 0;
//store jni lookup tables //store jni lookup tables
jclass listClass = (*env)->FindClass(env,"java/util/List"); jclass listClass = (*env)->FindClass(env,"java/util/List");
jclass fluidSimStorageClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk"); jclass fluidSimStorageClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk");
environment->lookupTable.serverFluidChunkClass = fluidSimStorageClass;
//JNIEnv *env, jclass clazz, const char *name, const char *sig //JNIEnv *env, jclass clazz, const char *name, const char *sig
environment->lookupTable.listTable.jListSize = (*env)->GetMethodID(env, listClass, "size", "()I"); 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.jListGet = (*env)->GetMethodID(env, listClass, "get", "(I)Ljava/lang/Object;");
@ -116,6 +120,7 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
environment->lookupTable.serverFluidChunkTable.updatedId = (*env)->GetFieldID(env,fluidSimStorageClass,"updated","Z"); environment->lookupTable.serverFluidChunkTable.updatedId = (*env)->GetFieldID(env,fluidSimStorageClass,"updated","Z");
environment->lookupTable.serverFluidChunkTable.asleepId = (*env)->GetFieldID(env,fluidSimStorageClass,"asleep","Z"); environment->lookupTable.serverFluidChunkTable.asleepId = (*env)->GetFieldID(env,fluidSimStorageClass,"asleep","Z");
environment->lookupTable.serverFluidChunkTable.homogenousId = (*env)->GetFieldID(env,fluidSimStorageClass,"isHomogenous","Z"); environment->lookupTable.serverFluidChunkTable.homogenousId = (*env)->GetFieldID(env,fluidSimStorageClass,"isHomogenous","Z");
environment->lookupTable.serverFluidChunkTable.normalizationRatioId = (*env)->GetStaticFieldID(env,fluidSimStorageClass,"normalizationRatio","F");
} }
/** /**

View File

@ -86,5 +86,9 @@ void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Enviro
} }
} }
} }
//alert java side to updated static values
float normalizationRatio = environment->normalizationRatio;
(*env)->SetStaticFloatField(env,environment->lookupTable.serverFluidChunkClass,environment->lookupTable.serverFluidChunkTable.normalizationRatioId,normalizationRatio);
} }

View File

@ -5,6 +5,7 @@ import electrosphere.client.fluid.manager.ClientFluidManager;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.fluid.manager.ServerFluidChunk;
import electrosphere.server.fluid.manager.ServerFluidManager; import electrosphere.server.fluid.manager.ServerFluidManager;
import imgui.ImGui; import imgui.ImGui;
@ -42,6 +43,7 @@ public class ImGuiFluidMonitor {
fluidManager.setSimulate(!fluidManager.getSimulate()); fluidManager.setSimulate(!fluidManager.getSimulate());
} }
ImGui.text("Broadcast Size (This Frame): " + fluidManager.getBroadcastSize()); ImGui.text("Broadcast Size (This Frame): " + fluidManager.getBroadcastSize());
ImGui.text("Normalization Ratio: " + ServerFluidChunk.getNormalizationRatio());
} }
if(ImGui.collapsingHeader("Client Data")){ if(ImGui.collapsingHeader("Client Data")){

View File

@ -171,6 +171,11 @@ public class ServerFluidChunk {
*/ */
public float totalDensity = 0; public float totalDensity = 0;
/**
* The normalization ratio used to smooth fluid simulation steps
*/
public static float normalizationRatio = 0;
/** /**
* Allocates the central arrays for this chunk * Allocates the central arrays for this chunk
*/ */
@ -549,4 +554,14 @@ public class ServerFluidChunk {
return this.isHomogenous; return this.isHomogenous;
} }
/**
* Gets the normalization ratio
* @return The normalization ratio
*/
public static float getNormalizationRatio() {
return normalizationRatio;
}
} }