// Creates a cube using an array. public static ArrayMesh Render(SubChunk chunk) { var arrayMesh = new ArrayMesh(); // Array containing other arrays. // OpenGL array buffer. var arrays = new Godot.Collections.Array(); arrays.Resize((int)ArrayMesh.ArrayType.Max); // Reset data. Vertices = new Vector3[9999]; Normals = new Vector3[9999]; Colors = new Color[9999]; vertexIdx = 0; if (chunk.isEmpty()) { return(null); } // If sub-chunk is completely surrounded. dont render. if (!chunk.RenderBottom && !chunk.RenderTop && !chunk.RenderLeft && !chunk.RenderRight && !chunk.RenderFront && !chunk.RenderBack) { return(null); } // 16 x 16 x 16 = 4096 blocks. for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { // No cube if not active. if (chunk.GetBlock(x, y, z) == -1) { continue; } // Create cube. CreateBlock(new Vector3(x, y, z), chunk); } } } System.Array.Resize(ref Vertices, vertexIdx); System.Array.Resize(ref Normals, vertexIdx); System.Array.Resize(ref Colors, vertexIdx); // Fill the array with the others arrays. arrays[0] = Vertices; arrays[1] = Normals; arrays[3] = Colors; if (Vertices.Length == 0) { return(null); } // Create surface from arrays. arrayMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); ApplyMaterial(arrayMesh); // Done. return(arrayMesh); }
private static void CreateBlock(Vector3 position, SubChunk chunk) { // subChunk index in the Chunk itself. [0, 15] int subChunkId = chunk.SubChunkId; // Position as integer. int x = (int)position.x; int y = (int)position.y; int z = (int)position.z; // False if there is a block next to those faces. bool left, right, top, bottom, front, back; top = y != 15 ? chunk.GetBlock(x, y + 1, z) == -1 : true; bottom = y != 0 ? chunk.GetBlock(x, y - 1, z) == -1 : true; left = x != 0 ? chunk.GetBlock(x - 1, y, z) == -1 : true; right = x != 15 ? chunk.GetBlock(x + 1, y, z) == -1 : true; front = z != 15 ? chunk.GetBlock(x, y, z + 1) == -1 : true; back = z != 0 ? chunk.GetBlock(x, y, z - 1) == -1 : true; // If the block is completly surrounded(not seen). if (left && right && top && bottom && front && back) { return; } // Should draw faces? except chunk borders. bool leftChunk = true; bool rightChunk = true; bool backChunk = true; bool frontChunk = true; if (x == 0) { leftChunk = chunk.Chunk.ChunkLeft.GetSubChunk(subChunkId).GetBlock(15, y, z) == -1; } if (x == 15) { rightChunk = chunk.Chunk.ChunkRight.GetSubChunk(subChunkId).GetBlock(0, y, z) == -1; } if (z == 0) { backChunk = chunk.Chunk.ChunkBack.GetSubChunk(subChunkId).GetBlock(x, y, 15) == -1; } if (z == 15) { frontChunk = chunk.Chunk.ChunkFront.GetSubChunk(subChunkId).GetBlock(x, y, 0) == -1; } // Check if there is a block in the above subchunk. // Dont check if the subchunk is the bottom or top one. bool topChunk = true; bool bottomChunk = true; if (subChunkId != 15) { SubChunk topSubChunk = chunk.Chunk.GetSubChunk(subChunkId + 1); if (topSubChunk.isFull()) { topChunk = true; } else { topChunk = topSubChunk.GetBlock(x, 0, z) == -1; } } if (subChunkId != 0) { SubChunk botSubChunk = chunk.Chunk.GetSubChunk(subChunkId - 1); if (botSubChunk.isFull()) { bottomChunk = false; } else { bottomChunk = botSubChunk.GetBlock(x, 15, z) == -1; } } // False if should not render chunk border faces. bool topBorder = y == 15 ? chunk.RenderTop && topChunk : top; bool bottomBorder = y == 0 ? chunk.RenderBottom && bottomChunk : bottom; bool leftBorder = x == 0 ? chunk.RenderLeft && leftChunk : left; bool rightBorder = x == 15 ? chunk.RenderRight && rightChunk : right; bool frontBorder = z == 15 ? chunk.RenderFront && frontChunk : front; bool backBorder = z == 0 ? chunk.RenderBack && backChunk : back; // Display the chunk in green if chunk is surrounded. int gx = (int)(chunk.Chunk.Position.x * 16) + x; int gz = (int)(chunk.Chunk.Position.y * 16) + z; CurrentColor = BlockPalette.GetColor((BLOCK_TYPE)chunk.GetBlock(x, y, z), gx, gz); // Represent each faces of a cube and if it should place // each faces. Placed in the same order in CUBE_FACES enum. bool[] lutFaces = { topBorder, bottomBorder, leftBorder, rightBorder, frontBorder, backBorder }; for (int i = 0; i < 6; i++) { if (lutFaces[i] == true) { CreateFace(i, position); } } }