public unsafe override TrackableChanges <XRParticipant> GetChanges(
                XRParticipant defaultParticipant,
                Allocator allocator)
            {
                if (!created)
                {
                    throw new InvalidOperationException($"The {typeof(ARKitParticipantSubsystem).Name} provider has not been created.");
                }

                using (var nativeChanges = Api.UnityARKit_TrackableProvider_acquireChanges(m_Ptr))
                {
                    var changes = new TrackableChanges <XRParticipant>(
                        nativeChanges.addedLength,
                        nativeChanges.updatedLength,
                        nativeChanges.removedLength,
                        allocator, defaultParticipant);

                    Api.UnityARKit_TrackableProvider_copyChanges(
                        m_Ptr, nativeChanges,
                        UnsafeUtility.SizeOf <XRParticipant>(),
                        changes.added.GetUnsafePtr(),
                        changes.updated.GetUnsafePtr(),
                        changes.removed.GetUnsafePtr());

                    return(changes);
                }
            }
예제 #2
0
        private bool UpdateTrackables()
        {
            if (xrReferencePointManager == null)
            {
                return(false);
            }
            TrackableChanges <XRReferencePoint> changes = xrReferencePointManager.GetChanges(Unity.Collections.Allocator.Temp);

            if (changes.isCreated && (changes.added.Length + changes.updated.Length + changes.removed.Length > 0))
            {
                DebugLogExtra($"Changes Fr{Time.frameCount:0000}: isCreated={changes.isCreated} Added={changes.added.Length}, Updated={changes.updated.Length} Removed={changes.removed.Length}");
                for (int i = 0; i < changes.added.Length; ++i)
                {
                    UpdateTracker("Added::", changes.added[i], anchorsByTrackableId);
                }
                for (int i = 0; i < changes.updated.Length; ++i)
                {
                    UpdateTracker("Updated::", changes.updated[i], anchorsByTrackableId);
                }
                for (int i = 0; i < changes.removed.Length; i++)
                {
                    RemoveTracker(changes.removed[i], anchorsByTrackableId);
                }
            }
            changes.Dispose();
            return(true);
        }
            public override TrackableChanges <UnityXRFace> GetChanges(UnityXRFace defaultFace, Allocator allocator)
            {
                var face = ARKitReceiver.Instance?.Face;

                if (face == null)
                {
                    return(new TrackableChanges <UnityXRFace>());
                }
                // Debug.Log($"GetChanges: {face}");

                var added   = face.added.Select(f => (UnityXRFace)f).ToList();
                var updated = face.updated.Select(f => (UnityXRFace)f).ToList();
                var removed = face.removed.Select(id => (UnityTrackableId)id).ToList();

                foreach (var f in added.ToArray())
                {
                    if (ids.Contains(f.trackableId))
                    {
                        added.Remove(f);
                    }
                    else
                    {
                        ids.Add(f.trackableId);
                    }
                }

                foreach (var f in updated.ToArray())
                {
                    // Send as new
                    if (!ids.Contains(f.trackableId))
                    {
                        updated.Remove(f);
                        added.Add(f);
                        ids.Add(f.trackableId);
                    }
                }
                foreach (var id in removed.ToArray())
                {
                    // Send ad
                    if (ids.Contains(id))
                    {
                        ids.Remove(id);
                    }
                    else
                    {
                        removed.Remove(id);
                    }
                }

                var nativeAdded   = new NativeArray <UnityXRFace>(added.ToArray(), Allocator.Temp);
                var nativeUpdated = new NativeArray <UnityXRFace>(updated.ToArray(), Allocator.Temp);
                var nativeRemoved = new NativeArray <UnityTrackableId>(removed.ToArray(), Allocator.Temp);

                return(TrackableChanges <UnityXRFace> .CopyFrom(nativeAdded, nativeUpdated, nativeRemoved, allocator));
            }
 public void CanBeDisposedMultipleTimes()
 {
     ForEachAllocator(allocator =>
     {
         var changes = new TrackableChanges <SubsystemTrackableData>(1, 1, 1, allocator);
         Assert.IsTrue(changes.isCreated);
         changes.Dispose();
         Assert.IsFalse(changes.isCreated);
         changes.Dispose();
     });
 }
            public override TrackableChanges <UnityEngine.XR.ARSubsystems.XRFace> GetChanges(UnityEngine.XR.ARSubsystems.XRFace defaultFace, Allocator allocator)
            {
                var changes = new TrackableChanges <UnityEngine.XR.ARSubsystems.XRFace>(m_AddedFaces.Count,
                                                                                        m_UpdatedFaces.Count, m_RemovedFaces.Count, allocator);
                var numAddedFaces = m_AddedFaces.Count;

                if (numAddedFaces > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numAddedFaces);
                    var i = 0;
                    foreach (var face in m_AddedFaces.Values)
                    {
                        m_ConversionBuffer[i++] = XRFaceFromIMRFace(face);
                    }
                    NativeArray <XRFace> .Copy(m_ConversionBuffer, changes.added.Reinterpret <XRFace>(), numAddedFaces);

                    m_AddedFaces.Clear();
                }

                var numUpdatedFaces = m_UpdatedFaces.Count;

                if (numUpdatedFaces > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numUpdatedFaces);
                    var i = 0;
                    foreach (var face in m_UpdatedFaces.Values)
                    {
                        m_ConversionBuffer[i++] = XRFaceFromIMRFace(face);
                    }
                    NativeArray <XRFace> .Copy(m_ConversionBuffer, changes.updated.Reinterpret <XRFace>(), numUpdatedFaces);

                    m_UpdatedFaces.Clear();
                }

                var numRemovedFaces = m_RemovedFaces.Count;

                if (numRemovedFaces > 0)
                {
                    Utils.EnsureCapacity(ref m_IdConversionBuffer, numRemovedFaces);
                    var i = 0;
                    foreach (var id in m_RemovedFaces)
                    {
                        m_IdConversionBuffer[i++] = new TrackableId(id.subId1, id.subId2);
                    }

                    NativeArray <TrackableId> .Copy(m_IdConversionBuffer, changes.removed, numRemovedFaces);

                    m_RemovedFaces.Clear();
                }

                return(changes);
            }
