/// <summary> /// Returns the point of the road where it reaches the intersetion /// </summary> /// <param name="segment"></param> /// <param name="intersection"></param> /// <param name="right"></param> private void GetRoadPoint(RoadSegment segment, Intersection intersection, bool right) { Vector3 direction = segment.GetOtherSide(intersection).Position - intersection.Position; Vector3 point; if (right) { point = new Vector3(direction.z, 0.0f, -direction.x); point = point.normalized * segment.GetRoadEdgeOffset(intersection); } else { point = new Vector3(-direction.z, 0.0f, direction.x); point = point.normalized * segment.GetRoadEdgeOffset(segment.GetOtherSide(intersection)); } segment.SetVertices(intersection, point, right); }
/// <summary> /// Returns point of intersection. If there is none, return the offset point. /// </summary> /// <param name="right"></param> /// <param name="left"></param> /// <param name="intersection"></param> /// <returns></returns> private void GetRoadPoint(RoadSegment right, RoadSegment left, Intersection intersection, List <Vector3> vertices) { // Direction from intersections along both roads Vector3 rightDirection = right.GetOtherSide(intersection).Position - intersection.Position; Vector3 leftDirection = left.GetOtherSide(intersection).Position - intersection.Position; float rightOffset = right.GetRoadEdgeOffset(right.GetOtherSide(intersection)); float leftOffset = left.GetRoadEdgeOffset(intersection); // Find offset point that is perpendicular to the direction. Offset is half the road width. // This point is on the edge of the road Vector3 rightPoint = new Vector3(-rightDirection.z, 0.0f, rightDirection.x); rightPoint = rightPoint.normalized * rightOffset; Vector3 leftPoint = new Vector3(leftDirection.z, 0.0f, -leftDirection.x); leftPoint = leftPoint.normalized * leftOffset; Vector3 intersectionPoint; if (!Mathf.Approximately(leftOffset, rightOffset) && Vector3.Angle(rightDirection, leftDirection) > 160.0f) { // The offset of the road edges are different and they are almost in a straight line // Create a circle at the center of the intersection with a radius the size of the bigger offset (+ 0.1f to avoid floating point errors causing missed tangents) // When the road edge collides with that circle, that is where it will be part of the intersection float radius = 0.0f; if (rightOffset < leftOffset) { radius = leftOffset + 0.1f; } else { radius = rightOffset + 0.1f; } intersectionPoint = GetCircleIntersection(radius, leftDirection, leftPoint, Vector3.zero); left.SetVertices(intersection, intersectionPoint, true); vertices.Add(intersectionPoint); intersectionPoint = GetCircleIntersection(radius, rightDirection, rightPoint, Vector3.zero); right.SetVertices(intersection, intersectionPoint, false); vertices.Add(intersectionPoint); } else { // If the offset for both edges is the same, find the intersection if (GetLineIntersection(out intersectionPoint, rightPoint, rightDirection, leftPoint, leftDirection)) { right.SetVertices(intersection, intersectionPoint, false); left.SetVertices(intersection, intersectionPoint, true); vertices.Add(intersectionPoint); } else { right.SetVertices(intersection, rightPoint, false); left.SetVertices(intersection, rightPoint, true); vertices.Add(rightPoint); } } }
/// <summary> /// Gets all the points that will form a sidewalk /// </summary> /// <param name="startIntersection"></param> /// <param name="roadSegment"></param> /// <param name="checks"></param> /// <param name="parent"></param> private Sidewalk CreateSidewalk(Intersection startIntersection, RoadSegment roadSegment, HashSet <SidewalkCheckHelper> checks, GameObject parent) { Intersection current = startIntersection; Intersection next = roadSegment.GetOtherSide(startIntersection); RoadSegment nextSegment = null; GameObject go = new GameObject(); go.name = "Sidewalk Mesh"; Sidewalk sidewalk = go.AddComponent <Sidewalk>(); sidewalk.OriginalVertices.Add(roadSegment.GetVertexWorldPosition(startIntersection, false)); SidewalkCheckHelper check = new SidewalkCheckHelper(); while (next != startIntersection) { int nextIndex = (next.Roads.IndexOf(roadSegment) + 1) % (next.Roads.Count); nextSegment = next.Roads[nextIndex]; check.Intersection = next; check.Road = nextSegment; checks.Add(check); if (next.Roads.Count == 1) { sidewalk.OriginalVertices.Add(nextSegment.GetVertexWorldPosition(next, true)); sidewalk.OriginalVertices.Add(nextSegment.GetVertexWorldPosition(next, false)); } else if (!(Mathf.Approximately(roadSegment.GetVertexWorldPosition(next, true).x, nextSegment.GetVertexWorldPosition(next, false).x) && Mathf.Approximately(roadSegment.GetVertexWorldPosition(next, true).z, nextSegment.GetVertexWorldPosition(next, false).z))) { sidewalk.OriginalVertices.Add(roadSegment.GetVertexWorldPosition(next, true)); sidewalk.OriginalVertices.Add(nextSegment.GetVertexWorldPosition(next, false)); } else { sidewalk.OriginalVertices.Add(nextSegment.GetVertexWorldPosition(next, false)); } current = next; next = nextSegment.GetOtherSide(next); roadSegment = nextSegment; } if (nextSegment != null && !(Mathf.Approximately(sidewalk.OriginalVertices[0].x, nextSegment.GetVertexWorldPosition(next, true).x) && Mathf.Approximately(sidewalk.OriginalVertices[0].z, nextSegment.GetVertexWorldPosition(next, true).z))) { sidewalk.OriginalVertices.Add(nextSegment.GetVertexWorldPosition(next, true)); } Vector3 sum = Vector3.zero; for (int i = 0; i < sidewalk.OriginalVertices.Count; i++) { sum += sidewalk.OriginalVertices[i]; } go.transform.position = sum / sidewalk.OriginalVertices.Count; sidewalk.SidewalkMaterial = city.SidewalkMaterial; sidewalk.InnerMaterial = city.InnerBlockMaterial; sidewalk.FixMeshOffset(); sidewalk.FindDirection(); sidewalk.CalculateVertices(); sidewalk.CreateMesh(); go.transform.parent = parent.transform; go.isStatic = true; return(sidewalk); }