/// <summary>
    /// Create the mesh
    /// </summary>
    /// <param name="a_vertices"></param>
    /// <param name="a_shapeToExtrude"></param>
    /// <returns></returns>
    private void CreateTackMesh(ProTwoDShape a_twoDShape)
    {
        //loop though all the vertices
        for (int i = 0; i < proMesh.Vertices.Count; i++)
        {
            //this is to check if we are on the last vertex of the twoDShape
            //e.x ((1 + 1) / 2) % 1 = 1
            //we are on the end of the twoDShape
            //we can not add trianles
            //so continue
            float value = ((i + 1) / (float)a_twoDShape.Vertices.Count) % 1f;
            if (i != 0 && value == 0)
            {
                continue;
            }

            //Make tri
            proMesh.Triangles.Add(i);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1);

            proMesh.Triangles.Add(i);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1);
            proMesh.Triangles.Add(i + 1);
        }
    }
    /// <summary>
    /// Create all the vertices for the mesh
    /// </summary>
    private void CreateTrackVertices()
    {
        ProTwoDShape pTwoDShape = CreateTwoDShape(MeshToExtrude);

        //Create an array of OrientedPoint
        OrientedPoint[] oPoints = new OrientedPoint[_spline.SmoothNumPoints];
        //Assign each oPoint
        for (int i = 0; i < oPoints.Length; i++)
        {
            //Get the point before current point
            Vector3 lastPoint = _spline.AllSmoothPoints[((i - 1) + oPoints.Length) % oPoints.Length];
            //Get current point
            Vector3 currentPoint = _spline.AllSmoothPoints[i];
            //Get the next point
            Vector3 nextPoint = _spline.AllSmoothPoints[((i + 1) + oPoints.Length) % oPoints.Length];

            //Get the direction from currentPoint to lastPoint
            Vector3 lc = currentPoint - lastPoint;
            //Get the direction from nextPoint to currentPoint
            Vector3 cn = nextPoint - currentPoint;

            //Avgrage the start and end points for each curve
            //Set the points direction. This direction is the forward vector
            Vector3 dir = (lc + cn) * 0.5f;
            dir.Normalize();

            //Get the right Vector
            dir = Vector3.Cross(dir, Vector3.up).normalized;

            //new the oPoint
            oPoints[i] = new OrientedPoint(_spline.AllSmoothPoints[i],
                                           Quaternion.LookRotation(dir, Vector3.up));
        }

        //Generate all the center points on the mesh
        //This will also set the forward rotation
        //and UV for each point
        for (int i = 0; i < oPoints.Length; i++)
        {
            for (int j = 0; j < pTwoDShape.Vertices.Count; j++)
            {
                //get the forward vector
                Vector3 fwd = oPoints[i].Rotation * Vector3.forward;
                //get the position
                Vector3 pos = oPoints[i].Position + (pTwoDShape.Vertices[j].x * fwd);
                pos.y = oPoints[i].Position.y + pTwoDShape.Vertices[j].y;

                //add the new vertex to the proMesh.Vertices list
                proMesh.Vertices.Add(pos);

                //Setup the uv coords for this vertex
                float   x  = (float)j / (pTwoDShape.Vertices.Count - 1);
                float   y  = (float)i / oPoints.Length;
                Vector2 uv = new Vector2(x, y);
                proMesh.Uvs.Add(uv);
            }
        }
    }
 public void CreateTrack()
 {
     if (path.NumPoints > 0)
     {
         proMesh = new ProMesh();
         ProTwoDShape pTwoDShape = CreateTwoDShape(MeshToExtrude);
         CreateTrackVertices();
         CreateTackMesh(pTwoDShape);
         CreateCurbVertices();
     }
     else
     {
         Debug.Log("SPLICE CREATOR: There is no spline. Make sure there is a Voronoi diagram gnerated. Then press the" +
                   " 'Generate Spline'");
     }
 }
    /// <summary>
    /// Create all the vertices for the curbs around the track
    /// </summary>
    private void CreateCurbVertices()
    {
        ProTwoDShape curbMesh = CreateTwoDShape(CurbMesh);

        float center = curbMesh.Center;

        for (int i = 0; i < curbMesh.Vertices.Count; i++)
        {
            Vector2 v = curbMesh.Vertices[i];
            v *= 100;
            curbMesh.Vertices[i] = v;
        }
        curbMesh.ShapeWidth *= 100;

        //Store all the curb meshes made
        List <CombineInstance> allCurbMeshes = new List <CombineInstance>();

        if (true)
        {
            //Go though all the vertices in the track mesh
            if (true)
            {
                int i = 0;
                //Store all the vertices for the current curb
                List <Vector3> curbVertices = new List <Vector3>();
                //Store all the uvs for the current curb
                List <Vector2> curbUvs = new List <Vector2>();
                //Store all the triangle for the current curb
                List <int> curbTriangles = new List <int>();

                //Get the number of segmnets each spline curve it broken
                //up into
                int segStart = proMesh.Vertices.Count;

                //if we are at the start of a curve
                if (i % segStart == 0)
                {
                    //Get the distance for the left side of the spline
                    float splineLeft = (proMesh.Vertices[i] -
                                        proMesh.Vertices[Helper.LoopIndex(i, segStart - 2, proMesh.Vertices.Count)]).magnitude;
                    //Get the distance for the right side of the spline
                    float splineRight = (proMesh.Vertices[Helper.ALoopIndex(i, proMesh.Vertices.Count)] -
                                         proMesh.Vertices[Helper.LoopIndex(i, segStart - 1, proMesh.Vertices.Count)]).magnitude;

                    //check which side of the track mesh is smaller
                    //this is the side which will have the curb made for
                    if (true)
                    {
                        curbMesh.Vertices.Reverse();
                        //Setup the vertices
                        for (int j = 0; j < segStart; j += 2)
                        {
                            for (int k = 0; k < curbMesh.Vertices.Count; k++)
                            {
                                Vector3 cV;
                                Vector3 cVT;
                                Vector3 dir;
                                if (j == 0 || j == segStart - 2)
                                {
                                    cV  = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)];
                                    cVT = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)];
                                }
                                else
                                {
                                    cV  = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)];
                                    cVT = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)];
                                }

                                dir = cV - cVT;
                                //ROTATE VERTICES

                                //Set the new vertex position
                                Vector3 pos;
                                if (curbMesh.Vertices[k].x < 0)
                                {
                                    pos = cVT + (curbMesh.Vertices[k].x * dir.normalized);
                                }
                                else
                                {
                                    pos = cV + (curbMesh.Vertices[k].x * dir.normalized);
                                }

                                if (onPlanXZ)
                                {
                                    pos.y = 0 + curbMesh.Vertices[k].y;
                                }
                                else
                                {
                                    pos.y += curbMesh.Vertices[k].y;
                                }

                                //add curb to vertex list
                                curbVertices.Add(pos);

                                //Set the new vertex uv
                                float   x  = (float)j / (curbMesh.Vertices.Count - 1);
                                float   y  = (float)i / 4 + 1;
                                Vector2 uv = new Vector2(x, y);
                                curbUvs.Add(uv);
                            }
                        }
                        //for (int j = segStart - 2; j < segStart; j += 2)
                        //{
                        //    for (int k = 0; k < curbMesh.Vertices.Count; k++)
                        //    {
                        //        //ROTATE VERTICES
                        //        Vector3 cV = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)];
                        //        Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)];
                        //        Vector3 dir = cV -
                        //                      cVT;

                        //        //Set the new vertex position
                        //        Vector3 pos;
                        //        if (curbMesh.Vertices[k].x < 0)
                        //            pos = cVT + (curbMesh.Vertices[k].x * dir.normalized);
                        //        else
                        //            pos = cV + (curbMesh.Vertices[k].x * dir.normalized);


                        //        pos.y = 0 + curbMesh.Vertices[k].y;


                        //        //add curb to vertex list
                        //        curbVertices.Add(pos);

                        //        //Set the new vertex uv
                        //        float x = (float)j / (curbMesh.Vertices.Count - 1);
                        //        float y = (float)i / 4 + 1;
                        //        Vector2 uv = new Vector2(x, y);
                        //        curbUvs.Add(uv);
                        //    }
                        //}
                        //Setup the triangles
                        for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count); j++)
                        {
                            float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f;
                            if (value != 0)
                            {
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j + 1);
                            }
                        }
                        curbMesh.Vertices.Reverse();
                    }

                    CombineInstance ci = new CombineInstance();
                    Mesh            m  = new Mesh();
                    m.vertices   = curbVertices.ToArray();
                    m.uv         = curbUvs.ToArray();
                    m.triangles  = curbTriangles.ToArray();
                    ci.mesh      = m;
                    ci.transform = transform.localToWorldMatrix;
                    allCurbMeshes.Add(ci);
                }
            }
        }

        curbsMesh = new Mesh();
        //Combine all curb meshs in to one
        curbsMesh.CombineMeshes(allCurbMeshes.ToArray());

        //Clean up all the meshes by destroying them
        for (int i = 0; i < allCurbMeshes.Count; i++)
        {
            allCurbMeshes[i].mesh.Clear();
        }

        //then create a new GameObject add a mesh filter and mesh renderer to it
        if (!curb)
        {
            curb = new GameObject("Curbs");
        }
        if (!curb.GetComponent <MeshFilter>())
        {
            curb.AddComponent <MeshFilter>();
        }
        if (!curb.GetComponent <MeshRenderer>())
        {
            curb.AddComponent <MeshRenderer>();
        }

        curbsMesh.RecalculateNormals();

        //set the mesh filter and mesh renderer
        curb.GetComponent <MeshFilter>().sharedMesh       = curbsMesh;
        curb.GetComponent <MeshRenderer>().sharedMaterial = CurbMaterial;
    }
    /// <summary>
    /// Create all the vertices for the curbs around the track
    /// </summary>
    private void CreateCurbVertices()
    {
        ProTwoDShape curbMesh = CreateTwoDShape(CurbMesh);

        for (int i = 0; i < curbMesh.Vertices.Count; i++)
        {
            Vector2 v = curbMesh.Vertices[i];
            v *= 100;
            curbMesh.Vertices[i] = v;
        }
        curbMesh.ShapeWidth *= 100;

        //Store all the curb meshes made
        List <CombineInstance> allCurbMeshes = new List <CombineInstance>();

        if (Spline.SplineCurveType == CurveType.Bezier)
        {
            //Go though all the vertices in the track mesh
            for (int i = 0; i < proMesh.Vertices.Count; i++)
            {
                //Store all the vertices for the current curb
                List <Vector3> curbVertices = new List <Vector3>();
                //Store all the uvs for the current curb
                List <Vector2> curbUvs = new List <Vector2>();
                //Store all the triangle for the current curb
                List <int> curbTriangles = new List <int>();

                //Get the number of segmnets each spline curve it broken
                //up into
                int segStart = ((Spline.SmoothSplineResoultion + 1) * 2);

                //if we are at the start of a curve
                if (i % segStart == 0)
                {
                    //Get the distance for the left side of the spline
                    float splineLeft = (proMesh.Vertices[i] -
                                        proMesh.Vertices[Helper.LoopIndex(i, segStart - 2, proMesh.Vertices.Count)]).magnitude;
                    //Get the distance for the right side of the spline
                    float splineRight = (proMesh.Vertices[Helper.ALoopIndex(i, proMesh.Vertices.Count)] -
                                         proMesh.Vertices[Helper.LoopIndex(i, segStart - 1, proMesh.Vertices.Count)]).magnitude;

                    //check which side of the track mesh is smaller
                    //this is the side which will have the curb made for
                    if (splineLeft < splineRight)
                    {
                        curbMesh.Vertices.Reverse();
                        //Setup the vertices
                        for (int j = 0; j < segStart; j += 2)
                        {
                            for (int k = 0; k < curbMesh.Vertices.Count; k++)
                            {
                                //ROTATE VERTICES
                                Vector3 cV  = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)];
                                Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)];
                                Vector3 dir = cV -
                                              cVT;

                                //Set the new vertex position
                                Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized);
                                pos += (curbMesh.ShapeWidth) * dir.normalized;

                                //if we are on the first or last row of vertices for this curb
                                //clamp the y value to 0
                                if (j == 0 || j == (segStart - 2))
                                {
                                    pos.y = 0;
                                }
                                else
                                {
                                    pos.y = 0 + curbMesh.Vertices[k].y;
                                }

                                //add curb to vertex list
                                curbVertices.Add(pos);

                                //Set the new vertex uv
                                float   x  = (float)j / (curbMesh.Vertices.Count - 1);
                                float   y  = (float)i / Spline.SmoothSplineResoultion + 1;
                                Vector2 uv = new Vector2(x, y);
                                curbUvs.Add(uv);
                            }
                        }
                        //Setup the triangles
                        for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count); j++)
                        {
                            float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f;
                            if (value != 0)
                            {
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j + 1);
                            }
                        }
                        curbMesh.Vertices.Reverse();
                    }
                    else if (splineLeft > splineRight)
                    {
                        for (int j = 1; j < segStart; j += 2)
                        {
                            for (int k = 0; k < curbMesh.Vertices.Count; k++)
                            {
                                //ROTATE VERTICES
                                Vector3 cV  = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)];
                                Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j - 1, proMesh.Vertices.Count)];
                                Vector3 dir = cV -
                                              cVT;

                                Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized);
                                pos += (curbMesh.ShapeWidth) * dir.normalized;

                                //if we are on the first or last row of vertices for this curb
                                //clamp the y value to 0
                                if (j == 1 || j == (segStart - 1))
                                {
                                    pos.y = 0;
                                }
                                else
                                {
                                    pos.y = 0 + curbMesh.Vertices[k].y;
                                }

                                //add curb inner vertex first
                                //curbVertices.Add(cV + (dir.normalized * 2));
                                //curbVertices.Add(cV);
                                curbVertices.Add(pos);

                                float   x  = (float)j / (curbMesh.Vertices.Count - 1);
                                float   y  = (float)i / segStart;
                                Vector2 uv = new Vector2(x, y);
                                curbUvs.Add(uv);
                            }
                        }
                        //Setup the triangles
                        for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 2); j++)
                        {
                            float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f;
                            if (value != 0)
                            {
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);

                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j + 1);
                            }
                        }
                    }

                    CombineInstance ci = new CombineInstance();
                    Mesh            m  = new Mesh();
                    m.vertices   = curbVertices.ToArray();
                    m.uv         = curbUvs.ToArray();
                    m.triangles  = curbTriangles.ToArray();
                    ci.mesh      = m;
                    ci.transform = transform.localToWorldMatrix;
                    allCurbMeshes.Add(ci);
                }
            }
        }
        else if (Spline.SplineCurveType == CurveType.CatmullRom)
        {
            //create the curbs from the control points. This assumes that the sharepest
            //part of the curve is the control point

            //Go though all the vertices in the track mesh
            for (int i = 0; i < proMesh.Vertices.Count; i++)
            {
                //Store all the vertices for the current curb
                List <Vector3> curbVertices = new List <Vector3>();
                //Store all the uvs for the current curb
                List <Vector2> curbUvs = new List <Vector2>();
                //Store all the triangle for the current curb
                List <int> curbTriangles = new List <int>();


                //Get the number of segmnets each spline curve it broken
                //up into
                int segStart = ((Spline.SmoothSplineResoultion + 1) * 2);

                if (i % segStart == 0)
                {
                    //Get the overall offset value form the control point
                    //this is the number of vertices from the control point
                    int offset = (segStart * 2) / 8;

                    //Get the start and end vertex point for the left side of the mesh
                    int leftStartIndex = Helper.LoopIndex(i, -(offset + 2), proMesh.Vertices.Count);
                    int leftEndIndex   = Helper.LoopIndex(i, (offset), proMesh.Vertices.Count);


                    //Get the distance for the left side of the spline
                    float splineLeft = (proMesh.Vertices[leftStartIndex] -
                                        proMesh.Vertices[leftEndIndex]).magnitude;

                    //Get the start and end vertex point for the right side of the mesh
                    int rightStartIndex = Helper.LoopIndex(i, -(offset + 1), proMesh.Vertices.Count);
                    int rightEndIndex   = Helper.LoopIndex(i, (offset + 1), proMesh.Vertices.Count);

                    //Get the distance for the right side of the spline
                    float splineRight = (proMesh.Vertices[rightStartIndex] -
                                         proMesh.Vertices[rightEndIndex]).magnitude;

                    //check which side of the track mesh is smaller
                    //this is the side which will have the curb made for
                    if (splineLeft < splineRight)
                    {
                        int cIndex = leftStartIndex;
                        curbMesh.Vertices.Reverse();
                        //create mesh
                        for (int j = 0; j < (offset * 2 + 1); j += 2)
                        {
                            cIndex = Helper.LoopIndex(leftStartIndex, j, proMesh.Vertices.Count);
                            for (int k = 0; k < curbMesh.Vertices.Count; k++)
                            {
                                //ROTATE VERTICES
                                Vector3 cV  = proMesh.Vertices[cIndex];
                                Vector3 cVT = proMesh.Vertices[Helper.ALoopIndex(cIndex, proMesh.Vertices.Count)];
                                Vector3 dir = cV -
                                              cVT;

                                //Set the new vertex position
                                Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized);
                                pos += (curbMesh.ShapeWidth) * dir.normalized;

                                //if we are on the first or last row of vertices for this curb
                                //clamp the y value to 0
                                if (j == 0 || j == (offset * 2 + 1) - 1)
                                {
                                    pos.y = 0;
                                }
                                else
                                {
                                    pos.y = 0 + curbMesh.Vertices[k].y;
                                }

                                //add curb to vertex list
                                curbVertices.Add(pos);

                                //Set the new vertex uv
                                float   x  = (float)j / (curbMesh.Vertices.Count - 1);
                                float   y  = (float)i / Spline.SmoothSplineResoultion + 1;
                                Vector2 uv = new Vector2(x, y);
                                curbUvs.Add(uv);
                            }
                        }

                        //Setup the triangles
                        for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 1); j++)
                        {
                            float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f;
                            if (value != 0)
                            {
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j + 1);
                            }
                        }
                        curbMesh.Vertices.Reverse();

                        //Add new mesh to the combine instance list
                        CombineInstance ci = new CombineInstance();
                        Mesh            m  = new Mesh();
                        m.vertices   = curbVertices.ToArray();
                        m.uv         = curbUvs.ToArray();
                        m.triangles  = curbTriangles.ToArray();
                        ci.mesh      = m;
                        ci.transform = transform.localToWorldMatrix;
                        allCurbMeshes.Add(ci);
                    }
                    else
                    {
                        int cIndex = rightStartIndex;

                        //create mesh
                        for (int j = 0; j < (offset * 2 + 1); j += 2)
                        {
                            cIndex = Helper.LoopIndex(rightStartIndex, j, proMesh.Vertices.Count);

                            for (int k = 0; k < curbMesh.Vertices.Count; k++)
                            {
                                Vector3 cV  = proMesh.Vertices[cIndex];
                                Vector3 cVT = proMesh.Vertices[Helper.SLoopIndex(cIndex, proMesh.Vertices.Count)];
                                Vector3 dir = cV -
                                              cVT;

                                //Set the new vertex position
                                Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized);
                                pos += (curbMesh.ShapeWidth) * dir.normalized;

                                //if we are on the first or last row of vertices for this curb
                                //clamp the y value to 0
                                if (j == 0 || j == (offset * 2 + 1) - 1)
                                {
                                    pos.y = 0;
                                }
                                else
                                {
                                    pos.y = 0 + curbMesh.Vertices[k].y;
                                }

                                //add curb to vertex list
                                curbVertices.Add(pos);

                                //Set the new vertex uv
                                float   x  = (float)j / (curbMesh.Vertices.Count - 1);
                                float   y  = (float)i / Spline.SmoothSplineResoultion + 1;
                                Vector2 uv = new Vector2(x, y);
                                curbUvs.Add(uv);
                            }
                        }
                        //Setup the triangles
                        for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 1); j++)
                        {
                            float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f;
                            if (value != 0)
                            {
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j);
                                curbTriangles.Add(j + curbMesh.Vertices.Count + 1);
                                curbTriangles.Add(j + 1);
                            }
                        }

                        //Add new mesh to the combine instance list
                        CombineInstance ci = new CombineInstance();
                        Mesh            m  = new Mesh();
                        m.vertices   = curbVertices.ToArray();
                        m.uv         = curbUvs.ToArray();
                        m.triangles  = curbTriangles.ToArray();
                        ci.mesh      = m;
                        ci.transform = transform.localToWorldMatrix;
                        allCurbMeshes.Add(ci);
                    }
                }
            }
        }
        curbsMesh = new Mesh();
        //Combine all curb meshs in to one
        curbsMesh.CombineMeshes(allCurbMeshes.ToArray());

        //Clean up all the meshes by destroying them
        for (int i = 0; i < allCurbMeshes.Count; i++)
        {
            allCurbMeshes[i].mesh.Clear();
        }
    }
    /// <summary>
    /// Create the mesh
    /// </summary>
    /// <param name="a_vertices"></param>
    /// <param name="a_shapeToExtrude"></param>
    /// <returns></returns>
    private Mesh CreateTackMesh(ProTwoDShape a_twoDShape)
    {
        //loop though all the vertices
        for (int i = 0; i < proMesh.Vertices.Count; i++)
        {
            //this is to check if we are on the last vertex of the twoDShape
            //e.x ((1 + 1) / 2) % 1 = 1
            //we are on the end of the twoDShape
            //we can not add trianles
            //so continue
            float value = ((i + 1) / (float)a_twoDShape.Vertices.Count) % 1f;
            if (i != 0 && value == 0)
            {
                continue;
            }

            //Make tri
            proMesh.Triangles.Add(i);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1);

            proMesh.Triangles.Add(i);
            proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1);
            proMesh.Triangles.Add(i + 1);
        }

        //create new lists for vertices, triangles and uvs
        List <Vector3> meshVer = new List <Vector3>();
        List <int>     meshTri = new List <int>();
        List <Vector2> meshUV  = new List <Vector2>();

        //store the current vertex/triangle count
        int currentVertexCount   = 0;
        int currentTriangleCount = 0;

        for (int i = 0; i < (proMesh.Vertices.Count / a_twoDShape.Vertices.Count) + 1; i++)
        {
            //if the currentVertexCount is greater than proMesh.Vertices.Count
            //then break
            if (currentVertexCount > proMesh.Vertices.Count - 1)
            {
                break;
            }

            //Add vertex line
            for (int j = 0; j < a_twoDShape.Vertices.Count; j++)
            {
                meshVer.Add(proMesh.Vertices[j + currentVertexCount]);
                meshUV.Add(proMesh.Uvs[j + currentVertexCount]);
            }
            //incerment currentVertexCount
            currentVertexCount += a_twoDShape.Vertices.Count;

            //add triangle line
            if (currentVertexCount >= a_twoDShape.Vertices.Count * 2)
            {
                for (int j = 0; j < ((a_twoDShape.Vertices.Count * 2) - 2) * 3; j++)
                {
                    meshTri.Add(proMesh.Triangles[j + currentTriangleCount]);
                }
                //incerment currentTriangleCount
                currentTriangleCount += ((a_twoDShape.Vertices.Count * 2) - 2) * 3;
            }
        }

        //Check if the spline has been closed. If it is
        //then do nothing. Otherwise close it
        if (_spline.SmoothSplineClosed)
        {
            int lastIndex = proMesh.Vertices.Count - 1;

            meshTri.Add(lastIndex - 1);
            meshTri.Add(0);
            meshTri.Add(1);

            meshTri.Add(lastIndex - 1);
            meshTri.Add(1);
            meshTri.Add(lastIndex);
        }

        //create a new mesh and assign the vertices, triangles and uvs
        Mesh mesh = new Mesh();

        mesh.vertices  = meshVer.ToArray();
        mesh.triangles = meshTri.ToArray();
        mesh.uv        = meshUV.ToArray();
        mesh.RecalculateNormals();

        //return mesh
        return(mesh);
    }