Ejemplo n.º 1
0
        public override void OnActivate()
        {
#if DEBUG
            bool logLaneConn = DebugSwitch.LaneConnections.Get();
            if (logLaneConn)
            {
                Log._Debug("LaneConnectorTool: OnActivate");
            }
#endif
            SelectedNodeId  = 0;
            selectedLaneEnd = null;
            hoveredLaneEnd  = null;
            stayInLaneMode  = StayInLaneMode.None;
            RefreshCurrentNodeMarkers();
        }
Ejemplo n.º 2
0
        public override void OnSecondaryClickOverlay()
        {
#if DEBUG
            bool logLaneConn = DebugSwitch.LaneConnections.Get();
#else
            const bool logLaneConn = false;
#endif

            if (IsCursorInPanel())
            {
                return;
            }

            switch (GetSelectionMode())
            {
            // also: case MarkerSelectionMode.None:
            default: {
                Log._DebugIf(
                    logLaneConn,
                    () => "LaneConnectorTool: OnSecondaryClickOverlay: nothing to do");
                stayInLaneMode = StayInLaneMode.None;
                break;
            }

            case SelectionMode.SelectSource: {
                // deselect node
                Log._DebugIf(
                    logLaneConn,
                    () => "LaneConnectorTool: OnSecondaryClickOverlay: selected node id = 0");
                SelectedNodeId = 0;
                break;
            }

            case SelectionMode.SelectTarget: {
                // deselect source marker
                Log._DebugIf(
                    logLaneConn,
                    () => "LaneConnectorTool: OnSecondaryClickOverlay: switch to selected source mode");
                selectedLaneEnd = null;
                break;
            }
            }
        }
Ejemplo n.º 3
0
        private bool CanConnect(LaneEnd source, LaneEnd target)
        {
            bool ret = source != target && source.IsSource && target.IsTarget;

            ret &= (target.VehicleType & source.VehicleType) != 0;

            bool IsRoad(LaneEnd laneEnd) =>
            (laneEnd.LaneType & LaneArrowManager.LANE_TYPES) != 0 &&
            (laneEnd.VehicleType & LaneArrowManager.VEHICLE_TYPES) != 0;

            // turning angle does not apply to roads.
            bool isRoad = IsRoad(source) && IsRoad(target);

            // checktrack turning angles are within bounds
            ret &= isRoad || CheckSegmentsTurningAngle(
                source.SegmentId,
                ref GetSeg(source.SegmentId),
                source.StartNode,
                target.SegmentId,
                ref GetSeg(target.SegmentId),
                target.StartNode);

            return(ret);
        }
Ejemplo n.º 4
0
        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 (GetSelectionMode() == SelectionMode.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;
                        selectedLaneEnd = 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 <LaneEnd> laneEnds = GetLaneEnds(
                            HoveredNodeId,
                            ref Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId]);

                        if (laneEnds != null)
                        {
                            SelectedNodeId  = HoveredNodeId;
                            selectedLaneEnd = null;
                            stayInLaneMode  = StayInLaneMode.None;

                            currentLaneEnds[SelectedNodeId] = laneEnds;
                        }

                        // this.allNodeMarkers[SelectedNodeId] = GetNodeMarkers(SelectedNodeId);
                    }
                }
                else
                {
                    Log._DebugIf(
                        logLaneConn,
                        () => $"LaneConnectorTool: Node {SelectedNodeId} has been deselected.");

                    // click on free spot. deselect node
                    SelectedNodeId  = 0;
                    selectedLaneEnd = null;
                    stayInLaneMode  = StayInLaneMode.None;
                    return;
                }
            }

            if (hoveredLaneEnd == null)
            {
                return;
            }

            //-----------------------------------
            // Hovered Marker
            //-----------------------------------
            stayInLaneMode = StayInLaneMode.None;

            Log._DebugIf(
                logLaneConn,
                () => $"LaneConnectorTool: hoveredMarker != null. selMode={GetSelectionMode()}");

            // hovered marker has been clicked
            if (GetSelectionMode() == SelectionMode.SelectSource)
            {
                // select source marker
                selectedLaneEnd = hoveredLaneEnd;
                Log._DebugIf(
                    logLaneConn,
                    () => "LaneConnectorTool: set selected marker");
            }
            else if (GetSelectionMode() == SelectionMode.SelectTarget)
            {
                // select target marker
                // bool success = false;
                if (LaneConnectionManager.Instance.RemoveLaneConnection(
                        selectedLaneEnd.LaneId,
                        hoveredLaneEnd.LaneId,
                        selectedLaneEnd.StartNode))
                {
                    // try to remove connection
                    selectedLaneEnd.ConnectedLaneEnds.Remove(hoveredLaneEnd);
                    Log._DebugIf(
                        logLaneConn,
                        () => $"LaneConnectorTool: removed lane connection: {selectedLaneEnd.LaneId}, " +
                        $"{hoveredLaneEnd.LaneId}");

                    // success = true;
                }
                else if (LaneConnectionManager.Instance.AddLaneConnection(
                             selectedLaneEnd.LaneId,
                             hoveredLaneEnd.LaneId,
                             selectedLaneEnd.StartNode))
                {
                    // try to add connection
                    selectedLaneEnd.ConnectedLaneEnds.Add(hoveredLaneEnd);
                    Log._DebugIf(
                        logLaneConn,
                        () => $"LaneConnectorTool: added lane connection: {selectedLaneEnd.LaneId}, " +
                        $"{hoveredLaneEnd.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;
                 *  }*/
            }
        }
Ejemplo n.º 5
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
            hoveredLaneEnd = null;

            ShowOverlay(false, cameraInfo);

            // draw bezier from source marker to mouse position in target marker selection
            if (SelectedNodeId != 0)
            {
                if (GetSelectionMode() == SelectionMode.SelectTarget)
                {
                    Vector3 selNodePos =
                        NetManager.instance.m_nodes.m_buffer[SelectedNodeId].m_position;

                    // Draw a currently dragged curve
                    var pos = HitPos;
                    if (hoveredLaneEnd == null)
                    {
                        float hitH = TrafficManagerTool.GetAccurateHitHeight();
                        pos.y = hitH; // fix height.
                        float mouseH = MousePosition.y;
                        if (hitH < mouseH - TrafficManagerTool.MAX_HIT_ERROR)
                        {
                            // for metros lane curve is projected on the ground.
                            pos = MousePosition;
                        }
                    }
                    else
                    {
                        // snap to hovered:
                        pos = hoveredLaneEnd.NodeMarker.TerrainPosition;
                    }
                    DrawLaneCurve(
                        cameraInfo,
                        selectedLaneEnd.NodeMarker.TerrainPosition,
                        pos,
                        selNodePos,
                        Color.Lerp(selectedLaneEnd.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)
                    {
                        selectedLaneEnd = null;
                        StayInLane(SelectedNodeId, stayInLaneMode);
                        RefreshCurrentNodeMarkers(SelectedNodeId);
                    }
                } // if stay in lane
            }     // if selected node

            if ((GetSelectionMode() == SelectionMode.None) && (HoveredNodeId != 0))
            {
                // draw hovered node
                MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0));
            }
        }
Ejemplo n.º 6
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
        }