コード例 #1
0
 // Update is called once per frame
 void Update()
 {
     if (statusText != null)
     {
         var    wltMgr   = WorldLockingManager.GetInstance();
         var    settings = wltMgr.Settings;
         string status   = settings.Enabled ? "on" : "off";
         statusText.text  = $"WLT {status}";
         statusText.color = settings.Enabled ? Color.green : Color.red;
     }
 }
 /// <summary>
 /// Callback for when the user has finished positioning the target.
 /// </summary>
 protected virtual void OnFinishManipulation()
 {
     if (WorldLockingManager.GetInstance().ApplyAdjustment)
     {
         SetFrozenPose(ExtractModelPose());
     }
     else
     {
         SetSpongyPose(ExtractModelPose());
     }
 }
コード例 #3
0
        private Vector3 GetGlobalHeadPosition()
        {
            WorldLockingManager wltMgr   = WorldLockingManager.GetInstance();
            Vector3             position = wltMgr.SpongyFromCamera.position;

            if (wltMgr.ApplyAdjustment)
            {
                position = wltMgr.FrozenFromSpongy.Multiply(position);
            }
            return(position);
        }
コード例 #4
0
        private void FindAndCheckPin(GameObject rig, string pinName)
        {
            SpacePin spacePin = FindPinByName(rig, pinName);

            Pose    virtualPose = spacePin.ModelingPoseGlobal;
            Pose    lockedPose  = spacePin.LockedPose;
            Pose    frozenPose  = WorldLockingManager.GetInstance().FrozenFromLocked.Multiply(lockedPose);
            Vector3 offset      = frozenPose.position - virtualPose.position;
            float   len         = Mathf.Abs(offset.magnitude - 1.0f);

            Assert.Less(len, 1.0e-4f);
        }
コード例 #5
0
        public void OnToggleManager()
        {
            var wltMgr   = WorldLockingManager.GetInstance();
            var settings = wltMgr.Settings;

            settings.Enabled = !settings.Enabled;
            wltMgr.Settings  = settings;
            for (int i = 0; i < targets.Count; ++i)
            {
                targets[i].SetActive(!targets[i].activeSelf);
            }
        }
 private void DestroyWorldAnchorHelper()
 {
     if (worldAnchor != null)
     {
         Destroy(worldAnchor.gameObject);
         worldAnchor = null;
     }
     if (AttachmentPoint != null)
     {
         WorldLockingManager.GetInstance().AttachmentPointManager.ReleaseAttachmentPoint(AttachmentPoint);
         AttachmentPoint = null;
     }
 }
コード例 #7
0
        private void FindAlignmentManager()
        {
            AlignSubtree subTree = targetSubtree;

            if (subTree != null)
            {
                FindAlignmentManagerFromSubtree(subTree);
            }
            else
            {
                SetAlignmentManager(WorldLockingManager.GetInstance().AlignmentManager);
            }
        }
        private void CheckAlignment(IAlignmentManager alignMgr, Vector3 virtualPos, Vector3 lockedPos)
        {
            WorldLockingManager mgr = WorldLockingManager.GetInstance();

            alignMgr.ComputePinnedPose(new Pose(lockedPos, Quaternion.identity));
            Pose    pinnedFromLocked = alignMgr.PinnedFromLocked;
            Pose    frozenFromLocked = mgr.FrozenFromPinned.Multiply(pinnedFromLocked);
            Pose    lockedFromFrozen = frozenFromLocked.Inverse();
            Vector3 computedLocked   = lockedFromFrozen.Multiply(virtualPos);
            bool    areEqual         = computedLocked == lockedPos;

            Assert.IsTrue(areEqual, $"c={computedLocked.ToString("F3")} l={lockedPos.ToString("F3")}");
        }
        public IEnumerator WorldLockingManagerTestContextSwitch()
        {
            GameObject rig = loadHelper.LoadBasicSceneRig();

            Assert.IsTrue(WorldLockingManager.GetInstance().AutoLoad);
            var context = loadHelper.LoadComponentOnGameObject <WorldLockingContext>("Prefabs/CoreTestContext_AllDisabled.prefab");

            Assert.IsFalse(WorldLockingManager.GetInstance().AutoLoad);
            GameObject.Destroy(context.gameObject);
            GameObject.Destroy(rig);

            yield return(null);
        }
