예제 #1
0
 public Chunk()
 {
     m_Data           = new ChunkData();
     m_SolidMeshes    = new Mesh[SectionCountInChunk];
     m_LiquidMeshes   = new Mesh[SectionCountInChunk];
     m_MeshDataBuffer = new ChunkMeshDataBuffer();
 }
        private void BuildLiquidMeshData(ChunkMeshDataBuffer buffer)
        {
            WorldManager world = WorldManager.Active;

            Profiler.BeginSample("Build Liquid Mesh");

            try
            {
                if (m_Data.GetRenderableLiquidCount(buffer.SectionIndex) <= 0)
                {
                    return;
                }

                int baseY = buffer.SectionIndex * SectionHeight;

                for (int dx = 0; dx < ChunkWidth; dx++)
                {
                    for (int dz = 0; dz < ChunkWidth; dz++)
                    {
                        int rx = PositionX + dx;
                        int rz = PositionZ + dz;

                        int maxY = m_Data.GetTopNonAirIndex(dx, dz);

                        for (int dy = 0; dy < SectionHeight; dy++)
                        {
                            int ry = baseY + dy;

                            if (ry > maxY)
                            {
                                break;
                            }

                            //if (ry == 0)
                            //    continue;

                            BlockType type  = m_Data.GetBlockType(dx, ry, dz);
                            Block     block = world.DataManager.GetBlockByType(type);

                            if (block.VertexType != BlockVertexType.Cube || !block.HasAllFlags(BlockFlags.Liquid))
                            {
                                continue;
                            }

                            float light = GetFinalLightLevelPrivate(dx, ry, dz) * OverMaxLight;

                            if (world.IsBlockTransparentAndNotWater(rx + 1, ry, rz))
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexPX(dx, dy, dz, light, light, light, light, block);
                            }

                            if (world.IsBlockTransparentAndNotWater(rx - 1, ry, rz))
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexNX(dx, dy, dz, light, light, light, light, block);
                            }

                            //if (world.IsBlockTransparentAndNotWater(rx, ry + 1, rz))
                            if (world.GetBlockType(rx, ry + 1, rz) != BlockType.Water)
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexPY(dx, dy, dz, light, light, light, light, block);
                            }

                            if (world.IsBlockTransparentAndNotWater(rx, ry - 1, rz))
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexNY(dx, dy, dz, light, light, light, light, block);
                            }

                            if (world.IsBlockTransparentAndNotWater(rx, ry, rz + 1))
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexPZ(dx, dy, dz, light, light, light, light, block);
                            }

                            if (world.IsBlockTransparentAndNotWater(rx, ry, rz - 1))
                            {
                                buffer.AddCubeTriangles();
                                buffer.AddCubeVertexNZ(dx, dy, dz, light, light, light, light, block);
                            }
                        }
                    }
                }
            }
#if !UNITY_EDITOR
            catch
            {
            }
#endif
            finally
            {
                Profiler.EndSample();
            }
        }
        private void BuildSolidMeshData(ChunkMeshDataBuffer buffer)
        {
            WorldManager world = WorldManager.Active;

            Profiler.BeginSample("Build Solid Mesh");

            try
            {
                if (m_Data.GetRenderableSolidCount(buffer.SectionIndex) <= 0)
                {
                    return;
                }

                int baseY = buffer.SectionIndex * SectionHeight;

                for (int dx = 0; dx < ChunkWidth; dx++)
                {
                    for (int dz = 0; dz < ChunkWidth; dz++)
                    {
                        int rx = PositionX + dx;
                        int rz = PositionZ + dz;

                        int maxY = m_Data.GetTopNonAirIndex(dx, dz);

                        for (int dy = 0; dy < SectionHeight; dy++)
                        {
                            int ry = baseY + dy;

                            if (ry > maxY)
                            {
                                break;
                            }

                            BlockType type  = m_Data.GetBlockType(dx, ry, dz);
                            Block     block = world.DataManager.GetBlockByType(type);

                            if (block.VertexType == BlockVertexType.None || block.HasAnyFlag(BlockFlags.Liquid))
                            {
                                continue;
                            }

                            switch (block.VertexType)
                            {
                            case BlockVertexType.Cube:
                            {
                                float light = block.LightValue * OverMaxLight;

                                if (world.IsBlockTransparent(rx + 1, ry, rz))
                                {
                                    float lb = (world.GetFinalLightLevel(rx + 1, ry, rz) + world.GetFinalLightLevel(rx + 1, ry - 1, rz) + world.GetFinalLightLevel(rx + 1, ry, rz - 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx + 1, ry, rz) + world.GetFinalLightLevel(rx + 1, ry - 1, rz) + world.GetFinalLightLevel(rx + 1, ry, rz + 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx + 1, ry, rz) + world.GetFinalLightLevel(rx + 1, ry + 1, rz) + world.GetFinalLightLevel(rx + 1, ry, rz + 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx + 1, ry, rz) + world.GetFinalLightLevel(rx + 1, ry + 1, rz) + world.GetFinalLightLevel(rx + 1, ry, rz - 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexPX(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }

                                if (world.IsBlockTransparent(rx - 1, ry, rz))
                                {
                                    float lb = (world.GetFinalLightLevel(rx - 1, ry, rz) + world.GetFinalLightLevel(rx - 1, ry - 1, rz) + world.GetFinalLightLevel(rx - 1, ry, rz + 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx - 1, ry, rz) + world.GetFinalLightLevel(rx - 1, ry - 1, rz) + world.GetFinalLightLevel(rx - 1, ry, rz - 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx - 1, ry, rz) + world.GetFinalLightLevel(rx - 1, ry + 1, rz) + world.GetFinalLightLevel(rx - 1, ry, rz - 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx - 1, ry, rz) + world.GetFinalLightLevel(rx - 1, ry + 1, rz) + world.GetFinalLightLevel(rx - 1, ry, rz + 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexNX(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }

                                if (world.IsBlockTransparent(rx, ry + 1, rz))
                                {
                                    float lb = (world.GetFinalLightLevel(rx, ry + 1, rz) + world.GetFinalLightLevel(rx, ry + 1, rz - 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz) + world.GetFinalLightLevel(rx - 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx, ry + 1, rz) + world.GetFinalLightLevel(rx, ry + 1, rz - 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz) + world.GetFinalLightLevel(rx + 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx, ry + 1, rz) + world.GetFinalLightLevel(rx, ry + 1, rz + 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz) + world.GetFinalLightLevel(rx + 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx, ry + 1, rz) + world.GetFinalLightLevel(rx, ry + 1, rz + 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz) + world.GetFinalLightLevel(rx - 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexPY(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }

                                if (ry > 0 && world.IsBlockTransparent(rx, ry - 1, rz))
                                {
                                    float lb = (world.GetFinalLightLevel(rx, ry - 1, rz) + world.GetFinalLightLevel(rx, ry - 1, rz - 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz) + world.GetFinalLightLevel(rx + 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx, ry - 1, rz) + world.GetFinalLightLevel(rx, ry - 1, rz - 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz) + world.GetFinalLightLevel(rx - 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx, ry - 1, rz) + world.GetFinalLightLevel(rx, ry - 1, rz + 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz) + world.GetFinalLightLevel(rx - 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx, ry - 1, rz) + world.GetFinalLightLevel(rx, ry - 1, rz + 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz) + world.GetFinalLightLevel(rx + 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexNY(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }

                                if (world.IsBlockTransparent(rx, ry, rz + 1))
                                {
                                    float lb = (world.GetFinalLightLevel(rx, ry, rz + 1) + world.GetFinalLightLevel(rx, ry - 1, rz + 1) + world.GetFinalLightLevel(rx + 1, ry, rz + 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx, ry, rz + 1) + world.GetFinalLightLevel(rx, ry - 1, rz + 1) + world.GetFinalLightLevel(rx - 1, ry, rz + 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx, ry, rz + 1) + world.GetFinalLightLevel(rx, ry + 1, rz + 1) + world.GetFinalLightLevel(rx - 1, ry, rz + 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx, ry, rz + 1) + world.GetFinalLightLevel(rx, ry + 1, rz + 1) + world.GetFinalLightLevel(rx + 1, ry, rz + 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz + 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexPZ(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }

                                if (world.IsBlockTransparent(rx, ry, rz - 1))
                                {
                                    float lb = (world.GetFinalLightLevel(rx, ry, rz - 1) + world.GetFinalLightLevel(rx, ry - 1, rz - 1) + world.GetFinalLightLevel(rx - 1, ry, rz - 1) + world.GetFinalLightLevel(rx - 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rb = (world.GetFinalLightLevel(rx, ry, rz - 1) + world.GetFinalLightLevel(rx, ry - 1, rz - 1) + world.GetFinalLightLevel(rx + 1, ry, rz - 1) + world.GetFinalLightLevel(rx + 1, ry - 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float rt = (world.GetFinalLightLevel(rx, ry, rz - 1) + world.GetFinalLightLevel(rx, ry + 1, rz - 1) + world.GetFinalLightLevel(rx + 1, ry, rz - 1) + world.GetFinalLightLevel(rx + 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;
                                    float lt = (world.GetFinalLightLevel(rx, ry, rz - 1) + world.GetFinalLightLevel(rx, ry + 1, rz - 1) + world.GetFinalLightLevel(rx - 1, ry, rz - 1) + world.GetFinalLightLevel(rx - 1, ry + 1, rz - 1)) * 0.25f * OverMaxLight;

                                    buffer.AddCubeTriangles();
                                    buffer.AddCubeVertexNZ(dx, dy, dz, Mathf.Max(lb, light), Mathf.Max(rb, light), Mathf.Max(rt, light), Mathf.Max(lt, light), block);
                                }
                            }
                            break;

                            case BlockVertexType.PerpendicularQuads:
                            {
                                float light = GetFinalLightLevelPrivate(dx, ry, dz) * OverMaxLight;

                                buffer.AddPerpendicularQuadsTriangles();
                                buffer.AddPerpendicularQuadsVertexFirst(dx, dy, dz, light, block);

                                buffer.AddPerpendicularQuadsTriangles();
                                buffer.AddPerpendicularQuadsVertexSecond(dx, dy, dz, light, block);
                            }
                            break;
                            }
                        }
                    }
                }
            }
#if !UNITY_EDITOR
            catch
            {
            }
#endif
            finally
            {
                Profiler.EndSample();
            }
        }