Пример #1
0
        private Vector3 m_Position;             // 当前坐标位置

        #endregion ======== 成员变量 ========

        #region ======== 构造函数 ========

        public Chunk(ChunkRenderer renderer, Vector3 position,
                     byte sizeX = DEFAULT_SIZE, byte sizeY = DEFAULT_SIZE, byte sizeZ = DEFAULT_SIZE)
        {
            Renderer  = renderer;
            Position  = position;
            SizeX     = sizeX;
            SizeY     = sizeY;
            SizeZ     = sizeZ;
            TotalSize = sizeX * sizeY * sizeZ;

            Blocks = new BlockGrid(this);
        }
Пример #2
0
        private static int GetBlockContainerSize(this BlockContainer container, int dimension)
        {
            switch (dimension)
            {
            case 0:
                return(container.SizeX());

            case 1:
                return(container.SizeY());

            case 2:
                return(container.SizeZ());

            default:
                throw new ArgumentOutOfRangeException(nameof(dimension));
            }
        }
Пример #3
0
        public static void Generate <T>(BlockContainer blocks, Func <int[], int[], int[], int, bool, VoxelFace, bool, IEnumerable <T> > createQuad,
                                        out T[] vertices, out int[] indices, bool cw = false) where T : IVertexType
        {
            try
            {
                var verts = new List <T>();
                var inds  = new List <int>();

                int[] size = { blocks.SizeX(), blocks.SizeY(), blocks.SizeZ() };
                // loop over the three directions; x -> 0, y -> 1, z -> 2
                for (var direction = 0; direction < 3; direction++)
                {
                    // u and v are the other two directions
                    var u = (direction + 1) % 3;
                    var v = (direction + 2) % 3;

                    // pos holds the current position in the grid
                    var pos = new int[3];
                    // 1 for the current direction and 0 for others, unit vector of the axis we're handling
                    var nextPos = new int[3];
                    // contains the rendering data for each face in the current layers, a layer being a slice of the grid; Note that this is linearized
                    var backFaces  = new VoxelFace[blocks.GetBlockContainerSize(u) * blocks.GetBlockContainerSize(v)];
                    var frontFaces = new VoxelFace[blocks.GetBlockContainerSize(u) * blocks.GetBlockContainerSize(v)];

                    nextPos[direction] = 1;

                    // outer loop goes through all layers
                    // we start at -1 because we check for faces *between* blocks and have to get the outer faces too
                    for (pos[direction] = -1; pos[direction] < blocks.GetBlockContainerSize(direction); pos[direction]++)
                    {
                        var noBack  = true;
                        var noFront = true;
                        // Get all faces that need to be rendered in the current layer (front and back seperately)
                        for (pos[v] = 0; pos[v] < size[v]; pos[v]++)
                        {
                            for (pos[u] = 0; pos[u] < size[u]; pos[u]++)
                            {
                                // if this block is visible and the one behind it is not we need to render the backface of the current block
                                // if this one is not visible but the one behind it is, we need to render the frontface of the 'behind' block
                                var index   = pos[v] * size[u] + pos[u];
                                var current = pos[direction] >= 0 && !blocks[(byte)pos[0], (byte)pos[1], (byte)pos[2]].IsEmpty();
                                var behind  = pos[direction] + 1 < blocks.GetBlockContainerSize(direction) &&
                                              !blocks[(byte)(pos[0] + nextPos[0]), (byte)(pos[1] + nextPos[1]), (byte)(pos[2] + nextPos[2])].IsEmpty();

                                if (current && !behind)
                                {
                                    backFaces[index] = new VoxelFace(blocks[(byte)pos[0], (byte)pos[1], (byte)pos[2]]);
                                    noBack           = false;
                                }
                                else if (!current && behind)
                                {
                                    frontFaces[index] = new VoxelFace(blocks[(byte)(pos[0] + nextPos[0]), (byte)(pos[1] + nextPos[1]), (byte)(pos[2] + nextPos[2])]);
                                    noFront           = false;
                                }
                            }
                        }

                        // Then process both layers to build quads
                        if (!noFront)
                        {
                            ProcessLayer(frontFaces, createQuad, verts, inds, pos[direction] + 1, direction, size, cw, false);
                        }
                        if (!noBack)
                        {
                            ProcessLayer(backFaces, createQuad, verts, inds, pos[direction] + 1, direction, size, !cw, true);
                        }
                    }
                }

                vertices = verts.ToArray();
                indices  = inds.ToArray();
            }
            catch (Exception e)
            {
                throw new Exception("Generate GreedyMesh failed!\r\n " + e.ToString());
            }
        }