8 using System.Collections;
13 public bool pauseGameWhenDashboardIsVisible =
true;
14 public bool lockPhysicsUpdateRateToRenderFrequency =
true;
17 public string externalCameraConfigPath =
"externalcamera.cfg";
19 public ETrackingUniverseOrigin trackingSpace = ETrackingUniverseOrigin.TrackingUniverseStanding;
21 static public EVREye eye {
get;
private set; }
28 if (_instance == null)
32 if (_instance == null)
33 _instance =
new GameObject(
"[SteamVR]").AddComponent<
SteamVR_Render>();
44 static private bool isQuitting;
45 void OnApplicationQuit()
48 SteamVR.SafeDispose();
54 instance.AddInternal(vrcam);
59 if (!isQuitting && _instance != null)
60 instance.RemoveInternal(vrcam);
66 return instance.TopInternal();
75 var camera = vrcam.GetComponent<Camera>();
76 var length = cameras.Length;
79 for (
int i = 0; i < length; i++)
81 var c = cameras[i].GetComponent<Camera>();
82 if (i == insert && c.depth > camera.depth)
83 sorted[insert++] = vrcam;
85 sorted[insert++] = cameras[i];
88 sorted[insert] = vrcam;
95 var length = cameras.Length;
97 for (
int i = 0; i < length; i++)
108 for (
int i = 0; i < length; i++)
112 sorted[insert++] = c;
120 if (cameras.Length > 0)
121 return cameras[cameras.Length - 1];
129 static private bool _pauseRendering;
130 static public bool pauseRendering
132 get {
return _pauseRendering; }
135 _pauseRendering = value;
137 var compositor = OpenVR.Compositor;
138 if (compositor != null)
139 compositor.SuspendRendering(value);
143 private WaitForEndOfFrame waitForEndOfFrame =
new WaitForEndOfFrame();
145 private IEnumerator RenderLoop()
147 while (Application.isPlaying)
149 yield
return waitForEndOfFrame;
154 var compositor = OpenVR.Compositor;
155 if (compositor != null)
157 if (!compositor.CanRenderScene())
160 compositor.SetTrackingSpace(trackingSpace);
163 var overlay = SteamVR_Overlay.instance;
165 overlay.UpdateOverlay();
167 RenderExternalCamera();
171 void RenderExternalCamera()
173 if (externalCamera == null)
176 if (!externalCamera.gameObject.activeInHierarchy)
179 var frameSkip = (int)Mathf.Max(externalCamera.config.frameSkip, 0.0f);
180 if (Time.frameCount % (frameSkip + 1) != 0)
184 externalCamera.AttachToCamera(TopInternal());
186 externalCamera.RenderNear();
187 externalCamera.RenderFar();
190 float sceneResolutionScale = 1.0f, timeScale = 1.0f;
192 private void OnInputFocus(
bool hasFocus)
196 if (pauseGameWhenDashboardIsVisible)
198 Time.timeScale = timeScale;
201 SteamVR_Camera.sceneResolutionScale = sceneResolutionScale;
205 if (pauseGameWhenDashboardIsVisible)
207 timeScale = Time.timeScale;
208 Time.timeScale = 0.0f;
211 sceneResolutionScale = SteamVR_Camera.sceneResolutionScale;
212 SteamVR_Camera.sceneResolutionScale = 0.5f;
219 foreach (System.Reflection.Assembly a in System.AppDomain.CurrentDomain.GetAssemblies())
221 var t = a.GetType(
"UnityEditor.EditorApplication");
224 t.GetProperty(
"isPlaying").SetValue(null,
false, null);
233 private string GetScreenshotFilename(uint screenshotHandle, EVRScreenshotPropertyFilenames screenshotPropertyFilename)
235 var error = EVRScreenshotError.None;
236 var capacity = OpenVR.Screenshots.GetScreenshotPropertyFilename(screenshotHandle, screenshotPropertyFilename, null, 0, ref error);
237 if (error != EVRScreenshotError.None && error != EVRScreenshotError.BufferTooSmall)
241 var result =
new System.Text.StringBuilder((int)capacity);
242 OpenVR.Screenshots.GetScreenshotPropertyFilename(screenshotHandle, screenshotPropertyFilename, result, capacity, ref error);
243 if (error != EVRScreenshotError.None)
245 return result.ToString();
250 private void OnRequestScreenshot(
VREvent_t vrEvent)
252 var screenshotHandle = vrEvent.data.screenshot.handle;
253 var screenshotType = (EVRScreenshotType)vrEvent.data.screenshot.type;
255 if (screenshotType == EVRScreenshotType.StereoPanorama)
257 string previewFilename = GetScreenshotFilename(screenshotHandle, EVRScreenshotPropertyFilenames.Preview);
258 string VRFilename = GetScreenshotFilename(screenshotHandle, EVRScreenshotPropertyFilenames.VR);
260 if (previewFilename == null || VRFilename == null)
265 GameObject screenshotPosition =
new GameObject(
"screenshotPosition");
266 screenshotPosition.transform.position = SteamVR_Render.Top().transform.position;
267 screenshotPosition.transform.rotation =
SteamVR_Render.Top().transform.rotation;
268 screenshotPosition.transform.localScale = SteamVR_Render.Top().transform.lossyScale;
269 SteamVR_Utils.TakeStereoScreenshot(screenshotHandle, screenshotPosition, 32, 0.064f, ref previewFilename, ref VRFilename);
272 OpenVR.Screenshots.SubmitScreenshot(screenshotHandle, screenshotType, previewFilename, VRFilename);
278 StartCoroutine(RenderLoop());
279 SteamVR_Events.InputFocus.Listen(OnInputFocus);
280 SteamVR_Events.System(EVREventType.VREvent_Quit).Listen(OnQuit);
281 SteamVR_Events.System(EVREventType.VREvent_RequestScreenshot).Listen(OnRequestScreenshot);
282 #if UNITY_2017_1_OR_NEWER
283 Application.onBeforeRender += OnBeforeRender;
285 Camera.onPreCull += OnCameraPreCull;
287 var vr = SteamVR.instance;
293 var types =
new EVRScreenshotType[] { EVRScreenshotType.StereoPanorama };
294 OpenVR.Screenshots.HookScreenshot(types);
300 SteamVR_Events.InputFocus.Remove(OnInputFocus);
301 SteamVR_Events.System(EVREventType.VREvent_Quit).Remove(OnQuit);
302 SteamVR_Events.System(EVREventType.VREvent_RequestScreenshot).Remove(OnRequestScreenshot);
303 #if UNITY_2017_1_OR_NEWER
304 Application.onBeforeRender -= OnBeforeRender;
306 Camera.onPreCull -= OnCameraPreCull;
312 if (externalCamera == null && System.IO.File.Exists(externalCameraConfigPath))
314 var prefab = Resources.Load<GameObject>(
"SteamVR_ExternalCamera");
315 var instance = Instantiate(prefab);
316 instance.gameObject.name =
"External Camera";
318 externalCamera = instance.transform.GetChild(0).GetComponent<SteamVR_ExternalCamera>();
319 externalCamera.configPath = externalCameraConfigPath;
320 externalCamera.ReadConfig();
324 public void UpdatePoses()
326 var compositor = OpenVR.Compositor;
327 if (compositor != null)
329 compositor.GetLastPoses(poses, gamePoses);
330 SteamVR_Events.NewPoses.Send(poses);
331 SteamVR_Events.NewPosesApplied.Send();
335 #if UNITY_2017_1_OR_NEWER
336 void OnBeforeRender() { UpdatePoses(); }
338 void OnCameraPreCull(Camera cam)
341 if (cam.cameraType != CameraType.VR)
345 if (Time.frameCount != lastFrameCount)
347 lastFrameCount = Time.frameCount;
351 static int lastFrameCount = -1;
357 SteamVR_Controller.Update();
360 var system = OpenVR.System;
364 var size = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(
VREvent_t));
365 for (
int i = 0; i < 64; i++)
367 if (!system.PollNextEvent(ref vrEvent, size))
370 switch ((EVREventType)vrEvent.eventType)
372 case EVREventType.VREvent_InputFocusCaptured:
373 if (vrEvent.data.process.oldPid == 0)
375 SteamVR_Events.InputFocus.Send(
false);
378 case EVREventType.VREvent_InputFocusReleased:
379 if (vrEvent.data.process.pid == 0)
381 SteamVR_Events.InputFocus.Send(
true);
384 case EVREventType.VREvent_ShowRenderModels:
385 SteamVR_Events.HideRenderModels.Send(
false);
387 case EVREventType.VREvent_HideRenderModels:
388 SteamVR_Events.HideRenderModels.Send(
true);
391 SteamVR_Events.System((EVREventType)vrEvent.eventType).Send(vrEvent);
398 Application.targetFrameRate = -1;
399 Application.runInBackground =
true;
400 QualitySettings.maxQueuedFrames = -1;
401 QualitySettings.vSyncCount = 0;
403 if (lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0.0f)
405 var vr = SteamVR.instance;
410 vr.compositor.GetFrameTiming(ref timing, 0);
412 Time.fixedDeltaTime = Time.timeScale / vr.hmd_DisplayFrequency;