I'm currently stuck in a problem relating the HololLens2. I try to access the spatial mapping directly during runtime. So I want to implement a scanning procedure, where the user has to scan the room and then I want to export this mesh. Basically I want to create the .obj of the room scan like in the device portal but during runtime.
Therefore I've implemented a solution, which I've found here: https://learn.microsoft.com/en-us/windows/mixed-reality/mrtk-unity/mrtk2/features/spatial-awareness/usage-guide?view=mrtkunity-2022-05
The problem now is that I don't get any meshes.
I currently use MRTK 2.8.3.0 and Unity 2022.3.10f1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.SpatialAwareness;
using TMPro;
using Unity.VisualScripting;
public class Scanner_new : MonoBehaviour
{
public GameObject txt;
static int count = 0;
// Start is called before the first frame update
void Start()
{
TextMeshPro textMesh = txt.GetComponent<TextMeshPro>();
// Use CoreServices to quickly get access to the IMixedRealitySpatialAwarenessSystem
var spatialAwarenessService = CoreServices.SpatialAwarenessSystem;
// Cast to the IMixedRealityDataProviderAccess to get access to the data providers
var dataProviderAccess = spatialAwarenessService as IMixedRealityDataProviderAccess;
var meshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
if(meshObserver == null){
count++;
textMesh.text = "No Observer! \n";
Debug.Log("No Observer! \n");
return;
}
textMesh.text += "Accessing all the meshes: \n";
// Loop through all known Meshes
foreach (SpatialAwarenessMeshObject meshObject in meshObserver.Meshes.Values)
{ textMesh.text = "here1 \n";
Mesh mesh = meshObject.Filter.mesh;
var triangles = mesh.GetTriangles(0);
foreach (var triangle in triangles){
textMesh.text = "here2 \n";
textMesh.text += triangle + "\n";
count++;
}
}
}
// Update is called once per frame
public void Updater()
{
TextMeshPro textMesh = txt.GetComponent<TextMeshPro>();
if(count == 0){
// Use CoreServices to quickly get access to the IMixedRealitySpatialAwarenessSystem
var spatialAwarenessService = CoreServices.SpatialAwarenessSystem;
// Cast to the IMixedRealityDataProviderAccess to get access to the data providers
var dataProviderAccess = spatialAwarenessService as IMixedRealityDataProviderAccess;
var meshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
if(meshObserver == null){
count++;
textMesh.text = "No Observer! \n";
Debug.Log("No Observer! \n");
return;
}
textMesh.text += "Accessing all the meshes: \n";
// Loop through all known Meshes
foreach (SpatialAwarenessMeshObject meshObject in meshObserver.Meshes.Values)
{
textMesh.text = "here1 \n";
Mesh mesh = meshObject.Filter.mesh;
var triangles = mesh.GetTriangles(0);
foreach (var triangle in triangles){
textMesh.text = "here2 \n";
textMesh.text += triangle + "\n";
count++;
}
}
}
}
}
Thanks for your help :)
Because I was busy for quite a long time to find a solution for this problem and now I have also found one I would like to share it here.
In Unity it is important that the Spatial Observer "OpenXR Spatial Mesh Observer" exists in the MixedReality Toollkit Gameobject in the Inspector under the Spatial Awareness tab.
If this is the case, the following code should work:
As you can see, the code is producing directly an .obj-file from the saved data. This code is inspired by the answer to the following question: MRTK 2.4 - Save Spatial Mesh on Runtime
The .obj-file can then be accessed over the device-portal->File Explorer and there in the localState-folder of your application :)