public static ushort FindConnactableSegment(ushort endNodeID, ushort segmentID0, out Vector2 hitPoint) { hitPoint = Vector2.zero; var flags = endNodeID.ToNode().m_flags; bool b = flags.IsFlagSet(NetNode.Flags.End | NetNode.Flags.Bend); b &= endNodeID.ToNode().Info.CanConnectPath(); //flags.IsFlagSet(NetNode.Flags.OnGround); if (!b) { return(0); } Vector2 dir = -GetSegmentDir(segmentID0, endNodeID).ToCS2D(); Vector3 pos = endNodeID.ToNode().m_position; Vector2 start = pos.ToCS2D(); float max_distance = 16 * MPU; float min_distance = max_distance + MathUtil.Epsilon; ushort ret = 0; foreach (ushort segmentID in ScanDirSegment(start, dir, max_distance)) { if (IsNodeTooCloseToSegment(endNodeID, segmentID)) { Log.Debug($"segment:{segmentID} was ignored because it is too close to endNodeID:{endNodeID}"); continue; } bool onGround = segmentID.ToSegment().Info.m_netAI is RoadAI; if (!onGround) { Log.Debug($"segment:{segmentID} was ignored because it is not on ground"); continue; } segmentID.ToSegment().GetClosestPositionAndDirection(pos, out Vector3 hit, out Vector3 _); Vector2 _hitPoint = hit.ToCS2D(); Vector2 diff = _hitPoint - start; float angle = UnsignedAngleRad(dir, diff) * Mathf.Rad2Deg; float distance = diff.magnitude; //Log.Debug($"segmentID={segmentID} angle={angle} distance={distance}"); if (angle >= 45) { Log.Debug($"segment:{segmentID} was ignored its angle is too much: {angle} degrees"); continue; } if (distance >= min_distance) { Log.Debug($"segment:{segmentID} was ignored distance>min_distance"); continue; } ret = segmentID; hitPoint = _hitPoint; min_distance = distance; } return(ret); }
public SegmentEndData(ushort segmentID, ushort nodeID) { NodeID = nodeID; SegmentID = segmentID; Calculate(); CornerOffset = DefaultCornerOffset; FlatJunctions = DefaultFlatJunctions; Twist = DefaultTwist; if (VERBOSE) { Log.Debug($"SegmentEndData() Direction={Direction} Slope={SlopeAngleDeg}"); } Assert(IsDefault(), $"\n{CornerOffset} == {DefaultCornerOffset} error = 0.1\n" + $"DeltaSlopeAngleDeg:{DeltaSlopeAngleDeg} == 0;" + $"Stretch:{Stretch} == 0; " + $"EmbankmentAngleDeg:{EmbankmentAngleDeg} == 0; \n" + $"LeftCorner.IsDefault():{LeftCorner.IsDefault()} " + $"RightCorner.IsDefault():{RightCorner.IsDefault()} \n" + $"FlatJunctions:{FlatJunctions} == {DefaultFlatJunctions} " + $"Twist:{Twist} == {DefaultTwist} \n" + $"NoCrossings:{NoCrossings} == false; " + $"NoMarkings:{NoMarkings} == false; " + $"NoJunctionTexture:{NoJunctionTexture} == false; " + $"NoJunctionProps:{NoJunctionProps} == false; " + $"NoTLProps:{NoTLProps} == false " ); Update(); }
/// <summary> /// this is called to make necessary changes to the node to handle external changes /// </summary> private void Refresh() { if (HelpersExtensions.VERBOSE) { Log.Debug("SegmentEndData.Refresh() for this\n" + Environment.StackTrace); } if (!CanModifyOffset()) { //Log.Debug("SegmentEndData.Refresh(): setting CornerOffset = DefaultCornerOffset"); CornerOffset = DefaultCornerOffset; } if (!CanModifyFlatJunctions()) { FlatJunctions = DefaultFlatJunctions; } if (!CanModifyTwist()) { Twist = DefaultTwist; } if (!CanModifyCorners()) { DeltaSlopeAngleDeg = 0; Stretch = EmbankmentAngleDeg = 0; } if (!FlatJunctions) { Twist = false; } }
public void Update() { if (VERBOSE) { var st = new StackTrace(fNeedFileInfo: true); Log.Debug(this + "\n" + st.ToStringPretty()); } NetManager.instance.UpdateNode(NodeID); }
public void UpdateAllFlags() { if (!NetUtil.IsSegmentValid(SegmentID)) { if (SegmentID.ToSegment().m_flags.IsFlagSet(NetSegment.Flags.Created)) { Log.Debug("Skip updating invalid segment:" + SegmentID); } return; } if (Log.VERBOSE) { Log.Debug($"NetSegmentExt.UpdateAllFlags() called. SegmentID={SegmentID}" /*Environment.StackTrace*/, false); } try { bool parkingLeft = false; bool parkingRight = false; float speed0 = -1; bool uniformSpeed = true; foreach (LaneData lane in NetUtil.IterateSegmentLanes(SegmentID)) { ref NetLaneExt laneExt = ref NetworkExtensionManager.Instance.LaneBuffer[lane.LaneID]; laneExt.UpdateLane(lane, SegmentID); if (laneExt.m_flags.IsFlagSet(NetLaneExt.Flags.ParkingAllowed)) { if (lane.LeftSide) { parkingLeft = true; } else { parkingRight = true; } } if (lane.LaneInfo.m_laneType.IsFlagSet(SpeedLimitManager.LANE_TYPES) && lane.LaneInfo.m_vehicleType.IsFlagSet(SpeedLimitManager.VEHICLE_TYPES)) { if (speed0 == -1) { speed0 = laneExt.SpeedLimit; } else { uniformSpeed &= laneExt.SpeedLimit == speed0; } } } m_flags = m_flags.SetFlags(Flags.ParkingAllowedLeft, parkingLeft); m_flags = m_flags.SetFlags(Flags.ParkingAllowedRight, parkingRight); m_flags = m_flags.SetFlags(Flags.UniformSpeedLimit, uniformSpeed); m_flags = m_flags.SetFlags(Flags.LeftHandTraffic, NetUtil.LHT); TMPEHelpers.GetMaxSpeedLimit(SegmentID, out ForwardSpeedLimit, out BackwardSpeedLimit); Curve = CalculateCurve(); Start.UpdateFlags(); Start.UpdateDirections(); End.UpdateFlags(); End.UpdateDirections(); if (Log.VERBOSE) { Log.Debug($"NetSegmentExt.UpdateAllFlags() succeeded for {this}" /*Environment.StackTrace*/, false); } } catch (Exception ex) {