/// <summary> /// Handle the privilege states. /// </summary> private void UpdatePrivilege() { switch (_state) { /// Privilege API has been started successfully, ready to make requests. case PrivilegeState.Started: { RequestPrivileges(); break; } /// Privilege requests have been made, wait until all privileges are granted before enabling the feature that requires privileges. case PrivilegeState.Requested: { foreach (MLPrivileges.Id priv in _privilegesToRequest) { if (!_privilegesGranted.Contains(priv)) { return; } } _state = PrivilegeState.Succeeded; #if PLATFORM_LUMIN OnPrivilegesDone(MLResult.Create(MLResult.Code.Ok)); #endif break; } /// Privileges have been denied, respond appropriately. case PrivilegeState.Failed: { #if PLATFORM_LUMIN OnPrivilegesDone(MLResult.Create(MLResult.Code.PrivilegeDenied)); #endif enabled = false; break; } } }
/// <summary> /// Having made a call to MLTokenAgentGetClientCredentialsAsync(), the user can call MLTokenAgentGetClientCredentialsWait() /// to detect whether the asynchronous call completed and if so, to retrieve the credentials in out_credentials. /// </summary> /// <param name="clientCredentials">Reference to the clientCredentials object.</param> /// <param name="credentials">Reference to the credentials struct of the clientCredentials object.</param> /// <param name="tokens">Reference to the tokens struct of the clientCredentials object.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the operation completed successfully before the timeout elapsed. /// MLResult.Result will be <c>MLResult.Code.Pending</c> if the timeout elapsed before the asynchronous call completed. /// 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 future or out_credentials were 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 static MLResult.Code ListenClientCredentialsResponse(MLTokenAgent.ClientCredentials clientCredentials, ref MLTokenAgent.Credentials credentials, ref MLTokenAgent.Tokens tokens) { try { IntPtr clientCredentialsPtr = clientCredentialsPtrMap.ContainsKey(clientCredentials) ? clientCredentialsPtrMap[clientCredentials] : IntPtr.Zero; IntPtr clientCredentialsFuturePtr = clientCredentialsFuturePtrMap.ContainsKey(clientCredentials) ? clientCredentialsFuturePtrMap[clientCredentials] : IntPtr.Zero; if (clientCredentialsFuturePtr == IntPtr.Zero) { MLPluginLog.Warning("MLTokenAgent.NativeBindings.ListenClientCredentialsResponse failed because a valid future pointer could not be found with the passed request."); return(MLResult.Code.UnspecifiedFailure); } //// Attempt to get data if available, 0 is passed as a timeout to immediately return and never wait for results. MLResult.Code resultCode = MLTokenAgent.NativeBindings.MLTokenAgentGetClientCredentialsWait(clientCredentialsFuturePtr, 0, ref clientCredentialsPtr); // If it succeeded, copy any modifications made to the profile in unmanaged memory by the Identity API to managed memory. if (MLResult.IsOK(resultCode)) { clientCredentialsFuturePtrMap.Remove(clientCredentials); clientCredentialsPtrMap.Remove(clientCredentials); clientCredentialsPtrMap.Add(clientCredentials, clientCredentialsPtr); MLTokenAgent.NativeBindings.ClientCredentialsNative clientCredentialsNative = (MLTokenAgent.NativeBindings.ClientCredentialsNative)Marshal.PtrToStructure(clientCredentialsPtr, typeof(MLTokenAgent.NativeBindings.ClientCredentialsNative)); credentials = clientCredentialsNative.Credentials; tokens = clientCredentials.Tokens; } else { credentials = new Credentials(); tokens = new Tokens(); } return(resultCode); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLTokenAgent.NativeBindings.ListenClientCredentialsResponse failed. Reason: API symbols not found."); return(MLResult.Code.UnspecifiedFailure); } }
/// <summary> /// Handles when a request queries the attribute names. /// </summary> public void ProcessRequest() { if (this.request == null) { return; } switch (this.request.RequestState) { case Request.State.REQUEST_ATTRIB_NAMES: this.RequestAttributeNamesAsync(); break; case Request.State.LISTENING_ATTRIB_NAMES: this.ListenAttributeNamesResponse(); break; case Request.State.REQUEST_ATTRIB_VALUES: this.RequestAttributeValuesAsync(); break; case Request.State.LISTENING_ATTRIB_VALUES: this.ListenAttributeValuesResponse(); break; case Request.State.DONE: this.request?.Callback?.Invoke(MLResult.Create(this.request.ResultCode)); //// Removes the profile if something when wrong with the request. if (!MLResult.IsOK(this.request.ResultCode)) { this.request = null; MLIdentity.RemoveProfile(this); } this.request = null; break; default: break; } }
private MLResult InternalUpdateWatchHistory(MLScreensWatchHistoryEntry entry, Texture2D thumbnailImage) { if (!entry.IsValid) { return(MLResult.Create(MLResult.Code.InvalidParam, "Invalid entry parameter")); } if (!_watchHistory.ContainsKey(entry.Id)) { return(MLResult.Create(MLResult.Code.InvalidParam, "Unknown entry Id")); } if (thumbnailImage != null && thumbnailImage.format != TextureFormat.RGB24) { return(MLResult.Create(MLResult.Code.InvalidParam, "Invalid thumbnail parameter format")); } MLScreensNativeBindings.MLScreensWatchHistoryEntryNative nativeEntry = MLScreensNativeBindings.MLScreensWatchHistoryEntryNative.Create(); nativeEntry.Data = entry; MLImageNativeBindings.MLImageNative thumbnail = thumbnailImage == null ? _defaultGrayThumbnailImage : CreateThumbnailImage(thumbnailImage); MLResult.Code resultCode = MLScreensNativeBindings.MLScreensUpdateWatchHistoryEntry(ref nativeEntry, ref thumbnail); if (thumbnail.Image != IntPtr.Zero && thumbnail.Image != _defaultGrayThumbnailImage.Image) { Marshal.FreeHGlobal(thumbnail.Image); } Marshal.FreeHGlobal(nativeEntry.Title); Marshal.FreeHGlobal(nativeEntry.Subtitle); Marshal.FreeHGlobal(nativeEntry.CustomData); var result = MLResult.Create(resultCode); if (result.IsOk) { _watchHistory[entry.Id] = entry; } return(result); }
/// <summary> /// Fetch the specified attributes and callback when result is known. /// </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 there was an internal error. /// </returns> public MLResult Fetch(Request.RequestAttibutesDelegate callback) { if (this.CurrentRequest != null) { MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Already fetching attributes"); MLPluginLog.ErrorFormat("MLIdentity.Profile.Fetch failed. Reason: {0}", result); return(result); } this.CurrentRequest = new Request { Callback = callback, ResultCode = MLResult.Code.Pending, RequestState = Request.State.REQUEST_ATTRIB_NAMES, }; MLIdentity.AddProfile(this); return(MLResult.Create(MLResult.Code.Ok)); }
/// <summary> /// Set the longer dimension of the image target. /// </summary> /// <param name="longerDimension"> Longer dimension in scene units. Default is meters.</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 internal invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public MLResult SetTargetLongerDimension(float longerDimension) { if (Mathf.Approximately(this.targetSettings.LongerDimension, longerDimension)) { return(MLResult.Create(MLResult.Code.Ok, "Longer dimension already set to value")); } float oldValue = this.targetSettings.LongerDimension; this.targetSettings.LongerDimension = longerDimension; MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateTargetSettings(this.trackerHandle, this.targetHandle, ref this.targetSettings); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { this.targetSettings.LongerDimension = oldValue; } return(result); }
/// <summary> /// <para>Attempts to cancel a previously requested selection process.</para> /// <para>If selection dialog has not yet been completed by the user, this request will /// dismiss the dialog and cancel the selection process.Otherwise this /// operation will return an error.</para> /// </summary> /// <returns> /// <para>MLResult.Result will be <c>MLResult.Code.Ok</c> if selection was successfully cancelled.</para> /// <para>MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if permissions haven't been granted to make this call.</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.ConnectionsCancellationPending</c> if the selection request has been found and the system is attempting to cancel the process.</para> /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsInvalidHandle</c> if input handle is invalid.</para> /// </returns> public static MLResult CancelSelection() { if (MLConnections.IsValidInstance()) { MLResult.Code resultCode = NativeBindings.MLConnectionsCancelSelection(_instance.selectionHandle); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { MLPluginLog.ErrorFormat("MLConnections.CancelSelection failed to cancel the selection requested. Reason: {0}", result); } return(result); } else { MLPluginLog.ErrorFormat("MLConnections.CancelSelection failed. Reason: No Instance for MLConnections"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLConnections.CancelSelection failed. Reason: No Instance for MLConnections")); } }
/// <summary> /// Creates a new ray cast tracker. /// </summary> /// <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> protected override MLResult StartAPI() { _instance.trackerHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLRaycastCreate(ref _instance.trackerHandle); if (resultCode != MLResult.Code.Ok) { MLResult result = MLResult.Create(resultCode); MLPluginLog.ErrorFormat("MLRaycast.StartAPI failed to create input tracker. Reason: {0}", result); return(result); } if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.trackerHandle)) { MLPluginLog.Error("MLRaycast.StartAPI failed. Reason: Invalid handle returned when initializing an instance of MLRaycast"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure)); } return(MLResult.Create(MLResult.Code.Ok)); }
/// <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.")); } }
/// <summary> /// Ends the collision matching the id and handle passed. /// </summary> /// <param name="collisionId">The id of the collider object.</param> /// <param name="collisionHandle">The handle for the collision session.</param> void EndCollision(CollisionType type, int collisionId, ulong collisionHandle) { MLResult result = MLMovement.EndCollision(sessionHandle, collisionHandle); if (type == CollisionType.Hard) { hardCollisionMap.Remove(collisionId); } else if (type == CollisionType.Soft) { softCollisionMap.Remove(collisionId); } if (!result.IsOk) { Debug.LogErrorFormat("MLMovementBehavior.EndCollision failed to end collision session, disabling script. Reason: {0}", result); enabled = false; return; } }
/// <summary> /// Starts a new soft collision session given some collider data. /// </summary> /// <param name="other">The collider data.</param> void StartSoftCollision(ref Collider other) { ulong collisionHandle = MagicLeapInternal.MagicLeapNativeBindings.InvalidHandle; Vector3 thisCenter = objectCollider.bounds.center; Vector3 otherCenter = other.bounds.center; float maxDistance = Vector3.Distance(thisCenter, otherCenter); float closesetDistance = maxDistance * (other.gameObject.GetComponent <MLMovementCollider>().MaxDepth / 100.0f); MLResult result = MLMovement.StartSoftCollision(sessionHandle, otherCenter, closesetDistance, maxDistance, out collisionHandle); if (!result.IsOk) { Debug.LogErrorFormat("MLMovementBehavior.StartSoftCollision failed to start a soft collision, disabling script. Reason: {0}", result); enabled = false; return; } softCollisionMap.Add(other.gameObject.GetInstanceID(), collisionHandle); }
/// <summary> /// Start up /// Note: This requires the privilege to be granted prior to Start() /// </summary> void Start() { MLResult result = MLPersistentStore.Start(); if (!result.IsOk) { Debug.LogErrorFormat("MLPersistentBehavior failed starting MLPersistentStore, disabling script. Reason: {0}", result); enabled = false; return; } result = MLPersistentCoordinateFrames.Start(); if (!result.IsOk) { MLPersistentStore.Stop(); Debug.LogErrorFormat("MLPersistentBehavior failed starting MLPersistentCoordinateFrames, disabling script. Reason: {0}", result); enabled = false; return; } if (string.IsNullOrEmpty(UniqueId)) { Debug.LogWarning("Unique Id is empty will try to use game object's name. It's good to provide a unique id for virtual objects to avoid weird behavior."); if (string.IsNullOrEmpty(gameObject.name)) { Debug.LogError("Either UniqueId or name should be non empty. Disabling component"); enabled = false; return; } UniqueId = gameObject.name; } if (MLPersistentCoordinateFrames.IsReady) { CreateOrRestoreBinding(); } else { MLPersistentCoordinateFrames.OnInitialized += HandleInitialized; } }
/// <summary> /// Request the specified privileges. This may solicit consent from the end-user. /// Note: The asynchronous callback occurs within the main thread. /// </summary> /// <param name="privilegeId">The privilege to request.</param> /// <param name="callback">Callback to be executed when the privilege request has completed.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the privilege request is in progress. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the callback is null. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started. /// Callback MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted. /// Callback MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied. /// </returns> public static MLResult RequestPrivilegeAsync(MLPrivileges.Id privilegeId, CallbackDelegate callback) { try { if (MLPrivileges.IsValidInstance()) { if (callback == null) { return(MLResult.Create(MLResult.Code.InvalidParam, "MLPrivileges.RequestPrivilegeAsync failed. Reason: Must send a valid callback.")); } if (!_instance.currentRequests.ContainsKey(privilegeId)) { IntPtr newRequest = IntPtr.Zero; MLResult.Code resultCode = NativeBindings.MLPrivilegesRequestPrivilegeAsync(privilegeId, ref newRequest); if (resultCode == MLResult.Code.Ok) { RequestPrivilegeQuery newQuery = new RequestPrivilegeQuery(callback, newRequest, privilegeId); _instance.currentRequests.Add(privilegeId, newQuery); } return(MLResult.Create(resultCode)); } else { return(MLResult.Create(MLResult.Code.Ok)); } } else { MLPluginLog.ErrorFormat("MLPrivileges.RequestPrivilegeAsync failed. Reason: No Instance for MLPrivileges."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilegeAsync failed. Reason: No Instance for MLPrivileges.")); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPrivileges.RequestPrivilegeAsync failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilegeAsync failed. Reason: API symbols not found.")); } }
/// <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> /// Process pending requests and call the callback specified in the startup config. /// </summary> private void ProcessPendingQueries() { try { foreach (var pending in this.currentRequests.OrderByDescending(x => x.Key)) { MLResult.Code result = NativeBindings.MLPrivilegesRequestPrivilegeTryGet(pending.Value.Request); if (result != MLResult.Code.Pending) { pending.Value.Result = MLResult.Create(result); pending.Value.Callback(pending.Value.Result, pending.Key); this.currentRequests.Remove(pending.Key); } } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPrivileges.ProcessPendingQueries failed. Reason: API symbols not found"); } }
/// <summary> /// Initializes the image tracker. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> protected override MLResult StartAPI() { this.handle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLImageTrackerCreate(ref this.trackerSettings, ref this.handle); MLResult result = MLResult.Create(resultCode); if (result.IsOk) { bool success = MagicLeapNativeBindings.MLHandleIsValid(this.handle); if (!success) { MLPluginLog.Error("MLImageTracker.StartApi failed. Reason: Invalid image tracker this.handle."); } } else { MLPluginLog.ErrorFormat("MLImageTracker.StartApi failed to create image tracker this.handle. Reason: {0}", result); } return(result); }
/// <summary> /// Sets the Image Tracker's settings to match the provided settings. /// </summary> /// <param name="customSettings">The new MLImageTracker.Settings wanted.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successfully updated the image tracker settings. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed to update the settings due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if failed to update the settings due to lack of privilege(s). /// </returns> public static MLResult UpdateTrackerSettings(MLImageTracker.Settings customSettings) { var currentSettings = GetCurrentTrackerSettings(); if (currentSettings == customSettings) { return(MLResult.Create(MLResult.Code.Ok, "No change needed")); } Instance.trackerSettings = new NativeBindings.MLImageTrackerSettingsNative(customSettings); MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateSettings(Instance.handle, ref Instance.trackerSettings); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { Instance.trackerSettings = new NativeBindings.MLImageTrackerSettingsNative(currentSettings); } return(result); }
/// <summary> /// Starts the MLInput, initializes the first controller, and registers the connection handlers /// </summary> void Awake() { if (!MLInput.IsStarted) { MLInputConfiguration config = new MLInputConfiguration(MLInputConfiguration.DEFAULT_TRIGGER_DOWN_THRESHOLD, MLInputConfiguration.DEFAULT_TRIGGER_UP_THRESHOLD, true); MLResult result = MLInput.Start(config); if (!result.IsOk) { Debug.LogErrorFormat("Error: ControllerConnectionHandler failed starting MLInput, disabling script. Reason: {0}", result); enabled = false; return; } } MLInput.OnControllerConnected += HandleOnControllerConnected; MLInput.OnControllerDisconnected += HandleOnControllerDisconnected; GetAllowedInput(); }
/// <summary> /// Destroys the video sink. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if destroying all handles was successful. /// MLResult.Result will be <c>MLResult.Code.WebRTCResultInstanceNotCreated</c> if MLWebRTC instance was not created. /// MLResult.Result will be <c>MLResult.Code.WebRTCResultMismatchingHandle</c> if an incorrect handle was sent. /// </returns> public override MLResult Destroy() { #if PLATFORM_LUMIN if (!MagicLeapNativeBindings.MLHandleIsValid(this.Handle)) { return(MLResult.Create(MLResult.Code.InvalidParam, "Handle is invalid.")); } updateVideoEvent.WaitOne(250); this.SetStream(null); MLResult.Code resultCode = NativeBindings.MLWebRTCVideoSinkDestroy(this.Handle); DidNativeCallSucceed(resultCode, "MLWebRTCVideoSinkDestroy()"); this.InvalidateHandle(); MLWebRTC.Instance.sinks.Remove(this); return(MLResult.Create(resultCode)); #else return(new MLResult()); #endif }
/// <summary> /// Requests for the hand mesh and executes the callback when the request is done. /// </summary> /// <param name="callback">Callback to execute when the request is done.</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 internal invalid input parameter. /// </returns> public static MLResult RequestHandMesh(RequestHandMeshCallback callback) { if (callback == null) { MLPluginLog.ErrorFormat("MLHandMeshing.RequestHandMesh failed. Reason: Passed input callback is null"); return(MLResult.Create(MLResult.Code.InvalidParam)); } ulong requestHandle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLHandMeshingRequestMesh(Instance.nativeTracker, ref requestHandle); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLHandMeshing.RequestHandMesh failed to request hand mesh. Reason: {0}", resultCode); return(MLResult.Create(resultCode)); } Instance.pendingQueries.Add(new Query(requestHandle, callback)); return(MLResult.Create(resultCode)); }
/// <summary> /// Internal call used to set the status of the Image Tracker. /// </summary> /// <param name="enabled">Used to enabled or disable Image Tracker to be enabled or disabled.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if there were invalid trackerSettings when setting the Image Tracker status. /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the Image Tracker status was updated successfully or if no change was needed. /// 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 there was an internal error. /// </returns> private MLResult SetTrackerStatusInternal(bool enabled) { if (this.trackerSettings.EnableTracker == enabled) { return(MLResult.Create(MLResult.Code.Ok, "No change needed")); } bool prevStatus = this.trackerSettings.EnableTracker; this.trackerSettings.EnableTracker = enabled; MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateSettings(this.handle, ref this.trackerSettings); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { this.trackerSettings.EnableTracker = prevStatus; } return(result); }
/// <summary> /// Checks whether the application has the specified privileges. /// This does not solicit consent from the end-user. /// </summary> /// <param name="privilegeId">The privilege to check for access.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted. /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started. /// </returns> public static MLResult CheckPrivilege(MLPrivileges.Id privilegeId) { try { if (MLPrivileges.IsValidInstance()) { MLResult.Code checkPrivilegeResult = NativeBindings.MLPrivilegesCheckPrivilege(privilegeId); return((checkPrivilegeResult == MLResult.Code.PrivilegeNotGranted) ? MLResult.Create(checkPrivilegeResult, "Privilege Denied or Not Yet Requested.") : MLResult.Create(checkPrivilegeResult)); } else { MLPluginLog.ErrorFormat("MLPrivileges.CheckPrivilege failed. Reason: No Instance for MLPrivileges."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.CheckPrivilege failed. Reason: No Instance for MLPrivileges.")); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPrivileges.CheckPrivilege failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.CheckPrivilege failed. Reason: API symbols not found.")); } }
/// <summary> /// Start this instance. /// </summary> void Start() { MLResult result = MLPersistentStore.Start(); if (!result.IsOk) { SetError("Failed to start persistent store. Disabling component"); enabled = false; return; } result = MLPersistentCoordinateFrames.Start(); if (!result.IsOk) { MLPersistentStore.Stop(); SetError("Failed to start coordinate frames system. disabling component"); enabled = false; return; } if (_representativePrefab == null) { SetError("Error: _representativePrefab must be set"); enabled = false; return; } List <MLPCF> pcfList; result = MLPersistentCoordinateFrames.GetAllPCFs(out pcfList, int.MaxValue); if (!result.IsOk) { MLPersistentStore.Stop(); MLPersistentCoordinateFrames.Stop(); SetError(result.ToString()); enabled = false; return; } TryShowingAllPCFs(pcfList); }
/// <summary> /// Destroys the Track and its associated media source. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if destroying all handles was successful. /// MLResult.Result will be <c>MLResult.Code.WebRTCResultInstanceNotCreated</c> if MLWebRTC instance was not created. /// MLResult.Result will be <c>MLResult.Code.WebRTCResultMismatchingHandle</c> if an incorrect handle was sent. /// </returns> public virtual MLResult DestroyLocal() { #if PLATFORM_LUMIN if (!this.IsLocal) { return(MLResult.Create(MLResult.Code.InvalidParam, "Souce is not local.")); } if (!MagicLeapNativeBindings.MLHandleIsValid(this.Handle)) { return(MLResult.Create(MLResult.Code.InvalidParam, "Source handle is invalid.")); } this.Cleanup(); MLResult.Code resultCode = MLResult.Code.Ok; // If this is a local source then we need to explicitly remove it from it's associated connections. foreach (MLWebRTC.PeerConnection connection in Instance.connections) { if (connection == this.ParentConnection) { connection.RemoveLocalTrack(this); break; } } MLWebRTC.Instance.localTracks.Remove(this); resultCode = Source.NativeBindings.MLWebRTCSourceDestroy(this.Handle); DidNativeCallSucceed(resultCode, "MLWebRTCSourceDestroy()"); this.Handle = MagicLeapNativeBindings.InvalidHandle; this.ParentConnection = null; return(MLResult.Create(resultCode)); #else return(new MLResult()); #endif }
/// <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> /// Call for querying the last known coarse/fine location. /// The accuracy field of the MLLocation.Location provides the estimate accuracy radius in meters. /// Returns the last known data on success and returns the last queried location data on failure. Latitude and Longitude of /// 0 should be assumed an Invalid Location. /// </summary> /// <param name="outLocation">Where to store the last known fine location. Only updates when getting the location succeeds. Latitude and Longitude of 0 should be assumed an Invalid Location.</param> /// <param name="isFine">Determines whether to query for fine location or coarse location.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the location was queried successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an internal error. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if there was an invalid location. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privilege(s). /// MLResult.Result will be <c>MLResult.Code.LocationProviderNotFound</c> if there was no provider or an invalid request was made. /// MLResult.Result will be <c>MLResult.Code.LocationNetworkConnection</c> if there was no internet connection. /// MLResult.Result will be <c>MLResult.Code.LocationNoLocation</c> if the location could not be found. /// </returns> public static MLResult MLLocationGetLastLocation(out MLLocation.Location outLocation, bool isFine) { // The automatic marshaling was not working properly for this structure. TimeStamp was always 0. To solve this // we use an IntPtr that has the proper default values set. NativeBindings.LocationNative location = NativeBindings.LocationNative.Create(); MLResult.Code resultCode; IntPtr myPointer = Marshal.AllocHGlobal(Marshal.SizeOf(location)); Marshal.StructureToPtr(location, myPointer, false); try { resultCode = isFine ? NativeBindings.MLLocationGetLastFineLocation(myPointer) : NativeBindings.MLLocationGetLastCoarseLocation(myPointer); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLLocation.NativeBindings.MLLocationGetLastLocation failed to get location. Reason: {0}", resultCode); } } catch (EntryPointNotFoundException) { MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocation API symbols not found."); MLPluginLog.ErrorFormat("MLLocation.NativeBindings.MLLocationGetLastLocation failed to get location. Reason: {0}", result); outLocation = new MLLocation.Location(); Marshal.FreeHGlobal(myPointer); return(result); } location = (NativeBindings.LocationNative)Marshal.PtrToStructure(myPointer, typeof(NativeBindings.LocationNative)); Marshal.FreeHGlobal(myPointer); MLResult finalResult = MLResult.Create(resultCode); outLocation = location.Data; return(finalResult); }
/// <summary> /// Request a subset of connections as manually selected by the user. The results are delivered via a callback /// </summary> /// <param name="maxSelectionAmount">Max number of connections to be selected. Min limit is 1.</param> /// <param name="userPrompt">Text prompt to be displayed to the user with selection dialog. The max length for the prompt is 40 characters.</param> /// <param name="defaultFilter">Type of filter applied by default to MLConnections list in selection dialog.</param> /// <returns> /// <para>MLResult.Result will be <c>MLResult.Code.Ok</c> if successfully submitted.</para> /// <para>MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if permissions haven't been granted to make this call.</para> /// </returns> public static MLResult GetSelection(uint maxSelectionAmount, string userPrompt, SelectionFilter defaultFilter) { if (MLConnections.IsValidInstance()) { NativeBindings.SelectionArgs argsToSend = NativeBindings.SelectionArgs.Create(maxSelectionAmount, userPrompt, defaultFilter); MLResult.Code resultCode = NativeBindings.MLConnectionsRequestSelection(ref argsToSend, ref _instance.selectionHandle); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { MLPluginLog.ErrorFormat("MLConnections.GetSelection failed to request a selection. Reason: {0}", result); } return(result); } else { MLPluginLog.ErrorFormat("MLConnections.GetSelection failed. Reason: No Instance for MLConnections"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLConnections.GetSelection failed. Reason: No Instance for MLConnections")); } }
/// <summary> /// Requests the specified privileges. This may possibly solicit consent from the end-user. /// </summary> /// <param name="privilegeIds">The privileges to request.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted. /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started. /// </returns> public static MLResult RequestPrivileges(params MLPrivileges.Id[] privilegeIds) { #if PLATFORM_LUMIN MLResult result = new MLResult(); foreach (MLPrivileges.Id privilegeId in privilegeIds) { result = CheckPrivilege(privilegeId); if (result.Result == MLResult.Code.PrivilegeGranted) { continue; } result = RequestPrivilege(privilegeId); if (result.Result != MLResult.Code.PrivilegeGranted) { return(result); } } #endif return(result); }
/// <summary> /// Request the specified privilege asynchronously. This may solicit consent from the end-user. /// This async override uses Tasks instead of a callback. /// </summary> /// <param name="privilegeId">The privilege to request.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted. /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started. /// </returns> private async Task <MLResult> RequestPrivilegeAsyncInternal(MLPrivileges.Id privilegeId) { var taskCompletionSource = new TaskCompletionSource <MLResult>(); if (this.currentRequests.ContainsKey(privilegeId)) { return(MLResult.Create(MLResult.Code.Ok)); } IntPtr newRequest = IntPtr.Zero; MLResult.Code resultCode = NativeBindings.MLPrivilegesRequestPrivilegeAsync(privilegeId, ref newRequest); if (!MLResult.IsOK(resultCode)) { return(MLResult.Create(resultCode)); } RequestPrivilegeQuery newQuery = new RequestPrivilegeQuery((result, id) => taskCompletionSource.SetResult(result), newRequest, privilegeId); this.currentRequests.Add(privilegeId, newQuery); return(await taskCompletionSource.Task); }
/// <summary> /// Destroy the found object native tracker. /// </summary> private void DestroyNativeTracker() { try { if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.handle)) { return; } MLResult.Code resultCode = NativeBindings.MLFoundObjectTrackerDestroy(_instance.handle); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("MLFoundObjects.DestroyNativeTracker failed to destroy found object tracker. Reason: {0}", MLResult.CodeToString(resultCode)); } _instance.handle = MagicLeapNativeBindings.InvalidHandle; } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLFoundObjects.DestroyNativeTracker failed. Reason: API symbols not found"); } }