/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using UnityEngine; using UnityEditor; using System.IO; /// /// From the selected transform, takes a cubemap screenshot that can be submitted with the application /// as a screenshot (or additionally used for reflection shaders). /// class OVRScreenshotWizard : ScriptableWizard { public enum TexFormat { JPEG, // 512kb at 1k x 1k resolution vs PNG, // 5.3mb } public enum SaveMode { SaveCubemapScreenshot, SaveUnityCubemap, SaveBoth, } public GameObject renderFrom = null; public int size = 2048; public SaveMode saveMode = SaveMode.SaveUnityCubemap; public string cubeMapFolder = "Assets/Textures/Cubemaps"; public TexFormat textureFormat = TexFormat.PNG; /// /// Validates the user's input /// void OnWizardUpdate() { helpString = "Select a game object positioned in the place where\nyou want to render the cubemap screenshot from: "; isValid = (renderFrom != null); } /// /// Create the asset path if it is not available. /// Assuming the newFolderPath is stated with "Assets", which is a requirement. /// static bool CreateAssetPath(string newFolderPath) { const int maxFoldersCount = 32; string currentPath; string[] pathFolders; pathFolders = newFolderPath.Split(new char[] { '/' }, maxFoldersCount); if (!string.Equals("Assets", pathFolders[0], System.StringComparison.OrdinalIgnoreCase)) { Debug.LogError("Folder path has to be started with \" Assets \" "); return false; } currentPath = "Assets"; for (int i = 1; i < pathFolders.Length; i++) { if (!string.IsNullOrEmpty(pathFolders[i])) { string newPath = currentPath + "/" + pathFolders[i]; if (!AssetDatabase.IsValidFolder(newPath)) AssetDatabase.CreateFolder(currentPath, pathFolders[i]); currentPath = newPath; } } Debug.Log("Created path: " + currentPath); return true; } /// /// Renders the cubemap /// void OnWizardCreate() { if (!AssetDatabase.IsValidFolder(cubeMapFolder)) { if (!CreateAssetPath(cubeMapFolder)) { Debug.LogError("Created path failed: " + cubeMapFolder); return; } } bool existingCamera = true; bool existingCameraStateSave = true; Camera camera = renderFrom.GetComponent(); if (camera == null) { camera = renderFrom.AddComponent(); camera.farClipPlane = 10000f; existingCamera = false; } else { existingCameraStateSave = camera.enabled; camera.enabled = true; } // find the last screenshot saved if (cubeMapFolder[cubeMapFolder.Length - 1] != '/') { cubeMapFolder += "/"; } int idx = 0; string[] fileNames = Directory.GetFiles(cubeMapFolder); foreach (string fileName in fileNames) { if (!fileName.ToLower().EndsWith(".cubemap")) { continue; } string temp = fileName.Replace(cubeMapFolder + "vr_screenshot_", string.Empty); temp = temp.Replace(".cubemap", string.Empty); int tempIdx = 0; if (int.TryParse(temp, out tempIdx)) { if (tempIdx > idx) { idx = tempIdx; } } } string pathName = string.Format("{0}vr_screenshot_{1}.cubemap", cubeMapFolder, (++idx).ToString("d2")); Cubemap cubemap = new Cubemap(size, TextureFormat.RGB24, false); // render into cubemap if ((camera != null) && (cubemap != null)) { // set up cubemap defaults OVRCubemapCapture.RenderIntoCubemap(camera, cubemap); if (existingCamera) { camera.enabled = existingCameraStateSave; } else { DestroyImmediate(camera); } // generate a regular texture as well? if ((saveMode == SaveMode.SaveCubemapScreenshot) || (saveMode == SaveMode.SaveBoth)) { GenerateTexture(cubemap, pathName); } if ((saveMode == SaveMode.SaveUnityCubemap) || (saveMode == SaveMode.SaveBoth)) { Debug.Log("Saving: " + pathName); // by default the unity cubemap isn't saved AssetDatabase.CreateAsset(cubemap, pathName); // reimport as necessary AssetDatabase.SaveAssets(); // select it in the project tree so developers can find it EditorGUIUtility.PingObject(cubemap); Selection.activeObject = cubemap; } AssetDatabase.Refresh(); } } /// /// Generates a NPOT 6x1 cubemap in the following format PX NX PY NY PZ NZ /// void GenerateTexture(Cubemap cubemap, string pathName) { // Encode the texture and save it to disk pathName = pathName.Replace(".cubemap", (textureFormat == TexFormat.PNG) ? ".png" : ".jpg").ToLower(); pathName = pathName.Replace(cubeMapFolder.ToLower(), ""); string format = textureFormat.ToString(); string fullPath = EditorUtility.SaveFilePanel(string.Format("Save Cubemap Screenshot as {0}", format), "", pathName, format.ToLower()); if (!string.IsNullOrEmpty(fullPath)) { Debug.Log("Saving: " + fullPath); OVRCubemapCapture.SaveCubemapCapture(cubemap, fullPath); } } /// /// Unity Editor menu option to take a screenshot /// [MenuItem("Oculus/Tools/OVR Screenshot Wizard", false, 100000)] static void TakeOVRScreenshot() { OVRScreenshotWizard wizard = ScriptableWizard.DisplayWizard("OVR Screenshot Wizard", "Render Cubemap"); if (wizard != null) { if (Selection.activeGameObject != null) wizard.renderFrom = Selection.activeGameObject; else wizard.renderFrom = Camera.main.gameObject; wizard.isValid = (wizard.renderFrom != null); } } }