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, $"clp={computedLocked.position.ToString("F3")}" + $" lpp={lockedPose.position.ToString("F3")}" + $" vpp={virtualPose.position.ToString("F3")}" + $" FfP={mgr.FrozenFromPinned.position.ToString("F3")}" + $" PfL={pinnedFromLocked.position.ToString("F3")}" ); bool areEqualRotatons = computedLocked.rotation == lockedPose.rotation; Assert.IsTrue(areEqualRotatons, $"clr={computedLocked.rotation.ToString("F3")}" + $"lpr={lockedPose.rotation.ToString("F3")}" + $" FfP={mgr.FrozenFromPinned.position.ToString("F3")}" + $" PfL={pinnedFromLocked.position.ToString("F3")}" ); }
private void VerifyAlignmentIdentity(IAlignmentManager alignMgr, PinData[] pinData) { for (int i = 0; i < pinData.Length; ++i) { alignMgr.ComputePinnedPose(new Pose(pinData[i].lockedPose.position, Quaternion.identity)); Pose pinnedFromLocked = alignMgr.PinnedFromLocked; bool isIdentityPosition = pinnedFromLocked.position == Vector3.zero; Assert.IsTrue(isIdentityPosition); bool isIdentityRotation = pinnedFromLocked.rotation == Quaternion.identity; Assert.IsTrue(isIdentityRotation); } }
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 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); }
/// <summary> /// Update is called by the update proxy. /// </summary> private void Update() { ErrorStatus = ""; if (hasPendingLoadTask) { ErrorStatus = "pending background load task"; return; } if (AdjustmentFrame == null) { Debug.Log("No WLM update because no adjustment frame set"); ErrorStatus = "no adjustment frame"; return; } // AnchorManager.Update takes care of creating anchors&edges and feeding the up-to-date state // into the FrozenWorld engine bool hasSpongyAnchors = AnchorManager.Update(); //#if UNITY_WSA if (!hasSpongyAnchors) { // IFragmentManager.Pause() will set all fragments to disconnected. ErrorStatus = AnchorManager.ErrorStatus; FragmentManager.Pause(); return; } //#endif // UNITY_WSA try { DiagnosticRecordings.Update(); } catch (Exception exception) { Debug.LogErrorFormat("Error writing WorldLocking diagnostics record: {0}", exception); } // The basic output from the FrozenWorld engine (current fragment and its alignment) // are applied to the unity scene FragmentManager.Update(AutoRefreeze, AutoMerge); /// The following assumes a camera hierarchy like this: /// Nodes_A => AdjustmentFrame => Nodes_B => camera /// The cumulative effect of Nodes_B is to transform from Spongy space to playspace. /// Spongy space is the space that the camera moves about in, and is the space that /// coordinates coming from scene agnostic APIs like XR are in. /// (Note the MRTK APIs are in Unity's global space, not Spongy space. /// The internal structure of that graph is inconsequential here, the only dependency /// is on the cumulative transform, PlayspaceFromSpongy. /// Likewise, the cumulative effect of Nodes_A is to transform from alignment space (described below) /// to Unity's global space, referred to here as FrozenSpace. /// The AdjustmentFrame's transform is composed of two transforms. /// The first comes from the FrozenWorld engine DLL as the inverse of Plugin.GetAlignment(), /// and transforms from Playspace to the base stable world locked space, labeled as /// LockedFromPlayspace. /// The second transforms from this stable but arbitrary space to a space locked /// to a finite set of real world markers. This transform is labeled PinnedFromLocked. /// The transform chain equivalent of the above camera hierarchy is: /// FrozenFromPinned * [PinnedFromLocked * LockedFromPlayspace] * PlayspaceFromSpongy * SpongyFromCamera /// /// FrozenFromSpongy and its inverse are useful for converting between the coordinates of scene agnostic APIs (e.g. XR) /// and Frozen coordinates, i.e. Unity's global space. /// FrozenFromLocked is convenient for converting between the "frozen" coordinates of the FrozenWorld engine DLL /// and Unity's global space, i.e. Frozen coordinate. if (Enabled) { Pose playspaceFromLocked = Plugin.GetAlignment(); LockedFromPlayspace = playspaceFromLocked.Inverse(); SpongyFromCamera = Plugin.GetSpongyHead(); Pose lockedHeadPose = LockedFromPlayspace.Multiply(PlayspaceFromSpongy.Multiply(SpongyFromCamera)); alignmentManager.ComputePinnedPose(lockedHeadPose); PinnedFromLocked = alignmentManager.PinnedFromLocked; } else { SpongyFromCamera = Camera.main.transform.GetLocalPose(); /// Note leave adjustment and pinning transforms alone, to facilitate /// comparison of behavior when toggling FW enabled. } AdjustmentFrame.SetLocalPose(PinnedFromLocked.Multiply(LockedFromPlayspace)); #if false && WLT_ARSUBSYSTEMS_PRESENT if ((AdjustmentFrame.GetGlobalPose().position != Vector3.zero) || (AdjustmentFrame.GetGlobalPose().rotation != Quaternion.identity)) { Debug.Log($"WLT: Adj{AnchorManagerXR.DebugVector3("O=", AdjustmentFrame.GetGlobalPose().position)}, {AnchorManagerXR.DebugEuler("R=", AdjustmentFrame.GetGlobalPose().rotation.eulerAngles)}"); } #endif // WLT_ARSUBSYSTEMS_PRESENT AutoSaveTriggerHook(); }