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]); * }*/ }
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 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 override GeneratedElement Copy() { GeneratedBezSpline copy = new GeneratedBezSpline(position, direction, endPosition, endDirection, widthStart, widthEnd, firstTwoCpsDistance, lastTwoCpsDistance); copy.b0 = b0; copy.b1 = b1; copy.b2 = b2; copy.b3 = b3; copy.bezier.b0 = b0; copy.bezier.b1 = b1; copy.bezier.b2 = b2; copy.bezier.b3 = b3; copy.resolution = resolution; copy.fillVerts(); return(copy); }
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 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); }
// 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(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 void CPChanged(int index, IntCpRole role, Vector3 newPosition, float newNextDistance, float newPrevDistance, float newDirection) { newPosition = new Vector3(newPosition.x, 0f, newPosition.z); int i = index - 1 < 0 ? copy.Elements.Length - 1 : index - 1; int i2 = index; if (role == IntCpRole.MIDPOINT) { if (copy.Elements[i].GetType() == typeof(GeneratedBezSpline) && copy.Elements[i2].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline old1 = (GeneratedBezSpline)copy.Elements[i]; GeneratedBezSpline old2 = (GeneratedBezSpline)copy.Elements[i2]; GeneratedBezSpline new1 = new GeneratedBezSpline(old1.Position, old1.Direction, newPosition, old1.EndDirection, old1.WidthStart, old1.WidthEnd, old1.FirstTwoCpsDistance, old1.LastTwoCpsDistance); GeneratedBezSpline new2 = new GeneratedBezSpline(newPosition, old2.Direction, old2.EndPosition, old2.EndDirection, old2.WidthStart, old2.WidthEnd, old2.FirstTwoCpsDistance, old2.LastTwoCpsDistance); copy.ReplaceElement(i, new1); copy.ReplaceElement(i2, new2); //Debug.Log("Updated 2 BezSplines: " + newPosition.ToString()); } else if (copy.Elements[i].GetType() == typeof(GeneratedBezSpline) && copy.Elements[i2].GetType() == typeof(GeneratedStraight)) { GeneratedBezSpline spline = (GeneratedBezSpline)copy.Elements[i]; GeneratedStraight straight = (GeneratedStraight)copy.Elements[i2]; GeneratedBezSpline afterSpline = (GeneratedBezSpline)copy.Elements[(i2 + 1) % copy.Elements.Length]; float newStraightDirectinon = Vector2.Angle(new Vector2(0f, 1f), new Vector2(straight.EndPosition.x, straight.EndPosition.z) - new Vector2(newPosition.x, newPosition.z)); if (Vector2.Angle(new Vector2(1f, 0f), new Vector2(straight.EndPosition.x, straight.EndPosition.z) - new Vector2(newPosition.x, newPosition.z)) > 90f) { newStraightDirectinon = 360 - newStraightDirectinon; } newStraightDirectinon = newStraightDirectinon * Mathf.PI / 180f; instObjects[i2].GetComponent <InteractiveCheckpoint>().ParamDirection = newStraightDirectinon; instObjects[i2].GetComponent <InteractiveCheckpoint>().DirectionChanged(); instObjects[(i2 + 1) % copy.Elements.Length].GetComponent <InteractiveCheckpoint>().ParamDirection = newStraightDirectinon; instObjects[(i2 + 1) % copy.Elements.Length].GetComponent <InteractiveCheckpoint>().DirectionChanged(); GeneratedBezSpline new1 = new GeneratedBezSpline(spline.Position, spline.Direction, newPosition, newStraightDirectinon, spline.WidthStart, spline.WidthEnd, spline.FirstTwoCpsDistance, spline.LastTwoCpsDistance); GeneratedBezSpline new2 = new GeneratedBezSpline(afterSpline.Position, newStraightDirectinon, afterSpline.EndPosition, afterSpline.EndDirection, afterSpline.WidthStart, afterSpline.WidthEnd, afterSpline.FirstTwoCpsDistance, afterSpline.LastTwoCpsDistance); GeneratedStraight newStraight = new GeneratedStraight(newPosition, newStraightDirectinon, Vector2.Distance(new Vector2(newPosition.x, newPosition.z), new Vector2(afterSpline.Position.x, afterSpline.Position.z)), straight.WidthStart, straight.WidthEnd); copy.ReplaceElement(i, new1); copy.ReplaceElement(i2, newStraight); copy.ReplaceElement((i2 + 1) % copy.Elements.Length, new2); //Debug.Log("Updated Straight - Spline: " + newPosition.ToString()); } else if (copy.Elements[i].GetType() == typeof(GeneratedStraight) && copy.Elements[i2].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline spline = (GeneratedBezSpline)copy.Elements[i2]; GeneratedStraight straight = (GeneratedStraight)copy.Elements[i]; GeneratedBezSpline afterSpline = (GeneratedBezSpline)copy.Elements[i - 1 >= 0 ? i - 1 : copy.Elements.Length - 1]; float newStraightDirectinon = Vector2.Angle(new Vector2(0f, 1f), new Vector2(newPosition.x, newPosition.z) - new Vector2(straight.Position.x, straight.Position.z)); if (Vector2.Angle(new Vector2(1f, 0f), new Vector2(newPosition.x, newPosition.z) - new Vector2(straight.Position.x, straight.Position.z)) > 90f) { newStraightDirectinon = 360 - newStraightDirectinon; } newStraightDirectinon = newStraightDirectinon * Mathf.PI / 180f; instObjects[i].GetComponent <InteractiveCheckpoint>().ParamDirection = newStraightDirectinon; instObjects[i].GetComponent <InteractiveCheckpoint>().DirectionChanged(); instObjects[i2].GetComponent <InteractiveCheckpoint>().ParamDirection = newStraightDirectinon; instObjects[i2].GetComponent <InteractiveCheckpoint>().DirectionChanged(); GeneratedBezSpline new1 = new GeneratedBezSpline(newPosition, newStraightDirectinon, spline.EndPosition, spline.EndDirection, spline.WidthStart, spline.WidthEnd, spline.FirstTwoCpsDistance, spline.LastTwoCpsDistance); GeneratedBezSpline new2 = new GeneratedBezSpline(afterSpline.Position, afterSpline.Direction, afterSpline.EndPosition, newStraightDirectinon, afterSpline.WidthStart, afterSpline.WidthEnd, afterSpline.FirstTwoCpsDistance, afterSpline.LastTwoCpsDistance); GeneratedStraight newStraight = new GeneratedStraight(straight.Position, newStraightDirectinon, Vector2.Distance(new Vector2(newPosition.x, newPosition.z), new Vector2(straight.Position.x, straight.Position.z)), straight.WidthStart, straight.WidthEnd); copy.ReplaceElement(i, newStraight); copy.ReplaceElement(i2, new1); copy.ReplaceElement(i - 1 >= 0 ? i - 1 : copy.Elements.Length - 1, new2); //Debug.Log("Updated Spline - Straight: " + newPosition.ToString()); } } else if (role == IntCpRole.NEXT_B1) { if (copy.Elements[i2].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline old = (GeneratedBezSpline)copy.Elements[i2]; GeneratedBezSpline new1 = new GeneratedBezSpline(old.Position, old.Direction, old.EndPosition, old.EndDirection, old.WidthStart, old.WidthEnd, newNextDistance, old.LastTwoCpsDistance); copy.ReplaceElement(i2, new1); } } else if (role == IntCpRole.PREV_B2) { if (copy.Elements[i].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline old = (GeneratedBezSpline)copy.Elements[i]; GeneratedBezSpline new1 = new GeneratedBezSpline(old.Position, old.Direction, old.EndPosition, old.EndDirection, old.WidthStart, old.WidthEnd, old.FirstTwoCpsDistance, newPrevDistance); copy.ReplaceElement(i, new1); } } else if (role == IntCpRole.DIRECTION) { if (copy.Elements[i].GetType() == typeof(GeneratedBezSpline) && copy.Elements[index].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline old1 = (GeneratedBezSpline)copy.Elements[i]; GeneratedBezSpline old2 = (GeneratedBezSpline)copy.Elements[index]; GeneratedBezSpline new1 = new GeneratedBezSpline(old1.Position, old1.Direction, old1.EndPosition, newDirection, old1.WidthStart, old1.WidthEnd, old1.FirstTwoCpsDistance, old1.LastTwoCpsDistance); GeneratedBezSpline new2 = new GeneratedBezSpline(old2.Position, newDirection, old2.EndPosition, old2.EndDirection, old2.WidthStart, old2.WidthEnd, old2.FirstTwoCpsDistance, old2.LastTwoCpsDistance); copy.ReplaceElement(i, new1); copy.ReplaceElement(index, new2); } } linesRenderer.RefreshTrack(copy); }
public void GenerateMesh() { // right Track Vertices List <Vector2> rT = new List <Vector2>(); // left Track Vertices List <Vector2> lT = new List <Vector2>(); // right Grass Vertices List <Vector2> rG = new List <Vector2>(); // right Grass Vertices List <Vector2> lG = new List <Vector2>(); /*if (Elements[0].GetType() == typeof(GeneratedStraight)) * { * GeneratedStraight straight = (GeneratedStraight)Elements[0]; * * Vector3 toRight = (Quaternion.Euler(0f, (straight.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(straight.WidthStart, 0f, 0f)); * * lT.Add(new Vector2((straight.Position - toRight).x, (straight.Position - toRight).z)); * rT.Add(new Vector2((straight.Position + toRight).x, (straight.Position + toRight).z)); * * } * else if (Elements[0].GetType() == typeof(GeneratedTurn)) * { * GeneratedTurn turn = (GeneratedTurn)Elements[0]; * * Vector3 toRight = (Quaternion.Euler(0f, (turn.Direction * 180f) / Mathf.PI, 0f)) * (new Vector3(turn.WidthStart, 0f, 0f)); * * lT.Add(new Vector2((turn.Position - toRight).x, (turn.Position - toRight).z)); * rT.Add(new Vector2((turn.Position + toRight).x, (turn.Position + toRight).z)); * } * else if (Elements[0].GetType() == typeof(GeneratedBezSpline)) * { * GeneratedBezSpline bezSpline = (GeneratedBezSpline)Elements[0]; * * lT.Add(new Vector2((bezSpline.RenderVertsLeft[0]).x, (bezSpline.RenderVertsLeft[0]).z)); * rT.Add(new Vector2((bezSpline.RenderVertsRight[0]).x, (bezSpline.RenderVertsRight[0]).z)); * }*/ for (int i = 0; i < Elements.Length; i++) { if (Elements[i].GetType() == typeof(GeneratedStraight)) { GeneratedStraight straight = (GeneratedStraight)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 / DiscreteTrack.straightSegmentingFactorMesh); for (int j = 1; j <= segmentsAmount; j++) { float s = ((float)j) / segmentsAmount; lT.Add(new Vector2((straight.Position + (toFront * s) - toRight).x, (straight.Position + (toFront * s) - toRight).z)); rT.Add(new Vector2((straight.Position + (toFront * s) + toRight).x, (straight.Position + (toFront * s) + toRight).z)); /* * -2 -1 * x-----x * |\ | * | \ | / \ * | \ | | Drive Direction * | \ | | * | \| * x-----x * -4 -3 * * */ } } else if (Elements[i].GetType() == typeof(GeneratedTurn)) { GeneratedTurn turn = (GeneratedTurn)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; lT.Add(new Vector2((segmentPos + toRightTurned * currentWidth * -1f + turn.Position).x, (segmentPos + toRightTurned * currentWidth * -1f + turn.Position).z)); rT.Add(new Vector2((segmentPos + toRightTurned * currentWidth + turn.Position).x, (segmentPos + toRightTurned * currentWidth + turn.Position).z)); } } else if (Elements[i].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline bezierSpline = (GeneratedBezSpline)Elements[i]; for (int j = 1; j < bezierSpline.RenderVertsLeft.Length; j++) { lT.Add(new Vector2((bezierSpline.RenderVertsLeft[j]).x, (bezierSpline.RenderVertsLeft[j]).z)); rT.Add(new Vector2((bezierSpline.RenderVertsRight[j]).x, (bezierSpline.RenderVertsRight[j]).z)); } } } // Cutting of the overlapping segments List <RenderVertexShortcut> lSCs = calculateShortcuts(lT); List <RenderVertexShortcut> rSCs = calculateShortcuts(rT); for (int i = 0; i < lSCs.Count; i++) { RenderVertexShortcut rvs = lSCs[i]; for (int j = rvs.indexBefore + 1; j < (rvs.indexAfter < rvs.indexBefore ? lT.Count : rvs.indexAfter); j++) { lT[j] = rvs.intersectPoint; } for (int j = 0; j < (rvs.indexAfter < rvs.indexBefore ? rvs.indexAfter : 0); j++) { lT[j] = rvs.intersectPoint; } } for (int i = 0; i < rSCs.Count; i++) { RenderVertexShortcut rvs = rSCs[i]; for (int j = rvs.indexBefore + 1; j < (rvs.indexAfter < rvs.indexBefore ? rT.Count : rvs.indexAfter); j++) { rT[j] = rvs.intersectPoint; } for (int j = 0; j < (rvs.indexAfter < rvs.indexBefore ? rvs.indexAfter : 0); j++) { rT[j] = rvs.intersectPoint; } } float grassWidth = 8f; List <Vector2> lGFull = new List <Vector2>(); List <Vector2> rGFull = new List <Vector2>(); for (int i = 0; i < lT.Count; i++) { int i0 = (i - 1) < 0 ? lT.Count - 1 : i - 1; int i2 = (i + 1) % lT.Count; Vector2 tangentLeft = lT[i2] - lT[i0]; Vector2 newVLeft = (new Vector2(-tangentLeft.y, tangentLeft.x)).normalized * grassWidth + lT[i]; Vector2 tangentRight = rT[i2] - rT[i0]; Vector2 newVRight = (new Vector2(tangentRight.y, -tangentRight.x)).normalized * grassWidth + rT[i]; Vector2 vLeft = (lT[i] - rT[i]).normalized * grassWidth + lT[i]; Vector2 vRight = (rT[i] - lT[i]).normalized * grassWidth + rT[i]; lG.Add(newVLeft); rG.Add(newVRight); lGFull.Add(newVLeft); rGFull.Add(newVRight); } int grassPlanesNewStartIndex = -1; if (discreteTrack != null) { Vector2 startFinishPos = new Vector2(elements[(int)discreteTrack.startFinishLineIndex].Position.x, elements[(int)discreteTrack.startFinishLineIndex].Position.z); float minDistance = float.MaxValue; for (int i = 0; i < lGFull.Count; i++) { if (Vector2.Distance(lGFull[i], startFinishPos) < minDistance) { grassPlanesNewStartIndex = i; minDistance = Vector2.Distance(lGFull[i], startFinishPos); } } Debug.Log("Grass start index: " + grassPlanesNewStartIndex); List <Vector2> lGFullNew = new List <Vector2>(); List <Vector2> rGFullNew = new List <Vector2>(); List <Vector2> rTNew = new List <Vector2>(); List <Vector2> lTNew = new List <Vector2>(); List <Vector2> rGNew = new List <Vector2>(); List <Vector2> lGNew = new List <Vector2>(); for (int i = 0; i < lGFull.Count; i++) { lGFullNew.Add(lGFull[(i + grassPlanesNewStartIndex) % lGFull.Count]); lTNew.Add(lT[(i + grassPlanesNewStartIndex) % lGFull.Count]); lGNew.Add(lG[(i + grassPlanesNewStartIndex) % lGFull.Count]); rGFullNew.Add(rGFull[(i + grassPlanesNewStartIndex) % lGFull.Count]); rTNew.Add(rT[(i + grassPlanesNewStartIndex) % lGFull.Count]); rGNew.Add(rG[(i + grassPlanesNewStartIndex) % lGFull.Count]); } lGFull = lGFullNew; rGFull = rGFullNew; rT = rTNew; lT = lTNew; lG = lGNew; rG = rGNew; } // Curbs curbsGenerator = new CurbsGenerator(lT.ToArray(), rT.ToArray(), grassPlanesNewStartIndex); curbsGenerator.CalculateCurbs(discreteTrack); /*lGFull.Add(lGFull[0]); * rGFull.Add(rGFull[0]); * lG.Add(lG[0]); * rG.Add(rG[0]); * lT.Add(lT[0]); * rT.Add(rT[0]);*/ // Generating the grass zones on the sides List <GeneratedGrassPlane> grassplanes = new List <GeneratedGrassPlane>(); GeneratedPlaneElement[] leftGrassPlanes = generateGrassplanes(lGFull, lG, lT, 0, 0, 0); GeneratedPlaneElement[] rightGrassPlanes = generateGrassplanes(rGFull, rG, rT, 0, 0, 0); GeneratedPlaneElement[] combinedPlanes = new GeneratedPlaneElement[leftGrassPlanes.Length + rightGrassPlanes.Length]; for (int i = 0; i < leftGrassPlanes.Length; i++) { combinedPlanes[i] = leftGrassPlanes[i]; } for (int i = 0; i < rightGrassPlanes.Length; i++) { combinedPlanes[i + leftGrassPlanes.Length] = rightGrassPlanes[i]; } // Track vertices List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); List <Vector2> uvs = new List <Vector2>(); float rightUvCounter = 0f; float leftUvCounter = 0f; vertices.Add(new Vector3(lT[0].x, 0f, lT[0].y)); uvs.Add(new Vector2(0f, leftUvCounter)); vertices.Add(new Vector3(rT[0].x, 0f, rT[0].y)); uvs.Add(new Vector2(1f, rightUvCounter)); for (int i = 1; i < lT.Count; i++) { vertices.Add(new Vector3(lT[i].x, 0f, lT[i].y)); leftUvCounter += (Vector3.Distance(vertices[vertices.Count - 3], vertices[vertices.Count - 1])) * (1f / 16f); uvs.Add(new Vector2(0f, leftUvCounter)); vertices.Add(new Vector3(rT[i].x, 0f, rT[i].y)); rightUvCounter += (Vector3.Distance(vertices[vertices.Count - 3], vertices[vertices.Count - 1])) * (1f / 16f); uvs.Add(new Vector2(1f, rightUvCounter)); triangles.Add(vertices.Count - 4); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 3); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 3); } vertices.Add(new Vector3(lT[0].x, 0f, lT[0].y)); leftUvCounter += (Vector3.Distance(vertices[vertices.Count - 3], vertices[vertices.Count - 1])) * (1f / 16f); uvs.Add(new Vector2(0f, leftUvCounter)); vertices.Add(new Vector3(rT[0].x, 0f, rT[0].y)); rightUvCounter += (Vector3.Distance(vertices[vertices.Count - 3], vertices[vertices.Count - 1])) * (1f / 16f); uvs.Add(new Vector2(1f, rightUvCounter)); triangles.Add(vertices.Count - 4); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 3); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 3); RenderVerticesTrack = vertices.ToArray(); RenderTrianglesTrack = triangles.ToArray(); RenderUVsTrack = uvs.ToArray(); // Grass vertices List <GeneratedGrassPlane> leftGrass = new List <GeneratedGrassPlane>(); for (int i = 0; i < leftGrassPlanes.Length; i++) { GeneratedGrassPlane plane = new GeneratedGrassPlane(); List <Vector3> verticesOutside = new List <Vector3>(); List <Vector3> directionsOutside = new List <Vector3>(); List <Vector3> verticesGrassLeft = new List <Vector3>(); List <int> trianglesGrassLeft = new List <int>(); List <Vector2> uvsGrassLeft = new List <Vector2>(); if (leftGrassPlanes[i].GetType() == typeof(GeneratedGrassPlane2D)) { GeneratedGrassPlane2D ggp2d = (GeneratedGrassPlane2D)leftGrassPlanes[i]; verticesOutside.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); uvsGrassLeft.Add(ggp2d.vertices[0]); verticesGrassLeft.Add(new Vector3(lT[ggp2d.trackStartIndex + 0].x, 0f, lT[ggp2d.trackStartIndex + 0].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.LeftWidths[ggp2d.trackStartIndex + 0])); uvsGrassLeft.Add(lT[ggp2d.trackStartIndex + 0]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); for (int j = 1; j < ggp2d.vertices.Count; j++) { bool locked = false; for (int k = 0; k < ggp2d.jumpIndices.Count; k++) { if (j + ggp2d.trackStartIndex >= ggp2d.jumpIndices[k] && j + ggp2d.trackStartIndex < ggp2d.jumpIndices[k] + ggp2d.jumpWidths[k]) { locked = true; } } if (!locked) { verticesOutside.Add(new Vector3(ggp2d.vertices[j].x, 0f, ggp2d.vertices[j].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[j].x, 0f, ggp2d.vertices[j].y)); uvsGrassLeft.Add(ggp2d.vertices[j]); verticesGrassLeft.Add(new Vector3(lT[ggp2d.trackStartIndex + j].x, 0f, lT[ggp2d.trackStartIndex + j].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.LeftWidths[ggp2d.trackStartIndex + j])); uvsGrassLeft.Add(lT[ggp2d.trackStartIndex + j]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); trianglesGrassLeft.Add(verticesGrassLeft.Count - 4); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 1); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); } } verticesOutside.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); uvsGrassLeft.Add(ggp2d.vertices[0]); verticesGrassLeft.Add(new Vector3(lT[ggp2d.trackStartIndex + 0].x, 0f, lT[ggp2d.trackStartIndex + 0].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.LeftWidths[ggp2d.trackStartIndex + 0])); uvsGrassLeft.Add(lT[ggp2d.trackStartIndex + 0]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); trianglesGrassLeft.Add(verticesGrassLeft.Count - 4); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 1); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); plane.vertices = verticesGrassLeft.ToArray(); plane.triangles = trianglesGrassLeft.ToArray(); plane.uvs = uvsGrassLeft.ToArray(); plane.AllowBordercross = true; plane.verticesOutside = verticesOutside.ToArray(); plane.directionsOutside = directionsOutside.ToArray(); leftGrass.Add(plane); } else { GeneratedPlaneBetween gpb = (GeneratedPlaneBetween)leftGrassPlanes[i]; for (int j = 0; j < gpb.vertices.Count; j++) { verticesGrassLeft.Add(new Vector3(gpb.vertices[j].x, 0f, gpb.vertices[j].y)); uvsGrassLeft.Add(gpb.vertices[j]); } plane.vertices = verticesGrassLeft.ToArray(); plane.triangles = gpb.triangles.ToArray(); plane.uvs = uvsGrassLeft.ToArray(); leftGrass.Add(plane); } } for (int i = 0; i < rightGrassPlanes.Length; i++) { GeneratedGrassPlane plane = new GeneratedGrassPlane(); List <Vector3> verticesOutside = new List <Vector3>(); List <Vector3> directionsOutside = new List <Vector3>(); List <Vector3> verticesGrassLeft = new List <Vector3>(); List <int> trianglesGrassLeft = new List <int>(); List <Vector2> uvsGrassLeft = new List <Vector2>(); if (rightGrassPlanes[i].GetType() == typeof(GeneratedGrassPlane2D)) { GeneratedGrassPlane2D ggp2d = (GeneratedGrassPlane2D)rightGrassPlanes[i]; verticesOutside.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); uvsGrassLeft.Add(ggp2d.vertices[0]); verticesGrassLeft.Add(new Vector3(rT[ggp2d.trackStartIndex + 0].x, 0f, rT[ggp2d.trackStartIndex + 0].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.RightWidths[ggp2d.trackStartIndex + 0])); uvsGrassLeft.Add(rT[ggp2d.trackStartIndex + 0]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); for (int j = 1; j < ggp2d.vertices.Count; j++) { bool locked = false; for (int k = 0; k < ggp2d.jumpIndices.Count; k++) { if (j + ggp2d.trackStartIndex >= ggp2d.jumpIndices[k] && j + ggp2d.trackStartIndex < ggp2d.jumpIndices[k] + ggp2d.jumpWidths[k]) { locked = true; } } if (!locked) { verticesOutside.Add(new Vector3(ggp2d.vertices[j].x, 0f, ggp2d.vertices[j].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[j].x, 0f, ggp2d.vertices[j].y)); uvsGrassLeft.Add(ggp2d.vertices[j]); verticesGrassLeft.Add(new Vector3(rT[ggp2d.trackStartIndex + j].x, 0f, rT[ggp2d.trackStartIndex + j].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.RightWidths[ggp2d.trackStartIndex + j])); uvsGrassLeft.Add(rT[ggp2d.trackStartIndex + j]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); trianglesGrassLeft.Add(verticesGrassLeft.Count - 4); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 1); } } verticesOutside.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); verticesGrassLeft.Add(new Vector3(ggp2d.vertices[0].x, 0f, ggp2d.vertices[0].y)); uvsGrassLeft.Add(ggp2d.vertices[0]); verticesGrassLeft.Add(new Vector3(rT[ggp2d.trackStartIndex + 0].x, 0f, rT[ggp2d.trackStartIndex + 0].y)); verticesGrassLeft[verticesGrassLeft.Count - 1] = verticesGrassLeft[verticesGrassLeft.Count - 2] + ((verticesGrassLeft[verticesGrassLeft.Count - 1] - verticesGrassLeft[verticesGrassLeft.Count - 2]).normalized * (Vector3.Distance(verticesGrassLeft[verticesGrassLeft.Count - 1], verticesGrassLeft[verticesGrassLeft.Count - 2]) - curbsGenerator.RightWidths[ggp2d.trackStartIndex + 0])); uvsGrassLeft.Add(rT[ggp2d.trackStartIndex + 0]); directionsOutside.Add((verticesGrassLeft[verticesGrassLeft.Count - 2] - verticesGrassLeft[verticesGrassLeft.Count - 1]).normalized); trianglesGrassLeft.Add(verticesGrassLeft.Count - 4); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 2); trianglesGrassLeft.Add(verticesGrassLeft.Count - 3); trianglesGrassLeft.Add(verticesGrassLeft.Count - 1); plane.vertices = verticesGrassLeft.ToArray(); plane.triangles = trianglesGrassLeft.ToArray(); plane.uvs = uvsGrassLeft.ToArray(); plane.AllowBordercross = true; plane.verticesOutside = verticesOutside.ToArray(); plane.directionsOutside = directionsOutside.ToArray(); leftGrass.Add(plane); } else { GeneratedPlaneBetween gpb = (GeneratedPlaneBetween)rightGrassPlanes[i]; for (int j = 0; j < gpb.vertices.Count; j++) { verticesGrassLeft.Add(new Vector3(gpb.vertices[j].x, 0f, gpb.vertices[j].y)); uvsGrassLeft.Add(gpb.vertices[j]); } for (int j = 0; j < gpb.triangles.Count; j += 3) { trianglesGrassLeft.Add(gpb.triangles[j]); trianglesGrassLeft.Add(gpb.triangles[j + 2]); trianglesGrassLeft.Add(gpb.triangles[j + 1]); } plane.vertices = verticesGrassLeft.ToArray(); plane.triangles = trianglesGrassLeft.ToArray(); plane.uvs = uvsGrassLeft.ToArray(); plane.AllowBordercross = false; leftGrass.Add(plane); } } GrassPlanes = leftGrass.ToArray(); }
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 BorderGenerator(TerrainModifier terrainModifier, List <GeneratedElement> elements, float startFinishLineIndex) { leftWall = new List <Vector3>(); rightWall = new List <Vector3>(); List <Vector2> left = new List <Vector2>(); List <Vector2> right = new List <Vector2>(); int startIndex = (int)startFinishLineIndex; for (int i = 0; i < elements.Count; i++) { if (elements[(i + startIndex) % elements.Count].GetType() == typeof(GeneratedStraight)) { GeneratedStraight straight = (GeneratedStraight)elements[(i + startIndex) % elements.Count]; 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; left.Add(new Vector2((straight.Position + (toFront * s) - toRight - (toRight.normalized * fixDistance)).x, (straight.Position + (toFront * s) - toRight - (toRight.normalized * fixDistance)).z)); right.Add(new Vector2((straight.Position + (toFront * s) + toRight + (toRight.normalized * fixDistance)).x, (straight.Position + (toFront * s) + toRight + (toRight.normalized * fixDistance)).z)); } } else if (elements[(i + startIndex) % elements.Count].GetType() == typeof(GeneratedTurn)) { GeneratedTurn turn = (GeneratedTurn)elements[(i + startIndex) % elements.Count]; 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; left.Add(new Vector2((segmentPos + toRightTurned * currentWidth * -1f + (toRightTurned.normalized * fixDistance * -1f) + turn.Position).x, (segmentPos + toRightTurned * currentWidth * -1f + (toRightTurned.normalized * fixDistance * -1f) + turn.Position).z)); right.Add(new Vector2((segmentPos + toRightTurned * currentWidth + (toRightTurned.normalized * fixDistance) + turn.Position).x, (segmentPos + toRightTurned * currentWidth + (toRightTurned.normalized * fixDistance) + turn.Position).z)); } } else if (elements[(i + startIndex) % elements.Count].GetType() == typeof(GeneratedBezSpline)) { GeneratedBezSpline bezierSpline = (GeneratedBezSpline)elements[(i + startIndex) % elements.Count]; for (int j = 1; j < bezierSpline.RenderVertsLeft.Length; j++) { Vector3 toRight = (bezierSpline.RenderVertsRight[j] - bezierSpline.RenderVertsLeft[j]).normalized; left.Add(new Vector2((bezierSpline.RenderVertsLeft[j] + (toRight * -fixDistance)).x, (bezierSpline.RenderVertsLeft[j] + (toRight * -fixDistance)).z)); right.Add(new Vector2((bezierSpline.RenderVertsRight[j] + (toRight * fixDistance)).x, (bezierSpline.RenderVertsRight[j] + (toRight * fixDistance)).z)); } } } bool[] leftIgnores = new bool[left.Count]; bool[] rightIgnores = new bool[right.Count]; for (int i = 0; i < leftIgnores.Length; i++) { leftIgnores[i] = false; } for (int i = 0; i < rightIgnores.Length; i++) { rightIgnores[i] = false; } for (int i = 0; i < left.Count; i++) { int i2 = (i + 1) % left.Count; Line lineToTest = new Line(left[i % left.Count], left[i2]); int jumpIndex = -1; for (int jT = 0 + 2; jT < left.Count - 40; jT++) { int j = (jT + i) % left.Count; int j2 = (j + 1) % left.Count; if (leftIgnores[j] == false) { Line other = new Line(left[j], left[j2]); Vector2 intersectPoint; if (lineToTest.Intersects(other, out intersectPoint)) { jumpIndex = (j < i ? j + left.Count : j); break; } } } leftWall.Add(new Vector3(left[i].x, terrainModifier.GetTensorHeight(left[i].x, left[i].y), left[i].y)); if (jumpIndex != -1) { for (int k = i; k < jumpIndex; k++) { leftIgnores[k % leftIgnores.Length] = true; } i = jumpIndex; leftWall.Add(new Vector3(left[i % left.Count].x, terrainModifier.GetTensorHeight(left[i % left.Count].x, left[i % left.Count].y), left[i % left.Count].y)); } } for (int i = 0; i < right.Count; i++) { int i2 = (i + 1) % right.Count; Line lineToTest = new Line(right[i], right[i2]); int jumpIndex = -1; for (int jT = 0 + 2; jT < right.Count - 40; jT++) { int j = (jT + i) % right.Count; int j2 = (j + 1) % right.Count; if (rightIgnores[j] == false) { Line other = new Line(right[j], right[j2]); Vector2 intersectPoint; if (lineToTest.Intersects(other, out intersectPoint)) { jumpIndex = (j < i ? j + right.Count : j); break; } } } rightWall.Add(new Vector3(right[i].x, terrainModifier.GetTensorHeight(right[i].x, right[i].y), right[i].y)); if (jumpIndex != -1) { for (int k = i; k < jumpIndex; k++) { rightIgnores[k % rightIgnores.Length] = true; } i = jumpIndex; rightWall.Add(new Vector3(right[i % right.Count].x, terrainModifier.GetTensorHeight(right[i % right.Count].x, right[i % right.Count].y), right[i % right.Count].y)); } } }
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--; } }