Oculus Handで手の甲の位置にMeshを生成する【Oculus,VR,Unity】

ハンドトラッキングをしたときにいろいろ処理を行う中で,手の甲の平面部分を使い部分があったためデバック用に 表示させたいと思います.

Demo

f:id:ayousanz:20201121212315g:plain

環境

  • Unity 2019.1.14
  • OOculus Integration 20.1

Pinchしたかどうかを取得する

方法としては以下の二つがあると思います.

  • OVRHand.GetFingerIsPinching(OVRHand.HandFinger.~) を使う
  • OVRHand.GetFingerPinchStrength(OVRHand.HandFinger.Index)を使う

OVRHand.GetFingerIsPinching(OVRHand.HandFinger.~)

指が現在ピンチ操作をしているかどうかを検出します.

OVRHand.GetFingerPinchStrength(OVRHand.HandFinger.Index)

現在ピンチ操作している指の強さをチェックします.

手の甲のボーンのそれぞれの位置を取得する.

各手のボーンのID(int)は以下のように設定されています. 公式サイトはこちら(以下はOVRSkelton.csの内部より引用)

       Invalid                 = OVRPlugin.BoneId.Invalid,

        Hand_Start              = OVRPlugin.BoneId.Hand_Start,
        Hand_WristRoot          = OVRPlugin.BoneId.Hand_WristRoot,          // root frame of the hand, where the wrist is located
        Hand_ForearmStub        = OVRPlugin.BoneId.Hand_ForearmStub,        // frame for user's forearm
        Hand_Thumb0             = OVRPlugin.BoneId.Hand_Thumb0,             // thumb trapezium bone
        Hand_Thumb1             = OVRPlugin.BoneId.Hand_Thumb1,             // thumb metacarpal bone
        Hand_Thumb2             = OVRPlugin.BoneId.Hand_Thumb2,             // thumb proximal phalange bone
        Hand_Thumb3             = OVRPlugin.BoneId.Hand_Thumb3,             // thumb distal phalange bone
        Hand_Index1             = OVRPlugin.BoneId.Hand_Index1,             // index proximal phalange bone
        Hand_Index2             = OVRPlugin.BoneId.Hand_Index2,             // index intermediate phalange bone
        Hand_Index3             = OVRPlugin.BoneId.Hand_Index3,             // index distal phalange bone
        Hand_Middle1            = OVRPlugin.BoneId.Hand_Middle1,            // middle proximal phalange bone
        Hand_Middle2            = OVRPlugin.BoneId.Hand_Middle2,            // middle intermediate phalange bone
        Hand_Middle3            = OVRPlugin.BoneId.Hand_Middle3,            // middle distal phalange bone
        Hand_Ring1              = OVRPlugin.BoneId.Hand_Ring1,              // ring proximal phalange bone
        Hand_Ring2              = OVRPlugin.BoneId.Hand_Ring2,              // ring intermediate phalange bone
        Hand_Ring3              = OVRPlugin.BoneId.Hand_Ring3,              // ring distal phalange bone
        Hand_Pinky0             = OVRPlugin.BoneId.Hand_Pinky0,             // pinky metacarpal bone
        Hand_Pinky1             = OVRPlugin.BoneId.Hand_Pinky1,             // pinky proximal phalange bone
        Hand_Pinky2             = OVRPlugin.BoneId.Hand_Pinky2,             // pinky intermediate phalange bone
        Hand_Pinky3             = OVRPlugin.BoneId.Hand_Pinky3,             // pinky distal phalange bone
        Hand_MaxSkinnable       = OVRPlugin.BoneId.Hand_MaxSkinnable,
        // Bone tips are position only. They are not used for skinning but are useful for hit-testing.
        // NOTE: Hand_ThumbTip == Hand_MaxSkinnable since the extended tips need to be contiguous
        Hand_ThumbTip           = OVRPlugin.BoneId.Hand_ThumbTip,           // tip of the thumb
        Hand_IndexTip           = OVRPlugin.BoneId.Hand_IndexTip,           // tip of the index finger
        Hand_MiddleTip          = OVRPlugin.BoneId.Hand_MiddleTip,          // tip of the middle finger
        Hand_RingTip            = OVRPlugin.BoneId.Hand_RingTip,            // tip of the ring finger
        Hand_PinkyTip           = OVRPlugin.BoneId.Hand_PinkyTip,           // tip of the pinky
        Hand_End                = OVRPlugin.BoneId.Hand_End,

twitterで見やすくまとめられている方もいらっしゃるので,公式よりも見やすい?

任意のボーンからメッシュを作成する

以下のサイトを参考にしています.

nn-hokuson.hatenablog.com

インデックスの順番だけ反時計回りにしないと表示されなかったので,注意です

var rightHandMesh = new Mesh
            {
                vertices = new[]
                {
                    rightHandSkeleton.Bones[3].Transform.position,
                    rightHandSkeleton.Bones[6].Transform.position,
                    rightHandSkeleton.Bones[15].Transform.position,
                    rightHandSkeleton.Bones[16].Transform.position
                },
                uv = new[] {new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 0), new Vector2(0, 1),},
                triangles = new[] {0, 1, 2, 1, 3, 2}
            };
            rightReferencePlane.GetComponent<MeshFilter>().sharedMesh = rightHandMesh;
            rightReferencePlane.GetComponent<MeshRenderer>().material = material;
            Debug.Log("基準 right hand planeの作成");