block meshgen memory work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-27 15:06:45 -04:00
parent 8784b08fe4
commit 64b10e5837
5 changed files with 299 additions and 113 deletions

8
.vscode/launch.json vendored
View File

@ -6,7 +6,7 @@
"name": "Launch Current File", "name": "Launch Current File",
"request": "launch", "request": "launch",
"mainClass": "${file}", "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" "preLaunchTask": "Install Native Lib"
}, },
{ {
@ -14,7 +14,7 @@
"name": "Launch Main", "name": "Launch Main",
"request": "launch", "request": "launch",
"mainClass": "electrosphere.engine.Main", "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", "projectName": "Renderer",
"preLaunchTask": "Install Native Lib" "preLaunchTask": "Install Native Lib"
}, },
@ -23,7 +23,7 @@
"name": "Launch Main (Debug Memory)", "name": "Launch Main (Debug Memory)",
"request": "launch", "request": "launch",
"mainClass": "electrosphere.engine.Main", "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", "projectName": "Renderer",
"preLaunchTask": "Install Native Lib" "preLaunchTask": "Install Native Lib"
}, },
@ -35,7 +35,7 @@
"env": { "env": {
"ALSOFT_LOGLEVEL": 4 "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" "projectName": "Renderer"
}, },
{ {

View File

@ -2008,6 +2008,9 @@ No allocations on client receiving chunk of blocks or terrain
Meshgen acceleration structure for block meshgen Meshgen acceleration structure for block meshgen
More profiling More profiling
(05/27/2025)
QuadMesh memory pooling

View File

@ -4,7 +4,6 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -18,6 +17,8 @@ import electrosphere.entity.state.collidable.MultiShapeTriGeomData;
import electrosphere.entity.state.collidable.TriGeomData; import electrosphere.entity.state.collidable.TriGeomData;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.meshgen.accel.MeshGenStore; 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.Material;
import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Mesh;
import electrosphere.renderer.model.Model; import electrosphere.renderer.model.Model;
@ -97,8 +98,8 @@ public class BlockMeshgen {
* @param quadMeshes The quad mesh list to fill * @param quadMeshes The quad mesh list to fill
* @param data The block data * @param data The block data
*/ */
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockMeshgenData data){ protected static void fillQuadMeshes(QuadMeshCache quadMeshCache, BlockMeshgenData data){
BlockMeshgen.fillQuadMeshes(quadMeshes, data, true, null); BlockMeshgen.fillQuadMeshes(quadMeshCache, data, true, null);
} }
@ -107,7 +108,7 @@ public class BlockMeshgen {
* @param quadMeshes The quad mesh list to fill * @param quadMeshes The quad mesh list to fill
* @param data The block data * @param data The block data
*/ */
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockMeshgenData data, boolean solids, Map<Integer,Boolean> solidsMap){ protected static void fillQuadMeshes(QuadMeshCache quadMeshCache, BlockMeshgenData data, boolean solids, Map<Integer,Boolean> solidsMap){
Vector3i dimensions = data.getDimensions(); Vector3i dimensions = data.getDimensions();
for(int z = 0; z < dimensions.z; z++){ for(int z = 0; z < dimensions.z; z++){
for(int x = 0; x < dimensions.x; x++){ for(int x = 0; x < dimensions.x; x++){
@ -119,21 +120,22 @@ public class BlockMeshgen {
} else { } else {
currentQuad.h = y - currentQuad.y; currentQuad.h = y - currentQuad.y;
//check if should merge with previous quad //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){ if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){
prevMesh.w = prevMesh.w + 1; prevMesh.w = prevMesh.w + 1;
currentQuad = null; quadMeshCache.destroy(currentQuad);
break; break;
} }
} }
if(currentQuad != null){
quadMeshes.add(currentQuad);
}
currentQuad = null; currentQuad = null;
} }
} else { } else {
if(currentQuad == null){ if(currentQuad == null){
currentQuad = new QuadMesh(); currentQuad = quadMeshCache.getNew();
currentQuad.x = x; currentQuad.x = x;
currentQuad.y = y; currentQuad.y = y;
currentQuad.z = z; currentQuad.z = z;
@ -145,17 +147,18 @@ public class BlockMeshgen {
} else { } else {
currentQuad.h = y - currentQuad.y; currentQuad.h = y - currentQuad.y;
//check if should merge with previous quad //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){ if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){
prevMesh.w = prevMesh.w + 1; prevMesh.w = prevMesh.w + 1;
currentQuad = null; quadMeshCache.destroy(currentQuad);
break; break;
} }
} }
if(currentQuad != null){ currentQuad = quadMeshCache.getNew();
quadMeshes.add(currentQuad);
}
currentQuad = new QuadMesh();
currentQuad.x = x; currentQuad.x = x;
currentQuad.y = y; currentQuad.y = y;
currentQuad.z = z; currentQuad.z = z;
@ -168,16 +171,17 @@ public class BlockMeshgen {
if(currentQuad != null){ if(currentQuad != null){
currentQuad.h = dimensions.y - currentQuad.y; currentQuad.h = dimensions.y - currentQuad.y;
//check if should merge with previous quad //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){ if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){
prevMesh.w = prevMesh.w + 1; prevMesh.w = prevMesh.w + 1;
currentQuad = null; quadMeshCache.destroy(currentQuad);
break; break;
} }
} }
if(currentQuad != null){
quadMeshes.add(currentQuad);
}
} }
} }
} }
@ -397,15 +401,15 @@ public class BlockMeshgen {
BlockMeshData rVal = new BlockMeshData(); BlockMeshData rVal = new BlockMeshData();
//calculate quad meshes //calculate quad meshes
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache quadMeshCache = QuadMeshCache.getF();
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap); BlockMeshgen.fillQuadMeshes(quadMeshCache, chunkData, solids, solidsMap);
//get acceleration structure //get acceleration structure
MeshGenStore meshGenStore = MeshGenStore.get(); MeshGenStore meshGenStore = MeshGenStore.get();
meshGenStore.clear(); meshGenStore.clear();
//sort //sort
Collections.sort(quadMeshes); quadMeshCache.sort();
int vertCount = 0; int vertCount = 0;
int faceCount = 0; int faceCount = 0;
@ -414,21 +418,21 @@ public class BlockMeshgen {
QuadMesh quad1 = null; QuadMesh quad1 = null;
QuadMesh quad2 = null; QuadMesh quad2 = null;
int zEnd = 0; int zEnd = 0;
for(int i = 0; i < quadMeshes.size();){ for(int i = 0; i < quadMeshCache.getActiveCount();){
quad1 = quadMeshes.get(i); quad1 = quadMeshCache.getActive(i);
zEnd = 1; zEnd = 1;
for(int j = i + 1; j < quadMeshes.size(); j++){ for(int j = i + 1; j < quadMeshCache.getActiveCount(); j++){
quad2 = quadMeshes.get(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){ if(quad1.x == quad2.x && quad1.y == quad2.y && quad1.w == quad2.w && quad1.h == quad2.h && quad1.z + zEnd == quad2.z){
zEnd++; zEnd++;
} else { } else {
BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type); BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
quad1 = quad2; quad1 = quad2;
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); // BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
vertCount = meshGenStore.getVertCount(); // vertCount = meshGenStore.getVertCount();
faceCount = meshGenStore.getFaceCount(); // faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape); // rVal.shapeData.add(blockSingleShape);
break; break;
} }
} }
@ -436,10 +440,10 @@ public class BlockMeshgen {
} }
if(quad1 != null){ if(quad1 != null){
BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type); BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount); // BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
vertCount = meshGenStore.getVertCount(); // vertCount = meshGenStore.getVertCount();
faceCount = meshGenStore.getFaceCount(); // faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape); // rVal.shapeData.add(blockSingleShape);
} }
// //
@ -472,6 +476,7 @@ public class BlockMeshgen {
rVal.samplerBuffer.put(rVal.samplers); rVal.samplerBuffer.put(rVal.samplers);
MeshGenStore.release(meshGenStore); MeshGenStore.release(meshGenStore);
QuadMeshCache.release(quadMeshCache);
return rVal; return rVal;
} }
@ -821,39 +826,4 @@ public class BlockMeshgen {
} }
} }
/**
* Intermediary structure used during rasterization
*/
public static class QuadMesh implements Comparable<QuadMesh> {
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;
}
}
} }

