Environmental Meshing
Meshing in the Magic Leap Unity Open XR SDK is controlled by the Unity ARMeshManager
component or the ARPointCloudManager
component depending on the render mode your application needs to use. This guide provides an overview of the Magic Leap Environmental Meshing OpenXR Feature.
using MagicLeap.OpenXR.Features.Meshing;
Prerequisites
Enable Meshing Feature Support
- Go to Edit > Project Settings > OpenXR > OpenXR Feature Groups and enable the Magic Leap 2 Meshing Subsystem support.
Enable Permissions
- Go to Edit > Project Settings > Magic Leap > Permissions and enable the SPATIAL_MAPPING Magic Leap permission.
Scripting
After replacing the default Main Camera object in your scene with the ML Rig from the ML Rig & Inputs package and adding either the ARMeshManager
, ARPointCloudManager
or both to the scene, you can enable meshing through scripting.
Initializing feature and manager
Retrieve the components from the relevant GameObject, then initialize and request permissions. On permissions being granted, enable the ARMeshManager
and modify the query to begin generating meshes.
[SerializeField] private ARMeshManager meshManager;
[SerializeField] private ARPointCloudManager pointCloudManager;
private MagicLeapMeshingFeature meshingFeature;
IEnumerator Start()
{
mainCamera = Camera.main;
meshManager.enabled = false;
pointCloudManager.enabled = false;
yield return new WaitUntil(Utils.AreSubsystemsLoaded<XRMeshSubsystem>);
meshingFeature = OpenXRSettings.Instance.GetFeature<MagicLeapMeshingFeature>();
if (!meshingFeature.enabled)
{
Debug.LogError($"MagicLeapMeshingFeature was not enabled. Disabling script");
enabled = false;
}
Permission.RequestUserPermission(MagicLeap.Android.Permissions.SpatialMapping);
}
Modifying mesh queries
Update each of the relevant fields for the manager and feature to generate meshes.
- Begin by creating an instance of the
MeshQuerySettings
struct; this can be modified as needed, and includes values to determine thefillHoleLength
,appliedDisconnectedComponentArea
, flags to represent generated mesh properties, and whether to use the ion allocator.
MeshingQuerySettings querySettings = MeshingQuerySettings.DefaultSettings();
- Modify the manager’s rotation/scale/position to modify the bounding box to generate meshes in. - Modify the density to increase/decrease tessellation of the mesh.
- When using the
Pointcloud
renderer, modify all values within themeshingFeature
instead
The settings even when using triangle mode can be updated via the feature's properties. The AR Mesh manager's usage is the one that is optional.
/* Triangles */
meshingFeature.MeshRenderMode = MeshingMode.Triangles
meshManager.transform.localScale = localScale;
meshManager.transform.rotation = Quaternion.Euler(rotation);
meshManager.transform.localPosition = localPosition;
meshManager.density = density;
/* PointCloud */
meshingFeature.MeshRenderMode = MeshingMode.PointCloud
meshingFeature.MeshDensity = meshSettings.meshDensity;
meshingFeature.MeshBoundsOrigin = meshSettings.meshBoundsOrigin;
meshingFeature.MeshBoundsRotation = Quaternion.Euler(meshSettings.meshBoundsRotation);
meshingFeature.MeshBoundsScale = meshSettings.meshBoundsScale;
After modifying settings, update the settings and invalidate all meshes. If you are not switching between render modes, this is all that needs to be done; otherwise, destroy all current meshes and continue.
The reason to invalidate the meshes is if there are meshes in the previous frame that could be seen as invalid. For example: The meshing backend does not remove the old meshes if the bounds are changed. So if it is not desired to keep old meshes that are no longer within the bounds that are currently being used, they must be invalidated and destroyed. If the use case requires multiple bounds that are valid, do not do this.
meshingFeature.UpdateMeshQuerySettings(in querySettings);
meshingFeature.InvalidateMeshes();
/* if switching render modes */
meshManager.DestroyAllMeshes();
meshManager.enabled = false;
pointCloudManager.SetTrackablesActive(false);
pointCloudManager.enabled = false;
Switching Render Modes
If switching render modes, the meshes must be destroyed so that the new render mode works.
If switching to PointCloud, disable the meshmanager
and enable the pointCloudManager
; otherwise, do the opposite.
// To pointCloud
meshManager.enabled = false;
pointCloudManager.enabled = true;
pointCloudManager.SetTrackablesActive(true);
//To Triangles
pointCloudManager.SetTrackablesActive(false);
pointCloudManager.enabled = false;
meshManager.enabled = true;