diff --git a/.vscode/launch.json b/.vscode/launch.json index c295062..8fd6c75 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,6 +5,15 @@ "name": "Launch Java Program", "request": "launch", "mainClass": "electrosphere.Main", + "preLaunchTask": "compileNoSteps", + "vmArgs": "-Djava.library.path=./shared-folder" + }, + { + "type": "java", + "name": "Launch Java Program (SAVE CHUNKS TO DISK)", + "request": "launch", + "mainClass": "electrosphere.Main", + "preLaunchTask": "compileWithSteps", "vmArgs": "-Djava.library.path=./shared-folder" } ] diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..059798a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "compileWithSteps", + "type": "shell", + "command": "SAVE_STEPS=1 ./src/main/c/compile.sh", + }, + { + "label": "compileNoSteps", + "type": "shell", + "command": "SAVE_STEPS=0 ./src/main/c/compile.sh", + } + ] +} \ No newline at end of file diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 765e648..810ad9f 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -73,6 +73,9 @@ bash + + 0 + ./src/main/c/compile.sh @@ -80,6 +83,10 @@ + + maven-surefire-plugin + 3.2.5 + @@ -103,6 +110,56 @@ + + + org.junit.jupiter + junit-jupiter-engine + 5.10.2 + test + + + junit-platform-engine + org.junit.platform + + + junit-jupiter-api + org.junit.jupiter + + + apiguardian-api + org.apiguardian + + + + + org.junit.platform + junit-platform-runner + 1.10.2 + test + + + junit + junit + + + junit-platform-launcher + org.junit.platform + + + junit-platform-suite-api + org.junit.platform + + + junit-platform-suite-commons + org.junit.platform + + + apiguardian-api + org.apiguardian + + + + diff --git a/pom.xml b/pom.xml index a923d85..b6874a4 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ + org.lwjgl lwjgl @@ -109,6 +110,19 @@ lwjgl-opengl ${lwjgl.natives} + + + org.junit.jupiter + junit-jupiter-engine + 5.10.2 + test + + + org.junit.platform + junit-platform-runner + 1.10.2 + test + @@ -181,6 +195,9 @@ bash + + 0 + ./src/main/c/compile.sh @@ -188,6 +205,11 @@ + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + diff --git a/src/main/c/compile.sh b/src/main/c/compile.sh index 7efde55..e019d55 100644 --- a/src/main/c/compile.sh +++ b/src/main/c/compile.sh @@ -1,5 +1,7 @@ cd ./src/main/c +echo "SAVE STEPS $SAVE_STEPS" + LIB_ENDING=".so" BASE_INCLUDE_DIR="" OS_INCLUDE_DIR="" @@ -61,7 +63,7 @@ INPUT_FILES="./src/javainterface.c" OUTPUT_FILE="./javainterface.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE -COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -msse -msse2 -msse3 -mmmx -m3dnow" +COMPILE_FLAGS="-c -fPIC -m64 -mavx -mavx2 -march=native -Ofast -msse -msse2 -msse3 -mmmx -m3dnow -DSAVE_STEPS=$SAVE_STEPS" INPUT_FILES="./src/fluidsim.c" OUTPUT_FILE="./fluidsim.o" gcc $COMPILE_FLAGS -I"$BASE_INCLUDE_DIR" -I"$OS_INCLUDE_DIR" $INPUT_FILES -o $OUTPUT_FILE diff --git a/src/main/c/src/fluidsim.c b/src/main/c/src/fluidsim.c index d04b4cb..c589cb5 100644 --- a/src/main/c/src/fluidsim.c +++ b/src/main/c/src/fluidsim.c @@ -13,7 +13,6 @@ #define DIM 18 #define LINEARSOLVERTIMES 20 -#define SAVE_STEPS 0 #define REALLY_SMALL_VALUE 0.00001 #define DIFFUSION_CONSTANT 0.00001 @@ -27,7 +26,7 @@ Chunk ** chunks = NULL; //jni help: //https://stackoverflow.com/questions/39823375/clarification-about-getfieldid -void saveStep(float * values, const char * name); +static inline void saveStep(float * values, const char * name); void simulate( int numChunks, @@ -510,8 +509,7 @@ void simulate( } - -void saveStep(float * values, const char * name){ +static inline void saveStep(float * values, const char * name){ if(SAVE_STEPS){ FILE *fp; int N = DIM; diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index 8bf44e9..7a18d41 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -2,6 +2,7 @@ package electrosphere; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; @@ -221,6 +222,81 @@ public class FluidSim { } + + + + // + // + //Management functions + // + // + /** + * Creates a fluid simulation array based on a given dimension set + * @param dimx the x dimension + * @param dimy the y dimension + * @param dimz the z dimension + * @return The array of fluid sim chunks + */ + public static FluidSim[][][] initFluidSim(int dimx, int dimy, int dimz){ + FluidSim[][][] simArray = new FluidSim[dimx][dimy][dimz]; + 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]); + } + } + } + } + + } + } + } + return simArray; + } + + + + + + + + + + + + + + + + + + + + + + static void printLayer(FluidSim[][][] simArray, int step, int layer){ if(step == 0){ @@ -370,7 +446,23 @@ public class FluidSim { - + /** + * Dumps this chunk's density values to disk + * @param path the path to dump to + */ + public void dumpToDisk(String path){ + OutputStream fileOS = null; + try { + fileOS = Files.newOutputStream(new File(path).toPath()); + ByteBuffer density = this.density[13]; + while(density.hasRemaining()){ + fileOS.write(density.get()); + } + fileOS.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } diff --git a/src/main/java/electrosphere/Main.java b/src/main/java/electrosphere/Main.java index 49ff840..388af70 100644 --- a/src/main/java/electrosphere/Main.java +++ b/src/main/java/electrosphere/Main.java @@ -2,7 +2,10 @@ package electrosphere; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; import java.util.concurrent.TimeUnit; @@ -17,14 +20,16 @@ import electrosphere.render.Mesh; */ public class Main { - static boolean render = true; + static boolean render = false; public static int endStep = -1; + + public static final float TIMESTEP = 0.001f; public static void main(String args[]){ - int dim = 3; - int vdim = 2; + int dim = 5; + int vdim = 5; int i = 0; long time = 0; long lastTime = 0; @@ -40,14 +45,15 @@ public class Main { } - FluidSim[][][] simArray = initFluidSim(dim,vdim,dim); + FluidSim[][][] simArray = FluidSim.initFluidSim(dim,vdim,dim); Mesh[][][] meshArray = null; if(render){ meshArray = initMeshes(dim,vdim,dim,simArray); } - + //uncomment this to generate test data + generateTestData(); while(true){ try { @@ -62,7 +68,7 @@ public class Main { // //Simulate // - FluidSim.simChunks(simArray,i,0.01f); + FluidSim.simChunks(simArray,i,TIMESTEP); // //Remesh // @@ -93,45 +99,6 @@ public class Main { } } - private static FluidSim[][][] initFluidSim(int dimx, int dimy, int dimz){ - FluidSim[][][] simArray = new FluidSim[dimx][dimy][dimz]; - 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]); - } - } - } - } - - } - } - } - return simArray; - } - private static Mesh[][][] initMeshes(int dimx, int dimy, int dimz, FluidSim[][][] simArray){ Mesh[][][] meshArray = new Mesh[dimx][dimy][dimz]; for(int x = 0; x < simArray.length; x++){ @@ -145,4 +112,126 @@ public class Main { return meshArray; } + /** + * Generates test data on disk in the test resources folder + */ + private static void generateTestData(){ + + //variables that will be used in generating data + int i = 0; + int dim = 1; + int length = 500; + FluidSim[][][] simArray; + int[] dims = new int[]{1,3,5}; + int[] lengths = new int[]{1,50,100,500}; + render = false; + + //clean up existing data + //this is scary recursive file logic, but the innermost callback has a guard to guarantee the file is underneath the testdata path + while(Files.exists(new File("./src/test/resources/testdata").toPath())){ + try { + Files.walk(new File("./src/test/resources/testdata").toPath()).forEach(path -> { + Path parent = new File("./src/test/resources/testdata").toPath().toAbsolutePath(); + Path child = path.toAbsolutePath(); + try { + TimeUnit.MILLISECONDS.sleep(1); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(child.startsWith(parent)){ + try { + System.out.println("Deleting " + path); + Files.delete(path); + } catch (IOException e) { + System.out.println("Failed to delete " + path); + e.printStackTrace(); + } + } + }); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + //create folders to contain test data + try { + Files.createDirectory(new File("./src/test/resources/testdata").toPath()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + for(int dimIterator = 0; dimIterator < dims.length; dimIterator++){ + dim = dims[dimIterator]; + try { + Files.createDirectory(new File("./src/test/resources/testdata/" + dim + "by" + dim).toPath()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + for(int lengthIterator = 0; lengthIterator < lengths.length; lengthIterator++){ + length = lengths[lengthIterator]; + try { + Files.createDirectory(new File("./src/test/resources/testdata/" + dim + "by" + dim + "/" + length + "steps").toPath()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + //main data generation loop + for(int dimIterator = 0; dimIterator < dims.length; dimIterator++){ + for(int lengthIterator = 0; lengthIterator < lengths.length; lengthIterator++){ + + + //actual main routine to generate data starts here + dim = dims[dimIterator]; + length = lengths[lengthIterator]; + System.out.println("Generating " + dim + "x" + dim + "x" + dim + " for " + length + " steps"); + + i = 0; + simArray = FluidSim.initFluidSim(dim,dim,dim); + for(i = 0; i < length; i++){ + FluidSim.simChunks(simArray,i,TIMESTEP); + } + + for(int x = 0; x < dim; x++){ + for(int y = 0; y < dim; y++){ + for(int z = 0; z < dim; z++){ + simArray[x][y][z].dumpToDisk("./src/test/resources/testdata/" + dim + "by" + dim + "/" + length + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + length + "Step.data"); + } + } + } + + for(int x = 0; x < dim; x++){ + for(int y = 0; y < dim; y++){ + for(int z = 0; z < dim; z++){ + byte[] bytes; + try { + bytes = Files.readAllBytes(new File("./src/test/resources/testdata/" + dim + "by" + dim + "/" + length + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + length + "Step.data").toPath()); + ByteBuffer densityBytes = simArray[0][0][0].getDensityBuffer(); + i = 0; + while(densityBytes.hasRemaining()){ + boolean pass = bytes[i] == densityBytes.get(); + if(!pass){ + System.err.println("failed to pass!"); + } + i++; + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + } + } + + + System.exit(0); + } + } diff --git a/src/test/java/LongRunTests.java b/src/test/java/LongRunTests.java new file mode 100644 index 0000000..42a3dd8 --- /dev/null +++ b/src/test/java/LongRunTests.java @@ -0,0 +1,180 @@ +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +import org.junit.Test; + +import electrosphere.FluidSim; +import electrosphere.Main; + +public class LongRunTests { + + // @Test + // public void test5by5Chunk1Step(){ + + // int dim = 5; + // int maxTimestep = 1; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test5by5Chunk50Step(){ + + // int dim = 5; + // int maxTimestep = 50; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test5by5Chunk100Step(){ + + // int dim = 5; + // int maxTimestep = 100; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test5by5Chunk500Step(){ + + // int dim = 5; + // int maxTimestep = 500; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + +} diff --git a/src/test/java/MediumRunTests.java b/src/test/java/MediumRunTests.java new file mode 100644 index 0000000..7967592 --- /dev/null +++ b/src/test/java/MediumRunTests.java @@ -0,0 +1,180 @@ +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +import org.junit.Test; + +import electrosphere.FluidSim; +import electrosphere.Main; + +public class MediumRunTests { + + // @Test + // public void test3by3Chunk1Step(){ + + // int dim = 3; + // int maxTimestep = 1; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test3by3Chunk50Step(){ + + // int dim = 3; + // int maxTimestep = 50; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test3by3Chunk100Step(){ + + // int dim = 3; + // int maxTimestep = 100; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test3by3Chunk500Step(){ + + // int dim = 3; + // int maxTimestep = 500; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + +} diff --git a/src/test/java/ShortRunTest.java b/src/test/java/ShortRunTest.java new file mode 100644 index 0000000..65b4f39 --- /dev/null +++ b/src/test/java/ShortRunTest.java @@ -0,0 +1,185 @@ + + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +import org.junit.Test; + +import electrosphere.FluidSim; +import electrosphere.Main; + +/** + * Tests stepping a single chunk by a single frame + */ +public class ShortRunTest { + + // @Test + // public void test1by1Chunk1Step(){ + + // int dim = 1; + // int maxTimestep = 1; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test1by1Chunk50Step(){ + + // int dim = 1; + // int maxTimestep = 50; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test1by1Chunk100Step(){ + + // int dim = 1; + // int maxTimestep = 100; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + + // @Test + // public void test1by1Chunk500Step(){ + + // int dim = 1; + // int maxTimestep = 500; + + // System.out.println("TEST: " + dim + "x" + dim + "x" + dim + " for " + maxTimestep + " steps"); + + // //init chunk array + // FluidSim[][][] simArray = FluidSim.initFluidSim(dim,dim,dim); + + // //simulate the chunk + // for(int i = 0; i < maxTimestep; i++){ + // FluidSim.simChunks(simArray, i, Main.TIMESTEP); + // } + + // for(int x = 0; x < dim; x++){ + // for(int y = 0; y < dim; y++){ + // for(int z = 0; z < dim; z++){ + // InputStream testFileIS = this.getClass().getResourceAsStream("./testdata/" + dim + "by" + dim + "/" + maxTimestep + "steps/chunk_" + x + "_" + y + "_" + z + "_" + dim + "by" + dim + "Chunk" + maxTimestep + "Step.data"); + // byte[] bytes; + // try { + // bytes = testFileIS.readAllBytes(); + // ByteBuffer densityBytes = simArray[x][y][z].getDensityBuffer(); + // int i = 0; + // while(densityBytes.hasRemaining()){ + // boolean pass = bytes[i] == densityBytes.get(); + // assert(pass); + // i++; + // } + // } catch (IOException e) { + // e.printStackTrace(); + // assert(false); + // } + // } + // } + // } + + // System.out.println("PASSED"); + + // } + +} diff --git a/src/test/resources/shader.fs b/src/test/resources/shader.fs new file mode 100644 index 0000000..fbf7c6f --- /dev/null +++ b/src/test/resources/shader.fs @@ -0,0 +1,57 @@ +#version 330 core + +out vec4 FragColor; + + +vec3 color = vec3(0.3,0.7,0.9); + +vec3 dLDirection = vec3(0.1,-0.9,0.1); +vec3 dLDiffuse = vec3(0.5,0.5,0.5); + +in vec3 FragPos; +in vec3 Normal; +in vec3 rawPos; + + +uniform vec3 viewPos; +// uniform DirLight dirLight; +// uniform PointLight pointLights[NR_POINT_LIGHTS]; +// uniform SpotLight spotLight; + +// function prototypes +vec3 CalcDirLight(vec3 normal, vec3 viewDir); + +void main(){ + vec3 norm = normalize(Normal); + vec3 viewDir = normalize(viewPos - FragPos); + + vec3 lightAmount = CalcDirLight(norm, viewDir); + + vec3 color = vec3(0.3,0.7,0.9); + if( + rawPos.x < 2 || rawPos.x > 16 || + rawPos.y < 2 || rawPos.y > 16 || + rawPos.z < 2 || rawPos.z > 16 + ){ + color = vec3(0.9,0.7,0.3); + } + color = color * lightAmount; + + //this final calculation is for transparency + FragColor = vec4(color,1.0); +} + +vec3 CalcDirLight(vec3 normal, vec3 viewDir){ + vec3 lightDir = normalize(-dLDirection); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), 0.6); + // combine results + vec3 diffuse = dLDiffuse * diff; + + vec3 specular = spec * color; + + return diffuse + specular; +} diff --git a/src/test/resources/shader.vs b/src/test/resources/shader.vs new file mode 100644 index 0000000..97b0628 --- /dev/null +++ b/src/test/resources/shader.vs @@ -0,0 +1,38 @@ +//Vertex Shader +#version 330 core + +//input buffers +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; + + +//coordinate space transformation matrices +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + + + +//output buffers +out vec3 Normal; +out vec3 FragPos; +out vec3 rawPos; + + + + +void main() { + //normalize posiiton and normal + vec4 FinalVertex = vec4(aPos, 1.0); + vec4 FinalNormal = vec4(aNormal, 1.0); + + + //push frag, normal, and texture positions to fragment shader + FragPos = vec3(model * FinalVertex); + Normal = mat3(transpose(inverse(model))) * aNormal; + rawPos = aPos; + + + //set final position with opengl space + gl_Position = projection * view * model * FinalVertex; +}