CrossRoad

AR、MR、VR、Babylon.jsを中心とした技術ブログ。 If you're non-Japanese native guys, check "English" category.

Babylon.jsでglb形式の建物モデルを読み込み、Oculus Questでテレポート移動させる方法

Babylon.jsでOculus Questのコントローラ入力の方法がわかってきたので、今度はテレポート移動を試してみました。

このようになります。

今回はこのテレポート移動を実現するための方法だけでなく、表示した博物館のモデルを読み込む手順も書きました。  

1. 建物の3Dモデルを入手する

今回はここの「The Entryway - Museum Diorama」を使わせていただきました。

https://poly.google.com/view/9bdkTVw8GE8

このモデルの形式はobjとusdz(iOS向け)です。今回はobj形式をダウンロードしました。なお、このモデルはマテリアルで直接色指定しており、テクスチャは使っていません。

2. objをglb形式に変換する

取得したモデルをbabylon.jsのimportMeshAsyncで読み込みます。

glb変換はBlender2.8(2.79ではありません)を使います。

なお、importMeshAsyncはobj読み込みにも対応していますが、objのままとglb変換した場合で比較するといくつか違っていました。(ソースコードは変えてません)

(1) 色合いが異なる

このようになります。

The same model data as obj and glb in bjs

glbの方が公開されている見本と色合いが近い感じがしました。

なお、objでは飛行機のおもちゃのモデルが表示されてませんが、これはobjとglbで開始時点のカメラ位置が変わったためです。なぜ変わったかは不明です。

(2) 容量

理由は調べてませんが、objからglb変換したことで10%程度容量が減りました(3.1 →2.8MB)。

(3) パフォーマンス

VRモードのときにFPSを表示できるようにしてないので体感ですが、objの方がカクツキが多い印象でした。

(2)と(3)があることから、glbを使った方がよいと思います。

3. コードを書く

全体のコードはgithubに置きました。この記事の末尾をご確認ください。

3.1 メッシュを読み込む

このように書きます。ImportMeshAsyncの第2引数がディレクトリ名、第3引数がメッシュのファイル名と覚えておけばとくに難しくありません。

BABYLON.SceneLoader.ImportMeshAsync("", "../model/", "museum_v7.glb", scene).then(function(result) {

   });

3.2 VRの基本設定をする

これを1行書くだけでです。これだけでブラウザ画面にHMDアイコンが表示され、アイコンをクリックするとVRモードになります。

var vrHelper = scene.createDefaultVRExperience();

3.3 テレポートを有効化する

これを1行書きます。 floorMeshNameがkeyで、このvalueにテレポート対象のメッシュの名称(ここでは"floor_primitive1")を指定します。

   vrHelper.enableTeleportation({
       floorMeshName: "floor_primitive1"
    });

なお、現時点では床にしたいメッシュを複数指定する方法が見つけられてません。ダメ元でこのように書いてみましたが、最後に書いたもの(ここでは"stair")しか認識されませんでした。

   vrHelper.enableTeleportation({
       floorMeshName: "floor"
       floorMeshName: "floor_primitive1"
       floorMeshName: "stair"
    });

単にjavascriptの理解が足りてないだけな気がしますが、方法がわかったら追記します。

3.4 コントローラを有効化する

以前書いた内容ですが、このように書きます。

 const leftHand = BABYLON.Mesh.CreateBox("leftHand",0.1, scene);
    leftHand.scaling.z = 2;
    leftHand.isVisible =false;

    const rightHand = BABYLON.Mesh.CreateBox("rightHand",0.1, scene);
    rightHand.scaling.z = 2;
    rightHand.isVisible =false;

enableTeleportation()の中にMain Triggerキーの入力受付処理が入っているので、今回はキー入力をとるコードは不要です。

4. 動作確認する

冒頭の動画のようになります。コントローラから出る光線を床に向け、コントローラのスティックを上方向にずらすと、テレポート先のリングが表示されます。

リングが出てからスティックにかけた指を離すと、その場所にテレポートします。今回テレポート可能な場所は下記の2箇所です。

Example of teleport activated position in babylonjs and oculus quest

5. 完成版のソースコード

ここに置きました。

GitHub - flushpot1125/babylonjs_gui

6. Tips

関係しそうなことを書いておきます。

6.1 importMeshAsyncで読み込んだメッシュを大きくするにはscalingを使用する

例えば、下記のように書くと読み込んだ建物のモデル全体の大きさが2倍になります。

 BABYLON.SceneLoader.ImportMeshAsync("", "../model/", "museum.glb", scene).then(function(result) {
     museumMesh = result.meshes[0].scaling = new BABYLON.Vector3(2,2,2);
   });

6.2 (未解決)scalingで大きくすると、enableTeleportationが効かなくなる

3.3で指定した floorMeshName: "floor_primitive1" があってもテレポートができなくなりました。理由がわかったら追記します。

7. おわりに

VRの基本的なことを1つずつ確認しながら進めてますが、シーンを作って移動までできるとそれっぽく見えますね。

今回メッシュのインポートと同時にGUI Text(空間にテキスト表示)を試していました。次はそれについて書こうと思います。