private static bool BuildMagicaMesh( World world, string meshLocation, ushort blockType, Vector3 meshOffset, float meshScale, out int[] trisOut, out Vector3[] vertsOut, out Color32[] colorsOut ) { trisOut = null; vertsOut = null; colorsOut = null; FileStream fs = null; try { string fullPath = Directories.ResourcesFolder + "/" + meshLocation; fs = new FileStream(fullPath, FileMode.Open); using (BinaryReader br = new BinaryReader(fs)) { // Load the magica vox model var data = MagicaVox.FromMagica(br); if (data == null) { return(false); } MagicaVox.MagicaVoxelChunk mvchunk = data.chunk; // Determine the biggest side int size = mvchunk.sizeX; if (mvchunk.sizeY > size) { size = mvchunk.sizeY; } if (mvchunk.sizeZ > size) { size = mvchunk.sizeZ; } // Determine the necessary size size += Env.ChunkPadding2; int pow = 1 + (int)Math.Log(size, 2); size = (1 << pow) - Env.ChunkPadding2; // Create a temporary chunk object Chunk chunk = new Chunk(size); chunk.Init(world, Vector3Int.zero); ChunkBlocks blocks = chunk.Blocks; // Convert the model's data to our internal system for (int y = 0; y < mvchunk.sizeY; y++) { for (int z = 0; z < mvchunk.sizeZ; z++) { for (int x = 0; x < mvchunk.sizeX; x++) { int index = Helpers.GetChunkIndex1DFrom3D(x, y, z, pow); int i = Helpers.GetIndex1DFrom3D(x, y, z, mvchunk.sizeX, mvchunk.sizeZ); ushort blockIndex = data.chunk.data[i]; Block colorBlock = world.blockProvider.BlockTypes[blockIndex]; blocks.SetInner( index, data.chunk.data[i] == 0 ? BlockProvider.AirBlock : new BlockData(blockIndex, colorBlock.Solid) ); } } } Block block = world.blockProvider.BlockTypes[blockType]; block.Custom = false; { // Build the mesh CubeMeshBuilder meshBuilder = new CubeMeshBuilder(meshScale, size) { SideMask = 0, Palette = data.palette }; meshBuilder.Build(chunk, out chunk.MinBounds, out chunk.MaxBounds); var batcher = chunk.RenderGeometryHandler.Batcher; if (batcher.Buffers != null && batcher.Buffers.Length > 0) { List <Vector3> tmpVertices = new List <Vector3>(); List <Color32> tmpColors = new List <Color32>(); List <int> tmpTriangles = new List <int>(); // Only consider the default material for now var buff = batcher.Buffers[0]; for (int i = 0; i < buff.Count; i++) { int sx = tmpVertices.Count; tmpVertices.AddRange(buff[i].Vertices); if (meshOffset != Vector3.zero) { for (int j = sx; j < buff[i].Vertices.Count; j++) { tmpVertices[j] += meshOffset; } } tmpColors.AddRange(buff[i].Colors); tmpTriangles.AddRange(buff[i].Triangles); } // Convert lists to arrays vertsOut = tmpVertices.ToArray(); colorsOut = tmpColors.ToArray(); trisOut = tmpTriangles.ToArray(); } } block.Custom = true; fs = null; } } catch (Exception ex) { Debug.LogException(ex); return(false); } finally { if (fs != null) { fs.Dispose(); } } return(true); }
private void Update() { if (!dirty) { return; } if (tile.coords == null || tile.coords.Length == 0) { return; } var meshBuilder = new CubeMeshBuilder(); var bounds = BoundsHelper.CalcBounds(tile.coords); var size = bounds.size; for (var i = 0; i < size.x; i++) { for (var j = 0; j < size.y; j++) { for (var k = 0; k < size.z; k++) { var c = bounds.position + new Vector3Int(i, j, k); var isGround = ground.IsGround(c); if (!isGround) { continue; } var dirs = new[] { Vector3Int.left, Vector3Int.right, new Vector3Int(0, 0, 1), new Vector3Int(0, 0, -1), Vector3Int.up }; foreach (var dir in dirs) { var next = c + dir; if (ground.IsGround(next)) { continue; } var axis = dir.x != 0 ? Axis.X : dir.y != 0 ? Axis.Y : Axis.Z; var front = axis == Axis.X ? dir.x > 0 : axis == Axis.Y ? dir.y > 0 : dir.z > 0; meshBuilder.AddQuad(axis, front, c, 0); } } } } var mesh = meshBuilder.Build(); meshFilter.mesh = mesh; dirty = false; }
private bool SetUpMesh(World world, string meshLocation, Vector3 positionOffset) { FileStream fs = null; try { string fullPath = Directories.ResourcesFolder + "/" + meshLocation + ".vox"; fs = new FileStream(fullPath, FileMode.Open); using (BinaryReader br = new BinaryReader(fs)) { // Load the magica vox model var data = MagicaVox.FromMagica(br); if (data == null) { return(false); } MagicaVox.MagicaVoxelChunk mvchunk = data.chunk; // Determine the biggest side int size = mvchunk.sizeX; if (mvchunk.sizeY > size) { size = mvchunk.sizeY; } if (mvchunk.sizeZ > size) { size = mvchunk.sizeZ; } // Determine the necessary size size += Env.ChunkPadding2; int pow = 1 + (int)Math.Log(size, 2); size = (1 << pow) - Env.ChunkPadding2; // Create a temporary chunk object Chunk chunk = new Chunk(size); chunk.Init(world, Vector3Int.zero); ChunkBlocks blocks = chunk.blocks; // Convert the model's data to our internal system for (int y = 0; y < mvchunk.sizeY; y++) { for (int z = 0; z < mvchunk.sizeZ; z++) { for (int x = 0; x < mvchunk.sizeX; x++) { int index = Helpers.GetChunkIndex1DFrom3D(x, y, z, pow); int i = Helpers.GetIndex1DFrom3D(x, y, z, mvchunk.sizeX, mvchunk.sizeZ); // TODO: Implement support for colors blocks.SetInner( index, data.chunk.data[i] == 0 ? BlockProvider.AirBlock : new BlockData(type, true)//new BlockData((ushort)i, true) ); } } } Block block = world.blockProvider.BlockTypes[type]; block.Custom = false; m_geomBuffer = new RenderGeometryBuffer() { Colors = new List <Color32>() }; { // Build the mesh CubeMeshBuilder meshBuilder = new CubeMeshBuilder(m_scale, size) { SideMask = 0, Type = type, Palette = data.palette }; meshBuilder.Build(chunk, out chunk.minBounds, out chunk.maxBounds); // Convert lists to arrays verts = m_geomBuffer.Vertices.ToArray(); colors = m_geomBuffer.Colors.ToArray(); tris = m_geomBuffer.Triangles.ToArray(); } m_geomBuffer = null; block.Custom = true; fs = null; } } catch (Exception ex) { Debug.LogException(ex); return(false); } finally { if (fs != null) { fs.Dispose(); } } return(true); }