コード例 #10
0
    private void Update()
    {
        _WorldPosition = TransformToLookAt.position;
        _LocalPosition = TransformToLookAt.localPosition;

        _WorldLockedPosition = WorldLockingManager.GetInstance().LockedFromFrozen.Multiply(TransformToLookAt.GetGlobalPose()).position;
        _LocalLockedPosition = WorldLockingManager.GetInstance().LockedFromFrozen.Multiply(TransformToLookAt.GetLocalPose()).position;

        //_WorldFrozenPosition = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(_WorldPosition);
        //_LocalFrozenPosition = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(_LocalPosition);

        SetTexts();
    }
コード例 #11
0
        /// <summary>
        /// Disable the effects of all pins, as if they had never been set.
        /// </summary>
        public void ClearAll()
        {
            for (int i = 0; i < spacePins.Count; ++i)
            {
                spacePins[i].Reset();
            }
            // Could optionally also reset all existing WorldAnchors for a true reset.
            // If wanted, uncomment this line.
            WorldLockingManager.GetInstance().Reset();

            // Also go back to idle mode.
            activePin = -1;
        }
コード例 #12
0
        /// <summary>
        /// Attempt to set a space pin from the QR code.
        /// </summary>
        /// <param name="qrCode">The source QR code.</param>
        /// <returns>True if a space pin was set from the current data.</returns>
        /// <remarks>
        /// Returning false does not necessarily mean an error occurred. For example, if the space pin
        /// has already been set from the given QR code, and the location hasn't changed, no action
        /// will be taken and the return value will be false. Or if the coordinate system is unable
        /// to resolve the transform to global space, again the return will be false, indicating
        /// trying again later.
        /// </remarks>
        public bool Update(QRCode qrCode)
        {
            coordinateSystem.SpatialNodeId = qrCode.SpatialGraphNodeId;
            sizeMeters = qrCode.PhysicalSideLength;
            Pose spongyPose;

            if (!coordinateSystem.ComputePose(out spongyPose))
            {
                return(false);
            }
            Pose frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose);

            return(UpdatePose(frozenPose));
        }
コード例 #13
0
            /// <summary>
            /// Attempt to set a space pin from the QR code.
            /// </summary>
            /// <param name="qrCode">The source QR code.</param>
            /// <returns>True if a space pin was set from the current data.</returns>
            /// <remarks>
            /// Returning false does not necessarily mean an error occurred. For example, if the space pin
            /// has already been set from the given QR code, and the location hasn't changed, no action
            /// will be taken and the return value will be false. Or if the coordinate system is unable
            /// to resolve the transform to global space, again the return will be false, indicating
            /// trying again later.
            /// </remarks>
            public bool Update(QRCode qrCode)
            {
                SimpleConsole.AddLine(trace, $"Update SpacePin {(coordinateSystem == null ? "null" : coordinateSystem.SpatialNodeId.ToString())}");
                coordinateSystem.SpatialNodeId = qrCode.SpatialGraphNodeId;
                sizeMeters = qrCode.PhysicalSideLength;
                Pose spongyPose;

                if (!coordinateSystem.ComputePose(out spongyPose))
                {
                    return(false);
                }
                Pose frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose);

                return(UpdatePose(frozenPose));
            }
