//----------------------------------------------------------------------- // // // Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // //----------------------------------------------------------------------- // Modifications copyright © 2020 Unity Technologies ApS #if AR_FOUNDATION_PRESENT || PACKAGE_DOCS_GENERATION using UnityEngine.XR.Interaction.Toolkit.Interactables; namespace UnityEngine.XR.Interaction.Toolkit.AR { /// /// Gesture for when the user performs a drag motion on the touch screen. /// public partial class DragGesture : Gesture { /// /// Initializes and returns an instance of . /// /// The gesture recognizer. /// The touch that started this gesture. public DragGesture(DragGestureRecognizer recognizer, Touch touch) : this(recognizer, new CommonTouch(touch)) { } /// /// Initializes and returns an instance of . /// /// The gesture recognizer. /// The touch that started this gesture. public DragGesture(DragGestureRecognizer recognizer, InputSystem.EnhancedTouch.Touch touch) : this(recognizer, new CommonTouch(touch)) { } DragGesture(DragGestureRecognizer recognizer, CommonTouch touch) : base(recognizer) { Reinitialize(touch); } internal void Reinitialize(Touch touch) => Reinitialize(new CommonTouch(touch)); internal void Reinitialize(InputSystem.EnhancedTouch.Touch touch) => Reinitialize(new CommonTouch(touch)); void Reinitialize(CommonTouch touch) { Reinitialize(); fingerId = touch.fingerId; startPosition = touch.position; position = startPosition; delta = Vector2.zero; } /// /// (Read Only) The id of the finger used in this gesture. /// public int fingerId { get; private set; } /// /// (Read Only) The screen position where the gesture started. /// public Vector2 startPosition { get; private set; } /// /// (Read Only) The current screen position of the gesture. /// public Vector2 position { get; private set; } /// /// (Read Only) The delta screen position of the gesture. /// public Vector2 delta { get; private set; } /// /// (Read Only) The gesture recognizer. /// protected DragGestureRecognizer dragRecognizer => (DragGestureRecognizer)recognizer; /// protected internal override bool CanStart() { if (GestureTouchesUtility.IsFingerIdRetained(fingerId)) { Cancel(); return false; } var touches = GestureTouchesUtility.touches; if (touches.Count > 1) { foreach (var currentTouch in touches) { if (currentTouch.fingerId != fingerId && !GestureTouchesUtility.IsFingerIdRetained(currentTouch.fingerId)) { return false; } } } if (GestureTouchesUtility.TryFindTouch(fingerId, out var touch)) { var pos = touch.position; var diff = (pos - startPosition).magnitude; if (GestureTouchesUtility.PixelsToInches(diff) >= dragRecognizer.slopInches) { return true; } } else { Cancel(); } return false; } /// protected internal override void OnStart() { GestureTouchesUtility.LockFingerId(fingerId); #pragma warning disable 618 // Using deprecated property to help with backwards compatibility. if (GestureTouchesUtility.RaycastFromCamera(startPosition, recognizer.xrOrigin, recognizer.arSessionOrigin, out var hit, recognizer.raycastMask, recognizer.raycastTriggerInteraction)) #pragma warning restore 618 { var gameObject = hit.transform.gameObject; if (gameObject != null) { var grabInteractable = gameObject.GetComponentInParent(); if (grabInteractable != null) { var interactableObject = grabInteractable.gameObject; if (interactableObject != null) targetObject = interactableObject; } else { #pragma warning disable 618 var baseGestureInteractable = gameObject.GetComponentInParent(); if (baseGestureInteractable != null) { var interactableObject = baseGestureInteractable.gameObject; if (interactableObject != null) targetObject = interactableObject; } #pragma warning restore 618 } } } GestureTouchesUtility.TryFindTouch(fingerId, out var touch); position = touch.position; } /// protected internal override bool UpdateGesture() { if (GestureTouchesUtility.TryFindTouch(fingerId, out var touch)) { if (touch.isPhaseMoved) { delta = touch.position - position; position = touch.position; return true; } if (touch.isPhaseEnded) { Complete(); } else if (touch.isPhaseCanceled) { Cancel(); } } else { Cancel(); } return false; } /// protected internal override void OnCancel() { } /// protected internal override void OnFinish() => GestureTouchesUtility.ReleaseFingerId(fingerId); } } #endif