Exemplo n.º 1
0
    //Build the mesh:
    public void BuildMesh()
    {
        List <Knot> knots = spline.knots;

        CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();

        int maxPoint = meshBuilder.Vertices.Count;

        float   distance = 0;
        Vector3 position = new Vector3(0, 0, 0);
        Vector3 n        = new Vector3(0, 0, 0);
        Vector3 bn       = new Vector3(0, 0, 0);
        Vector3 t        = new Vector3(0, 0, 0);

        float r = 0;

        for (int k = 0; k < 3; ++k)
        {
            int beginKnot = startKnot + k;
            int endKnot   = startKnot + k + 1;

            float beginDistance = knotLengths[beginKnot];
            float endDistance   = knotLengths[endKnot];

            int begin = (int)(beginDistance / trackLength);
            int end   = (int)(endDistance / trackLength);

            float totalLength  = endDistance - beginDistance;
            float nextDistance = end * trackLength;

            for (int i = begin; i < end; ++i)
            {
                if (i != 0 && beginKnot >= 3)
                {
                    // place the marker at spline to get distance
                    distance = trackLength * i;

                    spline.PlaceMarker(marker, distance);

                    // get the variable needed for the point on spline
                    position      = spline.GetPosition(marker);
                    splineTangent = spline.GetTangent(marker);

                    // finds transform for cursor at point in time
                    n  = Vector3.Lerp(knotNormals[endKnot], knotNormals[beginKnot], (endDistance - distance) / totalLength);
                    bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength);
                    t  = Vector3.Lerp(knotTangents[endKnot], knotTangents[beginKnot], (endDistance - distance) / totalLength);

                    r = Mathf.Lerp(knotRadius[endKnot], knotRadius[beginKnot], (endDistance - distance) / totalLength);
                    if (first)
                    {
                        first         = false;
                        firstPosition = position;
                        firstNormal   = n;
                        firstBinormal = bn;
                        firstTangent  = t;
                        firstRadius   = r;
                    }


                    if (i * (m_RadialSegmentCount + 1) >= maxPoint)
                    {
                        BuildNewShape(position, n, bn, t, r, meshBuilder.Vertices.Count > 0); // add new vertices
                    }
                    else
                    {
                        BuildExistingShape(position, n, bn, t, r, i); // update vertices and normals*/
                    }
                }
            }
        }

        ++startKnot;

        lastPosition = position;
        lastNormal   = n;
        lastBinormal = bn;
        lastTangent  = t;
        lastRadius   = r;

        //If the MeshFilter exists, attach the new mesh to it.
        //Assuming the GameObject also has a renderer attached, our new mesh will now be visible in the scene.
        if (filter != null)
        {
            filter.sharedMesh = meshBuilder.CreateMesh();
        }
    }
