XRAnchorSubsystem.cs
9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
using System;
using Unity.Collections;
#if UNITY_2020_2_OR_NEWER
using UnityEngine.SubsystemsImplementation;
#endif
namespace UnityEngine.XR.ARSubsystems
{
/// <summary>
/// Base class for a anchor subsystem.
/// </summary>
/// <remarks>
/// <para>An anchor is a pose in the physical environment that is tracked by an XR device.
/// As the device refines its understanding of the environment, anchors will be
/// updated, allowing developers to keep virtual content connected to a real-world position and orientation.</para>
/// <para>This abstract class should be implemented by an XR provider and instantiated using the <c>SubsystemManager</c>
/// to enumerate the available <see cref="XRAnchorSubsystemDescriptor"/>s.</para>
/// </remarks>
#if UNITY_2020_2_OR_NEWER
public class XRAnchorSubsystem
: TrackingSubsystem<XRAnchor, XRAnchorSubsystem, XRAnchorSubsystemDescriptor, XRAnchorSubsystem.Provider>
#else
public abstract class XRAnchorSubsystem
: TrackingSubsystem<XRAnchor, XRAnchorSubsystemDescriptor>
#endif
{
/// <summary>
/// Constructor. Do not invoke directly; use the <c>SubsystemManager</c>
/// to enumerate the available <see cref="XRAnchorSubsystemDescriptor"/>s
/// and call <c>Create</c> on the desired descriptor.
/// </summary>
public XRAnchorSubsystem()
{
#if !UNITY_2020_2_OR_NEWER
provider = CreateProvider();
#endif
}
#if !UNITY_2020_2_OR_NEWER
/// <summary>
/// Starts the subsystem.
/// </summary>
protected sealed override void OnStart() => provider.Start();
/// <summary>
/// Stops the subsystem.
/// </summary>
protected sealed override void OnStop() => provider.Stop();
/// <summary>
/// Destroys the subsystem.
/// </summary>
protected sealed override void OnDestroyed() => provider.Destroy();
#endif
/// <summary>
/// Get the changes (added, updated, and removed) anchors since the last call
/// to <see cref="GetChanges(Allocator)"/>.
/// </summary>
/// <param name="allocator">An allocator to use for the <c>NativeArray</c>s in <see cref="TrackableChanges{T}"/>.</param>
/// <returns>Changes since the last call to <see cref="GetChanges"/>.</returns>
public override TrackableChanges<XRAnchor> GetChanges(Allocator allocator)
{
if (!running)
throw new InvalidOperationException("Can't call \"GetChanges\" without \"Start\"ing the anchor subsystem!");
var changes = provider.GetChanges(XRAnchor.defaultValue, allocator);
#if DEVELOPMENT_BUILD || UNITY_EDITOR
m_ValidationUtility.ValidateAndDisposeIfThrown(changes);
#endif
return changes;
}
/// <summary>
/// Attempts to create a new anchor with the provide <paramref name="pose"/>.
/// </summary>
/// <param name="pose">The pose, in session space, of the new anchor.</param>
/// <param name="anchor">The new anchor. Only valid if this method returns <c>true</c>.</param>
/// <returns><c>true</c> if the new anchor was added, otherwise <c>false</c>.</returns>
public bool TryAddAnchor(Pose pose, out XRAnchor anchor)
{
return provider.TryAddAnchor(pose, out anchor);
}
/// <summary>
/// Attempts to create a new anchor "attached" to the trackable with id <paramref name="trackableToAffix"/>.
/// The behavior of the anchor depends on the type of trackable to which this anchor is attached.
/// </summary>
/// <param name="trackableToAffix">The id of the trackable to which to attach.</param>
/// <param name="pose">The pose, in session space, of the anchor to create.</param>
/// <param name="anchor">The new anchor. Only valid if this method returns <c>true</c>.</param>
/// <returns><c>true</c> if the new anchor was added, otherwise <c>false</c>.</returns>
public bool TryAttachAnchor(TrackableId trackableToAffix, Pose pose, out XRAnchor anchor)
{
return provider.TryAttachAnchor(trackableToAffix, pose, out anchor);
}
/// <summary>
/// Attempts to remove an existing anchor with <see cref="TrackableId"/> <paramref name="anchorId"/>.
/// </summary>
/// <param name="anchorId">The id of an existing anchor to remove.</param>
/// <returns><c>true</c> if the anchor was removed, otherwise <c>false</c>.</returns>
public bool TryRemoveAnchor(TrackableId anchorId)
{
return provider.TryRemoveAnchor(anchorId);
}
/// <summary>
/// An abstract class to be implemented by providers of this subsystem.
/// </summary>
public abstract class Provider
#if UNITY_2020_2_OR_NEWER
: SubsystemProvider<XRAnchorSubsystem>
#endif
{
#if !UNITY_2020_2_OR_NEWER
/// <summary>
/// Invoked when <c>Start</c> is called on the subsystem. This method is only called if the subsystem was not previously running.
/// </summary>
public virtual void Start() { }
/// <summary>
/// Invoked when <c>Stop</c> is called on the subsystem. This method is only called if the subsystem was previously running.
/// </summary>
public virtual void Stop() { }
/// <summary>
/// Called when <c>Destroy</c> is called on the subsystem.
/// </summary>
public virtual void Destroy() { }
#endif
/// <summary>
/// Invoked to get the changes to anchors (added, updated, and removed) since the last call to
/// <see cref="GetChanges(XRAnchor,Allocator)"/>.
/// </summary>
/// <param name="defaultAnchor">The default anchor. This should be used to initialize the returned
/// <c>NativeArray</c>s for backwards compatibility.
/// See <see cref="TrackableChanges{T}.TrackableChanges(void*, int, void*, int, void*, int, T, int, Unity.Collections.Allocator)"/>.
/// </param>
/// <param name="allocator">An allocator to use for the <c>NativeArray</c>s in <see cref="TrackableChanges{T}"/>.</param>
/// <returns>Changes since the last call to <see cref="GetChanges"/>.</returns>
public abstract TrackableChanges<XRAnchor> GetChanges(XRAnchor defaultAnchor, Allocator allocator);
/// <summary>
/// Should create a new anchor with the provide <paramref name="pose"/>.
/// </summary>
/// <param name="pose">The pose, in session space, of the new anchor.</param>
/// <param name="anchor">The new anchor. Must be valid only if this method returns <c>true</c>.</param>
/// <returns>Should return <c>true</c> if the new anchor was added, otherwise <c>false</c>.</returns>
public virtual bool TryAddAnchor(Pose pose, out XRAnchor anchor)
{
anchor = default(XRAnchor);
return false;
}
/// <summary>
/// Should create a new anchor "attached" to the trackable with id <paramref name="trackableToAffix"/>.
/// The behavior of the anchor depends on the type of trackable to which this anchor is attached and
/// may be implementation-defined.
/// </summary>
/// <param name="trackableToAffix">The id of the trackable to which to attach.</param>
/// <param name="pose">The pose, in session space, of the anchor to create.</param>
/// <param name="anchor">The new anchor. Must be valid only if this method returns <c>true</c>.</param>
/// <returns><c>true</c> if the new anchor was added, otherwise <c>false</c>.</returns>
public virtual bool TryAttachAnchor(
TrackableId trackableToAffix,
Pose pose,
out XRAnchor anchor)
{
anchor = default(XRAnchor);
return false;
}
/// <summary>
/// Should remove an existing anchor with <see cref="TrackableId"/> <paramref name="anchorId"/>.
/// </summary>
/// <param name="anchorId">The id of an existing anchor to remove.</param>
/// <returns>Should return <c>true</c> if the anchor was removed, otherwise <c>false</c>. If the anchor
/// does not exist, return <c>false</c>.</returns>
public virtual bool TryRemoveAnchor(TrackableId anchorId) => false;
}
#if !UNITY_2020_2_OR_NEWER
/// <summary>
/// Should return an instance of <see cref="Provider"/>.
/// </summary>
/// <returns>The interface to the implementation-specific provider.</returns>
protected abstract Provider CreateProvider();
/// <summary>
/// The provider created by the implementation that contains the required anchor functionality.
/// </summary>
protected Provider provider { get; }
#endif
#if DEVELOPMENT_BUILD || UNITY_EDITOR
ValidationUtility<XRAnchor> m_ValidationUtility =
new ValidationUtility<XRAnchor>();
#endif
}
}