public IEnumerator NearInteractionTouchableVolumeVariant() { var touchable = CreateTouchable <NearInteractionTouchableVolume>(Vector3.one); yield return(new WaitForFixedUpdate()); yield return(null); TestHand testHand = new TestHand(Handedness.Left); yield return(testHand.Show(Vector3.zero)); yield return(testHand.MoveTo(initialHandPosition)); using (var catcher = CreateTouchEventCatcher(touchable)) { // Touch started when entering collider yield return(testHand.MoveTo(objectPosition)); Assert.AreEqual(1, catcher.EventsStarted); Assert.AreEqual(0, catcher.EventsCompleted); // Ensure no touch up event fires while moving hand/pokepointer through collider to each corner of volume Vector3[] cornerPositions = new Vector3[8]; touchable.GetComponent <BoxCollider>().bounds.GetCornerPositions(ref cornerPositions); for (int i = 0; i < cornerPositions.Length; i++) { yield return(testHand.MoveTo(cornerPositions[i])); Assert.AreEqual(1, catcher.EventsStarted, "Received extra touch down when moving through volume to position " + cornerPositions[i]); Assert.AreEqual(0, catcher.EventsCompleted, "Received extra touch up when moving through volume to position " + cornerPositions[i]); } // Touch up when exit collider yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(1, catcher.EventsStarted); Assert.AreEqual(1, catcher.EventsCompleted); // No touch when moving outside the collider yield return(testHand.Hide()); yield return(testHand.Show(backPosition)); yield return(testHand.MoveTo(backPosition + new Vector3(2f, 0f, 0f))); Assert.AreEqual(1, catcher.EventsStarted); Assert.AreEqual(1, catcher.EventsCompleted); // Touch when moving off-center yield return(testHand.Hide()); yield return(testHand.Show(initialHandPosition + outOfBoundsOffset)); yield return(testHand.MoveTo(objectPosition + outOfBoundsOffset)); yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(2, catcher.EventsCompleted); } UnityEngine.Object.Destroy(touchable.gameObject); }
public IEnumerator SpherePointerDistances() { var rightHand = new TestHand(Handedness.Right); // Show hand far enough from the test collider Vector3 idlePos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(idlePos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); var pointer = rightHand.GetPointer <SpherePointer>(); pointer.NearObjectSectorAngle = 360.0f; pointer.PullbackDistance = 0.0f; Vector3 margin = new Vector3(0, 0, 0.001f); Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius); Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller"); Vector3 nearObjectPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius); Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsNearObject yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.True(pointer.IsInteractionEnabled); // Move hand back out to disable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Testing that we have more leeway when the pointer's nearObject smoothing factor is set // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(idlePos, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); }
public IEnumerator BBoxHandlerUI() { const int numSteps = 2; var bbox = InstantiateSceneAndDefaultBbox(); bbox.ShowRotationHandleForX = true; bbox.ShowRotationHandleForY = true; bbox.ShowRotationHandleForZ = true; bbox.ShowScaleHandles = true; bbox.ProximityEffectActive = true; bbox.ScaleHandleSize = 0.1f; bbox.RotationHandleSize = 0.1f; bbox.FarScale = 1.0f; bbox.MediumScale = 1.5f; bbox.CloseScale = 1.5f; yield return(null); var bounds = bbox.GetComponent <BoxCollider>().bounds; Assert.AreEqual(new Vector3(0, 0, 1.5f), bounds.center); Assert.AreEqual(new Vector3(.5f, .5f, .5f), bounds.size); var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService(); // Defining the edge and corner handlers that will be used Debug.Log(bbox.transform.Find("rigRoot/midpoint_0").GetChild(0)); var originalCornerHandlerScale = bbox.transform.Find("rigRoot/corner_0/visualsScale/visuals").transform.localScale; var cornerHandlerPosition = bbox.transform.Find("rigRoot/corner_0").transform.position; var originalEdgeHandlerScale = bbox.transform.Find("rigRoot/midpoint_0/Sphere").transform.localScale; var edgeHandlerPosition = bbox.transform.Find("rigRoot/midpoint_0").transform.position; // Wait for the scaling/unscaling animation to finish yield return(new WaitForSeconds(0.2f)); // Move the hand to a handler on the corner TestHand rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(new Vector3(0, 0, 0.5f))); var delta = new Vector3(0.1f, 0.1f, 0f); yield return(rightHand.MoveTo(cornerHandlerPosition, numSteps)); // Wait for the scaling/unscaling animation to finish yield return(new WaitForSeconds(0.4f)); TestUtilities.AssertAboutEqual(bbox.transform.Find("rigRoot/midpoint_0/Sphere").transform.localScale, originalEdgeHandlerScale, "The edge handler changed mistakingly"); TestUtilities.AssertAboutEqual(bbox.transform.Find("rigRoot/corner_0/visualsScale/visuals").transform.localScale.normalized, originalCornerHandlerScale.normalized, "The corner handler scale has changed"); Assert.AreApproximatelyEqual(bbox.transform.Find("rigRoot/corner_0/visualsScale/visuals").transform.localScale.x / originalCornerHandlerScale.x, bbox.MediumScale, 0.1f, "The corner handler did not grow when a pointer was near it"); // Move the hand to a handler on the edge yield return(rightHand.MoveTo(edgeHandlerPosition, numSteps)); // Wait for the scaling/unscaling animation to finish yield return(new WaitForSeconds(0.4f)); TestUtilities.AssertAboutEqual(bbox.transform.Find("rigRoot/corner_0/visualsScale/visuals").transform.localScale, originalCornerHandlerScale, "The corner handler changed mistakingly"); TestUtilities.AssertAboutEqual(bbox.transform.Find("rigRoot/midpoint_0/Sphere").transform.localScale.normalized, originalEdgeHandlerScale.normalized, "The edge handler scale has changed"); Assert.AreApproximatelyEqual(bbox.transform.Find("rigRoot/midpoint_0/Sphere").transform.localScale.x / originalEdgeHandlerScale.x, bbox.MediumScale, 0.1f, "The edge handler did not grow when a pointer was near it"); GameObject.Destroy(bbox.gameObject); // Wait for a frame to give Unity a change to actually destroy the object yield return(null); }
public IEnumerator NearInteractionTouchablePointerEvents() { var touchable = CreateTouchable <NearInteractionTouchable>(objectScale); touchable.SetLocalForward(touchNormal); touchable.SetBounds(new Vector2(0.5f, 0.5f)); touchable.EventsToReceive = TouchableEventType.Pointer; yield return(new WaitForFixedUpdate()); yield return(null); TestHand testHand = new TestHand(Handedness.Right); yield return(testHand.Show(initialHandPosition)); using (var catcher = CreatePointerEventCatcher(touchable)) { yield return(testHand.MoveTo(objectPosition)); Assert.AreEqual(1, catcher.EventsStarted); Assert.AreEqual(0, catcher.EventsCompleted); yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(1, catcher.EventsStarted); Assert.AreEqual(1, catcher.EventsCompleted); Assert.Greater(catcher.DragEventCount, 0); // Touch started and completed when entering and exiting behind the plane yield return(testHand.MoveTo(initialHandPosition)); yield return(testHand.MoveTo(objectPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(1, catcher.EventsCompleted); yield return(testHand.MoveTo(backPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(2, catcher.EventsCompleted); Assert.Greater(catcher.DragEventCount, 1); int dragEventCount = catcher.DragEventCount; // No touch when moving at behind the plane yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(2, catcher.EventsCompleted); Assert.AreEqual(dragEventCount, catcher.DragEventCount, "No drag events should fire when poke pointer moving behind plane"); // No touch when moving outside the bounds yield return(testHand.MoveTo(initialHandPosition + outOfBoundsOffset)); yield return(testHand.MoveTo(objectPosition + outOfBoundsOffset)); yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(2, catcher.EventsCompleted); Assert.AreEqual(dragEventCount, catcher.DragEventCount, "No drag events should fire when poke pointer moving outside bounds"); } yield return(testHand.Hide()); UnityEngine.Object.Destroy(touchable.gameObject); }
public IEnumerator ConstrainScaleMinMax() { float initialScale = 0.2f; float minScale = 0.5f; float maxScale = 2f; // set up cube with manipulation handler var testObject = GameObject.CreatePrimitive(PrimitiveType.Cube); testObject.transform.localScale = Vector3.one * initialScale; Vector3 initialObjectPosition = new Vector3(0f, 0f, 1f); testObject.transform.position = initialObjectPosition; var manipHandler = testObject.AddComponent <ObjectManipulator>(); manipHandler.HostTransform = testObject.transform; manipHandler.SmoothingActive = false; manipHandler.ManipulationType = ManipulationHandFlags.TwoHanded; var scaleHandler = testObject.EnsureComponent <MinMaxScaleConstraint>(); scaleHandler.ScaleMinimum = minScale; scaleHandler.ScaleMaximum = maxScale; // add near interaction grabbable to be able to grab the cube with the simulated articulated hand testObject.AddComponent <NearInteractionGrabbable>(); yield return(new WaitForFixedUpdate()); yield return(null); const int numHandSteps = 1; Vector3 initialHandPosition = new Vector3(0, 0, 0.5f); Vector3 leftGrabPosition = new Vector3(-0.1f, -0.1f, 1f); // grab the bottom left corner of the cube Vector3 rightGrabPosition = new Vector3(0.1f, -0.1f, 1f); // grab the bottom right corner of the cube TestHand leftHand = new TestHand(Handedness.Left); TestHand rightHand = new TestHand(Handedness.Right); // Hands grab object at initial positions yield return(leftHand.Show(initialHandPosition)); yield return(leftHand.MoveTo(leftGrabPosition, numHandSteps)); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(rightHand.Show(initialHandPosition)); yield return(rightHand.MoveTo(rightGrabPosition, numHandSteps)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // No change to scale yet Assert.AreEqual(Vector3.one * initialScale, testObject.transform.localScale); // Move hands beyond max scale limit yield return(leftHand.MoveTo(new Vector3(-scaleHandler.ScaleMaximum, 0, 0) + leftGrabPosition, numHandSteps)); yield return(rightHand.MoveTo(new Vector3(scaleHandler.ScaleMaximum, 0, 0) + rightGrabPosition, numHandSteps)); // Assert scale at max Assert.AreEqual(Vector3.one * scaleHandler.ScaleMaximum, testObject.transform.localScale); // Move hands beyond min scale limit yield return(leftHand.MoveTo(new Vector3(scaleHandler.ScaleMinimum, 0, 0) + leftGrabPosition, numHandSteps)); yield return(rightHand.MoveTo(new Vector3(-scaleHandler.ScaleMinimum, 0, 0) + rightGrabPosition, numHandSteps)); // Assert scale at min Assert.AreEqual(Vector3.one * scaleHandler.ScaleMinimum, testObject.transform.localScale); }
public IEnumerator CombinedConstraintFarNear() { TestUtilities.PlayspaceToOriginLookingForward(); var testObject = GameObject.CreatePrimitive(PrimitiveType.Cube); testObject.transform.localScale = Vector3.one * 0.2f; Vector3 originalPosition = Vector3.forward; testObject.transform.position = originalPosition; Quaternion originalRotation = Quaternion.identity; testObject.transform.rotation = originalRotation; var manipHandler = testObject.AddComponent <ObjectManipulator>(); manipHandler.HostTransform = testObject.transform; manipHandler.SmoothingActive = false; manipHandler.OneHandRotationModeFar = ObjectManipulator.RotateInOneHandType.RotateAboutObjectCenter; // add near interaction grabbable to be able to grab the cube with the simulated articulated hand testObject.AddComponent <NearInteractionGrabbable>(); // add an xyz rotate constraint for one handed so we can only move var rotateConstraint = manipHandler.EnsureComponent <RotationAxisConstraint>(); rotateConstraint.UseLocalSpaceForConstraint = false; rotateConstraint.ConstraintOnRotation = AxisFlags.XAxis | AxisFlags.YAxis | AxisFlags.ZAxis; rotateConstraint.ProximityType = ManipulationProximityFlags.Near; // add an xyz move constraint for two handed so we can only rotate var moveConstraint = manipHandler.EnsureComponent <MoveAxisConstraint>(); moveConstraint.UseLocalSpaceForConstraint = false; moveConstraint.ConstraintOnMovement = AxisFlags.XAxis | AxisFlags.YAxis | AxisFlags.ZAxis; moveConstraint.ProximityType = ManipulationProximityFlags.Far; yield return(new WaitForFixedUpdate()); yield return(null); const int numHandSteps = 1; TestHand leftHand = new TestHand(Handedness.Left); TestHand rightHand = new TestHand(Handedness.Right); yield return(leftHand.Show(new Vector3(-0.05f, 0, 1))); yield return(rightHand.Show(new Vector3(0.05f, 0, 1))); yield return(null); // near interaction yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(leftHand.Move((Vector3.left + Vector3.up) * 0.2f, numHandSteps)); yield return(null); TestUtilities.AssertAboutEqual(originalRotation, testObject.transform.rotation, "Rotation should be equal for near interaction"); TestUtilities.AssertNotAboutEqual(originalPosition, testObject.transform.position, "Position should not be equal for near interaction"); // far interaction yield return(leftHand.Move((Vector3.right + Vector3.down) * 0.2f, numHandSteps)); yield return(null); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(null); yield return(leftHand.MoveTo(new Vector3(-0.05f, -0.1f, 0.45f), numHandSteps)); yield return(rightHand.MoveTo(new Vector3(0.05f, -0.1f, 0.45f), numHandSteps)); yield return(null); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(leftHand.Move((Vector3.left + Vector3.up) * 0.2f, numHandSteps)); yield return(null); TestUtilities.AssertNotAboutEqual(originalRotation, testObject.transform.rotation, "Rotation should not be equal for far interaction"); TestUtilities.AssertAboutEqual(originalPosition, testObject.transform.position, "Position should be equal for far interaction"); }
public IEnumerator ConstrainMovementAxisWorldSpace() { TestUtilities.PlayspaceToOriginLookingForward(); // set up cube with manipulation handler var testObject = GameObject.CreatePrimitive(PrimitiveType.Cube); testObject.transform.localScale = Vector3.one * 0.2f; Vector3 initialObjectPosition = new Vector3(0f, 0f, 1f); testObject.transform.position = initialObjectPosition; var manipHandler = testObject.AddComponent <ObjectManipulator>(); manipHandler.HostTransform = testObject.transform; manipHandler.SmoothingActive = false; manipHandler.ManipulationType = ManipulationHandFlags.OneHanded; var constraint = manipHandler.EnsureComponent <MoveAxisConstraint>(); constraint.UseLocalSpaceForConstraint = false; yield return(new WaitForFixedUpdate()); yield return(null); float moveAmount = 1.5f; const int numHandSteps = 1; // Hand pointing at middle of cube Vector3 initialHandPosition = new Vector3(0.044f, -0.1f, 0.45f); TestHand hand = new TestHand(Handedness.Right); yield return(hand.Show(initialHandPosition)); yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Constrain x axis constraint.ConstraintOnMovement = AxisFlags.XAxis; yield return(hand.Move(Vector3.one * moveAmount, numHandSteps)); yield return(null); Assert.AreEqual(initialObjectPosition.x, testObject.transform.position.x); Assert.AreNotEqual(initialObjectPosition.y, testObject.transform.position.y); Assert.AreNotEqual(initialObjectPosition.z, testObject.transform.position.z); yield return(hand.MoveTo(initialHandPosition, numHandSteps)); yield return(null); // Constrain y axis constraint.ConstraintOnMovement = AxisFlags.YAxis; yield return(hand.Move(Vector3.one * moveAmount, numHandSteps)); yield return(null); Assert.AreNotEqual(initialObjectPosition.x, testObject.transform.position.x); Assert.AreEqual(initialObjectPosition.y, testObject.transform.position.y); Assert.AreNotEqual(initialObjectPosition.z, testObject.transform.position.z); yield return(hand.MoveTo(initialHandPosition, numHandSteps)); yield return(null); // Constrain z axis constraint.ConstraintOnMovement = AxisFlags.ZAxis; yield return(hand.Move(Vector3.one * moveAmount, numHandSteps)); yield return(null); Assert.AreNotEqual(initialObjectPosition.x, testObject.transform.position.x); Assert.AreNotEqual(initialObjectPosition.y, testObject.transform.position.y); Assert.AreEqual(initialObjectPosition.z, testObject.transform.position.z); yield return(hand.MoveTo(initialHandPosition, numHandSteps)); yield return(null); // Constrain two axes constraint.ConstraintOnMovement = AxisFlags.XAxis | AxisFlags.ZAxis; yield return(hand.Move(Vector3.one * moveAmount, numHandSteps)); yield return(null); Assert.AreEqual(initialObjectPosition.x, testObject.transform.position.x); Assert.AreNotEqual(initialObjectPosition.y, testObject.transform.position.y); Assert.AreEqual(initialObjectPosition.z, testObject.transform.position.z); }
public IEnumerator Test() { // Step once to receive focus events from gaze pointer yield return(null); var expected = new PointerHandler.State(); expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusEnter++; handler.state.AssertEqual(expected); // // Test that the correct pointer events are raised when using a single pointer // // Show hand far enough from the test collider to not give it focus var rightHand = new TestHand(Handedness.Right); Vector3 rightNoFocusPos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(rightNoFocusPos)); // Should receive focus left events from gaze pointer expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusExit++; handler.state.AssertEqual(expected); // Move hand closer to the collider so it gives it focus Vector3 rightFocusPos = new Vector3(0.05f, 0, 1.5f); yield return(rightHand.MoveTo(rightFocusPos, numFramesPerMove)); expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusEnter++; handler.state.AssertEqual(expected); // Trigger pinch int previousNumPointerDragged = handler.state.numPointerDragged; yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); expected.numPointerDown++; handler.state.AssertEqual(expected); Assert.Greater(handler.state.numPointerDragged, previousNumPointerDragged); // Maintain pinch for a number of frames previousNumPointerDragged = handler.state.numPointerDragged; yield return(rightHand.MoveTo(rightFocusPos, numFramesPerMove)); Assert.Greater(handler.state.numPointerDragged, previousNumPointerDragged); handler.state.AssertEqual(expected); // Release pinch yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); expected.numPointerUp++; expected.numPointerClicked++; handler.state.AssertEqual(expected); // Move back to no focus yield return(rightHand.MoveTo(rightNoFocusPos, numFramesPerMove)); expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusExit++; handler.state.AssertEqual(expected); // // Test that the correct pointer events are raised when using two pointers // // Show left hand far enough from the test collider to not give it focus var leftHand = new TestHand(Handedness.Left); Vector3 leftNoFocusPos = new Vector3(-0.05f, 0, 1.0f); yield return(leftHand.Show(leftNoFocusPos)); // Make sure no events have been raised handler.state.AssertEqual(expected); // Move left hand to give focus Vector3 leftFocusPos = new Vector3(-0.05f, 0, 1.5f); yield return(leftHand.MoveTo(leftFocusPos, numFramesPerMove)); expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusEnter++; handler.state.AssertEqual(expected); // Move right hand to give focus yield return(rightHand.MoveTo(rightFocusPos, numFramesPerMove)); // Focus enter should not be raised as the object is already in focus. expected.numBeforeFocusChange++; expected.numFocusChanged++; handler.state.AssertEqual(expected); // Pinch left previousNumPointerDragged = handler.state.numPointerDragged; yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); expected.numPointerDown++; handler.state.AssertEqual(expected); Assert.Greater(handler.state.numPointerDragged, previousNumPointerDragged); // Pinch right previousNumPointerDragged = handler.state.numPointerDragged; yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); expected.numPointerDown++; handler.state.AssertEqual(expected); // Should be at least two greater, because there are two pointers down. // This is technically difficult to reason over because there can be arbitrary // but this is the best effort aside from tracking per-pointer drag counts. Assert.Greater(handler.state.numPointerDragged, previousNumPointerDragged + 1); // Open left yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); expected.numPointerUp++; expected.numPointerClicked++; expected.numPointerDragged++; // Right pointer is still down handler.state.AssertEqual(expected); Assert.Greater(handler.state.numPointerDragged, previousNumPointerDragged); // Open right yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); expected.numPointerUp++; expected.numPointerClicked++; handler.state.AssertEqual(expected); // Move left out of focus yield return(leftHand.MoveTo(leftNoFocusPos, numFramesPerMove)); // Focus exit should not be raised as the object is still in focus. expected.numBeforeFocusChange++; expected.numFocusChanged++; handler.state.AssertEqual(expected); // Move right out of focus yield return(rightHand.MoveTo(rightNoFocusPos, numFramesPerMove)); expected.numBeforeFocusChange++; expected.numFocusChanged++; expected.numFocusExit++; handler.state.AssertEqual(expected); }
public IEnumerator ReleaseButton([ValueSource(nameof(PressableButtonsTestPrefabFilenames))] string prefabFilename) { GameObject testButton = InstantiateDefaultPressableButton(prefabFilename); TestUtilities.PlayspaceToOriginLookingForward(); PressableButton buttonComponent = testButton.GetComponent <PressableButton>(); Assert.IsNotNull(buttonComponent); bool buttonPressed = false; buttonComponent.ButtonPressed.AddListener(() => { buttonPressed = true; }); bool buttonReleased = false; buttonComponent.ButtonReleased.AddListener(() => { buttonReleased = true; }); Vector3 startHand = new Vector3(0, 0, -0.0081f); Vector3 inButtonOnPress = new Vector3(0, 0, 0.002f); // past press plane of mrtk pressablebutton prefab Vector3 rightOfButtonPress = new Vector3(0.02f, 0, 0.002f); // right of press plane, outside button Vector3 inButtonOnRelease = new Vector3(0, 0, -0.0015f); // release plane of mrtk pressablebutton prefab TestHand hand = new TestHand(Handedness.Right); // test scenarios in normal and low framerate int[] stepVariations = { 30, 2 }; for (int i = 0; i < stepVariations.Length; ++i) { int numSteps = stepVariations[i]; // test release yield return(hand.Show(startHand)); yield return(hand.MoveTo(inButtonOnPress, numSteps)); yield return(hand.MoveTo(inButtonOnRelease, numSteps)); yield return(hand.Hide()); Assert.IsTrue(buttonPressed, $"A{i} - Button did not get pressed when hand moved to press it."); Assert.IsTrue(buttonReleased, $"A{i} - Button did not get released."); buttonPressed = false; buttonReleased = false; Assert.IsTrue(buttonComponent.ReleaseOnTouchEnd == true, "default behavior of button should be release on touch end"); // test release on moving outside of button yield return(hand.Show(startHand)); yield return(hand.MoveTo(inButtonOnPress, numSteps)); yield return(hand.MoveTo(rightOfButtonPress, numSteps)); yield return(hand.Hide()); Assert.IsTrue(buttonPressed, $"B{i} - Button did not get pressed when hand moved to press it."); Assert.IsTrue(buttonReleased, $"B{i} - Button did not get released when hand exited the button."); buttonPressed = false; buttonReleased = false; buttonComponent.ReleaseOnTouchEnd = false; // test no release on moving outside of button when releaseOnTouchEnd is disabled yield return(hand.Show(startHand)); yield return(hand.MoveTo(inButtonOnPress, numSteps)); yield return(hand.MoveTo(rightOfButtonPress, numSteps)); yield return(hand.Hide()); Assert.IsTrue(buttonPressed, $"C{i} - Button did not get pressed when hand moved to press it."); Assert.IsFalse(buttonReleased, $"C{i} - Button did got released on exit even though releaseOnTouchEnd wasn't set"); buttonPressed = false; buttonReleased = false; buttonComponent.ReleaseOnTouchEnd = true; } Object.Destroy(testButton); yield return(null); }
public IEnumerator SpherePointerSectorAngle() { var rightHand = new TestHand(Handedness.Right); // Show hand far enough from the test collider Vector3 idlePos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(idlePos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); var pointer = rightHand.GetPointer <SpherePointer>(); pointer.NearObjectSectorAngle = 180.0f; pointer.PullbackDistance = 0.0f; // Orient the right hand so the grab axis is approximately aligned with the z axis Vector3 margin = new Vector3(0, 0, 0.001f); Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius); Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller"); Vector3 nearObjectPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius); Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsNearObject yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand but maintain IsNearObject yield return(rightHand.SetRotation(Quaternion.Euler(0, 90, 0), numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand 200 degrees and lose IsNearObject yield return(rightHand.SetRotation(Quaternion.Euler(0, 200, 0), numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand back to original orientation yield return(rightHand.SetRotation(Quaternion.Euler(0, 0, 0), numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.True(pointer.IsInteractionEnabled); // Move hand back out to disable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(idlePos, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); }
public IEnumerator TestDialogPrefabResults() { TestHand handRight = new TestHand(Handedness.Right); int handsteps = 30; // Testing near interactions handRight.Show(Vector3.zero); InstantiateFromPrefab("Test Dialog", "This is an example dialog", DialogButtonType.OK, true); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.IsTrue(dialogComponent.State == DialogState.WaitingForInput); yield return(handRight.Move(new Vector3(0.0f, -0.1f, 1.0f), handsteps)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.AreEqual(dialogResult, DialogButtonType.OK); Assert.AreEqual(dialogComponent.State, DialogState.Closed); GameObject.Destroy(dialogGameObject); GameObject.Destroy(dialogComponent); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // The dialog only supports displaying up to two options yield return(handRight.MoveTo(Vector3.zero)); InstantiateFromPrefab("Test Dialog", "This is an example dialog", DialogButtonType.Yes | DialogButtonType.No, true); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.IsTrue(dialogComponent.State == DialogState.WaitingForInput); yield return(handRight.Move(new Vector3(0.1f, -0.1f, 1.0f), handsteps)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.AreEqual(dialogResult, DialogButtonType.No); Assert.AreEqual(dialogComponent.State, DialogState.Closed); GameObject.Destroy(dialogGameObject); GameObject.Destroy(dialogComponent); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // Testing far interactions // The dialog only supports displaying up to two options yield return(handRight.MoveTo(Vector3.zero)); InstantiateFromPrefab("Test Dialog", "This is an example dialog", DialogButtonType.Yes | DialogButtonType.No, false); // Wait for the dialog to move to a stable position yield return(new WaitForSeconds(0.5f)); Assert.IsTrue(dialogComponent.State == DialogState.WaitingForInput); // moving the hand to an appropriate position to click on the dialog yield return(handRight.Move(new Vector3(-0.1f, -0.2f, 0.7f), handsteps)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.AreEqual(dialogResult, DialogButtonType.Yes); Assert.AreEqual(dialogComponent.State, DialogState.Closed); GameObject.Destroy(dialogGameObject); GameObject.Destroy(dialogComponent); }