playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.61k stars 1.34k forks source link

Add an event for XrManager in AR for when it finds the ground/floor and starts tracking camera position #4673

Open yaustar opened 2 years ago

yaustar commented 2 years ago

The reason for want this event is so that the developer can disable entities when going through the AR tracking phase and only show them once they can be anchored to the floor.

As far as I can tell, WebXR AR starts tracking when a pose is returned at this point:

https://github.com/playcanvas/engine/blob/main/src/xr/xr-manager.js#L689

@Maksims, would you be able to help advise on this please?

yaustar commented 2 years ago

Spoke to Maksims: In 1.57, the XrManager doesn't fire the 'update' event until there is a valid pose available so this could be used as a workaround until we've thought about this more

mvaligursky commented 2 years ago

This that was merged few days ago is related too https://github.com/playcanvas/engine/pull/4517

Maksims commented 2 years ago

That recent fix https://github.com/playcanvas/engine/pull/4517 - while avoiding an issue with Oculus Link is actually skipping other XR subsystems from updates and not doing rendering - which is last thing we want to do. Lack of pose from frame data - is a valid XR state, based on WebXR Specs: https://www.w3.org/TR/webxr/#dom-xrframe-getviewerpose

So we need a better fix for the issue, by providing a valid path with the pose === null case.

mvaligursky commented 2 years ago

Yep I had the same feeling after reading this ticket. Any suggestions on how to handle this?

Maksims commented 2 years ago

I've created an issue to address it: https://github.com/playcanvas/engine/issues/4675

Maksims commented 2 years ago

On the note of this issue, XR Spec does not provide any events or flags about underlying XR system tracking state, but lack of pose is basically a case of "no tracking", which we can use to have our own flag for it.

We already have a concept of tracking flag in XrHand: https://github.com/playcanvas/engine/blob/main/src/xr/xr-hand.js#L297-L304 With two additional events tracking and trackinglost: https://github.com/playcanvas/engine/blob/main/src/xr/xr-hand.js#L130-L140

Similar could be added for view state, except we don't have a dedicated class/object to refer to a view/pose, maybe something like:

if (camera.tracking) {

}

// or

camera.on('trackingloss', () => {

});
jpauloruschel commented 2 years ago

Further down the update method, we have this line: https://github.com/playcanvas/engine/blob/main/src/xr/xr-manager.js#L768

this.fire('update', frame);

You could also do something like this for getting the first tracked update:

this.app.xr.once('update', () => {
    // code here
});
yaustar commented 2 years ago

Yeah, that is probably what I would switch once 1.57 is current in the Editor. In 1.56, update is being fired each frame, pose or not 😅