public IEnumerator Setup()
        {
            PlayModeTestUtilities.Setup();
            PlayModeTestUtilities.EnsureInputModule();

            inputSim = PlayModeTestUtilities.GetInputSimulationService();
            Assert.NotNull(inputSim);

            Assert.NotNull(CoreServices.InputSystem);

            GameObject lightObj = new GameObject("Light");

            lightObj.transform.rotation = Quaternion.FromToRotation(Vector3.forward, new Vector3(1, -4, 2));
            Light light = lightObj.AddComponent <Light>();

            light.type = LightType.Directional;

            var shader = StandardShaderUtility.MrtkStandardShader;

            idleMaterial       = new Material(shader);
            idleMaterial.color = Color.yellow;

            pokeMaterial       = new Material(shader);
            pokeMaterial.color = Color.green;
            yield return(null);
        }
예제 #2
0
        public IEnumerator TestMotionControllerClickEvents()
        {
            // Switch to motion controller
            var iss        = PlayModeTestUtilities.GetInputSimulationService();
            var oldSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = ControllerSimulationMode.MotionController;

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

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

            var testMotionController = new TestMotionController(Handedness.Right);

            yield return(testMotionController.Show(new Vector3(1, 0, 0)));

            yield return(testMotionController.Click());

            yield return(testMotionController.Hide());

            Assert.True(wasClicked);

            // Restore the input simulation profile
            iss.ControllerSimulationMode = oldSimMode;

            yield return(null);
        }
        public IEnumerator ScaleViaNearInteration()
        {
            var bbox = InstantiateSceneAndDefaultBbox();

            yield return(null);

            var bounds = bbox.GetComponent <BoxCollider>().bounds;

            Debug.Assert(bounds.center == new Vector3(0, 0, 1.5f));
            Debug.Assert(bounds.size == new Vector3(.5f, .5f, .5f));

            var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            // front right corner is corner 3
            var frontRightCornerPos = bbox.ScaleCorners[3].transform.position;

            Vector3 initialHandPosition = new Vector3(0, 0, 0.5f);
            int     numSteps            = 30;
            var     delta = new Vector3(0.1f, 0.1f, 0f);

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

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

            yield return(PlayModeTestUtilities.MoveHandFromTo(frontRightCornerPos, frontRightCornerPos + delta, numSteps, ArticulatedHandPose.GestureId.Pinch, Handedness.Right, inputSimulationService));

            var endBounds = bbox.GetComponent <BoxCollider>().bounds;

            TestUtilities.AssertAboutEqual(endBounds.center, new Vector3(0.033f, 0.033f, 1.467f), "endBounds incorrect center");
            TestUtilities.AssertAboutEqual(endBounds.size, Vector3.one * .567f, "endBounds incorrect size");

            GameObject.Destroy(bbox.gameObject);
            // Wait for a frame to give Unity a change to actually destroy the object
            yield return(null);
        }
예제 #4
0
        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;
        }
        public override void Setup()
        {
            base.Setup();
            TestUtilities.PlayspaceToOriginLookingForward();

            inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();
        }
예제 #6
0
        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
            var iss        = PlayModeTestUtilities.GetInputSimulationService();
            var oldSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = 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);
            iss.ControllerSimulationMode = oldSimMode;
        }
예제 #7
0
        public void Setup()
        {
            PlayModeTestUtilities.Setup();
            PlayModeTestUtilities.EnsureInputModule();

            inputSim = PlayModeTestUtilities.GetInputSimulationService();
            Assert.NotNull(inputSim);

            Assert.IsTrue(MixedRealityServiceRegistry.TryGetService <IMixedRealityInputSystem>(out inputSystem));
            Assert.NotNull(inputSystem);

            GameObject lightObj = new GameObject("Light");

            lightObj.transform.rotation = Quaternion.FromToRotation(Vector3.forward, new Vector3(1, -4, 2));
            Light light = lightObj.AddComponent <Light>();

            light.type = LightType.Directional;

            var shader = StandardShaderUtility.MrtkStandardShader;

            idleMaterial       = new Material(shader);
            idleMaterial.color = Color.yellow;

            pokeMaterial       = new Material(shader);
            pokeMaterial.color = Color.green;
        }
