Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
716 lines
24 KiB
Java
716 lines
24 KiB
Java
package electrosphere.renderer.meshgen;
|
|
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.IntBuffer;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import org.joml.Vector2f;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3i;
|
|
import org.lwjgl.BufferUtils;
|
|
import org.lwjgl.opengl.GL40;
|
|
|
|
import electrosphere.client.block.BlockChunkData;
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.entity.state.collidable.MultiShapeTriGeomData;
|
|
import electrosphere.entity.state.collidable.TriGeomData;
|
|
import electrosphere.renderer.model.Material;
|
|
import electrosphere.renderer.model.Mesh;
|
|
import electrosphere.renderer.model.Model;
|
|
|
|
/**
|
|
* Generates a model for a block
|
|
*/
|
|
public class BlockMeshgen {
|
|
|
|
/**
|
|
* The indices to draw faces on cubes
|
|
*/
|
|
static final int[] CUBE_INDICES = new int[]{
|
|
//Top
|
|
2, 6, 7,
|
|
2, 3, 7,
|
|
|
|
//Bottom
|
|
0, 4, 5,
|
|
0, 1, 5,
|
|
|
|
//Left
|
|
0, 2, 6,
|
|
0, 4, 6,
|
|
|
|
//Right
|
|
1, 3, 7,
|
|
1, 5, 7,
|
|
|
|
//Front
|
|
0, 2, 3,
|
|
0, 1, 3,
|
|
|
|
//Back
|
|
4, 6, 7,
|
|
4, 5, 7
|
|
};
|
|
|
|
/**
|
|
* Position of the sampler data in the buffer
|
|
*/
|
|
static final int SAMPLER_SHADER_POSITION = 5;
|
|
|
|
/**
|
|
* The size of the sampler data per-vertex
|
|
*/
|
|
static final int SAMPLER_DATA_SIZE = 1;
|
|
|
|
|
|
/**
|
|
* Calculates the quad meshes for the provided data
|
|
* @param quadMeshes The quad mesh list to fill
|
|
* @param data The block data
|
|
*/
|
|
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockMeshgenData data){
|
|
Vector3i dimensions = data.getDimensions();
|
|
for(int z = 0; z < dimensions.z; z++){
|
|
for(int x = 0; x < dimensions.x; x++){
|
|
QuadMesh currentQuad = null;
|
|
for(int y = 0; y < dimensions.y; y++){
|
|
if(data.isEmpty(x, y, z)){
|
|
if(currentQuad == null){
|
|
continue;
|
|
} else {
|
|
currentQuad.h = y - currentQuad.y;
|
|
//check if should merge with previous quad
|
|
for(QuadMesh prevMesh : quadMeshes){
|
|
if(prevMesh.x + prevMesh.w == currentQuad.x && prevMesh.y == currentQuad.y && prevMesh.h == currentQuad.h && prevMesh.z == currentQuad.z){
|
|
prevMesh.w = prevMesh.w + 1;
|
|
currentQuad = null;
|
|
break;
|
|
}
|
|
}
|
|
if(currentQuad != null){
|
|
quadMeshes.add(currentQuad);
|
|
}
|
|
currentQuad = null;
|
|
}
|
|
} else {
|
|
if(currentQuad == null){
|
|
currentQuad = new QuadMesh();
|
|
currentQuad.x = x;
|
|
currentQuad.y = y;
|
|
currentQuad.z = z;
|
|
currentQuad.w = 1;
|
|
currentQuad.h = 1;
|
|
currentQuad.type = data.getType(x, y, z);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
if(currentQuad != null){
|
|
quadMeshes.add(currentQuad);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 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){
|
|
//
|
|
//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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
|
|
|
|
//
|
|
//face 5
|
|
//
|
|
|
|
//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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
|
|
|
|
//
|
|
//face 6
|
|
//
|
|
|
|
//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));
|
|
//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);
|
|
//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));
|
|
//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));
|
|
//samplers
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
samplers.add(samplerIndex);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Rasterizes a block chunk data into mesh data
|
|
* @param chunkData The block chunk data
|
|
* @return The mesh data
|
|
*/
|
|
public static BlockMeshData rasterize(BlockMeshgenData chunkData){
|
|
BlockMeshData rVal = new BlockMeshData();
|
|
|
|
//calculate quad meshes
|
|
List<QuadMesh> quadMeshes = new LinkedList<QuadMesh>();
|
|
BlockMeshgen.fillQuadMeshes(quadMeshes, chunkData);
|
|
|
|
//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
|
|
|
|
//sort
|
|
Collections.sort(quadMeshes);
|
|
|
|
int lastVertexCount = 0;
|
|
int lastFaceCount = 0;
|
|
|
|
//generate volumes
|
|
QuadMesh quad1 = null;
|
|
QuadMesh quad2 = null;
|
|
int zEnd = 0;
|
|
for(int i = 0; i < quadMeshes.size();){
|
|
quad1 = quadMeshes.get(i);
|
|
zEnd = 1;
|
|
for(int j = i + 1; j < quadMeshes.size(); j++){
|
|
quad2 = quadMeshes.get(j);
|
|
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());
|
|
quad1 = quad2;
|
|
|
|
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount);
|
|
lastVertexCount = verts.size();
|
|
lastFaceCount = indices.size();
|
|
rVal.shapeData.add(blockSingleShape);
|
|
break;
|
|
}
|
|
}
|
|
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();
|
|
rVal.shapeData.add(blockSingleShape);
|
|
}
|
|
|
|
//
|
|
//store in flat arrays
|
|
//
|
|
|
|
//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;
|
|
rVal.vertices[3 * i + 1] = currentVert.y;
|
|
rVal.vertices[3 * i + 2] = currentVert.z;
|
|
}
|
|
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.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.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;
|
|
rVal.uvs[2 * i + 1] = currentUV.y;
|
|
}
|
|
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.samplerBuffer = BufferUtils.createIntBuffer(rVal.samplers.length);
|
|
rVal.samplerBuffer.put(rVal.samplers);
|
|
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @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;
|
|
}
|
|
for(int i = lastFaceCount; i < indices.size(); i++){
|
|
blockSingleShape.faceElements[i - lastFaceCount] = indices.get(i) - lastVertCount;
|
|
}
|
|
return blockSingleShape;
|
|
}
|
|
|
|
/**
|
|
* Generates a mesh based on a block mesh data object
|
|
* @param data The block mesh data object
|
|
* @return The mesh
|
|
*/
|
|
protected static Mesh generateBlockMesh(BlockMeshData meshData){
|
|
Mesh mesh = new Mesh("blockChunk");
|
|
|
|
|
|
//
|
|
// VAO
|
|
//
|
|
mesh.generateVAO();
|
|
|
|
|
|
|
|
|
|
FloatBuffer vertexArrayBufferData = meshData.vertBuffer;
|
|
FloatBuffer normalArrayBufferData = meshData.normalBuffer;
|
|
FloatBuffer textureArrayBufferData = meshData.uvBuffer;
|
|
IntBuffer elementArrayBufferData = meshData.faceBuffer;
|
|
IntBuffer samplerArrayBufferData = meshData.samplerBuffer;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Buffer data to GPU
|
|
//
|
|
int elementCount = meshData.faceElements.length;
|
|
try {
|
|
//actually buffer vertices
|
|
if(vertexArrayBufferData.position() > 0){
|
|
vertexArrayBufferData.flip();
|
|
mesh.bufferVertices(vertexArrayBufferData, 3);
|
|
}
|
|
//actually buffer normals
|
|
if(normalArrayBufferData != null && normalArrayBufferData.position() > 0){
|
|
normalArrayBufferData.flip();
|
|
mesh.bufferNormals(normalArrayBufferData, 3);
|
|
}
|
|
//actually buffer UVs
|
|
if(textureArrayBufferData != null && textureArrayBufferData.position() > 0){
|
|
textureArrayBufferData.flip();
|
|
mesh.bufferTextureCoords(textureArrayBufferData, 2);
|
|
}
|
|
//buffer element indices
|
|
if(elementArrayBufferData.position() > 0){
|
|
elementArrayBufferData.flip();
|
|
mesh.bufferFaces(elementArrayBufferData, elementCount);
|
|
}
|
|
//buffer sampler indices
|
|
if(samplerArrayBufferData != null && samplerArrayBufferData.position() > 0){
|
|
samplerArrayBufferData.flip();
|
|
mesh.bufferCustomIntAttribArray(samplerArrayBufferData, SAMPLER_DATA_SIZE, SAMPLER_SHADER_POSITION);
|
|
}
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
|
|
//bounding sphere logic
|
|
int distance = BlockChunkData.CHUNK_DATA_WIDTH / 2;
|
|
mesh.updateBoundingSphere(
|
|
distance,
|
|
distance,
|
|
distance,
|
|
(float)Math.sqrt(
|
|
distance * distance +
|
|
distance * distance +
|
|
distance * distance
|
|
));
|
|
|
|
|
|
|
|
GL40.glBindVertexArray(0);
|
|
return mesh;
|
|
}
|
|
|
|
/**
|
|
* Generates the model for the block mesh
|
|
* @param chunkData The mesh data
|
|
* @return The model object
|
|
*/
|
|
public static Model generateBlockModel(BlockMeshData meshData){
|
|
Model rVal = new Model();
|
|
Mesh m = BlockMeshgen.generateBlockMesh(meshData);
|
|
|
|
//construct the material for the chunk
|
|
Material groundMat = new Material();
|
|
groundMat.setTexturePointer(Globals.blockTextureAtlas.getSpecular().getTexturePointer());
|
|
groundMat.setNormalTexturePointer(Globals.blockTextureAtlas.getNormal().getTexturePointer());
|
|
m.setMaterial(groundMat);
|
|
|
|
//shader logic
|
|
m.setShader(Globals.blockShader);
|
|
m.setParent(rVal);
|
|
|
|
rVal.getMeshes().add(m);
|
|
rVal.setBoundingSphere(m.getBoundingSphere());
|
|
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* Contains the geom data for a single shape in the block mesh
|
|
*/
|
|
public static class BlockSingleShape implements TriGeomData {
|
|
|
|
/**
|
|
* The verts
|
|
*/
|
|
float[] vertices;
|
|
|
|
/**
|
|
* The faces
|
|
*/
|
|
int[] faceElements;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param vertCount The number of verts
|
|
* @param faceCount The number of faces
|
|
*/
|
|
public BlockSingleShape(int vertCount, int faceCount){
|
|
vertices = new float[vertCount * 3];
|
|
faceElements = new int[faceCount];
|
|
}
|
|
|
|
@Override
|
|
public float[] getVertices() {
|
|
return vertices;
|
|
}
|
|
|
|
@Override
|
|
public int[] getFaceElements() {
|
|
return faceElements;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* The final rasterization data that is emitted
|
|
*/
|
|
public static class BlockMeshData implements TriGeomData, MultiShapeTriGeomData {
|
|
|
|
/**
|
|
* Vertex data in array form
|
|
*/
|
|
float[] vertices;
|
|
|
|
/**
|
|
* Normal data in array form
|
|
*/
|
|
float[] normals;
|
|
|
|
/**
|
|
* Face data in array form
|
|
*/
|
|
int[] faceElements;
|
|
|
|
/**
|
|
* UV data in array form
|
|
*/
|
|
float[] uvs;
|
|
|
|
/**
|
|
* Sampler data in array form
|
|
*/
|
|
int[] samplers;
|
|
|
|
/**
|
|
* Data broken out by each shape
|
|
*/
|
|
List<TriGeomData> shapeData = new LinkedList<TriGeomData>();
|
|
|
|
/**
|
|
* Buffer of vertex data
|
|
*/
|
|
FloatBuffer vertBuffer;
|
|
|
|
/**
|
|
* Buffer of normal data
|
|
*/
|
|
FloatBuffer normalBuffer;
|
|
|
|
/**
|
|
* Buffer of face data
|
|
*/
|
|
IntBuffer faceBuffer;
|
|
|
|
/**
|
|
* Buffer of UV data
|
|
*/
|
|
FloatBuffer uvBuffer;
|
|
|
|
/**
|
|
* Buffer of sampler data
|
|
*/
|
|
IntBuffer samplerBuffer;
|
|
|
|
@Override
|
|
public float[] getVertices() {
|
|
return vertices;
|
|
}
|
|
|
|
@Override
|
|
public int[] getFaceElements() {
|
|
return faceElements;
|
|
}
|
|
|
|
@Override
|
|
public Collection<TriGeomData> getData() {
|
|
return shapeData;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Intermediary structure used during rasterization
|
|
*/
|
|
public static class QuadMesh implements Comparable<QuadMesh> {
|
|
int x;
|
|
int y;
|
|
int z;
|
|
int w;
|
|
int h;
|
|
int type;
|
|
public QuadMesh(){}
|
|
public QuadMesh(int x, int y, int z, int w, int h, int type){
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.w = w;
|
|
this.h = h;
|
|
this.type = type;
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(QuadMesh other) {
|
|
if(this.y != other.y){
|
|
return this.y - other.y;
|
|
}
|
|
if(this.x != other.x){
|
|
return this.x - other.x;
|
|
}
|
|
if(this.w != other.w){
|
|
return other.w - this.w;
|
|
}
|
|
return other.h - this.h;
|
|
}
|
|
}
|
|
|
|
}
|