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 LOD components re-attach physics
VectorPool->JomlPool 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.FloatBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; 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;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
@ -18,6 +17,7 @@ import electrosphere.engine.Globals;
import electrosphere.entity.state.collidable.MultiShapeTriGeomData; 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.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;
@ -185,145 +185,136 @@ public class BlockMeshgen {
/** /**
* Meshes a box * Meshes a box
* @param verts The list of verts to store into * @param meshStore The store for mesh data
* @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 quad The quad * @param quad The quad
* @param depth The depth of the box * @param depth The depth of the box
* @param blockType The type of block * @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) * @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 //face 1
// //
int samplerIndex = Globals.blockTextureAtlas.getVoxelTypeOffset(blockType); int samplerIndex = Globals.blockTextureAtlas.getVoxelTypeOffset(blockType);
//verts //verts
verts.add(new Vector3f(quad.x, quad.y, 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);
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z).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);
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z).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);
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z).mul(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
indices.add(indexOffset + 0); meshStore.addFace(indexOffset + 0, indexOffset + 2, indexOffset + 3);
indices.add(indexOffset + 2); meshStore.addFace(indexOffset + 0, indexOffset + 3, indexOffset + 1);
indices.add(indexOffset + 3);
indices.add(indexOffset + 0);
indices.add(indexOffset + 3);
indices.add(indexOffset + 1);
//normals //normals
normals.add(new Vector3f(0,0,-1)); meshStore.addNormal(0, 0, -1);
normals.add(new Vector3f(0,0,-1)); meshStore.addNormal(0, 0, -1);
normals.add(new Vector3f(0,0,-1)); meshStore.addNormal(0, 0, -1);
normals.add(new Vector3f(0,0,-1)); meshStore.addNormal(0, 0, -1);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(quad.w, 0)); meshStore.addUV(quad.w, 0);
uvs.add(new Vector2f( 0, quad.h)); meshStore.addUV( 0, quad.h);
uvs.add(new Vector2f(quad.w, quad.h)); meshStore.addUV(quad.w, quad.h);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
// //
//face 2 //face 2
// //
//verts //verts
verts.add(new Vector3f(quad.x, quad.y, 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);
verts.add(new Vector3f(quad.x, 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 + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z ).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);
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 + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
//indices //indices
indices.add(indexOffset + 4); meshStore.addFace(indexOffset + 4, indexOffset + 7, indexOffset + 6);
indices.add(indexOffset + 7); meshStore.addFace(indexOffset + 4, indexOffset + 5, indexOffset + 7);
indices.add(indexOffset + 6);
indices.add(indexOffset + 4);
indices.add(indexOffset + 5);
indices.add(indexOffset + 7);
//normals //normals
normals.add(new Vector3f(-1,0,0)); meshStore.addNormal(-1, 0, 0);
normals.add(new Vector3f(-1,0,0)); meshStore.addNormal(-1, 0, 0);
normals.add(new Vector3f(-1,0,0)); meshStore.addNormal(-1, 0, 0);
normals.add(new Vector3f(-1,0,0)); meshStore.addNormal(-1, 0, 0);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(depth, 0)); meshStore.addUV( depth, 0);
uvs.add(new Vector2f( 0, quad.h)); meshStore.addUV( 0, quad.h);
uvs.add(new Vector2f(depth, quad.h)); meshStore.addUV( depth, quad.h);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
// //
//face 3 //face 3
// //
//verts //verts
verts.add(new Vector3f(quad.x, quad.y, 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);
verts.add(new Vector3f(quad.x, 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 + depth) * BlockChunkData.BLOCK_SIZE_MULTIPLIER);
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).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);
verts.add(new Vector3f(quad.x + quad.w, quad.y, 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 + 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
indices.add(indexOffset + 8); meshStore.addFace(indexOffset + 8, indexOffset + 10, indexOffset + 11);
indices.add(indexOffset + 10); meshStore.addFace(indexOffset + 9, indexOffset + 8, indexOffset + 11);
indices.add(indexOffset + 11);
indices.add(indexOffset + 9);
indices.add(indexOffset + 8);
indices.add(indexOffset + 11);
//normals //normals
normals.add(new Vector3f(0,-1,0)); meshStore.addNormal(0, -1, 0);
normals.add(new Vector3f(0,-1,0)); meshStore.addNormal(0, -1, 0);
normals.add(new Vector3f(0,-1,0)); meshStore.addNormal(0, -1, 0);
normals.add(new Vector3f(0,-1,0)); meshStore.addNormal(0, -1, 0);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(depth, 0)); meshStore.addUV( depth, 0);
uvs.add(new Vector2f( 0, quad.w)); meshStore.addUV( 0, quad.w);
uvs.add(new Vector2f(depth, quad.w)); meshStore.addUV( depth, quad.w);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
// //
//face 4 //face 4
// //
//verts //verts
verts.add(new Vector3f(quad.x, 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 + depth) * 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 + 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.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 + depth) * 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 + 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
indices.add(indexOffset + 12); meshStore.addFace(indexOffset + 12, indexOffset + 15, indexOffset + 14);
indices.add(indexOffset + 15); meshStore.addFace(indexOffset + 12, indexOffset + 13, indexOffset + 15);
indices.add(indexOffset + 14);
indices.add(indexOffset + 12);
indices.add(indexOffset + 13);
indices.add(indexOffset + 15);
//normals //normals
normals.add(new Vector3f(0,0,1)); meshStore.addNormal(0, 0, 1);
normals.add(new Vector3f(0,0,1)); meshStore.addNormal(0, 0, 1);
normals.add(new Vector3f(0,0,1)); meshStore.addNormal(0, 0, 1);
normals.add(new Vector3f(0,0,1)); meshStore.addNormal(0, 0, 1);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(quad.w, 0)); meshStore.addUV(quad.w, 0);
uvs.add(new Vector2f( 0, quad.h)); meshStore.addUV( 0, quad.h);
uvs.add(new Vector2f(quad.w, quad.h)); meshStore.addUV(quad.w, quad.h);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
// //
@ -331,32 +322,32 @@ public class BlockMeshgen {
// //
//verts //verts
verts.add(new Vector3f(quad.x + quad.w, quad.y, quad.z ).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);
verts.add(new Vector3f(quad.x + quad.w, quad.y, 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 + depth) * 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 + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * 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 + 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
indices.add(indexOffset + 16); meshStore.addFace(indexOffset + 16, indexOffset + 18, indexOffset + 19);
indices.add(indexOffset + 18); meshStore.addFace(indexOffset + 16, indexOffset + 19, indexOffset + 17);
indices.add(indexOffset + 19);
indices.add(indexOffset + 16);
indices.add(indexOffset + 19);
indices.add(indexOffset + 17);
//normals //normals
normals.add(new Vector3f(1,0,0)); meshStore.addNormal(1, 0, 0);
normals.add(new Vector3f(1,0,0)); meshStore.addNormal(1, 0, 0);
normals.add(new Vector3f(1,0,0)); meshStore.addNormal(1, 0, 0);
normals.add(new Vector3f(1,0,0)); meshStore.addNormal(1, 0, 0);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(depth, 0)); meshStore.addUV( depth, 0);
uvs.add(new Vector2f( 0, quad.h)); meshStore.addUV( 0, quad.h);
uvs.add(new Vector2f(depth, quad.h)); meshStore.addUV( depth, quad.h);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
// //
@ -364,32 +355,32 @@ public class BlockMeshgen {
// //
//verts //verts
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z ).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);
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 + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.z + depth) * 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 + quad.w) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, (quad.y + quad.h) * BlockChunkData.BLOCK_SIZE_MULTIPLIER, quad.z * 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 + 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 + //indicesindexOffset +
indices.add(indexOffset + 20); meshStore.addFace(indexOffset + 20, indexOffset + 23, indexOffset + 22);
indices.add(indexOffset + 23); meshStore.addFace(indexOffset + 20, indexOffset + 21, indexOffset + 23);
indices.add(indexOffset + 22);
indices.add(indexOffset + 20);
indices.add(indexOffset + 21);
indices.add(indexOffset + 23);
//normals //normals
normals.add(new Vector3f(0,1,0)); meshStore.addNormal(0, 1, 0);
normals.add(new Vector3f(0,1,0)); meshStore.addNormal(0, 1, 0);
normals.add(new Vector3f(0,1,0)); meshStore.addNormal(0, 1, 0);
normals.add(new Vector3f(0,1,0)); meshStore.addNormal(0, 1, 0);
//uvs //uvs
uvs.add(new Vector2f( 0, 0)); meshStore.addUV( 0, 0);
uvs.add(new Vector2f(depth, 0)); meshStore.addUV( depth, 0);
uvs.add(new Vector2f( 0, quad.w)); meshStore.addUV( 0, quad.w);
uvs.add(new Vector2f(depth, quad.w)); meshStore.addUV( depth, quad.w);
//samplers //samplers
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
samplers.add(samplerIndex); meshStore.addCustom2(samplerIndex);
} }
@ -409,18 +400,15 @@ public class BlockMeshgen {
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>(); List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>();
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap); BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData, solids, solidsMap);
//allocate lists to store mesh data in //get acceleration structure
List<Vector3f> verts = new LinkedList<Vector3f>(); MeshGenStore meshGenStore = MeshGenStore.get();
List<Vector3f> normals = new LinkedList<Vector3f>(); meshGenStore.clear();
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
//sort //sort
Collections.sort(quadMeshes); Collections.sort(quadMeshes);
int lastVertexCount = 0; int vertCount = 0;
int lastFaceCount = 0; int faceCount = 0;
//generate volumes //generate volumes
QuadMesh quad1 = null; 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){ 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(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size()); BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
quad1 = quad2; quad1 = quad2;
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount); BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
lastVertexCount = verts.size(); vertCount = meshGenStore.getVertCount();
lastFaceCount = indices.size(); faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape); rVal.shapeData.add(blockSingleShape);
break; break;
} }
@ -447,10 +435,10 @@ public class BlockMeshgen {
i = i + zEnd; i = i + zEnd;
} }
if(quad1 != null){ if(quad1 != null){
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size()); BlockMeshgen.meshifyBox(meshGenStore,quad1,zEnd,quad1.type);
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount); BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(meshGenStore, vertCount, faceCount);
lastVertexCount = verts.size(); vertCount = meshGenStore.getVertCount();
lastFaceCount = indices.size(); faceCount = meshGenStore.getFaceCount();
rVal.shapeData.add(blockSingleShape); rVal.shapeData.add(blockSingleShape);
} }
@ -459,53 +447,32 @@ public class BlockMeshgen {
// //
//verts //verts
rVal.vertices = new float[verts.size() * 3]; rVal.vertices = Arrays.copyOf(meshGenStore.getVertArr(),meshGenStore.getVertCount());
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.vertBuffer = BufferUtils.createFloatBuffer(rVal.vertices.length); rVal.vertBuffer = BufferUtils.createFloatBuffer(rVal.vertices.length);
rVal.vertBuffer.put(rVal.vertices); rVal.vertBuffer.put(rVal.vertices);
//faces //faces
rVal.faceElements = new int[indices.size()]; rVal.faceElements = Arrays.copyOf(meshGenStore.getFaceArr(),meshGenStore.getFaceCount());
for(int i = 0; i < indices.size(); i++){
rVal.faceElements[i] = indices.get(i);
}
rVal.faceBuffer = BufferUtils.createIntBuffer(rVal.faceElements.length); rVal.faceBuffer = BufferUtils.createIntBuffer(rVal.faceElements.length);
rVal.faceBuffer.put(rVal.faceElements); rVal.faceBuffer.put(rVal.faceElements);
//normals //normals
rVal.normals = new float[normals.size() * 3]; rVal.normals = Arrays.copyOf(meshGenStore.getNormalArr(),meshGenStore.getNormalCount());
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.normalBuffer = BufferUtils.createFloatBuffer(rVal.normals.length); rVal.normalBuffer = BufferUtils.createFloatBuffer(rVal.normals.length);
rVal.normalBuffer.put(rVal.normals); rVal.normalBuffer.put(rVal.normals);
//uvs //uvs
rVal.uvs = new float[uvs.size() * 2]; rVal.uvs = Arrays.copyOf(meshGenStore.getUvArr(),meshGenStore.getUvCount());
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.uvBuffer = BufferUtils.createFloatBuffer(rVal.uvs.length); rVal.uvBuffer = BufferUtils.createFloatBuffer(rVal.uvs.length);
rVal.uvBuffer.put(rVal.uvs); rVal.uvBuffer.put(rVal.uvs);
//samplers //samplers
rVal.samplers = new int[samplers.size()]; rVal.samplers = Arrays.copyOf(meshGenStore.getCustArr2(),meshGenStore.getCustCount2());
for(int i = 0; i < samplers.size(); i++){
rVal.samplers[i] = samplers.get(i);
}
rVal.samplerBuffer = BufferUtils.createIntBuffer(rVal.samplers.length); rVal.samplerBuffer = BufferUtils.createIntBuffer(rVal.samplers.length);
rVal.samplerBuffer.put(rVal.samplers); rVal.samplerBuffer.put(rVal.samplers);
MeshGenStore.release(meshGenStore);
return rVal; return rVal;
} }
@ -520,22 +487,16 @@ public class BlockMeshgen {
/** /**
* Copies vertex and index data from the combined array into a single shape * Copies vertex and index data from the combined array into a single shape
* @param verts The list of vertices * @param store The mesh generation store
* @param indices The list of indices
* @param lastVertCount The last vertex position that was copied
* @param lastFaceCount The last index position that was copied
* @return The data containing a single shape's worth of geometry data * @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){ private static BlockSingleShape copyDataToShape(MeshGenStore store, int vertCount, int faceCount){
BlockSingleShape blockSingleShape = new BlockSingleShape((verts.size() - lastVertCount),(indices.size() - lastFaceCount)); BlockSingleShape blockSingleShape = new BlockSingleShape((store.getVertCount() - vertCount),(store.getFaceCount() - faceCount));
for(int i = lastVertCount; i < verts.size(); i++){ for(int i = vertCount; i < store.getVertCount(); i++){
Vector3f vert = verts.get(i); blockSingleShape.vertices[(i - vertCount)] = store.getVert(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;
} }
for(int i = lastFaceCount; i < indices.size(); i++){ for(int i = faceCount; i < store.getFaceCount(); i++){
blockSingleShape.faceElements[i - lastFaceCount] = indices.get(i) - lastVertCount; blockSingleShape.faceElements[(i - faceCount)] = store.getFace(i);
} }
return blockSingleShape; 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.LinkedList;
import java.util.List; import java.util.List;
import org.joml.Vector2f;
import org.joml.Vector3f;
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.BlockMeshgen.QuadMesh;
import electrosphere.renderer.meshgen.accel.MeshGenStore;
import electrosphere.test.annotations.UnitTest; import electrosphere.test.annotations.UnitTest;
/** /**
@ -236,6 +234,8 @@ public class BlockMeshgenTests {
@UnitTest @UnitTest
public void test_meshifyBox_verts(){ public void test_meshifyBox_verts(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data //expected data
float[] expectedData = new float[]{ float[] expectedData = new float[]{
0,0,0, 0,0,0,
@ -273,31 +273,27 @@ public class BlockMeshgenTests {
} }
//setup data //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); QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1,1);
//call //call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0); BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result //error check result
assertEquals(expectedData.length / 3, verts.size()); assertEquals(expectedData.length, store.getVertCount());
int i = 0; float[] verts = store.getVertArr();
for(Vector3f vert : verts){ for(int i = 0; i < store.getVertCount(); i++){
assertEquals(expectedData[i + 0], vert.x); assertEquals(expectedData[i], verts[i]);
assertEquals(expectedData[i + 1], vert.y);
assertEquals(expectedData[i + 2], vert.z);
i = i + 3;
} }
MeshGenStore.release(store);
} }
@UnitTest @UnitTest
public void test_meshifyBox_normals(){ public void test_meshifyBox_normals(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data //expected data
float[] expectedData = new float[]{ float[] expectedData = new float[]{
0, 0,-1, 0, 0,-1,
@ -334,31 +330,27 @@ public class BlockMeshgenTests {
}; };
//setup data //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); QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1);
//call //call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0); BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result //error check result
assertEquals(expectedData.length / 3, normals.size()); assertEquals(expectedData.length / 3, store.getNormalCount() / 3);
int i = 0; float[] normals = store.getNormalArr();
for(Vector3f normal : normals){ for(int i = 0; i < store.getNormalCount(); i++){
assertEquals(expectedData[i + 0], normal.x); assertEquals(expectedData[i], normals[i]);
assertEquals(expectedData[i + 1], normal.y);
assertEquals(expectedData[i + 2], normal.z);
i = i + 3;
} }
MeshGenStore.release(store);
} }
@UnitTest @UnitTest
public void test_meshifyBox_uvs(){ public void test_meshifyBox_uvs(){
MeshGenStore store = MeshGenStore.get();
store.clear();
//expected data //expected data
float[] expectedData = new float[]{ float[] expectedData = new float[]{
0, 0, 0, 0,
@ -393,26 +385,21 @@ public class BlockMeshgenTests {
}; };
//setup data //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); QuadMesh quad = new QuadMesh(0, 0, 0, 1, 1, 1);
//call //call
BlockMeshgen.meshifyBox(verts, normals, uvs, indices, samplers, quad, 1, 1, 0); BlockMeshgen.meshifyBox(store, quad, 1, 1);
//error check result //error check result
assertEquals(expectedData.length / 2, uvs.size()); assertEquals(expectedData.length / 2, store.getUvCount() / 2);
int i = 0; float[] uvs = store.getUvArr();
for(Vector2f uv : uvs){ for(int i = 0; i < store.getUvCount(); i++){
assertEquals(expectedData[i + 0], uv.x); assertEquals(expectedData[i], uvs[i]);
assertEquals(expectedData[i + 1], uv.y);
i = i + 2;
} }
MeshGenStore.release(store);
} }
@UnitTest @UnitTest