高通 Vuforia 最新6-2-10版本 API 动态加载、卸载识别库 闪光灯 对焦 翻转摄像头 动态更改识别数量等

高通 Vuforia 最新6-2-10版本 API 动态加载、卸载识别库 闪光灯 对焦 翻转摄像头 动态更改识别数量 获取识别库名称、路径等
总之标题要长,要醒目,为了赚金币大笑大笑大笑


这两天整理了下高通最新的demo 对新版的函数整合了下,相关函数已经备注,有不对的地方大家留言相互交流下,不明白的可加QQ195754218


而且最近我一直在寻找能把动态创建的DataSet和对应的xml保存到本地方便下次加载的办法,如果有大佬知道求科普~不生感谢


话不多说上代码



using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Vuforia;

/// <summary>
/// 追踪功能设置类
/// </summary>
public class TrackableSettings : MonoBehaviour
{
    public const string Name = "TrackableSettings";
    static TrackableSettings() { }
    protected TrackableSettings() { }
    protected static volatile TrackableSettings instance = null;
    protected readonly object msyncRoot = new object();
    protected static readonly object mstaticSyncRoot = new object();
    public static TrackableSettings Instance
    {
        get
        {
            if (instance == null)
            {
                lock (mstaticSyncRoot)
                {
                    if (instance == null) instance = new GameObject(Name).AddComponent<TrackableSettings>();
                }
            }
            return instance;
        }
    }

    /// <summary>
    /// 识别数据集所在的文件路径
    /// </summary>
    private string dataSetDirectoryPath = null;

/// <summary>
/// 已经激活的识别数据集
/// </summary>
    protected Dictionary<string, string> mCurrentActiveDataSets = new Dictionary<string, string>();
    /// <summary>
    /// 所有数据集对应的路径
    /// </summary>
    protected Dictionary<string, string> mCurrentAllDataSets = new Dictionary<string, string>();
    /// <summary>
    /// 是否使用本地内置识别库
    /// </summary>
    public bool bLocal = false;
    /// <summary>
    /// 扩展追踪是否开启
    /// </summary>
    protected bool mExtTrackingEnabled = false;


    private void Awake()
    {
        //if (m_instance == null) m_instance = this;

        //if (gameObject.name == "GameObject") gameObject.name = Name;
    }

    private void Start()
    {
        Initialize();
    }

    private void Initialize()
    {
        dataSetDirectoryPath = Application.persistentDataPath + "/" + "DataDirectory"+"/";

        if (!Directory.Exists(dataSetDirectoryPath))
        {
            Directory.CreateDirectory(dataSetDirectoryPath);
        }
    }
    /// <summary>
    /// 获得扩展追踪开启状态
    /// </summary>
    /// <returns></returns>
    public bool IsExtendedTrackingEnabled()
    {
        return mExtTrackingEnabled;
    }

