diff --git a/.vscode/launch.json b/.vscode/launch.json index f62fc54e..4f5b55cf 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "name": "Launch Current File", "request": "launch", "mainClass": "${file}", - "vmArgs": "-Xmx8G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=7G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "preLaunchTask": "Install Native Lib" }, { @@ -14,7 +14,7 @@ "name": "Launch Main", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx8G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=7G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "projectName": "Renderer", "preLaunchTask": "Install Native Lib" }, @@ -23,7 +23,7 @@ "name": "Launch Main (Debug Memory)", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx8G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=7G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\" -javaagent:./lwjglx-debug-1.0.0.jar=t;o=trace.log", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\" -javaagent:./lwjglx-debug-1.0.0.jar=t;o=trace.log", "projectName": "Renderer", "preLaunchTask": "Install Native Lib" }, @@ -35,7 +35,7 @@ "env": { "ALSOFT_LOGLEVEL": 4 }, - "vmArgs": "-Xmx8G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=7G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "projectName": "Renderer" }, { diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d2c623c0..f14789e9 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -2008,6 +2008,9 @@ No allocations on client receiving chunk of blocks or terrain Meshgen acceleration structure for block meshgen More profiling +(05/27/2025) +QuadMesh memory pooling + diff --git a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java index 9079ba5d..bc343192 100644 --- a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java +++ b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java @@ -4,7 +4,6 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -18,6 +17,8 @@ import electrosphere.entity.state.collidable.MultiShapeTriGeomData; import electrosphere.entity.state.collidable.TriGeomData; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.meshgen.accel.MeshGenStore; +import electrosphere.renderer.meshgen.accel.QuadMeshCache; +import electrosphere.renderer.meshgen.accel.QuadMeshCache.QuadMesh; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Model; @@ -97,8 +98,8 @@ public class BlockMeshgen { * @param quadMeshes The quad mesh list to fill * @param data The block data */ - protected static void fillQuadMeshes(List quadMeshes, BlockMeshgenData data){ - BlockMeshgen.fillQuadMeshes(quadMeshes, data, true, null); + protected static void fillQuadMeshes(QuadMeshCache quadMeshCache, BlockMeshgenData data){ + BlockMeshgen.fillQuadMeshes(quadMeshCache, data, true, null); } @@ -107,7 +108,7 @@ public class BlockMeshgen { * @param quadMeshes The quad mesh list to fill * @param data The block data */ - protected static void fillQuadMeshes(List quadMeshes, BlockMeshgenData data, boolean solids, Map solidsMap){ + protected static void fillQuadMeshes(QuadMeshCache quadMeshCache, BlockMeshgenData data, boolean solids, Map solidsMap){ Vector3i dimensions = data.getDimensions(); for(int z = 0; z < dimensions.z; z++){ for(int x = 0; x < dimensions.x; x++){ @@ -119,21 +120,22 @@ public class BlockMeshgen { } else { currentQuad.h = y - currentQuad.y; //check if should merge with previous quad - for(QuadMesh prevMesh : quadMeshes){ + for(int j = 0; j < quadMeshCache.getActiveCount(); j++){ + QuadMesh prevMesh = quadMeshCache.getActive(j); + if(prevMesh == currentQuad){ + continue; + } if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){ prevMesh.w = prevMesh.w + 1; - currentQuad = null; + quadMeshCache.destroy(currentQuad); break; } } - if(currentQuad != null){ - quadMeshes.add(currentQuad); - } currentQuad = null; } } else { if(currentQuad == null){ - currentQuad = new QuadMesh(); + currentQuad = quadMeshCache.getNew(); currentQuad.x = x; currentQuad.y = y; currentQuad.z = z; @@ -145,17 +147,18 @@ public class BlockMeshgen { } else { currentQuad.h = y - currentQuad.y; //check if should merge with previous quad - for(QuadMesh prevMesh : quadMeshes){ + for(int j = 0; j < quadMeshCache.getActiveCount(); j++){ + QuadMesh prevMesh = quadMeshCache.getActive(j); + if(prevMesh == currentQuad){ + continue; + } if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){ prevMesh.w = prevMesh.w + 1; - currentQuad = null; + quadMeshCache.destroy(currentQuad); break; } } - if(currentQuad != null){ - quadMeshes.add(currentQuad); - } - currentQuad = new QuadMesh(); + currentQuad = quadMeshCache.getNew(); currentQuad.x = x; currentQuad.y = y; currentQuad.z = z; @@ -168,16 +171,17 @@ public class BlockMeshgen { if(currentQuad != null){ currentQuad.h = dimensions.y - currentQuad.y; //check if should merge with previous quad - for(QuadMesh prevMesh : quadMeshes){ + for(int j = 0; j < quadMeshCache.getActiveCount(); j++){ + QuadMesh prevMesh = quadMeshCache.getActive(j); + if(prevMesh == currentQuad){ + continue; + } if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){ prevMesh.w = prevMesh.w + 1; - currentQuad = null; + quadMeshCache.destroy(currentQuad); break; } } - if(currentQuad != null){ - quadMeshes.add(currentQuad); - } } } } @@ -397,15 +401,15 @@ public class BlockMeshgen { BlockMeshData rVal = new BlockMeshData(); //calculate quad meshes - List quadMeshes = new LinkedList(); - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap); + QuadMeshCache quadMeshCache = QuadMeshCache.getF(); + BlockMeshgen.fillQuadMeshes(quadMeshCache, chunkData, solids, solidsMap); //get acceleration structure MeshGenStore meshGenStore = MeshGenStore.get(); meshGenStore.clear(); //sort - Collections.sort(quadMeshes); + quadMeshCache.sort(); int vertCount = 0; int faceCount = 0; @@ -414,21 +418,21 @@ public class BlockMeshgen { QuadMesh quad1 = null; QuadMesh quad2 = null; int zEnd = 0; - for(int i = 0; i < quadMeshes.size();){ - quad1 = quadMeshes.get(i); + for(int i = 0; i < quadMeshCache.getActiveCount();){ + quad1 = quadMeshCache.getActive(i); zEnd = 1; - for(int j = i + 1; j < quadMeshes.size(); j++){ - quad2 = quadMeshes.get(j); + for(int j = i + 1; j < quadMeshCache.getActiveCount(); j++){ + quad2 = quadMeshCache.getActive(j); if(quad1.x == quad2.x && quad1.y == quad2.y && quad1.w == quad2.w && quad1.h == quad2.h && quad1.z + zEnd == quad2.z){ zEnd++; } else { BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type); quad1 = quad2; - BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); - vertCount = meshGenStore.getVertCount(); - faceCount = meshGenStore.getFaceCount(); - rVal.shapeData.add(blockSingleShape); + // BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); + // vertCount = meshGenStore.getVertCount(); + // faceCount = meshGenStore.getFaceCount(); + // rVal.shapeData.add(blockSingleShape); break; } } @@ -436,10 +440,10 @@ public class BlockMeshgen { } if(quad1 != null){ BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type); - BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); - vertCount = meshGenStore.getVertCount(); - faceCount = meshGenStore.getFaceCount(); - rVal.shapeData.add(blockSingleShape); + // BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); + // vertCount = meshGenStore.getVertCount(); + // faceCount = meshGenStore.getFaceCount(); + // rVal.shapeData.add(blockSingleShape); } // @@ -472,6 +476,7 @@ public class BlockMeshgen { rVal.samplerBuffer.put(rVal.samplers); MeshGenStore.release(meshGenStore); + QuadMeshCache.release(quadMeshCache); return rVal; } @@ -821,39 +826,4 @@ public class BlockMeshgen { } } - /** - * Intermediary structure used during rasterization - */ - public static class QuadMesh implements Comparable { - int x; - int y; - int z; - int w; - int h; - int type; - public QuadMesh(){} - public QuadMesh(int x, int y, int z, int w, int h, int type){ - this.x = x; - this.y = y; - this.z = z; - this.w = w; - this.h = h; - this.type = type; - } - - @Override - public int compareTo(QuadMesh other) { - if(this.y != other.y){ - return this.y - other.y; - } - if(this.x != other.x){ - return this.x - other.x; - } - if(this.w != other.w){ - return other.w - this.w; - } - return other.h - this.h; - } - } - } diff --git a/src/main/java/electrosphere/renderer/meshgen/accel/QuadMeshCache.java b/src/main/java/electrosphere/renderer/meshgen/accel/QuadMeshCache.java new file mode 100644 index 00000000..dd72ed17 --- /dev/null +++ b/src/main/java/electrosphere/renderer/meshgen/accel/QuadMeshCache.java @@ -0,0 +1,190 @@ +package electrosphere.renderer.meshgen.accel; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Cache for pooling quad meshes + */ +public class QuadMeshCache { + + /** + * Quads in a cache instance + */ + private static final int QUADS_PER_CACHE = 4096; + + + + /** + * Structure to store not-in-use objects + */ + static List cachePool = new LinkedList(); + + /** + * Lock for thread-safeing operations + */ + static ReentrantLock lock = new ReentrantLock(); + + + /** + * Gets a QuadMeshCache from the pool. Allocates if no free one is available. + * @param type The type of the message + * @return A QuadMeshCache + */ + public static QuadMeshCache getF(){ + QuadMeshCache rVal = null; + lock.lock(); + if(cachePool.size() > 0){ + rVal = QuadMeshCache.cachePool.remove(0); + } else { + rVal = new QuadMeshCache(); + } + rVal.reset(); + lock.unlock(); + return rVal; + } + + /** + * Releases a QuadMeshCache back into the pool + * @param data The object to release + */ + public static void release(QuadMeshCache data){ + lock.lock(); + QuadMeshCache.cachePool.add(data); + lock.unlock(); + } + + + + + + /** + * Set of quad meshes + */ + private QuadMesh[] quads = new QuadMesh[QuadMeshCache.QUADS_PER_CACHE]; + + /** + * The number of active quads + */ + private int activeCount = 0; + + /** + * Constructor for cache + */ + public QuadMeshCache(){ + for(int i = 0; i < QUADS_PER_CACHE; i++){ + quads[i] = new QuadMesh(); + } + } + + /** + * Resets the cache + */ + private void reset(){ + for(int i = 0; i < QUADS_PER_CACHE; i++){ + this.quads[i].reset(); + } + this.activeCount = 0; + } + + /** + * Sorts the quad array + */ + public void sort(){ + Arrays.sort(quads); + + //figure out how many quads are actually active + for(int i = 0; i < QUADS_PER_CACHE; i++){ + if(!quads[i].active){ + this.activeCount = i; + break; + } + } + } + + /** + * Gets a new quad mesh + * @return The quad mesh + */ + public QuadMesh getNew(){ + QuadMesh rVal = quads[activeCount]; + rVal.active = true; + activeCount++; + return rVal; + } + + /** + * Gets a quad mesh + * @return The quad mesh + */ + public QuadMesh getActive(int i){ + QuadMesh rVal = quads[i]; + return rVal; + } + + /** + * Destroys a quad mesh + * @param mesh The mesh + */ + public void destroy(QuadMesh mesh){ + mesh.active = false; + this.activeCount--; + } + + /** + * Gets the active count + * @return The active count + */ + public int getActiveCount(){ + return activeCount; + } + + /** + * Intermediary structure used during rasterization + */ + public static class QuadMesh implements Comparable { + public int x; + public int y; + public int z; + public int w; + public int h; + public int type; + public boolean active = false; + public void set(int x, int y, int z, int w, int h, int type){ + this.x = x; + this.y = y; + this.z = z; + this.w = w; + this.h = h; + this.type = type; + this.active = true; + } + + public void reset(){ + this.active = false; + } + + @Override + public int compareTo(QuadMesh other) { + if(this.active && !other.active){ + return -1; + } + if(other.active && !this.active){ + return 1; + } + if(this.y != other.y){ + return this.y - other.y; + } + if(this.x != other.x){ + return this.x - other.x; + } + if(this.w != other.w){ + return other.w - this.w; + } + return other.h - this.h; + } + } + +} diff --git a/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java b/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java index 9359ec5d..a8e333c3 100644 --- a/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java +++ b/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java @@ -2,13 +2,11 @@ package electrosphere.renderer.meshgen; import static org.junit.jupiter.api.Assertions.*; -import java.util.LinkedList; -import java.util.List; - import electrosphere.client.block.BlockChunkData; import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData; -import electrosphere.renderer.meshgen.BlockMeshgen.QuadMesh; import electrosphere.renderer.meshgen.accel.MeshGenStore; +import electrosphere.renderer.meshgen.accel.QuadMeshCache; +import electrosphere.renderer.meshgen.accel.QuadMeshCache.QuadMesh; import electrosphere.test.annotations.UnitTest; /** @@ -25,8 +23,10 @@ public class BlockMeshgenTests { public void test_fillQuadMeshes_1(){ //expected data + QuadMesh expectedQuad = new QuadMesh(); + expectedQuad.set(0,0,0,1,1,1); QuadMesh[] expectedData = new QuadMesh[]{ - new QuadMesh(0,0,0,1,1,1), + expectedQuad, }; //setup data @@ -34,18 +34,19 @@ public class BlockMeshgenTests { short[] types = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH]; chunkData.setType(types); chunkData.setType(0, 0, 0, (short)1); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(expectedData.length, quadMeshes.size()); + assertEquals(expectedData.length, cache.getActiveCount()); for(QuadMesh expected : expectedData){ boolean found = false; - for(QuadMesh actual : quadMeshes){ + for(int i = 0; i < cache.getActiveCount(); i++){ + QuadMesh actual = cache.getActive(i); if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){ found = true; assertEquals(expected.x, actual.x); @@ -57,14 +58,17 @@ public class BlockMeshgenTests { } assertEquals(true, found); } + + QuadMeshCache.release(cache); } @UnitTest public void test_fillQuadMeshes_2(){ //expected data QuadMesh[] expectedData = new QuadMesh[]{ - new QuadMesh(0,0,0,1,2,1), + new QuadMesh(), }; + expectedData[0].set(0,0,0,1,2,1); //setup data BlockChunkData chunkData = new BlockChunkData(); @@ -72,18 +76,19 @@ public class BlockMeshgenTests { chunkData.setType(types); chunkData.setType(0, 0, 0, (short)1); chunkData.setType(0, 1, 0, (short)1); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(expectedData.length, quadMeshes.size()); + assertEquals(expectedData.length, cache.getActiveCount()); for(QuadMesh expected : expectedData){ boolean found = false; - for(QuadMesh actual : quadMeshes){ + for(int i = 0; i < cache.getActiveCount(); i++){ + QuadMesh actual = cache.getActive(i); if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){ found = true; assertEquals(expected.x, actual.x); @@ -95,14 +100,16 @@ public class BlockMeshgenTests { } assertEquals(true, found); } + QuadMeshCache.release(cache); } @UnitTest public void test_fillQuadMeshes_3(){ //expected data QuadMesh[] expectedData = new QuadMesh[]{ - new QuadMesh(0,0,0,2,2,1), + new QuadMesh(), }; + expectedData[0].set(0,0,0,2,2,1); //setup data BlockChunkData chunkData = new BlockChunkData(); @@ -112,18 +119,19 @@ public class BlockMeshgenTests { chunkData.setType(0, 1, 0, (short)1); chunkData.setType(1, 0, 0, (short)1); chunkData.setType(1, 1, 0, (short)1); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(expectedData.length, quadMeshes.size()); + assertEquals(expectedData.length, cache.getActiveCount()); for(QuadMesh expected : expectedData){ boolean found = false; - for(QuadMesh actual : quadMeshes){ + for(int i = 0; i < cache.getActiveCount(); i++){ + QuadMesh actual = cache.getActive(i); if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){ found = true; assertEquals(expected.x, actual.x); @@ -135,15 +143,18 @@ public class BlockMeshgenTests { } assertEquals(true, found); } + QuadMeshCache.release(cache); } @UnitTest public void test_fillQuadMeshes_4(){ //expected data QuadMesh[] expectedData = new QuadMesh[]{ - new QuadMesh(0,0,0,1,1,1), - new QuadMesh(0,2,0,1,1,1), + new QuadMesh(), + new QuadMesh(), }; + expectedData[0].set(0,0,0,1,1,1); + expectedData[1].set(0,2,0,1,1,1); //setup data BlockChunkData chunkData = new BlockChunkData(); @@ -151,18 +162,19 @@ public class BlockMeshgenTests { chunkData.setType(types); chunkData.setType(0, 0, 0, (short)1); chunkData.setType(0, 2, 0, (short)1); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(expectedData.length, quadMeshes.size()); + assertEquals(expectedData.length, cache.getActiveCount()); for(QuadMesh expected : expectedData){ boolean found = false; - for(QuadMesh actual : quadMeshes){ + for(int i = 0; i < cache.getActiveCount(); i++){ + QuadMesh actual = cache.getActive(i); if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){ found = true; assertEquals(expected.x, actual.x); @@ -174,6 +186,7 @@ public class BlockMeshgenTests { } assertEquals(true, found); } + QuadMeshCache.release(cache); } @UnitTest @@ -182,23 +195,28 @@ public class BlockMeshgenTests { BlockChunkData chunkData = new BlockChunkData(); short[] types = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH]; chunkData.setType(types); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(0, quadMeshes.size()); + assertEquals(0, cache.getActiveCount()); + + QuadMeshCache.release(cache); } @UnitTest public void test_fillQuadMeshes_6(){ //expected data QuadMesh[] expectedData = new QuadMesh[]{ - new QuadMesh(5,0,8,1,1,1), - new QuadMesh(8,0,8,1,1,1), - new QuadMesh(7,0,4,1,1,1), + new QuadMesh(), + new QuadMesh(), + new QuadMesh(), }; + expectedData[0].set(5,0,8,1,1,1); + expectedData[1].set(8,0,8,1,1,1); + expectedData[2].set(7,0,4,1,1,1); //setup data BlockChunkData chunkData = new BlockChunkData(); @@ -207,18 +225,19 @@ public class BlockMeshgenTests { chunkData.setType(5, 0, 8, (short)1); chunkData.setType(8, 0, 8, (short)1); chunkData.setType(7, 0, 4, (short)1); - List quadMeshes = new LinkedList(); + QuadMeshCache cache = QuadMeshCache.getF(); //call - BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); + BlockMeshgen.fillQuadMeshes(cache, chunkData); //error check result - assertEquals(expectedData.length, quadMeshes.size()); + assertEquals(expectedData.length, cache.getActiveCount()); for(QuadMesh expected : expectedData){ boolean found = false; - for(QuadMesh actual : quadMeshes){ + for(int i = 0; i < cache.getActiveCount(); i++){ + QuadMesh actual = cache.getActive(i); if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){ found = true; assertEquals(expected.x, actual.x); @@ -230,6 +249,7 @@ public class BlockMeshgenTests { } assertEquals(true, found); } + QuadMeshCache.release(cache); } @UnitTest @@ -273,7 +293,8 @@ public class BlockMeshgenTests { } //setup data - QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1,1); + QuadMesh quad = new QuadMesh(); + quad.set(0, 0, 0, 1, 1,1); //call BlockMeshgen.meshifyBox(store, quad, 1, 1); @@ -330,7 +351,8 @@ public class BlockMeshgenTests { }; //setup data - QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1); + QuadMesh quad = new QuadMesh(); + quad.set(0, 0, 0, 1, 1, 1); //call BlockMeshgen.meshifyBox(store, quad, 1, 1); @@ -385,7 +407,8 @@ public class BlockMeshgenTests { }; //setup data - QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1); + QuadMesh quad = new QuadMesh(); + quad.set(0, 0, 0, 1, 1, 1); //call BlockMeshgen.meshifyBox(store, quad, 1, 1);