public bool SetupForSingleCamera(float left, float right, float top, float bottom)
        {
            List <XRDisplaySubsystem> xrDisplayList = new List <XRDisplaySubsystem>();

            SubsystemManager.GetInstances(xrDisplayList);
            if (xrDisplayList.Count != 1)
            {
                return(false);
            }
            XRDisplaySubsystem display = xrDisplayList[0];

            if (display.GetRenderPassCount() != 1)
            {
                return(false);
            }

            display.GetRenderPass(0, out var renderPass);
            if (renderPass.GetRenderParameterCount() != 1)
            {
                return(false);
            }

            SetProjectionParamsForSingleCamera(left, right, top, bottom);
            Debug.Log($"{PluginMetadata.DebugLogPrefix}Sent single-cam projection parameters to native plugin.");
            return(true);
        }
Example #2
0
        public IEnumerator CombinedFrustum()
        {
            var cameraGO = new GameObject("Test Cam");
            var camera   = cameraGO.AddComponent <Camera>();

            base.InitializeAndStart();
            OpenXRSettings.Instance.renderMode = OpenXRSettings.RenderMode.SinglePassInstanced;

            yield return(null);

            yield return(null);

            var displays = new List <XRDisplaySubsystem>();

            SubsystemManager.GetInstances(displays);

            Assert.That(displays.Count, Is.EqualTo(1));

            Assert.That(displays[0].GetRenderPassCount(), Is.EqualTo(1));

            displays[0].GetRenderPass(0, out var renderPass);

            renderPass.GetRenderParameter(camera, 0, out var renderParam0);
            renderPass.GetRenderParameter(camera, 1, out var renderParam1);
            displays[0].GetCullingParameters(camera, renderPass.cullingPassIndex, out var cullingParams);

            // no sense in re-implementing the combining logic here, just the fact they're different shows that we're not using left eye or right eye for culling.
            Assert.That(cullingParams.stereoViewMatrix, Is.Not.EqualTo(renderParam0.view));
            Assert.That(cullingParams.stereoProjectionMatrix, Is.Not.EqualTo(renderParam0.projection));

            Assert.That(cullingParams.stereoViewMatrix, Is.Not.EqualTo(renderParam1.view));
            Assert.That(cullingParams.stereoProjectionMatrix, Is.Not.EqualTo(renderParam0.projection));

            Object.Destroy(cameraGO);
        }
Example #3
0
    private void OnEnable()
    {
        Debug.Log("XRPlayerLocomotion OnEnable");
        instance = this;

        //Setting Tracking Origin to Floor, default device on Oculus Quest
        var xrInputSubsystems = new List <XRInputSubsystem>();

        SubsystemManager.GetInstances <XRInputSubsystem>(xrInputSubsystems);
        foreach (var ss in xrInputSubsystems)
        {
            if (ss.running)
            {
                ss.TrySetTrackingOriginMode(TrackingOriginModeFlags.Floor);
            }
        }

        teleportLine.enabled = false;

        var xrDisplaySubsystems = new List <XRDisplaySubsystem>();

        SubsystemManager.GetInstances <XRDisplaySubsystem>(xrDisplaySubsystems);
        mouseLook = !xrDisplaySubsystems.Exists(x => x.running);

        teleportCheck = transform.position;

        TransitionState(GroundedState);
    }
Example #4
0
        public override void OnApplicationPause(bool pauseStatus)
        {
            if (m_LoginCompleted != null && pauseStatus == false)
            {
                // Application just returned from tab.
                // Notes on the order when there is a successful login.
                // https://developer.android.com/guide/components/activities/activity-lifecycle
                // When a successful login happens, it triggers in onCreate(), and clears out the m_LoginCompleted field.

                var args = new IdentityLoginCallbackArgs();
                args.error            = new Error();
                args.error.errorClass = ErrorClass.ActionCancelled;

                var appleIdSubsystem = new List <SignInWithApplePlayerIdentitySubsystem>();
                SubsystemManager.GetInstances(appleIdSubsystem);

                appleIdSubsystem[0].m_LoginCompleted(args);
                appleIdSubsystem[0].m_LoginCompleted = null;

                m_LoginCompleted = null;
            }
            if (pauseStatus)
            {
                Application.Quit();
            }
        }
