OculusQeust의 핸드 추적을 따기를 시도했습니다.

Oculus Quest의 OVRHand에서 제스처를 취할 수 있을까라고 생각했습니다만, 아무래도 지금은 따기(Pinch) 정도밖에 제공되고 있는 것 같습니다. 거기서 우선은 각 손가락이 따고 있는 것을 어느 정도 알 수 있는지, 따고 있을 때에 손가락과 손가락이 얼마나 떨어져 있는지를 정확하게 알 수 있을까 시험해 보았습니다.

소감


  • 집게 손가락으로 잡았을 때의 정확도는 다른 손가락에 비해 높을 것입니다
  • 손가락과 손가락 사이의 거리가 연속적으로 변할 때 정확도가 높습니다
  • 아직도 지금부터 확장이 있을 것 같다

  • 시도한 것



    손가락으로 따기



    뽑은 상태를 얻을 수 있었을 때에는 손의 색이 바뀌는 프로그램을 만들어 보았습니다.


    한 손가락


  • 뽑았을 때에는 손이 노란색으로 바뀌도록 했습니다.
  • 집게 손가락, 가운데 손가락, 약지, 새끼 손가락으로 바꾸어 시험하고 있습니다만, 모두에서 문제 없게 판정되어 있는 것을 알 수 있습니다.

  • 두 손가락


  • 뽑았을 때에는 손이 보라색(디폴트)으로 바뀌도록(듯이) 했습니다. (즉, 1개로 노란색, 2개로 돌아가도록 하고 있습니다. 하지만, 제대로 한다면, 2개로 다른 색으로 하지 않으면 로스트하고 있는지, 2개로 인식하고 있는지 몰랐습니다 ...)
  • 집게손가락으로 뽑았을 때에 노란색이 되어 있습니다만, 가운데 손가락도 맞추어 뽑으면 보라색이 되어 있는 것을 알 수 있습니다.
  • 다른 손가락으로도 대략 동작하고 있습니다만, 손가락에 따라서는 정밀도가 달게 되는 일이 있는 것 같습니다.
  • 보이고 있는 각도에 의한 것일까라고 느끼고 있습니다만, 집게 손가락 부근의 정밀도가 제일 높게 느꼈습니다.

  • 손가락과 엄지의 거리



    각 손가락과 엄지 사이에 0.0~1.0(0.0이 붙은 값)의 값으로 어느 곳에서 완전히 붙는 곳까지 얻을 수 있습니다. 이 값을 바탕으로 큐브의 크기를 변경 (완전히 달라 붙으면 사라짐) 해 보았습니다.


  • 따지지 않은 상태, 따낸 상태에서의 값은 정확하고, 큐브의 변화는 없는 혹은, 큐브가 완전히 사라진 상태가 됩니다.
  • 연속적으로 변화하고있는 상태라면 자연스러운 변화를 볼 수 있습니다
  • 도중에 손가락을 멈추더라도 추적 흔들림에서 값 (큐브)의 변화를 볼 수 있습니다. 마지막 4초 정도는 손가락을 전혀 움직이고 있지 않습니다만, 큐브의 사이즈가 바뀌고 있는 것을 알 수 있을까 생각합니다.

  • 샘플 코드


    using UnityEngine;
    
    public class Detection : MonoBehaviour
    {
        [SerializeField] private OVRHand ovrHand;
        [SerializeField] private SkinnedMeshRenderer handRenderer;
    
        [SerializeField] private Material on;
        [SerializeField] private Material off;
        [SerializeField] private Transform cube;
    
        private bool _isIndexPinching;
        private bool _isMiddlePinching;
        private bool _isRingPinching;
        private bool _isPinkyPinching;
        private int _pinchingFingerNumber;
    
        void Update()
        {
            _isIndexPinching = ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Index);
            _isMiddlePinching = ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Middle);
            _isRingPinching = ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Ring);
            _isPinkyPinching = ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Pinky);
    
            _pinchingFingerNumber = 0;
            if (_isIndexPinching) _pinchingFingerNumber++;
            if (_isMiddlePinching) _pinchingFingerNumber++;
            if (_isRingPinching) _pinchingFingerNumber++;
            if (_isPinkyPinching) _pinchingFingerNumber++;
    
            // 一本指でピンチしているときだけ on にする
            handRenderer.materials = _pinchingFingerNumber == 1 ? new[] {on} : new[] {off};
    
            // 人差し指のピンチングの強さに応じて cube の scale を変更する
            var strength = ovrHand.GetFingerPinchStrength(OVRHand.HandFinger.Index);
            var scale = 0.075f * (1 - strength);
            cube.localScale = new Vector3(scale, scale, scale);
        }
    }
    
    

    보충


    public enum HandStatus
    {
        HandTracked = (1 << 0), // if this is set the hand pose and bone rotations data is usable
        InputStateValid = (1 << 1), // if this is set the pointer pose and pinch data is usable
        SystemGestureInProgress = (1 << 6), // if this is set the hand is currently processing a system gesture
    }
    

    OVRPlugin 안을 보면 HandStatusSystemGestureInProgress 의 값이 돌로 설정되어 있습니다. 이 사이에 뭔가 들어오는 것이 아닐까 생각됩니다. 또 BoneId 에 있는 코멘트도,
            // add new bones here
    

    그리고 아직 아직 앞으로 다양한 확장이 들어올 것 같다고 느꼈습니다.

    참고



    OculusQuest의 핸드 트래킹에 대해 여러 가지를 살펴 보았습니다.

    좋은 웹페이지 즐겨찾기