/// <summary> /// Returns a list of all the PCFs of the types provided by the typesMask inside the current map. /// </summary> /// <param name="callback">Delegate used to return the resulting MLResult.Result and list of found PCFs.</param> /// <param name="maxResults">The max number of PCFs to get.</param> /// <param name="typesMask">The bitmask of which PCF types to consider.</param> /// <param name="update">Determines if the PCFs should have their pose updated.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if all the PCFs from the current map have been found successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to no API instance being found. /// </returns> public static MLResult FindAllPCFs(OnFoundMultiPCFDelegate callback, uint maxResults = int.MaxValue, PCF.Types typesMask = PCF.Types.SingleUserSingleSession | PCF.Types.SingleUserMultiSession | PCF.Types.MultiUserMultiSession, bool update = true) { if (MLPersistentCoordinateFrames.IsValidInstance()) { QueryFilter queryFilter = QueryFilter.Create(); queryFilter.TypesMask = typesMask; queryFilter.MaxResults = maxResults; queryFilter.Sorted = false; FindPCFsByFilter(queryFilter, callback, update); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindAllPCFs failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.FindAllPCFs failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Returns filtered list of PCFs based on the parameters of the given queryFilter. /// </summary> /// <param name="queryFilter">Parameters used to curate the returned values.</param> /// <param name="callback">Delegate used to return the resulting MLResult.Result and list of found PCFs.</param> /// <param name="update">Determines if the PCFs should have their pose updated.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if all the PCFs from the current map have been found successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to no API instance being found. /// </returns> public static MLResult FindPCFsByFilter(QueryFilter queryFilter, OnFoundMultiPCFDelegate callback, bool update = true) { List <PCF> pcfList = new List <PCF>(); if (MLPersistentCoordinateFrames.IsValidInstance()) { NativeBindings.QueryFilterNative queryFilterNative = NativeBindings.QueryFilterNative.Create(); queryFilterNative.Data = queryFilter; MLThreadDispatch.ScheduleWork(() => { if (MLPersistentCoordinateFrames.IsValidInstance()) { try { uint numPCFs = 0; MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameGetCount(MLPersistentCoordinateFrames._instance.nativeTracker, ref numPCFs); MagicLeapNativeBindings.MLCoordinateFrameUID[] cfuidArray = new MagicLeapNativeBindings.MLCoordinateFrameUID[numPCFs]; if (MLResult.IsOK(resultCode) && numPCFs > 0) { //// With these conditions the user is asking for all PCFs, no need to use the slower thised query call. if (queryFilter.TypesMask == (PCF.Types.SingleUserSingleSession | PCF.Types.SingleUserMultiSession | PCF.Types.MultiUserMultiSession) && queryFilter.Radius <= 0 && !queryFilter.Sorted) { resultCode = NativeBindings.MLPersistentCoordinateFrameGetAllEx(_instance.nativeTracker, numPCFs, cfuidArray); } else { resultCode = NativeBindings.MLPersistentCoordinateFrameQuery(_instance.nativeTracker, in queryFilterNative, cfuidArray, out uint cfuidCount); } if (!MLResult.IsOK(resultCode)) { if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize) { MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.FindPCFsByFilter. Reason: {0}", MLResult.CodeToString(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode)); } return(false); } } else { if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize) { MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.FindPCFsByFilter. Reason: {0}", MLResult.CodeToString(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode)); } return(false); } MLThreadDispatch.ScheduleMain(() => { if (MLPersistentCoordinateFrames.IsValidInstance()) { if (MLResult.IsOK(resultCode) && MLPersistentCoordinateFrames.IsLocalized) { for (int i = 0; i < cfuidArray.Length; ++i) { MagicLeapNativeBindings.MLCoordinateFrameUID pcfCFUID = cfuidArray[i]; if (!pcfCFUID.Equals(MagicLeapNativeBindings.MLCoordinateFrameUID.EmptyFrame)) { PCF pcf = null; if (_instance.mapAllPCFs.ContainsKey(pcfCFUID)) { pcf = _instance.mapAllPCFs[pcfCFUID]; if (update) { MLResult result = pcf.Update(); if (!result.IsOk) { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed to update the found PCF with CFUID {0}, Reason: {1}", pcf.CFUID, result); } } } else { pcf = new PCF(pcfCFUID); _instance.mapAllPCFs.Add(pcfCFUID, pcf); pcf.Update(); } pcfList.Add(pcf); } } } callback?.Invoke(resultCode, pcfList); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames."); } }); return(true); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: API symbols not found."); callback?.Invoke(MLResult.Code.UnspecifiedFailure, pcfList); return(true); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames."); callback?.Invoke(MLResult.Code.UnspecifiedFailure, pcfList); return(true); } }); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames."); callback?.Invoke(MLResult.Code.UnspecifiedFailure, pcfList); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }