// Called before intersection is built
        private static void ReleaseCollidingSegments()
        {
            // We obtain a list of nodes adjacent to the deleted segment to know where to reconnect
            HashSet <ConnectionPoint> borderNodes = new HashSet <ConnectionPoint>();

            if (ToolControllerDetour.CollidingSegmentsCache2 == null)
            {
                return;
            }
            foreach (ushort segment in ToolControllerDetour.CollidingSegmentsCache2)
            {
                try
                {
                    //Debug.Log("Releasing segment " + segment);
                    NetSegment netSegment = NetUtil.Segment(segment);

                    // We keep untouchable segments
                    if ((netSegment.m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                    {
                        continue;
                    }

                    bool inverted = ((netSegment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None);

                    borderNodes.Add(new ConnectionPoint(netSegment.m_startNode, netSegment.m_startDirection, netSegment.Info, inverted));
                    borderNodes.Add(new ConnectionPoint(netSegment.m_endNode, netSegment.m_endDirection, netSegment.Info, !inverted));

                    WrappedSegment segmentW = _networkDictionary.RegisterSegment(segment);
                    _actionGroup.Actions.Add(segmentW);
                    segmentW.IsBuildAction = false;
                    segmentW.Release();

                    if (segmentW.StartNode.TryRelease())
                    {
                        _actionGroup.Actions.Add(segmentW.StartNode);
                        segmentW.StartNode.IsBuildAction = false;
                    }

                    if (segmentW.EndNode.TryRelease())
                    {
                        _actionGroup.Actions.Add(segmentW.EndNode);
                        segmentW.EndNode.IsBuildAction = false;
                    }

                    //NetUtil.ReleaseSegment(segment, true);
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
            }

            borderNodes.RemoveWhere(n => !NetUtil.ExistsNode(n.Node));

            ToolControllerDetour.CollidingSegmentsCache2 = null;

            //Debug.Log("Border nodes (1): " + borderNodes.Count);

            BuildingDecorationDetour.borderNodes = borderNodes;
        }
Exemplo n.º 2
0
        /* If node distance is too short, we travel one segment up from the border node and set the new node as the one to connect to */
        private void RepairShortSegment(ref Vector3 direction, ref ushort node)
        {
            //Debug.Log("Repairing short segment...");

            NetNode netNode = NetUtil.Node(node);

            // If there is more than one segment we cannot safely delete it (we don't even know from which segment we should pick)
            if (netNode.CountSegments() != 1)
            {
                return;
            }

            ushort     segmentId  = NetUtil.GetFirstSegment(netNode);
            NetSegment netSegment = NetUtil.Segment(segmentId);

            WrappedNode nodeW = _networkDictionary.RegisterNode(node);

            if (node == netSegment.m_startNode)
            {
                direction = netSegment.m_endDirection;
                node      = netSegment.m_endNode;
            }
            else
            {
                direction = netSegment.m_startDirection;
                node      = netSegment.m_startNode;
            }

            WrappedSegment segmentW = _networkDictionary.RegisterSegment(segmentId);

            _actionGroup.Actions.Add(segmentW);
            _actionGroup.Actions.Add(nodeW);
            segmentW.Release();
            nodeW.Release();
            segmentW.IsBuildAction = false;
            nodeW.IsBuildAction    = false;

            //NetUtil.ReleaseSegment(segmentId, true);
        }
        private void SnappingAlgorithmNew()
        {
            //Debug
            //EllipseTool.Instance.debugDraw = segmentBeziers;

            List <Bezier2> segmentBeziers    = makeBeziers(traveller.OuterSegments);
            List <Bezier2> ellipseBeziers    = traveller.Ellipse.Beziers;
            List <ushort>  processedSegments = new List <ushort>();

            /* We find all intersections between roads and ellipse beziers */
            for (int i = 0; i < segmentBeziers.Count; i++)
            {
                for (int j = 0; j < ellipseBeziers.Count; j++)
                {
                    if (ellipseBeziers[j].Intersect(segmentBeziers[i], out float t1, out float t2, ITERATIONS))
                    {
                        if (processedSegments.Contains(traveller.OuterSegments[i]))
                        {
                            continue;
                        }
                        else
                        {
                            processedSegments.Add(traveller.OuterSegments[i]);
                        }

                        //Debug.Log("Segment " + i.ToString() + " intersects ellipse bezier " + j.ToString());
                        Vector3 intersection = new Vector3(ellipseBeziers[j].Position(t1).x, CenterNode.m_position.y, ellipseBeziers[j].Position(t1).y);
                        segmentBeziers[i].Divide(out Bezier2 segementBezier1, out Bezier2 segementBezier2, t2);
                        Bezier2 outerBezier;
                        Vector2 outerNodePos = new Vector2(NetUtil.Node(traveller.OuterNodes[i]).m_position.x, NetUtil.Node(traveller.OuterNodes[i]).m_position.z);
                        bool    invert       = false;
                        // outerBezier - the bezier outside the ellipse (not the one inside)
                        if (segementBezier1.Position(0f) == outerNodePos || segementBezier1.Position(1f) == outerNodePos)
                        {
                            //Debug.Log("first is outer");
                            outerBezier = segementBezier1.Invert();
                            invert      = true;
                        }
                        else if (segementBezier2.Position(0f) == outerNodePos || segementBezier2.Position(1f) == outerNodePos)
                        {
                            //Debug.Log("second is probably outer");
                            outerBezier = segementBezier2;
                            invert      = false;
                        }
                        else
                        {
                            throw new Exception("Error - Failed to determine segment geometry.");
                        }

                        //debug:
                        //EllipseTool.Instance.debugDraw.Add(outerBezier);

                        /* We create a node at the intersection. */
                        WrappedNode newNode = new WrappedNode();
                        newNode.Position = intersection;
                        newNode.NetInfo  = CenterNode.Info;
                        RoundaboutNode raNode = new RoundaboutNode(newNode);
                        raNode.Create(ActionGroupRoads);
                        Intersections.Add(raNode);

                        WrappedNode    outerNode    = networkDictionary.RegisterNode(traveller.OuterNodes[i]);
                        WrappedSegment outerSegment = networkDictionary.RegisterSegment(traveller.OuterSegments[i]);

                        BezierToSegment(outerBezier, outerSegment, newNode, outerNode, invert);
                    }
                }
            }
        }