private static void ShowMsg(MapTrafficLane lane, MapTrafficLane otherLane) { Debug.LogWarning($"Can't determine lane relations between {lane.name} and {otherLane.name}"); Debug.Log("lane", lane.gameObject); Debug.Log("otherLane", otherLane.gameObject); }
public void SetLaneData() { lanes = new List <MapTrafficLane>(); lanes.AddRange(GetComponentsInChildren <MapTrafficLane>()); lanesForward = new List <MapTrafficLane>(); lanesReverse = new List <MapTrafficLane>(); // for laneSections with branching lanes, all lanes should have at least 3 waypoints for (var i = 0; i < lanes.Count; i++) { var lane = lanes[i]; // Self-reverse lane is not applied for this. Self-reverse lane is assigned to SOLID_WHITE manually. if (lane.isSelfReverseLane) { continue; } isOneWay = true; var laneIdx = lane.mapWorldPositions.Count - 1; // index to compute vector from lane to otherLane and distance between those two lanes var laneDir = (lane.mapWorldPositions[1] - lane.mapWorldPositions[0]).normalized; var minDistLeft = 50f; var minDistRight = 50f; lane.leftLaneForward = null; lane.leftLaneReverse = null; lane.rightLaneForward = null; lane.rightLaneReverse = null; for (var j = 0; j < lanes.Count; j++) { var otherLane = lanes[j]; if (lane == otherLane) { continue; } var otherIdx = otherLane.mapWorldPositions.Count - 1; // Check if these two lanes have same directions by check the dist between 1st pos in lane and (the 1st and last pos in otherLane). var isSameDirection = true; var laneDirection = (lane.mapWorldPositions[laneIdx] - lane.mapWorldPositions[0]).normalized; var otherLaneDirection = (otherLane.mapWorldPositions[otherIdx] - otherLane.mapWorldPositions[0]).normalized; if (Vector3.Dot(laneDirection, otherLaneDirection) < 0) { isSameDirection = false; } var otherIdxCross = isSameDirection ? 1 : otherLane.mapWorldPositions.Count - 2; var cross = Vector3.Cross(laneDir, (otherLane.mapWorldPositions[otherIdxCross] - lane.mapWorldPositions[1]).normalized).y; var dist = Mathf.RoundToInt(FindDistanceToLine(otherLane.mapWorldPositions[otherIdxCross], lane.mapWorldPositions[0], lane.mapWorldPositions[1])); if (isSameDirection) // same direction { if (cross < 0) // otherLane is left of lane { if (dist < minDistLeft) // closest lane left of lane is otherLane { minDistLeft = dist; lane.leftLaneForward = otherLane; } } else if (cross > 0) // otherLane is right of lane { if (dist < minDistRight) // closest lane right of lane is otherLane { minDistRight = dist; lane.rightLaneForward = otherLane; } } if (!lanesForward.Contains(lane) && !lanesReverse.Contains(lane)) { lanesForward.Add(lane); } if (!lanesForward.Contains(otherLane) && !lanesReverse.Contains(otherLane)) { lanesForward.Add(otherLane); } } else // opposite direction { isOneWay = false; if (cross < 0) // otherLane is left of lane { if (dist < minDistLeft) // closest lane left of lane is otherLane { minDistLeft = dist; lane.leftLaneReverse = otherLane; } } else if (cross > 0) // otherLane is right of lane { if (dist < minDistRight) // closest lane right of lane is otherLane { minDistRight = dist; lane.rightLaneReverse = otherLane; } } if (!lanesForward.Contains(lane) && !lanesReverse.Contains(lane)) { lanesForward.Add(lane); } if (!lanesReverse.Contains(otherLane) && !lanesForward.Contains(otherLane)) { lanesReverse.Add(otherLane); } } if (lane.leftLaneForward != null) { lane.leftLaneReverse = null; // null lane left reverse if not inside lane TODO right side } } } if (isOneWay == null) { return; } UpdateLaneRelationsByBoundaryLines(lanes); VerifyLaneRelations(lanes); int wayCount = isOneWay.Value ? 1 : 2; for (int i = 0; i < wayCount; i++) { MapTrafficLane currentLane = null; List <MapTrafficLane> edited = new List <MapTrafficLane>(); List <MapTrafficLane> currentLanes = i == 0 ? lanesForward : lanesReverse; foreach (var lane in currentLanes) { if (lane.rightLaneForward == null) { currentLane = lane; break; } } var numLanes = i == 0 ? lanesForward.Count : lanesReverse.Count; var cnt = 0; while (currentLane != null) { edited.Add(currentLane); currentLane.laneNumber = edited.Count; currentLane.laneCount = currentLanes.Count; currentLane = currentLane.leftLaneForward; cnt += 1; if (cnt > numLanes) { Debug.LogError("Erroneous loop! Please check this lane!"); #if UNITY_EDITOR UnityEditor.Selection.activeObject = currentLane.gameObject; #endif return; } } } }