mixedreality/com.microsoft.mixedreality..../SDK/Features/Utilities/SpatialMeshExporter.cs

82 lines
3.5 KiB
C#

// 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
{
/// <summary>
/// Utility to export current Spatial Mesh Data to OBJ file
/// </summary>
public static class SpatialMeshExporter
{
/// <summary>
/// Save spatial mesh data for all observers under the current Spatial Awareness system
/// </summary>
/// <param name="folderPath">Absolute folder path to place OBJ files</param>
/// <param name="consolidate">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</param>
/// <remarks>
/// <para>Accessing GameObject/Mesh data will occur as Coroutine on Unity Main thread. May impact performance.
/// If folder path does not exist, throws exception</para>
/// </remarks>
public static async Task Save(string folderPath, bool consolidate = true)
{
CreateFoldersIfDoesNotExist(folderPath);
var meshObservers = (CoreServices.SpatialAwarenessSystem as IMixedRealityDataProviderAccess).GetDataProviders<IMixedRealitySpatialAwarenessMeshObserver>();
foreach (var observer in meshObservers)
{
await Save(observer, folderPath, consolidate);
}
}
/// <summary>
/// Save spatial mesh data for given observer to folder path provided
/// </summary>
/// <param name="meshObserver">Observer to target for requests of spatial mesh data</param>
/// <param name="folderPath">Folder path to pull all OBJ files</param>
/// <param name="consolidate">if true, merge all mesh data from observer into one OBJ file. If false, create OBJ file per mesh object</param>
/// <remarks>
/// <para>Accessing GameObject/Mesh data will occur as Coroutine on Unity Main thread. May impact performance.
/// If folder path does not exist, throws exception</para>
/// </remarks>
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<Transform>();
// 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);
}
}
}
}