cellular sim determinism
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
ab5e65b14f
commit
0091f94daf
@ -24,6 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
#define DIM 18
|
#define DIM 18
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The spacing between chunks
|
||||||
|
*/
|
||||||
|
#define CHUNK_SPACING 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A chunk
|
* A chunk
|
||||||
*/
|
*/
|
||||||
|
|||||||
2
src/main/c/src/fluid/env/environment.c
vendored
2
src/main/c/src/fluid/env/environment.c
vendored
@ -8,7 +8,7 @@
|
|||||||
* Creates an environment
|
* Creates an environment
|
||||||
*/
|
*/
|
||||||
LIBRARY_API Environment * fluid_environment_create(){
|
LIBRARY_API Environment * fluid_environment_create(){
|
||||||
Environment * rVal = (Environment *)malloc(sizeof(Environment));
|
Environment * rVal = (Environment *)calloc(1,sizeof(Environment));
|
||||||
rVal->queue.cellularQueue = NULL;
|
rVal->queue.cellularQueue = NULL;
|
||||||
rVal->queue.gridQueue = NULL;
|
rVal->queue.gridQueue = NULL;
|
||||||
return rVal;
|
return rVal;
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
* Creates a fluid island solver
|
* Creates a fluid island solver
|
||||||
*/
|
*/
|
||||||
LIBRARY_API FluidIslandSolver * fluid_island_solver_create(){
|
LIBRARY_API FluidIslandSolver * fluid_island_solver_create(){
|
||||||
FluidIslandSolver * rVal = (FluidIslandSolver *)malloc(sizeof(FluidIslandSolver));
|
FluidIslandSolver * rVal = (FluidIslandSolver *)calloc(1,sizeof(FluidIslandSolver));
|
||||||
|
|
||||||
rVal->sparseArray = fluid_sparse_array_create();
|
rVal->sparseArray = fluid_sparse_array_create();
|
||||||
rVal->remaining = NULL;
|
rVal->remaining = NULL;
|
||||||
|
|||||||
@ -203,7 +203,7 @@ int readInChunks(JNIEnv * env, jobject chunkList, Environment * environment){
|
|||||||
if(cSideArrPos >= stbds_arrlen(chunkViewC)){
|
if(cSideArrPos >= stbds_arrlen(chunkViewC)){
|
||||||
// printf("allocate chunk %d\n",i);
|
// printf("allocate chunk %d\n",i);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
newChunk = (Chunk *)malloc(sizeof(Chunk));
|
newChunk = (Chunk *)calloc(1,sizeof(Chunk));
|
||||||
// printf("new chunk %p\n",newChunk);
|
// printf("new chunk %p\n",newChunk);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
stbds_arrput(chunkViewC,newChunk);
|
stbds_arrput(chunkViewC,newChunk);
|
||||||
|
|||||||
@ -94,6 +94,6 @@ void updateMetadata(JNIEnv * env, int numChunks, Chunk ** passedInChunks, Enviro
|
|||||||
|
|
||||||
|
|
||||||
//update frame state
|
//update frame state
|
||||||
environment->state.frame += 1;
|
environment->state.frame = environment->state.frame + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ int solveOffset(int chunkPos);
|
|||||||
LIBRARY_API SparseChunkArray * fluid_sparse_array_create(){
|
LIBRARY_API SparseChunkArray * fluid_sparse_array_create(){
|
||||||
|
|
||||||
//allocate the object itself
|
//allocate the object itself
|
||||||
SparseChunkArray * rVal = (SparseChunkArray *)malloc(sizeof(SparseChunkArray));
|
SparseChunkArray * rVal = (SparseChunkArray *)calloc(1,sizeof(SparseChunkArray));
|
||||||
if(rVal == NULL){
|
if(rVal == NULL){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,11 +33,16 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
|
|||||||
|
|
||||||
Chunk ** chunks = environment->queue.cellularQueue;
|
Chunk ** chunks = environment->queue.cellularQueue;
|
||||||
int chunkCount = stbds_arrlen(chunks);
|
int chunkCount = stbds_arrlen(chunks);
|
||||||
|
int worldX, worldY, worldZ;
|
||||||
|
int permuteX, permuteY, permuteZ;
|
||||||
|
|
||||||
for(int cellIndex = 0; cellIndex < chunkCount; cellIndex++){
|
for(int cellIndex = 0; cellIndex < chunkCount; cellIndex++){
|
||||||
Chunk * currentChunk = chunks[cellIndex];
|
Chunk * currentChunk = chunks[cellIndex];
|
||||||
//simulate here
|
worldX = currentChunk->x;
|
||||||
|
worldY = currentChunk->y;
|
||||||
|
worldZ = currentChunk->z;
|
||||||
|
|
||||||
|
//simulate here
|
||||||
float *d = currentChunk->d[CENTER_LOC];
|
float *d = currentChunk->d[CENTER_LOC];
|
||||||
float * bounds = currentChunk->bounds[CENTER_LOC];
|
float * bounds = currentChunk->bounds[CENTER_LOC];
|
||||||
float density;
|
float density;
|
||||||
@ -45,8 +50,17 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
|
|||||||
|
|
||||||
// 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);
|
// 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 y = 0; y < DIM; y++){
|
for(int y = 0; y < DIM; y++){
|
||||||
int shift = randutils_map(randutils_rand2(environment->state.frame,y),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1);
|
if(y == 0){
|
||||||
int permutation = randutils_map(randutils_rand2(environment->state.frame,y + 1),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1);
|
permuteY = DIM-2 + (CHUNK_SPACING * (worldY - 1));
|
||||||
|
|
||||||
|
} else if(y == DIM-1){
|
||||||
|
permuteY = 1 + (CHUNK_SPACING * (worldY + 1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
permuteY = y + (CHUNK_SPACING * worldY);
|
||||||
|
}
|
||||||
|
int shift = randutils_map(randutils_rand2(environment->state.frame,permuteY),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1);
|
||||||
|
// int permutation = randutils_map(randutils_rand2(environment->state.frame,y + 1),0,FLUID_CELLULAR_KERNEL_PERMUTATIONS - 1);
|
||||||
for(int x = 0; x < DIM; x++){
|
for(int x = 0; x < DIM; x++){
|
||||||
for(int z = 0; z < DIM; z++){
|
for(int z = 0; z < DIM; z++){
|
||||||
|
|
||||||
@ -119,15 +133,35 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//transfer laterally
|
//transfer laterally
|
||||||
// int permutation = (z % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) + ((x % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) * (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2));
|
//calculate permutation based on the location of the cell
|
||||||
|
if(x == 0){
|
||||||
|
permuteX = DIM-2 + (CHUNK_SPACING * (worldX - 1));
|
||||||
|
|
||||||
|
} else if(x == DIM-1){
|
||||||
|
permuteX = 1 + (CHUNK_SPACING * (worldX + 1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
permuteX = x + (CHUNK_SPACING * worldX);
|
||||||
|
}
|
||||||
|
if(z == 0){
|
||||||
|
permuteZ = DIM-2 + (CHUNK_SPACING * (worldZ - 1));
|
||||||
|
|
||||||
|
} else if(z == DIM-1){
|
||||||
|
permuteZ = 1 + (CHUNK_SPACING * (worldZ + 1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
permuteZ = z + (CHUNK_SPACING * worldZ);
|
||||||
|
}
|
||||||
|
int permutation = (permuteZ % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) + ((permuteX % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) * (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2));
|
||||||
// for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){
|
// for(int j = 0; j < FLUID_CELLULAR_KERNEL_SIZE; j++){
|
||||||
int nX = x + fluid_cellular_kernel_x[permutation][shift];
|
int nX = x + fluid_cellular_kernel_x[shift][permutation];
|
||||||
int nZ = z + fluid_cellular_kernel_z[permutation][shift];
|
int nZ = z + fluid_cellular_kernel_z[shift][permutation];
|
||||||
if(nX < 0 || nX >= DIM || nZ < 0 || nZ >= DIM){
|
if(nX < 0 || nX >= DIM || nZ < 0 || nZ >= DIM){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(bounds[IX(nX,y,nZ)] <= BOUND_CUTOFF_VALUE){
|
if(bounds[IX(nX,y,nZ)] <= BOUND_CUTOFF_VALUE){
|
||||||
if(d[IX(nX,y,nZ)] <= MIN_FLUID_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(nX,y,nZ)] = d[IX(x,y,z)];
|
||||||
d[IX(x,y,z)] = MIN_FLUID_VALUE;
|
d[IX(x,y,z)] = MIN_FLUID_VALUE;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
* @return The pool
|
* @return The pool
|
||||||
*/
|
*/
|
||||||
POOL * pool_create(int blockSize){
|
POOL * pool_create(int blockSize){
|
||||||
POOL * p = (POOL*)malloc(sizeof(POOL) );
|
POOL * p = (POOL*)calloc(1,sizeof(POOL) );
|
||||||
p->table = NULL;
|
p->table = NULL;
|
||||||
p->blockSize = blockSize;
|
p->blockSize = blockSize;
|
||||||
p->posCurr = 0;
|
p->posCurr = 0;
|
||||||
|
|||||||
@ -90,6 +90,7 @@ int fluid_sim_cellular_bounds_test1(){
|
|||||||
rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value was overwritten on border! -- %f %f \n");
|
rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value was overwritten on border! -- %f %f \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +99,7 @@ int fluid_sim_cellular_bounds_test2(){
|
|||||||
printf("fluid_sim_cellular_bounds_test2\n");
|
printf("fluid_sim_cellular_bounds_test2\n");
|
||||||
|
|
||||||
Environment * env = fluid_environment_create();
|
Environment * env = fluid_environment_create();
|
||||||
|
env->state.frame += 10;
|
||||||
|
|
||||||
int chunkCount = 27;
|
int chunkCount = 27;
|
||||||
|
|
||||||
@ -140,14 +142,65 @@ int fluid_sim_cellular_bounds_test2(){
|
|||||||
|
|
||||||
//assert that the density moved
|
//assert that the density moved
|
||||||
{
|
{
|
||||||
float borderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)];
|
float borderOldVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-1)];
|
||||||
float orderBorderVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-3)];
|
float borderNewVal = queue[0]->d[CENTER_LOC][IX(1,1,DIM-2)];
|
||||||
float transferedVal = queue[1]->d[CENTER_LOC][IX(1,1,0)];
|
float 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(borderOldVal,MIN_FLUID_VALUE,"Border old val has not changed! -- %f %f \n");
|
||||||
rVal += assertEqualsFloat(orderBorderVal,CELLULAR_TEST_PLACE_VAL,"Border value has not moved! -- %f %f \n");
|
rVal += assertEqualsFloat(borderNewVal,CELLULAR_TEST_PLACE_VAL,"Border new val not occupied! -- %f %f \n");
|
||||||
rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value was overwritten on border! -- %f %f \n");
|
rVal += assertEqualsFloat(transferedVal,CELLULAR_TEST_PLACE_VAL,"Value was overwritten on border! -- %f %f \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fluid_sim_cellular_stability_test1(){
|
||||||
|
int rVal = 0;
|
||||||
|
printf("fluid_sim_cellular_stability_test1\n");
|
||||||
|
|
||||||
|
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[1]->d[CENTER_LOC][IX(1,1,1)] = CELLULAR_TEST_PLACE_VAL;
|
||||||
|
|
||||||
|
//check sum beforehand
|
||||||
|
float originalSum = chunk_queue_sum(queue);
|
||||||
|
|
||||||
|
|
||||||
|
//dispatch and simulate
|
||||||
|
int frameCount = 50;
|
||||||
|
for(int i = 0; i < frameCount; i++){
|
||||||
|
fluid_solve_bounds(chunkCount,queue,env);
|
||||||
|
fluid_dispatch(chunkCount,queue,env);
|
||||||
|
fluid_simulate(env);
|
||||||
|
env->state.frame++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check sum beforehand
|
||||||
|
float afterSum = chunk_queue_sum(queue);
|
||||||
|
|
||||||
|
rVal += assertEqualsFloat(originalSum,afterSum,"cellular sim was unstable! %f %f \n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +210,7 @@ int fluid_sim_cellular_cellular_tests(int argc, char **argv){
|
|||||||
|
|
||||||
rVal += fluid_sim_cellular_bounds_test1();
|
rVal += fluid_sim_cellular_bounds_test1();
|
||||||
rVal += fluid_sim_cellular_bounds_test2();
|
rVal += fluid_sim_cellular_bounds_test2();
|
||||||
|
rVal += fluid_sim_cellular_stability_test1();
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -214,6 +214,25 @@ void chunk_link_neighbors(Chunk ** chunks){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sums all chunks in a queue
|
||||||
|
*/
|
||||||
|
float chunk_queue_sum(Chunk ** chunks){
|
||||||
|
float sum = 0;
|
||||||
|
int num = arrlen(chunks);
|
||||||
|
for(int i = 0; i < num; i++){
|
||||||
|
Chunk * current = chunks[i];
|
||||||
|
for(int x = 1; x < DIM - 2; x++){
|
||||||
|
for(int y = 1; y < DIM - 2; y++){
|
||||||
|
for(int z = 1; z < DIM - 2; z++){
|
||||||
|
sum = sum + current->d[CENTER_LOC][IX(x,y,z)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty test launcher
|
* Empty test launcher
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -88,4 +88,9 @@ void chunk_free_queue(Chunk ** chunks);
|
|||||||
*/
|
*/
|
||||||
void chunk_link_neighbors(Chunk ** chunks);
|
void chunk_link_neighbors(Chunk ** chunks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sums all chunks in a queue
|
||||||
|
*/
|
||||||
|
float chunk_queue_sum(Chunk ** chunks);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user