/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal { using System; using System.Collections.Generic; /// /// Manages AR system state and handles the session lifecycle. this class, application can create /// a session, configure it, start/pause or stop it. public class NRTrackableManager : ILifecycle { /// Dictionary of trackables. private Dictionary m_TrackableDict = new Dictionary(); /// Dictionary of trackable types. private Dictionary> m_TrackableTypeDict = new Dictionary>(); /// all trackables. private List m_AllTrackables = new List(); /// The new trackables. private List m_NewTrackables = new List(); /// The old trackables. private HashSet m_OldTrackables = new HashSet(); /// Temp trackable handle list. private List m_TempTrackableHandles = new List(); private NRTrackableSubsystem m_TrackableSubsystem; public NRTrackableSubsystem TrackableSubsystem { get { if (m_TrackableSubsystem == null) { string trackable_match = NRTrackableSubsystemDescriptor.Name; List trackableDes = new List(); NRSubsystemManager.GetSubsystemDescriptors(trackableDes); foreach (var descripe in trackableDes) { if (descripe.id.Equals(trackable_match)) { m_TrackableSubsystem = descripe.Create(); } } } return m_TrackableSubsystem; } } private NRPlaneSubsystem m_PlaneSubsystem; public NRPlaneSubsystem PlaneSubsystem { get { if (m_PlaneSubsystem == null) { string trackable_match = NRPlaneSubsystemDescriptor.Name; List trackableDes = new List(); NRSubsystemManager.GetSubsystemDescriptors(trackableDes); foreach (var descripe in trackableDes) { if (descripe.id.Equals(trackable_match)) { m_PlaneSubsystem = descripe.Create(); } } } return m_PlaneSubsystem; } } private NRTrackableImageSubsystem m_TrackableImagesSubsystem; public NRTrackableImageSubsystem TrackableImageSubsystem { get { if (m_TrackableImagesSubsystem == null) { string trackable_match = NRTrackableImageSubsystemDescriptor.Name; List trackableDes = new List(); NRSubsystemManager.GetSubsystemDescriptors(trackableDes); foreach (var descripe in trackableDes) { if (descripe.id.Equals(trackable_match)) { m_TrackableImagesSubsystem = descripe.Create(); } } } return m_TrackableImagesSubsystem; } } /// Constructor. /// The native interface. public NRTrackableManager() { } /// Creates a new NRTrackable. /// Handle of the trackable. /// The native interface. /// A NRTrackable. private NRTrackable Create(UInt64 trackable_handle) { if (trackable_handle == 0 || !TrackableSubsystem.running) { return null; } NRTrackable result; if (m_TrackableDict.TryGetValue(trackable_handle, out result)) { return result; } TrackableType trackableType = TrackableSubsystem.GetTrackableType(trackable_handle); if (trackableType == TrackableType.TRACKABLE_PLANE) { result = new NRTrackablePlane(trackable_handle); } else if (trackableType == TrackableType.TRACKABLE_IMAGE) { result = new NRTrackableImage(trackable_handle); } else { throw new NotImplementedException( "TrackableFactory::No constructor for requested trackable type."); } if (result != null) { m_TrackableDict.Add(trackable_handle, result); if (!m_TrackableTypeDict.ContainsKey(trackableType)) { m_TrackableTypeDict.Add(trackableType, new Dictionary()); } Dictionary trackbletype_dict = null; m_TrackableTypeDict.TryGetValue(trackableType, out trackbletype_dict); if (!trackbletype_dict.ContainsKey(trackable_handle)) { trackbletype_dict.Add(trackable_handle, result); m_AllTrackables.Add(result); } } return result; } /// Updates the trackables described by trackable_type. /// Type of the trackable. private void UpdateTrackables(TrackableType trackable_type) { if (!TrackableSubsystem.running) { return; } if (TrackableSubsystem.UpdateTrackables(trackable_type, m_TempTrackableHandles)) { for (int i = 0; i < m_TempTrackableHandles.Count; i++) { Create(m_TempTrackableHandles[i]); } } } /// Get the list of trackables with specified filter. /// Generic type parameter. /// trackableList A list where the returned trackable stored. The /// previous values will be cleared. /// Query filter. public void GetTrackables(List trackables, NRTrackableQueryFilter filter) where T : NRTrackable { TrackableType t_type = GetTrackableType(); // Update trackable by type UpdateTrackables(t_type); // Find the new trackable in this frame m_NewTrackables.Clear(); for (int i = 0; i < m_AllTrackables.Count; i++) { NRTrackable trackable = m_AllTrackables[i]; if (!m_OldTrackables.Contains(trackable)) { m_NewTrackables.Add(trackable); m_OldTrackables.Add(trackable); } } trackables.Clear(); if (filter == NRTrackableQueryFilter.All) { for (int i = 0; i < m_AllTrackables.Count; i++) { SafeAdd(m_AllTrackables[i], trackables); } } else if (filter == NRTrackableQueryFilter.New) { for (int i = 0; i < m_NewTrackables.Count; i++) { SafeAdd(m_NewTrackables[i], trackables); } } } /// Safe add. /// Generic type parameter. /// The trackable. /// trackableList A list where the returned trackable stored. The /// previous values will be cleared. private void SafeAdd(NRTrackable trackable, List trackables) where T : NRTrackable { if (trackable is T) { trackables.Add(trackable as T); } } /// Gets trackable type. /// Generic type parameter. /// The trackable type. private TrackableType GetTrackableType() where T : NRTrackable { if (typeof(NRTrackablePlane).Equals(typeof(T))) { return TrackableType.TRACKABLE_PLANE; } else if (typeof(NRTrackableImage).Equals(typeof(T))) { return TrackableType.TRACKABLE_IMAGE; } return TrackableType.TRACKABLE_BASE; } public void Start() { TrackableSubsystem.Start(); PlaneSubsystem.Start(); TrackableImageSubsystem.Start(); } public void Pause() { TrackableSubsystem.Pause(); PlaneSubsystem.Pause(); TrackableImageSubsystem.Pause(); } public void Resume() { TrackableSubsystem.Resume(); PlaneSubsystem.Resume(); TrackableImageSubsystem.Resume(); } public void Stop() { TrackableSubsystem.Stop(); PlaneSubsystem.Stop(); TrackableImageSubsystem.Stop(); } } }