actual fluid sim in bounded level
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-30 19:04:41 -05:00
parent 5caed003d1
commit f2fc2d2dc4
13 changed files with 192 additions and 22 deletions

View File

@ -10,6 +10,11 @@
"files.associations": { "files.associations": {
"electrosphere_fluidsim.h": "c", "electrosphere_fluidsim.h": "c",
"jni.h": "c", "jni.h": "c",
"electrosphere_server_fluid_simulator_fluidacceleratedsimulator.h": "c" "electrosphere_server_fluid_simulator_fluidacceleratedsimulator.h": "c",
"utilities.h": "c",
"simulation.h": "c",
"chunk.h": "c",
"chunkmask.h": "c",
"metadatacalc.h": "c"
} }
} }

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Sat Nov 30 18:07:55 EST 2024 #Sat Nov 30 19:02:40 EST 2024
buildNumber=427 buildNumber=435

View File

@ -68,12 +68,17 @@ INPUT_FILES="./src/fluidsim.c"
OUTPUT_FILE="./fluidsim.o" OUTPUT_FILE="./fluidsim.o"
gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE
COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -DSAVE_STEPS=$SAVE_STEPS"
INPUT_FILES="./src/metadatacalc.c"
OUTPUT_FILE="./metadatacalc.o"
gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE
#compile shared object file #compile shared object file
OUTPUT_FILE="libfluidsim$LIB_ENDING" OUTPUT_FILE="libfluidsim$LIB_ENDING"
COMPILE_FLAGS="-shared" COMPILE_FLAGS="-shared"
INPUT_FILES="fluidsim.o javainterface.o" INPUT_FILES="fluidsim.o javainterface.o metadatacalc.o"
gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE gcc $COMPILE_FLAGS $INPUT_FILES -o $OUTPUT_FILE
#move to resources #move to resources

View File

@ -7,6 +7,18 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#undef electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_SIMULATE_TIMESTEP
#define electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_SIMULATE_TIMESTEP 0.01f
#undef electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_GRAVITY_CONST
#define electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_GRAVITY_CONST 1000.0f
/*
* Class: electrosphere_server_fluid_simulator_FluidAcceleratedSimulator
* Method: init
* Signature: (F)V
*/
JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_init
(JNIEnv *, jclass, jfloat);
/* /*
* Class: electrosphere_server_fluid_simulator_FluidAcceleratedSimulator * Class: electrosphere_server_fluid_simulator_FluidAcceleratedSimulator
* Method: simulate * Method: simulate

View File

@ -0,0 +1,11 @@
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
/**
* Stores data about the simulation environment
*/
typedef struct {
float gravity;
} Environment;
#endif

View File

@ -0,0 +1,18 @@
#ifndef METADATACALC
#define METADATACALC
#include "./chunk.h"
#include "./environment.h"
/**
* Updates the metadata for all chunks
* @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in
* @param environment The environment data
*/
void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment);
#endif

View File

@ -2,7 +2,15 @@
#define SIMULATION_H #define SIMULATION_H
#include "./chunk.h" #include "./chunk.h"
#include "./environment.h"
void simulate(int numChunks, Chunk ** passedInChunks, float timestep); /**
* Performs the main simulation
* @param numChunks The number of chunks
* @param passedInChunks The chunks to simulate
* @param environment The environment data
* @param timestep The timestep to simulate by
*/
void simulate(int numChunks, Chunk ** passedInChunks, Environment * environment, float timestep);
#endif #endif

View File

