コード例 #1
0
ファイル: NBTHelper.cs プロジェクト: wetstreet/Theircraft
    public static void UpdateLighting(int x, int y, int z)
    {
        //Debug.Log("update lighting");
        //float start = Time.realtimeSinceStartup;

        Queue <Vector3Int> skyLightQueue = new Queue <Vector3Int>();
        Vector3Int         p             = new Vector3Int();

        // init
        for (int i = -15; i <= 15; i++)
        {
            for (int j = -15; j <= 15; j++)
            {
                p.Set(x + i, y, z + j);

                int chunkX = Mathf.FloorToInt(p.x / 16f);
                int chunkZ = Mathf.FloorToInt(p.z / 16f);

                int xInChunk = p.x - chunkX * 16;
                int zInChunk = p.z - chunkZ * 16;

                NBTChunk chunk = GetChunk(chunkX, chunkZ);
                for (int temp_y = chunk.Sections.Count * 16 - 1; temp_y >= 0; temp_y--)
                {
                    chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 0);
                }
            }
        }

        HashSet <Vector3Int> skyLightSet = new HashSet <Vector3Int>();

        // light from sun (no vertical falloff)
        for (int i = -15; i <= 15; i++)
        {
            for (int j = -15; j <= 15; j++)
            {
                p.Set(x + i, y, z + j);

                int chunkX = Mathf.FloorToInt(p.x / 16f);
                int chunkZ = Mathf.FloorToInt(p.z / 16f);

                int xInChunk = p.x - chunkX * 16;
                int zInChunk = p.z - chunkZ * 16;

                NBTChunk chunk  = GetChunk(chunkX, chunkZ);
                int      temp_y = chunk.Sections.Count * 16 - 1;
                while (NBTGeneratorManager.LightCanTravel(chunk.GetBlockByte(xInChunk, temp_y, zInChunk)))
                {
                    chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 15);
                    skyLightSet.Add(new Vector3Int(p.x, temp_y, p.z));
                    if (temp_y == 0)
                    {
                        break;
                    }
                    else
                    {
                        temp_y--;
                    }
                }
            }
        }

        foreach (Vector3Int skyLightPos in skyLightSet)
        {
            if (skyLightSet.Contains(skyLightPos + Vector3Int.left) &&
                skyLightSet.Contains(skyLightPos + Vector3Int.right) &&
                skyLightSet.Contains(skyLightPos + Vector3Int.forward) &&
                skyLightSet.Contains(skyLightPos + Vector3Int.back))
            {
                continue;
            }
            skyLightQueue.Enqueue(new Vector3Int(skyLightPos.x, skyLightPos.y, skyLightPos.z));
        }

        int count    = 0;
        int setcount = 0;

        // light propagation (use flood fill)
        Vector3Int[] arr = new Vector3Int[6];
        while (skyLightQueue.Count > 0)
        {
            count++;
            p = skyLightQueue.Dequeue();
            byte skyLight = GetSkyLightByte(p.x, p.y, p.z);

            arr[0] = p + Vector3Int.left;
            arr[1] = p + Vector3Int.right;
            arr[2] = p + Vector3Int.up;
            arr[3] = p + Vector3Int.down;
            arr[4] = p + Vector3Int.forward;
            arr[5] = p + Vector3Int.back;

            for (int i = 0; i < 6; i++)
            {
                Vector3Int nextPos = arr[i];
                if (NBTGeneratorManager.IsTransparent(GetBlockByte(nextPos.x, nextPos.y, nextPos.z)))
                {
                    byte nextSkyLight = GetSkyLightByte(nextPos.x, nextPos.y, nextPos.z);
                    if (nextSkyLight < skyLight - 1)
                    {
                        setcount++;
                        //Debug.Log("SetSkyLightByte,nextPos=" + nextPos.x + "," + nextPos.y + "," + nextPos.z);
                        SetSkyLightByte(nextPos.x, nextPos.y, nextPos.z, (byte)(skyLight - 1));
                        if (skyLight > 2)
                        {
                            skyLightQueue.Enqueue(nextPos);
                        }
                    }
                }
            }
        }

        //float end = Time.realtimeSinceStartup;
        //Debug.Log("time cost =" + (end - start) + ", actual propagation count=" + count + ",setcount=" + setcount);
    }