private void ShowSigns(bool viewOnly) { NetManager netManager = Singleton <NetManager> .instance; SpeedLimitManager speedLimitManager = SpeedLimitManager.Instance; var currentCamera = new CameraTransformValue(Camera.main); Transform currentCameraTransform = Camera.main.transform; Vector3 camPos = currentCameraTransform.position; if (!LastCachedCamera.Equals(currentCamera)) { // cache visible segments LastCachedCamera = currentCamera; CachedVisibleSegmentIds.Clear(); const float MAX_DIST = TrafficManagerTool.MAX_OVERLAY_DISTANCE * TrafficManagerTool.MAX_OVERLAY_DISTANCE; for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; } // if ((netManager.m_segments.m_buffer[segmentId].m_flags & // NetSegment.Flags.Untouchable) != NetSegment.Flags.None) continue; Vector3 distToCamera = netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos; if (distToCamera.sqrMagnitude > MAX_DIST) { continue; // do not draw if too distant } bool visible = MainTool.WorldToScreenPoint( netManager.m_segments.m_buffer[segmentId].m_bounds.center, out Vector3 _); if (!visible) { continue; } if (!speedLimitManager.MayHaveCustomSpeedLimits( (ushort)segmentId, ref netManager.m_segments.m_buffer[segmentId])) { continue; } CachedVisibleSegmentIds.Add((ushort)segmentId); } // end for all segments } for (int segmentIdIndex = CachedVisibleSegmentIds.Size - 1; segmentIdIndex >= 0; segmentIdIndex--) { ushort segmentId = CachedVisibleSegmentIds.Values[segmentIdIndex]; // draw speed limits if ((MainTool.GetToolMode() == ToolMode.VehicleRestrictions) && (segmentId == SelectedSegmentId)) { continue; } // no speed limit overlay on selected segment when in vehicle restrictions mode DrawSpeedLimitHandles( segmentId, ref netManager.m_segments.m_buffer[segmentId], viewOnly, ref camPos); } }
private bool DrawVehicleRestrictionHandles(ushort segmentId, ref NetSegment segment, bool viewOnly, out bool stateUpdated) { stateUpdated = false; if (viewOnly && !Options.vehicleRestrictionsOverlay && MainTool.GetToolMode() != ToolMode.VehicleRestrictions) { return(false); } Vector3 center = segment.m_bounds.center; bool visible = GeometryUtil.WorldToScreenPoint(center, out Vector3 _); if (!visible) { return(false); } Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; Vector3 diff = center - camPos; if (diff.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { return(false); // do not draw if too distant } int numLanes = GeometryUtil.GetSegmentNumVehicleLanes( segmentId, null, out int numDirections, VehicleRestrictionsManager.VEHICLE_TYPES); // draw vehicle restrictions over each lane NetInfo segmentInfo = segment.Info; Vector3 yu = (segment.m_endDirection - segment.m_startDirection).normalized; // if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) // yu = -yu; Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; float f = viewOnly ? 4f : 7f; // reserved sign size in game coordinates int maxNumSigns = 0; if (VehicleRestrictionsManager.Instance.IsRoadSegment(segmentInfo)) { maxNumSigns = RoadVehicleTypes.Length; } else if (VehicleRestrictionsManager.Instance.IsRailSegment(segmentInfo)) { maxNumSigns = RailVehicleTypes.Length; } // Vector3 zero = center - 0.5f * (float)(numLanes + numDirections - 1) * f * (xu + yu); // "bottom left" Vector3 zero = center - (0.5f * (numLanes - 1 + numDirections - 1) * f * xu) - (0.5f * maxNumSigns * f * yu); // "bottom left" // if (!viewOnly) // Log._Debug($"xu: {xu.ToString()} yu: {yu.ToString()} center: {center.ToString()} // zero: {zero.ToString()} numLanes: {numLanes} numDirections: {numDirections}");*/ uint x = 0; Color guiColor = GUI.color; IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes( segmentId, ref segment, null, VehicleRestrictionsManager.LANE_TYPES, VehicleRestrictionsManager.VEHICLE_TYPES); bool hovered = false; HashSet <NetInfo.Direction> directions = new HashSet <NetInfo.Direction>(); int sortedLaneIndex = -1; foreach (LanePos laneData in sortedLanes) { ++sortedLaneIndex; uint laneId = laneData.laneId; byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if (!directions.Contains(laneInfo.m_finalDirection)) { if (directions.Count > 0) { ++x; // space between different directions } directions.Add(laneInfo.m_finalDirection); } ExtVehicleType[] possibleVehicleTypes; if (VehicleRestrictionsManager.Instance.IsRoadLane(laneInfo)) { possibleVehicleTypes = RoadVehicleTypes; } else if (VehicleRestrictionsManager.Instance.IsRailLane(laneInfo)) { possibleVehicleTypes = RailVehicleTypes; } else { ++x; continue; } ExtVehicleType allowedTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes( segmentId, segmentInfo, laneIndex, laneInfo, VehicleRestrictionsMode.Configured); uint y = 0; #if DEBUG_disabled_xxx Vector3 labelCenter = zero + f * (float)x * xu + f * (float)y * yu; // in game coordinates Vector3 labelScreenPos; bool visible = GeometryUtil.WorldToScreenPoint(labelCenter, out labelScreenPos); // BUGBUG: Using screen.height might be wrong, consider U.UIScaler.ScreenHeight (from UIView.fixedHeight) labelScreenPos.y = Screen.height - labelScreenPos.y; diff = labelCenter - camPos; var labelZoom = 1.0f / diff.magnitude * 100f; _counterStyle.fontSize = (int)(11f * labelZoom); _counterStyle.normal.textColor = new Color(1f, 1f, 0f); string labelStr = $"Idx {laneIndex}"; Vector2 dim = _counterStyle.CalcSize(new GUIContent(labelStr)); Rect labelRect = new Rect(labelScreenPos.x - dim.x / 2f, labelScreenPos.y, dim.x, dim.y); GUI.Label(labelRect, labelStr, _counterStyle); ++y; #endif Color guiColor2 = GUI.color; GUI.color = GUI.color.WithAlpha(TrafficManagerTool.OverlayAlpha); foreach (ExtVehicleType vehicleType in possibleVehicleTypes) { bool allowed = VehicleRestrictionsManager.Instance.IsAllowed(allowedTypes, vehicleType); if (allowed && viewOnly) { continue; // do not draw allowed vehicles in view-only mode } bool hoveredHandle = MainTool.DrawGenericSquareOverlayGridTexture( RoadUI.VehicleRestrictionTextures[vehicleType][allowed], camPos, zero, f, xu, yu, x, y, vehicleRestrictionsSignSize, !viewOnly); if (hoveredHandle) { hovered = true; renderData_.segmentId = segmentId; renderData_.laneId = laneId; renderData_.laneIndex = laneIndex; renderData_.laneInfo = laneInfo; renderData_.SortedLaneIndex = sortedLaneIndex; } if (hoveredHandle && MainTool.CheckClicked()) { // toggle vehicle restrictions // Log._Debug($"Setting vehicle restrictions of segment {segmentId}, lane // idx {laneIndex}, {vehicleType.ToString()} to {!allowed}"); VehicleRestrictionsManager.Instance.ToggleAllowedType( segmentId, segmentInfo, laneIndex, laneId, laneInfo, vehicleType, !allowed); stateUpdated = true; RefreshCurrentRestrictedSegmentIds(segmentId); if (RoadMode) { ApplyRestrictionsToAllSegments(sortedLaneIndex, vehicleType); } } ++y; } GUI.color = guiColor2; ++x; } guiColor.a = 1f; GUI.color = guiColor; return(hovered); }
private void ShowSigns(bool viewOnly) { NetManager netManager = Singleton <NetManager> .instance; var currentCamera = new CameraTransformValue(InGameUtil.Instance.CachedMainCamera); Transform currentCameraTransform = InGameUtil.Instance.CachedCameraTransform; Vector3 camPos = currentCameraTransform.position; if (!LastCachedCamera.Equals(currentCamera)) { // cache visible segments LastCachedCamera = currentCamera; CachedVisibleSegmentIds.Clear(); for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; } // if ((netManager.m_segments.m_buffer[segmentId].m_flags // & NetSegment.Flags.Untouchable) != NetSegment.Flags.None) // continue; Vector3 distToCamera = netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos; if (distToCamera.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { continue; // do not draw if too distant } bool visible = GeometryUtil.WorldToScreenPoint( netManager.m_segments.m_buffer[segmentId].m_bounds.center, out Vector3 _); if (!visible) { continue; } if (!parkingManager.MayHaveParkingRestriction((ushort)segmentId)) { continue; } CachedVisibleSegmentIds.Add((ushort)segmentId); } // end for all segments } bool hovered = false; bool clicked = !viewOnly && MainTool.CheckClicked(); for (int segmentIdIndex = CachedVisibleSegmentIds.Size - 1; segmentIdIndex >= 0; segmentIdIndex--) { ushort segmentId = CachedVisibleSegmentIds.Values[segmentIdIndex]; // draw parking restrictions if ((MainTool.GetToolMode() == ToolMode.SpeedLimits) || ((MainTool.GetToolMode() == ToolMode.VehicleRestrictions) && (segmentId == SelectedSegmentId))) { continue; } // no parking restrictions overlay on selected segment when in vehicle restrictions mode var dir = DrawParkingRestrictionHandles( segmentId, clicked, ref netManager.m_segments.m_buffer[segmentId], viewOnly, ref camPos); if (dir != NetInfo.Direction.None) { renderInfo_.SegmentId = segmentId; renderInfo_.FinalDirection = dir; hovered = true; } } if (!hovered) { renderInfo_.SegmentId = 0; renderInfo_.FinalDirection = NetInfo.Direction.None; } }
private bool drawSignHandles(ushort nodeId, bool viewOnly, bool handleClick, ref Vector3 camPos, out bool stateUpdated) { bool hovered = false; stateUpdated = false; if (viewOnly && !Options.junctionRestrictionsOverlay && MainTool.GetToolMode() != ToolMode.JunctionRestrictions) { return(false); } NetManager netManager = Singleton <NetManager> .instance; var guiColor = GUI.color; Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position; for (int i = 0; i < 8; ++i) { ushort segmentId = netManager.m_nodes.m_buffer[nodeId].GetSegment(i); if (segmentId == 0) { continue; } SegmentGeometry geometry = SegmentGeometry.Get(segmentId); if (geometry == null) { Log.Error($"JunctionRestrictionsTool.drawSignHandles: No geometry information available for segment {segmentId}"); continue; } bool startNode = geometry.StartNodeId() == nodeId; bool incoming = geometry.IsIncoming(startNode); int numSignsPerRow = incoming ? 2 : 1; NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info; ItemClass connectionClass = segmentInfo.GetConnectionClass(); if (connectionClass.m_service != ItemClass.Service.Road) { continue; // only for road junctions } // draw all junction restriction signs Vector3 segmentCenterPos = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_bounds.center; Vector3 yu = (segmentCenterPos - nodePos).normalized; Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; float f = viewOnly ? 6f : 7f; // reserved sign size in game coordinates Vector3 centerStart = nodePos + yu * (viewOnly ? 5f : 14f); Vector3 zero = centerStart - 0.5f * (float)(numSignsPerRow - 1) * f * xu; // "top left" if (viewOnly) { if (Constants.ServiceFactory.SimulationService.LeftHandDrive) { zero -= xu * 8f; } else { zero += xu * 8f; } } bool signHovered; int x = 0; int y = 0; // draw "lane-changing when going straight allowed" sign at (0; 0) bool allowed = JunctionRestrictionsManager.Instance.IsLaneChangingAllowedWhenGoingStraight(segmentId, startNode); if (incoming && (!viewOnly || allowed != Options.allowLaneChangesWhileGoingStraight)) { DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.LaneChangeAllowedTexture2D : TextureResources.LaneChangeForbiddenTexture2D, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager.Instance.ToggleLaneChangingAllowedWhenGoingStraight(segmentId, startNode); stateUpdated = true; } } if (viewOnly) { ++y; } else { ++x; } } // draw "u-turns allowed" sign at (1; 0) allowed = JunctionRestrictionsManager.Instance.IsUturnAllowed(segmentId, startNode); if (incoming && (!viewOnly || allowed != Options.allowUTurns)) { DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.UturnAllowedTexture2D : TextureResources.UturnForbiddenTexture2D, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { if (!JunctionRestrictionsManager.Instance.ToggleUturnAllowed(segmentId, startNode)) { // TODO MainTool.ShowTooltip(Translation.GetString("..."), Singleton<NetManager>.instance.m_nodes.m_buffer[nodeId].m_position); } else { stateUpdated = true; } } } ++y; x = 0; } // draw "entering blocked junctions allowed" sign at (0; 1) allowed = JunctionRestrictionsManager.Instance.IsEnteringBlockedJunctionAllowed(segmentId, startNode); if (incoming && (!viewOnly || allowed != Options.allowEnterBlockedJunctions)) { DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.EnterBlockedJunctionAllowedTexture2D : TextureResources.EnterBlockedJunctionForbiddenTexture2D, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager.Instance.ToggleEnteringBlockedJunctionAllowed(segmentId, startNode); stateUpdated = true; } } if (viewOnly) { ++y; } else { ++x; } } // draw "pedestrian crossing allowed" sign at (1; 1) allowed = JunctionRestrictionsManager.Instance.IsPedestrianCrossingAllowed(segmentId, startNode); if (!viewOnly || !allowed) { DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TextureResources.PedestrianCrossingAllowedTexture2D : TextureResources.PedestrianCrossingForbiddenTexture2D, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager.Instance.TogglePedestrianCrossingAllowed(segmentId, startNode); stateUpdated = true; } } } } guiColor.a = 1f; GUI.color = guiColor; return(hovered); }
private void ShowSigns(bool viewOnly) { Quaternion camRot = Camera.main.transform.rotation; Vector3 camPos = Camera.main.transform.position; NetManager netManager = Singleton <NetManager> .instance; ParkingRestrictionsManager parkingManager = ParkingRestrictionsManager.Instance; if (lastCamPos == null || lastCamRot == null || !lastCamRot.Equals(camRot) || !lastCamPos.Equals(camPos)) { // cache visible segments currentlyVisibleSegmentIds.Clear(); for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; } /*if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None) * continue;*/ if ((netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos).magnitude > TrafficManagerTool.MaxOverlayDistance) { continue; // do not draw if too distant } Vector3 screenPos; bool visible = MainTool.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center, out screenPos); if (!visible) { continue; } if (!parkingManager.MayHaveParkingRestriction((ushort)segmentId)) { continue; } currentlyVisibleSegmentIds.Add((ushort)segmentId); } lastCamPos = camPos; lastCamRot = camRot; } bool handleHovered = false; bool clicked = !viewOnly && MainTool.CheckClicked(); foreach (ushort segmentId in currentlyVisibleSegmentIds) { Vector3 screenPos; bool visible = MainTool.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center, out screenPos); if (!visible) { continue; } NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info; // draw parking restrictions if (MainTool.GetToolMode() != ToolMode.SpeedLimits && (MainTool.GetToolMode() != ToolMode.VehicleRestrictions || segmentId != SelectedSegmentId)) // no parking restrictions overlay on selected segment when in vehicle restrictions mode { if (drawParkingRestrictionHandles((ushort)segmentId, clicked, ref netManager.m_segments.m_buffer[segmentId], viewOnly, ref camPos)) { handleHovered = true; } } } overlayHandleHovered = handleHovered; }
private bool drawSignHandles(bool debug, ushort nodeId, ref NetNode node, bool viewOnly, bool handleClick, ref Vector3 camPos, out bool stateUpdated) { bool hovered = false; stateUpdated = false; if (viewOnly && !(Options.junctionRestrictionsOverlay || PrioritySignsTool.showMassEditOverlay) && (MainTool.GetToolMode() != ToolMode.JunctionRestrictions)) { return(false); } // NetManager netManager = Singleton<NetManager>.instance; Color guiColor = GUI.color; Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; for (int i = 0; i < 8; ++i) { ushort segmentId = node.GetSegment(i); if (segmentId == 0) { continue; } bool startNode = (bool)Constants.ServiceFactory.NetService.IsStartNode(segmentId, nodeId); bool incoming = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)].incoming; int numSignsPerRow = incoming ? 2 : 1; NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info; ItemClass connectionClass = segmentInfo.GetConnectionClass(); if (connectionClass.m_service != ItemClass.Service.Road) { continue; // only for road junctions } // draw all junction restriction signs Vector3 segmentCenterPos = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId] .m_bounds.center; Vector3 yu = (segmentCenterPos - nodePos).normalized; Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; float f = viewOnly ? 6f : 7f; // reserved sign size in game coordinates Vector3 centerStart = nodePos + (yu * (viewOnly ? 5f : 14f)); Vector3 zero = centerStart - (0.5f * (numSignsPerRow - 1) * f * xu); // "top left" if (viewOnly) { if (Constants.ServiceFactory.SimulationService.TrafficDrivesOnLeft) { zero -= xu * 8f; } else { zero += xu * 8f; } } bool signHovered; int x = 0; int y = 0; bool hasSignInPrevRow = false; // draw "lane-changing when going straight allowed" sign at (0; 0) bool allowed = JunctionRestrictionsManager.Instance.IsLaneChangingAllowedWhenGoingStraight( segmentId, startNode); bool configurable = Constants.ManagerFactory.JunctionRestrictionsManager .IsLaneChangingAllowedWhenGoingStraightConfigurable( segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || (allowed != Constants.ManagerFactory .JunctionRestrictionsManager .GetDefaultLaneChangingAllowedWhenGoingStraight( segmentId, startNode, ref node))))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.LaneChangeAllowed : JunctionRestrictions.LaneChangeForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager.Instance.ToggleLaneChangingAllowedWhenGoingStraight( segmentId, startNode); stateUpdated = true; } } ++x; hasSignInPrevRow = true; } // draw "u-turns allowed" sign at (1; 0) allowed = JunctionRestrictionsManager.Instance.IsUturnAllowed(segmentId, startNode); configurable = Constants.ManagerFactory.JunctionRestrictionsManager.IsUturnAllowedConfigurable( segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || (allowed != Constants.ManagerFactory .JunctionRestrictionsManager .GetDefaultUturnAllowed( segmentId, startNode, ref node))))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.UturnAllowed : JunctionRestrictions.UturnForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { if (!JunctionRestrictionsManager.Instance.ToggleUturnAllowed( segmentId, startNode)) { // TODO MainTool.ShowTooltip(Translation.GetString("..."), Singleton<NetManager>.instance.m_nodes.m_buffer[nodeId].m_position); } else { stateUpdated = true; } } } x++; hasSignInPrevRow = true; } x = 0; if (hasSignInPrevRow) { ++y; hasSignInPrevRow = false; } // draw "entering blocked junctions allowed" sign at (0; 1) allowed = JunctionRestrictionsManager.Instance.IsEnteringBlockedJunctionAllowed( segmentId, startNode); configurable = Constants.ManagerFactory.JunctionRestrictionsManager .IsEnteringBlockedJunctionAllowedConfigurable( segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || (allowed != Constants.ManagerFactory .JunctionRestrictionsManager .GetDefaultEnteringBlockedJunctionAllowed( segmentId, startNode, ref node))))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.EnterBlockedJunctionAllowed : JunctionRestrictions.EnterBlockedJunctionForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager .Instance .ToggleEnteringBlockedJunctionAllowed(segmentId, startNode); stateUpdated = true; } } ++x; hasSignInPrevRow = true; } // draw "pedestrian crossing allowed" sign at (1; 1) allowed = JunctionRestrictionsManager.Instance.IsPedestrianCrossingAllowed( segmentId, startNode); configurable = Constants.ManagerFactory.JunctionRestrictionsManager .IsPedestrianCrossingAllowedConfigurable( segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || !allowed))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.PedestrianCrossingAllowed : JunctionRestrictions.PedestrianCrossingForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { JunctionRestrictionsManager.Instance.TogglePedestrianCrossingAllowed(segmentId, startNode); stateUpdated = true; } } x++; hasSignInPrevRow = true; } x = 0; if (hasSignInPrevRow) { ++y; hasSignInPrevRow = false; } if (!Options.turnOnRedEnabled) { continue; } //-------------------------------- // TURN ON RED ENABLED //-------------------------------- IJunctionRestrictionsManager junctionRestrictionsManager = Constants.ManagerFactory.JunctionRestrictionsManager; bool lht = Constants.ServiceFactory.SimulationService.TrafficDrivesOnLeft; // draw "turn-left-on-red allowed" sign at (2; 0) allowed = junctionRestrictionsManager.IsTurnOnRedAllowed(lht, segmentId, startNode); configurable = junctionRestrictionsManager.IsTurnOnRedAllowedConfigurable( lht, segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || (allowed != junctionRestrictionsManager .GetDefaultTurnOnRedAllowed( lht, segmentId, startNode, ref node))))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.LeftOnRedAllowed : JunctionRestrictions.LeftOnRedForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { junctionRestrictionsManager.ToggleTurnOnRedAllowed( lht, segmentId, startNode); stateUpdated = true; } } hasSignInPrevRow = true; } x++; // draw "turn-right-on-red allowed" sign at (2; 1) allowed = junctionRestrictionsManager.IsTurnOnRedAllowed( !lht, segmentId, startNode); configurable = junctionRestrictionsManager.IsTurnOnRedAllowedConfigurable( !lht, segmentId, startNode, ref node); if (debug || (configurable && (!viewOnly || (allowed != junctionRestrictionsManager .GetDefaultTurnOnRedAllowed( !lht, segmentId, startNode, ref node))))) { DrawSign( viewOnly, !configurable, ref camPos, ref xu, ref yu, f, ref zero, x, y, guiColor, allowed ? JunctionRestrictions.RightOnRedAllowed : JunctionRestrictions.RightOnRedForbidden, out signHovered); if (signHovered && handleClick) { hovered = true; if (MainTool.CheckClicked()) { junctionRestrictionsManager.ToggleTurnOnRedAllowed( !lht, segmentId, startNode); stateUpdated = true; } } hasSignInPrevRow = true; } } guiColor.a = 1f; GUI.color = guiColor; return(hovered); }
private bool drawVehicleRestrictionHandles(ushort segmentId, ref NetSegment segment, bool viewOnly, out bool stateUpdated) { stateUpdated = false; if (viewOnly && !Options.vehicleRestrictionsOverlay && MainTool.GetToolMode() != ToolMode.VehicleRestrictions) { return(false); } Vector3 center = segment.m_bounds.center; var screenPos = Camera.main.WorldToScreenPoint(center); screenPos.y = Screen.height - screenPos.y; if (screenPos.z < 0) { return(false); } var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; var diff = center - camPos; if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance) { return(false); // do not draw if too distant } int numDirections; int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes(segmentId, null, out numDirections, VehicleRestrictionsManager.VEHICLE_TYPES); // draw vehicle restrictions over each lane NetInfo segmentInfo = segment.Info; Vector3 yu = (segment.m_endDirection - segment.m_startDirection).normalized; /*if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) * yu = -yu;*/ Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; float f = viewOnly ? 4f : 7f; // reserved sign size in game coordinates int maxNumSigns = 0; if (VehicleRestrictionsManager.Instance.IsRoadSegment(segmentInfo)) { maxNumSigns = roadVehicleTypes.Length; } else if (VehicleRestrictionsManager.Instance.IsRailSegment(segmentInfo)) { maxNumSigns = railVehicleTypes.Length; } //Vector3 zero = center - 0.5f * (float)(numLanes + numDirections - 1) * f * (xu + yu); // "bottom left" Vector3 zero = center - 0.5f * (float)(numLanes - 1 + numDirections - 1) * f * xu - 0.5f * (float)maxNumSigns * f * yu; // "bottom left" /*if (!viewOnly) * Log._Debug($"xu: {xu.ToString()} yu: {yu.ToString()} center: {center.ToString()} zero: {zero.ToString()} numLanes: {numLanes} numDirections: {numDirections}");*/ uint x = 0; var guiColor = GUI.color; IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes(segmentId, ref segment, null, VehicleRestrictionsManager.LANE_TYPES, VehicleRestrictionsManager.VEHICLE_TYPES); bool hovered = false; HashSet <NetInfo.Direction> directions = new HashSet <NetInfo.Direction>(); int sortedLaneIndex = -1; foreach (LanePos laneData in sortedLanes) { ++sortedLaneIndex; uint laneId = laneData.laneId; byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if (!directions.Contains(laneInfo.m_finalDirection)) { if (directions.Count > 0) { ++x; // space between different directions } directions.Add(laneInfo.m_finalDirection); } ExtVehicleType[] possibleVehicleTypes = null; if (VehicleRestrictionsManager.Instance.IsRoadLane(laneInfo)) { possibleVehicleTypes = roadVehicleTypes; } else if (VehicleRestrictionsManager.Instance.IsRailLane(laneInfo)) { possibleVehicleTypes = railVehicleTypes; } else { ++x; continue; } ExtVehicleType allowedTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo, VehicleRestrictionsMode.Configured); uint y = 0; #if DEBUGx Vector3 labelCenter = zero + f * (float)x * xu + f * (float)y * yu; // in game coordinates var labelScreenPos = Camera.main.WorldToScreenPoint(labelCenter); labelScreenPos.y = Screen.height - labelScreenPos.y; diff = labelCenter - camPos; var labelZoom = 1.0f / diff.magnitude * 100f; _counterStyle.fontSize = (int)(11f * labelZoom); _counterStyle.normal.textColor = new Color(1f, 1f, 0f); string labelStr = $"Idx {laneIndex}"; Vector2 dim = _counterStyle.CalcSize(new GUIContent(labelStr)); Rect labelRect = new Rect(labelScreenPos.x - dim.x / 2f, labelScreenPos.y, dim.x, dim.y); GUI.Label(labelRect, labelStr, _counterStyle); ++y; #endif foreach (ExtVehicleType vehicleType in possibleVehicleTypes) { bool allowed = VehicleRestrictionsManager.Instance.IsAllowed(allowedTypes, vehicleType); if (allowed && viewOnly) { continue; // do not draw allowed vehicles in view-only mode } bool hoveredHandle = MainTool.DrawGenericSquareOverlayGridTexture(TextureResources.VehicleRestrictionTextures[vehicleType][allowed], ref camPos, ref zero, f, ref xu, ref yu, x, y, vehicleRestrictionsSignSize, !viewOnly, 0.5f, 0.8f); if (hoveredHandle) { hovered = true; } if (hoveredHandle && MainTool.CheckClicked()) { // toggle vehicle restrictions //Log._Debug($"Setting vehicle restrictions of segment {segmentId}, lane idx {laneIndex}, {vehicleType.ToString()} to {!allowed}"); VehicleRestrictionsManager.Instance.ToggleAllowedType(segmentId, segmentInfo, laneIndex, laneId, laneInfo, vehicleType, !allowed); stateUpdated = true; if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { ApplyRestrictionsToAllSegments(sortedLaneIndex); } } ++y; } ++x; } guiColor.a = 1f; GUI.color = guiColor; return(hovered); }
private void ShowSigns(bool viewOnly) { Quaternion camRot = Camera.main.transform.rotation; Vector3 camPos = Camera.main.transform.position; NetManager netManager = Singleton <NetManager> .instance; SpeedLimitManager speedLimitManager = SpeedLimitManager.Instance; if (lastCamPos == null || lastCamRot == null || !lastCamRot.Equals(camRot) || !lastCamPos.Equals(camPos)) { // cache visible segments currentlyVisibleSegmentIds.Clear(); for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { if (!Constants.ServiceFactory.NetService.IsSegmentValid((ushort)segmentId)) { continue; } // if ((netManager.m_segments.m_buffer[segmentId].m_flags & // NetSegment.Flags.Untouchable) != NetSegment.Flags.None) continue; if ((netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos) .magnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE) { continue; // do not draw if too distant } bool visible = MainTool.WorldToScreenPoint( netManager.m_segments.m_buffer[segmentId].m_bounds.center, out Vector3 _); if (!visible) { continue; } if (!speedLimitManager.MayHaveCustomSpeedLimits( (ushort)segmentId, ref netManager.m_segments.m_buffer[segmentId])) { continue; } currentlyVisibleSegmentIds.Add((ushort)segmentId); } // end for all segments lastCamPos = camPos; lastCamRot = camRot; } bool handleHovered = false; foreach (ushort segmentId in currentlyVisibleSegmentIds) { bool visible = MainTool.WorldToScreenPoint( netManager.m_segments.m_buffer[segmentId].m_bounds.center, out Vector3 _); if (!visible) { continue; } // draw speed limits if (MainTool.GetToolMode() == ToolMode.VehicleRestrictions && segmentId == SelectedSegmentId) { continue; } // no speed limit overlay on selected segment when in vehicle restrictions mode drawSpeedLimitHandles( segmentId, ref netManager.m_segments.m_buffer[segmentId], viewOnly, ref camPos); } }