diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index e4ff7c6e..ab3d1d91 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1241,11 +1241,11 @@ Fix placing character at end of world bounds Bump ode4j version Small collision engine code formatting -(14/04/2024) +(12/04/2024) Fix testing apparatus for native code on windows Fix doxygen also pointing at native code lib folder -(14/06/2024) +(12/06/2024) Fix arena loading Refactoring fluid sim code Refactoring fluid sim headers @@ -1261,6 +1261,10 @@ Native bounds solver Fix cellular sim bounds check Add hard walls to bounds solver +(12/07/2024) +Cellular bounds transfer properly +Fluid chunk terrain bounds transfer +Cellular transfer behavior work # TODO diff --git a/src/main/c/src/fluid/sim/cellular/cellular.c b/src/main/c/src/fluid/sim/cellular/cellular.c index abfbb640..ad378c99 100644 --- a/src/main/c/src/fluid/sim/cellular/cellular.c +++ b/src/main/c/src/fluid/sim/cellular/cellular.c @@ -9,12 +9,19 @@ #define FLUID_CELLULAR_DIFFUSE_RATE 0.001 #define FLUID_CELLULAR_DIFFUSE_RATE2 0.1 #define FLUID_CELLULAR_KERNEL_SIZE 4 +#define FLUID_CELLULAR_KERNEL_PERMUTATIONS 4 -int fluid_cellular_kernel_x[FLUID_CELLULAR_KERNEL_SIZE] = { - -1, 0, 1, 0 +int fluid_cellular_kernel_x[FLUID_CELLULAR_KERNEL_PERMUTATIONS][FLUID_CELLULAR_KERNEL_SIZE] = { + {-1, 0, 1, 0}, + { 0, -1, 0, 1}, + { 1, 0, -1, 0}, + { 0, 1, 0, -1}, }; -int fluid_cellular_kernel_z[FLUID_CELLULAR_KERNEL_SIZE] = { - 0, -1, 0, 1 +int fluid_cellular_kernel_z[FLUID_CELLULAR_KERNEL_PERMUTATIONS][FLUID_CELLULAR_KERNEL_SIZE] = { + { 0, -1, 0, 1}, + { 1, 0, -1, 0}, + { 0, 1, 0, -1}, + {-1, 0, 1, 0}, }; /** @@ -60,10 +67,9 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ // 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; - // } + if(bounds[IX(x,y,z)] > 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]; @@ -96,6 +102,7 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){ // } // } if(d[IX(x,y,z)] <= MIN_FLUID_VALUE){ + continue; } else { //transfer straight down if(y > 0){ @@ -109,9 +116,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[j]; - int nZ = z + fluid_cellular_kernel_z[j]; + int nX = x + fluid_cellular_kernel_x[permutation][j]; + int nZ = z + fluid_cellular_kernel_z[permutation][j]; if(nX < 0 || nX >= DIM || nZ < 0 || nZ >= DIM){ continue; } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index a547823f..e112e01f 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -101,6 +101,11 @@ public class ServerFluidChunk { */ FloatBuffer velocityZ; + /** + * The float view of the center bounds buffer + */ + FloatBuffer bounds; + /** * The array of all adjacent weight buffers for the fluid sim */ @@ -221,6 +226,7 @@ public class ServerFluidChunk { this.velocityX = this.bVelocityX[CENTER_BUFF].asFloatBuffer(); this.velocityY = this.bVelocityY[CENTER_BUFF].asFloatBuffer(); this.velocityZ = this.bVelocityZ[CENTER_BUFF].asFloatBuffer(); + this.bounds = this.bBounds[CENTER_BUFF].asFloatBuffer(); } /** @@ -443,6 +449,28 @@ public class ServerFluidChunk { velocityZ.put(index, velZ); } + /** + * Gets the bounds value at a given position + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @return The bounds value + */ + public float getBound(int x, int y, int z){ + return bounds.get(this.IX(x,y,z)); + } + + /** + * Sets the bounds value at a given position + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @param bound The bounds value + */ + public void setBound(int x, int y, int z, float bound){ + this.bounds.put(this.IX(x,y,z),bound); + } + /** * Gets the inddex into the buffer * @param x The x position diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index 37c73a71..7cc41a73 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -8,6 +8,7 @@ import electrosphere.server.fluid.generation.FluidGenerator; import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.simulator.FluidAcceleratedSimulator; import electrosphere.server.fluid.simulator.ServerFluidSimulator; +import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.util.FileUtils; import electrosphere.util.annotation.Exclude; @@ -334,6 +335,16 @@ public class ServerFluidManager { private ServerFluidChunk generateChunk(int worldX, int worldY, int worldZ){ lock.lock(); ServerFluidChunk rVal = chunkGenerator.generateChunk(worldX, worldY, worldZ); + ServerWorldData serverWorldData = this.parent; + ServerTerrainChunk terrainChunk = serverWorldData.getServerTerrainManager().getChunk(worldX, worldY, worldZ); + for(int x = ServerFluidChunk.TRUE_DATA_OFFSET; x < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; x++){ + for(int y = ServerFluidChunk.TRUE_DATA_OFFSET; y < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; y++){ + for(int z = ServerFluidChunk.TRUE_DATA_OFFSET; z < ServerFluidChunk.TRUE_DATA_DIM + ServerFluidChunk.TRUE_DATA_OFFSET; z++){ + rVal.setBound(x, y, z, terrainChunk.getWeight(x, y, z)); + rVal.setWeight(x, y, z, 0); + } + } + } this.linkNeighbors(rVal, worldX, worldY, worldZ); lock.unlock(); return rVal;