You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			502 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			502 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C#
		
	
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
 | 
						|
//
 | 
						|
// Purpose: Helper for smoothing over transitions between levels.
 | 
						|
//
 | 
						|
//=============================================================================
 | 
						|
 | 
						|
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
using Valve.VR;
 | 
						|
using System.IO;
 | 
						|
 | 
						|
namespace Valve.VR
 | 
						|
{
 | 
						|
    public class SteamVR_LoadLevel : MonoBehaviour
 | 
						|
    {
 | 
						|
        private static SteamVR_LoadLevel _active = null;
 | 
						|
        public static bool loading { get { return _active != null; } }
 | 
						|
        public static float progress
 | 
						|
        {
 | 
						|
            get { return (_active != null && _active.async != null) ? _active.async.progress : 0.0f; }
 | 
						|
        }
 | 
						|
        public static Texture progressTexture
 | 
						|
        {
 | 
						|
            get { return (_active != null) ? _active.renderTexture : null; }
 | 
						|
        }
 | 
						|
 | 
						|
        // Name of level to load.
 | 
						|
        public string levelName;
 | 
						|
 | 
						|
        // Name of internal process to launch (instead of levelName).
 | 
						|
        public string internalProcessPath;
 | 
						|
 | 
						|
        // The command-line args for the internal process to launch.
 | 
						|
        public string internalProcessArgs;
 | 
						|
 | 
						|
        // If true, call LoadLevelAdditiveAsync instead of LoadLevelAsync.
 | 
						|
        public bool loadAdditive;
 | 
						|
 | 
						|
        // Async load causes crashes in some apps.
 | 
						|
        public bool loadAsync = true;
 | 
						|
 | 
						|
        // Optional logo texture.
 | 
						|
        public Texture loadingScreen;
 | 
						|
 | 
						|
        // Optional progress bar textures.
 | 
						|
        public Texture progressBarEmpty, progressBarFull;
 | 
						|
 | 
						|
        // Sizes of overlays.
 | 
						|
        public float loadingScreenWidthInMeters = 6.0f;
 | 
						|
        public float progressBarWidthInMeters = 3.0f;
 | 
						|
 | 
						|
        // If specified, the loading screen will be positioned in the player's view this far away.
 | 
						|
        public float loadingScreenDistance = 0.0f;
 | 
						|
 | 
						|
        // Optional overrides for where to display loading screen and progress bar overlays.
 | 
						|
        // Otherwise defaults to using this object's transform.
 | 
						|
        public Transform loadingScreenTransform, progressBarTransform;
 | 
						|
 | 
						|
        // Optional skybox override textures.
 | 
						|
        public Texture front, back, left, right, top, bottom;
 | 
						|
 | 
						|
        // Colors to use when dropping to the compositor between levels if no skybox is set.
 | 
						|
        public Color backgroundColor = Color.black;
 | 
						|
 | 
						|
        // If false, the background color above gets applied as the foreground color in the compositor.
 | 
						|
        // This does not have any effect when using a skybox instead.
 | 
						|
        public bool showGrid = false;
 | 
						|
 | 
						|
        // Time to fade from current scene to the compositor and back.
 | 
						|
        public float fadeOutTime = 0.5f;
 | 
						|
        public float fadeInTime = 0.5f;
 | 
						|
 | 
						|
        // Additional time to wait after finished loading before we start fading the new scene back in.
 | 
						|
        // This is to cover up any initial hitching that takes place right at the start of levels.
 | 
						|
        // Most scenes should hopefully not require this.
 | 
						|
        public float postLoadSettleTime = 0.0f;
 | 
						|
 | 
						|
        // Time to fade loading screen in and out (also used for progress bar).
 | 
						|
        public float loadingScreenFadeInTime = 1.0f;
 | 
						|
        public float loadingScreenFadeOutTime = 0.25f;
 | 
						|
 | 
						|
        float fadeRate = 1.0f;
 | 
						|
        float alpha = 0.0f;
 | 
						|
 | 
						|
        AsyncOperation async; // used to track level load progress
 | 
						|
        RenderTexture renderTexture; // used to render progress bar
 | 
						|
 | 
						|
        ulong loadingScreenOverlayHandle = OpenVR.k_ulOverlayHandleInvalid;
 | 
						|
        ulong progressBarOverlayHandle = OpenVR.k_ulOverlayHandleInvalid;
 | 
						|
 | 
						|
        public bool autoTriggerOnEnable = false;
 | 
						|
 | 
						|
        void OnEnable()
 | 
						|
        {
 | 
						|
            if (autoTriggerOnEnable)
 | 
						|
                Trigger();
 | 
						|
        }
 | 
						|
 | 
						|
        public void Trigger()
 | 
						|
        {
 | 
						|
            if (!loading && !string.IsNullOrEmpty(levelName))
 | 
						|
                StartCoroutine(LoadLevel());
 | 
						|
        }
 | 
						|
 | 
						|
        // Helper function to quickly and simply load a level from script.
 | 
						|
        public static void Begin(string levelName,
 | 
						|
            bool showGrid = false, float fadeOutTime = 0.5f,
 | 
						|
            float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 1.0f)
 | 
						|
        {
 | 
						|
            var loader = new GameObject("loader").AddComponent<SteamVR_LoadLevel>();
 | 
						|
            loader.levelName = levelName;
 | 
						|
            loader.showGrid = showGrid;
 | 
						|
            loader.fadeOutTime = fadeOutTime;
 | 
						|
            loader.backgroundColor = new Color(r, g, b, a);
 | 
						|
            loader.Trigger();
 | 
						|
        }
 | 
						|
 | 
						|
        // Updates progress bar.
 | 
						|
        void OnGUI()
 | 
						|
        {
 | 
						|
            if (_active != this)
 | 
						|
                return;
 | 
						|
 | 
						|
            // Optionally create an overlay for our progress bar to use, separate from the loading screen.
 | 
						|
            if (progressBarEmpty != null && progressBarFull != null)
 | 
						|
            {
 | 
						|
                if (progressBarOverlayHandle == OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                    progressBarOverlayHandle = GetOverlayHandle("progressBar", progressBarTransform != null ? progressBarTransform : transform, progressBarWidthInMeters);
 | 
						|
 | 
						|
                if (progressBarOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                {
 | 
						|
                    var progress = (async != null) ? async.progress : 0.0f;
 | 
						|
 | 
						|
                    // Use the full bar size for everything.
 | 
						|
                    var w = progressBarFull.width;
 | 
						|
                    var h = progressBarFull.height;
 | 
						|
 | 
						|
                    // Create a separate render texture so we can composite the full image on top of the empty one.
 | 
						|
                    if (renderTexture == null)
 | 
						|
                    {
 | 
						|
                        renderTexture = new RenderTexture(w, h, 0);
 | 
						|
                        renderTexture.Create();
 | 
						|
                    }
 | 
						|
 | 
						|
                    var prevActive = RenderTexture.active;
 | 
						|
                    RenderTexture.active = renderTexture;
 | 
						|
 | 
						|
                    if (Event.current.type == EventType.Repaint)
 | 
						|
                        GL.Clear(false, true, Color.clear);
 | 
						|
 | 
						|
                    GUILayout.BeginArea(new Rect(0, 0, w, h));
 | 
						|
 | 
						|
                    GUI.DrawTexture(new Rect(0, 0, w, h), progressBarEmpty);
 | 
						|
 | 
						|
                    // Reveal the full bar texture based on progress.
 | 
						|
                    GUI.DrawTextureWithTexCoords(new Rect(0, 0, progress * w, h), progressBarFull, new Rect(0.0f, 0.0f, progress, 1.0f));
 | 
						|
 | 
						|
                    GUILayout.EndArea();
 | 
						|
 | 
						|
                    RenderTexture.active = prevActive;
 | 
						|
 | 
						|
                    // Texture needs to be set every frame after it is updated since SteamVR makes a copy internally to a shared texture.
 | 
						|
                    var overlay = OpenVR.Overlay;
 | 
						|
                    if (overlay != null)
 | 
						|
                    {
 | 
						|
                        var texture = new Texture_t();
 | 
						|
                        texture.handle = renderTexture.GetNativeTexturePtr();
 | 
						|
                        texture.eType = SteamVR.instance.textureType;
 | 
						|
                        texture.eColorSpace = EColorSpace.Auto;
 | 
						|
                        overlay.SetOverlayTexture(progressBarOverlayHandle, ref texture);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
#if false
 | 
						|
		// Draw loading screen and progress bar to 2d companion window as well.
 | 
						|
		if (loadingScreen != null)
 | 
						|
		{
 | 
						|
			var screenAspect = (float)Screen.width / Screen.height;
 | 
						|
			var textureAspect = (float)loadingScreen.width / loadingScreen.height;
 | 
						|
 | 
						|
			float w, h;
 | 
						|
			if (screenAspect < textureAspect)
 | 
						|
			{
 | 
						|
				// Clamp horizontally
 | 
						|
				w = Screen.width * 0.9f;
 | 
						|
				h = w / textureAspect;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				// Clamp vertically
 | 
						|
				h = Screen.height * 0.9f;
 | 
						|
				w = h * textureAspect;
 | 
						|
			}
 | 
						|
 | 
						|
			GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height));
 | 
						|
 | 
						|
			var x = Screen.width / 2 - w / 2;
 | 
						|
			var y = Screen.height / 2 - h / 2;
 | 
						|
			GUI.DrawTexture(new Rect(x, y, w, h), loadingScreen);
 | 
						|
 | 
						|
			GUILayout.EndArea();
 | 
						|
		}
 | 
						|
 | 
						|
		if (renderTexture != null)
 | 
						|
		{
 | 
						|
			var x = Screen.width / 2 - renderTexture.width / 2;
 | 
						|
			var y = Screen.height * 0.9f - renderTexture.height;
 | 
						|
			GUI.DrawTexture(new Rect(x, y, renderTexture.width, renderTexture.height), renderTexture);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
        }
 | 
						|
 | 
						|
        // Fade our overlays in/out over time.
 | 
						|
        void Update()
 | 
						|
        {
 | 
						|
            if (_active != this)
 | 
						|
                return;
 | 
						|
 | 
						|
            alpha = Mathf.Clamp01(alpha + fadeRate * Time.deltaTime);
 | 
						|
 | 
						|
            var overlay = OpenVR.Overlay;
 | 
						|
            if (overlay != null)
 | 
						|
            {
 | 
						|
                if (loadingScreenOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                    overlay.SetOverlayAlpha(loadingScreenOverlayHandle, alpha);
 | 
						|
 | 
						|
                if (progressBarOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                    overlay.SetOverlayAlpha(progressBarOverlayHandle, alpha);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Corourtine to handle all the steps across loading boundaries.
 | 
						|
        IEnumerator LoadLevel()
 | 
						|
        {
 | 
						|
            // Optionally rotate loading screen transform around the camera into view.
 | 
						|
            // We assume here that the loading screen is already facing toward the origin,
 | 
						|
            // and that the progress bar transform (if any) is a child and will follow along.
 | 
						|
            if (loadingScreen != null && loadingScreenDistance > 0.0f)
 | 
						|
            {
 | 
						|
                Transform hmd = this.transform;
 | 
						|
                if (Camera.main != null)
 | 
						|
                    hmd = Camera.main.transform;
 | 
						|
 | 
						|
                Quaternion rot = Quaternion.Euler(0.0f, hmd.eulerAngles.y, 0.0f);
 | 
						|
                Vector3 pos = hmd.position + (rot * new Vector3(0.0f, 0.0f, loadingScreenDistance));
 | 
						|
 | 
						|
                var t = loadingScreenTransform != null ? loadingScreenTransform : transform;
 | 
						|
                t.position = pos;
 | 
						|
                t.rotation = rot;
 | 
						|
            }
 | 
						|
 | 
						|
            _active = this;
 | 
						|
 | 
						|
            SteamVR_Events.Loading.Send(true);
 | 
						|
 | 
						|
            // Calculate rate for fading in loading screen and progress bar.
 | 
						|
            if (loadingScreenFadeInTime > 0.0f)
 | 
						|
            {
 | 
						|
                fadeRate = 1.0f / loadingScreenFadeInTime;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                alpha = 1.0f;
 | 
						|
            }
 | 
						|
 | 
						|
            var overlay = OpenVR.Overlay;
 | 
						|
 | 
						|
            // Optionally create our loading screen overlay.
 | 
						|
            if (loadingScreen != null && overlay != null)
 | 
						|
            {
 | 
						|
                loadingScreenOverlayHandle = GetOverlayHandle("loadingScreen", loadingScreenTransform != null ? loadingScreenTransform : transform, loadingScreenWidthInMeters);
 | 
						|
                if (loadingScreenOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                {
 | 
						|
                    var texture = new Texture_t();
 | 
						|
                    texture.handle = loadingScreen.GetNativeTexturePtr();
 | 
						|
                    texture.eType = SteamVR.instance.textureType;
 | 
						|
                    texture.eColorSpace = EColorSpace.Auto;
 | 
						|
                    overlay.SetOverlayTexture(loadingScreenOverlayHandle, ref texture);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            bool fadedForeground = false;
 | 
						|
 | 
						|
            // Fade out to compositor
 | 
						|
            SteamVR_Events.LoadingFadeOut.Send(fadeOutTime);
 | 
						|
 | 
						|
            // Optionally set a skybox to use as a backdrop in the compositor.
 | 
						|
            var compositor = OpenVR.Compositor;
 | 
						|
            if (compositor != null)
 | 
						|
            {
 | 
						|
                if (front != null)
 | 
						|
                {
 | 
						|
                    SteamVR_Skybox.SetOverride(front, back, left, right, top, bottom);
 | 
						|
 | 
						|
                    // Explicitly fade to the compositor since loading will cause us to stop rendering.
 | 
						|
                    compositor.FadeGrid(fadeOutTime, true);
 | 
						|
                    yield return new WaitForSeconds(fadeOutTime);
 | 
						|
                }
 | 
						|
                else if (backgroundColor != Color.clear)
 | 
						|
                {
 | 
						|
                    // Otherwise, use the specified background color.
 | 
						|
                    if (showGrid)
 | 
						|
                    {
 | 
						|
                        // Set compositor background color immediately, and start fading to it.
 | 
						|
                        compositor.FadeToColor(0.0f, backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a, true);
 | 
						|
                        compositor.FadeGrid(fadeOutTime, true);
 | 
						|
                        yield return new WaitForSeconds(fadeOutTime);
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        // Fade the foreground color in (which will blend on top of the scene), and then cut to the compositor.
 | 
						|
                        compositor.FadeToColor(fadeOutTime, backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a, false);
 | 
						|
                        yield return new WaitForSeconds(fadeOutTime + 0.1f);
 | 
						|
                        compositor.FadeGrid(0.0f, true);
 | 
						|
                        fadedForeground = true;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            // Now that we're fully faded out, we can stop submitting frames to the compositor.
 | 
						|
            SteamVR_Render.pauseRendering = true;
 | 
						|
 | 
						|
            // Continue waiting for the overlays to fully fade in before continuing.
 | 
						|
            while (alpha < 1.0f)
 | 
						|
                yield return null;
 | 
						|
 | 
						|
            // Keep us from getting destroyed when loading the new level, otherwise this coroutine will get stopped prematurely.
 | 
						|
            transform.parent = null;
 | 
						|
            DontDestroyOnLoad(gameObject);
 | 
						|
 | 
						|
            if (!string.IsNullOrEmpty(internalProcessPath))
 | 
						|
            {
 | 
						|
                Debug.Log("<b>[SteamVR]</b> Launching external application...");
 | 
						|
                var applications = OpenVR.Applications;
 | 
						|
                if (applications == null)
 | 
						|
                {
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> Failed to get OpenVR.Applications interface!");
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    var workingDirectory = Directory.GetCurrentDirectory();
 | 
						|
                    var fullPath = Path.Combine(workingDirectory, internalProcessPath);
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> LaunchingInternalProcess");
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> ExternalAppPath = " + internalProcessPath);
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> FullPath = " + fullPath);
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> ExternalAppArgs = " + internalProcessArgs);
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> WorkingDirectory = " + workingDirectory);
 | 
						|
                    var error = applications.LaunchInternalProcess(fullPath, internalProcessArgs, workingDirectory);
 | 
						|
                    Debug.Log("<b>[SteamVR]</b> LaunchInternalProcessError: " + error);
 | 
						|
#if UNITY_EDITOR
 | 
						|
                    UnityEditor.EditorApplication.isPlaying = false;
 | 
						|
#elif !UNITY_METRO
 | 
						|
				System.Diagnostics.Process.GetCurrentProcess().Kill();
 | 
						|
#endif
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                var mode = loadAdditive ? UnityEngine.SceneManagement.LoadSceneMode.Additive : UnityEngine.SceneManagement.LoadSceneMode.Single;
 | 
						|
                if (loadAsync)
 | 
						|
                {
 | 
						|
                    Application.backgroundLoadingPriority = ThreadPriority.Low;
 | 
						|
                    async = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(levelName, mode);
 | 
						|
 | 
						|
                    // Performing this in a while loop instead seems to help smooth things out.
 | 
						|
                    //yield return async;
 | 
						|
                    while (!async.isDone)
 | 
						|
                    {
 | 
						|
                        yield return null;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    UnityEngine.SceneManagement.SceneManager.LoadScene(levelName, mode);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            yield return null;
 | 
						|
 | 
						|
            System.GC.Collect();
 | 
						|
 | 
						|
            yield return null;
 | 
						|
 | 
						|
            Shader.WarmupAllShaders();
 | 
						|
 | 
						|
            // Optionally wait a short period of time after loading everything back in, but before we start rendering again
 | 
						|
            // in order to give everything a change to settle down to avoid any hitching at the start of the new level.
 | 
						|
            yield return new WaitForSeconds(postLoadSettleTime);
 | 
						|
 | 
						|
            SteamVR_Render.pauseRendering = false;
 | 
						|
 | 
						|
            // Fade out loading screen.
 | 
						|
            if (loadingScreenFadeOutTime > 0.0f)
 | 
						|
            {
 | 
						|
                fadeRate = -1.0f / loadingScreenFadeOutTime;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                alpha = 0.0f;
 | 
						|
            }
 | 
						|
 | 
						|
            // Fade out to compositor
 | 
						|
            SteamVR_Events.LoadingFadeIn.Send(fadeInTime);
 | 
						|
 | 
						|
            // Refresh compositor reference since loading scenes might have invalidated it.
 | 
						|
            compositor = OpenVR.Compositor;
 | 
						|
            if (compositor != null)
 | 
						|
            {
 | 
						|
                // Fade out foreground color if necessary.
 | 
						|
                if (fadedForeground)
 | 
						|
                {
 | 
						|
                    compositor.FadeGrid(0.0f, false);
 | 
						|
                    compositor.FadeToColor(fadeInTime, 0.0f, 0.0f, 0.0f, 0.0f, false);
 | 
						|
                    yield return new WaitForSeconds(fadeInTime);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    // Fade scene back in, and reset skybox once no longer visible.
 | 
						|
                    compositor.FadeGrid(fadeInTime, false);
 | 
						|
                    yield return new WaitForSeconds(fadeInTime);
 | 
						|
 | 
						|
                    if (front != null)
 | 
						|
                    {
 | 
						|
                        SteamVR_Skybox.ClearOverride();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            // Finally, stick around long enough for our overlays to fully fade out.
 | 
						|
            while (alpha > 0.0f)
 | 
						|
                yield return null;
 | 
						|
 | 
						|
            if (overlay != null)
 | 
						|
            {
 | 
						|
                if (progressBarOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                    overlay.HideOverlay(progressBarOverlayHandle);
 | 
						|
                if (loadingScreenOverlayHandle != OpenVR.k_ulOverlayHandleInvalid)
 | 
						|
                    overlay.HideOverlay(loadingScreenOverlayHandle);
 | 
						|
            }
 | 
						|
 | 
						|
            Destroy(gameObject);
 | 
						|
 | 
						|
            _active = null;
 | 
						|
 | 
						|
            SteamVR_Events.Loading.Send(false);
 | 
						|
        }
 | 
						|
 | 
						|
        // Helper to create (or reuse if possible) each of our different overlay types.
 | 
						|
        ulong GetOverlayHandle(string overlayName, Transform transform, float widthInMeters = 1.0f)
 | 
						|
        {
 | 
						|
            ulong handle = OpenVR.k_ulOverlayHandleInvalid;
 | 
						|
 | 
						|
            var overlay = OpenVR.Overlay;
 | 
						|
            if (overlay == null)
 | 
						|
                return handle;
 | 
						|
 | 
						|
            var key = SteamVR_Overlay.key + "." + overlayName;
 | 
						|
 | 
						|
            var error = overlay.FindOverlay(key, ref handle);
 | 
						|
            if (error != EVROverlayError.None)
 | 
						|
                error = overlay.CreateOverlay(key, overlayName, ref handle);
 | 
						|
            if (error == EVROverlayError.None)
 | 
						|
            {
 | 
						|
                overlay.ShowOverlay(handle);
 | 
						|
                overlay.SetOverlayAlpha(handle, alpha);
 | 
						|
                overlay.SetOverlayWidthInMeters(handle, widthInMeters);
 | 
						|
 | 
						|
                // D3D textures are upside-down in Unity to match OpenGL.
 | 
						|
                if (SteamVR.instance.textureType == ETextureType.DirectX)
 | 
						|
                {
 | 
						|
                    var textureBounds = new VRTextureBounds_t();
 | 
						|
                    textureBounds.uMin = 0;
 | 
						|
                    textureBounds.vMin = 1;
 | 
						|
                    textureBounds.uMax = 1;
 | 
						|
                    textureBounds.vMax = 0;
 | 
						|
                    overlay.SetOverlayTextureBounds(handle, ref textureBounds);
 | 
						|
                }
 | 
						|
 | 
						|
                // Convert from world space to tracking space using the top-most camera.
 | 
						|
                var vrcam = (loadingScreenDistance == 0.0f) ? SteamVR_Render.Top() : null;
 | 
						|
                if (vrcam != null && vrcam.origin != null)
 | 
						|
                {
 | 
						|
                    var offset = new SteamVR_Utils.RigidTransform(vrcam.origin, transform);
 | 
						|
                    offset.pos.x /= vrcam.origin.localScale.x;
 | 
						|
                    offset.pos.y /= vrcam.origin.localScale.y;
 | 
						|
                    offset.pos.z /= vrcam.origin.localScale.z;
 | 
						|
 | 
						|
                    var t = offset.ToHmdMatrix34();
 | 
						|
                    overlay.SetOverlayTransformAbsolute(handle, SteamVR.settings.trackingSpace, ref t);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    var t = new SteamVR_Utils.RigidTransform(transform).ToHmdMatrix34();
 | 
						|
                    overlay.SetOverlayTransformAbsolute(handle, SteamVR.settings.trackingSpace, ref t);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return handle;
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |