How do you update the WebXR camera if inside a moving elevator/space ship/car?

I’m at work, so I can’t test this out, but I was wondering if it would be possible to use a const and an if/else statement for childForCamera.position.addInPlace(xr.baseExperience.camera.position); in the same way that I used if…if else statements for reading the elevator const? When elevator == 4, it can set something like const unparentCamera = 1. Then:

xr.baseExperience.onInitialXRPoseSetObservable.add(()=>{

                // append the initial position of the camera to the parent node
            if(unparentCamera == 0){
                childForCamera.position.addInPlace(xr.baseExperience.camera.position);
            }
            else {
               childForCamera.position.addInPlace(null);//??
            }

                xr.baseExperience.sessionManager.onXRFrameObservable.add(()=>{ etc...

I probably broke a few Javascript laws there, since I’m not a coder. Just thinking out loud…

No, the if/else statement didn’t work I forgot to take line 326 into account:
xr.baseExperience.camera.position.copyFrom(childForCamera.getAbsolutePosition());

The if(unparentCamera == 0) part of the statement was accepted up to the point where unparentCamera was set to 1 and the “else” part of the statement tried to nullify or switch the childForCamera.position.addInPlace(). That’s when the scene froze. In other words, I’m grasping at straws…

t

I finally figured it out (going from “elevator-riding mode” to the non-elevator-riding mode, which allows the player to teleport again). I did it by using RanaanW’s first example (“change the camera’s position along with the elevator”) instead of the childForCamera example I’d been struggling with. I was also able to bring the camera back to elevator-riding mode. I haven’t yet applied this to the project I’ve been working on, but now I know that I can do it, and I’m pretty excited. :smile:

In the Playground below, I used RaananW’s example scene and added a few boxes and another sphere. I placed a single if statement in the xr.baseExperience.onInitialXRPoseSetObservable.add(() script that reads whether or not elevator var is set at 2 or less. If yes, the camera’s position is aligned with the moving sphere’s position. As soon as elevator var is set above 2, the camera becomes independent of the sphere, and regular real-world movement and teleporting are possible again. Right now I have a sphere movement loop going on. There’s a brief moment when elevator var is set to 3, and the camera is independent of the sphere, until elevator var is set at 0 again.

You can interrupt the loop and make the camera independent by using the controller’s trigger to click the stationary sphere. And you can reset elevator var to 0 and reset the camera’s position by clicking the box behind the sphere:

https://www.babylonjs-playground.com/#FGI273#151

Thanks again, RaananW, and thanks, Owen, for asking the elevator question that set me moving in the right direction!

Edit:
I applied my last Playground example’s gliding movement process (#151) to the way I want the camera to move through my scene’s rooms, corridors, ramps, elevators, etc., when not teleporting. Here I set up the sphere as a landing marker wherever the floor is clicked using the controller trigger. Sometimes it looks like the sphere is rolling toward the camera, but the camera is actually flying toward it. When the camera stops above the sphere and drops down to “land,” it becomes independent of the gliding process, and the player can teleport again. Teleportation isn’t possible while the camera is gliding through the air. As long as the camera is in the air, the player can click the floor repeatedly to change directions, because the gliding process is reset each time:
https://www.babylonjs-playground.com/#FGI273#154

2 Likes

Thank you so much for sharing!
I’m intending to have a similar functionality in my levels as well…

1 Like

Hi! Coming back to this thread after a while to see if anything has changed. Now that Babylon 5 has just been released :wink: :wink:

To summarize the thread above, (and pls correct me if I’m wrong), it’s possible to update the XRCamera position continuously with another moving mesh (like a boat) by copying positions on every frame BUT because the position of “head” to boat is fixed, the illusion of riding on the boat with freedom to shift side to side, stand-up or sit down in the boat is nullified. The illusion would only be maintained if you didn’t translate your head and only rotated it.

One question I have is, does WebXR provide any information regarding the local offset to our own room / local VR play area (the Oculus guardian boundary). If we could somehow get that, it seems like that’s the position we wish we could be be updating and not the camera directly?

(Forgive my crude drawing to illustrate my point – no pun intended).

That way the room’s is fixed to the boat, but I can still walk around the boat. But I dunno if that’s possible.

To answer your WebXR question :slight_smile:

There are different reference space types that you can use. we use local-floor per default, but you can change them when initializing your scene, according to your needs.

Ok, so I modified RaananW’s PG to make it relative to previous position.

Now your XR camera will follow the sphere, but also allow you to move around the “boat”.

The trick is to instead of setting the XR camera position to the child position, calculate an offset from previous child position to the current child position, and add that to the XR camera.

1 Like

:exclamation: :bowing_man: :bowing_man: :bowing_man: :exclamation:

Wow! This is awesome!

I’ve modified your example into an “elevator” that moves up, down and left right

https://playground.babylonjs.com/#F41V6N#846

I’m still trying to twist my brain into understanding why this works though… by nudging the camera with a frame-by-frame delta (the boat’s delta), we allow the xrCamera to freely move the way it was and still keep up with where the boat is going… in any direction.

I tried expanding on this idea to also support some rotation (changing the “yaw” slightly), but I seem to be rotating at different rates than the “boat”:
https://playground.babylonjs.com/#F41V6N#847 (experimentation with position and yaw rotation)

The webxr camera accepts a parent to which you can attach it. This is a very simple “elevator” simulation:

Babylon.js Playground (babylonjs.com)

You can move around while the elevator goes up. This is because the rig cameras (which are in charge of the webxr transformation) have the webxr camera as a parent.

2 Likes

ERMAHGERD! This is even simpler! When did this become available?!

Thanks @RaananW !

So sorry for not updating this thread… I was sure I did!!!

This is available for a while now ( [XR] Initial support for WebXR camera parenting by RaananW · Pull Request #10850 · BabylonJS/Babylon.js (github.com))

1 Like