コード例 #14
0
        private void FindAndCheckPin(GameObject rig, string pinName)
        {
            SpacePin spacePin = FindPinByName(rig, pinName);

            Pose virtualPose = spacePin.ModelingPoseGlobal;
            Pose lockedPose  = spacePin.LockedPose;

            Debug.Log($"FFL:{WorldLockingManager.GetInstance().FrozenFromLocked.position.ToString("F3")}"
                      + $"/ {WorldLockingManager.GetInstance().FrozenFromLocked.rotation.ToString("F3")}");
            Pose    frozenPose = WorldLockingManager.GetInstance().FrozenFromLocked.Multiply(lockedPose);
            Vector3 offset     = frozenPose.position - virtualPose.position;
            float   len        = Mathf.Abs(offset.magnitude - 1.0f);

            Assert.Less(len, 1.0e-4f, $"pin={spacePin.name} fr={frozenPose.position.ToString("F3")} vi={virtualPose.position.ToString("F3")}");
        }
        public IEnumerator WorldLockingManagerTestSettingsFromScript()
        {
            GameObject rig = loadHelper.LoadBasicSceneRig();

            var  settings    = WorldLockingManager.GetInstance().Settings;
            bool wasAutoLoad = settings.AutoLoad;

            settings.AutoLoad = !settings.AutoLoad;
            WorldLockingManager.GetInstance().Settings = settings;
            Assert.AreNotEqual(wasAutoLoad, WorldLockingManager.GetInstance().AutoLoad);

            GameObject.Destroy(rig);

            yield return(null);
        }
 // Update is called once per frame
 void Update()
 {
     if (AlwaysLock || !WorldLockingManager.GetInstance().Enabled)
     {
         Pose spongyPose = worldAnchor.transform.GetGlobalPose();
         frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose);
         transform.SetGlobalPose(frozenPose);
     }
     else
     {
         CheckFrozenPose();
         // Set pose to frozen space pose
         transform.SetGlobalPose(frozenPose);
     }
 }
コード例 #17
0
        private void CheckAlignment(IAlignmentManager alignMgr, Pose virtualPose, Pose lockedPose)
        {
            WorldLockingManager mgr = WorldLockingManager.GetInstance();

            alignMgr.ComputePinnedPose(new Pose(lockedPose.position, Quaternion.identity));
            Pose pinnedFromLocked  = alignMgr.PinnedFromLocked;
            Pose frozenFromLocked  = mgr.FrozenFromPinned.Multiply(pinnedFromLocked);
            Pose lockedFromFrozen  = frozenFromLocked.Inverse();
            Pose computedLocked    = lockedFromFrozen.Multiply(virtualPose);
            bool areEqualPositions = computedLocked.position == lockedPose.position;

            Assert.IsTrue(areEqualPositions);
            bool areEqualRotatons = computedLocked.rotation == lockedPose.rotation;

            Assert.IsTrue(areEqualRotatons);
        }
コード例 #18
0
        /// <summary>
        /// Disable the effects of all pins, as if they had never been set.
        /// </summary>
        public void ClearAll()
        {
            for (int i = 0; i < spacePins.Count; ++i)
            {
                spacePins[i].Reset();
            }
            // Reset on the pins has removed them from the AlignmentManager, but it won't
            // take effect until SendAlignmentAnchors() is called.
            WorldLockingManager.GetInstance().AlignmentManager.SendAlignmentAnchors();
            // Could optionally also reset all existing WorldAnchors for a true reset.
            // If wanted, uncomment this line.
            WorldLockingManager.GetInstance().Reset();

            // Also go back to idle mode.
            activePin = -1;
        }
        public IEnumerator TestPluginAddDeleteAnchors()
        {
            IPlugin plugin = WorldLockingManager.GetInstance().Plugin;

            plugin.ClearFrozenAnchors();

            List <AnchorPose> anchorPoses = new List <AnchorPose>();
            List <AnchorEdge> anchorEdges = new List <AnchorEdge>();

            /// Add some anchors
            SetupAnchorsForAddDeleteTest(0, 5, anchorPoses, anchorEdges);

            List <AnchorId> frozenIds = new List <AnchorId>();

            CopyFrozenIds(anchorPoses, 0, anchorPoses.Count, frozenIds);

            /// Run an update cycle. Check those anchors are still there.
            UpdateAndCheck(plugin, 0, anchorPoses, anchorEdges, frozenIds);

            SetupAnchorsForAddDeleteTest(10, 5, anchorPoses, anchorEdges);
            UpdateAndCheck(plugin, 0, anchorPoses, anchorEdges, frozenIds);
            CopyFrozenIds(anchorPoses, 0, anchorPoses.Count, frozenIds);
            UpdateAndCheck(plugin, 5, anchorPoses, anchorEdges, frozenIds);

            /// Remove an anchor from spongy list
            int      idxToRemove      = 3;
            AnchorId anchorIdToRemove = anchorPoses[idxToRemove].anchorId;

            RemoveEdge(anchorIdToRemove, anchorEdges);
            anchorPoses.RemoveAt(idxToRemove);

            /// Update and check.
            UpdateAndCheck(plugin, 0, anchorPoses, anchorEdges, frozenIds);
            UpdateAndCheck(plugin, 5, anchorPoses, anchorEdges, frozenIds);

            /// Remove another anchor from spongy list AND frozen.
            plugin.RemoveFrozenAnchor(anchorIdToRemove);
            CopyFrozenIds(anchorPoses, 0, anchorPoses.Count, frozenIds);

            /// Update and check.
            UpdateAndCheck(plugin, 5, anchorPoses, anchorEdges, frozenIds);
            UpdateAndCheck(plugin, 0, anchorPoses, anchorEdges, frozenIds);

            yield return(null);
        }
