Example #1
0
    public SpeedAnalyzer(ClosedSpline <Vector3> idealLine, ClosedSpline <float> bankSpline, CurvatureAnalyzer curvature, int sampleRate)
    {
        this.idealLine = idealLine;

        vs    = new float[sampleRate];
        force = new Vector3[sampleRate];

        for (int i = 0; i < sampleRate; i++)
        {
            vs[i]    = 0f;
            force[i] = Vector3.zero;
        }

        for (int twice = 0; twice < 2; twice++)
        {
            for (int i = 0; i < sampleRate; i++)
            {
                int iPrev = i - 1;
                if (iPrev < 0)
                {
                    iPrev = sampleRate - 1;
                }

                float sPrev = ((float)iPrev) / sampleRate;
                float s     = ((float)i) / sampleRate;

                float angleHere = Vector3.Angle(idealLine.TangentAt(sPrev)[1] - idealLine.TangentAt(sPrev)[0], new Vector3((idealLine.TangentAt(sPrev)[1] - idealLine.TangentAt(sPrev)[0]).x, 0f, (idealLine.TangentAt(sPrev)[1] - idealLine.TangentAt(sPrev)[0]).z));
                if ((idealLine.TangentAt(sPrev)[1] - idealLine.TangentAt(sPrev)[0]).y < 0f)
                {
                    angleHere = -angleHere;
                }

                float estimatedT = -1f + Mathf.Sqrt(1f + (Vector3.Distance(idealLine.SplineAt(s), idealLine.SplineAt(sPrev)) * 2f) / carAcceleration(vs[iPrev], angleHere));
                float v          = vs[iPrev] + estimatedT * carAcceleration(vs[iPrev], angleHere);

                float aZ = carAcceleration(vs[iPrev], angleHere);

                float radius = Mathf.Abs(1f / curvature.Curvature[(int)(s * curvature.Curvature.Length)]);

                float bankToRightAngle = bankSpline.SplineAt(s);

                float vMax = lateralAcceleration(bankToRightAngle, radius, curvature.Curvature[(int)(s * curvature.Curvature.Length)] >= 0f);

                //float vMax = Mathf.Sqrt(lateralAcceleration(v) * radius);

                if (vMax < v)
                {
                    v = vMax;
                    float vBack = v;
                    for (int j = 1; j < sampleRate; j++)
                    {
                        int index = i - j;
                        if (index < 0)
                        {
                            index = sampleRate + index;
                        }
                        int indexPrev = index + 1;
                        if (indexPrev >= sampleRate)
                        {
                            indexPrev = 0;
                        }

                        float sTempPrev = ((float)indexPrev) / sampleRate;
                        float sTemp     = ((float)index) / sampleRate;

                        float estimatedTTemp = -1f + Mathf.Sqrt(1f + (Vector3.Distance(idealLine.SplineAt(s), idealLine.SplineAt(sPrev)) * 2f) / carAcceleration(vs[iPrev], angleHere));
                        float vMaxBack       = vBack + estimatedTTemp * braking(vBack, angleHere);

                        if (vMaxBack < vs[index])
                        {
                            vs[index]    = vMaxBack;
                            force[index] = new Vector3((vMaxBack * vMaxBack) / radius, force[index].y, -braking(vBack, angleHere));
                            vBack        = vMaxBack;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                vs[i] = v;

                force[i] = new Vector3((v * v * Mathf.Sign(curvature.Curvature[(int)(s * curvature.Curvature.Length)])) / radius, 0f, aZ);
            }
        }
    }
Example #2
0
    public DiscreteTrack(GeneratedTrack track, TerrainModifier terrainModifier)
    {
        List <Vector3> lefts        = new List <Vector3>();
        List <Vector3> rights       = new List <Vector3>();
        List <Vector3> leftsCurv    = new List <Vector3>();
        List <Vector3> rightsCurv   = new List <Vector3>();
        List <int>     indcs        = new List <int>();
        int            indcsCounter = 0;

        List <float> idealLineMeshList = new List <float>();
        int          idLineMeshCounter = 0;

        for (int i = 0; i < track.Elements.Length; i++)
        {
            if (track.Elements[i].GetType() == typeof(GeneratedStraight))
            {
                Vector3 middle = track.Elements[i].Position;

                Vector3 toRight = (new Vector3(Mathf.Cos(track.Elements[i].Direction), 0f, -Mathf.Sin(track.Elements[i].Direction))).normalized;
                Vector3 toFront = (new Vector3(Mathf.Sin(track.Elements[i].Direction), 0f, Mathf.Cos(track.Elements[i].Direction))).normalized;

                lefts.Add(middle - toRight * track.Elements[i].WidthStart);
                rights.Add(middle + toRight * track.Elements[i].WidthStart);
                indcsCounter = -1;

                GeneratedStraight straight = (GeneratedStraight)track.Elements[i];
                int segsAmount             = (int)(straight.Length / straightSegmentingFactorIdealline);

                int segmentsAmountMesh = (int)(straight.Length / straightSegmentingFactorMesh);
                for (int j = 0; j < segmentsAmountMesh; j++)
                {
                    //idealLineMesh[idLineMeshCounter] = 1f;
                    idealLineMeshList.Add(1f);
                    idLineMeshCounter++;
                }

                for (int j = 0; j < segsAmount; j++)
                {
                    leftsCurv.Add(middle - toRight * track.Elements[i].WidthStart + toFront * straight.Length * (((float)j) / ((float)segsAmount)));
                    rightsCurv.Add(middle + toRight * track.Elements[i].WidthStart + toFront * straight.Length * (((float)j) / segsAmount));
                    indcsCounter++;
                }

                indcs.Add(indcsCounter);
            }
            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) / 30f)) + 1;

                for (int j = 0; 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;

                    lefts.Add(segmentPos + toRightTurned * currentWidth * -1f + turn.Position);
                    rights.Add(segmentPos + toRightTurned * currentWidth + turn.Position);
                    leftsCurv.Add(segmentPos + toRightTurned * currentWidth * -1f + turn.Position);
                    rightsCurv.Add(segmentPos + toRightTurned * currentWidth + turn.Position);
                    indcs.Add(0);
                }
            }
            else if (track.Elements[i].GetType() == typeof(GeneratedBezSpline))
            {
                GeneratedBezSpline bezierSpline = (GeneratedBezSpline)track.Elements[i];

                for (int j = 0; j < bezierSpline.RenderVertsLeft.Length - 1; j++)
                {
                    if (j == 0)
                    {
                        //idealLineMesh[idLineMeshCounter] = 2f;
                        idealLineMeshList.Add(2f);
                    }
                    else
                    {
                        //idealLineMesh[idLineMeshCounter] = 0f;
                        idealLineMeshList.Add(0f);
                    }
                    idLineMeshCounter++;

                    if (j % 3 == 0)
                    {
                        lefts.Add(bezierSpline.RenderVertsLeft[j]);
                        rights.Add(bezierSpline.RenderVertsRight[j]);
                        leftsCurv.Add(bezierSpline.RenderVertsLeft[j]);
                        rightsCurv.Add(bezierSpline.RenderVertsRight[j]);
                        indcs.Add(0);
                    }
                }
            }
        }

        idealLineMesh = idealLineMeshList.ToArray();

        leftPoints                 = lefts.ToArray();
        rightPoints                = rights.ToArray();
        leftPointsCurv             = leftsCurv.ToArray();
        rightPointsCurv            = rightsCurv.ToArray();
        indcsFromPathIntoCurvature = indcs.ToArray();

        shortestPathTrajectory = minimizePathTrajectory();
        if (false)
        {
            for (int i = 0; i < leftPoints.Length; i++)
            {
                int i2 = (i + 1) % leftPoints.Length;
                Debug.DrawLine(leftPoints[i], leftPoints[i2], Color.white, 10000f);
                Debug.DrawLine(rightPoints[i], rightPoints[i2], Color.white, 10000f);
                Debug.DrawLine(leftPoints[i], rightPoints[i], Color.white, 10000f);


                Debug.DrawLine(shortestPathTrajectory[i] * (leftPoints[i] - rightPoints[i]) + rightPoints[i], shortestPathTrajectory[i2] * (leftPoints[i2] - rightPoints[i2]) + rightPoints[i2], Color.green, 10000f);
            }
        }

        minimumCurvatureTrajectory = minimizeCurvatureTrajectory();

        if (false)
        {
            for (int i = 0; i < leftPointsCurv.Length; i++)
            {
                int i2 = (i + 1) % leftPointsCurv.Length;
                Debug.DrawLine(leftPointsCurv[i], leftPointsCurv[i2], Color.white, 10000f);
                Debug.DrawLine(rightPointsCurv[i], rightPointsCurv[i2], Color.white, 10000f);
                Debug.DrawLine(leftPointsCurv[i], rightPointsCurv[i], Color.white, 10000f);


                Debug.DrawLine(minimumCurvatureTrajectory[i] * (leftPointsCurv[i] - rightPointsCurv[i]) + rightPointsCurv[i], minimumCurvatureTrajectory[i2] * (leftPointsCurv[i2] - rightPointsCurv[i2]) + rightPointsCurv[i2], Color.green, 10000f);
            }
        }

        float epsilon = 0.1f;

        idealLine = applyEpsilon(shortestPathTrajectory, minimumCurvatureTrajectory, epsilon, indcsFromPathIntoCurvature);

        /*for (int i = 0; i < idealLine.Length; i++)
         * {
         *  Debug.Log("IL [" + i + "]: " + idealLine[i]);
         * }*/

        Debug.Log("cnter: " + idLineMeshCounter);

        transferToMeshIdealLine(track, idealLine, idealLineMesh);

        List <float>   cpsBankAngles  = new List <float>();
        List <Vector3> cpsMinDistance = new List <Vector3>();
        float          minDistance    = 15f;

        Vector3[] cps     = new Vector3[idealLine.Length];
        float[]   cpsBank = new float[idealLine.Length];
        cpsMinDistance.Add(idealLine[0] * (leftPointsCurv[0] - rightPointsCurv[0]) + rightPointsCurv[0]);
        for (int i = 1; i < idealLine.Length; i++)
        {
            Vector3 point = idealLine[i] * (leftPointsCurv[i] - rightPointsCurv[i]) + rightPointsCurv[i];
            //cps[i] = point;
            if (Vector3.Distance(cpsMinDistance[cpsMinDistance.Count - 1], point) > minDistance)
            {
                cpsBankAngles.Add(Vector3.Angle(new Vector3(rightPointsCurv[i].x - leftPointsCurv[i].x, terrainModifier.GetTensorHeight(rightPointsCurv[i].x, rightPointsCurv[i].z) - terrainModifier.GetTensorHeight(leftPointsCurv[i].x, leftPointsCurv[i].z), rightPointsCurv[i].z - leftPointsCurv[i].z), new Vector3((rightPointsCurv[i] - leftPointsCurv[i]).x, 0f, (rightPointsCurv[i] - leftPointsCurv[i]).z)) * Mathf.Sign((rightPointsCurv[i] - leftPointsCurv[i]).y));
                cpsMinDistance.Add(point);
            }
        }

        cps     = cpsMinDistance.ToArray();
        cpsBank = cpsBankAngles.ToArray();

        for (int i = 0; i < cps.Length; i++)
        {
            cps[i] = new Vector3(cps[i].x, terrainModifier.GetTensorHeight(cps[i].x, cps[i].z), cps[i].z);
        }

        idealLineSpline = new ClosedSpline <Vector3>(cps);
        ClosedSpline <float> bankSpline = new ClosedSpline <float>(cpsBank);

        curvatureAnalyzer = new CurvatureAnalyzer(idealLineSpline, 300);

        speedAnalyzer = new SpeedAnalyzer(idealLineSpline, bankSpline, curvatureAnalyzer, 300);

        curvatureAnalyzerTrack = new CurvatureAnalyzer(track, 300);

        curvatureIdealLineAnalyzer = new CurvatureIdeallineAnalyzer(idealLineSpline);

        float startFinishLength = 500f;
        float partStartFinish   = startFinishLength / track.TrackLength;

        int elementsStartFinishAmount = (int)(idealLineSpline.ControlPointsAmount * partStartFinish);

        elementsStartFinishAmount = (int)(partStartFinish * 300f);

        int startFinishIndex = minCurvatureForAmount(curvatureAnalyzerTrack.Curvature, elementsStartFinishAmount);

        float partpart = curvatureAnalyzerTrack.trackPartIndices[startFinishIndex];

        //Vector3 beginStartFinishPoint = idealLineSpline.controlPoints[startFinishIndex];

        Debug.Log("Start Finish point: " + partpart);


        int     elementStartFinishBeginIndex = (int)partpart;
        Vector3 elementStartPos = track.Elements[elementStartFinishBeginIndex].Position;

        startFinishLineIndex = partpart;
        //Debug.Log("Start Finish point: " + elementStartPos);
    }