コード例 #1
0
    /// <summary>
    /// Builds visible faces, fluid faces are added to child instead
    /// </summary>
    public virtual async Task BuildMesh()
    {
        List <Vector3> vertices  = new List <Vector3>();
        List <int>     triangles = new List <int>();
        List <Vector2> UVs       = new List <Vector2>();

        List <Vector3> fluidVertices  = new List <Vector3>();
        List <int>     fluidTriangles = new List <int>();
        List <Vector2> fluidUVs       = new List <Vector2>();

        List <Vector3> transparentVertices  = new List <Vector3>();
        List <int>     transparentTriangles = new List <int>();
        List <Vector2> transparentUVs       = new List <Vector2>();

        //reference to list to add to (solid / fluid / transparent)
        List <Vector3> vertexList;
        List <int>     triList;
        List <Vector2> uvList;

        //while (Blocks == null) await Generate();

        await Task.Run(() =>
        {
            for (int x = 0; x < SIZE; x++)
            {
                for (int z = 0; z < SIZE; z++)
                {
                    for (int y = 0; y < HEIGHT; y++)
                    {
                        var block = Blocks[x, y, z];
                        if (block == null)
                        {
                            continue;
                        }
                        if (block is Fluid)
                        {
                            vertexList = fluidVertices;
                            triList    = fluidTriangles;
                            uvList     = fluidUVs;
                        }
                        else if (block is BlockTransparent)
                        {
                            vertexList = transparentVertices;
                            triList    = transparentTriangles;
                            uvList     = transparentUVs;
                        }
                        else
                        {
                            vertexList = vertices;
                            triList    = triangles;
                            uvList     = UVs;
                        }

                        var blockIdx = new Vector3(x, y, z);
                        int numFaces = 0;
                        Block neighbour;

                        if (z == 0)
                        {
                            neighbour = TerrainGenerator.Instance.GetBlock(block.Pos - Vector3.forward);
                        }
                        else
                        {
                            neighbour = Blocks[x, y, z - 1];
                        }

                        if (block.DrawFaceNextTo(Direction.South, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.South, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.South));
                            numFaces++;
                        }


                        if (z == SIZE - 1)
                        {
                            neighbour = TerrainGenerator.Instance.GetBlock(block.Pos + Vector3.forward);
                        }
                        else
                        {
                            neighbour = Blocks[x, y, z + 1];
                        }

                        if (block.DrawFaceNextTo(Direction.North, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.North, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.North));
                            numFaces++;
                        }


                        if (x == 0)
                        {
                            neighbour = TerrainGenerator.Instance.GetBlock(block.Pos - Vector3.right);
                        }
                        else
                        {
                            neighbour = Blocks[x - 1, y, z];
                        }

                        if (block.DrawFaceNextTo(Direction.West, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.West, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.West));
                            numFaces++;
                        }


                        if (x == SIZE - 1)
                        {
                            neighbour = TerrainGenerator.Instance.GetBlock(block.Pos + Vector3.right);
                        }
                        else
                        {
                            neighbour = Blocks[x + 1, y, z];
                        }

                        if (block.DrawFaceNextTo(Direction.East, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.East, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.East));
                            numFaces++;
                        }


                        if (y == 0)
                        {
                            neighbour = null;
                        }
                        else
                        {
                            neighbour = Blocks[x, y - 1, z];
                        }

                        if (block.DrawFaceNextTo(Direction.Down, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.Down, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.Down));
                            numFaces++;
                        }

                        if (y == HEIGHT - 1)
                        {
                            neighbour = null;
                        }
                        else
                        {
                            neighbour = Blocks[x, y + 1, z];
                        }

                        if (block.DrawFaceNextTo(Direction.Up, neighbour))
                        {
                            foreach (var vertex in block.GetVertices(Direction.Up, neighbour))
                            {
                                vertexList.Add(blockIdx + vertex);
                            }
                            uvList.AddRange(block.GetUVs(Direction.Up));
                            numFaces++;
                        }

                        int triangleIdx = vertexList.Count - numFaces * 4;
                        for (int i = 0; i < numFaces; i++)
                        {
                            int i4 = i * 4;
                            triList.AddRange(new int[]
                            {
                                triangleIdx + i4, triangleIdx + i4 + 1, triangleIdx + i4 + 2,
                                triangleIdx + i4, triangleIdx + i4 + 2, triangleIdx + i4 + 3
                            });
                        }
                    }
                }
            }
        }
                       );

        fluidMesh.ApplyMesh(fluidVertices, fluidTriangles, fluidUVs);

        transparentMesh.ApplyMesh(transparentVertices, transparentTriangles, transparentUVs);

        ApplyMesh(vertices, triangles, UVs);
    }