Vuforia开发高阶三-用户自定义Target(第二部分)

前面介绍UDT基础开发,这里介绍怎么使用UDT的多Target对应不同模型的问题。  

对于UDT的示例,我觉得有必要把这个类单独拿出来讲一下,  
UserDefinedTargetEventHandler:这种类型的类在VuforiaAPI中很常见。Event Handler可以理解为事件控制器。  



复制代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Vuforia;
public class UserDefinedTargetEventHandler : MonoBehaviour, IUserDefinedTargetEventHandler
{
    #region PUBLIC_MEMBERS
    /// <summary>
    /// Can be set in the Unity inspector to reference a ImageTargetBehaviour that is instanciated for augmentations of new user defined targets.
    /// </summary>
    public ImageTargetBehaviour ImageTargetTemplate;
    public int IndexForMostRecentlyAddedTrackable
    {
        get
        {
            return ( mTargetCounter - 1 ) % 5;
        }
    }
    #endregion PUBLIC_MEMBERS
    #region PRIVATE_MEMBERS
    private UserDefinedTargetBuildingBehaviour mTargetBuildingBehaviour;
    private ObjectTracker mObjectTracker;
    // DataSet that newly defined targets are added to
    private DataSet mBuiltDataSet;
    // currently observed frame quality
    private ImageTargetBuilder.FrameQuality mFrameQuality = ImageTargetBuilder.FrameQuality.FRAME_QUALITY_NONE;
    // counter variable used to name duplicates of the image target template
    private int mTargetCounter;
    private SampleAppUIButton mNewUserDefinedTargetButton;
    #endregion PRIVATE_MEMBERS
    /// <summary>
    /// Registers this component as a handler for UserDefinedTargetBuildingBehaviour events
    /// </summary>
    public void Init()
    {
        mTargetBuildingBehaviour = GetComponent<UserDefinedTargetBuildingBehaviour>();
        if (mTargetBuildingBehaviour)
        {
            mTargetBuildingBehaviour.RegisterEventHandler(this);
            Debug.Log ("Registering to the events of IUserDefinedTargetEventHandler");
        }
        mNewUserDefinedTargetButton = MakeUIButton();
        mNewUserDefinedTargetButton.TappedOn += OnTappedOnNewTargetButton;
    }
    public void Draw()
    {
        mNewUserDefinedTargetButton.Draw();
    }
    #region IUserDefinedTargetEventHandler implementation
    /// <summary>
    /// Called when UserDefinedTargetBuildingBehaviour has been initialized successfully
    /// </summary>
    public void OnInitialized ()
    {
        mObjectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        if (mObjectTracker != null)
        {
            // create a new dataset
            mBuiltDataSet = mObjectTracker.CreateDataSet();
            mObjectTracker.ActivateDataSet(mBuiltDataSet);
        }
    }
    /// <summary>
    /// Updates the current frame quality
    /// </summary>
    public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
    {
        mFrameQuality = frameQuality;
    }
  
    /// <summary>
    /// Takes a new trackable source and adds it to the dataset
    /// This gets called automatically as soon as you 'BuildNewTarget with UserDefinedTargetBuildingBehaviour
    /// </summary>
    public void OnNewTrackableSource(TrackableSource trackableSource)
    {
        mTargetCounter++;
        // deactivates the dataset first
        mObjectTracker.DeactivateDataSet(mBuiltDataSet);
        // Destroy the oldest target if the dataset is full or the dataset 
        // already contains five user-defined targets.
        if (mBuiltDataSet.HasReachedTrackableLimit() || mBuiltDataSet.GetTrackables().Count() >= 5)
        {
            IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
            Trackable oldest = null;
            foreach (Trackable trackable in trackables)
                if (oldest == null || trackable.ID < oldest.ID)
                    oldest = trackable;
              
            if (oldest != null)
            {
                Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
                mBuiltDataSet.Destroy(oldest, true);
            }
        }
        // get predefined trackable and instantiate it
        ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
        imageTargetCopy.gameObject.name = "UserDefinedTarget-" + mTargetCounter;
        // add the duplicated trackable to the data set and activate it
        mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
        // activate the dataset again
        mObjectTracker.ActivateDataSet(mBuiltDataSet);
        //Extended Tracking with user defined targets only works with the most recently defined target.
        //If tracking is enabled on previous target, it will not work on newly defined target.
        //Don't need to call this if you don't care about extended tracking.
        StopExtendedTracking();
        mObjectTracker.Stop();
        mObjectTracker.ResetExtendedTracking();
        mObjectTracker.Start();
    }
    #endregion IUserDefinedTargetEventHandler implementation
    #region PRIVATE_METHODS
    /// <summary>
    /// Instantiates a new user-defined target and is also responsible for dispatching callback to 
    /// IUserDefinedTargetEventHandler::OnNewTrackableSource
    /// </summary>
    private void BuildNewTarget()
    {
        // create the name of the next target.
        // the TrackableName of the original, linked ImageTargetBehaviour is extended with a continuous number to ensure unique names
        string targetName = string.Format("{0}-{1}", ImageTargetTemplate.TrackableName, mTargetCounter);
        // generate a new target name:
        mTargetBuildingBehaviour.BuildNewTarget(targetName, ImageTargetTemplate.GetSize().x);
    }
    private void OnTappedOnNewTargetButton()
    {
        BuildNewTarget();
    }
    /// <summary>
    /// This method only demonstrates how to handle extended tracking feature when you have multiple targets in the scene
    /// So, this method could be removed otherwise
    /// </summary>
   private void StopExtendedTracking()
    {
        StateManager stateManager = TrackerManager.Instance.GetStateManager();
        //If the extended tracking is enabled, we first disable OTT for all the trackables
        //and then enable it for the newly created target
        //UDTUIEventHandler uiMenuEventHandler = FindObjectOfType(typeof(UDTUIEventHandler)) as UDTUIEventHandler;
        if(UDTUIEventHandler.ExtendedTrackingIsEnabled)
        {
            //Stop extended tracking on all the trackables
            foreach(var behaviour in stateManager.GetTrackableBehaviours())
            {
                var imageBehaviour = behaviour as ImageTargetBehaviour;
                if(imageBehaviour != null)
                {
                    imageBehaviour.ImageTarget.StopExtendedTracking();
                }
            }
            List<TrackableBehaviour> list =  stateManager.GetTrackableBehaviours().ToList();
            ImageTargetBehaviour bhvr = list[IndexForMostRecentlyAddedTrackable] as ImageTargetBehaviour;
            if(bhvr != null)
            {
                Debug.Log("ExtendedTracking enabled for " + bhvr.name);
                bhvr.ImageTarget.StartExtendedTracking();
            }
        }
    }
    private SampleAppUIButton MakeUIButton()
    {
        Rect rect = new Rect(0.36f * Screen.width, Screen.height - (130 * Screen.width)/800.0f, 0.28f * Screen.width, (100.0f * Screen.width)/800.0f);
        GUIStyle style = new GUIStyle();
        style.normal.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.active.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.onNormal.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.alignment = TextAnchor.MiddleCenter;
        Texture imageForButton = Resources.Load("UserInterface/icon_camera") as Texture;
        return new SampleAppUIButton(rect, style, imageForButton);
    }
    #endregion PRIVATE_METHODS
}

