public void ApplyCurb(GeneratedCurb curb, TerrainModifier terrainModifier) { // Todo height of TPP apply if (meshFilter == null) { meshFilter = GetComponent <MeshFilter>(); meshCollider = GetComponent <MeshCollider>(); } Vector3[] trVerts = new Vector3[curb.RenderVertices.Length]; for (int i = 0; i < trVerts.Length; i++) { trVerts[i] = curb.RenderVertices[i] + new Vector3(0f, terrainModifier.GetTensorHeight(curb.RenderVertices[i].x, curb.RenderVertices[i].z), 0f); } meshFilter.mesh.Clear(); meshFilter.mesh.vertices = trVerts; meshFilter.mesh.uv = curb.RenderUVs; meshFilter.mesh.subMeshCount = 1; meshFilter.mesh.SetTriangles(curb.RenderTriangles, 0); meshFilter.mesh.RecalculateNormals(); meshCollider.sharedMesh = meshFilter.mesh; }
public void RefreshPlane(TerrainModifier terrainModifier) { List <Vector3> verts = new List <Vector3>(); List <int> trias = new List <int>(); for (int x = -resolution; x <= resolution; x++) { for (int y = -resolution; y <= resolution; y++) { verts.Add(new Vector3(x * scale, terrainModifier.GetTensorHeight(x * scale, y * scale), y * scale)); } } for (int x = resolution * 2 + 1; x < verts.Count; x++) { if (x % (resolution * 2 + 1) != 0) { trias.Add(x - (resolution * 2 + 1) - 1); trias.Add(x - 1); trias.Add(x); trias.Add(x - (resolution * 2 + 1) - 1); trias.Add(x); trias.Add(x - (resolution * 2 + 1)); } } meshFilter.mesh.Clear(); meshFilter.mesh.vertices = verts.ToArray(); meshFilter.mesh.subMeshCount = 1; meshFilter.mesh.SetTriangles(trias.ToArray(), 0); meshFilter.mesh.RecalculateNormals(); meshCollider.sharedMesh = meshFilter.mesh; }
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 float GetTensorHeight(Vector3 position) { return(terrainModifier.GetTensorHeight(position.x, position.z)); }
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)); } } }