예제 #8
0
        public IEnumerator TestDisabledPointerCache()
        {
            TestButtonUtilities.InstantiateDefaultButton(TestButtonUtilities.DefaultButtonType.DefaultPushButton,
                                                         out Interactable interactable,
                                                         out Transform translateTargetObject);

            Vector3 targetStartPosition = translateTargetObject.localPosition;

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

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

            PlayModeTestUtilities.GetInputSimulationService().EnablePointerCache = false;

            var rightHand = new TestHand(Handedness.Right);

            yield return(rightHand.Show(Vector3.right));

            var rightPokePointer = PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right);

            Assert.IsNotNull(rightPokePointer);
            Assert.IsFalse(rightPokePointer.DestroyOnSourceLost);

            yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject));

            Assert.IsTrue(wasClicked);
            Assert.IsTrue(rightPokePointer == null);
            Assert.IsNull(PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right));

            wasClicked = false;
            yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject));

            Assert.IsTrue(wasClicked);
        }
예제 #9
0
        public IEnumerator TestHandModality()
        {
            var testObjects = InstantiateTestSolver <Orbital>();

            // Set solver handler to track hands
            testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint;

            // Set and save relevant positions
            Vector3 rightHandPos = Vector3.right * 20.0f;
            Vector3 leftHandPos  = Vector3.right * -20.0f;

            yield return(WaitForFrames(2));

            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            // Test orbital around right hand
            yield return(TestHandSolver(testObjects.target, inputSimulationService, rightHandPos, Handedness.Right));

            // Test orbital around left hand
            yield return(TestHandSolver(testObjects.target, inputSimulationService, leftHandPos, Handedness.Left));

            // Test orbital with both hands visible
            yield return(PlayModeTestUtilities.ShowHand(Handedness.Left, inputSimulationService, Utilities.ArticulatedHandPose.GestureId.Open, leftHandPos));

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

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

            Vector3 handOrbitalPos = testObjects.target.transform.position;

            Assert.LessOrEqual(Vector3.Distance(handOrbitalPos, leftHandPos), DistanceThreshold);
        }
        public IEnumerator TestGazeCursorArticulated()
        {
            IMixedRealityInputSystem inputSystem = PlayModeTestUtilities.GetInputSystem();

            yield return(null);

            // Verify that the gaze cursor is visible at the start
            Assert.IsTrue(inputSystem.GazeProvider.GazePointer.IsInteractionEnabled, "Gaze cursor should be visible at start");

            // raise hand up -- gaze cursor should no longer be visible
            // disable user input
            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            inputSimulationService.UserInputEnabled = false;

            ArticulatedHandPose gesturePose = ArticulatedHandPose.GetGesturePose(ArticulatedHandPose.GestureId.Open);
            var handOpenPose = PlayModeTestUtilities.GenerateHandPose(ArticulatedHandPose.GestureId.Open, Handedness.Right, Vector3.forward * 0.1f, Quaternion.identity);

            inputSimulationService.HandDataRight.Update(true, false, handOpenPose);
            yield return(null);

            // Gaze cursor should not be visible
            Assert.IsFalse(inputSystem.GazeProvider.GazePointer.IsInteractionEnabled, "Gaze cursor should not be visible when one articulated hand is up");
            inputSimulationService.HandDataRight.Update(false, false, handOpenPose);
            yield return(null);

            // Say "select" to make gaze cursor active again
            // Really we need to tear down the scene and create it again but MRTK doesn't support that yet
            var gazeInputSource = inputSystem.DetectedInputSources.Where(x => x.SourceName.Equals("Gaze")).First();

            inputSystem.RaiseSpeechCommandRecognized(gazeInputSource, RecognitionConfidenceLevel.High, new System.TimeSpan(), System.DateTime.Now, new SpeechCommands("select", KeyCode.Alpha1, MixedRealityInputAction.None));
            yield return(null);

            Assert.IsTrue(inputSystem.GazeProvider.GazePointer.IsInteractionEnabled, "Gaze cursor should be visible after select command");
        }
        /// <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 PrefabGGVZoom()
        {
            InstantiateFromPrefab();

            var iss        = PlayModeTestUtilities.GetInputSimulationService();
            var oldSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures;

            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());

            iss.ControllerSimulationMode = oldSimMode;
            yield return(null);
        }
