public static void ExtrudeMesh(Mesh srcMesh, Mesh extrudedMesh, Matrix4x4[] extrusion, Edge[] edges, bool invertFaces, CapMode capMode)
    {
        int extrudedVertexCount   = edges.Length * 2 * extrusion.Length;
        int triIndicesPerStep     = edges.Length * 6;
        int extrudedTriIndexCount = triIndicesPerStep * (extrusion.Length - 1);

        Vector3[] inputVertices  = srcMesh.vertices;
        Vector2[] inputUV        = srcMesh.uv;
        int[]     inputTriangles = srcMesh.triangles;

        Vector3[] vertices  = new Vector3[extrudedVertexCount + srcMesh.vertexCount * 2];
        Vector2[] uvs       = new Vector2[vertices.Length];
        int[]     triangles = new int[extrudedTriIndexCount + inputTriangles.Length * (int)capMode];

        // Build extruded vertices
        int v = 0;

        for (int i = 0; i < extrusion.Length; i++)
        {
            Matrix4x4 matrix = extrusion[i];
            float     vcoord = (float)i / (extrusion.Length - 1);
            foreach (Edge e in edges)
            {
                vertices[v + 0] = matrix.MultiplyPoint(inputVertices[e.vertexIndex[0]]);
                vertices[v + 1] = matrix.MultiplyPoint(inputVertices[e.vertexIndex[1]]);

                uvs[v + 0] = new Vector2(inputUV[e.vertexIndex[0]].x, vcoord);
                uvs[v + 1] = new Vector2(inputUV[e.vertexIndex[1]].x, vcoord);

                v += 2;
            }
        }

        // Build cap vertices
        // The bottom mesh we scale along it's negative extrusion direction. This way extruding a half sphere results in a capsule.
        if (capMode != CapMode.None)
        {
            for (int c = 0; c < 2; c++)
            {
                Matrix4x4 matrix         = extrusion[c == 0 ? 0 : extrusion.Length - 1];
                int       firstCapVertex = c == 0 ? extrudedVertexCount : extrudedVertexCount + inputVertices.Length;
                for (int i = 0; i < inputVertices.Length; i++)
                {
                    vertices[firstCapVertex + i] = matrix.MultiplyPoint(inputVertices[i]);
                    uvs[firstCapVertex + i]      = inputUV[i];
                }
            }
        }

        // Build extruded triangles
        for (int i = 0; i < extrusion.Length - 1; i++)
        {
            int baseVertexIndex = (edges.Length * 2) * i;
            int nextVertexIndex = (edges.Length * 2) * (i + 1);
            for (int e = 0; e < edges.Length; e++)
            {
                int triIndex = i * triIndicesPerStep + e * 6;

                triangles[triIndex + 0] = baseVertexIndex + e * 2;
                triangles[triIndex + 1] = nextVertexIndex + e * 2;
                triangles[triIndex + 2] = baseVertexIndex + e * 2 + 1;
                triangles[triIndex + 3] = nextVertexIndex + e * 2;
                triangles[triIndex + 4] = nextVertexIndex + e * 2 + 1;
                triangles[triIndex + 5] = baseVertexIndex + e * 2 + 1;
            }
        }

        // build cap triangles
        int triCount = inputTriangles.Length / 3;

        /*
         * // Top
         * {
         *      int firstCapVertex = extrudedVertexCount;
         *      int firstCapTriIndex = extrudedTriIndexCount;
         *      for (int i=0;i<triCount;i++)
         *      {
         *              triangles[i*3 + firstCapTriIndex + 0] = inputTriangles[i * 3 + 1] + firstCapVertex;
         *              triangles[i*3 + firstCapTriIndex + 1] = inputTriangles[i * 3 + 2] + firstCapVertex;
         *              triangles[i*3 + firstCapTriIndex + 2] = inputTriangles[i * 3 + 0] + firstCapVertex;
         *      }
         * }*/

        // Bottom
        if (capMode != CapMode.None)
        {
            int firstCapVertex   = extrudedVertexCount + inputVertices.Length;
            int firstCapTriIndex = extrudedTriIndexCount /*+ inputTriangles.Length*/;
            for (int i = 0; i < triCount; i++)
            {
                triangles[i * 3 + firstCapTriIndex + 0] = inputTriangles[i * 3 + 0] + firstCapVertex;
                triangles[i * 3 + firstCapTriIndex + 1] = inputTriangles[i * 3 + 2] + firstCapVertex;
                triangles[i * 3 + firstCapTriIndex + 2] = inputTriangles[i * 3 + 1] + firstCapVertex;
            }
        }

        if (invertFaces)
        {
            for (int i = 0; i < triangles.Length / 3; i++)
            {
                int temp = triangles[i * 3 + 0];
                triangles[i * 3 + 0] = triangles[i * 3 + 1];
                triangles[i * 3 + 1] = temp;
            }
        }

        extrudedMesh.Clear();
        extrudedMesh.name      = "extruded";
        extrudedMesh.vertices  = vertices;
        extrudedMesh.uv        = uvs;
        extrudedMesh.triangles = triangles;
        extrudedMesh.RecalculateNormals();
        ;
    }
 public static void ExtrudeMesh(Mesh srcMesh, Mesh extrudedMesh, Matrix4x4[] extrusion, bool invertFaces, CapMode capMode)
 {
     Edge[] edges = BuildManifoldEdges(srcMesh);
     ExtrudeMesh(srcMesh, extrudedMesh, extrusion, edges, invertFaces, capMode);
 }