Esempio n. 1
0
        public IEnumerator TestFocusProviderWithoutGaze()
        {
            IMixedRealityInputSystem inputSystem = PlayModeTestUtilities.GetInputSystem();

            yield return(null);

            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            yield return(null);

            // Put up a hand to ensure there's a second pointer, which will keep the FocusProvider UpdatePointers loop spinning
            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            // Verify that the GazeProvider exists at the start
            Assert.IsTrue(inputSystem.GazeProvider as MonoBehaviour != null, "Gaze provider should exist at start");
            yield return(null);

            // Destroy the GazeProvider
            Object.Destroy(inputSystem.GazeProvider as MonoBehaviour);
            yield return(null);

            // Verify that the GazeProvider no longer exists
            Assert.IsTrue(inputSystem.GazeProvider as MonoBehaviour == null, "Gaze provider should no longer exist");
            yield return(null);

            // Hide the hand for other tests
            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));
        }
        /// <summary>
        /// Hide the hand
        /// </summary>
        /// <param name="waitForFixedUpdate">If true, will wait a physics frame after hiding</param>
        public IEnumerator Hide(bool waitForFixedUpdate = true)
        {
            yield return(PlayModeTestUtilities.HideHand(handedness, simulationService));

            if (waitForFixedUpdate)
            {
                yield return(new WaitForFixedUpdate());
            }
        }
        /// <summary>
        /// Move the right from in the button to just in front of the button
        /// </summary>
        public static IEnumerator MoveHandAwayFromButton(Transform button)
        {
            Vector3 p2 = button.transform.position;
            Vector3 p3 = button.transform.position - button.TransformDirection(ButtonTranslateOffset);

            yield return(MoveHand(p2, p3));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, PlayModeTestUtilities.GetInputSimulationService()));
        }
