/// <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)); } }
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); } } } }