How to set the position and rotation of both the camera and xrCamera using createDefaultXRExperienceAsync

I’m using createDefaultXRExperienceAsync to create an XR scene but I can’t work out how to set the position and rotation of both the camera and xrCamera. Mainly because there seem to be between 1 and 4 cameras in the scene and I can’t work out which is which.

Help? Is this one for @RaananW?

(This question leads on from https://forum.babylonjs.com/t/changing-camera-position-on-pause-best-practice/12048 but is different enough for it’s own thread I think.)

For the camera you can set it like a mesh:

var camera = new BABYLON.DeviceOrientationCamera(“DevOr_camera”, new BABYLON.Vector3(0, 0, 0), scene);
camera.angularSensibility = 5000;
camera.minZ = 0;
camera.position = new BABYLON.Vector3(0, 1.2, 0);
camera.attachControl(canvas, true);

same is for the XR Camera

xrHelper = this.scene.createDefaultXRExperienceAsync…
xrHelper.camera.position = …

You just need to get the reference to the right cameras. The xr camera is referenced in the experience helper, the camera you created is named and referenced by you.

I just want to note that it is actually not really needed. The XR camera will take the regular camera’s transformation when entering XR and will copy its Frankenstein to the regular camera when leaving XR. The experience helper does the job for you

Frankenstein???

1 Like

Auto correction of my keyboard. Transformation, since you are asking

Thanks, that makes more sense.

Best auto correct issue EVER !!!

2 Likes

I’ve set up a playground (https://playground.babylonjs.com/#E50JA3#3).

Use Z and X to move between/restore two preset views.

  1. Using an ArcRotateCamera seems to be a “bad idea™”.
  2. In XR view setting the camera position and transformation seem to have no effect.
    I had to set xrHelper.baseExperience.camera.
  3. Switching back to normal view seems to put the camera at the origin and give it a spin.
  1. “Bad Idea” seems a bit harsh, but let’s go along with it. An Arc rotate camera does not have a rotation, as it is looking inwards towards a target. so, you can set the distance, the alpha/beta position, or the position in space, but not the rotation directly. You can read about it here - Cameras - Babylon.js Documentation. The demo you are showing will never work with an arc rotate, because, alas, you cannot set a rotation.
  2. I am not sure how you get keyboard input in XR (except for in the emulator or maybe in Windows MR devices) but - setting position does work:

Untitled_ Jul 6, 2020 11_10 AM

What doesn’t work is setting rotation once roationQuaternion is set. If the quaternion is set (as it is the case in XR), you will need to change the quaternion and not the rotation vector. This is documented in different places, this is worth a read - Euler Angles and Quaternions - Babylon.js Documentation

I am not sure why you say it has no effect, but my guess is that it is due to the keyboard input. What devices are you trying to use?

  1. The reason that happens is that the camera is attached to the canvas and is constantly recording changes you are making to the original camera (and) on the canvas. This would only be an issue when using desktop applications where you can interact with the canvas after entering XR, and I agree this is something that could happen automatically, but you will need to detach the canvas from the original camera and re-attach it when existing XR:

https://playground.babylonjs.com/#E50JA3#4

Quick note about setting the position - it is always better to reuse your vectors and not recreate them. I would use camera.position.set(1,2,3) instead of camera.position = new Vector3(1,2,3). You can also use .copyFrom if you want to copy from a different vector. But this is not a must, your app will react the same.

1 Like

Apologies if I’m being less than clear. I’m trying to learn a lot here.

  1. “bad idea™” was meant flippantly, hence ™.
  2. I’m only using the keyboard to make it easy to set the transformation in the example, it’s not intended for release. It’s not really relevant to the issues I’m trying to resolve.

I am not sure why you say it has no effect, but my guess is that it is due to the keyboard input. What devices are you trying to use?

That’s because I was setting rotation and not rotationQuaternion. My mistake, rectified.

Is xrHelper.baseExperience.camera the correct way to access the XR camera?

Thanks for the “set” tip, I did look for that particular method but couldn’t find it.

= = = = = = = = = = =

The XR camera will take the regular camera’s transformation when entering XR and will copy its transformation to the regular camera when leaving XR. The experience helper does the job for you.

Doesn’t this contradict what your say in point 3?

  1. The reason that happens is that the camera is attached to the canvas and is constantly recording changes you are making to the original camera (and) on the canvas. … you will need to detach the canvas from the original camera and re-attach it when existing XR:

Simpler, new example to try to illustrate my difficulties more clearly (https://playground.babylonjs.com/#FEX2N2). Switch between XR and normal view without panning or moving the camera. The camera transforms are not copied between views.
Is this correct behaviour? So, I’ll need to set the transform between view changes?

I want the game to be playable in XR and normal views on mobile. At any point the user might switch from XR to normal and vice versa, so the camera transform needs to be preserved between views (as the developer I jump between both views, so preserving the transform would be nice for me, too :smiley:).

TIA

XR time!

Nope, it doesn’t, but I might have not explained myself entirely. What happens is this - during XR init the current transformation of the current active camera is copied to the XR camera, excluding rotation on the X and Z axes. (So, only Y :wink: ) and position on the Y axis (height of the user is being set, ground is at 0). When leaving the XR session, the xr camera’s transformation is copied to the none-XR camera that becomes active right after.

In between, the canvas is still left attached to the non-VR camera. Any mouse movement or keyboard press will trigger events that will change the camera’s cameraDirection and position delta values (which is how our camera movement works), but as the camera doesn’t render (render loop is ignoring the non-active camera) it accumulates and doesn’t damp at all. detaching the non-vr (and non-active) camera from the canvas seems to do the trick. You can also totally “reset” its movement values, which will have the same effect.

Yep, it does, but with a certain conditions. Check this example:

Open yout console and see the camera’s position when entering and leaving XR. it is the same.

The things that don’t work in your demo are those two:

  1. Y is not being copied when entering XR, since we agree that “0” is ground level. After initialization you can set the camera’s Y to have any offset you like, but during init, if you don’t decide to ignore the transformation init, Y will be set to the player’s height.
  2. The Free camera (the non-VR camera) has a target set. which is 0,0,0. This is why, when leaving the scene on your version of the demo, the camera looks “down”. The position is copied, the rotation is copied, but then the target is applied. Remove the setTarget call, and set the player height correctly, and entering/leaving XR will work as you expect.

I’d forgotten about the Y offset for XR.

I think I’m homing in what I want it to do and how to do it.

I’m trying to get the basics down before doing the “good stuff”.

I’ll see how it goes.

Thanks.

2 Likes