読者です 読者をやめる 読者になる 読者になる

ForgeVision Engineer Blog

フォージビジョン エンジニア ブログ

視線追跡型VRゴーグル 「FOVE0」を試してみたお話 [サンプルプロジェクト調査編]

こんにちは! VR事業部の長谷川(id:waffle_maker)です。 前回はFOVE0の開封と準備でしたが、今回はUnityを使って色々と動かしてみます。

まずはキャリブレーションを実行

FOVEとPCを接続してランタイムを起動します。FOVEとPCは、HDMIケーブル1本、USBケーブル2本で接続します。

次に、前回の記事で記載した通り、タスクトレイにあるFOVE VRアイコンを右クリックし、「設定ツールの起動」を選択します。

f:id:waffle_maker:20170503060557p:plain

FOVEが接続されると上の画像の赤枠で囲んだ部分は、「ランタイムの停止」になっています。 もし、「ランタイムの開始」になっている場合は、ランタイムがまだ起動していないので、この場所をクリックして起動させます。

この状態でFOVEをかぶると、キャリブレーションを実行する画面が出ます。 キャリブレーションでは、目の前に出てくる緑色の球がゆっくり移動するので、それに合わせて視線を動かします。 1分程度で終わり、「キャリブレーションに成功しました。」という文字が出ると完了です。

Unity向けファイルは3種類

2017/05/03時点で、FOVEのDeveloperページには、Unityに関するファイルが3種類あります。

f:id:waffle_maker:20170503061322p:plain

以下、個別に解説します。

[1] Unityで作られたアプリケーション「EXAMPLE_CONTENT」を確認

まずは、EXAMPLE CONTENT というリンクをクリックして、サンプルアプリケーションを試してみます。 FOVEを接続してからexeを実行すると、このような画面が出ます。

f:id:waffle_maker:20170412194954j:plain

これは、部屋の中で視線の動きだけでライトを点灯、消灯させるデモです。

画像の中心にある緑色とピンク色の球が、自分の左右の眼の動きに合わせて動きます。壁にある小さな水色の球がスイッチです。

視線を動かし、緑かピンクの球を壁のスイッチに当てると、ライトが点灯します。もう一度当てると消灯します。

部屋の中の移動はできませんが、ポジショントラッキングカメラがあるので、そばに置いてあるテーブルに近づくことは可能です。

なお、ポジショントラッキングカメラは、OSVR1.3に付属していたカメラと同一ハードウェアでした。

[2] Unityのサンプルプロジェクト「UNITY_EXAMPLE」を確認

Unity5.5以上という指定があるので、先にver 5.5以降のUnityをインストールしておきます。

サンプルプロジェクトをUnityで開くと、このようなWarningが出ます。

f:id:waffle_maker:20170503055955p:plain

ここで、ContinueをクリックするとUnityが開きます。 ただし、下記のWarningが出ています。

f:id:waffle_maker:20170503061415p:plain

これらの原因は不明ですが、FOVEを動作させることができたので詳細は未調査です。

では、サンプルシーンを解説します。 SampleSceneというシーンを開くと、このような画面になります。

f:id:waffle_maker:20170503060224p:plain

Hierarchy ViewにあるSceneと書かれているオブジェクトは、部屋のモデルを集めたものです。

Fove Rigの子オブジェクトである、Fove Interfaceオブジェクトおよびコンポーネントが処理の中心です。

Fove Interfaceコンポーネントは、FOVEで視線入力を検出すると、FoveInterface.IsLookingAtColliderというメソッドで検出したことを通知します。 例えば、視線で見つめたものを変化させたいときは、変化させたいオブジェクトでFoveInterface.IsLookingAtColliderを呼ぶことで、視線入力を知ることができます。

今回のデモでは、部屋にあるCubeオブジェクトにアタッチされているFove Look Sampleスクリプトが、FoveInterface.IsLookingAtColliderを呼んでいます。

f:id:waffle_maker:20170503060433p:plain

視線で見つめるとCubeが光る処理は下記の通りです。

/* FOVELookSample .csの一部*/
    // Update is called once per frame
    void Update () {
        if (FoveInterface.IsLookingAtCollider(my_collider))
        {
            if (light_enabled)
            {
                l.enabled = true;
                m.SetColor("_EmissionColor", l.color);
                DynamicGI.SetEmissive(GetComponent<Renderer>(), l.color);
                m.EnableKeyword("_EMISSION");
            }
            //bool check = FoveInterface.IsLookingAtCollider(my_collider);
        } else
        {
            gameObject.GetComponent<Renderer> ().material.color = Color.white;
            //GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
            m.DisableKeyword("_EMISSION");
            if (light_enabled)
            {
                l.enabled = false;
                DynamicGI.SetEmissive(GetComponent<Renderer>(), Color.black);
            }
        }
    }

