예제 #1
0
    public void RefreshTrack(GeneratedTrack track)
    {
        int counterLeft  = 0;
        int counterRight = 0;

        for (int i = 0; i < track.Elements.Length; i++)
        {
            if (track.Elements[i].GetType() == typeof(GeneratedBezSpline))
            {
                GeneratedBezSpline spline = (GeneratedBezSpline)track.Elements[i];

                for (int j = 0; j < spline.RenderVertsLeft.Length; j++)
                {
                    Vector3 endPos = j + 1 < spline.RenderVertsLeft.Length ? new Vector3(spline.RenderVertsLeft[j + 1].x, track.GetTensorHeight(spline.RenderVertsLeft[j + 1]) + 1f, spline.RenderVertsLeft[j + 1].z) : track.Elements[(i + 1) % track.Elements.Length].Position;

                    doLine(new Vector3(spline.RenderVertsLeft[j].x, track.GetTensorHeight(spline.RenderVertsLeft[j]) + 1f, spline.RenderVertsLeft[j].z), endPos, true, counterLeft, Color.white);
                    counterLeft++;
                }
                for (int j = 0; j < spline.RenderVertsRight.Length; j++)
                {
                    Vector3 endPos = j + 1 < spline.RenderVertsRight.Length ? new Vector3(spline.RenderVertsRight[j + 1].x, track.GetTensorHeight(spline.RenderVertsRight[j + 1]) + 1f, spline.RenderVertsRight[j + 1].z) : track.Elements[(i + 1) % track.Elements.Length].Position;

                    doLine(new Vector3(spline.RenderVertsRight[j].x, track.GetTensorHeight(spline.RenderVertsRight[j]) + 1f, spline.RenderVertsRight[j].z), endPos, false, counterRight, Color.white);
                    counterRight++;
                }
            }
            else if (track.Elements[i].GetType() == typeof(GeneratedStraight))
            {
                int iPrev = i - 1 < 0 ? track.Elements.Length - 1 : i - 1;
                int iNext = (i + 1) % track.Elements.Length;
                GeneratedBezSpline splinePrev = (GeneratedBezSpline)track.Elements[iPrev];
                GeneratedBezSpline splineNext = (GeneratedBezSpline)track.Elements[iNext];

                Vector3 leftStartPos  = splinePrev.RenderVertsLeft[splinePrev.RenderVertsLeft.Length - 1];
                Vector3 rightStartPos = splinePrev.RenderVertsRight[splinePrev.RenderVertsRight.Length - 1];
                Vector3 leftEndPos    = splineNext.RenderVertsLeft[0];
                Vector3 rightEndPos   = splineNext.RenderVertsRight[0];

                leftStartPos  = new Vector3(leftStartPos.x, track.GetTensorHeight(leftStartPos) + 1f, leftStartPos.z);
                rightStartPos = new Vector3(rightStartPos.x, track.GetTensorHeight(rightStartPos) + 1f, rightStartPos.z);
                leftEndPos    = new Vector3(leftEndPos.x, track.GetTensorHeight(leftEndPos) + 1f, leftEndPos.z);
                rightEndPos   = new Vector3(rightEndPos.x, track.GetTensorHeight(rightEndPos) + 1f, rightEndPos.z);

                doLine(leftStartPos, leftEndPos, true, counterLeft, Color.blue);
                counterLeft++;
                doLine(rightStartPos, rightEndPos, false, counterRight, Color.blue);
                counterRight++;
            }
        }


        for (int i = counterLeft; i < instLinesLeft.Count; i++)
        {
            Destroy(instLinesLeft[i]);
            instLinesLeft.RemoveAt(i);
            i--;
        }
        for (int i = counterRight; i < instLinesRight.Count; i++)
        {
            Destroy(instLinesRight[i]);
            instLinesRight.RemoveAt(i);
            i--;
        }
    }
