English version is here
How to switching mode between WebVR and 2D view in Babylon.js - CrossRoad
Babylon.jsを使うと、以前紹介したようにWebVRコンテンツも開発できます。
Babylon.jsでWindows Mixed Realityヘッドセットのアプリを作る方法 - CrossRoad
WebVRモードにするには、はじめに表示した画面右下のVRヘッドセットマークを選択するだけです。
しかし、VRモードから通常の2Dモードに戻すボタンはありません。そのため、今まではページを再読み込みしていました。また、意外なことに調べても情報が出てきませんでした。
そこで、今回はVRモードから2Dモードに戻す方法を調べました。
動作環境です。
- Chrome : 71.0.3578.98
- Babylon.js : 3.3
- 1. Babylon.js サンプルコードには、VRモード切り替えボタンのソースコードが載っていない
- 2. Chrome Developer Toolで設定されたイベントを読み取る
- 3. Babylon.jsのSearchで使い方を確認する
- 4.実装して動作を確認する
- 5. Tips
- 6. おわりに
1. Babylon.js サンプルコードには、VRモード切り替えボタンのソースコードが載っていない
WebVRモードの最もシンプルなソースコードはこちらです。アクセス後、Zipボタンでhtmlを含む全ソースコードを取得できます。
https://www.babylonjs-playground.com/#VIGXA3#7
取得したindex.htmlには、html <button>
タグがありません。また、Babylon.jsのHPにあるDocumentをみても見つけることができませんでした。 html <button>
はサンプルコードのindex.htmlの中にはなく、babylon.jsから生成されるようです。
2. Chrome Developer Toolで設定されたイベントを読み取る
そこで、Chrome Developer Toolを使って、表示中のWebページからどこで宣言されているかを探しました。下記の記事を参考にさせていただきました。
Chrome上で、その他のツール / デベロッパーツールを選ぶと、Chrome Developer Toolを起動できます。このような画面です。
今回、WebVRボタンが押された時のイベントを読み取りたいので、画面の1〜5のように進めました。
1 : 画面の要素を選択できるようにする
2 : WebVRボタンを選択
3: Event Listenerを選択
4 : Clickイベントを選択
5: handlerを右クリック
ここで、Show function definition を選択すると、イベントハンドラと紐づいたソースコードが表示されます。
ここで、enterVR()、exitVR()というメソッドを発見できました。
3. Babylon.jsのSearchで使い方を確認する
Babylon.jsのHPは、全てのページの右上にSearchエリアがあります。
それぞれのメソッドを調べた結果、VRExperienceHelperのメソッドであることがわかりました。
4.実装して動作を確認する
最低限のコードを下記に置きました。
BJS_SwitchToNormal_WebVR/index.html at master · flushpot1125/BJS_SwitchToNormal_WebVR · GitHub
これは、360Photoのサンプルをベースとして、WebVRのコードを追加し、さらにActionManagerによってキーイベントで動くようにしています。
参考
How to do 360 Photo - Babylon.js Documentation
Use the WebVR experience helper - Babylon.js Documentation
Use Actions - Babylon.js Documentation
サンプルコードでは、キーボードの"s"でWebVRモードに移動、"e"でノーマルモードに移動(=WebVRモード終了)としています。動きは以下の動画の通りです。
5. Tips
5.1 enterVR()は、イベントリスナー系の中で呼ばないとエラーが出る
たとえば、こんなコードを書くとfullscreen errorが出ます。
var map = {}; //object for multiple key presses scene.actionManager = new BABYLON.ActionManager(scene); // for key event scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyDownTrigger, function (evt) { map[evt.sourceEvent.key] = evt.sourceEvent.type == "keydown"; })); // scene.registerAfterRender(function () { if (map["S"] ) {// pushed key "S" vrHelper.enterVR(); }; if (map["E"] ) { // pushed key "E" vrHelper.exitVR(); }; });
Uncaught (in promise) TypeError: fullscreen error at Function.e.RequestFullscreen (babylon.js:16) at e.enterFullscreen (babylon.js:16) at e.enterVR (babylon.js:16) at Object.callback ((index):124) at e.notifyObservers (babylon.js:16) at t.render (babylon.js:16) at (index):166 at e._renderLoop (babylon.js:16)
VRモードになり、両眼表示にはなるのですがフルスクリーンになりません。色々試したところ、ActionManagerというイベントハンドラと組み合わせることでRequestFullscreenを呼ぶことができました。
5.2 exitVR()を呼ぶだけではフルスクリーンを解除できない
これも色々試したところ、exitFullscreen()を一緒に呼ぶことで解決しました。
6. おわりに
fullscreen関係のAPIは、Babylon.jsというよりHTML5の仕様なのですが、enterVRやexitVRの中ですでに呼ばれてしまっていたので解決策がわからず、思ったより時間がかかりました。
ひとまずこれで、WebVRと2D Viewの切り替えが簡単になりました。次回はOculus GoでWebVRを表示したり、コントローラを扱う方法を書いてみる予定です。