void Start() { var feature = OpenXRSettings.Instance.GetFeature <MeshingTeapotFeature>(); if (null == feature || feature.enabled == false) { enabled = false; return; } var meshSubsystems = new List <XRMeshSubsystem>(); SubsystemManager.GetInstances(meshSubsystems); if (meshSubsystems.Count == 1) { s_MeshSubsystem = meshSubsystems[0]; textMesh.gameObject.SetActive(false); } else { #if UNITY_EDITOR textMesh.text = "Failed to initialize MeshSubsystem.\nTry reloading the Unity Editor"; #else textMesh.text = "Failed to initialize MeshSubsystem."; #endif enabled = false; } }
public static void SetMeshingFeature(this XRMeshSubsystem meshSubsystem, Feature feature) { // TODO (05/25/2020): update this to maintain the flags for the explicit magic leap subsystem // TODO (05/25/2020): move get default meshing settings to a shared place (MeshingSettings?) var settings = MLSpatialMapper.GetDefaultMeshingSettings(); if (feature.HasFlag(Feature.Meshing | Feature.PointCloud)) { if (feature.HasFlag(Feature.Meshing) && feature.HasFlag(Feature.PointCloud)) { throw new InvalidOperationException("Magic Leap does not support surfacing point cloud data while also surfacing meshing."); } if (feature.HasFlag(Feature.Meshing)) { settings.flags ^= MLMeshingFlags.PointCloud; } MeshingSettings.meshingSettings = settings; } else { throw new ArgumentException($"Attempted to set invalid feature {feature} on Magic Leap Mesh Subsystem."); } }
void StopSubsystem() { m_initialized = false; if (m_Loader != null) { m_Loader.StopMeshSubsystem(); } m_MeshSubsystem = null; }
public static void SetBoundingVolumeSphere(this XRMeshSubsystem meshing, Vector3 center, float radius) { WMRSphere sbb; sbb.cx = center.x; sbb.cy = center.y; sbb.cz = center.z; sbb.r = radius; NativeApi.SetBoundingVolumeSphere(sbb); }
public static void SetBoundingVolumeFrustum(this XRMeshSubsystem meshing, Plane[] planes) { for (int i = 0; i < 6; i++) { wmrp[i].d = planes[i].distance; wmrp[i].nx = planes[i].normal.x; wmrp[i].ny = planes[i].normal.y; wmrp[i].nz = planes[i].normal.z; } NativeApi.SetBoundingVolumeFrustum(wmrp, 6); }
/// <summary> /// Break up a single mesh with multiple face classifications into submeshes, each with an unique and uniform mesh /// classification. /// </summary> /// <param name="meshFilter">The mesh filter for the base mesh with multiple face classifications.</param> void BreakupMesh(MeshFilter meshFilter) { XRMeshSubsystem meshSubsystem = m_MeshManager.subsystem as XRMeshSubsystem; if (meshSubsystem == null) { return; } var meshId = ExtractTrackableId(meshFilter.name); var faceClassifications = meshSubsystem.GetFaceClassifications(meshId, Allocator.Persistent); if (!faceClassifications.IsCreated) { return; } using (faceClassifications) { if (faceClassifications.Length <= 0) { return; } var parent = meshFilter.transform.parent; MeshFilter[] meshFilters = new MeshFilter[k_NumClassifications]; meshFilters[(int)ARMeshClassification.None] = (m_NoneMeshPrefab == null) ? null : Instantiate(m_NoneMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Wall] = (m_WallMeshPrefab == null) ? null : Instantiate(m_WallMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Floor] = (m_FloorMeshPrefab == null) ? null : Instantiate(m_FloorMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Ceiling] = (m_CeilingMeshPrefab == null) ? null : Instantiate(m_CeilingMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Table] = (m_TableMeshPrefab == null) ? null : Instantiate(m_TableMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Seat] = (m_SeatMeshPrefab == null) ? null : Instantiate(m_SeatMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Window] = (m_WindowMeshPrefab == null) ? null : Instantiate(m_WindowMeshPrefab, parent); meshFilters[(int)ARMeshClassification.Door] = (m_DoorMeshPrefab == null) ? null : Instantiate(m_DoorMeshPrefab, parent); m_MeshFrackingMap[meshId] = meshFilters; var baseMesh = meshFilter.sharedMesh; for (int i = 0; i < k_NumClassifications; ++i) { var classifiedMeshFilter = meshFilters[i]; if (classifiedMeshFilter != null) { var classifiedMesh = classifiedMeshFilter.mesh; ExtractClassifiedMesh(baseMesh, faceClassifications, (ARMeshClassification)i, classifiedMesh); meshFilters[i].mesh = classifiedMesh; } } } }
public static void SetBoundingVolumeOrientedBox(this XRMeshSubsystem meshing, Vector3 center, Vector3 extents, Quaternion orientation) { WMROrientedBox obb; obb.cx = center.x; obb.cy = center.y; obb.cz = center.z; obb.ex = extents.x; obb.ey = extents.y; obb.ez = extents.z; obb.ox = orientation.x; obb.oy = orientation.y; obb.oz = orientation.z; obb.ow = orientation.w; NativeApi.SetBoundingVolumeOrientedBox(obb); }
/// <summary> /// Break up a single mesh with multiple face classifications into submeshes, each with an unique and uniform mesh /// classification. /// </summary> /// <param name="meshFilter">The mesh filter for the base mesh with multiple face classifications.</param> void BreakupMesh(MeshFilter meshFilter) { XRMeshSubsystem meshSubsystem = m_MeshManager.subsystem as XRMeshSubsystem; if (meshSubsystem == null) { return; } var meshId = ExtractTrackableId(meshFilter.name); var faceClassifications = meshSubsystem.GetFaceClassifications(meshId, Allocator.Persistent); if (!faceClassifications.IsCreated) { return; } using (faceClassifications) { if (faceClassifications.Length <= 0) { return; } var parent = meshFilter.transform.parent; //Discard wall/ceiling meshes MeshFilter[] meshFilters = new MeshFilter[] { Instantiate(m_Ground, parent), null, Instantiate(m_Ground, parent), null, Instantiate(m_Ground, parent), Instantiate(m_Ground, parent), null, null }; m_MeshFrackingMap[meshId] = meshFilters; var baseMesh = meshFilter.sharedMesh; for (int i = 0; i < k_NumClassifications; ++i) { var classifiedMeshFilter = meshFilters[i]; if (classifiedMeshFilter != null) { var classifiedMesh = classifiedMeshFilter.mesh; ExtractClassifiedMesh(baseMesh, faceClassifications, (ARMeshClassification)i, classifiedMesh); meshFilters[i].mesh = classifiedMesh; } } } }
/// <summary> /// Update the submeshes corresponding to the single mesh with multiple face classifications into submeshes. /// </summary> /// <param name="meshFilter">The mesh filter for the base mesh with multiple face classifications.</param> void UpdateMesh(MeshFilter meshFilter) { XRMeshSubsystem meshSubsystem = m_MeshManager.subsystem as XRMeshSubsystem; if (meshSubsystem == null) { return; } var meshId = ExtractTrackableId(meshFilter.name); var faceClassifications = meshSubsystem.GetFaceClassifications(meshId, Allocator.Persistent); if (!faceClassifications.IsCreated) { return; } using (faceClassifications) { if (faceClassifications.Length <= 0) { return; } var meshFilters = m_MeshFrackingMap[meshId]; var baseMesh = meshFilter.sharedMesh; var faceClassificationsList = faceClassifications.Select(classification => allowedClassifications[classification]).ToList(); for (int i = 0; i < k_NumClassifications; ++i) { var classifiedMeshFilter = meshFilters[i]; if (classifiedMeshFilter == null) { continue; } var classifiedMesh = classifiedMeshFilter.mesh; ExtractClassifiedMesh(baseMesh, faceClassificationsList, allowedClassificationsList[i], classifiedMesh); meshFilters[i].mesh = classifiedMesh; meshFilters[i].GetComponent <MeshCollider>().sharedMesh = classifiedMesh; } } }
public override void Initialize() { base.Initialize(); if (!Application.isPlaying || Application.isEditor || meshSubsystem != null) { return; } descriptors.Clear(); SubsystemManager.GetSubsystemDescriptors(descriptors); if (descriptors.Count > 0) { var descriptorToUse = descriptors[0]; if (descriptors.Count > 1) { var typeOfD = typeof(XRMeshSubsystemDescriptor); Debug.LogWarning($"Found {descriptors.Count} {typeOfD.Name}s. Using \"{descriptorToUse.id}\""); } meshSubsystem = descriptorToUse.Create(); } if (meshSubsystem == null) { throw new Exception("Failed to start Lumin Mesh Subsystem!"); } LuminApi.UnityMagicLeap_MeshingSetBatchSize(16); var levelOfDetail = MLSpatialMapper.LevelOfDetail.Medium; if (MeshLevelOfDetail == SpatialAwarenessMeshLevelOfDetail.Fine) { levelOfDetail = MLSpatialMapper.LevelOfDetail.Maximum; } LuminApi.UnityMagicLeap_MeshingSetLod(levelOfDetail); var settings = GetMeshingSettings(); LuminApi.UnityMagicLeap_MeshingUpdateSettings(settings); }
/// <summary> /// Update the submeshes corresponding to the single mesh with multiple face classifications into submeshes. /// </summary> /// <param name="meshFilter">The mesh filter for the base mesh with multiple face classifications.</param> void UpdateMesh(MeshFilter meshFilter) { XRMeshSubsystem meshSubsystem = m_MeshManager.subsystem as XRMeshSubsystem; if (meshSubsystem == null) { return; } var meshId = ExtractTrackableId(meshFilter.name); var faceClassifications = meshSubsystem.GetFaceClassifications(meshId, Allocator.Persistent); if (!faceClassifications.IsCreated) { return; } using (faceClassifications) { if (faceClassifications.Length <= 0) { return; } var meshFilters = m_MeshFrackingMap[meshId]; var baseMesh = meshFilter.sharedMesh; for (int i = 0; i < k_NumClassifications; ++i) { var classifiedMeshFilter = meshFilters[i]; if (classifiedMeshFilter != null) { var classifiedMesh = classifiedMeshFilter.mesh; ExtractClassifiedMesh(baseMesh, faceClassifications, (ARMeshClassification)i, classifiedMesh); meshFilters[i].mesh = classifiedMesh; } } } }
/// <summary> /// Creates the XRMeshSubsystem and handles the desired startup behavior. /// </summary> protected override void CreateObserver() { if (Service == null #if XR_MANAGEMENT_ENABLED || XRGeneralSettings.Instance == null || XRGeneralSettings.Instance.Manager == null || XRGeneralSettings.Instance.Manager.activeLoader == null #endif // XR_MANAGEMENT_ENABLED ) { return; } #if XR_MANAGEMENT_ENABLED meshSubsystem = XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem <XRMeshSubsystem>(); #else meshSubsystem = XRSubsystemHelpers.MeshSubsystem; #endif // XR_MANAGEMENT_ENABLED if (meshSubsystem != null) { ConfigureObserverVolume(); } }
IEnumerator Initialize() { while (XRGeneralSettings.Instance == null) { yield return(null); } while (XRGeneralSettings.Instance.Manager == null) { yield return(null); } m_Loader = XRGeneralSettings.Instance.Manager.ActiveLoaderAs <VarjoLoader>(); if (m_Loader != null) { m_MeshSubsystem = m_Loader.meshSubsystem; } StartSubsystem(); m_initialized = true; }
public static void GetMeshingDataForMesh(this XRMeshSubsystem meshing, UnityEngine.XR.MeshId meshId, out MeshingData data) { NativeApi.GetMeshingDataForMesh(meshId, out data); }
internal static bool RegisterNativeSubsystemCallbacks(this XRMeshSubsystem meshSubsystem) => NativeApi.RegisterMeshProviderFeatureCallbacks(s_OnMeshSubsystemStart, s_OnMeshSubsystemStop);
/// <summary> /// Break up a single mesh with multiple face classifications into submeshes, each with an unique and uniform mesh /// classification. /// </summary> /// <param name="meshFilter">The mesh filter for the base mesh with multiple face classifications.</param> void BreakupMesh(MeshFilter meshFilter) { XRMeshSubsystem meshSubsystem = m_MeshManager.subsystem as XRMeshSubsystem; if (meshSubsystem == null) { return; } var meshId = ExtractTrackableId(meshFilter.name); var faceClassifications = meshSubsystem.GetFaceClassifications(meshId, Allocator.Persistent); if (!faceClassifications.IsCreated) { return; } using (faceClassifications) { if (faceClassifications.Length <= 0) { return; } Debug.Log("Before faceClassificationsList"); var faceClassificationsList = faceClassifications.Select(classification => allowedClassifications[classification]).ToList(); Debug.Log("After faceClassificationsList"); var parent = meshFilter.transform.parent; MeshFilter[] meshFilters = new MeshFilter[k_NumClassifications]; meshFilters[0] = (m_FloorMeshPrefab == null) ? null : Instantiate(m_FloorMeshPrefab, parent); meshFilters[1] = (m_WallMeshPrefab == null) ? null : Instantiate(m_WallMeshPrefab, parent); meshFilters[2] = (m_TableMeshPrefab == null) ? null : Instantiate(m_TableMeshPrefab, parent); foreach (var entry in meshFilters) { entry.GetComponent <MeshRenderer>().enabled = MeshVisualizationEnabled; } m_MeshFrackingMap[meshId] = meshFilters; Debug.Log("Created meshFilters"); var baseMesh = meshFilter.sharedMesh; for (int i = 0; i < k_NumClassifications; ++i) { var classifiedMeshFilter = meshFilters[i]; if (classifiedMeshFilter == null) { continue; } var classifiedMesh = classifiedMeshFilter.mesh; ExtractClassifiedMesh(baseMesh, faceClassificationsList, allowedClassificationsList[i], classifiedMesh); Debug.Log($"Extracted meshFilters for {allowedClassificationsList[i]}"); meshFilters[i].mesh = classifiedMesh; meshFilters[i].GetComponent <MeshCollider>().sharedMesh = classifiedMesh; } } }
public static void ReleaseMeshingData(this XRMeshSubsystem meshing, ref MeshingData data) { NativeApi.ReleaseMeshingData(ref data); }
/// <summary> /// Returns the current classification enabled state. /// </summary> /// <param name="subsystem">The meshing subsystem.</param> /// <returns> /// <c>true</c> if the mesh classification is enabled. Otherwise, <c>false</c>. /// </returns> public static bool GetClassificationEnabled(this XRMeshSubsystem subsystem) { return(NativeApi.UnityARKit_MeshProvider_IsClassificationEnabled()); }
/// <summary> /// Get the face classifications for the given mesh ID. /// </summary> /// <param name="subsystem">The meshing subsystem.</param> /// <param name="meshId">The trackable ID representing the mesh.</param> /// <param name="allocator">The memory allocator type to use in allocating the native array memory.</param> /// <returns> /// An array of mesh classifications, one for each face in the mesh. /// </returns> public static unsafe NativeArray <ARMeshClassification> GetFaceClassifications(this XRMeshSubsystem subsystem, TrackableId meshId, Allocator allocator) { void *classifications = NativeApi.UnityARKit_MeshProvider_AcquireClassifications(meshId, out int numClassifications); try { if (classifications == null) { numClassifications = 0; } var meshClassifications = new NativeArray <ARMeshClassification>(numClassifications, allocator); if (classifications != null) { NativeArray <ARMeshClassification> tmp = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ARMeshClassification>(classifications, numClassifications, Allocator.None); meshClassifications.CopyFrom(tmp); } return(meshClassifications); } finally { NativeApi.UnityARKit_MeshProvider_ReleaseClassifications(classifications); } }
/// <summary> /// Sets the current classification enabled state. /// </summary> /// <param name="subsystem">The meshing subsystem.</param> /// <param name="enabled">Whether the mesh classification should be enabled.</param> public static void SetClassificationEnabled(this XRMeshSubsystem subsystem, bool enabled) { NativeApi.UnityARKit_MeshProvider_SetClassificationEnabled(enabled); }