コード例 #1
0
    public override Racetrack ApplyRacetrack(Racetrack racetrack)
    {
        angle  = 0f;
        radius = 3f;
        //Generate(amountOfCPs);

        Vector3[] checkpoints = new Vector3[amountOfCPs];

        for (int i = 0; i < amountOfCPs; i++)
        {
            //GameObject instCp = (GameObject)Instantiate(prefabControlpoint, instTrack.transform);
            angle  += Random.Range(minAngle, maxAngle);
            radius += Random.Range(minRadius, maxRadius);

            Vector2 point = new Vector2(Mathf.Sin((angle * Mathf.PI) / 180f) * radius, Mathf.Cos((angle * Mathf.PI) / 180f) * radius);

            checkpoints[i] = new Vector3(point.x, 0f, point.y);

            //instCp.transform.position = new Vector3(point.x, 0f, point.y);

            //instCPs.Add(instCp);
        }


        ClosedSpline <Vector3> clSpline = new ClosedSpline <Vector3>(checkpoints);

        //if (instTrack != null)
        //{
        racetrack.track = clSpline;
        //}

        return(racetrack);
    }
コード例 #2
0
ファイル: DiscreteTrack.cs プロジェクト: SimonBlasen/UnityML
    public float getCurvature(ClosedSpline <Vector2> spline)
    {
        float curvature  = 0f;
        int   resolution = 20;

        for (int i = 0; i < spline.ControlPointsAmount; i++)
        {
            float localMax = 0f;

            float s  = ((float)i) / spline.ControlPointsAmount;
            float s2 = ((float)((i + 1))) / spline.ControlPointsAmount;

            for (int j = 0; j < resolution; j++)
            {
                float locS  = s + (s2 - s) * (((float)j) / resolution);
                float locS2 = s + (s2 - s) * (((float)(j + 1)) / resolution);

                Vector2 t1 = spline.TangentAt(s)[1] - spline.TangentAt(s)[0];
                Vector2 t2 = spline.TangentAt(s2)[1] - spline.TangentAt(s2)[0];

                float curv = Vector2.Angle(t1, t2);

                if (curv > localMax)
                {
                    localMax = curv;
                }
            }

            curvature += localMax;
        }

        return(curvature);
    }
コード例 #3
0
ファイル: WidthProfiler.cs プロジェクト: SimonBlasen/UnityML
    public override Racetrack ApplyRacetrack(Racetrack racetrack)
    {
        float[] cps = new float[racetrack.track.controlPoints.Length];
        for (int i = 0; i < cps.Length; i++)
        {
            cps[i] = Random.Range(widthMin, widthMax);
        }

        ClosedSpline <float> widthSpline = new ClosedSpline <float>(cps);

        racetrack.width = widthSpline;

        return(racetrack);
    }
コード例 #4
0
ファイル: HeightProfiler.cs プロジェクト: SimonBlasen/UnityML
    public override Racetrack ApplyRacetrack(Racetrack racetrack)
    {
        float[] cps = new float[checkpointsAmount];
        for (int i = 0; i < cps.Length; i++)
        {
            float heightThere = terrain.SampleHeight(racetrack.track.SplineAt(((float)i) / ((float)cps.Length)) * 20f);
            //Debug.Log("Height (" + (int)(racetrack.track.controlPoints[i].x * 20f + transform.position.x) + "," + (int)(racetrack.track.controlPoints[i].z * 20f + transform.position.z) + "): " + heightThere);
            cps[i] = heightThere;
        }

        ClosedSpline <float> heightSpline = new ClosedSpline <float>(cps);

        racetrack.height = heightSpline;

        return(racetrack);
    }
