/// <summary> /// Gets the offset position/rotation values and the PCF of the current Perception root. /// </summary> /// <param name="offsetPosition">Stores the value of the current offset from the root's position.</param> /// <param name="offsetRotation">Stores the value of the current offset from the root's rotation.</param> /// <param name="pcf">Stores the reference to the current root PCF.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.MLPerceptionNotStarted</c> if unable to retrieve the Perception System. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// </returns> public static MLResult GetPerceptionRoot(out Vector3 offsetPosition, out Quaternion offsetRotation, out PCF pcf) { offsetPosition = Vector3.zero; offsetRotation = Quaternion.identity; pcf = new PCF(new MagicLeapNativeBindings.MLCoordinateFrameUID()); if (MLPersistentCoordinateFrames.IsValidInstance()) { try { MLResult.Code resultCode = NativeBindings.MLPerceptionGetRootCoordinateFrame(out MagicLeapNativeBindings.MLCoordinateFrameUID cfuid, out MagicLeapNativeBindings.MLTransform mlTransform); if (MLResult.IsOK(resultCode)) { offsetPosition = MLConvert.ToUnity(mlTransform.Position); offsetRotation = MLConvert.ToUnity(mlTransform.Rotation); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(resultCode)); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Process pending requests and call the callback specified in the startup config. /// </summary> private void ProcessPendingQueries() { try { if (_instance.pendingQueries.Count > 0) { // Process each individual pending query to get updated status. foreach (ulong handle in _instance.pendingQueries.Keys) { NativeBindings.Query query = _instance.pendingQueries[handle]; // Request the update. MLResult.Code resultCode = NativeBindings.MLFoundObjectGetResultCount(_instance.tracker, handle, out uint resultCount); if (MLResult.IsOK(resultCode)) { for (uint objectIndex = 0; objectIndex < resultCount; objectIndex++) { NativeBindings.FoundObjectNative foundObject = new NativeBindings.FoundObjectNative(); resultCode = NativeBindings.MLFoundObjectGetResult(_instance.tracker, handle, objectIndex, ref foundObject); if (MLResult.IsOK(resultCode)) { List <KeyValuePair <string, string> > properties = null; if (foundObject.PropertyCount > 0) { NativeBindings.PropertyNative objectProperty = new NativeBindings.PropertyNative(); properties = new List <KeyValuePair <string, string> >(); for (uint propertyIndex = 0; propertyIndex < foundObject.PropertyCount; propertyIndex++) { resultCode = NativeBindings.MLFoundObjectGetProperty(_instance.tracker, foundObject.Id, propertyIndex, ref objectProperty); if (MLResult.IsOK(resultCode)) { properties.Add(new KeyValuePair <string, string>(new string(objectProperty.Key), new string(objectProperty.Value))); } else { MLPluginLog.ErrorFormat("MLFoundObject.ProcessPendingQueries failed to get found object property. Reason: {0}", MLResult.CodeToString(resultCode)); } } } if (!_instance.completedQueries.ContainsKey(handle)) { _instance.completedQueries.Add(handle, new List <Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > > >()); } _instance.completedQueries[handle].Add(new Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > >( query, new FoundObject { Id = MLConvert.ToUnity(foundObject.Id), PropertyCount = foundObject.PropertyCount, Position = MLConvert.ToUnity(foundObject.Position), Rotation = MLConvert.ToUnity(foundObject.Rotation), Size = MLConvert.ToUnity(foundObject.Size) }, properties)); } else { MLPluginLog.ErrorFormat("MLFoundObject.ProcessPendingQueries failed to get found object. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } } else { MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to query found objects. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } foreach (ulong handle in _instance.errorQueries) { _instance.pendingQueries.Remove(handle); } _instance.errorQueries.Clear(); foreach (KeyValuePair <ulong, List <Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > > > > handle in _instance.completedQueries) { for (int i = 0; i < handle.Value.Count; ++i) { handle.Value[i].Item1.Callback(handle.Value[i].Item2, handle.Value[i].Item3); } _instance.pendingQueries.Remove(handle.Key); } _instance.completedQueries.Clear(); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLFoundObjects.ProcessPendingQueries failed. Reason: API symbols not found"); } }
/// <summary> /// Begin querying for planes. /// </summary> /// <param name="queryParams">All values are required, omitting values may result in unexpected behavior.</param> /// <param name="callback">Callback used to report query results.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> private MLResult BeginPlaneQuery(QueryParams queryParams, QueryResultsDelegate callback) { try { if (!NativeBindings.MLHandleIsValid(_instance.planesTracker)) { MLPluginLog.Error("MLPlanes.BeginPlaneQuery failed to request planes. Reason: Tracker handle is invalid"); return(MLResult.Create(MLResult.Code.InvalidParam)); } bool BeginQuery() { if (MLPlanes.IsValidInstance()) { NativeBindings.QueryParamsNative planeQuery = new NativeBindings.QueryParamsNative() { Data = queryParams }; ulong queryHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLPlanesQueryBegin(_instance.planesTracker, ref planeQuery, ref queryHandle); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed to request planes. Reason: {0}", MLResult.CodeToString(resultCode)); return(true); } // Create query object to prepresent this newly registered plane query. NativeBindings.Query query = new NativeBindings.Query((QueryResultsDelegate)callback, planeQuery.MaxResults, _instance.IsRequestingBoundaries(planeQuery.Flags)); bool GetPlanesResults() { if (MLPlanes.IsValidInstance()) { // Request the update. resultCode = NativeBindings.MLPlanesQueryGetResultsWithBoundaries(_instance.planesTracker, queryHandle, query.PlanesResultsUnmanaged, out uint numResults, ref query.PlaneBoundariesList); if (resultCode == MLResult.Code.Pending) { return(false); } if (resultCode == MLResult.Code.Ok) { query.ExtractPlanesFromQueryResults(numResults); resultCode = NativeBindings.MLPlanesReleaseBoundariesList(_instance.planesTracker, ref query.PlaneBoundariesList); if (resultCode == MLResult.Code.Ok) { query.Result = MLResult.Create(resultCode); if (query.Planes == null) { query.Planes = new Plane[] { }; } if (query.PlaneBoundaries == null) { query.PlaneBoundaries = new Boundaries[] { }; } MLThreadDispatch.ScheduleMain(() => { if (MLPlanes.IsValidInstance()) { callback(query.Result, query.Planes, query.PlaneBoundaries); } else { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed. Reason: No Instance for MLPlanes"); } }); } else { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed to release boundaries list. Reason: {0}", MLResult.CodeToString(resultCode)); } } else { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed to query planes. Reason: {0}", MLResult.CodeToString(resultCode)); } } else { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed. Reason: No Instance for MLPlanes"); } return(true); } MLThreadDispatch.ScheduleWork(GetPlanesResults); } else { MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed. Reason: No Instance for MLPlanes"); } return(true); } MLThreadDispatch.ScheduleWork(BeginQuery); return(MLResult.Create(MLResult.Code.Ok)); } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPlanes.BeginPlaneQuery failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPlanes.BeginPlaneQuery failed. Reason: API symbols not found")); } }
/// <summary> /// Used to safely make native calls. /// </summary> /// <param name="resultCode">MLResult.Code enum that the wrappedPlatformCall should set.</param> /// <param name="platformFunctionName">Name of the function for the log to print on failure.</param> /// <param name="wrappedPlatformCall">Anonymous function for making your native call that you should set resultCode with.</param> /// <param name="successCase">Predicate delegate for determining when a call was successful.</param> /// <param name="checkInstance">Determines if this call should check for a valid instance before running.</param> protected static void PlatformInvoke(out MLResult.Code resultCode, string platformFunctionName, Action wrappedPlatformCall, Predicate <MLResult.Code> successCase = null, bool checkInstance = true) { resultCode = MLResult.Code.UnspecifiedFailure; if (checkInstance && !IsValidInstance()) { MLPluginLog.ErrorFormat("{0} failed. Reason: {1} API has no valid instance.", platformFunctionName, typeof(T).Name); return; } try { wrappedPlatformCall?.Invoke(); bool success = successCase != null?successCase(resultCode) : MLResult.IsOK(resultCode); if (!success) { MLPluginLog.ErrorFormat("{0} failed. Reason: {1}", platformFunctionName, MLResult.CodeToString(resultCode)); } } catch (DllNotFoundException) { MLPluginLog.ErrorFormat("{0} failed. Reason: {1} API is currently available only on device.", platformFunctionName, typeof(T).Name); resultCode = MLResult.Code.APIDLLNotFound; } catch (EntryPointNotFoundException) { MLPluginLog.ErrorFormat("{0} failed. Reason: {1} API symbols not found.", platformFunctionName, typeof(T).Name); resultCode = MLResult.Code.APISymbolsNotFound; } }
/// <summary> /// Process pending requests and call the callback specified in the startup config. /// </summary> private void ProcessPendingQueriesAsync() { MLThreadDispatch.ScheduleWork(() => { try { if (_instance.pendingQueries.Count > 0) { // Process each individual pending query to get updated status. foreach (ulong handle in _instance.pendingQueries.Keys) { // Request the update. MLResult.Code resultCode = NativeBindings.MLFoundObjectGetResultCount(_instance.handle, handle, out uint resultCount); if (MLResult.IsOK(resultCode)) { FoundObject[] foundObjects = new FoundObject[resultCount]; // For each found object in the query, get it's reference and property values from the API. for (uint objectIndex = 0; objectIndex < resultCount; objectIndex++) { NativeBindings.FoundObjectNative nativeFoundObject = new NativeBindings.FoundObjectNative(); // Get the object reference from the API. resultCode = NativeBindings.MLFoundObjectGetResult(_instance.handle, handle, objectIndex, ref nativeFoundObject); if (MLResult.IsOK(resultCode)) { Dictionary <string, string> properties = new Dictionary <string, string>(); // Get the object's properties from the API. if (nativeFoundObject.PropertyCount > 0) { NativeBindings.PropertyNative objectProperty = new NativeBindings.PropertyNative(); for (uint propertyIndex = 0; propertyIndex < nativeFoundObject.PropertyCount; propertyIndex++) { resultCode = NativeBindings.MLFoundObjectGetProperty(_instance.handle, nativeFoundObject.Id, propertyIndex, ref objectProperty); if (MLResult.IsOK(resultCode)) { properties.Add(new string(objectProperty.Key).Replace("\0", string.Empty).ToLower(), new string(objectProperty.Value).Replace("\0", string.Empty)); } else { MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to get found object property. Reason: {0}", MLResult.CodeToString(resultCode)); } } } FoundObject foundObject = nativeFoundObject.Data; // Currently the only valid object properties are: label, score foundObject.Label = properties.ContainsKey("label") ? properties["label"] : string.Empty; foundObject.Confidence = properties.ContainsKey("score") ? Convert.ToSingle(properties["score"]) : 0f; foundObjects[objectIndex] = foundObject; } else { MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to get found object. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } if (!_instance.completedQueries.Contains(handle)) { _instance.completedQueries.Add(handle); } Query query = _instance.pendingQueries[handle]; // Dispatch list of found objects back to main. MLThreadDispatch.ScheduleMain(() => { query.Callback(MLResult.Create(resultCode), foundObjects); }); } else { MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to query found objects. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } foreach (ulong handle in _instance.errorQueries) { _instance.pendingQueries.TryRemove(handle, out Query q); } _instance.errorQueries.Clear(); foreach (ulong handle in _instance.completedQueries) { _instance.pendingQueries.TryRemove(handle, out Query q); } _instance.completedQueries.Clear(); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLFoundObjects.ProcessPendingQueries failed. Reason: API symbols not found"); } return(true); }); }
/// <summary> /// Queries a profile for a list of attribute values asynchronously. /// </summary> private void RequestAttributeValuesAsync() { MLResult.Code resultCode = MLIdentity.NativeBindings.RequestAttributeValuesAsync(this, ref this.attributes); if (MLResult.IsOK(resultCode)) { this.request.RequestState = Request.State.LISTENING_ATTRIB_VALUES; } else { MLPluginLog.WarningFormat("MLIdentity.Profile.RequestAttributeValuesAsync failed request for attribute values async. Reason: {0}", MLResult.CodeToString(resultCode)); this.request.RequestState = Request.State.DONE; } }
/// <summary> /// Polls for the result of pending ray cast requests. /// </summary> protected override void Update() { try { if (_instance.pendingQueries.Count > 0) { foreach (ulong handle in _instance.pendingQueries.Keys) { NativeBindings.MLRaycastResultNative raycastResult = NativeBindings.MLRaycastResultNative.Create(); MLResult.Code resultCode = NativeBindings.MLRaycastGetResult(_instance.trackerHandle, handle, ref raycastResult); if (resultCode == MLResult.Code.Ok) { _instance.completedQueries.Add(handle, raycastResult); } else if (resultCode != MLResult.Code.Pending) { MLPluginLog.ErrorFormat("MLRaycast.Update failed to get raycast result. Reason: {0}", MLResult.CodeToString(resultCode)); _instance.errorQueries.Add(handle); } } foreach (ulong handle in _instance.errorQueries) { _instance.pendingQueries.Remove(handle); } _instance.errorQueries.Clear(); foreach (KeyValuePair <ulong, NativeBindings.MLRaycastResultNative> handle in _instance.completedQueries) { // Check if there is a valid hit result. bool didHit = handle.Value.State != ResultState.RequestFailed && handle.Value.State != ResultState.NoCollision; _instance.pendingQueries[handle.Key]( handle.Value.State, didHit ? MLConvert.ToUnity(handle.Value.Hitpoint) : Vector3.zero, didHit ? MLConvert.ToUnity(handle.Value.Normal, true, false) : Vector3.zero, handle.Value.Confidence); _instance.pendingQueries.Remove(handle.Key); } _instance.completedQueries.Clear(); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLRaycast.Update failed. Reason: API symbols not found"); } }
/// <summary> /// Updates the settings of the found objects tracker. /// </summary> /// <param name="newSettings">The new settings to update the found objects tracker with.</param> /// <param name="callback">The callback to invoke when the settings have been updated or failed doing so.</param> /// <returns> /// MLResult.Result inside callback will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result inside callback will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result inside callback will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult UpdateSettingsAsync(Settings newSettings, OnUpdateSettingsDelegate callback = null) { MLResult result = MLResult.Create(MLResult.Code.Ok); MLThreadDispatch.ScheduleWork(() => { if (MLFoundObjects.IsValidInstance()) { NativeBindings.Settings settingsNative = new NativeBindings.Settings(); settingsNative.Data = newSettings; MLResult.Code resultCode = NativeBindings.MLFoundObjectTrackerUpdateSettings(_instance.handle, in settingsNative); if (MLResult.IsOK(resultCode)) { MLThreadDispatch.ScheduleMain(() => { result = MLResult.Create(resultCode); _instance.settings = newSettings; callback?.Invoke(result, _instance.settings); }); } else { MLPluginLog.ErrorFormat("MLFoundObjects.UpdateSettingsAsync failed to update settings. Reason: {0}", MLResult.CodeToString(resultCode)); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("MLFoundObjects.UpdateSettingsAsync failed to update settings. Reason: {0}", MLResult.CodeToString(resultCode))); MLThreadDispatch.ScheduleMain(() => { callback?.Invoke(result, _instance.settings); }); } } else { MLPluginLog.ErrorFormat("MLFoundObjects.GetObjects failed. Reason: No Instance for MLFoundObjects"); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLFoundObjects.GetFoundObjects failed. Reason: No Instance for MLFoundObjects"); MLThreadDispatch.ScheduleMain(() => { callback?.Invoke(result, _instance.settings); }); } return(true); }); return(result); }
/// <summary> /// Called by MLAPISingleton to start the API /// </summary> /// <returns> /// <para>MLResult.Result will be <c>MLResult.Code.AllocFailed</c> if the registration resource allocation failed.</para> /// <para>MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if a given argument is invalid.</para> /// <para>MLResult.Result will be <c>MLResult.Code.Ok</c> if successfully initialized.</para> /// <para>MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an unexpected failure.</para> /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsAlreadyRegistered</c> if this is a duplicate registration.</para> /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsNetworkFailure</c> if communication to the network failed.</para> /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsSystemFailure</c> if there was system failure.</para> /// </returns> protected override MLResult StartAPI() { MLResult.Code resultCode = NativeBindings.MLConnectionsRegistrationStartup(ref _instance.registerHandle); if (!MLResult.IsOK(resultCode) || !Native.MagicLeapNativeBindings.MLHandleIsValid(_instance.registerHandle)) { MLResult resultError = MLResult.Create(resultCode); MLPluginLog.ErrorFormat("MLConnections.Start failed in StartAPI() to register to receive invites. Handle is invalid or Reason: {0}", resultError); return(resultError); } NativeBindings.InviteCallbacks connectionCallbacks = NativeBindings.InviteCallbacks.Create(); resultCode = NativeBindings.MLConnectionsRegisterForInvite(_instance.registerHandle, connectionCallbacks, IntPtr.Zero); if (!MLResult.IsOK(resultCode)) { MLResult resultError = MLResult.Create(resultCode); MLPluginLog.ErrorFormat("MLConnections.Start failed in StartAPI() to set callbacks. Reason: {0}", resultError); return(resultError); } else { if (_instance.activeRequest) { // This check is just precautionary, but it should never happen. MLPluginLog.WarningFormat("MLConnections.Start allowed multiple active registrations."); } Instance.activeRequest = true; } resultCode = NativeBindings.MLConnectionsStartup(); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLConnections.Start failed in StartAPI() to initialize resources for sending an invite. Reason: {0}", MLResult.CodeToString(resultCode)); } else { _instance.sendInviteHasStarted = true; } return(MLResult.Create(resultCode)); }
/// <summary> /// Called by MLAPISingleton on destruction /// </summary> /// <param name="isSafeToAccessManagedObjects">Used for cleanup</param> protected override void CleanupAPI(bool isSafeToAccessManagedObjects) { if (Native.MagicLeapNativeBindings.MLHandleIsValid(this.registerHandle)) { MLResult.Code resultCode = NativeBindings.MLConnectionsRegistrationShutdown(this.registerHandle); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLConnections.Stop failed in CleapupAPI() to shutdown registration to receive invites. Reason: {0}", MLResult.CodeToString(resultCode)); } } // Shutdown should only be called if Startup was successful. if (this.sendInviteHasStarted) { MLResult.Code shutdownResultCode = NativeBindings.MLConnectionsShutdown(); if (!MLResult.IsOK(shutdownResultCode)) { MLPluginLog.ErrorFormat("MLConnections.Stop failed in CleapupAPI() to deinitialize all resources used for sending an invite. Reason: {0}", MLResult.CodeToString(shutdownResultCode)); } } this.registerHandle = Native.MagicLeapNativeBindings.InvalidHandle; this.activeRequest = false; this.sendInviteHasStarted = false; }
/// <summary> /// Poll the native API for barcode scanner results. /// </summary> /// <returns> /// An array of BarcodeData that contains the results /// that the scanner has collected since the last call to this function. This array /// may be empty if there are no new results. /// </returns> private static List <BarcodeData> MLBarcodeScannerGetResults() { try { // get results from native api MLResult.Code resultCode = NativeBindings.MLBarcodeScannerGetResult(Instance.Handle, out NativeBindings.MLBarcodeScannerResultArray scannerResults); if (MLResult.IsOK(resultCode)) { var managedResults = new List <BarcodeData>((int)scannerResults.Count); for (int i = 0; i < scannerResults.Count; i++) { // marshal native array into native structs long address = scannerResults.Detections.ToInt64() + (Marshal.SizeOf <IntPtr>() * i); NativeBindings.MLBarcodeScannerResult detectedResult = Marshal.PtrToStructure <NativeBindings.MLBarcodeScannerResult>(Marshal.ReadIntPtr(new IntPtr(address))); MLPluginLog.Debug($"MLBarcodeScanner results found: {detectedResult}"); // create managed version of data UnityEngine.Pose pose; if (((BarcodeType)detectedResult.Type) == BarcodeType.QR) { if (!MagicLeapNativeBindings.UnityMagicLeap_TryGetPose(detectedResult.CoordinateFrameUID, out pose)) { MLPluginLog.Error($"Barcode Scanner could not get pose data for coordinate frame id '{detectedResult.CoordinateFrameUID}'"); pose = Pose.identity; } } else { pose = Pose.identity; } managedResults.Add ( BarcodeData.Create ( (BarcodeType)detectedResult.Type, pose, detectedResult.DecodedData.Data, detectedResult.DecodedData.Size, detectedResult.ReprojectionError ) ); } // release native memory so results can be polled again if (MLResult.IsOK(NativeBindings.MLBarcodeScannerReleaseResult(scannerResults))) { return(managedResults); } else { MLPluginLog.Error($"MLBarcodeScanner.NativeBindings.MLBarcodeScannerReleaseResult failed when trying to release the results' memory. Reason: {MLResult.CodeToString(resultCode)}"); return(managedResults); } } else { MLPluginLog.Error($"MLBarcodeScanner.MLBarcodeScannerGetResult failed to obtain a result. Reason: {resultCode}"); return(default);
/// <summary> /// Checks native code results for failure. /// </summary> /// <param name="resultCode"> The result of the native function call. </param> /// <param name="functionName"> The name of the native function. </param> /// <param name="successCase"> /// Predicate delegate for determining when a call was successful. /// Defaults to a check against <c>MLResult.IsOK(resultCode)</c>. /// </param> /// <param name="showError"> /// Should the default error message be displayed /// if the <c>resultCode</c> is not expected? /// </param> /// <returns> /// <c>true</c> if the result of <c>successCase</c> matches <c>resultCode</c>. /// <c>false</c> otherwise. /// </returns> protected static bool DidNativeCallSucceed(MLResult.Code resultCode, string functionName = "A native function", Predicate <MLResult.Code> successCase = null, bool showError = true) { bool success = successCase != null?successCase(resultCode) : MLResult.IsOK(resultCode); if (!success && showError) { MLPluginLog.ErrorFormat($"{functionName} in the Magic Leap API failed. Reason: {MLResult.CodeToString(resultCode)} "); } return(success); }
/// <summary> /// Sets the localization status based on if PCFs can currently be found /// </summary> private void SetLocalizationStatus() { if (MLPersistentCoordinateFrames.IsValidInstance()) { try { MLResult result = MLResult.Create(MLResult.Code.Ok); uint numPCFs = 0; MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameGetCount(MLPersistentCoordinateFrames._instance.nativeTracker, ref numPCFs); if (!MLResult.IsOK(resultCode)) { if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize) { MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.SetLocalizationStatus. Reason: {0}", MLResult.CodeToString(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode)); } result = MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode))); } bool foundPCFs = result.IsOk && numPCFs > 0; if (!MLPersistentCoordinateFrames.IsLocalized && foundPCFs) { MLPersistentCoordinateFrames.IsLocalized = true; MLPersistentCoordinateFrames.OnLocalized?.Invoke(IsLocalized); } else if (MLPersistentCoordinateFrames.IsLocalized && !foundPCFs) { List <PCF> allPCFs = new List <PCF>(MLPersistentCoordinateFrames._instance.mapAllPCFs.Values); MLPersistentCoordinateFrames._instance.mapTrackedPCFs.Clear(); MLPersistentCoordinateFrames._instance.mapAllPCFs.Clear(); MLPersistentCoordinateFrames.IsLocalized = false; foreach (PCF pcf in allPCFs) { pcf.Update(); } MLPersistentCoordinateFrames._instance.mapUpdatedPCFsThisFrame.Clear(); MLPersistentCoordinateFrames.OnLocalized?.Invoke(MLPersistentCoordinateFrames.IsLocalized); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: API symbols not found."); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: No Instance for MLPersistentCoordinateFrames."); } }
/// <summary> /// Gets a managed operation result for a specific operation handle. /// </summary> /// <param name="handle">Handle to a specific operation.</param> /// <param name="result">Managed operation result.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if any of the parameters are invalid. /// MLResult.Result will be <c>MLResult.Code.Pending</c> if the request is still pending. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// MLResult.Result will be <c>MLResult.Code.ContactsCompleted</c> if the request is completed. /// MLResult.Result will be <c>MLResult.Code.ContactsHandleNotFound</c> if the request corresponding to the handle was not found. /// </returns> public static MLResult.Code GetManagedOperationResult(ulong handle, out MLContacts.OperationResult result) { MLResult.Code resultCode = NativeBindings.MLContactsTryGetOperationResult(handle, out IntPtr operationResultPtr); if (resultCode != MLResult.Code.Pending) { if (resultCode != MLResult.Code.ContactsCompleted) { MLPluginLog.ErrorFormat("NativeBindings.GetManagedOperationResult failed to get operation result. Reason: {0}", MLResult.CodeToString(resultCode)); } NativeBindings.OperationResultNative internalResult = (NativeBindings.OperationResultNative)Marshal.PtrToStructure(operationResultPtr, typeof(NativeBindings.OperationResultNative)); NativeBindings.ContactNative internalContact = (NativeBindings.ContactNative)Marshal.PtrToStructure(internalResult.Contact, typeof(NativeBindings.ContactNative)); result = new MLContacts.OperationResult() { Status = internalResult.Status, Contact = internalContact.Data, }; } else { result = new MLContacts.OperationResult(); } return(resultCode); }
/// <summary> /// Cleans up unmanaged memory. /// </summary> /// <param name="isSafeToAccessManagedObjects">Boolean that tells if it is safe to clear managed memory</param> protected override void CleanupAPI(bool isSafeToAccessManagedObjects) { try { if (isSafeToAccessManagedObjects) { _instance.currentRequests.Clear(); } MLResult.Code resultCode = NativeBindings.MLPrivilegesShutdown(); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLPrivileges.CleanupAPI failed to shutdown. Reason: {0}", MLResult.CodeToString(resultCode)); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPrivileges.CleanupAPI failed. Reason: API symbols not found"); } }
/// <summary> /// Gets a managed operation result for a specific operation handle. /// </summary> /// <param name="handle">Handle to a specific operation.</param> /// <param name="listResult">Managed operation result.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if any of the parameters are invalid. /// MLResult.Result will be <c>MLResult.Code.Pending</c> if the request is still pending. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// MLResult.Result will be <c>MLResult.Code.ContactsCompleted</c> if the request is completed. /// MLResult.Result will be <c>MLResult.Code.ContactsHandleNotFound</c> if the request corresponding to the handle was not found. /// </returns> public static MLResult.Code GetManagedListResult(ulong handle, out MLContacts.ListResult listResult) { MLResult.Code resultCode = NativeBindings.MLContactsTryGetListResult(handle, out IntPtr operationResultPtr); if (resultCode != MLResult.Code.Pending) { if (resultCode != MLResult.Code.ContactsCompleted) { MLPluginLog.ErrorFormat("NativeBindings.GetManagedListResult failed to get list result. Reason: {0}", MLResult.CodeToString(resultCode)); } NativeBindings.ListResultNative internalListResult = (NativeBindings.ListResultNative)Marshal.PtrToStructure(operationResultPtr, typeof(NativeBindings.ListResultNative)); listResult = new MLContacts.ListResult() { Status = internalListResult.Status, List = internalListResult.List.Data, Offset = Marshal.PtrToStringAnsi(internalListResult.Offset), TotalHits = internalListResult.TotalHits, }; } else { listResult = new MLContacts.ListResult(); } return(resultCode); }
/// <summary> /// Retrieves the type of the PCF associated with the given CFUID. /// </summary> /// <param name="cfuid">The CFUID to look up the PCF type with.</param> /// <param name="type">Stores the type of PCF associated with the given CFUID.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if a valid PCF was found. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to an invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map. /// MLResult.Result will be <c>MLResult.Code.PassableWorldNotFound</c> if the passed CFUID is not available. /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map. /// </returns> public static MLResult GetPCFTypeByCFUID(MagicLeapNativeBindings.MLCoordinateFrameUID cfuid, out PCF.Types type) { type = 0; if (MLPersistentCoordinateFrames.IsValidInstance()) { try { NativeBindings.FrameStateNative nativeState = NativeBindings.FrameStateNative.Create(); MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFramesGetFrameState(_instance.nativeTracker, in cfuid, ref nativeState); if (!MLResult.IsOK(resultCode)) { if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize) { MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.GetPCFTypeByCFUID. Reason: {0}", MLResult.CodeToString(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: {0}", MLResult.CodeToString(resultCode)); } return(MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: {0}", MLResult.CodeToString(resultCode)))); } else { type = nativeState.Type; return(MLResult.Create(resultCode)); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Request the list of detected found objects. /// Callback will never be called while request is still pending. /// </summary> /// <param name="callback"> /// Callback used to report query results. /// Callback MLResult code will never be <c>MLResult.Code.Pending</c>. /// </param> /// <returns> /// MLResult.Result inside callback will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result inside callback will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result inside callback will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult GetUniqueObjectLabelsAsync(OnGetUniqueObjectLabelsDelegate callback) { MLThreadDispatch.ScheduleWork(() => { string[] labels; MLResult result = MLResult.Create(MLResult.Code.Ok); if (MLFoundObjects.IsValidInstance()) { MLResult.Code resultCode = NativeBindings.MLFoundObjectGetAvailableLabelsCount(_instance.handle, out uint labelCount); result = MLResult.Create(resultCode); labels = new string[labelCount]; if (MLResult.IsOK(resultCode)) { for (uint i = 0; i < labelCount; ++i) { resultCode = NativeBindings.MLFoundObjectGetUniqueLabel(_instance.handle, i, 20, out string label); if (MLResult.IsOK(resultCode)) { labels[i] = label; } else { MLPluginLog.ErrorFormat("MLFoundObjects.GetUniqueObjectLabels failed getting a unique label. Reason: {0}", MLResult.CodeToString(resultCode)); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("MLFoundObjects.GetUniqueObjectLabels failed getting a unique label. Reason: {0}", MLResult.CodeToString(resultCode))); } } } else { MLPluginLog.ErrorFormat("MLFoundObjects.GetUniqueObjectLabels failed getting the unique label count. Reason: {0}", MLResult.CodeToString(resultCode)); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("MLFoundObjects.GetUniqueObjectLabels failed getting the unique label count. Reason: {0}", MLResult.CodeToString(resultCode))); } } else { labels = new string[0]; MLPluginLog.ErrorFormat("MLFoundObjects.GetUniqueObjectLabelsAsync failed. Reason: No Instance for MLFoundObjects."); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLFoundObjects.GetUniqueObjectLabelsAsync failed. Reason: No Instance for MLFoundObjects"); } MLThreadDispatch.ScheduleMain(() => { callback?.Invoke(result, labels); }); return(true); }); return(MLResult.Create(MLResult.Code.Ok)); }
/// <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="pcfList">Stores the resulting list of 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.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map. /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map. /// </returns> public static MLResult FindPCFsByFilter(QueryFilter queryFilter, out List <PCF> pcfList, bool update = true) { pcfList = new List <PCF>(); if (MLPersistentCoordinateFrames.IsValidInstance()) { try { uint numPCFs = 0; MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameGetCount(_instance.nativeTracker, ref numPCFs); if (MLResult.IsOK(resultCode) && numPCFs > 0) { MagicLeapNativeBindings.MLCoordinateFrameUID[] cfuidArray = new MagicLeapNativeBindings.MLCoordinateFrameUID[numPCFs]; NativeBindings.QueryFilterNative queryFilterNative = NativeBindings.QueryFilterNative.Create(); queryFilterNative.Data = queryFilter; uint cfuidCount = 0; //// With these conditions the user is asking for all PCFs, no need to use the slower filtered 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); cfuidCount = (uint)cfuidArray.Length; } else { resultCode = NativeBindings.MLPersistentCoordinateFrameQuery(_instance.nativeTracker, in queryFilterNative, cfuidArray, out cfuidCount); } if (MLResult.IsOK(resultCode)) { for (int i = 0; i < cfuidCount; ++i) { MagicLeapNativeBindings.MLCoordinateFrameUID pcfCFUID = cfuidArray[i]; if (!pcfCFUID.Equals(MagicLeapNativeBindings.MLCoordinateFrameUID.EmptyFrame)) { PCF pcf = null; if (_instance.mapAllPCFs.ContainsKey(pcfCFUID)) { pcf = _instance.mapAllPCFs[pcfCFUID]; } else { pcf = new PCF(pcfCFUID); _instance.mapAllPCFs.Add(pcfCFUID, pcf); } pcfList.Add(pcf); 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); } } } } return(MLResult.Create(MLResult.Code.Ok)); } 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.CodeToString(resultCode)); } return(MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: {0}", MLResult.CodeToString(resultCode)))); } } 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(MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode)))); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.FindPCFsByFilter failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Queries a profile for a list of attribute names asynchronously. /// </summary> private void RequestAttributeNamesAsync() { MLResult.Code resultCode = MLIdentity.NativeBindings.RequestAttributeNamesAsync(this, this.requestAttributes, ref this.attributes); if (MLResult.IsOK(resultCode)) { this.request.ResultCode = MLResult.Code.Pending; this.request.RequestState = (this.requestAttributes != null && this.requestAttributes.Length > 0) ? MLIdentity.Profile.Request.State.REQUEST_ATTRIB_VALUES : MLIdentity.Profile.Request.State.LISTENING_ATTRIB_NAMES; } else { MLPluginLog.WarningFormat("MLIdentity.Profile.RequestAttributeNamesAsync failed request for attribute names async. Reason: {0}", MLResult.CodeToString(resultCode)); this.request.ResultCode = resultCode; this.request.RequestState = MLIdentity.Profile.Request.State.DONE; } }
/// <summary> /// Starts the Persistent Coordinate Frames API. /// Initializes the PCF tracker. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the PCF tracker could be created successfully. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the tracker to initialize was null. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there were any missing privileges. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to an internal error. /// </returns> protected override MLResult StartAPI() { try { MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameTrackerCreate(ref _instance.nativeTracker); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.StartAPI failed to create PCF tracker. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(resultCode, "MLPersistentCoordinateFrames.StartAPI failed to create PCF tracker.")); } return(MLResult.Create(resultCode)); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.StartAPI failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.StartAPI failed. Reason: API symbols not found.")); } }
/// <summary> /// Destroy the planes native tracker. /// </summary> private void DestroyNativeTracker() { try { if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.planesTracker)) { return; } MLResult.Code resultCode = NativeBindings.MLPlanesDestroy(_instance.planesTracker); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLPlanes.DestroyNativeTracker failed to destroy planes tracker. Reason: {0}", MLResult.CodeToString(resultCode)); } _instance.planesTracker = MagicLeapNativeBindings.InvalidHandle; } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPlanes.DestroyNativeTracker failed. Reason: API symbols not found"); } }
/// <summary> /// Cleans up unmanaged memory. /// </summary> /// <param name="isSafeToAccessManagedObjects">Determines if the pendingPCFPoseQueries list should be cleared.</param> protected override void CleanupAPI(bool isSafeToAccessManagedObjects) { if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.nativeTracker)) { return; } try { MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameTrackerDestroy(_instance.nativeTracker); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.CleanupAPI failed to destroy PersistentCoordinateFrame tracker. Reason: {0}", MLResult.CodeToString(resultCode)); } _instance.nativeTracker = MagicLeapNativeBindings.InvalidHandle; } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.CleanupAPI failed. Reason: API symbols not found."); } }
/// <summary> /// Requests a ray cast with the given query parameters. /// </summary> /// <param name="query">Query parameters describing ray being cast.</param> /// <param name="callback">Delegate which will be called when the result of the ray cast is ready.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult Raycast(QueryParams query, OnRaycastResultDelegate callback) { try { if (MLRaycast.IsValidInstance()) { if (query == null || callback == null) { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: Invalid input parameters."); return(MLResult.Create(MLResult.Code.InvalidParam)); } bool RequestRaycast() { if (MLRaycast.IsValidInstance()) { NativeBindings.MLRaycastQueryNative queryNative = new NativeBindings.MLRaycastQueryNative() { Position = MLConvert.FromUnity(query.Position), Direction = MLConvert.FromUnity(query.Direction, true, false), UpVector = MLConvert.FromUnity(query.UpVector, true, false), Width = query.Width, Height = query.Height, HorizontalFovDegrees = query.HorizontalFovDegrees, CollideWithUnobserved = query.CollideWithUnobserved, }; ulong requestHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLRaycastRequest(_instance.trackerHandle, ref queryNative, ref requestHandle); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed to request a new ray cast. Reason: {0}", MLResult.CodeToString(resultCode)); return(true); } if (requestHandle == MagicLeapNativeBindings.InvalidHandle) { MLPluginLog.Error("MLRaycast.Raycast failed to request a new ray cast. Reason: Request handle is invalid."); return(true); } bool GetRaycastResults() { if (MLRaycast.IsValidInstance()) { NativeBindings.MLRaycastResultNative raycastResult = NativeBindings.MLRaycastResultNative.Create(); resultCode = NativeBindings.MLRaycastGetResult(_instance.trackerHandle, requestHandle, ref raycastResult); if (resultCode == MLResult.Code.Pending) { return(false); } if (resultCode == MLResult.Code.Ok) { // Check if there is a valid hit result. bool didHit = raycastResult.State != ResultState.RequestFailed && raycastResult.State != ResultState.NoCollision; MLThreadDispatch.ScheduleMain(() => { if (MLRaycast.IsValidInstance()) { callback( raycastResult.State, didHit ? MLConvert.ToUnity(raycastResult.Hitpoint) : Vector3.zero, didHit ? MLConvert.ToUnity(raycastResult.Normal, true, false) : Vector3.zero, raycastResult.Confidence); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } }); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed to get raycast result. Reason: {0}", MLResult.CodeToString(resultCode)); } } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } return(true); } MLThreadDispatch.ScheduleWork(GetRaycastResults); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); } return(true); } MLThreadDispatch.ScheduleWork(RequestRaycast); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLRaycast.Raycast failed. Reason: No Instance for MLRaycast"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLRaycast.Raycast failed. Reason: No Instance for MLRaycast")); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLRaycast.Raycast failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLRaycast.Raycast failed. Reason: API symbols not found")); } }
/// <summary> /// Fetches client credentials, can be used with a callback or as a blocking call. /// </summary> /// <param name="callback">The callback to notify when the CurrentRequest is complete.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the out_credentials was 0 (null). /// MLResult.Result will be <c>MLResult.Code.AllocFailed</c> if the operation failed to allocate memory. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if the caller does not have the ClientCredentialsRead privilege. /// MLResult.Result will be <c>MLResult.Code.TokenAgent*</c> if a token specific failure occurred during the operation. /// </returns> public MLResult Fetch(MLTokenAgent.ClientCredentials.Request.RequestAttibutesDelegate callback = null) { if (callback == null) { MLResult.Code resultCode = MLTokenAgent.NativeBindings.GetClientCredentials(this, ref this.credentials, ref this.tokens); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLTokenAgent.Fetch failed. Reason: {0}", MLResult.CodeToString(resultCode)); } return(MLResult.Create(resultCode)); } else { this.CurrentRequest = new Request { Callback = callback, ResultCode = MLResult.Code.Pending, RequestState = Request.State.REQUEST_CREDENTIALS }; MLTokenAgent.AddClientCredentials(this); return(MLResult.Create(MLResult.Code.Ok)); } }
/// <summary> /// Updates the state of the PCF. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to an invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privileges. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map. /// MLResult.Result will be <c>MLResult.Code.PassableWorldNotFound</c> if the passed CFUID is not available. /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map. /// </returns> private MLResult UpdateState() { if (MLPersistentCoordinateFrames.IsValidInstance()) { try { NativeBindings.FrameStateNative nativeState = NativeBindings.FrameStateNative.Create(); MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFramesGetFrameState(MLPersistentCoordinateFrames._instance.nativeTracker, in this.cfuid, ref nativeState); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("PCF.UpdateState failed to get frame state. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(resultCode, string.Format("PCF.UpdateState failed to get frame state. Reason: {0}", MLResult.CodeToString(resultCode)))); } this.FrameState = nativeState.Data(); return(MLResult.Create(resultCode)); } catch (EntryPointNotFoundException) { MLPluginLog.Error("PCF.UpdateState failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.UpdateState failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("PCF.UpdateState failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.UpdateState failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Sets the offset position/rotation values from the current Perception root and can also set the PCF to be used as the new Perception root to which all MLSnapshotGetTransform will be relative to. /// </summary> /// <param name="offsetPosition">The offset to set from the root's position.</param> /// <param name="offsetRotation">The offset to set from the root's rotation.</param> /// <param name="pcf">The PCF to set the root to.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.MLPerceptionNotStarted</c> if unable to retrieve the Perception System. /// MLResult.Result will be <c>MLResult.Code.MLPerceptionInvalidPCFRoot</c> if the provided CFUID is not associated with a valid PCF. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the CFUID is not valid. /// </returns> public static MLResult SetPerceptionRoot(Vector3 offsetPosition, Quaternion offsetRotation, PCF pcf = null) { if (MLPersistentCoordinateFrames.IsValidInstance()) { MLResult.Code resultCode = NativeBindings.SetPerceptionRoot(offsetPosition, offsetRotation, pcf); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode)))); } return(MLResult.Create(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }