Example #1
0
        public void OnPreprocessBuild(BuildReport report)
        {
            if (report.summary.platform != BuildTarget.Android)
            {
                return;
            }

            if (!ARCorePreprocessBuild.isARCoreLoaderEnabled)
            {
                return;
            }

            var assets    = AssetDatabase.FindAssets($"t:{nameof(XRReferenceImageLibrary)}");
            var libraries = assets
                            .Select(AssetDatabase.GUIDToAssetPath)
                            .Select(AssetDatabase.LoadAssetAtPath <XRReferenceImageLibrary>);

            var index = 0;

            foreach (var library in libraries)
            {
                index++;
                EditorUtility.DisplayProgressBar(
                    $"Compiling {nameof(XRReferenceImageLibrary)} ({index} of {assets.Length})",
                    $"{AssetDatabase.GetAssetPath(library)} ({library.count} image{(library.count == 1 ? "" : "s")})",
                    (float)index / assets.Length);

                try
                {
                    library.SetDataForKey(ARCoreImageDatabase.dataStoreKey, ArCoreImg.BuildDb(library));
                }
                catch (ArCoreImg.MissingTextureException e)
                {
                    Rethrow(library, $"{nameof(XRReferenceImage)} named '{e.referenceImage.name}' is missing a texture.", e);
                }
                catch (ArCoreImg.EncodeToPNGFailedException e)
                {
                    Rethrow(library, $"{nameof(XRReferenceImage)} named '{e.referenceImage.name}' could not be encoded to a PNG. Please check other errors in the console window.", e);
                }
                catch (ArCoreImg.BuildDatabaseFailedException e)
                {
                    Rethrow(library, $"The arcoreimg command line tool exited with code ({e.exitCode}) and stderr:\n{e.stdErr}", e);
                }
                catch (ArCoreImg.EmptyDatabaseException e)
                {
                    Rethrow(library, $"The arcoreimg command line tool ran successfully but did not produce an image database. This is likely a bug. Please provide these details to Unity:\n=== begin arcoreimg output ===\nstdout:\n{e.stdOut}\nstderr:\n{e.stdErr}\n=== end arcoreimg output===\n", e);
                }
            }
        }
Example #2
0
        void BuildImageTrackingAssets()
        {
            if (Directory.Exists(Application.streamingAssetsPath))
            {
                s_ShouldDeleteStreamingAssetsFolder = false;
            }
            else
            {
                // Delete the streaming assets folder at the end of the build pipeline
                // since it did not exist before we created it here.
                s_ShouldDeleteStreamingAssetsFolder = true;
                Directory.CreateDirectory(Application.streamingAssetsPath);
            }

            if (!Directory.Exists(ARCoreImageTrackingProvider.k_StreamingAssetsPath))
            {
                Directory.CreateDirectory(ARCoreImageTrackingProvider.k_StreamingAssetsPath);
            }

            try
            {
                string[] libGuids = AssetDatabase.FindAssets("t:xrReferenceImageLibrary");
                if (libGuids == null || libGuids.Length == 0)
                {
                    return;
                }

                // This is how much each library will contribute to the overall progress
                var          progressPerLibrary = 1f / libGuids.Length;
                const string progressBarText    = "Building ARCore Image Library";

                for (int libraryIndex = 0; libraryIndex < libGuids.Length; ++libraryIndex)
                {
                    var libGuid         = libGuids[libraryIndex];
                    var overallProgress = progressPerLibrary * libraryIndex;
                    var numSteps        = libGuids.Length + 1; // 1 per image plus arcoreimg
                    var libraryPath     = AssetDatabase.GUIDToAssetPath(libGuid);
                    var imageLib        = AssetDatabase.LoadAssetAtPath <XRReferenceImageLibrary>(libraryPath);

                    EditorUtility.DisplayProgressBar(progressBarText, imageLib.name, overallProgress);

                    var tempDirectory      = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
                    var inputImageListPath = Path.Combine(tempDirectory, Guid.NewGuid().ToString("N") + ".txt");

                    // prepare text file for arcoreimg to read from
                    try
                    {
                        Directory.CreateDirectory(tempDirectory);
                        using (var writer = new StreamWriter(inputImageListPath, false))
                        {
                            for (int i = 0; i < imageLib.count; i++)
                            {
                                var referenceImage     = imageLib[i];
                                var textureGuid        = referenceImage.textureGuid.ToString("N");
                                var assetPath          = AssetDatabase.GUIDToAssetPath(textureGuid);
                                var referenceImageName = referenceImage.guid.ToString("N");

                                EditorUtility.DisplayProgressBar(
                                    progressBarText,
                                    imageLib.name + ": " + assetPath,
                                    overallProgress + progressPerLibrary * i / numSteps);

                                var texture = AssetDatabase.LoadAssetAtPath <Texture2D>(assetPath);
                                if (texture == null)
                                {
                                    throw new BuildFailedException(string.Format(
                                                                       "ARCore Image Library Generation: Reference library at '{0}' is missing a texture at index {1}.",
                                                                       libraryPath, i));
                                }

                                var extension = Path.GetExtension(assetPath);

                                var entry = new StringBuilder();

                                if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
                                    string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
                                {
                                    entry.Append(referenceImageName).Append('|').Append(Path.GetFullPath(assetPath));
                                }
                                else
                                {
                                    var pngFilename = Path.Combine(tempDirectory, textureGuid + ".png");
                                    var bytes       = ImageConversion.EncodeToPNG(texture);
                                    if (bytes == null)
                                    {
                                        throw new BuildFailedException(string.Format(
                                                                           "ARCore Image Library Generation: Texture format for image '{0}' not supported. Inspect other error messages emitted during this build for more details.",
                                                                           texture.name));
                                    }

                                    File.WriteAllBytes(pngFilename, bytes);
                                    entry.Append(referenceImageName).Append('|').Append(pngFilename);
                                }

                                if (referenceImage.specifySize)
                                {
                                    entry.Append('|').Append(referenceImage.width.ToString("G", CultureInfo.InvariantCulture));
                                }

                                writer.WriteLine(entry.ToString());
                            }
                        }
                    }
                    catch
                    {
                        Directory.Delete(tempDirectory, true);
                        throw;
                    }

                    // launch arcoreimg and wait for it to return so we can process the asset
                    try
                    {
                        EditorUtility.DisplayProgressBar(
                            progressBarText,
                            imageLib.name + ": Invoking arcoreimg",
                            overallProgress + progressPerLibrary * (numSteps - 1) / numSteps);

                        // This file must have the .imgdb extension (the tool adds it otherwise)
                        var outputDbPath = ARCoreImageTrackingProvider.GetPathForLibrary(imageLib);
                        if (File.Exists(outputDbPath))
                        {
                            File.Delete(outputDbPath);
                        }

                        var(stdOut, stdErr, _) = ArCoreImg.BuildDb(inputImageListPath, outputDbPath);

                        if (!File.Exists(outputDbPath))
                        {
                            throw new BuildFailedException(
                                      $"Failed to generate image database. Output from arcoreimg:\n\nstdout:\n{stdOut}\n====\n\nstderr:\n{stdErr}\n====");
                        }
                    }
                    catch
                    {
                        Debug.LogError($"Failed to generated ARCore reference image library '{imageLib.name}'");
                        throw;
                    }
                    finally
                    {
                        Directory.Delete(tempDirectory, true);
                    }
                }
            }
            catch
            {
                RemoveGeneratedStreamingAssets();
                throw;
            }
        }