public override void OnToolGUI(Event e) { var hoveredSegment = false; if (SelectedNodeId != 0) { CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance; TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; if (!tlsMan.HasManualSimulation(SelectedNodeId)) { return; } tlsMan.TrafficLightSimulations[SelectedNodeId].Housekeeping(); /*if (Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode].CountSegments() == 2) { * _guiManualTrafficLightsCrosswalk(ref Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode]); * return; * }*/// TODO check NodeGeometry nodeGeometry = NodeGeometry.Get(SelectedNodeId); foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries) { if (end == null) { continue; } var position = CalculateNodePositionForSegment(Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId], ref Singleton <NetManager> .instance.m_segments.m_buffer[end.SegmentId]); var segmentLights = customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode, false); if (segmentLights == null) { continue; } var screenPos = Camera.main.WorldToScreenPoint(position); screenPos.y = Screen.height - screenPos.y; if (screenPos.z < 0) { continue; } var diff = position - Camera.main.transform.position; var zoom = 1.0f / diff.magnitude * 100f; // original / 2.5 var lightWidth = 41f * zoom; var lightHeight = 97f * zoom; var pedestrianWidth = 36f * zoom; var pedestrianHeight = 61f * zoom; // SWITCH MODE BUTTON var modeWidth = 41f * zoom; var modeHeight = 38f * zoom; var guiColor = GUI.color; if (segmentLights.PedestrianLightState != null) { // pedestrian light // SWITCH MANUAL PEDESTRIAN LIGHT BUTTON hoveredSegment = RenderManualPedestrianLightSwitch(zoom, end.SegmentId, screenPos, lightWidth, segmentLights, hoveredSegment); // SWITCH PEDESTRIAN LIGHT guiColor.a = _hoveredButton[0] == end.SegmentId && _hoveredButton[1] == 2 && segmentLights.ManualPedestrianMode ? 0.92f : 0.6f; 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, TextureResources.PedestrianGreenLightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: default: GUI.DrawTexture(myRect3, TextureResources.PedestrianRedLightTexture2D); break; } hoveredSegment = IsPedestrianLightHovered(myRect3, end.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(end.SegmentId, -1); var myRect1 = new Rect(offsetScreenPos.x - modeWidth / 2, offsetScreenPos.y - modeHeight / 2 + modeHeight - 7f * zoom, modeWidth, modeHeight); GUI.DrawTexture(myRect1, TextureResources.LightModeTexture2D); hoveredSegment = GetHoveredSegment(myRect1, end.SegmentId, hoveredSegment, segmentLight); // COUNTER hoveredSegment = RenderCounter(end.SegmentId, offsetScreenPos, modeWidth, modeHeight, zoom, segmentLights, hoveredSegment); if (vehicleType != ExtVehicleType.None) { // Info sign var infoWidth = 56.125f * zoom; var 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 = 0.6f; GUI.DrawTexture(infoRect, TextureResources.VehicleInfoSignTextures[TrafficManagerTool.InfoSignsToDisplay[k]]); ++numInfos; } } if (end.OutgoingOneWay) { continue; } var hasLeftSegment = end.NumLeftSegments > 0; var hasForwardSegment = end.NumStraightSegments > 0; var hasRightSegment = end.NumRightSegments > 0; switch (segmentLight.CurrentMode) { case LightMode.Simple: hoveredSegment = SimpleManualSegmentLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); break; case LightMode.SingleLeft: hoveredSegment = LeftForwardRManualSegmentLightMode(hasLeftSegment, end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment, hasForwardSegment, hasRightSegment); break; case LightMode.SingleRight: hoveredSegment = RightForwardLSegmentLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, hasForwardSegment, hasLeftSegment, segmentLight, hasRightSegment, hoveredSegment); break; default: // left arrow light if (hasLeftSegment) { hoveredSegment = LeftArrowLightMode(end.SegmentId, lightWidth, hasRightSegment, hasForwardSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } // forward arrow light if (hasForwardSegment) { hoveredSegment = ForwardArrowLightMode(end.SegmentId, lightWidth, hasRightSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } // right arrow light if (hasRightSegment) { hoveredSegment = RightArrowLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment); } break; } } } } if (hoveredSegment) { return; } _hoveredButton[0] = 0; _hoveredButton[1] = 0; }
private bool RightForwardLSegmentLightMode(int segmentId, Vector3 screenPos, float lightWidth, float pedestrianWidth, float zoom, float lightHeight, bool hasForwardSegment, bool hasLeftSegment, ICustomSegmentLight segmentDict, bool hasRightSegment, bool hoveredSegment) { SetAlpha(segmentId, 3); var myRect4 = new Rect(screenPos.x - lightWidth / 2 - lightWidth * 2 - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); if (hasForwardSegment && hasLeftSegment) { switch (segmentDict.LightLeft) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect4, TextureResources.GreenLightForwardLeftTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect4, TextureResources.RedLightForwardLeftTexture2D); break; } } else if (!hasLeftSegment) { if (!hasRightSegment) { myRect4 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); } switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect4, TextureResources.GreenLightStraightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect4, TextureResources.RedLightStraightTexture2D); break; } } else { if (!hasRightSegment) { myRect4 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); } switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect4, TextureResources.GreenLightLeftTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect4, TextureResources.RedLightLeftTexture2D); break; } } if (myRect4.Contains(Event.current.mousePosition)) { _hoveredButton[0] = segmentId; _hoveredButton[1] = 3; hoveredSegment = true; if (MainTool.CheckClicked()) { segmentDict.ChangeMainLight(); } } var guiColor = GUI.color; // right arrow light if (hasRightSegment) { guiColor.a = _hoveredButton[0] == segmentId && _hoveredButton[1] == 4 ? 0.92f : 0.6f; } GUI.color = guiColor; var myRect5 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); switch (segmentDict.LightRight) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TextureResources.GreenLightRightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TextureResources.RedLightRightTexture2D); break; } if (!myRect5.Contains(Event.current.mousePosition)) { return(hoveredSegment); } _hoveredButton[0] = segmentId; _hoveredButton[1] = 4; if (!MainTool.CheckClicked()) { return(true); } segmentDict.ChangeRightLight(); return(true); }
private bool RightArrowLightMode(int segmentId, Vector3 screenPos, float lightWidth, float pedestrianWidth, float zoom, float lightHeight, ICustomSegmentLight segmentDict, bool hoveredSegment) { SetAlpha(segmentId, 5); var myRect5 = new Rect(screenPos.x - lightWidth / 2 - lightWidth - pedestrianWidth + 5f * zoom, screenPos.y - lightHeight / 2, lightWidth, lightHeight); switch (segmentDict.LightRight) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect5, TextureResources.GreenLightRightTexture2D); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect5, TextureResources.RedLightRightTexture2D); break; } if (!myRect5.Contains(Event.current.mousePosition)) { return(hoveredSegment); } _hoveredButton[0] = segmentId; _hoveredButton[1] = 5; if (!MainTool.CheckClicked()) { return(true); } segmentDict.ChangeRightLight(); return(true); }
public List <Configuration.TimedTrafficLights> SaveData(ref bool success) { var ret = new List <Configuration.TimedTrafficLights>(); for (uint nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { try { if (!TrafficLightSimulations[nodeId].IsTimedLight()) { continue; } #if DEBUGSAVE Log._Debug($"Going to save timed light at node {nodeId}."); #endif ITimedTrafficLights timedNode = TrafficLightSimulations[nodeId].timedLight; timedNode.OnGeometryUpdate(); var cnfTimedLights = new Configuration.TimedTrafficLights { nodeId = timedNode.NodeId, nodeGroup = new List <ushort>(timedNode.NodeGroup), started = timedNode.IsStarted() }; ret.Add(cnfTimedLights); int stepIndex = timedNode.CurrentStep; if (timedNode.IsStarted() && timedNode.GetStep(timedNode.CurrentStep).IsInEndTransition()) { // if in end transition save the next step stepIndex = (stepIndex + 1) % timedNode.NumSteps(); } cnfTimedLights.currentStep = stepIndex; cnfTimedLights.timedSteps = new List <Configuration.TimedTrafficLightsStep>(); for (var j = 0; j < timedNode.NumSteps(); j++) { #if DEBUGSAVE Log._Debug($"Saving timed light step {j} at node {nodeId}."); #endif ITimedTrafficLightsStep timedStep = timedNode.GetStep(j); var cnfTimedStep = new Configuration.TimedTrafficLightsStep { minTime = timedStep.MinTime, maxTime = timedStep.MaxTime, changeMetric = (int)timedStep.ChangeMetric, waitFlowBalance = timedStep.WaitFlowBalance, segmentLights = new Dictionary <ushort, Configuration.CustomSegmentLights>() }; cnfTimedLights.timedSteps.Add(cnfTimedStep); foreach (KeyValuePair <ushort, ICustomSegmentLights> e in timedStep.CustomSegmentLights) { #if DEBUGSAVE Log._Debug($"Saving timed light step {j}, segment {e.Key} at node {nodeId}."); #endif ICustomSegmentLights segLights = e.Value; ushort lightsNodeId = segLights.NodeId; var cnfSegLights = new Configuration.CustomSegmentLights { nodeId = lightsNodeId, // TODO not needed segmentId = segLights.SegmentId, // TODO not needed customLights = new Dictionary <ExtVehicleType, Configuration.CustomSegmentLight>(), pedestrianLightState = segLights.PedestrianLightState, manualPedestrianMode = segLights.ManualPedestrianMode }; if (lightsNodeId == 0 || lightsNodeId != timedNode.NodeId) { Log.Warning( "Inconsistency detected: Timed traffic light @ node " + $"{timedNode.NodeId} contains custom traffic lights for the invalid " + $"segment ({segLights.SegmentId}) at step {j}: nId={lightsNodeId}"); continue; } cnfTimedStep.segmentLights.Add(e.Key, cnfSegLights); #if DEBUGSAVE Log._Debug($"Saving pedestrian light @ seg. {e.Key}, step {j}: " + $"{cnfSegLights.pedestrianLightState} {cnfSegLights.manualPedestrianMode}"); #endif foreach (KeyValuePair <API.Traffic.Enums.ExtVehicleType, ICustomSegmentLight> e2 in segLights.CustomLights) { #if DEBUGSAVE Log._Debug($"Saving timed light step {j}, segment {e.Key}, vehicleType " + $"{e2.Key} at node {nodeId}."); #endif ICustomSegmentLight segLight = e2.Value; var cnfSegLight = new Configuration.CustomSegmentLight { nodeId = lightsNodeId, // TODO not needed segmentId = segLights.SegmentId, // TODO not needed currentMode = (int)segLight.CurrentMode, leftLight = segLight.LightLeft, mainLight = segLight.LightMain, rightLight = segLight.LightRight }; cnfSegLights.customLights.Add( LegacyExtVehicleType.ToOld(e2.Key), cnfSegLight); } } } } catch (Exception e) { Log.Error( $"Exception occurred while saving timed traffic light @ {nodeId}: {e}"); success = false; } } return(ret); }
private bool GetHoveredSegment(Rect myRect1, int segmentId, bool hoveredSegment, ICustomSegmentLight segmentDict) { if (!myRect1.Contains(Event.current.mousePosition)) { return(hoveredSegment); } //Log.Message("mouse in myRect1"); _hoveredButton[0] = segmentId; _hoveredButton[1] = -1; if (!MainTool.CheckClicked()) { return(true); } segmentDict.ToggleMode(); return(true); }
// 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 }
// TODO improve & remove public void Housekeeping(bool mayDelete, bool calculateAutoPedLight) { #if DEBUGHK bool debug = DebugSwitch.TimedTrafficLights.Get() && DebugSettings.NodeId == NodeId; #endif // we intentionally never delete vehicle types (because we may want to retain traffic light states if a segment is upgraded or replaced) ICustomSegmentLight mainLight = MainSegmentLight; ushort nodeId = NodeId; HashSet <ExtVehicleType> setupLights = new HashSet <ExtVehicleType>(); IDictionary <byte, ExtVehicleType> allAllowedTypes = Constants.ManagerFactory.VehicleRestrictionsManager.GetAllowedVehicleTypesAsDict(SegmentId, nodeId, VehicleRestrictionsMode.Restricted); // TODO improve ExtVehicleType allAllowedMask = Constants.ManagerFactory.VehicleRestrictionsManager.GetAllowedVehicleTypes(SegmentId, nodeId, VehicleRestrictionsMode.Restricted); SeparateVehicleTypes = ExtVehicleType.None; #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping started @ seg. {SegmentId}, node {nodeId}, allAllowedTypes={allAllowedTypes.DictionaryToString()}, allAllowedMask={allAllowedMask}"); } #endif //bool addPedestrianLight = false; uint separateLanes = 0; int defaultLanes = 0; NetInfo segmentInfo = null; Constants.ServiceFactory.NetService.ProcessSegment(SegmentId, delegate(ushort segId, ref NetSegment segment) { VehicleTypeByLaneIndex = new ExtVehicleType?[segment.Info.m_lanes.Length]; segmentInfo = segment.Info; return(true); }); HashSet <byte> laneIndicesWithoutSeparateLights = new HashSet <byte>(allAllowedTypes.Keys); // TODO improve // check if separate traffic lights are required bool separateLightsRequired = false; foreach (KeyValuePair <byte, ExtVehicleType> e in allAllowedTypes) { if (e.Value != allAllowedMask) { separateLightsRequired = true; break; } } // set up vehicle-separated traffic lights if (separateLightsRequired) { foreach (KeyValuePair <byte, ExtVehicleType> e in allAllowedTypes) { byte laneIndex = e.Key; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; ExtVehicleType allowedTypes = e.Value; ExtVehicleType defaultMask = Constants.ManagerFactory.VehicleRestrictionsManager.GetDefaultAllowedVehicleTypes(SegmentId, segmentInfo, laneIndex, laneInfo, VehicleRestrictionsMode.Unrestricted); #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Processing lane {laneIndex} with allowedTypes={allowedTypes}, defaultMask={defaultMask}"); } #endif if (laneInfo.m_vehicleType == VehicleInfo.VehicleType.Car && allowedTypes == defaultMask) { #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}, lane {laneIndex}: Allowed types equal default mask. Ignoring lane."); } #endif // no vehicle restrictions applied, generic lights are handled further below ++defaultLanes; continue; } ExtVehicleType mask = allowedTypes & ~ExtVehicleType.Emergency; #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}, lane {laneIndex}: Trying to add {mask} light"); } #endif ICustomSegmentLight segmentLight; if (!CustomLights.TryGetValue(mask, out segmentLight)) { // add a new light segmentLight = new CustomSegmentLight(this, RoadBaseAI.TrafficLightState.Red); if (mainLight != null) { segmentLight.CurrentMode = mainLight.CurrentMode; segmentLight.SetStates(mainLight.LightMain, mainLight.LightLeft, mainLight.LightRight, false); } #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}, lane {laneIndex}: Light for mask {mask} does not exist. Created new light: {segmentLight} (mainLight: {mainLight})"); } #endif CustomLights.Add(mask, segmentLight); VehicleTypes.AddFirst(mask); } mainVehicleType = mask; VehicleTypeByLaneIndex[laneIndex] = mask; laneIndicesWithoutSeparateLights.Remove(laneIndex); ++separateLanes; //addPedestrianLight = true; setupLights.Add(mask); SeparateVehicleTypes |= mask; #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Finished processing lane {laneIndex}: mainVehicleType={mainVehicleType}, VehicleTypeByLaneIndex={VehicleTypeByLaneIndex.ArrayToString()}, laneIndicesWithoutSeparateLights={laneIndicesWithoutSeparateLights.CollectionToString()}, numLights={separateLanes}, SeparateVehicleTypes={SeparateVehicleTypes}"); } #endif } } if (separateLanes == 0 || defaultLanes > 0) { #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Adding default main vehicle light: {DEFAULT_MAIN_VEHICLETYPE}"); } #endif // generic traffic lights ICustomSegmentLight defaultSegmentLight; if (!CustomLights.TryGetValue(DEFAULT_MAIN_VEHICLETYPE, out defaultSegmentLight)) { defaultSegmentLight = new CustomSegmentLight(this, RoadBaseAI.TrafficLightState.Red); if (mainLight != null) { defaultSegmentLight.CurrentMode = mainLight.CurrentMode; defaultSegmentLight.SetStates(mainLight.LightMain, mainLight.LightLeft, mainLight.LightRight, false); } CustomLights.Add(DEFAULT_MAIN_VEHICLETYPE, defaultSegmentLight); VehicleTypes.AddFirst(DEFAULT_MAIN_VEHICLETYPE); } mainVehicleType = DEFAULT_MAIN_VEHICLETYPE; setupLights.Add(DEFAULT_MAIN_VEHICLETYPE); foreach (byte laneIndex in laneIndicesWithoutSeparateLights) { VehicleTypeByLaneIndex[laneIndex] = ExtVehicleType.None; } #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Added default main vehicle light: {defaultSegmentLight}"); } #endif //addPedestrianLight = true; } else { //addPedestrianLight = allAllowedMask == ExtVehicleType.None || (allAllowedMask & ~ExtVehicleType.RailVehicle) != ExtVehicleType.None; } #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Created all necessary lights. VehicleTypeByLaneIndex={VehicleTypeByLaneIndex.ArrayToString()}, CustomLights={CustomLights.DictionaryToString()}"); } #endif if (mayDelete) { // delete traffic lights for non-existing vehicle-separated configurations HashSet <ExtVehicleType> vehicleTypesToDelete = new HashSet <ExtVehicleType>(); foreach (KeyValuePair <ExtVehicleType, ICustomSegmentLight> e in CustomLights) { /*if (e.Key == DEFAULT_MAIN_VEHICLETYPE) { * continue; * }*/ if (!setupLights.Contains(e.Key)) { vehicleTypesToDelete.Add(e.Key); } } #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Going to delete unnecessary lights now: vehicleTypesToDelete={vehicleTypesToDelete.CollectionToString()}"); } #endif foreach (ExtVehicleType vehicleType in vehicleTypesToDelete) { CustomLights.Remove(vehicleType); VehicleTypes.Remove(vehicleType); } } if (CustomLights.ContainsKey(DEFAULT_MAIN_VEHICLETYPE) && VehicleTypes.First.Value != DEFAULT_MAIN_VEHICLETYPE) { VehicleTypes.Remove(DEFAULT_MAIN_VEHICLETYPE); VehicleTypes.AddFirst(DEFAULT_MAIN_VEHICLETYPE); } //if (addPedestrianLight) { #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: adding pedestrian light"); } #endif if (InternalPedestrianLightState == null) { InternalPedestrianLightState = RoadBaseAI.TrafficLightState.Red; } /*} else { * InternalPedestrianLightState = null; * }*/ OnChange(calculateAutoPedLight); #if DEBUGHK if (debug) { Log._Debug($"CustomSegmentLights.Housekeeping({mayDelete}, {calculateAutoPedLight}): housekeeping @ seg. {SegmentId}, node {nodeId}: Housekeeping complete. VehicleTypeByLaneIndex={VehicleTypeByLaneIndex.ArrayToString()} CustomLights={CustomLights.DictionaryToString()}"); } #endif }
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 = GeometryUtil.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, RoadUI.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[SelectedNodeId], 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; }
private bool LeftArrowLightMode(int segmentId, float lightWidth, bool hasRightSegment, bool hasForwardSegment, Vector3 screenPos, float pedestrianWidth, float zoom, float lightHeight, ICustomSegmentLight segmentDict, bool hoveredSegment) { SetAlpha(segmentId, 3); float offsetLight = lightWidth; if (hasRightSegment) { offsetLight += lightWidth; } if (hasForwardSegment) { offsetLight += lightWidth; } var myRect4 = new Rect( screenPos.x - (lightWidth / 2) - offsetLight - pedestrianWidth + (5f * zoom), screenPos.y - (lightHeight / 2), lightWidth, lightHeight); switch (segmentDict.LightLeft) { case RoadBaseAI.TrafficLightState.Green: GUI.DrawTexture(myRect4, TrafficLightTextures.GreenLightLeft); break; case RoadBaseAI.TrafficLightState.Red: GUI.DrawTexture(myRect4, TrafficLightTextures.RedLightLeft); break; } if (!myRect4.Contains(Event.current.mousePosition)) { return(hoveredSegment); } hoveredButton[0] = segmentId; hoveredButton[1] = 3; if (!MainTool.CheckClicked()) { return(true); } segmentDict.ChangeLeftLight(); if (!hasForwardSegment) { segmentDict.ChangeMainLight(); } return(true); }
private bool RightForwardLSegmentLightMode(int segmentId, Vector3 screenPos, float lightWidth, float pedestrianWidth, float zoom, float lightHeight, bool hasForwardSegment, bool hasLeftSegment, ICustomSegmentLight segmentDict, bool hasRightSegment, bool hoveredSegment) { SetAlpha(segmentId, 3); var myRect4 = new Rect( screenPos.x - (lightWidth / 2) - (lightWidth * 2) - pedestrianWidth + (5f * zoom), screenPos.y - (lightHeight / 2), lightWidth, lightHeight); if (hasForwardSegment && hasLeftSegment) { switch (segmentDict.LightLeft) { case RoadBaseAI.TrafficLightState.Green: { GUI.DrawTexture(myRect4, TrafficLightTextures.GreenLightForwardLeft); break; } case RoadBaseAI.TrafficLightState.Red: { GUI.DrawTexture(myRect4, TrafficLightTextures.RedLightForwardLeft); break; } } } else if (!hasLeftSegment) { if (!hasRightSegment) { myRect4 = new Rect( (screenPos.x - (lightWidth / 2) - lightWidth - pedestrianWidth) + (5f * zoom), screenPos.y - (lightHeight / 2), lightWidth, lightHeight); } switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: { GUI.DrawTexture(myRect4, TrafficLightTextures.GreenLightStraight); break; } case RoadBaseAI.TrafficLightState.Red: { GUI.DrawTexture(myRect4, TrafficLightTextures.RedLightStraight); break; } } } else { if (!hasRightSegment) { myRect4 = new Rect( screenPos.x - (lightWidth / 2) - lightWidth - pedestrianWidth + (5f * zoom), screenPos.y - (lightHeight / 2), lightWidth, lightHeight); } switch (segmentDict.LightMain) { case RoadBaseAI.TrafficLightState.Green: { GUI.DrawTexture(myRect4, TrafficLightTextures.GreenLightLeft); break; } case RoadBaseAI.TrafficLightState.Red: { GUI.DrawTexture(myRect4, TrafficLightTextures.RedLightLeft); break; } } } if (myRect4.Contains(Event.current.mousePosition)) { hoveredButton[0] = segmentId; hoveredButton[1] = 3; hoveredSegment = true; if (MainTool.CheckClicked()) { segmentDict.ChangeMainLight(); } } Color guiColor = GUI.color; // right arrow light if (hasRightSegment) { guiColor.a = TrafficManagerTool.GetHandleAlpha( hoveredButton[0] == segmentId && hoveredButton[1] == 4); } GUI.color = guiColor; var myRect5 = new Rect( screenPos.x - (lightWidth / 2) - lightWidth - pedestrianWidth + (5f * zoom), screenPos.y - (lightHeight / 2), lightWidth, lightHeight); switch (segmentDict.LightRight) { case RoadBaseAI.TrafficLightState.Green: { GUI.DrawTexture(myRect5, TrafficLightTextures.GreenLightRight); break; } case RoadBaseAI.TrafficLightState.Red: { GUI.DrawTexture(myRect5, TrafficLightTextures.RedLightRight); break; } } if (!myRect5.Contains(Event.current.mousePosition)) { return(hoveredSegment); } hoveredButton[0] = segmentId; hoveredButton[1] = 4; if (!MainTool.CheckClicked()) { return(true); } segmentDict.ChangeRightLight(); return(true); }