Пример #1
0
    /*
     *  c02 c12 c22
     *  c01 c11 c21
     *  c00 c10 c20
     */
    public void CubeBlock(int x, int y, int z, TerrainManager terrain, Rect[] texCoord, Color ca, Color cb, Color cc, Color cd)
    {
        Chunk c11 = terrain.ChunkWithBlock(x, y, z);

        Chunk c21 = terrain.ChunkWithBlock(x + 1, y, z);
        Chunk c01 = terrain.ChunkWithBlock(x - 1, y, z);
        Chunk c12 = terrain.ChunkWithBlock(x, y, z + 1);
        Chunk c10 = terrain.ChunkWithBlock(x, y, z - 1);

        Chunk c02 = terrain.ChunkWithBlock(x - 1, y, z + 1);
        Chunk c22 = terrain.ChunkWithBlock(x + 1, y, z + 1);
        Chunk c00 = terrain.ChunkWithBlock(x - 1, y, z - 1);
        Chunk c20 = terrain.ChunkWithBlock(x + 1, y, z - 1);

        int x2 = x & Chunk.SIZE_X_MINUS_ONE;
        int z2 = z & Chunk.SIZE_Z_MINUS_ONE;

        // l is short for light
        // light intencity at a, b, c, d
        float la, lb, lc, ld;

        // sm stands for shadow mask
        float sm;
        Color gi;

        // cell face: x positive
        if (BlockManager.blocks[c21[(x + 1) & Chunk.SIZE_X_MINUS_ONE, y, z2].index].isTransparent)
        {
            la = CalculateLighting(c20[ClipX(x2 + 1), y, ClipZ(z2 - 1)].lightF, c20[ClipX(x2 + 1), y + 1, ClipZ(z2 - 1)].lightF, c21[ClipX(x2 + 1), y + 1, z2].lightF, c21[ClipX(x2 + 1), y, z2].lightF);
            lb = CalculateLighting(c21[ClipX(x2 + 1), y, z2].lightF, c21[ClipX(x2 + 1), y + 1, z2].lightF, c22[ClipX(x2 + 1), y + 1, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y, ClipZ(z2 + 1)].lightF);
            lc = CalculateLighting(c21[ClipX(x2 + 1), y - 1, z2].lightF, c21[ClipX(x2 + 1), y, z2].lightF, c22[ClipX(x2 + 1), y, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y - 1, ClipZ(z2 + 1)].lightF);
            ld = CalculateLighting(c20[ClipX(x2 + 1), y - 1, ClipZ(z2 - 1)].lightF, c20[ClipX(x2 + 1), y, ClipZ(z2 - 1)].lightF, c21[ClipX(x2 + 1), y, z2].lightF, c21[ClipX(x2 + 1), y - 1, z2].lightF);
            ShadedVerticeQuad(new Vector3(x2 + 1, y + 1, z2),
                              new Vector3(x2 + 1, y + 1, z2 + 1),
                              new Vector3(x2 + 1, y, z2 + 1),
                              new Vector3(x2 + 1, y, z2),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Left]);
            sm = shadowMasks[CellFace.Left];
            gi = GIs[CellFace.Left];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
        // cell face: x negative
        if (BlockManager.blocks[c01[(x - 1) & Chunk.SIZE_X_MINUS_ONE, y, z2].index].isTransparent)
        {
            la = CalculateLighting(c01[ClipX(x2 - 1), y, z2].lightF, c01[ClipX(x2 - 1), y + 1, z2].lightF, c02[ClipX(x2 - 1), y + 1, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y, ClipZ(z2 + 1)].lightF);
            lb = CalculateLighting(c00[ClipX(x2 - 1), y, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y + 1, ClipZ(z2 - 1)].lightF, c01[ClipX(x2 - 1), y + 1, z2].lightF, c01[ClipX(x2 - 1), y, z2].lightF);
            lc = CalculateLighting(c00[ClipX(x2 - 1), y - 1, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y, ClipZ(z2 - 1)].lightF, c01[ClipX(x2 - 1), y, z2].lightF, c01[ClipX(x2 - 1), y - 1, z2].lightF);
            ld = CalculateLighting(c01[ClipX(x2 - 1), y - 1, z2].lightF, c01[ClipX(x2 - 1), y, z2].lightF, c02[ClipX(x2 - 1), y, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y - 1, ClipZ(z2 + 1)].lightF);
            ShadedVerticeQuad(new Vector3(x2, y + 1, z2 + 1),
                              new Vector3(x2, y + 1, z2),
                              new Vector3(x2, y, z2),
                              new Vector3(x2, y, z2 + 1),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Right]);
            sm = shadowMasks[CellFace.Right];
            gi = GIs[CellFace.Right];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
        // cell face: z positive
        if (BlockManager.blocks[c12[x2, y, (z + 1) & Chunk.SIZE_Z_MINUS_ONE].index].isTransparent)
        {
            la = CalculateLighting(c22[ClipX(x2 + 1), y + 1, ClipZ(z2 + 1)].lightF, c12[x2, y + 1, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y, ClipZ(z2 + 1)].lightF, c12[x2, y, ClipZ(z2 + 1)].lightF);
            lb = CalculateLighting(c12[x2, y + 1, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y + 1, ClipZ(z2 + 1)].lightF, c12[x2, y, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y, ClipZ(z2 + 1)].lightF);
            lc = CalculateLighting(c12[x2, y, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y, ClipZ(z2 + 1)].lightF, c12[x2, y - 1, ClipZ(z2 + 1)].lightF, c02[ClipX(x2 - 1), y - 1, ClipZ(z2 + 1)].lightF);
            ld = CalculateLighting(c22[ClipX(x2 + 1), y, ClipZ(z2 + 1)].lightF, c12[x2, y, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y - 1, ClipZ(z2 + 1)].lightF, c12[x2, y - 1, ClipZ(z2 + 1)].lightF);
            ShadedVerticeQuad(new Vector3(x2 + 1, y + 1, z2 + 1),
                              new Vector3(x2, y + 1, z2 + 1),
                              new Vector3(x2, y, z2 + 1),
                              new Vector3(x2 + 1, y, z2 + 1),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Front]);
            sm = shadowMasks[CellFace.Front];
            gi = GIs[CellFace.Front];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
        // cell face: z negative
        if (BlockManager.blocks[c10[x2, y, (z - 1) & Chunk.SIZE_Z_MINUS_ONE].index].isTransparent)
        {
            la = CalculateLighting(c10[x2, y + 1, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y + 1, ClipZ(z2 - 1)].lightF, c10[x2, y, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y, ClipZ(z2 - 1)].lightF);
            lb = CalculateLighting(c20[ClipX(x2 + 1), y + 1, ClipZ(z2 - 1)].lightF, c10[x2, y + 1, ClipZ(z2 - 1)].lightF, c20[ClipX(x2 + 1), y, ClipZ(z2 - 1)].lightF, c10[x2, y, ClipZ(z2 - 1)].lightF);
            lc = CalculateLighting(c20[ClipX(x2 + 1), y, ClipZ(z2 - 1)].lightF, c10[x2, y, ClipZ(z2 - 1)].lightF, c20[ClipX(x2 + 1), y - 1, ClipZ(z2 - 1)].lightF, c10[x2, y - 1, ClipZ(z2 - 1)].lightF);
            ld = CalculateLighting(c10[x2, y, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y, ClipZ(z2 - 1)].lightF, c10[x2, y - 1, ClipZ(z2 - 1)].lightF, c00[ClipX(x2 - 1), y - 1, ClipZ(z2 - 1)].lightF);
            ShadedVerticeQuad(new Vector3(x2, y + 1, z2),
                              new Vector3(x2 + 1, y + 1, z2),
                              new Vector3(x2 + 1, y, z2),
                              new Vector3(x2, y, z2),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Back]);
            sm = shadowMasks[CellFace.Back];
            gi = GIs[CellFace.Back];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
        // cell face: y positive
        if (BlockManager.blocks[c11[x2, y + 1, z2].index].isTransparent)
        {
            la = CalculateLighting(c00[ClipX(x2 - 1), y + 1, ClipZ(z2 - 1)].lightF, c01[ClipX(x2 - 1), y + 1, z2].lightF, c11[x2, y + 1, z2].lightF, c10[x2, y + 1, ClipZ(z2 - 1)].lightF);
            lb = CalculateLighting(c01[ClipX(x2 - 1), y + 1, z2].lightF, c02[ClipX(x2 - 1), y + 1, ClipZ(z2 + 1)].lightF, c12[x2, y + 1, ClipZ(z2 + 1)].lightF, c11[x2, y + 1, z2].lightF);
            lc = CalculateLighting(c11[x2, y + 1, z2].lightF, c12[x2, y + 1, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y + 1, ClipZ(z2 + 1)].lightF, c21[ClipX(x2 + 1), y + 1, z2].lightF);
            ld = CalculateLighting(c10[x2, y + 1, ClipZ(z2 - 1)].lightF, c11[x2, y + 1, z2].lightF, c21[ClipX(x2 + 1), y + 1, z2].lightF, c20[ClipX(x2 + 1), y + 1, ClipZ(z2 - 1)].lightF);
            ShadedVerticeQuad(new Vector3(x2, y + 1, z2),
                              new Vector3(x2, y + 1, z2 + 1),
                              new Vector3(x2 + 1, y + 1, z2 + 1),
                              new Vector3(x2 + 1, y + 1, z2),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Up]);
            sm = shadowMasks[CellFace.Up];
            gi = GIs[CellFace.Up];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
        // cell face: y negative
        if (BlockManager.blocks[c11[x2, y - 1, z2].index].isTransparent)
        {
            ld = CalculateLighting(c01[ClipX(x2 - 1), y - 1, z2].lightF, c02[ClipX(x2 - 1), y - 1, ClipZ(z2 + 1)].lightF, c12[x2, y - 1, ClipZ(z2 + 1)].lightF, c11[x2, y - 1, z2].lightF);
            la = CalculateLighting(c00[ClipX(x2 - 1), y - 1, ClipZ(z2 - 1)].lightF, c01[ClipX(x2 - 1), y - 1, z2].lightF, c11[x2, y - 1, z2].lightF, c10[x2, y - 1, ClipZ(z2 - 1)].lightF);
            lb = CalculateLighting(c10[x2, y - 1, ClipZ(z2 - 1)].lightF, c11[x2, y - 1, z2].lightF, c21[ClipX(x2 + 1), y - 1, z2].lightF, c20[ClipX(x2 + 1), y - 1, ClipZ(z2 - 1)].lightF);
            lc = CalculateLighting(c11[x2, y - 1, z2].lightF, c12[x2, y - 1, ClipZ(z2 + 1)].lightF, c22[ClipX(x2 + 1), y - 1, ClipZ(z2 + 1)].lightF, c21[ClipX(x2 + 1), y - 1, z2].lightF);
            ShadedVerticeQuad(new Vector3(x2, y, z2),
                              new Vector3(x2 + 1, y, z2),
                              new Vector3(x2 + 1, y, z2 + 1),
                              new Vector3(x2, y, z2 + 1),
                              la, lb, lc, ld);
            TexQuad(texCoord[CellFace.Down]);
            sm = shadowMasks[CellFace.Down];
            gi = GIs[CellFace.Down];
            ColorQuad(
                (ca * sm + gi) * la,
                (cb * sm + gi) * lb,
                (cc * sm + gi) * lc,
                (cd * sm + gi) * ld);
        }
    }