    /// <summary>
    /// 开启、关闭扩展追踪模式
    /// </summary>
    /// <param name="extTrackingEnabled">是否开启</param>
    public virtual void SwitchExtendedTracking(bool extTrackingEnabled)
    {
        //返回可以访问当前所有跟踪的状态管理器实例。
        StateManager stateManager = TrackerManager.Instance.GetStateManager();

        // 我们遍历所有trackablebehaviours启动或停止扩展跟踪他们所代表的目标。
        bool success = true;
        foreach (var tb in stateManager.GetTrackableBehaviours())
        {
            if (tb is ImageTargetBehaviour)
            {
                ImageTargetBehaviour itb = tb as ImageTargetBehaviour;
                if (extTrackingEnabled)
                {
                    if (!itb.ImageTarget.StartExtendedTracking())
                    {
                        success = false;
                        Debug.LogError("扩展跟踪开始失败,对应目标: " + itb.TrackableName);
                    }
                }
                else
                {
                    itb.ImageTarget.StopExtendedTracking();
                }
            }
            else if (tb is MultiTargetBehaviour)
            {
                MultiTargetBehaviour mtb = tb as MultiTargetBehaviour;
                if (extTrackingEnabled)
                {
                    if (!mtb.MultiTarget.StartExtendedTracking())
                    {
                        success = false;
                        Debug.LogError("Failed to start Extended Tracking on Target " + mtb.TrackableName);
                    }
                }
                else
                {
                    mtb.MultiTarget.StopExtendedTracking();
                }
            }
            else if (tb is CylinderTargetBehaviour)
            {
                CylinderTargetBehaviour ctb = tb as CylinderTargetBehaviour;
                if (extTrackingEnabled)
                {
                    if (!ctb.CylinderTarget.StartExtendedTracking())
                    {
                        success = false;
                        Debug.LogError("Failed to start Extended Tracking on Target " + ctb.TrackableName);
                    }
                }
                else
                {
                    ctb.CylinderTarget.StopExtendedTracking();
                }
            }
            else if (tb is ObjectTargetBehaviour)
            {
                ObjectTargetBehaviour otb = tb as ObjectTargetBehaviour;
                if (extTrackingEnabled)
                {
                    if (!otb.ObjectTarget.StartExtendedTracking())
                    {
                        success = false;
                        Debug.LogError("Failed to start Extended Tracking on Target " + otb.TrackableName);
                    }
                }
                else
                {
                    otb.ObjectTarget.StopExtendedTracking();
                }
            }
            else if (tb is VuMarkBehaviour)
            {
                VuMarkBehaviour vmb = tb as VuMarkBehaviour;
                if (extTrackingEnabled)
                {
                    if (!vmb.VuMarkTemplate.StartExtendedTracking())
                    {
                        success = false;
                        Debug.LogError("Failed to start Extended Tracking on Target " + vmb.TrackableName);
                    }
                }
                else
                {
                    vmb.VuMarkTemplate.StopExtendedTracking();
                }
            }
        }
        mExtTrackingEnabled = success && extTrackingEnabled;
    }
    /// <summary>
    /// 获取当前激活识别库名称列表
    /// </summary>
    /// <returns></returns>
    public List<string> GetActiveDatasetNameList()
    {
        ObjectTracker tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        List<DataSet> activeDataSets = tracker.GetActiveDataSets().ToList();
        List<string> tempList = new List<string>();
        for (int i = 0 ; i < activeDataSets.Count ; i++)
        {
            string datasetPath = activeDataSets.ElementAt(i).Path;
            Debug.Log("datasetPath:" + datasetPath);
            string datasetName = datasetPath.Substring(datasetPath.LastIndexOf("/") + 1);
            Debug.Log("datasetName:" + datasetName);
            tempList.Add(datasetName.TrimEnd(".xml".ToCharArray()));
        }
        return tempList;
    }
    /// <summary>
    /// 激活指定的识别数据集
    /// </summary>
    /// <param name="datasetName">数据集名称或绝对路径</param>
    public virtual void ActivateDataSet(string datasetName)
    {
        if (mCurrentActiveDataSets.ContainsKey(datasetName))
        {
            Debug.Log(string.Format("要激活的识别库:{0}已经加载", datasetName));
            return;
        } 

        // objecttracker跟踪包含在数据集,提供了用于创建和方法的激活数据。
        ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        IEnumerable<DataSet> datasets = objectTracker.GetDataSets();

        IEnumerable<DataSet> activeDataSets = objectTracker.GetActiveDataSets();
        List<DataSet> activeDataSetsToBeRemoved = activeDataSets.ToList();

        // 1. 循环遍历所有的活动数据集并禁用它们
        foreach (DataSet ads in activeDataSetsToBeRemoved)
        {
            objectTracker.DeactivateDataSet(ads);
        }

        // 在ObjectTracker运行时,不应该对数据集进行交换
        // 2. 所以首先要关闭tracker
        objectTracker.Stop();

        // 3. 然后,查找新数据集,如果存在,激活它
        foreach (DataSet ds in datasets)
        {
            if (ds.Path.Contains(datasetName))
            {
                objectTracker.ActivateDataSet(ds);
                mCurrentActiveDataSets.Add(datasetName, ds.Path);
            }
        }

        // 4. 最后重启traker.
        objectTracker.Start();
    }

