public void AddElement(GeneratedTrack track, long seed, float hcSpeed, float hcCurvature) { GameObject instEle = Instantiate(prefabElement, scrollContentElement.transform); instEle.GetComponent <ScrollSeedsElement>().Seed = seed; instEle.GetComponent <ScrollSeedsElement>().HCSpeed = hcSpeed; instEle.GetComponent <ScrollSeedsElement>().HCCurvature = hcCurvature; instEle.GetComponent <ScrollSeedsElement>().Track = track; instEle.GetComponent <ScrollSeedsElement>().GenerationRenderer = generationRenderer; instEle.transform.localPosition = new Vector3(3f + 125f, (instElements.Count * -30f) - 25f, 0f); instElements.Add(instEle); instElements.Sort((x, y) => y.GetComponent <ScrollSeedsElement>().IntrstValue.CompareTo(x.GetComponent <ScrollSeedsElement>().IntrstValue)); for (int i = 0; i < instElements.Count; i++) { instElements[i].transform.localPosition = new Vector3(3f + 125f, (i * -30f) - 25f, 0f); } scrollContentElement.GetComponent <RectTransform>().sizeDelta = new Vector2(0f, instElements.Count * 30f + 60f); }
private void transferToMeshIdealLine(GeneratedTrack track, float[] idealline, float[] ideallineMeshp) { int idLineMeshCounter = 0; int idLineCounter = 0; for (int i = 0; i < track.Elements.Length; i++) { if (track.Elements[i].GetType() == typeof(GeneratedStraight)) { 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++) { float s = ((float)j) / segmentsAmountMesh; int bef = (int)(s * segsAmount); int aft = bef + 1; float partialS = aft - (s * segsAmount); ideallineMeshp[idLineMeshCounter] = idealline[bef + idLineCounter] * partialS + idealline[aft + idLineCounter] * (1f - partialS); idLineMeshCounter++; } idLineCounter += segsAmount; } 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 % 3 == 0 && idLineMeshCounter < ideallineMeshp.Length) { ideallineMeshp[idLineMeshCounter] = idealline[idLineCounter]; idLineMeshCounter++; idLineCounter++; } else if (j % 3 == 1 && (idLineCounter + 1) < idealline.Length && idLineMeshCounter < ideallineMeshp.Length) { ideallineMeshp[idLineMeshCounter] = idealline[idLineCounter] * (2f / 3f) + idealline[idLineCounter + 1] * (1f / 3f); idLineMeshCounter++; } else if (j % 3 == 2 && (idLineCounter + 1) < idealline.Length && idLineMeshCounter < ideallineMeshp.Length) { ideallineMeshp[idLineMeshCounter] = idealline[idLineCounter] * (1f / 3f) + idealline[idLineCounter + 1] * (2f / 3f); idLineMeshCounter++; } } } //Debug.Log("cnter: " + idLineMeshCounter); } /*for (int i = 0; i < ideallineMeshp.Length; i++) * { * Debug.Log("IdlLineMsh [" + i + "]: " + ideallineMeshp[i]); * }*/ }
protected override void ThreadFunction() { if (Suppliers == null) { Suppliers = new GeneratedTrackSupplyer[0]; } track = DiscreteInt2Generator.GenerateTrack(10f, Width, Seed); track.Seed = Seed; if (GenRendererGUI.JumpFaultyTracks) { while (track.Faulty) { //Seed = Utils.longRandom(); Seed++; track = DiscreteInt2Generator.GenerateTrack(10f, Width, Seed); track.Seed = Seed; } } if (Terrain != null) { //track.ModifyTerrain(Terrain); track.SetTerrainModifier(TerrainModifier); } track.Analyze(); track.GenerateBorder(); for (int i = 0; i < Suppliers.Length; i++) { Suppliers[i].Track = track; Suppliers[i].TrackUpdated(); } track.GenerateMesh(); //track = track.Copy(); /*Render(track); * * for (int i = 0; i < supplyers.Length; i++) * { * supplyers[i].Track = track; * supplyers[i].TrackUpdated(); * }*/ }
public void Render(GeneratedTrack track) { //if (planeRenderer != null) //{ // planeRenderer.RefreshPlane(track.TerrainModifier); //} trackLength = track.TrackLength; currentRenderedTrack = track; }
public void InsertInbetween(bool straight) { int insertIndex = recentlyHovered.GetComponent <InteractiveCheckpoint>().ElementsIndex; int indexBefore = (insertIndex - 1) < 0 ? copy.Elements.Length - 1 : insertIndex - 1; int indexAfter = (insertIndex + 1) % copy.Elements.Length; if (straight == false || (straight && copy.Elements[indexBefore].GetType() == typeof(GeneratedBezSpline) && copy.Elements[insertIndex].GetType() == typeof(GeneratedBezSpline))) { List <GeneratedElement> newElements = new List <GeneratedElement>(); for (int i = 0; i < insertIndex; i++) { newElements.Add(copy.Elements[i]); } GeneratedElement newElement = null; if (straight) { GeneratedStraight newStraight = new GeneratedStraight(copy.Elements[indexBefore].EndPosition, copy.Elements[indexBefore].EndDirection, 0f, copy.Elements[indexBefore].WidthEnd); newElement = newStraight; } else { GeneratedBezSpline newSpline = new GeneratedBezSpline(copy.Elements[indexBefore].EndPosition, copy.Elements[indexBefore].EndDirection, copy.Elements[indexBefore].EndPosition, copy.Elements[indexBefore].EndDirection, copy.Elements[indexBefore].WidthEnd, copy.Elements[indexBefore].WidthEnd); newElement = newSpline; } newElements.Add(newElement); for (int i = insertIndex; i < copy.Elements.Length; i++) { newElements.Add(copy.Elements[i]); } GeneratedTrack newTrack = new GeneratedTrack(); for (int i = 0; i < newElements.Count; i++) { newTrack.AddElement(newElements[i]); } newTrack.SetTerrainModifier(copy.TerrainModifier); newTrack.Analyze(); SetTrack(newTrack); MakeEditable(); genRendererGUI.EnableEditButtons(); } }
public void SetTrack(GeneratedTrack track) { copy = track; for (int i = 0; i < instObjects.Count; i++) { Destroy(instObjects[i]); } instObjects.Clear(); linesRenderer.RefreshTrack(copy); genRendererGUI.DistableEditButtons(); }
public void MakeEditable() { copy = copy.Copy(); for (int i = 0; i < copy.Elements.Length; i++) { int i2 = (i + 1) % copy.Elements.Length; int i0 = i - 1 < 0 ? copy.Elements.Length - 1 : i - 1; GameObject instCP = Instantiate(prefabControlpoint); instCP.layer = 9; instCP.GetComponent <InteractiveCheckpoint>().Moveable = true; instCP.GetComponent <InteractiveCheckpoint>().ElementsIndex = i; instCP.GetComponent <InteractiveCheckpoint>().CpRole = IntCpRole.MIDPOINT; instCP.GetComponent <InteractiveCheckpoint>().Position = copy.Elements[i].Position; instCP.GetComponent <InteractiveCheckpoint>().GenTrack = this; instCP.GetComponent <InteractiveCheckpoint>().ParamDirection = copy.Elements[i].Direction; instCP.GetComponent <InteractiveCheckpoint>().ParamDistancePrev = 4f; instCP.GetComponent <InteractiveCheckpoint>().ParamDistanceNext = 4f; if (copy.Elements[i0].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline spline = (GeneratedBezSpline)copy.Elements[i0]; instCP.GetComponent <InteractiveCheckpoint>().ParamDistancePrev = spline.LastTwoCpsDistance; } if (copy.Elements[i].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline spline = (GeneratedBezSpline)copy.Elements[i]; instCP.GetComponent <InteractiveCheckpoint>().ParamDistanceNext = spline.FirstTwoCpsDistance; } if (copy.Elements[i0].GetType() == typeof(GeneratedBezSpline) && copy.Elements[i].GetType() == typeof(GeneratedBezSpline)) { instCP.GetComponent <InteractiveCheckpoint>().Turnable = true; } else { instCP.GetComponent <InteractiveCheckpoint>().Turnable = false; } instObjects.Add(instCP); } linesRenderer.RefreshTrack(copy); }
public void DeleteElement() { int insertIndex = recentlyHovered.GetComponent <InteractiveCheckpoint>().ElementsIndex; List <GeneratedElement> newElements = new List <GeneratedElement>(); for (int i = 0; i < insertIndex; i++) { bool jumpStraight = false; if (insertIndex != 0 && i == insertIndex - 1) { if (copy.Elements[insertIndex - 1].GetType() == typeof(GeneratedStraight) && copy.Elements[insertIndex + 1].GetType() == typeof(GeneratedStraight)) { jumpStraight = true; } } if (!jumpStraight) { newElements.Add(copy.Elements[i]); } } for (int i = insertIndex + 1; i < copy.Elements.Length; i++) { newElements.Add(copy.Elements[i]); } GeneratedTrack newTrack = new GeneratedTrack(); for (int i = 0; i < newElements.Count; i++) { newTrack.AddElement(newElements[i]); } newTrack.SetTerrainModifier(copy.TerrainModifier); newTrack.Analyze(); SetTrack(newTrack); MakeEditable(); genRendererGUI.EnableEditButtons(); }
public GeneratedTrack Copy() { GeneratedTrack copy = new GeneratedTrack(); for (int i = 0; i < Elements.Length; i++) { copy.AddElement(Elements[i].Copy()); } copy.SetTerrainModifier(terrainModifier); copy.discreteTrack = discreteTrack.Copy(copy); copy.curvatureIdeallineProfile = curvatureIdeallineProfile; copy.curvatureProfile = curvatureProfile; copy.speedProfile = speedProfile; return(copy); }
public CurvatureAnalyzer(GeneratedTrack track, int sampleRate) { curvatureValues = new float[sampleRate]; trackPartIndices = new float[sampleRate]; for (int i = 0; i < sampleRate; i++) { curvatureValues[i] = float.MaxValue; } float walkedDistance = 0f; for (int i = 0; i < track.Elements.Length; i++) { if (track.Elements[i].GetType() == typeof(GeneratedStraight)) { GeneratedStraight straight = (GeneratedStraight)track.Elements[i]; int startIndex = (int)((walkedDistance / track.TrackLength) * sampleRate); int endIndex = (int)(((walkedDistance + straight.Length) / track.TrackLength) * sampleRate); for (int j = startIndex; j < endIndex; j++) { curvatureValues[j] = 0f; trackPartIndices[j] = i + ((float)(j - startIndex)) / ((float)(endIndex - startIndex)); } walkedDistance += straight.Length; } else if (track.Elements[i].GetType() == typeof(GeneratedTurn)) { GeneratedTurn turn = (GeneratedTurn)track.Elements[i]; int startIndex = (int)((walkedDistance / track.TrackLength) * sampleRate); int endIndex = (int)(((walkedDistance + turn.Length) / track.TrackLength) * sampleRate); for (int j = startIndex; j < endIndex; j++) { curvatureValues[j] = (1f / turn.Radius) * Mathf.Sign(turn.Degree); } walkedDistance += turn.Length; } else if (track.Elements[i].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline spline = (GeneratedBezSpline)track.Elements[i]; int startIndex = (int)((walkedDistance / track.TrackLength) * sampleRate); int endIndex = (int)(((walkedDistance + spline.Length) / track.TrackLength) * sampleRate); for (int j = startIndex; j < endIndex; j++) { Vector3 tangent1 = spline.Spline.TangentAt(((((float)j) - startIndex + 0f)) / (endIndex - startIndex))[1] - spline.Spline.TangentAt(((((float)j) - startIndex + 0f)) / (endIndex - startIndex))[0]; Vector3 tangent2 = spline.Spline.TangentAt(((((float)j) - startIndex + 1f)) / (endIndex - startIndex))[1] - spline.Spline.TangentAt(((((float)j) - startIndex + 1f)) / (endIndex - startIndex))[0]; Vector2 pos1 = new Vector2(spline.Spline.At(((((float)j) - startIndex + 0f)) / (endIndex - startIndex)).x, spline.Spline.At(((((float)j) - startIndex + 0f)) / (endIndex - startIndex)).z); Vector2 pos2 = new Vector2(spline.Spline.At(((((float)j) - startIndex + 1f)) / (endIndex - startIndex)).x, spline.Spline.At(((((float)j) - startIndex + 1f)) / (endIndex - startIndex)).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[j] = 0f; } else { float radius = (Vector2.Distance(intersect, pos1) + Vector2.Distance(intersect, pos2)) * 0.5f; curvatureValues[j] = (1f / radius) * (Utils.PointRightTo(straightRay, intersect) ? 1f : -1f); } trackPartIndices[j] = i + ((float)(j - startIndex)) / ((float)(endIndex - startIndex)); } walkedDistance += spline.Length; } } int notSet = 0; for (int i = 0; i < sampleRate; i++) { if (curvatureValues[i] == float.MaxValue) { notSet++; } } Debug.Log("NotSet: " + notSet); }
public CurvatureAnalyzer(GeneratedTrack track) : this(track, 300) { }
// Use this for initialization void Start() { if (sappSpline != null) { GeneratedTrack generatedTrack = new GeneratedTrack(); for (int i = 0; i < sappSpline.controlPoints.Length; i++) { float s = ((float)i) / sappSpline.controlPoints.Length; int i2 = (i + 1) % sappSpline.controlPoints.Length; float s2 = ((float)i2) / sappSpline.controlPoints.Length; Vector3 pos1 = sappSpline.controlPoints[i].transform.position; Vector3 pos2 = sappSpline.controlPoints[i2].transform.position; Vector3 tangent1 = (sappSpline.TangentAt(s)[1] - sappSpline.TangentAt(s)[0]).normalized; Vector3 tangent2 = (sappSpline.TangentAt(s2)[1] - sappSpline.TangentAt(s2)[0]).normalized; float dir1 = Mathf.Acos(tangent1.z); // TODO restilche werte ausrechnen, und den entsprechenden GeneratedBezSpline erstellen GeneratedBezSpline bezSpline = new GeneratedBezSpline(pos1, dir1, pos2, dir1, 1f, 1f); generatedTrack.AddElement(bezSpline); } 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 = sappSpline.SplineAt(curPos); Vector3 pos2 = sappSpline.SplineAt(nextPos); Vector3 tangent1 = sappSpline.TangentAt(curPos)[1] - sappSpline.TangentAt(curPos)[0]; Vector3 tangent2 = sappSpline.TangentAt(nextPos)[1] - sappSpline.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; } if (debugInfo) { Debug.DrawLine(pos1, new Vector3(intersect.x, pos1.y, intersect.y), Color.yellow); Debug.DrawLine(pos2, new Vector3(intersect.x, pos2.y, intersect.y), Color.yellow); } } if (debugInfo) { //Debug.Log("Curvative: " + 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]++; } } } if (visualizerProfile != null) { visualizerProfile.SetTrackName(trackname); for (int i = 0; i < curvativeProfile.Length; i++) { visualizerProfile.SetBarValue(i, curvativeProfile[i] / ((float)sampleRate)); } } } }
public DiscreteTrack Copy(GeneratedTrack copyTrack) { DiscreteTrack copy = new DiscreteTrack(copyTrack, copyTrack.TerrainModifier); return(copy); }
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); }
// Update is called once per frame void Update() { if (generate) { generate = false; ActionGenerateToSeed(seed); } if (generateRandom) { generateRandom = false; ActionGenerateRandom(); } if (jobGenerateTrack != null && jobGenerateTrack.IsDone) { generatedTrack = jobGenerateTrack.Track; //generatedTrack.Analyze(); //generatedTrack.GenerateMesh(); //generatedTrack.SetTerrainModifier(terrainModifier); //generatedTrack.GenerateBorder(); if (tmcps == null) { } else { float[,] predef = new float[tmcps.GetLength(0), tmcps.GetLength(1)]; for (int x = 0; x < predef.GetLength(0); x++) { for (int y = 0; y < predef.GetLength(1); y++) { predef[x, y] = tmcps[x, y].transform.position.y; } } //generatedTrack.ModifyTerrain(terrain, predef); } if (generatedTrack.TerrainModifierCPs != null && tmcps == null) { /* * tmcps = new GameObject[generatedTrack.TerrainModifierCPs.GetLength(0), generatedTrack.TerrainModifierCPs.GetLength(1)]; * for (int x = 0; x < generatedTrack.TerrainModifierCPs.GetLength(0); x++) * { * for (int y = 0; y < generatedTrack.TerrainModifierCPs.GetLength(1); y++) * { * GameObject inst = Instantiate(cubeTerrainModifierCP); * tmcps[x, y] = inst; * tmcps[x, y].transform.position = new Vector3(x * 10f - 200f * 10f * 0.5f, generatedTrack.TerrainModifierCPs[x, y], y * 10f - 200f * 10f * 0.5f); * } * }*/ } jobGenerateTrack = null; /*for (int i = 0; i < supplyers.Length; i++) * { * supplyers[i].Track = generatedTrack; * supplyers[i].TrackUpdated(); * }*/ Render(generatedTrack); } if (jobList.Count > 0 && jobListIndex < jobList.Count) { if (jobList[jobListIndex].IsDone) { if (jobList[jobListIndex].Track.CurvatureIdeallineProfile.HC >= minHcCurvature && jobList[jobListIndex].Track.SpeedProfile.HC >= minHcSpeed) { //generatedTrack.SetTerrainModifier(terrainModifier); //generatedTrack.GenerateBorder(); hcTracks.Add(jobList[jobListIndex].Track); } int nextToStart = jobListIndex + 20; if (nextToStart < jobList.Count) { jobList[nextToStart].Start(); } jobListIndex++; } } }
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--; } }
public void Render(GeneratedTrack track) { Render(track, false); }
// Update is called once per frame void Update() { if (measureTime && completeRenderer.tempRem == false) { Debug.Log("Start: " + timeStart); Debug.Log("Now: " + Time.time); measureTime = false; double needed = DateTime.Now.Subtract(timeStart).TotalMilliseconds; Debug.Log("Needed: " + needed); textTimeNeeded.text = needed.ToString(); } if (startReallyRenderNow) { startReallyRenderNow = false; completeRenderer.Render(generationRenderer.CurrentRenderedTrack, generateMLStuff); generateMLStuff = false; } if (generationRenderer.HCTracks.Length >= 0) { textHCTracksAmount.text = generationRenderer.HCTracks.Length.ToString(); } if (oldTrackLength != generationRenderer.TrackLength) { oldTrackLength = generationRenderer.TrackLength; textTrackLength.text = oldTrackLength.ToString(); } if (generationRenderer.CurrentRenderedTrack != null && lastRefreshedTrack != generationRenderer.CurrentRenderedTrack) { lastRefreshedTrack = generationRenderer.CurrentRenderedTrack; textHCCurvativeCurrentTrack.text = generationRenderer.CurrentRenderedTrack.CurvatureProfile.HC.ToString(); textHCCurvativeIdeallineCurrentTrack.text = generationRenderer.CurrentRenderedTrack.CurvatureIdeallineProfile.HC.ToString(); textHCSpeedCurrentTrack.text = generationRenderer.CurrentRenderedTrack.SpeedProfile.HC.ToString(); histoCurvature.RenderProfile(lastRefreshedTrack.CurvatureProfile); histoSpeed.RenderProfile(lastRefreshedTrack.SpeedProfile); histoCurvatureIdealline.RenderProfile(lastRefreshedTrack.CurvatureIdeallineProfile); if (carVisualize != null) { carVisualize.SetTrack(lastRefreshedTrack.AnalyzedTrack, lastRefreshedTrack.TerrainModifier); } if (prefabIdealLine != null && toggleIdealLine.isOn) { if (instIdealLine != null) { Destroy(instIdealLine); instIdealLine = null; } instIdealLine = Instantiate(prefabIdealLine); instIdealLine.transform.position = new Vector3(0f, 0.15f, 0f); instIdealLine.GetComponent <ClosedSplineRenderer>().Width = 0.7f; instIdealLine.GetComponent <ClosedSplineRenderer>().ClosedSpline = lastRefreshedTrack.AnalyzedTrack.idealLineSpline; } } if (Input.GetKeyDown(KeyCode.Escape)) { topCamera.enabled = !topCamera.enabled; topCamera2.enabled = !topCamera2.enabled; GetComponentInParent <Canvas>().enabled = topCamera.enabled; driveCar.GetComponent <CarController>().enabled = !topCamera.enabled; driveCar.GetComponentInChildren <Camera>().enabled = !topCamera.enabled; driveCar.GetComponent <Rigidbody>().velocity = Vector3.zero; driveCar.GetComponent <Rigidbody>().angularVelocity = Vector3.zero; driveCar.transform.rotation = Quaternion.identity; driveCar.transform.position = new Vector3(completeRenderer.startFinishBow.transform.position.x, completeRenderer.startFinishBow.transform.position.y + 2f, completeRenderer.startFinishBow.transform.position.z); driveCar.transform.rotation = completeRenderer.startFinishBow.transform.rotation; } }
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); }
public GeneratedCurb(Vector3[] vertices, Vector3[] directions, float width, float height, float endAngle, Vector3 prevT, Vector3 afteT) { Width = width; height = 0.1f; Vector3[] innerVerts = new Vector3[vertices.Length]; Vector3[] outerVerts = new Vector3[vertices.Length]; Vector2[] borderLine = new Vector2[vertices.Length]; float wentDistance = 0f; innerVerts[0] = vertices[0]; Vector3 toForwardFirst = Vector3.Cross(directions[0], Vector3.up); Vector3 goOffsetFirst = Vector3.Cross(directions[0], toForwardFirst).normalized; if (goOffsetFirst.y < 0f) { goOffsetFirst *= -1f; } Vector3 newDirFirst = (directions[0].normalized * width + goOffsetFirst * minOuterOffset).normalized; outerVerts[0] = vertices[0] + directions[0].normalized * width; borderLine[0] = new Vector2(outerVerts[0].x, outerVerts[0].z); for (int i = 1; i < vertices.Length; i++) { innerVerts[i] = vertices[i]; Vector3 toForward = Vector3.Cross(directions[i], Vector3.up); Vector3 goOffset = Vector3.Cross(toForward, directions[i]).normalized; Vector3 newDir = (directions[i].normalized * width + goOffset * minOuterOffset).normalized; outerVerts[i] = vertices[i] + directions[i].normalized * width; borderLine[i] = new Vector2(outerVerts[i].x, outerVerts[i].z); } List <RenderVertexShortcut> scs = GeneratedTrack.calculateShortcuts(borderLine, true); for (int i = 0; i < scs.Count; i++) { RenderVertexShortcut rvs = scs[i]; for (int j = rvs.indexBefore + 1; j < rvs.indexAfter; j++) { // The 0.2f offset results of that the inner of a sharp curve may always be a little higher on the curbs outerVerts[j] = new Vector3(rvs.intersectPoint.x, (outerVerts[rvs.indexBefore].y + outerVerts[rvs.indexAfter].y) * 0.5f + 0.2f, rvs.intersectPoint.y); } } wentDistance = 0f; renderVertices.Add(new Vector3(innerVerts[0].x, 0f, innerVerts[0].z)); renderUVs.Add(new Vector2(0f, 0f)); toForwardFirst = Vector3.Cross(directions[0], Vector3.up); goOffsetFirst = Vector3.Cross(directions[0], toForwardFirst).normalized; if (goOffsetFirst.y < 0f) { goOffsetFirst *= -1f; } newDirFirst = (directions[0].normalized * width + goOffsetFirst * minOuterOffset).normalized; int plus3 = 0; if (height > 0f) { Vector3 v1 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[0].x, 0f, outerVerts[0].z)) - renderVertices[renderVertices.Count - 1]) * 0.25f + goOffsetFirst * (height * (2f / 3f)); Vector3 v2 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[0].x, 0f, outerVerts[0].z)) - renderVertices[renderVertices.Count - 1]) * 0.5f + goOffsetFirst * (height * (1f)); Vector3 v3 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[0].x, 0f, outerVerts[0].z)) - renderVertices[renderVertices.Count - 1]) * 0.75f + goOffsetFirst * (height * (2f / 3f)); renderVertices.Add(v1); renderVertices.Add(v2); renderVertices.Add(v3); renderUVs.Add(new Vector2(0.25f, 0f)); renderUVs.Add(new Vector2(0.5f, 0f)); renderUVs.Add(new Vector2(0.75f, 0f)); plus3 = 4; } renderVertices.Add(new Vector3(outerVerts[0].x, 0f, outerVerts[0].z)); renderUVs.Add(new Vector2(1f, 0f)); for (int i = 1; i < vertices.Length; i++) { wentDistance += Vector3.Distance(outerVerts[i - 1], outerVerts[i]); renderVertices.Add(new Vector3(innerVerts[i].x, 0f, innerVerts[i].z)); renderUVs.Add(new Vector2(0f, wentDistance * curbDistanceFactor)); Vector3 toForward = Vector3.Cross(directions[i], Vector3.up); Vector3 goOffset = Vector3.Cross(toForward, directions[i]).normalized; if (goOffset.y < 0f) { goOffset *= -1f; } if (height > 0f) { Vector3 v1 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[i].x, 0f, outerVerts[i].z)) - renderVertices[renderVertices.Count - 1]) * 0.25f + goOffset * (height * (2f / 3f)); Vector3 v2 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[i].x, 0f, outerVerts[i].z)) - renderVertices[renderVertices.Count - 1]) * 0.5f + goOffset * (height * (1f)); Vector3 v3 = renderVertices[renderVertices.Count - 1] + ((new Vector3(outerVerts[i].x, 0f, outerVerts[i].z)) - renderVertices[renderVertices.Count - 1]) * 0.75f + goOffset * (height * (2f / 3f)); renderVertices.Add(v1); renderVertices.Add(v2); renderVertices.Add(v3); renderUVs.Add(new Vector2(0.25f, wentDistance * curbDistanceFactor)); renderUVs.Add(new Vector2(0.5f, wentDistance * curbDistanceFactor)); renderUVs.Add(new Vector2(0.75f, wentDistance * curbDistanceFactor)); } renderVertices.Add(new Vector3(outerVerts[i].x, 0f, outerVerts[i].z)); renderUVs.Add(new Vector2(1f, wentDistance * curbDistanceFactor)); /*renderTriangles.Add(renderVertices.Count - 4 - plus3); * if (Vector3.Cross(renderVertices[renderVertices.Count - 4 - plus3] - renderVertices[renderVertices.Count - 3 - plus3], renderVertices[renderVertices.Count - 2] - renderVertices[renderVertices.Count - 4 - plus3]).y < 0) * { * renderTriangles.Add(renderVertices.Count - 3 - plus3); * renderTriangles.Add(renderVertices.Count - 2); * } * else * { * renderTriangles.Add(renderVertices.Count - 2); * renderTriangles.Add(renderVertices.Count - 3 - plus3); * }*/ if (plus3 == 0) { renderTriangles.Add(renderVertices.Count - 4 - plus3); if (Vector3.Cross(renderVertices[renderVertices.Count - 4 - plus3] - renderVertices[renderVertices.Count - 3 - plus3], renderVertices[renderVertices.Count - 2] - renderVertices[renderVertices.Count - 4 - plus3]).y < 0) { renderTriangles.Add(renderVertices.Count - 3 - plus3); renderTriangles.Add(renderVertices.Count - 2); } else { renderTriangles.Add(renderVertices.Count - 2); renderTriangles.Add(renderVertices.Count - 3 - plus3); } renderTriangles.Add(renderVertices.Count - 2); if (Vector3.Cross(renderVertices[renderVertices.Count - 2] - renderVertices[renderVertices.Count - 1], renderVertices[renderVertices.Count - 3 - plus3] - renderVertices[renderVertices.Count - 2]).y < 0) { renderTriangles.Add(renderVertices.Count - 1); renderTriangles.Add(renderVertices.Count - 3 - plus3); } else { renderTriangles.Add(renderVertices.Count - 3 - plus3); renderTriangles.Add(renderVertices.Count - 1); } } else { int newPlus1 = plus3 - 1; for (int j = 0; j < plus3; j++) { renderTriangles.Add(renderVertices.Count - 4 - newPlus1 - j); if (Vector3.Cross(renderVertices[renderVertices.Count - 4 - newPlus1 - j] - renderVertices[renderVertices.Count - 3 - newPlus1 - j], renderVertices[renderVertices.Count - 2 - j] - renderVertices[renderVertices.Count - 4 - newPlus1 - j]).y < 0) { renderTriangles.Add(renderVertices.Count - 3 - newPlus1 - j); renderTriangles.Add(renderVertices.Count - 2 - j); } else { renderTriangles.Add(renderVertices.Count - 2 - j); renderTriangles.Add(renderVertices.Count - 3 - newPlus1 - j); } renderTriangles.Add(renderVertices.Count - 2 - j); if (Vector3.Cross(renderVertices[renderVertices.Count - 2 - j] - renderVertices[renderVertices.Count - 1 - j], renderVertices[renderVertices.Count - 3 - newPlus1 - j] - renderVertices[renderVertices.Count - 2 - j]).y < 0) { renderTriangles.Add(renderVertices.Count - 1 - j); renderTriangles.Add(renderVertices.Count - 3 - newPlus1 - j); } else { renderTriangles.Add(renderVertices.Count - 3 - newPlus1 - j); renderTriangles.Add(renderVertices.Count - 1 - j); } } } } renderVertices.Add(new Vector3(prevT.x, 0f, prevT.z)); renderUVs.Add(new Vector2(0f, Vector3.Distance(renderVertices[renderVertices.Count - 1], renderVertices[0]) * -curbDistanceFactor)); renderVertices.Add(new Vector3(afteT.x, 0f, afteT.z)); renderUVs.Add(new Vector2(0f, (wentDistance + Vector3.Distance(renderVertices[renderVertices.Count - 1], renderVertices[renderVertices.Count - 4])) * curbDistanceFactor)); if (plus3 == 0) { renderTriangles.Add(renderVertices.Count - 2); if (Vector3.Cross(renderVertices[renderVertices.Count - 2] - renderVertices[0], renderVertices[1] - renderVertices[renderVertices.Count - 2]).y < 0) { renderTriangles.Add(0); renderTriangles.Add(1); } else { renderTriangles.Add(1); renderTriangles.Add(0); } renderTriangles.Add(renderVertices.Count - 1); if (Vector3.Cross(renderVertices[renderVertices.Count - 1] - renderVertices[renderVertices.Count - 4], renderVertices[renderVertices.Count - 3] - renderVertices[renderVertices.Count - 1]).y < 0) { renderTriangles.Add(renderVertices.Count - 4); renderTriangles.Add(renderVertices.Count - 3); } else { renderTriangles.Add(renderVertices.Count - 3); renderTriangles.Add(renderVertices.Count - 4); } } else { for (int j = 0; j < plus3; j++) { renderTriangles.Add(renderVertices.Count - 2); if (Vector3.Cross(renderVertices[renderVertices.Count - 2] - renderVertices[0 + j], renderVertices[1 + j] - renderVertices[renderVertices.Count - 2]).y < 0) { renderTriangles.Add(0 + j); renderTriangles.Add(1 + j); } else { renderTriangles.Add(1 + j); renderTriangles.Add(0 + j); } renderTriangles.Add(renderVertices.Count - 1); if (Vector3.Cross(renderVertices[renderVertices.Count - 1] - renderVertices[renderVertices.Count - 7 + j], renderVertices[renderVertices.Count - 6 + j] - renderVertices[renderVertices.Count - 1]).y < 0) { renderTriangles.Add(renderVertices.Count - 7 + j); renderTriangles.Add(renderVertices.Count - 6 + j); } else { renderTriangles.Add(renderVertices.Count - 6 + j); renderTriangles.Add(renderVertices.Count - 7 + j); } } } }
public static GeneratedTrack GenerateTrack(float length, float width, long seed) { float anglePeriod = param_AnglePeriod; float angleAmplitude = param_AngleAmplitude; float radiusPeriod = param_RadiusPeriod; float radiusAmplitude = param_RadiusAmplitude; float radiusOffset = param_RadiusOffset; // Segment Decider // // Decider works like this: // If noise returns < -1, the segment is a straight // If noise returns > 1, the segment is a turn // Else, it is a combination of both // float segDecMin = param_SegDecMin; float segDecMax = param_SegDecMax; float segDecPeriod = param_SegDecPeriod; float modePeriod = param_ModePeriod; perlinNoise = new PerlinNoise(seed); GeneratedTrack track = new GeneratedTrack(); track.Faulty = false; List <Circle> circles = new List <Circle>(); circles.Add(new Circle(new Vector2(0f, 150f), 250f, true)); circles.Add(new Circle(new Vector2(150f, -100f), 250f, true)); circles.Add(new Circle(new Vector2(-150f, -100f), 250f, true)); List <float> circleDirections = new List <float>(); for (int i = 0; i < circles.Count; i++) { int i2 = (i + 1) % circles.Count; Vector2 c1Toc2 = circles[i2].Midpoint - circles[i].Midpoint; Vector2 c1ToLeft = (new Vector2(-c1Toc2.y, c1Toc2.x)).normalized * circles[i].Radius; Vector2 c2ToLeft = (new Vector2(-c1Toc2.y, c1Toc2.x)).normalized * circles[i2].Radius; Vector2 c1Outs = circles[i].Midpoint + c1ToLeft; Vector2 c2Outs = circles[i2].Midpoint + c2ToLeft; Vector2 vec = c2Outs - c1Outs; float zAngle = Vector2.Angle(new Vector2(0f, 1f), vec); float xAngle = Vector2.Angle(new Vector2(1f, 0f), vec); float circleDirection = zAngle; if (xAngle > 90f) { circleDirection = 360f - zAngle; } circleDirection = circleDirection - 90f; if (circleDirection < 0f) { circleDirection = 360f - circleDirection; } circleDirections.Add(circleDirection); } int angleStep = 0; int radiusStep = 0; int segmentStep = 0; int circleIndex = 0; float currentAngle = 0f; float startRadius = perlinNoise.noise1(radiusStep * radiusPeriod) * radiusAmplitude + radiusOffset; Vector2 startPoint = new Vector2(Mathf.Sin((currentAngle * Mathf.PI) / 180f) * startRadius, Mathf.Cos((currentAngle * Mathf.PI) / 180f) * startRadius); while (true) { angleStep++; radiusStep++; segmentStep++; // Segment Decider is between [-1, 1] float segDec = perlinNoise.noise1(segmentStep * segDecPeriod) * ((Mathf.Abs(segDecMin) + Mathf.Abs(segDecMax)) / 2f); segDec = segDec + ((segDecMin + segDecMax) / 2f); segDec = segDec > 1f ? 1f : (segDec < -1f ? -1f : segDec); // Angle Delta between [0, angleAmplitude] float angleDelta = (perlinNoise.noise1(angleStep * anglePeriod) * 0.5f + 0.5f) * angleAmplitude; currentAngle += angleDelta; // Radius between [0, 2 * radiusAmplitude] float radius = perlinNoise.noise1(radiusStep * radiusPeriod) * radiusAmplitude + radiusOffset; // Mode is either PERFECT_PART_CIRCLES or BEZIER_SPLINES bool takeBezierSpline = false; if (generationMode == DiscreteGenerationMode.BEZIER_SPLINES) { takeBezierSpline = true; } else if (generationMode == DiscreteGenerationMode.PERFECT_PART_CIRCLES) { takeBezierSpline = false; } else { takeBezierSpline = perlinNoise.noise1(angleStep * modePeriod) >= 0f; } if (currentAngle >= circleDirections[circleIndex]) { circleIndex++; if (circleIndex >= circles.Count) { circleIndex = 0; } } //Debug.Log("TAKESPLINE: " + takeBezierSpline.ToString()); Vector2 point = new Vector2(Mathf.Sin((currentAngle * Mathf.PI) / 180f) * radius, Mathf.Cos((currentAngle * Mathf.PI) / 180f) * radius); point += circles[circleIndex].Midpoint; //Debug.Log("Iteration: " + angleStep); //Debug.Log("CurrentAngle: " + currentAngle); //Debug.Log("Radius: " + radius); //Debug.Log("SegDec: " + segDec); bool fixedEndpointDirection = false; float endpointDirection = Mathf.PI * 0.5f; float endpointWidth = width; if (currentAngle >= 360f) { fixedEndpointDirection = true; point = new Vector2(track.Elements[0].Position.x, track.Elements[0].Position.z); endpointDirection = track.Elements[0].Direction; endpointWidth = track.Elements[0].WidthStart; } Vector2 oldPoint; float oldDirection; if (track.Elements.Length == 0) { oldPoint = startPoint; oldDirection = Mathf.PI * 0.5f; } else { oldPoint = new Vector2(track.Elements[track.Elements.Length - 1].EndPosition.x, track.Elements[track.Elements.Length - 1].EndPosition.z); oldDirection = track.Elements[track.Elements.Length - 1].EndDirection; } if (fixedEndpointDirection == false) { // Completely a turn if (segDec >= 1f) { if (takeBezierSpline == false) { float[] radiusAndDegree = makeTurn(oldPoint, point, oldDirection); float circleRadius = radiusAndDegree[0]; float circleDegree = radiusAndDegree[1]; int splinesAmount = (int)(Mathf.Abs(circleDegree) / 90f) + 1; float degreeOneSpline = circleDegree / splinesAmount; float tanValue = 360f / degreeOneSpline; tanValue = Mathf.Abs((4f / 3f) * Mathf.Tan(Mathf.PI / (2f * tanValue)) * circleRadius); Vector2 prevSplinePoint = oldPoint; Debug.Log("Gonna do new"); for (int i = 0; i < splinesAmount; i++) { float tempStartDir = oldDirection + i * degreeOneSpline * (Mathf.PI / 180f); Vector2 midToPoint = (new Vector2(Mathf.Cos(tempStartDir) * Mathf.Sign(circleDegree), -Mathf.Sin(tempStartDir) * Mathf.Sign(circleDegree))).normalized * circleRadius; float tempEndDir = oldDirection + (i + 1) * degreeOneSpline * (Mathf.PI / 180f); Vector2 midToEndpoint = (new Vector2(Mathf.Cos(tempEndDir) * Mathf.Sign(circleDegree), -Mathf.Sin(tempEndDir) * Mathf.Sign(circleDegree))).normalized * circleRadius; Vector2 tempEndpoint = (prevSplinePoint + midToPoint) - midToEndpoint; GeneratedBezSpline spline = new GeneratedBezSpline(new Vector3(prevSplinePoint.x, 0f, prevSplinePoint.y), tempStartDir, new Vector3(tempEndpoint.x, 0f, tempEndpoint.y), tempEndDir, width, width, tanValue, tanValue); track.AddElement(spline); prevSplinePoint = tempEndpoint; //Debug.Log("Spline[" + i + "]"); } /*GeneratedTurn turn = new GeneratedTurn(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, circleRadius, circleDegree, width); * * Vector2 turnEndPoint = new Vector2(turn.EndPosition.x, turn.EndPosition.z); * if (Vector2.Distance(turnEndPoint, point) > 1f) * { * track.Faulty = true; * Debug.LogError("Too big distance"); * } * * track.AddElement(turn);*/ } else { /*float[] radiusAndDegree = makeTurn(oldPoint, point, oldDirection); * * float circleRadius = radiusAndDegree[0]; * float circleDegree = radiusAndDegree[1]; * * int splinesAmount = (int)(circleDegree / 90f) + 1; * * float degreeOneSpline = circleDegree / splinesAmount; * * float tanValue = 360f / degreeOneSpline; * tanValue = Mathf.Abs((4f / 3f) * Mathf.Tan(Mathf.PI / (2f * tanValue)) * circleRadius); * * Vector2 prevSplinePoint = oldPoint; * * Debug.Log("Gonna do new"); * * for (int i = 0; i < splinesAmount; i++) * { * float tempStartDir = oldDirection + i * degreeOneSpline * (Mathf.PI / 180f); * Vector2 midToPoint = (new Vector2(Mathf.Cos(tempStartDir), -Mathf.Sin(tempStartDir))).normalized * circleRadius; * * float tempEndDir = oldDirection + (i + 1) * degreeOneSpline * (Mathf.PI / 180f); * Vector2 midToEndpoint = (new Vector2(Mathf.Cos(tempEndDir), -Mathf.Sin(tempEndDir))).normalized * circleRadius; * * Vector2 tempEndpoint = (prevSplinePoint + midToPoint) - midToEndpoint; * * GeneratedBezSpline spline = new GeneratedBezSpline(new Vector3(prevSplinePoint.x, 0f, prevSplinePoint.y), tempStartDir, new Vector3(tempEndpoint.x, 0f, tempEndpoint.y), tempEndDir, width, width, tanValue, tanValue); * * track.AddElement(spline); * * prevSplinePoint = tempEndpoint; * * Debug.Log("Spline[" + i + "]"); * } */ Debug.Log("Did normal spline"); float[] radiusAndDegree = makeTurn(oldPoint, point, oldDirection); float circleRadius = radiusAndDegree[0]; float circleDegree = radiusAndDegree[1]; GeneratedTurn turn = new GeneratedTurn(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, circleRadius, circleDegree, width); float turnEndDirection = turn.EndDirection; float maxAngleToBeDoneBySpline = 90f; if (Mathf.Abs(turnEndDirection) > maxAngleToBeDoneBySpline * Mathf.PI / 180f) { turnEndDirection = Mathf.Sign(turnEndDirection) * (Mathf.PI * maxAngleToBeDoneBySpline / 180f); } float interDirection = (perlinNoise.noise1(angleStep * anglePeriod) * 0.5f + 0.5f) * (oldDirection - turnEndDirection) + turnEndDirection; GeneratedBezSpline turnSpline = new GeneratedBezSpline(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, new Vector3(point.x, 0f, point.y), interDirection, width, width); track.AddElement(turnSpline); } } // Part straight part turn else { if (false && takeBezierSpline == false) { float maxWidth = width; //TODO not only one width all the time float minRadius = maxWidth + 0.8f; float[] radiusAndDegree = makeTurn(oldPoint, point, oldDirection); float circleRadius = radiusAndDegree[0]; float circleDegree = radiusAndDegree[1]; float maxRadius = circleRadius; float circlePartRadius = (maxRadius - minRadius) * ((segDec + 1f) * 0.5f) + minRadius; Vector2 circleMiddle = Vector2.zero; float[] partcircleRadiusAndDegree = makeTurnFixedRadius(oldPoint, circlePartRadius, oldDirection, (circleDegree >= 0f), point); float partcircleDegree = partcircleRadiusAndDegree[0]; float partstraightLength = partcircleRadiusAndDegree[1]; GeneratedTurn turn = new GeneratedTurn(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, circlePartRadius, partcircleDegree, width); track.AddElement(turn); GeneratedStraight straight = new GeneratedStraight(turn.EndPosition, turn.EndDirection, partstraightLength, width); //straight.AddCurb(new GeneratedCurb(0.1f, 0.9f, true, true, true)); track.AddElement(straight); Vector2 bothEndPoint = new Vector2(straight.EndPosition.x, straight.EndPosition.z); if (Vector2.Distance(bothEndPoint, point) > 1f) { Debug.LogError("Too big distance"); track.Faulty = true; } } else { // Only straight if (false && segDec <= -1f && track.Elements.Length > 0 && track.Elements[track.Elements.Length - 1].GetType() == typeof(GeneratedBezSpline)) { float angleBetween = Vector2.Angle(new Vector2(0f, 1f), point - oldPoint); float angleRight = Vector2.Angle(new Vector2(1f, 0f), point - oldPoint); if (angleRight > 90f) { angleBetween = 360f - angleBetween; } float radianOldEndDirection = (angleBetween * Mathf.PI) / 180f; track.Elements[track.Elements.Length - 1].ForceEndDirection(radianOldEndDirection); GeneratedStraight straight = new GeneratedStraight(new Vector3(oldPoint.x, 0f, oldPoint.y), radianOldEndDirection, Vector2.Distance(oldPoint, point), width); track.AddElement(straight); } // Really part turn part straight else { float maxWidth = width; //TODO not only one width all the time float minRadius = maxWidth + 0.8f; float[] radiusAndDegree = makeTurn(oldPoint, point, oldDirection); float circleRadius = radiusAndDegree[0]; float circleDegree = radiusAndDegree[1]; float maxRadius = Mathf.Max(circleRadius * 0.4f, minRadius); float circlePartRadius = (maxRadius - minRadius) * ((segDec + 1f) * 0.5f) + minRadius; float[] partcircleRadiusAndDegree = makeTurnFixedRadius(oldPoint, circlePartRadius, oldDirection, (circleDegree >= 0f), point); float partcircleDegree = partcircleRadiusAndDegree[0]; float partstraightLength = partcircleRadiusAndDegree[1]; int splinesAmount = (int)(Mathf.Abs(partcircleDegree) / 90f) + 1; float degreeOneSpline = partcircleDegree / splinesAmount; float tanValue = 360f / degreeOneSpline; tanValue = Mathf.Abs((4f / 3f) * Mathf.Tan(Mathf.PI / (2f * tanValue)) * circlePartRadius); Vector2 prevSplinePoint = oldPoint; Debug.Log("Gonna do new"); for (int i = 0; i < splinesAmount; i++) { float tempStartDir = oldDirection + i * degreeOneSpline * (Mathf.PI / 180f); Vector2 midToPoint = (new Vector2(Mathf.Cos(tempStartDir) * Mathf.Sign(partcircleDegree), -Mathf.Sin(tempStartDir) * Mathf.Sign(partcircleDegree))).normalized * circlePartRadius; float tempEndDir = oldDirection + (i + 1) * degreeOneSpline * (Mathf.PI / 180f); Vector2 midToEndpoint = (new Vector2(Mathf.Cos(tempEndDir) * Mathf.Sign(partcircleDegree), -Mathf.Sin(tempEndDir) * Mathf.Sign(partcircleDegree))).normalized * circlePartRadius; Vector2 tempEndpoint = (prevSplinePoint + midToPoint) - midToEndpoint; GeneratedBezSpline spline = new GeneratedBezSpline(new Vector3(prevSplinePoint.x, 0f, prevSplinePoint.y), tempStartDir, new Vector3(tempEndpoint.x, 0f, tempEndpoint.y), tempEndDir, width, width, tanValue, tanValue); track.AddElement(spline); prevSplinePoint = tempEndpoint; //Debug.Log("Spline[" + i + "]"); } GeneratedStraight straight = new GeneratedStraight(track.Elements[track.Elements.Length - 1].EndPosition, track.Elements[track.Elements.Length - 1].EndDirection, Vector2.Distance(point, new Vector2(track.Elements[track.Elements.Length - 1].EndPosition.x, track.Elements[track.Elements.Length - 1].EndPosition.z)), width); //straight.AddCurb(new GeneratedCurb(0.1f, 0.9f, true, true, true)); track.AddElement(straight); Vector2 bothEndPoint = new Vector2(straight.EndPosition.x, straight.EndPosition.z); if (Vector2.Distance(bothEndPoint, point) > 1f) { track.Faulty = true; Debug.LogError("Too big distance"); } } } } } // Drive to a fixed endpoint else { // Two turns one straight if (false) { float[] angleStraightAndAngle = makeTwoTurnsOneStraight(oldPoint, point, oldDirection, endpointDirection, 1f, 0.5f, Mathf.Max(endpointWidth, width)); float circle1Radius = angleStraightAndAngle[0]; float circle1Degree = angleStraightAndAngle[1]; float straightLegnth = angleStraightAndAngle[2]; float circle2Radius = angleStraightAndAngle[3]; float circle2Degree = angleStraightAndAngle[4]; if (circle1Radius == 0f && circle1Degree == 0f && straightLegnth == 0f && circle2Degree == 0f && circle2Radius == 0f) { track.Faulty = true; } else { GeneratedTurn turn = new GeneratedTurn(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, circle1Radius, circle1Degree, width); track.AddElement(turn); GeneratedStraight straight = new GeneratedStraight(turn.EndPosition, turn.EndDirection, straightLegnth, width); track.AddElement(straight); GeneratedTurn turn2 = new GeneratedTurn(straight.EndPosition, straight.EndDirection, circle2Radius, circle2Degree, width); track.AddElement(turn2); } } // Do it with Beziers else { GeneratedBezSpline turnSpline = new GeneratedBezSpline(new Vector3(oldPoint.x, 0f, oldPoint.y), oldDirection, new Vector3(point.x, 0f, point.y), endpointDirection, width, width); track.AddElement(turnSpline); } } if (currentAngle >= 360f) { break; } } return(track); }
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; } }