コード例 #20
0
        private void Update()
        {
            var worldLockingManager = WorldLockingManager.GetInstance();

            ButtonRefreeze.IsEnabled = worldLockingManager.RefreezeIndicated;
            ButtonMerge.IsEnabled    = worldLockingManager.MergeIndicated;
            ButtonSave.IsEnabled     = !dashboardCommand.AutoSave;
            ButtonLoad.IsEnabled     = !dashboardCommand.AutoSave;

            CheckBoxShowAnchors.CurrentDimension    = dashboardCommand.AnchorVisualization ? 1 : 0;
            CheckBoxShowInfo.CurrentDimension       = dashboardCommand.InfoEnabled ? 1 : 0;
            CheckBoxShowMetrics.CurrentDimension    = dashboardCommand.MetricsEnabled ? 1 : 0;
            CheckBoxShowSpatMap.CurrentDimension    = dashboardCommand.SpatialMapDisplayEnabled ? 1 : 0;
            CheckBoxManagerEnabled.CurrentDimension = dashboardCommand.ManagerEnabled ? 1 : 0;
            CheckBoxAutoMerge.CurrentDimension      = dashboardCommand.AutoMerge ? 1 : 0;
            CheckBoxAutoSave.CurrentDimension       = dashboardCommand.AutoSave ? 1 : 0;
            CheckBoxAutoRefreeze.CurrentDimension   = dashboardCommand.AutoRefreeze ? 1 : 0;
        }
        private void CheckAlignment(List <AnchorPose> anchorPoses, List <AnchorEdge> anchorEdges, Pose movement)
        {
            Pose    spongyHead;
            IPlugin plugin = WorldLockingManager.GetInstance().Plugin;

            for (int k = 0; k < anchorPoses.Count; ++k)
            {
                spongyHead = anchorPoses[k].pose;
                plugin.ClearSpongyAnchors();
                plugin.Step_Init(spongyHead);
                plugin.AddSpongyAnchors(anchorPoses);
                plugin.SetMostSignificantSpongyAnchorId(anchorPoses[k].anchorId);
                plugin.AddSpongyEdges(anchorEdges);
                plugin.Step_Finish();

                var adjustment = plugin.GetAlignment();
                Assert.IsTrue(adjustment == movement, $"k={k} adjustment={adjustment}, movement={movement}");
            }
        }
