public void SetLightMode(ushort segmentId, bool startNode, ExtVehicleType vehicleType, LightMode mode) { ICustomSegmentLights liveLights = GetSegmentLights(segmentId, startNode); if (liveLights == null) { Log.Warning( $"CustomSegmentLightsManager.SetLightMode({segmentId}, {startNode}, " + $"{vehicleType}, {mode}): Could not retrieve segment lights."); return; } ICustomSegmentLight liveLight = liveLights.GetCustomLight(vehicleType); if (liveLight == null) { Log.Error( $"CustomSegmentLightsManager.SetLightMode: Cannot change light mode on seg. " + $"{segmentId} @ {startNode} for vehicle type {vehicleType} to {mode}: Vehicle light not found"); return; } liveLight.CurrentMode = mode; }
/// <summary> /// Configures traffic light for and for all lane types at input segmentId, nodeId, and step. /// </summary> /// <param name="step"></param> /// <param name="nodeId"></param> /// <param name="segmentId"></param> /// <param name="m">Determines which directions are green</param> private static void SetupHelper(ITimedTrafficLightsStep step, ushort nodeId, ushort segmentId, GreenDir m) { bool startNode = (bool)netService.IsStartNode(segmentId, nodeId); //get step data for side seg ICustomSegmentLights liveSegmentLights = customTrafficLightsManager.GetSegmentLights(segmentId, startNode); //for each lane type foreach (ExtVehicleType vehicleType in liveSegmentLights.VehicleTypes) { //set light mode ICustomSegmentLight liveSegmentLight = liveSegmentLights.GetCustomLight(vehicleType); liveSegmentLight.CurrentMode = LightMode.All; TimedLight(nodeId).ChangeLightMode( segmentId, vehicleType, liveSegmentLight.CurrentMode); // set light states var green = RoadBaseAI.TrafficLightState.Green; var red = RoadBaseAI.TrafficLightState.Red; switch (m) { case GreenDir.AllRed: liveSegmentLight.SetStates(red, red, red); break; case GreenDir.AllGreen: liveSegmentLight.SetStates(green, green, green); break; case GreenDir.ShortOnly: { // calculate directions ref ExtSegmentEnd segEnd = ref segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, nodeId)]; ref NetNode node = ref Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId]; segEndMan.CalculateOutgoingLeftStraightRightSegments(ref segEnd, ref node, out bool bLeft, out bool bForward, out bool bRight); bool bShort = RHT ? bRight : bLeft; bool bLong = RHT ? bLeft : bRight; if (bShort) { SetStates(liveSegmentLight, red, red, green); } else if (bLong) { // go forward instead of short SetStates(liveSegmentLight, green, red, red); } else { Debug.LogAssertion("Unreachable code."); liveSegmentLight.SetStates(green, green, green); } break; }
public override void OnToolGUI(Event e) { IExtSegmentManager segMan = Constants.ManagerFactory.ExtSegmentManager; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; var hoveredSegment = false; if (SelectedNodeId != 0) { CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance; TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; JunctionRestrictionsManager junctionRestrictionsManager = JunctionRestrictionsManager.Instance; if (!tlsMan.HasManualSimulation(SelectedNodeId)) { return; } tlsMan.TrafficLightSimulations[SelectedNodeId].Housekeeping(); // TODO check // if (Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode].CountSegments() == 2) { // _guiManualTrafficLightsCrosswalk( // ref Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode]); // return; // } NetNode[] nodesBuffer = Singleton <NetManager> .instance.m_nodes.m_buffer; NetSegment[] segmentsBuffer = Singleton <NetManager> .instance.m_segments.m_buffer; for (int i = 0; i < 8; ++i) { ushort segmentId = nodesBuffer[SelectedNodeId].GetSegment(i); if (segmentId == 0) { continue; } bool startNode = (bool)Constants.ServiceFactory.NetService.IsStartNode( segmentId, SelectedNodeId); Vector3 position = CalculateNodePositionForSegment( nodesBuffer[SelectedNodeId], ref segmentsBuffer[segmentId]); ICustomSegmentLights segmentLights = customTrafficLightsManager.GetSegmentLights(segmentId, startNode, false); if (segmentLights == null) { continue; } bool showPedLight = segmentLights.PedestrianLightState != null && junctionRestrictionsManager.IsPedestrianCrossingAllowed( segmentLights.SegmentId, segmentLights.StartNode); bool visible = MainTool.WorldToScreenPoint(position, out Vector3 screenPos); if (!visible) { continue; } Vector3 diff = position - Camera.main.transform.position; float zoom = 1.0f / diff.magnitude * 100f; // original / 2.5 float lightWidth = 41f * zoom; float lightHeight = 97f * zoom; float pedestrianWidth = 36f * zoom; float pedestrianHeight = 61f * zoom; // SWITCH MODE BUTTON float modeWidth = 41f * zoom; float modeHeight = 38f * zoom; Color guiColor = GUI.color; if (showPedLight) { // pedestrian light // SWITCH MANUAL PEDESTRIAN LIGHT BUTTON hoveredSegment = RenderManualPedestrianLightSwitch( zoom, segmentId, screenPos, lightWidth, segmentLights, hoveredSegment); // SWITCH PEDESTRIAN LIGHT guiColor.a = TrafficManagerTool.GetHandleAlpha( hoveredButton[0] == segmentId && hoveredButton[1] == 2 && segmentLights.ManualPedestrianMode); GUI.color = guiColor; var myRect3 = new Rect( screenPos.x - pedestrianWidth / 2 - lightWidth + 5f * zoom, screenPos.y - pedestrianHeight / 2 + 22f * zoom, pedestrianWidth, pedestrianHeight); switch (segmentLights.PedestrianLightState) { case RoadBaseAI.TrafficLightState.Green: { GUI.DrawTexture( myRect3, TrafficLightTextures.PedestrianGreenLight); break; } // also: case RoadBaseAI.TrafficLightState.Red: default: { GUI.DrawTexture( myRect3, TrafficLightTextures.PedestrianRedLight); break; } } hoveredSegment = IsPedestrianLightHovered( myRect3, segmentId, hoveredSegment, segmentLights); } int lightOffset = -1; foreach (ExtVehicleType vehicleType in segmentLights.VehicleTypes) { ++lightOffset; ICustomSegmentLight segmentLight = segmentLights.GetCustomLight(vehicleType); Vector3 offsetScreenPos = screenPos; offsetScreenPos.y -= (lightHeight + 10f * zoom) * lightOffset; SetAlpha(segmentId, -1); var myRect1 = new Rect( offsetScreenPos.x - modeWidth / 2, offsetScreenPos.y - modeHeight / 2 + modeHeight - 7f * zoom, modeWidth, modeHeight); GUI.DrawTexture(myRect1, TrafficLightTextures.LightMode); hoveredSegment = GetHoveredSegment( myRect1, segmentId, hoveredSegment, segmentLight); // COUNTER hoveredSegment = RenderCounter( segmentId, offsetScreenPos, modeWidth, modeHeight, zoom, segmentLights, hoveredSegment); if (vehicleType != ExtVehicleType.None) { // Info sign float infoWidth = 56.125f * zoom; float infoHeight = 51.375f * zoom; int numInfos = 0; for (int k = 0; k < TrafficManagerTool.InfoSignsToDisplay.Length; ++k) { if ((TrafficManagerTool.InfoSignsToDisplay[k] & vehicleType) == ExtVehicleType.None) { continue; } var infoRect = new Rect( offsetScreenPos.x + modeWidth / 2f + (7f * zoom * (float)(numInfos + 1)) + (infoWidth * (float)numInfos), offsetScreenPos.y - (infoHeight / 2f), infoWidth, infoHeight); guiColor.a = TrafficManagerTool.GetHandleAlpha(false); GUI.DrawTexture( infoRect, RoadUITextures.VehicleInfoSignTextures[TrafficManagerTool.InfoSignsToDisplay[k]]); ++numInfos; } } ExtSegment seg = segMan.ExtSegments[segmentId]; ExtSegmentEnd segEnd = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)]; if (seg.oneWay && segEnd.outgoing) { continue; } segEndMan.CalculateOutgoingLeftStraightRightSegments( ref segEnd, ref nodesBuffer[segmentId], out bool hasLeftSegment, out bool hasForwardSegment, out bool hasRightSegment); switch (segmentLight.CurrentMode) { case LightMode.Simple: { hoveredSegment = SimpleManualSegmentLightMode( segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); break; } case LightMode.SingleLeft: { hoveredSegment = LeftForwardRManualSegmentLightMode( hasLeftSegment, segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment, hasForwardSegment, hasRightSegment); break; } case LightMode.SingleRight: { hoveredSegment = RightForwardLSegmentLightMode( segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, hasForwardSegment, hasLeftSegment, segmentLight, hasRightSegment, hoveredSegment); break; } default: { // left arrow light if (hasLeftSegment) { hoveredSegment = LeftArrowLightMode( segmentId, lightWidth, hasRightSegment, hasForwardSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } // forward arrow light if (hasForwardSegment) { hoveredSegment = ForwardArrowLightMode( segmentId, lightWidth, hasRightSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } // right arrow light if (hasRightSegment) { hoveredSegment = RightArrowLightMode( segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } break; } } // end switch } // end foreach all vehicle type } // end for all 8 segments } // end if a node is selected if (hoveredSegment) { return; } hoveredButton[0] = 0; hoveredButton[1] = 0; }
// TODO this should be optimized protected void GetCustomTrafficLightState( #if DEBUG ushort vehicleId, ref Vehicle vehicleData, #endif ushort nodeId, ushort fromSegmentId, byte fromLaneIndex, ushort toSegmentId, out TrafficLightState vehicleLightState, out TrafficLightState pedestrianLightState, ref TrafficLightSimulation nodeSim) { // get responsible traffic light // Log._Debug($"GetTrafficLightState: Getting custom light for vehicle {vehicleId} @ // node {nodeId}, segment {fromSegmentId}, lane {fromLaneIndex}."); // SegmentGeometry geometry = SegmentGeometry.Get(fromSegmentId); // if (geometry == null) { // Log.Error($"GetTrafficLightState: No geometry information @ node {nodeId}, segment {fromSegmentId}."); // vehicleLightState = TrafficLightState.Green; // pedestrianLightState = TrafficLightState.Green; // return; // } // determine node position at `fromSegment` (start/end) // bool isStartNode = geometry.StartNodeId == nodeId; bool?isStartNode = Services.NetService.IsStartNode(fromSegmentId, nodeId); if (isStartNode == null) { Log.Error($"GetTrafficLightState: Invalid node {nodeId} for segment {fromSegmentId}."); vehicleLightState = TrafficLightState.Green; pedestrianLightState = TrafficLightState.Green; return; } ICustomSegmentLights lights = CustomSegmentLightsManager.Instance.GetSegmentLights( fromSegmentId, (bool)isStartNode, false); if (lights != null) { // get traffic lights state for pedestrians pedestrianLightState = lights.PedestrianLightState ?? TrafficLightState.Green; } else { pedestrianLightState = TrafficLightState.Green; Log._Debug($"GetTrafficLightState: No pedestrian light @ node {nodeId}, " + $"segment {fromSegmentId} found."); } ICustomSegmentLight light = lights == null ? null : lights.GetCustomLight(fromLaneIndex); if (lights == null || light == null) { // Log.Warning($"GetTrafficLightState: No custom light for vehicle {vehicleId} @ node // {nodeId}, segment {fromSegmentId}, lane {fromLaneIndex} found. lights null? // {lights == null} light null? {light == null}"); vehicleLightState = TrafficLightState.Green; return; } // get traffic light state from responsible traffic light vehicleLightState = light.GetLightState(toSegmentId); #if DEBUG // Log._Debug($"GetTrafficLightState: Getting light for vehicle {vehicleId} @ node {nodeId}, // segment {fromSegmentId}, lane {fromLaneIndex}. vehicleLightState={vehicleLightState}, // pedestrianLightState={pedestrianLightState}"); #endif }
private static void GetCustomTrafficLightState(ushort nodeId, ushort fromSegmentId, byte fromLaneIndex, ushort toSegmentId, out RoadBaseAI.TrafficLightState vehicleLightState, out RoadBaseAI.TrafficLightState pedestrianLightState, ref TrafficLightSimulation nodeSim) { SegmentGeometry segmentGeometry = SegmentGeometry.Get(fromSegmentId, false); if (segmentGeometry == null) { //Log.Error(string.Format("GetTrafficLightState: No geometry information @ node {0}, segment {1}.", nodeId, fromSegmentId)); vehicleLightState = RoadBaseAI.TrafficLightState.Green; pedestrianLightState = RoadBaseAI.TrafficLightState.Green; return; } bool startNode = segmentGeometry.StartNodeId() == nodeId; ICustomSegmentLights segmentLights = CustomSegmentLightsManager.Instance.GetSegmentLights(fromSegmentId, startNode, false, RoadBaseAI.TrafficLightState.Red); if (segmentLights != null) { pedestrianLightState = (segmentLights.PedestrianLightState.HasValue ? segmentLights.PedestrianLightState.Value : RoadBaseAI.TrafficLightState.Green); } else { pedestrianLightState = RoadBaseAI.TrafficLightState.Green; } ICustomSegmentLight customSegmentLight = (segmentLights == null) ? null : segmentLights.GetCustomLight(fromLaneIndex); if (segmentLights == null || customSegmentLight == null) { vehicleLightState = RoadBaseAI.TrafficLightState.Green; return; } if (toSegmentId == fromSegmentId) { vehicleLightState = (Constants.ServiceFactory.SimulationService.LeftHandDrive ? customSegmentLight.LightRight : customSegmentLight.LightLeft); return; } if (segmentGeometry.IsLeftSegment(toSegmentId, startNode)) { vehicleLightState = customSegmentLight.LightLeft; return; } if (segmentGeometry.IsRightSegment(toSegmentId, startNode)) { vehicleLightState = customSegmentLight.LightRight; return; } vehicleLightState = customSegmentLight.LightMain; }