CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

Babylon.jsのWebXRでplayerの位置を調整する方法

Babylon.jsでは、CameraのAPIを使うことでコンテンツの表示位置を決めることができます。

しかし、WebXRを使う場合、このcameraの位置が反映されません。そこで、今回はWebXRで作ったコンテンツがimmersive-vrモードになったときのPlayerの位置を指定する方法をまとめました。

動作はOculus Quest2 (28.0.0.221)、およびMacOSのFirefox (88.0.1) で確認しています。

1. WebXRを使わないときのCamera位置

doc.babylonjs.com

たとえば、このように書くことでGC空間でのカメラの位置を指定できます。

// Parameters : name, position, scene
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);

または、camera.positionの値を変更します。以下はcamera.positionの値を変更した場合です。

An example of camera position value on Babylon.js

Babylon.jsでWebXRコンテンツを作るときは、以下のコードを書くのが簡単な方法です。

    var xr = await scene.createDefaultXRExperienceAsync({
      //  xrInput: defaultXRExperience.input,
        floorMeshes: [environment.ground] /* Array of meshes to be used as landing points */
    });

これを書くことで、対応デバイスで表示すればimmersive-vr, immersive-arモードに遷移させることができます。しかし、先ほどのカメラ位置を変更してもimmersive-vrモードでは位置が変わりません。

2. WebXRのbaseExperienceを使うことで、immersive-vrモードでのカメラ位置を変更する

いろいろ調べましたが、このように書くことで変更できます。

gist.github.com

Playground (気軽に動作結果を試せるWebサービス)にサンプルコードをおきました。

https://www.babylonjs-playground.com/#W9IVC9#7

なお、公式ドキュメントにはWebXRCameraの説明があり、immersiveモードになったときに今のカメラ位置を反映できるとあります。

When entering XR you might want to duplicate the Non-XR camera's position and use it as the base position of the XR Camera. To do that you will need to find the absolute transformation of the old camera and apply it to the new one. Babylon allows you to do that with a single function of the XR Camera:

引用元:The WebXR Camera | Babylon.js Documentation

しかし、

xrCamera.setTransformationFromNonVRCamera(otherCamera);

の辺りを試したのですがうまくいきませんでした。

3. おわりに

WebXRの書き方はいくつかあるので、他の方法もあると思います。何かわかったら追記します。