diff --git a/.vscode/launch.json b/.vscode/launch.json index b162a4c5..1937b8ef 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,8 @@ "name": "Launch Current File", "request": "launch", "mainClass": "${file}", - "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"" + "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "preLaunchTask": "Install Native Lib" }, { "type": "java", @@ -17,7 +18,8 @@ "request": "launch", "mainClass": "electrosphere.engine.Main", "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", - "projectName": "Renderer" + "projectName": "Renderer", + "preLaunchTask": "Install Native Lib" }, { "type": "java", @@ -25,7 +27,8 @@ "request": "launch", "mainClass": "electrosphere.engine.Main", "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\" -javaagent:./lwjglx-debug-1.0.0.jar=t;o=trace.log", - "projectName": "Renderer" + "projectName": "Renderer", + "preLaunchTask": "Install Native Lib" }, { "type": "java", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7ead1806..b647664a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,6 +1,17 @@ { "version": "2.0.0", "tasks": [ + + { + "type": "shell", + "label": "Install Native Lib", + "command": "cp ./out/build/libStormEngine.* ./shared-folder", + "group": "build", + "detail": "Installs the native lib locally", + "dependsOn": ["CMake: build",] + }, + + { "type": "cmake", "label": "CMake: build", diff --git a/buildNumber.properties b/buildNumber.properties index ccd0c801..a92c4c9f 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Fri Dec 06 19:51:41 EST 2024 -buildNumber=579 +#Fri Dec 06 21:26:11 EST 2024 +buildNumber=600 diff --git a/src/main/c/includes/fluid/queue/chunk.h b/src/main/c/includes/fluid/queue/chunk.h index 50db4b48..158ce234 100644 --- a/src/main/c/includes/fluid/queue/chunk.h +++ b/src/main/c/includes/fluid/queue/chunk.h @@ -6,18 +6,18 @@ #ifndef CHUNK_H #define CHUNK_H -#define MIN_VALUE 0.0 -#define MAX_VALUE 1.0 +#define MIN_FLUID_VALUE 0.0f +#define MAX_FLUID_VALUE 1.0f /** * The cutoff value for the bounds array */ -#define BOUND_CUTOFF_VALUE 0.0 +#define BOUND_CUTOFF_VALUE 0.0f /** * Maximum value of bounds array for it to be considered a blocker */ -#define BOUND_MAX_VALUE 1.0 +#define BOUND_MAX_VALUE 1.0f /** * The dimension of a single chunk's array diff --git a/src/main/c/src/fluid/sim/cellular/cellular.c b/src/main/c/src/fluid/sim/cellular/cellular.c index d5370938..e0dd0ed7 100644 --- a/src/main/c/src/fluid/sim/cellular/cellular.c +++ b/src/main/c/src/fluid/sim/cellular/cellular.c @@ -7,6 +7,15 @@ #define FLUID_CELLULAR_DIFFUSE_RATE 0.001 +#define FLUID_CELLULAR_DIFFUSE_RATE2 0.1 +#define FLUID_CELLULAR_KERNEL_SIZE 4 + +int fluid_cellular_kernel_x[FLUID_CELLULAR_KERNEL_SIZE] = { + -1, 0, 1, 0 +}; +int fluid_cellular_kernel_z[FLUID_CELLULAR_KERNEL_SIZE] = { + 0, -1, 0, 1 +}; /** * Simulates the cellular chunk queue @@ -17,52 +26,99 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ Chunk ** chunks = environment->queue.cellularQueue; int chunkCount = stbds_arrlen(chunks); - for(int i = 0; i < chunkCount; i++){ - Chunk * currentChunk = chunks[i]; + for(int cellIndex = 0; cellIndex < chunkCount; cellIndex++){ + Chunk * currentChunk = chunks[cellIndex]; //simulate here - float * d = currentChunk->d[CENTER_LOC]; + float *d = currentChunk->d[CENTER_LOC]; float * bounds = currentChunk->bounds[CENTER_LOC]; + float density; + int transferred = 0; - // printf("%f %d %d %d\n",bounds[IX(1,0,1)],currentChunk->x,currentChunk->y,currentChunk->z); + // 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 = 1; x < DIM-1; x++){ for(int y = 1; y < DIM-1; y++){ for(int z = 1; z < DIM-1; z++){ //diffuse density - d[IX(x,y,z)] = d[IX(x,y,z)]; - if(x > 1){ - d[IX(x,y,z)] += (d[IX(x-1,y,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(x < DIM-2){ - d[IX(x,y,z)] += (d[IX(x+1,y,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(y > 1){ - d[IX(x,y,z)] += (d[IX(x,y-1,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(y < DIM-2){ - d[IX(x,y,z)] += (d[IX(x,y+1,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(z > 1){ - d[IX(x,y,z)] += (d[IX(x,y,z-1)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(z < DIM-2){ - d[IX(x,y,z)] += (d[IX(x,y,z+1)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; - } - if(d[IX(x,y,z)] <= 0){ + // d[IX(x,y,z)] = d[IX(x,y,z)]; + // if(x > 1){ + // d[IX(x,y,z)] += (d[IX(x-1,y,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // if(x < DIM-2){ + // d[IX(x,y,z)] += (d[IX(x+1,y,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // if(y > 1){ + // d[IX(x,y,z)] += (d[IX(x,y-1,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // if(y < DIM-2){ + // d[IX(x,y,z)] += (d[IX(x,y+1,z)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // if(z > 1){ + // d[IX(x,y,z)] += (d[IX(x,y,z-1)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // if(z < DIM-2){ + // d[IX(x,y,z)] += (d[IX(x,y,z+1)] - d[IX(x,y,z)]) * FLUID_CELLULAR_DIFFUSE_RATE; + // } + // float boundVal = bounds[IX(x,y,z)]; + // if(boundVal > BOUND_CUTOFF_VALUE){ + // continue; + // } + // for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){ + // density = d[IX(x,y,z)]; + // int nX = x + fluid_cellular_kernel_x[j]; + // int nZ = z + fluid_cellular_kernel_z[j]; + // float nDensity = d[IX(nX,y,nZ)]; + // if(nDensity > MIN_FLUID_VALUE){ + // float lateralDiff = nDensity - density; + // if(lateralDiff > 0){ + // float maxIntake = MAX_FLUID_VALUE - density; + // if(maxIntake > 0){ + // float transferLateral; + // transferLateral = lateralDiff; + // if(nDensity < transferLateral){ + // transferLateral = nDensity; + // } + // if(maxIntake < transferLateral){ + // transferLateral = maxIntake; + // } + // if(transferLateral > FLUID_CELLULAR_DIFFUSE_RATE2){ + // transferLateral = FLUID_CELLULAR_DIFFUSE_RATE2; + // } + // d[IX(nX,y,nZ)] -= transferLateral; + // d[IX(x,y,z)] += transferLateral; + // // if(d[IX(nX,y,nZ)] < MIN_FLUID_VALUE){ + // // d[IX(x,y,z)] += d[IX(nX,y,nZ)]; + // // d[IX(nX,y,nZ)] = MIN_FLUID_VALUE; + // // } + // } + // } + // } + // } + if(d[IX(x,y,z)] <= MIN_FLUID_VALUE){ } else { //transfer straight down - if(bounds[IX(x,y-1,z)] <= BOUND_CUTOFF_VALUE){ - float deltaLower = MAX_VALUE - d[IX(x,y-1,z)]; - if(deltaLower > 0){ - float transferLower; - if(d[IX(x,y,z)] >= deltaLower){ - transferLower = deltaLower; - } else { - transferLower = d[IX(x,y,z)]; + { + float nBound = bounds[IX(x,y-1,z)]; + if(nBound <= BOUND_CUTOFF_VALUE){ + if(d[IX(x,y-1,z)] <= MIN_FLUID_VALUE){ + d[IX(x,y-1,z)] = d[IX(x,y,z)]; + d[IX(x,y,z)] = MIN_FLUID_VALUE; + continue; + } + } + } + //transfer laterally + for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){ + int nX = x + fluid_cellular_kernel_x[j]; + int nZ = z + fluid_cellular_kernel_z[j]; + if(bounds[IX(nX,y,nZ)] <= BOUND_CUTOFF_VALUE){ + if(d[IX(nX,y,nZ)] <= MIN_FLUID_VALUE){ + printf("%d %d %d -> %d %d %d \n",x,y,z,nX,y,nZ); + d[IX(nX,y,nZ)] = d[IX(x,y,z)]; + d[IX(x,y,z)] = MIN_FLUID_VALUE; + break; } - d[IX(x,y,z)] -= transferLower; - d[IX(x,y-1,z)] += transferLower; } } } diff --git a/src/main/c/src/fluid/sim/grid/densitystep.c b/src/main/c/src/fluid/sim/grid/densitystep.c index 53656616..8596036b 100644 --- a/src/main/c/src/fluid/sim/grid/densitystep.c +++ b/src/main/c/src/fluid/sim/grid/densitystep.c @@ -29,10 +29,10 @@ void addDensity( environment->densityTracking.newDensity = environment->densityTracking.newDensity + dt * s[i]; environment->densityTracking.existingDensity = environment->densityTracking.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; + if(x[i] < MIN_FLUID_VALUE){ + x[i] = MIN_FLUID_VALUE; + } else if(x[i] > MAX_FLUID_VALUE){ + x[i] = MAX_FLUID_VALUE; } } } diff --git a/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java b/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java index c061b37b..cab695fe 100644 --- a/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java +++ b/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java @@ -21,6 +21,9 @@ public class ScriptClientVoxelUtils { */ static final float EDIT_INCREMENT = 0.1f; + //vertical offset from cursor position to spawn things at + static final Vector3d cursorVerticalOffset = new Vector3d(0,0.05,0); + /** * Applies the current voxel palette where the player's cursor is looking */ @@ -65,15 +68,16 @@ public class ScriptClientVoxelUtils { if(cursorPos == null){ cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE)); } + cursorPos = cursorPos.add(cursorVerticalOffset); Vector3i worldPos = new Vector3i( (int)(cursorPos.x / ServerTerrainChunk.CHUNK_DIMENSION), (int)(cursorPos.y / ServerTerrainChunk.CHUNK_DIMENSION), (int)(cursorPos.z / ServerTerrainChunk.CHUNK_DIMENSION) ); Vector3i voxelPos = new Vector3i( - (int)(cursorPos.x % ServerTerrainChunk.CHUNK_DIMENSION), - (int)(cursorPos.y % ServerTerrainChunk.CHUNK_DIMENSION), - (int)(cursorPos.z % ServerTerrainChunk.CHUNK_DIMENSION) + (int)(Math.ceil(cursorPos.x) % ServerTerrainChunk.CHUNK_DIMENSION), + (int)(Math.ceil(cursorPos.y) % ServerTerrainChunk.CHUNK_DIMENSION), + (int)(Math.ceil(cursorPos.z) % ServerTerrainChunk.CHUNK_DIMENSION) ); Globals.realmManager.first().getServerWorldData().getServerFluidManager().deformFluidAtLocationToValue(worldPos, voxelPos, 1.0f, 0); } diff --git a/src/test/c/fluid/queue/boundsolver_tests.c b/src/test/c/fluid/queue/boundsolver_tests.c index 62f41c72..76f427e1 100644 --- a/src/test/c/fluid/queue/boundsolver_tests.c +++ b/src/test/c/fluid/queue/boundsolver_tests.c @@ -863,6 +863,30 @@ int fluid_queue_boundsolver_tests(){ rVal += checkBounds(queue[i],kernelx[i],kernely[i],kernelz[i],0); } + { + int borderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)]; + int containedVal = queue[1]->d[CENTER_LOC][IX(1,1,0)]; + rVal += assertEquals(borderVal,containedVal,"chunk 0,0,1 should contain border values from 0,0,0 --- %d %d\n"); + } + + { + int borderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-1)]; + int containedVal = queue[1]->d[CENTER_LOC][IX(1,1,1)]; + rVal += assertEquals(borderVal,containedVal,"chunk 0,0,0 should contain border values from 0,0,1 --- %d %d\n"); + } + + { + int borderVal = queue[0]->d[CENTER_LOC][IX(DIM-2,1,1)]; + int containedVal = queue[9]->d[CENTER_LOC][IX(0,1,1)]; + rVal += assertEquals(borderVal,containedVal,"chunk 1,0,0 should contain border values from 0,0,0 --- %d %d\n"); + } + + { + int borderVal = queue[0]->d[CENTER_LOC][IX(DIM-1,1,1)]; + int containedVal = queue[9]->d[CENTER_LOC][IX(1,1,1)]; + rVal += assertEquals(borderVal,containedVal,"chunk 0,0,0 should contain border values from 1,0,0 --- %d %d\n"); + } + //cleanup test diff --git a/src/test/c/fluid/sim/cellular/cellular_tests.c b/src/test/c/fluid/sim/cellular/cellular_tests.c new file mode 100644 index 00000000..9589bb09 --- /dev/null +++ b/src/test/c/fluid/sim/cellular/cellular_tests.c @@ -0,0 +1,101 @@ +#include +#include + +#include "stb/stb_ds.h" + +#include "fluid/queue/chunk.h" +#include "fluid/queue/sparse.h" +#include "fluid/queue/chunkmask.h" +#include "fluid/env/utilities.h" +#include "fluid/queue/islandsolver.h" +#include "fluid/queue/boundsolver.h" +#include "fluid/dispatch/dispatcher.h" +#include "fluid/sim/simulator.h" +#include "../../../util/test.h" +#include "../../../util/chunk_test_utils.h" + + + +#define CELLULAR_TEST_PLACE_VAL 0.1f + +int fluid_sim_cellular_cellular_tests_kernelx[27] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +int fluid_sim_cellular_cellular_tests_kernely[27] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, + 0, 0, 0, 1, 1, 1, 2, 2, 2, + 0, 0, 0, 1, 1, 1, 2, 2, 2, +}; + +int fluid_sim_cellular_cellular_tests_kernelz[27] = { + 0, 1, 2, 0, 1, 2, 0, 1, 2, + 0, 1, 2, 0, 1, 2, 0, 1, 2, + 0, 1, 2, 0, 1, 2, 0, 1, 2, +}; + + + +int fluid_sim_cellular_bounds_tests(){ + int rVal = 0; + Environment * env = fluid_environment_create(); + + int chunkCount = 27; + + Chunk ** queue = NULL; + for(int i = 0; i < chunkCount; i++){ + arrput(queue,chunk_create( + fluid_sim_cellular_cellular_tests_kernelx[i], + fluid_sim_cellular_cellular_tests_kernely[i], + fluid_sim_cellular_cellular_tests_kernelz[i] + )); + } + + //link neighbors + chunk_link_neighbors(queue); + + //fill them with values + for(int i = 0; i < chunkCount; i++){ + chunk_fill(queue[i],0); + } + + //set border of 0,0,0 to push a value into z + queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)] = CELLULAR_TEST_PLACE_VAL; + + //call bounds setter + fluid_solve_bounds(chunkCount,queue,env); + + { + int borderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)]; + int transferedVal = queue[1]->d[CENTER_LOC][IX(1,1,0)]; + rVal += assertEqualsFloat(borderVal,CELLULAR_TEST_PLACE_VAL,"Border value was overwritten! -- %f %f \n"); + rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value want not transfered from border! -- %f %f \n"); + } + + //dispatch and simulate + fluid_dispatch(chunkCount,queue,env); + fluid_simulate(env); + + //assert that the density moved + { + int borderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)]; + int orderBorderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-3)]; + int transferedVal = queue[1]->d[CENTER_LOC][IX(1,1,0)]; + rVal += assertEqualsFloat(borderVal,MIN_FLUID_VALUE,"Border value has not changed! -- %f %f \n"); + rVal += assertEqualsFloat(orderBorderVal,CELLULAR_TEST_PLACE_VAL,"Border value has not moved! -- %f %f \n"); + rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value want not transfered from border! -- %f %f \n"); + } + + return rVal; +} + + +int fluid_sim_cellular_cellular_tests(int argc, char **argv){ + int rVal = 0; + + rVal += fluid_sim_cellular_bounds_tests(); + + return rVal; +}