/// <inheritdoc/>
        public bool Contains(Vector3 location, UnityBoundary.Type boundaryType = UnityBoundary.Type.TrackedArea)
        {
            if (!EdgeUtilities.IsValidPoint(location))
            {
                // Invalid location.
                return(false);
            }

            if (!FloorHeight.HasValue)
            {
                // No floor.
                return(false);
            }

            // Handle the user teleporting (boundary moves with them).
            location = MixedRealityPlayspace.InverseTransformPoint(location);

            if (FloorHeight.Value > location.y ||
                BoundaryHeight < location.y)
            {
                // Location below the floor or above the boundary height.
                return(false);
            }

            // Boundary coordinates are always "on the floor"
            Vector2 point = new Vector2(location.x, location.z);

            if (boundaryType == UnityBoundary.Type.PlayArea)
            {
                // Check the inscribed rectangle.
                if (rectangularBounds != null)
                {
                    return(rectangularBounds.IsInsideBoundary(point));
                }
            }
            else if (boundaryType == UnityBoundary.Type.TrackedArea)
            {
                // Check the geometry
                return(EdgeUtilities.IsInsideBoundary(Bounds, point));
            }

            // Not in either boundary type.
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Applies the configured observation extents.
        /// </summary>
        private void ConfigureObserverVolume()
        {
            using (ConfigureObserverVolumePerfMarker.Auto())
            {
                if (MixedRealityPlayspace.Transform == null)
                {
                    Debug.LogError("Unexpected failure acquiring MixedRealityPlayspace.");
                    return;
                }

                // If we aren't using a HoloLens or there isn't an XR device present, return.
                if (observer == null || HolographicSettings.IsDisplayOpaque || !XRDevice.isPresent)
                {
                    return;
                }

                // The observer's origin is in world space, we need it in the camera's parent's space
                // to set the volume. The MixedRealityPlayspace provides that space that the camera/head moves around in.
                Vector3    observerOriginPlayspace   = MixedRealityPlayspace.InverseTransformPoint(ObserverOrigin);
                Quaternion observerRotationPlayspace = Quaternion.Inverse(MixedRealityPlayspace.Rotation) * ObserverRotation;

                // Update the observer
                switch (ObserverVolumeType)
                {
                case VolumeType.AxisAlignedCube:
                    observer.SetVolumeAsAxisAlignedBox(observerOriginPlayspace, ObservationExtents);
                    break;

                case VolumeType.Sphere:
                    // We use the x value of the extents as the sphere radius
                    observer.SetVolumeAsSphere(observerOriginPlayspace, ObservationExtents.x);
                    break;

                case VolumeType.UserAlignedCube:
                    observer.SetVolumeAsOrientedBox(observerOriginPlayspace, ObservationExtents, observerRotationPlayspace);
                    break;

                default:
                    Debug.LogError($"Unsupported ObserverVolumeType value {ObserverVolumeType}");
                    break;
                }
            }
        }
Пример #3
0
        public IEnumerator ManipulationHandlerOneHandMoveFar()
        {
            // 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.04f, -0.18f, 0.3f); // grab point on the lower center part 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)))
            {
                // TODO: grab point is moving in this test and has to be covered by a different test
                if (type == ManipulationHandler.RotateInOneHandType.MaintainOriginalRotation)
                {
                    continue;
                }

                manipHandler.OneHandRotationModeFar = type;

                TestUtilities.PlayspaceToOriginLookingForward();

                yield return(hand.Show(initialHandPosition));

                yield return(null);

                // pinch and let go of the object again to make sure that any rotation adjustment we're doing is applied
                // at the beginning of our test and doesn't interfere with our grab position on the cubes surface while we're moving around
                yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Pinch));

                yield return(new WaitForFixedUpdate());

                yield return(null);

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

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


                // save relative pos grab point to object - for far interaction we need to check the grab point where the pointer ray hits the manipulated object
                InputSimulationService    simulationService = PlayModeTestUtilities.GetInputSimulationService();
                IMixedRealityController[] inputControllers  = simulationService.GetActiveControllers();
                // assume hand is first controller and pointer for this test
                IMixedRealityController handController = inputControllers[0];
                IMixedRealityPointer    handPointer    = handController.InputSource.Pointers[0];
                Vector3 initialGrabPosition            = handPointer.Result.Details.Point;
                Vector3 initialOffsetGrabToObjPivot    = MixedRealityPlayspace.InverseTransformPoint(initialGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position);

                // 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) * initialHandPosition;
                    yield return(hand.MoveTo(newHandPosition, numHandSteps));

                    yield return(new WaitForFixedUpdate());

                    yield return(null);


                    // make sure that the offset between grab point and object pivot hasn't changed while rotating
                    Vector3 newGrabPosition = handPointer.Result.Details.Point;
                    Vector3 offsetRotated   = MixedRealityPlayspace.InverseTransformPoint(newGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position);
                    TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, "Grab point on object changed during rotation");
                }

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

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