6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OculusQuest のハンドトラッキングで指の関節情報などを取得する方法

Last updated at Posted at 2020-01-03

OVRSkelton を利用すると、片手で24箇所の位置(以下の図の球の箇所)が取得できます。
lefthand.jpg

前提

Unity 2019.3.0f3
Oculus Integration 12.0

OVRSkelton.cs について

Oculus Integration でハンドトラッキングする時に追加する、OVRHandTrackingPrefab に最初から設定されているプログラムです。このプログラムが持っている Bones(OVRBoneというクラスのリスト)と、各位置を指し示す BoneId を利用することで、指の関節などの情報を取得します。

この方の記事がわかりやすいです。(この記事を書く前に知りたかった・・・)
https://qiita.com/divideby_zero/items/4949fadb2c60f810b3aa

部位取得の概要

部位 取得箇所数 指定方法の概要
親指 5 付け根側から 0, 1, 2, 3, tip
人差し指 4 付け根側から 1, 2, 3, tip
中指 4 付け根側から 1, 2, 3, tip
薬指 4 付け根側から 1, 2, 3, tip
小指 5 付け根側から 0, 1, 2, 3, tip
手首 2 WristRoot, ForearmStub

部位を指定するBoneIdの詳細

(上の図を見た方が解りやすい)

BoneId 部位の説明
Hand_WristRoot 手の付け根
Hand_ForearmStub 腕でも手に近いところ
Hand_Thumb0 親指の第3関節から手首側に小さな骨があり、その付け根
Hand_Thumb1 親指の第3関節
Hand_Thumb2 親指の第2関節
Hand_Thumb3 親指の第1関節
Hand_ThumbTip 親指の先端
Hand_Index1 人差し指の第3関節
Hand_Index2 人差し指の第2関節
Hand_Index3 人差し指の第1関節
Hand_IndexTip 人差し指の先端
Hand_Middle1 中指の第3関節
Hand_Middle2 中指の第2関節
Hand_Middle3 中指の第1関節
Hand_MiddleTip 中指の先端
Hand_Ring1 薬指の第3関節
Hand_Ring2 薬指の第2関節
Hand_Ring3 薬指の第1関節
Hand_RingTip 薬指の先端
Hand_Pinky0 小指の第3関節から手首側に伸びている骨の付け根
Hand_Pinky1 小指の第3関節
Hand_Pinky2 小指の第2関節
Hand_Pinky3 小指の第1関節
Hand_PinkyTip 小指の先端

外部から値を取得するプログラム

サンプル

using UnityEngine;

public class Hand : MonoBehaviour
{
    [SerializeField] private OVRSkeleton skeleton;

    [SerializeField] private Transform thumb0;
    [SerializeField] private Transform thumb1;
    [SerializeField] private Transform thumb2;
    [SerializeField] private Transform thumb3;
    [SerializeField] private Transform thumbTip;
    [SerializeField] private Transform index1;
    [SerializeField] private Transform index2;
    [SerializeField] private Transform index3;
    [SerializeField] private Transform indexTip;
    [SerializeField] private Transform middle1;
    [SerializeField] private Transform middle2;
    [SerializeField] private Transform middle3;
    [SerializeField] private Transform middleTip;
    [SerializeField] private Transform ring1;
    [SerializeField] private Transform ring2;
    [SerializeField] private Transform ring3;
    [SerializeField] private Transform ringTip;
    [SerializeField] private Transform pinky0;
    [SerializeField] private Transform pinky1;
    [SerializeField] private Transform pinky2;
    [SerializeField] private Transform pinky3;
    [SerializeField] private Transform pinkyTip;

    [SerializeField] private Transform start;
    [SerializeField] private Transform wristRoot;
    [SerializeField] private Transform forearmStub;
    [SerializeField] private Transform maxSkinnable;
    [SerializeField] private Transform end;
    
    void Update()
    {
        thumb0.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb0].Transform.position;
        thumb1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb1].Transform.position;
        thumb2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb2].Transform.position;
        thumb3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Thumb3].Transform.position;
        thumbTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_ThumbTip].Transform.position;

        index1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index1].Transform.position;
        index2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index2].Transform.position;
        index3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Index3].Transform.position;
        indexTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_IndexTip].Transform.position;

        middle1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle1].Transform.position;
        middle2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle2].Transform.position;
        middle3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Middle3].Transform.position;
        middleTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_MiddleTip].Transform.position;

        ring1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring1].Transform.position;
        ring2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring2].Transform.position;
        ring3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Ring3].Transform.position;
        ringTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_RingTip].Transform.position;

        pinky0.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky0].Transform.position;
        pinky1.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky1].Transform.position;
        pinky2.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky2].Transform.position;
        pinky3.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Pinky3].Transform.position;
        pinkyTip.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_PinkyTip].Transform.position;

        wristRoot.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_WristRoot].Transform.position;
        forearmStub.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_ForearmStub].Transform.position;

        start.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_Start].Transform.position;
        // maxSkinnable.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_MaxSkinnable].Transform.position;
        end.position = skeleton.Bones[(int) OVRSkeleton.BoneId.Hand_End].Transform.position;
    }
}

補足

  • Hand_Start、Hand_MaxSkinnable、Hand_End はBoneIdとしては使用されておらず、プログラムを読む限り、Enum の中で値を仕切るために使用されているように見える。
    • このプログラムを実行しても、Hand_Start、Hand_Endの球は表示されることがない。
    • Hand_MaxSkinnable をコメントアウトしているのは、親指の先端と同じ値が設定されているため。コメントを外すと親指の先端箇所に Hand_MaxSkinnable の球が表示される。
  • OVRSkelton の BoneId の enum の中に、 // add new bones here とコメントがあることから、これからまだ何かしらの値を追加していく想定見て取れる。それを見越しての、Hand_Start などなのだと思われる。
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?