82 lines
3.5 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|