예제 #6
0
            public override TrackableChanges <XRPointCloud> GetChanges(XRPointCloud defaultPointCloud,
                                                                       Allocator allocator)
            {
                var pointClouds = m_PointClouds;

                var added      = pointClouds.Keys.Except(m_PreviousIds);
                var updated    = pointClouds.Keys.Intersect(m_PreviousIds);
                var removed    = m_PreviousIds.Except(pointClouds.Keys);
                var numAdded   = added.Count();
                var numUpdated = updated.Count();
                var numRemoved = removed.Count();

                var changes = new TrackableChanges <XRPointCloud>(numAdded, numUpdated, numRemoved, allocator);

                if (numAdded > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numAdded);
                    var i = 0;
                    foreach (var pointCloud in added)
                    {
                        m_ConversionBuffer[i++] = new XRPointCloud(new TrackableId(pointCloud.subId1, pointCloud.subId2),
                                                                   Pose.identity, TrackingState.Tracking, IntPtr.Zero);
                    }

                    NativeArray <XRPointCloud> .Copy(m_ConversionBuffer, changes.added, numAdded);
                }

                if (numUpdated > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numUpdated);
                    var i = 0;
                    foreach (var pointCloud in updated)
                    {
                        m_ConversionBuffer[i++] = new XRPointCloud(new TrackableId(pointCloud.subId1, pointCloud.subId2),
                                                                   Pose.identity, TrackingState.Tracking, IntPtr.Zero);
                    }

                    NativeArray <XRPointCloud> .Copy(m_ConversionBuffer, changes.updated, numUpdated);
                }

                if (numRemoved > 0)
                {
                    var removedArray = removed.Select(id => new TrackableId(id.subId1, id.subId2)).ToArray();
                    changes.removed.CopyFrom(removedArray);
                }

                m_PreviousIds.Clear();
                m_PreviousIds.AddRange(pointClouds.Keys);

                return(changes);
            }
            public override TrackableChanges <BoundedPlane> GetChanges(BoundedPlane defaultPlane, Allocator allocator)
            {
                var changes        = new TrackableChanges <BoundedPlane>(m_AddedPlanes.Count, m_UpdatedPlanes.Count, m_RemovedPlanes.Count, allocator);
                var numAddedPlanes = m_AddedPlanes.Count;

                if (numAddedPlanes > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numAddedPlanes);
                    var i = 0;
                    foreach (var plane in m_AddedPlanes.Values)
                    {
                        m_ConversionBuffer[i++] = BoundedPlaneFromMRPlane(plane);
                    }
                    NativeArray <BoundedPlane> .Copy(m_ConversionBuffer, changes.added, numAddedPlanes);

                    m_AddedPlanes.Clear();
                }

                var numUpdatedPlanes = m_UpdatedPlanes.Count;

                if (numUpdatedPlanes > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numUpdatedPlanes);
                    var i = 0;
                    foreach (var plane in m_UpdatedPlanes.Values)
                    {
                        m_ConversionBuffer[i++] = BoundedPlaneFromMRPlane(plane);
                    }
                    NativeArray <BoundedPlane> .Copy(m_ConversionBuffer, changes.updated, numUpdatedPlanes);

                    m_UpdatedPlanes.Clear();
                }

                var numRemovedPlanes = m_RemovedPlanes.Count;

                if (numRemovedPlanes > 0)
                {
                    Utils.EnsureCapacity(ref m_IdConversionBuffer, numRemovedPlanes);
                    var i = 0;
                    foreach (var id in m_RemovedPlanes)
                    {
                        m_IdConversionBuffer[i++] = new TrackableId(id.subId1, id.subId2);
                    }
                    NativeArray <TrackableId> .Copy(m_IdConversionBuffer, changes.removed, numRemovedPlanes);

                    m_RemovedPlanes.Clear();
                }

                return(changes);
            }