Esempio n. 4
0
        public IEnumerator NearInteractionTouchableVolumeVariant()
        {
            var touchable = CreateTouchable <NearInteractionTouchableVolume>(Vector3.one);

            yield return(new WaitForFixedUpdate());

            yield return(null);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSim));

            using (var catcher = CreateEventCatcher(touchable))
            {
                // Touch started when entering collider
                yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition, objectPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                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);
                var currentPos = objectPosition;
                for (int i = 0; i < cornerPositions.Length; i++)
                {
                    yield return(PlayModeTestUtilities.MoveHandFromTo(currentPos, cornerPositions[i], numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                    currentPos = cornerPositions[i];
                    Assert.AreEqual(1, catcher.EventsStarted, "Received extra touch down when moving through volume to position " + currentPos);
                    Assert.AreEqual(0, catcher.EventsCompleted, "Received extra touch up when moving through volume to position " + currentPos);
                }

                // Touch up when exit collider
                yield return(PlayModeTestUtilities.MoveHandFromTo(currentPos, rightPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

                Assert.AreEqual(1, catcher.EventsStarted);
                Assert.AreEqual(1, catcher.EventsCompleted);

                // No touch when moving outside the collider
                yield return(PlayModeTestUtilities.MoveHandFromTo(backPosition, rightPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

                Assert.AreEqual(1, catcher.EventsStarted);
                Assert.AreEqual(1, catcher.EventsCompleted);

                // Touch when moving off-center
                yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition + outOfBoundsOffset, objectPosition + outOfBoundsOffset, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                yield return(PlayModeTestUtilities.MoveHandFromTo(objectPosition + outOfBoundsOffset, rightPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                Assert.AreEqual(2, catcher.EventsStarted);
                Assert.AreEqual(2, catcher.EventsCompleted);
            }

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSim));

            UnityEngine.Object.Destroy(touchable.gameObject);
        }
        private IEnumerator MoveHandAwayFromButton()
        {
            Vector3 p2 = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3 = Vector3.zero;

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, MoveHandNumSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));
        }
Esempio n. 6
0
        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);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSim));

            using (var catcher = CreateEventCatcher(touchable))
            {
                // Touch started and completed when entering and exiting
                yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition, objectPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                Assert.AreEqual(1, catcher.EventsStarted);
                Assert.AreEqual(0, catcher.EventsCompleted);
                yield return(PlayModeTestUtilities.MoveHandFromTo(objectPosition, rightPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

                Assert.AreEqual(1, catcher.EventsStarted);
                Assert.AreEqual(1, catcher.EventsCompleted);

                // Touch started and completed when entering and exiting behind the plane
                yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition, objectPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                Assert.AreEqual(2, catcher.EventsStarted);
                Assert.AreEqual(1, catcher.EventsCompleted);
                yield return(PlayModeTestUtilities.MoveHandFromTo(objectPosition, backPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

                Assert.AreEqual(2, catcher.EventsStarted);
                Assert.AreEqual(2, catcher.EventsCompleted);

                // No touch when moving at behind the plane
                yield return(PlayModeTestUtilities.MoveHandFromTo(backPosition, rightPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

                Assert.AreEqual(2, catcher.EventsStarted);
                Assert.AreEqual(2, catcher.EventsCompleted);

                // No touch when moving outside the bounds
                yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition + outOfBoundsOffset, objectPosition + outOfBoundsOffset, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                yield return(PlayModeTestUtilities.MoveHandFromTo(objectPosition + outOfBoundsOffset, rightPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

                Assert.AreEqual(2, catcher.EventsStarted);
                Assert.AreEqual(2, catcher.EventsCompleted);
            }

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSim));

            UnityEngine.Object.Destroy(touchable.gameObject);
        }
Esempio n. 7
0
        /// <summary>
        /// Move the right from in the button to just in front of the button
        /// </summary>
        public static IEnumerator MoveHandAwayFromButton(Transform button)
        {
            Vector3 p2 = button.transform.position;
            Vector3 p3 = button.transform.position - button.TransformDirection(ButtonTranslateOffset);

            // Move the hand back
            var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            yield return(PlayModeTestUtilities.MoveHand(p2, p3, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));
        }
        public IEnumerator TestSimulatedHandInputOnPrefab()
        {
            // Load interactable prefab
            GameObject   interactableObject;
            Interactable interactable;
            Transform    translateTargetObject;

            InstantiateDefaultInteractablePrefab(
                new Vector3(0.025f, 0.05f, 0.5f),
                new Vector3(-90f, 0f, 0f),
                out interactableObject,
                out interactable,
                out translateTargetObject);

            // Subscribe to interactable's on click so we know the click went through
            bool wasClicked = false;

            interactable.OnClick.AddListener(() => { wasClicked = true; });

            Vector3 targetStartPosition = translateTargetObject.localPosition;

            // Move the hand forward to intersect the interactable
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 32;
            Vector3 p1       = new Vector3(0.0f, 0f, 0f);
            Vector3 p2       = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3       = new Vector3(0.0f, 0f, 0.0f);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            float pressStartTime = Time.time;
            bool  wasTranslated  = false;

            while (Time.time < pressStartTime + buttonPressAnimationDelay)
            {   // If the transform is moved at any point during this interval, we were successful
                yield return(new WaitForFixedUpdate());

                wasTranslated |= targetStartPosition != translateTargetObject.localPosition;
            }

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(new WaitForSeconds(buttonReleaseAnimationDelay));

            Assert.True(wasClicked, "Interactable was not clicked.");
            Assert.True(wasTranslated, "Transform target object was not translated by action.");
        }
        public IEnumerator NearInteractionTouchableOverlapQuerySaturation()
        {
            // Use all the points
            int numTouchables = NumRandomPoints;
            var touchables    = new NearInteractionTouchable[numTouchables];
            var catchers      = new TouchEventCatcher[numTouchables];

            // Spread out touchables over a radius, decrease over time to increase density and fill the buffer
            float radiusStart = 1.0f;
            float radiusEnd   = 0.01f;

            for (int i = 0; i < numTouchables; ++i)
            {
                Vector3 r = GetRandomPoint(i);

                touchables[i] = CreateTouchable <NearInteractionTouchable>(0.15f);
                touchables[i].SetLocalForward(touchNormal);
                touchables[i].SetBounds(new Vector2(0.5f, 0.5f));
                touchables[i].transform.position = objectPosition + r * radiusStart;

                catchers[i] = CreateTouchEventCatcher(touchables[i]);
            }

            yield return(new WaitForFixedUpdate());

            yield return(null);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSim));

            yield return(PlayModeTestUtilities.MoveHand(initialHandPosition, objectPosition, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim, 1));

            for (int i = 0; i < PlayModeTestUtilities.ControllerMoveSteps; ++i)
            {
                float scale = radiusStart + (radiusEnd - radiusStart) * (i + 1) / PlayModeTestUtilities.ControllerMoveSteps;
                for (int j = 0; j < numTouchables; ++j)
                {
                    Vector3 r = GetRandomPoint(j + 10);
                    touchables[j].transform.position = objectPosition + r * scale;
                }
                yield return(null);
            }

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSim));

            foreach (NearInteractionTouchable touchable in touchables)
            {
                Object.Destroy(touchable.gameObject);
            }
        }
Esempio n. 10
0
        private IEnumerator TestHandSolver(GameObject target, InputSimulationService inputSimulationService, Vector3 handPos, Handedness hand)
        {
            yield return(PlayModeTestUtilities.ShowHand(hand, inputSimulationService, Utilities.ArticulatedHandPose.GestureId.Open, handPos));

            // Give time for cube to float to hand
            yield return(WaitForFrames(2));

            Vector3 handOrbitalPos = target.transform.position;

            Assert.LessOrEqual(Vector3.Distance(handOrbitalPos, handPos), DistanceThreshold);

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(WaitForFrames(2));
        }
        /// <summary>
        /// Move the hand forward to press button, then off to the right
        /// </summary>
        private IEnumerator PressButtonWithHand()
        {
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            Vector3 p1 = new Vector3(0, 0, 0.5f);
            Vector3 p2 = new Vector3(0, 0, 1.08f);
            Vector3 p3 = new Vector3(0.1f, 0, 1.08f);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService, ArticulatedHandPose.GestureId.Open, p1));

            yield return(PlayModeTestUtilities.MoveHand(p1, p2, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHand(p2, p3, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));
        }
        public IEnumerator NearInteractionTouchableStack()
        {
            // Ignoring this test for now, as it needs fixing
            Assert.Ignore();

            int numTouchables = 10;
            var touchables    = new NearInteractionTouchable[numTouchables];
            var catchers      = new TouchEventCatcher[numTouchables];

            for (int i = 0; i < numTouchables; ++i)
            {
                Vector3 r = GetRandomPoint(i);

                touchables[i] = CreateTouchable <NearInteractionTouchable>(0.15f);
                touchables[i].SetLocalForward(touchNormal);
                touchables[i].SetBounds(new Vector2(0.5f, 0.5f));
                touchables[i].transform.position = objectPosition + new Vector3(0.02f * r.x, 0.015f * r.y, 0.1f * i - 0.5f);

                catchers[i] = CreateTouchEventCatcher(touchables[i]);
            }

            yield return(new WaitForFixedUpdate());

            yield return(null);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSim));

            yield return(PlayModeTestUtilities.MoveHand(initialHandPosition, objectPosition, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSim));

            // No. 0 is touched initially
            TestEvents(catchers, new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
            yield return(PlayModeTestUtilities.MoveHand(objectPosition, rightPosition, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

            // Only No. 3 gets touched when moving through the row, because No. 0 is still active while inside the poke threshold
            TestEvents(catchers, new int[] { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 });
            yield return(PlayModeTestUtilities.MoveHand(rightPosition, objectPosition, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSim));

            // No. 3 touched a second time
            TestEvents(catchers, new int[] { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, new int[] { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0 });

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSim));

            foreach (NearInteractionTouchable touchable in touchables)
            {
                Object.Destroy(touchable.gameObject);
            }
        }
Esempio n. 13
0
        public IEnumerator PressButtonWithHand()
        {
            GameObject testButton = InstantiateDefaultPressableButton();

            // Move the camera to origin looking at +z to more easily see the button.
            TestUtilities.PlayspaceToOriginLookingForward();

            // For some reason, we would only get null pointers when the hand tries to click a button
            // at specific positions, hence the unusal z value.
            testButton.transform.position = new Vector3(0, 0, 1.067121f);
            // The scale of the button was also unusual in the repro case
            testButton.transform.localScale = Vector3.one * 1.5f;

            PressableButton buttonComponent = testButton.GetComponent <PressableButton>();

            Assert.IsNotNull(buttonComponent);

            bool buttonPressed = false;

            buttonComponent.ButtonPressed.AddListener(() =>
            {
                buttonPressed = true;
            });

            // Move the hand forward to press button, then off to the right
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 30;
            Vector3 p1       = new Vector3(0, 0, 0.5f);
            Vector3 p2       = new Vector3(0, 0, 1.08f);
            Vector3 p3       = new Vector3(0.1f, 0, 1.08f);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            Assert.IsTrue(buttonPressed, "Button did not get pressed when hand moved to press it.");

            Object.Destroy(testButton);

            yield return(null);
        }
        public IEnumerator TestHandInputOnPrefab()
        {
            // Load interactable prefab
            Interactable interactable;
            Transform    translateTargetObject;

            InstantiatePressButtonPrefab(
                new Vector3(0.025f, 0.05f, 0.5f),
                DefaultRotation,
                out interactable,
                out translateTargetObject);

            // Subscribe to interactable's on click so we know the click went through
            bool wasClicked = false;

            interactable.OnClick.AddListener(() => { wasClicked = true; });

            Vector3 targetStartPosition = translateTargetObject.localPosition;

            // Move the hand forward to intersect the interactable
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 32;
            Vector3 p1       = Vector3.zero;
            Vector3 p2       = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3       = Vector3.zero;

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(CheckButtonTranslation(targetStartPosition, translateTargetObject));

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(new WaitForSeconds(ButtonReleaseAnimationDelay));

            Assert.True(wasClicked, "Interactable was not clicked.");

            //Cleanup
            GameObject.Destroy(interactable.gameObject);
        }
        private IEnumerator TestClickPushButton(Vector3 targetStartPosition, Transform translateTargetObject, bool shouldClick = true)
        {
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 32;
            Vector3 p1       = Vector3.zero;
            Vector3 p2       = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3       = Vector3.zero;

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(CheckButtonTranslation(targetStartPosition, translateTargetObject, shouldClick));

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(new WaitForSeconds(ButtonReleaseAnimationDelay));
        }
Esempio n. 16
0
        public IEnumerator PressButtonFast([ValueSource(nameof(PressableButtonsTestPrefabFilenames))] string prefabFilename)
        {
            GameObject testButton = InstantiateDefaultPressableButton(prefabFilename);

            // Move the camera to origin looking at +z to more easily see the button.
            TestUtilities.PlayspaceToOriginLookingForward();

            PressableButton buttonComponent = testButton.GetComponent <PressableButton>();

            Assert.IsNotNull(buttonComponent);
            Assert.IsTrue(buttonComponent.EnforceFrontPush, "Button default behavior should have enforce front push enabled");

            bool buttonPressed = false;

            buttonComponent.ButtonPressed.AddListener(() =>
            {
                buttonPressed = true;
            });

            // move the hand quickly from very far distance into the button and check if it was pressed
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 2;
            Vector3 p1       = new Vector3(0, 0, -20.0f);
            Vector3 p2       = new Vector3(0, 0, 0.02f);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            Assert.IsTrue(buttonPressed, "Button did not get pressed when hand moved to press it.");

            Object.Destroy(testButton);

            yield return(null);
        }
Esempio n. 17
0
        private IEnumerator TestHandSolver(SetupData testData, InputSimulationService inputSimulationService, Vector3 handPos, Handedness hand)
        {
            Assert.IsTrue(testData.handler.TrackedTargetType == TrackedObjectType.ControllerRay ||
                          testData.handler.TrackedTargetType == TrackedObjectType.HandJoint, "TestHandSolver supports on ControllerRay and HandJoint tracked target types");

            yield return(PlayModeTestUtilities.ShowHand(hand, inputSimulationService, Utilities.ArticulatedHandPose.GestureId.Open, handPos));

            // Give time for cube to float to hand
            yield return(WaitForFrames(2));

            Vector3 handOrbitalPos = testData.target.transform.position;

            Assert.LessOrEqual(Vector3.Distance(handOrbitalPos, handPos), DistanceThreshold);

            Transform expectedTransform = null;

            if (testData.handler.TrackedTargetType == TrackedObjectType.ControllerRay)
            {
                expectedTransform = PointerUtils.GetPointer <LinePointer>(hand)?.transform;
            }
            else
            {
                var handJointService = (CoreServices.InputSystem as IMixedRealityDataProviderAccess)?.GetDataProvider <IMixedRealityHandJointService>();
                expectedTransform = handJointService.RequestJointTransform(testData.handler.TrackedHandJoint, hand);
            }

            Assert.AreEqual(testData.handler.CurrentTrackedHandedness, hand);
            Assert.IsNotNull(expectedTransform);

            // SolverHandler creates a dummy GameObject to provide a transform for tracking so it can be managed (allocated/deleted)
            // Look at the parent to compare transform equality for what we should be tracking against
            Assert.AreEqual(testData.handler.TransformTarget.parent, expectedTransform);

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(WaitForFrames(2));
        }
        public IEnumerator TestHandInputOnRuntimeAssembled()
        {
            // Load interactable
            Interactable interactable;
            Transform    translateTargetObject;

            AssembleInteractableButton(
                out interactable,
                out translateTargetObject);

            interactable.transform.position    = new Vector3(0.025f, 0.05f, 0.65f);
            interactable.transform.eulerAngles = new Vector3(-90f, 0f, 0f);

            // Subscribe to interactable's on click so we know the click went through
            bool wasClicked = false;

            interactable.OnClick.AddListener(() => { wasClicked = true; });

            Vector3 targetStartPosition = translateTargetObject.transform.localPosition;

            yield return(null);

            // Add a touchable and configure for touch events
            NearInteractionTouchable touchable = interactable.gameObject.AddComponent <NearInteractionTouchable>();

            touchable.EventsToReceive = TouchableEventType.Touch;
            touchable.SetBounds(Vector2.one);
            touchable.SetLocalForward(Vector3.up);
            touchable.SetLocalUp(Vector3.forward);
            touchable.SetLocalCenter(Vector3.up * 2.75f);

            // Add a touch handler and link touch started / touch completed events
            TouchHandler touchHandler = interactable.gameObject.AddComponent <TouchHandler>();

            touchHandler.OnTouchStarted.AddListener((HandTrackingInputEventData e) => interactable.SetInputDown());
            touchHandler.OnTouchCompleted.AddListener((HandTrackingInputEventData e) => interactable.SetInputUp());

            // Move the hand forward to intersect the interactable
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 32;
            Vector3 p1       = Vector3.zero;
            Vector3 p2       = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3       = Vector3.zero;

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(CheckButtonTranslation(targetStartPosition, translateTargetObject));

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(new WaitForSeconds(ButtonReleaseAnimationDelay));

            Assert.True(wasClicked, "Interactable was not clicked.");

            //Cleanup
            GameObject.Destroy(interactable.gameObject);
        }
Esempio n. 19
0
        public IEnumerator ManipulationHandlerForceRelease()
        {
            // 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 <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);

            // grab the cube - move it to the right
            var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int numSteps = 30;

            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(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(initialHandPosition, initialObjectPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(initialObjectPosition, rightPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSimulationService));

            yield return(null);

            // test if the object was properly translated
            float   maxError = 0.05f;
            Vector3 posDiff  = testObject.transform.position - rightPosition;

            Assert.IsTrue(posDiff.magnitude <= maxError, "ManipulationHandler translate failed");

            // forcefully end manipulation and drag with hand back to original position - object shouldn't move with hand
            manipHandler.ForceEndManipulation();
            yield return(PlayModeTestUtilities.MoveHandFromTo(rightPosition, initialObjectPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSimulationService));

            posDiff = testObject.transform.position - initialObjectPosition;
            Assert.IsTrue(posDiff.magnitude > maxError, "Manipulationhandler modified objects even though manipulation was forcefully ended.");
            posDiff = testObject.transform.position - rightPosition;
            Assert.IsTrue(posDiff.magnitude <= maxError, "Manipulated object didn't remain in place after forcefully ending manipulation");

            // move hand back to object
            yield return(PlayModeTestUtilities.MoveHandFromTo(initialObjectPosition, rightPosition, numSteps, ArticulatedHandPose.GestureId.Open, Handedness.Right, inputSimulationService));

            // grab object again and move to original position
            yield return(PlayModeTestUtilities.MoveHandFromTo(rightPosition, initialObjectPosition, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSimulationService));

            // test if object was moved by manipulationhandler
            posDiff = testObject.transform.position - initialObjectPosition;
            Assert.IsTrue(posDiff.magnitude <= maxError, "ManipulationHandler translate failed on valid manipulation after ForceEndManipulation");

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            GameObject.Destroy(testObject);
        }
        public IEnumerator TestSimulatedHandInputOnRuntimeAssembled()
        {
            // Load interactable prefab
            GameObject   interactableObject;
            Interactable interactable;
            Transform    translateTargetObject;

            AssembleInteractableButton(
                out interactableObject,
                out interactable,
                out translateTargetObject);

            interactableObject.transform.position    = new Vector3(0.025f, 0.05f, 0.65f);
            interactableObject.transform.eulerAngles = new Vector3(-90f, 0f, 0f);

            // Subscribe to interactable's on click so we know the click went through
            bool wasClicked = false;

            interactable.OnClick.AddListener(() => { wasClicked = true; });

            Vector3 targetStartPosition = translateTargetObject.transform.localPosition;

            yield return(null);

            // Add a touchable and configure for touch events
            NearInteractionTouchable touchable = interactableObject.AddComponent <NearInteractionTouchable>();

            touchable.EventsToReceive = TouchableEventType.Touch;
            touchable.Bounds          = Vector2.one;
            touchable.SetLocalForward(Vector3.up);
            touchable.SetLocalUp(Vector3.forward);
            touchable.LocalCenter = Vector3.up * 2.75f;

            // Add a touch handler and link touch started / touch completed events
            TouchHandler touchHandler = interactableObject.AddComponent <TouchHandler>();

            touchHandler.OnTouchStarted.AddListener((HandTrackingInputEventData e) => interactable.SetInputDown());
            touchHandler.OnTouchCompleted.AddListener((HandTrackingInputEventData e) => interactable.SetInputUp());

            // Move the hand forward to intersect the interactable
            var     inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
            int     numSteps = 32;
            Vector3 p1       = new Vector3(0.0f, 0f, 0f);
            Vector3 p2       = new Vector3(0.05f, 0f, 0.51f);
            Vector3 p3       = new Vector3(0.0f, 0f, 0.0f);

            yield return(PlayModeTestUtilities.ShowHand(Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.MoveHandFromTo(p1, p2, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            float pressStartTime = Time.time;
            bool  wasTranslated  = false;

            while (Time.time < pressStartTime + buttonPressAnimationDelay)
            {   // If the transform is moved at any point during this interval, we were successful
                yield return(new WaitForFixedUpdate());

                wasTranslated |= targetStartPosition != translateTargetObject.localPosition;
            }

            // Move the hand back
            yield return(PlayModeTestUtilities.MoveHandFromTo(p2, p3, numSteps, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));

            yield return(PlayModeTestUtilities.HideHand(Handedness.Right, inputSimulationService));

            yield return(new WaitForSeconds(buttonReleaseAnimationDelay));

            Assert.True(wasClicked, "Interactable was not clicked.");
            Assert.True(wasTranslated, "Transform target object was not translated by action.");
        }
        private IEnumerator TestTouchableDistances(BaseNearInteractionTouchable touchable, float colliderThickness, GameObject objectDownExpected)
        {
            Handedness handedness = Handedness.Right;

            ArticulatedHandPose.GestureId gesture = ArticulatedHandPose.GestureId.Open;

            yield return(PlayModeTestUtilities.ShowHand(handedness, inputSim));

            PokePointer       pokePointer = null;
            IMixedRealityHand hand        = HandJointUtils.FindHand(handedness);

            Assert.IsNotNull(hand);
            foreach (IMixedRealityPointer pointer in hand.InputSource.Pointers)
            {
                pokePointer = pointer as PokePointer;
                if (pokePointer)
                {
                    break;
                }
            }
            Assert.IsNotNull(pokePointer);
            float touchableDistance = pokePointer.TouchableDistance;

            float debounceThreshold = 0.01f;

            touchable.DebounceThreshold = debounceThreshold;

            Vector3 center = touchable.transform.position;

            float   margin    = 0.001f;
            Vector3 pStart    = center + new Vector3(0, 0, -touchableDistance - 0.5f);
            Vector3 pTouch    = center + new Vector3(0, 0, -touchableDistance + margin);
            Vector3 pPoke     = center + new Vector3(0, 0, -colliderThickness + margin);
            Vector3 pDebounce = center + new Vector3(0, 0, -colliderThickness - touchable.DebounceThreshold - margin);
            Vector3 pEnd      = center + new Vector3(0, 0, touchableDistance + 0.5f);

            // Test return beyond DebounceThreshold
            yield return(PlayModeTestUtilities.MoveHand(pStart, pStart, gesture, handedness, inputSim, 1));

            Assert.IsNull(pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pStart, pTouch, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pTouch, pPoke, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.AreEqual(objectDownExpected, pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pPoke, pDebounce, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pDebounce, pStart, gesture, handedness, inputSim));

            Assert.IsNull(pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            // Test touchable distance behind the surface
            yield return(PlayModeTestUtilities.MoveHand(pStart, pStart, gesture, handedness, inputSim, 1));

            Assert.IsNull(pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pStart, pTouch, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pTouch, pPoke, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.AreEqual(objectDownExpected, pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pPoke, pEnd, gesture, handedness, inputSim));

            Assert.IsNull(pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pEnd, pDebounce, gesture, handedness, inputSim));

            Assert.AreEqual(touchable, pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.MoveHand(pDebounce, pStart, gesture, handedness, inputSim));

            Assert.IsNull(pokePointer.ClosestProximityTouchable);
            Assert.IsNull(pokePointer.CurrentTouchableObjectDown);

            yield return(PlayModeTestUtilities.HideHand(handedness, inputSim));
        }