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());
             * }*/
        }
Пример #2
0
        /// <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());
            }
        }