private void BezierToSegment(Bezier2 bezier2, WrappedSegment oldSegmentW, WrappedNode startNodeW, WrappedNode endNodeW, bool invert) { NetSegment oldSegment = oldSegmentW.Get; Vector2 startDirection2d; Vector2 endDirection2d; Vector2 nodePos2d = new Vector2(startNodeW.Position.x, startNodeW.Position.z); startDirection2d = bezier2.Tangent(0f); endDirection2d = bezier2.Tangent(1f); Vector3 startDirection = (new Vector3(startDirection2d.x, 0, startDirection2d.y)); Vector3 endDirection = -(new Vector3(endDirection2d.x, 0, endDirection2d.y)); /* Unlike from the old algorithm, we use no padding when looking for the segments. That means the obtained segments can be arbitrarily short. * In that case, we take one more segment away from the ellipse.*/ if (VectorDistance(bezier2.a, bezier2.d) < MIN_BEZIER_LENGTH) { //Debug.Log("Segment is too short. Launching repair mechainsm." + VectorDistance(bezier2.a, bezier2.d)); nextSegmentInfo(oldSegmentW, ref endNodeW, ref endDirection); } // Debug // EllipseTool.Instance.debugDrawVector(20*startDirection, GetNode(startNodeId).m_position); // EllipseTool.Instance.debugDrawVector(20*endDirection, GetNode(endNodeId).m_position); startDirection.Normalize(); endDirection.Normalize(); if (oldSegment.m_flags.IsFlagSet(NetSegment.Flags.Invert)) { invert = !invert; } WrappedSegment newSegment = new WrappedSegment(); newSegment.StartNode = startNodeW; newSegment.EndNode = endNodeW; newSegment.StartDirection = startDirection; newSegment.EndDirection = endDirection; newSegment.NetInfo = oldSegment.Info; newSegment.Invert = invert; ActionGroupRoads.Actions.Add(newSegment); ActionGroupTMPE.Actions.Add(new EnteringBlockedJunctionAllowedAction(newSegment, true, true)); ActionGroupTMPE.Actions.Add(new YieldSignAction(newSegment, true)); /*try * { * ushort newSegmentId = NetAccess.CreateSegment(startNodeId, endNodeId, * startDirection, endDirection, oldSegment.Info, invert); * * * } * catch(Exception e) * { * UIWindow2.instance.ThrowErrorMsg("The game failed to create one of the road segments."); * Debug.LogError(e.ToString()); * }*/ }
/// <summary> /// Travels some distance on beizer and calculates the point and tangent at that distance. /// </summary> /// <param name="distance">distance to travel on the arc in meteres</param> /// <param name="tangent">normalized tangent on the curve toward the end of the beizer.</param> /// <returns>point on the curve at the given distance.</returns> public static Vector2 Travel2(this Bezier2 beizer, float distance, out Vector2 tangent) { if (beizer.IsStraight()) { tangent = (beizer.d - beizer.a).normalized; return(beizer.TravelStraight(distance)); } float t = beizer.Travel(0, distance); tangent = beizer.Tangent(t).normalized; return(beizer.Position(t)); }
private void BezierToSegment(Bezier2 bezier2, ushort oldSegmentId, ushort startNodeId, ushort endNodeId, bool invert) { NetSegment oldSegment = NetAccess.Segment(oldSegmentId); Vector2 startDirection2d; Vector2 endDirection2d; Vector2 nodePos2d = new Vector2(NetAccess.Node(startNodeId).m_position.x, NetAccess.Node(startNodeId).m_position.z); /*if ( Distance(nodePos2d,bezier2.Position(0f)) < 10e-3d) * { * //0f is on the ellipse * } * else if(Distance(nodePos2d, bezier2.Position(1f)) < 10e-3d) * { * //1f is on the ellipse * bezier2 = bezier2.Invert(); * invert = true; * } * else * { * throw new Exception(string.Format("Error - no intersection of bezier and point. Dist: {0}, {1}",Distance(nodePos2d,bezier2.Position(0f)), Distance(nodePos2d, bezier2.Position(1f)))); * }*/ startDirection2d = bezier2.Tangent(0f); endDirection2d = bezier2.Tangent(1f); Vector3 startDirection = (new Vector3(startDirection2d.x, 0, startDirection2d.y)); Vector3 endDirection = -(new Vector3(endDirection2d.x, 0, endDirection2d.y)); /* Unlike from the old algorithm, we use no padding when looking for the segments. That means the obtained segments can be arbitrarily short. * In that case, we take one more segment away from the ellipse.*/ if (VectorDistance(bezier2.a, bezier2.d) < MIN_BEZIER_LENGTH) { //Debug.Log("Segment is too short. Launching repair mechainsm." + VectorDistance(bezier2.a, bezier2.d)); if (nextSegmentInfo(endNodeId, oldSegmentId, out ushort endNodeIdNew, out Vector3 endDirectionNew)) { endNodeId = endNodeIdNew; endDirection = endDirectionNew; //Debug.Log("The segment length should be " + VectorDistance(GetNode(startNodeId).m_position,GetNode(endNodeId).m_position)); //EllipseTool.Instance.debugDrawPositions.Add(GetNode(endNodeIdNew).m_position); } } // Debug // EllipseTool.Instance.debugDrawVector(20*startDirection, GetNode(startNodeId).m_position); // EllipseTool.Instance.debugDrawVector(20*endDirection, GetNode(endNodeId).m_position); startDirection.Normalize(); endDirection.Normalize(); if (oldSegment.m_flags.IsFlagSet(NetSegment.Flags.Invert)) { invert = !invert; } try { ushort newSegmentId = NetAccess.CreateSegment(startNodeId, endNodeId, startDirection, endDirection, oldSegment.Info, invert); m_group.Actions.Add(new EnteringBlockedJunctionAllowedAction(newSegmentId, true, true)); m_group.Actions.Add(new YieldSignAction(newSegmentId, true)); } catch (Exception e) { UIWindow2.instance.ThrowErrorMsg("The game failed to create one of the road segments."); Debug.LogError(e.ToString()); } }