public IEnumerator GestureInteractor_SelectPlacementInteractable_CreatesGO([ValueSource(nameof(s_TouchInputSources))] GestureTouchesUtility.TouchInputSource touchInputSource) { SetupTouches(touchInputSource); var interactable = ObjectFactory.CreateGameObject("ARPlacementInteractable", typeof(ARPlacementInteractable)); var placementInteractable = interactable.GetComponent <ARPlacementInteractable>(); placementInteractable.placementPrefab = new GameObject(); placementInteractable.fallbackLayerMask = 1 << k_TestPlaneLayer; CreateTestPlane(); // This makes sure that the simulated touch is over the plane regardless of screen size. Vector3 screenPos = m_Camera.WorldToScreenPoint(interactable.transform.position); var objectPlacedCalled = 0; ARObjectPlacementEventArgs objectPlacedArgs = null; placementInteractable.objectPlaced.AddListener(args => { ++objectPlacedCalled; objectPlacedArgs = args; }); yield return(SimulateTouches( new Vector2[] { screenPos }, new Vector2[] { }, new Vector2[] { screenPos }, touchInputSource)); Assert.That(objectPlacedCalled, Is.EqualTo(1)); Assert.That(objectPlacedArgs, Is.Not.Null); Assert.That(objectPlacedArgs.placementInteractable, Is.SameAs(placementInteractable)); Assert.That(objectPlacedArgs.placementObject, Is.Not.Null); Assert.That(objectPlacedArgs.placementObject.transform.parent, Is.Not.Null); }
static void SetupTouches(GestureTouchesUtility.TouchInputSource touchInputSource) { GestureTouchesUtility.touchInputSource = touchInputSource; if (touchInputSource == GestureTouchesUtility.TouchInputSource.Enhanced) { InputSystem.InputSystem.AddDevice <Touchscreen>(); } }
public IEnumerator GestureInteractor_SelectSelectionInteractable_Selects([ValueSource(nameof(s_TouchInputSources))] GestureTouchesUtility.TouchInputSource touchInputSource) { SetupTouches(touchInputSource); var interactable = GameObject.CreatePrimitive(PrimitiveType.Cube); var selectionInteractable = interactable.AddComponent <ARSelectionInteractable>(); yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, new Vector2[] { }, new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, touchInputSource)); // Give interaction system a chance to process resulting interaction yield return(null); Assert.That(selectionInteractable.isSelected, Is.True); }
public IEnumerator GestureInteractor_TwistRotationInteractable_Rotates([ValueSource(nameof(s_TouchInputSources))] GestureTouchesUtility.TouchInputSource touchInputSource) { SetupTouches(touchInputSource); var interactable = GameObject.CreatePrimitive(PrimitiveType.Cube); interactable.AddComponent <ARSelectionInteractable>(); interactable.AddComponent <ARRotationInteractable>(); var originalRotation = interactable.transform.rotation; // Select yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, new Vector2[] { }, new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, touchInputSource)); // Twist const float startOffsetDelta = 100f; const float rotateOffsetDelta = 200f; yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2 - startOffsetDelta, Screen.height / 2), new Vector2(Screen.width / 2 + startOffsetDelta, Screen.height / 2) }, new Vector2[] { new Vector2(Screen.width / 2 - startOffsetDelta + rotateOffsetDelta, Screen.height / 2 - rotateOffsetDelta), new Vector2(Screen.width / 2 + startOffsetDelta - rotateOffsetDelta, Screen.height / 2 + rotateOffsetDelta) }, new Vector2[] { new Vector2(Screen.width / 2 - startOffsetDelta + rotateOffsetDelta, Screen.height / 2 - rotateOffsetDelta), new Vector2(Screen.width / 2 + startOffsetDelta - rotateOffsetDelta, Screen.height / 2 + rotateOffsetDelta) }, touchInputSource)); Assert.That(interactable.transform.rotation, Is.Not.EqualTo(originalRotation).Using(QuaternionEqualityComparer.Instance)); }
public IEnumerator GestureInteractor_PinchScaleInteractable_Scales([ValueSource(nameof(s_TouchInputSources))] GestureTouchesUtility.TouchInputSource touchInputSource) { SetupTouches(touchInputSource); var interactable = GameObject.CreatePrimitive(PrimitiveType.Cube); interactable.AddComponent <ARSelectionInteractable>(); interactable.AddComponent <ARScaleInteractable>(); var originalScale = interactable.transform.localScale; // Select yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, new Vector2[] { }, new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, touchInputSource)); // Pinch const float pinchStartOffset = 10f; const float pinchDelta = 200f; yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2 - pinchStartOffset, Screen.height / 2), new Vector2(Screen.width / 2 + pinchStartOffset, Screen.height / 2) }, new Vector2[] { new Vector2(Screen.width / 2 - pinchDelta, Screen.height / 2), new Vector2(Screen.width / 2 + pinchDelta, Screen.height / 2) }, new Vector2[] { new Vector2(Screen.width / 2 - pinchDelta, Screen.height / 2), new Vector2(Screen.width / 2 + pinchDelta, Screen.height / 2) }, touchInputSource)); Assert.That(interactable.transform.localScale.x, Is.GreaterThan(originalScale.x)); Assert.That(interactable.transform.localScale.y, Is.GreaterThan(originalScale.y)); Assert.That(interactable.transform.localScale.z, Is.GreaterThan(originalScale.z)); }
IEnumerator SimulateTouches(Vector2[] touchesBegan, Vector2[] touchesMoved, Vector2[] touchesEnded, GestureTouchesUtility.TouchInputSource touchInputSource) { Debug.Assert(touchesBegan.Length >= touchesMoved.Length); Debug.Assert(touchesBegan.Length >= touchesEnded.Length); Debug.Assert(touchInputSource == GestureTouchesUtility.TouchInputSource.Mock || touchInputSource == GestureTouchesUtility.TouchInputSource.Enhanced); // Give gesture recognizer a chance to process gesture input IEnumerator DoYield() { if (touchInputSource == GestureTouchesUtility.TouchInputSource.Enhanced) { InputSystem.InputSystem.Update(); } yield return(null); } if (touchesBegan.Length > 0) { GestureTouchesUtility.mockTouches.Clear(); for (var i = 0; i < touchesBegan.Length; ++i) { // For Input System, while a touch is ongoing, it must have a non-zero ID different from // all other ongoing touches. var id = i + 1; if (touchInputSource == GestureTouchesUtility.TouchInputSource.Mock) { GestureTouchesUtility.mockTouches.Add( new MockTouch { phase = TouchPhase.Began, deltaPosition = Vector2.zero, position = touchesBegan[i], fingerId = id, }); } else // Enhanced { BeginTouch(id, touchesBegan[i], true); } } yield return(DoYield()); } if (touchesMoved.Length > 0) { // Break move into steps to track const int moveSegments = 10; for (var iSegments = 0; iSegments < moveSegments; ++iSegments) { // Track initial move from start location GestureTouchesUtility.mockTouches.Clear(); for (var i = 0; i < touchesMoved.Length; ++i) { var deltaMove = (touchesMoved[i] - touchesBegan[i]) / moveSegments; var position = touchesBegan[i] + deltaMove * (iSegments + 1); var id = i + 1; if (touchInputSource == GestureTouchesUtility.TouchInputSource.Mock) { GestureTouchesUtility.mockTouches.Add( new MockTouch { phase = TouchPhase.Moved, deltaPosition = deltaMove, position = position, fingerId = id, }); } else // Enhanced { MoveTouch(id, position, deltaMove, true); } } yield return(DoYield()); } } if (touchesEnded.Length > 0) { GestureTouchesUtility.mockTouches.Clear(); for (var i = 0; i < touchesEnded.Length; ++i) { var deltaPosition = touchesEnded[i] - touchesBegan[i]; var id = i + 1; if (touchInputSource == GestureTouchesUtility.TouchInputSource.Mock) { GestureTouchesUtility.mockTouches.Add( new MockTouch { phase = TouchPhase.Ended, deltaPosition = deltaPosition, position = touchesEnded[i], fingerId = id, }); } else // Enhanced { EndTouch(id, touchesEnded[i], deltaPosition, true); } } yield return(DoYield()); } GestureTouchesUtility.mockTouches.Clear(); }
public IEnumerator GestureInteractor_DragTranslateInteractable_TranslatesAlongPlane([ValueSource(nameof(s_TouchInputSources))] GestureTouchesUtility.TouchInputSource touchInputSource) { SetupTouches(touchInputSource); var interactable = GameObject.CreatePrimitive(PrimitiveType.Cube); var selectionInteractable = interactable.AddComponent <ARSelectionInteractable>(); var translationInteractable = interactable.AddComponent <ARTranslationInteractable>(); translationInteractable.fallbackLayerMask = 1 << k_TestPlaneLayer; var parent = new GameObject("PlacementAnchor"); interactable.transform.parent = parent.transform; CreateTestPlane(); var originalPosition = interactable.transform.position; // Select yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, new Vector2[] { }, new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, touchInputSource)); // Give interaction system a chance to process resulting interaction yield return(null); Assert.That(selectionInteractable.isSelected, Is.True); // Drag const float translateDelta = 200f; yield return(SimulateTouches( new Vector2[] { new Vector2(Screen.width / 2, Screen.height / 2) }, new Vector2[] { new Vector2(Screen.width / 2 + translateDelta, Screen.height / 2 + translateDelta) }, new Vector2[] { new Vector2(Screen.width / 2 + translateDelta, Screen.height / 2 + translateDelta) }, touchInputSource)); Assert.That(selectionInteractable.isSelected, Is.True); // Translates along the XZ plane Assert.That(interactable.transform.position.x, Is.GreaterThan(originalPosition.x)); Assert.That(interactable.transform.position.z, Is.GreaterThan(originalPosition.z)); Assert.That(interactable.transform.position.y, Is.EqualTo(originalPosition.y).Within(1e-6f)); }