fix: hand mesh not visible after tracking lost/restored #227
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This should fix issue #213, but it might be a workaround for a more fundamental bug.
I recreated the problem without all the XR hand input event hassle. The issue currently arises when 2 array items are reversed in their order and the react key prop of the array is used. An example of that is here.
The root of the Problem seems to be with switchInstance in react-three-fiber. In the specific buggy scenario, switchInstance removes the second element from the parent and adds as it the first. (in the first switch), then it removes that element from the parent in the second switch (which it shouldn't). So it kind of has an old state? Maybe switchInstance should only remove elements when the position in the parent is the same?
This fix (not relying on array index anymore) causes switchInstance to not be called anymore.
For more info on why this "swapping" happens with the Quest 2:
When the Quest 2 fires an inputsourceschange event when you move a hand out of the hand tracked area, there is the removed tracked hand in the "removed" array, but also an inputsource in the "added" array. I am not sure why, maybe this is a fallback? Nonetheless, this causes 2 immediate sync events in three.js: [disconnect, connect]. In the listeners in XR.js, zustand (rightfully) swaps the order of the 2 XRControllers.