public void NotifyStartEndNode(ushort segmentId)
        {
            // notify observers of start node and end node (e.g. for separate traffic lights)
            ushort startNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode;
            ushort endNodeId   = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endNode;

            if (startNodeId != 0)
            {
                NodeGeometry.Get(startNodeId).NotifyObservers();
            }
            if (endNodeId != 0)
            {
                NodeGeometry.Get(endNodeId).NotifyObservers();
            }
        }
예제 #2
0
        public void NotifyStartEndNode(ushort segmentId)
        {
            // TODO this is hacky. Instead of notifying geometry observers we should add a seperate notification mechanic
            // notify observers of start node and end node (e.g. for separate traffic lights)
            ushort startNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode;
            ushort endNodeId   = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endNode;

            if (startNodeId != 0)
            {
                Constants.ManagerFactory.GeometryManager.MarkAsUpdated(NodeGeometry.Get(startNodeId));
            }
            if (endNodeId != 0)
            {
                Constants.ManagerFactory.GeometryManager.MarkAsUpdated(NodeGeometry.Get(endNodeId));
            }
        }
        public bool SetPrioritySign(ushort segmentId, bool startNode, PriorityType sign)
        {
            SegmentGeometry segGeo = SegmentGeometry.Get(segmentId);

            if (segGeo == null)
            {
                Log.Error($"PrioritySignsTool.SetPrioritySign: No geometry information available for segment {segmentId}");
                return(false);
            }
            ushort nodeId = segGeo.GetNodeId(startNode);

            // check for restrictions
            if (!MayNodeHavePrioritySigns(nodeId))
            {
                Log._Debug($"PrioritySignsTool.SetPrioritySign: MayNodeHavePrioritySigns({nodeId})=false");
                return(false);
            }

            bool success = TrafficPriorityManager.Instance.SetPrioritySign(segmentId, startNode, sign);

            Log._Debug($"PrioritySignsTool.SetPrioritySign: SetPrioritySign({segmentId}, {startNode}, {sign})={success}");
            if (success && (sign == PriorityType.Stop || sign == PriorityType.Yield))
            {
                // make all undefined segments a main road
                Log._Debug($"PrioritySignsTool.SetPrioritySign: flagging remaining segments at node {nodeId} as main road.");
                NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);
                foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
                {
                    if (endGeo == null)
                    {
                        continue;
                    }

                    if (endGeo.SegmentId == segmentId)
                    {
                        continue;
                    }

                    if (TrafficPriorityManager.Instance.GetPrioritySign(endGeo.SegmentId, endGeo.StartNode) == PriorityType.None)
                    {
                        Log._Debug($"PrioritySignsTool.SetPrioritySign: setting main priority sign for segment {endGeo.SegmentId} @ {nodeId}");
                        TrafficPriorityManager.Instance.SetPrioritySign(endGeo.SegmentId, endGeo.StartNode, PriorityType.Main);
                    }
                }
            }
            return(success);
        }
        /// <summary>
        /// Removes custom traffic lights at the given node
        /// </summary>
        /// <param name="nodeId"></param>
        public void RemoveNodeLights(ushort nodeId)
        {
            NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);

            /*if (!nodeGeo.IsValid())
             *      return;*/

            foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
            {
                if (endGeo == null)
                {
                    continue;
                }

                RemoveSegmentLight(endGeo.SegmentId, endGeo.StartNode);
            }
        }
        /// <summary>
        /// Add custom traffic lights at the given node
        /// </summary>
        /// <param name="nodeId"></param>
        public void AddNodeLights(ushort nodeId)
        {
            NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);

            if (!nodeGeo.IsValid())
            {
                return;
            }
            foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
            {
                if (endGeo == null)
                {
                    continue;
                }

                AddSegmentLights(endGeo.SegmentId, endGeo.StartNode);
            }
        }
        //private bool defaultPedestrianCrossingAllowed;

        public void UpdateDefaults(SegmentEndGeometry segmentEndGeometry)
        {
            NodeGeometry nodeGeo = NodeGeometry.Get(segmentEndGeometry.NodeId());

            bool newDefaultEnterWhenBlockedAllowed = false;

            NetNode.Flags _nodeFlags = NetNode.Flags.None;
            Constants.ServiceFactory.NetService.ProcessNode(segmentEndGeometry.NodeId(), delegate(ushort nodeId, ref NetNode node) {
                _nodeFlags      = node.m_flags;
                int numOutgoing = 0;
                int numIncoming = 0;
                node.CountLanes(nodeId, 0, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, true, ref numOutgoing, ref numIncoming);
                newDefaultEnterWhenBlockedAllowed = numOutgoing == 1 || numIncoming == 1;
                return(true);
            });
            defaultEnterWhenBlockedAllowed = newDefaultEnterWhenBlockedAllowed;
            //Log._Debug($"SegmentEndFlags.UpdateDefaults: this={this} _nodeFlags={_nodeFlags} defaultEnterWhenBlockedAllowed={defaultEnterWhenBlockedAllowed}");
        }
        /// <summary>
        /// Add custom traffic lights at the given node
        /// </summary>
        /// <param name="nodeId"></param>
        public void AddNodeLights(ushort nodeId)
        {
            NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);

            if (!nodeGeo.IsValid())
            {
                return;
            }

            foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
            {
                if (endGeo == null)
                {
                    continue;
                }

                AddSegmentLights(endGeo.SegmentId, endGeo.StartNode);

                DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, "Adding to Queue: " + nodeId);
                NetworkInterface.Network.UpdateSelectedIds(nodeId);
            }
        }
