夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

MRDL Surfacesを学ぶ HandSurface その2

本日はMRDLの[Surfaces]の調査枠です。

前回から[HandSurface]クラスを見ていっています。

前回は[HandSurface]クラスの概要を見ていきました。

redhologerbera.hatenablog.com

本日はLateUpdate関数を見ていきます。

〇LateUpdate

 protected override void LateUpdate()
    {
        base.LateUpdate();

        if (!MixedRealityToolkit.IsInitialized)
            return;

        if (!Initialized)
            return;

        #region hand tracking
  ...
        #endregion
    }
base.LateUpdate();

このbaseとは[HandSurface]クラスの基底クラスである[FingerSurface]を指します。

HandSurfaceのLateUpdate()が実行されるとFingerSurfaceのLateUpdateも同期して実行されます。

 if (!MixedRealityToolkit.IsInitialized)
            return;

        if (!Initialized)
            return;

MixedRealityToolkit.IsInitializedはMRTKのインスタンスが初期化されているかどうかを取得します。

microsoft.github.io

falseの場合、つまり初期化されていない場合処理が終了します。

またBool型変数[Initialized]も[FingerSurface]クラスの変数になります。

こちらもfalseの場合処理が終了します。

     #region hand tracking
        IMixedRealityInputSystem inputSystem = MixedRealityToolkit.Instance.GetService<IMixedRealityInputSystem>();
        IMixedRealityHandJointService handJointService = (inputSystem as MixedRealityInputSystem).GetDataProvider<IMixedRealityHandJointService>();

        int jointIndex = 0;
        // Right hand
        foreach (TrackedHandJoint joint in handJointTypes)
        {
            if (handJointService.IsHandTracked(Handedness.Right))
            {
                Transform jointTransform = handJointService.RequestJointTransform(joint, Handedness.Right);
                handJoints[jointIndex].position = jointTransform.position;
                handJoints[jointIndex].rotation = jointTransform.rotation;
                handJoints[jointIndex].gameObject.SetActive(true);
            }
            else if (!Application.isEditor || disableInactiveFingersInEditor)
            {
                handJoints[jointIndex].gameObject.SetActive(false);
            }
            jointIndex++;
        }

        // Left hand
          ...
        #endregion

ここでは左右のHandTracking情報を取得します。

    foreach (TrackedHandJoint joint in handJointTypes)
        {
            if (handJointService.IsHandTracked(Handedness.Right))
            {
                Transform jointTransform = handJointService.RequestJointTransform(joint, Handedness.Right);
                handJoints[jointIndex].position = jointTransform.position;
                handJoints[jointIndex].rotation = jointTransform.rotation;
                handJoints[jointIndex].gameObject.SetActive(true);
            }
            else if (!Application.isEditor || disableInactiveFingersInEditor)
            {
                handJoints[jointIndex].gameObject.SetActive(false);
            }
            jointIndex++;
        }

foreach文で[handJointTypes]の繰り返し処理が行われます。

この[handJointTypes]とは次のようにMRTKのHandTrackingで取得できるJointのうち[FingerSurface]クラスで定義されている[Tips](先端)を除く各ポイントが定義されています。

   protected TrackedHandJoint[] handJointTypes = new TrackedHandJoint[]
    {
        TrackedHandJoint.ThumbDistalJoint,
        TrackedHandJoint.ThumbMetacarpalJoint,
        TrackedHandJoint.ThumbProximalJoint,

        TrackedHandJoint.IndexDistalJoint,
        TrackedHandJoint.IndexKnuckle,
        TrackedHandJoint.IndexMetacarpal,
        TrackedHandJoint.IndexMiddleJoint,

        TrackedHandJoint.MiddleDistalJoint,
        TrackedHandJoint.MiddleKnuckle,
        TrackedHandJoint.MiddleMetacarpal,
        TrackedHandJoint.MiddleMiddleJoint,

        TrackedHandJoint.RingDistalJoint,
        TrackedHandJoint.RingKnuckle,
        TrackedHandJoint.RingMetacarpal,
        TrackedHandJoint.RingMiddleJoint,

        TrackedHandJoint.PinkyDistalJoint,
        TrackedHandJoint.PinkyKnuckle,
        TrackedHandJoint.PinkyMetacarpal,
        TrackedHandJoint.PinkyMiddleJoint,
    };

右手が検知されている状態では各Jointに関してposition、rotationと非表示になっている場合オブジェクトの有効化が行われています。

    if (handJointService.IsHandTracked(Handedness.Right))
            {
                Transform jointTransform = handJointService.RequestJointTransform(joint, Handedness.Right);
                handJoints[jointIndex].position = jointTransform.position;
                handJoints[jointIndex].rotation = jointTransform.rotation;
                handJoints[jointIndex].gameObject.SetActive(true);
            }
            else if (!Application.isEditor || disableInactiveFingersInEditor)
            {
                handJoints[jointIndex].gameObject.SetActive(false);
            }

[Application.isEditor]は実行されている環境がUnityEditorか実機かを返します。

[disableInactiveFingersInEditor]は定義されているBool型変数で初期状態でTrueになっています。

    [SerializeField]
    protected bool disableInactiveFingersInEditor = true;

手が検知できておらず、UnityEditor上で実行されておらず、かつdisableInactiveFingersInEditorがTrueの場合各Jointを非表示にします。

 これは実機で手が検知されていない場合に行われます。

以上のように[FingerSurface]クラスでは指先のTips、[HandSurface]クラスではその他のJointがそれぞれ検知されています。