Forum Discussion
Zeljko777
1 year 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...
- 1 year ago
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 :-)!
Zeljko777
1 year agoExplorer
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
- 1 year ago
- 11 months ago