using System; using System.Collections; using System.IO; using System.Runtime.InteropServices; using UnityEngine; using Valve.VR; public class SteamVR_Render : MonoBehaviour { public static EVREye eye { get; private set; } public static SteamVR_Render instance { get { if (SteamVR_Render._instance == null) { SteamVR_Render._instance = UnityEngine.Object.FindObjectOfType(); if (SteamVR_Render._instance == null) { SteamVR_Render._instance = new GameObject("[SteamVR]").AddComponent(); } } return SteamVR_Render._instance; } } private void OnDestroy() { SteamVR_Render._instance = null; } private void OnApplicationQuit() { SteamVR_Render.isQuitting = true; SteamVR.SafeDispose(); } public static void Add(SteamVR_Camera vrcam) { if (!SteamVR_Render.isQuitting) { SteamVR_Render.instance.AddInternal(vrcam); } } public static void Remove(SteamVR_Camera vrcam) { if (!SteamVR_Render.isQuitting && SteamVR_Render._instance != null) { SteamVR_Render.instance.RemoveInternal(vrcam); } } public static SteamVR_Camera Top() { if (!SteamVR_Render.isQuitting) { return SteamVR_Render.instance.TopInternal(); } return null; } private void AddInternal(SteamVR_Camera vrcam) { Camera component = vrcam.GetComponent(); int num = this.cameras.Length; SteamVR_Camera[] array = new SteamVR_Camera[num + 1]; int num2 = 0; for (int i = 0; i < num; i++) { Camera component2 = this.cameras[i].GetComponent(); if (i == num2 && component2.depth > component.depth) { array[num2++] = vrcam; } array[num2++] = this.cameras[i]; } if (num2 == num) { array[num2] = vrcam; } this.cameras = array; } private void RemoveInternal(SteamVR_Camera vrcam) { int num = this.cameras.Length; int num2 = 0; for (int i = 0; i < num; i++) { SteamVR_Camera x = this.cameras[i]; if (x == vrcam) { num2++; } } if (num2 == 0) { return; } SteamVR_Camera[] array = new SteamVR_Camera[num - num2]; int num3 = 0; for (int j = 0; j < num; j++) { SteamVR_Camera steamVR_Camera = this.cameras[j]; if (steamVR_Camera != vrcam) { array[num3++] = steamVR_Camera; } } this.cameras = array; } private SteamVR_Camera TopInternal() { if (this.cameras.Length > 0) { return this.cameras[this.cameras.Length - 1]; } return null; } public static bool pauseRendering { get { return SteamVR_Render._pauseRendering; } set { SteamVR_Render._pauseRendering = value; CVRCompositor compositor = OpenVR.Compositor; if (compositor != null) { compositor.SuspendRendering(value); } } } private IEnumerator RenderLoop() { for (;;) { yield return new WaitForEndOfFrame(); if (!SteamVR_Render.pauseRendering) { CVRCompositor compositor = OpenVR.Compositor; if (compositor != null) { if (!compositor.CanRenderScene()) { continue; } compositor.SetTrackingSpace(this.trackingSpace); } SteamVR_Overlay overlay = SteamVR_Overlay.instance; if (overlay != null) { overlay.UpdateOverlay(); } this.RenderExternalCamera(); } } yield break; } private void RenderExternalCamera() { if (this.externalCamera == null) { return; } if (!this.externalCamera.gameObject.activeInHierarchy) { return; } int num = (int)Mathf.Max(this.externalCamera.config.frameSkip, 0f); if (Time.frameCount % (num + 1) != 0) { return; } this.externalCamera.AttachToCamera(this.TopInternal()); this.externalCamera.RenderNear(); this.externalCamera.RenderFar(); } private void OnInputFocus(params object[] args) { bool flag = (bool)args[0]; if (flag) { if (this.pauseGameWhenDashboardIsVisible) { Time.timeScale = this.timeScale; } SteamVR_Camera.sceneResolutionScale = this.sceneResolutionScale; } else { if (this.pauseGameWhenDashboardIsVisible) { this.timeScale = Time.timeScale; Time.timeScale = 0f; } this.sceneResolutionScale = SteamVR_Camera.sceneResolutionScale; SteamVR_Camera.sceneResolutionScale = 0.5f; } } private void OnQuit(params object[] args) { Application.Quit(); } private void OnEnable() { base.StartCoroutine("RenderLoop"); SteamVR_Utils.Event.Listen("input_focus", new SteamVR_Utils.Event.Handler(this.OnInputFocus)); SteamVR_Utils.Event.Listen("Quit", new SteamVR_Utils.Event.Handler(this.OnQuit)); } private void OnDisable() { base.StopAllCoroutines(); SteamVR_Utils.Event.Remove("input_focus", new SteamVR_Utils.Event.Handler(this.OnInputFocus)); SteamVR_Utils.Event.Remove("Quit", new SteamVR_Utils.Event.Handler(this.OnQuit)); } private void Awake() { if (this.externalCamera == null && File.Exists(this.externalCameraConfigPath)) { GameObject original = Resources.Load("SteamVR_ExternalCamera"); GameObject gameObject = UnityEngine.Object.Instantiate(original); gameObject.gameObject.name = "External Camera"; this.externalCamera = gameObject.transform.GetChild(0).GetComponent(); this.externalCamera.configPath = this.externalCameraConfigPath; this.externalCamera.ReadConfig(); } } private void FixedUpdate() { } private void Update() { if (this.poseUpdater == null) { this.poseUpdater = new GameObject("poseUpdater") { transform = { parent = base.transform } }.AddComponent(); } SteamVR_Controller.Update(); CVRSystem system = OpenVR.System; if (system != null) { VREvent_t vrevent_t = default(VREvent_t); uint uncbVREvent = (uint)Marshal.SizeOf(typeof(VREvent_t)); for (int i = 0; i < 64; i++) { if (!system.PollNextEvent(ref vrevent_t, uncbVREvent)) { break; } EVREventType eventType = (EVREventType)vrevent_t.eventType; if (eventType != EVREventType.VREvent_InputFocusCaptured) { if (eventType != EVREventType.VREvent_InputFocusReleased) { if (eventType != EVREventType.VREvent_HideRenderModels) { if (eventType != EVREventType.VREvent_ShowRenderModels) { string name = Enum.GetName(typeof(EVREventType), vrevent_t.eventType); if (name != null) { SteamVR_Utils.Event.Send(name.Substring(8), new object[] { vrevent_t }); } } else { SteamVR_Utils.Event.Send("hide_render_models", new object[] { false }); } } else { SteamVR_Utils.Event.Send("hide_render_models", new object[] { true }); } } else if (vrevent_t.data.process.pid == 0u) { SteamVR_Utils.Event.Send("input_focus", new object[] { true }); } } else if (vrevent_t.data.process.oldPid == 0u) { SteamVR_Utils.Event.Send("input_focus", new object[] { false }); } } } Application.targetFrameRate = -1; Application.runInBackground = true; QualitySettings.maxQueuedFrames = -1; QualitySettings.vSyncCount = 0; if (this.lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0f) { SteamVR instance = SteamVR.instance; if (instance != null) { Compositor_FrameTiming compositor_FrameTiming = default(Compositor_FrameTiming); compositor_FrameTiming.m_nSize = (uint)Marshal.SizeOf(typeof(Compositor_FrameTiming)); instance.compositor.GetFrameTiming(ref compositor_FrameTiming, 0u); Time.fixedDeltaTime = Time.timeScale / instance.hmd_DisplayFrequency; Time.maximumDeltaTime = Time.fixedDeltaTime * compositor_FrameTiming.m_nNumFramePresents; } } } public bool pauseGameWhenDashboardIsVisible = true; public bool lockPhysicsUpdateRateToRenderFrequency = true; public SteamVR_ExternalCamera externalCamera; public string externalCameraConfigPath = "externalcamera.cfg"; public ETrackingUniverseOrigin trackingSpace = ETrackingUniverseOrigin.TrackingUniverseStanding; private static SteamVR_Render _instance; private static bool isQuitting; private SteamVR_Camera[] cameras = new SteamVR_Camera[0]; public TrackedDevicePose_t[] poses = new TrackedDevicePose_t[16]; public TrackedDevicePose_t[] gamePoses = new TrackedDevicePose_t[0]; private static bool _pauseRendering; private float sceneResolutionScale = 1f; private float timeScale = 1f; private SteamVR_UpdatePoses poseUpdater; }