Example #5
0
        private void Start()
        {
            LeftHandInputDevice = new PlayerHandInputDevice(HumanBodyPart.LeftHand, settings);

            RightHandInputDevice = new PlayerHandInputDevice(HumanBodyPart.RightHand, settings);

            SubsystemManager.GetInstances(_subsystems);

            foreach (var inputSubsystem in _subsystems)
            {
                Debug.Log("Detected subsystem " + inputSubsystem.GetType());
                inputSubsystem.TrySetTrackingOriginMode(TrackingOriginModeFlags.Floor);
            }


            if (_subsystems.Count == 0)
            {
                XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale);
                Debug.LogWarning("No Subsystems detected");
            }

            impulse = new byte[20];

            var caps = new HapticCapabilities();

            int clipCount = (int)(caps.bufferFrequencyHz * 2);

            impulse = new byte[clipCount];

            for (int i = 0; i < clipCount; i++)
            {
                impulse[i] = byte.MaxValue;
            }
        }
Example #6
0
        private void UpdateLockPhysicsUpdateRate()
        {
            if (VRModule.lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0.0f)
            {
                List <XRDisplaySubsystem> displaySystems = new List <XRDisplaySubsystem>();
                SubsystemManager.GetInstances <XRDisplaySubsystem>(displaySystems);

                float minRefreshRate = float.MaxValue;
                foreach (XRDisplaySubsystem system in displaySystems)
                {
                    float rate = 60.0f;
                    if (system.TryGetDisplayRefreshRate(out rate))
                    {
                        if (rate < minRefreshRate)
                        {
                            minRefreshRate = rate;
                        }
                    }
                }

                if (minRefreshRate > 0 && minRefreshRate < float.MaxValue)
                {
                    Time.fixedDeltaTime = 1.0f / minRefreshRate;
                }
            }
        }
Example #7
0
        public static void Update(Camera camera)
        {
            #if _XR_MODULE_ENABLED
            SubsystemManager.GetInstances(_displayList);
            #endif

            if (!IsRunning)
            {
                return;
            }

            // Let's cache these values for SPI.
            if (IsSinglePass)
            {
                if (IsNewSDKRunning && Display.GetRenderPassCount() > 0)
                {
                    Display.GetRenderPass(0, out XRDisplaySubsystem.XRRenderPass xrPass);
                    xrPass.GetRenderParameter(camera, 0, out XRDisplaySubsystem.XRRenderParameter xrLeftEye);
                    xrPass.GetRenderParameter(camera, 1, out XRDisplaySubsystem.XRRenderParameter xrRightEye);
                    LeftEyeViewMatrix        = xrLeftEye.view;
                    RightEyeViewMatrix       = xrRightEye.view;
                    LeftEyeProjectionMatrix  = xrLeftEye.projection;
                    RightEyeProjectionMatrix = xrRightEye.projection;
                }
                else
                {
                    LeftEyeViewMatrix        = camera.GetStereoViewMatrix(Camera.StereoscopicEye.Left);
                    RightEyeViewMatrix       = camera.GetStereoViewMatrix(Camera.StereoscopicEye.Right);
                    LeftEyeProjectionMatrix  = camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
                    RightEyeProjectionMatrix = camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
                }
            }
        }
Example #8
0
        void Start()
        {
            var feature = OpenXRSettings.Instance.GetFeature <MeshingTeapotFeature>();

            if (null == feature || feature.enabled == false)
            {
                enabled = false;
                return;
            }

            var meshSubsystems = new List <XRMeshSubsystem>();

            SubsystemManager.GetInstances(meshSubsystems);
            if (meshSubsystems.Count == 1)
            {
                s_MeshSubsystem = meshSubsystems[0];
                textMesh.gameObject.SetActive(false);
            }
            else
            {
#if UNITY_EDITOR
                textMesh.text = "Failed to initialize MeshSubsystem.\nTry reloading the Unity Editor";
#else
                textMesh.text = "Failed to initialize MeshSubsystem.";
#endif
                enabled = false;
            }
        }