コード例 #22
0
        private void Start()
        {
            //Ignore the collisions between layer 0 (default) and layer 5 (UI)
            Physics.IgnoreLayerCollision(0, 5, true);

            if (dashboardCommand == null)
            {
                throw new System.Exception("DashboardUI missing required DashboardCommand");
            }
            if (WorldLockingManager.GetInstance() == null)
            {
                throw new System.Exception("DashboardUI missing required WorldLockingManager");
            }

            if (!dashboardCommand.HasSpatialMap)
            {
                CheckBoxShowSpatMap.gameObject.SetActive(false);
            }
        }
        public IEnumerator WorldLockingManagerTestLinkagePassThrough()
        {
            // Use the Assert class to test conditions.
            // Use yield to skip a frame.
            GameObject rig = loadHelper.LoadBasicSceneRig();

            yield return(null);

            Transform cameraParentTest = new GameObject("CameraParentTest").transform;
            Transform adjustmentTest   = new GameObject("AdjustmentTest").transform;
            Transform cameraParent     = Camera.main.transform.parent;

            UnityEngine.Assertions.Assert.IsNotNull(cameraParent);
            GameObject adjustment = GameObject.Find("Adjustment");

            UnityEngine.Assertions.Assert.IsNotNull(adjustment);

            WorldLockingManager.GetInstance().CameraParent    = cameraParentTest;
            WorldLockingManager.GetInstance().AdjustmentFrame = adjustmentTest;

            Assert.AreEqual(cameraParentTest, WorldLockingManager.GetInstance().CameraParent);
            Assert.AreEqual(adjustmentTest, WorldLockingManager.GetInstance().AdjustmentFrame);

            Assert.IsTrue(WorldLockingManager.GetInstance().AutoMerge);
            var noMergeNoLinkage = loadHelper.LoadComponentOnGameObject <WorldLockingContext>("Prefabs/CoreTestContext_NoMergeNoLinkage.prefab");

            yield return(null);

            Assert.IsFalse(WorldLockingManager.GetInstance().AutoMerge);
            Assert.AreEqual(cameraParentTest, WorldLockingManager.GetInstance().CameraParent);
            Assert.AreEqual(adjustmentTest, WorldLockingManager.GetInstance().AdjustmentFrame);

            Assert.IsTrue(WorldLockingManager.GetInstance().AutoLoad);
            var allDisabled = loadHelper.LoadComponentOnGameObject <WorldLockingContext>("Prefabs/CoreTestContext_AllDisabled.prefab");

            yield return(null);

            Assert.IsFalse(WorldLockingManager.GetInstance().AutoLoad);
            Assert.AreEqual(cameraParent, WorldLockingManager.GetInstance().CameraParent);
            Assert.AreEqual(adjustment.transform, WorldLockingManager.GetInstance().AdjustmentFrame);

            yield return(null);
        }
コード例 #24
0
        public IEnumerator SaveLoadTestSpacePinOrientable()
        {
            GameObject rig = loadHelper.LoadBasicSceneRig();

            GameObject[]         gos  = new GameObject[pinData.Length];
            SpacePinOrientable[] spos = new SpacePinOrientable[pinData.Length];

            Quaternion rotThirty = Quaternion.AngleAxis(30.0f, new Vector3(0.0f, 1.0f, 0.0f));

            GameObject orienterGO = new GameObject("Orienter");
            IOrienter  orienter   = orienterGO.AddComponent <Orienter>();

            for (int i = 0; i < pinData.Length; ++i)
            {
                gos[i]           = new GameObject("GOs_" + i.ToString());
                spos[i]          = gos[i].AddComponent <SpacePinOrientable>();
                spos[i].Orienter = orienter;
            }
            /// Wait for their Start's to be called.
            yield return(null);

            for (int i = 0; i < spos.Length; ++i)
            {
                spos[i].transform.SetGlobalPose(pinData[i].virtualPose);
                spos[i].ResetModelingPose();
                Vector3 rotPosition = rotThirty * pinData[i].virtualPose.position;
                spos[i].SetFrozenPosition(rotPosition);
            }
            yield return(null);

            IAlignmentManager alignMgr = WorldLockingManager.GetInstance().AlignmentManager;

            /// This is an arbitrary position, not actually one of the pinned positions currently.
            alignMgr.ComputePinnedPose(new Pose(pinData[0].lockedPose.position, Quaternion.identity));
            Quaternion rot      = Quaternion.Inverse(alignMgr.PinnedFromLocked.rotation);
            bool       isThirty = rot == rotThirty;

            Assert.IsTrue(isThirty);

            GameObject.Destroy(rig);

            yield return(null);
        }
        private void Update()
        {
            var worldLockingManager = WorldLockingManager.GetInstance();

            if (worldLockingManager != null)
            {
                if (VersionTimestampEnabled)
                {
                    SetTextIfChanged(textMeshVersionTimestamp, CaptureVersionTimestamp(worldLockingManager));
                }
                if (ErrorStatusEnabled)
                {
                    SetTextIfChanged(textMeshErrorStatus, worldLockingManager.ErrorStatus);
                }

                bool indicatorActive = false;
                if (textMeshStateIndicator.text != null)
                {
                    if (worldLockingManager.RefreezeIndicated)
                    {
                        SetTextIfChanged(textMeshStateIndicator, "Refreeze indicated");
                        indicatorActive = true;
                    }
                    else if (worldLockingManager.MergeIndicated)
                    {
                        SetTextIfChanged(textMeshStateIndicator, "Merge indicated");
                        indicatorActive = true;
                    }
                }
                StateIndicatorEnabled = indicatorActive;

                if (InfoEnabled)
                {
                    SetTextIfChanged(textMeshInfo, CaptureInfoText(worldLockingManager));
                }

                if (MetricsEnabled)
                {
                    SetTextIfChanged(textMeshMetrics, CaptureMetrics(worldLockingManager));
                }
            }
        }
