block meshgen memory work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
8784b08fe4
commit
64b10e5837
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@ -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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user