デコシノニッキ

デコシノニッキ

ホロレンジャーの戦いの記録

MRTKの視線サンプルとAPI周りを覗く

MRKTのNewVersionがプレリリースされました

その中で視線や手の入力に関して先んじて実装が進んでいたようなので調べてみました

WindowsMixedRealityEyeGazeDataProvider.csにその気になる実装があります

Update文

            SpatialPointerPose pointerPose = SpatialPointerPose.TryGetAtTimestamp(WindowsMixedRealityUtilities.SpatialCoordinateSystem, PerceptionTimestampHelper.FromHistoricalTargetTime(DateTimeOffset.Now));
            if (pointerPose != null)
            {
                var eyes = pointerPose.Eyes; //<-ここ
                if ((eyes != null) && (eyes.Gaze.HasValue))
                {
                    Ray newGaze = new Ray(WindowsMixedRealityUtilities.SystemVector3ToUnity(eyes.Gaze.Value.Origin), WindowsMixedRealityUtilities.SystemVector3ToUnity(eyes.Gaze.Value.Direction));

                    if (SmoothEyeTracking)
                    {
                        newGaze = SmoothGaze(newGaze);
                    }

                    MixedRealityToolkit.InputSystem?.EyeGazeProvider?.UpdateEyeGaze(this, newGaze, eyes.UpdateTimestamp.TargetTime.UtcDateTime);
                }
            }

SpatialPointerPose.TryGetAtTimestampからSpatialPointerPoseが取得でき,その中にEyesが格納されているようです。

4/11日時点ではまだ,ドキュメントは更新されていないようです。
docs.microsoft.com

べた書きしているあたり,UnityではアイトラのAPIを提供する訳ではないようですね。

API

今回は検証にあたってWindows SDK 18362を入れています。(現行の最新版は17763)
で,実際にAPIを叩いてどんなサジェスチョンがでるかといったらざっとこんなもんでした。

            var eyes = pose.Eyes;

            bool 利用可能フラグ  = eyes.Gaze.HasValue;
            SpatialRay レイ     = eyes.Gaze.Value;
            Vector3 開始地点 = レイ.Origin;
            Vector3 向き     = レイ.Direction;

            bool キャリブレーションが有効か = eyes.IsCalibrationValid;
            PerceptionTimestamp タイムスタンプ = eyes.UpdateTimestamp;

とれるのは本当に生データのみで,MRTKではそれらを使いやすいようにカスタマイズしてくれています。

サッケード

視線解析では有名ですね。サッカードとも言ったり言わなかったり。
視線が跳躍する現象のことを言います。

        private bool IsSaccading(Ray rayOld, Ray rayNew)
        {
            Vector3 v1 = rayOld.origin + rayOld.direction;
            Vector3 v2 = rayNew.origin + rayNew.direction;

            //前の視点と今の視点の単位時間あたりの変量が,
            //閾値(MRTKでは2.5度しているみたいです)を超えるかどうか
            if (Vector3.Angle(v1, v2) > saccadeThreshInDegree)
            {
                Vector2 hv1 = new Vector2(v1.x, 0);
                Vector2 hv2 = new Vector2(v2.x, 0);
                if (Vector2.Angle(hv1, hv2) > saccadeThreshInDegree)
                {
                    Post_OnSaccadeHorizontally();
                }

                Vector2 vv1 = new Vector2(0, v1.y);
                Vector2 vv2 = new Vector2(0, v2.y);
                if (Vector2.Angle(vv1, vv2) > saccadeThreshInDegree)
                {
                    Post_OnSaccadeVertically();
                }

                Post_OnSaccade(); 

                return true;
            }
            return false;
        }

        //メンバでpublicで定義されているので拾うことができます
        public event Action OnSaccade;
        public event Action OnSaccadeX;
        public event Action OnSaccadeY;

サンプル

基本的にはGazeっぽい使い方になっています。
視線トラッキングのほうはEyeGazeとして区別しています。

f:id:haikage1755:20190411014508g:plain

面白かったのがこのスクロール表現。画面端に視線を向けるとスクロールする機能です。
これは実際やってみないと利便性はまだ判断できないですね。

f:id:haikage1755:20190411015301g:plain

それでこれも視線解析のお供,ヒートマップ。とりあえず可視化してって言われるとまずこれ。
レコーディングからリプレイ機能まで用意されているので,お仕事利用でも試す分にはすぐ始められてよいんじゃないでしょうか。 とはいえ3次元での記録はどうするのかはもうちょっと考える必要がありそうです。ARだとまずメッシュを貼るところからなので・・・

f:id:haikage1755:20190411015432g:plain

[デコシノニッキ]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」