コード例 #5
0
    public CurvatureIdeallineAnalyzer(ClosedSpline <Vector3> idealLine)
    {
        int n = idealLine.ControlPointsAmount;

        curvatureValues = new float[n];
        for (int i = 0; i < n; i++)
        {
            curvatureValues[i] = float.MaxValue;
        }


        for (int i = 0; i < n; i++)
        {
            float s  = ((float)i) / n;
            float s2 = ((float)(i + 1)) / n;


            Vector3 tangent1 = idealLine.TangentAt(s)[1] - idealLine.TangentAt(s)[0];
            Vector3 tangent2 = idealLine.TangentAt(s2)[1] - idealLine.TangentAt(s2)[0];
            Vector2 pos1     = new Vector2(idealLine.SplineAt(s).x, idealLine.SplineAt(s).z);
            Vector2 pos2     = new Vector2(idealLine.SplineAt(s2).x, idealLine.SplineAt(s2).z);
            Vector2 dir1     = new Vector2(tangent1.z, -tangent1.x);
            Vector2 dir2     = new Vector2(tangent2.z, -tangent2.x);
            Ray2D   ray1     = new Ray2D(pos1, dir1);
            Ray2D   ray2     = new Ray2D(pos2, dir2);

            Ray2D straightRay = new Ray2D(pos1, tangent1);

            bool    parallel;
            Vector2 intersect = Utils.Intersect2D(ray1, ray2, out parallel);
            if (parallel)
            {
                curvatureValues[i] = 0f;
            }
            else
            {
                float radius = (Vector2.Distance(intersect, pos1) + Vector2.Distance(intersect, pos2)) * 0.5f;

                curvatureValues[i] = (1f / radius) * (Utils.PointRightTo(straightRay, intersect) ? 1f : -1f);
            }
        }
    }
コード例 #6
0
    public override Racetrack ApplyRacetrack(Racetrack racetrack)
    {
        float[] cps = new float[checkpointsAmount];
        for (int i = 0; i < cps.Length; i++)
        {
            //Debug.Log("Height (" + (int)(racetrack.track.controlPoints[i].x * 20f + transform.position.x) + "," + (int)(racetrack.track.controlPoints[i].z * 20f + transform.position.z) + "): " + heightThere);


            Vector3   middlePosFirst = racetrack.track.SplineAt(((float)i) / ((float)cps.Length));
            Vector3[] tangentFirst   = racetrack.track.TangentAt(((float)i) / ((float)cps.Length));
            Vector3   forwardFirst   = tangentFirst[1] - tangentFirst[0];
            forwardFirst.Normalize();
            Vector3 sidewardsFirst = Quaternion.Euler(0f, 90f, 0f) * forwardFirst;
            sidewardsFirst.Normalize();

            Vector3 leftFirst  = (middlePosFirst - sidewardsFirst * racetrack.width.SplineAt(0f) * 0.5f);
            Vector3 rightFirst = (middlePosFirst + sidewardsFirst * racetrack.width.SplineAt(0f) * 0.5f);

            leftFirst  *= 20f;
            rightFirst *= 20f;

            float heightLeft  = terrain.SampleHeight(leftFirst);
            float heightRight = terrain.SampleHeight(rightFirst);

            Vector3 leftFirstH  = leftFirst;
            Vector3 rightFirstH = rightFirst;
            leftFirstH.y  = heightLeft;
            rightFirstH.y = heightRight;



            cps[i] = Vector3.Angle(leftFirst - rightFirst, leftFirstH - rightFirstH) * Mathf.Sign(heightRight - heightLeft);
        }

        ClosedSpline <float> heightSpline = new ClosedSpline <float>(cps);

        racetrack.bend = heightSpline;

        return(racetrack);
    }
コード例 #7
0
    // Use this for initialization
    void Start()
    {
        Vector3[] cpPosses = new Vector3[controlPoints.Length];
        for (int i = 0; i < controlPoints.Length; i++)
        {
            cpPosses[i] = controlPoints[i].transform.position;
        }

        clSpline = new ClosedSpline <Vector3>(cpPosses);

        for (int i = 0; i < controlPoints.Length; i++)
        {
            if (Application.isPlaying)
            {
                controlPoints[i].GetComponent <MeshRenderer>().enabled = false;
            }
            else
            {
                controlPoints[i].GetComponent <MeshRenderer>().enabled = true;
            }
        }
    }