예제 #13
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));
        }
        public IEnumerator TestHandCoachActivation()
        {
            InstantiateHandCoach(out HandInteractionHint handCoach);
            handCoach.AnimationState    = "HandFlip_R";
            handCoach.HideIfHandTracked = true;
            handCoach.HintDisplayDelay  = 0.0f;

            float timingLeeway = 0.1f;
            float fadeOutTime  = 1.0f;

            handCoach.transform.position = Vector3.forward;

            handCoach.StartHintLoop();
            yield return(new WaitForSeconds(timingLeeway));

            Assert.IsTrue(handCoach.VisualsRoot.activeSelf);

            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            yield return(null);

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

            yield return(new WaitForSeconds(fadeOutTime));

            Assert.IsFalse(handCoach.VisualsRoot.activeSelf);
        }
        /// <summary>
        /// Move the right hand from point 1 to point 2
        /// </summary>
        public static IEnumerator MoveHand(Vector3 p1, Vector3 p2)
        {
            // Move the hand towards
            var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

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

            yield return(PlayModeTestUtilities.MoveHand(p1, p2, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));
        }
        /// <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()));
        }
예제 #17
0
        public IEnumerator ManipulationHandlerRotateHeadGGV()
        {
            TestUtilities.PlayspaceToOriginLookingForward();

            // Switch to Gestures
            var iss    = PlayModeTestUtilities.GetInputSimulationService();
            var oldIsp = iss.InputSimulationProfile;
            var isp    = ScriptableObject.CreateInstance <MixedRealityInputSimulationProfile>();

            isp.HandSimulationMode     = HandSimulationMode.Gestures;
            iss.InputSimulationProfile = isp;

            // 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);
            Quaternion initialObjectRotation = testObject.transform.rotation;

            testObject.transform.position = initialObjectPosition;

            var manipHandler = testObject.AddComponent <ManipulationHandler>();

            manipHandler.HostTransform   = testObject.transform;
            manipHandler.SmoothingActive = false;

            Vector3   originalHandPosition = new Vector3(0, 0, 0.5f);
            TestHand  hand         = new TestHand(Handedness.Right);
            const int numHandSteps = 1;

            // Grab cube
            yield return(hand.Show(originalHandPosition));

            yield return(null);

            yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Pinch));

            // Rotate Head and readjust hand
            int numRotations = 10;

            for (int i = 0; i < numRotations; i++)
            {
                MixedRealityPlayspace.Transform.Rotate(Vector3.up, 180 / numRotations);
                yield return(hand.MoveTo(originalHandPosition, numHandSteps));

                yield return(null);

                // Test Object hasn't moved
                TestUtilities.AssertAboutEqual(initialObjectPosition, testObject.transform.position, "Object moved while rotating head");
                TestUtilities.AssertAboutEqual(initialObjectRotation, testObject.transform.rotation, "Object rotated while rotating head", 0.25f);
            }

            // Restore the input simulation profile
            iss.InputSimulationProfile = oldIsp;
            yield return(null);
        }