@ -31,10 +31,12 @@ Chunk ** chunks = NULL;
//https://stackoverflow.com/questions/39823375/clarification-about-getfieldid //https://stackoverflow.com/questions/39823375/clarification-about-getfieldid
static inline void saveStep(float * values, const char * name); static inline void saveStep(float * values, const char * name);
static inline void applyGravity(Chunk * currentChunk, Environment * environment);
void simulate( void simulate(
int numChunks, int numChunks,
Chunk ** passedInChunks, Chunk ** passedInChunks,
Environment * environment,
jfloat timestep jfloat timestep
){ ){
chunks = passedInChunks; chunks = passedInChunks;
@ -50,6 +52,7 @@ void simulate(
//solve chunk mask //solve chunk mask
for(int i = 0; i < numChunks; i++){ for(int i = 0; i < numChunks; i++){
Chunk * currentChunk = chunks[i]; Chunk * currentChunk = chunks[i];
applyGravity(currentChunk,environment);
addSourceToVectors( addSourceToVectors(
DIM, DIM,
currentChunk->chunkMask, currentChunk->chunkMask,
@ -539,4 +542,20 @@ static inline void saveStep(float * values, const char * name){
fclose(fp); fclose(fp);
} }
}
/**
* Applies gravity to the chunk
* @param currentChunk The chunk to apply on
* @param environment The environment data of the world
*/
static inline void applyGravity(Chunk * currentChunk, Environment * environment){
int N = DIM;
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;
}
}
}
} }

View File

@ -10,6 +10,7 @@
#include "../includes/chunkmask.h" #include "../includes/chunkmask.h"
#include "../includes/utilities.h" #include "../includes/utilities.h"
#include "../includes/simulation.h" #include "../includes/simulation.h"
#include "../includes/metadatacalc.h"
//defines //defines
@ -35,6 +36,9 @@ Chunk ** javaChunkView = NULL;
//the number of chunks //the number of chunks
int numChunks = 0; int numChunks = 0;
//the environment data
Environment * environment = NULL;
JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_simulate( JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_simulate(
JNIEnv * env, JNIEnv * env,
@ -43,7 +47,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jfloat dt jfloat dt
){ ){
readInChunks(env,chunkList); readInChunks(env,chunkList);
simulate(numChunks,javaChunkView,dt); simulate(numChunks,javaChunkView,environment,dt);
updateMetadata(numChunks,javaChunkView,environment);
} }
/** /**
@ -66,6 +71,19 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
numChunks = 0; numChunks = 0;
} }
/**
* Initializes the library
*/
JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_init(
JNIEnv * env,
jclass fluidSimClass,
jfloat gravity
){
if(environment == NULL){
environment = (Environment *)malloc(sizeof(Environment));
}
environment->gravity = gravity;
}
/** /**
* Reads chunks into the dynamic array * Reads chunks into the dynamic array

View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <immintrin.h>
#include <stdint.h>
#include "../includes/utilities.h"
#include "../includes/chunkmask.h"
#include "../includes/metadatacalc.h"
/**
* Updates the metadata for all chunks
* @param numChunks The number of chunks
* @param passedInChunks The chunks that were passed in
* @param environment The environment data
*/
void updateMetadata(int numChunks, Chunk ** passedInChunks, Environment * environment){
}

View File

@ -8,8 +8,6 @@ import java.nio.FloatBuffer;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/** /**
* Is a single chunk of terrain on the server * Is a single chunk of terrain on the server
@ -405,7 +403,7 @@ public class ServerFluidChunk {
* @return The index * @return The index
*/ */
public int IX(int x, int y, int z){ public int IX(int x, int y, int z){
return x * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION + y * ServerTerrainChunk.CHUNK_DIMENSION + z; return x * ServerFluidChunk.BUFFER_DIM * ServerFluidChunk.BUFFER_DIM + y * ServerFluidChunk.BUFFER_DIM + z;
} }
/** /**

View File

@ -26,6 +26,16 @@ import org.joml.Vector3i;
* Provides an interface for the server to query information about fluid * Provides an interface for the server to query information about fluid
*/ */
public class ServerFluidManager { public class ServerFluidManager {
/**
* DEfault size of the cache
*/
static final int DEFAULT_CACHE_SIZE = 500;
/**
* The number of frames to wait between updates
*/
static final int UPDATE_RATE = 0;
//the seed for the water //the seed for the water
long seed; long seed;
@ -38,7 +48,7 @@ public class ServerFluidManager {
//Basic idea is we associate string that contains chunk x&y&z with elevation //Basic idea is we associate string that contains chunk x&y&z with elevation
//While we incur a penalty with converting ints -> string, think this will //While we incur a penalty with converting ints -> string, think this will
//offset regenerating the array every time we want a new one //offset regenerating the array every time we want a new one
int cacheSize = 500; int cacheSize = DEFAULT_CACHE_SIZE;
@Exclude @Exclude
Map<String, ServerFluidChunk> chunkCache = new HashMap<String, ServerFluidChunk>(); Map<String, ServerFluidChunk> chunkCache = new HashMap<String, ServerFluidChunk>();
@Exclude @Exclude
@ -85,6 +95,12 @@ public class ServerFluidManager {
* The queue of chunks to broadcast * The queue of chunks to broadcast
*/ */
List<ServerFluidChunk> broadcastQueue = new LinkedList<ServerFluidChunk>(); List<ServerFluidChunk> broadcastQueue = new LinkedList<ServerFluidChunk>();
@Exclude
/**
* The update frame-skipping tracking variable
*/
int updatePhase = 0;
/** /**
@ -263,7 +279,9 @@ public class ServerFluidManager {
* @param worldZ The world z coordinate of the chunk * @param worldZ The world z coordinate of the chunk
*/ */
public void queue(int worldX, int worldY, int worldZ){ public void queue(int worldX, int worldY, int worldZ){
this.simulationQueue.add(this.getChunk(worldX, worldY, worldZ)); ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
fluidChunk.updated = true;
this.simulationQueue.add(fluidChunk);
} }
/** /**
@ -273,10 +291,18 @@ public class ServerFluidManager {
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate"); Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
lock.lock(); lock.lock();
if(simulate){ if(simulate){
if(this.serverFluidSimulator != null){ if(updatePhase == UPDATE_RATE){
this.serverFluidSimulator.simulate(this.simulationQueue,this.broadcastQueue); if(this.serverFluidSimulator != null){
this.serverFluidSimulator.simulate(this.simulationQueue,this.broadcastQueue);
}
} }
this.simulationQueue.clear(); this.simulationQueue.clear();
updatePhase++;
if(updatePhase > UPDATE_RATE){
updatePhase = 0;
}
} }
lock.unlock(); lock.unlock();
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();

View File

@ -26,6 +26,11 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
*/ */
public static final float SIMULATE_TIMESTEP = 0.01f; public static final float SIMULATE_TIMESTEP = 0.01f;
/**
* The gravity constant
*/
public static final float GRAVITY_CONST = -1000;
/** /**
* Load fluid sim library * Load fluid sim library
*/ */
@ -49,8 +54,29 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
* Starts up the simulator * Starts up the simulator
*/ */
public FluidAcceleratedSimulator(){ public FluidAcceleratedSimulator(){
FluidAcceleratedSimulator.init(FluidAcceleratedSimulator.GRAVITY_CONST);
} }
/**
* Initializes the data for the fluid sim library
*/
private static native void init(float gravity);
/**
* Main native simulation function
* @param chunks The list of chunks to simulate with
* @param timestep The timestep to simulate
*/
private static native void simulate(List<ServerFluidChunk> chunks, float timestep);
/**
* Frees all native memory
*/
private static native void free();
@Override @Override
public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){ public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){
FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP); FluidAcceleratedSimulator.simulate(fluidChunks, SIMULATE_TIMESTEP);
@ -61,13 +87,6 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
} }
} }
/**
* Main native simulation function
* @param chunks The list of chunks to simulate with
* @param timestep The timestep to simulate
*/
private static native void simulate(List<ServerFluidChunk> chunks, float timestep);
/** /**
* Cleans up the simulator's native state * Cleans up the simulator's native state
@ -76,9 +95,22 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
FluidAcceleratedSimulator.free(); FluidAcceleratedSimulator.free();
} }
/** /**
* Frees all native memory * Sums the density for a chunk
* @param fluidChunk The chunk
* @return The total density of the chunk
*/ */
private static native void free(); private static double sumAllDensity(ServerFluidChunk fluidChunk){
double rVal = 0;
for(int x = 0; x < ServerFluidChunk.BUFFER_DIM; x++){
for(int y = 0; y < ServerFluidChunk.BUFFER_DIM; y++){
for(int z = 0; z < ServerFluidChunk.BUFFER_DIM; z++){
rVal = rVal + fluidChunk.getWeight(x, y, z);
}
}
}
return rVal;
}
} }