/// <summary> /// Define the road and cross section /// </summary> /// <param name="couveSize">The size off set</param> /// <param name="index">The road index</param> /// <param name="roadNetworkNode">The main road node</param> /// <param name="road">The rode node to populate</param> /// <param name="crossSection">The cross section to populate</param> public static void DefineCrossSectionOffSet(float couveSize, int index, RoadNetworkNode roadNetworkNode, out RoadNetworkNode road, out RoadCrossSection crossSection) { road = roadNetworkNode.Details.Roads[index]; Vector3 pos = roadNetworkNode.gameObject.transform.position; float angleA = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoad(roadNetworkNode, index) + (Mathf.PI / 2)); Vector3 roadPointA = road.GetOffSetDownRoad(pos, (RoadConstructorHelper.CrossSectionDetails.RoadWidthValue * couveSize)); crossSection = new RoadCrossSection(roadPointA, angleA - (float)(Math.PI / 2), RoadConstructorHelper.CrossSection(road), RoadConstructorHelper.Materials(road)); }
/// <summary> /// Find the smallest road needed for this junction /// </summary> /// <param name="currentroadNode">The road node</param> /// <param name="crossSections">The cross section of the road</param> /// <param name="middlePoint">The middle point in the cross section</param> /// <returns>The cross seciton of the road that is nearest to the junction</returns> private RoadCrossSection FindSmallestRoadForJunction(RoadNetworkNode currentroadNode, RoadCrossSection crossSections, Vector3 middlePoint) { Vector3 a = crossSections.Middle; Vector3 diffline = a - middlePoint; float angleA = MathsHelper.GetAngleFrom(diffline.x, diffline.z); angleA = RoadUnionHelper.AngleClamp(crossSections.Angle - angleA) - Mathf.PI / 2; Vector3 diff = a - crossSections.CurbLeftEndDrop; float mag2 = diff.magnitude * Mathf.Cos(angleA); if (mag2 < 0) { mag2 = -mag2; } Vector3 roadPointA = currentroadNode.GetOffSetDownRoad(crossSections.Middle, mag2); float angleB = RoadUnionHelper.AngleClamp(GetAngleOfRoad(currentroadNode) + Mathf.PI / 2); RoadCrossSection rA = new RoadCrossSection(roadPointA, angleB - (float)(Math.PI / 2), RoadConstructorHelper.CrossSection(currentroadNode), RoadConstructorHelper.Materials(currentroadNode)); return(rA); }
/// <summary> /// Created the intersections of the roads /// </summary> /// <param name="roadBuilderObject">The road builder object</param> public void CreateLayout(RoadBuilder roadBuilderObject) { float angleRoadStart = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoad(_roadNetworkNode, 0)); Vector3 pos = _roadNetworkNode.transform.position; ICrossSection sc = _roadNetworkNode.gameObject.GetComponent <ICrossSection>(); if (sc == null) { sc = RoadConstructorHelper.CrossSectionDetails; } IMaterialFrequency mf = _roadNetworkNode.gameObject.GetComponent <IMaterialFrequency>(); if (mf == null) { mf = RoadConstructorHelper.MaterialFrequencySet; } RoadCrossSection rA = new RoadCrossSection(pos, angleRoadStart, sc, mf); StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, sc, mf, rA); }
/// <summary> /// Standard Constructor /// </summary> /// <param name="a">Guid A</param> /// <param name="nodeA">Node a</param> /// <param name="b">Guid B</param> /// <param name="nodeB">Node B</param> /// <param name="c">Giud C</param> /// <param name="nodeC">Node C</param> public RoadJunctionOrder(Guid a, RoadNetworkNode nodeA, Guid b, RoadNetworkNode nodeB, Guid c, RoadNetworkNode nodeC) { _orderedAngles = new List <float>(); _angles = new Dictionary <float, RoadCrossSection>(); _nodes = new Dictionary <float, RoadNetworkNode>(); RoadCrossSection road = IntersectionManager.Instance[a]; float angle = RoadUnionHelper.AngleClamp(road.Angle); _angles.Add(angle, road); _nodes.Add(angle, nodeA); _orderedAngles.Add(angle); road = IntersectionManager.Instance[b]; angle = RoadUnionHelper.AngleClamp(road.Angle); if (_angles.ContainsKey(angle)) { angle += 0.001f; } _angles.Add(angle, road); _nodes.Add(angle, nodeB); _orderedAngles.Add(angle); road = IntersectionManager.Instance[c]; angle = RoadUnionHelper.AngleClamp(road.Angle); if (_angles.ContainsKey(angle)) { angle += 0.002f; } if (_angles.ContainsKey(angle)) { angle += 0.001f; } _angles.Add(angle, road); _nodes.Add(angle, nodeC); _orderedAngles.Add(angle); _orderedAngles.Sort(); AnglesGaps agA = new AnglesGaps(_orderedAngles[0], _orderedAngles[1], 2); AnglesGaps agB = new AnglesGaps(_orderedAngles[1], _orderedAngles[2], 0); AnglesGaps agC = new AnglesGaps(_orderedAngles[2], _orderedAngles[0], 1); Dictionary <float, AnglesGaps> angleGapArray = new Dictionary <float, AnglesGaps>(); if (agA.RoadAngleGap == agB.RoadAngleGap) { agB.RoadAngleGap += 0.001f; } if (agB.RoadAngleGap == agC.RoadAngleGap) { agC.RoadAngleGap += 0.001f; } if (agA.RoadAngleGap == agC.RoadAngleGap) { agC.RoadAngleGap += 0.002f; } angleGapArray.Add(agA.RoadAngleGap, agA); angleGapArray.Add(agB.RoadAngleGap, agB); angleGapArray.Add(agC.RoadAngleGap, agC); List <float> orderedGapAngles = new List <float>(); orderedGapAngles.Add(agA.RoadAngleGap); orderedGapAngles.Add(agB.RoadAngleGap); orderedGapAngles.Add(agC.RoadAngleGap); orderedGapAngles.Sort(); _middle = angleGapArray[orderedGapAngles[2]].RoadIndex; _left = _middle - 1; if (_left < 0) { _left = 2; } _right = _middle + 1; if (_right > 2) { _right = 0; } }
/// <summary> /// Modify the terrain for the corner /// </summary> /// <param name="sections">The number of sections</param> /// <param name="tm">The terrain modifier</param> private void CreateCornerTerrain(int sections, TerrainModifier tm) { // this is not the best way - but it's a start // maybe have a function that returns a list of cross sections // find the point where the two roads meet Vector3 pos = _roadNetworkNode.gameObject.transform.position; // create a corne at this postion Vector3 newpos = pos; float roadAngleA = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 0) - Mathf.PI / 2); float roadAngleB = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 1) + Mathf.PI / 2); float roadAngleDifference = roadAngleB - roadAngleA; float couveSize = 1.85f; float x, z; float road_A_length = GetLengthOfRoad(0); float road_B_length = GetLengthOfRoad(1); float minLength = Mathf.Min(road_A_length, road_B_length); float offSetDownRoad = RoadConstructorHelper.CrossSectionDetails.RoadWidthValue * couveSize; if (offSetDownRoad > minLength / 2) { offSetDownRoad = minLength / 2; } RoadNetworkNode oppositeEnd = _roadNetworkNode.Details.Roads[1].GetComponent <RoadNetworkNode>(); Vector3 roadPointA = oppositeEnd.GetOffSetDownRoad(pos, (offSetDownRoad)); Vector3 outA; bool offSetPos = _roadNetworkNode.GetInnerCorner(0, 1, (offSetDownRoad), out outA); Vector3 CornerPoint = outA; newpos = CornerPoint; // get the gap form point to point Vector3 gap = CornerPoint - roadPointA; couveSize = offSetPos ? gap.magnitude : 0; couveSize = offSetPos ? gap.magnitude : 0; Radian currentAngle = new Radian(roadAngleA - (float)(Math.PI / 2)); roadAngleDifference = MathsHelper.ClampAngle(roadAngleDifference); if (roadAngleDifference > Mathf.PI) { roadAngleDifference = (Mathf.PI * 2) - roadAngleDifference; currentAngle = new Radian(roadAngleB + (float)(Math.PI / 2)); } float diff = roadAngleDifference; x = Mathf.Sin(currentAngle.Value) * (couveSize); z = Mathf.Cos(currentAngle.Value) * (couveSize); newpos.x -= x; newpos.z += z; ICrossSection crossSectionMiddle = RoadConstructorHelper.CrossSection(_roadNetworkNode); IMaterialFrequency materialFrequency = _roadNetworkNode.gameObject.GetComponent <IMaterialFrequency>(); if (materialFrequency == null) { materialFrequency = RoadConstructorHelper.MaterialFrequencySet; } RoadCrossSection rA = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency); float angleStep = Mathf.Abs(diff / sections); for (int i = 0; i < sections; i++) { newpos = CornerPoint; currentAngle.Value += angleStep; x = Mathf.Sin(currentAngle.Value) * (couveSize); z = Mathf.Cos(currentAngle.Value) * (couveSize); newpos.x -= x; newpos.z += z; RoadCrossSection rB = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency); tm.ApplyToTerrain(rA, rB); rA = rB; } RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 0); RoadConstructorHelper.ApplyLeadingStrights(_roadNetworkNode, tm, 1); }
/// <summary> /// Create the road object /// </summary> /// <param name="roadObject">The base object to add the road to</param> /// <param name="sections">The number of sections to use for this road</param> private void CreateCorner(RoadBuilder roadObject, int sections) { // find the point where the two roads meet Vector3 pos = _roadNetworkNode.gameObject.transform.position; // create a corne at this postion Vector3 newpos = pos; float roadAngleA = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 0) - (Mathf.PI / 2)); float roadAngleB = RoadUnionHelper.AngleClamp(RoadUnionHelper.GetAngleOfRoadClampped(_roadNetworkNode, 1) + (Mathf.PI / 2)); float roadAngleDifference = roadAngleB - roadAngleA; float couveSize = 1.85f; float x, z; float road_A_length = GetLengthOfRoad(0); float road_B_length = GetLengthOfRoad(1); float minLength = Mathf.Min(road_A_length, road_B_length); float offSetDownRoad = RoadConstructorHelper.CrossSectionDetails.RoadWidthValue * couveSize; if (offSetDownRoad > minLength / 2) { offSetDownRoad = minLength / 2; } RoadNetworkNode oppositeEnd = _roadNetworkNode.Details.Roads[1].GetComponent <RoadNetworkNode>(); Vector3 roadPointA = oppositeEnd.GetOffSetDownRoad(pos, (offSetDownRoad)); Vector3 outA; bool offSetPos = _roadNetworkNode.GetInnerCorner(0, 1, (offSetDownRoad), out outA); Vector3 CornerPoint = outA; newpos = CornerPoint; // get the gap form point to point Vector3 gap = CornerPoint - roadPointA; couveSize = offSetPos ? gap.magnitude : 0; couveSize = offSetPos ? gap.magnitude : 0; bool backward = false; Radian currentAngle = new Radian(roadAngleA - (float)(Math.PI / 2)); roadAngleDifference = MathsHelper.ClampAngle(roadAngleDifference); if (roadAngleDifference > Mathf.PI) { roadAngleDifference = (Mathf.PI * 2) - roadAngleDifference; currentAngle = new Radian(roadAngleB + (float)(Math.PI / 2)); backward = true; } float diff = roadAngleDifference; x = Mathf.Sin(currentAngle.Value) * (couveSize); z = Mathf.Cos(currentAngle.Value) * (couveSize); newpos.x -= x; newpos.z += z; ICrossSection crossSectionMiddle = RoadConstructorHelper.CrossSection(_roadNetworkNode); IMaterialFrequency materialFrequency = _roadNetworkNode.gameObject.GetComponent <IMaterialFrequency>(); if (materialFrequency == null) { materialFrequency = RoadConstructorHelper.MaterialFrequencySet; } RoadCrossSection rA = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency); RoadCrossSection Start = rA; float angleStep = Mathf.Abs(diff / sections); for (int i = 0; i < sections; i++) { newpos = CornerPoint; currentAngle.Value += angleStep; x = Mathf.Sin(currentAngle.Value) * (couveSize); z = Mathf.Cos(currentAngle.Value) * (couveSize); newpos.x -= x; newpos.z += z; RoadCrossSection rB = new RoadCrossSection(newpos, currentAngle.Value, crossSectionMiddle, materialFrequency); // TODO Sub divide corners - need to update before the add basic road! _meshSection.AddBasicRoad(IntersectionManager.Instance.AddLinkedIntersecions(rA, rB), RoadConstructorHelper.GetMainMaterial(materialFrequency), 0); rA = rB; } RoadCrossSection End = rA; if (backward) { StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, crossSectionMiddle, materialFrequency, End); StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name, crossSectionMiddle, materialFrequency, Start); } else { StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[1].name, crossSectionMiddle, materialFrequency, End); StreetManager.Instance.AddStreetEnd(_roadNetworkNode.name, _roadNetworkNode.Details.Roads[0].name, crossSectionMiddle, materialFrequency, Start); } }