Exemplo n.º 2
0
        private void RenderMesh()
        {
            if (advancedParameters.nbSegmentToParametrize == 0)
            {
                spline.Parametrize();
            }
            else
            {
                spline.Parametrize(spline.NbSegments - advancedParameters.nbSegmentToParametrize, spline.NbSegments);
            }

            float length = Mathf.Max(spline.Length() - 0.1f, 0);

            int nbQuad = ((int)(1f / width * length)) + 1 - quadOffset;

            if (allocatedNbQuad < nbQuad)    //allocate more memory for the mesh
            {
                Reallocate(nbQuad);
                length = Mathf.Max(spline.Length() - 0.1f, 0);
                nbQuad = ((int)(1f / width * length)) + 1 - quadOffset;
            }

            int   startingQuad = lastStartingQuad;
            float lastDistance = startingQuad * width + quadOffset * width;

            maxInstanciedTriCount = System.Math.Max(maxInstanciedTriCount, (nbQuad - 1) * NbTriIndexPerQuad);

            Vector3 n = normal;

            if (dynamicNormalUpdate)
            {
                if (n == Vector3.zero)
                {
                    n = (transform.position - Camera.main.transform.position).normalized;
                }

                for (int i = 0; i < normals.Length; i++)
                {
                    normals[i] = n;
                }
            }

            CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();
            spline.PlaceMarker(marker, lastDistance);

            Vector3 lastPosition = spline.GetPosition(marker);
            Vector3 lastTangent  = spline.GetTangent(marker);
            Vector3 lastBinormal = CatmullRomSpline.ComputeBinormal(lastTangent, n);

            int drawingEnd = meshDisposition == MeshDisposition.Fragmented ? nbQuad - 1 : nbQuad - 1;



            float startingDist = lastDistance;

            for (int i = startingQuad; i < drawingEnd; i++)
            {
                float distance         = lastDistance + width;
                int   firstVertexIndex = i * NbVertexPerQuad;
                int   firstTriIndex    = i * NbTriIndexPerQuad;

                spline.MoveMarker(marker, distance);

                Vector3 position = spline.GetPosition(marker);
                Vector3 tangent  = spline.GetTangent(marker);
                Vector3 binormal = CatmullRomSpline.ComputeBinormal(tangent, n);

                float h = FadeMultiplier(lastDistance, length);
                float h2 = FadeMultiplier(distance, length);
                float rh = h * height, rh2 = h2 * height;

                if (fadeType == FadeType.Alpha || fadeType == FadeType.None)
                {
                    rh  = h > 0 ? height : 0;
                    rh2 = h2 > 0 ? height : 0;
                }

                if (meshDisposition == MeshDisposition.Continuous)
                {
                    vertices[firstVertexIndex]     = transform.InverseTransformPoint(lastPosition - origin + (lastBinormal * (rh * 0.5f)));
                    vertices[firstVertexIndex + 1] = transform.InverseTransformPoint(lastPosition - origin + (-lastBinormal * (rh * 0.5f)));
                    vertices[firstVertexIndex + 2] = transform.InverseTransformPoint(position - origin + (binormal * (rh2 * 0.5f)));
                    vertices[firstVertexIndex + 3] = transform.InverseTransformPoint(position - origin + (-binormal * (rh2 * 0.5f)));

                    uv[firstVertexIndex]     = new Vector2(lastDistance / height, 1);
                    uv[firstVertexIndex + 1] = new Vector2(lastDistance / height, 0);
                    uv[firstVertexIndex + 2] = new Vector2(distance / height, 1);
                    uv[firstVertexIndex + 3] = new Vector2(distance / height, 0);
                }
                else
                {
                    Vector3 pos = lastPosition + (lastTangent * width * -0.5f) - origin;

                    vertices[firstVertexIndex]     = transform.InverseTransformPoint(pos + (lastBinormal * (rh * 0.5f)));
                    vertices[firstVertexIndex + 1] = transform.InverseTransformPoint(pos + (-lastBinormal * (rh * 0.5f)));
                    vertices[firstVertexIndex + 2] = transform.InverseTransformPoint(pos + (lastTangent * width) + (lastBinormal * (rh * 0.5f)));
                    vertices[firstVertexIndex + 3] = transform.InverseTransformPoint(pos + (lastTangent * width) + (-lastBinormal * (rh * 0.5f)));

                    uv[firstVertexIndex]     = new Vector2(0, 1);
                    uv[firstVertexIndex + 1] = new Vector2(0, 0);
                    uv[firstVertexIndex + 2] = new Vector2(1, 1);
                    uv[firstVertexIndex + 3] = new Vector2(1, 0);
                }

                float relLength = length - startingDist;
                uv2[firstVertexIndex]     = new Vector2((lastDistance - startingDist) / relLength, 1);
                uv2[firstVertexIndex + 1] = new Vector2((lastDistance - startingDist) / relLength, 0);
                uv2[firstVertexIndex + 2] = new Vector2((distance - startingDist) / relLength, 1);
                uv2[firstVertexIndex + 3] = new Vector2((distance - startingDist) / relLength, 0);

                triangles[firstTriIndex]     = firstVertexIndex;
                triangles[firstTriIndex + 1] = firstVertexIndex + 1;
                triangles[firstTriIndex + 2] = firstVertexIndex + 2;
                triangles[firstTriIndex + 3] = firstVertexIndex + 2;
                triangles[firstTriIndex + 4] = firstVertexIndex + 1;
                triangles[firstTriIndex + 5] = firstVertexIndex + 3;

                colors[firstVertexIndex]     = vertexColor;
                colors[firstVertexIndex + 1] = vertexColor;
                colors[firstVertexIndex + 2] = vertexColor;
                colors[firstVertexIndex + 3] = vertexColor;

                if (fadeType == FadeType.Alpha || fadeType == FadeType.Both)
                {
                    colors[firstVertexIndex].a     *= h;
                    colors[firstVertexIndex + 1].a *= h;
                    colors[firstVertexIndex + 2].a *= h2;
                    colors[firstVertexIndex + 3].a *= h2;
                }

                lastPosition = position;
                lastTangent  = tangent;
                lastBinormal = binormal;
                lastDistance = distance;
            }

            for (int i = (nbQuad - 1) * NbTriIndexPerQuad; i < maxInstanciedTriCount; i++) //clear a few tri ahead
            {
                triangles[i] = 0;
            }

            lastStartingQuad = advancedParameters.lengthToRedraw == 0 ?
                               System.Math.Max(0, nbQuad - ((int)(maxLength / width) + 5)) :
                               System.Math.Max(0, nbQuad - ((int)(advancedParameters.lengthToRedraw / width) + 5));

            mesh.Clear();
            mesh.vertices  = vertices;
            mesh.uv        = uv;
            mesh.uv2       = uv2;
            mesh.triangles = triangles;
            mesh.colors    = colors;
            mesh.normals   = normals;
        }