OnNewTrackableSource 这个方法,新建一个 Target的时候调用,即当你取了一个场景之后,就会掉用这个方法,并且 mTargetCounter 这个变量会自动增一。所以,对于不同的场景,自定义后渲染不同的模型,必然在这个方法中实现,并且个 mTargetCounter 这个变量密切相关。  

复制代码
/// <summary>
    /// Takes a new trackable source and adds it to the dataset
    /// This gets called automatically as soon as you 'BuildNewTarget with UserDefinedTargetBuildingBehaviour
    /// </summary>
    public void OnNewTrackableSource(TrackableSource trackableSource)
    {
        mTargetCounter++;
          
        // deactivates the dataset first
        mObjectTracker.DeactivateDataSet(mBuiltDataSet);
  
        // Destroy the oldest target if the dataset is full or the dataset 
        // already contains five user-defined targets.
        if (mBuiltDataSet.HasReachedTrackableLimit() || mBuiltDataSet.GetTrackables().Count() >= 5)
        {
            IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
            Trackable oldest = null;
            foreach (Trackable trackable in trackables)
                if (oldest == null || trackable.ID < oldest.ID)
                    oldest = trackable;
              
            if (oldest != null)
            {
                Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
                mBuiltDataSet.Destroy(oldest, true);
            }
        }
        // get predefined trackable and instantiate it
        // 
        ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
        imageTargetCopy.gameObject.name = "UserDefinedTarget-" + mTargetCounter;
          
        // add the duplicated trackable to the data set and activate it
        mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
  
        // activate the dataset again
        mObjectTracker.ActivateDataSet(mBuiltDataSet);
  
        //Extended Tracking with user defined targets only works with the most recently defined target.
        //If tracking is enabled on previous target, it will not work on newly defined target.
        //Don't need to call this if you don't care about extended tracking.
        StopExtendedTracking();
        mObjectTracker.Stop();
        mObjectTracker.ResetExtendedTracking();
        mObjectTracker.Start();
// 根据mTargetCounter 判断是第几个Target,1表示第一个,2表示第二个,以此类推。
// 当然,数量很多的时候,使用switch会更好。这里判断是第几个标志,然后对应添加不同的模型。如果需要使用非Unity原生模型,使用GameObject.Find方法获取模型对象即可。
        if (mTargetCounter == 1) {
            GameObject cube = GameObject.CreatePrimitive (PrimitiveType.Cube);
            cube.name = "mycube";
            cube.transform.parent = imageTargetCopy.transform;
            cube.transform.localScale = new Vector3 (0.25f, 0.25f, 0.25f);
            cube.transform.localPosition = new Vector3 (0, 0, 0);
            cube.transform.localRotation = Quaternion.identity;
        }  else if (mTargetCounter == 2) {
            GameObject sphere = GameObject.CreatePrimitive (PrimitiveType.Sphere);
            sphere.name = "mySphere";
            sphere.transform.parent = imageTargetCopy.transform;
            sphere.transform.localScale = new Vector3 (0.25f, 0.25f, 0.25f);
            sphere.transform.localPosition = new Vector3 (0, 0, 0);
            sphere.transform.localRotation = Quaternion.identity;
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值