예제 #8
0
        bool CheckThereAreNoAnchors()
        {
            XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>();

            Assert.NotNull(rpsub);

            TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp);

            bool hasNoAnchors = (currentRps == null) ? false :
                                currentRps?.added.Length == 0 &&
                                currentRps?.removed.Length == 0 &&
                                currentRps?.updated.Length == 0;

            return(hasNoAnchors);
        }
        public TrackableChanges <T> Modify(List <T> added, List <T> updated, List <UnityTrackableId> removed, Allocator allocator)
        {
            // Check Added
            foreach (var f in added.ToArray())
            {
                if (ids.Contains(f.trackableId))
                {
                    added.Remove(f);
                }
                else
                {
                    ids.Add(f.trackableId);
                }
            }

            // Check Updated
            foreach (var f in updated.ToArray())
            {
                // Send as new
                if (!ids.Contains(f.trackableId))
                {
                    updated.Remove(f);
                    added.Add(f);
                    ids.Add(f.trackableId);
                }
            }

            // Check Removed
            foreach (var id in removed.ToArray())
            {
                // Send ad
                if (ids.Contains(id))
                {
                    ids.Remove(id);
                }
                else
                {
                    removed.Remove(id);
                }
            }

            var nativeAdded   = new NativeArray <T>(added.ToArray(), Allocator.Temp);
            var nativeUpdated = new NativeArray <T>(updated.ToArray(), Allocator.Temp);
            var nativeRemoved = new NativeArray <UnityTrackableId>(removed.ToArray(), Allocator.Temp);

            return(TrackableChanges <T> .CopyFrom(nativeAdded, nativeUpdated, nativeRemoved, allocator));
        }
            public override TrackableChanges <XREnvironmentProbe> GetChanges(XREnvironmentProbe defaultEnvironmentProbe,
                                                                             Allocator allocator)
            {
                XREnvironmentProbe probe = XREnvironmentProbe.GetDefault();

                NativeApi.UnityARCore_EnvironmentProbeProvider_GetChanges(out int numAdded, out int numUpdated, out int numRemoved, ref probe);

                // There is only ever one probe currently so allocating using it as the default template is safe.
                var changes = new TrackableChanges <XREnvironmentProbe>(numAdded, numUpdated, numRemoved, allocator, probe);

                if (numRemoved > 0)
                {
                    var nativeRemovedArray = changes.removed;
                    nativeRemovedArray[0] = probe.trackableId;
                }

                return(changes);
            }
예제 #11
0
 public override unsafe TrackableChanges <XRAnchor> GetChanges(
     XRAnchor defaultAnchor,
     Allocator allocator)
 {
     try
     {
         return(TrackableChanges <XRAnchor> .CopyFrom(
                    new NativeArray <XRAnchor>(
                        NativeApi.addedAnchors.Select(m => m.ToXRAnchor(defaultAnchor)).ToArray(), allocator),
                    new NativeArray <XRAnchor>(
                        NativeApi.updatedAnchors.Select(m => m.ToXRAnchor(defaultAnchor)).ToArray(), allocator),
                    new NativeArray <TrackableId>(
                        NativeApi.removedAnchors.Select(m => m.id).ToArray(), allocator),
                    allocator));
     }
     finally
     {
         NativeApi.UnityXRMock_consumedAnchorChanges();
     }
 }
 public override TrackableChanges <BoundedPlane> GetChanges(
     BoundedPlane defaultPlane,
     Allocator allocator)
 {
     try
     {
         return(TrackableChanges <BoundedPlane> .CopyFrom(
                    new NativeArray <BoundedPlane>(
                        NativeApi.addedPlanes.Select(m => m.ToBoundedPlane(defaultPlane)).ToArray(), allocator),
                    new NativeArray <BoundedPlane>(
                        NativeApi.updatedPlanes.Select(m => m.ToBoundedPlane(defaultPlane)).ToArray(), allocator),
                    new NativeArray <TrackableId>(
                        NativeApi.removedPlanes.Select(m => m.id).ToArray(), allocator),
                    allocator));
     }
     finally
     {
         NativeApi.UnityXRMock_consumedPlaneChanges();
     }
 }
            public override unsafe TrackableChanges <XRReferencePoint> GetChanges(
                XRReferencePoint defaultReferencePoint,
                Allocator allocator)
            {
                using (var updated = GetUpdated(Allocator.Temp, out int updatedCount))
                {
                    var changes = new TrackableChanges <XRReferencePoint>(
                        m_PendingAdds.Count,
                        updatedCount,
                        m_PendingRemoves.Count,
                        allocator);

                    GetAdded(changes.added);
                    NativeArray <XRReferencePoint> .Copy(updated, changes.updated, updatedCount);

                    GetRemoved(changes.removed);

                    return(changes);
                }
            }
예제 #14
0
 public override unsafe TrackableChanges <XRReferencePoint> GetChanges(
     XRReferencePoint defaultReferencePoint,
     Allocator allocator)
 {
     try
     {
         return(TrackableChanges <XRReferencePoint> .CopyFrom(
                    new NativeArray <XRReferencePoint>(
                        NativeApi.addedRefPoints.Select(m => m.ToXRReferencePoint(defaultReferencePoint)).ToArray(), allocator),
                    new NativeArray <XRReferencePoint>(
                        NativeApi.updatedRefPoints.Select(m => m.ToXRReferencePoint(defaultReferencePoint)).ToArray(), allocator),
                    new NativeArray <TrackableId>(
                        NativeApi.removedRefPoints.Select(m => m.id).ToArray(), allocator),
                    allocator));
     }
     finally
     {
         NativeApi.UnityXRMock_consumedReferencePointChanges();
     }
 }
