如何访问 Hololens 3D 对象文件夹中的文件并在运行时将其发送到应用程序

Posted

技术标签:

【中文标题】如何访问 Hololens 3D 对象文件夹中的文件并在运行时将其发送到应用程序【英文标题】:How to access files in the Hololens 3D object Folder and get it to the apllication at run time 【发布时间】:2022-01-02 13:54:25 【问题描述】:

我一直在寻找可以访问 HoloLens 的内部文件夹(3D 模型文件夹)并将其加载到正在运行的应用程序的 SDK,我们尝试了很多链接都无济于事。谁能帮我们解决这个问题?

【问题讨论】:

请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。 【参考方案1】:

您的问题非常广泛,但老实说 UWP 是一个棘手的主题。我正在手机上输入此内容,但我希望它可以帮助您入门。


首先:Hololens 使用UWP

要在 UWP 应用程序中进行文件 IO,您需要使用仅适用于 asynchronous 的特殊 c# API!所以在开始之前先熟悉这个概念和关键字asyncawaitTask

进一步注意,Unity 的大部分 API 只能在 Unity 主线程上使用!因此,您将需要一个专用类来接收异步 Actions 并通过 ConcurrentQueue 将它们分派到下一个 Unity 主线程 Update 调用中,例如

using System;
using System.Collections.Concurrent;
using UnityEngine;

public class MainThreadDispatcher : MonoBehaviour

    private static MainThreadDispatcher _instance;

    public static MainThreadDispatcher Instance
    
        get
        
            if (_instance) return _instance;

            _instance = FindObjectOfType<MainThreadDispatcher>();

            if (_instance) return _instance;

            _instance = new GameObject(nameof(MainThreadDispatcher)).AddComponent<MainThreadDispatcher>();

            return _instance;
        
    

    private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>();

    private void Awake()
    
        if (_instance && _instance != this)
        
            Destroy(gameObject);
            return;
        

        _instance = this;
        DontDestroyOnLoad(gameObject);
    

    public void DoInMainThread(Action action)
    
        _actions.Enqueue(action);
    

    private void Update()
    
        while (_actions.TryDequeue(out var action))
        
            action?.Invoke();
        
    

现在这表明您很可能正在寻找Windows.Storage.KnownFolders.Objects3D,它是Windows.Storage.StorageFolder

在这里,您将使用GetFileAsync 以获得Windows.Storage.StorageFile

然后您使用Windows.Storage.FileIO.ReadBufferAsync 将该文件的内容读入IBuffer

最后,您可以使用ToArray 来获取原始的byte[]

在这一切之后,您必须将结果分派回 Unity 主线程,以便能够在那里使用它(或以另一种异步方式继续导入过程)。

你可以尝试使用类似的东西

using System;
using System.IO;
using System.Threading.Tasks;

#if WINDOWS_UWP // We only have these namespaces if on an UWP device
using Windows.Storage;
using System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions;
#endif

public static class Example

    // Instead of directly returning byte[] you will need to use a callback
    public static void GetFileContent(string filePath, Action<byte[]> onSuccess)
    
        Task.Run(async () => await FileLoadingTask(filePath, onSuccess));
    
    
    private static async Task FileLoadingTask(string filePath, Action<byte[]> onSuccess)
    
#if WINDOWS_UWP
        // Get the 3D Objects folder
        var folder = Windows.Storage.KnownFolders.Objects3D;
        // get a file within it
        var file = await folder.GetFileAsync(filePath);

        // read the content into a buffer
        var buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);
        // get a raw byte[]
        var bytes = buffer.ToArray();
#else
        // as a fallback and for testing in the Editor use he normal FileIO
        var folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "3D Objects");
        var fullFilePath = Path.Combine(folderPath, filePath);
        var bytes = await File.ReadAllBytesAsync(fullFilePath);
#endif

        // finally dispatch the callback action into the Unity main thread
        MainThreadDispatcher.Instance.DoInMainThread(() => onSuccess?.Invoke(bytes));
    


您如何处理返回的byte[] 取决于您!对于不同的文件类型,网上有很多加载器实现和库。


进一步阅读:

Stckoverflow - UWP: async read file into byte[] c# Manual - UWP - Create, write, and read a file

【讨论】:

以上是关于如何访问 Hololens 3D 对象文件夹中的文件并在运行时将其发送到应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Hololens - 访问相机框架

Unity3D Hololens 访问 Windows.Storage.KnownFolders

当一个对象在hololens中的另一个对象内部时如何选择内部游戏对象?

如何用Unity创建一个的简单的HoloLens 3D程序

HoloLens开发手记-实现3D应用启动器

Unity3D发布打包系列之——Hololens打包发布