User Manual

WebXR Input Sources in PlayCanvas

Input Source

An XrInputSource represents an input mechanism that allows the user to interact with a virtual world. Those include, but are not limited to: handheld controllers, optically tracked hands, gaze-based input methods and touch screens. But an input source is not explicitly associated with traditional gamepads, mice or keyboards.

Accessing Input Sources

A list of input sources is available on the XrInput manager which is created by the XrManager:

var inputSources = app.xr.input.inputSources;
for (var i = 0; i < inputSources.length; i++) {
    // iterate through each available input source
}

Input sources can be added and removed dynamically. This can be done by connecting physical devices, or some input sources have a lifespan only during their primary action (for example, a touchscreen in an AR-type session on mobile). You can subscribe to add and remove events:

app.xr.input.on('add', function (inputSource) {
    // input source been added

    inputSource.once('remove', function () {
        // know when input source has been removed
    });
});

Primary Action (select)

Each input source can have a primary action select. On gaze-based input sources, it is the touch of a screen/button. On handheld devices, it is the primary button/trigger. There are also selectstart and selectend events which you can subscribe to as follows:

inputSource.on('select', function () {
    // primary action
});

Or through the input manager:

app.xr.input.on('select', function (inputSource) {
    // primary action
});

Ray

Each input source has a Ray which has an origin where it points from, and a direction in which it is pointing. A ray is transformed in XR local space, and if camera ancestors are transformed, then the ray should be transformed accordingly. Some examples of input sources might be, but not limited to:

Here is an example illustrating how to check whether a ray has intersected with the bounding-box of a mesh:

if (meshInstance.aabb.intersectsRay(inputSource.ray)) {
    // input source is pointing on a mesh
}

Grip

Some input sources are associated with a physical handheld device, such as an Oculus Touch™, and can have position and rotation. Their position and rotation are calculated in XR session space. If the XR camera's parent is transformed, then the controller entity should be in the same parent, or inherit transformation accordingly:

if (inputSource.grip) {
    // can render device model

    // position and rotate associated entity with model
    entity.setLocalPosition(inputSource.position);
    entity.setLocalRotation(inputSource.rotation);
}

GamePad

If the platform supports the WebXR Gamepads Module, then an input source might have an associated GamePad object with it, which can be accessed to get buttons, triggers, axes and other input hardware states:

var gamepad = inputSource.gamepad;
if (gamepad) {
    if (gamepad.buttons[0] && gamepad.buttons[0].pressed) {
        // user pressed a button on a gamepad
    }
}

Profiles

Each input source might have a list of strings describing a type of input source, which is described in a profile registry. Based on this, you can figure out what type of model to render for handheld device or what capabilities it might have. Additionally, the profile registry lists gamepad mapping details, such as buttons and axes.

if (inputSource.profiles.indexOf('oculus-touch-v2') !== -1) {
    // it is an Oculus Touch™ handheld device
}