/// <summary>
    /// Display all the smoothed points of the spline
    /// </summary>
    private void DisplaySplineSmoothPoints()
    {
        //check if AllSmoothPoints is valid
        if (sc.Spline.AllSmoothPoints != null)
        {
            //if AllSmoothPoints is valid then loop though all the points
            //drawing them and connecting them
            for (int i = 0; i < sc.Spline.AllSmoothPoints.Count; i++)
            {
                Handles.color = Color.yellow;
                Handles.CylinderHandleCap(0, sc.Spline.AllSmoothPoints[i],
                                          Quaternion.AngleAxis(90, Vector3.right), 2f,
                                          EventType.Repaint);

                Handles.color = Color.green;
                Handles.DrawLine(sc.Spline.AllSmoothPoints[i],
                                 sc.Spline.AllSmoothPoints[Helper.ALoopIndex(i, sc.Spline.AllSmoothPoints.Count)]);
            }
        }
    }
    /// <summary>
    /// Display all the raw points of the spline
    /// </summary>
    private void DisplaySplineRawPoints()
    {
        //check if AllRawPoints is not null
        if (sc.Spline.AllRawPoints != null)
        {
            //if AllRawPoints is valid then loop though all the points
            //drawing then and connecting them to the next point
            for (int i = 0; i < sc.Spline.AllRawPoints.Count; i++)
            {
                Handles.color = Color.red;
                Handles.CylinderHandleCap(0, sc.Spline.AllRawPoints[i],
                                          Quaternion.AngleAxis(90, Vector3.right), 25f,
                                          EventType.Repaint);

                Handles.color = Color.magenta;
                Handles.DrawLine(sc.Spline.AllRawPoints[i],
                                 sc.Spline.AllRawPoints[Helper.ALoopIndex(i, sc.Spline.AllRawPoints.Count)]);
            }
        }
    }
    /// <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>
    /// Display all the control points
    /// </summary>
    private void DisplaySplineControlPoints()
    {
        //if ControlPoints is valid
        if (sc.Spline.ControlPoints != null)
        {
            //if unApplliedControlPoints is null
            //then set unApplliedControlPoints to the spline's control points
            if (unApplliedControlPoints == null || unApplliedControlPoints.Count != sc.Spline.ControlPoints.Count)
            {
                unApplliedControlPoints = sc.Spline.ControlPoints;
            }

            //If the control points are modifiable
            //them check for changes to the points
            if (sc.Spline.ControlPointsModifiable)
            {
                if (sc.Spline.SplineCurveType == CurveType.Bezier)
                {
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i += 3)
                    {
                        //Draw the start and end control point
                        Handles.color = (i != 0) ? Color.blue : Color.black;
                        Vector3 newPos = Handles.FreeMoveHandle(unApplliedControlPoints[i],
                                                                Quaternion.identity, 8f, Vector3.zero,
                                                                Handles.CylinderHandleCap);
                        //if newPos is not the same as the control point on the spline
                        if (sc.Spline.ControlPoints[i] != newPos)
                        {
                            //set unSavedChanges to true
                            unSavedChanges = true;
                            //set unApplliedControlPoints[i] to newPos
                            unApplliedControlPoints[i] = newPos;
                        }
                        newPos = Handles.FreeMoveHandle(unApplliedControlPoints[i + 2],
                                                        Quaternion.identity, 8f, Vector3.zero,
                                                        Handles.CylinderHandleCap);
                        //if newPos is not the same as the control point on the spline
                        if (sc.Spline.ControlPoints[i + 2] != newPos)
                        {
                            //set unSavedChanges to true
                            unSavedChanges = true;
                            //set unApplliedControlPoints[i] to newPos
                            unApplliedControlPoints[i + 2] = newPos;
                        }

                        //Draw the site point
                        Handles.color = Color.red;
                        newPos        = Handles.FreeMoveHandle(unApplliedControlPoints[i + 1],
                                                               Quaternion.identity, 8f, Vector3.zero,
                                                               Handles.CylinderHandleCap);
                        //if newPos is not the same as the control point on the spline
                        if (sc.Spline.ControlPoints[i + 1] != newPos)
                        {
                            //set unSavedChanges to true
                            unSavedChanges = true;
                            //set unApplliedControlPoints[i] to newPos
                            unApplliedControlPoints[i + 1] = newPos;
                        }
                    }
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i += 3)
                    {
                        //Draw the line between the control points
                        Handles.color = Color.cyan;
                        Handles.DrawBezier(unApplliedControlPoints[i], unApplliedControlPoints[i + 2],
                                           unApplliedControlPoints[i + 1], unApplliedControlPoints[i + 1],
                                           Color.cyan, null, 2);
                        Handles.DrawLine(sc.Spline.ControlPoints[i + 2], sc.Spline.ControlPoints[Helper.LoopIndex(i, 3, sc.Spline.ControlPoints.Count)]);
                    }
                }
                else if (sc.Spline.SplineCurveType == CurveType.CatmullRom)
                {
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i++)
                    {
                        //Draw the start and end control point
                        Handles.color = Color.red;
                        Vector3 newPos = Handles.FreeMoveHandle(unApplliedControlPoints[i],
                                                                Quaternion.identity, 8f, Vector3.zero,
                                                                Handles.CylinderHandleCap);
                        //if newPos is not the same as the control point on the spline
                        if (sc.Spline.ControlPoints[i] != newPos)
                        {
                            //set unSavedChanges to true
                            unSavedChanges = true;
                            //set unApplliedControlPoints[i] to newPos
                            unApplliedControlPoints[i] = newPos;
                        }
                    }
                    List <Vector3> points = new List <Vector3>();
                    //setup all the catmull-rom points to draw
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i++)
                    {
                        for (int j = 0; j < sc.Spline.SmoothSplineResoultion; j++)
                        {
                            points.Add(GetCatmullRom(unApplliedControlPoints[Helper.SLoopIndex(i, sc.Spline.ControlPoints.Count)],
                                                     unApplliedControlPoints[i],
                                                     unApplliedControlPoints[Helper.ALoopIndex(i, sc.Spline.ControlPoints.Count)],
                                                     unApplliedControlPoints[Helper.LoopIndex(i, 2, sc.Spline.ControlPoints.Count)],
                                                     j * (1f / sc.Spline.SmoothSplineResoultion)));
                        }
                    }
                    Handles.color = Color.cyan;
                    //draw all the points
                    for (int i = 0; i < points.Count; i++)
                    {
                        Handles.DrawLine(points[i], points[Helper.ALoopIndex(i, points.Count)]);
                    }
                }
            }
            else
            {
                if (sc.Spline.SplineCurveType == CurveType.Bezier)
                {
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i += 3)
                    {
                        //Draw the start and end control point
                        Handles.color = Color.blue;
                        Handles.CylinderHandleCap(0, sc.Spline.ControlPoints[i],
                                                  Quaternion.AngleAxis(90, Vector3.right), 8f,
                                                  EventType.Repaint);

                        Handles.CylinderHandleCap(0, sc.Spline.ControlPoints[i + 2],
                                                  Quaternion.AngleAxis(90, Vector3.right), 8f,
                                                  EventType.Repaint);


                        //Draw the site point
                        Handles.color = Color.red;
                        Handles.CylinderHandleCap(0, sc.Spline.ControlPoints[i + 1],
                                                  Quaternion.AngleAxis(90, Vector3.right), 8f,
                                                  EventType.Repaint);

                        //Draw the line between the control points
                        Handles.color = Color.cyan;
                        Handles.DrawLine(sc.Spline.ControlPoints[i], sc.Spline.ControlPoints[i + 1]);
                        Handles.DrawLine(sc.Spline.ControlPoints[i + 1], sc.Spline.ControlPoints[i + 2]);
                        Handles.DrawLine(sc.Spline.ControlPoints[i + 2], sc.Spline.ControlPoints[Helper.LoopIndex(i, 3, sc.Spline.ControlPoints.Count)]);
                    }
                }
                else if (sc.Spline.SplineCurveType == CurveType.CatmullRom)
                {
                    for (int i = 0; i < sc.Spline.ControlPoints.Count; i++)
                    {
                        //Draw the site point
                        Handles.color = Color.red;
                        Handles.CylinderHandleCap(0, sc.Spline.ControlPoints[i],
                                                  Quaternion.AngleAxis(90, Vector3.right), 8f,
                                                  EventType.Repaint);

                        //Draw the line between the control points
                        Handles.color = Color.cyan;
                        Handles.DrawLine(sc.Spline.ControlPoints[i], sc.Spline.ControlPoints[Helper.ALoopIndex(i, sc.Spline.ControlPoints.Count)]);
                    }
                }
            }
        }
    }
    /// <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>
    /// Generate the spline from all the current control points
    /// </summary>
    private void SmoothSplineFromControlPoints(List <Vector3> a_newControlPoints)
    {
        //Set ControlPoints to a_newControlPoints
        ControlPoints = a_newControlPoints;

        //List of new points. These points will be oriented
        List <OrientedPoint> splineEdge = new List <OrientedPoint>();

        if (SplineCurveType == CurveType.Bezier)
        {
            //Loop though allSmoothPoints
            for (int i = 1; i < ControlPoints.Count; i += 3)
            {
                //Check if two site's are close and facing the same direction
                //if there are within a range then set it as one point
                Vector3 cSite = ControlPoints[i];
                Vector3 nSite = ControlPoints[Helper.LoopIndex(i, 3, ControlPoints.Count)];

                //Get if the sites are within range
                if ((cSite - nSite).magnitude < 50)
                {
                    //if we are connecting the first and last site points
                    //remove the first set of points
                    if (Helper.ALoopIndex(i, ControlPoints.Count) == 0)
                    {
                        splineEdge.RemoveRange(0, smoothSplineSegmentResoultion + 1);
                    }

                    //Get all the control points for the current curve
                    Vector3 startPoint = ControlPoints[Helper.SLoopIndex(i, ControlPoints.Count)];
                    Vector3 midPoint   = ControlPoints[i];
                    Vector3 endPoint   = ControlPoints[Helper.ALoopIndex(i, ControlPoints.Count)];

                    //get the average direction
                    Vector3 dir = (((midPoint - startPoint) + (endPoint - midPoint)) * 0.5f).normalized;

                    //Make a new list for the curve
                    List <Vector3> newOPoints = new List <Vector3>();
                    for (int j = 0; j <= smoothSplineSegmentResoultion; j++)
                    {
                        //get the new point in the bezier curve
                        Vector3       pos = BezierCurve(startPoint, midPoint, midPoint, endPoint, j * (1f / smoothSplineSegmentResoultion));
                        OrientedPoint p   = new OrientedPoint(pos, Quaternion.LookRotation(
                                                                  (midPoint - pos).normalized, Vector3.up));
                        newOPoints.Add(p.Position);
                        splineEdge.Add(p);
                    }
                    i++;
                }
                else
                {
                    //Get all the control points for the current curve
                    Vector3 startPoint = ControlPoints[Helper.SLoopIndex(i, ControlPoints.Count)];
                    Vector3 midPoint   = ControlPoints[i];
                    Vector3 endPoint   = ControlPoints[Helper.ALoopIndex(i, ControlPoints.Count)];

                    //get the average direction
                    Vector3 dir = (((midPoint - startPoint) + (endPoint - midPoint)) * 0.5f).normalized;

                    //Make a new list for the curve
                    List <Vector3> newOPoints = new List <Vector3>();
                    for (int j = 0; j <= smoothSplineSegmentResoultion; j++)
                    {
                        //get the new point in the bezier curve
                        Vector3       pos = BezierCurve(startPoint, midPoint, midPoint, endPoint, j * (1f / smoothSplineSegmentResoultion));
                        OrientedPoint p   = new OrientedPoint(pos, Quaternion.LookRotation(
                                                                  (midPoint - pos).normalized, Vector3.up));
                        newOPoints.Add(p.Position);
                        splineEdge.Add(p);
                    }
                }
            }
        }
        else if (SplineCurveType == CurveType.CatmullRom)
        {
            for (int i = 0; i < ControlPoints.Count; i++)
            {
                //get all points needed for a spline from p1 to p2
                Vector3 p0 = ControlPoints[Helper.SLoopIndex(i, ControlPoints.Count)];
                Vector3 p1 = ControlPoints[i];
                Vector3 p2 = ControlPoints[Helper.ALoopIndex(i, ControlPoints.Count)];
                Vector3 p3 = ControlPoints[Helper.LoopIndex(i, 2, ControlPoints.Count)];

                for (int j = 0; j <= SmoothSplineResoultion; j++)
                {
                    Vector3 pos = GetCatmullRom(p0, p1, p2, p3, j * (1f / SmoothSplineResoultion));

                    splineEdge.Add(new OrientedPoint(pos, Quaternion.identity));
                }
            }
        }

        //clear the allSmoothPoints
        allSmoothPoints.Clear();
        //loop though all splineEdge's
        for (int i = 0; i < splineEdge.Count; i++)
        {
            //add each splineEdge's position to allSmoothPoints
            allSmoothPoints.Add(splineEdge[i].Position);
        }
        //set splinePoints to splineEdge
        splinePoints = splineEdge;
    }
    /// <summary>
    /// Smooth out all the corners in allSmoothSpline list
    /// </summary>
    private void SmoothSplineNoEdit()
    {
        //List of new points. These points will be oriented
        List <OrientedPoint> splineEdge = new List <OrientedPoint>();

        //List for all the control points (Control points are the site from the voronoi, the
        //start point of the bezier curve and end point of the bezier curve
        ControlPoints = new List <Vector3>();

        if (SplineCurveType == CurveType.Bezier)
        {
            //Loop though allSmoothPoints
            for (int i = 0; i < allSmoothPoints.Count; i++)
            {
                //Check if two site's are close and facing the same direction
                //if there are within a range then set it as one point
                Vector3 cSite = allSmoothPoints[i];
                Vector3 nSite = allSmoothPoints[((i + 1) + allSmoothPoints.Count) % allSmoothPoints.Count];

                //Get if the sites are within range
                if (ApplyAutoModifcations && (cSite - nSite).magnitude < 50)
                {
                    //if we are connecting the first and last site points
                    //remove the first set of points
                    if (((i + 1) + allSmoothPoints.Count) % allSmoothPoints.Count == 0)
                    {
                        splineEdge.RemoveRange(0, smoothSplineSegmentResoultion + 1);
                    }

                    //find the start point, midpoint and end point
                    Vector3 oStartPoint = (allSmoothPoints[((i - 1) + allSmoothPoints.Count) % allSmoothPoints.Count] + allSmoothPoints[i]) * 0.5f;
                    Vector3 startPoint  = (oStartPoint + allSmoothPoints[i]) * 0.5f;

                    Vector3 midPoint = (allSmoothPoints[i] + allSmoothPoints[((i + 1) +
                                                                              allSmoothPoints.Count) % allSmoothPoints.Count]) * 0.5f;

                    Vector3 oEndPoint = (allSmoothPoints[((i + 2) + allSmoothPoints.Count) % allSmoothPoints.Count] +
                                         allSmoothPoints[((i + 1) + allSmoothPoints.Count) % allSmoothPoints.Count]) * 0.5f;
                    Vector3 endPoint = (oEndPoint + allSmoothPoints[((i + 1) + allSmoothPoints.Count) % allSmoothPoints.Count]) * 0.5f;


                    //Add points to controlpoints
                    ControlPoints.Add(startPoint);
                    ControlPoints.Add(midPoint);
                    ControlPoints.Add(endPoint);

                    //Get the average direction
                    Vector3 dir = (((midPoint - oStartPoint) + (oEndPoint - midPoint)) * 0.5f).normalized;

                    //Make a new list for the curve
                    List <Vector3> newOPoints = new List <Vector3>();
                    for (int j = 0; j <= smoothSplineSegmentResoultion; j++)
                    {
                        //get the new point in the bezier curve
                        Vector3       pos = BezierCurve(startPoint, midPoint, midPoint, endPoint, j * (1f / smoothSplineSegmentResoultion));
                        OrientedPoint p   = new OrientedPoint(pos, Quaternion.LookRotation(
                                                                  (midPoint - pos).normalized, Vector3.up));
                        newOPoints.Add(p.Position);
                        splineEdge.Add(p);
                    }

                    i++;
                }
                else if (!ApplyAutoModifcations)
                {
                    //find the start point, midpoint and end point
                    Vector3 oStartPoint = (allSmoothPoints[((i - 1) + allSmoothPoints.Count) % allSmoothPoints.Count] + allSmoothPoints[i]) * 0.5f;
                    Vector3 startPoint  = (oStartPoint + allSmoothPoints[i]) * 0.5f;
                    Vector3 midPoint    = allSmoothPoints[i];
                    Vector3 oEndPoint   = (allSmoothPoints[((i + 1) + allSmoothPoints.Count) % allSmoothPoints.Count] + allSmoothPoints[i]) * 0.5f;
                    Vector3 endPoint    = (oEndPoint + allSmoothPoints[i]) * 0.5f;

                    if (ApplyAutoModifcations)
                    {
                        //check where the site is. If too close to a start or end point then the site will be moved
                        midPoint = SitePointCheck(startPoint, midPoint, endPoint);

                        //Get the average direction
                        Vector3 dir = (((allSmoothPoints[i] - startPoint) + (endPoint - allSmoothPoints[i])) * 0.5f).normalized;

                        float angle = Vector3.SignedAngle((endPoint - startPoint).normalized,
                                                          (midPoint - startPoint).normalized,
                                                          Vector3.up);

                        //if the angle from start to end point is greater than 75
                        //then move the site point to make the curve not as tight
                        if (Mathf.Abs(angle) > 75)
                        {
                            //Check which direction to move point in
                            Vector3 d  = (midPoint - startPoint).normalized;
                            Vector3 d1 = (midPoint - endPoint).normalized;
                            Vector3 d2 = ((d + d1) * 0.5f).normalized;

                            Vector3 d3 = Vector3.Cross(d2, Vector3.up);

                            midPoint += (d3 * 8);
                        }
                    }

                    //add the start, mid and end point to the Control points list
                    ControlPoints.Add(startPoint);
                    ControlPoints.Add(midPoint);
                    ControlPoints.Add(endPoint);

                    //Make a new list for the curve
                    List <Vector3> newOPoints = new List <Vector3>();
                    for (int j = 0; j <= smoothSplineSegmentResoultion; j++)
                    {
                        //get the new point in the bezier curve
                        Vector3       pos = BezierCurve(startPoint, midPoint, midPoint, endPoint, j * (1f / smoothSplineSegmentResoultion));
                        OrientedPoint p   = new OrientedPoint(pos, Quaternion.LookRotation(
                                                                  (midPoint - pos).normalized, Vector3.up));
                        newOPoints.Add(p.Position);
                        splineEdge.Add(p);
                    }
                }
            }
            //clear the allSmoothPoints
            allSmoothPoints.Clear();
            //loop though all splineEdge's
            for (int i = 0; i < splineEdge.Count; i++)
            {
                //add each splineEdge's position to allSmoothPoints
                allSmoothPoints.Add(splineEdge[i].Position);
            }
            //set splinePoints to splineEdge
            splinePoints = splineEdge;
        }
        else if (SplineCurveType == CurveType.CatmullRom)
        {
            for (int i = 0; i < AllSmoothPoints.Count; i++)
            {
                if (ApplyAutoModifcations)
                {
                    if ((AllSmoothPoints[i] - AllSmoothPoints[Helper.ALoopIndex(i, AllSmoothPoints.Count)]).magnitude
                        < 50)
                    {
                        Vector3 pos = (AllSmoothPoints[i] + AllSmoothPoints[Helper.ALoopIndex(i, AllSmoothPoints.Count)]) * 0.5f;

                        AllSmoothPoints.Insert(i, pos);
                        AllSmoothPoints.Remove(AllSmoothPoints[i]);
                        AllSmoothPoints.Remove(AllSmoothPoints[Helper.ALoopIndex(i, AllSmoothPoints.Count)]);
                    }
                }

                //get all points needed for a spline from p1 to p2
                Vector3 p0 = AllSmoothPoints[Helper.SLoopIndex(i, AllSmoothPoints.Count)];
                Vector3 p1 = AllSmoothPoints[i];
                Vector3 p2 = AllSmoothPoints[Helper.ALoopIndex(i, AllSmoothPoints.Count)];
                Vector3 p3 = AllSmoothPoints[Helper.LoopIndex(i, 2, AllSmoothPoints.Count)];

                ControlPoints.Add(AllSmoothPoints[i]);

                //spline start position
                Vector3 lastPos = p1;

                for (int j = 0; j <= SmoothSplineResoultion; j++)
                {
                    Vector3 pos = GetCatmullRom(p0, p1, p2, p3, j * (1f / SmoothSplineResoultion));
                    lastPos = pos;

                    splineEdge.Add(new OrientedPoint(pos, Quaternion.identity));
                }

                splineEdge.Remove(splineEdge[splineEdge.Count - 1]);
            }

            //clear the allSmoothPoints
            allSmoothPoints.Clear();
            //loop though all splineEdge's
            for (int i = 0; i < splineEdge.Count; i++)
            {
                //add each splineEdge's position to allSmoothPoints
                allSmoothPoints.Add(splineEdge[i].Position);
            }
            //set splinePoints to splineEdge
            splinePoints = splineEdge;
        }
    }