/// <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); }