public IEnumerator PrefabTouchZoom() { InstantiateFromPrefab(); TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.Show(Vector3.zero)); yield return(handRight.MoveTo(panZoom.transform.position, 10)); TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(Vector3.zero)); yield return(handLeft.MoveTo(panZoom.transform.position + Vector3.right * -0.01f, 10)); yield return(handRight.Move(new Vector3(0.01f, 0f, 0f))); yield return(handLeft.Move(new Vector3(-0.01f, 0f, 0f))); Assert.AreEqual(0.4, panZoom.CurrentScale, 0.1, "slate did not zoom in using two finger touch"); yield return(handRight.Hide()); yield return(handLeft.Hide()); }
public IEnumerator TestClickEvents() { PlayModeTestUtilities.PushHandSimulationProfile(); PlayModeTestUtilities.SetHandSimulationMode(HandSimulationMode.Gestures); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.zero)); CameraCache.Main.transform.LookAt(interactable.transform); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.Hide()); Assert.True(wasClicked); PlayModeTestUtilities.PopHandSimulationProfile(); }
public IEnumerator TestTouchEvents() { interactable.gameObject.AddComponent <NearInteractionTouchableVolume>(); var touchReceiver = interactable.AddReceiver <InteractableOnTouchReceiver>(); bool didTouch = false; bool didUntouch = false; touchReceiver.OnTouchStart.AddListener(() => didTouch = true); touchReceiver.OnTouchEnd.AddListener(() => didUntouch = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.forward)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.MoveTo(interactable.transform.position)); yield return(testHand.MoveTo(Vector3.forward)); yield return(testHand.Hide()); Assert.True(didTouch, "Did not receive touch event"); Assert.True(didUntouch, "Did not receive touch end event"); }
public IEnumerator TestClickEvents() { var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldSimMode = iss.ControllerSimulationMode; iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures; // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.zero)); CameraCache.Main.transform.LookAt(interactable.transform); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.Hide()); Assert.True(wasClicked); iss.ControllerSimulationMode = oldSimMode; }
private IEnumerator DirectPinchAndMoveSlider(PinchSlider slider, float toSliderValue) { Debug.Log($"moving hand to value {toSliderValue}"); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(initialPos)); yield return(rightHand.MoveTo(slider.ThumbRoot.transform.position)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); if (!(toSliderValue >= 0 && toSliderValue <= 1)) { throw new System.ArgumentException("toSliderValue must be between 0 and 1"); } yield return(rightHand.MoveTo(Vector3.Lerp(slider.SliderStartPosition, slider.SliderEndPosition, toSliderValue))); // Buffer time for the hand to move to finish moving yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Hide()); }
public IEnumerator TestGrabEvents() { var grabReceiver = interactable.AddReceiver <InteractableOnGrabReceiver>(); interactable.gameObject.AddComponent <NearInteractionGrabbable>(); bool didGrab = false; grabReceiver.OnGrab.AddListener(() => didGrab = true); bool didRelease = false; grabReceiver.OnRelease.AddListener(() => didRelease = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(interactable.transform.position)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.Hide()); Assert.True(didGrab, "Did not receive grab event"); Assert.True(didRelease, "Did not receive release event"); GameObject.Destroy(cube); yield return(null); }
/// <summary> /// Scroll a slate using GGV and ensure that the slate scrolls /// expected amount. Assumes panZoom has already been created. /// </summary> /// <param name="expectedScroll">The amount panZoom is expected to scroll</param> private IEnumerator RunGGVScrollTest(float expectedScroll) { var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldSimMode = iss.ControllerSimulationMode; iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures; Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handRight.Show(Vector3.zero)); // Move requires a slower action (i.e. higher numSteps) in order to // achieve a reliable pan. yield return(handRight.Move(new Vector3(0.0f, -0.1f, 0f), 30)); Assert.AreEqual(expectedScroll, totalPanDelta.y, 0.1, "pan delta is not correct"); yield return(handRight.Hide()); iss.ControllerSimulationMode = oldSimMode; yield return(null); }
public IEnumerator TestAssembleInteractableAndFarManip() { GameObject pinchSliderObject; PinchSlider slider; // This should not throw exception AssembleSlider(Vector3.forward, Vector3.zero, out pinchSliderObject, out slider); Debug.Assert(slider.SliderValue == 0.5, "Slider should have value 0.5 at start"); // Set up ggv simulation PlayModeTestUtilities.PushHandSimulationProfile(); PlayModeTestUtilities.SetHandSimulationMode(ControllerSimulationMode.HandGestures); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(initialPos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(rightHand.Move(new Vector3(0.1f, 0, 0))); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Hide()); Assert.That(slider.SliderValue, Is.GreaterThan(0.5)); // clean up GameObject.Destroy(pinchSliderObject); PlayModeTestUtilities.PopHandSimulationProfile(); }
public IEnumerator Prefab_RayScroll() { InstantiateFromPrefab(Vector3.forward); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right); Vector3 screenPoint = CameraCache.Main.ViewportToScreenPoint(new Vector3(0.5f, 0.25f, 0.5f)); yield return(h.Show(CameraCache.Main.ScreenToWorldPoint(screenPoint))); Assert.True(PointerUtils.TryGetHandRayEndPoint(Handedness.Right, out Vector3 hitPointStart)); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(h.Move(new Vector3(0, -0.05f, 0), 10)); Assert.True(PointerUtils.TryGetHandRayEndPoint(Handedness.Right, out Vector3 hitPointEnd)); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Open)); TestUtilities.AssertNotAboutEqual(hitPointStart, hitPointEnd, "ray should not stick on slate scrolling"); Assert.AreEqual(0.1, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
public IEnumerator PrefabGGVZoom() { InstantiateFromPrefab(); PlayModeTestUtilities.SetHandSimulationMode(HandSimulationMode.Gestures); TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.Show(new Vector3(0.0f, 0.0f, 0.6f))); TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(new Vector3(-0.1f, 0.0f, 0.6f))); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handRight.Move(new Vector3(0.005f, 0.0f, 0.0f), 10)); yield return(handLeft.Move(new Vector3(-0.005f, 0.0f, 0.0f), 10)); Assert.AreEqual(0.5, panZoom.CurrentScale, 0.1, "slate did not zoom in using two ggv hands"); yield return(handRight.Hide()); yield return(handLeft.Hide()); }
public IEnumerator NearInteractionTouchableVariant() { var touchable = CreateTouchable <NearInteractionTouchable>(ObjectScale); touchable.SetLocalForward(touchNormal); touchable.SetBounds(new Vector2(0.5f, 0.5f)); yield return(new WaitForFixedUpdate()); yield return(null); TestHand testHand = new TestHand(Handedness.Right); yield return(testHand.Show(initialHandPosition)); using (var catcher = CreateTouchEventCatcher(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); // 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); // No touch when moving at behind the plane yield return(testHand.MoveTo(rightPosition)); Assert.AreEqual(2, catcher.EventsStarted); Assert.AreEqual(2, catcher.EventsCompleted); // 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); } yield return(testHand.Hide()); Object.Destroy(touchable.gameObject); }
public IEnumerator TestHandConstraintPalmUpSolverPlacement() { // Instantiate our test GameObject with solver. var testObjects = InstantiateTestSolver <HandConstraintPalmUp>(); testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint; testObjects.handler.TrackedHandness = Handedness.Both; var handConstraintSolver = (HandConstraintPalmUp)testObjects.solver; handConstraintSolver.FollowHandUntilFacingCamera = true; // Ensure that FacingCameraTrackingThreshold is greater than FollowHandCameraFacingThresholdAngle Assert.AreEqual(handConstraintSolver.FacingCameraTrackingThreshold - handConstraintSolver.FollowHandCameraFacingThresholdAngle > 0, true); yield return(new WaitForSeconds(SolverUpdateWaitTime)); TestUtilities.AssertAboutEqual(testObjects.target.transform.position, Vector3.zero, "HandConstraintPalmUp solver did not start at the origin"); var cameraTransform = CameraCache.Main.transform; // Place hand 1 meter in front of user, 50 cm below eye level var handTestPos = cameraTransform.position + cameraTransform.forward - (Vector3.up * 0.5f); var cameraLookVector = (handTestPos - cameraTransform.position).normalized; // Generate hand rotation with hand palm facing camera var handRoation = Quaternion.LookRotation(cameraTransform.up, cameraLookVector); // Add a right hand. var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(handTestPos)); yield return(rightHand.SetRotation(handRoation)); yield return(new WaitForSeconds(SolverUpdateWaitTime)); // Ensure Rotation and offset behavior are following camera Assert.AreEqual(handConstraintSolver.RotationBehavior, HandConstraint.SolverRotationBehavior.LookAtMainCamera); Assert.AreEqual(handConstraintSolver.OffsetBehavior, HandConstraint.SolverOffsetBehavior.LookAtCameraRotation); // Rotate hand so palm is no longer within the FollowHandCameraFacingThresholdAngle var newHandRot = handRoation * Quaternion.Euler(-(handConstraintSolver.FollowHandCameraFacingThresholdAngle + 1), 0f, 0f); yield return(rightHand.SetRotation(newHandRot)); yield return(new WaitForSeconds(SolverUpdateWaitTime)); // Ensure Rotation and offset behavior are following camera Assert.AreEqual(handConstraintSolver.RotationBehavior, HandConstraint.SolverRotationBehavior.LookAtTrackedObject); Assert.AreEqual(handConstraintSolver.OffsetBehavior, HandConstraint.SolverOffsetBehavior.TrackedObjectRotation); yield return(rightHand.Hide()); yield return(new WaitForSeconds(SolverUpdateWaitTime)); }
public IEnumerator TestAssembleTouchSnapSlider() { GameObject pinchSliderObject; PinchSlider slider; // This should not throw exception AssembleSlider(Vector3.forward, Vector3.zero, out pinchSliderObject, out slider); // Set the slider to use step divisions slider.UseSliderStepDivisions = true; slider.SliderStepDivisions = 4; // Set slider to snap with touch slider.SnapToPosition = true; slider.IsTouchable = true; yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); bool interactionStarted = false; slider.OnInteractionStarted.AddListener((x) => interactionStarted = true); bool interactionUpdated = false; slider.OnValueUpdated.AddListener((x) => interactionUpdated = true); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.3f, 0, 0.0f); yield return(rightHand.Show(initialPos)); yield return(rightHand.Move(new Vector3(0, 0, 1.0f))); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.IsTrue(interactionStarted, "Slider did not raise interaction started."); Assert.IsTrue(interactionUpdated, "Slider did not raise SliderUpdated event."); Assert.AreEqual(0.75f, slider.SliderValue); yield return(rightHand.Move(new Vector3(-0.6f, 0, 0))); Assert.AreEqual(0.25f, slider.SliderValue); yield return(rightHand.Move(new Vector3(0.3f, 0, 0))); Assert.AreEqual(0.5f, slider.SliderValue); bool interactionEnded = false; slider.OnInteractionEnded.AddListener((x) => interactionEnded = true); yield return(rightHand.Hide()); Assert.IsTrue(interactionEnded, "Slider did not raise interaction ended."); GameObject.Destroy(pinchSliderObject); }
public IEnumerator ManipulationHandlerThrow() { // 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 rigidBody = testObject.AddComponent <Rigidbody>(); rigidBody.useGravity = false; var manipHandler = testObject.AddComponent <ManipulationHandler>(); manipHandler.HostTransform = testObject.transform; manipHandler.SmoothingActive = false; // 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); TestHand hand = new TestHand(Handedness.Right); // grab the cube - move it to the right var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService(); Vector3 handOffset = new Vector3(0, 0, 0.1f); Vector3 initialHandPosition = new Vector3(0, 0, 0.5f); Vector3 rightPosition = new Vector3(1f, 0f, 1f); yield return(hand.Show(initialHandPosition)); yield return(hand.MoveTo(initialObjectPosition)); yield return(hand.GrabAndThrowAt(rightPosition)); // With simulated hand angular velocity would not be equal to 0, because of how simulation // moves hand when releasing the Pitch. Even though it doesn't directly follow from hand movement, there will always be some rotation. Assert.NotZero(rigidBody.angularVelocity.magnitude, "Manipulationhandler should apply angular velocity to rigidBody upon release."); Assert.AreEqual(rigidBody.velocity, hand.GetVelocity(), "Manipulationhandler should apply hand velocity to rigidBody upon release."); // This is just for debugging purposes, so object's movement after release can be seen. yield return(hand.MoveTo(initialHandPosition)); yield return(hand.Hide()); GameObject.Destroy(testObject); yield return(null); }
public IEnumerator ZoomRotatedSlate() { // Configuring camera and hands to interact with rotated slate InstantiateFromPrefab(Vector3.right, Quaternion.LookRotation(Vector3.right)); MixedRealityPlayspace.PerformTransformation(p => p.Rotate(Vector3.up, 90)); yield return(null); // Right hand pinches slate TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.Show(panZoom.transform.position + Vector3.forward * -0.1f + Vector3.right * -0.3f)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Left hand pinches slate TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(panZoom.transform.position + Vector3.forward * 0.1f + Vector3.right * -0.3f)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Use both hands to zoom in yield return(handRight.Move(new Vector3(0f, 0f, -0.1f), 5)); yield return(handLeft.Move(new Vector3(0f, 0f, 0.1f), 5)); Assert.AreEqual(0.6, panZoom.CurrentScale, 0.1, "Rotated slate did not zoom in using near interaction"); // Reset slate and hands configuration panZoom.Reset(); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(null); // Both hands touch slate yield return(handRight.MoveTo(panZoom.transform.position + Vector3.forward * -0.1f)); yield return(handLeft.MoveTo(panZoom.transform.position + Vector3.forward * 0.1f)); yield return(null); // Use both hands to zoom in yield return(handRight.Move(new Vector3(0f, 0f, -0.1f), 5)); yield return(handLeft.Move(new Vector3(0f, 0f, 0.1f), 5)); Assert.AreEqual(0.6, panZoom.CurrentScale, 0.1, "Rotated slate did not zoom in using far interaction"); yield return(handRight.Hide()); yield return(handLeft.Hide()); }
public IEnumerator TestPressEvents() { var testHand = new TestHand(Handedness.Right); interactable.gameObject.AddComponent <NearInteractionGrabbable>(); var pressReceiver = interactable.AddReceiver <InteractableOnPressReceiver>(); bool didPress = false; pressReceiver.OnPress.AddListener(() => didPress = true); yield return(testHand.Show(interactable.transform.position)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(testHand.Hide()); Assert.True(didPress, "did not receive press event"); }
public IEnumerator Prefab_TouchScroll() { InstantiateFromPrefab(Vector3.forward); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right);; yield return(h.MoveTo(panObject.transform.position)); yield return(h.Move(new Vector3(0, -0.05f, 0), 10)); Assert.AreEqual(0.1, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
public IEnumerator TestAssembleInteractableAndEventsRaised() { GameObject pinchSliderObject; PinchSlider slider; // This should not throw exception AssembleSlider(Vector3.forward, Vector3.zero, out pinchSliderObject, out slider); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.05f, 0, 1.0f); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); bool interactionStarted = false; slider.OnInteractionStarted.AddListener((x) => interactionStarted = true); yield return(rightHand.Show(initialPos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); Assert.IsTrue(interactionStarted, "Slider did not raise interaction started."); bool interactionUpdated = false; slider.OnValueUpdated.AddListener((x) => interactionUpdated = true); yield return(rightHand.Move(new Vector3(0.1f, 0, 0))); Assert.IsTrue(interactionUpdated, "Slider did not raise SliderUpdated event."); bool interactionEnded = false; slider.OnInteractionEnded.AddListener((x) => interactionEnded = true); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Hide()); Assert.IsTrue(interactionEnded, "Slider did not raise interaction ended."); Assert.That(slider.SliderValue, Is.GreaterThan(0.5)); GameObject.Destroy(pinchSliderObject); }
public IEnumerator TestHandConstraint() { // Instantiate our test GameObject with solver. var testObjects = InstantiateTestSolver <HandConstraint>(); testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint; testObjects.handler.TrackedHandness = Handedness.Both; yield return(new WaitForSeconds(SolverUpdateWaitTime)); TestUtilities.AssertAboutEqual(testObjects.target.transform.position, Vector3.zero, "HandConstraint solver did not start at the origin"); // Add a right hand. var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.zero)); // Move the hand to 0, 0, 1 and ensure that the hand constraint followed. var handPosition = Vector3.forward; yield return(rightHand.MoveTo(handPosition)); yield return(new WaitForSeconds(SolverUpdateWaitTime)); // Make sure the solver is not in the same location as the hand because the solver should move to a hand safe zone. TestUtilities.AssertNotAboutEqual(testObjects.target.transform.position, handPosition, "HandConstraint solver is in the same location of the hand when it should be slightly offset from the hand."); // Make sure the solver is near the hand. Assert.LessOrEqual(Vector3.Distance(testObjects.target.transform.position, handPosition), HandDistanceThreshold, "HandConstraint solver is not within {0} units of the hand", HandDistanceThreshold); // Hide the right hand and create a left hand. yield return(rightHand.Hide()); var leftHand = new TestHand(Handedness.Left); handPosition = Vector3.zero; yield return(leftHand.Show(handPosition)); yield return(new WaitForSeconds(SolverUpdateWaitTime)); // Make sure the solver is now near the other hand. Assert.LessOrEqual(Vector3.Distance(testObjects.target.transform.position, handPosition), HandDistanceThreshold, "HandConstraint solver is not within {0} units of the hand", HandDistanceThreshold); }
public IEnumerator PrefabScrollUpZoomOutLimited() { var maxPanHorizontal = 4f; var maxPanVertical = 4f; InstantiatePanLimitedSlateFromPrefab(maxPanHorizontal: maxPanHorizontal, maxPanVertical: maxPanVertical); yield return(ScrollToLimit(new Vector3(1, 1, 0))); // Right hand pinches slate TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.MoveTo(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * 0.2f)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Left hand pinches slate TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * -0.2f)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Use both hands to zoom out yield return(handLeft.Move(new Vector3(0.1f, 0.1f, 0f), 10)); var uvs = new List <Vector2>(); meshFilter.mesh.GetUVs(0, uvs); #if UNITY_2019_1_OR_NEWER Assert.AreEqual(maxPanHorizontal * material.mainTextureScale.x, uvs[3].x, 0.05, "mesh uv is not correct"); Assert.AreEqual(maxPanVertical * material.mainTextureScale.y, uvs[3].y, 0.05, "mesh uv is not correct"); #else Assert.AreEqual(maxPanHorizontal * material.mainTextureScale.x, uvs[1].x, 0.05, "mesh uv is not correct"); Assert.AreEqual(maxPanVertical * material.mainTextureScale.y, uvs[1].y, 0.05, "mesh uv is not correct"); #endif yield return(handRight.Hide()); yield return(handLeft.Hide()); }
/// <summary> /// Scroll a slate using GGV and ensure that the slate scrolls /// expected amount. Assumes panZoom has already been created. /// </summary> /// <param name="expectedScroll">The amount panZoom is expected to scroll</param> private IEnumerator RunGGVScrollTest(float expectedScroll) { PlayModeTestUtilities.SetHandSimulationMode(HandSimulationMode.Gestures); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(h.Show(Vector3.zero)); yield return(h.Move(new Vector3(0.0f, -0.1f, 0f))); Assert.AreEqual(expectedScroll, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
public IEnumerator TestUseSourcePoseDataAsFallback() { TestHand rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); PokePointer pokePointer = PointerUtils.GetPointer <PokePointer>(Handedness.Right); Assert.IsNotNull(pokePointer); pokePointer.UseSourcePoseAsFallback = true; SpherePointer grabPointer = PointerUtils.GetPointer <SpherePointer>(Handedness.Right); Assert.IsNotNull(grabPointer); grabPointer.UseSourcePoseAsFallback = true; // Setting the pointer's pose action to a new input action is functionally equivalent to ensuring that an event is never raised of the pointer's desired pose action // This makes it so it will have to use the source pose data as a fallback pokePointer.PoseAction = new MixedRealityInputAction(); grabPointer.PoseAction = new MixedRealityInputAction(); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(rightHand.Hide()); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // The source pose is centered on the palm MixedRealityPose palmPose; HandJointUtils.TryGetJointPose(TrackedHandJoint.Palm, Handedness.Right, out palmPose); // This offset value is derived from the PokePointer's sourcePoseOffset property float pokePointerOffset = 0.075f; TestUtilities.AssertAboutEqual(pokePointer.Position, grabPointer.Position + pokePointer.transform.forward * pokePointerOffset, "pointer was not in the expected position"); TestUtilities.AssertAboutEqual(grabPointer.Position, palmPose.Position, "pointer was not in the expected position"); }
/// <summary> /// Scroll contents to the limit in the specified direction /// </summary> /// <param name="direction">Scroll direction</param> private IEnumerator ScrollToLimit(Vector3 direction) { TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.Show(Vector3.zero)); Vector3 screenPoint = CameraCache.Main.ViewportToScreenPoint(new Vector3(0.5f, 0.0f, 0.5f)); var moveDelta = -0.5f * direction; for (var i = 0; i < 3; i++) { yield return(handRight.MoveTo(CameraCache.Main.ScreenToWorldPoint(screenPoint))); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handRight.Move(moveDelta, 10)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Open)); } yield return(handRight.Hide()); }
public IEnumerator Prefab_RayScroll() { InstantiateFromPrefab(Vector3.forward); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right); Vector3 screenPoint = CameraCache.Main.ViewportToScreenPoint(new Vector3(0.5f, 0.25f, 0.5f)); yield return(h.Show(CameraCache.Main.ScreenToWorldPoint(screenPoint))); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(h.Move(new Vector3(0, -0.05f, 0), 10)); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Open)); Assert.AreEqual(0.1, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
public IEnumerator TestHoldEvents() { // Hold var holdReceiver = interactable.AddReceiver <InteractableOnHoldReceiver>(); bool didHold = false; holdReceiver.OnHold.AddListener(() => didHold = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(interactable.transform.position)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForSeconds(holdReceiver.HoldTime)); yield return(testHand.Hide()); Assert.True(didHold, "Did not receive hold event"); GameObject.Destroy(cube); yield return(null); }
public IEnumerator TestOverlap() { // Instantiate our test GameObject with solver. var testObjects = InstantiateTestSolver <Overlap>(); testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint; var targetTransform = testObjects.target.transform; TestUtilities.AssertAboutEqual(targetTransform.position, Vector3.zero, "Overlap not at original position"); TestUtilities.AssertAboutEqual(targetTransform.rotation, Quaternion.identity, "Overlap not at original rotation"); // Test that the solver flies to the position of the left hand var handPosition = Vector3.forward - Vector3.right; var handRotation = Quaternion.LookRotation(handPosition); var leftHand = new TestHand(Handedness.Left); yield return(leftHand.Show(handPosition)); yield return(leftHand.SetRotation(handRotation)); yield return(WaitForFrames(2)); var hand = PlayModeTestUtilities.GetInputSimulationService().GetHandDevice(Handedness.Left); Assert.IsNotNull(hand); Assert.IsTrue(hand.TryGetJoint(TrackedHandJoint.Palm, out MixedRealityPose pose)); TestUtilities.AssertAboutEqual(targetTransform.position, pose.Position, "Overlap solver is not at the same position as the left hand."); Assert.IsTrue(Quaternion.Angle(targetTransform.rotation, pose.Rotation) < 2.0f); // Make sure the solver did not move when hand was hidden yield return(leftHand.Hide()); yield return(WaitForFrames(2)); TestUtilities.AssertAboutEqual(targetTransform.position, pose.Position, "Overlap solver moved when the hand was hidden."); Assert.IsTrue(Quaternion.Angle(targetTransform.rotation, pose.Rotation) < 2.0f); }
public IEnumerator TestToggleEvents() { var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldSimMode = iss.ControllerSimulationMode; iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures; var toggleReceiver = interactable.AddReceiver <InteractableOnToggleReceiver>(); interactable.transform.position = Vector3.forward * 2f; interactable.NumOfDimensions = 2; interactable.CanSelect = true; interactable.CanDeselect = true; bool didSelect = false; bool didUnselect = false; toggleReceiver.OnSelect.AddListener(() => didSelect = true); toggleReceiver.OnDeselect.AddListener(() => didUnselect = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.forward)); CameraCache.Main.transform.LookAt(interactable.transform.position); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.Click()); yield return(testHand.Click()); yield return(testHand.Hide()); Assert.True(didSelect, "Toggle select did not fire"); Assert.True(didUnselect, "Toggle unselect did not fire"); iss.ControllerSimulationMode = oldSimMode; }
public IEnumerator TestPointerFOV() { var rightHand = new TestHand(Handedness.Right); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent <NearInteractionGrabbable>(); cube.AddComponent <NearInteractionTouchableVolume>(); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); var spherePointer = PointerUtils.GetPointer <SpherePointer>(Handedness.Right); var pokePointer = PointerUtils.GetPointer <PokePointer>(Handedness.Right); yield return(TestPointerFOVHelper(spherePointer, cube, rightHand)); yield return(TestPointerFOVHelper(pokePointer, cube, rightHand)); rightHand.Hide(); GameObject.Destroy(cube); }
public IEnumerator TestUseSourcePoseData() { TestHand rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); PokePointer pokePointer = PointerUtils.GetPointer <PokePointer>(Handedness.Right); Assert.IsNotNull(pokePointer); SpherePointer grabPointer = PointerUtils.GetPointer <SpherePointer>(Handedness.Right); Assert.IsNotNull(grabPointer); pokePointer.UseSourcePoseData = true; grabPointer.UseSourcePoseData = true; yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(rightHand.Hide()); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // The source pose is centered on the palm MixedRealityPose palmPose; HandJointUtils.TryGetJointPose(TrackedHandJoint.Palm, Handedness.Right, out palmPose); // This offset value is derived from the PokePointer's sourcePoseOffset property float pokePointerOffset = 0.075f; TestUtilities.AssertAboutEqual(pokePointer.Position, grabPointer.Position + pokePointer.transform.forward * pokePointerOffset, "pointer was not in the expected position"); TestUtilities.AssertAboutEqual(grabPointer.Position, palmPose.Position, "pointer was not in the expected position"); }
public IEnumerator CursorContextMove() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); // The cube needs to be moved from under the gaze cursor before we add the manipulation handler. // Because the cube is under the gaze cursor from the beginning, it gets a focus gained event // in Setup(). When we show the right hand, we get a focus lost event from the gaze pointer. // This messes with the CursorContextManipulationHandler hoverCount, as it decrements without // ever having incremented. To avoid this, we move the cube out of focus before we add the // ManipulationHandler and CursorContextManipulationHandler. cube.transform.localPosition = new Vector3(0, -2, 2); yield return(new WaitForFixedUpdate()); yield return(null); cube.AddComponent <ManipulationHandler>(); var temp = cube.AddComponent <CursorContextManipulationHandler>(); yield return(new WaitForFixedUpdate()); yield return(null); // Move cube back to original postion (described above) cube.transform.localPosition = new Vector3(0, 0, 2); yield return(new WaitForFixedUpdate()); yield return(null); // Show right hand on object var rightHand = new TestHand(Handedness.Right); Vector3 rightPos = new Vector3(0.05f, 0, 1.5f); yield return(rightHand.Show(rightPos)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.None); // Pinch right hand yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); // Show left hand on object var leftHand = new TestHand(Handedness.Left); Vector3 leftPos = new Vector3(-0.05f, 0, 1.5f); yield return(rightHand.Hide()); yield return(leftHand.Show(leftPos)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.None); // Pinch left hand yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); // Show both hands on object yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Show(rightPos)); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); Object.Destroy(cube.GetComponent <ManipulationHandler>()); Object.Destroy(cube.GetComponent <CursorContextManipulationHandler>()); }