diff --git a/buildNumber.properties b/buildNumber.properties index 2093a824..749ae378 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sun Dec 01 18:25:39 EST 2024 -buildNumber=485 +#Sun Dec 01 19:21:24 EST 2024 +buildNumber=502 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 37c89671..4e16ccb6 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1216,6 +1216,7 @@ Unsleeping fluid chunks on edit Conditionally rasterize fluid chunks based on homogeneity Awake fluid chunks based on neighbor state Fluid chunk conditionally send update based on sleep status +Fluid simulation normalization ratio diff --git a/src/fluid/includes/chunk.h b/src/fluid/includes/chunk.h index 5a2f21b6..54871df3 100644 --- a/src/fluid/includes/chunk.h +++ b/src/fluid/includes/chunk.h @@ -3,6 +3,9 @@ #include +#define MIN_VALUE 0 +#define MAX_VALUE 1 + /** * A chunk */ diff --git a/src/fluid/includes/environment.h b/src/fluid/includes/environment.h index f1313ccc..b65caa10 100644 --- a/src/fluid/includes/environment.h +++ b/src/fluid/includes/environment.h @@ -28,6 +28,7 @@ typedef struct { jfieldID totalDensityId; jfieldID asleepId; jfieldID homogenousId; + jfieldID normalizationRatioId; } ServerFluidChunkLookupTable; /** @@ -36,6 +37,7 @@ typedef struct { typedef struct { ListLookupTable listTable; ServerFluidChunkLookupTable serverFluidChunkTable; + jclass serverFluidChunkClass; } JNILookupTable; /** @@ -44,6 +46,9 @@ typedef struct { typedef struct { JNILookupTable lookupTable; float gravity; + double existingDensity; + double newDensity; + float normalizationRatio; } Environment; #endif \ No newline at end of file diff --git a/src/fluid/includes/mainFunctions.h b/src/fluid/includes/mainFunctions.h index 0d6040b3..ce90dda3 100644 --- a/src/fluid/includes/mainFunctions.h +++ b/src/fluid/includes/mainFunctions.h @@ -1,3 +1,5 @@ +#include "environment.h" + #ifndef MAINFUNC #define MAINFUNC @@ -60,13 +62,11 @@ static inline void finalizeProjection static inline void advectVectors (int, int, float **, float **, float **, float **, float **, float **, float, float, float); -/* - * Class: electrosphere_FluidSim - * Method: addDensity - * Signature: (II[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;F)V - */ -static inline void addDensity - (int, int, float **, float **, float); +/** + * Adds density to the density array + * @return The change in density within this chunk for this frame +*/ +static inline void addDensity(Environment * environment, int, int, float **, float **, float); /* * 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); + +/** + * 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 ( int N, diff --git a/src/fluid/src/densitystep.c b/src/fluid/src/densitystep.c index 0cd1266e..c7f97d79 100644 --- a/src/fluid/src/densitystep.c +++ b/src/fluid/src/densitystep.c @@ -8,20 +8,29 @@ /** * Adds density to the density array + * @return The change in density within this chunk for this frame */ static inline void addDensity( - int N, - int chunk_mask, - float ** d, - float ** d0, - float dt + Environment * environment, + int N, + int chunk_mask, + float ** d, + float ** d0, + float dt ){ int i; int size=N*N*N; float * x = GET_ARR_RAW(d,CENTER_LOC); float * s = GET_ARR_RAW(d0,CENTER_LOC); for(i=0; inewDensity = environment->newDensity + dt * s[i]; + environment->existingDensity = environment->existingDensity + x[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 * } } } -} \ No newline at end of file +} + + +/** + * 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; jexistingDensity = 0; + environment->newDensity = 0; for(int i = 0; i < numChunks; 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 @@ -512,6 +515,23 @@ void simulate( 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 y = 0; y < DIM; y++){ 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; } } } diff --git a/src/fluid/src/javainterface.c b/src/fluid/src/javainterface.c index 5e438479..7b104262 100644 --- a/src/fluid/src/javainterface.c +++ b/src/fluid/src/javainterface.c @@ -93,10 +93,14 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate //store variables from java side environment->gravity = gravity; + environment->existingDensity = 0; + environment->newDensity = 0; + environment->normalizationRatio = 0; //store jni lookup tables jclass listClass = (*env)->FindClass(env,"java/util/List"); jclass fluidSimStorageClass = (*env)->FindClass(env,"electrosphere/server/fluid/manager/ServerFluidChunk"); + environment->lookupTable.serverFluidChunkClass = fluidSimStorageClass; //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;"); @@ -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.asleepId = (*env)->GetFieldID(env,fluidSimStorageClass,"asleep","Z"); environment->lookupTable.serverFluidChunkTable.homogenousId = (*env)->GetFieldID(env,fluidSimStorageClass,"isHomogenous","Z"); + environment->lookupTable.serverFluidChunkTable.normalizationRatioId = (*env)->GetStaticFieldID(env,fluidSimStorageClass,"normalizationRatio","F"); } /** diff --git a/src/fluid/src/metadata/metadatacalc.c b/src/fluid/src/metadata/metadatacalc.c index ea2d7026..4f25aacb 100644 --- a/src/fluid/src/metadata/metadatacalc.c +++ b/src/fluid/src/metadata/metadatacalc.c @@ -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); } diff --git a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java index 4cd4c3a1..37b562e5 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiFluidMonitor.java @@ -5,6 +5,7 @@ import electrosphere.client.fluid.manager.ClientFluidManager; import electrosphere.engine.Globals; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import electrosphere.server.fluid.manager.ServerFluidChunk; import electrosphere.server.fluid.manager.ServerFluidManager; import imgui.ImGui; @@ -42,6 +43,7 @@ public class ImGuiFluidMonitor { fluidManager.setSimulate(!fluidManager.getSimulate()); } ImGui.text("Broadcast Size (This Frame): " + fluidManager.getBroadcastSize()); + ImGui.text("Normalization Ratio: " + ServerFluidChunk.getNormalizationRatio()); } if(ImGui.collapsingHeader("Client Data")){ diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index f9349444..c0a827b1 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -171,6 +171,11 @@ public class ServerFluidChunk { */ 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 */ @@ -549,4 +554,14 @@ public class ServerFluidChunk { return this.isHomogenous; } + /** + * Gets the normalization ratio + * @return The normalization ratio + */ + public static float getNormalizationRatio() { + return normalizationRatio; + } + + + }