private void UnsubscribeRefinement(RefinementBase refinement) { if (refinement == null) { throw new ArgumentNullException(nameof(refinement)); } refinement.RefinementCanceled -= LargeScaleRefinement_RefinementCanceled; refinement.RefinementFinished -= LargeScaleRefinement_RefinementFinished; }
/// <summary> /// Cancels the process of adding a refinement anchor. /// </summary> public void CancelAddAnchor() { // If in another mode, ignore if (mode != RefinementExampleMode.AddAnchor) { Debug.LogWarning($"{nameof(CancelAddAnchor)} called but in {mode}"); return; } // Now canceling mode = RefinementExampleMode.AddAnchorCancel; if (largeScaleRefinement != null) { // Cancel refinement of the large scale model if in progress if (largeScaleRefinement.IsRefining) { largeScaleRefinement.CancelRefinement(); } // Unsubscribe from refinement events UnsubscribeRefinement(largeScaleRefinement); // No current large scale refinement largeScaleRefinement = null; } // Unsubscribe from anchor events UnsubscribeAnchor(newAnchor); // Delete the new anchor game object and all children DestroyImmediate(newAnchor.gameObject); newAnchor = null; // Re-enable MultiParent alignment multiParent.enabled = true; // Show the model ShowModel(); // Done anchorStep = AddAnchorStep.Done; mode = RefinementExampleMode.None; }
/// <summary> /// Executes the specified step in a series of steps. /// </summary> /// <param name="step"> /// The <see cref="AddAnchorStep"/> step to execute. /// </param> private void DoStep(AddAnchorStep step) { // Log Debug.Log($"Doing {nameof(AddAnchorStep)}: {step}"); // Execute actions switch (step) { case AddAnchorStep.PlacingAnchor: // Hide the large-scale model HideModel(); // Instantiate the anchor prefab GameObject anchorGO = GameObject.Instantiate(anchorPrefab); // Set the parent so it's in the anchor container anchorGO.transform.SetParent(anchorContainer.transform, worldPositionStays: true); // Get the refining behavior newAnchor = anchorGO.GetComponentInChildren <RefinableModel>(); if (newAnchor == null) { throw new InvalidOperationException($"{nameof(AnchorPrefab)} does not have a {nameof(RefinableModel)} component."); } // Subscribe to anchor events SubscribeAnchor(newAnchor); // Put the anchor in placement mode newAnchor.RefinementMode = RefinableModelMode.Placing; break; //case AddAnchorStep.RefiningAnchor: // // Now refining anchor // newAnchor.RefinementMode = RefinableModelMode.Refining; // break; case AddAnchorStep.ModelRay: // Add a WorldAnchor to the anchor so it stays in place newAnchor.gameObject.AddComponent <WorldAnchor>(); // Done placing anchor newAnchor.RefinementMode = RefinableModelMode.Placed; // Show the model ShowModel(); // Disable MultiParent alignment on large-scale model so // that it can be positioned multiParent.enabled = false; // Detach from any current parent (if there is one) largeScaleFrame.transform.parent = null; // Create and subscribe to RayRefinement largeScaleRefinement = SubscribeRefinement <RayRefinement>(); // Start the new refining mode largeScaleRefinement.StartRefinement(); break; case AddAnchorStep.ModelNudge: // Unsubscribe from RayRefinement UnsubscribeRefinement <RayRefinement>(); // Create and subscribe to NudgeRefinement largeScaleRefinement = SubscribeRefinement <NudgeRefinement>(); // Start the new refining mode largeScaleRefinement.StartRefinement(); break; case AddAnchorStep.Finishing: // Finish refinement if still in progress if (largeScaleRefinement != null) { // Finish refinement of the large scale model if in progress if (largeScaleRefinement.IsRefining) { largeScaleRefinement.FinishRefinement(); } // Unsubscribe from refinement events UnsubscribeRefinement(largeScaleRefinement); // No current large scale refinement largeScaleRefinement = null; } // Unsubscribe from anchor events UnsubscribeAnchor(newAnchor); // Come up with an ID for this anchor string id = DateTime.Now.ToUniversalTime().Ticks.ToString(); // Create a new game object GameObject frameGO = new GameObject(id); // Set position and rotation same as the anchor frameGO.transform.position = newAnchor.transform.position; frameGO.transform.rotation = newAnchor.transform.rotation; // Parent it in the anchor container frameGO.transform.SetParent(anchorContainer.transform, worldPositionStays: true); // Add spatial frame to game object SpatialFrame newFrame = frameGO.AddComponent <SpatialFrame>(); // Give the frame an ID newFrame.Id = id; // Add a WorldAnchorAlignment to SpatialFrame WorldAnchorAlignment worldAlignment = frameGO.AddComponent <WorldAnchorAlignment>(); // Give the anchor an ID worldAlignment.AnchorId = id; // Temporarily parent the large model to the new frame largeScaleFrame.transform.SetParent(newFrame.transform, worldPositionStays: true); // Add this new frame to MultiParentAlignment as a new // parent option and using the current large-scale offset // from the anchor. multiParent.ParentOptions.Add(new ParentAlignmentOptions() { // Set frame Frame = newFrame, // Set offsets Position = largeScaleFrame.transform.localPosition, Rotation = largeScaleFrame.transform.localRotation.eulerAngles, Scale = largeScaleFrame.transform.localScale, }); // Unparent the large-scale model largeScaleFrame.transform.parent = null; // Delete the new anchor game object and all children DestroyImmediate(newAnchor.gameObject); newAnchor = null; // Show the model ShowModel(); // Re-enable MultiParent alignment multiParent.enabled = true; // Done anchorStep = AddAnchorStep.Done; mode = RefinementExampleMode.None; break; default: Debug.LogError($"Unknown step {step}"); break; } }