Example #9
0
        protected void UpdateLockPhysicsUpdateRate()
        {
            if (VRModule.lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0.0f)
            {
                var displaySystems = ListPool <XRDisplaySubsystem> .Get();

                try
                {
                    SubsystemManager.GetInstances(displaySystems);

                    var minRefreshRate = float.MaxValue;
                    foreach (XRDisplaySubsystem system in displaySystems)
                    {
                        float rate = 60.0f;
                        if (system.TryGetDisplayRefreshRate(out rate))
                        {
                            if (rate < minRefreshRate)
                            {
                                minRefreshRate = rate;
                            }
                        }
                    }

                    if (minRefreshRate > 0 && minRefreshRate < float.MaxValue)
                    {
                        Time.fixedDeltaTime = 1.0f / minRefreshRate;
                    }
                }
                finally { ListPool <XRDisplaySubsystem> .Release(displaySystems); }
            }
        }
Example #10
0
        public void ConnectDependency(MARSSceneModule dependency)
        {
            // List is cleared by GetInstances
            SubsystemManager.GetInstances(k_MarsXRSubsystems);
            m_MarsXRSubscribers.Clear();
            k_SubscriberObjects.Clear();
            foreach (var subsystem in k_MarsXRSubsystems)
            {
                // For most SubsystemLifecycleManagers we can guarantee that if they exist in the scene they have started
                // running their subsystems by this point, since they have lower script execution orders than MARSSession.
                // ARRaycastManager is an exception to this - it has a default execution order. So we make an exception for
                // the raycast subsystem here and assume that it will need a provider.
                // Also for Subsystems before version 3 the image marker subsystem does not report as running.
#if AR_SUBSYSTEMS_3_OR_NEWER
                if (subsystem.running || subsystem is RaycastSubsystem)
#else
                if (subsystem.running || subsystem is RaycastSubsystem || subsystem is ImageMarkerSubsystem)
#endif
                {
                    var subscriber = subsystem.FunctionalitySubscriber;
                    m_MarsXRSubscribers.Add(subscriber);
                    k_SubscriberObjects.Add(subscriber);
                }
            }

            if (k_SubscriberObjects.Count > 0)
            {
                dependency.AddRuntimeSceneObjects(k_SubscriberObjects);
            }
        }
    IEnumerator CheckForXr()
    {
        yield return(XRGeneralSettings.Instance.Manager.InitializeLoader());

        if (XRGeneralSettings.Instance.Manager.activeLoader == null)
        {
            Debug.LogError("Initializing XR Failed. Check Editor or Player log for details.");
        }
        else
        {
            List <XRDisplaySubsystem> displaySubsystems = new List <XRDisplaySubsystem>();

            SubsystemManager.GetInstances <XRDisplaySubsystem>(displaySubsystems);
            foreach (var subsystem in displaySubsystems)
            {
                Debug.Log($"XR SubSystem: {subsystem.SubsystemDescriptor.id}");
            }

            if (true == displaySubsystems?.Count > 0)
            {
                XRGeneralSettings.Instance.Manager.StartSubsystems();
            }

            yield return(null);

            StartCoroutine(ShowCurrentlyAvailableXRDevices());
        }
    }
Example #12
0
        IEnumerator changeOriginModeRoutine(TrackingOriginModeFlags trackingOrigin)
        {
            // Wait one frame as Unity has an issue with calling this immediately
            yield return(null);

            List <XRInputSubsystem> subsystems = new List <XRInputSubsystem>();

            SubsystemManager.GetInstances(subsystems);
            int subSystemsCount = subsystems.Count;

            if (subSystemsCount > 0)
            {
                for (int x = 0; x < subSystemsCount; x++)
                {
                    if (subsystems[x].TrySetTrackingOriginMode(trackingOrigin))
                    {
                        Debug.Log("Successfully set TrackingOriginMode to " + trackingOrigin);
                    }
                    else
                    {
                        Debug.Log("Failed to set TrackingOriginMode to " + trackingOrigin);
                    }
                }
            }
            else
            {
#if UNITY_2020
                Debug.LogWarning("No subsystems detected. Unable to set Tracking Origin to " + trackingOrigin);
#endif
            }
        }
