OVRDebugInfo.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /************************************************************************************
  2. Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
  3. Licensed under the Oculus Utilities SDK License Version 1.31 (the "License"); you may not use
  4. the Utilities SDK except in compliance with the License, which is provided at the time of installation
  5. or download, or which otherwise accompanies this software in either electronic or hard copy form.
  6. You may obtain a copy of the License at
  7. https://developer.oculus.com/licenses/utilities-1.31
  8. Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
  9. under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  10. ANY KIND, either express or implied. See the License for the specific language governing
  11. permissions and limitations under the License.
  12. ************************************************************************************/
  13. using UnityEngine;
  14. using System.Collections;
  15. using UnityEngine.UI;
  16. //-------------------------------------------------------------------------------------
  17. /// <summary>
  18. /// Shows debug information on a heads-up display.
  19. /// </summary>
  20. public class OVRDebugInfo : MonoBehaviour
  21. {
  22. #region GameObjects for Debug Information UIs
  23. GameObject debugUIManager;
  24. GameObject debugUIObject;
  25. GameObject riftPresent;
  26. GameObject fps;
  27. GameObject ipd;
  28. GameObject fov;
  29. GameObject height;
  30. GameObject depth;
  31. GameObject resolutionEyeTexture;
  32. GameObject latencies;
  33. GameObject texts;
  34. #endregion
  35. #region Debug strings
  36. string strRiftPresent = null; // "VR DISABLED"
  37. string strFPS = null; // "FPS: 0";
  38. string strIPD = null; // "IPD: 0.000";
  39. string strFOV = null; // "FOV: 0.0f";
  40. string strHeight = null; // "Height: 0.0f";
  41. string strDepth = null; // "Depth: 0.0f";
  42. string strResolutionEyeTexture = null; // "Resolution : {0} x {1}"
  43. string strLatencies = null; // "R: {0:F3} TW: {1:F3} PP: {2:F3} RE: {3:F3} TWE: {4:F3}"
  44. #endregion
  45. /// <summary>
  46. /// Variables for FPS
  47. /// </summary>
  48. float updateInterval = 0.5f;
  49. float accum = 0.0f;
  50. int frames = 0;
  51. float timeLeft = 0.0f;
  52. /// <summary>
  53. /// Managing for UI initialization
  54. /// </summary>
  55. bool initUIComponent = false;
  56. bool isInited = false;
  57. /// <summary>
  58. /// UIs Y offset
  59. /// </summary>
  60. float offsetY = 55.0f;
  61. /// <summary>
  62. /// Managing for rift detection UI
  63. /// </summary>
  64. float riftPresentTimeout = 0.0f;
  65. /// <summary>
  66. /// Turn on / off VR variables
  67. /// </summary>
  68. bool showVRVars = false;
  69. #region MonoBehaviour handler
  70. /// <summary>
  71. /// Initialization
  72. /// </summary>
  73. void Awake()
  74. {
  75. // Create canvas for using new GUI
  76. debugUIManager = new GameObject();
  77. debugUIManager.name = "DebugUIManager";
  78. debugUIManager.transform.parent = GameObject.Find("LeftEyeAnchor").transform;
  79. RectTransform rectTransform = debugUIManager.AddComponent<RectTransform>();
  80. rectTransform.sizeDelta = new Vector2(100f, 100f);
  81. rectTransform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
  82. rectTransform.localPosition = new Vector3(0.01f, 0.17f, 0.53f);
  83. rectTransform.localEulerAngles = Vector3.zero;
  84. Canvas canvas = debugUIManager.AddComponent<Canvas>();
  85. canvas.renderMode = RenderMode.WorldSpace;
  86. canvas.pixelPerfect = false;
  87. }
  88. /// <summary>
  89. /// Updating VR variables and managing UI present
  90. /// </summary>
  91. void Update()
  92. {
  93. if (initUIComponent && !isInited)
  94. {
  95. InitUIComponents();
  96. }
  97. if (Input.GetKeyDown(KeyCode.Space) && riftPresentTimeout < 0.0f)
  98. {
  99. initUIComponent = true;
  100. showVRVars ^= true;
  101. }
  102. UpdateDeviceDetection();
  103. // Presenting VR variables
  104. if (showVRVars)
  105. {
  106. debugUIManager.SetActive(true);
  107. UpdateVariable();
  108. UpdateStrings();
  109. }
  110. else
  111. {
  112. debugUIManager.SetActive(false);
  113. }
  114. }
  115. /// <summary>
  116. /// Initialize isInited value on OnDestroy
  117. /// </summary>
  118. void OnDestroy()
  119. {
  120. isInited = false;
  121. }
  122. #endregion
  123. #region Private Functions
  124. /// <summary>
  125. /// Initialize UI GameObjects
  126. /// </summary>
  127. void InitUIComponents()
  128. {
  129. float posY = 0.0f;
  130. int fontSize = 20;
  131. debugUIObject = new GameObject();
  132. debugUIObject.name = "DebugInfo";
  133. debugUIObject.transform.parent = GameObject.Find("DebugUIManager").transform;
  134. debugUIObject.transform.localPosition = new Vector3(0.0f, 100.0f, 0.0f);
  135. debugUIObject.transform.localEulerAngles = Vector3.zero;
  136. debugUIObject.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
  137. // Print out for FPS
  138. if (!string.IsNullOrEmpty(strFPS))
  139. {
  140. fps = VariableObjectManager(fps, "FPS", posY -= offsetY, strFPS, fontSize);
  141. }
  142. // Print out for IPD
  143. if (!string.IsNullOrEmpty(strIPD))
  144. {
  145. ipd = VariableObjectManager(ipd, "IPD", posY -= offsetY, strIPD, fontSize);
  146. }
  147. // Print out for FOV
  148. if (!string.IsNullOrEmpty(strFOV))
  149. {
  150. fov = VariableObjectManager(fov, "FOV", posY -= offsetY, strFOV, fontSize);
  151. }
  152. // Print out for Height
  153. if (!string.IsNullOrEmpty(strHeight))
  154. {
  155. height = VariableObjectManager(height, "Height", posY -= offsetY, strHeight, fontSize);
  156. }
  157. // Print out for Depth
  158. if (!string.IsNullOrEmpty(strDepth))
  159. {
  160. depth = VariableObjectManager(depth, "Depth", posY -= offsetY, strDepth, fontSize);
  161. }
  162. // Print out for Resoulution of Eye Texture
  163. if (!string.IsNullOrEmpty(strResolutionEyeTexture))
  164. {
  165. resolutionEyeTexture = VariableObjectManager(resolutionEyeTexture, "Resolution", posY -= offsetY, strResolutionEyeTexture, fontSize);
  166. }
  167. // Print out for Latency
  168. if (!string.IsNullOrEmpty(strLatencies))
  169. {
  170. latencies = VariableObjectManager(latencies, "Latency", posY -= offsetY, strLatencies, 17);
  171. posY = 0.0f;
  172. }
  173. initUIComponent = false;
  174. isInited = true;
  175. }
  176. /// <summary>
  177. /// Update VR Variables
  178. /// </summary>
  179. void UpdateVariable()
  180. {
  181. UpdateIPD();
  182. UpdateEyeHeightOffset();
  183. UpdateEyeDepthOffset();
  184. UpdateFOV();
  185. UpdateResolutionEyeTexture();
  186. UpdateLatencyValues();
  187. UpdateFPS();
  188. }
  189. /// <summary>
  190. /// Update Strings
  191. /// </summary>
  192. void UpdateStrings()
  193. {
  194. if (debugUIObject == null)
  195. return;
  196. if (!string.IsNullOrEmpty(strFPS))
  197. fps.GetComponentInChildren<Text>().text = strFPS;
  198. if (!string.IsNullOrEmpty(strIPD))
  199. ipd.GetComponentInChildren<Text>().text = strIPD;
  200. if (!string.IsNullOrEmpty(strFOV))
  201. fov.GetComponentInChildren<Text>().text = strFOV;
  202. if (!string.IsNullOrEmpty(strResolutionEyeTexture))
  203. resolutionEyeTexture.GetComponentInChildren<Text>().text = strResolutionEyeTexture;
  204. if (!string.IsNullOrEmpty(strLatencies))
  205. {
  206. latencies.GetComponentInChildren<Text>().text = strLatencies;
  207. latencies.GetComponentInChildren<Text>().fontSize = 14;
  208. }
  209. if (!string.IsNullOrEmpty(strHeight))
  210. height.GetComponentInChildren<Text>().text = strHeight;
  211. if (!string.IsNullOrEmpty(strDepth))
  212. depth.GetComponentInChildren<Text>().text = strDepth;
  213. }
  214. /// <summary>
  215. /// It's for rift present GUI
  216. /// </summary>
  217. void RiftPresentGUI(GameObject guiMainOBj)
  218. {
  219. riftPresent = ComponentComposition(riftPresent);
  220. riftPresent.transform.SetParent(guiMainOBj.transform);
  221. riftPresent.name = "RiftPresent";
  222. RectTransform rectTransform = riftPresent.GetComponent<RectTransform>();
  223. rectTransform.localPosition = new Vector3(0.0f, 0.0f, 0.0f);
  224. rectTransform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
  225. rectTransform.localEulerAngles = Vector3.zero;
  226. Text text = riftPresent.GetComponentInChildren<Text>();
  227. text.text = strRiftPresent;
  228. text.fontSize = 20;
  229. }
  230. /// <summary>
  231. /// Updates the device detection.
  232. /// </summary>
  233. void UpdateDeviceDetection()
  234. {
  235. if (riftPresentTimeout >= 0.0f)
  236. {
  237. riftPresentTimeout -= Time.deltaTime;
  238. }
  239. }
  240. /// <summary>
  241. /// Object Manager for Variables
  242. /// </summary>
  243. /// <returns> gameobject for each Variable </returns>
  244. GameObject VariableObjectManager(GameObject gameObject, string name, float posY, string str, int fontSize)
  245. {
  246. gameObject = ComponentComposition(gameObject);
  247. gameObject.name = name;
  248. gameObject.transform.SetParent(debugUIObject.transform);
  249. RectTransform rectTransform = gameObject.GetComponent<RectTransform>();
  250. rectTransform.localPosition = new Vector3(0.0f, posY -= offsetY, 0.0f);
  251. Text text = gameObject.GetComponentInChildren<Text>();
  252. text.text = str;
  253. text.fontSize = fontSize;
  254. gameObject.transform.localEulerAngles = Vector3.zero;
  255. rectTransform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
  256. return gameObject;
  257. }
  258. /// <summary>
  259. /// Component composition
  260. /// </summary>
  261. /// <returns> Composed gameobject. </returns>
  262. GameObject ComponentComposition(GameObject GO)
  263. {
  264. GO = new GameObject();
  265. GO.AddComponent<RectTransform>();
  266. GO.AddComponent<CanvasRenderer>();
  267. GO.AddComponent<Image>();
  268. GO.GetComponent<RectTransform>().sizeDelta = new Vector2(350f, 50f);
  269. GO.GetComponent<Image>().color = new Color(7f / 255f, 45f / 255f, 71f / 255f, 200f / 255f);
  270. texts = new GameObject();
  271. texts.AddComponent<RectTransform>();
  272. texts.AddComponent<CanvasRenderer>();
  273. texts.AddComponent<Text>();
  274. texts.GetComponent<RectTransform>().sizeDelta = new Vector2(350f, 50f);
  275. texts.GetComponent<Text>().font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
  276. texts.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
  277. texts.transform.SetParent(GO.transform);
  278. texts.name = "TextBox";
  279. return GO;
  280. }
  281. #endregion
  282. #region Debugging variables handler
  283. /// <summary>
  284. /// Updates the IPD.
  285. /// </summary>
  286. void UpdateIPD()
  287. {
  288. strIPD = System.String.Format("IPD (mm): {0:F4}", OVRManager.profile.ipd * 1000.0f);
  289. }
  290. /// <summary>
  291. /// Updates the eye height offset.
  292. /// </summary>
  293. void UpdateEyeHeightOffset()
  294. {
  295. float eyeHeight = OVRManager.profile.eyeHeight;
  296. strHeight = System.String.Format("Eye Height (m): {0:F3}", eyeHeight);
  297. }
  298. /// <summary>
  299. /// Updates the eye depth offset.
  300. /// </summary>
  301. void UpdateEyeDepthOffset()
  302. {
  303. float eyeDepth = OVRManager.profile.eyeDepth;
  304. strDepth = System.String.Format("Eye Depth (m): {0:F3}", eyeDepth);
  305. }
  306. /// <summary>
  307. /// Updates the FOV.
  308. /// </summary>
  309. void UpdateFOV()
  310. {
  311. #if UNITY_2017_2_OR_NEWER
  312. OVRDisplay.EyeRenderDesc eyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.XR.XRNode.LeftEye);
  313. #else
  314. OVRDisplay.EyeRenderDesc eyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.VR.VRNode.LeftEye);
  315. #endif
  316. strFOV = System.String.Format("FOV (deg): {0:F3}", eyeDesc.fov.y);
  317. }
  318. /// <summary>
  319. /// Updates resolution of eye texture
  320. /// </summary>
  321. void UpdateResolutionEyeTexture()
  322. {
  323. #if UNITY_2017_2_OR_NEWER
  324. OVRDisplay.EyeRenderDesc leftEyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.XR.XRNode.LeftEye);
  325. OVRDisplay.EyeRenderDesc rightEyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.XR.XRNode.RightEye);
  326. float scale = UnityEngine.XR.XRSettings.renderViewportScale;
  327. #else
  328. OVRDisplay.EyeRenderDesc leftEyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.VR.VRNode.LeftEye);
  329. OVRDisplay.EyeRenderDesc rightEyeDesc = OVRManager.display.GetEyeRenderDesc(UnityEngine.VR.VRNode.RightEye);
  330. float scale = UnityEngine.VR.VRSettings.renderViewportScale;
  331. #endif
  332. float w = (int)(scale * (float)(leftEyeDesc.resolution.x + rightEyeDesc.resolution.x));
  333. float h = (int)(scale * (float)Mathf.Max(leftEyeDesc.resolution.y, rightEyeDesc.resolution.y));
  334. strResolutionEyeTexture = System.String.Format("Resolution : {0} x {1}", w, h);
  335. }
  336. /// <summary>
  337. /// Updates latency values
  338. /// </summary>
  339. void UpdateLatencyValues()
  340. {
  341. #if !UNITY_ANDROID || UNITY_EDITOR
  342. OVRDisplay.LatencyData latency = OVRManager.display.latency;
  343. if (latency.render < 0.000001f && latency.timeWarp < 0.000001f && latency.postPresent < 0.000001f)
  344. strLatencies = System.String.Format("Latency values are not available.");
  345. else
  346. strLatencies = System.String.Format("Render: {0:F3} TimeWarp: {1:F3} Post-Present: {2:F3}\nRender Error: {3:F3} TimeWarp Error: {4:F3}",
  347. latency.render,
  348. latency.timeWarp,
  349. latency.postPresent,
  350. latency.renderError,
  351. latency.timeWarpError);
  352. #endif
  353. }
  354. /// <summary>
  355. /// Updates the FPS.
  356. /// </summary>
  357. void UpdateFPS()
  358. {
  359. timeLeft -= Time.unscaledDeltaTime;
  360. accum += Time.unscaledDeltaTime;
  361. ++frames;
  362. // Interval ended - update GUI text and start new interval
  363. if (timeLeft <= 0.0)
  364. {
  365. // display two fractional digits (f2 format)
  366. float fps = frames / accum;
  367. strFPS = System.String.Format("FPS: {0:F2}", fps);
  368. timeLeft += updateInterval;
  369. accum = 0.0f;
  370. frames = 0;
  371. }
  372. }
  373. #endregion
  374. }