また、Fove Interfaceの子オブジェクトには、SphereLeftとSpeherRightというオブジェクトがあり、ここにアタッチされているスクリプトにより Sphereオブジェクトの位置を検出することができます。

/* FOVE3DCursorLeft .csの一部*/
    void Update() {
        FoveInterface.EyeRays rays = FoveInterface.GetEyeRays();

        // TODO: calculate the convergence point in FoveInterface

        // Just hack in to use the left eye for now...
        RaycastHit hit;
        Physics.Raycast(rays.left, out hit, Mathf.Infinity);
        if (hit.point != Vector3.zero) // Vector3 is non-nullable; comparing to null is always false
        {
            transform.position = hit.point;
        }
        else
        {
            transform.position = rays.left.GetPoint(3.0f);
        }
    }

なお、現状のサンプルプロジェクトを調べた限りでは、FoveInstanceクラスのAPIは視線入力の結果を取得するget系の関数のみであり、何らかの値を設定するset系の関数は準備されていないため、視線入力の微調整は難しそうという印象を持ちました。

参考までに、FoveInstanceの定義を開いて、APIの一覧を下記に書き出しました。 Fove SDKAPI一覧は、下記に掲載されています。

Fove Unity SDK: Packages

#region Assembly FoveUnityPlugin, Version=0.5.6269.32729, Culture=neutral, PublicKeyToken=null
// <in-memory assembly>
#endregion

using System;
using Fove;

namespace UnityEngine
{
    public class FoveInterface : MonoBehaviour
    {
        public FoveInterface();

        public static EFVR_Eye CheckEyesClosed();
        public static bool CheckSoftwareVersions(out string error);
        public static bool EnsureEyeTrackingCalibration();
        public static string GetClientVersion();
        public static EyeRays GetEyeRays();
        public static GazeConvergenceData GetGazeConvergence();
        public static Vector3 GetHMDPosition();
        public static Quaternion GetHMDRotation();
        public static SFVR_Pose GetLastPose();
        public static Camera GetLeftEyeCamera();
        public static Vector3 GetLeftEyeVector();
        public static Vector3 GetNormalizedViewportPosition(Vector3 pos, EFVR_Eye eye);
        public static Camera GetRightEyeCamera();
        public static Vector3 GetRightEyeVector();
        public static string GetRuntimeVersion();
        [Obsolete("Please use IsEyeTrackingCalibrated instead")]
        public static bool IsCalibrated();
        public static bool IsEyeTrackingCalibrated();
        public static bool IsEyeTrackingCalibrating();
        public static bool IsHardwareConnected();
        public static bool IsHardwareReady();
        [Obsolete("You should get a reference and use the non-static version of this function.")]
        public static bool IsLookingAtCollider(Collider col);
        public static void TareOrientation();
        public static void TarePosition();
        public void ConnectCompositor();
        public void DisconnectCompositor();

        public struct EyeRays
        {
            public Ray left;
            public Ray right;

            public EyeRays(Ray l, Ray r);
        }

        public static class Version
        {
            public const int MAJOR = 1;
            public const int MINOR = 1;
            public const int RELEASE = 1;
        }
    }
}

[3] UnityのSDK「UNITY_PACKAGE」を確認

最後に、unitypackage形式のファイルを確認します。 Unityで新規プロジェクトを作り、unitypackageをインポートすると、先ほどのサンプルプロジェクトでも登場したFoveUnityPluginフォルダのみがAssetsフォルダに展開されます。

unitypackageのみを展開した場合

f:id:waffle_maker:20170503062704p:plain

Unityのサンプルプロジェクトの場合

f:id:waffle_maker:20170503062713p:plain

ざっと見る限りでは、それぞれのFoveUnityPluginフォルダの中身は同じでした。

ただし、視線の動きに合わせてオブジェクトを動かすには、sphereなどの適当なオブジェクトを準備し、[2]のサンプルプロジェクトに入っていたFOVE3DCursorRight.csとFOVE3DCursorLeft.csをアタッチする必要がありますが、これは[2]のみに入っています。 そのため、視線の動きを表示させたいときは、この2つのスクリプトを使う必要があります。

なお、「UNITY_PACKAGE」をダウンロードすると、pdfのマニュアルも同梱されているので、詳細はそちらをご確認ください。

終わりに

今回、一通りの使い方を整理しながら、UnityサンプルプロジェクトだけでなくFOVEのHPで提供されているサンプルアプリも試しました。 コントローラを持たず、首を振らなくても操作ができる視線入力は、VRにおいて新しい入力手段になりそうで、とても可能性を感じました。

一方、弊社で試した限りでは、現状のFOVEは視線認識の精度が不安定なところがあり、開発者キットであるという印象を持ちました。 弊社ではFOVEに限らずVRの案件に広く対応できますので、ご興味あればお気軽にお問い合わせください。