├── WorldLocking.Tools ├── Models │ ├── Arrow.fbx │ ├── Axis_LowPoly.fbx │ ├── Ring_LowPoly.fbx │ ├── Axis_LowPoly.fbx.meta │ ├── Arrow.fbx.meta │ └── Ring_LowPoly.fbx.meta ├── Editor.meta ├── Materials.meta ├── Models.meta ├── Prefabs.meta ├── Prefabs │ ├── AnchorGraphVisual.prefab.meta │ ├── Runtime Console.prefab.meta │ ├── FrozenAnchorSimple.prefab.meta │ ├── SpacePinVisualizer.prefab.meta │ ├── SpongyAnchorSimple.prefab.meta │ ├── SpongyAnchorVisual.prefab.meta │ ├── PercentageWorldCanvasPrefab.prefab.meta │ ├── FrameVisual.prefab.meta │ ├── FrozenAnchorVisual.prefab.meta │ ├── AnchorGraphVisual.prefab │ ├── SpacePinVisualizer.prefab │ ├── FrozenAnchorSimple.prefab │ └── SpongyAnchorSimple.prefab ├── Scripts.meta ├── Editor │ ├── WorldLocking.Tools.Editor.asmdef.meta │ ├── WorldLockingSetup.cs.meta │ └── WorldLocking.Tools.Editor.asmdef ├── Materials │ ├── WLT-Blue.mat.meta │ ├── WLT-Green.mat.meta │ ├── WLT-Line.mat.meta │ ├── WLT-Red.mat.meta │ ├── DebugVisualizerMeshMaterial.mat.meta │ ├── DebugVisualizerWeightMeshMaterial.mat.meta │ ├── DebugVisualizerWireframeMeshMaterial.mat.meta │ ├── DebugVisualizerExtrapolatedMeshMaterial.mat.meta │ ├── DebugVisualizerWeightMeshMaterial.mat │ ├── DebugVisualizerWireframeMeshMaterial.mat │ ├── DebugVisualizerExtrapolatedMeshMaterial.mat │ ├── DebugVisualizerMeshMaterial.mat │ └── WLT-Line.mat ├── Microsoft.MixedReality.WorldLocking.Tools.asmdef.meta ├── Scripts │ ├── AdjusterBase.cs.meta │ ├── AdjusterFixed.cs.meta │ ├── AdjusterMoving.cs.meta │ ├── ConnectingLine.cs.meta │ ├── FrameVisual.cs.meta │ ├── FrozenTapToAdd.cs.meta │ ├── SimpleConsole.cs.meta │ ├── SimpleSprite.cs.meta │ ├── StatusToText.cs.meta │ ├── AnchorGraphVisual.cs.meta │ ├── FrozenAnchorVisual.cs.meta │ ├── SpongyAnchorVisual.cs.meta │ ├── ToggleWorldAnchor.cs.meta │ ├── WorldAnchorAdapter.cs.meta │ ├── FrozenSpatialMapping.cs.meta │ ├── SpacePinMeshVisualizer.cs.meta │ ├── SpacePinPercentageVisualizer.cs.meta │ ├── AdjusterBase.cs │ ├── AdjusterMoving.cs │ ├── FrameVisual.cs │ ├── SimpleSprite.cs │ ├── FrozenAnchorVisual.cs │ ├── WorldAnchorAdapter.cs │ ├── ConnectingLine.cs │ ├── SpacePinPercentageVisualizer.cs │ ├── FrozenTapToAdd.cs │ ├── ToggleWorldAnchor.cs │ ├── SpongyAnchorVisual.cs │ └── AdjusterFixed.cs └── Microsoft.MixedReality.WorldLocking.Tools.asmdef ├── package.json.meta ├── WorldLocking.Core.meta ├── WorldLocking.Engine.meta ├── WorldLocking.Tools.meta ├── WorldLocking.Core ├── Editor.meta ├── Prefabs.meta ├── Scripts.meta ├── Scripts │ ├── ARF.meta │ ├── WSA.meta │ ├── XR.meta │ ├── ARCore.meta │ ├── Null.meta │ ├── Fragment.cs.meta │ ├── IOrienter.cs.meta │ ├── Orienter.cs.meta │ ├── SpacePin.cs.meta │ ├── AlignSubtree.cs.meta │ ├── AnchorManager.cs.meta │ ├── AnchorSettings.cs.meta │ ├── AttachmentPoint.cs.meta │ ├── Diagnostics.cs.meta │ ├── FragmentManager.cs.meta │ ├── IAnchorManager.cs.meta │ ├── LinkageSettings.cs.meta │ ├── ManagerSettings.cs.meta │ ├── PoseExtensions.cs.meta │ ├── ResourceMirror.cs.meta │ ├── SpongyAnchor.cs.meta │ ├── Triangulator.cs.meta │ ├── ARF │ │ ├── AnchorManagerARF.cs.meta │ │ ├── SpongyAnchorARF.cs.meta │ │ ├── AnchorManagerARF_2019.cs.meta │ │ ├── SpongyAnchorARF_2019.cs.meta │ │ └── AnchorManagerARF_OpenXR.cs.meta │ ├── AlignmentManager.cs.meta │ ├── DiagnosticsSettings.cs.meta │ ├── HeadPoseTrackerXR.cs.meta │ ├── IAlignmentManager.cs.meta │ ├── IAttachmentPoint.cs.meta │ ├── IFragmentManager.cs.meta │ ├── IHeadPoseTracker.cs.meta │ ├── OrienterThreeBody.cs.meta │ ├── SpacePinOrientable.cs.meta │ ├── WSA │ │ ├── AnchorManagerWSA.cs.meta │ │ ├── SpongyAnchorWSA.cs.meta │ │ └── SpongyAnchorWSA.cs │ ├── WorldLockingContext.cs.meta │ ├── WorldLockingManager.cs.meta │ ├── XR │ │ ├── AnchorManagerXR.cs.meta │ │ ├── SpongyAnchorXR.cs.meta │ │ ├── AnchorManagerXR_2018.cs.meta │ │ ├── AnchorManagerXR_OpenXR.cs.meta │ │ ├── AnchorManagerXR_WMR.cs.meta │ │ ├── SpongyAnchorXR.cs │ │ ├── AnchorManagerXR_WMR.cs │ │ └── AnchorManagerXR_OpenXR.cs │ ├── ARCore │ │ ├── SpongyAnchorARCore.cs.meta │ │ ├── AnchorManagerARCore.cs.meta │ │ ├── AnchorManagerARCore.cs │ │ └── SpongyAnchorARCore.cs │ ├── HeadPoseTrackerCamera.cs.meta │ ├── IAttachmentPointManager.cs.meta │ ├── Null │ │ ├── AnchorManagerNull.cs.meta │ │ ├── SpongyAnchorNull.cs.meta │ │ ├── SpongyAnchorNull.cs │ │ └── AnchorManagerNull.cs │ ├── RefitNotificationDelegate.cs.meta │ ├── IHeadPoseTracker.cs │ ├── RefitNotificationDelegate.cs │ ├── HeadPoseTrackerCamera.cs │ ├── SpongyAnchor.cs │ ├── HeadPoseTrackerXR.cs │ ├── DiagnosticsSettings.cs │ ├── IOrienter.cs │ ├── IAnchorManager.cs │ ├── WorldLockingContext.cs │ ├── IFragmentManager.cs │ ├── PoseExtensions.cs │ ├── LinkageSettings.cs │ ├── ManagerSettings.cs │ ├── AttachmentPoint.cs │ ├── IAttachmentPointManager.cs │ └── IAttachmentPoint.cs ├── Microsoft.MixedReality.WorldLocking.Core.asmdef.meta ├── Editor │ ├── Microsoft.MixedReality.WorldLocking.Core.Editor.asmdef.meta │ ├── WorldLockingContextEditor.cs.meta │ └── Microsoft.MixedReality.WorldLocking.Core.Editor.asmdef ├── Prefabs │ ├── WorldLockingManager.prefab.meta │ └── WorldLockingManager.prefab └── Microsoft.MixedReality.WorldLocking.Core.asmdef ├── README.md ├── WorldLocking.Engine ├── Microsoft.MixedReality.WorldLocking.Engine.asmdef.meta ├── Plugin.cs.meta ├── IPlugin.cs.meta ├── PluginNoop.cs.meta └── Microsoft.MixedReality.WorldLocking.Engine.asmdef └── package.json /WorldLocking.Tools/Models/Arrow.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuzzy-Door-Tech/WLT-MRTK3-Port/HEAD/WorldLocking.Tools/Models/Arrow.fbx -------------------------------------------------------------------------------- /WorldLocking.Tools/Models/Axis_LowPoly.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuzzy-Door-Tech/WLT-MRTK3-Port/HEAD/WorldLocking.Tools/Models/Axis_LowPoly.fbx -------------------------------------------------------------------------------- /WorldLocking.Tools/Models/Ring_LowPoly.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuzzy-Door-Tech/WLT-MRTK3-Port/HEAD/WorldLocking.Tools/Models/Ring_LowPoly.fbx -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d4db4e99636bec4ca5ddc64b9a3dde0 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Core.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b04f236737050742a861b6fe74d066a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Engine.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 322abafdd76e2ba4493f34b3343f63bf 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 661dbe3b9664e5c4da5ae3cf870ecdc2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a412f63d3ba690446af3dafbd85a25f4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d63a758a9f88e3b4b982a0cfad061f2c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 77a28986d0403614b92fd8db549180a3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2308a3c3afa3144b970ec81925db167 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WSA.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1eb903b3e2fc6c84f8bbdb44618d9f74 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7aeadb6515975c34d8bb38d27ac53b98 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8f92d9ee9892a14dadff94e37ace71a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca75611e089594947911df3b63e5b230 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Models.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49b653f4d666c6040bee5a0fa289f476 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5286fc1d0ca90e41a8882c8d08f30c7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/AnchorGraphVisual.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2fea6b6d80fd104ba370eec2ee4184f 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/Runtime Console.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43511b9bc697510418bae74800f78728 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8febf0ac5302cf24fae4e4924e1e922c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARCore.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5003b431025d904f8b394539d17746e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Null.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0dcf12667cdc0440b133a205116b4aa 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/FrozenAnchorSimple.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab6671261c0c306459e7e7604e4b3278 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/SpacePinVisualizer.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 788258058cd9c4a4696cb1bc0c93cc9d 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/SpongyAnchorSimple.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee5df711dcd3e54429c57b3e7e573afd 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/SpongyAnchorVisual.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5ba1fa0f254af640a17dc22e4688b87 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/PercentageWorldCanvasPrefab.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20ac37323fee4694891b0de09cb74933 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Editor/WorldLocking.Tools.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fac3af05c7857540b16171a4518cd5c 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WLT-MRTK3-Port 2 | 3 | We have been using this port for months with MRTK3, Unity 2021 and Unity 2022. It primarily provides support for using AR Foundation's XROrigin and related changes. 4 | 5 | This port is not actively supported by FuzzyDoorTech 6 | -------------------------------------------------------------------------------- /WorldLocking.Core/Microsoft.MixedReality.WorldLocking.Core.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19d8fc307d9d1c346a776d7cb7fd0ca9 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Engine/Microsoft.MixedReality.WorldLocking.Engine.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 927e0a945b06c394fac9d2c48d3e0b29 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/WLT-Blue.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16c776183f63c3f468f0367b410ea876 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/WLT-Green.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0cf8048742703a640b91ff91e5f1c4bc 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/WLT-Line.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0d9513524d19caa48a7071447d2cd84f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/WLT-Red.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e1deb091b121ff4189a75ae7387670c 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Microsoft.MixedReality.WorldLocking.Tools.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94cf667e337f6534fb9b9a24c9cfbfb4 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/FrameVisual.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14e05d2e3eab0df479903e125064ce4b 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 100100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Core/Editor/Microsoft.MixedReality.WorldLocking.Core.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 222261952238b6e459b77c3400061d9f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /WorldLocking.Core/Prefabs/WorldLockingManager.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0777d53f35d4cb42827b5c3bdf227bd 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 100100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerMeshMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e7629c5005d65c94ba769b3e2f1fe247 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/FrozenAnchorVisual.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d47affea335f196479d4ec680aca4223 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 100100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerWeightMeshMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e46624c9f6c5374da2204cd8c11e698 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerWireframeMeshMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30a725532743f544d8873fd08a9040bb 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerExtrapolatedMeshMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb6998e3870cb345a31ad89410518c1 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /WorldLocking.Engine/Plugin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c845d23e7fbdd94181c57e547a0c4a1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Engine/IPlugin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83bee2cfa11d1a24a97463a550c741f9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Engine/PluginNoop.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb637fa72a97b5a47bb0bf270f4cd5ce 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Fragment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10919751fc5215b429a127a52171053a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IOrienter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63551bd604a5fa94184ff64596961fe2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Orienter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8973142cb9c266c48a63aab9d3105687 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/SpacePin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90b7ad606f014604d9526d135c0fec88 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AlignSubtree.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5e87834f548844468f74826f83b0853 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AnchorManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 359bf51bf25d0024c938e830a0f8cd82 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AnchorSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70943d8a6ca6e614ebce458ae55fd813 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AttachmentPoint.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9cf331bfe19befc4aa70aba24929f82e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Diagnostics.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2181ac5b042c86f429361daf3463c0a5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/FragmentManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65e94037870937c4f9a3cd63a22379a4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAnchorManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a54ea0b6161dfea42996f9bb6623fc4a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/LinkageSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 396345c4fa78ce142a2b6cff585795ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ManagerSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ef8835cb44f7f54a9fc5b321e990aa7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/PoseExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76774d8e9718ebf4dbfd8e3e2fe324a1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ResourceMirror.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d3de409dc84fd2428d3b64535faa4be 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/SpongyAnchor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 37421933d6acd1547b9bddfad5c878cb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Triangulator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcde0bd1332e98d49b43c5873985a497 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c9d0d756af1f1f40bf114d8edb895ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterFixed.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b074ba52962ad9e48b9c239fc6f94689 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterMoving.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba31c0b790bb71d4c98d3e546111328b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/ConnectingLine.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db264e9ff4fc0ee4e928753a4967261a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrameVisual.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d209048f80c2f5f459c3e41beb3992d3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrozenTapToAdd.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1819a47a97b1ac8428177cc2c96d0d3d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SimpleConsole.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af00d72a16bffdb45b714197b779b5ec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SimpleSprite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dce5cced4f79ce94e99bec7a9653c45d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/StatusToText.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9e2d0456ebd9114baeaa71fe717a233 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF/AnchorManagerARF.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1925a16c4e858174992bce6bbe36dd5f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF/SpongyAnchorARF.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a86fb3d6e5a6c874e9aec84148f36d18 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AlignmentManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8f432b2dea342d408b77e0984dc1029 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/DiagnosticsSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93f7563a084b919469137dda8a51f66b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/HeadPoseTrackerXR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 05184b79dff087147b6e22f8c4506f7d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAlignmentManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3174560ebcc3d584faf954a72aa3e5a5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAttachmentPoint.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cbbb8292eacc17944a02a7b15e597443 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IFragmentManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c091b360373c4b4dbf0c6df85d05e48 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IHeadPoseTracker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4379652f130f2d48af23efea12a5c25 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/OrienterThreeBody.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 677c11a90b63d37498915986b5a9439c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/SpacePinOrientable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc82eeae7a27d4d4eb86e0e5036744b8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WSA/AnchorManagerWSA.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1efae7bd62260c4494cf4445fadc57c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WSA/SpongyAnchorWSA.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: feb9d8d22d63e4f4492b1f951960c94b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WorldLockingContext.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89a5fa969ae86b94db3d314558cf69ba 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WorldLockingManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0734df14efdfe242a43bfc28d2b3f03 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b4c0f6a4bbb7dbc47a16282b6ccbbd86 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/SpongyAnchorXR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9ec29c1c5399d2489996be73a276c7d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Editor/WorldLockingSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9433cd9fae1da904685c2a5302ebc29b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AnchorGraphVisual.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93bf53c0f434c774fae7087613e7f766 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrozenAnchorVisual.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 417748c2517fd2a469240fc7d65c062c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SpongyAnchorVisual.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb58f91d3e7cdd948ba2ac3090412cf7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/ToggleWorldAnchor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db943b71af8da78428cef8266cd145a8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/WorldAnchorAdapter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 025de2b0c1a2d624797e19a6af8dcd78 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Editor/WorldLockingContextEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6e139b43d462e3459c714b47f8ccf51 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARCore/SpongyAnchorARCore.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95ba25bb44a75ee42b9c722253416af7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF/AnchorManagerARF_2019.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7bd2bf1acd53ef847bba5ebf9e54c7a0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF/SpongyAnchorARF_2019.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bf211d9f99a54c44b0ddbe8d7872ae5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/HeadPoseTrackerCamera.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c0fb1399335cc24fa2f510aceb676ae 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAttachmentPointManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed975a455f9069349a82d256e0ed7e13 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Null/AnchorManagerNull.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b3188910a27cac4489888c8571393384 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Null/SpongyAnchorNull.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a9dec8b301cb5a41a64a099c944e113 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/RefitNotificationDelegate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60ec0667956d2344981188ddfbaabfaa 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR_2018.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 888efc03f1bc54940a1ac548e8c19a23 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR_OpenXR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c4ef6663a29e7b41980adbca5cc8734 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR_WMR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e8e935af4e687d4b8a2b22e11dee692 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrozenSpatialMapping.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 749224e69ec1d464a8a24ca6c4a06888 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SpacePinMeshVisualizer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e62df43f837dec04690c9413ceb5c046 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARCore/AnchorManagerARCore.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 35a171fa0ecc20c4a8ce43da3682cc73 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARF/AnchorManagerARF_OpenXR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba9695610d17e2b43913f864667af762 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SpacePinPercentageVisualizer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffc9eaa0c00b2bf46a69038142592bf8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /WorldLocking.Engine/Microsoft.MixedReality.WorldLocking.Engine.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Microsoft.MixedReality.WorldLocking.Engine", 3 | "references": [ 4 | "Microsoft.MixedReality.Unity.FrozenWorld.Engine" 5 | ], 6 | "optionalUnityReferences": [], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": true, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [] 14 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Editor/Microsoft.MixedReality.WorldLocking.Core.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Microsoft.MixedReality.WorldLocking.Core.Editor", 3 | "references": [ 4 | "Microsoft.MixedReality.WorldLocking.Core" 5 | ], 6 | "optionalUnityReferences": [], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [] 16 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Microsoft.MixedReality.WorldLocking.Tools.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Microsoft.MixedReality.WorldLocking.Tools", 3 | "references": [ 4 | "Microsoft.MixedReality.WorldLocking.Core", 5 | "Microsoft.MixedReality.WorldLocking.Engine" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [] 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.fuzzydoortech.worldlockingtools", 3 | "version": "1.0.0", 4 | "displayName": "World Locking Tools", 5 | "description": "Shared code across various projects", 6 | "unity": "2022.3", 7 | "unityRelease": "0f1", 8 | "documentationUrl": "", 9 | "changelogUrl": "", 10 | "licensesUrl": "", 11 | "dependencies": { 12 | 13 | }, 14 | "keywords": [ 15 | 16 | ], 17 | "author": { 18 | "name": "Microsoft", 19 | "email": "info@fuzzydoortech.com", 20 | "url": "https://viewscreen.com" 21 | }, 22 | "files": [ 23 | "Scripts*", 24 | "package.json.meta" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IHeadPoseTracker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Interface for retrieving the current head pose. 10 | /// 11 | public interface IHeadPoseTracker 12 | { 13 | /// 14 | /// Reset is called whenever there is a conceptual restart. Any cached information should be discarded 15 | /// and re-evaluated. 16 | /// 17 | void Reset(); 18 | 19 | /// 20 | /// Return the current head pose in Spongy (local) space. 21 | /// 22 | /// The current head pose. 23 | Pose GetHeadPose(); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/RefitNotificationDelegate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | 5 | namespace Microsoft.MixedReality.WorldLocking.Core 6 | { 7 | /// 8 | /// Delegate type for notification of refit operations. 9 | /// 10 | /// 11 | /// In the case of a merge operation, absorbedIds will contain all and only the ids of the fragments 12 | /// that were merged into mergedId, but not including mergedId. 13 | /// In the case of a refreeze operation, absorbedIds will also contain mergedId. 14 | /// 15 | /// The fragment id of the target merged fragment. 16 | /// Fragment ids of all affected fragments. 17 | public delegate void RefitNotificationDelegate(FragmentId mergedId, FragmentId[] absorbedIds); 18 | 19 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Editor/WorldLocking.Tools.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WorldLocking.Tools.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "Microsoft.MixedReality.WorldLocking.Core", 6 | "Microsoft.MixedReality.WorldLocking.Tools", 7 | "Unity.XR.ARFoundation", 8 | "Unity.XR.CoreUtils" 9 | ], 10 | "includePlatforms": [ 11 | "Editor" 12 | ], 13 | "excludePlatforms": [], 14 | "allowUnsafeCode": false, 15 | "overrideReferences": false, 16 | "precompiledReferences": [], 17 | "autoReferenced": true, 18 | "defineConstraints": [], 19 | "versionDefines": [ 20 | { 21 | "name": "com.unity.xr.arfoundation", 22 | "expression": "", 23 | "define": "WLT_ARSUBSYSTEMS_PRESENT" 24 | }, 25 | { 26 | "name": "com.unity.xr.arfoundation", 27 | "expression": "", 28 | "define": "WLT_ARFOUNDATION_PRESENT" 29 | } 30 | ], 31 | "noEngineReferences": false 32 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Tools 7 | { 8 | /// 9 | /// Dummy class to identify components as implementing Frozen World's adjustment handler(s). 10 | /// 11 | /// 12 | /// Derivation from this class is not necessary to implement the necessary handling 13 | /// of state and transform messages from the system, as that handling is implemented by delegates, not 14 | /// inheritance. However, having a component derived from this base class attached to an object notifies the system 15 | /// that the object's handling of Frozen World system adjustments is covered, and prevents 16 | /// the system from automatically adding its own handlers to that object (if so configured). 17 | /// 18 | public class AdjusterBase : MonoBehaviour 19 | { 20 | } 21 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/HeadPoseTrackerCamera.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | 8 | namespace Microsoft.MixedReality.WorldLocking.Core 9 | { 10 | public class HeadPoseTrackerCamera : IHeadPoseTracker 11 | { 12 | private Camera camera = Camera.main; 13 | 14 | public virtual void Reset() 15 | { 16 | camera = Camera.main; 17 | } 18 | 19 | public void BindToCamera(Camera c) 20 | { 21 | camera = c; 22 | } 23 | 24 | public virtual Pose GetHeadPose() 25 | { 26 | Pose headPose = Pose.identity; 27 | if (camera != null) 28 | { 29 | Pose spongyFromCamera = camera.transform.GetLocalPose(); 30 | headPose = spongyFromCamera; 31 | } 32 | return headPose; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterMoving.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.MixedReality.WorldLocking.Core; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Tools 7 | { 8 | 9 | /// 10 | /// Component to handle frozen world adjustments for dynamic (moving) objects. 11 | /// 12 | /// 13 | /// For stationary objects, use . 14 | /// 15 | /// This component uses the Unity Update pass to keep the World Locking Tools system 16 | /// apprised of the target object's position. While that operation is cheap, even 17 | /// just the cost of an additional Update() is best avoided for stationary objects. 18 | /// 19 | /// If the object moves very infrequently under script control, consider using an , 20 | /// and notifying it after moves with . 21 | /// 22 | public class AdjusterMoving : AdjusterFixed 23 | { 24 | /// 25 | /// Notify the system each frame of current position. 26 | /// 27 | private void Update() 28 | { 29 | UpdatePosition(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrameVisual.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Tools 7 | { 8 | /// 9 | /// Component for adjusting color and description text of visual origin markers in a frame (coordinate system axes). 10 | /// 11 | public class FrameVisual : MonoBehaviour 12 | { 13 | [SerializeField] 14 | [Tooltip("Visual marker to be colored")] 15 | private Renderer originMarker = null; 16 | 17 | [SerializeField] 18 | [Tooltip("Text object to be colored and set to the name of this GameObject")] 19 | private TextMesh originText = null; 20 | 21 | /// 22 | /// Text and axes color 23 | /// 24 | public Color color 25 | { 26 | get { return originText.color; } 27 | set 28 | { 29 | originText.color = value; 30 | for (int i = 0; i < originMarker.materials.Length; i++) 31 | { 32 | originMarker.materials[i].color = value; 33 | } 34 | } 35 | } 36 | 37 | private void Start() 38 | { 39 | originText.text = name; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/SpongyAnchor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Wrapper class for Unity spatial anchors, facilitating creation and persistence. 10 | /// 11 | public abstract class SpongyAnchor : MonoBehaviour 12 | { 13 | 14 | /// 15 | /// Returns true if the anchor is reliably located. False might mean loss of tracking or not fully initialized. 16 | /// 17 | public abstract bool IsLocated { get; } 18 | 19 | /// 20 | /// Return the anchor's pose in spongy space. 21 | /// 22 | public abstract Pose SpongyPose { get; } 23 | 24 | /// 25 | /// Whether the underlying spatial anchor is known to be in the local anchor store. 26 | /// 27 | /// 28 | /// Note that the anchor might be in the anchor store but isn't known to be, so IsSaved == false. 29 | /// In particular, a different anchor might be stored under the same name, in which case saving 30 | /// this anchor probably requires deleting the old anchor first. 31 | /// 32 | public virtual bool IsSaved { get; set; } = false; 33 | 34 | /// 35 | /// Diagnostic only - to be removed. 36 | /// 37 | public virtual Vector3 Delta { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/AnchorGraphVisual.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &4818818914751565137 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 3456838522220260497} 12 | - component: {fileID: 2243689008866668596} 13 | m_Layer: 2 14 | m_Name: AnchorGraphVisual 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &3456838522220260497 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 4818818914751565137} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_Children: [] 31 | m_Father: {fileID: 0} 32 | m_RootOrder: 0 33 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 34 | --- !u!114 &2243689008866668596 35 | MonoBehaviour: 36 | m_ObjectHideFlags: 0 37 | m_CorrespondingSourceObject: {fileID: 0} 38 | m_PrefabInstance: {fileID: 0} 39 | m_PrefabAsset: {fileID: 0} 40 | m_GameObject: {fileID: 4818818914751565137} 41 | m_Enabled: 1 42 | m_EditorHideFlags: 0 43 | m_Script: {fileID: 11500000, guid: 93bf53c0f434c774fae7087613e7f766, type: 3} 44 | m_Name: 45 | m_EditorClassIdentifier: 46 | Prefab_FrameViz: {fileID: 114836466068092498, guid: 14e05d2e3eab0df479903e125064ce4b, 47 | type: 3} 48 | Prefab_SpongyAnchorViz: {fileID: 1510356976864930653, guid: b5ba1fa0f254af640a17dc22e4688b87, 49 | type: 3} 50 | Prefab_FrozenAnchorViz: {fileID: 114965271361823434, guid: d47affea335f196479d4ec680aca4223, 51 | type: 3} 52 | connectingLine: {fileID: 2100000, guid: 0d9513524d19caa48a7071447d2cd84f, type: 2} 53 | -------------------------------------------------------------------------------- /WorldLocking.Core/Microsoft.MixedReality.WorldLocking.Core.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Microsoft.MixedReality.WorldLocking.Core", 3 | "rootNamespace": "", 4 | "references": [ 5 | "Unity.XR.ARFoundation", 6 | "Unity.XR.ARSubsystems", 7 | "Microsoft.MixedReality.WorldLocking.Engine", 8 | "UnityEngine.SpatialTracking", 9 | "GoogleARCore", 10 | "Microsoft.MixedReality.OpenXR", 11 | "Unity.XR.WindowsMixedReality", 12 | "Unity.XR.Management", 13 | "Unity.XR.OpenXR", 14 | "Unity.XR.CoreUtils" 15 | ], 16 | "includePlatforms": [], 17 | "excludePlatforms": [], 18 | "allowUnsafeCode": false, 19 | "overrideReferences": false, 20 | "precompiledReferences": [], 21 | "autoReferenced": true, 22 | "defineConstraints": [], 23 | "versionDefines": [ 24 | { 25 | "name": "com.unity.xr.arfoundation", 26 | "expression": "", 27 | "define": "WLT_ARFOUNDATION_PRESENT" 28 | }, 29 | { 30 | "name": "com.unity.xr.arfoundation", 31 | "expression": "", 32 | "define": "WLT_ARSUBSYSTEMS_PRESENT" 33 | }, 34 | { 35 | "name": "com.unity.xr.windowsmr.metro", 36 | "expression": "", 37 | "define": "WLT_LEGACY_WMR_XR_PRESENT" 38 | }, 39 | { 40 | "name": "com.microsoft.mixedreality.openxr", 41 | "expression": "", 42 | "define": "WLT_MICROSOFT_OPENXR_PRESENT" 43 | }, 44 | { 45 | "name": "com.unity.xr.windowsmr", 46 | "expression": "4.3", 47 | "define": "WLT_MICROSOFT_WMR_XR_4_3_PRESENT" 48 | }, 49 | { 50 | "name": "com.unity.xr.management", 51 | "expression": "", 52 | "define": "WLT_XR_MANAGEMENT_PRESENT" 53 | }, 54 | { 55 | "name": "com.unity.xr.openxr", 56 | "expression": "", 57 | "define": "WLT_XR_OPENXR_PRESENT" 58 | } 59 | ], 60 | "noEngineReferences": false 61 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Prefabs/WorldLockingManager.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &1141710421841518 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 4133740187393454} 12 | - component: {fileID: 114794997547214612} 13 | m_Layer: 0 14 | m_Name: WorldLockingManager 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &4133740187393454 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 1141710421841518} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_Children: [] 31 | m_Father: {fileID: 0} 32 | m_RootOrder: 0 33 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 34 | --- !u!114 &114794997547214612 35 | MonoBehaviour: 36 | m_ObjectHideFlags: 0 37 | m_CorrespondingSourceObject: {fileID: 0} 38 | m_PrefabInstance: {fileID: 0} 39 | m_PrefabAsset: {fileID: 0} 40 | m_GameObject: {fileID: 1141710421841518} 41 | m_Enabled: 1 42 | m_EditorHideFlags: 0 43 | m_Script: {fileID: 11500000, guid: 89a5fa969ae86b94db3d314558cf69ba, type: 3} 44 | m_Name: 45 | m_EditorClassIdentifier: 46 | shared: 47 | settings: 48 | useDefaults: 1 49 | Enabled: 1 50 | AutoMerge: 1 51 | AutoRefreeze: 1 52 | AutoLoad: 1 53 | AutoSave: 1 54 | linkageSettings: 55 | useExisting: 0 56 | AdjustmentFrame: {fileID: 0} 57 | CameraParent: {fileID: 0} 58 | diagnosticsSettings: 59 | settings: 60 | useDefaults: 1 61 | Enabled: 0 62 | StorageSubdirectory: FrozenWorldDiagnostics 63 | StorageFileTemplate: FrozenWorld-[Machine]-[Timestamp].hkfw 64 | MaxKilobytesPerFile: 2048 65 | MaxNumberOfFiles: 64 66 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/SpacePinVisualizer.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &656164348478012891 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 656164348478012889} 12 | - component: {fileID: 656164348478012890} 13 | m_Layer: 0 14 | m_Name: SpacePinVisualizer 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &656164348478012889 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 656164348478012891} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: -0.25, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_Children: [] 31 | m_Father: {fileID: 0} 32 | m_RootOrder: 0 33 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 34 | --- !u!114 &656164348478012890 35 | MonoBehaviour: 36 | m_ObjectHideFlags: 0 37 | m_CorrespondingSourceObject: {fileID: 0} 38 | m_PrefabInstance: {fileID: 0} 39 | m_PrefabAsset: {fileID: 0} 40 | m_GameObject: {fileID: 656164348478012891} 41 | m_Enabled: 1 42 | m_EditorHideFlags: 0 43 | m_Script: {fileID: 11500000, guid: e62df43f837dec04690c9413ceb5c046, type: 3} 44 | m_Name: 45 | m_EditorClassIdentifier: 46 | weightCubeMaxSize: 0.19 47 | downwardsOffsetFromUser: 1.65 48 | wireFrameMaterial: {fileID: 2100000, guid: 30a725532743f544d8873fd08a9040bb, type: 2} 49 | meshMaterial: {fileID: 2100000, guid: e7629c5005d65c94ba769b3e2f1fe247, type: 2} 50 | extrapolatedMeshMaterial: {fileID: 2100000, guid: 3cb6998e3870cb345a31ad89410518c1, 51 | type: 2} 52 | weightsMaterial: {fileID: 2100000, guid: 1e46624c9f6c5374da2204cd8c11e698, type: 2} 53 | percentageWorldSpaceCanvasPrefab: {fileID: 3335127461111217805, guid: 20ac37323fee4694891b0de09cb74933, 54 | type: 3} 55 | isVisible: 1 56 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SimpleSprite.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Microsoft.MixedReality.WorldLocking.Tools 6 | { 7 | /// 8 | /// Very simple class to rotate sprites to face the camera. 9 | /// 10 | public class SimpleSprite : MonoBehaviour 11 | { 12 | [Tooltip("Object to face towards. Defaults to camera at time Start is called.")] 13 | [SerializeField] 14 | private Transform target = null; 15 | 16 | /// 17 | /// Object to face towards. Defaults to camera at time Start is called. 18 | /// 19 | public Transform Target { get { return target; } set { target = value; } } 20 | 21 | [Tooltip("Swivel means rotate about Y-axis, set to false to face directly at target.")] 22 | [SerializeField] 23 | private bool swivel = true; 24 | 25 | /// 26 | /// Swivel means rotate about Y-axis, set to false to face directly at target. 27 | /// 28 | public bool Swivel { get { return swivel; } set { swivel = value; } } 29 | // Start is called before the first frame update 30 | void Start() 31 | { 32 | if (target == null) 33 | { 34 | target = Camera.main.transform; 35 | } 36 | } 37 | 38 | // Update is called once per frame 39 | void Update() 40 | { 41 | Vector3 fromTarget = transform.position - target.position; 42 | Vector3 targetUp = Vector3.up; 43 | if (swivel) 44 | { 45 | fromTarget.y = 0; 46 | } 47 | else if (target.up.sqrMagnitude > 0) 48 | { 49 | targetUp = target.up; 50 | } 51 | if (fromTarget.sqrMagnitude > 0) 52 | { 53 | Quaternion rotation = Quaternion.LookRotation(fromTarget, targetUp); 54 | 55 | transform.rotation = rotation; 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrozenAnchorVisual.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Tools 7 | { 8 | /// 9 | /// Component for controlling color and ID text of anchor visualizations. 10 | /// 11 | /// 12 | /// The text will be set to the AnchorID. 13 | /// The color will be kept in sync with the parent frame. 14 | /// 15 | public class FrozenAnchorVisual : MonoBehaviour 16 | { 17 | [SerializeField] 18 | [Tooltip("The anchor visualization icon that will have its color adjusted")] 19 | private Renderer iconObject = null; 20 | 21 | [SerializeField] 22 | [Tooltip("The anchor visualization ID text that will have its text&color adjusted")] 23 | private TextMesh textObject = null; 24 | 25 | private FrameVisual parent; 26 | 27 | /// 28 | /// Create an instance of a frame visualizer 29 | /// 30 | /// The name of the anchor to be displayed 31 | /// The frame visualization object that defines the color of this anchor 32 | /// 33 | public FrozenAnchorVisual Instantiate(string name, FrameVisual parent) 34 | { 35 | var res = Instantiate(this, parent.transform); 36 | res.parent = parent; 37 | res.name = name; 38 | if (res.textObject != null) 39 | { 40 | res.textObject.text = name; 41 | } 42 | return res; 43 | } 44 | 45 | private void Update() 46 | { 47 | var color = parent.color; 48 | 49 | if (iconObject != null) 50 | { 51 | iconObject.material.color = color; 52 | } 53 | if (textObject != null) 54 | { 55 | textObject.color = color; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/WorldAnchorAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | 8 | using Microsoft.MixedReality.WorldLocking.Core; 9 | 10 | namespace Microsoft.MixedReality.WorldLocking.Tools 11 | { 12 | /// 13 | /// Adapter for aligning an object with a WorldAnchor. 14 | /// 15 | public class WorldAnchorAdapter : MonoBehaviour 16 | { 17 | [SerializeField] 18 | [Tooltip("The GameObject holding the WorldAnchor component.")] 19 | private GameObject worldAnchorObject; 20 | /// 21 | /// The GameObject holding the WorldAnchor component. 22 | /// 23 | public GameObject WorldAnchorObject 24 | { 25 | get { return worldAnchorObject; } 26 | set { worldAnchorObject = value; CheckActive(); } 27 | } 28 | 29 | [SerializeField] 30 | [Tooltip("The GameObject to be aligned to the WorldAnchor.")] 31 | private Transform targetObject; 32 | /// 33 | /// The GameObject to be aligned to the WorldAnchor. 34 | /// 35 | public Transform TargetObject 36 | { 37 | get { return targetObject; } 38 | set { targetObject = value; CheckActive(); } 39 | } 40 | 41 | private bool active = false; 42 | 43 | private void CheckActive() 44 | { 45 | active = (targetObject != null) 46 | && (worldAnchorObject != null); 47 | } 48 | 49 | // Start is called before the first frame update 50 | void Start() 51 | { 52 | CheckActive(); 53 | } 54 | 55 | 56 | // Update is called once per frame 57 | // Alternatively, we could make this a coroutine, and call it at a user specified interval. 58 | private void Update() 59 | { 60 | if (active) 61 | { 62 | Pose spongyFromAnchor = WorldAnchorObject.transform.GetGlobalPose(); 63 | Pose frozenFromSpongy = WorldLockingManager.GetInstance().FrozenFromSpongy; 64 | Pose frozenFromAnchor = frozenFromSpongy.Multiply(spongyFromAnchor); 65 | TargetObject.SetGlobalPose(frozenFromAnchor); 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/HeadPoseTrackerXR.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | using UnityEngine.XR; 8 | 9 | namespace Microsoft.MixedReality.WorldLocking.Core 10 | { 11 | public class HeadPoseTrackerXR : IHeadPoseTracker 12 | { 13 | private readonly List nodeStates = new List(); 14 | 15 | private Pose headPose = Pose.identity; 16 | 17 | /// 18 | public void Reset() 19 | { 20 | headPose = Pose.identity; 21 | } 22 | 23 | /// 24 | public Pose GetHeadPose() 25 | { 26 | // Note: 27 | // The low-level input obtained via InputTracking.GetLocal???(XRNode.Head) is automatically kept in sync with 28 | // Camera.main.transform.local??? (unless XRDevice.DisableAutoXRCameraTracking(Camera.main, true) is used to deactivate 29 | // this mechanism). In theory, both could be used interchangeably, potentially allowing to avoid the dependency 30 | // on low-level code at this point. It is not clear though, whether both values follow exactly the same timing or which 31 | // one is more correct to be used at this point. More research might be necessary. 32 | // 33 | // The decision between low-level access via InputTracking and high-level access via Camera.main.transform should 34 | // be coordinated with the decision between high-level access to anchors and low-level access to 35 | // Windows.Perception.Spatial.SpatialAnchor -- see comment at top of SpongyAnchor.cs 36 | nodeStates.Clear(); 37 | InputTracking.GetNodeStates(nodeStates); 38 | for (int i = 0; i < nodeStates.Count; ++i) 39 | { 40 | if (nodeStates[i].nodeType == XRNode.Head) 41 | { 42 | Vector3 position; 43 | Quaternion rotation; 44 | if (nodeStates[i].tracked && nodeStates[i].TryGetPosition(out position) && nodeStates[i].TryGetRotation(out rotation)) 45 | { 46 | headPose = new Pose(position, rotation); 47 | } 48 | } 49 | } 50 | return headPose; 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/ConnectingLine.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Tools 7 | { 8 | /// 9 | /// Helper class for visualizing a graph of connected transforms. 10 | /// 11 | public class ConnectingLine : MonoBehaviour 12 | { 13 | private Transform TransformA; 14 | private Transform TransformB; 15 | 16 | private LineRenderer LineRenderer; 17 | 18 | /// 19 | /// Create line segment connecting two transforms and attached to a third 20 | /// 21 | /// Parent to hang the line segment off of 22 | /// Beginning endpoint of line segment 23 | /// Enging endpoint of line segment 24 | /// Width of the Unity LineRenderer 25 | /// Color of the line segment 26 | public static ConnectingLine Create(Transform parent, Transform transformA, Transform transformB, float width, Color color) 27 | { 28 | var gameObject = new GameObject("ConnectingLine"); 29 | gameObject.transform.parent = parent; 30 | var lineRenderer = gameObject.AddComponent(); 31 | Color startColor = color; 32 | Color endColor = Color.Lerp(color, Color.white - color, 0.5f); 33 | lineRenderer.startColor = startColor; 34 | lineRenderer.endColor = endColor; 35 | lineRenderer.startWidth = width; 36 | lineRenderer.endWidth = width; 37 | 38 | var lineMaterial = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply")); 39 | lineRenderer.material = lineMaterial; 40 | 41 | var res = gameObject.AddComponent(); 42 | res.LineRenderer = lineRenderer; 43 | res.TransformA = transformA; 44 | res.TransformB = transformB; 45 | return res; 46 | } 47 | 48 | /// 49 | /// Adjust line endpoints to linked transforms 50 | /// 51 | void Update() 52 | { 53 | LineRenderer.SetPosition(0, TransformA.position); 54 | LineRenderer.SetPosition(1, TransformB.position); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Null/SpongyAnchorNull.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Wrapper class for a no-op spatial, platform-free anchor. 10 | /// 11 | public class SpongyAnchorNull : SpongyAnchor 12 | { 13 | public static float TrackingStartDelayTime = 0.3f; 14 | 15 | private bool IsReliablyLocated 16 | { 17 | get 18 | { 19 | return true; 20 | } 21 | } 22 | 23 | /// 24 | /// Returns true if the anchor is reliably located. False might mean loss of tracking or not fully initialized. 25 | /// 26 | public override bool IsLocated 27 | { 28 | get 29 | { 30 | return IsReliablyLocated; 31 | } 32 | } 33 | 34 | public override Pose SpongyPose 35 | { 36 | get 37 | { 38 | return transform.GetGlobalPose(); 39 | } 40 | } 41 | 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// The ARReferencePoint (or later version ARAnchor) returned by mgr.AddReferencePoint() (later mgr.AddAnchor()) 49 | /// is a Unity component, attached (obviously) to a GameObject. 50 | /// So, an alternate (read better) way might be: 51 | /// AnchorManagerARF creates an ARReferencePoint(ARAnchor). 52 | /// It then adds a SpongyAnchorARF (while creating it with AddComponent) to the referencePoint's gameObject. 53 | /// SpongyAnchorARF then gets ref to referencePoint in Start (or Awake?) to implement IsLocated 54 | /// (and hopefully Save/Load later). 55 | /// There is a PROBLEM HERE: 56 | /// ARReferencePoints (ARAnchors) can't be destroyed via normal Unity destruction path. They must 57 | /// be explicitly destroyed via the ARReferencePointManager.RemoveReferencePoint(). 58 | /// The good news is that we are in control of the destruction of SpongyAnchors. So rather 59 | /// than destroying a SpongyAnchor by destroying its GameObject, as we do now (see AnchorManager.Reset() 60 | /// for example, plus other Destroy() calls in AnchorManager), we'll need a virtual specifically for 61 | /// destroying SpongyAnchors. 62 | /// 63 | 64 | // Start is called before the first frame update 65 | private void Start () 66 | { 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARCore/AnchorManagerARCore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | 8 | #if WLT_ARCORE_SDK_INCLUDED 9 | using GoogleARCore; 10 | #endif // WLT_ARCORE_SDK_INCLUDED 11 | 12 | // mafinc - installed Multiplayer HLAPI and Legacy Helpers for ARCore Examples, shouldn't need them when 13 | // ARCore Examples is pruned out. Actually, Legacy Helpers is still needed (for InstantPreview), but MHLAPI shouldn't be. 14 | 15 | namespace Microsoft.MixedReality.WorldLocking.Core 16 | { 17 | public class AnchorManagerARCore : AnchorManager 18 | { 19 | /// 20 | public override bool SupportsPersistence { get { return false; } } 21 | 22 | protected override float TrackingStartDelayTime { get { return SpongyAnchorARCore.TrackingStartDelayTime; } } 23 | 24 | public static AnchorManagerARCore TryCreate(IPlugin plugin, IHeadPoseTracker headTracker) 25 | { 26 | 27 | AnchorManagerARCore anchorManagerARCore = null; 28 | 29 | #if WLT_ARCORE_SDK_INCLUDED 30 | anchorManagerARCore = new AnchorManagerARCore(plugin, headTracker); 31 | #endif // WLT_ARCORE_SDK_INCLUDED 32 | 33 | return anchorManagerARCore; 34 | } 35 | 36 | /// 37 | /// Set up an anchor manager. 38 | /// 39 | /// The engine interface to update with the current anchor graph. 40 | private AnchorManagerARCore(IPlugin plugin, IHeadPoseTracker headTracker) 41 | : base(plugin, headTracker) 42 | { 43 | } 44 | 45 | protected override bool IsTracking() 46 | { 47 | #if WLT_ARCORE_SDK_INCLUDED 48 | return Session.Status == SessionStatus.Tracking; 49 | #else // WLT_ARCORE_SDK_INCLUDED 50 | return false; 51 | #endif // WLT_ARCORE_SDK_INCLUDED 52 | } 53 | 54 | protected override SpongyAnchor CreateAnchor(AnchorId id, Transform parent, Pose initialPose) 55 | { 56 | var newAnchorObject = new GameObject(id.FormatStr()); 57 | newAnchorObject.transform.parent = parent; 58 | newAnchorObject.transform.SetGlobalPose(initialPose); 59 | return newAnchorObject.AddComponent(); 60 | } 61 | 62 | protected override SpongyAnchor DestroyAnchor(AnchorId id, SpongyAnchor spongyAnchor) 63 | { 64 | if (spongyAnchor != null) 65 | { 66 | GameObject.Destroy(spongyAnchor.gameObject); 67 | } 68 | RemoveSpongyAnchorById(id); 69 | 70 | return null; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Models/Axis_LowPoly.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fa2d6dfe260b58469c737827cead8a5 3 | ModelImporter: 4 | serializedVersion: 23 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2100000: Axis 9 | 2300000: //RootNode 10 | 3300000: //RootNode 11 | 4300000: Axis 12 | externalObjects: {} 13 | materials: 14 | importMaterials: 1 15 | materialName: 0 16 | materialSearch: 1 17 | materialLocation: 1 18 | animations: 19 | legacyGenerateAnimations: 4 20 | bakeSimulation: 0 21 | resampleCurves: 1 22 | optimizeGameObjects: 0 23 | motionNodeName: 24 | rigImportErrors: 25 | rigImportWarnings: 26 | animationImportErrors: 27 | animationImportWarnings: 28 | animationRetargetingWarnings: 29 | animationDoRetargetingWarnings: 0 30 | importAnimatedCustomProperties: 0 31 | importConstraints: 0 32 | animationCompression: 1 33 | animationRotationError: 0.5 34 | animationPositionError: 0.5 35 | animationScaleError: 0.5 36 | animationWrapMode: 0 37 | extraExposedTransformPaths: [] 38 | extraUserProperties: [] 39 | clipAnimations: [] 40 | isReadable: 0 41 | meshes: 42 | lODScreenPercentages: [] 43 | globalScale: 1 44 | meshCompression: 0 45 | addColliders: 0 46 | useSRGBMaterialColor: 1 47 | importVisibility: 0 48 | importBlendShapes: 0 49 | importCameras: 0 50 | importLights: 0 51 | swapUVChannels: 0 52 | generateSecondaryUV: 0 53 | useFileUnits: 1 54 | optimizeMeshForGPU: 1 55 | keepQuads: 0 56 | weldVertices: 1 57 | preserveHierarchy: 0 58 | indexFormat: 0 59 | secondaryUVAngleDistortion: 8 60 | secondaryUVAreaDistortion: 15.000001 61 | secondaryUVHardAngle: 88 62 | secondaryUVPackMargin: 4 63 | useFileScale: 1 64 | previousCalculatedGlobalScale: 1 65 | hasPreviousCalculatedGlobalScale: 0 66 | tangentSpace: 67 | normalSmoothAngle: 60 68 | normalImportMode: 0 69 | tangentImportMode: 3 70 | normalCalculationMode: 4 71 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 72 | blendShapeNormalImportMode: 1 73 | normalSmoothingSource: 0 74 | importAnimation: 1 75 | copyAvatar: 0 76 | humanDescription: 77 | serializedVersion: 2 78 | human: [] 79 | skeleton: [] 80 | armTwist: 0.5 81 | foreArmTwist: 0.5 82 | upperLegTwist: 0.5 83 | legTwist: 0.5 84 | armStretch: 0.05 85 | legStretch: 0.05 86 | feetSpacing: 0 87 | rootMotionBoneName: 88 | hasTranslationDoF: 0 89 | hasExtraRoot: 0 90 | skeletonHasParents: 1 91 | lastHumanDescriptionAvatarSource: {instanceID: 0} 92 | animationType: 0 93 | humanoidOversampling: 1 94 | additionalBone: 0 95 | userData: 96 | assetBundleName: 97 | assetBundleVariant: 98 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SpacePinPercentageVisualizer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | using UnityEngine.UI; 8 | 9 | namespace Microsoft.MixedReality.WorldLocking.Tools 10 | { 11 | public class SpacePinPercentageVisualizer : MonoBehaviour 12 | { 13 | public Text percentageNumberText; 14 | public Outline percentageNumberTextOutline; 15 | 16 | [Header("Percentage Colors")] 17 | public Color lowPercentageColor; 18 | public Color middlePercentageColor; 19 | public Color highPercentageColor; 20 | 21 | [Header("Percentage Outline Colors")] 22 | public Color lowPercentageOutlineColor; 23 | public Color middlePercentageOutlineColor; 24 | public Color highPercentageOutlineColor; 25 | 26 | private Camera mainCamera = null; 27 | 28 | public void UpdatePercentage(float percentage) 29 | { 30 | if (percentageNumberText != null) 31 | { 32 | percentageNumberText.text = (Mathf.RoundToInt(percentage)).ToString() + "%"; 33 | 34 | float weight = percentage / 100.0f; 35 | UpdateColors(weight); 36 | } 37 | 38 | } 39 | 40 | public void SetVisibility(bool visibility) 41 | { 42 | if (percentageNumberText != null) 43 | { 44 | percentageNumberText.enabled = visibility; 45 | } 46 | } 47 | 48 | private void UpdateColors(float weight) 49 | { 50 | float lowWeight = Mathf.InverseLerp(0.5f, 0, weight); 51 | float middleWeight = 1 - (Mathf.Abs(0.5f - weight) * 2); 52 | float highWeight = Mathf.InverseLerp(0.5f, 1, weight); 53 | 54 | float sum = lowWeight + middleWeight + highWeight; 55 | 56 | lowWeight = lowWeight / sum; 57 | middleWeight = middleWeight / sum; 58 | highWeight = highWeight / sum; 59 | 60 | percentageNumberText.color = lowPercentageColor * lowWeight + middlePercentageColor * middleWeight + highPercentageColor * highWeight; 61 | percentageNumberTextOutline.effectColor = lowPercentageOutlineColor * lowWeight + middlePercentageOutlineColor * middleWeight + highPercentageOutlineColor * highWeight; 62 | } 63 | private void Awake() 64 | { 65 | mainCamera = Camera.main; 66 | SetVisibility(false); 67 | } 68 | 69 | private void Update() 70 | { 71 | if (mainCamera != null) 72 | { 73 | transform.LookAt(mainCamera.transform, Vector3.up); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ARCore/SpongyAnchorARCore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #define WLT_ARCORE_EXTRA_DEBUGGING 5 | 6 | #if WLT_DISABLE_LOGGING 7 | #undef WLT_ARCORE_EXTRA_DEBUGGING 8 | #endif // WLT_DISABLE_LOGGING 9 | 10 | using System.Collections; 11 | using System.Collections.Generic; 12 | using UnityEngine; 13 | 14 | #if WLT_ARCORE_SDK_INCLUDED 15 | using GoogleARCore; 16 | #endif // WLT_ARCORE_SDK_INCLUDED 17 | 18 | namespace Microsoft.MixedReality.WorldLocking.Core 19 | { 20 | public class SpongyAnchorARCore : SpongyAnchor 21 | { 22 | public static float TrackingStartDelayTime = 0.3f; 23 | 24 | private float lastNotLocatedTime = float.NegativeInfinity; 25 | 26 | #if WLT_ARCORE_SDK_INCLUDED 27 | private GoogleARCore.Anchor internalAnchor = null; 28 | #endif // WLT_ARCORE_SDK_INCLUDED 29 | 30 | /// 31 | /// Returns true if the anchor is reliably located. False might mean loss of tracking or not fully initialized. 32 | /// 33 | public override bool IsLocated => 34 | IsReliablyLocated && Time.unscaledTime > lastNotLocatedTime + TrackingStartDelayTime; 35 | 36 | private bool IsReliablyLocated 37 | { 38 | get 39 | { 40 | #if WLT_ARCORE_SDK_INCLUDED 41 | return internalAnchor != null && internalAnchor.TrackingState == GoogleARCore.TrackingState.Tracking; 42 | #else // WLT_ARCORE_SDK_INCLUDED 43 | return false; 44 | #endif // WLT_ARCORE_SDK_INCLUDED 45 | } 46 | } 47 | 48 | public override Pose SpongyPose 49 | { 50 | get 51 | { 52 | return transform.GetGlobalPose(); 53 | } 54 | } 55 | 56 | // Update is called once per frame 57 | private void Update() 58 | { 59 | if (!IsReliablyLocated) 60 | { 61 | lastNotLocatedTime = Time.unscaledTime; 62 | } 63 | #if WLT_ARCORE_SDK_INCLUDED 64 | else 65 | { 66 | Vector3 move = internalAnchor.transform.position - transform.position; 67 | #if WLT_ARCORE_EXTRA_DEBUGGING 68 | if (move.magnitude > 0.001f) 69 | { 70 | Debug.Log($"{name} Moving by {move.ToString("F3")}"); 71 | } 72 | #endif // WLT_ARCORE_EXTRA_DEBUGGING 73 | transform.SetGlobalPose(internalAnchor.transform.GetGlobalPose()); 74 | } 75 | #endif // WLT_ARCORE_SDK_INCLUDED 76 | } 77 | 78 | // Start is called before the first frame update 79 | private void Start() 80 | { 81 | #if WLT_ARCORE_SDK_INCLUDED 82 | internalAnchor = Session.CreateAnchor(transform.GetGlobalPose()); 83 | #endif // WLT_ARCORE_SDK_INCLUDED 84 | } 85 | 86 | } 87 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/DiagnosticsSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using UnityEngine; 8 | 9 | namespace Microsoft.MixedReality.WorldLocking.Core 10 | { 11 | /// 12 | /// Client tune-able settings for the diagnostics. Set through the WorldLockingManager. 13 | /// 14 | [System.Serializable] 15 | public struct DiagnosticsSettings 16 | { 17 | [SerializeField] 18 | [Tooltip("Ignore set values and use default behavior. When set, will reset all values to defaults.")] 19 | private bool useDefaults; 20 | /// 21 | /// Ignore set values and use default behavior. When set, will reset all values to defaults. 22 | /// 23 | public bool UseDefaults 24 | { 25 | get { return useDefaults; } 26 | set 27 | { 28 | useDefaults = value; 29 | if (useDefaults) 30 | { 31 | InitToDefaults(); 32 | } 33 | } 34 | } 35 | 36 | /// 37 | /// Diagnostics can be disabled if unneeded to reclaim any lost performance. 38 | /// 39 | [Tooltip("Diagnostics can be disabled if unneeded to reclaim any lost performance.")] 40 | public bool Enabled; 41 | 42 | /// 43 | /// Folder in which to keep diagnostics. 44 | /// 45 | [Tooltip("Folder in which to keep diagnostics.")] 46 | public string StorageSubdirectory; 47 | 48 | /// 49 | /// Base for auto-generated unique filename. 50 | /// 51 | [Tooltip("Base for auto-generated unique filename.")] 52 | public string StorageFileTemplate; 53 | 54 | /// 55 | /// Max file size. 56 | /// 57 | [Tooltip("Max file size.")] 58 | public int MaxKilobytesPerFile; 59 | 60 | /// 61 | /// Limit number of auto-generated files. 62 | /// 63 | [Tooltip("Limit number of auto-generated files.")] 64 | public int MaxNumberOfFiles; 65 | 66 | public DiagnosticsSettings InitToDefaults() 67 | { 68 | useDefaults = true; 69 | Enabled = false; 70 | StorageSubdirectory = "FrozenWorldDiagnostics"; 71 | StorageFileTemplate = "FrozenWorld-[Machine]-[Timestamp].hkfw"; 72 | MaxKilobytesPerFile = 2048; 73 | MaxNumberOfFiles = 64; 74 | return this; 75 | } 76 | } 77 | 78 | /// 79 | /// The SharedSettings boxes the Settings into a sharable reference. 80 | /// 81 | [System.Serializable] 82 | public class SharedDiagnosticsSettings 83 | { 84 | public DiagnosticsSettings settings; 85 | 86 | public SharedDiagnosticsSettings() 87 | { 88 | settings.InitToDefaults(); 89 | } 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerWeightMeshMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: DebugVisualizerWeightMeshMaterial 11 | m_Shader: {fileID: 209, guid: 0000000000000000f000000000000000, type: 0} 12 | m_Parent: {fileID: 0} 13 | m_ModifiedSerializedProperties: 0 14 | m_ValidKeywords: [] 15 | m_InvalidKeywords: [] 16 | m_LightmapFlags: 4 17 | m_EnableInstancingVariants: 0 18 | m_DoubleSidedGI: 0 19 | m_CustomRenderQueue: -1 20 | stringTagMap: {} 21 | disabledShaderPasses: [] 22 | m_LockedProperties: 23 | m_SavedProperties: 24 | serializedVersion: 3 25 | m_TexEnvs: 26 | - _BumpMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailAlbedoMap: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailMask: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DetailNormalMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _EmissionMap: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MainTex: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MetallicGlossMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _OcclusionMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _ParallaxMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | m_Ints: [] 63 | m_Floats: 64 | - _BlendOp: 0 65 | - _BumpScale: 1 66 | - _ColorWriteMask: 15 67 | - _CullMode: 2 68 | - _CustomMode: 0 69 | - _Cutoff: 0.5 70 | - _DetailNormalMapScale: 1 71 | - _DstBlend: 0 72 | - _GlossMapScale: 1 73 | - _Glossiness: 0.5 74 | - _GlossyReflections: 1 75 | - _InvFade: 1 76 | - _Metallic: 0 77 | - _Mode: 0 78 | - _OcclusionStrength: 1 79 | - _OutlineWidth: 0.1 80 | - _Parallax: 0.02 81 | - _RenderQueueOverride: -1 82 | - _SmoothnessTextureChannel: 0 83 | - _SpecularHighlights: 1 84 | - _SrcBlend: 1 85 | - _UVSec: 0 86 | - _Weight: 1 87 | - _WireThickness: 765 88 | - _ZOffsetFactor: 0 89 | - _ZOffsetUnits: 0 90 | - _ZTest: 4 91 | - _ZWrite: 1 92 | m_Colors: 93 | - _BaseColor: {r: 0.035716623, g: 0.019001435, b: 0.5754717, a: 1} 94 | - _Color: {r: 1, g: 1, b: 1, a: 1} 95 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 96 | - _Offset: {r: 0, g: 0, b: 0, a: 0} 97 | - _OutlineColor: {r: 1, g: 1, b: 1, a: 1} 98 | - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} 99 | - _VectorOffset: {r: 0, g: 0, b: 0, a: 0} 100 | - _WireColor: {r: 1, g: 1, b: 1, a: 1} 101 | m_BuildTextureStacks: [] 102 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IOrienter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Base class for a thing whose orientation can be inferred 10 | /// from the positions of a collection of IOrientables. 11 | /// 12 | public interface IOrientable 13 | { 14 | /// 15 | /// What fragment the object belongs in. Objects in different fragments don't affect each other. 16 | /// 17 | FragmentId FragmentId { get; } 18 | 19 | /// 20 | /// The position of the object in Modeling space. 21 | /// 22 | Vector3 ModelPosition { get; } 23 | 24 | /// 25 | /// The orientation of the object in Modeling space. 26 | /// 27 | Quaternion ModelRotation { get; } 28 | 29 | /// 30 | /// The desired position of the object in world locked space. 31 | /// 32 | Vector3 LockedPosition { get; } 33 | 34 | /// 35 | /// The desired rotation of the object in world locked space. 36 | /// 37 | Quaternion LockedRotation { get; } 38 | 39 | /// 40 | /// Accept a rotation computed externally (by an ). 41 | /// 42 | /// The Alignment Manager in charge. 43 | /// The rotation to apply, in world locked space. 44 | void PushRotation(IAlignmentManager mgr, Quaternion lockedRotation); 45 | } 46 | 47 | /// 48 | /// An object capable of computing self-consistent rotations for IOrientables based on their positions. 49 | /// 50 | public interface IOrienter 51 | { 52 | /// 53 | /// Optional subtree alignment manager. 54 | /// 55 | /// 56 | /// If unset, will use global alignment manager, ie WorldLockingManager.GetInstance().AlignmentManager. 57 | /// 58 | IAlignmentManager AlignmentManager { get; set; } 59 | 60 | /// 61 | /// Add this orientable to the list to be both source of rotation computation, and targets to apply the computed rotation. 62 | /// 63 | /// The object to start maintining the orientation of. 64 | void Register(IOrientable orientable); 65 | 66 | /// 67 | /// Stop managing orientation for this object, and release all references to it. 68 | /// 69 | /// The object to forget. 70 | void Unregister(IOrientable orientable); 71 | 72 | /// 73 | /// Compute a consistent orientation for all registered IOrientables in the given fragment. 74 | /// 75 | /// The fragment to selectively apply to. 76 | /// The manager governing the process. 77 | void Reorient(FragmentId fragmentId, IAlignmentManager mgr); 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/Null/AnchorManagerNull.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading.Tasks; 7 | using UnityEngine; 8 | 9 | namespace Microsoft.MixedReality.WorldLocking.Core 10 | { 11 | public class AnchorManagerNull : AnchorManager 12 | { 13 | /// 14 | public override bool SupportsPersistence { get { return false; } } 15 | 16 | protected override float TrackingStartDelayTime { get { return SpongyAnchorNull.TrackingStartDelayTime; } } 17 | 18 | public static AnchorManagerNull TryCreate(IPlugin plugin, IHeadPoseTracker headTracker) 19 | { 20 | AnchorManagerNull anchorManager = new AnchorManagerNull(plugin, headTracker); 21 | 22 | return anchorManager; 23 | } 24 | 25 | /// 26 | /// Set up an anchor manager. 27 | /// 28 | /// The engine interface to update with the current anchor graph. 29 | private AnchorManagerNull(IPlugin plugin, IHeadPoseTracker headTracker) 30 | : base(plugin, headTracker) 31 | { 32 | DebugLogSetup($"Null: Creating AnchorManagerNull"); 33 | } 34 | 35 | protected override bool IsTracking() 36 | { 37 | return true; 38 | } 39 | 40 | protected override SpongyAnchor CreateAnchor(AnchorId id, Transform parent, Pose initialPose) 41 | { 42 | var newAnchorObject = new GameObject(id.FormatStr()); 43 | newAnchorObject.transform.parent = parent; 44 | newAnchorObject.transform.SetGlobalPose(initialPose); 45 | return newAnchorObject.AddComponent(); 46 | } 47 | 48 | protected override SpongyAnchor DestroyAnchor(AnchorId id, SpongyAnchor spongyAnchor) 49 | { 50 | if (spongyAnchor != null) 51 | { 52 | GameObject.Destroy(spongyAnchor.gameObject); 53 | } 54 | RemoveSpongyAnchorById(id); 55 | 56 | return null; 57 | } 58 | 59 | protected override async Task SaveAnchors(List spongyAnchors) 60 | { 61 | await Task.CompletedTask; 62 | } 63 | 64 | 65 | /// 66 | /// Load the spongy anchors from persistent storage 67 | /// 68 | /// 69 | /// The set of spongy anchors loaded by this routine is defined by the frozen anchors 70 | /// previously loaded into the plugin. 71 | /// 72 | /// Likewise, when a spongy anchor fails to load, this routine will delete its frozen 73 | /// counterpart from the plugin. 74 | /// 75 | protected override async Task LoadAnchors(IPlugin plugin, AnchorId firstId, Transform parent, List spongyAnchors) 76 | { 77 | /// Placeholder for consistency. Persistence not implemented for Null, so 78 | /// to be consistent with this APIs contract, we must clear all frozen anchors from the plugin. 79 | plugin.ClearFrozenAnchors(); 80 | 81 | await Task.CompletedTask; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerWireframeMeshMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: DebugVisualizerWireframeMeshMaterial 11 | m_Shader: {fileID: 207, guid: 0000000000000000f000000000000000, type: 0} 12 | m_Parent: {fileID: 0} 13 | m_ModifiedSerializedProperties: 0 14 | m_ValidKeywords: [] 15 | m_InvalidKeywords: 16 | - _USECIRCULARVIGNETTE_ON 17 | - _USEOUTLINEANIMATION_ON 18 | m_LightmapFlags: 4 19 | m_EnableInstancingVariants: 0 20 | m_DoubleSidedGI: 0 21 | m_CustomRenderQueue: -1 22 | stringTagMap: {} 23 | disabledShaderPasses: [] 24 | m_LockedProperties: 25 | m_SavedProperties: 26 | serializedVersion: 3 27 | m_TexEnvs: 28 | - _BumpMap: 29 | m_Texture: {fileID: 0} 30 | m_Scale: {x: 1, y: 1} 31 | m_Offset: {x: 0, y: 0} 32 | - _DetailAlbedoMap: 33 | m_Texture: {fileID: 0} 34 | m_Scale: {x: 1, y: 1} 35 | m_Offset: {x: 0, y: 0} 36 | - _DetailMask: 37 | m_Texture: {fileID: 0} 38 | m_Scale: {x: 1, y: 1} 39 | m_Offset: {x: 0, y: 0} 40 | - _DetailNormalMap: 41 | m_Texture: {fileID: 0} 42 | m_Scale: {x: 1, y: 1} 43 | m_Offset: {x: 0, y: 0} 44 | - _EmissionMap: 45 | m_Texture: {fileID: 0} 46 | m_Scale: {x: 1, y: 1} 47 | m_Offset: {x: 0, y: 0} 48 | - _MainTex: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | - _MetallicGlossMap: 53 | m_Texture: {fileID: 0} 54 | m_Scale: {x: 1, y: 1} 55 | m_Offset: {x: 0, y: 0} 56 | - _OcclusionMap: 57 | m_Texture: {fileID: 0} 58 | m_Scale: {x: 1, y: 1} 59 | m_Offset: {x: 0, y: 0} 60 | - _ParallaxMap: 61 | m_Texture: {fileID: 0} 62 | m_Scale: {x: 1, y: 1} 63 | m_Offset: {x: 0, y: 0} 64 | m_Ints: [] 65 | m_Floats: 66 | - _BlendOp: 0 67 | - _BumpScale: 1 68 | - _ColorWriteMask: 15 69 | - _CullMode: 2 70 | - _CustomMode: 0 71 | - _Cutoff: 0.5 72 | - _DetailNormalMapScale: 1 73 | - _DstBlend: 0 74 | - _GlossMapScale: 1 75 | - _Glossiness: 0.5 76 | - _GlossyReflections: 1 77 | - _InvFade: 1 78 | - _Metallic: 0 79 | - _Mode: 0 80 | - _OcclusionStrength: 1 81 | - _OutlineWidth: 1 82 | - _Parallax: 0.02 83 | - _RenderQueueOverride: -1 84 | - _SmoothnessTextureChannel: 0 85 | - _SpecularHighlights: 1 86 | - _SrcBlend: 1 87 | - _UVSec: 0 88 | - _UseCircularVignette: 0 89 | - _UseOutlineAnimation: 0 90 | - _UsePositionMarker: 0 91 | - _Weight: 0.732 92 | - _WireThickness: 765 93 | - _ZOffsetFactor: 0 94 | - _ZOffsetUnits: 0 95 | - _ZTest: 4 96 | - _ZWrite: 1 97 | m_Colors: 98 | - _BaseColor: {r: 0.035716623, g: 0.019001435, b: 0.5754717, a: 1} 99 | - _Color: {r: 1, g: 1, b: 1, a: 1} 100 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 101 | - _HeadSetWorldPosition: {r: 0, g: 0, b: 0, a: 0} 102 | - _MainColor: {r: 1, g: 1, b: 1, a: 0} 103 | - _OutlineColor: {r: 0, g: 0.9021225, b: 1, a: 1} 104 | - _VectorOffset: {r: 0, g: 0, b: 0, a: 0} 105 | - _WireColor: {r: 1, g: 1, b: 1, a: 1} 106 | m_BuildTextureStacks: [] 107 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerExtrapolatedMeshMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: DebugVisualizerExtrapolatedMeshMaterial 11 | m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0} 12 | m_Parent: {fileID: 0} 13 | m_ModifiedSerializedProperties: 0 14 | m_ValidKeywords: [] 15 | m_InvalidKeywords: 16 | - _USECIRCULARVIGNETTE_ON 17 | m_LightmapFlags: 4 18 | m_EnableInstancingVariants: 0 19 | m_DoubleSidedGI: 0 20 | m_CustomRenderQueue: -1 21 | stringTagMap: {} 22 | disabledShaderPasses: [] 23 | m_LockedProperties: 24 | m_SavedProperties: 25 | serializedVersion: 3 26 | m_TexEnvs: 27 | - _BumpMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailAlbedoMap: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailMask: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _DetailNormalMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _EmissionMap: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MainTex: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _MetallicGlossMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _OcclusionMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | - _ParallaxMap: 60 | m_Texture: {fileID: 0} 61 | m_Scale: {x: 1, y: 1} 62 | m_Offset: {x: 0, y: 0} 63 | m_Ints: [] 64 | m_Floats: 65 | - _BlendOp: 0 66 | - _BumpScale: 1 67 | - _ColorWriteMask: 15 68 | - _CullMode: 2 69 | - _CustomMode: 0 70 | - _Cutoff: 0.5 71 | - _DetailNormalMapScale: 1 72 | - _DstBlend: 0 73 | - _GlossMapScale: 1 74 | - _Glossiness: 0.5 75 | - _GlossyReflections: 1 76 | - _InvFade: 1 77 | - _Metallic: 0 78 | - _Mode: 0 79 | - _OcclusionStrength: 1 80 | - _OutlineWidth: 1 81 | - _Parallax: 0.02 82 | - _RenderQueueOverride: -1 83 | - _SmoothnessTextureChannel: 0 84 | - _SpecularHighlights: 1 85 | - _SrcBlend: 1 86 | - _UVSec: 0 87 | - _UseCircularVignette: 0 88 | - _UseOutlineAnimation: 0 89 | - _UsePositionMarker: 0 90 | - _Weight: 0.732 91 | - _WireThickness: 765 92 | - _ZOffsetFactor: 0 93 | - _ZOffsetUnits: 0 94 | - _ZTest: 4 95 | - _ZWrite: 1 96 | m_Colors: 97 | - _BaseColor: {r: 0.035716623, g: 0.019001435, b: 0.5754717, a: 1} 98 | - _Color: {r: 1, g: 1, b: 1, a: 1} 99 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 100 | - _HeadSetWorldPosition: {r: 0, g: 0, b: 0, a: 0} 101 | - _MainColor: {r: 1, g: 0.6153064, b: 0, a: 0} 102 | - _OutlineColor: {r: 1, g: 0.45229974, b: 0, a: 1} 103 | - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} 104 | - _VectorOffset: {r: 0, g: 0, b: 0, a: 0} 105 | - _WireColor: {r: 1, g: 1, b: 1, a: 1} 106 | m_BuildTextureStacks: [] 107 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/DebugVisualizerMeshMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: DebugVisualizerMeshMaterial 11 | m_Shader: {fileID: 207, guid: 0000000000000000f000000000000000, type: 0} 12 | m_Parent: {fileID: 0} 13 | m_ModifiedSerializedProperties: 0 14 | m_ValidKeywords: [] 15 | m_InvalidKeywords: 16 | - SHADER_FEATURE_UsePositionMarker 17 | - _USEPOSITIONMARKER_ON 18 | m_LightmapFlags: 4 19 | m_EnableInstancingVariants: 0 20 | m_DoubleSidedGI: 0 21 | m_CustomRenderQueue: -1 22 | stringTagMap: {} 23 | disabledShaderPasses: [] 24 | m_LockedProperties: 25 | m_SavedProperties: 26 | serializedVersion: 3 27 | m_TexEnvs: 28 | - _BumpMap: 29 | m_Texture: {fileID: 0} 30 | m_Scale: {x: 1, y: 1} 31 | m_Offset: {x: 0, y: 0} 32 | - _Detail: 33 | m_Texture: {fileID: 0} 34 | m_Scale: {x: 1, y: 1} 35 | m_Offset: {x: 0, y: 0} 36 | - _DetailAlbedoMap: 37 | m_Texture: {fileID: 0} 38 | m_Scale: {x: 1, y: 1} 39 | m_Offset: {x: 0, y: 0} 40 | - _DetailMask: 41 | m_Texture: {fileID: 0} 42 | m_Scale: {x: 1, y: 1} 43 | m_Offset: {x: 0, y: 0} 44 | - _DetailNormalMap: 45 | m_Texture: {fileID: 0} 46 | m_Scale: {x: 1, y: 1} 47 | m_Offset: {x: 0, y: 0} 48 | - _EmissionMap: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | - _MainTex: 53 | m_Texture: {fileID: 0} 54 | m_Scale: {x: 1, y: 1} 55 | m_Offset: {x: 0, y: 0} 56 | - _MetallicGlossMap: 57 | m_Texture: {fileID: 0} 58 | m_Scale: {x: 1, y: 1} 59 | m_Offset: {x: 0, y: 0} 60 | - _OcclusionMap: 61 | m_Texture: {fileID: 0} 62 | m_Scale: {x: 1, y: 1} 63 | m_Offset: {x: 0, y: 0} 64 | - _ParallaxMap: 65 | m_Texture: {fileID: 0} 66 | m_Scale: {x: 1, y: 1} 67 | m_Offset: {x: 0, y: 0} 68 | m_Ints: [] 69 | m_Floats: 70 | - _BlendOp: 0 71 | - _BumpScale: 1 72 | - _ColorWriteMask: 15 73 | - _CullMode: 2 74 | - _CustomMode: 0 75 | - _Cutoff: 0.5 76 | - _DetailNormalMapScale: 1 77 | - _DstBlend: 0 78 | - _GlossMapScale: 1 79 | - _Glossiness: 0.5 80 | - _GlossyReflections: 1 81 | - _InvFade: 1 82 | - _Metallic: 0 83 | - _Mode: 0 84 | - _OcclusionStrength: 1 85 | - _OutlineWidth: 1.25 86 | - _Parallax: 0.02 87 | - _RenderQueueOverride: -1 88 | - _SmoothnessTextureChannel: 0 89 | - _SpecularHighlights: 1 90 | - _SrcBlend: 1 91 | - _UVSec: 0 92 | - _UseCircularVignette: 0 93 | - _UseOutlineAnimation: 0 94 | - _UsePositionMarker: 1 95 | - _Weight: 0.732 96 | - _WireThickness: 765 97 | - _ZOffsetFactor: 0 98 | - _ZOffsetUnits: 0 99 | - _ZTest: 4 100 | - _ZWrite: 1 101 | m_Colors: 102 | - _BaseColor: {r: 0.035716623, g: 0.019001435, b: 0.5754717, a: 1} 103 | - _Color: {r: 1, g: 1, b: 1, a: 1} 104 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 105 | - _HeadSetWorldPosition: {r: 0, g: 0, b: 0, a: 0} 106 | - _MainColor: {r: 0.2783019, g: 0.88396233, b: 1, a: 0} 107 | - _OutlineColor: {r: 1, g: 1, b: 1, a: 1} 108 | - _VectorOffset: {r: 0, g: 0, b: 0, a: 0} 109 | - _WireColor: {r: 1, g: 1, b: 1, a: 1} 110 | m_BuildTextureStacks: [] 111 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Models/Arrow.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d1275d23e72ae44b96ad5db1d91ad17 3 | ModelImporter: 4 | serializedVersion: 22200 5 | internalIDToNameTable: 6 | - first: 7 | 1: 100000 8 | second: //RootNode 9 | - first: 10 | 4: 400000 11 | second: //RootNode 12 | - first: 13 | 21: 2100000 14 | second: TeleportMarker 15 | - first: 16 | 23: 2300000 17 | second: //RootNode 18 | - first: 19 | 33: 3300000 20 | second: //RootNode 21 | - first: 22 | 43: 4300000 23 | second: Arrow 24 | externalObjects: {} 25 | materials: 26 | materialImportMode: 1 27 | materialName: 0 28 | materialSearch: 1 29 | materialLocation: 1 30 | animations: 31 | legacyGenerateAnimations: 4 32 | bakeSimulation: 0 33 | resampleCurves: 1 34 | optimizeGameObjects: 0 35 | removeConstantScaleCurves: 0 36 | motionNodeName: 37 | rigImportErrors: 38 | rigImportWarnings: 39 | animationImportErrors: 40 | animationImportWarnings: 41 | animationRetargetingWarnings: 42 | animationDoRetargetingWarnings: 0 43 | importAnimatedCustomProperties: 0 44 | importConstraints: 0 45 | animationCompression: 1 46 | animationRotationError: 0.5 47 | animationPositionError: 0.5 48 | animationScaleError: 0.5 49 | animationWrapMode: 0 50 | extraExposedTransformPaths: [] 51 | extraUserProperties: [] 52 | clipAnimations: [] 53 | isReadable: 1 54 | meshes: 55 | lODScreenPercentages: [] 56 | globalScale: 1 57 | meshCompression: 0 58 | addColliders: 0 59 | useSRGBMaterialColor: 1 60 | sortHierarchyByName: 1 61 | importVisibility: 1 62 | importBlendShapes: 1 63 | importCameras: 1 64 | importLights: 1 65 | nodeNameCollisionStrategy: 0 66 | fileIdsGeneration: 1 67 | swapUVChannels: 0 68 | generateSecondaryUV: 0 69 | useFileUnits: 1 70 | keepQuads: 0 71 | weldVertices: 1 72 | bakeAxisConversion: 0 73 | preserveHierarchy: 0 74 | skinWeightsMode: 0 75 | maxBonesPerVertex: 4 76 | minBoneWeight: 0.001 77 | optimizeBones: 1 78 | meshOptimizationFlags: -1 79 | indexFormat: 0 80 | secondaryUVAngleDistortion: 8 81 | secondaryUVAreaDistortion: 15.000001 82 | secondaryUVHardAngle: 88 83 | secondaryUVMarginMethod: 0 84 | secondaryUVMinLightmapResolution: 40 85 | secondaryUVMinObjectScale: 1 86 | secondaryUVPackMargin: 4 87 | useFileScale: 1 88 | strictVertexDataChecks: 0 89 | tangentSpace: 90 | normalSmoothAngle: 60 91 | normalImportMode: 0 92 | tangentImportMode: 3 93 | normalCalculationMode: 4 94 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 95 | blendShapeNormalImportMode: 1 96 | normalSmoothingSource: 0 97 | referencedClips: [] 98 | importAnimation: 1 99 | humanDescription: 100 | serializedVersion: 3 101 | human: [] 102 | skeleton: [] 103 | armTwist: 0.5 104 | foreArmTwist: 0.5 105 | upperLegTwist: 0.5 106 | legTwist: 0.5 107 | armStretch: 0.05 108 | legStretch: 0.05 109 | feetSpacing: 0 110 | globalScale: 1 111 | rootMotionBoneName: 112 | hasTranslationDoF: 0 113 | hasExtraRoot: 0 114 | skeletonHasParents: 1 115 | lastHumanDescriptionAvatarSource: {instanceID: 0} 116 | autoGenerateAvatarMappingIfUnspecified: 1 117 | animationType: 0 118 | humanoidOversampling: 1 119 | avatarSetup: 0 120 | addHumanoidExtraRootOnlyWhenUsingAvatar: 0 121 | importBlendShapeDeformPercent: 0 122 | remapMaterialsIfMaterialImportModeIsNone: 1 123 | additionalBone: 0 124 | userData: 125 | assetBundleName: 126 | assetBundleVariant: 127 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Models/Ring_LowPoly.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d8f5794256f0584fafffb9214e10f63 3 | ModelImporter: 4 | serializedVersion: 22200 5 | internalIDToNameTable: 6 | - first: 7 | 1: 100000 8 | second: //RootNode 9 | - first: 10 | 4: 400000 11 | second: //RootNode 12 | - first: 13 | 21: 2100000 14 | second: Ring 15 | - first: 16 | 23: 2300000 17 | second: //RootNode 18 | - first: 19 | 33: 3300000 20 | second: //RootNode 21 | - first: 22 | 43: 4300000 23 | second: Ring 24 | externalObjects: {} 25 | materials: 26 | materialImportMode: 1 27 | materialName: 0 28 | materialSearch: 1 29 | materialLocation: 1 30 | animations: 31 | legacyGenerateAnimations: 4 32 | bakeSimulation: 0 33 | resampleCurves: 1 34 | optimizeGameObjects: 0 35 | removeConstantScaleCurves: 0 36 | motionNodeName: 37 | rigImportErrors: 38 | rigImportWarnings: 39 | animationImportErrors: 40 | animationImportWarnings: 41 | animationRetargetingWarnings: 42 | animationDoRetargetingWarnings: 0 43 | importAnimatedCustomProperties: 0 44 | importConstraints: 0 45 | animationCompression: 1 46 | animationRotationError: 0.5 47 | animationPositionError: 0.5 48 | animationScaleError: 0.5 49 | animationWrapMode: 0 50 | extraExposedTransformPaths: [] 51 | extraUserProperties: [] 52 | clipAnimations: [] 53 | isReadable: 1 54 | meshes: 55 | lODScreenPercentages: [] 56 | globalScale: 1 57 | meshCompression: 0 58 | addColliders: 0 59 | useSRGBMaterialColor: 1 60 | sortHierarchyByName: 1 61 | importVisibility: 0 62 | importBlendShapes: 0 63 | importCameras: 0 64 | importLights: 0 65 | nodeNameCollisionStrategy: 0 66 | fileIdsGeneration: 1 67 | swapUVChannels: 0 68 | generateSecondaryUV: 0 69 | useFileUnits: 1 70 | keepQuads: 0 71 | weldVertices: 1 72 | bakeAxisConversion: 0 73 | preserveHierarchy: 0 74 | skinWeightsMode: 0 75 | maxBonesPerVertex: 4 76 | minBoneWeight: 0.001 77 | optimizeBones: 1 78 | meshOptimizationFlags: -1 79 | indexFormat: 0 80 | secondaryUVAngleDistortion: 8 81 | secondaryUVAreaDistortion: 15.000001 82 | secondaryUVHardAngle: 88 83 | secondaryUVMarginMethod: 0 84 | secondaryUVMinLightmapResolution: 40 85 | secondaryUVMinObjectScale: 1 86 | secondaryUVPackMargin: 4 87 | useFileScale: 1 88 | strictVertexDataChecks: 0 89 | tangentSpace: 90 | normalSmoothAngle: 60 91 | normalImportMode: 0 92 | tangentImportMode: 3 93 | normalCalculationMode: 4 94 | legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 95 | blendShapeNormalImportMode: 1 96 | normalSmoothingSource: 0 97 | referencedClips: [] 98 | importAnimation: 1 99 | humanDescription: 100 | serializedVersion: 3 101 | human: [] 102 | skeleton: [] 103 | armTwist: 0.5 104 | foreArmTwist: 0.5 105 | upperLegTwist: 0.5 106 | legTwist: 0.5 107 | armStretch: 0.05 108 | legStretch: 0.05 109 | feetSpacing: 0 110 | globalScale: 1 111 | rootMotionBoneName: 112 | hasTranslationDoF: 0 113 | hasExtraRoot: 0 114 | skeletonHasParents: 1 115 | lastHumanDescriptionAvatarSource: {instanceID: 0} 116 | autoGenerateAvatarMappingIfUnspecified: 1 117 | animationType: 0 118 | humanoidOversampling: 1 119 | avatarSetup: 0 120 | addHumanoidExtraRootOnlyWhenUsingAvatar: 0 121 | importBlendShapeDeformPercent: 0 122 | remapMaterialsIfMaterialImportModeIsNone: 1 123 | additionalBone: 0 124 | userData: 125 | assetBundleName: 126 | assetBundleVariant: 127 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAnchorManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Create and persist a network of anchors around the camera as it moves around, 10 | /// and feed them into the plugin. 11 | /// 12 | public interface IAnchorManager : System.IDisposable 13 | { 14 | /// 15 | /// Whether the underlying anchors can be locally persisted and reloaded. 16 | /// 17 | bool SupportsPersistence { get; } 18 | 19 | /// 20 | /// Return the current number of spongy anchors. 21 | /// 22 | /// 23 | /// The number of anchors known to AnchorManager should always be identical to the 24 | /// frozen anchors known to the engine. 25 | /// 26 | int NumAnchors { get; } 27 | 28 | /// 29 | /// The number of edges connecting spongy anchors. 30 | /// 31 | int NumEdges { get; } 32 | 33 | /// 34 | /// Error string for last error, cleared at beginning of each update. 35 | /// 36 | string ErrorStatus { get; } 37 | 38 | /// 39 | /// Minimum distance of head to nearest anchor to create a new anchor. 40 | /// 41 | float MinNewAnchorDistance { get; set; } 42 | 43 | /// 44 | /// Maximum distance between two anchors to create an edge between them. 45 | /// 46 | /// 47 | /// Note that the MaxAnchorEdgeLength should be longer than the MinAnchorDistance, 48 | /// or else anchors will not be connected into a graph as they are created. 49 | /// 50 | float MaxAnchorEdgeLength { get; set; } 51 | 52 | /// 53 | /// Maximum number of local anchors in the internal anchor graph. 54 | /// 55 | /// 56 | /// Zero or negative means unlimited anchors. 57 | /// 58 | int MaxLocalAnchors { get; set; } 59 | 60 | /// 61 | /// Get the transform from spongy space to the space anchors are located in. 62 | /// 63 | /// 64 | /// This varies according to the design of the underlying platform anchor subsystem. 65 | /// It may also vary over time (so don't cache this). 66 | /// 67 | UnityEngine.Pose AnchorFromSpongy { get; } 68 | 69 | /// 70 | /// Delete all spongy anchor objects and reset internal state 71 | /// 72 | void Reset(); 73 | 74 | /// 75 | /// Create any needed anchors/edges and update plugin 76 | /// 77 | /// Whether any anchors are active and were updated. 78 | bool Update(); 79 | 80 | /// 81 | /// Save the spongy anchors to persistent storage 82 | /// 83 | Task SaveAnchors(); 84 | 85 | /// 86 | /// Load the spongy anchors from persistent storage 87 | /// 88 | /// 89 | /// The set of spongy anchors loaded by this routine is defined by the frozen anchors 90 | /// previously loaded into the plugin. 91 | /// 92 | /// Likewise, when a spongy anchor fails to load, this routine will delete its frozen 93 | /// counterpart from the plugin. 94 | /// 95 | Task LoadAnchors(); 96 | 97 | } 98 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WorldLockingContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using UnityEngine; 6 | using UnityEngine.SceneManagement; 7 | 8 | namespace Microsoft.MixedReality.WorldLocking.Core 9 | { 10 | /// 11 | /// The central component for providing WorldLocking functionality to a scene 12 | /// 13 | /// 14 | /// This component must be placed on a single GameObject in the scene. Typically, this would be a dedicated root GameObject with 15 | /// identity transform. 16 | /// 17 | public class WorldLockingContext : MonoBehaviour { 18 | 19 | #region Public properties 20 | /// 21 | /// Hide settings in inspector, because they are published via custom editor. 22 | /// 23 | [HideInInspector] 24 | [SerializeField] 25 | private SharedManagerSettings shared = new SharedManagerSettings(); 26 | 27 | /// 28 | /// WorldLocking settings. These are shared with the manager when active. Changes from script 29 | /// should be made through the manager's interface, but will be visible here in inspector. 30 | /// 31 | public SharedManagerSettings SharedSettings => shared; 32 | 33 | /// 34 | /// Hide settings in inspector, because they are published via custom editor. 35 | /// 36 | [HideInInspector] 37 | [SerializeField] 38 | private SharedDiagnosticsSettings diagnosticsSettings = new SharedDiagnosticsSettings(); 39 | 40 | /// 41 | /// Diagnostics settings. These are shared with the manager when active. Changes from script 42 | /// should be made through the manager's interface, but will be visible here in inspector. 43 | /// 44 | public SharedDiagnosticsSettings DiagnosticsSettings => diagnosticsSettings; 45 | #endregion 46 | 47 | 48 | #region Unity internals 49 | /// 50 | /// Register for active scene change notifications. 51 | /// Also, if the current scene is this's scene, push settings. 52 | /// 53 | private void OnEnable() 54 | { 55 | SceneManager.activeSceneChanged += OnActiveSceneChanged; 56 | CheckPushSettings(SceneManager.GetActiveScene()); 57 | } 58 | 59 | /// 60 | /// On disable, unregister for notifications. 61 | /// 62 | private void OnDisable() 63 | { 64 | SceneManager.activeSceneChanged -= OnActiveSceneChanged; 65 | } 66 | 67 | #endregion Unity internals 68 | 69 | #region Callback on scene change 70 | /// 71 | /// Callback for when the active scene changes. If the new scene will be the 72 | /// scene belonging to this, push contained settings. Otherwise ignore. 73 | /// 74 | /// 75 | /// 76 | private void OnActiveSceneChanged(Scene current, Scene next) 77 | { 78 | CheckPushSettings(next); 79 | } 80 | 81 | /// 82 | /// Push contained settings if the input scene matches this's scene. 83 | /// 84 | /// 85 | private void CheckPushSettings(Scene scene) 86 | { 87 | if (scene == this.gameObject.scene) 88 | { 89 | WorldLockingManager manager = WorldLockingManager.GetInstance(); 90 | manager.SetContext(this); 91 | } 92 | } 93 | #endregion Callback on scene change 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IFragmentManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | namespace Microsoft.MixedReality.WorldLocking.Core 5 | { 6 | /// 7 | /// Interface for managing fragments. This mostly comprises the bookkeeping of managing 8 | /// associations, and the intimately related application of refit operations. 9 | /// 10 | public interface IFragmentManager 11 | { 12 | /// 13 | /// Current number of fragments. 14 | /// 15 | int NumFragments { get; } 16 | 17 | /// 18 | /// Get id of currently active fragment 19 | /// 20 | FragmentId CurrentFragmentId { get; } 21 | 22 | /// 23 | /// Return a copy of the current list of fragment ids. 24 | /// 25 | FragmentId[] FragmentIds { get; } 26 | 27 | /// 28 | /// Get the current state of a given fragment. 29 | /// 30 | /// Identifier of the fragment to query. 31 | /// The state 32 | AttachmentPointStateType GetFragmentState(FragmentId id); 33 | 34 | /// 35 | /// Notify all fragments of their current state. 36 | /// 37 | void ApplyActiveCurrentFragment(); 38 | 39 | /// 40 | /// Register a delegate for refit notifications. 41 | /// 42 | /// The delegate to call. 43 | void RegisterForRefitNotifications(RefitNotificationDelegate del); 44 | 45 | /// 46 | /// Unregister a previously registered delegate for refit notifications. 47 | /// 48 | /// The delegate to unregister. 49 | void UnregisterForRefitNotifications(RefitNotificationDelegate del); 50 | 51 | /// 52 | /// Perform any pending refit operations and reconcile state accordingly. 53 | /// 54 | /// True to automatically perform a refreeze if indicated by the plugin. 55 | /// True to automatically perform a merge if indicated by the plugin. 56 | void Update(bool autoRefreeze, bool autoMerge); 57 | 58 | /// 59 | /// Set all fragments unconnected during a temporary system outage, especially 60 | /// while tracking is lost. 61 | /// 62 | /// 63 | /// Fragments to resume as they were on next update. Pause may be called multiple 64 | /// consecutive frames, as long as the system outage continues, but only Pause or 65 | /// Update should be called on a given frame. 66 | /// 67 | void Pause(); 68 | 69 | /// 70 | /// Clear all internal state and resources. 71 | /// 72 | void Reset(); 73 | 74 | /// 75 | /// Call on the plugin to compute the merge, then apply by 76 | /// setting transforms and adjusting scene graph. 77 | /// 78 | /// True for successful merge. 79 | /// 80 | /// It is unnecessary to manually merge if autoMerge is true with Update() 81 | /// 82 | bool Merge(); 83 | 84 | /// 85 | /// Manually invoke a refreeze operation on the plugin, and make all necessary adjustments 86 | /// in bookkeeping after. 87 | /// 88 | /// True for successful refreeze. 89 | /// 90 | /// It is unnecessary to manually refreeze if autoRefreeze is true with Update() 91 | /// 92 | bool Refreeze(); 93 | 94 | } 95 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/FrozenTapToAdd.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #pragma warning disable CS0618 5 | 6 | #if UNITY_WSA && !UNITY_2020_1_OR_NEWER 7 | #define WLT_ENABLE_LEGACY_WSA 8 | #endif 9 | 10 | using UnityEngine; 11 | #if WLT_ENABLE_LEGACY_WSA 12 | using UnityEngine.XR.WSA.Input; 13 | #endif // WLT_ENABLE_LEGACY_WSA 14 | 15 | using Microsoft.MixedReality.WorldLocking.Core; 16 | 17 | namespace Microsoft.MixedReality.WorldLocking.Tools 18 | { 19 | /// 20 | /// Simple class to adapt Unity's input results from spongy space into frozen space. 21 | /// This is unnecessary when using MRTK's input system, which already provides this 22 | /// and other enhancements and abstactions. 23 | /// 24 | public class FrozenTapToAdd : MonoBehaviour 25 | { 26 | [SerializeField] 27 | [Tooltip("The prefab to place in the world at gaze position on air taps.")] 28 | private GameObject prefabToPlace = null; 29 | /// 30 | /// The prefab to place in the world at gaze position on air taps. 31 | /// 32 | public GameObject PrefabToPlace => prefabToPlace; 33 | 34 | /// 35 | /// Enable and disable processing of tap events. 36 | /// 37 | public bool Active { get; set; } 38 | 39 | #if WLT_ENABLE_LEGACY_WSA 40 | private GestureRecognizer gestureRecognizer; 41 | #endif // WLT_ENABLE_LEGACY_WSA 42 | 43 | private WorldLockingManager manager { get { return WorldLockingManager.GetInstance(); } } 44 | 45 | // Start is called before the first frame update 46 | private void Start() 47 | { 48 | #if WLT_ENABLE_LEGACY_WSA 49 | gestureRecognizer = new GestureRecognizer(); 50 | gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap); 51 | 52 | gestureRecognizer.Tapped += HandleTapped; 53 | 54 | gestureRecognizer.StartCapturingGestures(); 55 | #endif // WLT_ENABLE_LEGACY_WSA 56 | } 57 | 58 | #if WLT_ENABLE_LEGACY_WSA 59 | private void HandleTapped(TappedEventArgs eventArgs) 60 | { 61 | 62 | if (Active && PrefabToPlace != null) 63 | { 64 | // The tap event happens in Spongy space, so any arguments 65 | // from it are in spongy space and need to be converted to frozen space, 66 | // because the ray tests are done in frozen space. 67 | var spongyHeadPose = eventArgs.headPose; 68 | var frozenHeadPose = manager.FrozenFromSpongy.Multiply(spongyHeadPose); 69 | 70 | var rayStart = frozenHeadPose.position; 71 | var rayDir = frozenHeadPose.forward; 72 | 73 | int ignoreRaycastLayer = Physics.IgnoreRaycastLayer; 74 | int hitLayers = ~(ignoreRaycastLayer); 75 | RaycastHit hitInfo; 76 | if (Physics.Raycast(rayStart, rayDir, out hitInfo, Mathf.Infinity, hitLayers)) 77 | { 78 | int uiLayer = LayerMask.GetMask("UI"); 79 | if (hitInfo.collider == null || ((1 << hitInfo.collider.gameObject.layer) & uiLayer) == 0) 80 | { 81 | var hitPos = hitInfo.point; 82 | var hitUp = hitInfo.normal; 83 | var toRay = rayStart - hitPos; 84 | var hitDirProj = toRay - Vector3.Dot(toRay, hitInfo.normal) * hitInfo.normal / hitInfo.normal.sqrMagnitude; 85 | var hitRot = Quaternion.LookRotation(hitDirProj, hitUp); 86 | 87 | var newObj = GameObject.Instantiate(PrefabToPlace, hitPos, hitRot, transform); 88 | 89 | newObj.AddComponent(); 90 | } 91 | } 92 | } 93 | } 94 | #endif // WLT_ENABLE_LEGACY_WSA 95 | } 96 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/PoseExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | /// 7 | /// UnityEngine.Pose is a lightweight class value expressing a mathematical transform (position & rotation) 8 | /// 9 | /// (Unlike the Unity Transform, a component that always belongs to a GameObject and also expresses a the 10 | /// parent-child relation within a hierarchy) 11 | /// 12 | /// This file defines Extension Methods 13 | /// (see https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods) 14 | /// for missing operations and assignments on that class. 15 | /// 16 | /// The syntax is suboptimal Extension Methods do not support properties and operators. Ultimately, the best solution would be 17 | /// to define these operations within the Unity code itself where proper syntax could be achieved. 18 | /// 19 | 20 | namespace Microsoft.MixedReality.WorldLocking.Core 21 | { 22 | 23 | /// 24 | /// Conversion function between a pose and a transform. 25 | /// 26 | public static class TransformExtensions 27 | { 28 | public static Pose GetLocalPose(this Transform transform) 29 | { 30 | return new Pose(transform.localPosition, transform.localRotation); 31 | } 32 | 33 | public static Pose GetGlobalPose(this Transform transform) 34 | { 35 | return new Pose(transform.position, transform.rotation); 36 | } 37 | 38 | public static void SetLocalPose(this Transform transform, Pose pose) 39 | { 40 | transform.localPosition = pose.position; 41 | transform.localRotation = pose.rotation; 42 | } 43 | 44 | public static void SetGlobalPose(this Transform transform, Pose pose) 45 | { 46 | transform.position = pose.position; 47 | transform.rotation = pose.rotation; 48 | } 49 | } 50 | 51 | /// 52 | /// Extensions for Poses to enable basic transform math. 53 | /// 54 | public static class PoseExtensions 55 | { 56 | /* 57 | * application of a transform on a position, defined such that: 58 | * transform.position == FromGlobal(parent.transform) * localPosition 59 | */ 60 | public static Vector3 Multiply(this Pose pose, Vector3 position) 61 | { 62 | return pose.position + pose.rotation * position; 63 | } 64 | 65 | /* 66 | * chaining of transforms, defined such that 67 | * V' = lhs * (rhs * V) 68 | * = (lhs.pos,lhs.rot) * (rhs.pos + rhs.rot * V) 69 | * = lhs.pos + lhs.rot * (rhs.pos + rhs.rot * V) 70 | * = lhs.pos + lhs.rot * rhs.pos + lhs.rot * rhs.rot * V 71 | * = (lhs.pos + lhs.rot * rhs.pos , lhs.rot * rhs.rot) * V 72 | * = (lhs * rhs) * V 73 | */ 74 | 75 | public static Pose Multiply(this Pose lhs, Pose rhs) 76 | { 77 | return new Pose(lhs.position + lhs.rotation * rhs.position, lhs.rotation * rhs.rotation); 78 | } 79 | 80 | /* 81 | * inverse of transform, defined such that 82 | * 1 == inv(t) * t == t * inv(t) 83 | * 84 | * inv(t) * t 85 | * = (-inv(t.rot)*t.pos , inv(t.rot)) * (t.pos, t.rot) 86 | * = (-inv(t.rot)*t.pos + inv(t.rot) * t.pos , inv(t.rot) * t.rot) 87 | * = 1 88 | * 89 | * t * inv(t) 90 | * = (t.pos, t.rot) * (-inv(t.rot)*t.pos , inv(t.rot)) 91 | * = (t.pos + t.rot * (-inv(t.rot)*t.pos) , t.rot * inv(t.rot)) 92 | * = 1 93 | */ 94 | public static Pose Inverse(this Pose t) 95 | { 96 | var inv_t_rotation = Quaternion.Inverse(t.rotation); 97 | return new Pose(-(inv_t_rotation * t.position), inv_t_rotation); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/FrozenAnchorSimple.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &8677525280094201165 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 8936718249758435033} 12 | - component: {fileID: 2374158611049360179} 13 | - component: {fileID: 6670492942120058968} 14 | - component: {fileID: 446856176931405589} 15 | - component: {fileID: 413374782782081283} 16 | m_Layer: 0 17 | m_Name: FrozenAnchorSimple 18 | m_TagString: Untagged 19 | m_Icon: {fileID: 0} 20 | m_NavMeshLayer: 0 21 | m_StaticEditorFlags: 0 22 | m_IsActive: 1 23 | --- !u!4 &8936718249758435033 24 | Transform: 25 | m_ObjectHideFlags: 0 26 | m_CorrespondingSourceObject: {fileID: 0} 27 | m_PrefabInstance: {fileID: 0} 28 | m_PrefabAsset: {fileID: 0} 29 | m_GameObject: {fileID: 8677525280094201165} 30 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 31 | m_LocalPosition: {x: 0, y: 0, z: 0} 32 | m_LocalScale: {x: 0.02, y: 0.02, z: 0.02} 33 | m_ConstrainProportionsScale: 0 34 | m_Children: [] 35 | m_Father: {fileID: 0} 36 | m_RootOrder: 0 37 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 38 | --- !u!33 &2374158611049360179 39 | MeshFilter: 40 | m_ObjectHideFlags: 0 41 | m_CorrespondingSourceObject: {fileID: 0} 42 | m_PrefabInstance: {fileID: 0} 43 | m_PrefabAsset: {fileID: 0} 44 | m_GameObject: {fileID: 8677525280094201165} 45 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 46 | --- !u!23 &6670492942120058968 47 | MeshRenderer: 48 | m_ObjectHideFlags: 0 49 | m_CorrespondingSourceObject: {fileID: 0} 50 | m_PrefabInstance: {fileID: 0} 51 | m_PrefabAsset: {fileID: 0} 52 | m_GameObject: {fileID: 8677525280094201165} 53 | m_Enabled: 1 54 | m_CastShadows: 1 55 | m_ReceiveShadows: 1 56 | m_DynamicOccludee: 1 57 | m_StaticShadowCaster: 0 58 | m_MotionVectors: 1 59 | m_LightProbeUsage: 1 60 | m_ReflectionProbeUsage: 1 61 | m_RayTracingMode: 2 62 | m_RayTraceProcedural: 0 63 | m_RenderingLayerMask: 1 64 | m_RendererPriority: 0 65 | m_Materials: 66 | - {fileID: 2100000, guid: 22af01504e795b246ba8294b971269a5, type: 2} 67 | m_StaticBatchInfo: 68 | firstSubMesh: 0 69 | subMeshCount: 0 70 | m_StaticBatchRoot: {fileID: 0} 71 | m_ProbeAnchor: {fileID: 0} 72 | m_LightProbeVolumeOverride: {fileID: 0} 73 | m_ScaleInLightmap: 1 74 | m_ReceiveGI: 1 75 | m_PreserveUVs: 0 76 | m_IgnoreNormalsForChartDetection: 0 77 | m_ImportantGI: 0 78 | m_StitchLightmapSeams: 0 79 | m_SelectedEditorRenderState: 3 80 | m_MinimumChartSize: 4 81 | m_AutoUVMaxDistance: 0.5 82 | m_AutoUVMaxAngle: 89 83 | m_LightmapParameters: {fileID: 0} 84 | m_SortingLayerID: 0 85 | m_SortingLayer: 0 86 | m_SortingOrder: 0 87 | m_AdditionalVertexStreams: {fileID: 0} 88 | --- !u!65 &446856176931405589 89 | BoxCollider: 90 | m_ObjectHideFlags: 0 91 | m_CorrespondingSourceObject: {fileID: 0} 92 | m_PrefabInstance: {fileID: 0} 93 | m_PrefabAsset: {fileID: 0} 94 | m_GameObject: {fileID: 8677525280094201165} 95 | m_Material: {fileID: 0} 96 | m_IncludeLayers: 97 | serializedVersion: 2 98 | m_Bits: 0 99 | m_ExcludeLayers: 100 | serializedVersion: 2 101 | m_Bits: 0 102 | m_LayerOverridePriority: 0 103 | m_IsTrigger: 0 104 | m_ProvidesContacts: 0 105 | m_Enabled: 1 106 | serializedVersion: 3 107 | m_Size: {x: 1, y: 1, z: 1} 108 | m_Center: {x: 0, y: 0, z: 0} 109 | --- !u!114 &413374782782081283 110 | MonoBehaviour: 111 | m_ObjectHideFlags: 0 112 | m_CorrespondingSourceObject: {fileID: 0} 113 | m_PrefabInstance: {fileID: 0} 114 | m_PrefabAsset: {fileID: 0} 115 | m_GameObject: {fileID: 8677525280094201165} 116 | m_Enabled: 1 117 | m_EditorHideFlags: 0 118 | m_Script: {fileID: 11500000, guid: 417748c2517fd2a469240fc7d65c062c, type: 3} 119 | m_Name: 120 | m_EditorClassIdentifier: 121 | iconObject: {fileID: 0} 122 | textObject: {fileID: 0} 123 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/LinkageSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Explicitly set required Transform objects. 10 | /// 11 | /// 12 | /// If Use Existing is not set, then null Transform objects will override the currently set Transforms. 13 | /// When one of the Transform objects is set to null, the system attempts to infer a reasonable choice. 14 | /// For complicated scenes, this inference may be incorrect. For non-trivial scenes: 15 | /// ** If the camera rig is loaded per scene, then a Linkage Setting (via WorldLockingContext) should 16 | /// be set per scene explicitly pointing into that scene's camera hierarchy. 17 | /// ** If the camera rig is loaded once in a shared scene, the Linkage Setting should be in that scene only, 18 | /// and all other Linkage Settings should set "Use Existing" to true. 19 | /// ** If the camera rig is created/managed dynamically from script, then that script should also be responsible 20 | /// for setting the appropriate linkages, and all LinkageSettings should specify "Use Existing". 21 | /// 22 | [System.Serializable] 23 | public struct LinkageSettings 24 | { 25 | [SerializeField] 26 | [Tooltip("Ignore set values keep existing linkage, and use whatever was set last.")] 27 | private bool useExisting; 28 | /// 29 | /// Ignore set values keep existing linkage, and use whatever was set last. 30 | /// 31 | public bool UseExisting 32 | { 33 | get { return useExisting; } 34 | set 35 | { 36 | useExisting = value; 37 | } 38 | } 39 | 40 | [SerializeField] 41 | [Tooltip("Apply world locking adjustment to the AdjustmentFrame.")] 42 | private bool applyAdjustment; 43 | 44 | /// 45 | /// Zero out pitch and roll from the FrozenWorldEngine correction. 46 | /// 47 | [Tooltip("Zero out pitch and roll from the FrozenWorldEngine correction.")] 48 | public bool NoPitchAndRoll; 49 | 50 | /// 51 | /// Apply world locking adjustment to the AdjustmentFrame. 52 | /// 53 | /// 54 | /// If this is false, then it is up to the application to apply the correction. 55 | /// This allows the correction to be applied selectively to subsets of the scene hierarchy. 56 | /// 57 | public bool ApplyAdjustment { get { return applyAdjustment; } set { applyAdjustment = value; } } 58 | 59 | /// 60 | /// The transform at which to apply the camera adjustment. This can't be the camera node, as its 61 | /// transform is overwritten every frame with head pose data. But the camera should be an attached 62 | /// descendant of this node. 63 | /// 64 | [Tooltip("The transform at which to apply the camera adjustment.")] 65 | public Transform AdjustmentFrame; 66 | 67 | /// 68 | /// The camera parent node defines the "spongy frame of reference". All raw head based data, 69 | /// such as the spatial mapping, gesture events, and XR head pose data, are relative to this 70 | /// transform. 71 | /// 72 | [Tooltip("The Transform the camera is attached to. This extra node allows camera movement (e.g. Teleport).")] 73 | public Transform CameraParent; 74 | 75 | /// 76 | /// Init all fields to default values. 77 | /// 78 | public void InitToDefaults() 79 | { 80 | UseExisting = false; 81 | NoPitchAndRoll = false; 82 | ApplyAdjustment = true; 83 | AdjustmentFrame = null; 84 | CameraParent = null; 85 | } 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Prefabs/SpongyAnchorSimple.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &6744884967928005467 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 8541454267844005796} 12 | - component: {fileID: 7218465943553265922} 13 | - component: {fileID: 7543844474854983433} 14 | - component: {fileID: 4143949385058428273} 15 | - component: {fileID: 8628558959919653721} 16 | m_Layer: 0 17 | m_Name: SpongyAnchorSimple 18 | m_TagString: Untagged 19 | m_Icon: {fileID: 0} 20 | m_NavMeshLayer: 0 21 | m_StaticEditorFlags: 0 22 | m_IsActive: 1 23 | --- !u!4 &8541454267844005796 24 | Transform: 25 | m_ObjectHideFlags: 0 26 | m_CorrespondingSourceObject: {fileID: 0} 27 | m_PrefabInstance: {fileID: 0} 28 | m_PrefabAsset: {fileID: 0} 29 | m_GameObject: {fileID: 6744884967928005467} 30 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 31 | m_LocalPosition: {x: 0, y: 0, z: 0} 32 | m_LocalScale: {x: 0.02, y: 0.02, z: 0.02} 33 | m_ConstrainProportionsScale: 0 34 | m_Children: [] 35 | m_Father: {fileID: 0} 36 | m_RootOrder: 0 37 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 38 | --- !u!33 &7218465943553265922 39 | MeshFilter: 40 | m_ObjectHideFlags: 0 41 | m_CorrespondingSourceObject: {fileID: 0} 42 | m_PrefabInstance: {fileID: 0} 43 | m_PrefabAsset: {fileID: 0} 44 | m_GameObject: {fileID: 6744884967928005467} 45 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 46 | --- !u!23 &7543844474854983433 47 | MeshRenderer: 48 | m_ObjectHideFlags: 0 49 | m_CorrespondingSourceObject: {fileID: 0} 50 | m_PrefabInstance: {fileID: 0} 51 | m_PrefabAsset: {fileID: 0} 52 | m_GameObject: {fileID: 6744884967928005467} 53 | m_Enabled: 1 54 | m_CastShadows: 1 55 | m_ReceiveShadows: 1 56 | m_DynamicOccludee: 1 57 | m_StaticShadowCaster: 0 58 | m_MotionVectors: 1 59 | m_LightProbeUsage: 1 60 | m_ReflectionProbeUsage: 1 61 | m_RayTracingMode: 2 62 | m_RayTraceProcedural: 0 63 | m_RenderingLayerMask: 1 64 | m_RendererPriority: 0 65 | m_Materials: 66 | - {fileID: 2100000, guid: 0bd06e950ac4aa341bf4abc3c456b841, type: 2} 67 | m_StaticBatchInfo: 68 | firstSubMesh: 0 69 | subMeshCount: 0 70 | m_StaticBatchRoot: {fileID: 0} 71 | m_ProbeAnchor: {fileID: 0} 72 | m_LightProbeVolumeOverride: {fileID: 0} 73 | m_ScaleInLightmap: 1 74 | m_ReceiveGI: 1 75 | m_PreserveUVs: 0 76 | m_IgnoreNormalsForChartDetection: 0 77 | m_ImportantGI: 0 78 | m_StitchLightmapSeams: 0 79 | m_SelectedEditorRenderState: 3 80 | m_MinimumChartSize: 4 81 | m_AutoUVMaxDistance: 0.5 82 | m_AutoUVMaxAngle: 89 83 | m_LightmapParameters: {fileID: 0} 84 | m_SortingLayerID: 0 85 | m_SortingLayer: 0 86 | m_SortingOrder: 0 87 | m_AdditionalVertexStreams: {fileID: 0} 88 | --- !u!65 &4143949385058428273 89 | BoxCollider: 90 | m_ObjectHideFlags: 0 91 | m_CorrespondingSourceObject: {fileID: 0} 92 | m_PrefabInstance: {fileID: 0} 93 | m_PrefabAsset: {fileID: 0} 94 | m_GameObject: {fileID: 6744884967928005467} 95 | m_Material: {fileID: 0} 96 | m_IncludeLayers: 97 | serializedVersion: 2 98 | m_Bits: 0 99 | m_ExcludeLayers: 100 | serializedVersion: 2 101 | m_Bits: 0 102 | m_LayerOverridePriority: 0 103 | m_IsTrigger: 0 104 | m_ProvidesContacts: 0 105 | m_Enabled: 1 106 | serializedVersion: 3 107 | m_Size: {x: 1, y: 1, z: 1} 108 | m_Center: {x: 0, y: 0, z: 0} 109 | --- !u!114 &8628558959919653721 110 | MonoBehaviour: 111 | m_ObjectHideFlags: 0 112 | m_CorrespondingSourceObject: {fileID: 0} 113 | m_PrefabInstance: {fileID: 0} 114 | m_PrefabAsset: {fileID: 0} 115 | m_GameObject: {fileID: 6744884967928005467} 116 | m_Enabled: 1 117 | m_EditorHideFlags: 0 118 | m_Script: {fileID: 11500000, guid: fb58f91d3e7cdd948ba2ac3090412cf7, type: 3} 119 | m_Name: 120 | m_EditorClassIdentifier: 121 | ringObject: {fileID: 0} 122 | discObject: {fileID: 0} 123 | textObject: {fileID: 0} 124 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/ManagerSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Manager settings. 10 | /// 11 | [System.Serializable] 12 | public struct ManagerSettings 13 | { 14 | [SerializeField] 15 | [Tooltip("Ignore set values and use default behavior. When set, will reset all values to defaults.")] 16 | private bool useDefaults; 17 | 18 | /// 19 | /// Ignore set values and use default behavior. When set, will reset all values to defaults. 20 | /// 21 | public bool UseDefaults 22 | { 23 | get { return useDefaults; } 24 | set 25 | { 26 | useDefaults = value; 27 | if (useDefaults) 28 | { 29 | InitToDefaults(); 30 | } 31 | } 32 | } 33 | 34 | /// 35 | /// Whether the WorldLocking stabilization is active or bypassed (if not Enabled). 36 | /// 37 | [Tooltip("Whether the WorldLocking stabilization is active or bypassed (if not Enabled).")] 38 | public bool Enabled; 39 | 40 | /// 41 | /// Automatically trigger a fragment merge whenever the FrozenWorld engine indicates that 42 | /// one would be appropriate. 43 | /// 44 | [Tooltip("Automatically trigger a fragment merge whenever the FrozenWorld engine indicates that one would be appropriate.")] 45 | public bool AutoMerge; 46 | 47 | /// 48 | /// Automatically trigger a refreeze whenever the FrozenWorld engine indicates that 49 | /// one would be appropriate. 50 | /// 51 | [Tooltip("Automatically trigger a fragment refreeze whenever the FrozenWorld engine indicates that one would be appropriate.")] 52 | public bool AutoRefreeze; 53 | 54 | /// 55 | /// Automatically load the WorldLocking state from disk from previous run at startup. 56 | /// 57 | [Tooltip("Automatically load the WorldLocking state from disk from previous run at startup.")] 58 | public bool AutoLoad; 59 | 60 | /// 61 | /// Periodically save the WorldLocking state to disk. 62 | /// 63 | [Tooltip("Periodically save the WorldLocking state to disk.")] 64 | public bool AutoSave; 65 | 66 | /// 67 | /// Put this into default initialized state. 68 | /// 69 | /// This initialized to defaults. 70 | public ManagerSettings InitToDefaults() 71 | { 72 | AutoMerge = true; 73 | AutoRefreeze = true; 74 | AutoLoad = true; 75 | AutoSave = true; 76 | Enabled = true; 77 | return this; 78 | } 79 | } 80 | 81 | /// 82 | /// Shareable (reference type) version of Settings (value struct). 83 | /// 84 | [System.Serializable] 85 | public class SharedManagerSettings 86 | { 87 | /// 88 | /// The manager settings to be shared. 89 | /// 90 | public ManagerSettings settings; 91 | 92 | /// 93 | /// Transform links to be shared. 94 | /// 95 | public LinkageSettings linkageSettings; 96 | 97 | /// 98 | /// Anchor management settings. 99 | /// 100 | public AnchorSettings anchorSettings; 101 | 102 | /// 103 | /// Wrap a copy of settings initialized to default values. 104 | /// 105 | public SharedManagerSettings() 106 | { 107 | settings.InitToDefaults(); 108 | linkageSettings.InitToDefaults(); 109 | anchorSettings.InitToDefaults(); 110 | } 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /WorldLocking.Tools/Materials/WLT-Line.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: WLT-Line 11 | m_Shader: {fileID: 4800000, guid: 8516d7a69675844a7a0b7095af7c46af, type: 3} 12 | m_Parent: {fileID: 0} 13 | m_ModifiedSerializedProperties: 0 14 | m_ValidKeywords: [] 15 | m_InvalidKeywords: 16 | - _FLIPBOOKBLENDING_OFF 17 | m_LightmapFlags: 4 18 | m_EnableInstancingVariants: 0 19 | m_DoubleSidedGI: 0 20 | m_CustomRenderQueue: -1 21 | stringTagMap: 22 | RenderType: Opaque 23 | disabledShaderPasses: [] 24 | m_LockedProperties: 25 | m_SavedProperties: 26 | serializedVersion: 3 27 | m_TexEnvs: 28 | - _BaseMap: 29 | m_Texture: {fileID: 0} 30 | m_Scale: {x: 1, y: 1} 31 | m_Offset: {x: 0, y: 0} 32 | - _BumpMap: 33 | m_Texture: {fileID: 0} 34 | m_Scale: {x: 1, y: 1} 35 | m_Offset: {x: 0, y: 0} 36 | - _DetailAlbedoMap: 37 | m_Texture: {fileID: 0} 38 | m_Scale: {x: 1, y: 1} 39 | m_Offset: {x: 0, y: 0} 40 | - _DetailMask: 41 | m_Texture: {fileID: 0} 42 | m_Scale: {x: 1, y: 1} 43 | m_Offset: {x: 0, y: 0} 44 | - _DetailNormalMap: 45 | m_Texture: {fileID: 0} 46 | m_Scale: {x: 1, y: 1} 47 | m_Offset: {x: 0, y: 0} 48 | - _EmissionMap: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | - _MainTex: 53 | m_Texture: {fileID: 0} 54 | m_Scale: {x: 1, y: 1} 55 | m_Offset: {x: 0, y: 0} 56 | - _MetallicGlossMap: 57 | m_Texture: {fileID: 0} 58 | m_Scale: {x: 1, y: 1} 59 | m_Offset: {x: 0, y: 0} 60 | - _OcclusionMap: 61 | m_Texture: {fileID: 0} 62 | m_Scale: {x: 1, y: 1} 63 | m_Offset: {x: 0, y: 0} 64 | - _ParallaxMap: 65 | m_Texture: {fileID: 0} 66 | m_Scale: {x: 1, y: 1} 67 | m_Offset: {x: 0, y: 0} 68 | - _SpecGlossMap: 69 | m_Texture: {fileID: 0} 70 | m_Scale: {x: 1, y: 1} 71 | m_Offset: {x: 0, y: 0} 72 | m_Ints: [] 73 | m_Floats: 74 | - _AlphaClip: 0 75 | - _AlphaToMask: 0 76 | - _Blend: 0 77 | - _BlendOp: 0 78 | - _BumpScale: 1 79 | - _CameraFadingEnabled: 0 80 | - _CameraFarFadeDistance: 2 81 | - _CameraNearFadeDistance: 1 82 | - _ColorMode: 0 83 | - _Cull: 2 84 | - _Cutoff: 0.5 85 | - _DetailNormalMapScale: 1 86 | - _DistortionBlend: 0.5 87 | - _DistortionEnabled: 0 88 | - _DistortionStrength: 1 89 | - _DistortionStrengthScaled: 0.1 90 | - _DstBlend: 0 91 | - _DstBlendAlpha: 0 92 | - _FlipbookBlending: 0 93 | - _FlipbookMode: 0 94 | - _GlossMapScale: 1 95 | - _Glossiness: 0.5 96 | - _GlossyReflections: 1 97 | - _InvFade: 1 98 | - _Metallic: 0 99 | - _Mode: 0 100 | - _OcclusionStrength: 1 101 | - _Parallax: 0.02 102 | - _QueueOffset: 0 103 | - _ReceiveShadows: 1 104 | - _Smoothness: 0.5 105 | - _SmoothnessSource: 0 106 | - _SmoothnessTextureChannel: 0 107 | - _SoftParticlesEnabled: 0 108 | - _SoftParticlesFarFadeDistance: 1 109 | - _SoftParticlesNearFadeDistance: 0 110 | - _SpecularHighlights: 1 111 | - _SrcBlend: 1 112 | - _SrcBlendAlpha: 1 113 | - _Surface: 0 114 | - _UVSec: 0 115 | - _ZWrite: 1 116 | m_Colors: 117 | - _BaseColor: {r: 1, g: 1, b: 1, a: 1} 118 | - _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} 119 | - _CameraFadeParams: {r: 0, g: 0, b: 0, a: 0} 120 | - _Color: {r: 1, g: 1, b: 1, a: 1} 121 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 122 | - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} 123 | - _SpecColor: {r: 1, g: 1, b: 1, a: 1} 124 | m_BuildTextureStacks: [] 125 | --- !u!114 &7040465137138721238 126 | MonoBehaviour: 127 | m_ObjectHideFlags: 11 128 | m_CorrespondingSourceObject: {fileID: 0} 129 | m_PrefabInstance: {fileID: 0} 130 | m_PrefabAsset: {fileID: 0} 131 | m_GameObject: {fileID: 0} 132 | m_Enabled: 1 133 | m_EditorHideFlags: 0 134 | m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} 135 | m_Name: 136 | m_EditorClassIdentifier: 137 | version: 7 138 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/SpongyAnchorXR.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | //#define WLT_EXTRA_LOGGING 5 | 6 | #if WLT_DISABLE_LOGGING 7 | #undef WLT_EXTRA_LOGGING 8 | #endif // WLT_DISABLE_LOGGING 9 | 10 | using UnityEngine; 11 | #if WLT_ARSUBSYSTEMS_PRESENT 12 | using UnityEngine.XR.ARSubsystems; 13 | #endif // WLT_ARSUBSYSTEMS_PRESENT 14 | 15 | namespace Microsoft.MixedReality.WorldLocking.Core 16 | { 17 | /// 18 | /// Wrapper class for Unity XRAnchor, facilitating creation and persistence. 19 | /// 20 | public class SpongyAnchorXR : SpongyAnchor 21 | { 22 | public static float TrackingStartDelayTime = 0.3f; 23 | 24 | private float lastNotLocatedTime = float.NegativeInfinity; 25 | 26 | #if WLT_ARSUBSYSTEMS_PRESENT 27 | private TrackableId trackableId = TrackableId.invalidId; 28 | 29 | public TrackableId TrackableId { get { return trackableId; } set { trackableId = value; } } 30 | #endif // WLT_ARSUBSYSTEMS_PRESENT 31 | 32 | /// 33 | /// Whether the anchor is being tracked reliably. 34 | /// 35 | /// 36 | /// This state is managed by the anchor manager. 37 | /// 38 | public bool IsReliablyLocated { get; set; } 39 | 40 | /// 41 | /// Returns true if the anchor is reliably located. False might mean loss of tracking or not fully initialized. 42 | /// 43 | public override bool IsLocated 44 | { 45 | get 46 | { 47 | #if WLT_EXTRA_LOGGING 48 | if (IsReliablyLocated && !(Time.unscaledTime > lastNotLocatedTime + TrackingStartDelayTime)) 49 | { 50 | Debug.Log($"Anchor {name} located but waiting TrackingStartDelayTime {Time.unscaledTime} > {lastNotLocatedTime} + {TrackingStartDelayTime}"); 51 | } 52 | #endif // WLT_EXTRA_LOGGING 53 | return IsReliablyLocated && Time.unscaledTime > lastNotLocatedTime + TrackingStartDelayTime; 54 | } 55 | } 56 | 57 | public override Pose SpongyPose 58 | { 59 | get 60 | { 61 | Pose spongyPose = transform.GetGlobalPose(); 62 | return spongyPose; 63 | } 64 | } 65 | 66 | 67 | /// 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// The ARReferencePoint (or later version ARAnchor) returned by mgr.AddReferencePoint() (later mgr.AddAnchor()) 74 | /// is a Unity component, attached (obviously) to a GameObject. 75 | /// So, an alternate (read better) way might be: 76 | /// AnchorManagerARF creates an ARReferencePoint(ARAnchor). 77 | /// It then adds a SpongyAnchorARF (while creating it with AddComponent) to the referencePoint's gameObject. 78 | /// SpongyAnchorARF then gets ref to referencePoint in Start (or Awake?) to implement IsLocated 79 | /// (and hopefully Save/Load later). 80 | /// There is a PROBLEM HERE: 81 | /// ARReferencePoints (ARAnchors) can't be destroyed via normal Unity destruction path. They must 82 | /// be explicitly destroyed via the ARReferencePointManager.RemoveReferencePoint(). 83 | /// The good news is that we are in control of the destruction of SpongyAnchors. So rather 84 | /// than destroying a SpongyAnchor by destroying its GameObject, as we do now (see AnchorManager.Reset() 85 | /// for example, plus other Destroy() calls in AnchorManager), we'll need a virtual specifically for 86 | /// destroying SpongyAnchors. 87 | /// 88 | 89 | // Start is called before the first frame update 90 | private void Start () 91 | { 92 | lastNotLocatedTime = Time.unscaledTime; 93 | } 94 | 95 | // mafinc - This seems a wasteful use of Update. Possibly set lastNotLocatedTime while iterating 96 | // in AnchorManager? 97 | private void Update () 98 | { 99 | /// Set lastNotLocatedTime if not located 100 | if (!IsReliablyLocated) 101 | { 102 | #if WLT_EXTRA_LOGGING 103 | Debug.Log($"LastNotLocated {name} is {Time.unscaledTime}"); 104 | #endif // WLT_EXTRA_LOGGING 105 | lastNotLocatedTime = Time.unscaledTime; 106 | } 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/AttachmentPoint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Implementation of the IAttachmentPoint interface. Provides implementations, as well 10 | /// as a binding to the update delegates. 11 | /// 12 | public class AttachmentPoint : IAttachmentPoint 13 | { 14 | /// 15 | public string Name { get; set; } 16 | 17 | /// 18 | public AnchorId AnchorId { get; private set; } 19 | 20 | /// 21 | public FragmentId FragmentId { get; private set; } 22 | 23 | /// 24 | public Vector3 LocationFromAnchor { get; set; } = Vector3.zero; 25 | 26 | /// 27 | public Vector3 CachedPosition { get; set; } 28 | 29 | /// 30 | public AttachmentPointStateType State { get; set; } 31 | 32 | /// 33 | public Pose ObjectAdjustment { get; set; } 34 | 35 | /// 36 | public Vector3 ObjectPosition { get; set; } 37 | 38 | /// 39 | /// Handler for system positional adjustments. May be null 40 | /// 41 | public AdjustLocationDelegate LocationHandler { get; private set; } 42 | 43 | /// 44 | /// Handler for system connectivity adjustments. May be null. 45 | /// 46 | public AdjustStateDelegate StateHandler { get; private set; } 47 | 48 | /// 49 | /// Constructor, sets handlers 50 | /// 51 | /// Handler for positional adjustments, may be null. 52 | /// Handler for connectivity adjustments, may be null. 53 | public AttachmentPoint(AdjustLocationDelegate locationHandler, AdjustStateDelegate stateHandler) 54 | { 55 | this.LocationHandler = locationHandler; 56 | this.StateHandler = stateHandler; 57 | } 58 | 59 | /// 60 | public void MoveTo(IAttachmentPointManager manager, Vector3 newFrozenPosition) 61 | { 62 | manager.MoveAttachmentPoint(this, newFrozenPosition); 63 | } 64 | 65 | /// 66 | public void TeleportTo(IAttachmentPointManager manager, Vector3 newFrozenPosition, IAttachmentPoint parent) 67 | { 68 | manager.TeleportAttachmentPoint(this, newFrozenPosition, parent); 69 | } 70 | 71 | /// 72 | /// If state has changed, record the new state and pass on to client handler (if any). 73 | /// 74 | /// The state to change to. 75 | public void HandleStateChange(AttachmentPointStateType newState) 76 | { 77 | if (newState != State) 78 | { 79 | State = newState; 80 | StateHandler?.Invoke(newState); 81 | } 82 | } 83 | 84 | /// 85 | /// Keep track of cumulative transform adjustment, and pass on to client adjustment handler (if any). 86 | /// 87 | /// 88 | /// See and 89 | /// 90 | /// 91 | public void HandlePoseAdjustment(Pose adjustment) 92 | { 93 | ObjectPosition = adjustment.Multiply(ObjectPosition); 94 | ObjectAdjustment = ObjectAdjustment.Multiply(adjustment); 95 | LocationHandler?.Invoke(adjustment); 96 | } 97 | 98 | /// 99 | /// Set internals of attachment point to new values. 100 | /// 101 | /// New fragment 102 | /// Cache last position moved to. 103 | /// New anchor id 104 | /// New displacement from anchor 105 | public void Set(FragmentId fragmentId, Vector3 cachedPosition, AnchorId anchorId, Vector3 locationFromAnchor) 106 | { 107 | this.AnchorId = anchorId; 108 | this.FragmentId = fragmentId; 109 | this.CachedPosition = cachedPosition; 110 | this.LocationFromAnchor = locationFromAnchor; 111 | } 112 | 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAttachmentPointManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// Interface for application creation and manipulation of attachment points. In particular, the creation and release 10 | /// of attachment points must be conducted through the IAttachmentPointManager. 11 | /// 12 | /// 13 | /// Obtain access to the attachment point manager through the WorldLockingManager. 14 | /// 15 | public interface IAttachmentPointManager 16 | { 17 | /// 18 | /// Create and register a new attachment point. 19 | /// 20 | /// 21 | /// The attachment point itself is a fairly opaque handle. Its effects are propagated to the client via the 22 | /// two handlers associated with it. 23 | /// The context interface is optional. It should be given if the new attachment point is conceptually 24 | /// spawned from an existing attachment point (or its target object). 25 | /// If null, then conceptually the new attachment point was spawned from the current camera. 26 | /// The attachment point itself is a fairly opaque handle. The actual adjustments are made via 27 | /// notifications through the two delegates passed into the creation. 28 | /// The locationHandler is strictly to notify of adjustments when refitting (Merge or Refreeze). 29 | /// The stateHandler notifies whether this attachment point is "connected" with the current fragment. 30 | /// Both handlers are optional and may be null. 31 | /// 32 | /// The position in the frozen space at which to start the attachment point 33 | /// The optional context into which to create the attachment point (may be null) 34 | /// Delegate to handle Frozen World engine system adjustments to position 35 | /// Delegate to handle Frozen World engine connectivity changes 36 | /// The new attachment point interface. 37 | IAttachmentPoint CreateAttachmentPoint(Vector3 frozenPosition, IAttachmentPoint context, 38 | AdjustLocationDelegate locationHandler, AdjustStateDelegate stateHandler); 39 | 40 | /// 41 | /// Release an attachment point for disposal. The attachment point is no longer valid after this call. 42 | /// This also un-registers the handlers (if any) given when it was created. 43 | /// 44 | /// 45 | /// In the unlikely circumstance that another attachment point has been spawned from this one 46 | /// but has not yet been processed (is still in the pending queue), 47 | /// that relationship is broken on release of this one, and when the other attachment point is 48 | /// finally processed, it will be as if it was created with a null context. 49 | /// 50 | /// The attachment point to release. 51 | void ReleaseAttachmentPoint(IAttachmentPoint attachPointIface); 52 | 53 | /// 54 | /// Move (as opposed to Teleport) means that the object is meant to have traversed 55 | /// frozen space from its old position to the given new position on some continuous path. 56 | /// 57 | /// 58 | /// Not to be used for automatic (i.e. FrozenWorld Engine instigated) moves. 59 | /// Use this for continuous movement through space. For discontinuous movement (i.e. teleportation), use 60 | /// 61 | /// Attachment point to move 62 | /// The new position in frozen space 63 | void MoveAttachmentPoint(IAttachmentPoint attachPointIface, Vector3 newFrozenPosition); 64 | 65 | /// 66 | /// Teleport (as opposed to Move) means that the object is meant to have disappeared at its old position 67 | /// and instantaneously reappeared at its new position in frozen space without traversing the space in between. 68 | /// 69 | /// 70 | /// Use this for discontinuous movement through space (i.e. teleportation). For continuous movement, use . 71 | /// This is equivalent to releasing the attachment point () and creating it () 72 | /// at the new location in the given context, except that using Teleport allows the reference to the existing attachment point to remains valid. 73 | /// 74 | /// The attachment point to teleport 75 | /// The position to teleport to. 76 | /// The optional context. 77 | void TeleportAttachmentPoint(IAttachmentPoint attachPointIface, Vector3 newFrozenPosition, IAttachmentPoint context); 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/WSA/SpongyAnchorWSA.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #if UNITY_WSA && !UNITY_2020_1_OR_NEWER 5 | #define WLT_ENABLE_LEGACY_WSA 6 | #endif 7 | 8 | using UnityEngine; 9 | #if WLT_ENABLE_LEGACY_WSA 10 | using UnityEngine.XR.WSA; 11 | using UnityEngine.XR.WSA.Persistence; 12 | #endif // WLT_ENABLE_LEGACY_WSA 13 | 14 | #pragma warning disable CS0618 15 | 16 | namespace Microsoft.MixedReality.WorldLocking.Core 17 | { 18 | /// 19 | /// Wrapper class for Unity WorldAnchor, facilitating creation and persistence. 20 | /// 21 | public class SpongyAnchorWSA : SpongyAnchor 22 | { 23 | /// 24 | /// Timeout that protects against SpatialAnchor easing 25 | /// 26 | /// 27 | /// The Unity WorldAnchor component is based on the API property Windows.Perception.Spatial.SpatialAnchor.CoordinateSystem 28 | /// (see https://docs.microsoft.com/en-us/uwp/api/windows.perception.spatial.spatialanchor.coordinatesystem) 29 | /// 30 | /// In contrast to its companion property RawCoordinateSystem, this value is smoothed out over a time of 300ms 31 | /// (determined experimentally) whenever the correct anchor position is re-established after a tracking loss. 32 | /// 33 | /// Since Unity does not offer access to the raw value, we here introduce a delay after each time isLocated switches back 34 | /// to true to avoid feeding the FrozenWorld Engine with incorrect initial data. 35 | /// 36 | /// Note: It would be worth trying direct access to SpatialAnchor is possible (COM-5081). First attempts 37 | /// failed to do this in some straightforward way from Unity-C# code. Further research would be required. 38 | /// 39 | public static float TrackingStartDelayTime = 0.3f; 40 | 41 | private float lastNotLocatedTime = float.NegativeInfinity; 42 | #if WLT_ENABLE_LEGACY_WSA 43 | private WorldAnchor worldAnchor = null; 44 | #else 45 | private SpongyAnchor dummy = null; 46 | #endif // WLT_ENABLE_LEGACY_WSA 47 | 48 | /// 49 | /// Returns true if the anchor is reliably located. False might mean loss of tracking or not fully initialized. 50 | /// 51 | public override bool IsLocated => 52 | IsReliablyLocated && Time.unscaledTime > lastNotLocatedTime + TrackingStartDelayTime; 53 | 54 | private bool IsReliablyLocated 55 | { 56 | get 57 | { 58 | #if WLT_ENABLE_LEGACY_WSA 59 | return worldAnchor != null && worldAnchor.isLocated; 60 | #else // WLT_ENABLE_LEGACY_WSA 61 | return false; 62 | #endif // WLT_ENABLE_LEGACY_WSA 63 | } 64 | } 65 | 66 | public override Pose SpongyPose 67 | { 68 | get 69 | { 70 | return transform.GetGlobalPose(); 71 | } 72 | } 73 | 74 | // Start is called before the first frame update 75 | private void Start () 76 | { 77 | #if WLT_ENABLE_LEGACY_WSA 78 | if (worldAnchor == null) 79 | { 80 | worldAnchor = gameObject.AddComponent(); 81 | } 82 | #else 83 | dummy = this; 84 | if (IsSaved && lastNotLocatedTime > 0) 85 | { 86 | IsSaved = false; 87 | lastNotLocatedTime = float.NegativeInfinity; 88 | } 89 | #endif // WLT_ENABLE_LEGACY_WSA 90 | } 91 | 92 | #if WLT_ENABLE_LEGACY_WSA 93 | // Update is called once per frame 94 | private void Update () 95 | { 96 | if (!IsReliablyLocated) 97 | { 98 | lastNotLocatedTime = Time.unscaledTime; 99 | } 100 | } 101 | #endif // WLT_ENABLE_LEGACY_WSA 102 | 103 | #if WLT_ENABLE_LEGACY_WSA 104 | 105 | /// 106 | /// Save to the anchor store, replacing any existing anchor (by name). 107 | /// 108 | /// 109 | public void Save (WorldAnchorStore store) 110 | { 111 | if (IsSaved) 112 | { 113 | return; 114 | } 115 | if (worldAnchor == null) 116 | { 117 | return; 118 | } 119 | 120 | store.Delete(name); 121 | bool success = store.Save(name, worldAnchor); 122 | Debug.Assert(success); 123 | IsSaved = true; 124 | } 125 | 126 | /// 127 | /// Load from the anchor store, losing whatever state was before load. 128 | /// 129 | /// 130 | /// 131 | public bool Load (WorldAnchorStore store) 132 | { 133 | if (worldAnchor) 134 | { 135 | Destroy(worldAnchor); 136 | } 137 | worldAnchor = store.Load(name, gameObject); 138 | IsSaved = true; 139 | return worldAnchor != null; 140 | } 141 | #endif // WLT_ENABLE_LEGACY_WSA 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/IAttachmentPoint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using UnityEngine; 5 | 6 | namespace Microsoft.MixedReality.WorldLocking.Core 7 | { 8 | /// 9 | /// The states an attachment point can be in. 10 | /// 11 | public enum AttachmentPointStateType 12 | { 13 | Invalid = 0, // Doesn't exist 14 | Pending, // Exists, but is still under construction 15 | Normal, // Exists, and is active and valid 16 | Unconnected, // Exists, but is disconnected from the active fragment. Location data unreliable. 17 | Released, // Existed, but has been released. Is now garbage. 18 | } 19 | 20 | /// 21 | /// Notification from the system that the state of the fragment containing the attachment point has changed. 22 | /// The client can take action to hide objects in disconnected space if desired. 23 | /// 24 | /// The new state of the containing fragment 25 | public delegate void AdjustStateDelegate(AttachmentPointStateType state); 26 | 27 | /// 28 | /// Notification that a correction in the world locked space has been computed and 29 | /// should be applied to this object. 30 | /// 31 | /// The adjustment to apply 32 | public delegate void AdjustLocationDelegate(Pose adjustment); 33 | 34 | /// 35 | /// Opaque handle to an attachment point. Create one of these to enable 36 | /// WorldLocking to adjust an attached object as corrections to the world locked space 37 | /// optimization are made. 38 | /// 39 | /// 40 | /// The attachment point gives an interface for notifying the system that you have moved 41 | /// the attached object, and the system indicates that it has computed an adjustment 42 | /// for the object through the callbacks passed into the creation routine. 43 | /// Alternatively, polling is also supported through the State and ObjectAdjustment accessors. 44 | /// 45 | public interface IAttachmentPoint 46 | { 47 | /// 48 | /// Name is auto-populated on create with something unique, but can 49 | /// be renamed to anything useful and convenient. It is only used as 50 | /// a label, so can be anything (including empty or null). 51 | /// 52 | string Name { get; set; } 53 | 54 | /// 55 | /// Associated anchor id 56 | /// 57 | AnchorId AnchorId { get; } 58 | 59 | /// 60 | /// Associated fragment id 61 | /// 62 | FragmentId FragmentId { get; } 63 | 64 | /// 65 | /// Position of attachment point in anchor point's space. 66 | /// 67 | Vector3 LocationFromAnchor { get; } 68 | 69 | /// 70 | /// Internal history cache. 71 | /// 72 | Vector3 CachedPosition { get; } 73 | 74 | /// 75 | /// Current state of this attachment point. 76 | /// 77 | /// 78 | /// Positioning information is only valid when state is Normal. See 79 | /// 80 | AttachmentPointStateType State { get; } 81 | 82 | /// 83 | /// The position of object(s) bound to this attachment point. 84 | /// 85 | Vector3 ObjectPosition { get; } 86 | 87 | /// 88 | /// Cumulative transform adjustment for object(s) bound to this attachment point. 89 | /// 90 | Pose ObjectAdjustment { get; } 91 | 92 | /// 93 | /// Notify attachment point that it has moved incrementally to a new position. 94 | /// 95 | /// 96 | /// This should be used for conceptually continuous motion. For discontinuous motion (i.e. teleport), 97 | /// use . This is equivalent to 98 | /// 99 | /// The mananger 100 | /// The new position 101 | void MoveTo(IAttachmentPointManager manager, Vector3 newFrozenPosition); 102 | 103 | /// 104 | /// Notify attachment point that it has teleported to a new position. 105 | /// 106 | /// 107 | /// This should be used for discontinuous movement, i.e. teleporting. For continuous motion, use . 108 | /// This is equivalent to 109 | /// 110 | /// The manager 111 | /// The new position 112 | /// The context into which to teleport. Can be null. 113 | void TeleportTo(IAttachmentPointManager manager, Vector3 newFrozenPosition, IAttachmentPoint context); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR_WMR.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #if UNITY_2020_1_OR_NEWER 5 | 6 | #if WLT_ARSUBSYSTEMS_PRESENT 7 | 8 | #if WLT_MICROSOFT_WMR_XR_4_3_PRESENT && UNITY_WSA 9 | #define WLT_XR_PERSISTENCE 10 | #endif // WLT_XR_PERSISTENCE 11 | 12 | //#define WLT_EXTRA_LOGGING 13 | 14 | #if WLT_DISABLE_LOGGING 15 | #undef WLT_EXTRA_LOGGING 16 | #endif // WLT_DISABLE_LOGGING 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Threading.Tasks; 21 | using UnityEngine; 22 | using UnityEngine.XR; 23 | 24 | #if WLT_XR_PERSISTENCE 25 | using UnityEngine.XR.WindowsMR; 26 | #endif // WLT_XR_PERSISTENCE 27 | 28 | using UnityEngine.SpatialTracking; 29 | using UnityEngine.XR.ARSubsystems; 30 | 31 | namespace Microsoft.MixedReality.WorldLocking.Core 32 | { 33 | /// 34 | /// 35 | /// 36 | /// 37 | public partial class AnchorManagerXR : AnchorManager 38 | { 39 | 40 | private bool wmrPersistence = false; 41 | 42 | #if WLT_XR_PERSISTENCE 43 | private XRAnchorStore wmrAnchorStore = null; 44 | 45 | private async Task EnsureWMRAnchorStore() 46 | { 47 | if (wmrAnchorStore == null) 48 | { 49 | DebugLogExtra($"Getting new WMR XRAnchorStore."); 50 | wmrAnchorStore = await xrAnchorManager.TryGetAnchorStoreAsync(); 51 | } 52 | wmrPersistence = wmrAnchorStore != null; 53 | return wmrAnchorStore; 54 | } 55 | #endif // WLT_XR_PERSISTENCE 56 | 57 | protected async Task SaveAnchorsWMR(List spongyAnchors) 58 | { 59 | Debug.Assert(wmrPersistence, "Trying to save WMR anchors when unsupported."); 60 | #if WLT_XR_PERSISTENCE 61 | var anchorStore = await EnsureWMRAnchorStore(); 62 | if (anchorStore == null) 63 | { 64 | return; 65 | } 66 | DebugLogExtra($"Got WMR anchorStore for Save"); 67 | 68 | foreach (var keyval in spongyAnchors) 69 | { 70 | var id = keyval.anchorId; 71 | var anchor = keyval.spongyAnchor; 72 | Debug.Assert(anchor.name == id.FormatStr()); 73 | if (!anchor.IsSaved) 74 | { 75 | var anchorXR = anchor as SpongyAnchorXR; 76 | Debug.Assert(anchorXR != null); 77 | anchorStore.UnpersistAnchor(anchor.name); 78 | anchorStore.TryPersistAnchor(anchorXR.TrackableId, anchor.name); 79 | anchor.IsSaved = true; 80 | } 81 | } 82 | 83 | #else // WLT_XR_PERSISTENCE 84 | await Task.CompletedTask; 85 | #endif // WLT_XR_PERSISTENCE 86 | } 87 | 88 | /// 89 | /// Load the spongy anchors from persistent storage 90 | /// 91 | /// 92 | /// The set of spongy anchors loaded by this routine is defined by the frozen anchors 93 | /// previously loaded into the plugin. 94 | /// 95 | /// Likewise, when a spongy anchor fails to load, this routine will delete its frozen 96 | /// counterpart from the plugin. 97 | /// 98 | protected async Task LoadAnchorsWMR(IPlugin plugin, AnchorId firstId, Transform parent, List spongyAnchors) 99 | { 100 | Debug.Assert(wmrPersistence, "Trying to save WMR anchors when unsupported."); 101 | #if WLT_XR_PERSISTENCE 102 | DebugLogExtra($"Load enter: AnchorSubsystem is {xrAnchorManager.running}"); 103 | 104 | var anchorStore = await EnsureWMRAnchorStore(); 105 | if (anchorStore == null) 106 | { 107 | return; 108 | } 109 | DebugLogExtra($"Got WMR anchorStore for Load"); 110 | 111 | var anchorIds = plugin.GetFrozenAnchorIds(); 112 | 113 | AnchorId maxId = firstId; 114 | 115 | foreach (var id in anchorIds) 116 | { 117 | var trackableId = anchorStore.LoadAnchor(id.FormatStr()); 118 | if (trackableId != TrackableId.invalidId) 119 | { 120 | DebugLogExtra($"LoadAnchor returns {trackableId}"); 121 | // We create the anchor here, but don't have a xrAnchor (XRAnchor) for it yet 122 | var spongyAnchorXR = PrepAnchor(id, parent, trackableId, Pose.identity); 123 | spongyAnchors.Add(new SpongyAnchorWithId() 124 | { 125 | anchorId = id, 126 | spongyAnchor = spongyAnchorXR 127 | }); 128 | spongyAnchorXR.IsSaved = true; 129 | } 130 | else 131 | { 132 | plugin.RemoveFrozenAnchor(id); 133 | } 134 | } 135 | 136 | DebugLogExtra($"Load exit: AnchorSubsystem is {xrAnchorManager.running}"); 137 | 138 | #else // WLT_XR_PERSISTENCE 139 | await Task.CompletedTask; 140 | #endif // WLT_XR_PERSISTENCE 141 | } 142 | } 143 | } 144 | 145 | #endif // WLT_ARSUBSYSTEMS_PRESENT 146 | 147 | #endif // UNITY_2020_1_OR_NEWER 148 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/ToggleWorldAnchor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #if UNITY_WSA && !UNITY_2020_1_OR_NEWER 5 | #define WLT_ENABLE_LEGACY_WSA 6 | #endif 7 | 8 | using System.Collections; 9 | using System.Collections.Generic; 10 | using UnityEngine; 11 | 12 | #if WLT_ENABLE_LEGACY_WSA 13 | using UnityEngine.XR.WSA; 14 | #endif // WLT_ENABLE_LEGACY_WSA 15 | 16 | using Microsoft.MixedReality.WorldLocking.Core; 17 | 18 | namespace Microsoft.MixedReality.WorldLocking.Tools 19 | { 20 | public class ToggleWorldAnchor : MonoBehaviour 21 | { 22 | protected IAttachmentPoint AttachmentPoint { get; private set; } 23 | 24 | #if WLT_ENABLE_LEGACY_WSA 25 | private WorldAnchor worldAnchor = null; 26 | #endif // WLT_ENABLE_LEGACY_WSA 27 | 28 | private bool frozenPoseIsSpongy = false; 29 | private Pose frozenPose = Pose.identity; 30 | 31 | [SerializeField] 32 | [Tooltip("Always use WorldAnchor to world lock, whether Frozen World is active or not.")] 33 | private bool alwaysLock = false; 34 | /// 35 | /// Always use WorldAnchor to world lock, whether Frozen World is active or not. 36 | /// 37 | public bool AlwaysLock { get { return alwaysLock; } set { alwaysLock = value; } } 38 | 39 | // Start is called before the first frame update 40 | void Start() 41 | { 42 | Debug.Assert(WorldLockingManager.GetInstance() != null, "Unexpected null WorldLockingManager"); 43 | // dummy use of variables to silence unused variable warning in non-WSA build. 44 | if (frozenPoseIsSpongy) 45 | { 46 | frozenPose = Pose.identity; 47 | } 48 | } 49 | 50 | private void OnEnable() 51 | { 52 | #if WLT_ENABLE_LEGACY_WSA 53 | /// Setup world anchor helper. 54 | CreateWorldAnchorHelper(); 55 | #endif // WLT_ENABLE_LEGACY_WSA 56 | } 57 | 58 | private void OnDisable() 59 | { 60 | #if WLT_ENABLE_LEGACY_WSA 61 | /// Tear down world anchor helper. 62 | DestroyWorldAnchorHelper(); 63 | #endif // WLT_ENABLE_LEGACY_WSA 64 | } 65 | 66 | #if WLT_ENABLE_LEGACY_WSA 67 | // Update is called once per frame 68 | void Update() 69 | { 70 | if (AlwaysLock || !WorldLockingManager.GetInstance().Enabled) 71 | { 72 | Pose spongyPose = worldAnchor.transform.GetGlobalPose(); 73 | frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose); 74 | transform.SetGlobalPose(frozenPose); 75 | } 76 | else 77 | { 78 | CheckFrozenPose(); 79 | // Set pose to frozen space pose 80 | transform.SetGlobalPose(frozenPose); 81 | } 82 | } 83 | 84 | private void CheckFrozenPose() 85 | { 86 | if (frozenPoseIsSpongy) 87 | { 88 | Pose spongyPose = worldAnchor.transform.GetGlobalPose(); 89 | Debug.Assert(WorldLockingManager.GetInstance().Enabled, "Should wait until WorldLockingManager is active to check the frozen pose."); 90 | frozenPose = WorldLockingManager.GetInstance().FrozenFromSpongy.Multiply(spongyPose); 91 | frozenPoseIsSpongy = false; 92 | } 93 | } 94 | 95 | private void CreateWorldAnchorHelper() 96 | { 97 | GameObject goHelper = new GameObject(name + "WorldAnchorHelper"); 98 | goHelper.transform.SetParent(transform); 99 | goHelper.hideFlags = HideFlags.HideAndDontSave; 100 | frozenPose = transform.GetGlobalPose(); 101 | Pose spongyPose = WorldLockingManager.GetInstance().SpongyFromFrozen.Multiply(frozenPose); 102 | if (!WorldLockingManager.GetInstance().Enabled) 103 | { 104 | frozenPoseIsSpongy = true; 105 | } 106 | goHelper.transform.SetGlobalPose(spongyPose); 107 | worldAnchor = goHelper.AddComponent(); 108 | 109 | AttachmentPoint = WorldLockingManager.GetInstance().AttachmentPointManager.CreateAttachmentPoint(gameObject.transform.position, null, 110 | HandleAdjustLocation, // Handle adjustments to position 111 | null // Handle connectedness of fragment 112 | ); 113 | AttachmentPoint.Name = string.Format($"{gameObject.name}=>{AttachmentPoint.Name}"); 114 | } 115 | 116 | /// Adjust frozen space pose upon refit operations. 117 | private void HandleAdjustLocation(Pose adjustment) 118 | { 119 | frozenPose = adjustment.Multiply(frozenPose); 120 | } 121 | 122 | private void DestroyWorldAnchorHelper() 123 | { 124 | if (worldAnchor != null) 125 | { 126 | Destroy(worldAnchor.gameObject); 127 | worldAnchor = null; 128 | } 129 | if (AttachmentPoint != null) 130 | { 131 | WorldLockingManager.GetInstance().AttachmentPointManager.ReleaseAttachmentPoint(AttachmentPoint); 132 | AttachmentPoint = null; 133 | } 134 | } 135 | #endif // WLT_ENABLE_LEGACY_WSA 136 | 137 | } 138 | } -------------------------------------------------------------------------------- /WorldLocking.Core/Scripts/XR/AnchorManagerXR_OpenXR.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | #if UNITY_2020_1_OR_NEWER 5 | 6 | #if WLT_ARSUBSYSTEMS_PRESENT 7 | 8 | #if WLT_MICROSOFT_OPENXR_PRESENT && UNITY_WSA 9 | #define WLT_XR_PERSISTENCE 10 | #endif // WLT_XR_PERSISTENCE 11 | 12 | //#define WLT_EXTRA_LOGGING 13 | 14 | #if WLT_DISABLE_LOGGING 15 | #undef WLT_EXTRA_LOGGING 16 | #endif // WLT_DISABLE_LOGGING 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Threading.Tasks; 21 | using UnityEngine; 22 | using UnityEngine.XR; 23 | 24 | #if WLT_XR_PERSISTENCE 25 | //using Microsoft.MixedReality.ARSubsystems; 26 | using Microsoft.MixedReality.OpenXR; 27 | #endif // WLT_XR_PERSISTENCE 28 | 29 | using UnityEngine.SpatialTracking; 30 | using UnityEngine.XR.ARSubsystems; 31 | 32 | namespace Microsoft.MixedReality.WorldLocking.Core 33 | { 34 | /// 35 | /// 36 | /// 37 | /// 38 | public partial class AnchorManagerXR : AnchorManager 39 | { 40 | private bool openXRPersistence = false; 41 | 42 | #if WLT_XR_PERSISTENCE 43 | private XRAnchorStore openXRAnchorStore = null; 44 | 45 | private async Task EnsureOpenXRAnchorStore() 46 | { 47 | if (openXRAnchorStore == null) 48 | { 49 | DebugLogExtra($"Getting new OpenXR XRAnchorStore."); 50 | // openXRAnchorStore = await xrAnchorManager.LoadAnchorStoreAsync(); 51 | openXRAnchorStore = await XRAnchorStore.LoadAsync(xrAnchorManager); 52 | } 53 | openXRPersistence = openXRAnchorStore != null; 54 | return openXRAnchorStore; 55 | } 56 | #endif // WLT_XR_PERSISTENCE 57 | 58 | protected async Task SaveAnchorsOpenXR(List spongyAnchors) 59 | { 60 | Debug.Assert(openXRPersistence, "Attempting to save via OpenXR when unsupported."); 61 | #if WLT_XR_PERSISTENCE 62 | 63 | var anchorStore = await EnsureOpenXRAnchorStore(); 64 | if (anchorStore == null) 65 | { 66 | return; 67 | } 68 | DebugLogExtra($"Got OpenXR anchorStore for Save"); 69 | 70 | foreach (var keyval in spongyAnchors) 71 | { 72 | var id = keyval.anchorId; 73 | var anchor = keyval.spongyAnchor; 74 | Debug.Assert(anchor.name == id.FormatStr()); 75 | if (!anchor.IsSaved) 76 | { 77 | var anchorXR = anchor as SpongyAnchorXR; 78 | Debug.Assert(anchorXR != null); 79 | anchorStore.UnpersistAnchor(anchor.name); 80 | anchorStore.TryPersistAnchor(anchorXR.TrackableId, anchor.name); 81 | anchor.IsSaved = true; 82 | } 83 | } 84 | 85 | #else // WLT_XR_PERSISTENCE 86 | await Task.CompletedTask; 87 | #endif // WLT_XR_PERSISTENCE 88 | } 89 | 90 | /// 91 | /// Load the spongy anchors from persistent storage 92 | /// 93 | /// 94 | /// The set of spongy anchors loaded by this routine is defined by the frozen anchors 95 | /// previously loaded into the plugin. 96 | /// 97 | /// Likewise, when a spongy anchor fails to load, this routine will delete its frozen 98 | /// counterpart from the plugin. 99 | /// 100 | protected async Task LoadAnchorsOpenXR(IPlugin plugin, AnchorId firstId, Transform parent, List spongyAnchors) 101 | { 102 | Debug.Assert(openXRPersistence, "Attempting to save via OpenXR when unsupported."); 103 | #if WLT_XR_PERSISTENCE 104 | DebugLogExtra($"Load enter: AnchorSubsystem is {xrAnchorManager.running}"); 105 | 106 | var anchorStore = await EnsureOpenXRAnchorStore(); 107 | if (anchorStore == null) 108 | { 109 | return; 110 | } 111 | DebugLogExtra($"Got OpenXR anchorStore for Load"); 112 | 113 | var anchorIds = plugin.GetFrozenAnchorIds(); 114 | 115 | AnchorId maxId = firstId; 116 | 117 | foreach (var id in anchorIds) 118 | { 119 | var trackableId = anchorStore.LoadAnchor(id.FormatStr()); 120 | if (trackableId != TrackableId.invalidId) 121 | { 122 | DebugLogExtra($"LoadAnchor returns {trackableId}"); 123 | // We create the anchor here, but don't have a xrAnchor (XRAnchor) for it yet 124 | var spongyAnchorXR = PrepAnchor(id, parent, trackableId, Pose.identity); 125 | spongyAnchors.Add(new SpongyAnchorWithId() 126 | { 127 | anchorId = id, 128 | spongyAnchor = spongyAnchorXR 129 | }); 130 | spongyAnchorXR.IsSaved = true; 131 | } 132 | else 133 | { 134 | plugin.RemoveFrozenAnchor(id); 135 | } 136 | } 137 | 138 | DebugLogExtra($"Load exit: AnchorSubsystem is {xrAnchorManager.running}"); 139 | 140 | #else // WLT_XR_PERSISTENCE 141 | await Task.CompletedTask; 142 | #endif // WLT_XR_PERSISTENCE 143 | } 144 | } 145 | } 146 | 147 | #endif // WLT_ARSUBSYSTEMS_PRESENT 148 | 149 | #endif // UNITY_2020_1_OR_NEWER 150 | 151 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/SpongyAnchorVisual.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | using System; 5 | using UnityEngine; 6 | 7 | using Microsoft.MixedReality.WorldLocking.Core; 8 | 9 | namespace Microsoft.MixedReality.WorldLocking.Tools 10 | { 11 | /// 12 | /// Component for controlling location, visual appearance and ID text of a spongy anchor visualization. 13 | /// 14 | /// 15 | /// Spongy anchors are visualized by a concentric pair of an outer ring and an inner disc 16 | /// The outer ring of fixed size indicates the state of the spatial anchor by its color: 17 | /// 18 | /// green: support(area of inner circle indicating relevance) 19 | /// red: support with zero relevance 20 | /// yellow: not a support 21 | /// gray: anchor not located(i.e.currently not part of spongy world) 22 | /// 23 | /// The inner disc indicates the relevance of the spongy anchor (0..100%) by its area. 24 | /// 25 | public class SpongyAnchorVisual : MonoBehaviour 26 | { 27 | /// 28 | /// The SpongyAnchor on a separate GameObject for syncing this GameObject's localPose")] 29 | /// 30 | private SpongyAnchor spongyAnchor = null; 31 | 32 | [SerializeField] 33 | [Tooltip("The child object that will have its color controlled")] 34 | private Renderer ringObject = null; 35 | 36 | [SerializeField] 37 | [Tooltip("The child object that will have its scale controlled")] 38 | private GameObject discObject = null; 39 | 40 | [SerializeField] 41 | [Tooltip("The child Text object that will have its color and text controlled")] 42 | private TextMesh textObject = null; 43 | 44 | private Color color; 45 | 46 | /// 47 | /// Set in AnchorGraphVisual. 48 | /// 49 | private float verticalDisplacement = 0; 50 | 51 | /// 52 | /// Create a visualizer for a spongy anchor. 53 | /// 54 | /// Coordinate space to create the visualizer in 55 | /// The spongyAnchor component assigned to some other object that this object is supposed to sync with 56 | /// 57 | public SpongyAnchorVisual Instantiate(FrameVisual parent, SpongyAnchor spongyAnchor, float verticalDisplacement) 58 | { 59 | var res = Instantiate(this, parent.transform); 60 | res.name = spongyAnchor.name; 61 | if (res.textObject != null) 62 | { 63 | res.textObject.text = res.name; 64 | } 65 | res.spongyAnchor = spongyAnchor; 66 | res.color = Color.gray; 67 | res.verticalDisplacement = verticalDisplacement; 68 | return res; 69 | } 70 | 71 | private void Update() 72 | { 73 | var color = this.color; 74 | 75 | // Unity's implementation of spatial anchor adjusts its global transform to track the 76 | // SpatialAnchor coordinate system. Here we want to keep the local transform of the visualization 77 | // towards its parent to track the SpatialAnchor, so we copy the global pose of the anchor to the 78 | // local pose of the visualization object. 79 | // This is because the visualizations tree is rooted at the SpongyFrame, which also contains the camera (and MRTK Playspace). 80 | // The SpongyFrame is adjusted by FrozeWorld every frame. This means that giving a transform M relative to the SpongyFrame, 81 | // as done here, will put the object _relative to the camera_ in the same place as setting M as the world transform 82 | // if SpongyFrame wasn't there, i.e. Unity World Space. 83 | Pose localPose = spongyAnchor.SpongyPose; 84 | localPose.position = new Vector3(localPose.position.x, localPose.position.y + verticalDisplacement, localPose.position.z); 85 | transform.SetLocalPose(localPose); 86 | 87 | if (!spongyAnchor.IsLocated) 88 | color = Color.gray; 89 | 90 | if (ringObject != null) 91 | { 92 | ringObject.material.color = color; 93 | } 94 | if (textObject != null) 95 | { 96 | textObject.color = color; 97 | } 98 | } 99 | 100 | /// 101 | /// Set the relevance, which sets the color. 102 | /// 103 | /// The new relevance 104 | public void SetSupportRelevance(float relevance) 105 | { 106 | if (relevance > 0.0f) 107 | { 108 | color = Color.green; 109 | var rad = (float)Math.Sqrt(relevance); 110 | if (discObject != null) 111 | { 112 | discObject.SetActive(true); 113 | discObject.transform.localScale = new Vector3(rad, 1.0f, rad); 114 | } 115 | } 116 | else 117 | { 118 | color = Color.red; 119 | if (discObject != null) 120 | { 121 | discObject.SetActive(false); 122 | } 123 | } 124 | } 125 | 126 | /// 127 | /// Declare as not being a support. 128 | /// 129 | public void SetNoSupport() 130 | { 131 | color = Color.yellow; 132 | if (discObject != null) 133 | { 134 | discObject.SetActive(false); 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /WorldLocking.Tools/Scripts/AdjusterFixed.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See LICENSE in the project root for license information. 3 | 4 | //#define WLT_EXTRA_DEBUG_ADJUSTER 5 | 6 | using UnityEngine; 7 | 8 | using Microsoft.MixedReality.WorldLocking.Core; 9 | 10 | #if WLT_EXTRA_DEBUG_ADJUSTER 11 | using System.IO; 12 | #endif // WLT_EXTRA_DEBUG_ADJUSTER 13 | 14 | namespace Microsoft.MixedReality.WorldLocking.Tools 15 | { 16 | 17 | /// 18 | /// Component to handle frozen world adjustments for fixed (stationary) objects. 19 | /// 20 | /// 21 | /// For dynamic objects, use . 22 | /// 23 | /// This component is appropriate for inheriting from, to let it take care of 24 | /// lifetime management and book-keeping, then just override 25 | /// and/or with actions more suitable 26 | /// for your application. 27 | /// 28 | public class AdjusterFixed : AdjusterBase 29 | { 30 | /// 31 | /// The attachment point manager interface which this component subscribes to. 32 | /// 33 | protected IAttachmentPointManager Manager { get { return WorldLockingManager.GetInstance().AttachmentPointManager; } } 34 | 35 | /// 36 | /// The attachment point which this component wraps. 37 | /// 38 | protected IAttachmentPoint AttachmentPoint { get; private set; } 39 | 40 | /// 41 | /// Ask the manager for an attachment point, passing delegates for update 42 | /// 43 | private void Start() 44 | { 45 | AttachmentPoint = Manager.CreateAttachmentPoint(gameObject.transform.position, null, 46 | HandleAdjustLocation, // Handle adjustments to position 47 | HandleAdjustState // Handle connectedness of fragment 48 | ); 49 | AttachmentPoint.Name = string.Format($"{gameObject.name}=>{AttachmentPoint.Name}"); 50 | } 51 | 52 | /// 53 | /// Let the manager know the attachment point is freed. 54 | /// 55 | private void OnDestroy() 56 | { 57 | Manager.ReleaseAttachmentPoint(AttachmentPoint); 58 | AttachmentPoint = null; 59 | } 60 | 61 | /// 62 | /// For infrequent moves under script control, UpdatePosition notifies the system that the 63 | /// object has relocated. It should be called after any scripted movement of the object 64 | /// (but **not** after movement triggered by WLT, such as in ). 65 | /// 66 | public void UpdatePosition() 67 | { 68 | if (AttachmentPoint != null) 69 | { 70 | Manager.MoveAttachmentPoint(AttachmentPoint, gameObject.transform.position); 71 | } 72 | } 73 | 74 | /// 75 | /// Handle a pose adjustment due to a refit operation. 76 | /// 77 | /// The pose adjustment to apply/ 78 | /// 79 | /// This simple implementation folds the adjustment into the current pose. 80 | /// 81 | protected virtual void HandleAdjustLocation(Pose adjustment) 82 | { 83 | #if WLT_EXTRA_DEBUG_ADJUSTER 84 | string msg = $"{name}:\n"; 85 | msg += DebugPose("adj", adjustment); 86 | msg += DebugPose("from", transform.GetGlobalPose()); 87 | #endif // WLT_EXTRA_DEBUG_ADJUSTER 88 | 89 | Pose pose = gameObject.transform.GetGlobalPose(); 90 | pose = adjustment.Multiply(pose); 91 | gameObject.transform.SetGlobalPose(pose); 92 | 93 | #if WLT_EXTRA_DEBUG_ADJUSTER 94 | msg += DebugPose("to", transform.GetGlobalPose()); 95 | msg += DebugAttachmentPoint("att", AttachmentPoint); 96 | msg += $"End {name}\n"; 97 | DebugMessage(msg); 98 | #endif // WLT_EXTRA_DEBUG_ADJUSTER 99 | } 100 | 101 | #if WLT_EXTRA_DEBUG_ADJUSTER 102 | private string DebugPose(string label, Pose pose) 103 | { 104 | return $"--- {label} {pose.position.ToString("F3")} {pose.rotation.ToString("F3")}\n"; 105 | } 106 | 107 | private string DebugAttachmentPoint(string label, IAttachmentPoint att) 108 | { 109 | return $"aaa {label} A:{att.AnchorId} F:{att.FragmentId} {att.State} {att.LocationFromAnchor.ToString("F3")}\n"; 110 | } 111 | 112 | private void DebugMessage(string msg) 113 | { 114 | string fileName = "refit.txt"; 115 | fileName = Path.Combine(Application.persistentDataPath, fileName); 116 | using (StreamWriter writer = File.AppendText(fileName)) 117 | { 118 | writer.WriteLine(msg); 119 | writer.Flush(); 120 | } 121 | } 122 | #endif // WLT_EXTRA_DEBUG_ADJUSTER 123 | 124 | /// 125 | /// Handle a change in associated fragment state. 126 | /// 127 | /// The new state. 128 | /// 129 | /// The only state under which the visual location can be regarded as reliable 130 | /// is the Normal state. 131 | /// This simple implementation disables the object tree when its location is unreliable, 132 | /// and enables it when its location is reliable. 133 | /// Actual appropriate behavior is highly application dependent. Some questions to ask: 134 | /// * Is there a more appropriate way to hide the object (e.g. move it far away)? 135 | /// * Should the update pause, or just stop rendering? (Disabling pauses update **and** render). 136 | /// * Is it better to hide the object, or to display it in alternate form? 137 | /// * Etc. 138 | /// 139 | protected virtual void HandleAdjustState(AttachmentPointStateType state) 140 | { 141 | #if WLT_EXTRA_DEBUG_ADJUSTER 142 | DebugMessage($"{name} to state {state}"); 143 | #endif // WLT_EXTRA_DEBUG_ADJUSTER 144 | bool visible = state == AttachmentPointStateType.Normal; 145 | if (visible != gameObject.activeSelf) 146 | { 147 | gameObject.SetActive(visible); 148 | } 149 | } 150 | 151 | } 152 | } --------------------------------------------------------------------------------