Пример #2
0
        public void Execute()
        {
            var chunk = terrain.GetChunk(chunkx, chunkz);

            if (chunk.chunkState == Chunk.ChunkState.InvalidLighting)
            {
                int startx = chunkx << Chunk.CHUNK_X_SHIFT;
                int startz = chunkz << Chunk.CHUNK_Z_SHIFT;
                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        bool isUnderground = false;
                        int  y             = 127;
                        while (y > 1)
                        {
                            var cell = chunk[x, y, z];
                            if (isUnderground)
                            {
                                cell.light     = 0;
                                chunk[x, y, z] = cell;
                            }
                            else
                            {
                                cell.light     = LightSettings.GlobalLightLevel;
                                chunk[x, y, z] = cell;
                                lightUpdates.Push(new Vector3Int(x + startx, y, z + startz));
                            }

                            if (!isUnderground && !BlockManager.blocks[chunk[x, y - 1, z].index].isTransparent)
                            {
                                isUnderground = true;
                                var shift = chunk.GetShiftData(x, z);
                                shift.maxHeight = y - 1;
                                chunk.SetShiftData(x, z, shift);
                            }
                            y--;
                        }
                    }
                }
            }

            while (lightUpdates.Count > 0)
            {
                var pos   = lightUpdates.Pop();
                int light = terrain.GetCell(pos).light;

                if (light < 2)
                {
                    continue;
                }

                Chunk c11 = terrain.ChunkWithBlock(pos.x, pos.y, pos.z);
                Chunk c21 = terrain.ChunkWithBlock(pos.x + 1, pos.y, pos.z);
                Chunk c01 = terrain.ChunkWithBlock(pos.x - 1, pos.y, pos.z);
                Chunk c12 = terrain.ChunkWithBlock(pos.x, pos.y, pos.z + 1);
                Chunk c10 = terrain.ChunkWithBlock(pos.x, pos.y, pos.z - 1);
                Chunk c02 = terrain.ChunkWithBlock(pos.x - 1, pos.y, pos.z + 1);
                Chunk c22 = terrain.ChunkWithBlock(pos.x + 1, pos.y, pos.z + 1);
                Chunk c00 = terrain.ChunkWithBlock(pos.x - 1, pos.y, pos.z - 1);
                Chunk c20 = terrain.ChunkWithBlock(pos.x + 1, pos.y, pos.z - 1);

                if (c21 != null)
                {
                    ProcessCell(new Vector3Int(pos.x + 1, pos.y, pos.z), c21, light);
                }

                if (c01 != null)
                {
                    ProcessCell(new Vector3Int(pos.x - 1, pos.y, pos.z), c01, light);
                }

                if (c12 != null)
                {
                    ProcessCell(new Vector3Int(pos.x, pos.y, pos.z + 1), c12, light);
                }

                if (c10 != null)
                {
                    ProcessCell(new Vector3Int(pos.x, pos.y, pos.z - 1), c10, light);
                }

                if (pos.y < 127)
                {
                    ProcessCell(new Vector3Int(pos.x, pos.y + 1, pos.z), c11, light);
                }

                if (pos.y > 1)
                {
                    ProcessCell(new Vector3Int(pos.x, pos.y - 1, pos.z), c11, light);
                }
            }
        }