Oculus에서 Leapmotion의 HandController 활용

12015 단어 LeapMotionUnityC#
Leapmotion의 OVR 프레젠테이션 원고의 내용을 조금만 바꾸면 Oculus에서 보이는 화면에 Leapmotion 추적의 손을 간단하게 표시할 수 있다.
하지만 손의 위치나 손의 상태에 따라 움직이거나 움직이는 것만으로는 부족하다.
이런 경우Leap.Controller는 적당한 이용류가 필요하다.
실제 제작된 샘플은 이런 느낌↓

Cube는 오른손, Sphere는 왼손의 위치를 나타냅니다.
Oculus에 Leapmotion을 부착해 손으로 위에 올려놓으면 실제 손의 위치에 가까운 느낌으로 대상을 이동시킨다.
여기 있습니다이번에 만든 샘플은 GiitHub입니다..
(SampleFiles 디렉토리의 Main 장면은 위 내용)

샘플 코드


다음은 Leapmotion 프레젠테이션의 손 위치와 대체로 동일하게 수정된 동작입니다.
위의 애니메이션 Gif 디스플레이 코드입니다.
(자신이 이용하는 환경, 규모, 체감치가 많이 포함되어 있기 때문에 이런 느낌으로 수정하는 것이 좋습니다. 참고해주세요)
using UnityEngine;
using System.Collections;
using Leap;

public class LeapControllerSample : MonoBehaviour {

    [SerializeField] GameObject m_leftTarget;
    [SerializeField] GameObject m_rightTarget;
    [SerializeField] bool m_isHeadMounted = true;

    Controller leap;
    float moveScale = 0.5f;

    void Start() {
        // Leap Controllerを生成
        leap = new Controller();

        // Optimize for top-down tracking if on head mounted display.
        Controller.PolicyFlag policy_flags = leap.PolicyFlags;
        if (m_isHeadMounted) {
            policy_flags |= Controller.PolicyFlag.POLICY_OPTIMIZE_HMD;
        }
        else {
            policy_flags &= ~Controller.PolicyFlag.POLICY_OPTIMIZE_HMD;
        }

        leap.SetPolicyFlags(policy_flags);
    }

    // LeapのVectorからUnityのVector3に変換
    Vector3 ToVector3(Vector v) {
        return new Vector3(v.x, v.y, v.z);
    }

    // ヘッドトラッキングモード時のLeapのVectorを
    // 視点位置とリンクするよう変換する
    Vector3 ConvertPosition(Vector v) {

        Vector3 pos = ToVector3(v);

        // Normalize to range of -1 to 1
        pos *= 2;
        pos -= Vector3.one;

        // Convert to the Unity coordinate.
        // Leap has especial coordinates, 0s are left, bottom and back.
        // Also See `IntaractionBox coordinates`.
        float tmp = pos.z;
        pos.x  = -pos.x;
        pos.z  = pos.y;
        pos.y  = -tmp;
        return pos;
    }

    void Update() {

        Frame frame = leap.Frame();
        InteractionBox interactionBox = frame.InteractionBox;
        HandList hands = frame.Hands;

        for (int i = 0; i < frame.Hands.Count; i++) {
            // 左手
            if (frame.Hands[i].IsLeft) {
                Vector normalizedPosition = interactionBox.NormalizePoint(frame.Hands[i].PalmPosition);

                Vector3 handPosition = ConvertPosition(normalizedPosition);

                // 変換した位置を実際に利用するスケールなどに応じて係数を掛ける
                handPosition.z -= 2.0f;
                handPosition *= moveScale;

                m_leftTarget.transform.position = handPosition;
            }
            // 右手
            else if (frame.Hands[i].IsRight) {
                Vector normalizedPosition = interactionBox.NormalizePoint(frame.Hands[i].PalmPosition);

                Vector3 handPosition = ConvertPosition(normalizedPosition);

                // 変換した位置を実際に利用するスケールなどに応じて係数を掛ける
                handPosition.z -= 2.0f;
                handPosition *= moveScale;

                m_rightTarget.transform.position = handPosition;
            }
        }
    }
}

IntaractionBox


LeapmotionIntaractionBox이라는 개념에서 추적한 손의 위치를 수치로 변환한다.
문서에서 이미지를 인용하면 다음과 같은 이미지입니다.

왼쪽 후방 아래쪽(0, 0, 0)의 위치로 오른쪽, 위, 앞으로 이동하면 각 수치가 아래쪽1으로 올라간다.
샘플 코드에서는 이 문제를 고려해 손을 눈 중앙에 놓고 좌우로 이동할 때-1〜1 사이를 수정했다.(ConvertPosition 방법)

좋은 웹페이지 즐겨찾기