Exemplo n.º 3
0
    //Build the mesh:
    public void UpdateMesh()
    {
        List <Knot> knots = spline.knots;

        CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();

        int maxPoint = meshBuilder.Vertices.Count;

        Vector3 position     = new Vector3(0, 0, 0);
        Vector3 lastPosition = new Vector3(0, 0, 0);
        Vector3 t            = new Vector3(0, 0, 0);

        for (int k = 0; k < 3; ++k)
        {
            int beginKnot = startKnot + k;
            int endKnot   = startKnot + k + 1;

            float beginDistance = knotLengths[beginKnot];
            float endDistance   = knotLengths[endKnot];

            int begin = (int)(beginDistance / trackLength);
            int end   = (int)(endDistance / trackLength);

            float totalLength = endDistance - beginDistance;

            spline.PlaceMarker(marker, trackLength * begin - 1);
            lastPosition = spline.GetPosition(marker);

            for (int i = begin; i < end; ++i)
            {
                // place the marker at spline to get distance
                float distance = trackLength * i;
                spline.PlaceMarker(marker, distance);

                // get the variable needed for the point on spline
                position = spline.GetPosition(marker);

                // finds transform for cursor at point in time
                Vector3 bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength);

                // find via cross product
                Vector3 normal    = Vector3.Cross(position - lastPosition, bn);
                Vector3 linePoint = bn * 0.5f;

                // find points for mesh vertices
                Vector3 point  = position + linePoint;
                Vector3 point2 = position - linePoint;

                // build or update mesh
                if (i * 4 >= maxPoint)
                {
                    BuildQuad(meshBuilder, point, point2, normal);
                }
                else
                {
                    UpdateQuad(meshBuilder, point, point2, normal, i);
                }

                // gets last position
                lastPosition = position;
            }
        }

        ++startKnot;

        // creates mesh for filter and renderer
        CreateMesh();
    }
