Exemplo n.º 1
0
        public IEnumerator SpherePointerDistances()
        {
            Vector3 margin = new Vector3(0, 0, 0.001f);

            var rightHand = new TestHand(Handedness.Right);

            // Show hand far enough from the test collider
            Vector3 idlePos = new Vector3(0.05f, 0, 1.0f);

            yield return(rightHand.Show(idlePos));

            var pointer = rightHand.GetPointer <SpherePointer>();

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 nearObjectPos         = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius);
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);
            // Move hand back out to disable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand back out to disable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(idlePos, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
        }
        public IEnumerator SpherePointerPullbackDistance()
        {
            // Approximate distance covered by the pullback distance;
            Vector3 pullbackDelta = new Vector3(0, 0, 0.08f);

            var rightHand = new TestHand(Handedness.Right);

            // Show hand far enough from the test collider
            Vector3 idlePos = new Vector3(0.05f, 0, 1.0f);

            yield return(rightHand.Show(idlePos));

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            pointer.NearObjectSectorAngle = 360.0f;
            pointer.PullbackDistance      = 0.08f;
            pointer.TryGetNearGraspPoint(out Vector3 graspPoint);
            // Orient the right hand so the grab axis is approximately aligned with the z axis

            Vector3 margin           = new Vector3(0, 0, 0.001f);
            Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius);

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 nearObjectPos         = new Vector3(0.05f, 0, colliderSurfaceZ - (pointer.NearObjectRadius));
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(nearObjectPos + margin + pullbackDelta, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand back out to disable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(idlePos, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
        }
        public IEnumerator 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>();

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

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

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

            Assert.AreEqual(rightHand.GetPointer <TeleportPointer>().TeleportSurfaceResult, Physics.TeleportSurfaceResult.Invalid);

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

            Assert.AreEqual(rightHand.GetPointer <TeleportPointer>().TeleportSurfaceResult, Physics.TeleportSurfaceResult.None);
        }
