cellular stability work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-12-08 18:47:40 -05:00
parent 3a87349a66
commit 662d9a83f2
3 changed files with 1080 additions and 72 deletions

View File

@ -32,6 +32,26 @@
*/
LIBRARY_API void fluid_cellular_simulate(Environment * environment);
/**
* Gets the x velocity of a given position
* @param environment The environment storing the simulation queues
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @preturn The flow direction of x
*/
LIBRARY_API int fluid_cellular_get_flow_x(Environment * environment, int x, int y, int z);
/**
* Gets the z velocity of a given position
* @param environment The environment storing the simulation queues
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @preturn The flow direction of z
*/
LIBRARY_API int fluid_cellular_get_flow_z(Environment * environment, int x, int y, int z);

View File

@ -41,6 +41,12 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
int worldX, worldY, worldZ;
int permuteX, permuteY, permuteZ;
int frame = environment->state.frame;
int permuteRand;
int adjacentXKernel;
int adjacentZKernel;
double oldSum = 0;
double newSum = 0;
for(int cellIndex = 0; cellIndex < chunkCount; cellIndex++){
Chunk * currentChunk = chunks[cellIndex];
@ -54,6 +60,9 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
float density;
int transferred = 0;
oldSum = 0;
newSum = 0;
// 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++){
if(y == 0){
@ -70,6 +79,7 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
// 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 z = 0; z < DIM; z++){
oldSum = oldSum + d[IX(x,y,z)];
if(bounds[IX(x,y,z)] > BOUND_CUTOFF_VALUE){
continue;
}
@ -123,6 +133,12 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
if(permuteY % 16 == 0){
fluid_cellular_lat_tracker[x][z] = 1;
}
// if(worldX == 0 && worldZ == 0 && x == 1 && z == 1){
// printf("vertical\n");
// printf("[%d %d %d] <%d,%d,%d> --> <%d,%d,%d> \n",worldX,worldY,worldZ,x,y,z,x,y-1,z);
// printf("%f %d %d --> %d %d \n",transfer,permuteX,permuteZ,permuteX,permuteZ);
// printf("%f %f \n",d[IX(x,y,z)],d[IX(x,y-1,z)]);
// }
// printf("vertical\n");
// printf("[%d %d %d] <%d,%d,%d> --> <%d,%d,%d> %f \n",worldX,worldY,worldZ,x,y,z,x,y-1,z,transfer);
// printf("%d %d %d --> %d %d %d \n",permuteX,y,permuteZ,permuteX,y-1,permuteZ);
@ -142,23 +158,138 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
}
// float permutRand = randutils_rand3(permuteX,permuteZ,environment->state.frame);
int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ,frame),0,3);
int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ,frame),0,4);
// int permutation = (permuteZ % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2)) + (((permuteX % (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2))) * (FLUID_CELLULAR_KERNEL_PERMUTATIONS / 2));
int permutation = permuteRand;
int xKernel = fluid_cellular_kernel_x[shift][permutation];
int zKernel = fluid_cellular_kernel_z[shift][permutation];
int nX = x + xKernel;
int nZ = z + zKernel;
int realNeighborX = permuteX + xKernel;
int realNeighborZ = permuteZ + zKernel;
// if(permuteX == 2 && permuteZ == 3){
// printf("[%d %d %d] <%d,%d,%d>\n",worldX,worldY,worldZ,x,y,z);
// printf("%d %d \n",permuteX,permuteZ);
// printf("targeting %d %d \n",xKernel,zKernel);
// printf("\n");
// }
// if(realNeighborX == 2 && realNeighborZ == 3){
// printf("[%d %d %d] <%d,%d,%d>\n",worldX,worldY,worldZ,x,y,z);
// printf("%d %d \n",permuteX,permuteZ);
// printf("targeting %d %d \n",realNeighborX,realNeighborZ);
// printf("\n");
// }
// printf("[%d %d %d] <%d,%d,%d>\n",worldX,worldY,worldZ,x,y,z);
// printf("%d %d \n",permuteX,permuteZ);
if(nX < 0 || nX >= DIM || nZ < 0 || nZ >= DIM){
continue;
}
// int skip = 0;
// for(int q = 0; q < 2; q++){
// if(permuteX % 16 == q){
// skip = 1;
// }
// }
// if(skip == 1){
// continue;
// }
// |O ||
//-++-------------------------++
//-++-------------------------++
// |O ||
// |O ||
// |O ||
// |O ||
// |O ||
// |O ||
// |O ||
// |O ||
// |O ||
//-++-------------------------++
//-++-------------------------++
// |O ||
//
//we are dealing with the OOOOOOOOO here
//
// if(permuteX % 16 > 1 && permuteZ % 16 == 1){
// int pass = 0;
// if(zKernel == 1){
// pass = 1;
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-2,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel != 1){
// pass = 0;
// }
// }
// if(zKernel == -1){
// pass = 1;
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-2,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == 1){
// pass = 0;
// }
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ-1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentXKernel == -1){
// pass = 0;
// }
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ-1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentXKernel == 1){
// pass = 0;
// }
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentXKernel == -1){
// pass = 0;
// }
// if(adjacentXKernel == 1){
// pass = 0;
// }
// if(adjacentZKernel == -1){
// pass = 0;
// }
// if(adjacentZKernel == 1){
// pass = 0;
// }
// }
// if(pass == 0){
// continue;
// }
// }
// if(permuteX % 16 > 1 && permuteZ % 16 == 0){
// int pass = 0;
// if(pass == 0){
// continue;
// }
// }
// if(x < 2 || z < 1 || x > DIM-3 || z > DIM-2){
// continue;
// }
// if((z < 2 || z > DIM-3) && (xKernel != 0)){
// continue;
// }
// if((x < 2 || x > DIM-3) && (zKernel != 0)){
// continue;
// }
// if(zKernel != 0){
// continue;
// }
//15<-(16)<-17
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 0 && xKernel == -1){
int permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,3);
int adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == -1){
continue;
}
@ -166,7 +297,552 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 0 && zKernel == -1){
int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,3);
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == -1){
continue;
}
}
// 15
// V
//15<-(16)
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 0 && xKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == 1){
continue;
}
}
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 0 && zKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == 1){
continue;
}
}
//16<-(17)<-18
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 1 && xKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == -1){
continue;
}
}
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 1 && zKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == -1){
continue;
}
}
//
// 15,15 16,15 17,15 18,15
// +---------------+
// 15,16 | 16,16 17,16 | 18,16
// | |
// 15,17 | 16,17 17,17 | 18,17
// +---------------+
// 15,18 16,18 17,18 18,18
//
//every chunk is guaranteed to have the data in the box for its corners
// if(permuteZ % 16 == 15){
// if(xKernel != 0){
// continue;
// }
// }
// if(permuteZ % 16 == 0 && permuteX % 16 == 15){
// // if(xKernel != 0){
// continue;
// // }
// }
// if(permuteZ % 16 == 0 && permuteX % 16 == 0){
// // if(xKernel != 0){
// continue;
// // }
// }
// if(permuteZ % 16 == 0 && permuteX % 16 == 1){
// // if(xKernel != 0){
// continue;
// // }
// }
// if(permuteZ % 16 == 0 && permuteX % 16 == 2){
// // if(xKernel != 0){
// continue;
// // }
// }
// if(permuteZ % 16 == 1){
// if(xKernel != 0){
// continue;
// }
// }
// if(permuteZ % 16 == 1){
// if(xKernel != 0){
// continue;
// }
// }
// if(permuteX % 16 == 15){
// if(zKernel != 0){
// continue;
// }
// }
// if(permuteX % 16 == 0){
// if(zKernel != 0){
// continue;
// }
// }
// if(permuteX % 16 == 1){
// if(zKernel != 0){
// continue;
// }
// }
// if(permuteX % 16 == 1){
// if(zKernel != 0){
// continue;
// }
// }
// // 17,15
// // ^
// // (17,16)<- 18,16
// //
// //
// if(permuteX % 16 == 1 && permuteZ % 16 == 0){
// if(zKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == -1){
// continue;
// }
// }
// }
// // 17,15
// // V
// // (17,16)-> 18,16
// //
// //
// if(permuteX % 16 == 1 && permuteZ % 16 == 0){
// if(xKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == 1){
// continue;
// }
// }
// }
// //
// //
// // (17,17)<- 18,17
// // V
// // 17,18
// if(permuteX % 16 == 1 && permuteZ % 16 == 1){
// if(zKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == -1){
// continue;
// }
// }
// }
// //
// //
// // (17,17)-> 18,17
// // ^
// // 17,18
// if(permuteX % 16 == 1 && permuteZ % 16 == 1){
// if(xKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -1){
// continue;
// }
// }
// }
// // 16,15
// // ^
// // 15,16 ->(16,16)
// //
// //
// if(permuteX % 16 == 0 && permuteZ % 16 == 0){
// if(zKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == 1){
// continue;
// }
// }
// }
// // 16,15
// // V
// // 15,16 <-(16,16)
// //
// //
// if(permuteX % 16 == 0 && permuteZ % 16 == 0){
// if(xKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == 1){
// continue;
// }
// }
// }
// //
// //
// // 15,17 ->(16,17)
// // V
// // 17,18
// if(permuteX % 16 == 0 && permuteZ % 16 == 1){
// if(zKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == 1){
// continue;
// }
// }
// }
// //
// //
// // 15,17 <-(16,17)
// // ^
// // 17,18
// if(permuteX % 16 == 0 && permuteZ % 16 == 1){
// if(xKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -1){
// continue;
// }
// }
// }
// //
// //
// // 15,17 ->(16,17)
// // ^
// // 17,18
// if(permuteX % 16 == 0 && permuteZ % 16 == 1){
// if(xKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -1){
// continue;
// }
// }
// }
// //
// // 15,15 16,15 17,15 18,15
// // +---------------+
// // 15,16 | 16,16 17,16 | 18,16
// // | |
// // 15,17 | 16,17 17,17 | 18,17
// // +---------------+
// // 15,18 16,18 17,18 18,18
// //
// //every chunk is guaranteed to have the data in the box for its corners
// //
// //inserting into square from top edge
// //
// // (17,15)
// // V
// // 16,16 -> 17,16
// //
// //
// if(permuteX % 16 == 1 && permuteZ % 16 == 15){
// if(zKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ+1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == 1){
// continue;
// }
// }
// }
// // (16,15)
// // V
// // 16,16 <- 17,16
// //
// //
// if(permuteX % 16 == 0 && permuteZ % 16 == 15){
// if(zKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ+1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == -1){
// continue;
// }
// }
// }
// //
// //inserting into square from left edge
// //
// //
// //
// //(15,16)-> 16,16
// // V
// // 16,17
// if(permuteX % 16 == 15 && permuteZ % 16 == 0){
// if(xKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ+1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -11){
// continue;
// }
// }
// }
// // 16,16
// // ^
// //(15,17)-> 16,17
// //
// //
// if(permuteX % 16 == 15 && permuteZ % 16 == 0){
// if(xKernel == 1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ-1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -1){
// continue;
// }
// }
// }
// //
// //inserting into square from bottom edge
// //
// //
// //
// // 16,17 <- 17,17
// // ^
// // (17,18)
// if(permuteX % 16 == 1 && permuteZ % 16 == 2){
// if(zKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ-1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == -1){
// continue;
// }
// }
// }
// //
// //
// // 16,17 -> 17,17
// // ^
// // (16,18)
// if(permuteX % 16 == 0 && permuteZ % 16 == 2){
// if(zKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ-1,frame),0,4);
// adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
// if(adjacentXKernel == 1){
// continue;
// }
// }
// }
// //
// //inserting into square from right edge
// //
// //
// //
// // 17,16 <-(18,16)
// // ^
// // 17,17
// if(permuteX % 16 == 2 && permuteZ % 16 == 0){
// if(xKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ+1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == -1){
// continue;
// }
// }
// }
// // 17,16
// // V
// // 17,17 <-(18,17)
// //
// //
// if(permuteX % 16 == 2 && permuteZ % 16 == 1){
// if(xKernel == -1){
// permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ-1,frame),0,4);
// adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// if(adjacentZKernel == 1){
// continue;
// }
// }
// }
//(15)->16->17
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 15 && xKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX+1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == 1){
continue;
}
}
// (15)
// V
// 16
// V
// 17
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 15 && zKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == 1){
continue;
}
}
// 16<-17<-(18)
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 2 && xKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == -1){
continue;
}
}
// 16
// ^
// 17
// ^
// (18)
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 2 && zKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == -1){
continue;
}
}
//16->(17)->18
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 1 && xKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == 1){
continue;
}
}
// (16)
// V
// 17
// V
// 18
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 1 && zKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == 1){
continue;
}
}
//15->16<-(17)
if(permuteX % 16 == 1 && xKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX-2,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == 1){
continue;
}
}
if(permuteZ % 16 == 1 && zKernel == -1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-2,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == 1){
continue;
}
}
//(16)->17<-18
if(permuteX % 16 == 0 && xKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX+2,permuteZ,frame),0,4);
adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == -1){
continue;
}
}
if(permuteZ % 16 == 0 && zKernel == 1){
permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+2,frame),0,4);
adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == -1){
continue;
}
}
if(permuteZ % 16 == 0 && zKernel == 1){
int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ+2,frame),0,4);
int adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == -1){
continue;
@ -174,29 +850,38 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
}
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteX % 16 == 1 && xKernel == 1){
int permuteRand = randutils_map(randutils_rand3(permuteX-1,permuteZ,frame),0,3);
int adjacentXKernel = fluid_cellular_kernel_x[shift][permuteRand];
if(adjacentXKernel == 1){
continue;
}
}
//basically if we're about to pull negative and the NEXT voxel is also pulling negative, don't
//this prevents density desync between chunks
if(permuteZ % 16 == 1 && zKernel == 1){
if(permuteZ % 16 == 2 && zKernel == -1){
int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,3);
int adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
if(adjacentZKernel == 1){
if(adjacentZKernel == -1){
continue;
}
}
if(bounds[IX(nX,y,nZ)] <= BOUND_CUTOFF_VALUE){
if(d[IX(nX,y,nZ)] <= MAX_FLUID_VALUE - FLUID_CELLULAR_DIFFUSE_RATE2 && d[IX(nX,y,nZ)] < d[IX(x,y,z)]){
float transfer = FLUID_CELLULAR_DIFFUSE_RATE2;
if(d[IX(x,y,z)] < FLUID_CELLULAR_DIFFUSE_RATE2){
transfer = d[IX(x,y,z)];
}
// if(worldX == 2 && worldZ == 2){
// if(realNeighborZ == 17 && realNeighborX == 8){
// printf("lateral\n");
// printf("[%d %d %d] <%d,%d,%d> --> <%d,%d,%d> \n",worldX,worldY,worldZ,x,y,z,nX,y,nZ);
// printf("%f %d %d --> %d %d \n",transfer,permuteX,permuteZ,permuteX + xKernel,permuteZ + zKernel);
// printf("%d %d \n",xKernel,zKernel);
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
// int permuteRand = randutils_map(randutils_rand3(permuteX,permuteZ-1,frame),0,3);
// int adjacentZKernel = fluid_cellular_kernel_z[shift][permuteRand];
// printf("%d %d \n",permuteRand,adjacentZKernel);
// printf("transfer!\n");
// }
// if(permuteX == 45){
// printf("lateral\n");
// printf("[%d %d %d] <%d,%d,%d> --> <%d,%d,%d> \n",worldX,worldY,worldZ,x,y,z,nX,y,nZ);
// printf("%f %d %d --> %d %d \n",transfer,permuteX,permuteZ,permuteX + xKernel,permuteZ + zKernel);
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
// }
// if(worldX == 0 && worldZ == 0){
// printf("lateral\n");
// printf("[%d %d %d] <%d,%d,%d> --> <%d,%d,%d> \n",worldX,worldY,worldZ,x,y,z,nX,y,nZ);
// printf("%f %d %d --> %d %d \n",transfer,permuteX,permuteZ,permuteX + xKernel,permuteZ + zKernel);
@ -208,8 +893,16 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
d[IX(nX,y,nZ)] = d[IX(nX,y,nZ)] + transfer;
d[IX(x,y,z)] = d[IX(x,y,z)] - transfer;
// if(worldX == 0 && worldZ == 0){
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
// printf("\n");
// }
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
// printf("\n");
// if(permuteX == 45){
// printf("%f %f \n",d[IX(x,y,z)],d[IX(nX,y,nZ)]);
// printf("\n");
// }
}
}
@ -223,6 +916,56 @@ LIBRARY_API void fluid_cellular_simulate(Environment * environment){
}
}
}
// for(int x = 0; x < DIM; x++){
// for(int y = 0; y < DIM; y++){
// for(int z = 0; z < DIM; z++){
// newSum = newSum + d[IX(x,y,z)];
// }
// }
// }
// if(newSum > 0){
// double newRatio = oldSum / newSum;
// printf("newRatio: %lf = %lf / %lf \n",newRatio,oldSum,newSum);
// for(int x = 0; x < DIM; x++){
// for(int y = 0; y < DIM; y++){
// for(int z = 0; z < DIM; z++){
// d[IX(x,y,z)] = (float)(d[IX(x,y,z)] * newRatio);
// }
// }
// }
// }
}
}
/**
* Gets the x velocity of a given position
* @param environment The environment storing the simulation queues
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @preturn The flow direction of x
*/
LIBRARY_API int fluid_cellular_get_flow_x(Environment * environment, int x, int y, int z){
int shift = environment->state.frame % FLUID_CELLULAR_KERNEL_PERMUTATIONS;
int permuteRand = randutils_map(randutils_rand3(x,z,environment->state.frame),0,4);
int permutation = permuteRand;
return fluid_cellular_kernel_x[shift][permutation];
}
/**
* Gets the z velocity of a given position
* @param environment The environment storing the simulation queues
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @preturn The flow direction of z
*/
LIBRARY_API int fluid_cellular_get_flow_z(Environment * environment, int x, int y, int z){
int shift = environment->state.frame % FLUID_CELLULAR_KERNEL_PERMUTATIONS;
int permuteRand = randutils_map(randutils_rand3(x,z,environment->state.frame),0,4);
int permutation = permuteRand;
return fluid_cellular_kernel_z[shift][permutation];
}

