static void ExportSelected(BasisTransformation basisTransform, string fileExtension = "usd", bool exportMonoBehaviours = false) { Scene scene = null; foreach (GameObject go in Selection.gameObjects) { if (scene == null) { scene = InitForSave(go.name, fileExtension); if (scene == null) { return; } } try { SceneExporter.Export(go, scene, basisTransform, exportUnvarying: true, zeroRootTransform: false, exportMonoBehaviours: exportMonoBehaviours); } catch (System.Exception ex) { Debug.LogException(ex); continue; } } if (scene != null) { scene.Save(); scene.Close(); } }
/// <summary> /// Writes overrides over the given scene. The given scene is referenced into the override /// scene being exported. /// </summary> /// <param name="sceneInWhichToStoreTransforms"></param> public void ExportOverrides(Scene sceneInWhichToStoreTransforms) { var sceneToReference = this; var overs = sceneInWhichToStoreTransforms; if (overs == null) { return; } var baseLayer = sceneToReference.GetScene(); if (baseLayer == null) { throw new Exception("Could not open base layer: " + sceneToReference.usdFullPath); } overs.Time = baseLayer.Time; overs.StartTime = baseLayer.StartTime; overs.EndTime = baseLayer.EndTime; overs.WriteMode = Scene.WriteModes.Over; overs.UpAxis = baseLayer.UpAxis; try { SceneExporter.Export(sceneToReference.gameObject, overs, BasisTransformation.SlowAndSafe, exportUnvarying: false, zeroRootTransform: true); var rel = ImporterBase.MakeRelativePath(overs.FilePath, sceneToReference.usdFullPath); GetFirstPrim(overs).GetReferences().AddReference(rel, GetFirstPrim(baseLayer).GetPath()); } catch (System.Exception ex) { Debug.LogException(ex); return; } finally { if (overs != null) { overs.Save(); overs.Close(); } } }
/// <summary> /// Writes overrides to the currently targeted subLayer. /// </summary> public void SaveToLayer() { var stageRoot = GetComponent <UsdAsset>(); Scene subLayerScene = Scene.Create(m_targetLayer); if (subLayerScene == null) { throw new NullReferenceException("Could not create layer: " + m_targetLayer); } Scene rootScene = Scene.Open(stageRoot.usdFullPath); if (rootScene == null) { throw new NullReferenceException("Could not open base layer: " + stageRoot.usdFullPath); } SetupNewSubLayer(rootScene, subLayerScene); rootScene.Close(); rootScene = null; try { SceneExporter.Export(stageRoot.gameObject, subLayerScene, stageRoot.m_changeHandedness, exportUnvarying: false, zeroRootTransform: false); } catch (Exception ex) { Debug.LogException(ex); return; } finally { if (subLayerScene != null) { subLayerScene.Save(); subLayerScene.Close(); subLayerScene = null; } } }
void ProcessRecording(double currentTime, GameObject root) { if (!root || m_isPaused) { return; } if (Clip.UsdScene == null) { Debug.LogError("Process: clip.scene is null"); } if (Clip.Context.scene == null) { Debug.LogError("Process: context.scene is null"); } Clip.UsdScene.Time = currentTime; Clip.Context.exportMaterials = false; SceneExporter.Export(root, Clip.Context, zeroRootTransform: false); }
public static void ExportGameObjects(GameObject[] objects, Scene scene, BasisTransformation basisTransform, bool exportMonoBehaviours = false) { if (scene == null) { return; } foreach (GameObject go in objects) { try { SceneExporter.Export(go, scene, basisTransform, exportUnvarying: true, zeroRootTransform: false, exportMonoBehaviours: exportMonoBehaviours); } catch (System.Exception ex) { Debug.LogException(ex); } } scene.Save(); scene.Close(); }
// ------------------------------------------------------------------------------------------ // // 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); } }
public static void ExportUsdz(string usdzFilePath, GameObject root) { // Ensure USD is initialized before changing CWD. // This does not protect us against external changes to CWD, so we are actively looking for // a more robust solution with UPM devs. InitUsd.Initialize(); // Keep the current directory to restore it at the end. var currentDir = Directory.GetCurrentDirectory(); // Setup a temporary directory to export the wanted USD file and zip it. string tmpDirPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); DirectoryInfo tmpDir = Directory.CreateDirectory(tmpDirPath); // Get the usd file name to export and the usdz file name of the archive. string usdcFileName = Path.GetFileNameWithoutExtension(usdzFilePath) + ".usdc"; string usdzFileName = Path.GetFileName(usdzFilePath); try { // Set the current working directory to the tmp directory to export with relative paths. Directory.SetCurrentDirectory(tmpDirPath); // Create the tmp .usd scene, into which the data will be exported. Scene scene = ExportHelpers.InitForSave(Path.Combine(tmpDirPath, usdcFileName)); Vector3 localScale = root.transform.localScale; try { // USDZ is in centimeters. root.transform.localScale = localScale * 100; // Export the temp scene. SceneExporter.Export(root, scene, BasisTransformation.SlowAndSafe, // Required by ARKit exportUnvarying: true, zeroRootTransform: false, exportMaterials: true); } finally { // Undo temp scale. root.transform.localScale = localScale; // Flush any in-flight edits and release the scene so the file can be deleted. scene.Save(); scene.Close(); scene = null; } SdfAssetPath assetPath = new SdfAssetPath(usdcFileName); bool success = pxr.UsdCs.UsdUtilsCreateNewARKitUsdzPackage(assetPath, usdzFileName); if (!success) { Debug.LogError("Couldn't export " + root.name + " to the usdz file: " + usdzFilePath); return; } File.Copy(usdzFileName, usdzFilePath, overwrite: true); } finally { // Clean up temp files. Directory.SetCurrentDirectory(currentDir); tmpDir.Delete(recursive: true); } }
// ------------------------------------------------------------------------------------------ // // Recording Control. // ------------------------------------------------------------------------------------------ // public void BeginRecording(double currentTime, GameObject root) { InitUsd.Initialize(); if (!root) { Debug.LogError("ExportRoot not assigned."); return; } if (Clip.UsdScene != null) { Clip.UsdScene.Close(); Clip.UsdScene = null; } try { if (string.IsNullOrEmpty(Clip.m_usdFile)) { Clip.UsdScene = Scene.Create(); } 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); //} // TODO: How does one extract the time mode (frames or seconds) from the Timeline? Clip.UsdScene.Stage.SetFramesPerSecond(30); Clip.UsdScene.Stage.SetTimeCodesPerSecond(1); // 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; Clip.UsdScene.StartTime = currentTime; // 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; } throw; } }
public static void ExportUsdz(string usdzFilePath, GameObject root) { // Setup a temp directory for zipping up files. string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var tmpUsdName = Path.GetFileNameWithoutExtension(usdzFilePath); var di = Directory.CreateDirectory(tempDirectory); var tmpUsdFilePath = Path.Combine(tempDirectory, tmpUsdName + ".usdc"); var curDir = Directory.GetCurrentDirectory(); var supportedExtensions = new System.Collections.Generic.HashSet <string>(); supportedExtensions.Add(".usd"); supportedExtensions.Add(".usda"); supportedExtensions.Add(".usdc"); supportedExtensions.Add(".jpg"); supportedExtensions.Add(".jpeg"); supportedExtensions.Add(".jpe"); supportedExtensions.Add(".jif"); supportedExtensions.Add(".jfif"); supportedExtensions.Add(".jfi"); supportedExtensions.Add(".png"); // Create the temp .usd scene, into which the data will be exported. var scene = InitForSave(tmpUsdFilePath); var localScale = root.transform.localScale; try { try { // USDZ is in centimeters. root.transform.localScale = localScale * 100; // Set the current working directory to the USDZ directory so the paths in USD // will be relative. Directory.SetCurrentDirectory(tempDirectory); // Export the temp scene. SceneExporter.Export(root, scene, BasisTransformation.SlowAndSafe, // Required by ARKit exportUnvarying: true, zeroRootTransform: false, exportMaterials: true); } finally { // Undo temp scale. root.transform.localScale = localScale; // Flush any in-flight edits and release the scene so the file can be deleted. scene.Save(); scene.Close(); scene = null; } // Copy resulting files into the USDZ archive. var filesToArchive = new pxr.StdStringVector(); // According to the USDZ spec, the first file in the archive must be the primary USD file. filesToArchive.Add(tmpUsdFilePath); foreach (var fileInfo in di.GetFiles()) { if (fileInfo.Name.ToLower() == Path.GetFileName(tmpUsdFilePath).ToLower()) { continue; } var relPath = ImporterBase.MakeRelativePath(tmpUsdFilePath, fileInfo.FullName); var ext = Path.GetExtension(relPath).ToLower(); if (!supportedExtensions.Contains(ext)) { Debug.LogWarning("Unsupported file type in USDZ: " + relPath); continue; } filesToArchive.Add(relPath); } // Write the USDZ file. pxr.UsdCs.WriteUsdZip(usdzFilePath, filesToArchive); } finally { // Clean up temp files. Directory.SetCurrentDirectory(curDir); di.Delete(recursive: true); } }