Exemplo n.º 4
0
        public IEnumerator TestPrioritizedLayerMask()
        {
            TestUtilities.PlayspaceToOriginLookingForward();

            TestHand hand = new TestHand(Handedness.Right);

            yield return(hand.Show(Vector3.forward, true));

            var shellHandRayPointer = hand.GetPointer <ShellHandRayPointer>();

            string spatialAwarenessLayerName = LayerMask.LayerToName(BaseSpatialObserver.DefaultSpatialAwarenessLayer);

            shellHandRayPointer.PrioritizedLayerMasksOverride = new LayerMask[] { LayerMask.GetMask(spatialAwarenessLayerName), LayerMask.GetMask("Default") };

            var pointerDirection = shellHandRayPointer.Rotation * Vector3.forward;

            var noPriorityCube = CreateTestCube(shellHandRayPointer.Position + pointerDirection * 2.0f);

            noPriorityCube.name  = "NoPriorityCube";
            noPriorityCube.layer = 18;                                                                    // assign to random layer

            var lowPriorityCube = CreateTestCube(shellHandRayPointer.Position + pointerDirection * 3.0f); // uses default layer

            lowPriorityCube.name = "LowPriorityCube";

            var highPriorityCube = CreateTestCube(shellHandRayPointer.Position + pointerDirection * 4.0f);

            highPriorityCube.layer = BaseSpatialObserver.DefaultSpatialAwarenessLayer;
            highPriorityCube.name  = "HighPriorityCube";

            //
            // Test High Priority cube, although farthest, is selected as raycast target
            //
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.AreEqual(highPriorityCube, shellHandRayPointer.Result?.CurrentPointerTarget, $"{highPriorityCube.name} should be raycast target by shell hand ray pointer");

            //
            // With HighPriorityCube disabled, test Low Priority cube, although farther, is selected as raycast target
            //
            highPriorityCube.SetActive(false);
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.AreEqual(lowPriorityCube, shellHandRayPointer.Result?.CurrentPointerTarget, $"{lowPriorityCube.name} should be raycast target by shell hand ray pointer");

            //
            // Test noPriorityCube still not selected in raycast
            //
            lowPriorityCube.SetActive(false);
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.IsNull(shellHandRayPointer.Result?.CurrentPointerTarget, $"{noPriorityCube.name} should NOT be raycast target by shell hand ray pointer");
        }
        public IEnumerator GrabLayerMasks()
        {
            // Initialize hand
            var rightHand = new TestHand(Handedness.Right);

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

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand to object, IsNearObject, IsInteractionEnabled should be true
            yield return(rightHand.MoveTo(interactionEnabledPos));

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);

            // Set layer to spatial mesh, which sphere pointer should be ignoring
            // assumption: layer 31 is the spatial mesh layer
            cube.SetLayerRecursively(31);
            yield return(null);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Set layer back to default
            cube.SetLayerRecursively(0);
            yield return(null);

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);

            // Remove the grabbable component, ray should turn on
            GameObject.Destroy(cube.GetComponent <NearInteractionGrabbable>());
            yield return(null);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Add back the grabbable, ray should turn off
            cube.AddComponent <NearInteractionGrabbable>();
            yield return(null);

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);
        }
        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");
        }
        public IEnumerator GrabLayerMasksWithOverlap()
        {
            // Initialize hand
            var rightHand = new TestHand(Handedness.Right);

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

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Initialize overlapRect
            overlapRect.SetActive(true);

            // Set the cube's layer to spatial mesh, which sphere pointer should be ignoring
            // assumption: layer 31 is the spatial mesh layer
            cube.SetLayerRecursively(31);
            yield return(null);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand to object, IsNearObject, IsInteractionEnabled should be true
            yield return(rightHand.MoveTo(interactionEnabledPos));

            Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == overlapRect, " the overlapping rectangle was not in focus");
            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);

            // Set cube's layer back to default
            // Set overlapRect's layer to spatial mesh, which sphere pointer should be ignoring
            // assumption: layer 31 is the spatial mesh layer
            overlapRect.SetLayerRecursively(31);
            cube.SetLayerRecursively(0);
            yield return(null);

            Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == cube, " the inner cube was not in focus");

            // Reinitialize the overlapRect
            overlapRect.SetLayerRecursively(0);
            overlapRect.SetActive(false);
        }
        public IEnumerator TestDisableFocusLockedObject()
        {
            TestUtilities.PlayspaceToOriginLookingForward();
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

            cube.AddComponent <ManipulationHandler>(); // Add focus handler so focus can lock
            cube.transform.position   = Vector3.right;
            cube.transform.localScale = Vector3.one * 0.2f;

            const int numHandSteps = 1;

            // No initial focus
            cube.transform.position = Vector3.forward;
            TestHand hand = new TestHand(Handedness.Right);

            yield return(hand.Show(Vector3.forward * 0.5f));

            yield return(null);

            var handRayPointer = hand.GetPointer <ShellHandRayPointer>();

            Assert.IsNull(handRayPointer.Result.CurrentPointerTarget);

            // Focus lock cube
            yield return(hand.MoveTo(new Vector3(0.06f, -0.1f, 0.5f), numHandSteps));

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

            yield return(null);

            Assert.IsTrue(handRayPointer.IsFocusLocked);
            Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget);

            // Deactivate the cube
            cube.SetActive(false);
            yield return(null);

            Assert.IsFalse(handRayPointer.IsFocusLocked);
            Assert.IsNull(handRayPointer.Result.CurrentPointerTarget);

            // Reactivate the cube
            cube.SetActive(true);
            yield return(null);

            Assert.IsFalse(handRayPointer.IsFocusLocked);
            Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget);
        }
        public IEnumerator TestDestroyFocusObject()
        {
            TestUtilities.PlayspaceToOriginLookingForward();
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

            cube.transform.position   = Vector3.right;
            cube.transform.localScale = Vector3.one * 0.2f;

            const int numHandSteps = 1;

            // No initial focus
            cube.transform.position = Vector3.forward;
            TestHand hand = new TestHand(Handedness.Right);

            yield return(hand.Show(Vector3.forward * 0.5f));

            yield return(null);

            var handRayPointer = hand.GetPointer <ShellHandRayPointer>();

            Assert.IsNull(handRayPointer.Result.CurrentPointerTarget);

            // Focus on cube
            yield return(hand.MoveTo(new Vector3(0.06f, -0.1f, 0.5f), numHandSteps));

            yield return(null);

            Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget);

            // Destroy the cube
            Object.DestroyImmediate(cube);
            yield return(null);

            Assert.IsNull(handRayPointer.Result.CurrentPointerTarget);
            // Verify that CurrentPointer is not still referencing the destroyed GameObject
            Assert.IsTrue(ReferenceEquals(handRayPointer.Result.CurrentPointerTarget, null));
        }