예제 #8
0
        /// <summary>
        /// Recalculates lane arrows based on present lane connections.
        /// </summary>
        /// <param name="laneId"></param>
        /// <param name="nodeId"></param>
        private void RecalculateLaneArrows(uint laneId, ushort nodeId, bool startNode)
        {
#if DEBUGCONN
            Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}) called");
#endif
            if (!Options.laneConnectorEnabled)
            {
                return;
            }

            if (!Flags.mayHaveLaneArrows(laneId, startNode))
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId}, startNode? {startNode} must not have lane arrows");
#endif
                return;
            }

            if (!HasConnections(laneId, startNode))
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId} does not have outgoing connections");
#endif
                return;
            }

            if (nodeId == 0)
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node");
#endif
                return;
            }

            Flags.LaneArrows arrows = Flags.LaneArrows.None;

            NetManager netManager = Singleton <NetManager> .instance;
            ushort     segmentId  = netManager.m_lanes.m_buffer[laneId].m_segment;

            if (segmentId == 0)
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment");
#endif
                return;
            }

#if DEBUGCONN
            Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): startNode? {startNode}");
#endif

            NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);
            if (!nodeGeo.IsValid())
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node geometry");
#endif
                return;
            }

            SegmentGeometry segmentGeo = SegmentGeometry.Get(segmentId);
            if (segmentGeo == null)
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment geometry");
#endif
                return;
            }

            ushort[] connectedSegmentIds = segmentGeo.GetConnectedSegments(startNode);
            if (connectedSegmentIds == null)
            {
#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): connectedSegmentIds is null");
#endif
                return;
            }
            ushort[] allSegmentIds = new ushort[connectedSegmentIds.Length + 1];
            allSegmentIds[0] = segmentId;
            Array.Copy(connectedSegmentIds, 0, allSegmentIds, 1, connectedSegmentIds.Length);

            foreach (ushort otherSegmentId in allSegmentIds)
            {
                if (otherSegmentId == 0)
                {
                    continue;
                }
                ArrowDirection dir = segmentGeo.GetDirection(otherSegmentId, startNode);

#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}. dir={dir}");
#endif

                // check if arrow has already been set for this direction
                switch (dir)
                {
                case ArrowDirection.Turn:
                    if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                    {
                        if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None)
                        {
                            continue;
                        }
                    }
                    break;

                case ArrowDirection.Forward:
                    if ((arrows & Flags.LaneArrows.Forward) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                case ArrowDirection.Left:
                    if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                case ArrowDirection.Right:
                    if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                default:
                    continue;
                }

#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: need to determine arrows");
#endif

                bool addArrow = false;

                uint curLaneId = netManager.m_segments.m_buffer[otherSegmentId].m_lanes;
                while (curLaneId != 0)
                {
#if DEBUGCONN
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: checking lane {curLaneId}");
#endif
                    if (AreLanesConnected(laneId, curLaneId, startNode))
                    {
#if DEBUGCONN
                        Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: checking lane {curLaneId}: lanes are connected");
#endif
                        addArrow = true;
                        break;
                    }

                    curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
                }

#if DEBUGCONN
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: finished processing lanes. addArrow={addArrow} arrows (before)={arrows}");
#endif
                if (addArrow)
                {
                    switch (dir)
                    {
                    case ArrowDirection.Turn:
                        if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                        {
                            arrows |= Flags.LaneArrows.Right;
                        }
                        else
                        {
                            arrows |= Flags.LaneArrows.Left;
                        }
                        break;

                    case ArrowDirection.Forward:
                        arrows |= Flags.LaneArrows.Forward;
                        break;

                    case ArrowDirection.Left:
                        arrows |= Flags.LaneArrows.Left;
                        break;

                    case ArrowDirection.Right:
                        arrows |= Flags.LaneArrows.Right;
                        break;

                    default:
                        continue;
                    }

#if DEBUGCONN
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: arrows={arrows}");
#endif
                }
            }

