Examples: Add XRInputEventsDispatcher and demo
Related issue: #21039
Description
This addition makes the creation of dynamic WebXR controller input events easier, based on WebXR Input Profiles and the Motion Controllers library.
Usage
let inputEventsDispatcher = new XRInputEventsDispatcher( renderer.xr, [ 0, 1 ] ); // takes WebXRManager and controllerIndices
inputEventsDispatcher.registerInputForEvents( 'left', 'button' ); // registers all components with button in their id
inputEventsDispatcher.addEventListener( 'left-button', onAnyButton ); // dispatches custom events with references to updated data
Event Structure in XRInputEventsDispatcher
{
type: eventTypeString, // `${handedness}-${partialId}`
target: XRInputEventsDispatcher,
partialId: partialId, // same as the one used while registering
handedness: handedness,
xrInputSource: xrInputSource, // useful to have this reference in some situations
components: matchedComponents // all components with id that include partialId
}
Demo Link On Glitch
I reversed my branch to the last useful commit to undo an accidental Merge Commit, please ignore the force-push. I can create another MR from a different branch if this leads to any issues.
I have added some considerations for discussion in the Immersive Controls thread
I have modified the example to make it independent of the XRControllerModelFactory. I think this makes the example clearer, also demos that this class calls Motion Controller methods on its own. I haven't pushed the changes yet, but you can find it in this Glitch example. I am also using a custom build of motion-controllers.module.js that incorporates some changes I have suggested on that repo (i.e. ability to call updateValuesFromGamepad when visual response changes aren't used, saves on some computation each frame)
I have changed the demo functionality for the thumbsticks/touchpad axes to snap-turn and smooth locomotion (instead of just moving a demo cube). I have kept the underlying XRInputEventsDispatcher class fairly lean to offer high flexibility, so for now the code related to snap-turn and smooth motion is inside the example. I would like some feedback on how much of the code to keep in the example vs. moving more of it to a separate JS module. It might make sense to separate out the snap-turn and smooth locomotion bits from the example here and the teleport functionality in the webxr_vr_teleport example to different class(es). Thoughts?
Looking at the scope of this MR in the wider task of having ImmersiveControls as discussed in #21039, I think this MR's approach is balanced, not too specific and provides high flexibility when dealing with different input control schemes. @Mugen87 @mrdoob Any suggestions for improvements? Also please help me mention / ping other relevant people in this thread. Thanks!