static void MenuExportSelectedAsUsdz() { var defaultName = Path.GetFileNameWithoutExtension(Selection.activeGameObject.name); var filePath = EditorUtility.SaveFilePanel("Export USDZ File", "", defaultName, "usdz"); if (filePath == null || filePath.Length == 0) { return; } var fileDir = Path.GetDirectoryName(filePath); if (!Directory.Exists(fileDir)) { var di = Directory.CreateDirectory(fileDir); if (!di.Exists) { Debug.LogError("Failed to create directory: " + fileDir); return; } } UsdzExporter.ExportUsdz(filePath, Selection.activeGameObject); }
// ------------------------------------------------------------------------------------------ // // Recording Control. // ------------------------------------------------------------------------------------------ // public void BeginRecording(double currentTime, GameObject root) { InitUsd.Initialize(); _root = root; if (!root) { Debug.LogError("ExportRoot not assigned."); return; } if (Clip.UsdScene != null) { Clip.UsdScene.Close(); Clip.UsdScene = null; } // Keep the current directory to restore it at the end. currentDir = Directory.GetCurrentDirectory(); var localScale = root.transform.localScale; try { if (string.IsNullOrEmpty(Clip.m_usdFile)) { Clip.UsdScene = Scene.Create(); } else if (Clip.IsUSDZ) { // Setup a temporary directory to export the wanted USD file and zip it. string tmpDirPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); usdzTemporaryDir = Directory.CreateDirectory(tmpDirPath); // Get the usd file name to export and the usdz file name of the archive. usdcFileName = Path.GetFileNameWithoutExtension(Clip.m_usdFile) + ".usdc"; usdzFileName = Path.GetFileName(Clip.m_usdFile); var fi = new FileInfo(Clip.m_usdFile); usdzFilePath = fi.FullName; // Set the current working directory to the tmp directory to export with relative paths. Directory.SetCurrentDirectory(tmpDirPath); Clip.UsdScene = UsdzExporter.InitForSave(usdcFileName); } else { Clip.UsdScene = Scene.Create(Clip.m_usdFile); } // Set the frame rate in USD as well. // // This both set the "time samples per second" and the playback rate. // Setting times samples per second allows the authoring code to express samples as integer // values, avoiding floating point error; so by setting FrameRate = 60, the samples written // at time=0 through time=59 represent the first second of playback. // // Stage.TimeCodesPerSecond is set implicitly to 1 / FrameRate. //m_usdScene.FrameRate = Clip.frame; // When authoring in terms of seconds, at any frame rate the samles written at // time = 0.0 through time = 1.0 represent the first second of playback. The framerate // above will only be used as a target frame rate. //if (m_timeUnits == TimeCode.Seconds) { // m_usdScene.Stage.SetTimeCodesPerSecond(1); //} // Regardless of the actual sampling rate (e.g. Timeline playback speed), we are converting // the timecode from seconds to frames with a sampling rate of 60 FPS. This has the nice quality // of adding additional numerical stability. // In the event that the timeline is not configured for 60 FPS playback, we rely on USD's linear // interpolation mode to up-sample to 60 FPS. Clip.UsdScene.FrameRate = kExportFrameRate; Clip.UsdScene.Stage.SetInterpolationType(pxr.UsdInterpolationType.UsdInterpolationTypeLinear); // For simplicity in this example, adding game objects while recording is not supported. Clip.Context = new ExportContext(); Clip.Context.scene = Clip.UsdScene; Clip.Context.basisTransform = Clip.m_convertHandedness; Clip.Context.activePolicy = Clip.m_activePolicy; Clip.Context.exportMaterials = Clip.m_exportMaterials; // USDZ is in centimeters. Clip.Context.scale = Clip.IsUSDZ ? 100.0f : 1.0f; Clip.UsdScene.StartTime = currentTime * kExportFrameRate; // Export the "default" frame, that is, all data which doesn't vary over time. Clip.UsdScene.Time = null; SceneExporter.SyncExportContext(root, Clip.Context); SceneExporter.Export(root, Clip.Context, zeroRootTransform: false); } catch { if (Clip.UsdScene != null) { Debug.LogError("Set scene to null"); Clip.UsdScene.Close(); Clip.UsdScene = null; } if (Clip.IsUSDZ) { usdzTemporaryDir.Delete(recursive: true); } throw; } finally { Directory.SetCurrentDirectory(currentDir); } }