眼球追踪技术 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,通过改变帧的不同区域的着色速率来提高渲染性能和质量。

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