예제 #15
0
        bool CheckAnchorUpdateState(TrackableId id, UpdateState updateState)
        {
            XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>();

            Assert.NotNull(rpsub);

            TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp);

            Assert.IsNotNull(currentRps);

            XRAnchor?   rp        = null;
            TrackableId idToCheck = defaultId;

            switch (updateState)
            {
            case UpdateState.Added:
                Assert.AreNotEqual(0, currentRps?.added.Length ?? 0);
                rp        = currentRps?.added[0] ?? null;
                idToCheck = rp?.trackableId ?? defaultId;
                break;

            case UpdateState.Updated:
                Assert.AreNotEqual(0, currentRps?.updated.Length ?? 0);
                rp        = currentRps?.updated[0] ?? null;
                idToCheck = rp?.trackableId ?? defaultId;
                break;

            case UpdateState.Removed:
                Assert.AreNotEqual(0, currentRps?.removed.Length ?? 0);
                idToCheck = currentRps?.removed[0] ?? defaultId;
                break;

            case UpdateState.None:
            default:
                return(false);
            }


            return(idToCheck == id);
        }
            /// <summary>
            /// Get changes to the passed XRReferencePoint
            /// </summary>
            /// <param name="defaultReferencePoint">The XRReferencePoint to get changes for.</param>
            /// <param name="allocator">Reference to the allocator for the XRReferencePoint.</param>
            /// <returns></returns>
            public override unsafe TrackableChanges <XRReferencePoint> GetChanges(
                XRReferencePoint defaultReferencePoint,
                Allocator allocator)
            {
                int   addedCount, updatedCount, removedCount, elementSize;
                void *addedPtr, updatedPtr, removedPtr;
                var   context = NativeApi.UnityWindowsMR_refPoints_acquireChanges(
                    out addedPtr, out addedCount,
                    out updatedPtr, out updatedCount,
                    out removedPtr, out removedCount,
                    out elementSize);

                try
                {
                    // Yes, this is an extra copy, but the hit is small compared with the code needed to get rid of it.
                    // If this becomes a problem we can eliminate the extra copy by doing something similar to
                    // NativeCopyUtility.PtrToNativeArrayWithDefault only with a pre-allocated array properties
                    // from using the TrackableChanges(int, int, int allocator) constructor.
                    var added   = NativeCopyUtility.PtrToNativeArrayWithDefault <XRReferencePoint>(defaultReferencePoint, addedPtr, elementSize, addedCount, allocator);
                    var updated = NativeCopyUtility.PtrToNativeArrayWithDefault <XRReferencePoint>(defaultReferencePoint, updatedPtr, elementSize, updatedCount, allocator);
                    var removed = NativeCopyUtility.PtrToNativeArrayWithDefault <TrackableId>(default(TrackableId), removedPtr, elementSize, removedCount, allocator);


                    var ret = TrackableChanges <XRReferencePoint> .CopyFrom(
                        added,
                        updated,
                        removed,
                        allocator);

                    added.Dispose();
                    updated.Dispose();
                    removed.Dispose();
                    return(ret);
                }
                finally
                {
                    NativeApi.UnityWindowsMR_refPoints_releaseChanges(context);
                }
            }
예제 #17
0
        IEnumerator RemoveAndCheckAnchor(TrackableId id, Action <TrackableId> callback)
        {
            XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>();

            Assert.NotNull(rpsub);

            rpsub.TryRemoveAnchor(id);

            yield return(null);

            TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp);

            Assert.IsNotNull(currentRps);
            Assert.AreNotEqual(0, currentRps?.removed.Length ?? 0);

            TrackableId?rpRemoved = currentRps?.removed[0] ?? null;

            if (callback != null)
            {
                callback.Invoke(rpRemoved ?? defaultId);
            }
        }