コード例 #26
0
        private void CalculatePinPositionsFromCurrentInterpolant()
        {
            if (currentInterpolant == null)
            {
                return;
            }

            bool hasBoundaryVertex = false;

            for (int i = 0; i < currentInterpolant.idx.Length; i++)
            {
                if (currentInterpolant.weights[i] <= 0.001f && currentInterpolant.idx[i] == 0)
                {
                    hasBoundaryVertex        = true;
                    currentBoundaryVertexIDx = i;
                }
            }

            currentBoundaryVertexIDx = hasBoundaryVertex ? currentBoundaryVertexIDx : -1;

            Vector3 lockedHeadPosition = GetLockedHeadPosition();

            lockedHeadPosition.y = 0.0f;

            firstPinPosition  = currentBoundaryVertexIDx == 0 ? lockedHeadPosition : triangulator.Vertices[currentInterpolant.idx[0] + 4];
            secondPinPosition = currentBoundaryVertexIDx == 1 ? lockedHeadPosition : triangulator.Vertices[currentInterpolant.idx[1] + 4];
            thirdPinPosition  = currentBoundaryVertexIDx == 2 ? lockedHeadPosition : triangulator.Vertices[currentInterpolant.idx[2] + 4];

            Pose frozenFromLocked = WorldLockingManager.GetInstance().FrozenFromLocked;

            firstPinPosition  = frozenFromLocked.Multiply(firstPinPosition);
            secondPinPosition = frozenFromLocked.Multiply(secondPinPosition);
            thirdPinPosition  = frozenFromLocked.Multiply(thirdPinPosition);

            //    DEBUG TRIANGLE    //
            //firstPinPosition = new Vector3(5.0f, 0.0f, 0.0f);
            //secondPinPosition = new Vector3(1.0f, 0.0f, 1.0f);
            //thirdPinPosition = new Vector3(-1.0f,0.0f,-1.0f);

            firstPinPosition.y = secondPinPosition.y = thirdPinPosition.y = 0.0f;
        }
コード例 #27
0
    private MarkerData GetMarkerDataByQrCode(QRCode qrCode)
    {
        _tmpCoordinateSystem.SpatialNodeId = qrCode.SpatialGraphNodeId;

        if (_tmpCoordinateSystem.ComputePose(out Pose spongyPose))
        {
            Pose frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose);
            MyPositionMarkerHelper.SetGlobalPose(frozenPose);

            Pose localPose = MyPositionMarkerHelper.GetLocalPose();

            return(new MarkerData(
                       true,
                       qrCode.Data,
                       localPose.position,
                       localPose.rotation,
                       qrCode.PhysicalSideLength
                       ));
        }
        return(null);
    }
