/*============================================================================== Copyright (c) 2019 PTC Inc. All Rights Reserved. Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc. All Rights Reserved. Confidential and Proprietary - Protected under copyright and other laws. ==============================================================================*/ using UnityEngine; using UnityEngine.Events; using Vuforia; /// /// A custom handler that implements the ITrackableEventHandler interface. /// /// Changes made to this file could be overwritten when upgrading the Vuforia version. /// When implementing custom event handler behavior, consider inheriting from this class instead. /// public class DefaultTrackableEventHandler : MonoBehaviour { public enum TrackingStatusFilter { Tracked, Tracked_ExtendedTracked, Tracked_ExtendedTracked_Limited } /// /// A filter that can be set to either: /// - Only consider a target if it's in view (TRACKED) /// - Also consider the target if's outside of the view, but the environment is tracked (EXTENDED_TRACKED) /// - Even consider the target if tracking is in LIMITED mode, e.g. the environment is just 3dof tracked. /// public TrackingStatusFilter StatusFilter = TrackingStatusFilter.Tracked_ExtendedTracked_Limited; public UnityEvent OnTargetFound; public UnityEvent OnTargetLost; protected TrackableBehaviour mTrackableBehaviour; protected TrackableBehaviour.Status m_PreviousStatus; protected TrackableBehaviour.Status m_NewStatus; protected bool m_CallbackReceivedOnce = false; protected virtual void Start() { mTrackableBehaviour = GetComponent(); if (mTrackableBehaviour) { mTrackableBehaviour.RegisterOnTrackableStatusChanged(OnTrackableStatusChanged); } } protected virtual void OnDestroy() { if (mTrackableBehaviour) { mTrackableBehaviour.UnregisterOnTrackableStatusChanged(OnTrackableStatusChanged); } } void OnTrackableStatusChanged(TrackableBehaviour.StatusChangeResult statusChangeResult) { m_PreviousStatus = statusChangeResult.PreviousStatus; m_NewStatus = statusChangeResult.NewStatus; Debug.LogFormat("Trackable {0} {1} -- {2}", mTrackableBehaviour.TrackableName, mTrackableBehaviour.CurrentStatus, mTrackableBehaviour.CurrentStatusInfo); HandleTrackableStatusChanged(); } protected virtual void HandleTrackableStatusChanged() { if (!ShouldBeRendered(m_PreviousStatus) && ShouldBeRendered(m_NewStatus)) { OnTrackingFound(); } else if (ShouldBeRendered(m_PreviousStatus) && !ShouldBeRendered(m_NewStatus)) { OnTrackingLost(); } else { if (!m_CallbackReceivedOnce && !ShouldBeRendered(m_NewStatus)) { // This is the first time we are receiving this callback, and the target is not visible yet. // --> Hide the augmentation. OnTrackingLost(); } } m_CallbackReceivedOnce = true; } protected bool ShouldBeRendered(TrackableBehaviour.Status status) { if (status == TrackableBehaviour.Status.DETECTED || status == TrackableBehaviour.Status.TRACKED) { // always render the augmentation when status is DETECTED or TRACKED, regardless of filter return true; } if (StatusFilter == TrackingStatusFilter.Tracked_ExtendedTracked) { if (status == TrackableBehaviour.Status.EXTENDED_TRACKED) { // also return true if the target is extended tracked return true; } } if (StatusFilter == TrackingStatusFilter.Tracked_ExtendedTracked_Limited) { if (status == TrackableBehaviour.Status.EXTENDED_TRACKED || status == TrackableBehaviour.Status.LIMITED) { // in this mode, render the augmentation even if the target's tracking status is LIMITED. // this is mainly recommended for Anchors. return true; } } return false; } [SerializeField] public Transform AnchorObj; protected virtual void OnTrackingFound() { if (mTrackableBehaviour) { var rendererComponents = mTrackableBehaviour.GetComponentsInChildren(true); var colliderComponents = mTrackableBehaviour.GetComponentsInChildren(true); var canvasComponents = mTrackableBehaviour.GetComponentsInChildren(true); // Enable rendering: foreach (var component in rendererComponents) component.enabled = true; // Enable colliders: foreach (var component in colliderComponents) component.enabled = true; // Enable canvas': foreach (var component in canvasComponents) component.enabled = true; if (AnchorObj != null) { AnchorObj.SetParent(null); } } if (OnTargetFound != null) OnTargetFound.Invoke(); } protected virtual void OnTrackingLost() { if (mTrackableBehaviour) { var rendererComponents = mTrackableBehaviour.GetComponentsInChildren(true); var colliderComponents = mTrackableBehaviour.GetComponentsInChildren(true); var canvasComponents = mTrackableBehaviour.GetComponentsInChildren(true); // Disable rendering: foreach (var component in rendererComponents) component.enabled = false; // Disable colliders: foreach (var component in colliderComponents) component.enabled = false; // Disable canvas': foreach (var component in canvasComponents) component.enabled = false; } if (OnTargetLost != null) OnTargetLost.Invoke(); } public void ToggleDeviceTracking(bool enableDeviceTracking) { var posDeviceTracker = TrackerManager.Instance.InitTracker(); if (enableDeviceTracking) posDeviceTracker.Start(); else posDeviceTracker.Stop(); } }