예제 #18
0
        public static TrackableChanges <XRPointCloud> ConsumeChanges(XRPointCloud defaultPointCloud, Allocator allocator)
        {
            lock (stateLock)
            {
                try
                {
                    if (allocator != Allocator.None)
                    {
                        T[] EfficientArray <T>(IEnumerable <DepthApi.DepthInfo> collection, Func <DepthApi.DepthInfo, T> converter)
                        => collection.Any(m => true) ? collection.Select(converter).ToArray() : Array.Empty <T>();

                        return(TrackableChanges <XRPointCloud> .CopyFrom(
                                   new NativeArray <XRPointCloud>(
                                       EfficientArray(DepthApi.added, m => m.ToPointCloud(defaultPointCloud)), allocator),
                                   new NativeArray <XRPointCloud>(
                                       EfficientArray(DepthApi.updated, m => m.ToPointCloud(defaultPointCloud)), allocator),
                                   new NativeArray <TrackableId>(
                                       EfficientArray(DepthApi.removed, m => m.trackableId), allocator),
                                   allocator));
                    }
                    else
                    {
                        return(default);
예제 #19
0
        public static TrackableChanges <BoundedPlane> ConsumeChanges(BoundedPlane defaultPlane, Allocator allocator)
        {
            lock (stateLock)
            {
                try
                {
                    if (allocator != Allocator.None)
                    {
                        T[] EfficientArray <T>(IEnumerable <PlaneApi.PlaneInfo> collection, Func <PlaneApi.PlaneInfo, T> converter)
                        => collection.Any(m => true) ? collection.Select(converter).ToArray() : Array.Empty <T>();

                        return(TrackableChanges <BoundedPlane> .CopyFrom(
                                   new NativeArray <BoundedPlane>(
                                       EfficientArray(PlaneApi.added.Values, m => m.ToBoundedPlane(defaultPlane)), allocator),
                                   new NativeArray <BoundedPlane>(
                                       EfficientArray(PlaneApi.updated.Values, m => m.ToBoundedPlane(defaultPlane)), allocator),
                                   new NativeArray <TrackableId>(
                                       EfficientArray(PlaneApi.removed.Values, m => m.id), allocator),
                                   allocator));
                    }
                    else
                    {
                        return(default);
예제 #20
0
        public static TrackableChanges <XRAnchor> ConsumeChanges(XRAnchor defaultAnchor, Allocator allocator)
        {
            lock (stateLock)
            {
                try
                {
                    if (allocator != Allocator.None)
                    {
                        T[] EfficientArray <T>(IEnumerable <AnchorApi.AnchorInfo> collection, Func <AnchorApi.AnchorInfo, T> converter)
                        => collection.Any(m => true) ? collection.Select(converter).ToArray() : Array.Empty <T>();

                        return(TrackableChanges <XRAnchor> .CopyFrom(
                                   new NativeArray <XRAnchor>(
                                       EfficientArray(AnchorApi.added.Values, m => m.ToXRAnchor(defaultAnchor)), allocator),
                                   new NativeArray <XRAnchor>(
                                       EfficientArray(AnchorApi.updated.Values, m => m.ToXRAnchor(defaultAnchor)), allocator),
                                   new NativeArray <TrackableId>(
                                       EfficientArray(AnchorApi.removed.Values, m => m.id), allocator),
                                   allocator));
                    }
                    else
                    {
                        return(default);
        private bool UpdateTrackables()
        {
            if (xrAnchorManager == null)
            {
                return(false);
            }
#if !UNITY_ANDROID && !UNITY_IOS
            if (sessionSubsystem != null)
            {
                sessionSubsystem.Update(new XRSessionUpdateParams
                {
                    screenOrientation = Screen.orientation,
                    screenDimensions  = new Vector2Int(Screen.width, Screen.height)
                });
            }
#endif // !UNITY_ANDROID && !UNITY_IOS
            DebugLogExtra($"UpdateTrackables {Time.frameCount} XRAnchorSubsystem is {xrAnchorManager.running}");
            TrackableChanges <XRAnchor> changes = xrAnchorManager.GetChanges(Unity.Collections.Allocator.Temp);
            if (changes.isCreated && (changes.added.Length + changes.updated.Length + changes.removed.Length > 0))
            {
                DebugLogExtra($"Changes Fr{Time.frameCount:0000}: isCreated={changes.isCreated} Added={changes.added.Length}, Updated={changes.updated.Length} Removed={changes.removed.Length}");
                for (int i = 0; i < changes.added.Length; ++i)
                {
                    UpdateTracker("Added::", changes.added[i], anchorsByTrackableId);
                }
                for (int i = 0; i < changes.updated.Length; ++i)
                {
                    UpdateTracker("Updated::", changes.updated[i], anchorsByTrackableId);
                }
                for (int i = 0; i < changes.removed.Length; i++)
                {
                    RemoveTracker(changes.removed[i], anchorsByTrackableId);
                }
            }
            changes.Dispose();
            return(true);
        }
        public unsafe void HandlesZero()
        {
            ForEachAllocator(allocator =>
            {
                using (var trackableChanges = new TrackableChanges <SubsystemTrackableData>(
                           null, 0,
                           null, 0,
                           null, 0,
                           SubsystemTrackableData.defaultValue,
                           UnsafeUtility.SizeOf <ProviderTrackableData>(), allocator))
                {
                    Assert.AreEqual(0, trackableChanges.added.Length);
                    Assert.AreEqual(0, trackableChanges.updated.Length);
                    Assert.AreEqual(0, trackableChanges.removed.Length);
                }

                using (var trackableChanges = new TrackableChanges <SubsystemTrackableData>(0, 0, 0, allocator))
                {
                    Assert.AreEqual(0, trackableChanges.added.Length);
                    Assert.AreEqual(0, trackableChanges.updated.Length);
                    Assert.AreEqual(0, trackableChanges.removed.Length);
                }
            });
        }
예제 #23
0
        IEnumerator AddAndCheckAnchor(Action <TrackableId> callback)
        {
            XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>();

            Assert.NotNull(rpsub);

            XRAnchor rp;
            bool     ret = rpsub.TryAddAnchor(defaultPose, out rp);

            Assert.IsTrue(ret);
            Assert.AreNotEqual(defaultId, rp.trackableId);

            yield return(null);

            TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp);

            Assert.IsNotNull(currentRps);
            Assert.AreNotEqual(0, currentRps?.added.Length ?? 0);

            if (callback != null)
            {
                callback.Invoke(currentRps?.added[0].trackableId ?? defaultId);
            }
        }
        public unsafe void TestTrackableChangesCopiesPointers()
        {
            const int addedCount   = 7;
            const int updatedCount = 11;
            const int removedCount = 13;
            var       addedPtr     = stackalloc ProviderTrackableData[addedCount];
            var       updatedPtr   = stackalloc ProviderTrackableData[updatedCount];
            var       removedPtr   = stackalloc TrackableId[removedCount];

            for (var i = 0; i < addedCount; i++)
            {
                addedPtr[i] = ProviderTrackableData.random;
            }

            for (var i = 0; i < updatedCount; i++)
            {
                updatedPtr[i] = ProviderTrackableData.random;
            }

            for (var i = 0; i < removedCount; i++)
            {
                removedPtr[i] = GenerateRandomId();
            }

            ForEachAllocator(allocator =>
            {
                using (var trackableChanges = new TrackableChanges <SubsystemTrackableData>(
                           addedPtr, addedCount,
                           updatedPtr, updatedCount,
                           removedPtr, removedCount,
                           SubsystemTrackableData.defaultValue,
                           UnsafeUtility.SizeOf <ProviderTrackableData>(), allocator))
                {
                    Assert.IsTrue(trackableChanges.isCreated);
                    Assert.AreEqual(addedCount, trackableChanges.added.Length);
                    Assert.AreEqual(updatedCount, trackableChanges.updated.Length);
                    Assert.AreEqual(removedCount, trackableChanges.removed.Length);

                    for (var i = 0; i < addedCount; i++)
                    {
                        var added = trackableChanges.added[i];
                        Assert.AreEqual(addedPtr[i], added.ToProviderTrackableData());
                        Assert.AreEqual(DataAddedInALaterVersion.defaultValue, added.dataAddedInALaterVersion);
                        Assert.AreEqual(0, UnsafeUtility.MemCmp(addedPtr + i, &added, sizeof(ProviderTrackableData)));
                    }

                    for (var i = 0; i < updatedCount; i++)
                    {
                        var updated = trackableChanges.updated[i];
                        Assert.AreEqual(updatedPtr[i], updated.ToProviderTrackableData());
                        Assert.AreEqual(DataAddedInALaterVersion.defaultValue, updated.dataAddedInALaterVersion);
                        Assert.AreEqual(0, UnsafeUtility.MemCmp(updatedPtr + i, &updated, sizeof(ProviderTrackableData)));
                    }

                    for (var i = 0; i < removedCount; i++)
                    {
                        var removed = trackableChanges.removed[i];
                        Assert.AreEqual(removedPtr[i], removed);
                        Assert.AreEqual(0, UnsafeUtility.MemCmp(removedPtr + i, &removed, sizeof(TrackableId)));
                    }
                }
            });
        }
        public void IsCreatedIsFalse()
        {
            TrackableChanges <SubsystemTrackableData> changes = default;

            Assert.IsFalse(changes.isCreated);
        }
        public void UncreatedCanBeDisposed()
        {
            TrackableChanges <SubsystemTrackableData> changes = default;

            changes.Dispose();
        }
            public override TrackableChanges <XRTrackedImage> GetChanges(XRTrackedImage defaultTrackedImage, Allocator allocator)
            {
                TrackableChanges <XRTrackedImage> changes;
                var numAddedMarkers = m_Added.Count;

                if (numAddedMarkers > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numAddedMarkers);
                    for (var i = 0; i < numAddedMarkers; i++)
                    {
                        var added = m_Added[i];

                        // if the same trackable ID is present more than once in a frame, the ARF validation utility
                        // will throw an error in the editor and dev builds.  Because subsystem tracking doesn't update every frame,
                        // it's possible to get the same marker in both.  Use the most recent version as an add if this happens.
                        if (m_Updated.TryGetValue(added.id, out var updatedValue))
                        {
                            m_Added[i] = updatedValue;
                            m_Updated.Remove(added.id);
                        }
                    }

                    // create this after in case any have been removed from the updated collection
                    changes = new TrackableChanges <XRTrackedImage>(m_Added.Count, m_Updated.Count, m_Removed.Count, allocator);

                    for (var i = 0; i < numAddedMarkers; i++)
                    {
                        m_ConversionBuffer[i] = TrackedImageFromMRMarker(m_Added[i]);
                    }

                    NativeArray <XRTrackedImage> .Copy(m_ConversionBuffer, changes.added, numAddedMarkers);

                    m_Added.Clear();
                }
                else
                {
                    changes = new TrackableChanges <XRTrackedImage>(m_Added.Count, m_Updated.Count, m_Removed.Count, allocator);
                }

                var numUpdatedMarkers = m_Updated.Count;

                if (numUpdatedMarkers > 0)
                {
                    Utils.EnsureCapacity(ref m_ConversionBuffer, numUpdatedMarkers);
                    var i = 0;
                    foreach (var updatedMarker in m_Updated.Values)
                    {
                        m_ConversionBuffer[i++] = TrackedImageFromMRMarker(updatedMarker);
                    }

                    NativeArray <XRTrackedImage> .Copy(m_ConversionBuffer, changes.updated, numUpdatedMarkers);

                    m_Updated.Clear();
                }

                var numRemovedMarkers = m_Removed.Count;

                if (numRemovedMarkers > 0)
                {
                    Utils.EnsureCapacity(ref m_IdConversionBuffer, numRemovedMarkers);
                    var i = 0;
                    foreach (var id in m_Removed)
                    {
                        m_IdConversionBuffer[i++] = new TrackableId(id.subId1, id.subId2);
                    }

                    NativeArray <TrackableId> .Copy(m_IdConversionBuffer, changes.removed, numRemovedMarkers);

                    m_Removed.Clear();
                }

                return(changes);
            }