コード例 #8
0
    public TerrainModifier(Terrain terrain, List <GeneratedElement> elements)
    {
        this.terrain = terrain;

        float[] cpsLeft  = new float[elements.Count];
        float[] cpsRight = new float[elements.Count];

        for (int i = 0; i < elements.Count; i++)
        {
            Vector3 toRight = (Quaternion.Euler(0f, (elements[i].Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(elements[i].WidthEnd, 0f, 0f));

            Vector3 samplePosLeft  = elements[i].Position - toRight;
            Vector3 samplePosRight = elements[i].Position + toRight;

            cpsLeft[i]  = terrain.SampleHeight(samplePosLeft);
            cpsRight[i] = terrain.SampleHeight(samplePosRight);
        }

        heightsLeft  = new ClosedSpline <float>(cpsLeft);
        heightsRight = new ClosedSpline <float>(cpsRight);

        int   cpsAmount = 2000;
        float scale     = 10f;

        float[,] cps = new float[cpsAmount + 1, cpsAmount + 1];

        for (int x = cpsAmount / -2; x <= cpsAmount / 2; x++)
        {
            for (int y = cpsAmount / -2; y <= cpsAmount / 2; y++)
            {
                cps[x + cpsAmount / 2, y + cpsAmount / 2] = terrain.SampleHeight(new Vector3(x * scale, 0f, y * scale));
            }
        }

        tempGeneratedCPs = cps;

        tensorProductPlane = new TensorProductPlane(new Vector3((cpsAmount / -2) * scale, 0f, (cpsAmount / -2) * scale), scale, cps);
    }
コード例 #9
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);
            }
        }
    }
コード例 #10
0
 public CurvatureAnalyzer(ClosedSpline <Vector3> spline) : this(spline, 300)
 {
 }
コード例 #11
0
    public CurvatureAnalyzer(ClosedSpline <Vector3> spline, int sampleRate)
    {
        this.spline     = spline;
        this.sampleRate = sampleRate;

        curvatureValues = new float[sampleRate];

        curvativeBins = new float[17];
        for (int i = -8; i <= 8; i++)
        {
            curvativeBins[i + 8] = (((float)i) * maxBinValue) / 8.0f;
        }

        if (curvativeBins != null && curvativeBins.Length > 0)
        {
            curvativeProfile = new int[curvativeBins.Length];
            for (int i = 0; i < curvativeProfile.Length; i++)
            {
                curvativeProfile[i] = 0;
            }
        }

        for (int i = 0; i < sampleRate; i++)
        {
            float curPos  = ((float)i) / ((float)sampleRate);
            float nextPos = ((float)(i + 1)) / ((float)sampleRate);

            Vector3 pos1 = spline.SplineAt(curPos);
            Vector3 pos2 = spline.SplineAt(nextPos);

            Vector3 tangent1 = spline.TangentAt(curPos)[1] - spline.TangentAt(curPos)[0];
            Vector3 tangent2 = spline.TangentAt(nextPos)[1] - spline.TangentAt(nextPos)[0];

            Vector3 inside1 = Vector3.Cross(tangent1, Vector3.up);
            Vector3 inside2 = Vector3.Cross(tangent2, Vector3.up);

            Vector2 vec2Pos1    = new Vector2(pos1.x, pos1.z);
            Vector2 vec2Pos2    = new Vector2(pos2.x, pos2.z);
            Vector2 vec2Inside1 = new Vector2(inside1.x, inside1.z);
            Vector2 vec2Inside2 = new Vector2(inside2.x, inside2.z);

            Line line1 = new Line(vec2Pos1, vec2Pos1 + vec2Inside1);
            Line line2 = new Line(vec2Pos2, vec2Pos2 + vec2Inside2);

            Vector2 intersect = Vector2.zero;

            bool intersects = line1.Intersects(line2, out intersect);

            float curvative = 0f;

            if (intersect != Vector2.zero)
            {
                float radius1 = Vector2.Distance(intersect, vec2Pos1);
                float radius2 = Vector2.Distance(intersect, vec2Pos2);

                float avgRadius = (radius1 + radius2) * 0.5f;

                curvative = 1f / avgRadius;

                Vector3 toRight      = (inside1 - pos1).normalized;
                Vector3 intersectDir = ((new Vector3(intersect.x, pos1.y, intersect.y)) - pos1).normalized;

                if (Vector3.Angle(toRight, intersectDir) >= 90)
                {
                    curvative *= -1f;
                }

                curvatureValues[i] = curvative;
            }

            if (curvativeBins != null && curvativeBins.Length > 0)
            {
                bool found = false;
                for (int j = 0; j < curvativeBins.Length; j++)
                {
                    if (curvative < curvativeBins[j])
                    {
                        curvativeProfile[j]++;
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    curvativeProfile[curvativeProfile.Length - 1]++;
                }
            }
        }
    }
コード例 #12
0
ファイル: DiscreteTrack.cs プロジェクト: SimonBlasen/UnityML
    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);
    }
