public Vector3 SnapExtents1D(Extents1D currentExtents, Vector3 currentPosition, Vector3 slideOrigin, Vector3 slideDirection, float snappingStep, out SnapResult1D snapResult) { snapResult = SnapResult1D.None; var offsetPos = currentPosition - slideOrigin; var offsetDistance = SnappingUtility.WorldPointToDistance(offsetPos, slideDirection); var currDistance = offsetDistance - this.startOffset; var movedExtents = currentExtents + offsetDistance; var snappedExtents = movedExtents; snappedExtents.min = SnappingUtility.SnapValue(movedExtents.min, snappingStep); snappedExtents.max = SnappingUtility.SnapValue(movedExtents.max, snappingStep); var snappedExtentsOffset = snappedExtents - movedExtents; var snappedPivot = SnappingUtility.SnapValue(currDistance, snappingStep) - currDistance; if (!Snapping.BoundsSnappingActive && !Snapping.PivotSnappingActive) { return(currentPosition); } var abs_pivot = Snapping.PivotSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedPivot)) : float.PositiveInfinity; var abs_min_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedExtentsOffset.min)) : float.PositiveInfinity; var abs_max_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedExtentsOffset.max)) : float.PositiveInfinity; var snappedOffsetDistance = (abs_pivot < abs_min_extents && abs_pivot < abs_max_extents) ? snappedPivot : ((abs_min_extents < abs_max_extents) ? snappedExtentsOffset.min : snappedExtentsOffset.max); if (abs_min_extents <= abs_max_extents && abs_min_extents <= abs_pivot) { snapResult |= SnapResult1D.Min; } if (abs_max_extents <= abs_min_extents && abs_max_extents <= abs_pivot) { snapResult |= SnapResult1D.Max; } if (abs_pivot <= abs_min_extents && abs_pivot <= abs_max_extents) { snapResult |= SnapResult1D.Pivot; } min = slideOrigin + SnappingUtility.DistanceToWorldPoint(snappedExtents.min, slideDirection); max = slideOrigin + SnappingUtility.DistanceToWorldPoint(snappedExtents.max, slideDirection); var newOffset = offsetDistance + snappedOffsetDistance; if (Mathf.Abs(snappedOffsetDistance) > Mathf.Abs(offsetDistance)) { newOffset = 0; } var snappedDistance = SnappingUtility.DistanceToWorldPoint(newOffset, slideDirection); var snappedPosition = (snappedDistance + slideOrigin); return(snappedPosition); }
public void Initialize(Vector2 currentMousePosition, Vector3 slideOrigin, Vector3 slideDirection, float snappingStep, Axis axis) { this.slideDirection = slideDirection; this.snappingStep = snappingStep; this.slideOrigin = SceneHandleUtility.ProjectPointRay(Grid.ActiveGrid.Center, slideOrigin, slideDirection); this.slideExtents.min = this.slideExtents.max = 0; this.snappedPosition = this.slideOrigin; this.slidePosition = this.slideOrigin; this.slideOffset = slideOrigin - this.slideOrigin; this.startOffset = SnappingUtility.WorldPointToDistance(this.slidePosition - slideOrigin, slideDirection); this.startMousePosition = currentMousePosition; this.slideAxis = axis; this.snapResult = SnapResult1D.None; this.min = slideOrigin + SnappingUtility.DistanceToWorldPoint(slideExtents.min, slideDirection); this.max = slideOrigin + SnappingUtility.DistanceToWorldPoint(slideExtents.max, slideDirection); }
public static void RenderSnapping1D(Vector3 min, Vector3 max, Vector3 pivot, Vector3 slideDirection, SnapResult1D snapResult, Axis axis) { if (Event.current.type != EventType.Repaint) { return; } using (new SceneHandles.DrawingScope(Matrix4x4.identity)) { if (max == min && (snapResult & SnapResult1D.Min) != 0) { snapResult &= ~SnapResult1D.Max; } if (pivot == min && (snapResult & SnapResult1D.Min) != 0) { snapResult &= ~SnapResult1D.Pivot; } if (pivot == max && (snapResult & SnapResult1D.Max) != 0) { snapResult &= ~SnapResult1D.Pivot; } var grid = Grid.ActiveGrid; var dotX = Mathf.Abs(Vector3.Dot(grid.Forward.normalized, slideDirection)); var dotZ = Mathf.Abs(Vector3.Dot(grid.Right.normalized, slideDirection)); var dotY = Mathf.Abs(Vector3.Dot(grid.Up.normalized, slideDirection)); if ((dotY - dotX) < 0.00001f && (dotY - dotZ) < 0.00001f && ((1.0f - dotX) < 0.00001f || (1.0f - dotZ) < 0.00001f)) { var direction = (dotX < dotZ) ? grid.Forward : grid.Right; if ((snapResult & SnapResult1D.Pivot) != 0) { SceneHandles.DrawDottedLine(pivot + (direction * -1000), pivot + (direction * 1000), 4.0f); } if ((snapResult & SnapResult1D.Min) != 0) { SceneHandles.DrawDottedLine(min + (direction * -1000), min + (direction * 1000), 4.0f); } if ((snapResult & SnapResult1D.Max) != 0) { SceneHandles.DrawDottedLine(max + (direction * -1000), max + (direction * 1000), 4.0f); } } } }
public Vector3 SnapExtents1D(Vector3 currentPosition) { this.snapResult = SnapResult1D.None; var boundsActive = Snapping.BoundsSnappingActive; var pivotActive = Snapping.PivotSnappingActive; // Get custom snapping positions along the ray var haveCustomSnapping = Snapping.GetCustomSnappingPoints(this.slideOffset + slidePosition, this.slideDirection, 0, s_CustomSnapPoints); if (!boundsActive && !pivotActive && !haveCustomSnapping) { return(currentPosition); } const float kMinPointSnap = 0.25f; float minPointSnap = !(boundsActive || pivotActive) ? kMinPointSnap : float.PositiveInfinity; // Offset to snapped position relative to the unsnapped position // (used to determine which snap value is closest to unsnapped position) // Smallest value is used float snappedOffsetDistance = float.PositiveInfinity; float snappedOffsetAbsDistance = float.PositiveInfinity; var deltaToOrigin = currentPosition - this.slideOrigin; var distanceToOrigin = SnappingUtility.WorldPointToDistance(deltaToOrigin, this.slideDirection); var quantized_min_extents = float.PositiveInfinity; var quantized_max_extents = float.PositiveInfinity; var snappedExtents = Extents1D.empty; if (boundsActive) { (float abs_distance, float snappedOffset, float quantized_min, float quantized_max) = Snapping.SnapBounds(this.slideExtents + distanceToOrigin, this.snappingStep); quantized_min_extents = quantized_min; quantized_max_extents = quantized_max; snappedExtents.min = this.slideExtents.min + distanceToOrigin + Mathf.Abs(quantized_min_extents); snappedExtents.max = this.slideExtents.min + distanceToOrigin + Mathf.Abs(quantized_max_extents); if (snappedOffsetAbsDistance > abs_distance) { snappedOffsetAbsDistance = abs_distance; snappedOffsetDistance = snappedOffset; } } var quantized_pivot = float.PositiveInfinity; if (pivotActive) { (float abs_distance, float snappedOffset, float quantized) = Snapping.SnapPoint(this.startOffset + distanceToOrigin, this.snappingStep); quantized_pivot = quantized; if (snappedOffsetAbsDistance > abs_distance) { snappedOffsetAbsDistance = abs_distance; snappedOffsetDistance = snappedOffset; } } if (haveCustomSnapping) { (float abs_distance, float snappedOffset) = Snapping.SnapCustom(s_CustomSnapPoints, this.startOffset + distanceToOrigin, this.slideDirection, minPointSnap, s_CustomDistances); if (snappedOffsetAbsDistance > abs_distance) { snappedOffsetAbsDistance = abs_distance; snappedOffsetDistance = snappedOffset; } } // If we didn't actually snap, just return the actual unsnapped position if (float.IsInfinity(snappedOffsetDistance)) { return(currentPosition); } // Snap against drag start position if (Mathf.Abs(snappedOffsetDistance) > Mathf.Abs(distanceToOrigin)) { snappedOffsetDistance = distanceToOrigin; } var quantizedDistance = SnappingUtility.Quantize(snappedOffsetDistance); // Figure out what kind of snapping visualization to show, this needs to be done afterwards since // while we're snapping each type of snap can override the next one. // Yet at the same time it's possible to snap with multiple snap-types at the same time. if (boundsActive) { if (quantizedDistance == quantized_min_extents) { this.snapResult |= SnapResult1D.Min; } if (quantizedDistance == quantized_max_extents) { this.snapResult |= SnapResult1D.Max; } min = this.slideOrigin + SnappingUtility.DistanceToWorldPoint(snappedExtents.min, this.slideDirection); max = this.slideOrigin + SnappingUtility.DistanceToWorldPoint(snappedExtents.max, this.slideDirection); } if (pivotActive) { if (quantizedDistance == quantized_pivot) { this.snapResult |= SnapResult1D.Pivot; } } if (haveCustomSnapping) { Snapping.SendCustomSnappedEvents(quantizedDistance, s_CustomDistances, 0); } // Calculate the new position based on the snapped offset var newOffset = distanceToOrigin - snappedOffsetDistance; var snappedDistance = SnappingUtility.DistanceToWorldPoint(newOffset, this.slideDirection); var snappedPosition = (snappedDistance + this.slideOrigin); return(snappedPosition); }