Exemplo n.º 4
0
    public void CreateMeshTrail()
    {
        // creates a new mesh builder for generating mesh
        meshBuilder = new MeshBuilder();

        // find the max count of control points
        int max = 0;

        for (int i = 0; i < lineList.Count; ++i)
        {
            if (max < lineList[i].Count)
            {
                max = lineList[i].Count;
            }
        }

        // redistribute points for lines with smaller number of control points
        for (int i = 0; i < lineList.Count; ++i)
        {
            // if line does not have enough control points
            if (max > lineList[i].Count)
            {
                List <Vector3> l     = new List <Vector3>();
                float          frac1 = 0;
                float          frac2 = 0;
                int            index = 1;

                // add beginning point
                l.Add(lineList[i][0]);

                // interpolate between two points
                for (int j = 1; j < lineList[i].Count; ++j)
                {
                    frac1 = (float)index / (max - 1);
                    frac2 = (float)j / (lineList[i].Count - 1);

                    // if the point is distributed between the 2 control point
                    while (frac1 < frac2)
                    {
                        Vector3 diff = (lineList[i][j] - lineList[i][j - 1]);
                        l.Add(lineList[i][j - 1] + diff * frac1);
                        ++index;
                        frac1 = (float)index / (max - 1);
                    }
                    // endpoint of the 2 control point
                    l.Add(lineList[i][j]);
                    ++index;
                }
                lineList[i] = l;
            }
        }


        if (smooth) // create smooth sections
        {
            List <Vector3> listA;

            CatmullRomSpline spline;
            splineList = new List <CatmullRomSpline>();
            // generate the splines
            for (int j = 0; j < lineList[0].Count; ++j) // cycle the jth point of all lines
            {
                spline = new CatmullRomSpline();
                for (int i = 0; i < lineList.Count; ++i) // cycle through all the lines
                {
                    listA = lineList[i];

                    if (i == 0 || i == lineList.Count - 1)
                    {
                        for (int n = 0; n < 3; ++n)
                        {
                            spline.knots.Add(new Knot(listA[j]));
                        }
                    }
                    else
                    {
                        spline.knots.Add(new Knot(listA[j]));
                    }
                }
                spline.Parametrize();
                splineList.Add(spline);
            }

            // find the maxlength for division
            float maxLength = -1;
            for (int i = 0; i < splineList.Count; ++i)
            {
                if (maxLength < splineList[i].Length())
                {
                    maxLength = splineList[i].Length();
                }
            }


            float trackLength = 0.01f;
            int   maxCount    = (int)(maxLength / trackLength);
            int   total       = 0;
            int   offset      = 1;
            CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();

            // Render the trail, spline by spline
            Vector3 posA;
            Vector3 posB;
            Vector3 tangentA;
            Vector3 tangentB;

            // NOTE: Creates SEPARATE quad spline
            // Quad 0: spline 0 and spline 1
            // Quad 1: spline 1 and spline 2
            // Quad 2: spline 2 and spline 3 .. etc
            for (int i = 0; i < splineList.Count - 1; ++i)
            {
                CatmullRomSpline splineA = splineList[i];
                CatmullRomSpline splineB = splineList[i + 1];
                for (int j = offset; j < maxCount; ++j)
                {
                    // grab positions and tangents
                    splineA.PlaceMarker(marker, j * splineA.Length() / maxCount);
                    posA     = splineA.GetPosition(marker);
                    tangentA = splineA.GetTangent(marker);

                    splineB.PlaceMarker(marker, j * splineB.Length() / maxCount);
                    posB     = splineB.GetPosition(marker);
                    tangentB = splineB.GetTangent(marker);

                    // calculate the normals
                    Vector3 normalA = Vector3.Cross((posA - posB), tangentA).normalized;
                    Vector3 normalB = Vector3.Cross(tangentB, (posB - posA)).normalized;

                    // build the splines
                    BuildQuadSpline(meshBuilder, posA, posB, normalA, normalB, total, false);
                }

                // update offset for rendering separate quad splines
                total = meshBuilder.Vertices.Count;
            }
        }
        else // create smooth sections
        {
            List <Vector3> listA;
            List <Vector3> listB;

            int total = 0;
            for (int j = 0; j < lineList[0].Count - 1; ++j)
            {
                for (int i = 0; i < lineList.Count - 1; ++i)
                {
                    listA = lineList[i];
                    listB = lineList[i + 1];
                    BuildQuad(meshBuilder, listA[j], listB[j], listA[j + 1], listB[j + 1], total);
                }
                total = meshBuilder.Vertices.Count;
            }
        }

        BuildMesh();
    }
