/****************************************************************************
* Copyright 2019 Nreal Techonology Limited. All rights reserved.
*
* This file is part of NRSDK.
*
* https://www.nreal.ai/
*
*****************************************************************************/
namespace NRKernal.Experimental.Persistence
{
using System;
using UnityEngine;
using System.Collections.Generic;
/// An image tracking anchor tool.
public class ImageTrackingAnchorTool : MonoBehaviour
{
/// Event queue for all listeners interested in OnAnchorLoaded events.
public event Action OnAnchorLoaded;
/// Event queue for all listeners interested in OnAnchorPoseUpdate events.
public event Action OnAnchorPoseUpdate;
/// The tracking image visualizer prefab.
public TrackingImageVisualizerForAnchor TrackingImageVisualizerPrefab;
/// Zero-based index of the used image.
public int usedImageIndex = 0;
/// The visualizer.
TrackingImageVisualizerForAnchor visualizer;
private bool m_IsStart = true;
/// True to use map.
public bool useMap = false;
/// The anchor key.
public string anchorKey;
/// The anchor store.
private NRWorldAnchorStore anchorStore;
/// The current anchor.
private NRWorldAnchor currentAnchor;
void Start()
{
if (useMap)
{
this.LoadAnchor();
}
}
private void LoadAnchor()
{
NRWorldAnchorStore.GetAsync((store) =>
{
NRDebugger.Info("[ImageTrackingAnchorTool] Get world anchor map success.");
this.anchorStore = store;
var keys = anchorStore.GetAllIds();
if (keys == null)
{
NRDebugger.Info("[ImageTrackingAnchorTool] Can not get any keys...");
return;
}
foreach (var item in keys)
{
if (item.Equals(anchorKey))
{
GameObject go = new GameObject(anchorKey);
currentAnchor = anchorStore.Load(anchorKey, go);
NRDebugger.Info("[ImageTrackingAnchorTool] Find the anchor :" + anchorKey);
OnAnchorLoaded?.Invoke(anchorKey, currentAnchor);
break;
}
}
});
}
private void Update()
{
if (!m_IsStart)
{
return;
}
List trackableImages = new List();
NRFrame.GetTrackables(trackableImages, NRTrackableQueryFilter.All);
Pose pose;
foreach (var image in trackableImages)
{
if (image.GetDataBaseIndex() == usedImageIndex)
{
pose = image.GetCenterPose();
if (visualizer == null)
{
visualizer = (TrackingImageVisualizerForAnchor)Instantiate(TrackingImageVisualizerPrefab, pose.position, pose.rotation);
visualizer.Image = image;
if (useMap)
{
visualizer.OnConfirm += SaveAnchor;
}
}
break;
}
}
// Update pose.
if (useMap)
{
if (currentAnchor != null && currentAnchor.GetTrackingState() == TrackingState.Tracking)
{
pose = currentAnchor.GetCenterPose();
OnAnchorPoseUpdate?.Invoke(pose);
}
}
else
{
if (visualizer != null && visualizer.Image.GetTrackingState() == TrackingState.Tracking)
{
pose = visualizer.Image.GetCenterPose();
OnAnchorPoseUpdate?.Invoke(pose);
}
}
}
/// True to lock, false to unlock the save.
private bool saveLock = false;
/// Saves the anchor.
private void SaveAnchor()
{
if (anchorStore == null || saveLock || visualizer == null || string.IsNullOrEmpty(anchorKey)
|| visualizer.Image.GetTrackingState() != TrackingState.Tracking)
{
NRDebugger.Warning("[ImageTrackingAnchorTool] Can not save the anchor!");
return;
}
Invoke("Unlock", 1f);
anchorStore.Delete(anchorKey);
NRDebugger.Info("[ImageTrackingAnchorTool] Save the anchor.");
// Avoid to frequent calls.
saveLock = true;
currentAnchor = anchorStore.AddAnchor(anchorKey,
new Pose(visualizer.transform.position, visualizer.transform.rotation));
OnAnchorLoaded?.Invoke(anchorKey, currentAnchor);
}
/// Unlocks this object.
private void Unlock()
{
saveLock = false;
}
/// Switch trackable image.
/// True to isopen.
public void SwitchTrackableImage(bool isopen)
{
NRDebugger.Info("[ImageTrackingAnchorTool] SwitchTrackableImage:" + isopen);
m_IsStart = isopen;
visualizer?.gameObject.SetActive(isopen);
//var config = NRSessionManager.Instance.NRSessionBehaviour.SessionConfig;
//config.ImageTrackingMode = isopen ? TrackableImageFindingMode.ENABLE : TrackableImageFindingMode.DISABLE;
//NRSessionManager.Instance.SetConfiguration(config);
}
}
}