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); } } }
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; } }