Ejemplo n.º 1
0
    MeshData GetMesh(NBTChunk chunk, Vector3Int pos)
    {
        byte eastType     = chunk.GetBlockByte(pos + Vector3Int.right);
        bool eastConnect  = !NBTGeneratorManager.IsTransparent(eastType) || NBTGeneratorManager.IsFence(eastType);
        byte southType    = chunk.GetBlockByte(pos + Vector3Int.back);
        bool southConnect = !NBTGeneratorManager.IsTransparent(southType) || NBTGeneratorManager.IsFence(southType);
        byte westType     = chunk.GetBlockByte(pos + Vector3Int.left);
        bool westConnect  = !NBTGeneratorManager.IsTransparent(westType) || NBTGeneratorManager.IsFence(westType);
        byte northType    = chunk.GetBlockByte(pos + Vector3Int.forward);
        bool northConnect = !NBTGeneratorManager.IsTransparent(northType) || NBTGeneratorManager.IsFence(northType);

        int index = 0;

        if (westConnect)
        {
            index += 8;
        }
        if (northConnect)
        {
            index += 4;
        }
        if (eastConnect)
        {
            index += 2;
        }
        if (southConnect)
        {
            index += 1;
        }

        return(meshes[index]);
    }
Ejemplo n.º 2
0
    public override void AddCube(NBTChunk chunk, byte blockData, Vector3Int pos, NBTGameObject nbtGO)
    {
        ca.pos       = pos;
        ca.blockData = blockData;

        InitBlockAttributes(chunk, ref ca);

        bool topIsSnow = chunk.GetBlockByte(pos.x, pos.y + 1, pos.z) == 78;

        if (!chunk.HasOpaqueBlock(pos.x, pos.y, pos.z - 1))
        {
            FaceAttributes fa = GetFrontFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            if (topIsSnow)
            {
                fa.faceIndex = TextureArrayManager.GetIndexByName("grass_side_snowed");
            }
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
        if (!chunk.HasOpaqueBlock(pos.x + 1, pos.y, pos.z))
        {
            FaceAttributes fa = GetRightFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            if (topIsSnow)
            {
                fa.faceIndex = TextureArrayManager.GetIndexByName("grass_side_snowed");
            }
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
        if (!chunk.HasOpaqueBlock(pos.x - 1, pos.y, pos.z))
        {
            FaceAttributes fa = GetLeftFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            if (topIsSnow)
            {
                fa.faceIndex = TextureArrayManager.GetIndexByName("grass_side_snowed");
            }
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
        if (!chunk.HasOpaqueBlock(pos.x, pos.y, pos.z + 1))
        {
            FaceAttributes fa = GetBackFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            if (topIsSnow)
            {
                fa.faceIndex = TextureArrayManager.GetIndexByName("grass_side_snowed");
            }
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
        if (!chunk.HasOpaqueBlock(pos.x, pos.y + 1, pos.z))
        {
            FaceAttributes fa = GetTopFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            if (topIsSnow)
            {
                fa.faceIndex = TextureArrayManager.GetIndexByName("snow");
            }
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
        if (!chunk.HasOpaqueBlock(pos.x, pos.y - 1, pos.z))
        {
            FaceAttributes fa = GetBottomFaceAttributes(chunk, nbtGO.nbtMesh, ca);
            AddFace(nbtGO.nbtMesh, fa, ca);
        }
    }
Ejemplo n.º 3
0
    public static void SetBlockByte(int x, int y, int z, byte type)
    {
        int chunkX = Mathf.FloorToInt(x / 16f);
        int chunkZ = Mathf.FloorToInt(z / 16f);

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

        NBTChunk    chunk        = GetChunk(chunkX, chunkZ);
        NBTBlock    oldGenerator = NBTGeneratorManager.GetMeshGenerator(chunk.GetBlockByte(xInChunk, y, zInChunk));
        UpdateFlags updateFlag   = GetUpdateFlags(oldGenerator);

        if (type == 0)
        {
            chunk.GetBlockData(xInChunk, y + 1, zInChunk, out byte topType, out byte topData);
            NBTBlock topGenerator = NBTGeneratorManager.GetMeshGenerator(topType);
            if (topGenerator != null && topGenerator is NBTPlant)
            {
                BreakBlockEffect.Create(topType, topData, new Vector3(x, y + 1, z));
                chunk.SetBlockByte(xInChunk, y + 1, zInChunk, 0);
                updateFlag |= UpdateFlags.NotCollidable;
            }
        }

        chunk.SetBlockByte(xInChunk, y, zInChunk, type);
        if (updateFlag.HasFlag(UpdateFlags.Lighting))
        {
            UpdateLighting(x, y, z);
        }
        chunk.RebuildMesh(updateFlag);

        NBTChunk leftChunk = GetChunk(chunkX - 1, chunkZ);

        if (xInChunk == 0)
        {
            leftChunk.RebuildMesh();
        }

        NBTChunk rightChunk = GetChunk(chunkX + 1, chunkZ);

        if (xInChunk == 15)
        {
            rightChunk.RebuildMesh();
        }

        NBTChunk backChunk = GetChunk(chunkX, chunkZ - 1);

        if (zInChunk == 0)
        {
            backChunk.RebuildMesh();
        }

        NBTChunk frontChunk = GetChunk(chunkX, chunkZ + 1);

        if (zInChunk == 15)
        {
            frontChunk.RebuildMesh();
        }
    }
Ejemplo n.º 4
0
    public static byte GetBlockByte(int x, int y, int z)
    {
        int chunkX = Mathf.FloorToInt(x / 16f);
        int chunkY = Mathf.FloorToInt(y / 16f);
        int chunkZ = Mathf.FloorToInt(z / 16f);

        int xInChunk = x - chunkX * 16;
        int yInChunk = y - chunkY * 16;
        int zInChunk = z - chunkZ * 16;

        NBTChunk chunk = GetChunk(chunkX, chunkZ);

        if (chunk != null)
        {
            return(chunk.GetBlockByte(xInChunk, y, zInChunk));
        }
        else
        {
            //TagNodeCompound Chunk = GetChunkNode(chunkX, chunkZ);
            //if (Chunk != null)
            //{
            //    TagNodeCompound Level = Chunk["Level"] as TagNodeCompound;

            //    TagNodeList Sections = Level["Sections"] as TagNodeList;
            //    if (chunkY < Sections.Count)
            //    {
            //        TagNodeCompound section = Sections[chunkY] as TagNodeCompound;

            //        TagNodeByteArray Blocks = section["Blocks"] as TagNodeByteArray;
            //        byte[] blocks = new byte[4096];
            //        Buffer.BlockCopy(Blocks, 0, blocks, 0, 4096);

            //        int blockPos = yInChunk * 16 * 16 + zInChunk * 16 + xInChunk;
            //        return blocks[blockPos];
            //    }
            //}
        }
        return(0);
    }
Ejemplo n.º 5
0
    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);
    }