예제 #18
0
        public IEnumerator ScaleViaHoloLens1Interaction()
        {
            var bbox = InstantiateSceneAndDefaultBbox();

            yield return(null);

            yield return(null);

            var bounds      = bbox.GetComponent <BoxCollider>().bounds;
            var startCenter = new Vector3(0, 0, 1.5f);
            var startSize   = new Vector3(.5f, .5f, .5f);

            TestUtilities.AssertAboutEqual(bounds.center, startCenter, "bbox incorrect center at start");
            TestUtilities.AssertAboutEqual(bounds.size, startSize, "bbox incorrect size at start");

            // Switch to hand gestures
            var iss        = PlayModeTestUtilities.GetInputSimulationService();
            var oldSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures;

            CameraCache.Main.transform.LookAt(bbox.ScaleCorners[3].transform);

            var      startHandPos = CameraCache.Main.transform.TransformPoint(new Vector3(0.1f, 0f, 1.5f));
            TestHand rightHand    = new TestHand(Handedness.Right);

            yield return(rightHand.Show(startHandPos));

            yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch));

            // After pinching, center should remain the same
            var afterPinchbounds = bbox.GetComponent <BoxCollider>().bounds;

            TestUtilities.AssertAboutEqual(afterPinchbounds.center, startCenter, "bbox incorrect center after pinch");
            TestUtilities.AssertAboutEqual(afterPinchbounds.size, startSize, "bbox incorrect size after pinch");

            var delta = new Vector3(0.1f, 0.1f, 0f);

            yield return(rightHand.Move(delta));

            var endBounds = bbox.GetComponent <BoxCollider>().bounds;

            TestUtilities.AssertAboutEqual(endBounds.center, new Vector3(0.033f, 0.033f, 1.467f), "endBounds incorrect center", 0.02f);
            TestUtilities.AssertAboutEqual(endBounds.size, Vector3.one * .561f, "endBounds incorrect size", 0.02f);

            Object.Destroy(bbox.gameObject);
            // Wait for a frame to give Unity a change to actually destroy the object
            yield return(null);

            // Restore the input simulation profile
            iss.ControllerSimulationMode = oldSimMode;

            yield return(null);
        }
예제 #19
0
        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);
        }
예제 #20
0
        /// <summary>
        /// Move the right hand from in front of the button through to the button
        /// </summary>
        public static IEnumerator MoveHandToButton(Transform button)
        {
            Vector3 p1 = button.transform.position - button.TransformDirection(ButtonTranslateOffset);
            Vector3 p2 = button.transform.position;

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

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

            yield return(PlayModeTestUtilities.MoveHand(p1, p2, ArticulatedHandPose.GestureId.Poke, Handedness.Right, inputSimulationService));
        }
예제 #21
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.");
        }