    /// <summary>
    /// 关闭指定识别数据集
    /// </summary>
    /// <param name="datasetName">数据集名称或绝对路径</param>
    public virtual void DeactivateDateset(string datasetName)
    {
        if (!mCurrentActiveDataSets.ContainsKey(datasetName))
        {
            Debug.Log(string.Format("要关闭的识别库:{0}不存在", datasetName));
            return;
        }

        ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        IEnumerable<DataSet> datasets = objectTracker.GetDataSets();

        IEnumerable<DataSet> activeDataSets = objectTracker.GetActiveDataSets();

        List<DataSet> activeDataSetsToBeRemoved = activeDataSets.ToList();

        List<DataSet> dataSetsToBeActive = new List<DataSet>();

        foreach (DataSet ads in activeDataSetsToBeRemoved)
        {
            if (!ads.Path.Contains(datasetName))
            {
                dataSetsToBeActive.Add(ads);
            }
            objectTracker.DeactivateDataSet(ads);
        }

        objectTracker.Stop();

        foreach (DataSet ds in dataSetsToBeActive)
        {
            objectTracker.ActivateDataSet(ds);
        }
        mCurrentActiveDataSets.Remove(datasetName);

        objectTracker.Start();
    }
    /// <summary>
    /// 载入识别数据集
    /// </summary>
    /// <param name="DataSetName">数据集名称</param>
    /// <param name="Local">是否是本地识别数据集</param>
    public virtual void LoadDataSet(string DataSetName, bool Local = true)
    {
        ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        objectTracker.Stop();
        bool bLoadDataSet = false;
        DataSet mDataSet = null;
        if (VuforiaRuntimeUtilities.IsVuforiaEnabled())
        {
            objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
            mDataSet = objectTracker.CreateDataSet();
            if (!Local)
            {
                bLoadDataSet = mDataSet.Load(dataSetDirectoryPath+DataSetName+".xml", VuforiaUnity.StorageType.STORAGE_ABSOLUTE);//绝对路径 一般用来加载网络下载的识别库(dat和xml文件)  
            }
            else
            {
                bLoadDataSet = mDataSet.Load(DataSetName);//本地预制的识别库  
            }
        }

        if (bLoadDataSet)
        {
            mCurrentAllDataSets.Add(DataSetName, mDataSet.Path);

            UpdateImageTarget();
            Debug.Log("加载识别数据库成功并激活");

            if (objectTracker.ActivateDataSet(mDataSet))
            {
                mCurrentActiveDataSets.Add(DataSetName, mDataSet.Path);
            }
            else
            {
                Debug.Log(DataSetName + "激活失败");
            }

        }
        else
        {
            Debug.Log("加载识别数据库失败");
        }

        CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_TRIGGERAUTO);

        CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);

        objectTracker.Start();//开启识别器 (可以理解为摄像头)  
    }
    /// <summary>
    /// 更新ImageTarget上的信息
    /// </summary>
   public virtual void UpdateImageTarget()
    {
        ImageTargetBehaviour[] m_ImageTargetBehaviours = GameObject.FindObjectsOfType<ImageTargetBehaviour>();
        for (int i = 0 ; i < m_ImageTargetBehaviours.Length ; i++)
        {
            ImageTargetBehaviour imageTargetBehaviour = m_ImageTargetBehaviours[i];
            imageTargetBehaviour.name = m_ImageTargetBehaviours[i].ImageTarget.Name + "Target";
            imageTargetBehaviour.gameObject.AddComponent<DefaultTrackableEventHandler>();
            imageTargetBehaviour.gameObject.AddComponent<TurnOffBehaviour>();
        }
    }
    /// <summary>
    /// 卸载所有识别数据集(识别库)
    /// </summary>
    public virtual void UnLoadAllDataSet()
    {
        ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        bool isVuforiaEnabled = VuforiaRuntimeUtilities.IsVuforiaEnabled();

        if (isVuforiaEnabled)
        {
            //1. 关闭跟踪器
            objectTracker.Stop();
            //获取对应数据集合集(和激活数据集写法略有不同)
            IEnumerable<DataSet> dataSets = objectTracker.GetActiveDataSets();
            IEnumerator<DataSet> dEnumerator = dataSets.GetEnumerator();
            List<DataSet> listDataSet = new List<DataSet>();

            while (dEnumerator.MoveNext())
            {
                listDataSet.Add(dEnumerator.Current);
            }
            //关闭每一个数据集
            for (int i = 0 ; i < listDataSet.Count ; i++)
            {
                Debug.Log("关闭对应数据集:" + listDataSet[i].Path);
                objectTracker.DeactivateDataSet(listDataSet[i]);
            }

            for (int i = 0 ; i < listDataSet.Count ; i++)
            {
                Debug.Log("关闭对应数据集:" + listDataSet[i].Path);
                objectTracker.DestroyDataSet(listDataSet[i], false);
            }

            //管理所有可跟踪行为的状态
            StateManager stateManager = TrackerManager.Instance.GetStateManager();
            //ImageTargetBehaviour[] ImageTargetBehaviours = GameObject.FindObjectsOfType<ImageTargetBehaviour>();
            IEnumerable<TrackableBehaviour> IETrackableBehaviours = stateManager.GetTrackableBehaviours();
            //销毁对应创建的ImageTarget跟踪具体行为(就是在imagetarget上设置的参数)和销毁对应的GameObject
            foreach (var tb in IETrackableBehaviours)
            {
                stateManager.DestroyTrackableBehavioursForTrackable(tb.Trackable, true);
            }
            objectTracker.DestroyAllDataSets(true);
            Debug.Log("销毁识别数据成功");

            mCurrentActiveDataSets.Clear();
            mCurrentAllDataSets.Clear();
        }
        else
        {
            Debug.Log("销毁数据失败");
        }
    }

    /// <summary>
    /// 设置同时识别Image的个数
    /// </summary>
    /// <param name="TrackedCount"></param>
    public virtual void SetTrackedImageCount(int TrackedCount)
    {
        VuforiaUnity.SetHint(VuforiaUnity.VuforiaHint.HINT_MAX_SIMULTANEOUS_IMAGE_TARGETS, TrackedCount);
    }
    /// <summary>
    /// 设置同时识别3D物体的个数
    /// </summary>
    /// <param name="TrackedCount"></param>
    public virtual void SetTrackedObjectCount(int TrackedCount)
    {
        VuforiaUnity.SetHint(VuforiaUnity.VuforiaHint.HINT_MAX_SIMULTANEOUS_OBJECT_TARGETS, TrackedCount);
    }
}



