/// <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; } } } }
/// <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; } } }