2019/6/26 追記
デフォルトのTouchコントローラのモデルが残ってしまう問題の解決方法を追記しました。
Babylon.jsでVRコンテンツを作り、VRヘッドセットでアクセスすると、コントローラもVR空間に表示されます。
ただし、5月に発売したばかりのOculus Questでアクセスすると、Oculus Touchのコントローラが表示されます。 (Babylon.js v4.1.0の場合)
そこで、今回はコントローラを別のモデルに差し替える方法をまとめました。
- 1. 前提:コントローラのモデルは、拡張子.babylon形式で格納されている
- 2. コントローラの代わりとなるモデルの調整方法
- 3. コントローラのモデルを差し替える
- 4. 動作確認する
- 5. 現状の問題点
- 6. おわりに
1. 前提:コントローラのモデルは、拡張子.babylon形式で格納されている
通常、Babylon.jsでコンテンツ開発する時、コントローラの指定をコードで書くことはありません。これはBabylon.jsのライブラリ側で定義されているためです。
これを確認するには、上記のGithubからgit cloneしたものを調べます。
assets/mesh/controllers/oculus の中にある、left.babylonとright.babylonがOculus Touchのコントローラです。このように表示されます。
- src/Gamepads/Controllers/oculusTouchController.ts
public initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void) { let meshName; // Hand if (this.hand === 'left') { meshName = OculusTouchController.MODEL_LEFT_FILENAME; // left.babylon } else { // Right is the default if no hand is specified meshName = OculusTouchController.MODEL_RIGHT_FILENAME; //right.babylon } SceneLoader.ImportMesh("", OculusTouchController.MODEL_BASE_URL, meshName, scene, (newMeshes) => { /* Parent Mesh name: oculus_touch_left - body - trigger - thumbstick - grip - button_y - button_x - button_enter */ this._defaultModel = newMeshes[1]; this.attachToMesh(this._defaultModel); if (meshLoaded) { meshLoaded(this._defaultModel); } });
ただし、モデルの読み込みには.glbも対応しています。今回はglb形式のファイルを使いました。
2. コントローラの代わりとなるモデルの調整方法
Blenderのver2.8を使います。2.79ではテクスチャが出力されないためです。以下のswordモデルを使わせていただきました。
これは、以前Babylon.js Editorの使い方紹介でも使いました。
【2018/12/16更新】UnityのようなGUIでWebGLコンテンツが作れるBabylon.js Editorの基本的な使い方 - CrossRoad
2.1 scaleはBlender基本図形のCylinderのscale=0.4程度に合わせる
Blenderで読み込んだら、Cylinderを表示させます。次にswordモデルをインポートします。
VR空間で使用するQuestのコントローラはCylinderよりも少し小さいので、swordの大きさを調節します。ここでは、swordが4つのパーツに分かれています。Lameという剣部分だけ後で使いたいので、それ以外をjoin機能で結合します。
次に、swordのモデルのscaleをx,y,z全て0.015まで下げます。これでだいたいCylinderと同程度になり、Oculus Questで表示しても違和感ないサイズになります。
2.2 swordの柄部分のoriginを変更する
Blenderには、オブジェクトの原点を変更する機能があります。以下の画像に書いた(1)〜(4)に沿って進めます。
(1) OutlinerからCameraとCylinderを削除
(2) 3D cursorを選択 (ver2.79ではデフォルト表示されていましたが、2.80からは矢印アイコンと独立しています)
(3) swordの柄部分を選択
- (4) Origin to 3D Cursorを選択
- (5) Reset All to Default Valuesを選択
これで、Questで表示されるコントローラの位置がswordの柄付近になります。
2.3 glb形式でexportする
BlenderのFile / Export / gltf 2.0 を選択すると、左下に出力設定が表示されます。1つのモデルしか表示していない場合は特に設定変更不要です。
これで、大きさを調整したswordのglbファイルが出力されます。
3. コントローラのモデルを差し替える
作成したモデルをソースコードから参照できる場所に配置し、下記のコードを書きます。
2019/6/26 追記
@YSAIQSさん情報に基づき、コードを修正しました。ありがとうございます。
ふと気になったのですが、AttachをonBeforeRenderObservableに書くと毎フレームごとにAttachされませんか?調べるとコントローラ側のObservableが使えそうです。あと、こちらの環境ではボタン押下でシーンが止まる現象は起きていません。以下は公式サンプルの改変です。文字数https://t.co/EbWym33qVJ
— XEGASY (@YSAIQS) 2019年6月25日
var rightSwordMesh; BABYLON.SceneLoader.ImportMeshAsync("", "filePath", "sword.glb", scene).then(function(result) { rightSwordMesh = result.meshes[0];) });
vrHelper.webVRCamera.onControllersAttachedObservable.add(e => { vrHelper.webVRCamera.rightController.attachToMesh(rightSwordMesh); });
4. 動作確認する
このようになります。
同じように調整することで、Oculus Questのコントローラも表示できます。 Questのコントローラモデルは@mirako_maruchoさんご提供のものを使わせていただきました。
Quest用コントローラ、ざっくりですがUE4で使う方どうぞ。近日中に詳細ブログに書くと思う。たぶんhttps://t.co/Ydh506PpZ9 pic.twitter.com/gApYCQxjhq
— mirako (@mirako_marucho) 2019年6月8日
Oculus Questのコントローラ配布場所
sketchfab.com5. 現状の問題点
(解決)5.1 Oculus Touchのコントローラのモデルが消えない
今回右手側を差し替えましたが、VRモードになった瞬間に元のOculus Touchのコントローラが残ってしまいます。消す方法がわかったら追記します。
2019/6/26 追記
解決しました。以下のコードで消えます。
var vrHelper = scene.createDefaultVRExperience({controllerMeshes:false}); //var vrHelper = scene.createDefaultVRExperience();
createDefaultVRExperience()の引数を空にする、あるいはcontrollerMeshes:trueにすると、デフォルトコントローラのメッシュが表示されます。falseにすると非表示になります。
左右のコントローラのモデルを変更する処理を書いた状態で、controllerMeshesを変更するとこのようになります。
5.2 (解決)ボタンを押すとページが停止する
2019/6/26更新
ボタンを押すと止まっていましたが、これはonBeforeRenderObservable(毎フレーム呼ばれる)の中で呼んでいたためでした。呼び場所を変えることで発生しなくなりました。
しかし、コントローラを別のモデルに変更し、controllerMeshes:falseを使うと、うまくコントローラが表示されません。
また、controllerMeshes:trueにするとボタン入力はできるのですが、デフォルトのOculus Touchコントローラが残ったままになります。
この辺はもう少しBabylonjsの理解が進んだら解決できる気がするので、一旦保留しようと思います。
6. おわりに
最初、attachToMesh関数に気づかず、Babylon.jsのコード自体をビルドして確認していました。例えば、このツイートで表示したときはBabylon.jsのコードをビルドしてから表示させたものです。
#babylonjs を使って、oculus questのコントローラをswordに変えてみました。ついでに少しエフェクトをつけてます。 pic.twitter.com/4pwqJzglZr
— Limes (@WheetTweet) 2019年6月18日
Babylon.jsをビルドすると色々できることも多いので、次回はビルド方法について書く予定です。