Example #13
0
        void Update()
        {
            XRInputSubsystem subsystem = null;

            SubsystemManager.GetInstances(s_InputSubsystems);
            if (s_InputSubsystems.Count > 0)
            {
                subsystem = s_InputSubsystems[0];
            }

            m_SupportedTrackingOriginModes = subsystem?.GetSupportedTrackingOriginModes() ?? TrackingOriginModeFlags.Unknown;

            if (m_CurrentTrackingOriginMode != m_DesiredTrackingOriginMode & m_DesiredTrackingOriginMode != TrackingOriginModeFlags.Unknown)
            {
                subsystem?.TrySetTrackingOriginMode(m_DesiredTrackingOriginMode);
            }
            m_CurrentTrackingOriginMode = subsystem?.GetTrackingOriginMode() ?? TrackingOriginModeFlags.Unknown;

            if (m_CurrentTrackingOriginModeDisplay != null)
            {
                m_CurrentTrackingOriginModeDisplay.text = m_CurrentTrackingOriginMode.ToString();
            }

            if (m_RecenteredImage != null)
            {
                float lerp = (Time.time - m_LastRecenteredTime) / m_RecenteredColorResetTime;
                lerp = Mathf.Clamp(lerp, 0.0f, 1.0f);
                m_RecenteredImage.color = Color.Lerp(m_RecenteredColor, m_RecenteredOffColor, lerp);
            }
        }
Example #14
0
        XRInputSubsystem GetActiveSubsystemInstance()
        {
            XRInputSubsystem activeSubsystem = null;

#if USE_XR_MANAGEMENT
            // If the XR management package has been included, query the currently
            // active loader for the created subsystem, if one exists.
            if (XRGeneralSettings.Instance != null && XRGeneralSettings.Instance.Manager != null)
            {
                XRLoader loader = XRGeneralSettings.Instance.Manager.activeLoader;
                if (loader != null)
                {
                    activeSubsystem = loader.GetLoadedSubsystem <XRInputSubsystem>();
                }
            }
#endif
            // If XR management is not used or no loader has been set, check for
            // any active subsystem instances in the SubsystemManager.
            if (activeSubsystem == null)
            {
                List <XRInputSubsystem> subsystemInstances = new List <XRInputSubsystem>();
                SubsystemManager.GetInstances(subsystemInstances);
                if (subsystemInstances.Count > 0)
                {
                    activeSubsystem = subsystemInstances[0];
                }
            }

            return(activeSubsystem);
        }
Example #15
0
        private XRInputSubsystemType DetectCurrentInputSubsystemType()
        {
            List <XRInputSubsystem> systems = new List <XRInputSubsystem>();

            SubsystemManager.GetInstances(systems);
            if (systems.Count == 0)
            {
                Debug.LogWarning("No XRInputSubsystem detected.");
                return(XRInputSubsystemType.Unknown);
            }

            string id = systems[0].SubsystemDescriptor.id;

            Debug.Log("Activated XRInputSubsystem Name: " + id);

            if (Regex.IsMatch(id, @"openvr", RegexOptions.IgnoreCase))
            {
                return(XRInputSubsystemType.OpenVR);
            }
            else if (Regex.IsMatch(id, @"oculus", RegexOptions.IgnoreCase))
            {
                return(XRInputSubsystemType.Oculus);
            }
            else if (Regex.IsMatch(id, @"windows mixed reality", RegexOptions.IgnoreCase))
            {
                return(XRInputSubsystemType.WMR);
            }
            else if (Regex.IsMatch(id, @"magicleap", RegexOptions.IgnoreCase))
            {
                return(XRInputSubsystemType.MagicLeap);
            }

            return(XRInputSubsystemType.Unknown);
        }
        /// <inheritdoc/>
        protected override List <Vector3> GetBoundaryGeometry()
        {
            // Boundaries are supported for Room Scale experiences only.
            if (XRSubsystemHelpers.InputSubsystem?.GetTrackingOriginMode() != TrackingOriginModeFlags.Floor)
            {
                return(null);
            }

            // Get the boundary geometry.
            var boundaryGeometry = new List <Vector3>(0);

            if (!XRSubsystemHelpers.InputSubsystem.TryGetBoundaryPoints(boundaryGeometry) || boundaryGeometry.Count == 0)
            {
#if UNITY_2019_3_OR_NEWER
                // If the "main" input subsystem doesn't have an available boundary, check the rest of them
                SubsystemManager.GetInstances(XRInputSubsystems);
                foreach (XRInputSubsystem xrInputSubsystem in XRInputSubsystems)
                {
                    if (xrInputSubsystem.running &&
                        xrInputSubsystem.TryGetBoundaryPoints(boundaryGeometry) &&
                        boundaryGeometry.Count > 0)
                    {
                        return(boundaryGeometry);
                    }
                }
#endif // UNITY_2019_3_OR_NEWER
                return(null);
            }

            return(boundaryGeometry);
        }
