/// <summary> /// Updates smart cap /// </summary> /// <param name="updateShared">Shared mesh of cap should be updated too?</param> void UpdateCapSmart(bool updateShared) { #region Check mesh Mesh capMesh; if (CapObj.GetComponent <MeshFilter>().sharedMesh == null) { capMesh = new Mesh(); capMesh.name = "Terrain2D_cap_mesh_" + InstanceId; CapObj.GetComponent <MeshFilter>().mesh = capMesh; } else { if (updateShared) { capMesh = CapObj.GetComponent <MeshFilter>().sharedMesh; capMesh.Clear(); } else { capMesh = CapObj.GetComponent <MeshFilter>().mesh; } } #endregion Vector3[] vertices = GetVertsPos(); SmartCapAreas = new List <SmartCapArea>(); #region Create smart cap areas SmartCapArea curSmartCapArea = new SmartCapArea(); bool nextSmartCapArea = false; int counterSign = 1; for (int i = 0; i < vertices.Length; i += 2) { if (i == vertices.Length - 2) { counterSign = -1; } if (Mathf.Abs(vertices[i].y - vertices[i + (2 * counterSign)].y) < SmartCapCutHeight) { if (!nextSmartCapArea) { SmartCapAreas.Add(new SmartCapArea()); curSmartCapArea = SmartCapAreas[SmartCapAreas.Count - 1]; nextSmartCapArea = true; } curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f)); curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f)); } else { if (nextSmartCapArea) { curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f)); curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f)); } nextSmartCapArea = false; } } #endregion #region Remove too small areas for (int i = SmartCapAreas.Count - 1; i >= 0; i--) { SmartCapAreas[i].MainSegmentsCount = (SmartCapAreas[i].VertsPoints.Count - 2) / 2; if (SmartCapAreas[i].MainSegmentsCount < Resolution) { SmartCapAreas.RemoveAt(i); } } #endregion #region Combine all vertices List <Vector3> totalCapVertices = new List <Vector3>(); Vector3[] sideVertices = new Vector3[4]; for (int i = 0; i < SmartCapAreas.Count; i++) { curSmartCapArea = SmartCapAreas[i]; //Add side segments vertices sideVertices[0] = curSmartCapArea.VertsPoints[0] - new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[1] = curSmartCapArea.VertsPoints[1] - new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[2] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 1] + new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[3] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 2] + new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[0].y += (sideVertices[0].y - curSmartCapArea.VertsPoints[2].y); sideVertices[1].y += (sideVertices[1].y - curSmartCapArea.VertsPoints[3].y); sideVertices[2].y += (sideVertices[2].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 3].y); sideVertices[3].y += (sideVertices[3].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 4].y); curSmartCapArea.VertsPoints.Insert(0, sideVertices[1]); curSmartCapArea.VertsPoints.Insert(0, sideVertices[0]); curSmartCapArea.VertsPoints.Add(sideVertices[3]); curSmartCapArea.VertsPoints.Add(sideVertices[2]); for (int j = 0; j < curSmartCapArea.VertsPoints.Count; j += 2) { totalCapVertices.Add(curSmartCapArea.VertsPoints[j]); totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]); if (j >= 2 && j <= curSmartCapArea.VertsPoints.Count - 3) { totalCapVertices.Add(curSmartCapArea.VertsPoints[j]); totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]); } } } #endregion #region Generate UV Vector2[] uv = new Vector2[totalCapVertices.Count]; float uvPerUnit = (SmartCapSegmentsUv.y - SmartCapSegmentsUv.x) / Resolution; int uvIndex = 0; for (int i = 0; i < SmartCapAreas.Count; i++) { curSmartCapArea = SmartCapAreas[i]; uv[uvIndex] = new Vector2(0, 1); uv[uvIndex + 1] = new Vector2(0, 0); uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x, 1); uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x, 0); uvIndex += 4; int unitCounter = 0; int uvTotalVerts = curSmartCapArea.VertsPoints.Count + (curSmartCapArea.VertsPoints.Count - 14); for (int j = 0; j < uvTotalVerts; j += 4) { uv[uvIndex] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 1); uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 0); uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 1); uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 0); uvIndex += 4; unitCounter++; if (unitCounter >= Resolution) { unitCounter = 0; } } if (uv[uvIndex - 1].x < SmartCapSegmentsUv.y) { SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 1]); SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 2]); } uv[uvIndex] = new Vector2(SmartCapSegmentsUv.y, 1); uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.y, 0); uv[uvIndex + 2] = new Vector2(1, 1); uv[uvIndex + 3] = new Vector2(1, 0); uvIndex += 4; } #endregion #region Generate triangles int unusedVertsCount = 0; foreach (var smartCapArea in SmartCapAreas) { unusedVertsCount += smartCapArea.VertsPoints.Count - 4; } int[] totalCapTris = new int[((totalCapVertices.Count - unusedVertsCount) - 2) * 3]; int curTrisIndex = 0; int vertCounter = 0; bool toSide = false; for (int i = 0; i < SmartCapAreas.Count; i++) { SmartCapArea curArea = SmartCapAreas[i]; int skipVertCounter = 0; for (int j = 2; j < curArea.VertsPoints.Count + (curArea.VertsPoints.Count - 4); j++) { if (skipVertCounter > 1) { vertCounter += 2; j += 2; skipVertCounter = 0; } if (toSide) { totalCapTris[curTrisIndex] = vertCounter; totalCapTris[curTrisIndex + 1] = vertCounter + 1; totalCapTris[curTrisIndex + 2] = vertCounter + 2; } else { totalCapTris[curTrisIndex] = vertCounter + 2; totalCapTris[curTrisIndex + 1] = vertCounter + 1; totalCapTris[curTrisIndex + 2] = vertCounter; } toSide = !toSide; vertCounter++; curTrisIndex += 3; skipVertCounter++; } vertCounter += 2; toSide = false; } #endregion capMesh.SetVertices(totalCapVertices); capMesh.triangles = totalCapTris; capMesh.normals = GetMeshNormals(totalCapVertices.Count); capMesh.uv = uv; capMesh.SetColors(GetMeshColors(CapColor, totalCapVertices.Count).ToList()); capMesh.RecalculateBounds(); }
/// <summary> /// Updates smart cap /// </summary> /// <param name="updateShared">Shared mesh of cap should be updated too?</param> void UpdateCapSmart(bool updateShared) { #region Check mesh Mesh capMesh; if (CapObj.GetComponent<MeshFilter>().sharedMesh == null) { capMesh = new Mesh(); capMesh.name = "Terrain2D_cap_mesh_" + InstanceId; CapObj.GetComponent<MeshFilter>().mesh = capMesh; } else { if (updateShared) { capMesh = CapObj.GetComponent<MeshFilter>().sharedMesh; capMesh.Clear(); } else capMesh = CapObj.GetComponent<MeshFilter>().mesh; } #endregion Vector3[] vertices = GetVertsPos(); SmartCapAreas = new List<SmartCapArea>(); #region Create smart cap areas SmartCapArea curSmartCapArea = new SmartCapArea(); bool nextSmartCapArea = false; int counterSign = 1; for (int i = 0; i < vertices.Length; i += 2) { if (i == vertices.Length - 2) counterSign = -1; if (Mathf.Abs(vertices[i].y - vertices[i + (2 * counterSign)].y) < SmartCapCutHeight) { if (!nextSmartCapArea) { SmartCapAreas.Add(new SmartCapArea()); curSmartCapArea = SmartCapAreas[SmartCapAreas.Count - 1]; nextSmartCapArea = true; } curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f)); curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f)); } else { if (nextSmartCapArea) { curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f)); curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f)); } nextSmartCapArea = false; } } #endregion #region Remove too small areas for (int i = SmartCapAreas.Count - 1; i >= 0; i--) { SmartCapAreas[i].MainSegmentsCount = (SmartCapAreas[i].VertsPoints.Count - 2) / 2; if (SmartCapAreas[i].MainSegmentsCount < Resolution) SmartCapAreas.RemoveAt(i); } #endregion #region Combine all vertices List<Vector3> totalCapVertices = new List<Vector3>(); Vector3[] sideVertices = new Vector3[4]; for (int i = 0; i < SmartCapAreas.Count; i++) { curSmartCapArea = SmartCapAreas[i]; //Add side segments vertices sideVertices[0] = curSmartCapArea.VertsPoints[0] - new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[1] = curSmartCapArea.VertsPoints[1] - new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[2] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 1] + new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[3] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 2] + new Vector3(SmartCapSideSegmentsWidth, 0, 0); sideVertices[0].y += (sideVertices[0].y - curSmartCapArea.VertsPoints[2].y); sideVertices[1].y += (sideVertices[1].y - curSmartCapArea.VertsPoints[3].y); sideVertices[2].y += (sideVertices[2].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 3].y); sideVertices[3].y += (sideVertices[3].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 4].y); curSmartCapArea.VertsPoints.Insert(0, sideVertices[1]); curSmartCapArea.VertsPoints.Insert(0, sideVertices[0]); curSmartCapArea.VertsPoints.Add(sideVertices[3]); curSmartCapArea.VertsPoints.Add(sideVertices[2]); for (int j = 0; j < curSmartCapArea.VertsPoints.Count; j += 2) { totalCapVertices.Add(curSmartCapArea.VertsPoints[j]); totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]); if (j >= 2 && j <= curSmartCapArea.VertsPoints.Count - 3) { totalCapVertices.Add(curSmartCapArea.VertsPoints[j]); totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]); } } } #endregion #region Generate UV Vector2[] uv = new Vector2[totalCapVertices.Count]; float uvPerUnit = (SmartCapSegmentsUv.y - SmartCapSegmentsUv.x) / Resolution; int uvIndex = 0; for (int i = 0; i < SmartCapAreas.Count; i++) { curSmartCapArea = SmartCapAreas[i]; uv[uvIndex] = new Vector2(0, 1); uv[uvIndex + 1] = new Vector2(0, 0); uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x, 1); uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x, 0); uvIndex += 4; int unitCounter = 0; int uvTotalVerts = curSmartCapArea.VertsPoints.Count + (curSmartCapArea.VertsPoints.Count - 14); for (int j = 0; j < uvTotalVerts; j += 4) { uv[uvIndex] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 1); uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 0); uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 1); uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 0); uvIndex += 4; unitCounter++; if (unitCounter >= Resolution) unitCounter = 0; } if (uv[uvIndex - 1].x < SmartCapSegmentsUv.y) { SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 1]); SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 2]); } uv[uvIndex] = new Vector2(SmartCapSegmentsUv.y, 1); uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.y, 0); uv[uvIndex + 2] = new Vector2(1, 1); uv[uvIndex + 3] = new Vector2(1, 0); uvIndex += 4; } #endregion #region Generate triangles int unusedVertsCount = 0; foreach (var smartCapArea in SmartCapAreas) { unusedVertsCount += smartCapArea.VertsPoints.Count - 4; } int[] totalCapTris = new int[((totalCapVertices.Count - unusedVertsCount) - 2) * 3]; int curTrisIndex = 0; int vertCounter = 0; bool toSide = false; for (int i = 0; i < SmartCapAreas.Count; i++) { SmartCapArea curArea = SmartCapAreas[i]; int skipVertCounter = 0; for (int j = 2; j < curArea.VertsPoints.Count + (curArea.VertsPoints.Count - 4); j++) { if (skipVertCounter > 1) { vertCounter += 2; j += 2; skipVertCounter = 0; } if (toSide) { totalCapTris[curTrisIndex] = vertCounter; totalCapTris[curTrisIndex + 1] = vertCounter + 1; totalCapTris[curTrisIndex + 2] = vertCounter + 2; } else { totalCapTris[curTrisIndex] = vertCounter + 2; totalCapTris[curTrisIndex + 1] = vertCounter + 1; totalCapTris[curTrisIndex + 2] = vertCounter; } toSide = !toSide; vertCounter++; curTrisIndex += 3; skipVertCounter++; } vertCounter += 2; toSide = false; } #endregion capMesh.SetVertices(totalCapVertices); capMesh.triangles = totalCapTris; capMesh.normals = GetMeshNormals(totalCapVertices.Count); capMesh.uv = uv; capMesh.SetColors(GetMeshColors(CapColor, totalCapVertices.Count).ToList()); capMesh.RecalculateBounds(); }