MRTK 2.4-在运行时保存空间网格

问题描述

现在,我正在尝试将Hololens上的空间网格保存为obj文件。我的问题是,当尝试打开obj文件时,例如在Blender(或3D Viewer)中,出现错误IndexError: List index out of range。因此,我想我给了三角形错误的索引(在MeshToString()的最后一部分),但我不知道如何正确地进行操作。

有效的方法:例如,如果我从第一个网格过滤器中仅取出一个网格,并在+ lastFaceIndex中切出MeshToString(),则效果很好。但这只是我房间的一部分。而且我想从房间里获得整个网格,所以我必须通过所有的网格过滤器并得到我的网格,然后将它们写入obj文件,但是我不知道如何给三角形赋予正确的索引。 >
另外我还注意到,如果我通过设备门户网站下载的网格大约有4.8MB,但是我通过我的统一应用程序下载的网格只有1.4MB。

我的设置:
Unity 2019.3.14 MRTK 2.4 HoloLens第二代

GetSpatialMesh():

private void GetSpatialMesh()
{
    if (_observer == null)
        return;

    List<Mesh> meshes = new List<Mesh>();
    // Loop through all known Meshes
    foreach (SpatialAwarenessMeshObject meshObject in _observer.Meshes.Values)
        meshes.Add(meshObject.Filter.mesh);
    WriteMeshToFile("MyMesh.obj",meshes);
}

WriteMeshToFile():

public static void WriteMeshToFile(string fileName,IEnumerable<Mesh> meshes)
{
    string path = Path.Combine(Application.persistentDataPath,fileName);
    using (var file = new FileStream(path,FileMode.Create,FileAccess.Write,FileShare.Write))
    {
        faceCount = 0;
        using (var writer = new StreamWriter(file,Encoding.UTF8))
        {
            int o = 0;
            foreach (Mesh mesh in meshes)
            {
                o++;
                writer.WriteLine("o Object." + o);
                writer.Write(MeshToString(mesh,faceCount));
                writer.WriteLine("");
            }
        }
    }
}

MeshToString():

public static string MeshToString(Mesh m,int lastFaceIndex = 0)
{
    StringBuilder sb = new StringBuilder();

    foreach (Vector3 v in m.vertices)
    {
        sb.Append(string.Format("v {0} {1} {2}\n",v.x,v.y,v.z));
    }
    sb.Append("\n");
    foreach (Vector3 v in m.normals)
    {
        sb.Append(string.Format("vn {0} {1} {2}\n",v.z));
    }
    sb.Append("\n");
    foreach (Vector3 v in m.uv)
    {
        sb.Append(string.Format("vt {0} {1}\n",v.y));
    }
    for (int material = 0; material < m.subMeshCount; material++)
    {
        int[] triangles = m.GetTriangles(material);
        for (int i = 0; i < triangles.Length; i += 3)
        {
            faceCount += 3;
            sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",triangles[i] + 1 + lastFaceIndex,triangles[i + 1] + 1 + lastFaceIndex,triangles[i + 2] + 1 + lastFaceIndex));
        }
    }
    return sb.ToString();
}

解决方案:
场景理解sample project对我没有用,所以我只是通过nuget manager统一获取了sdk。我使用了SceneUnderstandingManager(属于示例项目的一部分)中的代码,这些代码在下面的答案中由Hernando-MSFT引用。

解决方法

我注意到您发布的代码基于Legacy HoloToolkit,但是所有支持现在都将由更新的Scene understanding SDK提供。由于您使用的是HoloLens2,因此建议您使用“场景理解” SDK查询空间映射数据的静态版本,并将序列化的场景字节保存到磁盘。 扫描房间后,调用SceneObserver.ComputeSerializedAsync将场景序列化为字节数组。

Microsoft.MixedReality.SceneUnderstanding.Samples是一个基于Unity的示例应用程序,展示了HoloLens 2上的“场景理解”。它展示了如何通过将ComputeSerializedAsync的输出保存到文件Line1154来保存捕获的任何场景。

此外,SaveObjsToDiskAsync函数演示如何将场景理解中的Unity对象保存为Obj文件:Line1206

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...