예제 #23
0
        public IEnumerator TriggerButtonFarInteractionWithMotionController([ValueSource(nameof(PressableButtonsTestPrefabPaths))] string prefabFilename)
        {
            GameObject testButton = InstantiateDefaultPressableButton(prefabFilename);

            TestUtilities.PlayspaceToOriginLookingForward();

            Interactable interactableComponent = testButton.GetComponent <Interactable>();
            Button       buttonComponent       = testButton.GetComponent <Button>();

            Assert.IsTrue(interactableComponent != null || buttonComponent != null, "Depending on button type, there should be either an Interactable or a UnityUI Button on the control");

            var objectToMoveAndScale = testButton.transform;

            if (buttonComponent != null)
            {
                objectToMoveAndScale = testButton.transform.parent;
            }

            objectToMoveAndScale.position   += new Vector3(0f, 0.3f, 0.8f);
            objectToMoveAndScale.localScale *= 15f; // scale button up so it's easier to hit it with the far interaction pointer
            yield return(new WaitForFixedUpdate());

            yield return(null);

            bool buttonTriggered = false;

            var onClickEvent = (interactableComponent != null) ? interactableComponent.OnClick : buttonComponent.onClick;

            onClickEvent.AddListener(() =>
            {
                buttonTriggered = true;
            });

            // Switch to motion controller
            var iss            = PlayModeTestUtilities.GetInputSimulationService();
            var oldHandSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = ControllerSimulationMode.MotionController;
            TestMotionController motionController   = new TestMotionController(Handedness.Right);
            Vector3 initialmotionControllerPosition = new Vector3(0.05f, -0.05f, 0.3f); // orient hand so far interaction ray will hit button

            yield return(motionController.Show(initialmotionControllerPosition));

            yield return(motionController.Click());

            Assert.IsTrue(buttonTriggered, "Button did not get triggered with far interaction.");

            Object.Destroy(testButton);
            // Restore the input simulation profile
            iss.ControllerSimulationMode = oldHandSimMode;
            yield return(null);
        }
        public IEnumerator TestTeleportStrafe()
        {
            var iss = PlayModeTestUtilities.GetInputSimulationService();

            // Create a floor and make sure it's below the camera
            var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);

            floor.transform.position = -0.5f * Vector3.up;

            // Bring out the right hand and set it to the teleport gesture
            TestUtilities.PlayspaceToOriginLookingForward();
            Vector3 initialPosition = MixedRealityPlayspace.Position;

            TestHand rightHand = new TestHand(Handedness.Right);

            // Make sure the hand is in front of the camera
            yield return(rightHand.Show(Vector3.forward * 0.6f));

            rightHand.SetRotation(Quaternion.identity);

            TeleportPointer teleportPointer = rightHand.GetPointer <TeleportPointer>();

            teleportPointer.PerformStrafe();
            TestUtilities.AssertAboutEqual(MixedRealityPlayspace.Position, initialPosition - Vector3.forward * teleportPointer.strafeAmount, "Did not strafe to the expected position");

            teleportPointer.checkForFloorOnStrafe   = true;
            teleportPointer.adjustHeightOnStrafe    = true;
            teleportPointer.strafeAmount            = 1.0f;
            teleportPointer.maxHeightChangeOnStrafe = 0.5f;

            TestUtilities.PlayspaceToOriginLookingForward();
            teleportPointer.PerformStrafe();
            TestUtilities.AssertAboutEqual(MixedRealityPlayspace.Position, initialPosition, "Performed an invalid strafe");

            var floor2 = GameObject.CreatePrimitive(PrimitiveType.Cube);

            floor2.transform.position = new Vector3(0, -0.25f, -1.0f);
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            TestUtilities.PlayspaceToOriginLookingForward();
            teleportPointer.PerformStrafe();
            TestUtilities.AssertAboutEqual(MixedRealityPlayspace.Position, initialPosition + new Vector3(0, 0.25f, -teleportPointer.strafeAmount), "Height did not change on strafe");

            floor2.transform.position = new Vector3(0, -0.75f, -1.0f);
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            TestUtilities.PlayspaceToOriginLookingForward();
            teleportPointer.PerformStrafe();
            TestUtilities.AssertAboutEqual(MixedRealityPlayspace.Position, initialPosition + new Vector3(0, -0.25f, -teleportPointer.strafeAmount), "Height did not change on strafe");
        }
        /// <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));
        }
예제 #26
0
        public IEnumerator TestTargetTypes()
        {
            Vector3 rightHandPos       = Vector3.right * 50.0f;
            Vector3 leftHandPos        = -rightHandPos;
            Vector3 customTransformPos = Vector3.up * 50.0f;

            var transformOverride = new GameObject("Override");

            transformOverride.transform.position = customTransformPos;

            var testObjects = InstantiateTestSolver <Orbital>();
            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            // Test orbital around right hand
            {
                testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint;
                yield return(TestHandSolver(testObjects, inputSimulationService, rightHandPos, Handedness.Right));
            }

            // Test orbital around left hand line pointer
            {
                testObjects.handler.TrackedTargetType = TrackedObjectType.ControllerRay;
                testObjects.handler.TrackedHandness   = Handedness.Left;

                yield return(TestHandSolver(testObjects, inputSimulationService, leftHandPos, Handedness.Left));
            }

            // Test orbital around head
            {
                testObjects.handler.TrackedTargetType = TrackedObjectType.Head;

                yield return(WaitForFrames(2));

                Assert.LessOrEqual(Vector3.Distance(testObjects.target.transform.position, CameraCache.Main.transform.position), DistanceThreshold);
            }

            // Test orbital around custom override
            {
                testObjects.handler.TrackedTargetType = TrackedObjectType.CustomOverride;
                testObjects.handler.TransformOverride = transformOverride.transform;

                yield return(WaitForFrames(2));

                Assert.LessOrEqual(Vector3.Distance(testObjects.target.transform.position, customTransformPos), DistanceThreshold);

                yield return(WaitForFrames(2));
            }
        }
