static public bool StartVideoCapture(string filePath, VideoRecorder recorder, UsdPathSerializer usdPathSerializer, bool offlineRender = false) { // Only one video at a time. if (m_ActiveVideoRecording != null) { return(false); } // Don't start recording unless there is enough space left. if (!FileUtils.InitializeDirectoryWithUserError( Path.GetDirectoryName(filePath), "Failed to start video capture")) { return(false); } // Vertical video is disabled. recorder.IsPortrait = false; // Start the capture first, which may fail, so do this before toggling any state. // While the state below is important for the actual frame capture, starting the capture process // does not require it. int sampleRate = 0; if (AudioCaptureManager.m_Instance.IsCapturingAudio) { sampleRate = AudioCaptureManager.m_Instance.SampleRate; } if (!recorder.StartCapture(filePath, sampleRate, AudioCaptureManager.m_Instance.IsCapturingAudio, offlineRender, offlineRender ? App.UserConfig.Video.OfflineFPS : App.UserConfig.Video.FPS)) { OutputWindowScript.ReportFileSaved("Failed to start capture!", null, OutputWindowScript.InfoCardSpawnPos.Brush); return(false); } m_ActiveVideoRecording = recorder; // Perform any necessary VR camera rendering optimizations to reduce CPU & GPU workload // Debug reduce quality for capture. // XXX This should just be ADAPTIVE RENDERING if (m_DebugVideoCaptureQualityLevel != -1) { m_PreCaptureQualityLevel = QualityControls.m_Instance.QualityLevel; QualityControls.m_Instance.QualityLevel = m_DebugVideoCaptureQualityLevel; } //App.VrSdk.SetHmdScalingFactor(m_VideoCaptureResolutionScale); // Setup SSAA RenderWrapper wrapper = recorder.gameObject.GetComponent <RenderWrapper>(); m_PreCaptureSuperSampling = wrapper.SuperSampling; wrapper.SuperSampling = m_SuperSampling; #if USD_SUPPORTED // Read from the Usd serializer if we're recording offline. Write to it otherwise. m_UsdPathSerializer = usdPathSerializer; if (!offlineRender) { m_UsdPath = SaveLoadScript.m_Instance.SceneFile.Valid ? Path.ChangeExtension(filePath, "usda") : null; m_RecordingStopwatch = new System.Diagnostics.Stopwatch(); m_RecordingStopwatch.Start(); if (!m_UsdPathSerializer.StartRecording()) { UnityEngine.Object.Destroy(m_UsdPathSerializer); m_UsdPathSerializer = null; } } else { recorder.SetCaptureFramerate(Mathf.RoundToInt(App.UserConfig.Video.OfflineFPS)); m_UsdPath = null; if (m_UsdPathSerializer.Load(App.Config.m_VideoPathToRender)) { m_UsdPathSerializer.StartPlayback(); } else { UnityEngine.Object.Destroy(m_UsdPathSerializer); m_UsdPathSerializer = null; } } #endif return(true); }
/// Like the other CreateLocal but passes the name through a sanitizer. /// Use this if you don't control where "name" comes from. public static ExportFileReference CreateSafeLocal(string originalLocation, string unsafeName) { return(CreateLocal(originalLocation, FileUtils.SanitizeFilenameAndPreserveUniqueness(unsafeName))); }
public static void ExportScene() { var current = SaveLoadScript.m_Instance.SceneFile; string safeHumanName = FileUtils.SanitizeFilename(current.HumanName); string basename = FileUtils.SanitizeFilename( (current.Valid && (safeHumanName != "")) ? safeHumanName : "Untitled"); string parent = FileUtils.GenerateNonexistentFilename(App.UserExportPath(), basename, ""); if (!FileUtils.InitializeDirectoryWithUserError( parent, "Failed to create export directory")) { return; } // Set up progress bar. var progress = new Progress(); if (App.PlatformConfig.EnableExportJson) { progress.SetWork("json"); } #if FBX_SUPPORTED if (App.PlatformConfig.EnableExportFbx) { progress.SetWork("fbx"); } #endif #if USD_SUPPORTED if (App.PlatformConfig.EnableExportUsd) { progress.SetWork("usd"); } #endif #if LATK_SUPPORTED if (App.PlatformConfig.EnableExportLatk) { progress.SetWork("latk"); } #endif #if (UNITY_EDITOR || EXPERIMENTAL_ENABLED) if (Config.IsExperimental) { progress.SetWork("wrl"); progress.SetWork("stl"); #if FBX_SUPPORTED progress.SetWork("obj"); #endif } #endif if (App.PlatformConfig.EnableExportGlb) { progress.SetWork("glb"); } string filename; if (App.PlatformConfig.EnableExportJson && (filename = MakeExportPath(parent, basename, "json")) != null) { using (var unused = new AutoTimer("raw export")) { OverlayManager.m_Instance.UpdateProgress(0.1f); ExportRaw.Export(filename); } } progress.CompleteWork("json"); #if FBX_SUPPORTED if (App.PlatformConfig.EnableExportFbx && (filename = MakeExportPath(parent, basename, "fbx")) != null) { using (var unused = new AutoTimer("fbx export")) { OverlayManager.m_Instance.UpdateProgress(0.3f); ExportFbx.Export(filename, App.UserConfig.Export.ExportBinaryFbx ? ExportFbx.kFbxBinary : ExportFbx.kFbxAscii, App.UserConfig.Export.ExportFbxVersion); OverlayManager.m_Instance.UpdateProgress(0.5f); } } progress.CompleteWork("fbx"); #endif #if USD_SUPPORTED if (App.PlatformConfig.EnableExportUsd && (filename = MakeExportPath(parent, basename, "usd")) != null) { using (var unused = new AutoTimer("usd export")) { ExportUsd.ExportPayload(filename); } } progress.CompleteWork("usd"); #endif #if LATK_SUPPORTED if (App.PlatformConfig.EnableExportLatk && (filename = MakeExportPath(parent, basename, "latk")) != null) { using (var unused = new AutoTimer("latk export")) { ExportLatk.Export(filename); } } progress.CompleteWork("latk"); #endif #if (UNITY_EDITOR || EXPERIMENTAL_ENABLED) if (Config.IsExperimental && (filename = MakeExportPath(parent, basename, "wrl")) != null) { ExportVrml.Export(filename); progress.CompleteWork("wrl"); } if (Config.IsExperimental && (filename = MakeExportPath(parent, basename, "stl")) != null) { ExportStl.Export(filename); progress.CompleteWork("stl"); } #if FBX_SUPPORTED if (Config.IsExperimental && App.PlatformConfig.EnableExportFbx && (filename = MakeExportPath(parent, basename, "obj")) != null) { // This has never been tested with the new fbx export style and may not work ExportFbx.Export(filename, ExportFbx.kObj); progress.CompleteWork("obj"); } #endif #endif if (App.PlatformConfig.EnableExportGlb) { string extension = App.Config.m_EnableGlbVersion2 ? "glb" : "glb1"; int gltfVersion = App.Config.m_EnableGlbVersion2 ? 2 : 1; filename = MakeExportPath(parent, basename, extension); if (filename != null) { using (var unused = new AutoTimer("glb export")) { OverlayManager.m_Instance.UpdateProgress(0.7f); var exporter = new ExportGlTF(); // TBT doesn't need (or want) brush textures in the output because it replaces all // the materials, so it's fine to keep those http:. However, Sketchfab doesn't support // http textures so if uploaded, this glb will have missing textures. exporter.ExportBrushStrokes( filename, AxisConvention.kGltf2, binary: true, doExtras: false, includeLocalMediaContent: true, gltfVersion: gltfVersion, selfContained: true ); progress.CompleteWork("glb"); } } } OutputWindowScript.m_Instance.CreateInfoCardAtController( InputManager.ControllerName.Brush, basename + " exported!"); ControllerConsoleScript.m_Instance.AddNewLine("Located in " + App.UserExportPath()); string readmeFilename = Path.Combine(App.UserExportPath(), kExportReadmeName); if (!File.Exists(readmeFilename) && !Directory.Exists(readmeFilename)) { File.WriteAllText(readmeFilename, kExportReadmeBody); } }
public void Init() { string cacheDir = Path.Combine(Application.persistentDataPath, "assetCache"); m_CacheDir = cacheDir.Replace("\\", "/"); // Use a different directory from m_CacheDir to avoid having to make ValidGltfCache() // smart enough to allow directories with only a thumbnail and no asset data. m_ThumbnailCacheDir = Path.Combine(Application.persistentDataPath, "assetThumbnail") .Replace("\\", "/"); m_ActiveRequests = new List <AssetGetter>(); m_RequestLoadQueue = new List <ModelLoadRequest>(); m_LoadQueue = new List <ModelLoadRequest>(); FileUtils.InitializeDirectoryWithUserError(m_CacheDir, "Failed to create asset cache"); // Create and populate model map. m_ModelsByAssetId = new Dictionary <string, Model>(); try { foreach (string folderPath in EnumerateCacheDirectories()) { string folderName = Path.GetFileName(folderPath); string gltfFile = ValidGltfCache(folderPath, folderName); if (gltfFile != null) { string path = Path.Combine(folderPath, folderName); path = Path.Combine(path, gltfFile); m_ModelsByAssetId[folderName] = new Model(Model.Location.PolyAsset(folderName, path)); } else { Debug.LogWarningFormat("Deleting invalid cache folder {0}", folderName); Directory.Delete(folderPath, true); } } } catch (DirectoryNotFoundException e) { Debug.LogException(e); } catch (UnauthorizedAccessException e) { Debug.LogException(e); } m_AssetSetByType = new Dictionary <PolySetType, AssetSet> { { PolySetType.User, new AssetSet() }, { PolySetType.Liked, new AssetSet() }, { PolySetType.Featured, new AssetSet { m_RefreshRequested = true } } }; App.Instance.AppExit += () => { var models = EnumerateCacheDirectories() .OrderBy(d => Directory.GetLastAccessTimeUtc(d)).ToArray(); for (int excess = models.Count() - kAssetDiskCacheSize; excess > 0; excess--) { Directory.Delete(models[excess - 1], true); } }; }