Exemple #1
0
        // 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);
            }
        }