예제 #27
0
        public IEnumerator TestTeleportLayers()
        {
            var iss = PlayModeTestUtilities.GetInputSimulationService();

            // Create a floor and make sure it's below the camera
            var floor = GameObject.CreatePrimitive(PrimitiveType.Plane);

            floor.transform.position = -0.5f * Vector3.up;

            // Bring out the right hand and set it to the teleport gesture
            TestUtilities.PlayspaceToOriginLookingForward();
            float initialForwardPosition = MixedRealityPlayspace.Position.z;

            TestHand rightHand = new TestHand(Handedness.Right);

            // Make sure the hand is in front of the camera
            yield return(rightHand.Show(Vector3.forward * 0.6f));

            rightHand.SetRotation(Quaternion.identity);

            yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.TeleportStart));

            // Wait for the hand to animate
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            yield return(new WaitForSeconds(1.0f / iss.InputSimulationProfile.HandGestureAnimationSpeed + 0.1f));

            TeleportPointer teleportPointer = rightHand.GetPointer <TeleportPointer>();

            teleportPointer.PrioritizedLayerMasksOverride = new LayerMask[1] {
                UnityEngine.Physics.AllLayers ^ (1 << LayerMask.NameToLayer("UI"))
            };

            floor.layer = LayerMask.NameToLayer("Default");
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.AreEqual(Physics.TeleportSurfaceResult.Valid, teleportPointer.TeleportSurfaceResult);

            floor.layer = LayerMask.NameToLayer("Ignore Raycast");
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.AreEqual(Physics.TeleportSurfaceResult.Invalid, teleportPointer.TeleportSurfaceResult);

            floor.layer = LayerMask.NameToLayer("UI");
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.AreEqual(Physics.TeleportSurfaceResult.None, teleportPointer.TeleportSurfaceResult);
        }
예제 #28
0
        public IEnumerator TestEditorProfile()
        {
            PlayModeTestUtilities.Setup();

            InputSimulationService inputSimulationService = PlayModeTestUtilities.GetInputSimulationService();

            inputSimulationService.UserInputEnabled = true;

            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            var allPointers = GetAllPointers();

            // https://nunit.org/docs/2.5.5/collectionConstraints.html
            Assert.That(allPointers, Has.Some.InstanceOf(typeof(GGVPointer)));
            Assert.That(allPointers, Has.No.InstanceOf(typeof(ShellHandRayPointer)));
        }
예제 #29
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 TestMotionControllerPointerDirectionToCameraDirection()
        {
            var inputSystem = PlayModeTestUtilities.GetInputSystem();

            // Switch to motion controller
            var iss        = PlayModeTestUtilities.GetInputSimulationService();
            var oldSimMode = iss.ControllerSimulationMode;

            iss.ControllerSimulationMode = ControllerSimulationMode.MotionController;

            // Raise the motion controller
            var rightMotionController = new TestMotionController(Handedness.Right);

            // Set initial position and show motion controller
            Vector3 initialPos = TestUtilities.PositionRelativeToPlayspace(new Vector3(0.01f, 0.1f, 0.5f));

            yield return(rightMotionController.Show(initialPos));

            // Return first motion controller that is right and source type controller
            var motionController = inputSystem.DetectedControllers.First(x => x.ControllerHandedness == Handedness.Right && x.InputSource.SourceType == InputSourceType.Controller);

            Assert.IsNotNull(motionController);

            // Get the line pointer from the motion controller
            var linePointer = motionController.InputSource.Pointers.OfType <ShellHandRayPointer>().First();

            Assert.IsNotNull(linePointer);

            Vector3 linePointerOrigin = linePointer.Position;

            // Check that the line pointer origin is within half a centimeter of the initial position of the motion controller
            var distance = Vector3.Distance(initialPos, linePointerOrigin);

            Assert.LessOrEqual(distance, 0.005f);

            // Check that the angle between the line pointer ray and camera forward does not exceed 40 degrees
            float angle = Vector3.Angle(linePointer.Rays[0].Direction, CameraCache.Main.transform.forward);

            Assert.LessOrEqual(angle, 40.0f);

            // Restore the input simulation profile
            iss.ControllerSimulationMode = oldSimMode;
            yield return(null);
        }