private void InteractionManager_SourceReleasedCallback(InteractionSourceState state) { AFocuser focuser = GetFocuserForSource(state.source.kind); OnReleasedEvent(focuser); }
private void InteractionManager_SourceLost(InteractionSourceState state) { pressedHands.Remove(state.source.id); }
private void InteractionManager_SourceLost(InteractionSourceState hand) { // Stop displaying the guidance indicator when the user's hand leaves the view. RemoveTrackedHand(hand); }
/// <summary> /// Update the trigger and grasped input from the device. /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform.</param> private void UpdateTriggerData(InteractionSourceState interactionSourceState, MixedRealityInteractionMapping interactionMapping) { using (UpdateTriggerDataPerfMarker.Auto()) { switch (interactionMapping.InputType) { case DeviceInputType.TriggerPress: case DeviceInputType.GripPress: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.grasped; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled if (interactionMapping.BoolData) { CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } case DeviceInputType.Select: { // Get the select pressed state, factoring in a workaround for Unity issue #1033526. // When that issue is fixed, it should be possible change the line below to: // interactionMapping.BoolData = interactionSourceState.selectPressed; interactionMapping.BoolData = GetSelectPressedWorkaround(interactionSourceState); // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled if (interactionMapping.BoolData) { CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } case DeviceInputType.Trigger: { // Update the interaction data source interactionMapping.FloatData = interactionSourceState.selectPressedAmount; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled CoreServices.InputSystem?.RaiseFloatInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionSourceState.selectPressedAmount); } break; } case DeviceInputType.TriggerTouch: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.selectPressedAmount > 0; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system event if it's enabled if (interactionSourceState.selectPressedAmount > 0) { CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } } } }
protected virtual void UpdatePose(InteractionSourceState state) { UpdateAngularVelocity(state.sourcePose); UpdateControllerPose(state.sourcePose); }
private void InteractionManager_SourceDetected(InteractionSourceState state) { handDetected = true; }
private void InteractionManager_SourceLost(InteractionSourceState state) { handDetected = false; }
private void SourceManager_SourcePressed(InteractionSourceState state) { PressedSources.Add(state.source.kind); }
private void SourceManager_SourceReleased(InteractionSourceState state) { PressedSources.Remove(state.source.kind); }
public virtual void OnPreRaycast() { if (InputSource == null) { rays[0] = default(RayStep); } else { Debug.Assert(InputSource.SupportsInputInfo(InputSourceId, SupportedInputInfo.Pointing), string.Format("{0} with id {1} does not support pointing!", InputSource, InputSourceId)); #if UNITY_WSA && UNITY_2017_2_OR_NEWER // For visualization with controllers, we don't want to use the event-based data the InputManager has. // Instead, we query the source states manually here. InteractionSourceState[] currentReading = InteractionManager.GetCurrentReading(); for (int i = 0; i < currentReading.Length; i++) { InteractionSourceState sourceState = currentReading[i]; if (sourceState.source.id != InputSourceId) { continue; } selectPressed = sourceState.selectPressed; Vector3 position; Vector3 forward; if (!sourceState.sourcePose.TryGetPosition(out position)) { return; } if (!sourceState.sourcePose.TryGetForward(out forward, InteractionSourceNode.Pointer)) { return; } if (CameraCache.Main.transform.parent != null) { position = CameraCache.Main.transform.parent.TransformPoint(position); forward = CameraCache.Main.transform.parent.TransformDirection(forward); } rays[0].CopyRay(new Ray(position, forward), FocusManager.Instance.GetPointingExtent(this)); } #else Ray pointingRay; if (InputSource.TryGetPointingRay(InputSourceId, out pointingRay)) { rays[0].CopyRay(pointingRay, FocusManager.Instance.GetPointingExtent(this)); } #endif } if (RayStabilizer != null) { RayStabilizer.UpdateStability(rays[0].Origin, rays[0].Direction); rays[0].CopyRay(RayStabilizer.StableRay, FocusManager.Instance.GetPointingExtent(this)); } }
void RefreshSource(InteractionSourceState state) { }
/// <summary> /// Raised when we detect an interaction source. /// </summary> /// <param name="state"></param> private void InteractionManager_SourceDetected(InteractionSourceState state) { trackedInteractionSource.Add(state.source.id); }
private void InteractionManager_SourceReleased(InteractionSourceState hand) { // 2.a: Reset FocusedGameObject. ResetFocusedGameObject(); }
private void InteractionManager_SourceLost(InteractionSourceState hand) { HandDetected = false; ResetFocusedGameObject(); }
/// <summary> /// Update the Touchpad input from the device /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param> /// <param name="interactionMapping"></param> private void UpdateTouchPadData(InteractionSourceState interactionSourceState, MixedRealityInteractionMapping interactionMapping) { switch (interactionMapping.InputType) { case DeviceInputType.TouchpadTouch: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.touchpadTouched; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionSourceState.touchpadTouched) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } case DeviceInputType.TouchpadPress: { //Update the interaction data source interactionMapping.BoolData = interactionSourceState.touchpadPressed; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionSourceState.touchpadPressed) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } case DeviceInputType.Touchpad: { // Update the interaction data source interactionMapping.Vector2Data = interactionSourceState.touchpadPosition; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled MixedRealityToolkit.InputSystem?.RaisePositionInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionSourceState.touchpadPosition); } break; } } }
private void InteractionManager_InteractionSourcePressed(InteractionSourceState state) { InputManager.Instance.RaiseSourceDown(this, state.source.id, InteractionSourcePressInfo.Select); }
/// <summary> /// Update the Trigger input from the device /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param> /// <param name="interactionMapping"></param> protected void UpdateTriggerData(InteractionSourceState interactionSourceState, MixedRealityInteractionMapping interactionMapping) { switch (interactionMapping.InputType) { case DeviceInputType.TriggerPress: // Update the interaction data source interactionMapping.BoolData = interactionSourceState.grasped; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionMapping.BoolData) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; case DeviceInputType.Select: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.selectPressed; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionSourceState.selectPressed) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } case DeviceInputType.Trigger: { // Update the interaction data source interactionMapping.FloatData = interactionSourceState.selectPressedAmount; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled MixedRealityToolkit.InputSystem?.RaiseFloatInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionSourceState.selectPressedAmount); } break; } case DeviceInputType.TriggerTouch: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.selectPressedAmount > 0; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionSourceState.selectPressedAmount > 0) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } break; } } }
/// <summary> /// Updates the source information. /// </summary> /// <param name="interactionSourceState">Interaction source to use to update the source information.</param> /// <param name="sourceData">SourceData structure to update.</param> private void UpdateSourceData(InteractionSourceState interactionSourceState, SourceData sourceData) { Debug.Assert(interactionSourceState.source.id == sourceData.SourceId, "An UpdateSourceState call happened with mismatched source ID."); Debug.Assert(interactionSourceState.source.kind == sourceData.SourceKind, "An UpdateSourceState call happened with mismatched source kind."); Vector3 newPointerPosition = Vector3.zero; sourceData.PointerPosition.IsAvailable = #if UNITY_2017_2_OR_NEWER interactionSourceState.sourcePose.TryGetPosition(out newPointerPosition, InteractionSourceNode.Pointer); #else interactionSourceState.properties.location.TryGetPosition(out newPointerPosition); #endif // Using a heuristic for IsSupported, since the APIs don't yet support querying this capability directly. sourceData.PointerPosition.IsSupported |= sourceData.PointerPosition.IsAvailable; Vector3 newGripPosition = Vector3.zero; sourceData.GripPosition.IsAvailable = #if UNITY_2017_2_OR_NEWER interactionSourceState.sourcePose.TryGetPosition(out newGripPosition, InteractionSourceNode.Grip); #else false; #endif // Using a heuristic for IsSupported, since the APIs don't yet support querying this capability directly. sourceData.GripPosition.IsSupported |= sourceData.GripPosition.IsAvailable; if (CameraCache.Main.transform.parent != null) { newPointerPosition = CameraCache.Main.transform.parent.TransformPoint(newPointerPosition); newGripPosition = CameraCache.Main.transform.parent.TransformPoint(newGripPosition); } if (sourceData.PointerPosition.IsAvailable || sourceData.GripPosition.IsAvailable) { sourceData.PositionUpdated = !(sourceData.PointerPosition.CurrentReading.Equals(newPointerPosition) && sourceData.GripPosition.CurrentReading.Equals(newGripPosition)); } sourceData.PointerPosition.CurrentReading = newPointerPosition; sourceData.GripPosition.CurrentReading = newGripPosition; Quaternion newPointerRotation = Quaternion.identity; sourceData.PointerRotation.IsAvailable = #if UNITY_2017_2_OR_NEWER interactionSourceState.sourcePose.TryGetRotation(out newPointerRotation, InteractionSourceNode.Pointer); #else false; #endif // Using a heuristic for IsSupported, since the APIs don't yet support querying this capability directly. sourceData.PointerRotation.IsSupported |= sourceData.PointerRotation.IsAvailable; Quaternion newGripRotation = Quaternion.identity; sourceData.GripRotation.IsAvailable = #if UNITY_2017_2_OR_NEWER interactionSourceState.sourcePose.TryGetRotation(out newGripRotation, InteractionSourceNode.Grip); #else false; #endif // Using a heuristic for IsSupported, since the APIs don't yet support querying this capability directly. sourceData.GripRotation.IsSupported |= sourceData.GripRotation.IsAvailable; if (CameraCache.Main.transform.parent != null) { newPointerRotation.eulerAngles = CameraCache.Main.transform.parent.TransformDirection(newPointerRotation.eulerAngles); newGripRotation.eulerAngles = CameraCache.Main.transform.parent.TransformDirection(newGripRotation.eulerAngles); } if (sourceData.PointerRotation.IsAvailable || sourceData.GripRotation.IsAvailable) { sourceData.RotationUpdated = !(sourceData.PointerRotation.CurrentReading.Equals(newPointerRotation) && sourceData.GripRotation.CurrentReading.Equals(newGripRotation)); } sourceData.PointerRotation.CurrentReading = newPointerRotation; sourceData.GripRotation.CurrentReading = newGripRotation; Vector3 pointerForward = Vector3.zero; sourceData.PointingRay.IsSupported = #if UNITY_2017_2_OR_NEWER interactionSourceState.source.supportsPointing; #else false; #endif sourceData.PointingRay.IsAvailable = #if UNITY_2017_2_OR_NEWER sourceData.PointerPosition.IsAvailable&& interactionSourceState.sourcePose.TryGetForward(out pointerForward, InteractionSourceNode.Pointer); #else false; #endif if (CameraCache.Main.transform.parent != null) { pointerForward = CameraCache.Main.transform.parent.TransformDirection(pointerForward); } sourceData.PointingRay.CurrentReading = new Ray(sourceData.PointerPosition.CurrentReading, pointerForward); sourceData.Thumbstick.IsSupported = #if UNITY_2017_2_OR_NEWER interactionSourceState.source.supportsThumbstick; #else false; #endif sourceData.Thumbstick.IsAvailable = sourceData.Thumbstick.IsSupported; if (sourceData.Thumbstick.IsAvailable) { AxisButton2D newThumbstick = AxisButton2D.GetThumbstick(interactionSourceState); sourceData.ThumbstickPositionUpdated = sourceData.Thumbstick.CurrentReading.Position != newThumbstick.Position; sourceData.Thumbstick.CurrentReading = newThumbstick; } else { sourceData.Thumbstick.CurrentReading = default(AxisButton2D); } sourceData.Touchpad.IsSupported = #if UNITY_2017_2_OR_NEWER interactionSourceState.source.supportsTouchpad; #else false; #endif sourceData.Touchpad.IsAvailable = sourceData.Touchpad.IsSupported; if (sourceData.Touchpad.IsAvailable) { TouchpadData newTouchpad = TouchpadData.GetTouchpad(interactionSourceState); sourceData.TouchpadPositionUpdated = !sourceData.Touchpad.CurrentReading.AxisButton.Position.Equals(newTouchpad.AxisButton.Position); sourceData.TouchpadTouchedUpdated = !sourceData.Touchpad.CurrentReading.Touched.Equals(newTouchpad.Touched); sourceData.Touchpad.CurrentReading = newTouchpad; } else { sourceData.Touchpad.CurrentReading = default(TouchpadData); } sourceData.Select.IsSupported = true; // All input mechanisms support "select". sourceData.Select.IsAvailable = sourceData.Select.IsSupported; AxisButton1D newSelect = AxisButton1D.GetSelect(interactionSourceState); sourceData.SelectPressedAmountUpdated = !sourceData.Select.CurrentReading.PressedAmount.Equals(newSelect.PressedAmount); sourceData.Select.CurrentReading = newSelect; sourceData.Grasp.IsSupported = #if UNITY_2017_2_OR_NEWER interactionSourceState.source.supportsGrasp; #else false; #endif sourceData.Grasp.IsAvailable = sourceData.Grasp.IsSupported; sourceData.Grasp.CurrentReading = #if UNITY_2017_2_OR_NEWER (sourceData.Grasp.IsAvailable && interactionSourceState.grasped); #else false; #endif sourceData.Menu.IsSupported = #if UNITY_2017_2_OR_NEWER interactionSourceState.source.supportsMenu; #else false; #endif sourceData.Menu.IsAvailable = sourceData.Menu.IsSupported; sourceData.Menu.CurrentReading = #if UNITY_2017_2_OR_NEWER (sourceData.Menu.IsAvailable && interactionSourceState.menuPressed); #else false; #endif }
private void InteractionManager_SourceUpdated(InteractionSourceState state) { state.properties.location.TryGetPosition(out handPosition); }
/// <summary> /// Update the Trigger input from the device /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param> /// <param name="interactionMapping"></param> private void UpdateTriggerData(InteractionSourceState interactionSourceState, MixedRealityInteractionMapping interactionMapping) { switch (interactionMapping.InputType) { case DeviceInputType.TriggerPress: //Update the interaction data source interactionMapping.BoolData = interactionSourceState.grasped; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionMapping.BoolData) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } // If our value was updated, raise it. if (interactionMapping.Updated) { MixedRealityToolkit.InputSystem?.RaiseOnInputPressed(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } break; case DeviceInputType.Select: { bool selectPressed = interactionSourceState.selectPressed; // BEGIN WORKAROUND: Unity issue #1033526 // See https://issuetracker.unity3d.com/issues/hololens-interactionsourcestate-dot-selectpressed-is-false-when-air-tap-and-hold // Bug was discovered May 2018 and still exists as of today Feb 2019 in version 2018.3.4f1, timeline for fix is unknown // The bug only affects the development workflow via Holographic Remoting or Simulation if (interactionSourceState.source.kind == InteractionSourceKind.Hand) { Debug.Assert(!(UnityEngine.XR.WSA.HolographicRemoting.ConnectionState == UnityEngine.XR.WSA.HolographicStreamerConnectionState.Connected && interactionSourceState.selectPressed), "Unity issue #1033526 seems to have been resolved. Please remove this ugly workaround!"); // This workaround is safe as long as all these assumptions hold: Debug.Assert(!interactionSourceState.source.supportsGrasp); Debug.Assert(!interactionSourceState.source.supportsMenu); Debug.Assert(!interactionSourceState.source.supportsPointing); Debug.Assert(!interactionSourceState.source.supportsThumbstick); Debug.Assert(!interactionSourceState.source.supportsTouchpad); selectPressed = interactionSourceState.anyPressed; } // END WORKAROUND: Unity issue #1033526 interactionMapping.BoolData = selectPressed; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionMapping.BoolData) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } // If our value was updated, raise it. if (interactionMapping.Updated) { MixedRealityToolkit.InputSystem?.RaiseOnInputPressed(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } break; } case DeviceInputType.Trigger: { // Update the interaction data source interactionMapping.FloatData = interactionSourceState.selectPressedAmount; // If our value was updated, raise it. if (interactionMapping.Updated) { // Raise input system Event if it enabled MixedRealityToolkit.InputSystem?.RaiseOnInputPressed(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionSourceState.selectPressedAmount); } break; } case DeviceInputType.TriggerTouch: { // Update the interaction data source interactionMapping.BoolData = interactionSourceState.selectPressedAmount > 0; // If our value changed raise it. if (interactionMapping.Changed) { // Raise input system Event if it enabled if (interactionSourceState.selectPressedAmount > 0) { MixedRealityToolkit.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } else { MixedRealityToolkit.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction); } } // If our value was updated, raise it. if (interactionMapping.Updated) { // Raise input system Event if it enabled MixedRealityToolkit.InputSystem?.RaiseOnInputPressed(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionSourceState.selectPressedAmount); } break; } } }
/// <summary> /// Update the source input from the device. /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform.</param> private void UpdateSourceData(InteractionSourceState interactionSourceState) { using (UpdateSourceDataPerfMarker.Auto()) { var lastState = TrackingState; var sourceKind = interactionSourceState.source.kind; lastSourcePose = currentSourcePose; if (sourceKind == InteractionSourceKind.Hand || (sourceKind == InteractionSourceKind.Controller && interactionSourceState.source.supportsPointing)) { // The source is either a hand or a controller that supports pointing. // We can now check for position and rotation. IsPositionAvailable = interactionSourceState.sourcePose.TryGetPosition(out currentSourcePosition); if (IsPositionAvailable) { IsPositionApproximate = (interactionSourceState.sourcePose.positionAccuracy == InteractionSourcePositionAccuracy.Approximate); } else { IsPositionApproximate = false; } IsRotationAvailable = interactionSourceState.sourcePose.TryGetRotation(out currentSourceRotation); // We want the source to follow the Playspace, so fold in the playspace transform here to // put the source pose into world space. currentSourcePosition = MixedRealityPlayspace.TransformPoint(currentSourcePosition); currentSourceRotation = MixedRealityPlayspace.Rotation * currentSourceRotation; // Devices are considered tracked if we receive position OR rotation data from the sensors. TrackingState = (IsPositionAvailable || IsRotationAvailable) ? TrackingState.Tracked : TrackingState.NotTracked; } else { // The input source does not support tracking. TrackingState = TrackingState.NotApplicable; } currentSourcePose.Position = currentSourcePosition; currentSourcePose.Rotation = currentSourceRotation; // Raise input system events if it is enabled. if (lastState != TrackingState) { CoreServices.InputSystem?.RaiseSourceTrackingStateChanged(InputSource, this, TrackingState); } if (TrackingState == TrackingState.Tracked && lastSourcePose != currentSourcePose) { if (IsPositionAvailable && IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, currentSourcePose); } else if (IsPositionAvailable && !IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourcePositionChanged(InputSource, this, currentSourcePosition); } else if (!IsPositionAvailable && IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourceRotationChanged(InputSource, this, currentSourceRotation); } } } }
private void InteractionManager_SourceReleased(InteractionSourceState hand) { HideHandGuidance(hand); }
/// <summary> /// Update the hand data from the device. /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform.</param> private void UpdateHandData(InteractionSourceState interactionSourceState) { #if WINDOWS_UWP // Articulated hand support is only present in the 18362 version and beyond Windows // SDK (which contains the V8 drop of the Universal API Contract). In particular, // the HandPose related APIs are only present on this version and above. if (!WindowsApiChecker.UniversalApiContractV8_IsAvailable) { return; } PerceptionTimestamp perceptionTimestamp = PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now); IReadOnlyList <SpatialInteractionSourceState> sources = SpatialInteractionManager?.GetDetectedSourcesAtTimestamp(perceptionTimestamp); foreach (SpatialInteractionSourceState sourceState in sources) { if (sourceState.Source.Id.Equals(interactionSourceState.source.id)) { HandPose handPose = sourceState.TryGetHandPose(); if (InputSystem.InputSystemProfile.HandTrackingProfile.EnableHandMeshVisualization) { // Accessing the hand mesh data involves copying quite a bit of data, so only do it if application requests it. if (handMeshObserver == null && !hasRequestedHandMeshObserver) { SetHandMeshObserver(sourceState); hasRequestedHandMeshObserver = true; } if (handMeshObserver != null && handMeshTriangleIndices == null) { uint indexCount = handMeshObserver.TriangleIndexCount; ushort[] indices = new ushort[indexCount]; handMeshObserver.GetTriangleIndices(indices); handMeshTriangleIndices = new int[indexCount]; Array.Copy(indices, handMeshTriangleIndices, (int)handMeshObserver.TriangleIndexCount); // Compute neutral pose Vector3[] neutralPoseVertices = new Vector3[handMeshObserver.VertexCount]; HandPose neutralPose = handMeshObserver.NeutralPose; var vertexAndNormals = new HandMeshVertex[handMeshObserver.VertexCount]; HandMeshVertexState handMeshVertexState = handMeshObserver.GetVertexStateForPose(neutralPose); handMeshVertexState.GetVertices(vertexAndNormals); for (int i = 0; i < handMeshObserver.VertexCount; i++) { neutralPoseVertices[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Position); } // Compute UV mapping InitializeUVs(neutralPoseVertices); } if (handPose != null && handMeshObserver != null && handMeshTriangleIndices != null) { var vertexAndNormals = new HandMeshVertex[handMeshObserver.VertexCount]; var handMeshVertexState = handMeshObserver.GetVertexStateForPose(handPose); handMeshVertexState.GetVertices(vertexAndNormals); var meshTransform = handMeshVertexState.CoordinateSystem.TryGetTransformTo(WindowsMixedRealityUtilities.SpatialCoordinateSystem); if (meshTransform.HasValue) { System.Numerics.Vector3 scale; System.Numerics.Quaternion rotation; System.Numerics.Vector3 translation; System.Numerics.Matrix4x4.Decompose(meshTransform.Value, out scale, out rotation, out translation); var handMeshVertices = new Vector3[handMeshObserver.VertexCount]; var handMeshNormals = new Vector3[handMeshObserver.VertexCount]; for (int i = 0; i < handMeshObserver.VertexCount; i++) { handMeshVertices[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Position); handMeshNormals[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(vertexAndNormals[i].Normal); } HandMeshInfo handMeshInfo = new HandMeshInfo { vertices = handMeshVertices, normals = handMeshNormals, triangles = handMeshTriangleIndices, uvs = handMeshUVs, position = WindowsMixedRealityUtilities.SystemVector3ToUnity(translation), rotation = WindowsMixedRealityUtilities.SystemQuaternionToUnity(rotation) }; InputSystem?.RaiseHandMeshUpdated(InputSource, ControllerHandedness, handMeshInfo); } } } else { // if hand mesh visualization is disabled make sure to destroy our hand mesh observer if it has already been created if (handMeshObserver != null) { // notify that hand mesh has been updated (cleared) HandMeshInfo handMeshInfo = new HandMeshInfo(); InputSystem?.RaiseHandMeshUpdated(InputSource, ControllerHandedness, handMeshInfo); hasRequestedHandMeshObserver = false; handMeshObserver = null; } } if (handPose != null && handPose.TryGetJoints(WindowsMixedRealityUtilities.SpatialCoordinateSystem, jointIndices, jointPoses)) { for (int i = 0; i < jointPoses.Length; i++) { unityJointOrientations[i] = WindowsMixedRealityUtilities.SystemQuaternionToUnity(jointPoses[i].Orientation); unityJointPositions[i] = WindowsMixedRealityUtilities.SystemVector3ToUnity(jointPoses[i].Position); // We want the controller to follow the Playspace, so fold in the playspace transform here to // put the controller pose into world space. unityJointPositions[i] = MixedRealityPlayspace.TransformPoint(unityJointPositions[i]); unityJointOrientations[i] = MixedRealityPlayspace.Rotation * unityJointOrientations[i]; if (jointIndices[i] == HandJointKind.IndexTip) { lastIndexTipRadius = jointPoses[i].Radius; } TrackedHandJoint handJoint = ConvertHandJointKindToTrackedHandJoint(jointIndices[i]); if (!unityJointPoses.ContainsKey(handJoint)) { unityJointPoses.Add(handJoint, new MixedRealityPose(unityJointPositions[i], unityJointOrientations[i])); } else { unityJointPoses[handJoint] = new MixedRealityPose(unityJointPositions[i], unityJointOrientations[i]); } } InputSystem?.RaiseHandJointsUpdated(InputSource, ControllerHandedness, unityJointPoses); } } } #endif // WINDOWS_UWP }
private void HideHandGuidance(InteractionSourceState hand) { handGuidance.SetActive(false); handId = null; }
// Workaround for Select Button // Issue: Pressed and Released event only recognize Select once and Select is pressed when selectPressedAmount==1, // so on press Select State is not always true and therefore not 'pressed'. // Updating SelectPressed in UpdateEvent of WSA.XR causes issues because the event and Unity Update are not synched // and therefore VRTK's polling of GetPressDown and GetPressUp might already been overwritten. protected virtual void UpdateSelectButton(InteractionSourceState state) { prevButtonState.SelectPressed = currentButtonState.SelectPressed; currentButtonState.SelectPressed = state.selectPressed; }
public SelectManipilateEventArgs(InteractionSourceState sourceState, bool selectPressed, float selectPressedAmount, InteractionSourceHandedness handedness) : base(sourceState, handedness) { SelectPressed = selectPressed; SelectPressedAmount = selectPressedAmount; }
private void InteractionManager_SourceReleased(InteractionSourceState hand) { // Stop displaying the guidance indicator when the user releases their finger from the pressed state. RemoveTrackedHand(hand); }
/// <summary> /// Update the controller data from the provided platform state /// </summary> /// <param name="interactionSourceState">The InteractionSourceState retrieved from the platform</param> public virtual void UpdateController(InteractionSourceState interactionSourceState) { if (!Enabled) { return; } UpdateControllerData(interactionSourceState); EnsureControllerModel(interactionSourceState); if (Interactions == null) { Debug.LogError($"No interaction configuration for Windows Mixed Reality Motion Controller {ControllerHandedness}"); Enabled = false; } for (int i = 0; i < Interactions?.Length; i++) { switch (Interactions[i].InputType) { case DeviceInputType.None: break; case DeviceInputType.SpatialPointer: UpdatePointerData(interactionSourceState, Interactions[i]); break; case DeviceInputType.Select: case DeviceInputType.Trigger: case DeviceInputType.TriggerTouch: case DeviceInputType.TriggerPress: UpdateTriggerData(interactionSourceState, Interactions[i]); break; case DeviceInputType.SpatialGrip: UpdateGripData(interactionSourceState, Interactions[i]); break; case DeviceInputType.ThumbStick: case DeviceInputType.ThumbStickPress: UpdateThumbStickData(interactionSourceState, Interactions[i]); break; case DeviceInputType.Touchpad: case DeviceInputType.TouchpadTouch: case DeviceInputType.TouchpadPress: UpdateTouchPadData(interactionSourceState, Interactions[i]); break; case DeviceInputType.Menu: UpdateMenuData(interactionSourceState, Interactions[i]); break; default: Debug.LogError($"Input [{Interactions[i].InputType}] is not handled for this controller [WindowsMixedRealityController]"); Enabled = false; break; } } LastSourceStateReading = interactionSourceState; }
// This fires when the finger is released. private void InteractionManager_SourceReleased(InteractionSourceState hand) { RemoveTrackedHand(hand); }
private void InteractionManager_SourceReleased(InteractionSourceState state) { trackedHand.Remove(state.source.id); }