using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; namespace MagicLeap.OpenXR.Features.MarkerUnderstanding { public partial class MagicLeapMarkerUnderstandingFeature { private readonly List markerDetectors = new(); /// /// The maximum number of marker detectors allowed at once. /// public const int MarkerDetectorsLimit = 64; /// /// The active marker detectors tracked by the marker understanding feature. /// /// A readonly list of the active marker detectors. public IReadOnlyList MarkerDetectors => markerDetectors; private MarkerUnderstandingNativeFunctions nativeFunctions; /// /// Creates a marker detector with predefined settings. /// /// The marker detector settings to be associated with the marker detector to be created. /// The marker detector that has been created. Returns null if the number of active marker detectors is at the limit or an error occurred. public MarkerDetector CreateMarkerDetector(MarkerDetectorSettings settings) { if (markerDetectors.Count >= MarkerDetectorsLimit) { Debug.LogError($"The number of active marker detectors cannot exceed {MarkerDetectorsLimit}"); return null; } var markerDetector = new MarkerDetector(settings, nativeFunctions, this); if(markerDetector.Status == MarkerDetectorStatus.Error) { Debug.LogError($"Failed to create Marker Detector"); return null; } markerDetectors.Add(markerDetector); return markerDetector; } /// /// Provides the ability to modify a marker detector with new settings. /// Note: this method actually destroys the old marker detector and replaces it with a newly created one. /// However, this approach maintains the index position of it in the marker detectors list. /// /// The marker detector settings to be associated with the marker detector to be created. /// The specified marker detector to modify. /// The newly created marker detector that replaced the old one. This returns null if the specified marker detector is not tracked. public void ModifyMarkerDetector(MarkerDetectorSettings settings, ref MarkerDetector markerDetector) { var index = markerDetectors.IndexOf(markerDetector, 0); if (index == -1) { Debug.LogError("Marker detector cannot be modified because it is not tracked by the MarkerUnderstandingFeature. Either it was already destroyed or not created properly."); return; } DestroyMarkerDetector(markerDetector); markerDetector = new MarkerDetector(settings, nativeFunctions, this); markerDetector.UpdateData(); markerDetectors.Insert(index, markerDetector); } /// /// Updates the status and data for all actively tracked marker detectors. /// public void UpdateMarkerDetectors() { foreach (var markerDetector in markerDetectors) { markerDetector.UpdateData(); } } /// /// Destroys the specified marker detector. /// /// The marker detector to be destroyed. public void DestroyMarkerDetector(MarkerDetector markerDetector) { markerDetectors.Remove(markerDetector); markerDetector.Destroy(); } /// /// Destroys all actively tracked marker detectors. /// public void DestroyAllMarkerDetectors() { var markerTrackers = markerDetectors.ToList(); markerDetectors.Clear(); Task.Run(() => { foreach (var markerDetector in markerTrackers) { markerDetector.Destroy(); } }); } } }