public void PrepareTopFaces(RectInt area, float tileSize) { var cellData = data.GetCellData(); area.ClampToBounds(data.Rect); //build normal verts and normals for (var x = area.xMin; x < area.xMax; x++) { for (var y = area.yMin; y < area.yMax; y++) { var cell = data.Cell(x, y); //var x1 = x - ChunkBounds.xMin; //var y1 = y - ChunkBounds.yMin; var tv = new Vector3[4]; if (cell == null) { Debug.LogError($"Could not find cell in bounds at {x},{y}"); } tv[0] = new Vector3((x + 0) * tileSize, cell.Heights[0] * RoMapData.YScale, (y + 1) * tileSize); tv[1] = new Vector3((x + 1) * tileSize, cell.Heights[1] * RoMapData.YScale, (y + 1) * tileSize); tv[2] = new Vector3((x + 0) * tileSize, cell.Heights[2] * RoMapData.YScale, (y + 0) * tileSize); tv[3] = new Vector3((x + 1) * tileSize, cell.Heights[3] * RoMapData.YScale, (y + 0) * tileSize); vertexData[x + y * data.Width] = tv; var normal = VectorHelper.CalcQuadNormal(tv[0], tv[1], tv[2], tv[3]); cellNormals[x + y * data.Width] = normal; var normals = new Vector3[4]; for (var i = 0; i < 4; i++) { normals[i] = normal; } normalData[x + y * data.Width] = normals; cellColors[x + y * data.Width] = cell.Top.Color; } } }
public void RebuildMeshData(float tileSize, bool paintEmptyTilesBlack) { //var verts = new List<Vector3>(); //var normals = new List<Vector3>(); //var uvs = new List<Vector2>(); //var tris = new List<int>(); //var colors = new List<Color>(); gameObject.layer = GetLayerForChunk(); Material.mainTexture = MapData.Atlas; var mesh = new MeshBuilder(); var shadow = new MeshBuilder(); var cellData = MapData.GetCellData(); var sharedData = MapData.SharedMeshData; sharedData.RebuildArea(ChunkBounds, tileSize, paintEmptyTilesBlack); for (var x = ChunkBounds.xMin; x < ChunkBounds.xMax; x++) { for (var y = ChunkBounds.yMin; y < ChunkBounds.yMax; y++) { var pos = x + y * MapData.Width; if (pos >= cellData.Length) { Debug.LogError($"{x} {y} {ChunkBounds} {ChunkBounds.yMax}"); } var cell = cellData[pos]; var x1 = x - ChunkBounds.xMin; var y1 = y - ChunkBounds.yMin; if (true) //always draw top cell, no matter what { var m = mesh; if (paintEmptyTilesBlack && (cell.Top.Texture == null || cell.Top.Texture == "BACKSIDE" || cell.Top.Texture == "BLACK")) { m = shadow; } var offset = Vector3.zero; if (MapData.IsWalkTable) { offset += new Vector3(0f, 0.01f, 0f); } var tVerts = sharedData.GetTileVertices(new Vector2Int(x, y), transform.position - offset); var tNormals = sharedData.GetTileNormals(new Vector2Int(x, y));// topNormals[x1 + y1 * ChunkBounds.width]; var tColors = sharedData.GetTileColors(new Vector2Int(x, y)); m.StartTriangle(); m.AddVertices(tVerts); m.AddUVs(MapData.TranslateTileTextureUVs(cell.Top)); m.AddColors(tColors); m.AddNormals(tNormals); m.AddTriangles(new[] { 0, 1, 3, 3, 2, 0 }); } if (cell.Right.Enabled && x + 1 < MapData.Width && !MapData.IsWalkTable) { var m = mesh; if (paintEmptyTilesBlack && (cell.Right.Texture == null || cell.Right.Texture == "BACKSIDE" || cell.Right.Texture == "BLACK")) { m = shadow; } var neighbor = cellData[x + 1 + y * MapData.Width]; var r1 = new Vector3((x1 + 1) * tileSize, cell.Heights[1] * RoMapData.YScale, (y1 + 1) * tileSize); var r2 = new Vector3((x1 + 1) * tileSize, neighbor.Heights[0] * RoMapData.YScale, (y1 + 1) * tileSize); var r3 = new Vector3((x1 + 1) * tileSize, cell.Heights[3] * RoMapData.YScale, (y1 + 0) * tileSize); var r4 = new Vector3((x1 + 1) * tileSize, neighbor.Heights[2] * RoMapData.YScale, (y1 + 0) * tileSize); var rnormal = VectorHelper.CalcQuadNormal(r1, r2, r3, r4); m.StartTriangle(); m.AddVertices(new[] { r1, r2, r3, r4 }); m.AddNormals(new[] { rnormal, rnormal, rnormal, rnormal }); m.AddUVs(MapData.TranslateTileTextureUVs(cell.Right)); m.AddColors(sharedData.GetAveragedRightColors(new Vector2Int(x, y))); m.AddTriangles(new[] { 0, 1, 3, 3, 2, 0 }); } if (cell.Front.Enabled && y - 1 >= 0 && !MapData.IsWalkTable) { var m = mesh; if (paintEmptyTilesBlack && (cell.Front.Texture == null || cell.Front.Texture == "BACKSIDE" || cell.Front.Texture == "BLACK")) { m = shadow; } var neighbor = cellData[x + (y - 1) * MapData.Width]; var f1 = new Vector3((x1 + 0) * tileSize, cell.Heights[2] * RoMapData.YScale, (y1 + 0) * tileSize); var f2 = new Vector3((x1 + 1) * tileSize, cell.Heights[3] * RoMapData.YScale, (y1 + 0) * tileSize); var f3 = new Vector3((x1 + 0) * tileSize, neighbor.Heights[0] * RoMapData.YScale, (y1 + 0) * tileSize); var f4 = new Vector3((x1 + 1) * tileSize, neighbor.Heights[1] * RoMapData.YScale, (y1 + 0) * tileSize); var fNormal = VectorHelper.CalcQuadNormal(f1, f2, f3, f4); m.StartTriangle(); m.AddVertices(new[] { f1, f2, f3, f4 }); m.AddNormals(new[] { fNormal, fNormal, fNormal, fNormal }); m.AddUVs(MapData.TranslateTileTextureUVs(cell.Front)); m.AddColors(sharedData.GetAveragedFrontColors(new Vector2Int(x, y))); m.AddTriangles(new[] { 0, 1, 3, 3, 2, 0 }); } } } //if (!mesh.HasMesh()) //{ // Debug.Log($"Chunk {name} is empty."); // return; //} needRebuild = true; delayToRebuild = Random.Range(4f, 8f); Mesh = mesh.Build(name); if (shadow.HasMesh()) { MakeShadowlessChild(shadow.Build(name + " shadow")); } else { RemoveOldChildren(); } MeshFilter.sharedMesh = Mesh; Collider.sharedMesh = Mesh; NeedsUVUpdate = true; //Mesh.UploadMeshData(false); //if (!rebuildUVs) // return; //if (delayUVRebuild) //{ // if (rebuildCoroutine != null) // EditorCoroutineUtility.StopCoroutine(rebuildCoroutine); // rebuildCoroutine = EditorCoroutineUtility.StartCoroutine(DelayedRebuild(delayToRebuild), this); //} //else //{ // Debug.Log("Do rebuild immediately!"); // //RebuildUvs(); // if (rebuildCoroutine != null) // EditorCoroutineUtility.StopCoroutine(rebuildCoroutine); // rebuildCoroutine = null; // Debug.Log(Mesh.uv2); // //Mesh.UploadMeshData(false); //} }