View File

@ -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<QuadMeshCache> cachePool = new LinkedList<QuadMeshCache>();
/**
* 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<QuadMesh> {
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;
}
}
}

View File

@ -2,13 +2,11 @@ package electrosphere.renderer.meshgen;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import java.util.LinkedList;
import java.util.List;
import electrosphere.client.block.BlockChunkData; import electrosphere.client.block.BlockChunkData;
import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData; import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
import electrosphere.renderer.meshgen.BlockMeshgen.QuadMesh;
import electrosphere.renderer.meshgen.accel.MeshGenStore; import electrosphere.renderer.meshgen.accel.MeshGenStore;
import electrosphere.renderer.meshgen.accel.QuadMeshCache;
import electrosphere.renderer.meshgen.accel.QuadMeshCache.QuadMesh;
import electrosphere.test.annotations.UnitTest; import electrosphere.test.annotations.UnitTest;
/** /**
@ -25,8 +23,10 @@ public class BlockMeshgenTests {
public void test_fillQuadMeshes_1(){ public void test_fillQuadMeshes_1(){
//expected data //expected data
QuadMesh expectedQuad = new QuadMesh();
expectedQuad.set(0,0,0,1,1,1);
QuadMesh[] expectedData = new QuadMesh[]{ QuadMesh[] expectedData = new QuadMesh[]{
new QuadMesh(0,0,0,1,1,1), expectedQuad,
}; };
//setup data //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]; short[] types = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH];
chunkData.setType(types); chunkData.setType(types);
chunkData.setType(0, 0, 0, (short)1); chunkData.setType(0, 0, 0, (short)1);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(expectedData.length, quadMeshes.size()); assertEquals(expectedData.length, cache.getActiveCount());
for(QuadMesh expected : expectedData){ for(QuadMesh expected : expectedData){
boolean found = false; 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){ if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){
found = true; found = true;
assertEquals(expected.x, actual.x); assertEquals(expected.x, actual.x);
@ -57,14 +58,17 @@ public class BlockMeshgenTests {
} }
assertEquals(true, found); assertEquals(true, found);
} }
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
public void test_fillQuadMeshes_2(){ public void test_fillQuadMeshes_2(){
//expected data //expected data
QuadMesh[] expectedData = new QuadMesh[]{ 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 //setup data
BlockChunkData chunkData = new BlockChunkData(); BlockChunkData chunkData = new BlockChunkData();
@ -72,18 +76,19 @@ public class BlockMeshgenTests {
chunkData.setType(types); chunkData.setType(types);
chunkData.setType(0, 0, 0, (short)1); chunkData.setType(0, 0, 0, (short)1);
chunkData.setType(0, 1, 0, (short)1); chunkData.setType(0, 1, 0, (short)1);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(expectedData.length, quadMeshes.size()); assertEquals(expectedData.length, cache.getActiveCount());
for(QuadMesh expected : expectedData){ for(QuadMesh expected : expectedData){
boolean found = false; 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){ if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){
found = true; found = true;
assertEquals(expected.x, actual.x); assertEquals(expected.x, actual.x);
@ -95,14 +100,16 @@ public class BlockMeshgenTests {
} }
assertEquals(true, found); assertEquals(true, found);
} }
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
public void test_fillQuadMeshes_3(){ public void test_fillQuadMeshes_3(){
//expected data //expected data
QuadMesh[] expectedData = new QuadMesh[]{ 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 //setup data
BlockChunkData chunkData = new BlockChunkData(); BlockChunkData chunkData = new BlockChunkData();
@ -112,18 +119,19 @@ public class BlockMeshgenTests {
chunkData.setType(0, 1, 0, (short)1); chunkData.setType(0, 1, 0, (short)1);
chunkData.setType(1, 0, 0, (short)1); chunkData.setType(1, 0, 0, (short)1);
chunkData.setType(1, 1, 0, (short)1); chunkData.setType(1, 1, 0, (short)1);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(expectedData.length, quadMeshes.size()); assertEquals(expectedData.length, cache.getActiveCount());
for(QuadMesh expected : expectedData){ for(QuadMesh expected : expectedData){
boolean found = false; 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){ if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){
found = true; found = true;
assertEquals(expected.x, actual.x); assertEquals(expected.x, actual.x);
@ -135,15 +143,18 @@ public class BlockMeshgenTests {
} }
assertEquals(true, found); assertEquals(true, found);
} }
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
public void test_fillQuadMeshes_4(){ public void test_fillQuadMeshes_4(){
//expected data //expected data
QuadMesh[] expectedData = new QuadMesh[]{ QuadMesh[] expectedData = new QuadMesh[]{
new QuadMesh(0,0,0,1,1,1), new QuadMesh(),
new QuadMesh(0,2,0,1,1,1), new QuadMesh(),
}; };
expectedData[0].set(0,0,0,1,1,1);
expectedData[1].set(0,2,0,1,1,1);
//setup data //setup data
BlockChunkData chunkData = new BlockChunkData(); BlockChunkData chunkData = new BlockChunkData();
@ -151,18 +162,19 @@ public class BlockMeshgenTests {
chunkData.setType(types); chunkData.setType(types);
chunkData.setType(0, 0, 0, (short)1); chunkData.setType(0, 0, 0, (short)1);
chunkData.setType(0, 2, 0, (short)1); chunkData.setType(0, 2, 0, (short)1);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(expectedData.length, quadMeshes.size()); assertEquals(expectedData.length, cache.getActiveCount());
for(QuadMesh expected : expectedData){ for(QuadMesh expected : expectedData){
boolean found = false; 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){ if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){
found = true; found = true;
assertEquals(expected.x, actual.x); assertEquals(expected.x, actual.x);
@ -174,6 +186,7 @@ public class BlockMeshgenTests {
} }
assertEquals(true, found); assertEquals(true, found);
} }
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
@ -182,23 +195,28 @@ public class BlockMeshgenTests {
BlockChunkData chunkData = new BlockChunkData(); BlockChunkData chunkData = new BlockChunkData();
short[] types = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH]; short[] types = new short[BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH * BlockChunkData.CHUNK_DATA_WIDTH];
chunkData.setType(types); chunkData.setType(types);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(0, quadMeshes.size()); assertEquals(0, cache.getActiveCount());
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
public void test_fillQuadMeshes_6(){ public void test_fillQuadMeshes_6(){
//expected data //expected data
QuadMesh[] expectedData = new QuadMesh[]{ QuadMesh[] expectedData = new QuadMesh[]{
new QuadMesh(5,0,8,1,1,1), new QuadMesh(),
new QuadMesh(8,0,8,1,1,1), new QuadMesh(),
new QuadMesh(7,0,4,1,1,1), 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 //setup data
BlockChunkData chunkData = new BlockChunkData(); BlockChunkData chunkData = new BlockChunkData();
@ -207,18 +225,19 @@ public class BlockMeshgenTests {
chunkData.setType(5, 0, 8, (short)1); chunkData.setType(5, 0, 8, (short)1);
chunkData.setType(8, 0, 8, (short)1); chunkData.setType(8, 0, 8, (short)1);
chunkData.setType(7, 0, 4, (short)1); chunkData.setType(7, 0, 4, (short)1);
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); QuadMeshCache cache = QuadMeshCache.getF();
//call //call
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData); BlockMeshgen.fillQuadMeshes(cache, chunkData);
//error check result //error check result
assertEquals(expectedData.length, quadMeshes.size()); assertEquals(expectedData.length, cache.getActiveCount());
for(QuadMesh expected : expectedData){ for(QuadMesh expected : expectedData){
boolean found = false; 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){ if(expected.x == actual.x && expected.y == actual.y && expected.w == actual.w && expected.h == actual.h){
found = true; found = true;
assertEquals(expected.x, actual.x); assertEquals(expected.x, actual.x);
@ -230,6 +249,7 @@ public class BlockMeshgenTests {
} }
assertEquals(true, found); assertEquals(true, found);
} }
QuadMeshCache.release(cache);
} }
@UnitTest @UnitTest
@ -273,7 +293,8 @@ public class BlockMeshgenTests {
} }
//setup data //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 //call
BlockMeshgen.meshifyBox(store, quad, 1, 1); BlockMeshgen.meshifyBox(store, quad, 1, 1);
@ -330,7 +351,8 @@ public class BlockMeshgenTests {
}; };
//setup data //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 //call
BlockMeshgen.meshifyBox(store, quad, 1, 1); BlockMeshgen.meshifyBox(store, quad, 1, 1);
@ -385,7 +407,8 @@ public class BlockMeshgenTests {
}; };
//setup data //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 //call
BlockMeshgen.meshifyBox(store, quad, 1, 1); BlockMeshgen.meshifyBox(store, quad, 1, 1);