#if DEBUGCONN
            Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): setting lane arrows to {arrows}");
#endif

            LaneArrowManager.Instance.SetLaneArrows(laneId, arrows, true);
        }
예제 #9
0
        public override void OnToolGUI(Event e)
        {
            var hoveredSegment = false;

            if (SelectedNodeId != 0)
            {
                CustomSegmentLightsManager    customTrafficLightsManager = CustomSegmentLightsManager.Instance;
                TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance;

                var nodeSimulation = tlsMan.GetNodeSimulation(SelectedNodeId);
                if (nodeSimulation == null || !nodeSimulation.IsManualLight())
                {
                    return;
                }
                nodeSimulation.housekeeping();

                /*if (Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode].CountSegments() == 2) {
                 *      _guiManualTrafficLightsCrosswalk(ref Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode]);
                 *      return;
                 * }*/// TODO check

                NodeGeometry nodeGeometry = NodeGeometry.Get(SelectedNodeId);
                foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
                {
                    if (end == null)
                    {
                        continue;
                    }

                    var position      = CalculateNodePositionForSegment(Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId], ref Singleton <NetManager> .instance.m_segments.m_buffer[end.SegmentId]);
                    var segmentLights = customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode, false);
                    if (segmentLights == null)
                    {
                        continue;
                    }

                    var screenPos = Camera.main.WorldToScreenPoint(position);
                    screenPos.y = Screen.height - screenPos.y;

                    if (screenPos.z < 0)
                    {
                        continue;
                    }

                    var diff = position - Camera.main.transform.position;
                    var zoom = 1.0f / diff.magnitude * 100f;

                    // original / 2.5
                    var lightWidth  = 41f * zoom;
                    var lightHeight = 97f * zoom;

                    var pedestrianWidth  = 36f * zoom;
                    var pedestrianHeight = 61f * zoom;

                    // SWITCH MODE BUTTON
                    var modeWidth  = 41f * zoom;
                    var modeHeight = 38f * zoom;

                    var guiColor = GUI.color;

                    if (segmentLights.PedestrianLightState != null)
                    {
                        // pedestrian light

                        // SWITCH MANUAL PEDESTRIAN LIGHT BUTTON
                        hoveredSegment = RenderManualPedestrianLightSwitch(zoom, end.SegmentId, screenPos, lightWidth, segmentLights, hoveredSegment);

                        // SWITCH PEDESTRIAN LIGHT
                        guiColor.a = _hoveredButton[0] == end.SegmentId && _hoveredButton[1] == 2 && segmentLights.ManualPedestrianMode ? 0.92f : 0.6f;
                        GUI.color  = guiColor;

                        var myRect3 = new Rect(screenPos.x - pedestrianWidth / 2 - lightWidth + 5f * zoom, screenPos.y - pedestrianHeight / 2 + 22f * zoom, pedestrianWidth, pedestrianHeight);

                        switch (segmentLights.PedestrianLightState)
                        {
                        case RoadBaseAI.TrafficLightState.Green:
                            GUI.DrawTexture(myRect3, TrafficLightToolTextureResources.PedestrianGreenLightTexture2D);
                            break;

                        case RoadBaseAI.TrafficLightState.Red:
                        default:
                            GUI.DrawTexture(myRect3, TrafficLightToolTextureResources.PedestrianRedLightTexture2D);
                            break;
                        }

                        hoveredSegment = IsPedestrianLightHovered(myRect3, end.SegmentId, hoveredSegment, segmentLights);
                    }

                    int lightOffset = -1;
                    foreach (ExtVehicleType vehicleType in segmentLights.VehicleTypes)
                    {
                        ++lightOffset;
                        CustomSegmentLight segmentLight = segmentLights.GetCustomLight(vehicleType);

                        Vector3 offsetScreenPos = screenPos;
                        offsetScreenPos.y -= (lightHeight + 10f * zoom) * lightOffset;

                        SetAlpha(end.SegmentId, -1);

                        var myRect1 = new Rect(offsetScreenPos.x - modeWidth / 2, offsetScreenPos.y - modeHeight / 2 + modeHeight - 7f * zoom, modeWidth, modeHeight);

                        GUI.DrawTexture(myRect1, TrafficLightToolTextureResources.LightModeTexture2D);

                        hoveredSegment = GetHoveredSegment(myRect1, end.SegmentId, hoveredSegment, segmentLight);

                        // COUNTER
                        hoveredSegment = RenderCounter(end.SegmentId, offsetScreenPos, modeWidth, modeHeight, zoom, segmentLights, hoveredSegment);

                        if (lightOffset > 0)
                        {
                            // Info sign
                            var infoWidth  = 56.125f * zoom;
                            var infoHeight = 51.375f * zoom;

                            int numInfos = 0;
                            for (int k = 0; k < TrafficManagerTool.InfoSignsToDisplay.Length; ++k)
                            {
                                if ((TrafficManagerTool.InfoSignsToDisplay[k] & vehicleType) == ExtVehicleType.None)
                                {
                                    continue;
                                }
                                var infoRect = new Rect(offsetScreenPos.x + modeWidth / 2f + 7f * zoom * (float)(numInfos + 1) + infoWidth * (float)numInfos, offsetScreenPos.y - infoHeight / 2f, infoWidth, infoHeight);
                                guiColor.a = 0.6f;
                                GUI.DrawTexture(infoRect, TrafficLightToolTextureResources.VehicleInfoSignTextures[TrafficManagerTool.InfoSignsToDisplay[k]]);
                                ++numInfos;
                            }
                        }

                        if (end.OutgoingOneWay)
                        {
                            continue;
                        }

                        var hasLeftSegment    = end.NumLeftSegments > 0;
                        var hasForwardSegment = end.NumStraightSegments > 0;
                        var hasRightSegment   = end.NumRightSegments > 0;

                        switch (segmentLight.CurrentMode)
                        {
                        case CustomSegmentLight.Mode.Simple:
                            hoveredSegment = SimpleManualSegmentLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            break;

                        case CustomSegmentLight.Mode.SingleLeft:
                            hoveredSegment = LeftForwardRManualSegmentLightMode(hasLeftSegment, end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment, hasForwardSegment, hasRightSegment);
                            break;

                        case CustomSegmentLight.Mode.SingleRight:
                            hoveredSegment = RightForwardLSegmentLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, hasForwardSegment, hasLeftSegment, segmentLight, hasRightSegment, hoveredSegment);
                            break;

                        default:
                            // left arrow light
                            if (hasLeftSegment)
                            {
                                hoveredSegment = LeftArrowLightMode(end.SegmentId, lightWidth, hasRightSegment, hasForwardSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }

                            // forward arrow light
                            if (hasForwardSegment)
                            {
                                hoveredSegment = ForwardArrowLightMode(end.SegmentId, lightWidth, hasRightSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }

                            // right arrow light
                            if (hasRightSegment)
                            {
                                hoveredSegment = RightArrowLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }
                            break;
                        }
                    }
                }
            }

            if (hoveredSegment)
            {
                return;
            }
            _hoveredButton[0] = 0;
            _hoveredButton[1] = 0;
        }
        public void ShowGUI(bool viewOnly)
        {
            try {
                TrafficLightSimulationManager tlsMan  = TrafficLightSimulationManager.Instance;
                TrafficPriorityManager        prioMan = TrafficPriorityManager.Instance;
                TrafficLightManager           tlm     = TrafficLightManager.Instance;

                Vector3 camPos = Constants.ServiceFactory.SimulationService.CameraPosition;

                bool clicked = !viewOnly?MainTool.CheckClicked() : false;

                ushort removedNodeId    = 0;
                bool   showRemoveButton = false;
                foreach (ushort nodeId in currentPriorityNodeIds)
                {
                    if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId))
                    {
                        continue;
                    }

                    if (!MainTool.IsNodeWithinViewDistance(nodeId))
                    {
                        continue;
                    }

                    NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);

                    Vector3 nodePos = default(Vector3);
                    Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) {
                        nodePos = node.m_position;
                        return(true);
                    });

                    foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
                    {
                        if (endGeo == null)
                        {
                            continue;
                        }
                        if (endGeo.OutgoingOneWay)
                        {
                            continue;
                        }
                        ushort segmentId = endGeo.SegmentId;
                        bool   startNode = endGeo.StartNode;

                        // calculate sign position
                        Vector3 signPos = nodePos;

                        Constants.ServiceFactory.NetService.ProcessSegment(segmentId, delegate(ushort sId, ref NetSegment segment) {
                            signPos += 10f * (startNode ? segment.m_startDirection : segment.m_endDirection);
                            return(true);
                        });

                        Vector3 signScreenPos;
                        if (!MainTool.WorldToScreenPoint(signPos, out signScreenPos))
                        {
                            continue;
                        }

                        // draw sign and handle input
                        PriorityType sign = prioMan.GetPrioritySign(segmentId, startNode);
                        if (viewOnly && sign == PriorityType.None)
                        {
                            continue;
                        }
                        if (!viewOnly && sign != PriorityType.None)
                        {
                            showRemoveButton = true;
                        }

                        if (MainTool.DrawGenericSquareOverlayTexture(TextureResources.PrioritySignTextures[sign], camPos, signPos, 90f, !viewOnly) && clicked)
                        {
                            PriorityType?newSign = null;
                            switch (sign)
                            {
                            case PriorityType.Main:
                                newSign = PriorityType.Yield;
                                break;

                            case PriorityType.Yield:
                                newSign = PriorityType.Stop;
                                break;

                            case PriorityType.Stop:
                                newSign = PriorityType.Main;
                                break;

                            case PriorityType.None:
                            default:
                                newSign = prioMan.CountPrioritySignsAtNode(nodeId, PriorityType.Main) >= 2 ? PriorityType.Yield : PriorityType.Main;
                                break;
                            }

                            if (newSign != null)
                            {
                                SetPrioritySign(segmentId, startNode, (PriorityType)newSign);
                            }
                        }                 // draw sign
                    }                     // foreach segment end

                    if (viewOnly)
                    {
                        continue;
                    }

                    // draw remove button and handle click
                    if (showRemoveButton && MainTool.DrawHoverableSquareOverlayTexture(TextureResources.SignRemoveTexture2D, camPos, nodePos, 90f) && clicked)
                    {
                        prioMan.RemovePrioritySignsFromNode(nodeId);
                        Log._Debug($"PrioritySignsTool.ShowGUI: Removed priority signs from node {nodeId}");
                        removedNodeId = nodeId;
                    }
                }                 // foreach node

                if (removedNodeId != 0)
                {
                    currentPriorityNodeIds.Remove(removedNodeId);
                    SelectedNodeId = 0;
                }
            } catch (Exception e) {
                Log.Error(e.ToString());
            }
        }
