2323// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2424//
2525
26+ using HoloToolkit . Unity ;
2627using Microsoft . SpatialAlignment . Persistence . Json ;
2728using Newtonsoft . Json ;
2829using System ;
@@ -44,8 +45,8 @@ private enum AddAnchorStep
4445 {
4546 New ,
4647 PlacingAnchor ,
47- // RefiningAnchor ,
48- RefiningModel ,
48+ ModelRay ,
49+ ModelNudge ,
4950 Finishing ,
5051 Done ,
5152 }
@@ -130,7 +131,7 @@ private void DoStep(AddAnchorStep step)
130131 // break;
131132
132133
133- case AddAnchorStep . RefiningModel :
134+ case AddAnchorStep . ModelRay :
134135
135136 // Add a WorldAnchor to the anchor so it stays in place
136137 newAnchor . gameObject . AddComponent < WorldAnchor > ( ) ;
@@ -148,17 +149,41 @@ private void DoStep(AddAnchorStep step)
148149 // Detach from any current parent (if there is one)
149150 largeScaleFrame . transform . parent = null ;
150151
151- // Put the model in refining mode
152+ // Create and subscribe to RayRefinement
153+ largeScaleRefinement = SubscribeRefinement < RayRefinement > ( ) ;
154+
155+ // Start the new refining mode
152156 largeScaleRefinement . StartRefinement ( ) ;
153157 break ;
154158
159+ case AddAnchorStep . ModelNudge :
160+
161+ // Unsubscribe from RayRefinement
162+ UnsubscribeRefinement < RayRefinement > ( ) ;
163+
164+ // Create and subscribe to NudgeRefinement
165+ largeScaleRefinement = SubscribeRefinement < NudgeRefinement > ( ) ;
166+
167+ // Start the new refining mode
168+ largeScaleRefinement . StartRefinement ( ) ;
169+ break ;
155170
156171 case AddAnchorStep . Finishing :
157172
158173 // Finish refinement if still in progress
159- if ( largeScaleRefinement . IsRefining )
174+ if ( largeScaleRefinement != null )
160175 {
161- largeScaleRefinement . FinishRefinement ( ) ;
176+ // Finish refinement of the large scale model if in progress
177+ if ( largeScaleRefinement . IsRefining )
178+ {
179+ largeScaleRefinement . FinishRefinement ( ) ;
180+ }
181+
182+ // Unsubscribe from refinement events
183+ UnsubscribeRefinement ( largeScaleRefinement ) ;
184+
185+ // No current large scale refinement
186+ largeScaleRefinement = null ;
162187 }
163188
164189 // Unsubscribe from anchor events
@@ -259,19 +284,6 @@ private void GatherDependencies()
259284 }
260285 else
261286 {
262- // Make sure large scale has a refinement controller
263- largeScaleRefinement = largeScaleModel . GetComponent < RefinementBase > ( ) ;
264-
265- // If none is found, use ray-based refinement
266- if ( largeScaleRefinement == null )
267- {
268- largeScaleRefinement = largeScaleModel . AddComponent < RayRefinement > ( ) ;
269- }
270-
271- // Subscribe to refinement events
272- largeScaleRefinement . RefinementCanceled += LargeScaleRefinement_RefinementCanceled ;
273- largeScaleRefinement . RefinementFinished += LargeScaleRefinement_RefinementFinished ;
274-
275287 // Attempt to get the frame
276288 largeScaleFrame = largeScaleModel . GetComponent < SpatialFrame > ( ) ;
277289 }
@@ -303,13 +315,45 @@ private void SubscribeAnchor(RefinableModel anchor)
303315 anchor . RefinementModeChanged += Anchor_RefinementModeChanged ;
304316 }
305317
318+ private TRefinement SubscribeRefinement < TRefinement > ( ) where TRefinement : RefinementBase
319+ {
320+ // If refinement doesn't exist, add it
321+ TRefinement refinement = largeScaleModel . EnsureComponent < TRefinement > ( ) ;
322+
323+ // Subscribe to refinement events
324+ refinement . RefinementCanceled += LargeScaleRefinement_RefinementCanceled ;
325+ refinement . RefinementFinished += LargeScaleRefinement_RefinementFinished ;
326+
327+ // Return the refinement
328+ return refinement ;
329+ }
330+
306331 private void UnsubscribeAnchor ( RefinableModel anchor )
307332 {
308333 // Unsubscribe from refinement events
309334 anchor . RefinementCanceled -= Anchor_CanceledRefinement ;
310335 anchor . RefinementFinished -= Anchor_FinishedRefinement ;
311336 anchor . RefinementModeChanged -= Anchor_RefinementModeChanged ;
312337 }
338+
339+ private void UnsubscribeRefinement ( RefinementBase refinement )
340+ {
341+ if ( refinement == null ) throw new ArgumentNullException ( nameof ( refinement ) ) ;
342+ refinement . RefinementCanceled -= LargeScaleRefinement_RefinementCanceled ;
343+ refinement . RefinementFinished -= LargeScaleRefinement_RefinementFinished ;
344+ }
345+
346+ private void UnsubscribeRefinement < TRefinement > ( ) where TRefinement : RefinementBase
347+ {
348+ // Attempt to get the refinement
349+ TRefinement refinement = largeScaleModel . GetComponent < TRefinement > ( ) ;
350+
351+ // If found, unsubscribe from refinement events
352+ if ( refinement != null )
353+ {
354+ UnsubscribeRefinement ( refinement ) ;
355+ }
356+ }
313357 #endregion // Internal Methods
314358
315359 #region Overrides / Event Handlers
@@ -404,10 +448,19 @@ public void CancelAddAnchor()
404448 // Now canceling
405449 mode = RefinementExampleMode . AddAnchorCancel ;
406450
407- // Cancel refinement of the large scale model if in progress
408- if ( largeScaleRefinement . IsRefining )
451+ if ( largeScaleRefinement != null )
409452 {
410- largeScaleRefinement . CancelRefinement ( ) ;
453+ // Cancel refinement of the large scale model if in progress
454+ if ( largeScaleRefinement . IsRefining )
455+ {
456+ largeScaleRefinement . CancelRefinement ( ) ;
457+ }
458+
459+ // Unsubscribe from refinement events
460+ UnsubscribeRefinement ( largeScaleRefinement ) ;
461+
462+ // No current large scale refinement
463+ largeScaleRefinement = null ;
411464 }
412465
413466 // Unsubscribe from anchor events
0 commit comments