Exemplo n.º 5
0
    //Build the mesh:
    public void BuildMesh()
    {
        CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();

        int maxPoint = meshBuilder.Vertices.Count;

        Vector3 position = new Vector3(0, 0, 0);
        Vector3 t        = new Vector3(0, 0, 0);

        float width     = 0;
        float height    = 0;
        float thickness = 0;

        for (int k = 0; k < 3; ++k)
        {
            int beginKnot = startKnot + k;
            int endKnot   = startKnot + k + 1;

            float beginDistance = knotLengths[beginKnot];
            float endDistance   = knotLengths[endKnot];

            int begin = (int)(beginDistance / trackLength);
            int end   = (int)(endDistance / trackLength);

            float totalLength = endDistance - beginDistance;

            for (int i = begin; i < end; ++i)
            {
                if (i != 0 && beginKnot >= 3)
                {
                    // place the marker at spline to get distance
                    float distance = trackLength * i;
                    spline.PlaceMarker(marker, distance);

                    // get the variable needed for the point on spline
                    position      = spline.GetPosition(marker);
                    splineTangent = spline.GetTangent(marker);

                    // finds transform for cursor at point in time
                    Vector3 n  = Vector3.Lerp(knotNormals[endKnot], knotNormals[beginKnot], (endDistance - distance) / totalLength);
                    Vector3 bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength);
                    t = Vector3.Lerp(knotTangents[endKnot], knotTangents[beginKnot], (endDistance - distance) / totalLength);

                    width     = Mathf.Lerp(knotWidth[endKnot], knotWidth[beginKnot], (endDistance - distance) / totalLength);
                    height    = Mathf.Lerp(knotHeight[endKnot], knotHeight[beginKnot], (endDistance - distance) / totalLength);
                    thickness = Mathf.Lerp(knotThickness[endKnot], knotThickness[beginKnot], (endDistance - distance) / totalLength);

                    if (first)
                    {
                        first         = false;
                        firstPosition = position;
                        firstNormal   = n;
                        firstBinormal = bn;
                        firstTangent  = t;

                        firstWidth     = width;
                        firstHeight    = height;
                        firstThickness = thickness;
                    }

                    // setup shape for specified section
                    SetupShape(n, bn, t, width, height, thickness);

                    if (i * (shapePoints.Length) >= maxPoint)
                    {
                        BuildNewShape(position, meshBuilder.Vertices.Count > 0); // add new vertices
                    }
                    else
                    {
                        BuildExistingShape(position, i); // update vertices and normals*/
                    }
                }
            }
        }

        lastTangent  = t;
        lastPosition = position;

        ++startKnot;

        //If the MeshFilter exists, attach the new mesh to it.
        //Assuming the GameObject also has a renderer attached, our new mesh will now be visible in the scene.
        if (filter != null)
        {
            filter.sharedMesh = meshBuilder.CreateMesh();
        }
    }
