OVRDebugInfo.cs 14 KB

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