コード例 #1
0
        /// <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."));
            }
        }
コード例 #2
0
        /// <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");
            }
        }
コード例 #3
0
        /// <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"));
            }
        }
コード例 #4
0
        /// <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;
            }
        }
コード例 #5
0
        /// <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);
            });
        }
コード例 #6
0
            /// <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;
                }
            }
コード例 #7
0
        /// <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");
            }
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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));
        }
コード例 #10
0
        /// <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;
        }
コード例 #11
0
        /// <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);
コード例 #12
0
        /// <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);
        }
コード例 #13
0
        /// <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.");
            }
        }
コード例 #14
0
                /// <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);
                }
コード例 #15
0
        /// <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");
            }
        }
コード例 #16
0
                /// <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);
                }
コード例 #17
0
        /// <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."));
            }
        }
コード例 #18
0
        /// <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));
        }
コード例 #19
0
        /// <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."));
            }
        }
コード例 #20
0
            /// <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;
                }
            }
コード例 #21
0
        /// <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."));
            }
        }
コード例 #22
0
        /// <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");
            }
        }
コード例 #23
0
        /// <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.");
            }
        }
コード例 #24
0
        /// <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"));
            }
        }
コード例 #25
0
            /// <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));
                }
            }
コード例 #26
0
            /// <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."));
                }
            }
コード例 #27
0
        /// <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."));
            }
        }