Exemple #1
0
    public unsafe void SaveChunk(BlockTerrain.Chunk chunk)
    {
        if (!chunk.isEdited)
        {
            return;
        }
        lock (locker)
        {
            Point2 p = new Point2(chunk.chunkx, chunk.chunky);
            long   value;
            if (chunkOffsets.TryGetValue(p, out value))
            {
                stream.Seek(value, SeekOrigin.Begin);
                WriteChunkHeader(stream, chunk.chunkx, chunk.chunky);

                fixed(byte *bptr = &buffer[0])
                {
                    int *iptr = (int *)bptr;

                    for (int x = 0; x < 16; x++)
                    {
                        for (int y = 0; y < 16; y++)
                        {
                            int index = BlockTerrain.GetCellIndex(15 - x, 0, y);
                            int h     = 0;
                            while (h < 128)
                            {
                                *iptr = chunk.GetCellValue(index);
                                iptr++;
                                h++;
                                index++;
                            }
                        }
                    }
                }

                stream.Write(buffer, 0, 131072);

                fixed(byte *bptr = &buffer[0])
                {
                    int *iptr = (int *)bptr;

                    for (int x = 0; x < 16; x++)
                    {
                        int index = BlockTerrain.GetShiftIndex(15 - x, 0);
                        int h     = 0;
                        while (h < 16)
                        {
                            *iptr = chunk.GetShiftValue(index);
                            iptr++;
                            h++;
                            index++;
                        }
                    }
                }

                stream.Write(buffer, 0, 1024);
            }
        }
    }
Exemple #2
0
    public void GenerateNormalBlocks(BlockTerrain.Chunk chunk)
    {
        bool[]         isTransparent = BlocksData.IsTransparent;
        INormalBlock[] normalBlocks  = BlocksData.NormalBlocks;

        for (int x = 0; x < 16; x++)
        {
            for (int z = 0; z < 16; z++)
            {
                for (int y = 0; y < 128; y++)
                {
                    int value   = chunk.GetCellValue(x, y, z);
                    int content = BlockTerrain.GetContent(value);
                    if (isTransparent[content])
                    {
                        normalBlocks[content].GenerateTerrain(x, y, z, value, chunk, this);
                    }
                }
            }
        }
    }
Exemple #3
0
    public void GenerateCubeBlocks(BlockTerrain.Chunk chunk)
    {
        bool[] isTransparent              = BlocksData.IsTransparent;
        IStandardCubeBlock[] cubeBlocks   = BlocksData.StandardCubeBlocks;
        INormalBlock[]       normalBlocks = BlocksData.NormalBlocks;

        for (int x = 0; x < 16; x++)
        {
            for (int z = 0; z < 16; z++)
            {
                for (int y = 0; y < 128; y++)
                {
                    int value   = chunk.GetCellValue(x, y, z);
                    int content = BlockTerrain.GetContent(value);
                    if (isTransparent[content])
                    {
                        normalBlocks[content].GenerateTerrain(x, y, z, value, chunk, this);
                    }
                    else
                    {
                        Vector3 v000 = new Vector3(x, y, z);
                        Vector3 v001 = new Vector3(x, y, z + 1.0f);
                        Vector3 v010 = new Vector3(x, y + 1.0f, z);
                        Vector3 v011 = new Vector3(x, y + 1.0f, z + 1.0f);
                        Vector3 v100 = new Vector3(x + 1.0f, y, z);
                        Vector3 v101 = new Vector3(x + 1.0f, y, z + 1.0f);
                        Vector3 v110 = new Vector3(x + 1.0f, y + 1.0f, z);
                        Vector3 v111 = new Vector3(x + 1.0f, y + 1.0f, z + 1.0f);

                        var cellFace = new CellFace();
                        var block    = cubeBlocks[content];
                        int neighbor = chunk.GetCellContent(x - 1, y, z);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.BACK, chunk, ref cellFace);
                            Terrain.NormalQuad(v000, v001, v011, v010, cellFace.TextureSlot, cellFace.Color);
                        }

                        neighbor = chunk.GetCellContent(x, y - 1, z);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.BOTTOM, chunk, ref cellFace);
                            Terrain.NormalQuad(v001, v000, v100, v101, cellFace.TextureSlot, cellFace.Color);
                        }

                        neighbor = chunk.GetCellContent(x, y, z - 1);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.LEFT, chunk, ref cellFace);
                            Terrain.NormalQuad(v100, v000, v010, v110, cellFace.TextureSlot, cellFace.Color);
                        }

                        neighbor = chunk.GetCellContent(x + 1, y, z);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.FRONT, chunk, ref cellFace);
                            Terrain.NormalQuad(v101, v100, v110, v111, cellFace.TextureSlot, cellFace.Color);
                        }

                        neighbor = chunk.GetCellContent(x, y + 1, z);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.TOP, chunk, ref cellFace);
                            Terrain.NormalQuad(v011, v111, v110, v010, cellFace.TextureSlot, cellFace.Color);
                        }

                        neighbor = chunk.GetCellContent(x, y, z + 1);
                        if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor])
                        {
                            block.GenerateTerrain(x, y, z, value, CellFace.RIGHT, chunk, ref cellFace);
                            Terrain.NormalQuad(v001, v101, v111, v011, cellFace.TextureSlot, cellFace.Color);
                        }
                    }
                }
            }
        }
    }
Exemple #4
0
    public void GenerateChunkMesh(BlockTerrain.Chunk chunk)
    {
        bool[] isTrans = BlocksData.IsTransparent;
        IStandardCubeBlock[] blocks = BlocksData.StandardCubeBlocks;

        CellFace[] mask;
        int        u, v, n, w, h, j, i, l, k;

        int[] off;
        int[] x;
        int[] dim = new int[] { 16, 128, 16 };

        for (int d = 0; d < 3; d++)
        {
            off = new int[] { 0, 0, 0 };
            x   = new int[] { 0, 0, 0 };
            u   = (d + 1) % 3;
            v   = (d + 2) % 3;

            off[d] = 1;

            //face = d;

            mask = new CellFace[dim[u] * dim[v]];
            for (x[d] = -1; x[d] < dim[d];)
            {
                //Debug.LogFormat("x[d]: {0}", x[d]);
                for (n = 0; n < mask.Length; n++)
                {
                    mask[n].TextureSlot = -1;
                }

                n = 0;
                for (x[v] = 0; x[v] < dim[v]; x[v]++)
                {
                    for (x[u] = 0; x[u] < dim[u]; x[u]++)
                    {
                        int va = chunk.GetCellValue(x[0], x[1], x[2]);
                        int vb = chunk.GetCellValue(x[0] + off[0], x[1] + off[1], x[2] + off[2]);
                        if (va == BlockTerrain.NULL_BLOCK_VALUE || vb == BlockTerrain.NULL_BLOCK_VALUE)
                        {
                            break;
                        }
                        int ca = BlockTerrain.GetContent(va);
                        int cb = BlockTerrain.GetContent(vb);
                        //Debug.LogFormat("{0} and {1}: {2}, {3}", new Point3(x[0], x[1], x[2]), new Point3(x[0] + off[0], x[1] + off[1], x[2] + off[2]), a.Name, b.Name);
                        if (isTrans[ca])
                        {
                            if (!isTrans[cb] && (((x[0] + off[0])) & 16) == 0)
                            {
                                mask[n].IsOpposite = true;
                                blocks[cb].GenerateTerrain(x[0] + off[0], x[1] + off[1], x[2] + off[2], vb, CellFace.opposite[d], chunk, ref mask[n]);
                            }
                        }
                        else
                        {
                            if (isTrans[cb])
                            {
                                mask[n].IsOpposite = false;
                                blocks[ca].GenerateTerrain(x[0], x[1], x[2], va, d, chunk, ref mask[n]);
                            }
                        }
                        n++;
                    }
                }

                ++x[d];
                n = 0;
                for (j = 0; j < dim[v]; j++)
                {
                    for (i = 0; i < dim[u];)
                    {
                        if (mask[n].TextureSlot != -1)
                        {
                            for (w = 1; i + w < dim[u] && mask[w + n] == mask[n]; w++)
                            {
                            }
                            for (h = 1; h + j < dim[v]; h++)
                            {
                                for (k = 0; k < w; k++)
                                {
                                    if (mask[n + k + h * dim[u]] != mask[n])
                                    {
                                        goto Done;
                                    }
                                }
                            }
Done:
                            //Debug.LogFormat("quard: {0}, {1}, {2}, {3}; {4}", j, i, h, w, x[d]);

                            x[u] = i;
                            x[v] = j;
                            int[] du = new int[] { 0, 0, 0 };
                            int[] dv = new int[] { 0, 0, 0 };
                            du[u] = w;
                            dv[v] = h;

                            int textureSlot = mask[n].TextureSlot;
                            if (!mask[n].IsOpposite)
                            {
                                Terrain.Quad(
                                    new Vector3(x[0], x[1], x[2]),
                                    new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]),
                                    new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]),
                                    new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]),
                                    textureSlot,
                                    mask[n].Color
                                    );
                            }
                            else
                            {
                                Terrain.Quad(
                                    new Vector3(x[0], x[1], x[2]),
                                    new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]),
                                    new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]),
                                    new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]),
                                    textureSlot,
                                    mask[n].Color
                                    );
                            }

                            for (l = 0; l < h; l++)
                            {
                                for (k = 0; k < w; k++)
                                {
                                    mask[n + k + l * dim[u]].TextureSlot = -1;
                                }
                            }
                            i += w;
                            n += w;
                        }
                        else
                        {
                            i++;
                            n++;
                        }
                    }
                }
            }
        }
    }
Exemple #5
0
    public void GenerateFluidTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, GreedyTerrainMesh terrainMesh, Color topColor, Color sideColor)
    {
        float height1, height2, height3, height4;

        int data = BlockTerrain.GetData(value);

        if (GetIsTop(data))
        {
            int   cellValueFast  = chunk.GetCellValue(x - 1, y, z - 1);
            int   cellValueFast2 = chunk.GetCellValue(x, y, z - 1);
            int   cellValueFast3 = chunk.GetCellValue(x + 1, y, z - 1);
            int   cellValueFast4 = chunk.GetCellValue(x - 1, y, z);
            int   cellValueFast5 = chunk.GetCellValue(x + 1, y, z);
            int   cellValueFast6 = chunk.GetCellValue(x - 1, y, z + 1);
            int   cellValueFast7 = chunk.GetCellValue(x, y, z + 1);
            int   cellValueFast8 = chunk.GetCellValue(x + 1, y, z + 1);
            float h           = CalculateNeighborHeight(cellValueFast);
            float num         = CalculateNeighborHeight(cellValueFast2);
            float h2          = CalculateNeighborHeight(cellValueFast3);
            float num2        = CalculateNeighborHeight(cellValueFast4);
            float num3        = CalculateNeighborHeight(cellValueFast5);
            float h3          = CalculateNeighborHeight(cellValueFast6);
            float num4        = CalculateNeighborHeight(cellValueFast7);
            float h4          = CalculateNeighborHeight(cellValueFast8);
            float levelHeight = GetLevelHeight(GetLevel(data));
            height1 = CalculateFluidVertexHeight(h, num, num2, levelHeight);
            height2 = CalculateFluidVertexHeight(num, h2, levelHeight, num3);
            height3 = CalculateFluidVertexHeight(levelHeight, num3, num4, h4);
            height4 = CalculateFluidVertexHeight(num2, levelHeight, h3, num4);
        }
        else
        {
            height1 = 1f;
            height2 = 1f;
            height3 = 1f;
            height4 = 1f;
        }

        Vector3 v000 = new Vector3(x, y, z);
        Vector3 v001 = new Vector3(x, y, z + 1f);
        Vector3 v010 = new Vector3(x, y + height1, z);
        Vector3 v011 = new Vector3(x, y + height4, z + 1f);
        Vector3 v100 = new Vector3(x + 1.0f, y, z);
        Vector3 v101 = new Vector3(x + 1.0f, y, z + 1f);
        Vector3 v110 = new Vector3(x + 1.0f, y + height2, z);
        Vector3 v111 = new Vector3(x + 1.0f, y + height3, z + 1f);

        int v = chunk.GetCellValue(x - 1, y, z);

        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v001, v011, v010, v000, TextureSlot, sideColor);
        }

        v = chunk.GetCellValue(x, y - 1, z);
        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v000, v100, v101, v001, TextureSlot, sideColor);
        }

        v = chunk.GetCellValue(x, y, z - 1);
        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v000, v010, v110, v100, TextureSlot, sideColor);
        }

        v = chunk.GetCellValue(x + 1, y, z);
        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v100, v110, v111, v101, TextureSlot, sideColor);
        }

        v = chunk.GetCellValue(x, y + 1, z);
        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v111, v110, v010, v011, TextureSlot, topColor);
        }

        v = chunk.GetCellValue(x, y, z + 1);
        if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index)
        {
            terrainMesh.NormalQuad(v101, v111, v011, v001, TextureSlot, sideColor);
        }
    }