public void PreProcess(ref LaneInfo inLanes, ref JunctionInfo nodeInfo) { int inLaneCount = inLanes.GetLaneCount(); int inBusLaneCount = inLanes.GetBusLaneCount(); if (inLaneCount == inBusLaneCount) { //If all IN lanes are bus lanes, all IN and OUT lanes are treated as normal car lanes. return; } int outLaneCount = nodeInfo.GetLaneCount(); int outBusLaneCount = nodeInfo.GetBusLaneCount(); if (outLaneCount == outBusLaneCount) { //If all OUT lanes are bus lanes, all IN and OUT lanes are also treated as normal car lanes. return; } // If the number of IN car lanes is greater than OUT car lanes, then OUT bus lanes are also treated as normal car lanes. bool applyOutLaneRules = (inLaneCount - inBusLaneCount) <= (outLaneCount - outBusLaneCount); // Pre-process IN lanes int i = 0; var posToRemove = new List <float>(); foreach (var lane in inLanes.lanes) { if (inLanes.busLaneIds.Contains(lane.Value)) { inBusLanes.Add(lane.Key, lane.Value); inBusLaneIndices.Add(i); inLanes.busLaneIds.Remove(lane.Value); posToRemove.Add(lane.Key); } i += 1; } foreach (var pos in posToRemove) { inLanes.lanes.Remove(pos); } // Pre-process OUT lanes if (applyOutLaneRules) { outBusLaneIndices = nodeInfo.GetBusLaneIndices(); outBusLaneDirections = nodeInfo.RemoveLanes(outBusLaneIndices); } }
public void AddLanes(LaneInfo laneInfo, float angleDeg) { if (roads.ContainsKey(angleDeg)) { // Two roads with same angle, could be Road Anarchy + Vanilla Overpass Project roads[angleDeg].MergeWith(laneInfo); } else { roads.Add(angleDeg, laneInfo); } laneCounts[GetDirectionFromAngle(angleDeg)] += laneInfo.lanes.Count; }
public void MergeWith(LaneInfo other) { foreach (var otherLane in other.lanes) { var otherLanePos = otherLane.Key; while (lanes.ContainsKey(otherLanePos)) { otherLanePos += 1e-7f; } lanes.Add(otherLanePos, otherLane.Value); } foreach (var otherBusLaneId in other.busLaneIds) { busLaneIds.Add(otherBusLaneId); } }
public static void AssignLanes(LaneInfo inLanes, Vector3 outVector, ushort segmentID, ushort nodeID, NetNode junctionNode, bool lht) { var nodeInfo = AnalyseNode(junctionNode, nodeID, segmentID, vehicleLaneTypes, VehicleInfo.VehicleType.Car, outVector); if (nodeInfo.GetLaneCount() == 0) { // This can happen if multiple one-way roads meet creating a dead end. return; } if (lht) { inLanes.Mirror(); nodeInfo.Mirror(); } var busLaneHandler = new BusLaneHandler(); busLaneHandler.PreProcess(ref inLanes, ref nodeInfo); AdjustSharpTurns(inLanes.GetLaneCount(), ref nodeInfo); List <LaneConnectionInfo> lanesInfo = AssignLanes(inLanes.lanes.Count, nodeInfo.laneCounts[Direction.Left], nodeInfo.laneCounts[Direction.Forward], nodeInfo.laneCounts[Direction.Right]); AccountForSharpTurnLanes(ref lanesInfo, (byte)nodeInfo.laneCounts[Direction.SharpLeft], (byte)nodeInfo.laneCounts[Direction.SharpRight]); busLaneHandler.PostProcess(ref inLanes, ref lanesInfo); if (lht) { inLanes.Mirror(); LHTHandler.Mirror(ref lanesInfo); } int i = 0; NetManager netManager = Singleton <NetManager> .instance; foreach (var lane in inLanes.lanes) { var laneInfo = lanesInfo[i]; var laneId = lane.Value; // Note: NetLane is a value type netManager.m_lanes.m_buffer[laneId].m_firstTarget = (byte)(laneInfo.firstTarget); netManager.m_lanes.m_buffer[laneId].m_lastTarget = (byte)(laneInfo.lastTarget + 1); NetLane.Flags flags = (NetLane.Flags)netManager.m_lanes.m_buffer[laneId].m_flags; flags &= noDirections; flags |= laneInfo.direction; netManager.m_lanes.m_buffer[laneId].m_flags = (ushort)flags; i += 1; } }
public void PostProcess(ref LaneInfo inLanes, ref List <LaneConnectionInfo> info) { // Post-process OUT lanes for (int i = 0; i < outBusLaneIndices.Count; ++i) { var busLaneIndex = outBusLaneIndices[i]; var busLaneDir = ToArrowDirection(outBusLaneDirections[i]); var lastInLane = info[info.Count - 1]; if (busLaneIndex > lastInLane.lastTarget) { // If the bus lane is the rightmost OUT lane, add it to the rightmost IN lane. lastInLane.lastTarget += 1; lastInLane.direction |= busLaneDir; } else { for (int k = 0; k < info.Count; ++k) { var lane = info[k]; if (lane.lastTarget < busLaneIndex) { // The bus lane is to the right of this IN lane's target (with 1 possible exception, see below) continue; } else if (lane.firstTarget > busLaneIndex) { // The bus lane is to the left of this IN lane's target lane.firstTarget += 1; lane.lastTarget += 1; } else { // The bus lane will be assigned to the same IN lane as the OUT lane to the right, // unless the bus left turns left, and the IN lane does not already allow turning left, // in which case it will be assigned to the IN lane to the left (which should already be turning left). if (busLaneDir == NetLane.Flags.Left && (lane.direction & busLaneDir) == 0 && k > 0) { var previousInLane = info[k - 1]; previousInLane.lastTarget += 1; previousInLane.direction |= busLaneDir; lane.firstTarget += 1; lane.lastTarget += 1; continue; } // The bus lane is within this IN lane's target. lane.lastTarget += 1; lane.direction |= busLaneDir; } } } } // Post-process IN lanes foreach (var busLaneIndex in inBusLaneIndices) { var busLane = new LaneConnectionInfo(NetLane.Flags.None, 255, 0); if (busLaneIndex > 0) { var laneToTheLeft = info[busLaneIndex - 1]; //busLane.direction = laneToTheLeft.direction; // Hidden busLane.firstTarget = laneToTheLeft.firstTarget; busLane.lastTarget = laneToTheLeft.lastTarget; } if (busLaneIndex < info.Count) { var laneToTheRight = info[busLaneIndex]; //busLane.direction |= laneToTheRight.direction; // Hidden busLane.firstTarget = Math.Min(busLane.firstTarget, laneToTheRight.firstTarget); busLane.lastTarget = Math.Max(busLane.lastTarget, laneToTheRight.lastTarget); } info.Insert(busLaneIndex, busLane); } foreach (var busLane in inBusLanes) { inLanes.lanes.Add(busLane.Key, busLane.Value); } }