Beispiel #1
0
        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.");
            }
        }
Beispiel #3
0
 void StopSubsystem()
 {
     m_initialized = false;
     if (m_Loader != null)
     {
         m_Loader.StopMeshSubsystem();
     }
     m_MeshSubsystem = null;
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
 }
Beispiel #6
0
        /// <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;
                    }
                }
            }
        }
Beispiel #7
0
        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);
        }
Beispiel #11
0
        /// <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();
            }
        }
Beispiel #13
0
    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;
    }
Beispiel #14
0
 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;
                }
            }
        }
Beispiel #17
0
 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);
 }