Example #17
0
        /// <summary>
        /// Handles re-centering and off-setting the camera in space depending on which tracking space it is setup in.
        /// </summary>
#if UNITY_2019_3_OR_NEWER
        bool SetupCamera()
        {
            SubsystemManager.GetInstances <XRInputSubsystem>(s_InputSubsystems);

            bool initialized = true;

            if (s_InputSubsystems.Count != 0)
            {
                for (int i = 0; i < s_InputSubsystems.Count; i++)
                {
                    initialized &= SetupCamera(s_InputSubsystems[i]);
                }
            }
            else
            {
                // Disable Obsolete warnings for TrackingSpaceType, explicitly to allow a proper upgrade path.
#pragma warning disable 0618

                if (m_RequestedTrackingMode == UserRequestedTrackingMode.Floor)
                {
                    SetupCameraLegacy(TrackingSpaceType.RoomScale);
                }
                else
                {
                    SetupCameraLegacy(TrackingSpaceType.Stationary);
                }

#pragma warning restore 0618
            }

            return(initialized);
        }
Example #18
0
        public static void Update(Camera camera)
        {
#if _XR_ENABLED
            SubsystemManager.GetInstances(_displayList);
#endif

            if (!IsRunning || !IsSinglePass)
            {
                return;
            }

#if _XR_ENABLED
            // XR SPI only has one pass by definition.
            Display.GetRenderPass(renderPassIndex: 0, out XRDisplaySubsystem.XRRenderPass xrPass);
            // Grab left and right eye.
            xrPass.GetRenderParameter(camera, renderParameterIndex: 0, out XRDisplaySubsystem.XRRenderParameter xrLeftEye);
            xrPass.GetRenderParameter(camera, renderParameterIndex: 1, out XRDisplaySubsystem.XRRenderParameter xrRightEye);
            // Store all the matrices.
            LeftEyeViewMatrix                   = xrLeftEye.view;
            RightEyeViewMatrix                  = xrRightEye.view;
            LeftEyeProjectionMatrix             = xrLeftEye.projection;
            RightEyeProjectionMatrix            = xrRightEye.projection;
            LeftEyeViewProjectionMatrix         = LeftEyeProjectionMatrix * LeftEyeViewMatrix;
            RightEyeViewProjectionMatrix        = RightEyeProjectionMatrix * RightEyeViewMatrix;
            LeftEyeInverseViewProjectionMatrix  = LeftEyeViewProjectionMatrix.inverse;
            RightEyeInverseViewProjectionMatrix = RightEyeViewProjectionMatrix.inverse;
#endif
        }
Example #19
0
    public void SetVREnabled(bool enabled)
    {
        List <XRDisplaySubsystem> displaySubsystems = new List <XRDisplaySubsystem>();

        SubsystemManager.GetInstances <XRDisplaySubsystem>(displaySubsystems);
        foreach (var displaysubsys in displaySubsystems)
        {
            if (enabled && !displaysubsys.running)
            {
                displaysubsys.Start();
            }
            else if (!enabled && displaysubsys.running)
            {
                displaysubsys.Stop();
            }
        }
        foreach (var nonvrgo in nonvrOnlyGOs)
        {
            nonvrgo.SetActive(!enabled);
        }
        foreach (var vrgo in vrOnlyGOs)
        {
            vrgo.SetActive(enabled);
        }
    }