using UnityEngine;
using Vuforia;


/// <summary>
///帧率设置类
/// </summary>
public class FrameRateSettings : MonoBehaviour
{
    public const string Name = "FrameRateSettings";
    static FrameRateSettings() { }
    protected FrameRateSettings() { }
    protected static volatile FrameRateSettings m_instance = null;
    protected readonly object m_syncRoot = new object();
    protected static readonly object m_staticSyncRoot = new object();

    public static FrameRateSettings Instance
    {
        get
        {
            if (m_instance == null)
            {
                lock (m_staticSyncRoot)
                {
                    if (m_instance == null) m_instance = new GameObject(Name).AddComponent<FrameRateSettings>();
                }
            }
            return m_instance;
        }
        //set { m_instance = value; }
    }

    void Awake()
    {
        if (m_instance == null) m_instance = this;

        if (gameObject.name == "GameObject") gameObject.name = Name;
    }


    void Start()
    {
        VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
    }


    /// <summary>
    /// 高通全面启动的帧率设置回调
    /// </summary>
    private void OnVuforiaStarted()
    {
        //查询在unity中推荐的帧率(默认 AR或VR  省电 高帧数 四种模式)

        int targetFps = VuforiaRenderer.Instance.GetRecommendedFps(VuforiaRenderer.FpsHint.NONE);

        /*默认情况下,我们使用application.targetframerate设置推荐的帧速率。
         谷歌纸板不使用垂直同步,和OVR明确禁用它。如果开发商
         使用VSYNC的质量设置,他们也应该把他们的qualitysettings.vsynccount
           根据上面返回的值。
         例如:如果物体的FPS > 50 > vsynccount = 1;其他vsynccount = 2;
        */
        if (Application.targetFrameRate != targetFps)
        {
            Debug.Log("Setting frame rate to " + targetFps + "fps");
            Application.targetFrameRate = targetFps;
        }
    }

}


using UnityEngine;
using System.Collections;
using Vuforia;

/// <summary>
/// 摄像机功能设置类
/// </summary>
public class CameraSettings : MonoBehaviour
{
    public const string Name = "CameraSettings";
    static CameraSettings() { }
    protected CameraSettings() { }
    protected static volatile CameraSettings m_instance = null;
    protected readonly object m_syncRoot = new object();
    protected static readonly object m_staticSyncRoot = new object();


    public static CameraSettings Instance
    {
        get
        {
            if (m_instance == null)
            {
                lock (m_staticSyncRoot)
                {
                    if (m_instance == null) m_instance = new GameObject(Name).AddComponent<CameraSettings>();
                }
            }
            return m_instance;
        }

        //set { m_instance = value; }
    }




    private bool mVuforiaStarted = false;
    private bool mAutofocusEnabled = true;
    private bool mFlashTorchEnabled = false;
    private CameraDevice.CameraDirection mActiveDirection = CameraDevice.CameraDirection.CAMERA_DEFAULT;

    void Awake()
    {
        if (m_instance == null) m_instance = this;

        if (gameObject.name == "GameObject") gameObject.name = Name;
    }

    void Start()
    {
        var vuforia = VuforiaARController.Instance;
        //vuforia已经全面启动回调,包括相机和跟踪器。可以注册多个回调函数
        vuforia.RegisterVuforiaStartedCallback(OnVuforiaStarted);
        //停止和恢复的回调,这个是回复后重新让摄像机对焦(对应状态自动传入对应的bool值)
        vuforia.RegisterOnPauseCallback(OnPaused);
    }

