From 0b9f62cc0e6464a605256737467eaf6a0ef87d55 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 1 Dec 2024 18:24:02 -0500 Subject: [PATCH] Awake fluid chunks based on neighbor state --- buildNumber.properties | 4 +- docs/src/progress/renderertodo.md | 1 + src/fluid/includes/chunkmask.h | 5 +++ src/fluid/includes/environment.h | 1 + src/fluid/src/javainterface.c | 1 + src/fluid/src/metadata/metadatacalc.c | 44 ++++++++++++++++--- .../fluid/manager/ServerFluidChunk.java | 40 ++++++++++------- .../fluid/manager/ServerFluidManager.java | 2 +- 8 files changed, 73 insertions(+), 25 deletions(-) diff --git a/buildNumber.properties b/buildNumber.properties index b2d17e48..4cd5487d 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sun Dec 01 17:46:45 EST 2024 -buildNumber=482 +#Sun Dec 01 18:23:03 EST 2024 +buildNumber=484 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 390aee55..c211b3f5 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1214,6 +1214,7 @@ Memory pooling for chunk buffer allocations Server homogenous fluid chunk declarations Unsleeping fluid chunks on edit Conditionally rasterize fluid chunks based on homogeneity +Awake fluid chunks based on neighbor state diff --git a/src/fluid/includes/chunkmask.h b/src/fluid/includes/chunkmask.h index a0003dc2..9eb5e7a1 100644 --- a/src/fluid/includes/chunkmask.h +++ b/src/fluid/includes/chunkmask.h @@ -3,6 +3,11 @@ #ifndef CHUNKMASK_H #define CHUNKMASK_H +/** + * The number of entries in the neighbor array + */ +#define NEIGHBOR_ARRAY_COUNT 27 + #define CENTER_LOC 13 #define CHUNK_222 1 diff --git a/src/fluid/includes/environment.h b/src/fluid/includes/environment.h index be08a17d..f1313ccc 100644 --- a/src/fluid/includes/environment.h +++ b/src/fluid/includes/environment.h @@ -22,6 +22,7 @@ typedef struct { jfieldID u0JId; jfieldID v0JId; jfieldID w0JId; + jfieldID neighborsId; jfieldID chunkmaskJId; jfieldID updatedId; jfieldID totalDensityId; diff --git a/src/fluid/src/javainterface.c b/src/fluid/src/javainterface.c index 4d3f1b92..5e438479 100644 --- a/src/fluid/src/javainterface.c +++ b/src/fluid/src/javainterface.c @@ -110,6 +110,7 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate environment->lookupTable.serverFluidChunkTable.u0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityX","[Ljava/nio/ByteBuffer;"); environment->lookupTable.serverFluidChunkTable.v0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityY","[Ljava/nio/ByteBuffer;"); environment->lookupTable.serverFluidChunkTable.w0JId = (*env)->GetFieldID(env,fluidSimStorageClass,"b0VelocityZ","[Ljava/nio/ByteBuffer;"); + environment->lookupTable.serverFluidChunkTable.neighborsId = (*env)->GetFieldID(env,fluidSimStorageClass,"neighbors","[Lelectrosphere/server/fluid/manager/ServerFluidChunk;"); environment->lookupTable.serverFluidChunkTable.chunkmaskJId = (*env)->GetFieldID(env,fluidSimStorageClass,"chunkMask","I"); environment->lookupTable.serverFluidChunkTable.totalDensityId = (*env)->GetFieldID(env,fluidSimStorageClass,"totalDensity","F"); environment->lookupTable.serverFluidChunkTable.updatedId = (*env)->GetFieldID(env,fluidSimStorageClass,"updated","Z"); diff --git a/src/fluid/src/metadata/metadatacalc.c b/src/fluid/src/metadata/metadatacalc.c index df899d7a..7a639b86 100644 --- a/src/fluid/src/metadata/metadatacalc.c +++ b/src/fluid/src/metadata/metadatacalc.c @@ -41,17 +41,49 @@ void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Enviro } } } + //get whether the chunk is currently homogenous or not + int homogenous = sum <= 0 ? JNI_TRUE : JNI_FALSE; + (*env)->SetBooleanField(env,jObj,environment->lookupTable.serverFluidChunkTable.homogenousId,homogenous); //update total density (*env)->SetBooleanField(env,jObj,updatedId,JNI_TRUE); (*env)->SetFloatField(env,jObj,totalDensityId,sum); - if(sum <= 0){ - //sleep the chunk if it has no density - (*env)->SetBooleanField(env,jObj,environment->lookupTable.serverFluidChunkTable.asleepId,JNI_TRUE); - (*env)->SetBooleanField(env,jObj,environment->lookupTable.serverFluidChunkTable.homogenousId,JNI_TRUE); - } else { - (*env)->SetBooleanField(env,jObj,environment->lookupTable.serverFluidChunkTable.homogenousId,JNI_FALSE); + //check if any neighbor is non-homogenous + jobject neighborArr = (*env)->GetObjectField(env,jObj,environment->lookupTable.serverFluidChunkTable.neighborsId); + int nonHomogenousNeighbor = JNI_FALSE; + for(int j = 0; j < NEIGHBOR_ARRAY_COUNT; j++){ + if(j == CENTER_LOC){ + continue; + } + jobject neighborObj = (*env)->GetObjectArrayElement(env,neighborArr,j); + if(neighborObj != NULL){ + int neighborHomogenous = (*env)->GetBooleanField(env,neighborObj,environment->lookupTable.serverFluidChunkTable.homogenousId); + if(neighborHomogenous == JNI_FALSE){ + nonHomogenousNeighbor = JNI_TRUE; + break; + } + } + } + + //figure out if this chunk should sleep or not + int shouldSleep = JNI_TRUE; + if(nonHomogenousNeighbor == JNI_TRUE || homogenous == JNI_FALSE){ + shouldSleep = JNI_FALSE; + } + (*env)->SetBooleanField(env,jObj,environment->lookupTable.serverFluidChunkTable.asleepId,shouldSleep); + + //if this cell is awake AND non-homogenous, make sure all neighbors are awake + if(shouldSleep == JNI_FALSE && homogenous == JNI_FALSE){ + for(int j = 0; j < NEIGHBOR_ARRAY_COUNT; j++){ + if(j == CENTER_LOC){ + continue; + } + jobject neighborObj = (*env)->GetObjectArrayElement(env,neighborArr,j); + if(neighborObj != NULL){ + (*env)->SetBooleanField(env,neighborObj,environment->lookupTable.serverFluidChunkTable.asleepId,JNI_FALSE); + } + } } } } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java index 36cb0930..f9349444 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidChunk.java @@ -141,6 +141,11 @@ public class ServerFluidChunk { */ public ByteBuffer[] b0VelocityZ = new ByteBuffer[ARRAY_CT]; + /** + * The array of pointers to neighboring chunks + */ + public ServerFluidChunk[] neighbors = new ServerFluidChunk[ARRAY_CT]; + /** * The chunk mask -- Stores which adjacent chunks are populated and which aren't */ @@ -473,24 +478,27 @@ public class ServerFluidChunk { * @param neighbor The neighbor ServerFluidChunk */ public void setNeighbor(int x, int y, int z, ServerFluidChunk neighbor){ + int index = ServerFluidChunk.getNeighborIndex(x, y, z); if(neighbor == null){ - bWeights[getNeighborIndex(x,y,z)] = null; - b0Weights[getNeighborIndex(x,y,z)] = null; - bVelocityX[getNeighborIndex(x,y,z)] = null; - bVelocityY[getNeighborIndex(x,y,z)] = null; - bVelocityZ[getNeighborIndex(x,y,z)] = null; - b0VelocityX[getNeighborIndex(x,y,z)] = null; - b0VelocityY[getNeighborIndex(x,y,z)] = null; - b0VelocityZ[getNeighborIndex(x,y,z)] = null; + bWeights[index ]= null; + b0Weights[index] = null; + bVelocityX[index] = null; + bVelocityY[index] = null; + bVelocityZ[index] = null; + b0VelocityX[index] = null; + b0VelocityY[index] = null; + b0VelocityZ[index] = null; + neighbors[index] = null; } else { - bWeights[getNeighborIndex(x,y,z)] = neighbor.bWeights[CENTER_BUFF]; - b0Weights[getNeighborIndex(x,y,z)] = neighbor.b0Weights[CENTER_BUFF]; - bVelocityX[getNeighborIndex(x,y,z)] = neighbor.bVelocityX[CENTER_BUFF]; - bVelocityY[getNeighborIndex(x,y,z)] = neighbor.bVelocityY[CENTER_BUFF]; - bVelocityZ[getNeighborIndex(x,y,z)] = neighbor.bVelocityZ[CENTER_BUFF]; - b0VelocityX[getNeighborIndex(x,y,z)] = neighbor.b0VelocityX[CENTER_BUFF]; - b0VelocityY[getNeighborIndex(x,y,z)] = neighbor.b0VelocityY[CENTER_BUFF]; - b0VelocityZ[getNeighborIndex(x,y,z)] = neighbor.b0VelocityZ[CENTER_BUFF]; + bWeights[index] = neighbor.bWeights[CENTER_BUFF]; + b0Weights[index] = neighbor.b0Weights[CENTER_BUFF]; + bVelocityX[index] = neighbor.bVelocityX[CENTER_BUFF]; + bVelocityY[index] = neighbor.bVelocityY[CENTER_BUFF]; + bVelocityZ[index] = neighbor.bVelocityZ[CENTER_BUFF]; + b0VelocityX[index] = neighbor.b0VelocityX[CENTER_BUFF]; + b0VelocityY[index] = neighbor.b0VelocityY[CENTER_BUFF]; + b0VelocityZ[index] = neighbor.b0VelocityZ[CENTER_BUFF]; + neighbors[index] = neighbor; } } diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index a721490e..2b66bff5 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -292,7 +292,7 @@ public class ServerFluidManager { public void queue(int worldX, int worldY, int worldZ){ if(simulate){ ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); - if(fluidChunk.isAllocated()){ + if(fluidChunk.isAllocated() && !fluidChunk.isAsleep()){ this.simulationQueue.add(fluidChunk); } }