/// <summary>
        ///  Intersects mouse ray with marker bounds.
        /// </summary>
        /// <returns><c>true</c>if mouse ray intersects with marker <c>false</c> otherwise</returns>
        internal bool IntersectRay()
        {
            Camera currentCamera = Camera.main;
            Ray    mouseRay      = currentCamera.ScreenPointToRay(Input.mousePosition);
            float  hitH          = TrafficManagerTool.GetAccurateHitHeight();

            Vector3 pos    = Position;
            float   mouseH = ModUI.GetTrafficManagerTool(false).MousePosition.y;

            if (hitH < mouseH - TrafficManagerTool.MAX_HIT_ERROR)
            {
                // For metros use projection on the terrain.
                pos = TerrainPosition;
            }
            else if (hitH - pos.y > TrafficManagerTool.MAX_HIT_ERROR)
            {
                // if marker is projected on road plane above then modify its height
                pos.y = hitH;
            }
            Bounds bounds = new Bounds(Vector3.zero, Vector3.one * Radius)
            {
                center = pos,
            };

            return(bounds.IntersectRay(mouseRay));
        }
        /// <summary>
        ///  Intersects mouse ray with marker bounds.
        /// </summary>
        /// <returns><c>true</c>if mouse ray intersects with marker <c>false</c> otherwise</returns>
        internal bool IntersectRay()
        {
            Ray   mouseRay = InGameUtil.Instance.CachedMainCamera.ScreenPointToRay(Input.mousePosition);
            float hitH     = TrafficManagerTool.GetAccurateHitHeight();

            Bounds bounds = new Bounds(Vector3.zero, Vector3.one * Radius)
            {
                center = Position
            };

            return(bounds.IntersectRay(mouseRay));
        }
Exemplo n.º 3
0
        /// <summary>
        ///  Intersects mouse ray with lane bounds.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="hitH">vertical hit position of the raycast</param>
        /// <param name="hitH">vertical raycast hit position.</param>
        internal bool IntersectRay()
        {
            Ray   mouseRay = InGameUtil.Instance.CachedMainCamera.ScreenPointToRay(Input.mousePosition);
            float hitH     = TrafficManagerTool.GetAccurateHitHeight();

            CalculateBounds(hitH);
            foreach (Bounds bounds in bounds)
            {
                if (bounds.IntersectRay(mouseRay))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        ///  Intersects mouse ray with lane bounds.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="hitH">vertical hit position of the raycast</param>
        /// <param name="hitH">vertical raycast hit position.</param>
        internal bool IntersectRay()
        {
            Camera currentCamera = Camera.main;
            Ray    mouseRay      = currentCamera.ScreenPointToRay(Input.mousePosition);
            float  hitH          = TrafficManagerTool.GetAccurateHitHeight();

            CalculateBounds(hitH);
            foreach (Bounds bounds in bounds)
            {
                if (bounds.IntersectRay(mouseRay))
                {
                    return(true);
                }
            }

            return(false);
        }
        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
        }
Exemplo n.º 7
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;

            // 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
        }