private static bool CanNodeBranchInDirection(ushort nodeId, Vector3 direction) { var closestSegmentId = NetNodeUtility.GetClosestSegmentId(nodeId, direction); var exitDirection = NetNodeUtility.GetSegmentExitDirection(nodeId, closestSegmentId); var exitAngle = Vector3Extensions.GetSignedAngleBetween(direction.Flatten(), exitDirection.Flatten(), Vector3.up); return(Mathf.Abs(exitAngle) >= 45f); }
public static NetTool.ControlPoint SnapDirectionOverride(NetTool.ControlPoint newPoint, NetTool.ControlPoint oldPoint, NetInfo info, out bool success, out float minDistanceSq) { if (Debug.Enabled) { DebugPrint = string.Format("oldPoint: {0}\nnewPoint:{1}", StringUtil.ToString(oldPoint), StringUtil.ToString(newPoint)); } GuideLines.Clear(); SnappedGuideLine = null; minDistanceSq = info.GetMinNodeDistance(); minDistanceSq = minDistanceSq * minDistanceSq; var controlPoint = newPoint; success = false; if (EnableSnapping) { // If dragging from a node if (oldPoint.m_node != 0 && !newPoint.m_outside) { // Node the road build operation is starting from var sourceNodeId = oldPoint.m_node; var sourceNode = NetManager.instance.m_nodes.m_buffer[sourceNodeId]; // Direction and length of the line from the node to the users control point var userLineDirection = (newPoint.m_position - sourceNode.m_position).Flatten(); var userLineLength = userLineDirection.magnitude; userLineDirection.Normalize(); var closestSegmentId = NetNodeUtility.GetClosestSegmentId(sourceNodeId, userLineDirection); if (closestSegmentId > 0) { // Snap to angle increments originating from this closest segment var closestSegmentDirection = NetNodeUtility.GetSegmentExitDirection(sourceNodeId, closestSegmentId); var currentAngle = Vector3Extensions.Angle(closestSegmentDirection, userLineDirection, Vector3.up); var snappedAngle = Mathf.Round(currentAngle / Settings.SnapAngle) * Settings.SnapAngle; var snappedDirection = Quaternion.AngleAxis(snappedAngle, Vector3.up) * closestSegmentDirection; controlPoint.m_direction = snappedDirection.normalized; controlPoint.m_position = sourceNode.m_position + userLineLength * controlPoint.m_direction; controlPoint.m_position.y = newPoint.m_position.y; minDistanceSq = (newPoint.m_position - controlPoint.m_position).sqrMagnitude; success = true; //minDistanceSq = olpo; } } else if (oldPoint.m_segment != 0 && !newPoint.m_outside) { // Else if dragging from a segment // Segment the road build operation is starting from var sourceSegmentId = oldPoint.m_segment; var sourceSegment = NetManager.instance.m_segments.m_buffer[sourceSegmentId]; Vector3 segmentDirection; Vector3 segmentPosition; // Direction and length of the line between control points var userLineDirection = (newPoint.m_position - oldPoint.m_position).Flatten(); var userLineLength = userLineDirection.magnitude; userLineDirection.Normalize(); // Get direction of the segment at the branch position sourceSegment.GetClosestPositionAndDirection(oldPoint.m_position, out segmentPosition, out segmentDirection); var currentAngle = Vector3Extensions.Angle(segmentDirection, userLineDirection, Vector3.up); segmentDirection = segmentDirection.Flatten().normalized; var snappedAngle = Mathf.Round(currentAngle / Settings.SnapAngle) * Settings.SnapAngle; var snappedDirection = Quaternion.AngleAxis(snappedAngle, Vector3.up) * segmentDirection; controlPoint.m_direction = snappedDirection.normalized; controlPoint.m_position = oldPoint.m_position + userLineLength * controlPoint.m_direction; controlPoint.m_position.y = newPoint.m_position.y; minDistanceSq = (newPoint.m_position - controlPoint.m_position).sqrMagnitude; success = true; } else if (oldPoint.m_direction.sqrMagnitude > 0.5f) { if (newPoint.m_node == 0 && !newPoint.m_outside) { // Let's do some snapping between control point directions var currentAngle = Vector3Extensions.Angle(oldPoint.m_direction, newPoint.m_direction, Vector3.up); var snappedAngle = Mathf.Round(currentAngle / Settings.SnapAngle) * Settings.SnapAngle; var snappedDirection = Quaternion.AngleAxis(snappedAngle, Vector3.up) * oldPoint.m_direction.Flatten(); controlPoint.m_direction = snappedDirection.normalized; controlPoint.m_position = oldPoint.m_position + Vector3.Distance(oldPoint.m_position.Flatten(), newPoint.m_position.Flatten()) * controlPoint.m_direction; controlPoint.m_position.y = newPoint.m_position.y; success = true; } } else if (oldPoint.m_segment == 0 && oldPoint.m_node == 0 && newPoint.m_segment == 0 && oldPoint.m_segment == 0) { // Snap to angles based from north var userLineDirection = (newPoint.m_position - oldPoint.m_position).Flatten(); var userLineLength = userLineDirection.magnitude; userLineDirection.Normalize(); var snapDirection = Vector3.forward; var currentAngle = Vector3Extensions.Angle(snapDirection, userLineDirection, Vector3.up); var snappedAngle = Mathf.Round(currentAngle / Settings.SnapAngle) * Settings.SnapAngle; var snappedDirection = Quaternion.AngleAxis(snappedAngle, Vector3.up) * snapDirection; controlPoint.m_direction = snappedDirection.normalized; controlPoint.m_position = oldPoint.m_position + userLineLength * controlPoint.m_direction; controlPoint.m_position.y = newPoint.m_position.y; minDistanceSq = (newPoint.m_position - controlPoint.m_position).sqrMagnitude; success = true; } } else { // Run the default snapping Revert(); controlPoint = NetTool.SnapDirection(newPoint, oldPoint, info, out success, out minDistanceSq); Deploy(); } if (EnableAdvancedSnapping) { if (controlPoint.m_segment == 0 && controlPoint.m_node == 0) { controlPoint = SnapDirectionGuideLines(controlPoint, oldPoint, info, ref success, ref minDistanceSq); } } return(controlPoint); }