// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.SpatialAwareness.Utilities { /// /// Utility to export current Spatial Mesh Data to OBJ file /// public static class SpatialMeshExporter { /// /// Save spatial mesh data for all observers under the current Spatial Awareness system /// /// Absolute folder path to place OBJ files /// If true, attempts to consolidate all meshes per Observer into one OBJ file. If false, creates an OBJ file per mesh object on each observer /// /// Accessing GameObject/Mesh data will occur as Coroutine on Unity Main thread. May impact performance. /// If folder path does not exist, throws exception /// public static async Task Save(string folderPath, bool consolidate = true) { CreateFoldersIfDoesNotExist(folderPath); var meshObservers = (CoreServices.SpatialAwarenessSystem as IMixedRealityDataProviderAccess).GetDataProviders(); foreach (var observer in meshObservers) { await Save(observer, folderPath, consolidate); } } /// /// Save spatial mesh data for given observer to folder path provided /// /// Observer to target for requests of spatial mesh data /// Folder path to pull all OBJ files /// if true, merge all mesh data from observer into one OBJ file. If false, create OBJ file per mesh object /// /// Accessing GameObject/Mesh data will occur as Coroutine on Unity Main thread. May impact performance. /// If folder path does not exist, throws exception /// public static async Task Save(IMixedRealitySpatialAwarenessMeshObserver meshObserver, string folderPath, bool consolidate = true) { CreateFoldersIfDoesNotExist(folderPath); await SaveInternal(meshObserver, folderPath, consolidate); } private static IEnumerator SaveInternal(IMixedRealitySpatialAwarenessMeshObserver meshObserver, string folderPath, bool consolidate = true) { var targets = new HashSet(); // Build up unique set of GameObjects to target to pull Mesh data foreach (SpatialAwarenessMeshObject meshObject in meshObserver.Meshes.Values) { targets.Add(consolidate ? meshObject.GameObject.transform.parent : meshObject.GameObject.transform); } foreach (var target in targets) { string filePath = Path.Combine(folderPath, target.name + ".obj"); yield return target.gameObject.ExportOBJAsync(filePath, true); } } private static void CreateFoldersIfDoesNotExist(string folderPath) { if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } } }