/// <inheritdoc />
        public override void UpdateController(InputDevice inputDevice)
        {
            if (!Enabled)
            {
                return;
            }

            using (UpdateControllerPerfMarker.Auto())
            {
                base.UpdateController(inputDevice);

                UpdateHandData(inputDevice);

                for (int i = 0; i < Interactions?.Length; i++)
                {
                    switch (Interactions[i].InputType)
                    {
                    case DeviceInputType.IndexFinger:
                        handDefinition?.UpdateCurrentIndexPose(Interactions[i]);
                        break;

                    case DeviceInputType.ThumbStick:
                        handDefinition?.UpdateCurrentTeleportPose(Interactions[i]);
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Update the controller data from the provided platform state
        /// </summary>
        /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param>
        public void UpdateController(OVRHand hand, OVRSkeleton ovrSkeleton, Transform trackingOrigin)
        {
            if (!Enabled || hand == null || ovrSkeleton == null)
            {
                return;
            }

            bool isTracked = UpdateHandData(hand, ovrSkeleton);

            IsPositionAvailable = IsRotationAvailable = isTracked;

            if (isTracked)
            {
                // Leverage Oculus Platform Hand Ray - instead of simulating it in a crummy way
                currentPointerPose.Position = trackingOrigin.TransformPoint(hand.PointerPose.position);

                Vector3 pointerForward = trackingOrigin.TransformDirection(hand.PointerPose.forward);
                Vector3 pointerUp      = trackingOrigin.TransformDirection(hand.PointerPose.up);

                currentPointerPose.Rotation = Quaternion.LookRotation(pointerForward, pointerUp);

                currentGripPose = jointPoses[TrackedHandJoint.Palm];

                CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, currentGripPose);

                UpdateVelocity();
            }

            for (int i = 0; i < Interactions?.Length; i++)
            {
                switch (Interactions[i].InputType)
                {
                case DeviceInputType.SpatialPointer:
                    Interactions[i].PoseData = currentPointerPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, currentPointerPose);
                    }
                    break;

                case DeviceInputType.SpatialGrip:
                    Interactions[i].PoseData = currentGripPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, currentGripPose);
                    }
                    break;

                case DeviceInputType.Select:
                    Interactions[i].BoolData = IsPinching || IsGrabbing;

                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.TriggerPress:
                    Interactions[i].BoolData = IsPinching || IsGrabbing;

                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.IndexFinger:
                    handDefinition.UpdateCurrentIndexPose(Interactions[i]);
                    break;

                case DeviceInputType.ThumbStick:
                    handDefinition.UpdateCurrentTeleportPose(Interactions[i]);
                    break;
                }
            }
        }
        /// <summary>
        /// The OpenXR plug-in uses extensions to expose all possible data, which might be surfaced through multiple input devices.
        /// This method is overridden to account for multiple input devices.
        /// </summary>
        /// <param name="inputDevice">The current input device to grab data from.</param>
        public override void UpdateController(InputDevice inputDevice)
        {
            if (!Enabled)
            {
                return;
            }

            if (Interactions == null)
            {
                Debug.LogError($"No interaction configuration for {GetType().Name}");
                Enabled = false;
            }

            using (UpdateControllerPerfMarker.Auto())
            {
                if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 _))
                {
                    base.UpdateController(inputDevice);

                    // We've gotten device data from the platform, don't attempt to infer other input actions
                    // from the hand joint data
                    receivingDeviceInputs = true;
                }
                else
                {
                    UpdateHandData(inputDevice);

                    // Updating the Index finger pose right after getting the hand data
                    // regardless of whether device data is present
                    for (int i = 0; i < Interactions?.Length; i++)
                    {
                        var interactionMapping = Interactions[i];
                        switch (interactionMapping.InputType)
                        {
                        case DeviceInputType.IndexFinger:
                            handDefinition?.UpdateCurrentIndexPose(interactionMapping);
                            break;
                        }
                    }

                    // If we aren't getting device data, infer input actions, velocity, etc from hand joint data
                    if (!receivingDeviceInputs)
                    {
                        for (int i = 0; i < Interactions?.Length; i++)
                        {
                            var interactionMapping = Interactions[i];
                            switch (interactionMapping.InputType)
                            {
                            case DeviceInputType.SpatialGrip:
                                if (TryGetJoint(TrackedHandJoint.Palm, out MixedRealityPose currentGripPose))
                                {
                                    interactionMapping.PoseData = currentGripPose;

                                    if (interactionMapping.Changed)
                                    {
                                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, currentGripPose);

                                        // Spatial Grip is also used as the basis for the source pose when device data is not provided
                                        // We need to rotate it by an offset to properly represent the source pose.
                                        MixedRealityPose CurrentControllerPose = currentGripPose;
                                        CurrentControllerPose.Rotation *= (ControllerHandedness == Handedness.Left ? leftPalmOffset : rightPalmOffset);

                                        CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, CurrentControllerPose);
                                        IsPositionAvailable = IsRotationAvailable = true;
                                    }
                                }
                                break;

                            case DeviceInputType.Select:
                            case DeviceInputType.TriggerPress:
                            case DeviceInputType.GripPress:
                                interactionMapping.BoolData = IsPinching || IsGrabbing;

                                if (interactionMapping.Changed)
                                {
                                    if (interactionMapping.BoolData)
                                    {
                                        CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction);
                                    }
                                    else
                                    {
                                        CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction);
                                    }
                                }
                                break;

                            case DeviceInputType.SpatialPointer:
                                handDefinition?.UpdatePointerPose(interactionMapping);
                                break;

                            // Gotta do this only for non-AR devices
                            case DeviceInputType.ThumbStick:
                                handDefinition?.UpdateCurrentTeleportPose(interactionMapping);
                                break;
                            }
                        }

                        // Update the controller velocity based on the hand definition's calculations
                        handDefinition?.UpdateVelocity();
                        Velocity        = (handDefinition?.Velocity).Value;
                        AngularVelocity = (handDefinition?.AngularVelocity).Value;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Updates the visibility of the hand ray and raises input system events based on joint pose data.
        /// </summary>
        protected void UpdateInteractions()
        {
            MixedRealityPose pointerPose = jointPoses[TrackedHandJoint.Palm];
            MixedRealityPose gripPose    = jointPoses[TrackedHandJoint.Palm];
            MixedRealityPose indexPose   = jointPoses[TrackedHandJoint.IndexTip];

            // Only update the hand ray if the hand is in pointing pose
            if (IsInPointingPose)
            {
                HandRay.Update(pointerPose.Position, GetPalmNormal(), CameraCache.Main.transform, ControllerHandedness);
                Ray ray = HandRay.Ray;

                pointerPose.Position = ray.origin;
                pointerPose.Rotation = Quaternion.LookRotation(ray.direction);
            }

            for (int i = 0; i < Interactions?.Length; i++)
            {
                switch (Interactions[i].InputType)
                {
                case DeviceInputType.SpatialPointer:
                    Interactions[i].PoseData = pointerPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, pointerPose);
                    }
                    break;

                case DeviceInputType.SpatialGrip:
                    Interactions[i].PoseData = gripPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, gripPose);
                    }
                    break;

                case DeviceInputType.Select:
                case DeviceInputType.TriggerPress:
                    Interactions[i].BoolData = IsPinching;
                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.IndexFinger:
                    handDefinition.UpdateCurrentIndexPose(Interactions[i]);
                    break;

                case DeviceInputType.ThumbStick:
                    handDefinition.UpdateCurrentTeleportPose(Interactions[i]);
                    break;
                }
            }
        }