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

This commit is contained in:
austin 2025-05-26 18:53:28 -04:00
parent 04336f6f30
commit d831509290
4 changed files with 470 additions and 238 deletions

View File

@ -2002,6 +2002,10 @@ Increase human move speed
LOD components re-attach physics
VectorPool->JomlPool
(05/26/2025)
Major NetArranger architecture rework
No allocations on client receiving chunk of blocks or terrain
Meshgen acceleration structure for block meshgen

View File

@ -2,14 +2,13 @@ package electrosphere.renderer.meshgen;
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;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.lwjgl.BufferUtils;
@ -18,6 +17,7 @@ import electrosphere.engine.Globals;
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.model.Material;
import electrosphere.renderer.model.Mesh;
import electrosphere.renderer.model.Model;
@ -185,145 +185,136 @@ public class BlockMeshgen {
/**
* Meshes a box
* @param verts The list of verts to store into
* @param normals The list of normals to store into
* @param uvs The list of uvs to store into
* @param indices The list of indices to store into
* @param samplers The sampler for a given vertex
* @param meshStore The store for mesh data
* @param quad The quad
* @param depth The depth of the box
* @param blockType The type of block
* @param indexOffset The offset for the indices that will be added (ie, if there are already vertices in the verts list, pass in the size of the vert list)
*/
protected static void meshifyBox(List<Vector3f> verts, List<Vector3f> normals, List<Vector2f> uvs, List<Integer> indices, List<Integer> samplers, QuadMesh quad, int depth, int blockType, int indexOffset){
protected static void meshifyBox(MeshGenStore meshStore, QuadMesh quad, int depth, int blockType){
int indexOffset = meshStore.getVertCount() / 3;
//
//face 1
//
int samplerIndex = Globals.blockTextureAtlas.getVoxelTypeOffset(blockType);
//verts
verts.add(new Vector3f(quad.x, quad.y, quad.z).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
//indices
indices.add(indexOffset + 0);
indices.add(indexOffset + 2);
indices.add(indexOffset + 3);
indices.add(indexOffset + 0);
indices.add(indexOffset + 3);
indices.add(indexOffset + 1);
meshStore.addFace(indexOffset + 0, indexOffset + 2, indexOffset + 3);
meshStore.addFace(indexOffset + 0, indexOffset + 3, indexOffset + 1);
//normals
normals.add(new Vector3f(0,0,-1));
normals.add(new Vector3f(0,0,-1));
normals.add(new Vector3f(0,0,-1));
normals.add(new Vector3f(0,0,-1));
meshStore.addNormal(0, 0, -1);
meshStore.addNormal(0, 0, -1);
meshStore.addNormal(0, 0, -1);
meshStore.addNormal(0, 0, -1);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(quad.w, 0));
uvs.add(new Vector2f( 0, quad.h));
uvs.add(new Vector2f(quad.w, quad.h));
meshStore.addUV( 0, 0);
meshStore.addUV(quad.w, 0);
meshStore.addUV( 0, quad.h);
meshStore.addUV(quad.w, quad.h);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
//
//face 2
//
//verts
verts.add(new Vector3f(quad.x, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
//indices
indices.add(indexOffset + 4);
indices.add(indexOffset + 7);
indices.add(indexOffset + 6);
indices.add(indexOffset + 4);
indices.add(indexOffset + 5);
indices.add(indexOffset + 7);
meshStore.addFace(indexOffset + 4, indexOffset + 7, indexOffset + 6);
meshStore.addFace(indexOffset + 4, indexOffset + 5, indexOffset + 7);
//normals
normals.add(new Vector3f(-1,0,0));
normals.add(new Vector3f(-1,0,0));
normals.add(new Vector3f(-1,0,0));
normals.add(new Vector3f(-1,0,0));
meshStore.addNormal(-1, 0, 0);
meshStore.addNormal(-1, 0, 0);
meshStore.addNormal(-1, 0, 0);
meshStore.addNormal(-1, 0, 0);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(depth, 0));
uvs.add(new Vector2f( 0, quad.h));
uvs.add(new Vector2f(depth, quad.h));
meshStore.addUV( 0, 0);
meshStore.addUV( depth, 0);
meshStore.addUV( 0, quad.h);
meshStore.addUV( depth, quad.h);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
//
//face 3
//
//verts
verts.add(new Vector3f(quad.x, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
// verts.add(new Vector3f(quad.x, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices
indices.add(indexOffset + 8);
indices.add(indexOffset + 10);
indices.add(indexOffset + 11);
indices.add(indexOffset + 9);
indices.add(indexOffset + 8);
indices.add(indexOffset + 11);
meshStore.addFace(indexOffset + 8, indexOffset + 10, indexOffset + 11);
meshStore.addFace(indexOffset + 9, indexOffset + 8, indexOffset + 11);
//normals
normals.add(new Vector3f(0,-1,0));
normals.add(new Vector3f(0,-1,0));
normals.add(new Vector3f(0,-1,0));
normals.add(new Vector3f(0,-1,0));
meshStore.addNormal(0, -1, 0);
meshStore.addNormal(0, -1, 0);
meshStore.addNormal(0, -1, 0);
meshStore.addNormal(0, -1, 0);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(depth, 0));
uvs.add(new Vector2f( 0, quad.w));
uvs.add(new Vector2f(depth, quad.w));
meshStore.addUV( 0, 0);
meshStore.addUV( depth, 0);
meshStore.addUV( 0, quad.w);
meshStore.addUV( depth, quad.w);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
//
//face 4
//
//verts
verts.add(new Vector3f(quad.x, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
// verts.add(new Vector3f(quad.x, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices
indices.add(indexOffset + 12);
indices.add(indexOffset + 15);
indices.add(indexOffset + 14);
indices.add(indexOffset + 12);
indices.add(indexOffset + 13);
indices.add(indexOffset + 15);
meshStore.addFace(indexOffset + 12, indexOffset + 15, indexOffset + 14);
meshStore.addFace(indexOffset + 12, indexOffset + 13, indexOffset + 15);
//normals
normals.add(new Vector3f(0,0,1));
normals.add(new Vector3f(0,0,1));
normals.add(new Vector3f(0,0,1));
normals.add(new Vector3f(0,0,1));
meshStore.addNormal(0, 0, 1);
meshStore.addNormal(0, 0, 1);
meshStore.addNormal(0, 0, 1);
meshStore.addNormal(0, 0, 1);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(quad.w, 0));
uvs.add(new Vector2f( 0, quad.h));
uvs.add(new Vector2f(quad.w, quad.h));
meshStore.addUV( 0, 0);
meshStore.addUV(quad.w, 0);
meshStore.addUV( 0, quad.h);
meshStore.addUV(quad.w, quad.h);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
//
@ -331,32 +322,32 @@ public class BlockMeshgen {
//
//verts
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
// verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices
indices.add(indexOffset + 16);
indices.add(indexOffset + 18);
indices.add(indexOffset + 19);
indices.add(indexOffset + 16);
indices.add(indexOffset + 19);
indices.add(indexOffset + 17);
meshStore.addFace(indexOffset + 16, indexOffset + 18, indexOffset + 19);
meshStore.addFace(indexOffset + 16, indexOffset + 19, indexOffset + 17);
//normals
normals.add(new Vector3f(1,0,0));
normals.add(new Vector3f(1,0,0));
normals.add(new Vector3f(1,0,0));
normals.add(new Vector3f(1,0,0));
meshStore.addNormal(1, 0, 0);
meshStore.addNormal(1, 0, 0);
meshStore.addNormal(1, 0, 0);
meshStore.addNormal(1, 0, 0);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(depth, 0));
uvs.add(new Vector2f( 0, quad.h));
uvs.add(new Vector2f(depth, quad.h));
meshStore.addUV( 0, 0);
meshStore.addUV( depth, 0);
meshStore.addUV( 0, quad.h);
meshStore.addUV( depth, quad.h);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
//
@ -364,32 +355,32 @@ public class BlockMeshgen {
//
//verts
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert(quad.x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
meshStore.addVert((quad.x + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
// verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z ).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
// verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indicesindexOffset +
indices.add(indexOffset + 20);
indices.add(indexOffset + 23);
indices.add(indexOffset + 22);
indices.add(indexOffset + 20);
indices.add(indexOffset + 21);
indices.add(indexOffset + 23);
meshStore.addFace(indexOffset + 20, indexOffset + 23, indexOffset + 22);
meshStore.addFace(indexOffset + 20, indexOffset + 21, indexOffset + 23);
//normals
normals.add(new Vector3f(0,1,0));
normals.add(new Vector3f(0,1,0));
normals.add(new Vector3f(0,1,0));
normals.add(new Vector3f(0,1,0));
meshStore.addNormal(0, 1, 0);
meshStore.addNormal(0, 1, 0);
meshStore.addNormal(0, 1, 0);
meshStore.addNormal(0, 1, 0);
//uvs
uvs.add(new Vector2f( 0, 0));
uvs.add(new Vector2f(depth, 0));
uvs.add(new Vector2f( 0, quad.w));
uvs.add(new Vector2f(depth, quad.w));
meshStore.addUV( 0, 0);
meshStore.addUV( depth, 0);
meshStore.addUV( 0, quad.w);
meshStore.addUV( depth, quad.w);
//samplers
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
samplers.add(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
meshStore.addCustom2(samplerIndex);
}
@ -409,18 +400,15 @@ public class BlockMeshgen {
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>();
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap);
//allocate lists to store mesh data in
List<Vector3f> verts = new LinkedList<Vector3f>();
List<Vector3f> normals = new LinkedList<Vector3f>();
List<Vector2f> uvs = new LinkedList<Vector2f>();
List<Integer> indices = new LinkedList<Integer>();
List<Integer> samplers = new LinkedList<Integer>(); //the texture to sample for this quad
//get acceleration structure
MeshGenStore meshGenStore = MeshGenStore.get();
meshGenStore.clear();
//sort
Collections.sort(quadMeshes);
int lastVertexCount = 0;
int lastFaceCount = 0;
int vertCount = 0;
int faceCount = 0;
//generate volumes
QuadMesh quad1 = null;
@ -434,12 +422,12 @@ public class BlockMeshgen {
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(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
quad1 = quad2;
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount);
lastVertexCount = verts.size();
lastFaceCount = indices.size();
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
vertCount = meshGenStore.getVertCount();
faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape);
break;
}
@ -447,10 +435,10 @@ public class BlockMeshgen {
i = i + zEnd;
}
if(quad1 != null){
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount);
lastVertexCount = verts.size();
lastFaceCount = indices.size();
BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
vertCount = meshGenStore.getVertCount();
faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape);
}
@ -459,53 +447,32 @@ public class BlockMeshgen {
//
//verts
rVal.vertices = new float[verts.size() * 3];
for(int i = 0; i < verts.size(); i++){
Vector3f currentVert = verts.get(i);
rVal.vertices[3 * i + 0] = currentVert.x * scalingFactor;
rVal.vertices[3 * i + 1] = currentVert.y * scalingFactor;
rVal.vertices[3 * i + 2] = currentVert.z * scalingFactor;
}
rVal.vertices = Arrays.copyOf(meshGenStore.getVertArr(),meshGenStore.getVertCount());
rVal.vertBuffer = BufferUtils.createFloatBuffer(rVal.vertices.length);
rVal.vertBuffer.put(rVal.vertices);
//faces
rVal.faceElements = new int[indices.size()];
for(int i = 0; i < indices.size(); i++){
rVal.faceElements[i] = indices.get(i);
}
rVal.faceElements = Arrays.copyOf(meshGenStore.getFaceArr(),meshGenStore.getFaceCount());
rVal.faceBuffer = BufferUtils.createIntBuffer(rVal.faceElements.length);
rVal.faceBuffer.put(rVal.faceElements);
//normals
rVal.normals = new float[normals.size() * 3];
for(int i = 0; i < normals.size(); i++){
Vector3f currentNormal = normals.get(i);
rVal.normals[3 * i + 0] = currentNormal.x;
rVal.normals[3 * i + 1] = currentNormal.y;
rVal.normals[3 * i + 2] = currentNormal.z;
}
rVal.normals = Arrays.copyOf(meshGenStore.getNormalArr(),meshGenStore.getNormalCount());
rVal.normalBuffer = BufferUtils.createFloatBuffer(rVal.normals.length);
rVal.normalBuffer.put(rVal.normals);
//uvs
rVal.uvs = new float[uvs.size() * 2];
for(int i = 0; i < uvs.size(); i++){
Vector2f currentUV = uvs.get(i);
rVal.uvs[2 * i + 0] = currentUV.x * scalingFactor;
rVal.uvs[2 * i + 1] = currentUV.y * scalingFactor;
}
rVal.uvs = Arrays.copyOf(meshGenStore.getUvArr(),meshGenStore.getUvCount());
rVal.uvBuffer = BufferUtils.createFloatBuffer(rVal.uvs.length);
rVal.uvBuffer.put(rVal.uvs);
//samplers
rVal.samplers = new int[samplers.size()];
for(int i = 0; i < samplers.size(); i++){
rVal.samplers[i] = samplers.get(i);
}
rVal.samplers = Arrays.copyOf(meshGenStore.getCustArr2(),meshGenStore.getCustCount2());
rVal.samplerBuffer = BufferUtils.createIntBuffer(rVal.samplers.length);
rVal.samplerBuffer.put(rVal.samplers);
MeshGenStore.release(meshGenStore);
return rVal;
}
@ -520,22 +487,16 @@ public class BlockMeshgen {
/**
* Copies vertex and index data from the combined array into a single shape
* @param verts The list of vertices
* @param indices The list of indices
* @param lastVertCount The last vertex position that was copied
* @param lastFaceCount The last index position that was copied
* @param store The mesh generation store
* @return The data containing a single shape's worth of geometry data
*/
private static BlockSingleShape copyDataToShape(List<Vector3f> verts, List<Integer> indices, int lastVertCount, int lastFaceCount){
BlockSingleShape blockSingleShape = new BlockSingleShape((verts.size() - lastVertCount),(indices.size() - lastFaceCount));
for(int i = lastVertCount; i < verts.size(); i++){
Vector3f vert = verts.get(i);
blockSingleShape.vertices[(i - lastVertCount) * 3 + 0] = vert.x;
blockSingleShape.vertices[(i - lastVertCount) * 3 + 1] = vert.y;
blockSingleShape.vertices[(i - lastVertCount) * 3 + 2] = vert.z;
private static BlockSingleShape copyDataToShape(MeshGenStore store, int vertCount, int faceCount){
BlockSingleShape blockSingleShape = new BlockSingleShape((store.getVertCount() - vertCount),(store.getFaceCount() - faceCount));
for(int i = vertCount; i < store.getVertCount(); i++){
blockSingleShape.vertices[(i - vertCount)] = store.getVert(i);
}
for(int i = lastFaceCount; i < indices.size(); i++){
blockSingleShape.faceElements[i - lastFaceCount] = indices.get(i) - lastVertCount;
for(int i = faceCount; i < store.getFaceCount(); i++){
blockSingleShape.faceElements[(i - faceCount)] = store.getFace(i);
}
return blockSingleShape;
}

View File

@ -0,0 +1,280 @@
package electrosphere.renderer.meshgen.accel;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* Store used for meshgen. Relies on arrays to accelerate operations
*/
public class MeshGenStore {
/**
* Size of each array in this store
*/
public static final int ARRAY_SIZE = 50000;
//
//object pooling potion of class
//
/**
* List for pooling stores
*/
private static final List<MeshGenStore> pool = new LinkedList<MeshGenStore>();
/**
* Lock for thread-safeing operations
*/
private static ReentrantLock lock = new ReentrantLock();
/**
* Gets a MeshGenStore from the pool. Allocates if no free one is available.
* @param type The type of the message
* @return A MeshGenStore
*/
public static MeshGenStore get(){
MeshGenStore rVal = null;
lock.lock();
if(pool.size() > 0){
rVal = pool.remove(0);
} else {
rVal = new MeshGenStore();
}
lock.unlock();
return rVal;
}
/**
* Releases a MeshGenStore back into the pool
* @param data The object to release
*/
public static void release(MeshGenStore data){
lock.lock();
MeshGenStore.pool.add(data);
lock.unlock();
}
/**
* Array for storing verts
*/
private float[] vertArr = new float[ARRAY_SIZE * 3];
/**
* Array for storing normals
*/
private float[] normalArr = new float[ARRAY_SIZE * 3];
/**
* Array for storing face data
*/
private int[] faceArr = new int[ARRAY_SIZE];
/**
* The uv array
*/
private float[] uvArr = new float[ARRAY_SIZE * 2];
/**
* Array for storing custom values
*/
private float[] custArr1 = new float[ARRAY_SIZE * 3];
/**
* Array for storing custom values
*/
private int[] custArr2 = new int[ARRAY_SIZE * 3];
/**
* The number of elements in the vert array
*/
private int vertCount = 0;
/**
* The number of elements in the normal array
*/
private int normalCount = 0;
/**
* The number of elements in the face array
*/
private int faceCount = 0;
/**
* The number of elements in the uv array
*/
private int uvCount = 0;
/**
* The number of elements in the custom array 1
*/
private int custCount1 = 0;
/**
* The number of elements in the custom array 2
*/
private int custCount2 = 0;
/**
* Adds a vert to the store
*/
public void addVert(float x, float y, float z){
vertArr[vertCount + 0] = x;
vertArr[vertCount + 1] = y;
vertArr[vertCount + 2] = z;
vertCount = vertCount + 3;
}
public void addNormal(float x, float y, float z){
normalArr[normalCount + 0] = x;
normalArr[normalCount + 1] = y;
normalArr[normalCount + 2] = z;
normalCount = normalCount + 3;
}
public void addFace(int x, int y, int z){
faceArr[faceCount + 0] = x;
faceArr[faceCount + 1] = y;
faceArr[faceCount + 2] = z;
faceCount = faceCount + 3;
}
public void addUV(float x, float y){
uvArr[uvCount + 0] = x;
uvArr[uvCount + 1] = y;
uvCount = uvCount + 2;
}
public void addCustom1(float x, float y, float z){
custArr1[custCount1 + 0] = x;
custArr1[custCount1 + 1] = y;
custArr1[custCount1 + 2] = z;
custCount1 = custCount1 + 3;
}
public void addCustom1(float x, float y){
custArr1[custCount1 + 0] = x;
custArr1[custCount1 + 1] = y;
custCount1 = custCount1 + 2;
}
public void addCustom1(float x){
custArr1[custCount1 + 0] = x;
custCount1 = custCount1 + 1;
}
public void addCustom2(int x, int y, int z){
custArr2[custCount2 + 0] = x;
custArr2[custCount2 + 1] = y;
custArr2[custCount2 + 2] = z;
custCount2 = custCount2 + 3;
}
public void addCustom2(int x, int y){
custArr2[custCount2 + 0] = x;
custArr2[custCount2 + 1] = y;
custCount2 = custCount2 + 2;
}
public void addCustom2(int x){
custArr2[custCount2 + 0] = x;
custCount2 = custCount2 + 1;
}
public float[] getVertArr() {
return vertArr;
}
public float[] getNormalArr() {
return normalArr;
}
public int[] getFaceArr() {
return faceArr;
}
public float[] getUvArr() {
return uvArr;
}
public float[] getCustArr1() {
return custArr1;
}
public int getVertCount() {
return vertCount;
}
public int getNormalCount() {
return normalCount;
}
public int getFaceCount() {
return faceCount;
}
public int getUvCount() {
return uvCount;
}
public int getCustCount1() {
return custCount1;
}
public int[] getCustArr2() {
return custArr2;
}
public int getCustCount2() {
return custCount2;
}
/**
* Gets the vert at a given index
* @param index The index
* @return The vert
*/
public float getVert(int index){
return vertArr[index];
}
public int getFace(int index){
return faceArr[index];
}
/**
* Clears the data in the store
*/
public void clear(){
vertCount = 0;
normalCount = 0;
faceCount = 0;
uvCount = 0;
custCount1 = 0;
custCount2 = 0;
}
}

View File

@ -5,12 +5,10 @@ import static org.junit.jupiter.api.Assertions.*;
import java.util.LinkedList;
import java.util.List;
import org.joml.Vector2f;
import org.joml.Vector3f;
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.test.annotations.UnitTest;
/**
@ -236,6 +234,8 @@ public class BlockMeshgenTests {
@UnitTest
public void test_meshifyBox_verts(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data
float[] expectedData = new float[]{
0,0,0,
@ -273,31 +273,27 @@ public class BlockMeshgenTests {
}
//setup data
List<Vector3f> verts = new LinkedList<Vector3f>();
List<Vector3f> normals = new LinkedList<Vector3f>();
List<Vector2f> uvs = new LinkedList<Vector2f>();
List<Integer> indices = new LinkedList<Integer>();
List<Integer> samplers = new LinkedList<Integer>();
QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1,1);
//call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0);
BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result
assertEquals(expectedData.length / 3, verts.size());
assertEquals(expectedData.length, store.getVertCount());
int i = 0;
for(Vector3f vert : verts){
assertEquals(expectedData[i + 0], vert.x);
assertEquals(expectedData[i + 1], vert.y);
assertEquals(expectedData[i + 2], vert.z);
i = i + 3;
float[] verts = store.getVertArr();
for(int i = 0; i < store.getVertCount(); i++){
assertEquals(expectedData[i], verts[i]);
}
MeshGenStore.release(store);
}
@UnitTest
public void test_meshifyBox_normals(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data
float[] expectedData = new float[]{
0, 0,-1,
@ -334,31 +330,27 @@ public class BlockMeshgenTests {
};
//setup data
List<Vector3f> verts = new LinkedList<Vector3f>();
List<Vector3f> normals = new LinkedList<Vector3f>();
List<Vector2f> uvs = new LinkedList<Vector2f>();
List<Integer> indices = new LinkedList<Integer>();
List<Integer> samplers = new LinkedList<Integer>();
QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1);
//call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0);
BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result
assertEquals(expectedData.length / 3, normals.size());
assertEquals(expectedData.length / 3, store.getNormalCount() / 3);
int i = 0;
for(Vector3f normal : normals){
assertEquals(expectedData[i + 0], normal.x);
assertEquals(expectedData[i + 1], normal.y);
assertEquals(expectedData[i + 2], normal.z);
i = i + 3;
float[] normals = store.getNormalArr();
for(int i = 0; i < store.getNormalCount(); i++){
assertEquals(expectedData[i], normals[i]);
}
MeshGenStore.release(store);
}
@UnitTest
public void test_meshifyBox_uvs(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data
float[] expectedData = new float[]{
0, 0,
@ -393,26 +385,21 @@ public class BlockMeshgenTests {
};
//setup data
List<Vector3f> verts = new LinkedList<Vector3f>();
List<Vector3f> normals = new LinkedList<Vector3f>();
List<Vector2f> uvs = new LinkedList<Vector2f>();
List<Integer> indices = new LinkedList<Integer>();
List<Integer> samplers = new LinkedList<Integer>();
QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1);
//call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0);
BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result
assertEquals(expectedData.length / 2, uvs.size());
assertEquals(expectedData.length / 2, store.getUvCount() / 2);
int i = 0;
for(Vector2f uv : uvs){
assertEquals(expectedData[i + 0], uv.x);
assertEquals(expectedData[i + 1], uv.y);
i = i + 2;
float[] uvs = store.getUvArr();
for(int i = 0; i < store.getUvCount(); i++){
assertEquals(expectedData[i], uvs[i]);
}
MeshGenStore.release(store);
}
@UnitTest