예제 #2
0
    public void Render(GeneratedTrack track, bool mlStuff)
    {
        for (int i = 0; i < instMLStuff.Count; i++)
        {
            Destroy(instMLStuff[i]);
        }

        instMLStuff = new List <GameObject>();

        //if (planeRenderer != null)
        //{
        //    planeRenderer.RefreshPlane(track.TerrainModifier);
        //}

        trackLength = track.TrackLength;

        vertices.Clear();
        triangles.Clear();
        uvs.Clear();

        int debugCounter = 0;

        for (int i = 0; i < instDebugObjects.Count; i++)
        {
            Destroy(instDebugObjects[i]);
        }
        instDebugObjects.Clear();

        for (int i = 0; i < instCurbs.Count; i++)
        {
            Destroy(instCurbs[i]);
        }
        instCurbs.Clear();


        /*if (track.Elements[0].GetType() == typeof(GeneratedStraight))
         * {
         *  GeneratedStraight straight = (GeneratedStraight)track.Elements[0];
         *
         *  Vector3 toRight = (Quaternion.Euler(0f, (straight.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(straight.WidthStart, 0f, 0f));
         *
         *  vertices.Add(straight.Position - toRight);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *  vertices.Add(straight.Position + toRight);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *
         * }
         * else if (track.Elements[0].GetType() == typeof(GeneratedTurn))
         * {
         *  GeneratedTurn turn = (GeneratedTurn)track.Elements[0];
         *
         *  Vector3 toRight = (Quaternion.Euler(0f, (turn.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(turn.WidthStart, 0f, 0f));
         *
         *  vertices.Add(turn.Position - toRight);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *  vertices.Add(turn.Position + toRight);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         * }
         * else if (track.Elements[0].GetType() == typeof(GeneratedBezSpline))
         * {
         *  GeneratedBezSpline bezSpline = (GeneratedBezSpline)track.Elements[0];
         *
         *  vertices.Add(bezSpline.RenderVertsLeft[0]);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *  vertices.Add(bezSpline.RenderVertsRight[0]);
         *  uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         * }
         *
         *
         * for (int i = 0; i < track.Elements.Length; i++)
         * {
         *
         *  int verticesCountBefore = vertices.Count;
         *
         *  //if (track.Elements[i].GetType() != typeof(GeneratedStraight))
         *  //{
         *      GameObject instDebugText = Instantiate(debugText);
         *      instDebugText.transform.position = track.Elements[i].Position;
         *      instDebugText.GetComponent<DebugPoint>().Text = debugCounter.ToString();
         *
         *      instDebugObjects.Add(instDebugText);
         *
         *      debugCounter++;
         *  //}
         *
         *  if (track.Elements[i].GetType() == typeof(GeneratedStraight))
         *  {
         *      GeneratedStraight straight = (GeneratedStraight)track.Elements[i];
         *
         *      Vector3 toRight = (Quaternion.Euler(0f, (straight.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(straight.WidthEnd, 0f, 0f));
         *      Vector3 toFront = (Quaternion.Euler(0f, (straight.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(0f, 0f, straight.Length));
         *
         *
         *      int segmentsAmount = (int)(straight.Length / 4f);
         *
         *      for (int j = 1; j <= segmentsAmount; j++)
         *      {
         *          float s = ((float)j) / segmentsAmount;
         *
         *
         *          vertices.Add(straight.Position + (toFront * s) - toRight);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *          vertices.Add(straight.Position + (toFront * s) + toRight);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *
         *
         *          triangles.Add(vertices.Count - 4);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 3);
         *
         *          triangles.Add(vertices.Count - 3);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 1);
         *      }
         *  }
         *  else if (track.Elements[i].GetType() == typeof(GeneratedTurn))
         *  {
         *      GeneratedTurn turn = (GeneratedTurn)track.Elements[i];
         *
         *      bool rightTurn = turn.Degree >= 0f;
         *
         *      Vector3 toRight = (Quaternion.Euler(0f, (turn.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(1f, 0f, 0f));
         *      Vector3 toFront = (Quaternion.Euler(0f, (turn.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(0f, 0f, 1f));
         *
         *      Vector3 middlePoint = toRight * turn.Radius * (rightTurn ? 1f : -1f);
         *
         *      int segmentsAmount = ((int)(Mathf.Abs(turn.Degree) / maxTurnDegreeResolution)) + 1;
         *
         *      for (int j = 1; j <= segmentsAmount; j++)
         *      {
         *          Vector3 toRightTurned = (Quaternion.Euler(0f, (turn.Degree / ((float)segmentsAmount)) * j, 0f)) * toRight;
         *
         *          Vector3 segmentPos = middlePoint + (toRightTurned * (rightTurn ? -1f : 1f) * turn.Radius);
         *
         *          float currentWidth = (turn.WidthEnd - turn.WidthStart) * (float)((float)j / (float)segmentsAmount) + turn.WidthStart;
         *
         *          vertices.Add(segmentPos + toRightTurned * currentWidth * -1f + turn.Position);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *          vertices.Add(segmentPos + toRightTurned * currentWidth + turn.Position);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *
         *
         *          triangles.Add(vertices.Count - 4);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 3);
         *
         *          triangles.Add(vertices.Count - 3);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 1);
         *      }
         *  }
         *  else if (track.Elements[i].GetType() == typeof(GeneratedBezSpline))
         *  {
         *      GeneratedBezSpline bezierSpline = (GeneratedBezSpline)track.Elements[i];
         *
         *      for (int j = 1; j < bezierSpline.RenderVertsLeft.Length; j++)
         *      {
         *          vertices.Add(bezierSpline.RenderVertsLeft[j]);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *          vertices.Add(bezierSpline.RenderVertsRight[j]);
         *          uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));
         *
         *
         *          triangles.Add(vertices.Count - 4);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 3);
         *
         *          triangles.Add(vertices.Count - 3);
         *          triangles.Add(vertices.Count - 2);
         *          triangles.Add(vertices.Count - 1);
         *      }
         *  }
         *
         *  if (curbsEnabled && track.Elements[i].Curbs.Length > 0)
         *  {
         *      for (int j = 0; j < track.Elements[i].Curbs.Length; j++)
         *      {
         *          GameObject instCurb = Instantiate(curbPrefab, transform);
         *          instCurb.GetComponent<CurbRenderer>().ApplyCurb(track.Elements[i].Curbs[j], track.Elements[i]);
         *          instCurb.transform.localPosition = Vector3.zero;
         *          instCurbs.Add(instCurb);
         *      }
         *  }
         *
         *
         *
         *  //List<Vector3> sectorVertices = new List<Vector3>();
         *  //for (int j = verticesCountBefore; j < vertices.Count; j++)
         *  //{
         *  //    sectorVertices.Add(vertices[j]);
         *  //}
         *
         *  //track.TerrainModifier.FillSectorsByElements(sectorVertices, i);
         * }
         */

        Debug.Log("Generate Mesh: " + Time.time);

        track.GenerateMesh();
        vertices  = new List <Vector3>(track.RenderVerticesTrack);
        triangles = new List <int>(track.RenderTrianglesTrack);
        uvs       = new List <Vector2>(track.RenderUVsTrack);

        if (mlStuff)
        {
            Vector3[] leftMLPoints  = new Vector3[vertices.Count / 2];
            Vector3[] rightMLPoints = new Vector3[vertices.Count / 2];
            for (int i = 0; i < leftMLPoints.Length; i++)
            {
                leftMLPoints[i]  = vertices[i * 2 + 0];
                rightMLPoints[i] = vertices[i * 2 + 1];

                GameObject cubeI = Instantiate(mlCheckpointCubePrefab);
                cubeI.transform.position   = (leftMLPoints[i] + rightMLPoints[i]) * 0.5f;
                cubeI.transform.right      = leftMLPoints[i] - rightMLPoints[i];
                cubeI.transform.localScale = new Vector3((leftMLPoints[i] - rightMLPoints[i]).magnitude, 6f, 0.1f);

                instMLStuff.Add(cubeI);
            }
            GameObject instWallLeftML = Instantiate(wallPrefab);
            instWallLeftML.transform.position = Vector3.zero;
            GameObject instWallRightML = Instantiate(wallPrefab);
            instWallRightML.transform.position = Vector3.zero;

            instWallLeftML.GetComponent <WallRenderer>().Points  = leftMLPoints;
            instWallRightML.GetComponent <WallRenderer>().Points = rightMLPoints;

            instWallLeftML.name = "ML_Wall_Left";
            instWallLeftML.name = "ML_Wall_Right";

            instMLStuff.Add(instWallLeftML);
            instMLStuff.Add(instWallRightML);
        }



        //3,751



        int     startFinishElementIndex = (int)track.AnalyzedTrack.startFinishLineIndex;
        float   sStartFinishElement     = track.AnalyzedTrack.startFinishLineIndex - startFinishElementIndex;
        Vector3 posStartFinish          = Vector3.zero;
        float   rotStartFinish          = 0f;

        if (track.Elements[startFinishElementIndex].GetType() == typeof(GeneratedStraight))
        {
            GeneratedStraight straight = (GeneratedStraight)track.Elements[startFinishElementIndex];
            posStartFinish = straight.Position + (straight.EndPosition - straight.Position) * sStartFinishElement;
            rotStartFinish = straight.Direction;
        }
        else
        {
            GeneratedBezSpline spline = (GeneratedBezSpline)track.Elements[startFinishElementIndex];
            int vertSplineIndex       = (int)(spline.RenderVertsLeft.Length * sStartFinishElement);
            posStartFinish = spline.RenderVertsLeft[vertSplineIndex] + 0.5f * (spline.RenderVertsRight[vertSplineIndex] - spline.RenderVertsLeft[vertSplineIndex]);
            rotStartFinish = Vector2.Angle(new Vector2((spline.RenderVertsRight[vertSplineIndex] - spline.RenderVertsLeft[vertSplineIndex]).x, (spline.RenderVertsRight[vertSplineIndex] - spline.RenderVertsLeft[vertSplineIndex]).z), new Vector2(0f, 1f));
            if (Vector2.Angle(new Vector2((spline.RenderVertsRight[vertSplineIndex] - spline.RenderVertsLeft[vertSplineIndex]).x, (spline.RenderVertsRight[vertSplineIndex] - spline.RenderVertsLeft[vertSplineIndex]).z), new Vector2(1f, 0f)) > 90f)
            {
                rotStartFinish = 360 - rotStartFinish;
            }

            rotStartFinish  = rotStartFinish * Mathf.PI / 180f;
            rotStartFinish -= (Mathf.PI * 0.5f);
        }

        posStartFinish = new Vector3(posStartFinish.x, track.GetTensorHeight(posStartFinish), posStartFinish.z);

        startFinishBow.transform.position = posStartFinish;
        startFinishBow.transform.rotation = Quaternion.Euler(0f, rotStartFinish * 180f / Mathf.PI, 0f);


        //3,924



        Debug.Log("Generate Grass planes: " + Time.time);

        for (int j = 0; j < track.GrassPlanes.Length; j++)
        {
            Vector3[] grassLeftVerts = track.GrassPlanes[j].vertices;
            for (int i = 0; i < grassLeftVerts.Length; i++)
            {
                grassLeftVerts[i] = grassLeftVerts[i] + new Vector3(0f, track.GetTensorHeight(grassLeftVerts[i]), 0f);
            }


            GameObject grassLeft = Instantiate(grassPlanePrefab);
            grassLeft.transform.position = transform.position;
            grassLeft.GetComponent <MeshFilter>().mesh.Clear();
            grassLeft.GetComponent <MeshFilter>().mesh.vertices     = grassLeftVerts;
            grassLeft.GetComponent <MeshFilter>().mesh.uv           = track.GrassPlanes[j].uvs;
            grassLeft.GetComponent <MeshFilter>().mesh.subMeshCount = 1;
            grassLeft.GetComponent <MeshFilter>().mesh.SetTriangles(track.GrassPlanes[j].triangles, 0);
            grassLeft.GetComponent <MeshFilter>().mesh.RecalculateNormals();
            grassLeft.GetComponent <MeshCollider>().sharedMesh = grassLeft.GetComponent <MeshFilter>().mesh;

            instDebugObjects.Add(grassLeft);


            if (track.GrassPlanes[j].AllowBordercross)
            {
                List <Vector3> borderVerts = new List <Vector3>();
                List <Vector3> borderDirs  = new List <Vector3>();
                for (int k = 0; k < track.GrassPlanes[j].verticesOutside.Length; k++)
                {
                    int k0 = (k - 1) < 0 ? track.GrassPlanes[j].verticesOutside.Length - 1 : (k - 1);
                    int k2 = (k + 1) % track.GrassPlanes[j].verticesOutside.Length;

                    if (Vector3.Distance(track.GrassPlanes[j].verticesOutside[k], track.GrassPlanes[j].verticesOutside[k2]) >= 0.01f)
                    {
                        borderVerts.Add(track.GrassPlanes[j].verticesOutside[k] + new Vector3(0f, track.GetTensorHeight(track.GrassPlanes[j].verticesOutside[k]), 0f));
                        borderDirs.Add(track.GrassPlanes[j].directionsOutside[k]);
                    }
                }



                GameObject instLeftCrossover = Instantiate(crossoverRegionPrefab, transform);
                instLeftCrossover.transform.localPosition = Vector3.zero;
                instLeftCrossover.GetComponent <CrossoverRegion>().GeneratedTrack = track;
                instLeftCrossover.GetComponent <CrossoverRegion>().Render(borderVerts.ToArray(), borderDirs.ToArray(), true);

                instDebugObjects.Add(instLeftCrossover);
            }
        }

        if (track.Circles != null)
        {
            for (int i = 0; i < track.Circles.Length; i++)
            {
                GameObject instDebugCircle = Instantiate(debugText);
                instDebugCircle.transform.position = new Vector3(track.Circles[i].Midpoint.x, 0f, track.Circles[i].Midpoint.y);

                instDebugObjects.Add(instDebugCircle);
            }
        }


        //5,544



        for (int i = 0; i < vertices.Count; i++)
        {
            //int currentElement = elementsVertices[i];
            vertices[i] = vertices[i] + new Vector3(0f, track.GetTensorHeight(vertices[i]), 0f);
        }



        //5,560



        //
        // Cross over region
        //


        Vector3[] leftVertices    = new Vector3[vertices.Count / 2];
        Vector3[] rightVertices   = new Vector3[vertices.Count / 2];
        Vector3[] leftDirections  = new Vector3[vertices.Count / 2];
        Vector3[] rightDirections = new Vector3[vertices.Count / 2];

        for (int i = 0; i < vertices.Count; i++)
        {
            if (i % 2 == 0)
            {
                leftVertices[i / 2]   = vertices[i];
                leftDirections[i / 2] = vertices[i] - vertices[i + 1];
            }
            else
            {
                rightVertices[(i - 1) / 2]   = vertices[vertices.Count - i];
                rightDirections[(i - 1) / 2] = vertices[vertices.Count - i] - vertices[vertices.Count - i - 1];
            }
        }


        Debug.Log("Generate Curbs: " + Time.time);

        for (int i = 0; i < track.Curbs.Length; i++)
        {
            GameObject instCurb = Instantiate(curbPrefab);
            instCurb.transform.position = new Vector3(0f, 0.5f, 0f);
            instCurb.GetComponent <CurbRenderer>().ApplyCurb(track.Curbs[i], track.TerrainModifier);
            instDebugObjects.Add(instCurb);
        }



        if (instWallLeft != null)
        {
            Destroy(instWallLeft);
            instWallLeft = null;
        }
        if (instWallRight != null)
        {
            Destroy(instWallRight);
            instWallRight = null;
        }

        instWallLeft = Instantiate(wallPrefab);
        instWallLeft.transform.position = Vector3.zero;
        instWallRight = Instantiate(wallPrefab);
        instWallRight.transform.position = Vector3.zero;

        instWallLeft.GetComponent <WallRenderer>().Points  = track.BorderGenerator.WallLeft;
        instWallRight.GetComponent <WallRenderer>().Points = track.BorderGenerator.WallRight;


        //5,730



        Debug.Log("Set track mesh: " + Time.time);



        meshFilter.mesh.Clear();
        meshFilter.mesh.vertices = vertices.ToArray();
        meshFilter.mesh.uv       = uvs.ToArray();

        meshFilter.mesh.subMeshCount = 1;

        meshFilter.mesh.SetTriangles(triangles.ToArray(), 0);

        meshFilter.mesh.RecalculateNormals();

        meshCollider.sharedMesh = meshFilter.mesh;


        //5,743


        Debug.Log("Apply grass: " + Time.time);

        terrainModifier.ApplyGrass(vertices.ToArray());

        //61,596



        Debug.Log("Adjust terrain to track: " + Time.time);

        terrainGenerator.AdjustTerrainToTrack(vertices.ToArray());


        currentRenderedTrack = track;



        tempRem = false;

        //Debug.Log("Finished: " + Time.time);
    }
