#include #include #include #include #include "includes/utilities.h" #include "includes/chunkmask.h" void advectDensity(JNIEnv * env, uint32_t chunk_mask, int N, int b, float ** d, float ** d0, float * u, float * v, float * w, float dt); /* * Class: electrosphere_FluidSim * Method: addDensity * Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;F)V */ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_addDensity (JNIEnv * env, jobject this, jint N, jint chunk_mask, float ** d, float ** d0, jfloat dt){ int i; int size=N*N*N; float * x = GET_ARR_RAW(env,d,CENTER_LOC); float * s = GET_ARR_RAW(env,d0,CENTER_LOC); for(i=0; iN-1){ for(i=i-8; i < N-1; i++){ x[IX(i,j,k)] = (x0[IX(i,j,k)] + a*(x[IX(i-1,j,k)]+x[IX(i+1,j,k)]+x[IX(i,j-1,k)]+x[IX(i,j+1,k)]+x[IX(i,j,k-1)]+x[IX(i,j,k+1)]))/c; } } } } } /* * Class: electrosphere_FluidSim * Method: advectDensity * Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;FFF)V */ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_advectDensity (JNIEnv * env, jobject this, jint N, jint chunk_mask, float ** d, float ** d0, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, jfloat DIFFUSION_CONST, jfloat VISCOSITY_CONST, jfloat dt){ advectDensity(env,chunk_mask,N,3,d,d0,GET_ARR(env,jru,CENTER_LOC),GET_ARR(env,jrv,CENTER_LOC),GET_ARR(env,jrw,CENTER_LOC),dt); } void advectDensity(JNIEnv * env, uint32_t chunk_mask, int N, int b, float ** d, float ** d0, float * u, float * v, float * w, float dt){ int i, j, k, i0, j0, k0, i1, j1, k1; int m,n,o; float x, y, z, s0, t0, s1, t1, u1, u0, dtx,dty,dtz; dtx=dty=dtz=dt*N; float * center_d = GET_ARR_RAW(env,d,CENTER_LOC); float * center_d0 = GET_ARR_RAW(env,d0,CENTER_LOC); for(k=1; k= N-1){ m += 1; } if(y < 1){ n -= 1; } if(y >= N-1){ n += 1; } if(z < 1){ o -= 1; } if(z >= N-1){ o += 1; } //If the out of bounds coordinate is in bounds for a neighbor chunk, use that chunk as source instead // if(CK(m,n,o) != CENTER_LOC){ // printf("Looking in border chunk\n"); // } // if(x > 16){ // printf("%f %d %d %d\n",m,n,o); // } // if(CK(m,n,o) != CENTER_LOC && ARR_EXISTS(chunk_mask,m,n,o)){ // // printf("Hit other chunk\n"); // d0 = GET_ARR(env,jrd0,CK(m,n,o)); // x = x + CHUNK_NORMALIZE_U[CK(m,n,o)] * (N-1); // y = y + CHUNK_NORMALIZE_V[CK(m,n,o)] * (N-1); // z = z + CHUNK_NORMALIZE_W[CK(m,n,o)] * (N-1); // } if(x < 0.001f){ //cases to consider: //m = 0, x = -10 //m = 2, x = 0.01 x=0.001f; i0=(int)0; i1=1; s0 = 0.999f; s1 = 0.001f; } else if(x >= N - 1){ //cases to consider: //m = 0, x = 17.01 //m = 2, x = 20 x = N-1; i0=(int)N-2; i1=N-1; s0 = 0.001f; s1 = 0.999f; } else { i0=(int)x; i1=i0+1; s1 = x-i0; s0 = 1-s1; } //clamp location within chunk // if (x<0.5f) x=0.5f; // if (x>N+0.5f) x=N+0.5f; if (y<0.5f) y=0.5f; if (y>N+0.5f) y=N+0.5f; if (z<0.5f) z=0.5f; if (z>N+0.5f) z=N+0.5f; //get actual indices // i0=(int)x; // i1=i0+1; j0=(int)y; j1=j0+1; k0=(int)z; k1=k0+1; //calculate percentage of each index // s1 = x-i0; // s0 = 1-s1; t1 = y-j0; t0 = 1-t1; u1 = z-k0; u0 = 1-u1; if(i0 >= N){ i0 = N - 1; } // if(i0 < 0){ // i0 = 0; // } if(j0 >= N){ j0 = N - 1; } // if(j0 < 0){ // j0 = 0; // } if(k0 >= N){ k0 = N - 1; } // if(k0 < 0){ // k0 = 0; // } if(i1 >= N){ i1 = N - 1; } // if(i1 < 0){ // i1 = 0; // } if(j1 >= N){ j1 = N - 1; } // if(j1 < 0){ // j1 = 0; // } if(k1 >= N){ k1 = N - 1; } // if(k1 < 0){ // k1 = 0; // } center_d[IX(i,j,k)] = s0*( t0*u0*center_d0[IX(i0,j0,k0)]+ t1*u0*center_d0[IX(i0,j1,k0)]+ t0*u1*center_d0[IX(i0,j0,k1)]+ t1*u1*center_d0[IX(i0,j1,k1)] )+ s1*( t0*u0*center_d0[IX(i1,j0,k0)]+ t1*u0*center_d0[IX(i1,j1,k0)]+ t0*u1*center_d0[IX(i1,j0,k1)]+ t1*u1*center_d0[IX(i1,j1,k1)] ); } } } }