public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { if (MainTool.GetToolController().IsInsideUI || !Cursor.visible) { return; } // For current camera store its position and cast a ray via mouse position Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; // 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(InGameUtil.Instance.CachedMainCamera); if (!LastCachedCamera.Equals(currentCameraState)) { CachedVisibleNodeIds.Clear(); LastCachedCamera = currentCameraState; FilterVisibleNodes(camPos); } // Render the current hovered node as blue if ((HoveredNodeId != 0) && Flags.MayHaveTrafficLight(HoveredNodeId)) { MainTool.DrawNodeCircle( cameraInfo, HoveredNodeId, Input.GetMouseButton(0), false); } }
/// <summary> /// For all nodes find those which are potentially visible, and not too far from the camera /// </summary> /// <param name="camPos">Position of the camera</param> private void FilterVisibleNodes(Vector3 camPos) { for (ushort nodeId = 1; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { continue; } //--------------------------------------- // If cannot have a traffic light at all //--------------------------------------- if (!Flags.MayHaveTrafficLight(nodeId)) { continue; } //-------------------------------------------- // Only allow traffic lights on normal roads, not rail or metro etc. //-------------------------------------------- ItemClass connectionClass = NetManager.instance.m_nodes.m_buffer[nodeId].Info.GetConnectionClass(); if ((connectionClass == null) || (connectionClass.m_service != ItemClass.Service.Road)) { 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); } }
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 || 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; // 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]; bool hasMarkers = currentLaneEnds.TryGetValue((ushort)nodeId, out List <LaneEnd> laneEnds); if (!viewOnly && (GetSelectionMode() == SelectionMode.None)) { MainTool.DrawNodeCircle( cameraInfo, (ushort)nodeId, DefaultLaneEndColor, true); } if (!hasMarkers) { continue; } foreach (LaneEnd laneEnd in laneEnds) { if (!Constants.ServiceFactory.NetService.IsLaneValid(laneEnd.LaneId)) { continue; } if (laneEnd != selectedLaneEnd) { foreach (LaneEnd targetLaneEnd in laneEnd.ConnectedLaneEnds) { // render lane connection from laneEnd to targetLaneEnd if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneEnd.LaneId)) { continue; } DrawLaneCurve( cameraInfo, laneEnd.NodeMarker.TerrainPosition, targetLaneEnd.NodeMarker.TerrainPosition, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, laneEnd.Color, Color.black); } } if (viewOnly || (nodeId != SelectedNodeId)) { continue; } bool drawMarker = false; bool SourceMode = GetSelectionMode() == SelectionMode.SelectSource; bool TargetMode = GetSelectionMode() == SelectionMode.SelectTarget; if (SourceMode & laneEnd.IsSource) { // draw source marker in source selection mode, // make exception for markers that have no target: foreach (var targetLaneEnd in laneEnds) { if (CanConnect(laneEnd, targetLaneEnd)) { drawMarker = true; break; } } } else if (TargetMode) { // selected source marker in target selection mode drawMarker = selectedLaneEnd == laneEnd || CanConnect(selectedLaneEnd, laneEnd); } // highlight hovered marker and selected marker if (drawMarker) { bool markerIsHovered = false; if (hoveredLaneEnd == null) { float hitH = TrafficManagerTool.GetAccurateHitHeight(); markerIsHovered = laneEnd.IntersectRay(); if (markerIsHovered) { hoveredLaneEnd = laneEnd; } } bool isTarget = selectedLaneEnd != null && laneEnd != selectedLaneEnd; var color = isTarget ? Color.white : laneEnd.Color; bool highlightMarker = laneEnd == selectedLaneEnd || markerIsHovered; laneEnd.RenderOverlay(cameraInfo, color, highlightMarker); } // if drawMarker if (selectedLaneEnd != null) { // lane curves for selectedMarker will be drawn last to // be on the top of other lane markers. foreach (LaneEnd targetLaneEnd in selectedLaneEnd.ConnectedLaneEnds) { if (!Constants.ServiceFactory.NetService.IsLaneValid(targetLaneEnd.LaneId)) { continue; } DrawLaneCurve( cameraInfo, selectedLaneEnd.NodeMarker.TerrainPosition, targetLaneEnd.NodeMarker.TerrainPosition, NetManager.instance.m_nodes.m_buffer[nodeId].m_position, selectedLaneEnd.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; 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 }