コード例 #13
0
    public override Racetrack ApplyRacetrack(Racetrack racetrack)
    {
        if (instTrack != null)
        {
            Destroy(instTrack);
            instTrack = null;
        }
        instTrack = Instantiate(renderedTrackPrefab, transform);
        instTrack.transform.localPosition = Vector3.zero;

        Vector3[] leftCps  = new Vector3[racetrack.track.controlPoints.Length];
        Vector3[] rightCps = new Vector3[racetrack.track.controlPoints.Length];

        for (int i = 0; i < leftCps.Length; i++)
        {
            Vector3   cpPos     = racetrack.track.controlPoints[i];
            Vector3[] tangentCp = racetrack.track.TangentAt(((float)i) / ((float)leftCps.Length));
            Vector3   forwardCp = tangentCp[1] - tangentCp[0];
            forwardCp.Normalize();
            Vector3 sidewardsCp = Quaternion.Euler(0f, 90f, 0f) * forwardCp;
            sidewardsCp.Normalize();
            rightCps[i] = cpPos + sidewardsCp * racetrack.width.controlPoints[i] * 0.5f;
            leftCps[i]  = cpPos - sidewardsCp * racetrack.width.controlPoints[i] * 0.5f;
        }

        ClosedSpline <Vector3> leftTrack  = new ClosedSpline <Vector3>(leftCps);
        ClosedSpline <Vector3> rightTrack = new ClosedSpline <Vector3>(rightCps);



        MeshFilter meshFilter = instTrack.GetComponent <MeshFilter>();

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

        List <int> trianglesWhite = new List <int>();

        List <int> trianglesGrass = new List <int>();


        float xPosFirst = 0f;

        /*Vector3 middlePosFirst = racetrack.track.SplineAt(xPosFirst);
         *
         * Vector3[] tangentFirst = racetrack.track.TangentAt(xPosFirst);
         *
         * Vector3 forwardFirst = tangentFirst[1] - tangentFirst[0];
         * forwardFirst.Normalize();
         * Vector3 sidewardsFirst = Quaternion.Euler(0f, 90f, 0f) * forwardFirst;
         *
         * sidewardsFirst.Normalize();
         *
         * Vector3 firstl_p = sidewardsFirst * -0.5f * racetrack.width.SplineAt(xPosFirst) + middlePosFirst;
         * Vector3 firstr_p = sidewardsFirst * 0.5f * racetrack.width.SplineAt(xPosFirst) + middlePosFirst;
         *
         * Vector3 firstl_whiteBegin = firstl_p + sidewardsFirst * whiteStripOffset;
         * Vector3 firstr_whiteBegin = firstr_p - sidewardsFirst * whiteStripOffset;
         *
         * Vector3 firstl_whiteInner = firstl_whiteBegin + sidewardsFirst * whiteStripWidth;
         * Vector3 firstr_whiteInner = firstr_whiteBegin - sidewardsFirst * whiteStripWidth;
         *
         * Vector3 firstl_grassSameHeight = firstl_p - sidewardsFirst * grassWidth;
         * Vector3 firstr_grassSameHeight = firstr_p + sidewardsFirst * grassWidth;
         *
         * Vector3 firstl_grassHill = firstl_grassSameHeight - sidewardsFirst * grassHillWidth + Vector3.Cross(sidewardsFirst, forwardFirst) * grassHillHeight;
         * Vector3 firstr_grassHill = firstr_grassSameHeight + sidewardsFirst * grassHillWidth + Vector3.Cross(sidewardsFirst, forwardFirst) * grassHillHeight;*/

        Vector3[] tangentFirstLeft = leftTrack.TangentAt(xPosFirst);
        Vector3   forwardFirstLeft = tangentFirstLeft[1] - tangentFirstLeft[0];

        forwardFirstLeft.Normalize();
        Vector3 sidewardsFirstLeft = Quaternion.Euler(0f, 90f, 0f) * forwardFirstLeft;

        sidewardsFirstLeft.Normalize();

        Vector3[] tangentFirstRight = rightTrack.TangentAt(xPosFirst);
        Vector3   forwardFirstRight = tangentFirstRight[1] - tangentFirstRight[0];

        forwardFirstRight.Normalize();
        Vector3 sidewardsFirstRight = Quaternion.Euler(0f, 90f, 0f) * forwardFirstRight;

        sidewardsFirstRight.Normalize();

        Vector3 firstl_p = leftTrack.SplineAt(xPosFirst);
        Vector3 firstr_p = rightTrack.SplineAt(xPosFirst);

        Vector3 firstl_whiteBegin = firstl_p + sidewardsFirstLeft * whiteStripOffset;
        Vector3 firstr_whiteBegin = firstr_p - sidewardsFirstRight * whiteStripOffset;

        Vector3 firstl_whiteInner = firstl_whiteBegin + sidewardsFirstLeft * whiteStripWidth;
        Vector3 firstr_whiteInner = firstr_whiteBegin - sidewardsFirstRight * whiteStripWidth;

        Vector3 firstl_grassSameHeight = firstl_p - sidewardsFirstLeft * grassWidth;
        Vector3 firstr_grassSameHeight = firstr_p + sidewardsFirstRight * grassWidth;

        Vector3 firstl_grassHill = firstl_grassSameHeight - sidewardsFirstLeft * grassHillWidth + Vector3.Cross(sidewardsFirstLeft, forwardFirstLeft) * grassHillHeight;
        Vector3 firstr_grassHill = firstr_grassSameHeight + sidewardsFirstRight * grassHillWidth + Vector3.Cross(sidewardsFirstRight, forwardFirstRight) * grassHillHeight;

        vertices.Add(firstl_grassHill);
        vertices.Add(firstl_grassSameHeight);
        vertices.Add(firstl_p);
        vertices.Add(firstl_whiteBegin);
        vertices.Add(firstl_whiteInner);
        vertices.Add(firstr_whiteInner);
        vertices.Add(firstr_whiteBegin);
        vertices.Add(firstr_p);
        vertices.Add(firstr_grassSameHeight);
        vertices.Add(firstr_grassHill);

        uvs.Add(new Vector2(firstl_grassHill.x, firstl_grassHill.z));
        uvs.Add(new Vector2(firstl_grassSameHeight.x, firstl_grassSameHeight.z));
        uvs.Add(new Vector2(firstl_p.x, firstl_p.z));
        uvs.Add(new Vector2(firstl_whiteBegin.x, firstl_whiteBegin.z));
        uvs.Add(new Vector2(firstl_whiteInner.x, firstl_whiteInner.z));
        uvs.Add(new Vector2(firstr_whiteInner.x, firstr_whiteInner.z));
        uvs.Add(new Vector2(firstr_whiteBegin.x, firstr_whiteBegin.z));
        uvs.Add(new Vector2(firstr_p.x, firstr_p.z));
        uvs.Add(new Vector2(firstr_grassSameHeight.x, firstr_grassSameHeight.z));
        uvs.Add(new Vector2(firstr_grassHill.x, firstr_grassHill.z));

        for (int i = 1; i < resolution; i++)
        {
            float xPos = ((float)i) / ((float)resolution);

            /*Vector3 middlePos = racetrack.track.SplineAt(xPos);
             *
             * Vector3[] tangent = racetrack.track.TangentAt(xPos);
             *
             * Vector3 forward = tangent[1] - tangent[0];
             * forward.Normalize();
             * Vector3 sidewards = Quaternion.Euler(0f, 90f, 0f) * forward;
             *
             * sidewards.Normalize();
             *
             * Vector3 l_p = sidewards * -0.5f * racetrack.width.SplineAt(xPos) + middlePos;
             * Vector3 r_p = sidewards * 0.5f * racetrack.width.SplineAt(xPos) + middlePos;
             *
             * Vector3 l_whiteBegin = l_p + sidewards * whiteStripOffset;
             * Vector3 r_whiteBegin = r_p - sidewards * whiteStripOffset;
             *
             * Vector3 l_whiteInner = l_whiteBegin + sidewards * whiteStripWidth;
             * Vector3 r_whiteInner = r_whiteBegin - sidewards * whiteStripWidth;
             *
             * Vector3 l_grassSameHeight = l_p - sidewards * grassWidth;
             * Vector3 r_grassSameHeight = r_p + sidewards * grassWidth;
             *
             * Vector3 l_grassHill = l_grassSameHeight - sidewards * grassHillWidth + Vector3.Cross(sidewards, forward) * grassHillHeight;
             * Vector3 r_grassHill = r_grassSameHeight + sidewards * grassHillWidth + Vector3.Cross(sidewards, forward) * grassHillHeight;*/

            Vector3[] tangentLeft = leftTrack.TangentAt(xPos);
            Vector3   forwardLeft = tangentLeft[1] - tangentLeft[0];
            forwardLeft.Normalize();
            Vector3 sidewardsLeft = Quaternion.Euler(0f, 90f, 0f) * forwardLeft;
            sidewardsLeft.Normalize();

            Vector3[] tangentRight = rightTrack.TangentAt(xPos);
            Vector3   forwardRight = tangentRight[1] - tangentRight[0];
            forwardRight.Normalize();
            Vector3 sidewardsRight = Quaternion.Euler(0f, 90f, 0f) * forwardRight;
            sidewardsRight.Normalize();

            Vector3 l_p = leftTrack.SplineAt(xPos);
            Vector3 r_p = rightTrack.SplineAt(xPos);

            Vector3 l_whiteBegin = l_p + sidewardsLeft * whiteStripOffset;
            Vector3 r_whiteBegin = r_p - sidewardsRight * whiteStripOffset;

            Vector3 l_whiteInner = l_whiteBegin + sidewardsLeft * whiteStripWidth;
            Vector3 r_whiteInner = r_whiteBegin - sidewardsRight * whiteStripWidth;

            Vector3 l_grassSameHeight = l_p - sidewardsLeft * grassWidth;
            Vector3 r_grassSameHeight = r_p + sidewardsRight * grassWidth;

            Vector3 l_grassHill = l_grassSameHeight - sidewardsLeft * grassHillWidth + Vector3.Cross(sidewardsLeft, forwardLeft) * grassHillHeight;
            Vector3 r_grassHill = r_grassSameHeight + sidewardsRight * grassHillWidth + Vector3.Cross(sidewardsRight, forwardRight) * grassHillHeight;


            vertices.Add(l_grassHill);
            vertices.Add(l_grassSameHeight);
            vertices.Add(l_p);
            vertices.Add(l_whiteBegin);
            vertices.Add(l_whiteInner);
            vertices.Add(r_whiteInner);
            vertices.Add(r_whiteBegin);
            vertices.Add(r_p);
            vertices.Add(r_grassSameHeight);
            vertices.Add(r_grassHill);

            uvs.Add(new Vector2(l_grassHill.x, l_grassHill.z));
            uvs.Add(new Vector2(l_grassSameHeight.x, l_grassSameHeight.z));
            uvs.Add(new Vector2(l_p.x, l_p.z));
            uvs.Add(new Vector2(l_whiteBegin.x, l_whiteBegin.z));
            uvs.Add(new Vector2(l_whiteInner.x, l_whiteInner.z));
            uvs.Add(new Vector2(r_whiteInner.x, r_whiteInner.z));
            uvs.Add(new Vector2(r_whiteBegin.x, r_whiteBegin.z));
            uvs.Add(new Vector2(r_p.x, r_p.z));
            uvs.Add(new Vector2(r_grassSameHeight.x, r_grassSameHeight.z));
            uvs.Add(new Vector2(r_grassHill.x, r_grassHill.z));

            triangles.Add((i - 1) * 10 + 2);
            triangles.Add((i - 0) * 10 + 2);
            triangles.Add((i - 1) * 10 + 3);
            triangles.Add((i - 1) * 10 + 3);
            triangles.Add((i - 0) * 10 + 2);
            triangles.Add((i - 0) * 10 + 3);

            triangles.Add((i - 1) * 10 + 4);
            triangles.Add((i - 0) * 10 + 4);
            triangles.Add((i - 1) * 10 + 5);
            triangles.Add((i - 1) * 10 + 5);
            triangles.Add((i - 0) * 10 + 4);
            triangles.Add((i - 0) * 10 + 5);

            triangles.Add((i - 1) * 10 + 6);
            triangles.Add((i - 0) * 10 + 6);
            triangles.Add((i - 1) * 10 + 7);
            triangles.Add((i - 1) * 10 + 7);
            triangles.Add((i - 0) * 10 + 6);
            triangles.Add((i - 0) * 10 + 7);



            trianglesWhite.Add((i - 1) * 10 + 3);
            trianglesWhite.Add((i - 0) * 10 + 3);
            trianglesWhite.Add((i - 1) * 10 + 4);
            trianglesWhite.Add((i - 1) * 10 + 4);
            trianglesWhite.Add((i - 0) * 10 + 3);
            trianglesWhite.Add((i - 0) * 10 + 4);

            trianglesWhite.Add((i - 1) * 10 + 5);
            trianglesWhite.Add((i - 0) * 10 + 5);
            trianglesWhite.Add((i - 1) * 10 + 6);
            trianglesWhite.Add((i - 1) * 10 + 6);
            trianglesWhite.Add((i - 0) * 10 + 5);
            trianglesWhite.Add((i - 0) * 10 + 6);



            trianglesGrass.Add((i - 1) * 10 + 0);
            trianglesGrass.Add((i - 0) * 10 + 0);
            trianglesGrass.Add((i - 1) * 10 + 1);
            trianglesGrass.Add((i - 1) * 10 + 1);
            trianglesGrass.Add((i - 0) * 10 + 0);
            trianglesGrass.Add((i - 0) * 10 + 1);

            trianglesGrass.Add((i - 1) * 10 + 1);
            trianglesGrass.Add((i - 0) * 10 + 1);
            trianglesGrass.Add((i - 1) * 10 + 2);
            trianglesGrass.Add((i - 1) * 10 + 2);
            trianglesGrass.Add((i - 0) * 10 + 1);
            trianglesGrass.Add((i - 0) * 10 + 2);

            trianglesGrass.Add((i - 1) * 10 + 7);
            trianglesGrass.Add((i - 0) * 10 + 7);
            trianglesGrass.Add((i - 1) * 10 + 8);
            trianglesGrass.Add((i - 1) * 10 + 8);
            trianglesGrass.Add((i - 0) * 10 + 7);
            trianglesGrass.Add((i - 0) * 10 + 8);

            trianglesGrass.Add((i - 1) * 10 + 8);
            trianglesGrass.Add((i - 0) * 10 + 8);
            trianglesGrass.Add((i - 1) * 10 + 9);
            trianglesGrass.Add((i - 1) * 10 + 9);
            trianglesGrass.Add((i - 0) * 10 + 8);
            trianglesGrass.Add((i - 0) * 10 + 9);
        }

        if (true)
        {
            #region Last One

            triangles.Add((resolution - 1) * 10 + 2);
            triangles.Add((0) * 10 + 2);
            triangles.Add((resolution - 1) * 10 + 3);
            triangles.Add((resolution - 1) * 10 + 3);
            triangles.Add((0) * 10 + 2);
            triangles.Add((0) * 10 + 3);

            triangles.Add((resolution - 1) * 10 + 4);
            triangles.Add((0) * 10 + 4);
            triangles.Add((resolution - 1) * 10 + 5);
            triangles.Add((resolution - 1) * 10 + 5);
            triangles.Add((0) * 10 + 4);
            triangles.Add((0) * 10 + 5);

            triangles.Add((resolution - 1) * 10 + 6);
            triangles.Add((0) * 10 + 6);
            triangles.Add((resolution - 1) * 10 + 7);
            triangles.Add((resolution - 1) * 10 + 7);
            triangles.Add((0) * 10 + 6);
            triangles.Add((0) * 10 + 7);



            trianglesWhite.Add((resolution - 1) * 10 + 3);
            trianglesWhite.Add((0) * 10 + 3);
            trianglesWhite.Add((resolution - 1) * 10 + 4);
            trianglesWhite.Add((resolution - 1) * 10 + 4);
            trianglesWhite.Add((0) * 10 + 3);
            trianglesWhite.Add((0) * 10 + 4);

            trianglesWhite.Add((resolution - 1) * 10 + 5);
            trianglesWhite.Add((0) * 10 + 5);
            trianglesWhite.Add((resolution - 1) * 10 + 6);
            trianglesWhite.Add((resolution - 1) * 10 + 6);
            trianglesWhite.Add((0) * 10 + 5);
            trianglesWhite.Add((0) * 10 + 6);



            trianglesGrass.Add((resolution - 1) * 10 + 0);
            trianglesGrass.Add((0) * 10 + 0);
            trianglesGrass.Add((resolution - 1) * 10 + 1);
            trianglesGrass.Add((resolution - 1) * 10 + 1);
            trianglesGrass.Add((0) * 10 + 0);
            trianglesGrass.Add((0) * 10 + 1);

            trianglesGrass.Add((resolution - 1) * 10 + 1);
            trianglesGrass.Add((0) * 10 + 1);
            trianglesGrass.Add((resolution - 1) * 10 + 2);
            trianglesGrass.Add((resolution - 1) * 10 + 2);
            trianglesGrass.Add((0) * 10 + 1);
            trianglesGrass.Add((0) * 10 + 2);

            trianglesGrass.Add((resolution - 1) * 10 + 7);
            trianglesGrass.Add((0) * 10 + 7);
            trianglesGrass.Add((resolution - 1) * 10 + 8);
            trianglesGrass.Add((resolution - 1) * 10 + 8);
            trianglesGrass.Add((0) * 10 + 7);
            trianglesGrass.Add((0) * 10 + 8);

            trianglesGrass.Add((resolution - 1) * 10 + 8);
            trianglesGrass.Add((0) * 10 + 8);
            trianglesGrass.Add((resolution - 1) * 10 + 9);
            trianglesGrass.Add((resolution - 1) * 10 + 9);
            trianglesGrass.Add((0) * 10 + 8);
            trianglesGrass.Add((0) * 10 + 9);
            #endregion
        }



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

        meshFilter.mesh.subMeshCount = 3;

        Debug.Log("Submeshcount: " + meshFilter.mesh.subMeshCount);

        meshFilter.mesh.SetTriangles(triangles.ToArray(), 0);
        meshFilter.mesh.SetTriangles(trianglesWhite.ToArray(), 1);
        meshFilter.mesh.SetTriangles(trianglesGrass.ToArray(), 2);

        meshFilter.mesh.RecalculateNormals();

        instTrack.GetComponent <MeshCollider>().sharedMesh = meshFilter.mesh;



        /*for (int i = 0; i < resolution; i++)
         * {
         *  float xPos = ((float)i) / ((float)resolution);
         *
         *  GameObject inst = (GameObject)Instantiate(prefabPoint);
         *  inst.transform.position = racetrack.track.SplineAt(xPos);
         * }*/

        return(racetrack);
    }