Skip to main content
Version: 14 May 2024

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.

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($"{nameof(MagicLeapMeshingFeature)} was not enabled. Disabling script");
enabled = false;
}
MLPermissions.RequestPermission(MLPermission.SpatialMapping, permissionCallbacks);
}

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 the fillHoleLength, appliedDisconnectedComponentArea, flags to represent generated mesh properties, and whether to use the ion allocator.
MagicLeapMeshingFeature.MeshingQuerySettings querySettings = MagicLeapMeshingFeature.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 the meshingFeature instead
note

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 = MagicLeapMeshingFeature.MeshingMode.Triangles
meshManager.transform.localScale = localScale;
meshManager.transform.rotation = Quaternion.Euler(rotation);
meshManager.transform.localPosition = localPosition;
meshManager.density = density;
/* PointCloud */
meshingFeature.MeshRenderMode = MagicLeapMeshingFeature.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.

note

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

note

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;