public void SetLaneData() { lanes = new List <MapLane>(); lanes.AddRange(GetComponentsInChildren <MapLane>()); lanesForward = new List <MapLane>(); lanesReverse = new List <MapLane>(); // 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; 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; } if (isSameDirection) // same direction { 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 (!lanesForward.Contains(lane) && !lanesReverse.Contains(lane)) { lanesForward.Add(lane); } if (!lanesReverse.Contains(otherLane) && !lanesForward.Contains(otherLane)) { lanesReverse.Add(otherLane); } } } } if (isOneWay == null) { return; } setLaneRelations(lanes); int wayCount = isOneWay.Value ? 1 : 2; for (int i = 0; i < wayCount; i++) { MapLane currentLane = null; List <MapLane> edited = new List <MapLane>(); List <MapLane> 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; } } } }
public void SetLaneData() { lanes = new List <MapLane>(); lanes.AddRange(GetComponentsInChildren <MapLane>()); lanesForward = new List <MapLane>(); lanesReverse = new List <MapLane>(); // 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; // set default left/right bound type. lane.leftBoundType = LaneBoundaryType.DOTTED_WHITE; lane.rightBoundType = LaneBoundaryType.DOTTED_WHITE; var idx = 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; } // 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[lane.mapWorldPositions.Count - 1] - lane.mapWorldPositions[0]).normalized; var otherLaneDirection = (otherLane.mapWorldPositions[otherLane.mapWorldPositions.Count - 1] - otherLane.mapWorldPositions[0]).normalized; if (Vector3.Dot(laneDirection, otherLaneDirection) < 0) { isSameDirection = false; } if (isSameDirection) // same direction { var cross = Vector3.Cross(laneDir, (otherLane.mapWorldPositions[idx] - lane.mapWorldPositions[idx]).normalized).y; var dist = Mathf.RoundToInt(Vector3.Distance(lane.mapWorldPositions[idx], otherLane.mapWorldPositions[idx])); 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; var cross = Vector3.Cross(laneDir, (otherLane.mapWorldPositions[otherLane.mapWorldPositions.Count - 1 - idx] - lane.mapWorldPositions[idx]).normalized).y; var dist = Mathf.RoundToInt(Vector3.Distance(lane.mapWorldPositions[idx], otherLane.mapWorldPositions[otherLane.mapWorldPositions.Count - 1 - idx])); 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; } int wayCount = isOneWay.Value ? 1 : 2; for (int i = 0; i < wayCount; i++) { MapLane currentLane = null; List <MapLane> edited = new List <MapLane>(); List <MapLane> currentLanes = i == 0 ? lanesForward : lanesReverse; foreach (var lane in currentLanes) { if (lane.rightLaneForward == null) { currentLane = lane; lane.rightBoundType = LaneBoundaryType.CURB; 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; } } // Set left boundary type for the left most lane if (isOneWay.Value) { edited[edited.Count - 1].leftBoundType = LaneBoundaryType.CURB; } else { edited[edited.Count - 1].leftBoundType = LaneBoundaryType.DOUBLE_YELLOW; } } }
private static void ShowMsg(MapLane lane, MapLane otherLane) { Debug.LogWarning($"Can't determine lane relations between {lane.name} and {otherLane.name}"); Debug.Log("lane", lane.gameObject); Debug.Log("otherLane", otherLane.gameObject); }