예제 #3
0
    public void Render(Vector3[] points, Vector3[] directions, bool circle)
    {
        int stepsAmount = 0;

        Line[] lines = new Line[circle ? points.Length : points.Length - 1];
        for (int i = 0; i < lines.Length; i++)
        {
            int i2 = (i + 1) % points.Length;
            lines[i] = new Line(new Vector2(points[i].x, points[i].z), new Vector2(points[i2].x, points[i2].z));
        }

        List <Vector3> vertices  = new List <Vector3>();
        List <Vector2> uvs       = new List <Vector2>();
        List <int>     triangles = new List <int>();

        float angle = 0f;

        if (points.Length >= 4)
        {
            for (int i = 0; i < points.Length; i++)
            {
                Vector3 toRight;
                if (circle)
                {
                    Vector3 nextPoint = points[(i + 1) % points.Length];
                    Vector3 prevPoint = points[i - 1 < 0 ? points.Length - 1 : i - 1];

                    toRight = (nextPoint - prevPoint).normalized;

                    angle = 0f;// Vector3.Angle(points[i] - prevPoint, nextPoint - points[i]);

                    for (int j = -2; j <= 2; j++)
                    {
                        int prevJ = (j + i - 1) < 0 ? (points.Length + (j + i - 1)) : ((j + i - 1) % points.Length);
                        int nextJ = (j + i + 1) < 0 ? (points.Length + (j + i + 1)) : ((j + i + 1) % points.Length);
                        int atJ   = (j + i) < 0 ? (points.Length + (j + i)) : ((j + i) % points.Length);

                        float angleHere = Vector3.Angle(points[atJ] - points[prevJ], points[nextJ] - points[atJ]);

                        float factor = 0f;
                        if (Mathf.Abs(j) == 2)
                        {
                            factor = 0.06f;
                        }
                        else if (Mathf.Abs(j) == 1)
                        {
                            factor = 0.23f;
                        }
                        else
                        {
                            factor = 0.42f;
                        }

                        angle += (angleHere * factor);
                    }

                    Vector2 forward = new Vector2(points[i].x - prevPoint.x, points[i].z - prevPoint.z);
                    Ray2D   rayF    = new Ray2D(new Vector2(prevPoint.x, prevPoint.z), forward);

                    if ((Utils.PointRightTo(rayF, new Vector2(nextPoint.x, nextPoint.z))) == (Vector2.Angle(new Vector2(-directions[i].z, directions[i].x), rayF.direction) >= 90f))
                    {
                        angle = 0f;
                    }
                }
                else
                {
                    if (i == 0)
                    {
                        toRight = (points[i + 1] - points[0]).normalized;
                    }
                    else if (i == points.Length - 1)
                    {
                        toRight = (points[points.Length - 1] - points[points.Length - 2]).normalized;
                    }
                    else
                    {
                        Vector3 nextPoint = points[i + 1];
                        Vector3 prevPoint = points[i - 1];

                        toRight = (nextPoint - prevPoint).normalized;
                    }
                }

                Vector3 down = Vector3.Cross(toRight, directions[i]).normalized;
                if (down.y > 0f)
                {
                    down *= -1f;
                }

                float minDistance = float.MaxValue;
                int   lineIndex   = -1;
                Line  thisLine    = new Line(new Vector2(points[i].x + directions[i].normalized.x * 0.05f, points[i].z + directions[i].normalized.z * 0.05f), new Vector2(points[i].x + directions[i].normalized.x, points[i].z + directions[i].normalized.z));
                for (int j = 0; j < lines.Length; j++)
                {
                    int     j1 = j == 0 ? lines.Length - 1 : j - 1;
                    int     j2 = (j + 1) % lines.Length;
                    Vector2 intersectPoint;
                    if (j1 != i && j != i && j2 != i && lines[i].Intersects(thisLine, out intersectPoint))
                    {
                        if (Vector2.Distance(intersectPoint, new Vector2(points[i].x, points[i].z)) < minDistance)
                        {
                            minDistance = Vector2.Distance(intersectPoint, new Vector2(points[i].x, points[i].z));
                            lineIndex   = j;
                        }
                    }
                }

                if (lineIndex != -1)
                {
                    if (minDistance < 0.1f)
                    {
                        minDistance = 0.1f;
                    }

                    int     lineIndex2  = (lineIndex + 1) % points.Length;
                    Vector3 lowestPoint = points[lineIndex];
                    if (lowestPoint.y > points[lineIndex2].y)
                    {
                        lowestPoint = points[lineIndex2];
                    }

                    directions[i] = new Vector3(directions[i].normalized.x, (lowestPoint.y - points[i].y) * (1f / minDistance), directions[i].normalized.z);
                }

                uvs.Add(new Vector2(points[i].x, points[i].z));
                vertices.Add(points[i]);

                int   counter = 0;
                float x       = 0f;
                while (stepsAmount == 0 ? x < maxDistance : counter < stepsAmount)
                {
                    float[] func = fallFunction(angleResolution * counter);

                    x = func[0];

                    Vector3 vert = points[i] + directions[i].normalized * func[0] * Mathf.Min((1f / (angle / 4.5f)), 1f) + down * func[1];

                    //vertices.Add(new Vector3(vert.x, (GeneratedTrack.GetTensorHeight(vert) - 1.2f) * (x / maxDistance) + ((maxDistance - x) / maxDistance) * vert.y, vert.z));
                    vertices.Add(new Vector3(vert.x, (GeneratedTrack.GetTensorHeight(vert)) + (x / maxDistance) * -1.2f, vert.z));
                    uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));

                    counter++;
                }

                if (stepsAmount == 0)
                {
                    stepsAmount = counter;
                }


                if (i > 0)
                {
                    for (int j = 0; j < stepsAmount - 1; j++)
                    {
                        if (Vector3.Cross((vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 1 + stepsAmount + 1)]), (vertices[vertices.Count - (j + 1 + stepsAmount + 1)] - vertices[vertices.Count - (j + 2 + stepsAmount + 1)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 1));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                        }

                        if (Vector3.Cross((vertices[vertices.Count - (j + 2)] - vertices[vertices.Count - (j + 1)]), (vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 2 + stepsAmount + 1)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 2));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                        }
                    }
                }
                if (i == points.Length - 1 && circle)
                {
                    for (int j = 0; j < stepsAmount - 1; j++)
                    {
                        if (Vector3.Cross((vertices[stepsAmount - (j + 1)] - vertices[vertices.Count - (j + 1)]), (vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 2)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(stepsAmount - (j + 1));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                        }

                        if (Vector3.Cross((vertices[stepsAmount - (j + 2)] - vertices[stepsAmount - (j + 1)]), (vertices[stepsAmount - (j + 1)] - vertices[vertices.Count - (j + 2)])).y > 0f)
                        {
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(stepsAmount - (j + 2));
                        }
                        else
                        {
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(stepsAmount - (j + 2));
                            triangles.Add(vertices.Count - (j + 2));
                        }
                    }
                }
            }


            GetComponent <MeshFilter>().mesh.Clear();
            GetComponent <MeshFilter>().mesh.vertices = vertices.ToArray();

            for (int i = 0; i < uvs.Count; i++)
            {
                //uvs[i] = uvs[i] / 15f;
            }

            GetComponent <MeshFilter>().mesh.uv = uvs.ToArray();

            GetComponent <MeshFilter>().mesh.subMeshCount = 1;

            GetComponent <MeshFilter>().mesh.SetTriangles(triangles.ToArray(), 0);

            GetComponent <MeshFilter>().mesh.RecalculateNormals();

            GetComponent <MeshCollider>().sharedMesh = GetComponent <MeshFilter>().mesh;
        }
    }