private static List <Vector3> intersect(Bezeir b1, Bezeir b2) { Vector2 A2 = b1.P0 - 2 * b1.P1 + b1.P2; Vector2 A1 = -2 * b1.P0 + 2 * b1.P1; Vector2 A0 = b1.P0; Vector2 B2 = b2.P0 - 2 * b2.P1 + b2.P2; Vector2 B1 = -2 * b2.P0 + 2 * b2.P1; Vector2 B0 = b2.P0; return(filter(Algebra.parametricFunctionSolver(A0, A1, A2, B0, B1, B2), b1, b2)); }
public static Curve TryInit(Vector3 _P0, Vector3 _P1, Vector3 _P2) { if (Geometry.Parallel(_P1 - _P0, _P2 - _P1)) { Debug.LogWarning("Bezeir Ctrl Point Parallel!"); return(Line.TryInit(_P0, _P2)); } Bezeir candidate = new Bezeir(_P0, _P1, _P2); if (Algebra.isclose(candidate.length, 0f)) { Debug.LogWarning("try creating Bezeir of zero length!"); return(null); } else { return(candidate); } }
public override List <Curve> segmentation(float maxlen) { List <Curve> result = new List <Curve>(); float lastEnd = 0f; int fragCount = Mathf.CeilToInt(this.length / maxlen); for (int multipler = 0; multipler < fragCount; multipler++) { float thisEnd; thisEnd = Algebra.NewTown(this.lengthByParam, this.lengthGradient, Mathf.Min(this.length, (float)(multipler + 1) * maxlen), Mathf.Min(1f, maxlen / this.length * (multipler + 1))); Curve fragment = Bezeir.TryInit(this.P0, this.P1, this.P2, this.z_start + this.z_offset * lastEnd, this.z_start + this.z_offset * thisEnd); fragment.t_start = toGlobalParam(lastEnd); fragment.t_end = toGlobalParam(thisEnd); result.Add(fragment); lastEnd = thisEnd; } return(result); }
Road generateVirtualRoad(int i1, int i2) { Road r1 = connection[i1]; Road r2 = connection[i2]; if (outLaneRange[i1, i2] == null) { return(null); } int loOutLaneNum = outLaneRange[i1, i2].First; int hiOutLaneNum = outLaneRange[i1, i2].Second; int loInLaneNum = inLaneRange[i2, i1].First; int hiInLaneNum = inLaneRange[i2, i1].Second; Debug.Assert(hiOutLaneNum - loOutLaneNum == hiInLaneNum - loInLaneNum); float r1_margin = startof(r1.curve) ? r1.margin0Param : r1.margin1Param; float r2_margin = startof(r2.curve) ? r2.margin0Param : r2.margin1Param; float r1_radiOffset = 0.5f * (r1.getLaneCenterOffset(loOutLaneNum, !startof(r1.curve)) + r1.getLaneCenterOffset(hiOutLaneNum, !startof(r1.curve))); float r2_radiOffset = 0.5f * (r2.getLaneCenterOffset(loInLaneNum, startof(r2.curve)) + r2.getLaneCenterOffset(hiInLaneNum, startof(r2.curve))); Vector3 r1_endPos = r1.at(r1_margin) + r1.rightNormal(r1_margin) * r1_radiOffset; Vector3 r2_endPos = r2.at(r2_margin) + r2.rightNormal(r2_margin) * r2_radiOffset; List <string> virtualRoadLaneCfg = new List <string>(); int virtualRoadLaneCount = hiOutLaneNum - loOutLaneNum + 1; for (int i = 0; i != virtualRoadLaneCount; ++i) { virtualRoadLaneCfg.Add("lane"); if (i != virtualRoadLaneCount - 1) { virtualRoadLaneCfg.Add("dash_white"); } } Vector2 r1_direction = startof(r1.curve) ? -r1.curve.direction_2d(r1_margin) : r1.curve.direction_2d(r1_margin); Vector2 r2_direction = startof(r2.curve) ? -r2.curve.direction_2d(r2_margin) : r2.curve.direction_2d(r2_margin); if (Geometry.Parallel(r1_direction, r2_direction)) { /*TODO: perform a U turn when r1 = r2*/ if (Algebra.isRoadNodeClose(r1_endPos, r2_endPos)) { /*exact same lane config for neighbors, just go straight*/ return(null); } //return new Road(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg, _noEntity: true); return(createNoEntityRoadIfNotNull(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg)); } else { Curve l1 = Line.TryInit(Algebra.toVector2(r1_endPos), Algebra.toVector2(r1_endPos) + Algebra.InfLength * r1_direction, r1_endPos.y, r1_endPos.y); Curve l2 = Line.TryInit(Algebra.toVector2(r2_endPos), Algebra.toVector2(r2_endPos) + Algebra.InfLength * r2_direction, r2_endPos.y, r2_endPos.y); List <Vector3> intereSectionPoint = Geometry.curveIntersect(l1, l2); if (intereSectionPoint.Count == 1) { //return new Road(Bezeir.TryInit(r1_endPos, intereSectionPoint.First(), r2_endPos), virtualRoadLaneCfg, _noEntity: true); return(createNoEntityRoadIfNotNull(Bezeir.TryInit(r1_endPos, intereSectionPoint.First(), r2_endPos), virtualRoadLaneCfg)); } else { //return new Road(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg, _noEntity: true); return(createNoEntityRoadIfNotNull(Line.TryInit(r1_endPos, r2_endPos), virtualRoadLaneCfg)); } } }
Pair <float, float> smoothenCrossing(Road r1, Road r2, out List <Curve> smootheners) { float r1_angle = startof(r1.curve) ? r1.curve.angle_ending(true) : r1.curve.angle_ending(false); float r2_angle = startof(r2.curve) ? r2.curve.angle_ending(true) : r2.curve.angle_ending(false); float delta_angle = r1_angle < r2_angle ? r2_angle - r1_angle : r2_angle + 2 * Mathf.PI - r1_angle; this.r1 = r1; this.r2 = r2; smootheners = new List <Curve>(); Vector2 streetCorner = approxStreetCorner(); //debugPoints.Add(Algebra.toVector3(streetCorner)); switch (Geometry.getAngleType(delta_angle)) { case angleType.Sharp: case angleType.Blunt: if (c1_offset > 0f && c2_offset > 0f) { /*c1,c2>0*/ float extraSmoothingLength = arcSmoothingRadius / Mathf.Tan(delta_angle / 2); addIfNotNull(smootheners, Arc.TryInit(r1.curve.at_ending_2d(startof(r1.curve), c1_offset + extraSmoothingLength) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), c1_offset + extraSmoothingLength) + Mathf.PI / 2) * r1.width / 2, Mathf.PI - delta_angle, r2.curve.at_ending_2d(startof(r2.curve), c2_offset + extraSmoothingLength) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), c2_offset + extraSmoothingLength) - Mathf.PI / 2) * r2.width / 2)); return(new Pair <float, float>(c1_offset + extraSmoothingLength, c2_offset + extraSmoothingLength)); } if (c1_offset > 0f) { /*c1>0, c2<=0*/ float smoothRadius = -c2_offset; addIfNotNull(smootheners, Arc.TryInit(r1.curve.at_ending_2d(startof(r1.curve), c1_offset + smoothRadius) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), c1_offset + smoothRadius) + Mathf.PI / 2) * r1.width / 2, Mathf.PI - delta_angle, r2.curve.at_ending_2d(startof(r2.curve)) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve)) - Mathf.PI / 2) * r2.width / 2)); /*TODO: calculate more precise delta_angle*/ return(new Pair <float, float>(c1_offset + smoothRadius, 0)); } if (c2_offset > 0f) { /*c1<0, c2>0*/ float smoothRadius = -c1_offset; Curve smoothener = Arc.TryInit(r1.curve.at_ending_2d(startof(r1.curve)) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve)) + Mathf.PI / 2) * r1.width / 2, Mathf.PI - delta_angle, r2.curve.at_ending_2d(startof(r2.curve), c2_offset + smoothRadius) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), c2_offset + smoothRadius) - Mathf.PI / 2) * r2.width / 2); addIfNotNull(smootheners, smoothener); return(new Pair <float, float>(0, c2_offset + smoothRadius)); } Debug.Assert(false); break; case angleType.Flat: if (r1.width == r2.width) { return(new Pair <float, float>(0, 0)); } float widthDiff = Math.Abs(r1.width - r2.width) / 2; if (r1.width > r2.width) { Vector2 P0 = r1.curve.at_ending_2d(startof(r1.curve)) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve)) + Mathf.PI / 2) * r1.width / 2; Vector2 P1 = r2.curve.at_ending_2d(startof(r2.curve), widthDiff * bezeirSmoothingScale * 0.25f) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), widthDiff * bezeirSmoothingScale * 0.25f) + Mathf.PI / 2) * r1.width / 2; Vector2 P4 = r2.curve.at_ending_2d(startof(r2.curve), widthDiff * bezeirSmoothingScale) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), widthDiff * bezeirSmoothingScale) - Mathf.PI / 2) * r2.width / 2; Vector2 P3 = r2.curve.at_ending_2d(startof(r2.curve), widthDiff * bezeirSmoothingScale * 0.75f) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), widthDiff * bezeirSmoothingScale * 0.75f) - Mathf.PI / 2) * r2.width / 2; Vector2 P2 = (P1 + P3) / 2; addIfNotNull(smootheners, Bezeir.TryInit(P0, P1, P2)); addIfNotNull(smootheners, Bezeir.TryInit(P2, P3, P4)); return(new Pair <float, float>(0f, widthDiff * bezeirSmoothingScale)); } else { Vector2 P0 = r1.curve.at_ending_2d(startof(r1.curve), widthDiff * bezeirSmoothingScale) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), widthDiff * bezeirSmoothingScale) + Mathf.PI / 2) * r1.width / 2; Vector2 P1 = r1.curve.at_ending_2d(startof(r1.curve), widthDiff * bezeirSmoothingScale * 0.75f) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), widthDiff * bezeirSmoothingScale * 0.75f) + Mathf.PI / 2) * r1.width / 2; Vector2 P3 = r1.curve.at_ending_2d(startof(r1.curve), widthDiff * bezeirSmoothingScale * 0.25f) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), widthDiff * bezeirSmoothingScale * 0.25f) + Mathf.PI / 2) * r2.width / 2; Vector2 P4 = r2.curve.at_ending_2d(startof(r2.curve)) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve)) - Mathf.PI / 2) * r2.width / 2; Vector2 P2 = (P1 + P3) / 2; addIfNotNull(smootheners, Bezeir.TryInit(P0, P1, P2)); addIfNotNull(smootheners, Bezeir.TryInit(P2, P3, P4)); return(new Pair <float, float>(widthDiff * bezeirSmoothingScale, 0f)); } case angleType.Reflex: float arcRadius = Mathf.Max(r1.width / 2, r2.width / 2); float bWidthDiff = Mathf.Abs(r1.width - r2.width) / 2; Curve arcSmoothener = Arc.TryInit(twodPosition, twodPosition + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve)) + Mathf.PI / 2) * arcRadius, delta_angle - Mathf.PI); if (r1.width == r2.width) { addIfNotNull(smootheners, arcSmoothener); return(new Pair <float, float>(0f, 0f)); } if (r1.width > r2.width) { Vector2 P0 = r2.curve.at_ending_2d(startof(r2.curve)) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve)) - Mathf.PI / 2) * r1.width / 2; Vector2 P1 = r2.curve.at_ending_2d(startof(r2.curve), bWidthDiff * bezeirSmoothingScale * 0.25f) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), bWidthDiff * bezeirSmoothingScale * 0.25f) - Mathf.PI / 2) * r1.width / 2; Vector2 P4 = r2.curve.at_ending_2d(startof(r2.curve), bWidthDiff * bezeirSmoothingScale) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), bWidthDiff * bezeirSmoothingScale) - Mathf.PI / 2) * r2.width / 2; Vector2 P3 = r2.curve.at_ending_2d(startof(r2.curve), bWidthDiff * bezeirSmoothingScale * 0.75f) + Algebra.angle2dir(r2.curve.angle_ending(startof(r2.curve), bWidthDiff * bezeirSmoothingScale * 0.75f) - Mathf.PI / 2) * r2.width / 2; Vector2 P2 = (P1 + P3) / 2; addIfNotNull(smootheners, arcSmoothener); addIfNotNull(smootheners, Bezeir.TryInit(P0, P1, P2)); addIfNotNull(smootheners, Bezeir.TryInit(P2, P3, P4)); return(new Pair <float, float>(0f, bWidthDiff * bezeirSmoothingScale)); } else { Vector2 P0 = r1.curve.at_ending_2d(startof(r1.curve), bWidthDiff * bezeirSmoothingScale) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), bWidthDiff * bezeirSmoothingScale) + Mathf.PI / 2) * r1.width / 2; Vector2 P1 = r1.curve.at_ending_2d(startof(r1.curve), bWidthDiff * bezeirSmoothingScale * 0.75f) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), bWidthDiff * bezeirSmoothingScale * 0.75f) + Mathf.PI / 2) * r1.width / 2; Vector2 P3 = r1.curve.at_ending_2d(startof(r1.curve), bWidthDiff * bezeirSmoothingScale * 0.25f) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve), bWidthDiff * bezeirSmoothingScale * 0.25f) + Mathf.PI / 2) * r2.width / 2; Vector2 P4 = r1.curve.at_ending_2d(startof(r1.curve)) + Algebra.angle2dir(r1.curve.angle_ending(startof(r1.curve)) + Mathf.PI / 2) * r2.width / 2; Vector2 P2 = (P1 + P3) / 2; addIfNotNull(smootheners, Bezeir.TryInit(P0, P1, P2)); addIfNotNull(smootheners, Bezeir.TryInit(P2, P3, P4)); addIfNotNull(smootheners, arcSmoothener); return(new Pair <float, float>(bWidthDiff * bezeirSmoothingScale, 0f)); } default: return(new Pair <float, float>(-1f, -1f)); } return(new Pair <float, float>(-1f, -1f)); }
private static List <Vector3> intersect(Line b1, Bezeir b2) { return(intersect(b2, b1)); }
public void Update() { clearAngleDrawing(); laneConfig = GameObject.FindWithTag("UI/laneconfig").GetComponent <LaneConfigPanelBehavior>().laneconfigresult; interestedApproxLines.Clear(); if (pointer >= 1) { interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1] + Vector3.back * Algebra.InfLength, controlPoint[pointer - 1] + Vector3.forward * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1] + Vector3.left * Algebra.InfLength, controlPoint[pointer - 1] + Vector3.right * Algebra.InfLength)); if (targetRoad != null && !Algebra.isProjectionClose(controlPoint[pointer - 1], targetRoad.curve.AttouchPoint(controlPoint[pointer - 1]))) { interestedApproxLines.Add(Line.TryInit(controlPoint[pointer - 1], targetRoad.curve.AttouchPoint(controlPoint[pointer - 1]))); } } if (indicatorType == IndicatorType.none) { nodeIndicator.transform.localScale = Vector3.zero; } if (controlPoint[pointer].x != Vector3.negativeInfinity.x && indicatorType != IndicatorType.none) { Vector3 adjustedAttach; if (targetRoad != null) { adjustedAttach = targetRoad.at(targetRoad.curve.paramOf(targetRoad.curve.AttouchPoint(controlPoint[pointer])).Value); } else { adjustedAttach = controlPoint[pointer]; } nodeIndicator.transform.position = new Vector3(adjustedAttach.x, adjustedAttach.y / 2 + 0.1f, adjustedAttach.z); nodeIndicator.transform.localScale = new Vector3(1.5f, Mathf.Max(1f, adjustedAttach.y / 2), 1.5f); if (indicatorType == IndicatorType.line) { if (pointer == 1) { Destroy(roadIndicator); addAngleDrawing(controlPoint[1], controlPoint[0]); addAngleDrawing(controlPoint[0], controlPoint[1]); Road cp0_targetRoad; roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad); if (cp0_targetRoad != null) { //perpendicular interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) + Mathf.PI / 2) * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) - Mathf.PI / 2) * Algebra.InfLength)); //extension if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0])) { Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } else { if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0])) { Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } } } if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1])) { roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig); } } if (pointer == 2) { roadManager.addRoad(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig); reset(); } } if (indicatorType == IndicatorType.bezeir) { if (pointer == 1) { Destroy(roadIndicator); addAngleDrawing(controlPoint[1], controlPoint[0]); addAngleDrawing(controlPoint[0], controlPoint[1]); interestedApproxLines.Add(Line.TryInit(controlPoint[0] + Vector3.back * Algebra.InfLength, controlPoint[0] + Vector3.forward * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[0] + Vector3.left * Algebra.InfLength, controlPoint[0] + Vector3.right * Algebra.InfLength)); Road cp0_targetRoad; roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad); if (cp0_targetRoad != null) { interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) + Mathf.PI / 2) * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d((float)cp0_targetRoad.curve.paramOf(controlPoint[0])) - Mathf.PI / 2) * Algebra.InfLength)); if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0])) { Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } else { if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0])) { Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } } } if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1])) { roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(Line.TryInit(controlPoint[0], controlPoint[1]), laneConfig); } } if (pointer == 2) { if (!Geometry.Parallel(controlPoint[1] - controlPoint[0], controlPoint[2] - controlPoint[1]) && !Algebra.isRoadNodeClose(controlPoint[2], controlPoint[1])) { Destroy(roadIndicator); addAngleDrawing(controlPoint[2], controlPoint[1]); roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(Bezeir.TryInit(controlPoint[0], controlPoint[1], controlPoint[2]), laneConfig); } } if (pointer == 3) { if (!Geometry.Parallel(controlPoint[1] - controlPoint[0], controlPoint[2] - controlPoint[1]) && !Algebra.isRoadNodeClose(controlPoint[2], controlPoint[1])) { roadManager.addRoad(Bezeir.TryInit(controlPoint[0], controlPoint[1], controlPoint[2]), laneConfig); reset(); } else { pointer = 2; } } } if (indicatorType == IndicatorType.arc) { if (pointer == 1) { Road cp0_targetRoad; roadManager.approxNodeToExistingRoad(controlPoint[0], out cp0_targetRoad); if (cp0_targetRoad != null) { addAngleDrawing(controlPoint[0], controlPoint[1]); if (Algebra.isclose(cp0_targetRoad.curve.at_ending(true), controlPoint[0])) { interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(0f) + Mathf.PI / 2) * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(0f) - Mathf.PI / 2) * Algebra.InfLength)); Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(true), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } else { if (Algebra.isclose(cp0_targetRoad.curve.at_ending(false), controlPoint[0])) { interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(1f) + Mathf.PI / 2) * Algebra.InfLength)); interestedApproxLines.Add(Line.TryInit(controlPoint[0], controlPoint[0] + Algebra.angle2dir_3d(cp0_targetRoad.curve.Angle_2d(1f) - Mathf.PI / 2) * Algebra.InfLength)); Node crossingRoad; roadManager.findNodeAt(cp0_targetRoad.curve.at_ending(false), out crossingRoad); Debug.Assert(crossingRoad != null); interestedApproxLines.AddRange(crossingRoad.directionalLines(Algebra.InfLength, reverse: true)); } } } /*ind[0] is start, ind[1] isorigin*/ Destroy(roadIndicator); if (!Algebra.isProjectionClose(controlPoint[0], controlPoint[1])) { roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(Line.TryInit(controlPoint[1], controlPoint[0]), laneConfig); if (!Algebra.isclose(controlPoint[1], controlPoint[0])) { roadConfigure.generate(Arc.TryInit(controlPoint[1], controlPoint[0], 1.999f * Mathf.PI), laneConfig); } } } if (pointer == 2) { Vector3 basedir = controlPoint[0] - controlPoint[1]; Vector3 towardsdir = controlPoint[2] - controlPoint[1]; interestedApproxLines.Add(Arc.TryInit(controlPoint[1], controlPoint[0], Mathf.PI * 1.999f)); if (!Algebra.isProjectionClose(Vector3.zero, towardsdir) && !Algebra.isProjectionClose(controlPoint[1], controlPoint[0]) && !Geometry.Parallel(basedir, towardsdir)) { Destroy(roadIndicator); roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(Arc.TryInit(Algebra.toVector2(controlPoint[1]), Algebra.toVector2(controlPoint[0]), Mathf.Deg2Rad * Vector2.SignedAngle(Algebra.toVector2(basedir), Algebra.toVector2(towardsdir)), controlPoint[0].y, controlPoint[2].y), laneConfig); roadConfigure.generate(Arc.TryInit(controlPoint[1], controlPoint[1] + Vector3.right, 1.999f * Mathf.PI), laneConfig); } } if (pointer == 3) { Vector3 basedir = controlPoint[0] - controlPoint[1]; Vector3 towardsdir = controlPoint[2] - controlPoint[1]; if (Algebra.isclose(0, towardsdir.magnitude)) { pointer = 2; } else { roadManager.addRoad(Arc.TryInit(Algebra.toVector2(controlPoint[1]), Algebra.toVector2(controlPoint[0]), Mathf.Deg2Rad * Vector2.SignedAngle(Algebra.toVector2(basedir), Algebra.toVector2(towardsdir)), controlPoint[0].y, controlPoint[2].y), laneConfig); reset(); } } } if (indicatorType == IndicatorType.delete) { if (pointer == 0) { Destroy(roadIndicator); if (targetRoad != null) { roadIndicator = Instantiate(roadIndicatorPrefab, transform); RoadRenderer roadConfigure = roadIndicator.GetComponent <RoadRenderer>(); roadConfigure.generate(targetRoad.marginedOutCurve, new List <string> { "removal_" + targetRoad.width }); } } else { if (targetRoad != null) { roadManager.deleteRoad(targetRoad); reset(); } else { pointer = 0; } } } } }