Forum Discussion
Zeljko777
2 years agoExplorer
Problems with MultiRoomMeshes
I have created a new Unity project. The goal was to create a passthrough project that runs exclusively on Windows PCs. The 3D objects should then be created based on the room data. In its final stage, the game will run on the PC, with the headset used for visualization! However, I encountered an issue that arises with multi-room data. If only one room is stored in the Meta Quest, the problem does not occur.
The software I used:
- Unity 2022.3.53f1
- VS2022 Community Edition
- Meta XR All-in-One-SDK
For testing, I used the Blockbuilder function:
- OVRCameraRig
- SceneMesh Experimental
More information can be found in the images!
Has anyone experienced the same issue or can reproduce it?
Hallo, I have solved the problem. Here is a update of the Code! You can use it it for the MetaQuestAllinOnesdk :-!
using System.Collections.Generic;using UnityEngine;using System.Linq;public class RoomMeshController : MonoBehaviour{[SerializeField] private GameObject _meshPrefab;private RoomMeshEvent _roomMeshEvent;private Dictionary<Guid, RoomMeshAnchor> _roomMeshAnchors;private void Awake(){_roomMeshAnchors = new Dictionary<Guid, RoomMeshAnchor>();_roomMeshEvent = FindObjectOfType<RoomMeshEvent>();}private IEnumerator Start(){var timeout = 10f;var startTime = Time.time;while (!OVRPermissionsRequester.IsPermissionGranted(OVRPermissionsRequester.Permission.Scene)){if (Time.time - startTime > timeout){Debug.LogWarning($"[{nameof(RoomMeshController)}] Spatial Data permission is required to load Room Mesh.");yield break;}yield return null;}yield return LoadRoomMesh();yield return UpdateVolume();foreach (var anchor in _roomMeshAnchors.Values){timeout = 3f;startTime = Time.time;while (!anchor.IsCompleted){if (Time.time - startTime > timeout){Debug.LogWarning($"[{nameof(RoomMeshController)}] Failed to create Room Mesh for anchor {anchor.gameObject.name}.");continue;}yield return null;}_roomMeshEvent.OnRoomMeshLoadCompleted?.Invoke(anchor.GetComponent<MeshFilter>());}}private IEnumerator UpdateVolume(){foreach (var anchor in _roomMeshAnchors.Values){while (!anchor.IsCompleted) yield return null;var parentMeshFilter = anchor.GetComponent<MeshFilter>();var parentMesh = parentMeshFilter.sharedMesh;var vertices = new List<Vector3>();var triangles = new List<int>();parentMesh.GetVertices(vertices);parentMesh.GetTriangles(triangles, 0);var c = new Color[triangles.Count];var v = new Vector3[triangles.Count];var idx = new int[triangles.Count];for (var i = 0; i < triangles.Count; i++){c[i] = new Color(i % 3 == 0 ? 1.0f : 0.0f,i % 3 == 1 ? 1.0f : 0.0f,i % 3 == 2 ? 1.0f : 0.0f);v[i] = vertices[triangles[i]];idx[i] = i;}var mesh = new Mesh{indexFormat = IndexFormat.UInt32};mesh.SetVertices(v);mesh.SetColors(c);mesh.SetIndices(idx, MeshTopology.Triangles, 0, true, 0);mesh.RecalculateBounds();mesh.RecalculateNormals();parentMeshFilter.sharedMesh = mesh;}}private IEnumerator LoadRoomMesh(){using (new OVRObjectPool.ListScope<OVRAnchor>(out var anchors)){var task = OVRAnchor.FetchAnchorsAsync(anchors, new OVRAnchor.FetchOptions{SingleComponentType = typeof(OVRTriangleMesh)});while (task.IsPending) yield return null;if (anchors.Count == 0){Debug.LogWarning($"[{nameof(RoomMeshController)}] No RoomMesh available.");yield break;}foreach (var anchor in anchors){if (!anchor.TryGetComponent(out OVRLocatable locatableComponent)){Debug.LogWarning($"[{nameof(RoomMeshController)}] Failed to localize the room mesh anchor.");continue;}var localizeTask = locatableComponent.SetEnabledAsync(true);while (localizeTask.IsPending) yield return null;InstantiateRoomMesh(anchor, _meshPrefab);}}}private void InstantiateRoomMesh(OVRAnchor anchor, GameObject prefab){var roomMeshAnchor = Instantiate(prefab, Vector3.zero, Quaternion.identity).GetComponent<RoomMeshAnchor>();roomMeshAnchor.gameObject.name = anchor.Uuid.ToString();roomMeshAnchor.gameObject.SetActive(true);roomMeshAnchor.Initialize(anchor);_roomMeshAnchors[anchor.Uuid] = roomMeshAnchor;}}}
Please Look in The Codes the Changes, so you can Work with MultiMeshRooms :-)!
1 Reply
Replies have been turned off for this discussion
- Zeljko777Explorer
Hallo, I have solved the problem. Here is a update of the Code! You can use it it for the MetaQuestAllinOnesdk :-!
using System.Collections.Generic;using UnityEngine;using System.Linq;public class RoomMeshController : MonoBehaviour{[SerializeField] private GameObject _meshPrefab;private RoomMeshEvent _roomMeshEvent;private Dictionary<Guid, RoomMeshAnchor> _roomMeshAnchors;private void Awake(){_roomMeshAnchors = new Dictionary<Guid, RoomMeshAnchor>();_roomMeshEvent = FindObjectOfType<RoomMeshEvent>();}private IEnumerator Start(){var timeout = 10f;var startTime = Time.time;while (!OVRPermissionsRequester.IsPermissionGranted(OVRPermissionsRequester.Permission.Scene)){if (Time.time - startTime > timeout){Debug.LogWarning($"[{nameof(RoomMeshController)}] Spatial Data permission is required to load Room Mesh.");yield break;}yield return null;}yield return LoadRoomMesh();yield return UpdateVolume();foreach (var anchor in _roomMeshAnchors.Values){timeout = 3f;startTime = Time.time;while (!anchor.IsCompleted){if (Time.time - startTime > timeout){Debug.LogWarning($"[{nameof(RoomMeshController)}] Failed to create Room Mesh for anchor {anchor.gameObject.name}.");continue;}yield return null;}_roomMeshEvent.OnRoomMeshLoadCompleted?.Invoke(anchor.GetComponent<MeshFilter>());}}private IEnumerator UpdateVolume(){foreach (var anchor in _roomMeshAnchors.Values){while (!anchor.IsCompleted) yield return null;var parentMeshFilter = anchor.GetComponent<MeshFilter>();var parentMesh = parentMeshFilter.sharedMesh;var vertices = new List<Vector3>();var triangles = new List<int>();parentMesh.GetVertices(vertices);parentMesh.GetTriangles(triangles, 0);var c = new Color[triangles.Count];var v = new Vector3[triangles.Count];var idx = new int[triangles.Count];for (var i = 0; i < triangles.Count; i++){c[i] = new Color(i % 3 == 0 ? 1.0f : 0.0f,i % 3 == 1 ? 1.0f : 0.0f,i % 3 == 2 ? 1.0f : 0.0f);v[i] = vertices[triangles[i]];idx[i] = i;}var mesh = new Mesh{indexFormat = IndexFormat.UInt32};mesh.SetVertices(v);mesh.SetColors(c);mesh.SetIndices(idx, MeshTopology.Triangles, 0, true, 0);mesh.RecalculateBounds();mesh.RecalculateNormals();parentMeshFilter.sharedMesh = mesh;}}private IEnumerator LoadRoomMesh(){using (new OVRObjectPool.ListScope<OVRAnchor>(out var anchors)){var task = OVRAnchor.FetchAnchorsAsync(anchors, new OVRAnchor.FetchOptions{SingleComponentType = typeof(OVRTriangleMesh)});while (task.IsPending) yield return null;if (anchors.Count == 0){Debug.LogWarning($"[{nameof(RoomMeshController)}] No RoomMesh available.");yield break;}foreach (var anchor in anchors){if (!anchor.TryGetComponent(out OVRLocatable locatableComponent)){Debug.LogWarning($"[{nameof(RoomMeshController)}] Failed to localize the room mesh anchor.");continue;}var localizeTask = locatableComponent.SetEnabledAsync(true);while (localizeTask.IsPending) yield return null;InstantiateRoomMesh(anchor, _meshPrefab);}}}private void InstantiateRoomMesh(OVRAnchor anchor, GameObject prefab){var roomMeshAnchor = Instantiate(prefab, Vector3.zero, Quaternion.identity).GetComponent<RoomMeshAnchor>();roomMeshAnchor.gameObject.name = anchor.Uuid.ToString();roomMeshAnchor.gameObject.SetActive(true);roomMeshAnchor.Initialize(anchor);_roomMeshAnchors[anchor.Uuid] = roomMeshAnchor;}}}
Please Look in The Codes the Changes, so you can Work with MultiMeshRooms :-)!
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 2 years ago
- 8 months ago