Daydreamの6DOFをJavaで扱う

JavaのGoogle VR SDKを使って,Mirage Soloの6DOFを扱った話

Mirage Soloで色々試していますが,6DOFに対応できれば没入感がかなり違うので,対応しました.

GvrApiをどうするか

6DOFをJavaのGoogle VR SDKから扱う場合,

GvrApi.getHeadSpaceFromStartSpaceTransform()

を使うことになるのですが,
GvrApi Google VR

このGvrApiはJavaの場合,GvrLayout から取得する必要があり,アプリの作りによっては対応できませんでした.

例えばSDK付属のサンプル「sdk-treasurehunt」では,無理だと思います.

これで頓挫していました...

それが,最近リリースされた
GVRのバージョン1.170.0

では,GvrViewからGvrApiを取得できるようになりました!

これで希望が見えました.

※9/8時点で,GvrViewのAPIドキュメント
GvrView には未反映ですが,
実装にはgetGvrApi()メソッドが追加されています.

6DOFの実装

マニフェストに,

<uses-feature android:name="android.hardware.vr.headtracking" 

の追加が必要です.
Enabling 6DOF head tracking

Javaの実装としては,GvrApi.getHeadSpaceFromStartSpaceTransform()を呼びだすだけです.

単純化した例ですと,こんな感じです.

final long headOffsetNanos = TimeUnit.MILLISECONDS.toNanos(50);
final float[] headFromWorld = new float[16];

GvrApi gvrApi = gvrView.getGvrApi();
gvrApi.getHeadSpaceFromStartSpaceTransform(
headFromWorld, System.nanoTime() + headOffsetNanos);

得られるheadFromWorldは,変換行列です.

自分の場合は単純にX,Yの移動量が欲しかったので,GvrView.StereoRenderer#onNewFrame()内で上記呼び出しをして,

float headDx = headFromWorld[12];
float headDy = headFromWorld[13];

という感じで平行移動の量だけを取得して使っています.

この移動量を反映して地形の再描画を行うことで,6DOF対応の快適な没入感が得られました.

参考

GvrApi Google VR

SDK doesnot expose user handedness preference for UX-C2 Issue 571

How can i get 6DOF information in android studio project Issue 578

Comment