Пример #1
0
        private void SpreadSkyLight(IBoundedLitBlockCollection[,] chunkMap, int[,] heightMap, int lx, int ly, int lz)
        {
            BlockInfo primary      = _blockset.GetInfo(lx, ly, lz);
            int       primaryLight = _blockset.GetSkyLight(lx, ly, lz);
            int       priLum       = Math.Max(BlockInfo.MAX_LUMINANCE - primary.Opacity, 0);

            if (primaryLight < priLum)
            {
                _blockset.SetSkyLight(lx, ly, lz, priLum);
            }

            if (primaryLight > BlockInfo.MAX_LUMINANCE - 1 || !primary.TransmitsLight)
            {
                return;
            }

            Queue <LightRecord> spread = new Queue <LightRecord>();

            int xdim = _xdim;
            int ydim = _ydim;
            int zdim = _zdim;

            int lxi = lx + xdim;
            int lzi = lz + zdim;

            int strength = (primary.Opacity > 0) ? priLum : priLum - 1;

            if (ly > 0)
            {
                if (heightMap[lxi, lzi] > ly - 1)
                {
                    spread.Enqueue(new LightRecord(lx, ly - 1, lz, strength));
                }
                else
                {
                    spread.Enqueue(new LightRecord(lx, ly - 1, lz, priLum));
                }
            }

            if (ly < ydim - 1)
            {
                if (heightMap[lxi, lzi] > ly + 1)
                {
                    spread.Enqueue(new LightRecord(lx, ly + 1, lz, strength));
                }
            }

            if (heightMap[lxi - 1, lzi] > ly)
            {
                spread.Enqueue(new LightRecord(lx - 1, ly, lz, strength));
            }
            if (heightMap[lxi + 1, lzi] > ly)
            {
                spread.Enqueue(new LightRecord(lx + 1, ly, lz, strength));
            }
            if (heightMap[lxi, lzi - 1] > ly)
            {
                spread.Enqueue(new LightRecord(lx, ly, lz - 1, strength));
            }
            if (heightMap[lxi, lzi + 1] > ly)
            {
                spread.Enqueue(new LightRecord(lx, ly, lz + 1, strength));
            }

            while (spread.Count > 0)
            {
                LightRecord rec = spread.Dequeue();

                int xi = rec.x + xdim;
                int zi = rec.z + zdim;

                IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim];
                if (cc == null)
                {
                    continue;
                }

                int x = xi % xdim;
                int y = rec.y;
                int z = zi % zdim;

                BlockInfo info  = cc.GetInfo(x, y, z);
                int       light = cc.GetSkyLight(x, y, z);

                int dimStr = Math.Max(rec.str - info.Opacity, 0);

                if (dimStr > light)
                {
                    cc.SetSkyLight(x, y, z, dimStr);

                    if (info.TransmitsLight)
                    {
                        strength = (info.Opacity > 0) ? dimStr : dimStr - 1;

                        if (rec.y > 0)
                        {
                            if (heightMap[xi, zi] > rec.y - 1)
                            {
                                spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, strength));
                            }
                            else
                            {
                                spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, dimStr));
                            }
                        }

                        if (rec.y < ydim - 1)
                        {
                            if (heightMap[xi, zi] > rec.y + 1)
                            {
                                spread.Enqueue(new LightRecord(rec.x, rec.y + 1, rec.z, strength));
                            }
                        }

                        if (heightMap[xi - 1, zi] > rec.y)
                        {
                            spread.Enqueue(new LightRecord(rec.x - 1, rec.y, rec.z, strength));
                        }
                        if (heightMap[xi + 1, zi] > rec.y)
                        {
                            spread.Enqueue(new LightRecord(rec.x + 1, rec.y, rec.z, strength));
                        }
                        if (heightMap[xi, zi - 1] > rec.y)
                        {
                            spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z - 1, strength));
                        }
                        if (heightMap[xi, zi + 1] > rec.y)
                        {
                            spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z + 1, strength));
                        }
                    }
                }
            }
        }
Пример #2
0
        private void SpreadBlockLight(IBoundedLitBlockCollection[,] chunkMap, int lx, int ly, int lz)
        {
            BlockInfo primary      = _blockset.GetInfo(lx, ly, lz);
            int       primaryLight = _blockset.GetBlockLight(lx, ly, lz);
            int       priLum       = Math.Max(primary.Luminance - primary.Opacity, 0);

            if (primaryLight < priLum)
            {
                _blockset.SetBlockLight(lx, ly, lz, priLum);
            }

            if (primaryLight > primary.Luminance - 1 && !primary.TransmitsLight)
            {
                return;
            }

            int xdim = _xdim;
            int ydim = _ydim;
            int zdim = _zdim;

            Queue <LightRecord> spread = new Queue <LightRecord>();

            if (ly > 0)
            {
                spread.Enqueue(new LightRecord(lx, ly - 1, lz, primary.Luminance - 1));
            }
            if (ly < ydim - 1)
            {
                spread.Enqueue(new LightRecord(lx, ly + 1, lz, primary.Luminance - 1));
            }

            spread.Enqueue(new LightRecord(lx - 1, ly, lz, primary.Luminance - 1));
            spread.Enqueue(new LightRecord(lx + 1, ly, lz, primary.Luminance - 1));
            spread.Enqueue(new LightRecord(lx, ly, lz - 1, primary.Luminance - 1));
            spread.Enqueue(new LightRecord(lx, ly, lz + 1, primary.Luminance - 1));

            while (spread.Count > 0)
            {
                LightRecord rec = spread.Dequeue();

                int xi = rec.x + xdim;
                int zi = rec.z + zdim;

                IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim];
                if (cc == null)
                {
                    continue;
                }

                int x = xi % xdim;
                int y = rec.y;
                int z = zi % zdim;

                BlockInfo info  = cc.GetInfo(x, y, z);
                int       light = cc.GetBlockLight(x, y, z);

                int dimStr = Math.Max(rec.str - info.Opacity, 0);

                if (dimStr > light)
                {
                    cc.SetBlockLight(x, y, z, dimStr);

                    if (info.TransmitsLight)
                    {
                        int strength = (info.Opacity > 0) ? dimStr : dimStr - 1;

                        if (rec.y > 0)
                        {
                            spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, strength));
                        }
                        if (rec.y < ydim - 1)
                        {
                            spread.Enqueue(new LightRecord(rec.x, rec.y + 1, rec.z, strength));
                        }

                        spread.Enqueue(new LightRecord(rec.x - 1, rec.y, rec.z, strength));
                        spread.Enqueue(new LightRecord(rec.x + 1, rec.y, rec.z, strength));
                        spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z - 1, strength));
                        spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z + 1, strength));
                    }
                }
            }
        }