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); }
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); }
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); }
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); }
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); } } }
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); }
// 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; } } }
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); }
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); } } }
public CurvatureAnalyzer(ClosedSpline <Vector3> spline) : this(spline, 300) { }
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]++; } } } }
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); }
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); }