View File

@ -52,6 +52,26 @@ Chunk * fluid_sim_cellular_test_get_chunk(Chunk ** queue, int x, int y, int z){
return queue[x * 3 * 3 + y * 3 + z];
}
void fluid_sim_cellular_test_describe_chunks(Chunk ** queue){
float chunkSum = 0;
int compareX, compareZ;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
chunkSum = 0;
for(int x = 1; x < DIM-1; x++){
for(int z = 1; z < DIM-1; z++){
compareX = i;
compareZ = j;
float newVal = fluid_sim_cellular_test_get_chunk(queue,compareX,0,compareZ)->d[CENTER_LOC][IX(x,1,z)];
chunkSum = chunkSum + newVal;
}
}
printf("[%d %d] %f \n",i,j,chunkSum);
}
}
}
void fluid_sim_cellular_test_diagnose_desync(Chunk ** queue){
@ -120,6 +140,107 @@ void fluid_sim_cellular_test_print_slice(Chunk * chunk, int y){
}
}
void fluid_sim_cellular_test_print_slice_big(Chunk ** queue, int y){
for(int i = 0; i < 3; i++){
for(int x = 1; x < DIM-1; x++){
for(int j = 0; j < 3; j++){
for(int z = 1; z < DIM-1; z++){
Chunk * chunk = queue[i * 3 * 3 + j];
float * d = chunk->d[CENTER_LOC];
printf("%.2f ", d[IX(x,y,z)]);
}
}
printf("\n");
}
}
// float * d = chunk->d[CENTER_LOC];
// for(int x = 0; x < DIM; x++){
// for(int z = 0; z < DIM; z++){
// printf("%.2f ", d[IX(x,y,z)]);
// }
// printf("\n");
// }
}
void fluid_sim_cellular_test_print_slice_big_vis(Chunk ** queue, int y){
for(int z = 1; z < (DIM-2)*3+1; z++){
printf(" %2d ",z);
}
printf("\n");
for(int i = 0; i < 3; i++){
for(int x = 1; x < DIM-1; x++){
float sum = 0;
for(int j = 0; j < 3; j++){
for(int z = 1; z < DIM-1; z++){
Chunk * chunk = queue[i * 3 * 3 + j];
float * d = chunk->d[CENTER_LOC];
float val = d[IX(x,y,z)];
sum = sum + val;
if(val >= 0.95){
printf(" M ");
} else if(val < 0.05){
printf(" 0 ");
} else {
printf("%0.1f ", d[IX(x,y,z)]);
}
}
}
printf(" [%d] %f ",x,sum);
printf("\n");
}
}
// float * d = chunk->d[CENTER_LOC];
// for(int x = 0; x < DIM; x++){
// for(int z = 0; z < DIM; z++){
// printf("%.2f ", d[IX(x,y,z)]);
// }
// printf("\n");
// }
}
void fluid_sim_cellular_test_print_flow_big(Environment * environment, int y){
printf(" ");
for(int z = 1; z < (DIM-2)*3; z++){
if(z % 16 == 1 && z > 1){
printf(" ");
}
printf("%2d ",z);
}
printf("\n");
for(int x = 1; x < (DIM-2)*3+1; x++){
printf("%2d ",x);
for(int z = 1; z < (DIM-2)*3; z++){
int flowX = fluid_cellular_get_flow_x(environment, x, y, z);
int flowZ = fluid_cellular_get_flow_z(environment, x, y, z);
if(z % 16 == 1 && z > 1){
printf(" ");
}
if(flowX == -1){
printf("^ ");
} else if(flowX == 1){
printf("V ");
} else if(flowZ == -1){
printf("< ");
} else if(flowZ == 1){
printf("> ");
} else {
printf(" ");
}
}
if(x % 16 == 0){
printf("\n");
}
printf("\n");
}
// float * d = chunk->d[CENTER_LOC];
// for(int x = 0; x < DIM; x++){
// for(int z = 0; z < DIM; z++){
// printf("%.2f ", d[IX(x,y,z)]);
// }
// printf("\n");
// }
}
int fluid_sim_cellular_bounds_test1(){
@ -724,7 +845,7 @@ int fluid_sim_cellular_stability_test7(){
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
printf("frame: %d --- %f \n", frameCounter,currentSum);
// printf("frame: %d --- %f \n", frameCounter,currentSum);
fluid_solve_bounds(chunkCount,queue,env);
fluid_dispatch(chunkCount,queue,env);
fluid_simulate(env);
@ -738,7 +859,7 @@ int fluid_sim_cellular_stability_test7(){
fluid_sim_cellular_test_diagnose_desync(queue);
break;
}
printf("\n");
// printf("\n");
env->state.frame++;
}
@ -1101,7 +1222,7 @@ int fluid_sim_cellular_stability_test12(){
float originalSum = chunk_queue_sum(queue);
//dispatch and simulate
int frameCount = 100;
int frameCount = 1000;
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
@ -1180,7 +1301,7 @@ int fluid_sim_cellular_stability_test13(){
float originalSum = chunk_queue_sum(queue);
//dispatch and simulate
int frameCount = 100;
int frameCount = 1000;
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
@ -1261,74 +1382,25 @@ int fluid_sim_cellular_stability_test14(){
float slice[16 * 3][16 * 3];
int compareX = 2;
int compareZ = 2;
float compSum = 0;
//dispatch and simulate
int frameCount = 100;
int frameCount = 1000;
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
float delta = fabs(originalSum - currentSum);
if(delta > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD1){
fluid_sim_cellular_test_print_slice_big_vis(queue,1);
printf("Failed to equal sums! \n");
rVal += assertEqualsFloat(currentSum,originalSum,"Sums are not identical! %f %f \n");
printf("desync by frame %d \n",frameCounter);
break;
}
// printf("frame: %d --- %f \n", frameCounter,currentSum);
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
for(int x = 1; x < DIM-1; x++){
for(int z = 1; z < DIM-1; z++){
Chunk * chunk = fluid_sim_cellular_test_get_chunk(queue,compareX,0,compareZ);
float * d = chunk->d[CENTER_LOC];
slice[x-1 + i * 16][z-1 + j * 16] = d[IX(x,1,z)];
}
}
}
}
fluid_solve_bounds(chunkCount,queue,env);
fluid_dispatch(chunkCount,queue,env);
fluid_simulate(env);
fluid_solve_bounds(chunkCount,queue,env);
// compSum= 0 ;
// for(int i = 0; i < 3; i++){
// for(int j = 0; j < 3; j++){
// for(int x = 1; x < DIM-1; x++){
// for(int z = 1; z < DIM-1; z++){
// compareX = i;
// compareZ = j;
// float newVal = fluid_sim_cellular_test_get_chunk(queue,compareX,0,compareZ)->d[CENTER_LOC][IX(x,1,z)];
// float sliceVal = slice[x-1 + i * 16][z-1 + j * 16];
// if(fabs(newVal - sliceVal) > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD2){
// compSum = compSum + (newVal - sliceVal);
// // printf("change at %d %d -- %f %f \n",x,z,sliceVal,newVal);
// }
// }
// }
// }
// }
// if(compSum > 1.0f){
// printf("compSum: %f \n",compSum);
// for(int i = 0; i < 3; i++){
// for(int j = 0; j < 3; j++){
// for(int x = 1; x < DIM-1; x++){
// for(int z = 1; z < DIM-1; z++){
// compareX = i;
// compareZ = j;
// float newVal = fluid_sim_cellular_test_get_chunk(queue,compareX,0,compareZ)->d[CENTER_LOC][IX(x,1,z)];
// float sliceVal = slice[x-1 + i * 16][z-1 + j * 16];
// if(fabs(newVal - sliceVal) > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD2){
// printf("change at %d %d -- %f %f \n",x + i * 16,z + j * 16,sliceVal,newVal);
// }
// }
// }
// }
// }
// rVal++;
// break;
// }
// printf("\n");
env->state.frame++;
}
@ -1346,7 +1418,178 @@ int fluid_sim_cellular_stability_test14(){
rVal += assertEqualsFloat(originalSum,afterSum,"cellular sim was unstable! %f %f \n");
}
printf("\n");
// printf("\n");
return rVal;
}
int fluid_sim_cellular_stability_test15(){
int rVal = 0;
printf("fluid_sim_cellular_stability_test15\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);
}
//fill the bottom plane of chunks
for(int x = 0; x < 3; x++){
for(int z = 0; z < 3; z++){
float ** d = queue[x * 3 * 3 + z]->d;
for(int i = 1; i < DIM-2; i++){
for(int j = 1; j < DIM-2; j++){
d[CENTER_LOC][IX(i,1,j)] = MAX_FLUID_VALUE;
d[CENTER_LOC][IX(i,2,j)] = MAX_FLUID_VALUE;
}
}
}
}
//check sum beforehand
float originalSum = chunk_queue_sum(queue);
float slice[16 * 3][16 * 3];
int compareX = 2;
int compareZ = 2;
//dispatch and simulate
int frameCount = 100;
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
float delta = fabs(originalSum - currentSum);
if(delta > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD1){
printf("SLICE 1\n\n");
fluid_sim_cellular_test_print_slice_big_vis(queue,1);
printf("\n\n\n");
printf("SLICE 2\n\n");
fluid_sim_cellular_test_print_slice_big_vis(queue,2);
printf("Failed to equal sums! \n");
rVal += assertEqualsFloat(currentSum,originalSum,"Sums are not identical! %f %f \n");
printf("desync by frame %d \n",frameCounter);
break;
}
// printf("frame: %d --- %f \n", frameCounter,currentSum);
fluid_solve_bounds(chunkCount,queue,env);
fluid_dispatch(chunkCount,queue,env);
fluid_simulate(env);
fluid_solve_bounds(chunkCount,queue,env);
env->state.frame++;
}
//solve bounds afterwards to properly push data back into real arrays
//ie, if data is pushed out of bounds from one chunk to another, must
//then copy it into the in-bounds chunk
fluid_solve_bounds(chunkCount,queue,env);
//check sum beforehand
float afterSum = chunk_queue_sum(queue);
//diff the sums to see if we've changed value a lot
float delta = fabs(originalSum - afterSum);
if(delta > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD1){
rVal += assertEqualsFloat(originalSum,afterSum,"cellular sim was unstable! %f %f \n");
}
// printf("\n");
return rVal;
}
int fluid_sim_cellular_stability_test16(){
int rVal = 0;
printf("fluid_sim_cellular_stability_test16\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);
}
//fill the bottom plane of chunks
for(int x = 0; x < 3; x++){
for(int z = 0; z < 3; z++){
float ** d = queue[x * 3 * 3 + z]->d;
for(int i = 2; i < DIM-2; i++){
for(int j = 2; j < DIM-2; j++){
d[CENTER_LOC][IX(i,1,j)] = MAX_FLUID_VALUE;
}
}
}
}
//check sum beforehand
float originalSum = chunk_queue_sum(queue);
float slice[16 * 3][16 * 3];
int compareX = 2;
int compareZ = 2;
//dispatch and simulate
int frameCount = 1000;
int frameCounter;
for(frameCounter = 0; frameCounter < frameCount; frameCounter++){
float currentSum = chunk_queue_sum(queue);
float delta = fabs(originalSum - currentSum);
if(delta > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD1){
fluid_sim_cellular_test_print_slice_big_vis(queue,1);
printf("Failed to equal sums! \n");
rVal += assertEqualsFloat(currentSum,originalSum,"Sums are not identical! %f %f \n");
printf("desync by frame %d \n",frameCounter);
break;
}
// printf("frame: %d --- %f \n", frameCounter,currentSum);
fluid_solve_bounds(chunkCount,queue,env);
fluid_dispatch(chunkCount,queue,env);
fluid_simulate(env);
fluid_solve_bounds(chunkCount,queue,env);
env->state.frame++;
}
//solve bounds afterwards to properly push data back into real arrays
//ie, if data is pushed out of bounds from one chunk to another, must
//then copy it into the in-bounds chunk
fluid_solve_bounds(chunkCount,queue,env);
//check sum beforehand
float afterSum = chunk_queue_sum(queue);
//diff the sums to see if we've changed value a lot
float delta = fabs(originalSum - afterSum);
if(delta > FLUID_CELLULAR_TOLLERABLE_LOSS_THRESHOLD1){
rVal += assertEqualsFloat(originalSum,afterSum,"cellular sim was unstable! %f %f \n");
}
// printf("\n");
return rVal;
}
@ -1370,6 +1613,8 @@ int fluid_sim_cellular_cellular_tests(int argc, char **argv){
rVal += fluid_sim_cellular_stability_test12();
rVal += fluid_sim_cellular_stability_test13();
// rVal += fluid_sim_cellular_stability_test14();
// rVal += fluid_sim_cellular_stability_test15();
// rVal += fluid_sim_cellular_stability_test16();
return rVal;
}