示例#1
0
        private int NeighborLight(IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z)
        {
            if (y < 0 || y >= _ydim)
            {
                return(0);
            }

            int xdim = _xdim;
            int zdim = _zdim;

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

            IBoundedLitBlockCollection src = chunkMap[xi / xdim, zi / zdim];

            if (src == null)
            {
                return(0);
            }

            x = xi % xdim;
            z = zi % zdim;

            BlockInfo info = src.GetInfo(x, y, z);

            if (!info.TransmitsLight)
            {
                return(info.Luminance);
            }

            int light = src.GetBlockLight(x, y, z);

            return(Math.Max((info.Opacity > 0) ? light : light - 1, info.Luminance - 1));
        }
示例#2
0
        private void TestBlockLight(IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2)
        {
            int light1 = _blockset.GetBlockLight(x1, y1, z1);
            int light2 = chunk.GetBlockLight(x2, y2, z2);
            int lum1   = _blockset.GetInfo(x1, y1, z1).Luminance;
            int lum2   = chunk.GetInfo(x2, y2, z2).Luminance;

            int v1 = Math.Max(light1, lum1);
            int v2 = Math.Max(light2, lum2);

            if (Math.Abs(v1 - v2) > 1)
            {
                QueueRelight(new BlockKey(x1, y1, z1));
            }
        }
示例#3
0
        private void TestBlockLight(IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2)
        {
            int light1 = _blockset.GetBlockLight(x1, y1, z1);
            int light2 = chunk.GetBlockLight(x2, y2, z2);
            int lum1 = _blockset.GetInfo(x1, y1, z1).Luminance;
            int lum2 = chunk.GetInfo(x2, y2, z2).Luminance;

            int v1 = Math.Max(light1, lum1);
            int v2 = Math.Max(light2, lum2);
            if (Math.Abs(v1 - v2) > 1) {
                QueueRelight(new BlockKey(x1, y1, z1));
            }
        }
示例#4
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));
                    }
                }
            }
        }
示例#5
0
        private void UpdateBlockLight()
        {
            IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap();

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

            while (_update.Count > 0)
            {
                BlockKey k     = _update.Dequeue();
                int      index = LightBitmapIndex(k);
                _lightbit[index] = false;

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

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

                int lle = NeighborLight(chunkMap, k.x, k.y, k.z - 1);
                int lln = NeighborLight(chunkMap, k.x - 1, k.y, k.z);
                int lls = NeighborLight(chunkMap, k.x, k.y, k.z + 1);
                int llw = NeighborLight(chunkMap, k.x + 1, k.y, k.z);
                int lld = NeighborLight(chunkMap, k.x, k.y - 1, k.z);
                int llu = NeighborLight(chunkMap, k.x, k.y + 1, k.z);

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

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

                int light = Math.Max(info.Luminance, 0);
                light = Math.Max(light, lle);
                light = Math.Max(light, lln);
                light = Math.Max(light, lls);
                light = Math.Max(light, llw);
                light = Math.Max(light, lld);
                light = Math.Max(light, llu);

                light = Math.Max(light - info.Opacity, 0);

                if (light != lightval)
                {
                    //Console.WriteLine("Block Light: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z);

                    cc.SetBlockLight(x, y, z, light);

                    if (info.TransmitsLight)
                    {
                        if (k.y > 0)
                        {
                            QueueRelight(new BlockKey(k.x, k.y - 1, k.z));
                        }
                        if (k.y < ydim - 1)
                        {
                            QueueRelight(new BlockKey(k.x, k.y + 1, k.z));
                        }

                        QueueRelight(new BlockKey(k.x - 1, k.y, k.z));
                        QueueRelight(new BlockKey(k.x + 1, k.y, k.z));
                        QueueRelight(new BlockKey(k.x, k.y, k.z - 1));
                        QueueRelight(new BlockKey(k.x, k.y, k.z + 1));
                    }
                }
            }
        }