コード例 #28
0
        /// <summary>
        /// Given a new frozen pose, send it to SpacePin system if appropriate.
        /// </summary>
        /// <param name="frozenPose">New frozen space pose.</param>
        /// <returns>True if the pose was pushed to the SpacePin system.</returns>
        private bool UpdatePose(Pose frozenPose)
        {
            bool didCommit  = false;
            var  wltMgr     = WorldLockingManager.GetInstance();
            Pose lockedPose = wltMgr.LockedFromFrozen.Multiply(frozenPose);

            if (NeedCommit(lockedPose))
            {
                didCommit = CommitPose(frozenPose, lockedPose);
            }
            else if (highlightProxy != null)
            {
                if (!highlightProxy.activeSelf)
                {
                    // Proxy has deactivated itself at end of animation, go ahead and destroy it.
                    Destroy(highlightProxy);
                    highlightProxy = null;
                }
            }
            return(didCommit);
        }
        public IEnumerator AlignmentManagerTestBasic()
        {
            var rig = loadHelper.LoadBasicSceneRig();

            /// This context ensures FW is enabled, but also gives a MonoBehavior to run coroutines off of.
            WorldLockingContext context = loadHelper.LoadComponentOnGameObject <WorldLockingContext>("Prefabs/CoreTestContext_AllEnabled.prefab");
            var alignMgr = WorldLockingManager.GetInstance().AlignmentManager;

            yield return(context.StartCoroutine(CheckSinglePin(alignMgr, 0)));

            yield return(context.StartCoroutine(CheckSinglePin(alignMgr, 1)));

            yield return(context.StartCoroutine(CheckDualPins(alignMgr, 0, 1)));

            yield return(context.StartCoroutine(CheckDualPins(alignMgr, 1, 2)));

            yield return(context.StartCoroutine(CheckDualPins(alignMgr, 0, 2)));

            alignMgr.ClearAlignmentAnchors();
            for (int i = 0; i < 2; ++i)
            {
                alignMgr.AddAlignmentAnchor(pinData[i].name, pinData[i].virtualPose, pinData[i].lockedPose);
            }
            alignMgr.SendAlignmentAnchors();

            yield return(null);

            CheckAlignment(alignMgr, pinData[0].virtualPose.position, pinData[0].lockedPose.position);

            CheckAlignment(alignMgr, pinData[1].virtualPose.position, pinData[1].lockedPose.position);

            CheckAlignment(alignMgr,
                           (pinData[0].virtualPose.position + pinData[1].virtualPose.position) * 0.5f,
                           (pinData[0].lockedPose.position + pinData[1].lockedPose.position) * 0.5f);

            GameObject.Destroy(context.gameObject);
            GameObject.Destroy(rig);

            yield return(null);
        }
        private void CreateWorldAnchorHelper()
        {
            GameObject goHelper = new GameObject(name + "WorldAnchorHelper");

            goHelper.transform.SetParent(transform);
            goHelper.hideFlags = HideFlags.HideAndDontSave;
            frozenPose         = transform.GetGlobalPose();
            Pose spongyPose = WorldLockingManager.GetInstance().SpongyFromFrozen.Multiply(frozenPose);

            if (!WorldLockingManager.GetInstance().Enabled)
            {
                frozenPoseIsSpongy = true;
            }
            goHelper.transform.SetGlobalPose(spongyPose);
            worldAnchor = goHelper.AddComponent <WorldAnchor>();

            AttachmentPoint = WorldLockingManager.GetInstance().AttachmentPointManager.CreateAttachmentPoint(gameObject.transform.position, null,
                                                                                                             HandleAdjustLocation, // Handle adjustments to position
                                                                                                             null                  // Handle connectedness of fragment
                                                                                                             );
            AttachmentPoint.Name = string.Format($"{gameObject.name}=>{AttachmentPoint.Name}");
        }