    private void OnVuforiaStarted()
    {
        mVuforiaStarted = true;
        //开启自动对焦
        SwitchAutofocus(true);
    }

    private void OnPaused(bool paused)
    {
        bool appResumed = !paused;
        if (appResumed && mVuforiaStarted)
        {
            // 恢复原来的对焦方式
            if (mAutofocusEnabled)
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
            else
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
        }
        else
        {
            //闪光灯状态更改 因为闪光灯会自动被操作系统关闭
            mFlashTorchEnabled = false;
        }
    }


    public bool IsFlashTorchEnabled()
    {
        return mFlashTorchEnabled;
    }
    /// <summary>
    /// 闪光灯开关
    /// </summary>
    /// <param name="ON">是否开启闪光灯</param>
    public virtual void SwitchFlashTorch(bool ON)
    {
        if (CameraDevice.Instance.SetFlashTorchMode(ON))
        {
            Debug.Log("成功开启闪光灯 " + ON);
            mFlashTorchEnabled = ON;
        }
        else
        {
            Debug.Log("开启闪光灯失败 " + ON);
            mFlashTorchEnabled = false;
        }
    }

    public virtual bool IsAutofocusEnabled()
    {
        return mAutofocusEnabled;
    }
    /// <summary>
    /// 是否开启自动对焦
    /// </summary>
    /// <param name="ON">是否开启自动对焦</param>
    public virtual void SwitchAutofocus(bool ON)
    {
        if (ON)
        {
            if (CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO))
            {
                Debug.Log("成功开启连续对焦");
                mAutofocusEnabled = true;
            }
            else
            {
                // Fallback to normal focus mode
                Debug.Log("未能启用连续自动对焦,切换到正常对焦模式");
                mAutofocusEnabled = false;
                CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
            }
        }
        else
        {
            Debug.Log("禁用连续自动对焦(启用正常对焦模式).");
            mAutofocusEnabled = false;
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
        }
    }
    /// <summary>
    /// 强制触发一次对焦
    /// </summary>
    public virtual void TriggerAutofocusEvent()
    {

        CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_TRIGGERAUTO);

        // 恢复到原来的对焦模式
        StartCoroutine(RestoreOriginalFocusMode());
    }

    private IEnumerator RestoreOriginalFocusMode()
    {
        yield return new WaitForSeconds(1.5f);

        if (mAutofocusEnabled)
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
        else
            CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
    }

    /// <summary>
    /// 前后摄像机调换
    /// </summary>
    /// <param name="camDir">摄像机方向</param>
    public virtual void SelectCamera(CameraDevice.CameraDirection camDir)
    {
        if (RestartCamera(camDir))
        {
            mActiveDirection = camDir;

            // Upon camera restart, flash is turned off
            mFlashTorchEnabled = false;
        }
    }
    /// <summary>
    /// 转换摄像机需要把原来的摄像机状态关掉卸载然后重新初始化
    /// </summary>
    /// <param name="direction">摄像机方向</param>
    /// <returns></returns>
    public virtual bool RestartCamera(CameraDevice.CameraDirection direction)
    {
        ObjectTracker tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        if (tracker != null)
            tracker.Stop();

        CameraDevice.Instance.Stop();
        CameraDevice.Instance.Deinit();

        if (!CameraDevice.Instance.Init(direction))
        {
            Debug.Log("初始化失败,指定的方向为: " + direction.ToString());
            return false;
        }
        if (!CameraDevice.Instance.Start())
        {
            Debug.Log("摄像机启动失败,指定的方向为: " + direction.ToString());
            return false;
        }

        if (tracker != null)
        {
            if (!tracker.Start())
            {
                Debug.Log("Tracker重新启动失败");
                return false;
            }
        }

        return true;
    }
    /// <summary>
    /// 在IOS上翻转摄像头会出现摄像头上下颠倒的情况,在CameraDevice.Instance.Start()后调用次函数,反之忽略即可
    /// </summary>
    /// <returns></returns>
    IEnumerator Refresh()
    {
        yield return new WaitForEndOfFrame();
        Camera.main.transform.localEulerAngles = new Vector3(0, 0, 180.0f);
    }
    /// <summary>
    /// 是否为前置摄像头
    /// </summary>
    /// <returns></returns>
    public virtual bool IsFrontCameraActive()
    {
        return (mActiveDirection == CameraDevice.CameraDirection.CAMERA_FRONT);
    }

}






  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值