From 01a2ab603cae0fa38a3c9d4879d603eee321a6bc Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 7 Dec 2024 15:12:29 -0500 Subject: [PATCH] cellular sim deterministic work --- .vscode/settings.json | 4 +- docs/src/progress/renderertodo.md | 2 + src/main/c/includes/fluid/env/environment.h | 5 ++- src/main/c/includes/math/mathutils.h | 23 ++++++++++ src/main/c/includes/math/randutils.h | 28 ++++++++++++ src/main/c/src/fluid/queue/javainterface.c | 7 +-- src/main/c/src/fluid/queue/metadatacalc.c | 6 ++- src/main/c/src/fluid/sim/cellular/cellular.c | 17 +++++--- src/main/c/src/fluid/sim/grid/densitystep.c | 4 +- src/main/c/src/fluid/sim/grid/fluidsim.c | 8 ++-- src/main/c/src/math/mathutils.c | 27 ++++++++++++ src/main/c/src/math/randutils.c | 46 ++++++++++++++++++++ src/test/c/math/mathutils_tests.c | 26 +++++++++++ src/test/c/math/randutils_tests.c | 15 +++++++ 14 files changed, 198 insertions(+), 20 deletions(-) create mode 100644 src/main/c/includes/math/mathutils.h create mode 100644 src/main/c/includes/math/randutils.h create mode 100644 src/main/c/src/math/mathutils.c create mode 100644 src/main/c/src/math/randutils.c create mode 100644 src/test/c/math/mathutils_tests.c create mode 100644 src/test/c/math/randutils_tests.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 46abdf5a..17a210db 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,6 +36,8 @@ "dispatcher.h": "c", "cellular.h": "c", "limits": "c", - "boundsolver.h": "c" + "boundsolver.h": "c", + "randutils.h": "c", + "mathutils.h": "c" } } \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index ab3d1d91..7fd8c353 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1265,6 +1265,8 @@ Add hard walls to bounds solver Cellular bounds transfer properly Fluid chunk terrain bounds transfer Cellular transfer behavior work +Native math utils +Frame tracking on native side # TODO diff --git a/src/main/c/includes/fluid/env/environment.h b/src/main/c/includes/fluid/env/environment.h index 9ee08d2f..06f847e2 100644 --- a/src/main/c/includes/fluid/env/environment.h +++ b/src/main/c/includes/fluid/env/environment.h @@ -71,7 +71,8 @@ typedef struct { double existingDensity; double newDensity; float normalizationRatio; -} FluidDensityTracking; + int frame; +} FluidSimState; /** * Stores data about the simulation environment @@ -80,7 +81,7 @@ typedef struct { JNILookupTable lookupTable; FluidSimQueue queue; FluidSimConsts consts; - FluidDensityTracking densityTracking; + FluidSimState state; } Environment; /** diff --git a/src/main/c/includes/math/mathutils.h b/src/main/c/includes/math/mathutils.h new file mode 100644 index 00000000..a88ef92f --- /dev/null +++ b/src/main/c/includes/math/mathutils.h @@ -0,0 +1,23 @@ +#ifndef MATHUTILS_H +#define MATHUTILS_H + +#include "public.h" + + +/** + * Calculates the fractional component of a float + */ +LIBRARY_API float fract(float x); + +/** + * Calculates the dot product of 2D vectors + */ +LIBRARY_API float dot2(float x1, float y1, float x2, float y2); + +/** + * Calculates the dot product of 3D vectors + */ +LIBRARY_API float dot3(float x1, float y1, float z1, float x2, float y2, float z2); + + +#endif \ No newline at end of file diff --git a/src/main/c/includes/math/randutils.h b/src/main/c/includes/math/randutils.h new file mode 100644 index 00000000..edff7a27 --- /dev/null +++ b/src/main/c/includes/math/randutils.h @@ -0,0 +1,28 @@ +#ifndef RANDUTILS_H +#define RANDUTILS_H + +#include "public.h" + + +/** + * Generates a random number given a seed value + */ +LIBRARY_API float randutils_rand1(float x); + +/** + * Generates a random number given two seed values + */ +LIBRARY_API float randutils_rand2(float x, float y); + +/** + * Generates a random number given three seed values + */ +LIBRARY_API float randutils_rand3(float x, float y, float z); + +/** + * Maps a float of range [0,1] to an integer range + */ +LIBRARY_API float randutils_map(float x, int min, int max); + + +#endif \ No newline at end of file diff --git a/src/main/c/src/fluid/queue/javainterface.c b/src/main/c/src/fluid/queue/javainterface.c index 3626b2c7..05fec145 100644 --- a/src/main/c/src/fluid/queue/javainterface.c +++ b/src/main/c/src/fluid/queue/javainterface.c @@ -100,9 +100,10 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate //store variables from java side environment->consts.gravity = gravity; - environment->densityTracking.existingDensity = 0; - environment->densityTracking.newDensity = 0; - environment->densityTracking.normalizationRatio = 0; + environment->state.existingDensity = 0; + environment->state.newDensity = 0; + environment->state.normalizationRatio = 0; + environment->state.frame = 0; //store jni lookup tables jclass listClass = (*env)->FindClass(env,"java/util/List"); diff --git a/src/main/c/src/fluid/queue/metadatacalc.c b/src/main/c/src/fluid/queue/metadatacalc.c index 14f6b672..051f1be3 100644 --- a/src/main/c/src/fluid/queue/metadatacalc.c +++ b/src/main/c/src/fluid/queue/metadatacalc.c @@ -89,7 +89,11 @@ void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Enviro } //alert java side to updated static values - float normalizationRatio = environment->densityTracking.normalizationRatio; + float normalizationRatio = environment->state.normalizationRatio; (*env)->SetStaticFloatField(env,environment->lookupTable.serverFluidChunkClass,environment->lookupTable.serverFluidChunkTable.normalizationRatioId,normalizationRatio); + + + //update frame state + environment->state.frame += 1; } diff --git a/src/main/c/src/fluid/sim/cellular/cellular.c b/src/main/c/src/fluid/sim/cellular/cellular.c index ad378c99..5199a79f 100644 --- a/src/main/c/src/fluid/sim/cellular/cellular.c +++ b/src/main/c/src/fluid/sim/cellular/cellular.c @@ -4,6 +4,7 @@ #include "fluid/sim/cellular/cellular.h" #include "fluid/queue/chunkmask.h" #include "fluid/env/utilities.h" +#include "math/randutils.h" #define FLUID_CELLULAR_DIFFUSE_RATE 0.001 @@ -43,8 +44,10 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ int transferred = 0; // printf("%f %f %f %d %d %d\n",bounds[IX(0,1,1)],bounds[IX(1,0,1)],bounds[IX(1,1,0)],currentChunk->x,currentChunk->y,currentChunk->z); - for(int x = 0; x < DIM; x++){ - for(int y = 0; y < DIM; y++){ + for(int y = 0; y < DIM; y++){ + int shift = randutils_map(randutils_rand2(environment->state.frame,y),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1); + int permutation = randutils_map(randutils_rand2(environment->state.frame,y + 1),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1); + for(int x = 0; x < DIM; x++){ for(int z = 0; z < DIM; z++){ //diffuse density @@ -116,10 +119,10 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ } } //transfer laterally - int permutation = (z % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) + ((x % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) * (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)); - for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){ - int nX = x + fluid_cellular_kernel_x[permutation][j]; - int nZ = z + fluid_cellular_kernel_z[permutation][j]; + // int permutation = (z % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) + ((x % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) * (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)); + // for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){ + int nX = x + fluid_cellular_kernel_x[permutation][shift]; + int nZ = z + fluid_cellular_kernel_z[permutation][shift]; if(nX < 0 || nX >= DIM || nZ < 0 || nZ >= DIM){ continue; } @@ -130,7 +133,7 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ break; } } - } + // } } } } diff --git a/src/main/c/src/fluid/sim/grid/densitystep.c b/src/main/c/src/fluid/sim/grid/densitystep.c index 8596036b..784d72eb 100644 --- a/src/main/c/src/fluid/sim/grid/densitystep.c +++ b/src/main/c/src/fluid/sim/grid/densitystep.c @@ -26,8 +26,8 @@ void addDensity( float * x = GET_ARR_RAW(d,CENTER_LOC); float * s = GET_ARR_RAW(d0,CENTER_LOC); for(i=0; idensityTracking.newDensity = environment->densityTracking.newDensity + dt * s[i]; - environment->densityTracking.existingDensity = environment->densityTracking.existingDensity + x[i]; + environment->state.newDensity = environment->state.newDensity + dt * s[i]; + environment->state.existingDensity = environment->state.existingDensity + x[i]; x[i] += dt*s[i]; if(x[i] < MIN_FLUID_VALUE){ x[i] = MIN_FLUID_VALUE; diff --git a/src/main/c/src/fluid/sim/grid/fluidsim.c b/src/main/c/src/fluid/sim/grid/fluidsim.c index 2ff60530..ae48083b 100644 --- a/src/main/c/src/fluid/sim/grid/fluidsim.c +++ b/src/main/c/src/fluid/sim/grid/fluidsim.c @@ -445,8 +445,8 @@ void fluid_grid_simulate( //add density { double deltaDensity = 0; - environment->densityTracking.existingDensity = 0; - environment->densityTracking.newDensity = 0; + environment->state.existingDensity = 0; + environment->state.newDensity = 0; for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; addDensity(environment,DIM,currentChunk->chunkMask,currentChunk->d,currentChunk->d0,timestep); @@ -525,8 +525,8 @@ void fluid_grid_simulate( } float normalizationRatio = 0; if(transformedDensity != 0){ - normalizationRatio = (environment->densityTracking.existingDensity + environment->densityTracking.newDensity) / transformedDensity; - environment->densityTracking.normalizationRatio = normalizationRatio; + normalizationRatio = (environment->state.existingDensity + environment->state.newDensity) / transformedDensity; + environment->state.normalizationRatio = normalizationRatio; } for(int i = 0; i < numChunks; i++){ Chunk * currentChunk = chunks[i]; diff --git a/src/main/c/src/math/mathutils.c b/src/main/c/src/math/mathutils.c new file mode 100644 index 00000000..9b5c7a31 --- /dev/null +++ b/src/main/c/src/math/mathutils.c @@ -0,0 +1,27 @@ +#include + + +#include "math/mathutils.h" + + +/** + * Calculates the fractional component of a float + */ +LIBRARY_API float fract(float x){ + return x - floor(x); +} + +/** + * Calculates the dot product of 2D vectors + */ +LIBRARY_API float dot2(float x1, float y1, float x2, float y2){ + return (x1 * x2) + (y1 * y2); +} + +/** + * Calculates the dot product of 3D vectors + */ +LIBRARY_API float dot3(float x1, float y1, float z1, float x2, float y2, float z2){ + return (x1 * x2) + (y1 * y2) + (z1 * z2); +} + diff --git a/src/main/c/src/math/randutils.c b/src/main/c/src/math/randutils.c new file mode 100644 index 00000000..e4bcb37a --- /dev/null +++ b/src/main/c/src/math/randutils.c @@ -0,0 +1,46 @@ +#include + +#include "math/mathutils.h" +#include "math/randutils.h" + +/** + * The magnitude of the random oscillator + */ +#define MATHUTILS_RAND_MAG 100000.0f + +/** + * Vectors used for prng generation + */ +#define MATHUTILS_RAND_VEC_X 111.154315f +#define MATHUTILS_RAND_VEC_Y 123.631631f +#define MATHUTILS_RAND_VEC_Z 117.724545f + +/** + * Generates a random number given a seed value + */ +LIBRARY_API float randutils_rand1(float x){ + return fract(sin(x) * MATHUTILS_RAND_MAG); +} + +/** + * Generates a random number given two seed values + */ +LIBRARY_API float randutils_rand2(float x, float y){ + return fract(sin(dot2(x,y,MATHUTILS_RAND_VEC_X,MATHUTILS_RAND_VEC_Y)) * MATHUTILS_RAND_MAG); +} + +/** + * Generates a random number given three seed values + */ +LIBRARY_API float randutils_rand3(float x, float y, float z){ + return fract(sin(dot3(x,y,z,MATHUTILS_RAND_VEC_X,MATHUTILS_RAND_VEC_Y,MATHUTILS_RAND_VEC_Z)) * MATHUTILS_RAND_MAG); +} + +/** + * Maps a float of range [0,1] to an integer range + */ +LIBRARY_API float randutils_map(float x, int min, int max){ + return (int)(x * (max - min) + min); +} + + diff --git a/src/test/c/math/mathutils_tests.c b/src/test/c/math/mathutils_tests.c new file mode 100644 index 00000000..6818ec23 --- /dev/null +++ b/src/test/c/math/mathutils_tests.c @@ -0,0 +1,26 @@ + +#include "math/mathutils.h" +#include "../util/test.h" + + +int math_mathutils_tests(){ + int rVal = 0; + + //test fract() + rVal += assertEqualsFloat(0.5,fract(1.5),"Fract failed to calculate correctly! %f %f \n"); + rVal += assertEqualsFloat(0.0,fract(1.0),"Fract failed to calculate correctly! %f %f \n"); + + //test dot2() + rVal += assertEqualsFloat(1,dot2(1,0,1,0),"dot2 should be 1! %f %f \n"); + rVal += assertEqualsFloat(-1,dot2(1,0,-1,0),"dot2 should be -1! %f %f \n"); + rVal += assertEqualsFloat(0,dot2(1,0,0,1),"dot2 should be 0! %f %f \n"); + + + //test dot3() + rVal += assertEqualsFloat(1,dot3(1,0,0,1,0,0),"dot3 should be 1! %f %f \n"); + rVal += assertEqualsFloat(-1,dot3(1,0,0,-1,0,0),"dot3 should be -1! %f %f \n"); + rVal += assertEqualsFloat(0,dot3(1,0,0,0,1,0),"dot3 should be 0! %f %f \n"); + + + return rVal; +} \ No newline at end of file diff --git a/src/test/c/math/randutils_tests.c b/src/test/c/math/randutils_tests.c new file mode 100644 index 00000000..810ce63b --- /dev/null +++ b/src/test/c/math/randutils_tests.c @@ -0,0 +1,15 @@ + +#include "math/mathutils.h" +#include "math/randutils.h" +#include "../util/test.h" + + +int math_randutils_tests(){ + int rVal = 0; + + randutils_rand1(1); + randutils_rand2(1,2); + randutils_rand3(1,2,3); + + return rVal; +} \ No newline at end of file