Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] OnHandLost and OnLastHandDeactivated is not invoked for a specific hand (UnityEditor) #940

Open
ArDevKarl opened this issue Oct 10, 2024 · 1 comment
Assignees
Labels
Priority: Medium The priority of the issue is medium. Type: Bug A problem with an existing feature that can be fixed with the next patched release.

Comments

@ArDevKarl
Copy link

ArDevKarl commented Oct 10, 2024

Describe the bug

OnHandLost and OnLastHandDeactivated of the SolverHander are never called when tracking only one hand (Left).
Cannot test it on the HoloLens 2 right now, so this bug may only an Editor issue.

Interestingly, if the SolverHandlers Tracked Handedness is "Everything", all events work as intended.

To reproduce

Create a GameObject and add:

  • SolverHandler
  • HandConstraint

Edit the SolverHandler:

  • Tracked Target Type: HandJoint
    - Tracked Handedness: Left
  • Tracked Hand Joint: Palm

Register a console output to all events of the HandConstraint.
Press play and use the left hand simulation.

You'll see that OnHandActivate and OnFirstHandDetected are called but OnLastHandDeactivated and OnHandLost are not.

Expected behavior

OnLastHandDeactivated and OnHandLost are called, when the left simulated hand disappears.

Setup

  • Unity 2022.3.7f1
  • MRTK3 (4.0.0-pre.1)

Target platform (please complete the following information)

  • Unity Editor, HoloLens 2
@ArDevKarl ArDevKarl added Needs: Triage Needs to be triaged. Type: Bug A problem with an existing feature that can be fixed with the next patched release. labels Oct 10, 2024
@shaynie shaynie added Priority: Medium The priority of the issue is medium. and removed Needs: Triage Needs to be triaged. labels Oct 23, 2024
@MaxPalmer-UH
Copy link
Contributor

MaxPalmer-UH commented Nov 15, 2024

I've been looking into this. It appears the cause of the bug relates to the interplay between the SolverHandler class and the HandConstraint class and the logic they use to determine if a hand is being actively tracked.

When the SolverHandler TrackedHandedness mode is set to Both/Everything, when AttachToNewTrackedObject is called it looks to see if the preferred hand is being tracked and if not, if the other hand is being tracked - i.e. it's checking for a hand swap / change of handedness. If neither hand is now tracked (or the preferred hand stops being tracked) it sets the currentTrackedHandedness to the other hand or None. Its criteria for determining if a hand is tracked is to look at the relevant XRNode (e.g. left/right hand) and checks if HasValue is true AND crucially will also try to read the palm joint data if so. This attempt to read the palm position will fail if the hand is not actively being tracked (even though HasValue will always be true). The value of currentTrackedHandedness is used by the HandConstraint class, mapping to it's trackedNode state. When this value effectively changes, it triggers the logic in SolverUpdate in HandConstraint.cs to fire the relevant OnFirstHandDetected/OnHandActivate/OnLastHandLost/OnHandDeactivate event.

When SolverHandler TrackedHandedness is set to Left (and also presumably Right), SolverHandler.AttachToNewTrackedObject will never update the currentTrackedHandedness based on the tracked hand state (as it doesn't look for a hand swap) - so it will remain set to left or right. Therefore, when SolverUpdate in HandConstraint.cs is called, the trackedNode will (effectively) remain the same - i.e. left or right. The event firing logic would still be fine IF when the hand stops being tracked the XRNode.HasValue flag changed value to false, but it does not. If it adopted the same logic used in SolverHandler and also checked to see if it could also retrieve the palm position, then the tracking state change would be picked up and the events triggered.

I'd recommend that HandConstraint::SolverUpdate use the same logic for determining whether a hand is tracked as SolverHandler - (i.e. as defined in IsHandTracked) and looks at both the XRNode.HasValue flag and whether it can actually retrieve the palm joint position, rather than just looking for a change of handedness or whether the current XRNode returns true for HasValue. @keveleigh what do you think? If you agree I'll make that change.

Note: I assume that XRNode.HasValue always stays true because of a quirk of how individual OpenXR providers interpret whether a hand is being tracked or not - i.e. it's reporting if hand tracking is possible, not if a hand is currently being tracked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: Medium The priority of the issue is medium. Type: Bug A problem with an existing feature that can be fixed with the next patched release.
Projects
None yet
Development

No branches or pull requests

3 participants