What properties have any effect on a WebXR camera?


#1

I am generating a function to set up an XR camera in a “browser” does not require a click to enter XR mode. First, a fallback camera is made, then an experience is created.

As the enterXRAsync code is running right after the experience is created & light definitions still need to run, I am checking ._isSupported to avoid an exception being thrown.

Assuming successful, what additional properties can really be set on the XR camera from those on the fallback camera? Maybe fov, minZ, maxZ, speed, inertia, & ellipsoid? No hurry, since I do not actually have a device. I almost never default on fov on a desktop scene.

function defineCameras(scene, positionOffset) {
    let camera;

    // setup a fallback camera for WebXR
    camera = new BABYLON.UniversalCamera("XR_Fallback", new QI.V(7.3589,4.9583,-6.9258), scene);
    if (positionOffset) camera.position.addInPlace(positionOffset);
    camera.setCameraRigMode(0,{interaxialDistance: .0637});
    camera.rotation = new QI.V(.4615,-.8149,0);
    camera.fov = .6911;
    camera.minZ = .1;
    camera.maxZ = 100;
    camera.speed = 1;
    camera.inertia = 0.9;
    camera.checkCollisions = false;
    camera.applyGravity = false;
    camera.ellipsoid = new QI.V(.2,.9,.2);
    scene.setActiveCameraByID("XR_Fallback");

    const helper = BABYLON.WebXRExperienceHelper.CreateAsync(scene);
    if (helper._isSupported){
        // values probably going to change here; using values for exokit ML examples
        helper.enterXRAsync({exclusive: true}, {frameOfReferenceType: "stage"}).then(() => {
            helper.setPositionOfCameraUsingContainer(new QI.V(7.3589,4.9583,-6.9258));
            helper.rotateCameraByQuaternionUsingContainer(new QI.Q(.3484,-.6153,0,-.7071));
    });
}

#2

This does not anwer your question about cameras, so sorry for that in advance. I would stay away from anything starting with an underscore as it may not be “supported” going forward.

I haven’t tested this, but from reading the spec, I think you need to test if it is supported and more over I think it’s a user activated event and you need to listen to changes for support (ie: a device is plugged in after).
var supported = await helper.supportsSessionAsync({exclusive: true});

I would check out the WebXREnterExitUIButton.

edit: nevermind I see you are using exokit. keep up posted on your progress - very interesting. thanks for sharing.


#3

The XRCamera, at the moment is a FreeCamera that doesnt render that has a couple TargetCameras as children for each xr view (eg. per eye), their view and projection matrix are updated every frame but all other properties should be modifiable like the onces you listed (things like speed/inertia wont have any effect thought because the position of the camera is manually set each frame).

The other thing to worry about is all the modes that xr can support (VR, AR, AR on phone, sitting, standing, etc.) so you might have different fallback settings for different types (eg. 3dof headset) you might want to update the position of the xr camera to where the fallback camera was (And I would do this via a xr camera parent node as outlined in the docs made so far).


#4

Thanks, guys. I have update the function, so that properties which have no meaning in XR are not set in the fallback camera. Most properties are not really easy to be set on sub cameras other than minZ, maxZ, & FOV. That is because those are updated on the sub cameras every frame (think I wrote that).

The problem with changing any other settings is that you would to do it in a helper._session.onXRFrameObservable.add(...), because the sub cameras will not exist until then. That’s a second underscore variable need to be referenced.

For AR, gravity & collisions do not make sense. ellipsoid is at the FreeCamera level, so it cannot set on a target camera.

I am already setting the position & rotation of the fallback & headset to the same thing.

Probably should add UI for all the modes & better supports checking, but for now just going unchecked hard coding works first. This is what going with for now:

function defineCameras(scene, positionOffset) {
    let camera;

    // setup a fallback camera for WebXR
    camera = new BABYLON.UniversalCamera("XR_Fallback", new QI.V(7.3589,4.9583,-6.9258), scene);
    if (positionOffset) camera.position.addInPlace(positionOffset);
    camera.rotation = new QI.V(.4615,-.8149,0);
    camera.fov = .6911;
    camera.minZ = .1;
    camera.maxZ = 100;
    scene.activeCamera = camera;

    const helper = BABYLON.WebXRExperienceHelper.CreateAsync(scene);
    if (helper._isSupported){
        // values probably going to change here; using values from exokit ML examples
        helper.enterXRAsync({exclusive: true}, {frameOfReferenceType: "stage"}).then(() => {
            helper.setPositionOfCameraUsingContainer(new QI.V(7.3589,4.9583,-6.9258));
            helper.rotateCameraByQuaternionUsingContainer(new QI.Q(.3484,-.6153,0,-.7071));
            helper.camera.fov = .6911;
            helper.camera.minZ = .1;
            helper.camera.maxZ = 100;
        });
    }
}