public static TriangulatedMesh Add(Vector3 position, Vector2[] points, List <Triangulation.IntTriple> connections, Material meshMat = null, bool attachRigidbody = true) { GameObject triangulatedMesh = new GameObject(); triangulatedMesh.transform.position = MeshHelper.GetCenter(points); TriangulatedMesh triComponent = triangulatedMesh.AddComponent <TriangulatedMesh>(); triComponent.Build(points, connections, meshMat); if (attachRigidbody) { triangulatedMesh.AddComponent <Rigidbody2D>(); } return(triComponent); }
public static GearMesh AddGear(Vector3 position, float innerRadius, float rootRadius, float outerRadius, int sides, Material meshMat = null, bool attachRigidbody = true) { MeshHelper.SetupMaterial(ref meshMat); GameObject gear = new GameObject(); gear.transform.position = position; GearMesh gearComponent = gear.AddComponent <GearMesh>(); gearComponent.Build(innerRadius, rootRadius, outerRadius, sides, meshMat); if (attachRigidbody) { gear.AddComponent <Rigidbody2D>(); } return(gearComponent); }
protected override void BuildMeshComponents() { BaseVertices = ConvexVertices; Vertices = MeshHelper.ConvertVec2ToVec3(ConvexHull.QuickHull(MeshHelper.ConvertVec3ToVec2(ConvexVertices)).ToArray()); // oh no Triangles = new int[Vertices.Length * 3]; for (int i = 1; i < Vertices.Length - 1; i++) { Triangles[i * 3 + 0] = 0; Triangles[i * 3 + 1] = i; Triangles[i * 3 + 2] = i + 1; } UVs = MeshHelper.UVUnwrap(Vertices); }
protected override bool ValidateMesh() { if (P1 == P2 || P2 == P3 || P3 == P1) { Debug.LogWarning("TriangleMesh::ValidateMesh: some of the points are identity!"); return(false); } int sign = MeshHelper.GetSide(P2, P1, P3); if (sign == 0) { Debug.LogWarning("TriangleMesh::ValidateMesh: Given points are colinear!"); return(false); } return(true); }
protected override void BuildMeshComponents() { Vertices = new Vector3[sides + 1]; Triangles = new int[3 * sides]; float angleDelta = deg360 / sides; Vertices[0] = shift; for (int i = 1; i < sides + 1; i++) { Vector3 vertPos = new Vector3(Mathf.Cos(i * angleDelta), Mathf.Sin(i * angleDelta)) * radius; Vertices[i] = vertPos; Triangles[(i - 1) * 3 + 0] = (1 + i % sides); Triangles[(i - 1) * 3 + 1] = 1 + (i - 1) % sides; Triangles[(i - 1) * 3 + 2] = 0; } UVs = MeshHelper.UVUnwrap(Vertices); }
protected override bool ValidateMesh() { if (p1 == p2 || p2 == p3 || p3 == p1) { Debug.LogWarning("TriangleMesh::ValidateMesh: some of the points are identity!"); return(false); } int sign = MeshHelper.GetSide(p2, p1, p3); if (sign == 0) { Debug.LogWarning("TriangleMesh::ValidateMesh: Given points are colinear!"); return(false); } return(true); }
protected override void BuildMeshComponents() { Vector2 center = MeshHelper.GetCenter(Vertices); Vertices = new Vector3[Points.Length]; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = Points[i] - center; } Triangles = new int[Connections.Count * 3]; for (int i = 0; i < Connections.Count; i++) { Triangles[i * 3 + 0] = Connections[i].A; Triangles[i * 3 + 1] = Connections[i].B; Triangles[i * 3 + 2] = Connections[i].C; } UVs = MeshHelper.UVUnwrap(Vertices); }
protected void BuildMesh(ref Material meshMatt) { if (!Validate || ValidateMesh()) { MeshHelper.CheckMaterial(ref meshMatt); _Mesh = new Mesh(); GetOrAddComponents(); C_MR.material = meshMatt; BuildMeshComponents(); UpdateMeshFilter(); UpdateCollider(); } else { Debug.LogError("MeshBase::BuildMesh: " + name + " generation failed"); } }
protected override void BuildMeshComponents() { bool isCircle = innerRadius == 0; Vertices = new Vector3[isCircle ? sides + 1 : 2 * sides]; Triangles = new int[isCircle ? 3 * sides : 6 * sides]; if (isCircle) { //build ordinary circle Vertices[0] = Vector3.zero; float angleDelta = deg360 / sides; for (int i = 1; i < sides + 1; i++) { Vector3 vertPos = new Vector3(Mathf.Cos(i * angleDelta), Mathf.Sin(i * angleDelta)) * outerRadius; Vertices[i] = vertPos; Triangles[(i - 1) * 3 + 0] = 0; Triangles[(i - 1) * 3 + 1] = 1 + (i - 1) % sides; Triangles[(i - 1) * 3 + 2] = 1 + i % sides; } } else { //build a ring! float angleDelta = deg360 / sides; int triangleIndex = 0; for (int i = 0; i < sides; i++) { Vector3 vertPosInner = new Vector3(Mathf.Cos(i * angleDelta), Mathf.Sin(i * angleDelta)) * innerRadius; Vector3 vertPosOuter = new Vector3(Mathf.Cos(i * angleDelta), Mathf.Sin(i * angleDelta)) * outerRadius; Vertices[i] = vertPosInner; Vertices[i + sides] = vertPosOuter; Triangles[triangleIndex++] = i; Triangles[triangleIndex++] = (i + 1) % (sides); Triangles[triangleIndex++] = (i + sides); Triangles[triangleIndex++] = (i + 1) % (sides * 2); Triangles[triangleIndex++] = (i + sides); Triangles[triangleIndex++] = (i + sides + 1) % (sides * 2); } } UVs = MeshHelper.UVUnwrap(Vertices); }
public static TriangulatedMesh ConvertToTriangulatedMesh(TriangulableMesh sourceMeshScript) { //check if mesh is already a triangulated one if (sourceMeshScript.GetType() == triangulatedMeshType) { return(sourceMeshScript.GetComponent <TriangulatedMesh>()); } Object.DestroyImmediate(sourceMeshScript.GetComponent <Collider2D>()); TriangulatedMesh triangulatedMesh = sourceMeshScript.gameObject.AddComponent <TriangulatedMesh>(); Vector2[] points = MeshHelper.ConvertVec3ToVec2(sourceMeshScript.GetTriangulableVertices()); List <Triangulation.IntTriple> connections = Triangulation.TriangulationToInt3(new List <Vector2>(points)); triangulatedMesh.Build(points, connections, sourceMeshScript.C_MR.sharedMaterial); //delete base component Object.DestroyImmediate(sourceMeshScript); return(triangulatedMesh); }
protected override void BuildMeshComponents() { Vertices = new Vector3[1 + sides * 2]; Triangles = new int[2 * sides * 3]; UVs = new Vector2[1 + sides * 2]; Vertices[0] = new Vector3(0, 0); float angleDelta = 360 / (float)sides / 2 * Mathf.Deg2Rad; float angleShift = -360f / (sides * 4) * Mathf.Deg2Rad; for (int i = 0; i < sides * 2; i++) { Vector3 vertVec = new Vector3(Mathf.Cos(i * angleDelta + angleShift), Mathf.Sin(i * angleDelta + angleShift)); Vertices[1 + i] = vertVec * (i % 2 == 0 ? radiusA : radiusB); Triangles[(i * 3 + 2) % Triangles.Length] = 0; Triangles[(i * 3 + 1) % Triangles.Length] = 1 + i % (sides * 2); Triangles[i * 3] = 1 + (i + 1) % (sides * 2); } UVs = MeshHelper.UVUnwrap(Vertices); }
//assign variables, get components and build mesh public void Build(float innerRadius, float rootRadius, float outerRadius, int sides, Material meshMat = null) { MeshHelper.SetupMaterial(ref meshMat); name = "Gear"; InnerRadius = innerRadius; RootRadius = rootRadius; OuterRadius = outerRadius; Sides = sides; _Mesh = new Mesh(); GetOrAddComponents(); C_MR.material = meshMat; if (!Validate || ValidateMesh()) { BuildMeshComponents(); UpdateMeshFilter(); UpdateCollider(); } }
public static LineMesh AddLine(Vector3 position, Vector2[] lineVerts, float lineWidth, bool useDoubleCollider, Space space, Material meshMat = null, bool attachRigidbody = true) { GameObject line = new GameObject(); if (space == Space.Self) { line.transform.position = position; } else { line.transform.position = position + (Vector3)MeshHelper.GetCenter(lineVerts); } LineMesh lineComponent = line.AddComponent <LineMesh>(); lineComponent.Build(lineVerts, lineWidth, useDoubleCollider, meshMat); if (attachRigidbody) { line.AddComponent <Rigidbody2D>(); } return(lineComponent); }
public static SplineShapeMesh AddSplineShape(Vector3 position, Vector2[] splinePoints, float resolution = 0.2f, float?minArea = null, Space space = Space.World, Material meshMat = null, bool attachRigidbody = true) { GameObject splineShapeMesh = new GameObject(); if (space == Space.Self) { splineShapeMesh.transform.position = position; } else { splineShapeMesh.transform.position = position + (Vector3)MeshHelper.GetCenter(splinePoints); } SplineShapeMesh splineMeshComponent = splineShapeMesh.AddComponent <SplineShapeMesh>(); splineMeshComponent.Build(splinePoints, resolution, minArea, meshMat); if (attachRigidbody) { splineShapeMesh.AddComponent <Rigidbody2D>(); } return(splineMeshComponent); }
public static SplineCurveMesh AddSplineCurve(Vector3 position, Vector2[] splinePoints, float resolution, float width, bool useDoubleCollider, float?minArea, Space space, Material meshMat = null, bool attachRigidbody = true) { GameObject curve = new GameObject(); if (space == Space.Self) { curve.transform.position = position; } else { curve.transform.position = position + (Vector3)MeshHelper.GetCenter(splinePoints); } curve.transform.position = position; SplineCurveMesh curveComponent = curve.AddComponent <SplineCurveMesh>(); curveComponent.Build(splinePoints, resolution, width, useDoubleCollider, minArea, meshMat); if (attachRigidbody) { curve.AddComponent <Rigidbody2D>(); } return(curveComponent); }
public static bool IsShapeClockWise(List<Vector2> sourcePoints) { Debug.Assert(sourcePoints.Count>=3, "Triangulation::IsShapeClockwise: points count must be greater than two!"); double sum = 0; for (int i = 0; i < sourcePoints.Count; i++) { int k1 = i + 1; if (k1 >= sourcePoints.Count) k1 -= sourcePoints.Count; int k2 = i + 2; if (k2 >= sourcePoints.Count) k2 -= sourcePoints.Count; if (AreVecsConvex(sourcePoints[i], sourcePoints[k1], sourcePoints[k2])) { sum += MeshHelper.AngleBetweenPoints(sourcePoints[i], sourcePoints[k1], sourcePoints[k2]); } else { sum += 360 - MeshHelper.AngleBetweenPoints(sourcePoints[i], sourcePoints[k1], sourcePoints[k2]); } } return System.Math.Round(sum) == 180 * (sourcePoints.Count - 2); }
public static List<IntTriple> TriangulationToInt3(List<Vector2> sourcePoints) { List<IntTriple> triangles = new List<IntTriple>(); int MAX = sourcePoints.Count * sourcePoints.Count; //temporary List of points List<VecIndexPair> verts = VecIndexPair.Get(sourcePoints); //was shape drew clockwise? bool isCW = IsShapeClockWise(sourcePoints); int start = 0; int repeats = 0; while (verts.Count > 2 && repeats < MAX) { bool earNotFound = true; while (earNotFound && repeats < MAX) { repeats++; start %= verts.Count; int middle = (start + 1) % verts.Count; int end = (start + 2) % verts.Count; //change the order to fit triangle mesh facing triangles.Add(new IntTriple(verts[start].index, verts[end].index, verts[middle].index)); //is current point convex? bool isConvex = IsPointConvex(verts[start].v, verts[middle].v, verts[middle].v, verts[end].v, !isCW) && IsPointConvex(verts[middle].v, verts[end].v, verts[end].v, verts[start].v, !isCW) && IsPointConvex(verts[end].v, verts[start].v, verts[start].v, verts[middle].v, !isCW); if (!isConvex) { //reject the triangle start++; triangles.RemoveAt(triangles.Count - 1); continue; } bool noPointsIn = true; for (int i = 0; i < verts.Count; i++) { if (i != start && i != middle && i != end) if (MeshHelper.IsPointInTriangle(verts[i].v, verts[start].v, verts[middle].v, verts[end].v) && noPointsIn) { //there's a point in triangle noPointsIn = false; //reject the triangle start++; triangles.RemoveAt(triangles.Count - 1); break; } } if (noPointsIn) { earNotFound = false; //add triangle to set verts.RemoveAt(middle); } } } return triangles; }
public override void UpdateCollider() { C_PC2D.points = MeshHelper.ConvertVec3ToVec2(Vertices); }
public static List <Vector3> Simplify(List <Vector3> points, float minArea, bool isClosed, bool useCopy = true) { const int minPointsCount = 10; var pts = useCopy ? new List <Vector3>(points) : points; if (isClosed) { int prevPointCount; int index = 0; do { prevPointCount = pts.Count; while (index < pts.Count && pts.Count >= minPointsCount) { Vector2 p1 = pts[index]; Vector2 p2 = pts[(index + 1) % pts.Count]; Vector2 p3 = pts[(index + 2) % pts.Count]; var area = MeshHelper.GetTriangleArea(p1, p2, p3); if (area < minArea) { pts.RemoveAt((index + 1) % pts.Count); index += 2; } else { index++; } } index %= pts.Count; } while (prevPointCount != pts.Count); } else { int prevPointCount; do { prevPointCount = pts.Count; int index = 0; while (index < pts.Count - 2 && pts.Count >= minPointsCount) { Vector2 p1 = pts[index]; Vector2 p2 = pts[index + 1]; Vector2 p3 = pts[index + 2]; var area = MeshHelper.GetTriangleArea(p1, p2, p3); if (area < minArea) { pts.RemoveAt(index + 1); index += 2; } else { index++; } } } while (prevPointCount != pts.Count); } return(pts); }
public static float BoundingBoxArea(IList <Vector2> splinePoints) { var bounds = MeshHelper.GetBounds(splinePoints); return((bounds.z - bounds.x) * (bounds.w - bounds.y)); }
protected override void BuildMeshComponents() { #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft = new List <Vector2>(); cachedVertsRight = new List <Vector2>(); } #endregion List <Vector3> verticesList = new List <Vector3>(); List <int> trianglesList = new List <int>(); Vector2 center = new Vector2(); for (int i = 0; i < lineVerts.Length; i++) { center += lineVerts[i]; } center /= lineVerts.Length; for (int i = 0; i < lineVerts.Length; i++) { lineVerts[i] -= center; } int currentVertIndex = 0; int currentTriIndex = 0; //add first two vertices float angle = Mathf.Atan2(lineVerts[1].y - lineVerts[0].y, lineVerts[1].x - lineVerts[0].x); float oldAngle, angleDiff; Vector2 p1 = new Vector2(Mathf.Cos(angle + deg90), Mathf.Sin(angle + deg90)) * lineWidth; Vector2 p2 = new Vector2(Mathf.Cos(angle - deg90), Mathf.Sin(angle - deg90)) * lineWidth; if (p1 != p2) { verticesList.Add(lineVerts[currentVertIndex] + p1); verticesList.Add(lineVerts[currentVertIndex] + p2); #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft.Add(verticesList[verticesList.Count - 2]); cachedVertsRight.Add(verticesList[verticesList.Count - 1]); } #endregion } else { verticesList.Add(lineVerts[currentVertIndex]); #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft.Add(verticesList[verticesList.Count - 1]); cachedVertsRight.Add(verticesList[verticesList.Count - 1]); } #endregion } oldAngle = angle; currentVertIndex++; // add middle vertices for (int i = 0; i < lineVerts.Length - 2; i++, currentVertIndex++) { angle = Mathf.Atan2(lineVerts[currentVertIndex + 1].y - lineVerts[currentVertIndex].y, lineVerts[currentVertIndex + 1].x - lineVerts[currentVertIndex].x); angleDiff = oldAngle + MeshHelper.AngleDifference(oldAngle, angle) * 0.5f; p1 = new Vector2(Mathf.Cos(angleDiff + deg90), Mathf.Sin(angleDiff + deg90)) * lineWidth; p2 = new Vector2(Mathf.Cos(angleDiff - deg90), Mathf.Sin(angleDiff - deg90)) * lineWidth; if (p1 != p2) { verticesList.Add(lineVerts[currentVertIndex] + p1); verticesList.Add(lineVerts[currentVertIndex] + p2); trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 1); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 2); currentTriIndex += 2; } else { verticesList.Add(lineVerts[currentTriIndex] + p1); if (verticesList[verticesList.Count - 1] != verticesList[verticesList.Count - 2]) { trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 1); currentTriIndex++; } } #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft.Add(verticesList[verticesList.Count - 2]); cachedVertsRight.Add(verticesList[verticesList.Count - 1]); } #endregion oldAngle = angle; } //add last two vertices if (lineVerts[0] != lineVerts[currentVertIndex]) { angle = Mathf.Atan2(lineVerts[currentVertIndex].y - lineVerts[currentVertIndex - 1].y, lineVerts[currentVertIndex].x - lineVerts[currentVertIndex - 1].x); p1 = new Vector2(Mathf.Cos(angle + deg90), Mathf.Sin(angle + deg90)) * lineWidth; p2 = new Vector2(Mathf.Cos(angle - deg90), Mathf.Sin(angle - deg90)) * lineWidth; if (p1 != p2) { verticesList.Add(lineVerts[currentVertIndex] + p1); verticesList.Add(lineVerts[currentVertIndex] + p2); trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 1); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 2); } else { //make LineMesh loop if (verticesList[verticesList.Count - 1] != verticesList[verticesList.Count - 2]) { verticesList.Add(lineVerts[currentTriIndex] + p1); trianglesList.Add(currentTriIndex + 0); trianglesList.Add(currentTriIndex + 3); trianglesList.Add(currentTriIndex + 1); } } #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft.Add(verticesList[verticesList.Count - 2]); cachedVertsRight.Add(verticesList[verticesList.Count - 1]); } #endregion } else { oldAngle = Mathf.Atan2( lineVerts[0].y - lineVerts[currentVertIndex].y, lineVerts[0].x - lineVerts[currentVertIndex].x); angle = Mathf.Atan2( lineVerts[1].y - lineVerts[0].y, lineVerts[1].x - lineVerts[0].x); angleDiff = oldAngle + MeshHelper.AngleDifference(oldAngle, angle) * 0.5f - deg90; p1 = new Vector2(Mathf.Cos(angleDiff - deg90), Mathf.Sin(angleDiff - deg90)) * lineWidth; p2 = new Vector2(Mathf.Cos(angleDiff + deg90), Mathf.Sin(angleDiff + deg90)) * lineWidth; verticesList[0] = lineVerts[currentVertIndex] + p1; verticesList[1] = lineVerts[currentVertIndex] + p2; #region DoubleCollider if (useDoubleCollider) { cachedVertsLeft[0] = verticesList[0]; cachedVertsRight[0] = verticesList[1]; cachedVertsLeft.Add(verticesList[verticesList.Count - 2]); cachedVertsRight.Add(verticesList[verticesList.Count - 1]); } #endregion trianglesList.Add(0); trianglesList.Add(verticesList.Count - 1); trianglesList.Add(1); trianglesList.Add(verticesList.Count - 1); trianglesList.Add(0); trianglesList.Add(verticesList.Count - 2); } Vertices = verticesList.ToArray(); Triangles = trianglesList.ToArray(); UVs = MeshHelper.UVUnwrap(Vertices); }
//convert to quad public QuadrangleMesh ToQuad(bool attachRigidbody = true) { return(QuadrangleMesh.AddQuadrangle(transform.position, MeshHelper.ConvertVec3ToVec2(Vertices), Space.World, C_MR.material, attachRigidbody)); }
public override void UpdateCollider() { C_PC2D.SetPath(0, MeshHelper.ConvertVec3ToVec2(Vertices)); }
public static List<Vector2Triple> GetTriangles(List<Vector2> sourcePoints) { List<Vector2Triple> triangles = new List<Vector2Triple>(); int MAX = sourcePoints.Count * sourcePoints.Count; //temporary List of points List<Vector2> verts = sourcePoints; //was shape drawn clockwise? bool isCW = IsShapeClockWise(verts); int start = 0; int repeats = 0; while (verts.Count > 2 && repeats < MAX) { bool earNotFound = true; while (earNotFound && repeats < MAX) { repeats++; start %= verts.Count; int middle = (start + 1) % verts.Count; int end = (start + 2) % verts.Count; triangles.Add(new Vector2Triple(verts[start], verts[middle], verts[end])); //is current point convex? bool isConvex = IsPointConvex(verts[start], verts[middle], verts[middle], verts[end], !isCW) && IsPointConvex(verts[middle], verts[end], verts[end], verts[start], !isCW) && IsPointConvex(verts[end], verts[start], verts[start], verts[middle], !isCW); if (!isConvex) { //reject the triangle start++; triangles.RemoveAt(triangles.Count - 1); continue; } bool noPointsIn = true; for (int i = 0; i < verts.Count; i++) if (i != start && i != middle && i != end) if (MeshHelper.IsPointInTriangle(verts[i], verts[start], verts[middle], verts[end]) && noPointsIn) { //there's a point in triangle noPointsIn = false; //reject the triangle start++; triangles.RemoveAt(triangles.Count - 1); break; } if (noPointsIn) { earNotFound = false; //add triangle to set verts.RemoveAt(middle); } } } return triangles; }
protected override void BuildMeshComponents() { int doubleSides = 2 * Sides; Vertices = new Vector3[6 * Sides]; Triangles = new int[6 * 3 * Sides]; float angleDelta = deg360 / doubleSides; float angleShift = angleDelta * 0.5f; float outerAngleShift = angleDelta * 0.2f; int triangleIndex = 0; for (int i = 0; i < doubleSides; i++) { Vector3 innerVertPos = new Vector3(Mathf.Cos(i * angleDelta + angleShift), Mathf.Sin(i * angleDelta + angleShift)) * InnerRadius; Vector3 rootVertPos = new Vector3(Mathf.Cos(i * angleDelta + angleShift), Mathf.Sin(i * angleDelta + angleShift)) * RootRadius; Vector3 outerVertPos; if (i % 2 == 0) { outerVertPos = new Vector3(Mathf.Cos(i * angleDelta + angleShift + outerAngleShift), Mathf.Sin(i * angleDelta + angleShift + outerAngleShift)) * OuterRadius; } else { outerVertPos = new Vector3(Mathf.Cos(i * angleDelta + angleShift - outerAngleShift), Mathf.Sin(i * angleDelta + angleShift - outerAngleShift)) * OuterRadius; } Vertices[i * 3 + 0] = innerVertPos; Vertices[i * 3 + 1] = rootVertPos; Vertices[i * 3 + 2] = outerVertPos; int a = 3 * i; int b = 3 * i + 1; int c = (3 * (i + 1)) % (3 * doubleSides); int d = (3 * (i + 1) + 1) % (3 * doubleSides); Triangles[triangleIndex++] = d; Triangles[triangleIndex++] = b; Triangles[triangleIndex++] = c; Triangles[triangleIndex++] = b; Triangles[triangleIndex++] = a; Triangles[triangleIndex++] = c; //add tooth if (i % 2 == 0) { a = 3 * i + 1; b = 3 * i + 2; c = (3 * (i + 1) + 1) % (3 * doubleSides); d = (3 * (i + 1) + 2) % (3 * doubleSides); Triangles[triangleIndex++] = d; Triangles[triangleIndex++] = b; Triangles[triangleIndex++] = c; Triangles[triangleIndex++] = b; Triangles[triangleIndex++] = a; Triangles[triangleIndex++] = c; } } UVs = MeshHelper.UVUnwrap(Vertices); }