Multiarrays
This commit is contained in:
parent
426dd88d29
commit
ad95b64b88
102
src/main/c/chunkmask.c
Normal file
102
src/main/c/chunkmask.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include <jni.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "includes/utilities.h"
|
||||||
|
#include "includes/chunkmask.h"
|
||||||
|
|
||||||
|
uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the bitmask for available chunks for the provided chunk's neighbor array
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_electrosphere_FluidSim_calculateChunkMask(JNIEnv * env, jobject this, jobjectArray jrx){
|
||||||
|
return matrix_transform(env,jrx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates a mask that represents all nearby chunks that are actually accessible and exist
|
||||||
|
*/
|
||||||
|
uint32_t matrix_transform(JNIEnv * env, jobjectArray jrx){
|
||||||
|
|
||||||
|
//The returned value, an availability mask that contains the availability of each neighbor chunk
|
||||||
|
uint32_t rVal = 0;
|
||||||
|
|
||||||
|
//Add to maks for initial chunks
|
||||||
|
for(int i = 0; i < CENTER_LOC; i++){
|
||||||
|
if((*env)->GetObjectArrayElement(env,jrx,i)!=NULL){
|
||||||
|
rVal = rVal + 1;
|
||||||
|
}
|
||||||
|
rVal = rVal << 1;
|
||||||
|
}
|
||||||
|
//add 1 for center chunk because we already have that
|
||||||
|
rVal = rVal + 1;
|
||||||
|
rVal = rVal << 1;
|
||||||
|
//continue on for remaining chunks
|
||||||
|
for(int i = CENTER_LOC+1; i < 27; i++){
|
||||||
|
if((*env)->GetObjectArrayElement(env,jrx,i)!=NULL){
|
||||||
|
rVal = rVal + 1;
|
||||||
|
}
|
||||||
|
if(i < 26){
|
||||||
|
rVal = rVal << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t CHUNK_INDEX_ARR[] = {
|
||||||
|
CHUNK_000, CHUNK_100, CHUNK_200,
|
||||||
|
CHUNK_010, CHUNK_110, CHUNK_210,
|
||||||
|
CHUNK_020, CHUNK_120, CHUNK_220,
|
||||||
|
|
||||||
|
CHUNK_001, CHUNK_101, CHUNK_201,
|
||||||
|
CHUNK_011, CHUNK_111, CHUNK_211,
|
||||||
|
CHUNK_021, CHUNK_121, CHUNK_221,
|
||||||
|
|
||||||
|
CHUNK_002, CHUNK_102, CHUNK_202,
|
||||||
|
CHUNK_012, CHUNK_112, CHUNK_212,
|
||||||
|
CHUNK_022, CHUNK_122, CHUNK_222,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//control offsetting the advect sampler location if a valid neighbor chunk is hit
|
||||||
|
const char CHUNK_NORMALIZE_U[] = {
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
-1, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char CHUNK_NORMALIZE_V[] = {
|
||||||
|
-1, -1, -1,
|
||||||
|
0, 0, 0,
|
||||||
|
1, 1, 1,
|
||||||
|
|
||||||
|
-1, -1, -1,
|
||||||
|
0, 0, 0,
|
||||||
|
1, 1, 1,
|
||||||
|
|
||||||
|
-1, -1, -1,
|
||||||
|
0, 0, 0,
|
||||||
|
1, 1, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char CHUNK_NORMALIZE_W[] = {
|
||||||
|
-1, -1, -1,
|
||||||
|
-1, -1, -1,
|
||||||
|
-1, -1, -1,
|
||||||
|
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
|
||||||
|
1, 1, 1,
|
||||||
|
1, 1, 1,
|
||||||
|
1, 1, 1,
|
||||||
|
};
|
||||||
@ -1,22 +1,24 @@
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "includes/utilities.h"
|
||||||
|
#include "includes/chunkmask.h"
|
||||||
|
|
||||||
|
|
||||||
#define SWAP(x0,x) {float *tmp=x0;x0=x;x=tmp;}
|
|
||||||
#define IX(i,j,k) ((i)+(N)*(j)+(N*N)*(k))
|
|
||||||
|
|
||||||
#define LINEARSOLVERTIMES 10
|
#define LINEARSOLVERTIMES 10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void diffuse(int N, int b, float * x, float * x0, float diff, float dt);
|
void diffuse(JNIEnv * env, uint32_t chunk_mask, int N, int b, float * x, float * x0, float diff, float dt);
|
||||||
void advect(int N, int b, float * d, float * d0, float * u, float * v, float * w, float dt);
|
void advect(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray jrd, float * d0, float * u, float * v, float * w, float dt);
|
||||||
void project(int N, float * u, float * v, float * w, float * p, float * div);
|
void project(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float * p, float * div);
|
||||||
void set_bnd(int N, int b, float * x);
|
void set_bnd(JNIEnv * env, uint32_t chunk_mask, int N, int b, float * x);
|
||||||
void dens_step(int N, float * x, float * x0, float * u, float * v, float * w, float diff, float dt);
|
void dens_step(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jrx, float * x0, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float diff, float dt);
|
||||||
void vel_step(int N, float * u, float * v, float * w, float * u0, float * v0, float * w0, float visc, float dt);
|
void vel_step(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float * u0, float * v0, float * w0, float visc, float dt);
|
||||||
void lin_solve(int N, int b, float* x, float* x0, float a, float c);
|
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core simulation function
|
* The core simulation function
|
||||||
@ -25,8 +27,7 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate(
|
|||||||
JNIEnv * env,
|
JNIEnv * env,
|
||||||
jobject this,
|
jobject this,
|
||||||
jint DIM_X,
|
jint DIM_X,
|
||||||
jint DIM_Y,
|
jint chunk_mask,
|
||||||
jint DIM_Z,
|
|
||||||
jobject jx,
|
jobject jx,
|
||||||
jobject jx0,
|
jobject jx0,
|
||||||
jobject ju,
|
jobject ju,
|
||||||
@ -39,18 +40,18 @@ JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate(
|
|||||||
jfloat VISCOSITY_RATE,
|
jfloat VISCOSITY_RATE,
|
||||||
jfloat timestep){
|
jfloat timestep){
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
float * x = (*env)->GetDirectBufferAddress(env,jx);
|
// float * x = (*env)->GetDirectBufferAddress(env,jx);
|
||||||
float * x0 = (*env)->GetDirectBufferAddress(env,jx0);
|
float * x0 = (*env)->GetDirectBufferAddress(env,jx0);
|
||||||
float * u = (*env)->GetDirectBufferAddress(env,ju);
|
// float * u = (*env)->GetDirectBufferAddress(env,ju);
|
||||||
float * v = (*env)->GetDirectBufferAddress(env,jv);
|
// float * v = (*env)->GetDirectBufferAddress(env,jv);
|
||||||
float * w = (*env)->GetDirectBufferAddress(env,jw);
|
// float * w = (*env)->GetDirectBufferAddress(env,jw);
|
||||||
float * u0 = (*env)->GetDirectBufferAddress(env,ju0);
|
float * u0 = (*env)->GetDirectBufferAddress(env,ju0);
|
||||||
float * v0 = (*env)->GetDirectBufferAddress(env,jv0);
|
float * v0 = (*env)->GetDirectBufferAddress(env,jv0);
|
||||||
float * w0 = (*env)->GetDirectBufferAddress(env,jw0);
|
float * w0 = (*env)->GetDirectBufferAddress(env,jw0);
|
||||||
int N = DIM_X;
|
int N = DIM_X;
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
vel_step(DIM_X, u, v, w, u0, v0, w0, VISCOSITY_RATE, timestep);
|
vel_step(env, chunk_mask, DIM_X, ju, jv, jw, u0, v0, w0, VISCOSITY_RATE, timestep);
|
||||||
dens_step(DIM_X, x, x0, u, v, w, DIFFUSION_RATE, timestep);
|
dens_step(env, chunk_mask, DIM_X, jx, x0, ju, jv, jw, DIFFUSION_RATE, timestep);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,20 +68,22 @@ void add_source(int N, float * x, float * s, float dt){
|
|||||||
/**
|
/**
|
||||||
* Diffuses a given array by a diffusion constant
|
* Diffuses a given array by a diffusion constant
|
||||||
*/
|
*/
|
||||||
void diffuse(int N, int b, float * x, float * x0, float diff, float dt){
|
void diffuse(JNIEnv * env, uint32_t chunk_mask, int N, int b, float * x, float * x0, float diff, float dt){
|
||||||
float a=dt*diff*N*N*N;
|
float a=dt*diff*N*N*N;
|
||||||
lin_solve(N, b, x, x0, a, 1+6*a);
|
lin_solve(env, chunk_mask, N, b, x, x0, a, 1+6*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Advects a given array based on the force vectors in the simulation
|
* Advects a given array based on the force vectors in the simulation
|
||||||
*/
|
*/
|
||||||
void advect(int N, int b, float * d, float * d0, float * u, float * v, float * w, float dt){
|
void advect(JNIEnv * env, uint32_t chunk_mask, int N, int b, jobjectArray jrd, float * d0, float * u, float * v, float * w, float dt){
|
||||||
int i, j, k, i0, j0, k0, i1, j1, k1;
|
int i, j, k, i0, j0, k0, i1, j1, k1;
|
||||||
float x, y, z, s0, t0, s1, t1, u1, u0, dtx,dty,dtz;
|
float x, y, z, s0, t0, s1, t1, u1, u0, dtx,dty,dtz;
|
||||||
|
|
||||||
dtx=dty=dtz=dt*N;
|
dtx=dty=dtz=dt*N;
|
||||||
|
|
||||||
|
float * d = GET_ARR(env,jrd,CENTER_LOC);
|
||||||
|
|
||||||
for(k=1; k<N-1; k++){
|
for(k=1; k<N-1; k++){
|
||||||
for(j=1; j<N-1; j++){
|
for(j=1; j<N-1; j++){
|
||||||
for(i=1; i<N-1; i++){
|
for(i=1; i<N-1; i++){
|
||||||
@ -131,41 +134,48 @@ void advect(int N, int b, float * d, float * d0, float * u, float * v, float * w
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_bnd(N, b, d);
|
set_bnd(env, chunk_mask, N, b, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main density step function
|
* The main density step function
|
||||||
*/
|
*/
|
||||||
void dens_step(int N, float * x, float * x0, float * u, float * v, float * w, float diff, float dt){
|
void dens_step(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jrx, float * x0, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float diff, float dt){
|
||||||
|
float * x = GET_ARR(env,jrx,CENTER_LOC);
|
||||||
|
float * u = GET_ARR(env,jru,CENTER_LOC);
|
||||||
|
float * v = GET_ARR(env,jrv,CENTER_LOC);
|
||||||
|
float * w = GET_ARR(env,jrw,CENTER_LOC);
|
||||||
add_source(N, x, x0, dt);
|
add_source(N, x, x0, dt);
|
||||||
SWAP(x0, x);
|
SWAP(x0, x);
|
||||||
diffuse(N, 0, x, x0, diff, dt);
|
diffuse(env, chunk_mask, N, 0, x, x0, diff, dt);
|
||||||
SWAP(x0, x);
|
SWAP(x0, x);
|
||||||
advect(N, 0, x, x0, u, v, w, dt);
|
advect(env, chunk_mask, N, 0, jrx, x0, u, v, w, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main velocity step function
|
* The main velocity step function
|
||||||
*/
|
*/
|
||||||
void vel_step(int N, float * u, float * v, float * w, float * u0, float * v0, float * w0, float visc, float dt){
|
void vel_step(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float * u0, float * v0, float * w0, float visc, float dt){
|
||||||
|
float * u = GET_ARR(env,jru,CENTER_LOC);
|
||||||
|
float * v = GET_ARR(env,jrv,CENTER_LOC);
|
||||||
|
float * w = GET_ARR(env,jrw,CENTER_LOC);
|
||||||
add_source(N, u, u0, dt);
|
add_source(N, u, u0, dt);
|
||||||
add_source(N, v, v0, dt);
|
add_source(N, v, v0, dt);
|
||||||
add_source(N, w, w0, dt);
|
add_source(N, w, w0, dt);
|
||||||
SWAP(u0, u);
|
SWAP(u0, u);
|
||||||
diffuse(N, 1, u, u0, visc, dt);
|
diffuse(env, chunk_mask, N, 1, u, u0, visc, dt);
|
||||||
SWAP(v0, v);
|
SWAP(v0, v);
|
||||||
diffuse(N, 2, v, v0, visc, dt);
|
diffuse(env, chunk_mask, N, 2, v, v0, visc, dt);
|
||||||
SWAP(w0, w);
|
SWAP(w0, w);
|
||||||
diffuse(N, 3, w, w0, visc, dt);
|
diffuse(env, chunk_mask, N, 3, w, w0, visc, dt);
|
||||||
project(N, u, v, w, u0, v0);
|
project(env, chunk_mask, N, jru, jrv, jrw, u0, v0);
|
||||||
SWAP(u0, u);
|
SWAP(u0, u);
|
||||||
SWAP(v0, v);
|
SWAP(v0, v);
|
||||||
SWAP(w0, w);
|
SWAP(w0, w);
|
||||||
advect(N, 1, u, u0, u0, v0, w0, dt);
|
advect(env, chunk_mask, N, 1, jru, u0, u0, v0, w0, dt);
|
||||||
advect(N, 2, v, v0, u0, v0, w0, dt);
|
advect(env, chunk_mask, N, 2, jrv, v0, u0, v0, w0, dt);
|
||||||
advect(N, 3, w, w0, u0, v0, w0, dt);
|
advect(env, chunk_mask, N, 3, jrw, w0, u0, v0, w0, dt);
|
||||||
project(N, u, v, w, u0, v0);
|
project(env, chunk_mask, N, jru, jrv, jrw, u0, v0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//used for temporary vector storage when appropriate
|
//used for temporary vector storage when appropriate
|
||||||
@ -174,7 +184,7 @@ float container[16];
|
|||||||
/**
|
/**
|
||||||
* Projects a given array based on force vectors
|
* Projects a given array based on force vectors
|
||||||
*/
|
*/
|
||||||
void project(int N, float * u, float * v, float * w, float * p, float * div){
|
void project(JNIEnv * env, uint32_t chunk_mask, int N, jobjectArray jru, jobjectArray jrv, jobjectArray jrw, float * p, float * div){
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
__m256 nVector = _mm256_set1_ps(N);
|
__m256 nVector = _mm256_set1_ps(N);
|
||||||
@ -182,6 +192,10 @@ void project(int N, float * u, float * v, float * w, float * p, float * div){
|
|||||||
__m256 zeroVec = _mm256_set1_ps(0);
|
__m256 zeroVec = _mm256_set1_ps(0);
|
||||||
__m256 vector, vector2, vector3;
|
__m256 vector, vector2, vector3;
|
||||||
|
|
||||||
|
float * u = GET_ARR(env,jru,CENTER_LOC);
|
||||||
|
float * v = GET_ARR(env,jrv,CENTER_LOC);
|
||||||
|
float * w = GET_ARR(env,jrw,CENTER_LOC);
|
||||||
|
|
||||||
for(k=1; k<N-1; k++){
|
for(k=1; k<N-1; k++){
|
||||||
for(j=1; j<N-1; j++){
|
for(j=1; j<N-1; j++){
|
||||||
i = 1;
|
i = 1;
|
||||||
@ -231,10 +245,10 @@ void project(int N, float * u, float * v, float * w, float * p, float * div){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_bnd(N, 0, div);
|
set_bnd(env, chunk_mask, N, 0, div);
|
||||||
set_bnd(N, 0, p);
|
set_bnd(env, chunk_mask, N, 0, p);
|
||||||
|
|
||||||
lin_solve(N, 0, p, div, 1, 6);
|
lin_solve(env, chunk_mask, N, 0, p, div, 1, 6);
|
||||||
|
|
||||||
|
|
||||||
constScalar = _mm256_set1_ps(0.5f*N);
|
constScalar = _mm256_set1_ps(0.5f*N);
|
||||||
@ -294,15 +308,15 @@ void project(int N, float * u, float * v, float * w, float * p, float * div){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_bnd(N, 1, u);
|
set_bnd(env, chunk_mask, N, 1, u);
|
||||||
set_bnd(N, 2, v);
|
set_bnd(env, chunk_mask, N, 2, v);
|
||||||
set_bnd(N, 3, w);
|
set_bnd(env, chunk_mask, N, 3, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Solves a linear system of equations in a vectorized manner
|
* Solves a linear system of equations in a vectorized manner
|
||||||
*/
|
*/
|
||||||
void lin_solve(int N, int b, float* x, float* x0, float a, float c){
|
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c){
|
||||||
int i, j, k, l, m;
|
int i, j, k, l, m;
|
||||||
__m256 aScalar = _mm256_set1_ps(a);
|
__m256 aScalar = _mm256_set1_ps(a);
|
||||||
__m256 cScalar = _mm256_set1_ps(c);
|
__m256 cScalar = _mm256_set1_ps(c);
|
||||||
@ -333,14 +347,14 @@ void lin_solve(int N, int b, float* x, float* x0, float a, float c){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_bnd(N, b, x);
|
set_bnd(env, chunk_mask, N, b, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the bounds of the simulation
|
* Sets the bounds of the simulation
|
||||||
*/
|
*/
|
||||||
void set_bnd(int N, int b, float * target){
|
void set_bnd(JNIEnv * env, uint32_t chunk_mask, int N, int b, float * target){
|
||||||
int DIM = N;
|
int DIM = N;
|
||||||
for(int x=1; x < DIM-1; x++){
|
for(int x=1; x < DIM-1; x++){
|
||||||
for(int y = 1; y < DIM-1; y++){
|
for(int y = 1; y < DIM-1; y++){
|
||||||
|
|||||||
48
src/main/c/includes/chunkmask.h
Normal file
48
src/main/c/includes/chunkmask.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef CHUNKMASK_H
|
||||||
|
#define CHUNKMASK_H
|
||||||
|
|
||||||
|
#define CENTER_LOC 13
|
||||||
|
|
||||||
|
#define CHUNK_222 1
|
||||||
|
#define CHUNK_122 2
|
||||||
|
#define CHUNK_022 4
|
||||||
|
#define CHUNK_212 8
|
||||||
|
#define CHUNK_112 16
|
||||||
|
#define CHUNK_012 32
|
||||||
|
#define CHUNK_202 64
|
||||||
|
#define CHUNK_102 128
|
||||||
|
#define CHUNK_002 256
|
||||||
|
|
||||||
|
#define CHUNK_221 512
|
||||||
|
#define CHUNK_121 1024
|
||||||
|
#define CHUNK_021 2048
|
||||||
|
#define CHUNK_211 4096
|
||||||
|
#define CHUNK_111 8192
|
||||||
|
#define CHUNK_011 16384
|
||||||
|
#define CHUNK_201 32768
|
||||||
|
#define CHUNK_101 65536
|
||||||
|
#define CHUNK_001 131072
|
||||||
|
|
||||||
|
#define CHUNK_220 262144
|
||||||
|
#define CHUNK_120 524288
|
||||||
|
#define CHUNK_020 1048576
|
||||||
|
#define CHUNK_210 2097152
|
||||||
|
#define CHUNK_110 4194304
|
||||||
|
#define CHUNK_010 8388608
|
||||||
|
#define CHUNK_200 16777216
|
||||||
|
#define CHUNK_100 33554432
|
||||||
|
#define CHUNK_000 67108864
|
||||||
|
|
||||||
|
extern const uint32_t CHUNK_INDEX_ARR[];
|
||||||
|
|
||||||
|
|
||||||
|
//control offsetting the advect sampler location if a valid neighbor chunk is hit
|
||||||
|
extern const char CHUNK_NORMALIZE_U[];
|
||||||
|
|
||||||
|
extern const char CHUNK_NORMALIZE_V[];
|
||||||
|
|
||||||
|
extern const char CHUNK_NORMALIZE_W[];
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -20,10 +20,26 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
* Class: electrosphere_FluidSim
|
* Class: electrosphere_FluidSim
|
||||||
* Method: simulate
|
* Method: simulate
|
||||||
* Signature: (IIILjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
|
* Signature: (II[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FFF)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate
|
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_simulate
|
||||||
(JNIEnv *, jobject, jint, jint, jint, jobject, jobject, jobject, jobject, jobject, jobject, jobject, jobject, jfloat, jfloat, jfloat);
|
(JNIEnv *, jobject, jint, jint, jobjectArray, jobject, jobjectArray, jobjectArray, jobjectArray, jobject, jobject, jobject, jfloat, jfloat, jfloat);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: electrosphere_FluidSim
|
||||||
|
* Method: linSolve
|
||||||
|
* Signature: (IIILjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;FF)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_linSolve
|
||||||
|
(JNIEnv *, jobject, jint, jint, jint, jobject, jobject, jfloat, jfloat);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: electrosphere_FluidSim
|
||||||
|
* Method: calculateChunkMask
|
||||||
|
* Signature: ([Ljava/nio/ByteBuffer;)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_electrosphere_FluidSim_calculateChunkMask
|
||||||
|
(JNIEnv *, jobject, jobjectArray);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/main/c/includes/utilities.h
Normal file
15
src/main/c/includes/utilities.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <jni.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef UTILITIES_H
|
||||||
|
#define UTILITIES_H
|
||||||
|
|
||||||
|
#define SWAP(x0,x) {float *tmp=x0;x0=x;x=tmp;}
|
||||||
|
#define IX(i,j,k) ((i)+(N)*(j)+(N*N)*(k))
|
||||||
|
#define CK(m,n,o) ((m)+(n)*(3)+(o)*(3)*(3))
|
||||||
|
#define GET_ARR(env,src,i) (*env)->GetDirectBufferAddress(env,(*env)->GetObjectArrayElement(env,src,i))
|
||||||
|
#define ARR_EXISTS(chunk_mask,m,n,o) (chunk_mask & CHUNK_INDEX_ARR[CK(m,n,o)]) > 0
|
||||||
|
|
||||||
|
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c);
|
||||||
|
|
||||||
|
#endif
|
||||||
59
src/main/c/linearsolver.c
Normal file
59
src/main/c/linearsolver.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include <jni.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "includes/utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_electrosphere_FluidSim_linSolve(
|
||||||
|
JNIEnv * env,
|
||||||
|
jobject this,
|
||||||
|
jint chunk_mask_raw,
|
||||||
|
jint DIM_X,
|
||||||
|
jint br,
|
||||||
|
jobject jrx,
|
||||||
|
jobject jrx0,
|
||||||
|
jfloat ar,
|
||||||
|
jfloat cr
|
||||||
|
){
|
||||||
|
//adapt object types
|
||||||
|
float * x = (*env)->GetDirectBufferAddress(env,jrx);
|
||||||
|
float * x0 = (*env)->GetDirectBufferAddress(env,jrx0);
|
||||||
|
|
||||||
|
//solve
|
||||||
|
lin_solve(env,chunk_mask_raw,DIM_X,br,x,x0,ar,cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves a linear system of equations in a vectorized manner
|
||||||
|
*/
|
||||||
|
void lin_solve(JNIEnv * env, uint32_t chunk_mask, int N, int b, float* x, float* x0, float a, float c){
|
||||||
|
int i, j, k, l, m;
|
||||||
|
__m256 aScalar = _mm256_set1_ps(a);
|
||||||
|
__m256 cScalar = _mm256_set1_ps(c);
|
||||||
|
// update for each cell
|
||||||
|
for(k=1; k<N-1; k++){
|
||||||
|
for(j=1; j<N-1; j++){
|
||||||
|
int n = 0;
|
||||||
|
//solve as much as possible vectorized
|
||||||
|
for(i = 1; i < N-1; i=i+8){
|
||||||
|
__m256 vector = _mm256_loadu_ps(&x[IX(i-1,j,k)]);
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i+1,j,k)]));
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j-1,k)]));
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j+1,k)]));
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j,k-1)]));
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x[IX(i,j,k+1)]));
|
||||||
|
vector = _mm256_mul_ps(vector,aScalar);
|
||||||
|
vector = _mm256_add_ps(vector,_mm256_loadu_ps(&x0[IX(i,j,k)]));
|
||||||
|
vector = _mm256_div_ps(vector,cScalar);
|
||||||
|
_mm256_storeu_ps(&x[IX(i,j,k)],vector);
|
||||||
|
}
|
||||||
|
//If there is any leftover, perform manual solving
|
||||||
|
if(i>N-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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.joml.Vector2i;
|
import org.joml.Vector2i;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.PointerBuffer;
|
import org.lwjgl.PointerBuffer;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
@ -28,14 +29,41 @@ public class FluidSim {
|
|||||||
|
|
||||||
public static final int DIM = 18;
|
public static final int DIM = 18;
|
||||||
|
|
||||||
ByteBuffer x = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
//
|
||||||
ByteBuffer x0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// +-------------+ ^ Y
|
||||||
ByteBuffer u = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// / | / | | _
|
||||||
ByteBuffer v = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// / | / | | /\ Z
|
||||||
ByteBuffer w = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
//(0,2,0) +-----+-------+ | | /
|
||||||
ByteBuffer u0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// | +-------+-----+ | /
|
||||||
ByteBuffer v0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// | / | / | /
|
||||||
ByteBuffer w0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
// | / | / |/
|
||||||
|
// +-------------+ (2,0,0) +---------------> X
|
||||||
|
|
||||||
|
//Buffers that contain density for current frame
|
||||||
|
ByteBuffer[] density = new ByteBuffer[27];
|
||||||
|
//Buffers that contain new density to add to the simulation
|
||||||
|
ByteBuffer densityAddition;
|
||||||
|
//Buffers that contain u vector directions
|
||||||
|
ByteBuffer[] uVector = new ByteBuffer[27];
|
||||||
|
//Buffers that contain v vector directions
|
||||||
|
ByteBuffer[] vVector = new ByteBuffer[27];
|
||||||
|
//Buffers that contain w vector directions
|
||||||
|
ByteBuffer[] wVector = new ByteBuffer[27];
|
||||||
|
//Buffers that contain u vector directions to add to the simulation
|
||||||
|
ByteBuffer uAdditionVector;
|
||||||
|
//Buffers that contain v vector directions to add to the simulation
|
||||||
|
ByteBuffer vAdditionVector;
|
||||||
|
//Buffers that contain w vector directions to add to the simulation
|
||||||
|
ByteBuffer wAdditionVector;
|
||||||
|
|
||||||
|
// ByteBuffer x = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer x0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer u = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer v = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer w = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer u0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer v0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
// ByteBuffer w0 = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
|
|
||||||
//The densities for every voxel for the current frame
|
//The densities for every voxel for the current frame
|
||||||
float[] densityArrayView = new float[DIM * DIM * DIM];
|
float[] densityArrayView = new float[DIM * DIM * DIM];
|
||||||
@ -58,19 +86,31 @@ public class FluidSim {
|
|||||||
|
|
||||||
static final float GRAVITY = -1000f;
|
static final float GRAVITY = -1000f;
|
||||||
|
|
||||||
public void setup(){
|
public void setup(Vector3i offset){
|
||||||
x.order(ByteOrder.LITTLE_ENDIAN);
|
//allocate buffers for this chunk
|
||||||
x0.order(ByteOrder.LITTLE_ENDIAN);
|
density[13] = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
u.order(ByteOrder.LITTLE_ENDIAN);
|
densityAddition = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
v.order(ByteOrder.LITTLE_ENDIAN);
|
uVector[13] = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
w.order(ByteOrder.LITTLE_ENDIAN);
|
vVector[13] = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
u0.order(ByteOrder.LITTLE_ENDIAN);
|
wVector[13] = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
v0.order(ByteOrder.LITTLE_ENDIAN);
|
uAdditionVector = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
w0.order(ByteOrder.LITTLE_ENDIAN);
|
vAdditionVector = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
FloatBuffer xf = x.asFloatBuffer();
|
wAdditionVector = ByteBuffer.allocateDirect(DIM * DIM * DIM * 4);
|
||||||
FloatBuffer uf = u.asFloatBuffer();
|
//order endian-ness
|
||||||
FloatBuffer vf = v.asFloatBuffer();
|
density[13].order(ByteOrder.LITTLE_ENDIAN);
|
||||||
FloatBuffer wf = w.asFloatBuffer();
|
densityAddition.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
uVector[13].order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
vVector[13].order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
wVector[13].order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
uAdditionVector.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
vAdditionVector.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
wAdditionVector.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
//set initial values for chunk
|
||||||
|
FloatBuffer xf = density[13].asFloatBuffer();
|
||||||
|
FloatBuffer uf = uVector[13].asFloatBuffer();
|
||||||
|
FloatBuffer vf = vVector[13].asFloatBuffer();
|
||||||
|
FloatBuffer wf = wVector[13].asFloatBuffer();
|
||||||
|
|
||||||
Random rand = new Random(1);
|
Random rand = new Random(1);
|
||||||
//make a cube of water in the center
|
//make a cube of water in the center
|
||||||
@ -78,12 +118,12 @@ public class FluidSim {
|
|||||||
for(int j = 0; j < DIM; j++){
|
for(int j = 0; j < DIM; j++){
|
||||||
for(int k = 0; k < DIM; k++){
|
for(int k = 0; k < DIM; k++){
|
||||||
if(
|
if(
|
||||||
Math.abs(16 - i) < 4 &&
|
Math.abs(8 - i) < 4 &&
|
||||||
Math.abs(j) < 4 &&
|
Math.abs(j) < 4 &&
|
||||||
Math.abs(10 - k) < 4
|
Math.abs(16 - k) < 4
|
||||||
){
|
){
|
||||||
xf.put(1);
|
xf.put(1);
|
||||||
uf.put(rand.nextFloat() * 0.1f);
|
uf.put(18);
|
||||||
vf.put(-1f);
|
vf.put(-1f);
|
||||||
wf.put(rand.nextFloat() * 0.1f);
|
wf.put(rand.nextFloat() * 0.1f);
|
||||||
} else {
|
} else {
|
||||||
@ -112,31 +152,45 @@ public class FluidSim {
|
|||||||
//
|
//
|
||||||
writeNewStateIntoBuffers();
|
writeNewStateIntoBuffers();
|
||||||
|
|
||||||
if(x.position() > 0){
|
// if(x.position() > 0){
|
||||||
x.position(0);
|
// x.position(0);
|
||||||
}
|
// }
|
||||||
if(x0.position() > 0){
|
// if(x0.position() > 0){
|
||||||
x0.position(0);
|
// x0.position(0);
|
||||||
}
|
// }
|
||||||
if(u.position() > 0){
|
// if(u.position() > 0){
|
||||||
u.position(0);
|
// u.position(0);
|
||||||
}
|
// }
|
||||||
if(v.position() > 0){
|
// if(v.position() > 0){
|
||||||
v.position(0);
|
// v.position(0);
|
||||||
}
|
// }
|
||||||
if(w.position() > 0){
|
// if(w.position() > 0){
|
||||||
w.position(0);
|
// w.position(0);
|
||||||
}
|
// }
|
||||||
if(u0.position() > 0){
|
// if(u0.position() > 0){
|
||||||
u0.position(0);
|
// u0.position(0);
|
||||||
}
|
// }
|
||||||
if(v0.position() > 0){
|
// if(v0.position() > 0){
|
||||||
v0.position(0);
|
// v0.position(0);
|
||||||
}
|
// }
|
||||||
if(w0.position() > 0){
|
// if(w0.position() > 0){
|
||||||
w0.position(0);
|
// w0.position(0);
|
||||||
}
|
// }
|
||||||
simulate(DIM, DIM, DIM, x, x0, u, v, w, u0, v0, w0, DIFFUSION_CONSTANT, VISCOSITY_CONSTANT, timestep);
|
simulate(
|
||||||
|
DIM,
|
||||||
|
0,
|
||||||
|
density,
|
||||||
|
densityAddition,
|
||||||
|
uVector,
|
||||||
|
vVector,
|
||||||
|
wVector,
|
||||||
|
uAdditionVector,
|
||||||
|
vAdditionVector,
|
||||||
|
wAdditionVector,
|
||||||
|
DIFFUSION_CONSTANT,
|
||||||
|
VISCOSITY_CONSTANT,
|
||||||
|
timestep
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
//Reads out the results of the fluid sim
|
//Reads out the results of the fluid sim
|
||||||
@ -153,25 +207,29 @@ public class FluidSim {
|
|||||||
//
|
//
|
||||||
//Read data back into arrays
|
//Read data back into arrays
|
||||||
//
|
//
|
||||||
if(x.position() > 0){
|
if(density[13].position() > 0){
|
||||||
x.position(0);
|
density[13].position(0);
|
||||||
}
|
}
|
||||||
if(u.position() > 0){
|
if(uVector[13].position() > 0){
|
||||||
u.position(0);
|
uVector[13].position(0);
|
||||||
}
|
}
|
||||||
if(v.position() > 0){
|
if(vVector[13].position() > 0){
|
||||||
v.position(0);
|
vVector[13].position(0);
|
||||||
}
|
}
|
||||||
if(w.position() > 0){
|
if(wVector[13].position() > 0){
|
||||||
w.position(0);
|
wVector[13].position(0);
|
||||||
}
|
}
|
||||||
|
FloatBuffer xFloatView = density[13].asFloatBuffer();
|
||||||
|
FloatBuffer uFloatView = uVector[13].asFloatBuffer();
|
||||||
|
FloatBuffer vFloatView = vVector[13].asFloatBuffer();
|
||||||
|
FloatBuffer wFloatView = wVector[13].asFloatBuffer();
|
||||||
for(int i = 0; i < DIM; i++){
|
for(int i = 0; i < DIM; i++){
|
||||||
for(int j = 0; j < DIM; j++){
|
for(int j = 0; j < DIM; j++){
|
||||||
for(int k = 0; k < DIM; k++){
|
for(int k = 0; k < DIM; k++){
|
||||||
densityArrayView[IX(i,j,k)] = x.getFloat();
|
densityArrayView[IX(i,j,k)] = xFloatView.get();
|
||||||
uArrayView[IX(i,j,k)] = u.getFloat();
|
uArrayView[IX(i,j,k)] = uFloatView.get();
|
||||||
vArrayView[IX(i,j,k)] = v.getFloat();
|
vArrayView[IX(i,j,k)] = vFloatView.get();
|
||||||
wArrayView[IX(i,j,k)] = w.getFloat();
|
wArrayView[IX(i,j,k)] = wFloatView.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,22 +239,22 @@ public class FluidSim {
|
|||||||
* Writes data from the java-side arrays into buffers that get passed into c-side
|
* Writes data from the java-side arrays into buffers that get passed into c-side
|
||||||
*/
|
*/
|
||||||
private void writeNewStateIntoBuffers(){
|
private void writeNewStateIntoBuffers(){
|
||||||
if(x0.position() > 0){
|
if(densityAddition.position() > 0){
|
||||||
x0.position(0);
|
densityAddition.position(0);
|
||||||
}
|
}
|
||||||
if(u0.position() > 0){
|
if(uAdditionVector.position() > 0){
|
||||||
u0.position(0);
|
uAdditionVector.position(0);
|
||||||
}
|
}
|
||||||
if(v0.position() > 0){
|
if(vAdditionVector.position() > 0){
|
||||||
v0.position(0);
|
vAdditionVector.position(0);
|
||||||
}
|
}
|
||||||
if(w0.position() > 0){
|
if(wAdditionVector.position() > 0){
|
||||||
w0.position(0);
|
wAdditionVector.position(0);
|
||||||
}
|
}
|
||||||
FloatBuffer x0FloatView = x0.asFloatBuffer();
|
FloatBuffer x0FloatView = densityAddition.asFloatBuffer();
|
||||||
FloatBuffer u0FloatView = u0.asFloatBuffer();
|
FloatBuffer u0FloatView = uAdditionVector.asFloatBuffer();
|
||||||
FloatBuffer v0FloatView = v0.asFloatBuffer();
|
FloatBuffer v0FloatView = vAdditionVector.asFloatBuffer();
|
||||||
FloatBuffer w0FloatView = w0.asFloatBuffer();
|
FloatBuffer w0FloatView = wAdditionVector.asFloatBuffer();
|
||||||
for(int i = 0; i < DIM; i++){
|
for(int i = 0; i < DIM; i++){
|
||||||
for(int j = 0; j < DIM; j++){
|
for(int j = 0; j < DIM; j++){
|
||||||
for(int k = 0; k < DIM; k++){
|
for(int k = 0; k < DIM; k++){
|
||||||
@ -241,13 +299,12 @@ public class FluidSim {
|
|||||||
*/
|
*/
|
||||||
private native void simulate(
|
private native void simulate(
|
||||||
int DIM_X,
|
int DIM_X,
|
||||||
int DIM_Y,
|
int chunkMask,
|
||||||
int DIM_Z,
|
ByteBuffer[] x,
|
||||||
ByteBuffer x,
|
|
||||||
ByteBuffer x0,
|
ByteBuffer x0,
|
||||||
ByteBuffer u,
|
ByteBuffer[] u,
|
||||||
ByteBuffer v,
|
ByteBuffer[] v,
|
||||||
ByteBuffer w,
|
ByteBuffer[] w,
|
||||||
ByteBuffer u0,
|
ByteBuffer u0,
|
||||||
ByteBuffer v0,
|
ByteBuffer v0,
|
||||||
ByteBuffer w0,
|
ByteBuffer w0,
|
||||||
@ -256,6 +313,10 @@ public class FluidSim {
|
|||||||
float timestep
|
float timestep
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private native void linSolve(int chunk_mask, int N, int b, ByteBuffer x, ByteBuffer x0, float a, float c);
|
||||||
|
|
||||||
|
private native int calculateChunkMask(ByteBuffer[] densityBuffers);
|
||||||
|
|
||||||
public float[] getData(){
|
public float[] getData(){
|
||||||
return densityArrayView;
|
return densityArrayView;
|
||||||
}
|
}
|
||||||
@ -264,4 +325,31 @@ public class FluidSim {
|
|||||||
return ((x)+(DIM)*(y) + (DIM)*(DIM)*(z));
|
return ((x)+(DIM)*(y) + (DIM)*(DIM)*(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final int getNeighborIndex(int x, int y, int z){
|
||||||
|
return x + y * 3 + z * 3 * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getDensityBuffer(){
|
||||||
|
return density[getNeighborIndex(1,1,1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getUBuffer(){
|
||||||
|
return uVector[getNeighborIndex(1,1,1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getVBuffer(){
|
||||||
|
return vVector[getNeighborIndex(1,1,1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getWBuffer(){
|
||||||
|
return wVector[getNeighborIndex(1,1,1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNeighbor(int x, int y, int z, FluidSim neighbor){
|
||||||
|
density[getNeighborIndex(x,y,z)] = neighbor.getDensityBuffer();
|
||||||
|
uVector[getNeighborIndex(x,y,z)] = neighbor.getUBuffer();
|
||||||
|
vVector[getNeighborIndex(x,y,z)] = neighbor.getVBuffer();
|
||||||
|
wVector[getNeighborIndex(x,y,z)] = neighbor.getWBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,11 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.render.GLFWContext;
|
import electrosphere.render.GLFWContext;
|
||||||
import electrosphere.render.Mesh;
|
import electrosphere.render.Mesh;
|
||||||
|
|
||||||
@ -14,30 +17,114 @@ import electrosphere.render.Mesh;
|
|||||||
*/
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String args[]){
|
public static void main(String args[]){
|
||||||
try {
|
try {
|
||||||
GLFWContext.init();
|
GLFWContext.init();
|
||||||
FluidSim sim = new FluidSim();
|
//init shader program
|
||||||
sim.setup();
|
Mesh.initShaderProgram();
|
||||||
Mesh.meshInitially(sim);
|
int dim = 1;
|
||||||
|
FluidSim[][][] simArray = new FluidSim[dim][1][1];
|
||||||
|
for(int x = 0; x < simArray.length; x++){
|
||||||
|
for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
simArray[x][y][z] = new FluidSim();
|
||||||
|
simArray[x][y][z].setup(new Vector3i(x,y,z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//set sim adjacencies
|
||||||
|
for(int x = 0; x < simArray.length; x++){
|
||||||
|
for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
FluidSim current = simArray[x][y][z];
|
||||||
|
|
||||||
|
for(int i = -1; i < 2; i++){
|
||||||
|
for(int j = -1; j < 2; j++){
|
||||||
|
for(int k = -1; k < 2; k++){
|
||||||
|
if(i == j && j == k && k == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(
|
||||||
|
0 <= x + i && x + i < simArray.length &&
|
||||||
|
0 <= y + j && y + j < simArray[0].length &&
|
||||||
|
0 <= z + k && z + k < simArray[0][0].length
|
||||||
|
){
|
||||||
|
current.setNeighbor(i+1,j+1,k+1,simArray[x+i][y+j][z+k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FluidSim sim = new FluidSim();
|
||||||
|
// sim.setup();
|
||||||
|
Mesh[][][] meshArray = new Mesh[dim][1][1];
|
||||||
|
for(int x = 0; x < simArray.length; x++){
|
||||||
|
for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
meshArray[x][y][z] = new Mesh(simArray[x][y][z], new Vector3i(z * 16, y * 16, x * 16));
|
||||||
|
meshArray[x][y][z].meshInitially();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Mesh mesh = new Mesh(sim);
|
||||||
|
// mesh.meshInitially();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
long time = 0;
|
long time = 0;
|
||||||
long lastTime = 0;
|
long lastTime = 0;
|
||||||
|
Scanner scan = new Scanner(System.in);
|
||||||
while(true){
|
while(true){
|
||||||
try {
|
try {
|
||||||
TimeUnit.MILLISECONDS.sleep(2);
|
TimeUnit.MILLISECONDS.sleep(2);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//Transfer data
|
||||||
|
//
|
||||||
lastTime = System.currentTimeMillis();
|
lastTime = System.currentTimeMillis();
|
||||||
sim.simulate(i,0.001f);
|
// for(int x = 0; x < simArray.length; x++){
|
||||||
|
// for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
// for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
// simArray[x][y][z].transfer();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//Simulate
|
||||||
|
//
|
||||||
|
for(int x = 0; x < simArray.length; x++){
|
||||||
|
for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
simArray[x][y][z].simulate(i, 0.001f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
time = time + (System.currentTimeMillis() - lastTime);
|
time = time + (System.currentTimeMillis() - lastTime);
|
||||||
Mesh.remesh(sim,i);
|
//
|
||||||
GLFWContext.redraw();
|
//Remesh
|
||||||
|
//
|
||||||
|
for(int x = 0; x < simArray.length; x++){
|
||||||
|
for(int y = 0; y < simArray[0].length; y++){
|
||||||
|
for(int z = 0; z < simArray[0][0].length; z++){
|
||||||
|
meshArray[x][y][z].remesh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//redraw
|
||||||
|
GLFWContext.redraw(meshArray);
|
||||||
i++;
|
i++;
|
||||||
if(i == 1000){
|
if(i == 1000){
|
||||||
System.out.println(time / 1000.0);
|
System.out.println(time / 1000.0);
|
||||||
}
|
}
|
||||||
|
if(i > 3){
|
||||||
|
// scan.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch(Throwable ex){
|
} catch(Throwable ex){
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
|
|||||||
@ -82,13 +82,19 @@ public class GLFWContext {
|
|||||||
GLFW.glfwSwapInterval(0);
|
GLFW.glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void redraw(){
|
public static void redraw(Mesh[][][] meshes){
|
||||||
//clear screen
|
//clear screen
|
||||||
GL44.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
GL44.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
GL44.glClear(GL44.GL_COLOR_BUFFER_BIT | GL44.
|
GL44.glClear(GL44.GL_COLOR_BUFFER_BIT | GL44.
|
||||||
GL_DEPTH_BUFFER_BIT);
|
GL_DEPTH_BUFFER_BIT);
|
||||||
//draw here
|
//draw here
|
||||||
Mesh.draw();
|
for(int x = 0; x < meshes.length; x++){
|
||||||
|
for(int y = 0; y < meshes[0].length; y++){
|
||||||
|
for(int z = 0; z < meshes[0][0].length; z++){
|
||||||
|
meshes[x][y][z].draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//ending stuff
|
//ending stuff
|
||||||
GLFW.glfwSwapBuffers(window);
|
GLFW.glfwSwapBuffers(window);
|
||||||
GLFW.glfwPollEvents();
|
GLFW.glfwPollEvents();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user