private float GetLocalOffset(SnapDirection snapDirection) { float result = 0; switch (snapDirection) { case SnapDirection.X: result = -_mesh.bounds.min.x * transform.localScale.x; break; case SnapDirection.NX: result = _mesh.bounds.max.x * transform.localScale.x; break; case SnapDirection.Y: result = -_mesh.bounds.min.y * transform.localScale.y; break; case SnapDirection.NY: result = _mesh.bounds.max.y * transform.localScale.y; break; case SnapDirection.Z: result = -_mesh.bounds.min.z * transform.localScale.z; break; case SnapDirection.NZ: result = _mesh.bounds.max.z * transform.localScale.z; break; } return(result); }
private Vector3 GetSnapDirectionVector(SnapDirection snapDirection) { Vector3 result = Vector3.zero; switch (snapDirection) { case SnapDirection.X: result = transform.right; break; case SnapDirection.NX: result = -transform.right; break; case SnapDirection.Y: result = transform.up; break; case SnapDirection.NY: result = -transform.up; break; case SnapDirection.Z: result = transform.forward; break; case SnapDirection.NZ: result = -transform.forward; break; } return(result); }
public void ProcessMovementOnMouseDrag() { RaycastHit hit; LayerMask mask = LayerMask.GetMask("Default"); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); bool didHit = false; didHit = Physics.Raycast(ray, out hit, Mathf.Infinity, mask.value); if (didHit && doSnap) { if (!_bIsSnapped) { _bIsSnapped = true; _snapDirection = ComputeSnapDirection(hit); } float localOffset = GetLocalOffset(_snapDirection); Vector3 snapDirectionVector = GetSnapDirectionVector(_snapDirection); if ((snapDirectionVector - hit.normal).magnitude > 0.01) { Quaternion rotation = Quaternion.FromToRotation(snapDirectionVector, hit.normal); Vector3 up = rotation * transform.up; Vector3 forward = rotation * transform.forward; transform.rotation = Quaternion.LookRotation(forward, up); } transform.position = hit.point + hit.normal.normalized * (localOffset + snapOffset); } else { _bIsSnapped = false; transform.position = GetMouseAsWorldPoint() + _mOffset; } }
private SnapDirection ComputeSnapDirection(RaycastHit hit) { SnapDirection snapDirection = SnapDirection.Y; var y = Vector3.Dot(transform.up, hit.normal); var x = Vector3.Dot(transform.right, hit.normal); var z = Vector3.Dot(transform.forward, hit.normal); if (Mathf.Abs(x) > Mathf.Abs(y) && Mathf.Abs(x) > Mathf.Abs(z) && (x > 0)) { snapDirection = SnapDirection.X; } if (Mathf.Abs(x) > Mathf.Abs(y) && Mathf.Abs(x) > Mathf.Abs(z) && (x < 0)) { snapDirection = SnapDirection.NX; } if (Mathf.Abs(y) > Mathf.Abs(x) && Mathf.Abs(y) > Mathf.Abs(z) && (y > 0)) { snapDirection = SnapDirection.Y; } if (Mathf.Abs(y) > Mathf.Abs(x) && Mathf.Abs(y) > Mathf.Abs(z) && (y < 0)) { snapDirection = SnapDirection.NY; } if (Mathf.Abs(z) > Mathf.Abs(y) && Mathf.Abs(z) > Mathf.Abs(x) && (z > 0)) { snapDirection = SnapDirection.Z; } if (Mathf.Abs(z) > Mathf.Abs(y) && Mathf.Abs(z) > Mathf.Abs(x) && (z < 0)) { snapDirection = SnapDirection.NZ; } return(snapDirection); }
/// <summary> /// Snaps the given value to be one of the values in the given list based on the snapDirection. /// </summary> /// <param name="value">The value to snap</param> /// <param name="snapDirection">Used to control how the given value snaps</param> /// <param name="snapList">A sorted list from low to high of values to snap to or an empty list</param> /// <returns>A value from the snapList that the passed in value was "snapped". If the snapList is /// empty, the given value is return unchanged.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Will be returned if when resolving the /// snap value the snap list encounters an out of order snapList OR an invalid snapDirection. </exception> public static int SnapTo(this int value, SnapDirection snapDirection, params int[] snapList) { if (snapList == null || snapList.Length == 0) { return(value); } var index = 0; var snapValueFirst = snapList[index++]; if (snapList.Length == 1 || value <= snapValueFirst) { return(snapValueFirst); } do { var snapValueSecond = snapList[index++]; if (snapValueFirst >= snapValueSecond) { throw new ArgumentOutOfRangeException($"Expected {snapValueFirst} to be less then {snapValueSecond}"); } if (value == snapValueSecond) { return(snapValueSecond); } if (value < snapValueSecond) { var firstDiff = Abs(snapValueFirst - value); var secondDiff = Abs(snapValueSecond - value); int SnapToNearest() => (firstDiff < secondDiff ? snapValueFirst : snapValueSecond); switch (snapDirection) { case SnapDirection.NearestRoundUp: return(firstDiff == secondDiff ? snapValueSecond : SnapToNearest()); case SnapDirection.NearestRoundDown: return(firstDiff == secondDiff ? snapValueFirst : SnapToNearest()); case SnapDirection.AlwaysRoundDown: return(snapValueFirst); case SnapDirection.AlwaysRoundUp: return(snapValueSecond); default: throw new ArgumentOutOfRangeException(nameof(snapDirection), snapDirection, "Unknown snap direction"); } } snapValueFirst = snapValueSecond; } while(index < snapList.Length); return(snapValueFirst); }
protected virtual void Resize(SnappingWindow snappingWindow, Point offset, SnapDirection direction) { var bounds = snappingWindow.Adapter.Bounds; if (this.ResizeDirection.HasFlag(ResizeDirection.Left)) { if (direction.HasFlag(SnapDirection.InsideLeft) && direction.HasFlag(SnapDirection.InsideRight)) { bounds.X = snappingWindow.PreviousBounds.X + offset.X; bounds.Width = snappingWindow.PreviousBounds.Width - offset.X; } else if (direction.HasFlag(SnapDirection.InsideLeft) || direction.HasFlag(SnapDirection.OutsideRight)) { bounds.X = snappingWindow.PreviousBounds.X + offset.X; } } if (this.ResizeDirection.HasFlag(ResizeDirection.Right)) { if (direction.HasFlag(SnapDirection.InsideLeft) && direction.HasFlag(SnapDirection.InsideRight)) { bounds.Width = snappingWindow.PreviousBounds.Width + offset.X; } else if (direction.HasFlag(SnapDirection.OutsideLeft) || direction.HasFlag(SnapDirection.InsideRight)) { bounds.X = snappingWindow.PreviousBounds.X + offset.X; } } if (this.ResizeDirection.HasFlag(ResizeDirection.Top)) { if (direction.HasFlag(SnapDirection.InsideTop) && direction.HasFlag(SnapDirection.InsideBottom)) { bounds.Y = snappingWindow.PreviousBounds.Y + offset.Y; bounds.Height = snappingWindow.PreviousBounds.Height - offset.Y; } else if (direction.HasFlag(SnapDirection.InsideTop) || direction.HasFlag(SnapDirection.OutsideBottom)) { bounds.Y = snappingWindow.PreviousBounds.Y + offset.Y; } } if (this.ResizeDirection.HasFlag(ResizeDirection.Bottom)) { if (direction.HasFlag(SnapDirection.InsideTop) && direction.HasFlag(SnapDirection.InsideBottom)) { bounds.Height = snappingWindow.PreviousBounds.Height + offset.Y; } else if (direction.HasFlag(SnapDirection.OutsideTop) || direction.HasFlag(SnapDirection.InsideBottom)) { bounds.Y = snappingWindow.PreviousBounds.Y + offset.Y; } } if (snappingWindow.Adapter.Bounds != bounds) { snappingWindow.Adapter.Bounds = bounds; } }
private float GetDistanceFromGround(SnapDirection snapDirection, Vector2 mousePosition) { if (snapDirection.HasFlag(SnapDirection.left) || snapDirection.HasFlag(SnapDirection.right)) { return(Mathf.Abs(GroundPosition.x - mousePosition.x)); } else { return(Mathf.Abs(GroundPosition.y - mousePosition.y)); } }
private float GetDeltaPosition(SnapDirection snapDirection, Vector2 mouseDelta) { if (snapDirection.HasFlag(SnapDirection.left) || snapDirection.HasFlag(SnapDirection.right)) { return(mouseDelta.y); } else { return(mouseDelta.x); } }
protected virtual void Move(SnappingWindow snappingWindow, Point offset, SnapDirection direction) { var bounds = snappingWindow.Adapter.Bounds; var location = new Point( snappingWindow.PreviousBounds.X - offset.X, snappingWindow.PreviousBounds.Y - offset.Y ); bounds.Location = location; if (snappingWindow.Adapter.Bounds != bounds) { snappingWindow.Adapter.Bounds = bounds; } }
private float GetRotationOffset(SnapDirection snapDirection, bool upSideDown = false) { switch (snapDirection) { case SnapDirection.left: return(upSideDown ? 90 : -90); case SnapDirection.right: return(upSideDown ? -90 : 90); case SnapDirection.up: return(upSideDown ? 0 : 180); default: return(upSideDown ? 180 : 0); } }
private Vector2 GetSnapDirecton(SnapDirection snapDirection) { switch (snapDirection) { case SnapDirection.left: return(Vector2.left); case SnapDirection.right: return(Vector2.right); case SnapDirection.up: return(Vector2.up); case SnapDirection.down: return(Vector2.down); } return(Vector2.zero); }
protected virtual bool IsStuck(SnappingWindow snappingWindow, SnapDirection direction) { if (this.ResizeDirection.HasFlag(ResizeDirection.Left)) { return(direction.HasFlag(SnapDirection.InsideLeft) || direction.HasFlag(SnapDirection.OutsideRight)); } if (this.ResizeDirection.HasFlag(ResizeDirection.Right)) { return(direction.HasFlag(SnapDirection.InsideRight) || direction.HasFlag(SnapDirection.OutsideLeft)); } if (this.ResizeDirection.HasFlag(ResizeDirection.Top)) { return(direction.HasFlag(SnapDirection.InsideTop) || direction.HasFlag(SnapDirection.OutsideBottom)); } if (this.ResizeDirection.HasFlag(ResizeDirection.Bottom)) { return(direction.HasFlag(SnapDirection.InsideBottom) || direction.HasFlag(SnapDirection.OutsideTop)); } return(false); }
private void SnapToPageInDirection(SnapDirection snapDirection) { int closestPageIndex = 0; bool didClamp; float directionBias = pageProvider.GetSpacing() * 0.55f; switch (snapDirection) { case SnapDirection.Right: float rightOffset = targetScrollOffset + directionBias; closestPageIndex = IndexFromOffset(rightOffset, out didClamp); if (!didClamp) { OnSwipeRight.Invoke(); } break; case SnapDirection.Left: float leftOffset = targetScrollOffset - directionBias; closestPageIndex = IndexFromOffset(leftOffset, out didClamp); if (!didClamp) { OnSwipeLeft.Invoke(); } break; case SnapDirection.Closest: closestPageIndex = IndexFromOffset(targetScrollOffset, out didClamp); OnSnapClosest.Invoke(); break; default: throw new System.Exception("Invalid SnapDirection: " + snapDirection); } /// If we found a page in that direction. SnapToPage(closestPageIndex, false, true); }
private void ChceckForSurface(Transform transform, Vector2 mousePosition, SnapDirection snapDirection, LayerMask lasyerMask, bool upSideDown = false) { Grounded = false; Vector2 surfaceDirection = GetSnapDirecton(snapDirection); RaycastHit2D hit = Physics2D.Raycast(mousePosition - surfaceDirection, surfaceDirection, snapDistance + 1, lasyerMask); Debug.DrawRay(mousePosition - surfaceDirection, surfaceDirection, Color.green, 0.1f); if (hit.collider != null) { normal = hit.normal; if (Mathf.Abs(Vector2.Angle(-surfaceDirection, normal)) > maxSlope) { transform.rotation = Quaternion.identity; return; } GroundPosition = hit.point; float x = -hit.normal.y; float y = hit.normal.x; x = surfaceDirection.y < 0 ? x : -x; y = surfaceDirection.x < 0 ? -y : y; SlideDirection = new Vector2(x, y); float zRotation = Vector2.SignedAngle(-surfaceDirection, normal); zRotation += GetRotationOffset(snapDirection, upSideDown); transform.rotation = Quaternion.Euler(0, 0, zRotation); Grounded = true; } else { transform.rotation = Quaternion.identity; return; } }
/// <summary> /// Constructor that is called when the user drops - here, we'll essentially /// push the original drag event info down to the base class and store off /// our direction and offset. /// </summary> public ToolboxSnapDragDropEventArgs(SnapDirection snapDirections, Point offset, DragEventArgs origArgs) : base(origArgs.Data, origArgs.KeyState, origArgs.X, origArgs.Y, origArgs.AllowedEffect, origArgs.Effect) { throw new NotImplementedException(SR.NotImplementedByDesign); }
public ToolboxSnapDragDropEventArgs(SnapDirection snapDirections, Point offset, DragEventArgs origArgs) : base(origArgs.Data, origArgs.KeyState, origArgs.X, origArgs.Y, origArgs.AllowedEffect, origArgs.Effect) { this.snapDirections = snapDirections; this.offset = offset; }
public Vector2 Snap(Transform transform, Vector2 currentPosition, Vector2 mouseDeltaPosition, SnapDirection snapDirection, LayerMask lasyerMask, bool upSideDown = false) { Vector2 output = currentPosition; ChceckForSurface(transform, currentPosition, snapDirection, lasyerMask, upSideDown); if (Grounded && GetDistanceFromGround(snapDirection, currentPosition) < snapDistance + 1) { output = GroundPosition + SlideDirection * GetDeltaPosition(snapDirection, mouseDeltaPosition); } return(output); }
private static void SnapActiveWindow(SnapDirection dir) { RectangleF activeRelativeRectangle = GetActiveWindowRelativeRectangleF(); Rectangle workingArea = GetScreenActiveWindowIsOn().WorkingArea; RectangleF[] snapAreas = null; switch (dir) { case SnapDirection.TopLeft: case SnapDirection.TopRight: case SnapDirection.BottomLeft: case SnapDirection.BottomRight: snapAreas = new RectangleF[CornerSnapSizes.Count]; CornerSnapSizes.CopyTo(snapAreas); break; case SnapDirection.Top: case SnapDirection.Bottom: snapAreas = new RectangleF[TopSnapSizes.Count]; TopSnapSizes.CopyTo(snapAreas); break; case SnapDirection.Left: case SnapDirection.Right: snapAreas = new RectangleF[SideSnapSizes.Count]; SideSnapSizes.CopyTo(snapAreas); break; case SnapDirection.Center: snapAreas = new RectangleF[CenterSnapSizes.Count]; CenterSnapSizes.CopyTo(snapAreas); break; } //offset snap areas X switch (dir) { case SnapDirection.TopLeft: case SnapDirection.Top: case SnapDirection.Left: case SnapDirection.Bottom: case SnapDirection.BottomLeft: case SnapDirection.Center: break;//do nothing case SnapDirection.BottomRight: case SnapDirection.TopRight: case SnapDirection.Right: for (int i = 0; i < snapAreas.Length; i++) { snapAreas[i].X = 1 - snapAreas[i].Width; } break; } //offset snap areas Y switch (dir) { case SnapDirection.Top: case SnapDirection.Left: case SnapDirection.Right: case SnapDirection.TopLeft: case SnapDirection.TopRight: case SnapDirection.Center: break;//do nothing case SnapDirection.BottomRight: case SnapDirection.Bottom: case SnapDirection.BottomLeft: for (int i = 0; i < snapAreas.Length; i++) { snapAreas[i].Y = 1 - snapAreas[i].Height; } break; } //if already snapped to 2 than use 3, ect int snapIndex = 0; for (int i = snapAreas.Length-2; i>=0 ; i--) { if(CloseEnough(activeRelativeRectangle, snapAreas[i])) { snapIndex = ++i; break; } } int newX = workingArea.X + (int)(snapAreas[snapIndex].X * workingArea.Width); int newY = workingArea.Y + (int)(snapAreas[snapIndex].Y * workingArea.Height); int newW = (int)(snapAreas[snapIndex].Width * workingArea.Width); int newH = (int)(snapAreas[snapIndex].Height * workingArea.Height); MoveActiveWindowTo(newX, newY, newW, newH); }
private void SnapToPageInDirection(SnapDirection snapDirection) { int closestPageIndex = 0; bool didClamp; float directionBias = pageProvider.GetSpacing() * 0.55f; switch (snapDirection) { case SnapDirection.Right: float rightOffset = targetScrollOffset + directionBias; closestPageIndex = IndexFromOffset(rightOffset, out didClamp); if (!didClamp) { OnSwipeRight.Invoke(); } break; case SnapDirection.Left: float leftOffset = targetScrollOffset - directionBias; closestPageIndex = IndexFromOffset(leftOffset, out didClamp); if (!didClamp) { OnSwipeLeft.Invoke(); } break; case SnapDirection.Closest: closestPageIndex = IndexFromOffset(targetScrollOffset, out didClamp); OnSnapClosest.Invoke(); break; default: throw new System.Exception("Invalid SnapDirection: " + snapDirection); } /// If we found a page in that direction. SnapToPage(closestPageIndex); }
/// <summary> /// Default constructor. /// </summary> /// <param name="pose">The HandPose to measure.</param> /// <param name="score">Score of the snap.</param> /// <param name="direction">Direction of the snap.</param> public ScoredHandPose(HandPose pose, float score, SnapDirection direction) { this.Pose = pose; this.Score = score; this.Direction = direction; }
public override ScoredHandPose CalculateBestPose(HandPose userPose, float?scoreWeight = null, SnapDirection direction = SnapDirection.Any, float scale = 1f) { SnapPoint under = null; SnapPoint over = null; float t = 0f; (under, over, t) = FindRange(scale); ScoredHandPose?result = null; if (t >= 0f) { result = ScoredHandPose.Lerp( under.CalculateBestPose(userPose, scoreWeight, direction), over.CalculateBestPose(userPose, scoreWeight, direction), t); } if (!result.HasValue) { Debug.LogError("Invalid range"); return(points[0].CalculateBestPose(userPose, scoreWeight, direction)); } return(result.Value); }
/// <summary> /// Find the best valid hand-pose at this snap point. /// Remember that a snap point can actually have a whole surface the user can snap to. /// In some cases it can also have different hand scales with their surfaces, it will interpolate /// between the best available matches. /// </summary> /// <param name="userPose">Hand pose to compare to the snap point.</param> /// <param name="scoreWeight">How much to score the position or the rotation difference.</param> /// <param name="direction">Consider only poses at the surface using the provided direction.</param> /// <param name="scale">The desired scale of the hand to compare.</param> /// <returns>The most similar valid HandPose at this SnapPoint</returns> public abstract ScoredHandPose CalculateBestPose(HandPose userPose, float?scoreWeight = null, SnapDirection direction = SnapDirection.Any, float scale = 1f);