OVRScreenshotWizard.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.IO;
  4. /// <summary>
  5. /// From the selected transform, takes a cubemap screenshot that can be submitted with the application
  6. /// as a screenshot (or additionally used for reflection shaders).
  7. /// </summary>
  8. class OVRScreenshotWizard : ScriptableWizard
  9. {
  10. public enum TexFormat
  11. {
  12. JPEG, // 512kb at 1k x 1k resolution vs
  13. PNG, // 5.3mb
  14. }
  15. public enum SaveMode {
  16. SaveCubemapScreenshot,
  17. SaveUnityCubemap,
  18. SaveBoth,
  19. }
  20. public GameObject renderFrom = null;
  21. public int size = 2048;
  22. public SaveMode saveMode = SaveMode.SaveUnityCubemap;
  23. public string cubeMapFolder = "Assets/Textures/Cubemaps";
  24. public TexFormat textureFormat = TexFormat.PNG;
  25. /// <summary>
  26. /// Validates the user's input
  27. /// </summary>
  28. void OnWizardUpdate()
  29. {
  30. helpString = "Select a game object positioned in the place where\nyou want to render the cubemap screenshot from: ";
  31. isValid = (renderFrom != null);
  32. }
  33. /// <summary>
  34. /// Create the asset path if it is not available.
  35. /// Assuming the newFolderPath is stated with "Assets", which is a requirement.
  36. /// </summary>
  37. static bool CreateAssetPath( string newFolderPath )
  38. {
  39. const int maxFoldersCount = 32;
  40. string currentPath;
  41. string[] pathFolders;
  42. pathFolders = newFolderPath.Split (new char[]{ '/' }, maxFoldersCount);
  43. if (!string.Equals ("Assets", pathFolders [0], System.StringComparison.OrdinalIgnoreCase))
  44. {
  45. Debug.LogError( "Folder path has to be started with \" Assets \" " );
  46. return false;
  47. }
  48. currentPath = "Assets";
  49. for (int i = 1; i < pathFolders.Length; i++)
  50. {
  51. if (!string.IsNullOrEmpty(pathFolders[i]))
  52. {
  53. string newPath = currentPath + "/" + pathFolders[i];
  54. if (!AssetDatabase.IsValidFolder(newPath))
  55. AssetDatabase.CreateFolder(currentPath, pathFolders[i]);
  56. currentPath = newPath;
  57. }
  58. }
  59. Debug.Log( "Created path: " + currentPath );
  60. return true;
  61. }
  62. /// <summary>
  63. /// Renders the cubemap
  64. /// </summary>
  65. void OnWizardCreate()
  66. {
  67. if ( !AssetDatabase.IsValidFolder( cubeMapFolder ) )
  68. {
  69. if (!CreateAssetPath(cubeMapFolder))
  70. {
  71. Debug.LogError( "Created path failed: " + cubeMapFolder );
  72. return;
  73. }
  74. }
  75. bool existingCamera = true;
  76. bool existingCameraStateSave = true;
  77. Camera camera = renderFrom.GetComponent<Camera>();
  78. if (camera == null)
  79. {
  80. camera = renderFrom.AddComponent<Camera>();
  81. camera.farClipPlane = 10000f;
  82. existingCamera = false;
  83. }
  84. else
  85. {
  86. existingCameraStateSave = camera.enabled;
  87. camera.enabled = true;
  88. }
  89. // find the last screenshot saved
  90. if (cubeMapFolder[cubeMapFolder.Length-1] != '/')
  91. {
  92. cubeMapFolder += "/";
  93. }
  94. int idx = 0;
  95. string[] fileNames = Directory.GetFiles(cubeMapFolder);
  96. foreach(string fileName in fileNames)
  97. {
  98. if (!fileName.ToLower().EndsWith(".cubemap"))
  99. {
  100. continue;
  101. }
  102. string temp = fileName.Replace(cubeMapFolder + "vr_screenshot_", string.Empty);
  103. temp = temp.Replace(".cubemap", string.Empty);
  104. int tempIdx = 0;
  105. if (int.TryParse( temp, out tempIdx ))
  106. {
  107. if (tempIdx > idx)
  108. {
  109. idx = tempIdx;
  110. }
  111. }
  112. }
  113. string pathName = string.Format("{0}vr_screenshot_{1}.cubemap", cubeMapFolder, (++idx).ToString("d2"));
  114. Cubemap cubemap = new Cubemap(size, TextureFormat.RGB24, false);
  115. // render into cubemap
  116. if ((camera != null) && (cubemap != null))
  117. {
  118. // set up cubemap defaults
  119. OVRCubemapCapture.RenderIntoCubemap(camera, cubemap);
  120. if (existingCamera)
  121. {
  122. camera.enabled = existingCameraStateSave;
  123. }
  124. else
  125. {
  126. DestroyImmediate(camera);
  127. }
  128. // generate a regular texture as well?
  129. if ( ( saveMode == SaveMode.SaveCubemapScreenshot ) || ( saveMode == SaveMode.SaveBoth ) )
  130. {
  131. GenerateTexture(cubemap, pathName);
  132. }
  133. if ( ( saveMode == SaveMode.SaveUnityCubemap ) || ( saveMode == SaveMode.SaveBoth ) )
  134. {
  135. Debug.Log( "Saving: " + pathName );
  136. // by default the unity cubemap isn't saved
  137. AssetDatabase.CreateAsset( cubemap, pathName );
  138. // reimport as necessary
  139. AssetDatabase.SaveAssets();
  140. // select it in the project tree so developers can find it
  141. EditorGUIUtility.PingObject( cubemap );
  142. Selection.activeObject = cubemap;
  143. }
  144. AssetDatabase.Refresh();
  145. }
  146. }
  147. /// <summary>
  148. /// Generates a NPOT 6x1 cubemap in the following format PX NX PY NY PZ NZ
  149. /// </summary>
  150. void GenerateTexture(Cubemap cubemap, string pathName)
  151. {
  152. // Encode the texture and save it to disk
  153. pathName = pathName.Replace(".cubemap", (textureFormat == TexFormat.PNG) ? ".png" : ".jpg" ).ToLower();
  154. pathName = pathName.Replace( cubeMapFolder.ToLower(), "" );
  155. string format = textureFormat.ToString();
  156. string fullPath = EditorUtility.SaveFilePanel( string.Format( "Save Cubemap Screenshot as {0}", format ), "", pathName, format.ToLower() );
  157. if ( !string.IsNullOrEmpty( fullPath ) )
  158. {
  159. Debug.Log( "Saving: " + fullPath );
  160. OVRCubemapCapture.SaveCubemapCapture(cubemap, fullPath);
  161. }
  162. }
  163. /// <summary>
  164. /// Unity Editor menu option to take a screenshot
  165. /// </summary>
  166. [MenuItem("Tools/Oculus/OVR Screenshot Wizard",false,100000)]
  167. static void TakeOVRScreenshot()
  168. {
  169. OVRScreenshotWizard wizard = ScriptableWizard.DisplayWizard<OVRScreenshotWizard>("OVR Screenshot Wizard", "Render Cubemap");
  170. if (wizard != null)
  171. {
  172. if (Selection.activeGameObject != null)
  173. wizard.renderFrom = Selection.activeGameObject;
  174. else
  175. wizard.renderFrom = Camera.main.gameObject;
  176. wizard.isValid = (wizard.renderFrom != null);
  177. }
  178. }
  179. }