예제 #11
0
        public void SimulationStep(bool onlyFirstPass = false)
        {
#if DEBUGGEO
            bool debug = GlobalConfig.Instance.Debug.Switches[5];
#endif
            if (!stateUpdated)
            {
                return;
            }

            NetManager netManager = Singleton <NetManager> .instance;
            if (!onlyFirstPass && (netManager.m_segmentsUpdated || netManager.m_nodesUpdated))               // TODO maybe refactor NetManager use (however this could influence performance)
            {
#if DEBUGGEO
                if (debug)
                {
                    Log._Debug($"GeometryManager.SimulationStep(): Skipping! stateUpdated={stateUpdated}, m_segmentsUpdated={netManager.m_segmentsUpdated}, m_nodesUpdated={netManager.m_nodesUpdated}");
                }
#endif
                return;
            }

            try {
                Monitor.Enter(updateLock);

                bool updatesMissing = onlyFirstPass;
                for (int pass = 0; pass < (onlyFirstPass ? 1 : 2); ++pass)
                {
                    bool firstPass = pass == 0;

                    int len = updatedSegmentBuckets.Length;
                    for (int i = 0; i < len; i++)
                    {
                        ulong segMask = updatedSegmentBuckets[i];
                        if (segMask != 0uL)
                        {
                            for (int m = 0; m < 64; m++)
                            {
                                if ((segMask & 1uL << m) != 0uL)
                                {
                                    ushort          segmentId       = (ushort)(i << 6 | m);
                                    SegmentGeometry segmentGeometry = SegmentGeometry.Get(segmentId, true);
                                    if (firstPass ^ !segmentGeometry.IsValid())
                                    {
                                        if (!firstPass)
                                        {
                                            updatesMissing = true;
#if DEBUGGEO
                                            if (debug)
                                            {
                                                Log.Warning($"GeometryManager.SimulationStep(): Detected invalid segment {segmentGeometry.SegmentId} in second pass");
                                            }
#endif
                                        }
                                        continue;
                                    }
#if DEBUGGEO
                                    if (debug)
                                    {
                                        Log._Debug($"GeometryManager.SimulationStep(): Notifying observers about segment {segmentGeometry.SegmentId}. Valid? {segmentGeometry.IsValid()} First pass? {firstPass}");
                                    }
#endif
                                    NotifyObservers(new GeometryUpdate(segmentGeometry));
                                    updatedSegmentBuckets[i] &= ~(1uL << m);
                                }
                            }
                        }
                    }

                    len = updatedNodeBuckets.Length;
                    for (int i = 0; i < len; i++)
                    {
                        ulong nodeMask = updatedNodeBuckets[i];
                        if (nodeMask != 0uL)
                        {
                            for (int m = 0; m < 64; m++)
                            {
                                if ((nodeMask & 1uL << m) != 0uL)
                                {
                                    ushort       nodeId       = (ushort)(i << 6 | m);
                                    NodeGeometry nodeGeometry = NodeGeometry.Get(nodeId);
                                    if (firstPass ^ !nodeGeometry.IsValid())
                                    {
                                        if (!firstPass)
                                        {
                                            updatesMissing = true;
#if DEBUGGEO
                                            if (debug)
                                            {
                                                Log.Warning($"GeometryManager.SimulationStep(): Detected invalid node {nodeGeometry.NodeId} in second pass");
                                            }
#endif
                                        }
                                        continue;
                                    }
#if DEBUGGEO
                                    if (debug)
                                    {
                                        Log._Debug($"GeometryManager.SimulationStep(): Notifying observers about node {nodeGeometry.NodeId}. Valid? {nodeGeometry.IsValid()} First pass? {firstPass}");
                                    }
#endif
                                    NotifyObservers(new GeometryUpdate(nodeGeometry));
                                    updatedNodeBuckets[i] &= ~(1uL << m);
                                }
                            }
                        }
                    }
                }

                if (!updatesMissing)
                {
                    while (segmentReplacements.Count > 0)
                    {
                        SegmentEndReplacement replacement = segmentReplacements.Dequeue();
#if DEBUGGEO
                        if (debug)
                        {
                            Log._Debug($"GeometryManager.SimulationStep(): Notifying observers about segment end replacement {replacement}");
                        }
#endif
                        NotifyObservers(new GeometryUpdate(replacement));
                    }

                    stateUpdated = false;
                }
            } finally {
                Monitor.Exit(updateLock);
            }
        }