Beispiel #1
0
        /// <summary>
        /// Creates native 3d vector from a Unity vector.
        /// </summary>
        /// <param name="vec">A Unity vector.</param>
        /// <param name="transformFromRUF">(Optional) If false, prevents conversion to the native SDK coordinate system.</param>
        /// <param name="applyScale">(Optional) If false, prevents scaling to the native SDK's unit per meter scale.</param>
        /// <returns>A native vector.</returns>
        public static MagicLeapNativeBindings.MLVec3f FromUnity(Vector3 vec, bool transformFromRUF = true, bool applyScale = true)
        {
            if (transformFromRUF)
            {
                vec.z = -vec.z;
            }

            if (applyScale)
            {
                if (MLDevice.WorldScale == 0.0f)
                {
                    MLPluginLog.Error("Divide by zero, unit scale vector contains 0");
                }
                else
                {
                    vec = vec / MLDevice.WorldScale;
                }
            }

            MagicLeapNativeBindings.MLVec3f outVec = new MagicLeapNativeBindings.MLVec3f();
            outVec.X = vec.x;
            outVec.Y = vec.y;
            outVec.Z = vec.z;

            return(outVec);
        }
Beispiel #2
0
        private MLResult GetItemDetailsInternal(string[] itemIds, Action <MLPurchaseItemDetail> callback)
        {
            // Create handle
            ulong handle = MagicLeapNativeBindings.InvalidHandle;

            MLResult.Code detailsResult = MLPurchaseNativeBindings.MLPurchaseItemDetailsCreate(ref handle);
            MLResult      result        = MLResult.Create(detailsResult);

            if (!result.IsOk || !MagicLeapNativeBindings.MLHandleIsValid(handle))
            {
                MLPluginLog.ErrorFormat("MLPurchase.GetItemDetailsInternal failed, unable to create item details query. Reason: {0}", result);
                return(result);
            }

            result = InitiateItemDetailsQuery(handle, itemIds);

            if (!result.IsOk)
            {
                MLPluginLog.ErrorFormat("MLPurchase.GetItemDetailsInternal failed to submit item details request. Reason: {0}", result);
                DestroyItemDetail(handle);
            }
            else
            {
                _pendingItemDetailQueries.Add(new ItemDetailQueryInfo(handle, callback));
            }
            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Converts playlist URLs to UTF8 and sets it to use for the playlist in the MusicService.
        /// </summary>
        /// <param name="playlist">The array of URLs</param>
        /// <param name="size">The size of the playList array</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.PrivilegeDenied</c> if necessary privilege is missing.
        /// MLResult.Result will be <c>MLResult.Code.MediaGenericNoInit</c> if not connected.
        /// </returns>
        public static MLResult.Code SetPlayListHelper(string[] playlist, ulong size)
        {
            try
            {
                IntPtr[] intPtrList = new IntPtr[playlist.Length];
                for (int i = 0; i < playlist.Length; ++i)
                {
                    intPtrList[i] = MLConvert.EncodeToUnmanagedUTF8(playlist[i]);
                }

                MLResult.Code resultCode = MLMusicServiceNativeBindings.MLMusicServiceSetPlayList(intPtrList, size);

                for (int i = 0; i < intPtrList.Length; ++i)
                {
                    Marshal.FreeHGlobal(intPtrList[i]);
                }

                return(resultCode);
            }
            catch (System.EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLMusicServiceNativeBindings.SetPlayListHelper failed. Reason: API symbols not found");
                return(MLResult.Code.UnspecifiedFailure);
            }
        }
Beispiel #4
0
        private MLResult GetAllPurchaseHistoryInternal(Action <MLPurchaseHistoryQuery> callback)
        {
            ulong handle = MagicLeapNativeBindings.InvalidHandle;

            MLResult.Code historyResult = MLPurchaseNativeBindings.MLPurchaseHistoryQueryCreate(ref handle);
            MLResult      result        = MLResult.Create(historyResult);

            if (!result.IsOk || !MagicLeapNativeBindings.MLHandleIsValid(handle))
            {
                MLPluginLog.ErrorFormat("MLPurchase.GetAllPurchaseHistoryInternal failed to create purchase history query. Reason: {0}", result);
                return(result);
            }

            historyResult = MLPurchaseNativeBindings.MLPurchaseHistoryQueryGetPage(handle, MaxPurchaseHistoryItems);
            result        = MLResult.Create(historyResult);
            if (!result.IsOk)
            {
                MLPluginLog.ErrorFormat("MLPurchase.GetAllPurchaseHistoryInternal failed to submit purchase history query. Reason: {0}", result);
                DestroyPurchaseHistoryQuery(handle);
            }
            else
            {
                _pendingPurchaseHistoryQueries.Add(new PurchaseHistoryQueryInfo(handle, callback));
            }
            return(result);
        }
Beispiel #5
0
        private MLResult MakePurchaseInternal(string token, Action <MLPurchaseRequest> callback)
        {
            ulong handle = MagicLeapNativeBindings.InvalidHandle;

            MLResult.Code purchaseResult = MLPurchaseNativeBindings.MLPurchaseCreate(ref handle);
            MLResult      result         = MLResult.Create(purchaseResult);

            if (!result.IsOk || !MagicLeapNativeBindings.MLHandleIsValid(handle))
            {
                MLPluginLog.ErrorFormat("MLPurchase.MakePurchaseInternal failed to create purchase request. Reason: {0}", result);
                return(result);
            }

            MLPluginLog.Debug("Purchasing: " + token);
            purchaseResult = MLPurchaseNativeBindings.MLPurchaseSubmit(handle, token);
            result         = MLResult.Create(purchaseResult);
            if (!result.IsOk)
            {
                MLPluginLog.ErrorFormat("MLPurchase.MakePurchaseInternal failed to submit purchase request. Reason: {0}", result);
                DestroyPurchaseRequest(handle);
            }
            else
            {
                _pendingPurchaseRequests.Add(new PurchaseRequestInfo(handle, callback));
            }
            return(result);
        }
        /// <summary>
        /// Reads the JSON file and stores the results into the list of serialized bindings.
        /// </summary>
        /// <returns>The list of bindings found in the JSON file.</returns>
        public List <T> LoadFromFile()
        {
            if (Bindings.Count != 0)
            {
                return(Bindings);
            }

            string fullPath = Path.Combine(Application.persistentDataPath, this.fileName);

            if (fullPath != null && File.Exists(fullPath))
            {
                StreamReader reader = new StreamReader(fullPath);
                if (reader != null)
                {
                    string jsonString = reader.ReadToEnd();
                    this.serializedData = JsonUtility.FromJson <SerializeBindings>(jsonString);
                    reader.Dispose();
                }
                else
                {
                    MLPluginLog.Error("BindingsLocalStorage.LoadFromFile failed to create StreamReader.");
                    return(new List <T>());
                }
            }
            else
            {
                MLPluginLog.WarningFormat("File was not found: {0}", fullPath);
                return(new List <T>());
            }

            return(Bindings);
        }
Beispiel #7
0
        /// <summary>
        /// Convert Unity Texture2D to a byte array.
        /// Texture2D should be in one of the following formats: DXT1, RGBA32, RGB24.
        /// For DXT1 and RGBA32, resulting byte array is in RGBA format.
        /// For RGB24, resulting byte array is in RGB format.
        /// The origin of the byte array will be at the top left corner.
        /// Returns null on unsupported formats.
        /// </summary>
        /// <param name="texture">Texture to extract byte array from</param>
        /// <param name="numChannels">Out parameter to determine how many bytes per pixel</param>
        /// <returns>Returns an array of bytes that holds the converted texture</returns>
        public static byte[] ConvertToByteArray(Texture2D texture, out int numChannels)
        {
            byte[] encodedImage = null;
            numChannels = 0;

            // [1] Convert the unity texture to RGBA pixel format (if needed).
            // For a pixel at (x,y) the channel c data of that pixels is at the position
            // given by [(width * y + x)*channels + c].
            if (TextureFormat.DXT1 == texture.format)
            {
                Color32[] colorArray = texture.GetPixels32();
                numChannels = Marshal.SizeOf(typeof(Color32));
                int totalBytes = numChannels * colorArray.Length;
                encodedImage = new byte[totalBytes];
                GCHandle handle = default(GCHandle);
                try
                {
                    handle = GCHandle.Alloc(colorArray, GCHandleType.Pinned);
                    IntPtr ptr = handle.AddrOfPinnedObject();
                    Marshal.Copy(ptr, encodedImage, 0, totalBytes);
                }
                finally
                {
                    if (handle != default(GCHandle))
                    {
                        handle.Free();
                    }
                }
            }
            else if (TextureFormat.RGBA32 == texture.format)
            {
                numChannels  = 4;
                encodedImage = texture.GetRawTextureData();
            }
            else if (TextureFormat.RGB24 == texture.format)
            {
                numChannels  = 3;
                encodedImage = texture.GetRawTextureData();
            }
            else
            {
                MLPluginLog.Error("MLTextureUtils.ConvertToByteArray failed to convert to byte array. Reason: unsupported format. Use RGBA32, RGB24 or DXT1 format when importing textures.");
                return(encodedImage);
            }

            // [2] Convert to coorindate frame used by Lumin OS
            // Unity texture origin in bottom left, but Lumin OS is expecting top left to be the origin.
            int rowLength = texture.width * numChannels;
            var rowTemp   = new byte[rowLength];

            for (var i = 0; i < texture.height / 2; i++)
            {
                Buffer.BlockCopy(encodedImage, i * rowLength, rowTemp, 0, rowLength);
                Buffer.BlockCopy(encodedImage, (texture.height - i - 1) * rowLength, encodedImage, i * rowLength, rowLength);
                Buffer.BlockCopy(rowTemp, 0, encodedImage, (texture.height - i - 1) * rowLength, rowLength);
            }

            return(encodedImage);
        }
Beispiel #8
0
        private void UpdatePurchaseHistoryQuery()
        {
            List <PurchaseHistoryQueryInfo> completedQueries = new List <PurchaseHistoryQueryInfo>();

            for (int i = 0; i < _pendingPurchaseHistoryQueries.Count; ++i)
            {
                PurchaseHistoryQueryInfo info          = _pendingPurchaseHistoryQueries[i];
                MLPurchaseHistoryResult  historyResult = MLPurchaseHistoryResult.Create();
                info.Details.Result = MLPurchaseNativeBindings.MLPurchaseHistoryQueryGetPageResult(info.Handle, ref historyResult);

                if (info.Details.Result == MLResult.Code.Ok)
                {
                    if (historyResult.status == MLCloudStatus.Done)
                    {
                        uint numPurchaseConfirmationsToAdd = Math.Min(historyResult.count, info.NumItemsLeft);
                        for (int j = 0; j < numPurchaseConfirmationsToAdd; j++)
                        {
                            IntPtr offsetPtr = new IntPtr(historyResult.confirmations.ToInt64() + (Marshal.SizeOf(typeof(MLPurchaseConfirmation)) * j));
                            info.Details.PurchaseConfirmations.Add((MLPurchaseConfirmation)Marshal.PtrToStructure(offsetPtr, typeof(MLPurchaseConfirmation)));
                        }
                        info.NumItemsLeft -= numPurchaseConfirmationsToAdd;

                        MLPluginLog.DebugFormat("purchase history query: hasNextPage {0}, fetchAll {1}, NumItemsLeft {2}",
                                                historyResult.hasNextPage ? "true" : "false",
                                                info.FetchAll ? "true" : "false",
                                                info.NumItemsLeft.ToString()); // TESTING

                        if (historyResult.hasNextPage && (info.FetchAll || info.NumItemsLeft > 0))
                        {
                            info.Details.Result = MLPurchaseNativeBindings.MLPurchaseHistoryQueryGetPage(info.Handle, Math.Min(info.NumItemsLeft, MaxPurchaseHistoryItems));
                            if (info.Details.Result != MLResult.Code.Ok)
                            {
                                MLPluginLog.ErrorFormat("MLPurchase.UpdatePurchaseHistoryQuery failed to query for succeeding purchase history pages. Reason: {0}", GetResultString(info.Details.Result));
                                completedQueries.Add(info);
                            }
                        }
                        else
                        {
                            completedQueries.Add(info);
                        }
                    }
                }
                else
                {
                    MLPluginLog.Debug("purchase history query get page result, result: " + info.Details.Result.ToString());
                    completedQueries.Add(info);
                }
            }

            PublishPurchaseHistories(completedQueries);
        }
Beispiel #9
0
 /// <summary>
 /// Converts URL string to UTF8 and sets it for the MusicService.
 /// </summary>
 /// <param name="url">The URL to play</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.PrivilegeDenied</c> if necessary privilege is missing.
 /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error.
 /// MLResult.Result will be <c>MLResult.Code.MediaGenericNoInit</c> if not connected.
 /// </returns>
 public static MLResult.Code SetURLHelper(string url)
 {
     try
     {
         IntPtr        urlPtr     = MLConvert.EncodeToUnmanagedUTF8(url);
         MLResult.Code resultCode = MLMusicServiceNativeBindings.MLMusicServiceSetURL(urlPtr);
         Marshal.FreeHGlobal(urlPtr);
         return(resultCode);
     }
     catch (System.EntryPointNotFoundException)
     {
         MLPluginLog.Error("MLMusicServiceNativeBindings.SetURLHelper failed. Reason: API symbols not found");
         return(MLResult.Code.UnspecifiedFailure);
     }
 }
Beispiel #10
0
 private bool DestroyPurchaseHistoryQuery(ulong handle)
 {
     if (MagicLeapNativeBindings.MLHandleIsValid(handle))
     {
         MLResult.Code result = MLPurchaseNativeBindings.MLPurchaseHistoryQueryDestroy(handle);
         if (result == MLResult.Code.Ok)
         {
             return(true);
         }
         MLPluginLog.ErrorFormat("MLPurchase.DestroyPurchaseHistoryQuery failed to free purchase history query handle. Reason: {0}", GetResultString(result));
         return(false);
     }
     MLPluginLog.Error("MLPurchase.DestroyPurchaseHistoryQuery failed, handle is invalid.");
     return(false);
 }
Beispiel #11
0
 /// <summary>
 /// Properly dispose the Item Detail Query handle
 /// </summary>
 /// <param name="handle">Item Detail Query handle to be destroyed</param>
 /// <returns>Retrun true on success, otherwise false</returns>
 private bool DestroyItemDetail(ulong handle)
 {
     if (MagicLeapNativeBindings.MLHandleIsValid(handle))
     {
         MLResult.Code result = MLPurchaseNativeBindings.MLPurchaseItemDetailsDestroy(handle);
         if (result == MLResult.Code.Ok)
         {
             return(true);
         }
         MLPluginLog.ErrorFormat("MLPurchase.DestroyItemDetail failed, unable to free item details handle. Reason: {0}", GetResultString(result));
         return(false);
     }
     MLPluginLog.ErrorFormat("MLPurchase.DestroyItemDetail failed, handle is invalid.");
     return(false);
 }
Beispiel #12
0
        /// <summary>
        /// Begin query for the whole purchase history
        /// </summary>
        /// <param name="callback">Method to be called when the query is completed</param>
        /// <returns>
        /// MLResult.Result will be MLResult.Code.Ok if successful.
        ///
        /// MLResult.Result will be MLResult.Code.AllocFailed if the handle cannot be allocated.
        ///
        /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if there is an unexpected failure.
        ///
        /// MLResult.Result will be MLResult.Code.InvalidParam if any input parameters are invalid.
        ///
        /// MLResult.Result will be MLResult.Code.PrivilegeDenied if there is an privilege error with the purchase details system call.
        ///
        /// MLResult.Result will be MLResult.Code.CloudSystemError if there is an issue with the cloud service, e.g. service is not available for any reason.
        /// </returns>
        public static MLResult GetAllPurchaseHistory(Action <MLPurchaseHistoryQuery> callback)
        {
            if (!IsStarted)
            {
                MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Please call MLPurchase.Start() first");
                MLPluginLog.ErrorFormat("MLPurchase.GetAllPurchaseHistory failed to get entire purchase history. Reason: {0}", result);
                return(result);
            }

            if (callback == null)
            {
                MLResult result = MLResult.Create(MLResult.Code.InvalidParam, "Invalid MakePurchaseHistoryQuery params");
                MLPluginLog.ErrorFormat("MLPurchase.GetAllPurchaseHistory failed to get entire purchase history. Reason: {0}", result);
                return(result);
            }

            return(Instance.GetAllPurchaseHistoryInternal(callback));
        }
Beispiel #13
0
        /// <summary>
        /// Initiates a purchase
        /// </summary>
        /// <param name="token">Token returned by MLPurchaseItemDetailsResult</param>
        /// <param name="callback">Method to be called when the purchase is completed</param>
        /// <returns>
        /// MLResult.Result will be MLResult.Code.Ok if successful.
        ///
        /// MLResult.Result will be MLResult.Code.AllocFailed if the handle cannot be allocated.
        ///
        /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if there is an unexpected failure.
        ///
        /// MLResult.Result will be MLResult.Code.InvalidParam if any input parameters are invalid.
        ///
        /// MLResult.Result will be MLResult.Code.PrivilegeDenied if there is an privilege error with the purchase details system call.
        ///
        /// MLResult.Result will be MLResult.Code.CloudSystemError if there is an issue with the cloud service, e.g. service is not available for any reason.
        /// </returns>
        public static MLResult MakePurchase(string token, Action <MLPurchaseRequest> callback)
        {
            if (!IsStarted)
            {
                MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Please call MLPurchase.Start() first");
                MLPluginLog.ErrorFormat("MLPurchase.MakePurchase failed to make a purchase. Reason: {0}", result);
                return(result);
            }

            if (callback == null)
            {
                MLResult result = MLResult.Create(MLResult.Code.InvalidParam, "Invalid callback parameter passed.");
                MLPluginLog.ErrorFormat("MLPurchase.MakePurchase failed to make a purchase. Reason: {0}", result);
                return(result);
            }

            return(Instance.MakePurchaseInternal(token, callback));
        }
Beispiel #14
0
        /// <summary>
        /// Request for the details for the given IAP ids
        /// </summary>
        /// <param name="itemIds">Array of IAP ids</param>
        /// <param name="callback">Method to be called when the query is completed</param>
        /// <returns>
        /// MLResult.Result will be MLResult.Code.Ok if successful.
        ///
        /// MLResult.Result will be MLResult.Code.AllocFailed if the handle cannot be allocated.
        ///
        /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if there is an unexpected failure.
        ///
        /// MLResult.Result will be MLResult.Code.InvalidParam if any input parameters are invalid.
        ///
        /// MLResult.Result will be MLResult.Code.PrivilegeDenied if there is an privilege error with the purchase details system call.
        ///
        /// MLResult.Result will be MLResult.Code.CloudSystemError if there is an issue with the cloud service, e.g. service is not available for any reason.
        /// </returns>
        public static MLResult GetItemDetails(string[] itemIds, Action <MLPurchaseItemDetail> callback)
        {
            if (!IsStarted)
            {
                MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Please call MLPurchase.Start() first.");
                MLPluginLog.ErrorFormat("MLPurchase.GetItemDetails failed to get item details. Reason: {0}", result);
                return(result);
            }

            if (itemIds == null || itemIds.Length == 0 || callback == null)
            {
                MLResult result = MLResult.Create(MLResult.Code.InvalidParam, "Invalid GetItemDetails params.");
                MLPluginLog.Error(result);
                return(result);
            }

            return(Instance.GetItemDetailsInternal(itemIds, callback));
        }
                /// <summary>
                /// Create an initialized version of this struct.
                /// </summary>
                /// <returns>An initialized version of this struct.</returns>
                public static SettingsNative Create()
                {
                    if (!defaultSettings.HasValue)
                    {
                        SettingsNative settings = new SettingsNative()
                        {
                            Version                      = 1u,
                            SwayHistorySize              = 0u,
                            MaxDeltaAngle                = 0.0f,
                            ControlDampeningFactor       = 0.0f,
                            MaxSwayAngle                 = 0.0f,
                            MaximumHeadposeRotationSpeed = 0.0f,
                            MaximumHeadposeMovementSpeed = 0.0f,
                            MaximumDepthDeltaForSway     = 0.0f,
                            MinimumDistance              = 0.0f,
                            MaximumDistance              = 0.0f,
                            MaximumSwayTimeSeconds       = 0.0f,
                            EndResolveTimeoutSeconds     = 0.0f,
                        };

                        try
                        {
                            MLResult.Code result = NativeBindings.MLMovementGetDefaultSettings(out settings);
                            if (result != MLResult.Code.Ok)
                            {
                                MLPluginLog.ErrorFormat("MLMovement.NativeBindings.SettingsNative.Create failed to get default movement settings. Reason: {0}", result);
                            }
                        }
                        catch (System.DllNotFoundException)
                        {
                            MLPluginLog.Error("MLMovement API is currently available only on device.");
                        }
                        catch (System.EntryPointNotFoundException)
                        {
                            MLPluginLog.Error("MLMovement API symbols not found");
                        }

                        defaultSettings = settings;
                    }

                    return(defaultSettings.Value);
                }
Beispiel #16
0
            /// <summary>
            /// Allocates the static pointer to the CallbacksNative passed in. This is used to pass it into the CAPI.
            /// </summary>
            /// <returns>The pointer to the native callbacks.</returns>
            public static IntPtr AllocateSystemCallbacks()
            {
                if (SystemCallbacks != IntPtr.Zero)
                {
                    MLPluginLog.Error("MLMusicServiceNativeBindings.CallbacksNative.AllocateCallbacksPointer failed to allocate new callbacks pointer. Reason: Static callback pointer was already allocated, please call MLMusicServiceNativeBindings.CallbacksNative.DeallocateCallbacksPointer and try again");
                    return(IntPtr.Zero);
                }

                SystemCallbacks = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CallbacksNative)));
                CallbacksNative callbacks = CallbacksNative.Create();

                callbacks.OnPlaybackStateChange = HandlePlaybackStateChange;
                callbacks.OnRepeatStateChange   = HandleRepeatStateChange;
                callbacks.OnShuffleStateChange  = HandleShuffleStateChange;
                callbacks.OnMetadataChange      = HandleMetadataChange;
                callbacks.OnPositionChange      = HandlePositionChange;
                callbacks.OnError        = HandleError;
                callbacks.OnStatusChange = HandleStatusChange;
                callbacks.OnVolumeChange = HandleVolumeChange;
                Marshal.StructureToPtr(callbacks, SystemCallbacks, false);
                return(SystemCallbacks);
            }