Example #1
0
    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);
    }
Example #2
0
        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);
    }