眼球追蹤技術 Unity+ HTC vive Pro + DroolonF1 (二)

本篇將如何開發,如果您喜歡請收藏、點贊、打賞~

博主使用環境:Unity 2018.3.7、   Win 10 x64、 HTC vive Pro

demo下載:下載地址

1.新建Camera

2.ViveSR--Prefabs中拖入預製體SRanipal Eye Framework,默認設置即可

3.ViveSR--Prefabs中拖入預製體 Gaze Ray Sample,調整Length Of Ray的數值,取決於你相機到物體之間的距離

4.新建Canvas,Render Mode改爲 World Space,指定相機

5.在畫布上添加幾個Button,在按鈕上添加Box Collider、 Rigidbody組件,取消重力

6.新建Layer,將Button設置爲新建的Layer

7.自己寫個觸發事件或者Debug測試

8.運行unity ,校準視角,注視button查看效果。

 

PS:事件觸發利用的是Ray射線,這一部分很簡單,自行了解相關知識即可。

相關代碼已經在我上傳的DEMO裏有寫,非常詳細,還有我漢化的備註。就不一一貼出來了。

//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
using System;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace ViveSR.anipal.Eye
{
    public class SRanipal_EyeFocusSample : MonoBehaviour
    {
        public UnityEvent ThereEvent;
        public GameObject CanvasTime;

        public static FocusInfo FocusInfo;//焦點信息
        private readonly float MaxDistance = 100;//最大距離
        private readonly GazeIndex[] GazePriority = new GazeIndex[] { GazeIndex.COMBINE, GazeIndex.LEFT, GazeIndex.RIGHT };//注視 編號 1.結合2.左眼 3.右眼
        private static EyeData eyeData = new EyeData();//眼部 數據
        private bool eye_callback_registered = false;//眼睛回調函數是否被註銷

        private void Start()
        {
            //如果沒有啓用anipal的Eye模塊。報錯停止
            if (!SRanipal_Eye_Framework.Instance.EnableEye)
            {
                enabled = false;
                return;
            }


        }


        private void Update()
        {
            //檢查是否啓用anipal的Eye模塊的狀態是否處於工作狀態或者支持狀態 
            if (SRanipal_Eye_Framework.Status != SRanipal_Eye_Framework.FrameworkStatus.WORKING &&
                SRanipal_Eye_Framework.Status != SRanipal_Eye_Framework.FrameworkStatus.NOT_SUPPORT) return;


            //使用回調獲取數據 並且 回調事件沒有被註銷
            if (SRanipal_Eye_Framework.Instance.EnableEyeDataCallback == true && eye_callback_registered == false)
            {
                SRanipal_Eye.WrapperRegisterEyeDataCallback(Marshal.GetFunctionPointerForDelegate((SRanipal_Eye.CallbackBasic)EyeCallback));
                eye_callback_registered = true;
            }

            //註銷事件
            else if (SRanipal_Eye_Framework.Instance.EnableEyeDataCallback == false && eye_callback_registered == true)
            {
                SRanipal_Eye.WrapperUnRegisterEyeDataCallback(Marshal.GetFunctionPointerForDelegate((SRanipal_Eye.CallbackBasic)EyeCallback));
                eye_callback_registered = false;
            }

            //調用眼部事件
            foreach (GazeIndex index in GazePriority)
            {
                Ray GazeRay;//發射射線
                //int dart_board_layer_id = LayerMask.NameToLayer("NoReflection");//獲取眼部注視的物體層級序號

                bool eye_focus;//眼部註冊 bool

                //請求回調事件(返回序號【結合 左  右】返回射線 集中點信息 )
                if (eye_callback_registered)
                    //向所有觸發器發射 射線
                    eye_focus = SRanipal_Eye.Focus(index, out GazeRay, out FocusInfo, 0, MaxDistance, eyeData);//左右眼、返回射線、射線信息、角度、距離、眼部信息(幀率等)
                else
                    eye_focus = SRanipal_Eye.Focus(index, out GazeRay, out FocusInfo, 0, MaxDistance);

                //啓用眼部追蹤開關
                if (eye_focus)
                {
                    if (FocusInfo.collider.gameObject.tag == "CanvasUI")
                    {
                        addTime += Time.deltaTime;

                        CanvasTime.SetActive(true);
                        CanvasTime.transform.position = FocusInfo.collider.gameObject.transform.position;
                        CanvasTime.GetComponent<Image>().fillAmount += Time.deltaTime / 3;

                        if (addTime >= 3f)
                        {
                            ThereEvent.Invoke();//執行事件

                            addTime = 0f;
                            CanvasTime.SetActive(false);
                            CanvasTime.GetComponent<Image>().fillAmount = 0;
                        }

                    }
                    else
                    {
                        addTime = 0f;
                        CanvasTime.SetActive(false);
                        CanvasTime.GetComponent<Image>().fillAmount = 0;
                    }

                }
            }
        }

        float addTime = 0f;//倒計時


        private void Release()
        {
            if (eye_callback_registered == true)
            {
                SRanipal_Eye.WrapperUnRegisterEyeDataCallback(Marshal.GetFunctionPointerForDelegate((SRanipal_Eye.CallbackBasic)EyeCallback));
                eye_callback_registered = false;
            }
        }
        private static void EyeCallback(ref EyeData eye_data)
        {
            eyeData = eye_data;
        }

    }
}

下一篇我們 寫 英偉達最新的VRS,通過改變幀的不同區域的着色速率來提高渲染性能和質量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章