/****************************************************************************
* 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();
}
}
}