Exemplo n.º 6
0
    // create mesh for curved extrusion
    public void CreateMeshTrail(float nValue)
    {
        // throws out previous mesh if nValue is set
        List <Knot> knots = spline.knots;

        CatmullRomSpline.Marker marker     = new CatmullRomSpline.Marker();
        CatmullRomSpline.Marker markerSide = new CatmullRomSpline.Marker();

        int     maxPoint = meshBuilder.Vertices.Count;
        Vector3 position = new Vector3(0, 0, 0);
        Vector3 sidePos  = new Vector3(0, 0, 0);
        Vector3 normPos  = new Vector3(0, 0, 1f) * nValue;

        // makes points based on the distance segments
        int begin = 0;
        int end   = (int)(spline.Length() / trackLength);

        int beginSide = (int)(knotLengths[0] / trackLength);
        int endSide   = (int)(splineSide.Length() / trackLength);

        int offset          = 5;
        int totalPoints     = end - begin - offset;
        int totalPointsSide = (int)(splineSide.Length() / trackLength) - begin - offset;

        totalPoints     *= 2;
        totalPointsSide *= 2;

        // IMPORTANT!!! : DEPENDS UPON THE CONSTRAINTS
        // calculates the normal in order to determine the render direction
        // place the marker at spline to get distance

        bool reverse = true;

        // Restarts rendering if a volume is being generated
        if (nValue <= -0.01f || nValue >= 0.01f)
        {
            beginSide   = 0;
            meshBuilder = new MeshBuilder();

            spline.PlaceMarker(marker, trackLength * offset);

            splineSide.PlaceMarker(markerSide, 0);
            Vector3 diffSide = splineSide.GetPosition(markerSide);
            splineSide.PlaceMarker(markerSide, trackLength * (endSide - 1));
            diffSide -= splineSide.GetPosition(markerSide);
            diffSide  = new Vector3(diffSide.x, 0, 0);

            print("Normal: " + normPos);
            print("Tangent: " + spline.GetTangent(marker));
            print("Side: " + diffSide);
            print("Cross: " + Vector3.Cross(spline.GetTangent(marker), normPos));

            reverse = (Vector3.Dot(Vector3.Cross(spline.GetTangent(marker), normPos), diffSide) > 0);

            if (reverse)
            {
                print("REVERSE!");
            }
            else
            {
                print("FORWARD!");
            }
        }

        beginSide = (offset > beginSide) ? offset : beginSide;

        // iterate through the entire path of the spline
        for (int j = beginSide; j < endSide; ++j)
        {
            // place the marker at spline to get distance
            splineSide.PlaceMarker(marker, trackLength * j);

            sidePos = splineSide.GetPosition(marker);

            Vector3 sideTangent = splineSide.GetTangent(marker);

            for (int i = begin + offset; i < end; ++i)
            {
                // place the marker at spline to get distance
                spline.PlaceMarker(marker, trackLength * i);

                // get the variable needed for the point on spline
                position = spline.GetPosition(marker) + sidePos;

                Vector3 tangent = spline.GetTangent(marker);

                Vector3 normal = normPos.normalized;

                // build or update mesh
                if (nValue > -0.01f && nValue < 0.01f)
                {
                    if ((j - offset) >= meshBuilder.Vertices.Count / totalPoints)
                    {
                        BuildQuadSpline(meshBuilder, position, normal, totalPoints, Vector3.zero, Vector3.zero, 0, reverse);
                    }
                    else
                    {
                        UpdateQuadSpline(meshBuilder, position, normal, totalPoints, Vector3.zero, Vector3.zero, i - offset, j - offset, reverse);
                    }
                }
                else
                {
                    Vector3 startPos = Vector3.zero;
                    Vector3 endPos   = normPos;

                    if ((j - offset) >= meshBuilder.Vertices.Count / totalPoints)
                    {
                        BuildQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, 0, reverse);
                    }
                    else
                    {
                        UpdateQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, i - offset, j - offset, reverse);
                    }
                }
            }
        }

        // detect if there is a structure or not
        if (nValue <= -0.01f || nValue >= 0.01f)
        {
            int p = meshBuilder.Vertices.Count;

            // build sides out of the spline
            splineSide.PlaceMarker(marker, trackLength * offset);
            Vector3 startPos = splineSide.GetPosition(marker);
            splineSide.PlaceMarker(marker, trackLength * (endSide - 1));
            Vector3 endPos = splineSide.GetPosition(marker);

            for (int j = 0; j < 2; ++j)
            {
                for (int i = begin + offset; i < end; ++i)
                {
                    // place the marker at spline to get distance
                    spline.PlaceMarker(marker, trackLength * i);

                    // get the variable needed for the point on spline
                    position = spline.GetPosition(marker);
                    if (j == 1)
                    {
                        position += normPos;
                    }

                    Vector3 tangent = spline.GetTangent(marker);

                    Vector3 normal = Vector3.Cross(tangent, normPos).normalized;

                    BuildQuadSpline(meshBuilder, position, normal, totalPoints, endPos, startPos, p, reverse);
                }
            }

            p = meshBuilder.Vertices.Count;

            // build caps out of the side spline
            spline.PlaceMarker(marker, trackLength * offset);
            startPos = spline.GetPosition(marker);
            spline.PlaceMarker(marker, trackLength * (end - 1));
            endPos = spline.GetPosition(marker);

            for (int j = 0; j < 2; ++j)
            {
                for (int i = begin + offset; i < endSide; ++i)
                {
                    // place the marker at spline to get distance
                    splineSide.PlaceMarker(marker, trackLength * i);

                    // get the variable needed for the point on spline
                    position = splineSide.GetPosition(marker);
                    if (j == 1)
                    {
                        position += normPos;
                    }

                    Vector3 tangent = splineSide.GetTangent(marker);

                    Vector3 normal = Vector3.Cross(tangent, normPos).normalized;

                    BuildQuadSpline(meshBuilder, position, normal, totalPointsSide, startPos, endPos, p, reverse);
                }
            }
        }

        filter.sharedMesh = meshBuilder.CreateMesh();
    }