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": {
"electrosphere_fluidsim.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
#Sat Nov 30 18:07:55 EST 2024
buildNumber=427
#Sat Nov 30 19:02:40 EST 2024
buildNumber=435

View File

@ -68,12 +68,17 @@ INPUT_FILES="./src/fluidsim.c"
OUTPUT_FILE="./fluidsim.o"
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
OUTPUT_FILE="libfluidsim$LIB_ENDING"
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
#move to resources

View File

@ -7,6 +7,18 @@
#ifdef __cplusplus
extern "C" {
#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
* 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
#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

View File

@ -31,10 +31,12 @@ Chunk ** chunks = NULL;
//https://stackoverflow.com/questions/39823375/clarification-about-getfieldid
static inline void saveStep(float * values, const char * name);
static inline void applyGravity(Chunk * currentChunk, Environment * environment);
void simulate(
int numChunks,
Chunk ** passedInChunks,
Environment * environment,
jfloat timestep
){
chunks = passedInChunks;
@ -50,6 +52,7 @@ void simulate(
//solve chunk mask
for(int i = 0; i < numChunks; i++){
Chunk * currentChunk = chunks[i];
applyGravity(currentChunk,environment);
addSourceToVectors(
DIM,
currentChunk->chunkMask,
@ -540,3 +543,19 @@ static inline void saveStep(float * values, const char * name){
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/utilities.h"
#include "../includes/simulation.h"
#include "../includes/metadatacalc.h"
//defines
@ -35,6 +36,9 @@ Chunk ** javaChunkView = NULL;
//the number of chunks
int numChunks = 0;
//the environment data
Environment * environment = NULL;
JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAcceleratedSimulator_simulate(
JNIEnv * env,
@ -43,7 +47,8 @@ JNIEXPORT void JNICALL Java_electrosphere_server_fluid_simulator_FluidAccelerate
jfloat dt
){
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;
}
/**
* 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

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.Vector3i;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/**
* Is a single chunk of terrain on the server
@ -405,7 +403,7 @@ public class ServerFluidChunk {
* @return The index
*/
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

@ -27,6 +27,16 @@ import org.joml.Vector3i;
*/
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
long seed;
@ -38,7 +48,7 @@ public class ServerFluidManager {
//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
//offset regenerating the array every time we want a new one
int cacheSize = 500;
int cacheSize = DEFAULT_CACHE_SIZE;
@Exclude
Map<String, ServerFluidChunk> chunkCache = new HashMap<String, ServerFluidChunk>();
@Exclude
@ -86,6 +96,12 @@ public class ServerFluidManager {
*/
List<ServerFluidChunk> broadcastQueue = new LinkedList<ServerFluidChunk>();
@Exclude
/**
* The update frame-skipping tracking variable
*/
int updatePhase = 0;
/**
* Constructor
@ -263,7 +279,9 @@ public class ServerFluidManager {
* @param worldZ The world z coordinate of the chunk
*/
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");
lock.lock();
if(simulate){
if(updatePhase == UPDATE_RATE){
if(this.serverFluidSimulator != null){
this.serverFluidSimulator.simulate(this.simulationQueue,this.broadcastQueue);
}
}
this.simulationQueue.clear();
updatePhase++;
if(updatePhase > UPDATE_RATE){
updatePhase = 0;
}
}
lock.unlock();
Globals.profiler.endCpuSample();

View File

@ -26,6 +26,11 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
*/
public static final float SIMULATE_TIMESTEP = 0.01f;
/**
* The gravity constant
*/
public static final float GRAVITY_CONST = -1000;
/**
* Load fluid sim library
*/
@ -49,8 +54,29 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
* Starts up the simulator
*/
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
public void simulate(List<ServerFluidChunk> fluidChunks, List<ServerFluidChunk> broadcastQueue){
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
@ -76,9 +95,22 @@ public class FluidAcceleratedSimulator implements ServerFluidSimulator {
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;
}
}