public override void OnSecondaryClickOverlay() { if (IsCursorInPanel()) { return; } switch (GetMarkerSelectionMode()) { case MarkerSelectionMode.None: default: #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: OnSecondaryClickOverlay: nothing to do"); #endif stayInLaneMode = StayInLaneMode.None; break; case MarkerSelectionMode.SelectSource: // deselect node #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: OnSecondaryClickOverlay: selected node id = 0"); #endif SelectedNodeId = 0; break; case MarkerSelectionMode.SelectTarget: // deselect source marker #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: OnSecondaryClickOverlay: switch to selected source mode"); #endif selectedMarker = null; break; } }
void HandleIntersectionRouting() { FastList <NodeLaneMarker> nodeMarkers; if (m_nodeMarkers.TryGetValue(m_selectedNode, out nodeMarkers)) { Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); NodeLaneMarker hoveredMarker = null; Bounds bounds = new Bounds(Vector3.zero, Vector3.one); for (int i = 0; i < nodeMarkers.m_size; i++) { NodeLaneMarker marker = nodeMarkers.m_buffer[i]; if (!IsActive(marker)) { continue; } bounds.center = marker.m_position; if (bounds.IntersectRay(mouseRay)) { hoveredMarker = marker; marker.m_size = 2f; } else { marker.m_size = 1f; } } if (hoveredMarker != null && Input.GetMouseButtonUp(0)) { if (m_selectedMarker == null) { m_selectedMarker = hoveredMarker; } else if (RoadManager.RemoveLaneConnection(m_selectedMarker.m_lane, hoveredMarker.m_lane)) { m_selectedMarker.m_connections.Remove(hoveredMarker); } else if (RoadManager.AddLaneConnection(m_selectedMarker.m_lane, hoveredMarker.m_lane)) { m_selectedMarker.m_connections.Add(hoveredMarker); } } } if (Input.GetMouseButtonUp(1)) { if (m_selectedMarker != null) { m_selectedMarker = null; } else { m_selectedNode = 0; } } }
public override void OnActivate() { #if DEBUGCONN Log._Debug("TppLaneConnectorTool: OnActivate"); #endif SelectedNodeId = 0; selectedMarker = null; hoveredMarker = null; }
protected override void OnEnable() { base.OnEnable(); m_hoveredNode = m_hoveredSegment = 0; m_selectedNode = 0; m_selectedMarker = null; m_selectedLaneMarkers.Clear(); m_segments.Clear(); m_hoveredLaneMarkers.Clear(); }
public override void OnActivate() { #if DEBUGCONN Log._Debug("TppLaneConnectorTool: OnActivate"); #endif SelectedNodeId = 0; selectedMarker = null; hoveredMarker = null; stayInLaneMode = StayInLaneMode.None; RefreshCurrentNodeMarkers(); }
bool IsActive(NodeLaneMarker marker) { if (m_selectedMarker != null && (marker.m_isSource || NetManager.instance.m_lanes.m_buffer[m_selectedMarker.m_lane].m_segment == NetManager.instance.m_lanes.m_buffer[marker.m_lane].m_segment)) { return(false); } else if (m_selectedMarker == null && !marker.m_isSource) { return(false); } return(true); }
private bool IsLaneMarkerHovered(NodeLaneMarker laneMarker, ref Ray mouseRay) { Bounds bounds = new Bounds(Vector3.zero, Vector3.one); bounds.center = laneMarker.position; if (bounds.IntersectRay(mouseRay)) { return(true); } bounds = new Bounds(Vector3.zero, Vector3.one); bounds.center = laneMarker.secondaryPosition; return(bounds.IntersectRay(mouseRay)); }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { //Log._Debug($"TppLaneConnectorTool: RenderOverlay. SelectedNodeId={SelectedNodeId} SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} HoveredSegmentId={HoveredSegmentId} IsInsideUI={MainTool.GetToolController().IsInsideUI}"); // draw lane markers and connections hoveredMarker = null; ShowOverlay(false, cameraInfo); // draw bezier from source marker to mouse position in target marker selection if (SelectedNodeId != 0) { if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { Vector3 selNodePos = NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position; ToolBase.RaycastOutput output; if (RayCastSegmentAndNode(out output)) { RenderLane(cameraInfo, selectedMarker.position, output.m_hitPos, selNodePos, selectedMarker.color); } } if (Input.GetKey(KeyCode.Delete)) { // remove all connections at selected node List <NodeLaneMarker> nodeMarkers = GetNodeMarkers(SelectedNodeId); if (nodeMarkers != null) { selectedMarker = null; foreach (NodeLaneMarker sourceLaneMarker in nodeMarkers) { foreach (NodeLaneMarker targetLaneMarker in sourceLaneMarker.connectedMarkers) { LaneConnectionManager.Instance().RemoveLaneConnection(sourceLaneMarker.laneId, targetLaneMarker.laneId, sourceLaneMarker.startNode); } } } RefreshCurrentNodeMarkers(); } } if (GetMarkerSelectionMode() == MarkerSelectionMode.None && HoveredNodeId != 0) { // draw hovered node MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); } }
public override void OnActivate() { #if DEBUGCONN bool debug = GlobalConfig.Instance.Debug.Switches[23]; if (debug) { Log._Debug("TppLaneConnectorTool: OnActivate"); } #endif SelectedNodeId = 0; selectedMarker = null; hoveredMarker = null; stayInLaneMode = StayInLaneMode.None; RefreshCurrentNodeMarkers(); }
public override void OnActivate() { #if DEBUG bool logLaneConn = DebugSwitch.LaneConnections.Get(); if (logLaneConn) { Log._Debug("LaneConnectorTool: OnActivate"); } #endif SelectedNodeId = 0; selectedMarker = null; hoveredMarker = null; stayInLaneMode = StayInLaneMode.None; RefreshCurrentNodeMarkers(); }
protected override void OnEnable() { base.OnEnable(); // hack to stop bug that disables and enables this tool the first time the panel is clicked if (Time.realtimeSinceStartup - time < 0.2f) { time = 0; return; } ToolCursor = null; m_hoveredNode = m_hoveredSegment = 0; m_selectedNode = 0; m_selectedMarker = null; }
public override void OnSecondaryClickOverlay() { #if DEBUG bool logLaneConn = DebugSwitch.LaneConnections.Get(); #else const bool logLaneConn = false; #endif if (IsCursorInPanel()) { return; } switch (GetMarkerSelectionMode()) { // also: case MarkerSelectionMode.None: default: { Log._DebugIf( logLaneConn, () => "LaneConnectorTool: OnSecondaryClickOverlay: nothing to do"); stayInLaneMode = StayInLaneMode.None; break; } case MarkerSelectionMode.SelectSource: { // deselect node Log._DebugIf( logLaneConn, () => "LaneConnectorTool: OnSecondaryClickOverlay: selected node id = 0"); SelectedNodeId = 0; break; } case MarkerSelectionMode.SelectTarget: { // deselect source marker Log._DebugIf( logLaneConn, () => "LaneConnectorTool: OnSecondaryClickOverlay: switch to selected source mode"); selectedMarker = null; break; } } }
protected override void OnEnable() { base.OnEnable(); // hack to stop bug that disables and enables this tool the first time the panel is clicked if (Time.realtimeSinceStartup - time < 0.2f) { time = 0; return; } m_hoveredNode = m_hoveredSegment = 0; m_selectedNode = 0; m_selectedMarker = null; m_selectedLaneMarkers.Clear(); m_segments.Clear(); m_hoveredLaneMarkers.Clear(); if (OnEndLaneCustomization != null) { OnEndLaneCustomization(); } }
public override void OnPrimaryClickOverlay() { #if DEBUG bool logLaneConn = DebugSwitch.LaneConnections.Get(); #else const bool logLaneConn = false; #endif Log._DebugIf( logLaneConn, () => $"LaneConnectorTool: OnPrimaryClickOverlay. SelectedNodeId={SelectedNodeId} " + $"SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} " + $"HoveredSegmentId={HoveredSegmentId}"); if (IsCursorInPanel()) { return; } if (GetMarkerSelectionMode() == MarkerSelectionMode.None) { if (HoveredNodeId != 0) { Log._DebugIf( logLaneConn, () => "LaneConnectorTool: HoveredNode != 0"); if (NetManager.instance.m_nodes.m_buffer[HoveredNodeId].CountSegments() < 2) { // this node cannot be configured (dead end) Log._DebugIf( logLaneConn, () => "LaneConnectorTool: Node is a dead end"); SelectedNodeId = 0; selectedMarker = null; stayInLaneMode = StayInLaneMode.None; return; } if (SelectedNodeId != HoveredNodeId) { Log._DebugIf( logLaneConn, () => $"Node {HoveredNodeId} has been selected. Creating markers."); // selected node has changed. create markers List <NodeLaneMarker> markers = GetNodeMarkers( HoveredNodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId]); if (markers != null) { SelectedNodeId = HoveredNodeId; selectedMarker = null; stayInLaneMode = StayInLaneMode.None; currentNodeMarkers[SelectedNodeId] = markers; } // this.allNodeMarkers[SelectedNodeId] = GetNodeMarkers(SelectedNodeId); } } else { Log._DebugIf( logLaneConn, () => $"LaneConnectorTool: Node {SelectedNodeId} has been deselected."); // click on free spot. deselect node SelectedNodeId = 0; selectedMarker = null; stayInLaneMode = StayInLaneMode.None; return; } } if (hoveredMarker == null) { return; } //----------------------------------- // Hovered Marker //----------------------------------- stayInLaneMode = StayInLaneMode.None; Log._DebugIf( logLaneConn, () => $"LaneConnectorTool: hoveredMarker != null. selMode={GetMarkerSelectionMode()}"); // hovered marker has been clicked if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource) { // select source marker selectedMarker = hoveredMarker; Log._DebugIf( logLaneConn, () => "LaneConnectorTool: set selected marker"); } else if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { // select target marker // bool success = false; if (LaneConnectionManager.Instance.RemoveLaneConnection( selectedMarker.LaneId, hoveredMarker.LaneId, selectedMarker.StartNode)) { // try to remove connection selectedMarker.ConnectedMarkers.Remove(hoveredMarker); Log._DebugIf( logLaneConn, () => $"LaneConnectorTool: removed lane connection: {selectedMarker.LaneId}, " + $"{hoveredMarker.LaneId}"); // success = true; } else if (LaneConnectionManager.Instance.AddLaneConnection( selectedMarker.LaneId, hoveredMarker.LaneId, selectedMarker.StartNode)) { // try to add connection selectedMarker.ConnectedMarkers.Add(hoveredMarker); Log._DebugIf( logLaneConn, () => $"LaneConnectorTool: added lane connection: {selectedMarker.LaneId}, " + $"{hoveredMarker.LaneId}"); // success = true; } /*if (success) { * // connection has been modified. switch back to source marker selection * Log._Debug($"LaneConnectorTool: switch back to source marker selection"); * selectedMarker = null; * selMode = MarkerSelectionMode.SelectSource; * }*/ } }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { // Log._Debug($"LaneConnectorTool: RenderOverlay. SelectedNodeId={SelectedNodeId} // SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} // HoveredSegmentId={HoveredSegmentId} IsInsideUI={MainTool.GetToolController().IsInsideUI}"); // draw lane markers and connections hoveredMarker = null; ShowOverlay(false, cameraInfo); // draw bezier from source marker to mouse position in target marker selection if (SelectedNodeId != 0) { if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { Vector3 selNodePos = NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position; // Draw a currently dragged curve var pos = HitPos; if (hoveredMarker == null) { float hitH = TrafficManagerTool.GetAccurateHitHeight(); pos.y = hitH; // fix height. float mouseH = MousePosition.y; if (hitH < mouseH - MAX_HIT_ERROR) { // for metros lane curve is projected on the ground. pos = MousePosition; } } else { // snap to hovered: pos = hoveredMarker.SecondaryPosition; } DrawLaneCurve( cameraInfo, selectedMarker.Position, pos, selNodePos, Color.Lerp(selectedMarker.Color, Color.white, 0.33f), Color.white, size: 0.11f); } bool deleteAll = (frameClearPressed > 0) && ((Time.frameCount - frameClearPressed) < 20); // 0.33 sec NetNode[] nodesBuffer = Singleton <NetManager> .instance.m_nodes.m_buffer; // Must press Shift+S (or another shortcut) within last 20 frames for this to work bool stayInLane = (frameStayInLanePressed > 0) && ((Time.frameCount - frameStayInLanePressed) < 20) && // 0.33 sec (nodesBuffer[SelectedNodeId].CountSegments() == 2); if (stayInLane) { frameStayInLanePressed = 0; // not pressed anymore (consumed) deleteAll = true; } if (deleteAll) { frameClearPressed = 0; // consumed // remove all connections at selected node LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(SelectedNodeId); RefreshCurrentNodeMarkers(SelectedNodeId); } if (stayInLane) { // "stay in lane" switch (stayInLaneMode) { case StayInLaneMode.None: { stayInLaneMode = StayInLaneMode.Both; break; } case StayInLaneMode.Both: { stayInLaneMode = StayInLaneMode.Forward; break; } case StayInLaneMode.Forward: { stayInLaneMode = StayInLaneMode.Backward; break; } case StayInLaneMode.Backward: { stayInLaneMode = StayInLaneMode.None; break; } } if (stayInLaneMode != StayInLaneMode.None) { selectedMarker = null; StayInLane(SelectedNodeId, stayInLaneMode); RefreshCurrentNodeMarkers(SelectedNodeId); } } // if stay in lane } // if selected node if ((GetMarkerSelectionMode() == MarkerSelectionMode.None) && (HoveredNodeId != 0)) { // draw hovered node MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); } }
private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { if (viewOnly && !(Options.connectedLanesOverlay || PrioritySignsTool.MassEditOVerlay.IsActive)) { return; } NetManager netManager = Singleton <NetManager> .instance; Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; // Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Camera currentCamera = Camera.main; Ray mouseRay = currentCamera.ScreenPointToRay(Input.mousePosition); // Check if camera pos/angle has changed then re-filter the visible nodes // Assumption: The states checked in this loop don't change while the tool is active var currentCameraState = new CameraTransformValue(currentCamera); if (!LastCachedCamera.Equals(currentCameraState)) { CachedVisibleNodeIds.Clear(); LastCachedCamera = currentCameraState; for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; } //--------------------------- // Check the connection class //--------------------------- // TODO refactor connection class check ItemClass connectionClass = NetManager.instance.m_nodes.m_buffer[nodeId].Info.GetConnectionClass(); if ((connectionClass == null) || !((connectionClass.m_service == ItemClass.Service.Road) || ((connectionClass.m_service == ItemClass.Service.PublicTransport) && ((connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain) || (connectionClass.m_subService == ItemClass.SubService.PublicTransportMetro) || (connectionClass.m_subService == ItemClass.SubService.PublicTransportMonorail))))) { continue; } //-------------------------- // Check the camera distance //-------------------------- Vector3 diff = NetManager.instance.m_nodes.m_buffer[nodeId].m_position - camPos; if (diff.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { continue; // do not draw if too distant } // Add CachedVisibleNodeIds.Add(nodeId); } } for (int cacheIndex = CachedVisibleNodeIds.Size - 1; cacheIndex >= 0; cacheIndex--) { var nodeId = CachedVisibleNodeIds.Values[cacheIndex]; List <NodeLaneMarker> nodeMarkers; bool hasMarkers = currentNodeMarkers.TryGetValue((ushort)nodeId, out nodeMarkers); if (!viewOnly && (GetMarkerSelectionMode() == MarkerSelectionMode.None)) { MainTool.DrawNodeCircle( cameraInfo, (ushort)nodeId, DefaultNodeMarkerColor, true); } if (!hasMarkers) { continue; } foreach (NodeLaneMarker laneMarker in nodeMarkers) { if (!Constants.ServiceFactory.NetService.IsLaneValid(laneMarker.LaneId)) { continue; } if (laneMarker != selectedMarker) { foreach (NodeLaneMarker targetLaneMarker in laneMarker.ConnectedMarkers) { // render lane connection from laneMarker to targetLaneMarker if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneMarker.LaneId)) { continue; } DrawLaneCurve( cameraInfo, laneMarker.Position, targetLaneMarker.Position, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, laneMarker.Color, Color.black); } } if (viewOnly || (nodeId != SelectedNodeId)) { continue; } // draw source marker in source selection mode, // draw target marker (if segment turning angles are within bounds) and // selected source marker in target selection mode bool drawMarker = ((GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource) && laneMarker.IsSource) || ((GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) && ((laneMarker.IsTarget && ((laneMarker.VehicleType & selectedMarker.VehicleType) != VehicleInfo.VehicleType.None) && CheckSegmentsTurningAngle( selectedMarker.SegmentId, ref netManager.m_segments.m_buffer[selectedMarker.SegmentId], selectedMarker.StartNode, laneMarker.SegmentId, ref netManager.m_segments.m_buffer[laneMarker.SegmentId], laneMarker.StartNode)) || (laneMarker == selectedMarker))); // highlight hovered marker and selected marker if (drawMarker) { bool markerIsHovered = false; if (hoveredMarker == null) { float hitH = TrafficManagerTool.GetAccurateHitHeight(); markerIsHovered = laneMarker.segmentLaneMarker.IntersectRay(ref mouseRay, hitH); if (markerIsHovered) { hoveredMarker = laneMarker; } } bool isTarget = selectedMarker != null && laneMarker != selectedMarker; var color = isTarget ? Color.white : laneMarker.Color; bool highlightMarker = laneMarker == selectedMarker || markerIsHovered; if (highlightMarker) { laneMarker.segmentLaneMarker.RenderOverlay(cameraInfo, color, enlarge: true); } laneMarker.RenderOverlay(cameraInfo, color, enlarge: highlightMarker); } // if drawMarker if (selectedMarker != null) { // lane curves for selectedMarker will be drawn last to // be on the top of other lane markers. foreach (NodeLaneMarker targetLaneMarker in selectedMarker.ConnectedMarkers) { if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneMarker.LaneId)) { continue; } DrawLaneCurve( cameraInfo, selectedMarker.Position, targetLaneMarker.Position, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, selectedMarker.Color, Color.grey, size: 0.18f // Embolden ); } // end foreach selectedMarker.ConnectedMarkers } // end if selectedMarker != null } // end foreach lanemarker in node markers } // end for node in all nodes }
private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { if (viewOnly && !Options.connectedLanesOverlay) { return; } NetManager netManager = Singleton <NetManager> .instance; var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; //Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; } // TODO refactor connection class check ItemClass connectionClass = NetManager.instance.m_nodes.m_buffer[nodeId].Info.GetConnectionClass(); if (connectionClass == null || !(connectionClass.m_service == ItemClass.Service.Road || (connectionClass.m_service == ItemClass.Service.PublicTransport && (connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain || connectionClass.m_subService == ItemClass.SubService.PublicTransportMetro || connectionClass.m_subService == ItemClass.SubService.PublicTransportMonorail)))) { continue; } var diff = NetManager.instance.m_nodes.m_buffer[nodeId].m_position - camPos; if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance) { continue; // do not draw if too distant } List <NodeLaneMarker> nodeMarkers; var hasMarkers = currentNodeMarkers.TryGetValue((ushort)nodeId, out nodeMarkers); if (!viewOnly && GetMarkerSelectionMode() == MarkerSelectionMode.None) { MainTool.DrawNodeCircle(cameraInfo, (ushort)nodeId, DefaultNodeMarkerColor, true); } if (hasMarkers) { foreach (NodeLaneMarker laneMarker in nodeMarkers) { if (!Constants.ServiceFactory.NetService.IsLaneValid(laneMarker.laneId)) { continue; } foreach (NodeLaneMarker targetLaneMarker in laneMarker.connectedMarkers) { // render lane connection from laneMarker to targetLaneMarker if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneMarker.laneId)) { continue; } RenderLane(cameraInfo, laneMarker.position, targetLaneMarker.position, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, laneMarker.color); } if (!viewOnly && nodeId == SelectedNodeId) { //bounds.center = laneMarker.position; bool markerIsHovered = IsLaneMarkerHovered(laneMarker, ref mouseRay);// bounds.IntersectRay(mouseRay); // draw source marker in source selection mode, // draw target marker (if segment turning angles are within bounds) and selected source marker in target selection mode bool drawMarker = (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource && laneMarker.isSource) || (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget && ( (laneMarker.isTarget && (laneMarker.vehicleType & selectedMarker.vehicleType) != VehicleInfo.VehicleType.None && CheckSegmentsTurningAngle(selectedMarker.segmentId, ref netManager.m_segments.m_buffer[selectedMarker.segmentId], selectedMarker.startNode, laneMarker.segmentId, ref netManager.m_segments.m_buffer[laneMarker.segmentId], laneMarker.startNode) ) || laneMarker == selectedMarker)); // highlight hovered marker and selected marker bool highlightMarker = drawMarker && (laneMarker == selectedMarker || markerIsHovered); if (drawMarker) { if (highlightMarker) { laneMarker.radius = 2f; } else { laneMarker.radius = 1f; } } else { markerIsHovered = false; } if (markerIsHovered) { /*if (hoveredMarker != sourceLaneMarker) * Log._Debug($"Marker @ lane {sourceLaneMarker.laneId} hovered");*/ hoveredMarker = laneMarker; } if (drawMarker) { //DrawLaneMarker(laneMarker, cameraInfo); RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.color, laneMarker.position, laneMarker.radius, laneMarker.position.y - 100f, laneMarker.position.y + 100f, false, true); } } } } } }
private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { if (viewOnly && !Options.connectedLanesOverlay) { return; } NetManager netManager = Singleton <NetManager> .instance; var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; //Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); foreach (KeyValuePair <ushort, List <NodeLaneMarker> > e in currentNodeMarkers) { ushort nodeId = e.Key; List <NodeLaneMarker> nodeMarkers = e.Value; Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[nodeId].m_position; var diff = nodePos - camPos; if (diff.magnitude > TrafficManagerTool.PriorityCloseLod) { continue; // do not draw if too distant } if (!viewOnly && GetMarkerSelectionMode() == MarkerSelectionMode.None) { MainTool.DrawNodeCircle(cameraInfo, nodeId, DefaultNodeMarkerColor, true); } foreach (NodeLaneMarker laneMarker in nodeMarkers) { foreach (NodeLaneMarker targetLaneMarker in laneMarker.connectedMarkers) { // render lane connection from laneMarker to targetLaneMarker RenderLane(cameraInfo, laneMarker.position, targetLaneMarker.position, nodePos, laneMarker.color); } if (!viewOnly && nodeId == SelectedNodeId) { //bounds.center = laneMarker.position; bool markerIsHovered = IsLaneMarkerHovered(laneMarker, ref mouseRay); // bounds.IntersectRay(mouseRay); // draw source marker in source selection mode, // draw target marker (if segment turning angles are within bounds) and selected source marker in target selection mode bool drawMarker = (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource && laneMarker.isSource) || (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget && ( (!laneMarker.isSource && (laneMarker.vehicleType & selectedMarker.vehicleType) != VehicleInfo.VehicleType.None && CheckSegmentsTurningAngle(selectedMarker.segmentId, ref netManager.m_segments.m_buffer[selectedMarker.segmentId], selectedMarker.startNode, laneMarker.segmentId, ref netManager.m_segments.m_buffer[laneMarker.segmentId], laneMarker.startNode) ) || laneMarker == selectedMarker)); // highlight hovered marker and selected marker bool highlightMarker = drawMarker && (laneMarker == selectedMarker || markerIsHovered); if (drawMarker) { if (highlightMarker) { laneMarker.radius = 2f; } else { laneMarker.radius = 1f; } } else { markerIsHovered = false; } if (markerIsHovered) { /*if (hoveredMarker != sourceLaneMarker) * Log._Debug($"Marker @ lane {sourceLaneMarker.laneId} hovered");*/ hoveredMarker = laneMarker; } if (drawMarker) { //DrawLaneMarker(laneMarker, cameraInfo); RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.color, laneMarker.position, laneMarker.radius, laneMarker.position.y - 100f, laneMarker.position.y + 100f, false, true); } } } } }
void HandleIntersectionRouting() { FastList<NodeLaneMarker> nodeMarkers; if (m_nodeMarkers.TryGetValue(m_selectedNode, out nodeMarkers)) { Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); NodeLaneMarker hoveredMarker = null; Bounds bounds = new Bounds(Vector3.zero, Vector3.one); for (int i = 0; i < nodeMarkers.m_size; i++) { NodeLaneMarker marker = nodeMarkers.m_buffer[i]; if (!IsActive(marker)) continue; bounds.center = marker.m_position; if (bounds.IntersectRay(mouseRay)) { hoveredMarker = marker; marker.m_size = 2f; } else marker.m_size = 1f; } if (hoveredMarker != null && Input.GetMouseButtonUp(0)) { if (m_selectedMarker == null) { m_selectedMarker = hoveredMarker; } else if (RoadManager.RemoveLaneConnection(m_selectedMarker.m_lane, hoveredMarker.m_lane)) { m_selectedMarker.m_connections.Remove(hoveredMarker); } else if (RoadManager.AddLaneConnection(m_selectedMarker.m_lane, hoveredMarker.m_lane)) { m_selectedMarker.m_connections.Add(hoveredMarker); } } } if (Input.GetMouseButtonUp(1)) { if (m_selectedMarker != null) m_selectedMarker = null; else m_selectedNode = 0; } }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { //Log._Debug($"TppLaneConnectorTool: RenderOverlay. SelectedNodeId={SelectedNodeId} SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} HoveredSegmentId={HoveredSegmentId} IsInsideUI={MainTool.GetToolController().IsInsideUI}"); // draw lane markers and connections hoveredMarker = null; ShowOverlay(false, cameraInfo); // draw bezier from source marker to mouse position in target marker selection if (SelectedNodeId != 0) { if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { Vector3 selNodePos = NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position; ToolBase.RaycastOutput output; if (RayCastSegmentAndNode(out output)) { RenderLane(cameraInfo, selectedMarker.position, output.m_hitPos, selNodePos, selectedMarker.color); } } bool deleteAll = Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace); bool stayInLane = Input.GetKeyDown(KeyCode.S) && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) && Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].CountSegments() == 2; if (stayInLane) { deleteAll = true; } if (deleteAll) { // remove all connections at selected node LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(SelectedNodeId); RefreshCurrentNodeMarkers(SelectedNodeId); } if (stayInLane) { // "stay in lane" switch (stayInLaneMode) { case StayInLaneMode.None: stayInLaneMode = StayInLaneMode.Both; break; case StayInLaneMode.Both: stayInLaneMode = StayInLaneMode.Forward; break; case StayInLaneMode.Forward: stayInLaneMode = StayInLaneMode.Backward; break; case StayInLaneMode.Backward: stayInLaneMode = StayInLaneMode.None; break; } if (stayInLaneMode != StayInLaneMode.None) { List <NodeLaneMarker> nodeMarkers = GetNodeMarkers(SelectedNodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId]); if (nodeMarkers != null) { selectedMarker = null; foreach (NodeLaneMarker sourceLaneMarker in nodeMarkers) { if (!sourceLaneMarker.isSource) { continue; } if (stayInLaneMode == StayInLaneMode.Forward || stayInLaneMode == StayInLaneMode.Backward) { if (sourceLaneMarker.finalDirection == NetInfo.Direction.Backward ^ stayInLaneMode == StayInLaneMode.Backward) { continue; } } foreach (NodeLaneMarker targetLaneMarker in nodeMarkers) { if (!targetLaneMarker.isTarget || targetLaneMarker.segmentId == sourceLaneMarker.segmentId) { continue; } if (targetLaneMarker.innerSimilarLaneIndex == sourceLaneMarker.innerSimilarLaneIndex) { Log._Debug($"Adding lane connection {sourceLaneMarker.laneId} -> {targetLaneMarker.laneId}"); LaneConnectionManager.Instance.AddLaneConnection(sourceLaneMarker.laneId, targetLaneMarker.laneId, sourceLaneMarker.startNode); } } } } RefreshCurrentNodeMarkers(SelectedNodeId); } } } if (GetMarkerSelectionMode() == MarkerSelectionMode.None && HoveredNodeId != 0) { // draw hovered node MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); } }
private static List <LaneEnd> GetLaneEnds(ushort nodeId, ref NetNode node) { if (nodeId == 0) { return(null); } if ((node.m_flags & NetNode.Flags.Created) == NetNode.Flags.None) { return(null); } List <LaneEnd> laneEnds = new List <LaneEnd>(); int nodeMarkerColorIndex = 0; LaneConnectionManager connManager = LaneConnectionManager.Instance; int offsetMultiplier = node.CountSegments() <= 2 ? 3 : 1; for (int i = 0; i < 8; i++) { ushort segmentId = node.GetSegment(i); if (segmentId == 0) { continue; } NetSegment[] segmentsBuffer = NetManager.instance.m_segments.m_buffer; bool startNode = segmentsBuffer[segmentId].m_startNode == nodeId; Vector3 offset = segmentsBuffer[segmentId] .FindDirection(segmentId, nodeId) * offsetMultiplier; NetInfo.Lane[] lanes = segmentsBuffer[segmentId].Info.m_lanes; uint laneId = segmentsBuffer[segmentId].m_lanes; for (byte laneIndex = 0; (laneIndex < lanes.Length) && (laneId != 0); laneIndex++) { NetInfo.Lane laneInfo = lanes[laneIndex]; if (((laneInfo.m_laneType & LaneConnectionManager.LANE_TYPES) != NetInfo.LaneType.None) && ((laneInfo.m_vehicleType & LaneConnectionManager.VEHICLE_TYPES) != VehicleInfo.VehicleType.None)) { if (connManager.GetLaneEndPoint( segmentId, startNode, laneIndex, laneId, laneInfo, out bool isSource, out bool isTarget, out Vector3? pos)) { pos = pos.Value + offset; float terrainY = Singleton <TerrainManager> .instance.SampleDetailHeightSmooth(pos.Value); var terrainPos = new Vector3(pos.Value.x, terrainY, pos.Value.z); Color32 nodeMarkerColor = isSource ? COLOR_CHOICES[nodeMarkerColorIndex % COLOR_CHOICES.Length] : default; // or black (not used while rendering) NetLane lane = NetManager.instance.m_lanes.m_buffer[laneId]; Bezier3 bezier = lane.m_bezier; if (startNode) { bezier.a = (Vector3)pos; } else { bezier.d = (Vector3)pos; } SegmentLaneMarker segmentMarker = new SegmentLaneMarker(bezier); NodeLaneMarker nodeMarker = new NodeLaneMarker { TerrainPosition = terrainPos, Position = (Vector3)pos, }; laneEnds.Add( new LaneEnd { SegmentId = segmentId, LaneId = laneId, NodeId = nodeId, StartNode = startNode, Color = nodeMarkerColor, IsSource = isSource, IsTarget = isTarget, LaneType = laneInfo.m_laneType, VehicleType = laneInfo.m_vehicleType, InnerSimilarLaneIndex = ((byte)(laneInfo.m_direction & NetInfo.Direction.Forward) != 0) ? laneInfo.m_similarLaneIndex : laneInfo.m_similarLaneCount - laneInfo.m_similarLaneIndex - 1, SegmentIndex = i, NodeMarker = nodeMarker, SegmentMarker = segmentMarker, }); if (isSource) { nodeMarkerColorIndex++; } } } laneId = NetManager.instance.m_lanes.m_buffer[laneId].m_nextLane; } } if (laneEnds.Count == 0) { return(null); } foreach (LaneEnd laneEnd1 in laneEnds) { if (!laneEnd1.IsSource) { continue; } uint[] connections = LaneConnectionManager.Instance.GetLaneConnections( laneEnd1.LaneId, laneEnd1.StartNode); if ((connections == null) || (connections.Length == 0)) { continue; } foreach (LaneEnd laneEnd2 in laneEnds) { if (!laneEnd2.IsTarget) { continue; } if (connections.Contains(laneEnd2.LaneId)) { laneEnd1.ConnectedLaneEnds.Add(laneEnd2); } } } return(laneEnds); }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { base.RenderOverlay(cameraInfo); if (m_selectedNode != 0) { FastList <NodeLaneMarker> nodeMarkers; if (m_nodeMarkers.TryGetValue(m_selectedNode, out nodeMarkers)) { Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[m_selectedNode].m_position; for (int i = 0; i < nodeMarkers.m_size; i++) { NodeLaneMarker laneMarker = nodeMarkers.m_buffer[i]; for (int j = 0; j < laneMarker.m_connections.m_size; j++) { RenderLane(cameraInfo, laneMarker.m_position, laneMarker.m_connections.m_buffer[j].m_position, nodePos, laneMarker.m_color); } if (m_selectedMarker != laneMarker && !IsActive(laneMarker)) { continue; } if (m_selectedMarker == laneMarker) { RaycastOutput output; if (RayCastSegmentAndNode(out output)) { RenderLane(cameraInfo, m_selectedMarker.m_position, output.m_hitPos, nodePos, m_selectedMarker.m_color); m_selectedMarker.m_size = 2f; } } RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.m_color, laneMarker.m_position, laneMarker.m_size, -1f, 1280f, false, true); } } } foreach (ushort node in m_nodeMarkers.Keys) { if (node == m_selectedNode || (NetManager.instance.m_nodes.m_buffer[node].m_flags & CUSTOMIZED_NODE_FLAG) != CUSTOMIZED_NODE_FLAG) { continue; } FastList <NodeLaneMarker> list = m_nodeMarkers[node]; Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[node].m_position; for (int i = 0; i < list.m_size; i++) { NodeLaneMarker laneMarker = list.m_buffer[i]; Color color = laneMarker.m_color; color.a = 0.75f; for (int j = 0; j < laneMarker.m_connections.m_size; j++) { if (((NetLane.Flags)NetManager.instance.m_lanes.m_buffer[laneMarker.m_connections.m_buffer[j].m_lane].m_flags & NetLane.Flags.Created) == NetLane.Flags.Created) { RenderLane(cameraInfo, laneMarker.m_position, laneMarker.m_connections.m_buffer[j].m_position, nodePos, color); } } } } if (m_hoveredNode != 0) { NetNode node = NetManager.instance.m_nodes.m_buffer[m_hoveredNode]; RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, new Color(0f, 0f, 0.5f, 0.75f), node.m_position, 15f, -1f, 1280f, false, true); } }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { base.RenderOverlay(cameraInfo); if (m_selectedNode != 0) { FastList <NodeLaneMarker> nodeMarkers; if (m_nodeMarkers.TryGetValue(m_selectedNode, out nodeMarkers)) { Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[m_selectedNode].m_position; for (int i = 0; i < nodeMarkers.m_size; i++) { NodeLaneMarker laneMarker = nodeMarkers.m_buffer[i]; for (int j = 0; j < laneMarker.m_connections.m_size; j++) { RenderLane(cameraInfo, laneMarker.m_position, laneMarker.m_connections.m_buffer[j].m_position, nodePos, laneMarker.m_color); } if (m_selectedMarker != laneMarker && !IsActive(laneMarker)) { continue; } if (m_selectedMarker == laneMarker) { RaycastOutput output; if (RayCastSegmentAndNode(out output)) { RenderLane(cameraInfo, m_selectedMarker.m_position, output.m_hitPos, nodePos, m_selectedMarker.m_color); m_selectedMarker.m_size = 2f; } } RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, laneMarker.m_color, laneMarker.m_position, laneMarker.m_size, laneMarker.m_position.y - 1f, laneMarker.m_position.y + 1f, true, true); } } } else { foreach (KeyValuePair <int, FastList <SegmentLaneMarker> > keyValuePair in m_hoveredLaneMarkers) { bool renderBig = false; if (m_hoveredLanes == keyValuePair.Key) { renderBig = true; } FastList <SegmentLaneMarker> laneMarkers = keyValuePair.Value; for (int i = 0; i < laneMarkers.m_size; i++) { RenderManager.instance.OverlayEffect.DrawBezier(cameraInfo, new Color(0f, 0f, 1f, 0.75f), laneMarkers.m_buffer[i].m_bezier, renderBig ? 2f : laneMarkers.m_buffer[i].m_size, 0, 0, Mathf.Min(laneMarkers.m_buffer[i].m_bezier.a.y, laneMarkers.m_buffer[i].m_bezier.d.y) - 1f, Mathf.Max(laneMarkers.m_buffer[i].m_bezier.a.y, laneMarkers.m_buffer[i].m_bezier.d.y) + 1f, true, false); } } foreach (SegmentLaneMarker marker in m_selectedLaneMarkers) { RenderManager.instance.OverlayEffect.DrawBezier(cameraInfo, new Color(0f, 1f, 0f, 0.75f), marker.m_bezier, 2f, 0, 0, Mathf.Min(marker.m_bezier.a.y, marker.m_bezier.d.y) - 1f, Mathf.Max(marker.m_bezier.a.y, marker.m_bezier.d.y) + 1f, true, false); } } foreach (ushort node in m_nodeMarkers.Keys) { if (node == m_selectedNode || (NetManager.instance.m_nodes.m_buffer[node].m_flags & CUSTOMIZED_NODE_FLAG) != CUSTOMIZED_NODE_FLAG) { continue; } FastList <NodeLaneMarker> list = m_nodeMarkers[node]; Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[node].m_position; for (int i = 0; i < list.m_size; i++) { NodeLaneMarker laneMarker = list.m_buffer[i]; Color color = laneMarker.m_color; color.a = 0.75f; for (int j = 0; j < laneMarker.m_connections.m_size; j++) { if (((NetLane.Flags)NetManager.instance.m_lanes.m_buffer[laneMarker.m_connections.m_buffer[j].m_lane].m_flags & NetLane.Flags.Created) == NetLane.Flags.Created) { RenderLane(cameraInfo, laneMarker.m_position, laneMarker.m_connections.m_buffer[j].m_position, nodePos, color); } } } } if (m_hoveredNode != 0) { NetNode node = NetManager.instance.m_nodes.m_buffer[m_hoveredNode]; RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, new Color(0f, 0f, 0.5f, 0.75f), node.m_position, 15f, node.m_position.y - 1f, node.m_position.y + 1f, true, true); } }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { // Log._Debug($"LaneConnectorTool: RenderOverlay. SelectedNodeId={SelectedNodeId} // SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} // HoveredSegmentId={HoveredSegmentId} IsInsideUI={MainTool.GetToolController().IsInsideUI}"); // draw lane markers and connections hoveredMarker = null; ShowOverlay(false, cameraInfo); // draw bezier from source marker to mouse position in target marker selection if (SelectedNodeId != 0) { if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { Vector3 selNodePos = NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position; ToolBase.RaycastOutput output; // Draw a currently dragged curve if (RayCastSegmentAndNode(out output)) { DrawLaneCurve( cameraInfo, selectedMarker.Position, output.m_hitPos, selNodePos, Color.Lerp(selectedMarker.Color, Color.white, 0.33f), Color.white); } } bool deleteAll = (frameClearPressed > 0) && ((Time.frameCount - frameClearPressed) < 20); // 0.33 sec NetNode[] nodesBuffer = Singleton <NetManager> .instance.m_nodes.m_buffer; // Must press Shift+S (or another shortcut) within last 20 frames for this to work bool stayInLane = (frameStayInLanePressed > 0) && ((Time.frameCount - frameStayInLanePressed) < 20) && // 0.33 sec (nodesBuffer[SelectedNodeId].CountSegments() == 2); if (stayInLane) { frameStayInLanePressed = 0; // not pressed anymore (consumed) deleteAll = true; } if (deleteAll) { frameClearPressed = 0; // consumed // remove all connections at selected node LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(SelectedNodeId); RefreshCurrentNodeMarkers(SelectedNodeId); } if (stayInLane) { // "stay in lane" switch (stayInLaneMode) { case StayInLaneMode.None: { stayInLaneMode = StayInLaneMode.Both; break; } case StayInLaneMode.Both: { stayInLaneMode = StayInLaneMode.Forward; break; } case StayInLaneMode.Forward: { stayInLaneMode = StayInLaneMode.Backward; break; } case StayInLaneMode.Backward: { stayInLaneMode = StayInLaneMode.None; break; } } if (stayInLaneMode != StayInLaneMode.None) { selectedMarker = null; StayInLane(SelectedNodeId, stayInLaneMode); RefreshCurrentNodeMarkers(SelectedNodeId); } } // if stay in lane } // if selected node if ((GetMarkerSelectionMode() == MarkerSelectionMode.None) && (HoveredNodeId != 0)) { // draw hovered node MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); } }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { //Log._Debug($"LaneConnectorTool: RenderOverlay. SelectedNodeId={SelectedNodeId} SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} HoveredSegmentId={HoveredSegmentId} IsInsideUI={MainTool.GetToolController().IsInsideUI}"); // draw lane markers and connections hoveredMarker = null; ShowOverlay(false, cameraInfo); // draw bezier from source marker to mouse position in target marker selection if (SelectedNodeId != 0) { if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { Vector3 selNodePos = NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position; ToolBase.RaycastOutput output; if (RayCastSegmentAndNode(out output)) { RenderLane(cameraInfo, selectedMarker.position, output.m_hitPos, selNodePos, selectedMarker.color); } } var deleteAll = frameClearPressed > 0 && (Time.frameCount - frameClearPressed) < 20; // 0.33 sec // Must press Shift+S (or another shortcut) within last 20 frames for this to work var stayInLane = frameStayInLanePressed > 0 && (Time.frameCount - frameStayInLanePressed) < 20 && // 0.33 sec Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].CountSegments() == 2; if (stayInLane) { frameStayInLanePressed = 0; // not pressed anymore (consumed) deleteAll = true; } if (deleteAll) { frameClearPressed = 0; // consumed // remove all connections at selected node LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(SelectedNodeId); RefreshCurrentNodeMarkers(SelectedNodeId); } if (stayInLane) { // "stay in lane" switch (stayInLaneMode) { case StayInLaneMode.None: stayInLaneMode = StayInLaneMode.Both; break; case StayInLaneMode.Both: stayInLaneMode = StayInLaneMode.Forward; break; case StayInLaneMode.Forward: stayInLaneMode = StayInLaneMode.Backward; break; case StayInLaneMode.Backward: stayInLaneMode = StayInLaneMode.None; break; } if (stayInLaneMode != StayInLaneMode.None) { List <NodeLaneMarker> nodeMarkers = GetNodeMarkers(SelectedNodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId]); if (nodeMarkers != null) { selectedMarker = null; foreach (NodeLaneMarker sourceLaneMarker in nodeMarkers) { if (!sourceLaneMarker.isSource) { continue; } if (stayInLaneMode == StayInLaneMode.Forward || stayInLaneMode == StayInLaneMode.Backward) { if (sourceLaneMarker.segmentIndex == 0 ^ stayInLaneMode == StayInLaneMode.Backward) { continue; } } foreach (NodeLaneMarker targetLaneMarker in nodeMarkers) { if (!targetLaneMarker.isTarget || targetLaneMarker.segmentId == sourceLaneMarker.segmentId) { continue; } if (targetLaneMarker.innerSimilarLaneIndex == sourceLaneMarker.innerSimilarLaneIndex) { Log._Debug($"Adding lane connection {sourceLaneMarker.laneId} -> {targetLaneMarker.laneId}"); LaneConnectionManager.Instance.AddLaneConnection(sourceLaneMarker.laneId, targetLaneMarker.laneId, sourceLaneMarker.startNode); } } } } RefreshCurrentNodeMarkers(SelectedNodeId); } } } if (GetMarkerSelectionMode() == MarkerSelectionMode.None && HoveredNodeId != 0) { // draw hovered node MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); } }
private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { if (viewOnly && !Options.connectedLanesOverlay) { return; } var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); for (ushort nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { /*foreach (KeyValuePair<ushort, List<NodeLaneMarker>> e in allNodeMarkers) { * ushort nodeId = e.Key; * List<NodeLaneMarker> nodeMarkers = e.Value;*/ Vector3 nodePos = NetManager.instance.m_nodes.m_buffer[nodeId].m_position; var diff = nodePos - camPos; if (diff.magnitude > TrafficManagerTool.PriorityCloseLod) { continue; // do not draw if too distant } List <NodeLaneMarker> nodeMarkers = GetNodeMarkers(nodeId); if (nodeMarkers == null) { continue; } foreach (NodeLaneMarker sourceLaneMarker in nodeMarkers) { foreach (NodeLaneMarker targetLaneMarker in sourceLaneMarker.connectedMarkers) { // render lane connection RenderLane(cameraInfo, sourceLaneMarker.position, targetLaneMarker.position, nodePos, sourceLaneMarker.color); } if (!viewOnly && nodeId == SelectedNodeId) { bounds.center = sourceLaneMarker.position; bool markerIsHovered = bounds.IntersectRay(mouseRay); // draw source marker in source selection mode, draw target marker and selected source marker in target selection mode bool drawMarker = (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource && sourceLaneMarker.isSource) || (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget && ( (!sourceLaneMarker.isSource && //(sourceLaneMarker.laneType & selectedMarker.laneType) != NetInfo.LaneType.None && (sourceLaneMarker.vehicleType & selectedMarker.vehicleType) != VehicleInfo.VehicleType.None) || sourceLaneMarker == selectedMarker)); // highlight hovered marker and selected marker bool highlightMarker = drawMarker && (sourceLaneMarker == selectedMarker || markerIsHovered); if (drawMarker) { if (highlightMarker) { sourceLaneMarker.radius = 2f; } else { sourceLaneMarker.radius = 1f; } } else { markerIsHovered = false; } if (markerIsHovered) { /*if (hoveredMarker != sourceLaneMarker) * Log._Debug($"Marker @ lane {sourceLaneMarker.laneId} hovered");*/ hoveredMarker = sourceLaneMarker; } if (drawMarker) { RenderManager.instance.OverlayEffect.DrawCircle(cameraInfo, sourceLaneMarker.color, sourceLaneMarker.position, sourceLaneMarker.radius, -1f, 1280f, false, true); } } } } }
protected override void OnEnable() { base.OnEnable(); // hack to stop bug that disables and enables this tool the first time the panel is clicked if (Time.realtimeSinceStartup - time < 0.2f) { time = 0; return; } m_hoveredNode = m_hoveredSegment = 0; m_selectedNode = 0; m_selectedMarker = null; m_selectedLaneMarkers.Clear(); m_segments.Clear(); m_hoveredLaneMarkers.Clear(); if (OnEndLaneCustomization != null) OnEndLaneCustomization(); }
public override void OnPrimaryClickOverlay() { #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: OnPrimaryClickOverlay. SelectedNodeId={SelectedNodeId} SelectedSegmentId={SelectedSegmentId} HoveredNodeId={HoveredNodeId} HoveredSegmentId={HoveredSegmentId}"); #endif if (GetMarkerSelectionMode() == MarkerSelectionMode.None) { if (HoveredNodeId != 0) { #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: HoveredNode != 0"); #endif if (NetManager.instance.m_nodes.m_buffer[HoveredNodeId].CountSegments() < 2) { // this node cannot be configured (dead end) #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: Node is a dead end"); #endif SelectedNodeId = 0; selectedMarker = null; return; } if (SelectedNodeId != HoveredNodeId) { #if DEBUGCONN Log._Debug($"Node {HoveredNodeId} has been selected. Creating markers."); #endif SelectedNodeId = HoveredNodeId; selectedMarker = null; // selected node has changed. create markers //this.allNodeMarkers[SelectedNodeId] = GetNodeMarkers(SelectedNodeId); } } else { #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: Node {SelectedNodeId} has been deselected."); #endif // click on free spot. deselect node SelectedNodeId = 0; selectedMarker = null; return; } } if (hoveredMarker != null) { #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: hoveredMarker != null. selMode={GetMarkerSelectionMode()}"); #endif // hovered marker has been clicked if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource) { // select source marker selectedMarker = hoveredMarker; #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: set selected marker"); #endif } else if (GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) { // select target marker //bool success = false; if (Singleton <LaneConnectionManager> .instance.RemoveLaneConnection(selectedMarker.laneId, hoveredMarker.laneId, selectedMarker.startNode)) // try to remove connection { selectedMarker.connectedMarkers.Remove(hoveredMarker); #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: removed lane connection: {selectedMarker.laneId}, {hoveredMarker.laneId}"); #endif //success = true; } else if (Singleton <LaneConnectionManager> .instance.AddLaneConnection(selectedMarker.laneId, hoveredMarker.laneId, selectedMarker.startNode)) // try to add connection { selectedMarker.connectedMarkers.Add(hoveredMarker); #if DEBUGCONN Log._Debug($"TppLaneConnectorTool: added lane connection: {selectedMarker.laneId}, {hoveredMarker.laneId}"); #endif //success = true; } /*if (success) { * // connection has been modified. switch back to source marker selection * Log._Debug($"TppLaneConnectorTool: switch back to source marker selection"); * selectedMarker = null; * selMode = MarkerSelectionMode.SelectSource; * }*/ } } }
bool IsActive(NodeLaneMarker marker) { if (m_selectedMarker != null && (marker.m_isSource || NetManager.instance.m_lanes.m_buffer[m_selectedMarker.m_lane].m_segment == NetManager.instance.m_lanes.m_buffer[marker.m_lane].m_segment)) return false; else if (m_selectedMarker == null && !marker.m_isSource) return false; return true; }
private void ShowOverlay(bool viewOnly, RenderManager.CameraInfo cameraInfo) { if (viewOnly && !Options.connectedLanesOverlay) { return; } NetManager netManager = Singleton <NetManager> .instance; Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; // Bounds bounds = new Bounds(Vector3.zero, Vector3.one); Camera currentCamera = Camera.main; Ray mouseRay = currentCamera.ScreenPointToRay(Input.mousePosition); // Check if camera pos/angle has changed then re-filter the visible nodes // Assumption: The states checked in this loop don't change while the tool is active var currentCameraState = new CameraTransformValue(currentCamera); if (!LastCachedCamera.Equals(currentCameraState)) { CachedVisibleNodeIds.Clear(); LastCachedCamera = currentCameraState; for (uint nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; } //--------------------------- // Check the connection class //--------------------------- // TODO refactor connection class check ItemClass connectionClass = NetManager.instance.m_nodes.m_buffer[nodeId].Info.GetConnectionClass(); if ((connectionClass == null) || !((connectionClass.m_service == ItemClass.Service.Road) || ((connectionClass.m_service == ItemClass.Service.PublicTransport) && ((connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain) || (connectionClass.m_subService == ItemClass.SubService.PublicTransportMetro) || (connectionClass.m_subService == ItemClass.SubService.PublicTransportMonorail))))) { continue; } //-------------------------- // Check the camera distance //-------------------------- Vector3 diff = NetManager.instance.m_nodes.m_buffer[nodeId].m_position - camPos; if (diff.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { continue; // do not draw if too distant } // Add CachedVisibleNodeIds.Add(nodeId); } } for (int cacheIndex = CachedVisibleNodeIds.Size - 1; cacheIndex >= 0; cacheIndex--) { var nodeId = CachedVisibleNodeIds.Values[cacheIndex]; List <NodeLaneMarker> nodeMarkers; bool hasMarkers = currentNodeMarkers.TryGetValue((ushort)nodeId, out nodeMarkers); if (!viewOnly && (GetMarkerSelectionMode() == MarkerSelectionMode.None)) { MainTool.DrawNodeCircle( cameraInfo, (ushort)nodeId, DefaultNodeMarkerColor, true); } if (!hasMarkers) { continue; } foreach (NodeLaneMarker laneMarker in nodeMarkers) { if (!Constants.ServiceFactory.NetService.IsLaneValid(laneMarker.LaneId)) { continue; } foreach (NodeLaneMarker targetLaneMarker in laneMarker.ConnectedMarkers) { // render lane connection from laneMarker to targetLaneMarker if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneMarker.LaneId)) { continue; } DrawLaneCurve( cameraInfo, laneMarker.Position, targetLaneMarker.Position, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, laneMarker.Color, Color.black); } if (viewOnly || (nodeId != SelectedNodeId)) { continue; } // bounds.center = laneMarker.position; // bounds.IntersectRay(mouseRay); bool markerIsHovered = IsLaneMarkerHovered(laneMarker, ref mouseRay); // draw source marker in source selection mode, // draw target marker (if segment turning angles are within bounds) and // selected source marker in target selection mode bool drawMarker = ((GetMarkerSelectionMode() == MarkerSelectionMode.SelectSource) && laneMarker.IsSource) || ((GetMarkerSelectionMode() == MarkerSelectionMode.SelectTarget) && ((laneMarker.IsTarget && ((laneMarker.VehicleType & selectedMarker.VehicleType) != VehicleInfo.VehicleType.None) && CheckSegmentsTurningAngle( selectedMarker.SegmentId, ref netManager.m_segments.m_buffer[selectedMarker.SegmentId], selectedMarker.StartNode, laneMarker.SegmentId, ref netManager.m_segments.m_buffer[laneMarker.SegmentId], laneMarker.StartNode)) || (laneMarker == selectedMarker))); // highlight hovered marker and selected marker bool highlightMarker = drawMarker && ((laneMarker == selectedMarker) || markerIsHovered); if (drawMarker) { laneMarker.Radius = highlightMarker ? 2f : 1f; } else { markerIsHovered = false; } if (markerIsHovered) { hoveredMarker = laneMarker; } var circleColor = laneMarker.IsTarget ? Color.white : laneMarker.Color; if (drawMarker) { RenderManager.instance.OverlayEffect.DrawCircle( cameraInfo, circleColor, laneMarker.Position, laneMarker.Radius, laneMarker.Position.y - 100f, // through all the geometry -100..100 laneMarker.Position.y + 100f, false, true); RenderManager.instance.OverlayEffect.DrawCircle( cameraInfo, Color.black, laneMarker.Position, laneMarker.Radius * 0.75f, // inner black laneMarker.Position.y - 100f, // through all the geometry -100..100 laneMarker.Position.y + 100f, false, false); } } // end foreach lanemarker in node markers } // end for node in all nodes }