Example #20
0
        private void Awake()
        {
            // This is intended for app remoting and shouldn't run in the editor
            if (Application.isEditor)
            {
                DisableConnection2DUI();
                return;
            }

            SubsystemManager.GetInstances(XRDisplaySubsystems);
            foreach (XRDisplaySubsystem xrDisplaySubsystem in XRDisplaySubsystems)
            {
                // If a running XR display is found, assume an XR headset is attached.
                // In this case, don't display the UI, since the app has already launched
                // into an XR experience and it's too late to connect remoting.
                if (xrDisplaySubsystem.running)
                {
                    var connectionValid = Remoting.AppRemoting.TryGetConnectionState(out Remoting.ConnectionState connectionState, out Remoting.DisconnectReason disconnectReason);
                    if (!connectionValid || connectionState == Remoting.ConnectionState.Disconnected)
                    {
                        DisableConnection2DUI();
                    }
                    else
                    {
                        HideConnection2DUI();
                    }

                    return;
                }
            }

            ShowConnection2DUI();
        }
Example #21
0
        public void Recenter()
        {
#if USING_XR_MANAGEMENT
            var subsystems = new List <XRInputSubsystem>();
            SubsystemManager.GetInstances <XRInputSubsystem>(subsystems);

            for (int i = 0; i < subsystems.Count; i++)
            {
                var currentInputSubsystem = subsystems[i];
                if (currentInputSubsystem != null)
                {
                    if (!currentInputSubsystem.TryRecenter())
                    {
                        Debug.Log($"Failed to recenter.");
                    }
                }
            }
#elif !UNITY_2020_1_OR_NEWER
#pragma warning disable 0618
            InputTracking.Recenter();
#pragma warning restore 0618
#endif

            this.ExecuteNextUpdate(() => HMDRecentered.Invoke());
        }
Example #22
0
    private bool IsAnyXRDisplaySubsystemRunning()
    {
        var xrDisplaySubsystems = new List <XRDisplaySubsystem>();

        SubsystemManager.GetInstances(xrDisplaySubsystems);

        return(xrDisplaySubsystems.Any(xrDisplaySubsystem => xrDisplaySubsystem.running));
    }
Example #23
0
 private void OnDestroy()
 {
     SubsystemManager.GetInstances(s_InputSubsystems);
     foreach (var subsystem in s_InputSubsystems)
     {
         subsystem.trackingOriginUpdated -= OnTrackingOriginUpdated;
     }
 }
Example #24
0
 // Start is called before the first frame update
 void Start()
 {
     SubsystemManager.GetInstances(subsystems);
     for (int i = 0; i < subsystems.Count; i++)
     {
         subsystems[i].TrySetTrackingOriginMode(trackingOrigin);
     }
 }
Example #25
0
 private void OnDisable()
 {
     SubsystemManager.GetInstances(s_InputSubsystems);
     for (int i = 0; i < s_InputSubsystems.Count; i++)
     {
         s_InputSubsystems[i].trackingOriginUpdated -= TrackingOriginUpdated;
     }
 }
Example #26
0
        static void GetDisplaySubsystem()
        {
#if UNITY_2020_2_OR_NEWER
            //SubsystemManager.GetSubsystems(displayList);
            SubsystemManager.GetInstances(displayList);
#else
            SubsystemManager.GetInstances(displayList);
#endif
        }
Example #27
0
    public void VerifyXrDevice_IsPresent()
    {
        List <XRDisplaySubsystem> displays = new List <XRDisplaySubsystem>();

        SubsystemManager.GetInstances(displays);

        AssertNotUsingEmulation();
        Assert.IsTrue(displays.Count > 0, "XR Device is not present");
    }
Example #28
0
    void ResetView()
    {
        List <UnityEngine.XR.XRInputSubsystem> subsystems = new List <UnityEngine.XR.XRInputSubsystem>();

        SubsystemManager.GetInstances <UnityEngine.XR.XRInputSubsystem>(subsystems);
        for (int i = 0; i < subsystems.Count; i++)
        {
            subsystems[i].TryRecenter();
        }
    }
Example #29
0
    private void Start()
    {
        lastPos = position;
        InitIgnoreColliders();

        var xrDisplaySubsystems = new List <XRDisplaySubsystem>();

        SubsystemManager.GetInstances <XRDisplaySubsystem>(xrDisplaySubsystems);
        mouseLook = !xrDisplaySubsystems.Exists(x => x.running);
    }
Example #30
0
        void Start()
        {
            List <XRInputSubsystem> subsystems = new List <XRInputSubsystem>();

            SubsystemManager.GetInstances(subsystems);
            for (int i = 0; i < subsystems.Count; i++)
            {
                subsystems[i].TrySetTrackingOriginMode(mode);
            }
        }