Beispiel #1
0
        /// <summary>
        /// Adds a distance measurement from the last control point to the closest segment.
        /// </summary>
        private static void CalculateNearbySegments(NetToolProxy netTool, ICollection <Measurement> measurements)
        {
            if (netTool.ControlPointsCount == 0)
            {
                return;
            }

            if (netTool.NodePositions.m_size <= 1)
            {
                return;
            }

            if (SnapController.SnappedGuideLine.HasValue)
            {
                return;
            }

            var lastNode = netTool.NodePositions[netTool.NodePositions.m_size - 1];

            int count;

            NetUtil.GetClosestSegments(netTool.NetInfo, lastNode.m_position, _segments, out count);

            if (count == 0)
            {
                return;
            }

            var p1 = lastNode.m_position;

            var minDist = float.MaxValue;
            var p       = Vector3.zero;
            var found   = false;

            for (var i = 0; i < count; i++)
            {
                if (netTool.ControlPoints[0].m_segment > 0 && _segments[i] == netTool.ControlPoints[0].m_segment)
                {
                    continue;
                }

                var s = NetManager.instance.m_segments.m_buffer[_segments[i]];

                if (!NetUtil.AreSimilarClass(s.Info, netTool.NetInfo))
                {
                    continue;
                }

                var p2 = s.GetClosestPosition(p1);

                // Discard if closest segment position is too close to the source node
                if (Vector3.Distance(netTool.ControlPoints[0].m_position, p2) < Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var closestPoint = Util.ClosestPointOnLineSegment(p1, p2, netTool.ControlPoints[0].m_position);

                // Discard if the line contains the start control point
                if (Vector3.Distance(closestPoint, netTool.ControlPoints[0].m_position) <
                    Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var direction = p2 - p1;
                var dist      = direction.sqrMagnitude;
                direction.Normalize();

                if (dist < minDist)
                {
                    minDist = dist;
                    p       = p2;
                    found   = true;
                }
            }

            if (found && Mathf.Sqrt(minDist) > Settings.MinimumDistanceMeasure)
            {
                measurements.Add(new DistanceMeasurement(Vector3.Distance(p1, p), Vector3Extensions.Average(p1, p), true,
                                                         p1, p,
                                                         MeasurementFlags.Secondary));
            }
        }
Beispiel #2
0
        public static void CalculateGuideLines(NetInfo netInfo, NetTool.ControlPoint startPoint,
                                               NetTool.ControlPoint endPoint,
                                               IList <GuideLine> resultList)
        {
            lock (SegmentCache)
            {
                var startPosition = startPoint.m_position;
                var endPosition   = endPoint.m_position;

                //var segments = NetManager.instance.m_segments;
                //NetManager.instance.GetClosestSegments(endPosition, SegmentCache, out _segmentCacheCount);

                NetUtil.GetClosestSegments(netInfo, endPosition, SegmentCache, out _segmentCacheCount);
                SnapController.DebugPrint = string.Format("Closest Segment Count: {0}", _segmentCacheCount);

                var c = _segmentCacheCount;
                for (ushort i = 0; i < c; i++)
                {
                    var segmentId = SegmentCache[i];

                    var s = NetManager.instance.m_segments.m_buffer[segmentId];

                    // Ensure they are part of the same network
                    if (!NetUtil.AreSimilarClass(s.Info, netInfo))
                    {
                        continue;
                    }

                    if (
                        Vector3Extensions.DistanceSquared(
                            NetManager.instance.m_nodes.m_buffer[s.m_startNode].m_position, endPosition) >
                        Settings.MaxGuideLineQueryDistanceSqr)
                    {
                        continue;
                    }

                    // Test the start and end of the segment

                    // Check if the node can branch in the guide direction (angles less than 45deg or so should be discarded)
                    if (CanNodeBranchInDirection(s.m_endNode, s.m_startDirection))
                    {
                        var endNode = NetManager.instance.m_nodes.m_buffer[s.m_endNode];

                        TestLine(s.Info, startPosition, endPosition,
                                 endNode.m_position,
                                 endNode.m_position + s.m_startDirection.Flatten(),
                                 resultList, segmentId, s.m_endNode);
                    }

                    if (CanNodeBranchInDirection(s.m_startNode, s.m_endDirection))
                    {
                        var startNode = NetManager.instance.m_nodes.m_buffer[s.m_startNode];

                        TestLine(s.Info, startPosition, endPosition,
                                 startNode.m_position,
                                 startNode.m_position + s.m_endDirection.Flatten(),
                                 resultList, segmentId, s.m_startNode);
                    }
                }
            }
        }