/// <summary> /// Create a new GameObject with a ProBuilderMesh component, MeshFilter, and MeshRenderer, then initializes the ProBuilderMesh with a set of positions and faces. /// </summary> /// <param name="positions">Vertex positions array.</param> /// <param name="faces">Faces array.</param> /// <returns>A reference to the new ProBuilderMesh component.</returns> public static ProBuilderMesh Create(IEnumerable <Vector3> positions, IEnumerable <Face> faces) { GameObject go = new GameObject(); ProBuilderMesh pb = go.AddComponent <ProBuilderMesh>(); go.name = "ProBuilder Mesh"; pb.m_MeshFormatVersion = k_MeshFormatVersion; pb.RebuildWithPositionsAndFaces(positions, faces); return(pb); }
// Set mesh geometry by extruding along a set of points. internal static void Extrude(IList <Vector3> points, float radius, int radiusRows, bool closeLoop, bool smooth, ref ProBuilderMesh target, IList <Quaternion> pointRotations = null) { if (points == null || points.Count < 2) { return; } int cnt = points.Count; int rows = System.Math.Max(3, radiusRows); int rowsPlus1 = rows + 1; int rowsPlus1Times2 = rows * 2; int vertexCount = ((closeLoop ? cnt : cnt - 1) * 2) * rowsPlus1Times2; bool vertexCountsMatch = false; // vertexCount == (target == null ? 0 : target.vertexCount); bool hasPointRotations = pointRotations != null && pointRotations.Count == points.Count; Vector3[] positions = new Vector3[vertexCount]; Face[] faces = vertexCountsMatch ? null : new Face[(closeLoop ? cnt : cnt - 1) * rows]; int triangleIndex = 0, faceIndex = 0, vertexIndex = 0; int segmentCount = (closeLoop ? cnt : cnt - 1); for (int i = 0; i < segmentCount; i++) { float secant_a, secant_b; Quaternion rotation_a = GetRingRotation(points, i, closeLoop, out secant_a); Quaternion rotation_b = GetRingRotation(points, (i + 1) % cnt, closeLoop, out secant_b); if (hasPointRotations) { rotation_a = rotation_a * pointRotations[i]; rotation_b = rotation_b * pointRotations[(i + 1) % cnt]; } Vector3[] ringA = VertexRing(rotation_a, points[i], radius, rowsPlus1); Vector3[] ringB = VertexRing(rotation_b, points[(i + 1) % cnt], radius, rowsPlus1); System.Array.Copy(ringA, 0, positions, vertexIndex, rowsPlus1Times2); vertexIndex += rowsPlus1Times2; System.Array.Copy(ringB, 0, positions, vertexIndex, rowsPlus1Times2); vertexIndex += rowsPlus1Times2; if (!vertexCountsMatch) { for (int n = 0; n < rowsPlus1Times2; n += 2) { faces[faceIndex] = new Face(new int[6] { triangleIndex, triangleIndex + 1, triangleIndex + rowsPlus1Times2, triangleIndex + rowsPlus1Times2, triangleIndex + 1, triangleIndex + rowsPlus1Times2 + 1 }); if (smooth) { faces[faceIndex].smoothingGroup = 2; } faceIndex++; triangleIndex += 2; } triangleIndex += rowsPlus1Times2; } } if (target != null) { if (faces != null) { target.RebuildWithPositionsAndFaces(positions, faces); } else { target.positions = positions; target.ToMesh(); target.Refresh(RefreshMask.UV | RefreshMask.Colors | RefreshMask.Normals | RefreshMask.Tangents); } } else { target = ProBuilderMesh.Create(positions, faces); } }