diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 2b9df15b..e55bf06a 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -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 diff --git a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java index 1e2d2a49..9079ba5d 100644 --- a/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java +++ b/src/main/java/electrosphere/renderer/meshgen/BlockMeshgen.java @@ -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 verts, List normals, List uvs, List indices, List 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 quadMeshes = new LinkedList(); BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap); - //allocate lists to store mesh data in - List verts = new LinkedList(); - List normals = new LinkedList(); - List uvs = new LinkedList(); - List indices = new LinkedList(); - List samplers = new LinkedList(); //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 verts, List 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; } diff --git a/src/main/java/electrosphere/renderer/meshgen/accel/MeshGenStore.java b/src/main/java/electrosphere/renderer/meshgen/accel/MeshGenStore.java new file mode 100644 index 00000000..6a8cebcc --- /dev/null +++ b/src/main/java/electrosphere/renderer/meshgen/accel/MeshGenStore.java @@ -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 pool = new LinkedList(); + + /** + * 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; + } + + + +} diff --git a/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java b/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java index 56b263d5..9359ec5d 100644 --- a/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java +++ b/src/test/java/electrosphere/renderer/meshgen/BlockMeshgenTests.java @@ -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 verts = new LinkedList(); - List normals = new LinkedList(); - List uvs = new LinkedList(); - List indices = new LinkedList(); - List samplers = new LinkedList(); 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 verts = new LinkedList(); - List normals = new LinkedList(); - List uvs = new LinkedList(); - List indices = new LinkedList(); - List samplers = new LinkedList(); 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 verts = new LinkedList(); - List normals = new LinkedList(); - List uvs = new LinkedList(); - List indices = new LinkedList(); - List samplers = new LinkedList(); 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