Exemplo n.º 10
0
        public IEnumerator GrabVolumesWithOverlap()
        {
            // Initialize overlapRect and cube
            overlapRect.SetActive(true);
            overlapRect.transform.localScale = Vector3.one * 2;
            overlapRect.transform.position   = Vector3.zero;

            cube.transform.localScale = Vector3.one;
            cube.transform.position   = Vector3.zero;

            // Initialize hand
            var rightHand = new TestHand(Handedness.Right);

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

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");

            Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == cube, " the cube was not in focus");
            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);

            // Switch the scale of the cube and rect
            overlapRect.transform.localScale = Vector3.one;
            cube.transform.localScale        = Vector3.one * 2;

            // Wait for the input system to process the changes
            yield return(PlayModeTestUtilities.WaitForInputSystemUpdate());

            Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == overlapRect, " the overlapping rectangle was not in focus");

            // Reinitialize the overlapRect
            overlapRect.SetActive(false);
        }
        public IEnumerator SpherePointerSectorAngle()
        {
            var rightHand = new TestHand(Handedness.Right);

            // Show hand far enough from the test collider
            Vector3 idlePos = new Vector3(0.05f, 0, 1.0f);

            yield return(rightHand.Show(idlePos));

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            pointer.NearObjectSectorAngle = 180.0f;
            pointer.PullbackDistance      = 0.0f;
            // Orient the right hand so the grab axis is approximately aligned with the z axis

            Vector3 margin           = new Vector3(0, 0, 0.001f);
            Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius);

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 nearObjectPos         = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius);
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Rotate hand but maintain IsNearObject
            yield return(rightHand.SetRotation(Quaternion.Euler(0, 90, 0), numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Rotate hand 200 degrees and lose IsNearObject
            yield return(rightHand.SetRotation(Quaternion.Euler(0, 200, 0), numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Rotate hand back to original orientation
            yield return(rightHand.SetRotation(Quaternion.Euler(0, 0, 0), numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);

            // Move hand back out to disable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand back out to disable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(idlePos, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
        }
        public IEnumerator SpherePointerDistances()
        {
            var rightHand = new TestHand(Handedness.Right);

            // Show hand far enough from the test collider
            Vector3 idlePos = new Vector3(0.05f, 0, 1.0f);

            yield return(rightHand.Show(idlePos));

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

            var pointer = rightHand.GetPointer <SpherePointer>();

            pointer.NearObjectSectorAngle = 360.0f;
            pointer.PullbackDistance      = 0.0f;

            Vector3 margin           = new Vector3(0, 0, 0.001f);
            Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius);

            Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller");
            Vector3 nearObjectPos         = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius);
            Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius);

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand closer to the collider to enable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.True(pointer.IsInteractionEnabled);
            // Move hand back out to disable IsInteractionEnabled
            yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Move hand back out to disable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            // Testing that we have more leeway when the pointer's nearObject smoothing factor is set
            // Move hand back out to disable IsNearObject
            yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
            yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove));

            Assert.True(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);

            yield return(rightHand.MoveTo(idlePos, numFramesPerMove));

            Assert.False(pointer.IsNearObject);
            Assert.False(pointer.IsInteractionEnabled);
        }
Exemplo n.º 13
0
        public IEnumerator ManipulationHandlerOneHandMoveNear()
        {
            // 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;
            manipHandler.ManipulationType = ManipulationHandler.HandMovementType.OneHandedOnly;

            // add near interaction grabbable to be able to grab the cube with the simulated articulated hand
            testObject.AddComponent <NearInteractionGrabbable>();

            yield return(new WaitForFixedUpdate());

            yield return(null);

            const int numCircleSteps = 10;
            const int numHandSteps   = 3;

            Vector3  initialHandPosition = new Vector3(0, 0, 0.5f);
            Vector3  initialGrabPosition = new Vector3(-0.1f, -0.1f, 1f); // grab the left bottom corner of the cube
            TestHand hand = new TestHand(Handedness.Right);

            // do this test for every one hand rotation mode
            foreach (ManipulationHandler.RotateInOneHandType type in Enum.GetValues(typeof(ManipulationHandler.RotateInOneHandType)))
            {
                manipHandler.OneHandRotationModeNear = type;

                TestUtilities.PlayspaceToOriginLookingForward();

                yield return(hand.Show(initialHandPosition));

                var pointer = hand.GetPointer <SpherePointer>();
                Assert.IsNotNull(pointer);

                yield return(hand.MoveTo(initialGrabPosition, numHandSteps));

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

                // save relative pos grab point to object
                Vector3 initialOffsetGrabToObjPivot = pointer.Position - testObject.transform.position;
                Vector3 initialGrabPointInObject    = testObject.transform.InverseTransformPoint(manipHandler.GetPointerGrabPoint(pointer.PointerId));

                // full circle
                const int degreeStep = 360 / numCircleSteps;

                // rotating the pointer in a circle around "the user"
                for (int i = 1; i <= numCircleSteps; ++i)
                {
                    // rotate main camera (user)
                    MixedRealityPlayspace.PerformTransformation(
                        p =>
                    {
                        p.position         = MixedRealityPlayspace.Position;
                        Vector3 rotatedFwd = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * Vector3.forward;
                        p.LookAt(rotatedFwd);
                    });

                    yield return(null);

                    // move hand with the camera
                    Vector3 newHandPosition = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * initialGrabPosition;
                    yield return(hand.MoveTo(newHandPosition, numHandSteps));

                    if (type == ManipulationHandler.RotateInOneHandType.RotateAboutObjectCenter)
                    {
                        // make sure that the offset between hand and object centre hasn't changed while rotating
                        Vector3 offsetRotated = pointer.Position - testObject.transform.position;
                        TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, $"Object offset changed during rotation using {type}");
                    }
                    else
                    {
                        // make sure that the offset between grab point and object pivot hasn't changed while rotating
                        Vector3 grabPoint     = manipHandler.GetPointerGrabPoint(pointer.PointerId);
                        Vector3 cornerRotated = testObject.transform.TransformPoint(initialGrabPointInObject);
                        TestUtilities.AssertAboutEqual(cornerRotated, grabPoint, $"Grab point on object changed during rotation using {type}");
                    }
                }

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

                yield return(hand.Hide());
            }
        }