/* For circles only. */ private VectorNodeStruct CheckAngularDistance(VectorNodeStruct p1, VectorNodeStruct p2) { VectorNodeStruct prevNode = p1; double angDif = NormalizeAngle(prevNode.angle - p2.angle); if (p1 == p2) { angDif = 2 * Math.PI; } /* If the distance between two nodes is too great, we put in an intermediate node inbetween */ while (angDif > m_maxAngDistance) { recursionGuard(); double angle = NormalizeAngle(prevNode.angle - angDif / Math.Ceiling(angDif / m_maxAngDistance)); Vector3 vector = ellipse.VectorAtAbsoluteAngle(angle); ushort newNodeId = NetAccess.CreateNode(centerNodeNetInfo, vector); VectorNodeStruct newNode = new VectorNodeStruct(newNodeId); newNode.angle = angle; ConnectNodes(newNode, prevNode); prevNode = newNode; angDif = NormalizeAngle(prevNode.angle - p2.angle); } return(prevNode); }
public FinalConnector(NetInfo centerNodeNetInfo, EdgeIntersections2 edgeIntersections, Ellipse ellipse, bool insertControllingVertices) { intersections = edgeIntersections?.Intersections ?? new List <VectorNodeStruct>(); m_group = edgeIntersections?.TmpeActionGroup(); this.ellipse = ellipse; pleasenoinfiniterecursion = 0; this.centerNodeNetInfo = centerNodeNetInfo; leftHandTraffic = Singleton <SimulationManager> .instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True; // We ensure that the segments are not too long. For circles only (with ellipses it would be more difficult) m_maxAngDistance = Math.Min(Math.PI * 25 / ellipse.RadiusMain, Math.PI / 2 + 0.1d); bool isCircle = ellipse.IsCircle(); if (!isCircle && insertControllingVertices) { /* See doc in the method below */ InsertIntermediateNodes(); } /* If the list of edge nodes is empty, we add one default intersection. */ if (isCircle && intersections.Count == 0) { Vector3 defaultIntersection = new Vector3(ellipse.RadiusMain, 0, 0) + ellipse.Center; ushort newNodeId = NetAccess.CreateNode(centerNodeNetInfo, defaultIntersection); intersections.Add(new VectorNodeStruct(newNodeId)); } int count = intersections.Count; foreach (VectorNodeStruct item in intersections) { item.angle = Ellipse.VectorsAngle(item.vector - ellipse.Center); } /* We sort the nodes according to their angles */ intersections.Sort(); /* Goes over all the nodes and conntets each of them to the angulary closest neighbour. (In a given direction) */ for (int i = 0; i < count; i++) { VectorNodeStruct prevNode = intersections[i]; if (isCircle) { prevNode = CheckAngularDistance(intersections[i], intersections[(i + 1) % count]); } ConnectNodes(intersections[(i + 1) % count], prevNode); } if (m_group != null) { ModThreading.Timer(m_group); } }
private void ConnectNodes(VectorNodeStruct vectorNode1, VectorNodeStruct vectorNode2) { bool invert = leftHandTraffic; vectorNode1.Create(centerNodeNetInfo); vectorNode2.Create(centerNodeNetInfo); /* NetNode node1 = GetNode(vectorNode1.nodeId); * NetNode node2 = GetNode(vectorNode2.nodeId);*/ double angle1 = getAbsoluteAngle(vectorNode1.vector); double angle2 = getAbsoluteAngle(vectorNode2.vector); Vector3 vec1 = ellipse.TangentAtAbsoluteAngle(angle1); Vector3 vec2 = ellipse.TangentAtAbsoluteAngle(angle2); vec1.Normalize(); vec2.Normalize(); vec2 = -vec2; /*EllipseTool.Instance.debugDrawVector(10*vec1, vectorNode1.vector); * EllipseTool.Instance.debugDrawVector(10*vec2, vectorNode2.vector);*/ //NetInfo netPrefab = PrefabCollection<NetInfo>.FindLoaded("Oneway Road"); NetInfo netPrefab = UI.UIWindow2.instance.dropDown.Value; ushort newSegmentId = NetAccess.CreateSegment(vectorNode1.nodeId, vectorNode2.nodeId, vec1, vec2, netPrefab, invert, leftHandTraffic, true); /* Sometime in the future ;) */ try { SetupTMPE(newSegmentId); } catch (Exception e) { Debug.LogError(e); } //Debug.Log(string.Format("Building segment between nodes {0}, {1}, bezier scale {2}", node1, node2, scale)); }