/// <summary> /// Imports the USD scene incrementally, setting a fixed time budget per frame for import /// operations. Uses StartCoroutine. /// </summary> public void ImportUsdAsCoroutine(GameObject goRoot, string usdFilePath, double time, SceneImportOptions importOptions, float targetFrameMilliseconds) { InitUsd.Initialize(); var scene = Scene.Open(usdFilePath); if (scene == null) { throw new Exception("Failed to open: " + usdFilePath); } scene.Time = time; if (scene == null) { throw new Exception("Null USD Scene"); } scene.SetInterpolation(importOptions.interpolate ? Scene.InterpolationMode.Linear : Scene.InterpolationMode.Held); var primMap = new PrimMap(); var importer = SceneImporter.BuildScene(scene, goRoot, importOptions, primMap, targetFrameMilliseconds, composingSubtree: false); StartCoroutine(importer); }
public static string ImportAsTimelineClip(Scene scene) { string path = scene.FilePath; var importOptions = new SceneImportOptions(); importOptions.projectAssetPath = GetSelectedAssetPath(); importOptions.usdRootPath = GetDefaultRoot(scene); importOptions.changeHandedness = BasisTransformation.FastWithNegativeScale; string prefabPath = GetPrefabPath(path, importOptions.projectAssetPath); string clipName = Path.GetFileNameWithoutExtension(path); var go = new GameObject(GetObjectName(importOptions.usdRootPath, path)); try { // Ensure we have at least one GameObject with the import settings. XformImporter.BuildSceneRoot(scene, go.transform, importOptions); SceneImporter.SavePrefab(go, prefabPath, clipName, importOptions); return(prefabPath); } finally { GameObject.DestroyImmediate(go); scene.Close(); } }
public static string ImportAsPrefab(Scene scene) { string path = scene.FilePath; // Time-varying data is not supported and often scenes are written without "Default" time // values, which makes setting an arbitrary time safer (because if only default was authored // the time will be ignored and values will resolve to default time automatically). scene.Time = 1.0; var importOptions = new SceneImportOptions(); importOptions.projectAssetPath = GetSelectedAssetPath(); importOptions.usdRootPath = GetDefaultRoot(scene); string prefabPath = GetPrefabPath(path, importOptions.projectAssetPath); string clipName = Path.GetFileNameWithoutExtension(path); var go = new GameObject(GetObjectName(importOptions.usdRootPath, path)); try { UsdToGameObject(go, scene, importOptions); SceneImporter.SavePrefab(go, prefabPath, clipName, importOptions); return(prefabPath); } finally { Object.DestroyImmediate(go); scene.Close(); } }
/// <summary> /// Reimports the USD scene, either fully rebuilding every object or updating them in-place. /// </summary> /// <param name="forceRebuild">Destroys each GameObject before reimporting.</param> public void Reload(bool forceRebuild) { var options = new SceneImportOptions(); StateToOptions(ref options); options.forceRebuild = forceRebuild; if (string.IsNullOrEmpty(options.projectAssetPath)) { options.projectAssetPath = "Assets/"; OptionsToState(options); } var root = gameObject; string assetPath = GetPrefabAssetPath(root); // The prefab asset path will be null for prefab instances. // When the assetPath is not null, the object is the prefab itself. if (!string.IsNullOrEmpty(assetPath)) { if (options.forceRebuild) { DestroyAllImportedObjects(); } pxr.UsdStageLoadRules.Rule activeLoadRule = m_lastScene.Stage.GetLoadRules().GetEffectiveRuleForPath(new pxr.SdfPath("/")); if ((activeLoadRule == pxr.UsdStageLoadRules.Rule.AllRule && options.payloadPolicy == PayloadPolicy.DontLoadPayloads) || (activeLoadRule == pxr.UsdStageLoadRules.Rule.NoneRule && options.payloadPolicy == PayloadPolicy.LoadAll)) { ClearLastData(); } SceneImporter.ImportUsd(root, GetScene(), new PrimMap(), options); #if UNITY_EDITOR string clipName = Path.GetFileNameWithoutExtension(usdFullPath); // As an optimization, we could detect if any meshes or materials were created and only // rebuild the prefab in those cases. SceneImporter.SavePrefab(root, assetPath, clipName, options); #endif } else { // An instance of a prefab or a vanilla game object. // Just reload the scene into memory and let the user decide if they want to send those // changes back to the prefab or not. if (forceRebuild) { // First, destroy all existing USD game objects. DestroyAllImportedObjects(); } ClearLastData(); SceneImporter.ImportUsd(root, GetScene(), new PrimMap(), options); } }
/// <summary> /// Reimports the USD scene, either fully rebuilding every object or updating them in-place. /// </summary> /// <param name="forceRebuild">Destroys each GameObject before reimporting.</param> public void Reload(bool forceRebuild) { var options = new SceneImportOptions(); StateToOptions(ref options); options.forceRebuild = forceRebuild; if (string.IsNullOrEmpty(options.projectAssetPath)) { options.projectAssetPath = "Assets/"; OptionsToState(options); } var root = gameObject; string assetPath = GetPrefabAssetPath(root); // The prefab asset path will be null for prefab instances. // When the assetPath is not null, the object is the prefab itself. if (!string.IsNullOrEmpty(assetPath)) { if (options.forceRebuild) { DestroyAllImportedObjects(); } SceneImporter.ImportUsd(root, GetScene(), new PrimMap(), options); #if UNITY_EDITOR string clipName = Path.GetFileNameWithoutExtension(usdFullPath); // As an optimization, we could detect if any meshes or materials were created and only // rebuild the prefab in those cases. SceneImporter.SavePrefab(root, assetPath, clipName, options); #endif } else { // An instance of a prefab or a vanilla game object. // Just reload the scene into memory and let the user decide if they want to send those // changes back to the prefab or not. if (forceRebuild) { // First, destroy all existing USD game objects. DestroyAllImportedObjects(); } m_lastScene = null; m_lastPrimMap = null; m_lastAccessMask = null; SceneImporter.ImportUsd(root, GetScene(), new PrimMap(), options); } }
public static GameObject UsdToGameObject(GameObject parent, Scene scene, SceneImportOptions importOptions) { try { SceneImporter.ImportUsd(parent, scene, new PrimMap(), importOptions); } finally { scene.Close(); } return(parent); }
/// <summary> /// Loads or unloads the given payload object. Throws an exception if game object deos not have /// a UsdPrimSource behaviour. /// </summary> public void SetPayloadState(GameObject go, bool isLoaded) { var primSrc = go.GetComponent <UsdPrimSource>(); if (!primSrc) { throw new Exception("UsdPrimSource not found: " + UnityTypeConverter.GetPath(go.transform)); } var usdPrimPath = primSrc.m_usdPrimPath; InitUsd.Initialize(); var scene = GetScene(); if (scene == null) { throw new Exception("Failed to open: " + usdFullPath); } var prim = scene.GetPrimAtPath(usdPrimPath); if (prim == null || !prim) { throw new Exception("Prim not found: " + usdPrimPath); } foreach (var child in go.transform.GetComponentsInChildren <UsdPrimSource>().ToList()) { if (!child || child.gameObject == go) { continue; } GameObject.DestroyImmediate(child.gameObject); } if (!isLoaded) { prim.Unload(); return; } else { prim.Load(); } SceneImportOptions importOptions = new SceneImportOptions(); this.StateToOptions(ref importOptions); importOptions.usdRootPath = prim.GetPath(); SceneImporter.ImportUsd(go, scene, new PrimMap(), true, importOptions); }
public static void MenuImportAsPrefab() { var scene = InitForOpen(); if (scene == null) { return; } string path = scene.FilePath; // Time-varying data is not supported and often scenes are written without "Default" time // values, which makes setting an arbitrary time safer (because if only default was authored // the time will be ignored and values will resolve to default time automatically). scene.Time = 1.0; var importOptions = new SceneImportOptions(); importOptions.projectAssetPath = GetSelectedAssetPath(); importOptions.changeHandedness = BasisTransformation.SlowAndSafe; importOptions.materialImportMode = MaterialImportMode.ImportDisplayColor; importOptions.usdRootPath = GetDefaultRoot(scene); var invalidChars = Path.GetInvalidFileNameChars(); var prefabName = string.Join("_", GetPrefabName(path).Split(invalidChars, System.StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); string prefabPath = importOptions.projectAssetPath + prefabName + ".prefab"; prefabPath = AssetDatabase.GenerateUniqueAssetPath(prefabPath); string clipName = Path.GetFileNameWithoutExtension(path); var go = new GameObject(GetObjectName(importOptions.usdRootPath, path)); try { UsdToGameObject(go, scene, importOptions); SceneImporter.SavePrefab(go, prefabPath, clipName, importOptions); } finally { GameObject.DestroyImmediate(go); scene.Close(); } }
/// <summary> /// Sets the variant selections in USD at the given prim path based on the selections parameter. /// </summary> /// <param name="go">The gameObject at the root of the variant set.</param> /// <param name="usdPrimPath">The USD prim at which to set the variant selection.</param> /// <param name="selections">A collection of (variant set, selection) pairs.</param> /// <remarks> /// A USD prim can have zero or more variant sets, for example a single prim amy have /// "modelingVariant" and "shadingVariant" sets. Each set can have their own slection. /// </remarks> /// <example> /// If two sets with selections are modelingVariant=CupWithHandle and shadingVariant=BrightBlue, /// resulting in a bright blue cup with a handle. In this example, the selections dictionary /// would contain: /// { "modelingVariant" = "CupWithHandle", /// "shadingVariant" = "BrightBlue" } /// </example> public void SetVariantSelection(GameObject go, string usdPrimPath, Dictionary <string, string> selections) { InitUsd.Initialize(); var scene = GetScene(); if (scene == null) { throw new Exception("Failed to open: " + usdFullPath); } var prim = scene.GetPrimAtPath(usdPrimPath); if (prim == null || !prim) { throw new Exception("Prim not found: " + usdPrimPath); } var varSets = prim.GetVariantSets(); foreach (var sel in selections) { if (!varSets.HasVariantSet(sel.Key)) { throw new Exception("Unknown varient set: " + sel.Key + " at " + usdPrimPath); } varSets.GetVariantSet(sel.Key).SetVariantSelection(sel.Value); } // TODO: sparsely remove prims, rather than blowing away all the children. foreach (Transform child in go.transform) { GameObject.DestroyImmediate(child.gameObject); } SceneImportOptions importOptions = new SceneImportOptions(); this.StateToOptions(ref importOptions); importOptions.usdRootPath = prim.GetPath(); SceneImporter.ImportUsd(go, scene, new PrimMap(), true, importOptions); }
public static void ImportUsd(GameObject goRoot, Scene scene, PrimMap primMap, bool composingSubtree, SceneImportOptions importOptions) { if (scene == null) { throw new ImportException("Null USD Scene"); } scene.SetInterpolation(importOptions.interpolate ? Scene.InterpolationMode.Linear : Scene.InterpolationMode.Held); SceneImporter.BuildScene(scene, goRoot, importOptions, primMap, composingSubtree); }
public static void MenuImportAsTimelineClip() { var scene = InitForOpen(); if (scene == null) { return; } string path = scene.FilePath; var invalidChars = Path.GetInvalidFileNameChars(); var prefabName = string.Join("_", GetPrefabName(path).Split(invalidChars, System.StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); string prefabPath = GetSelectedAssetPath() + prefabName + ".prefab"; prefabPath = AssetDatabase.GenerateUniqueAssetPath(prefabPath); string clipName = Path.GetFileNameWithoutExtension(path); var importOptions = new SceneImportOptions(); importOptions.projectAssetPath = GetSelectedAssetPath(); importOptions.changeHandedness = BasisTransformation.FastWithNegativeScale; importOptions.materialImportMode = MaterialImportMode.ImportDisplayColor; importOptions.usdRootPath = GetDefaultRoot(scene); var go = new GameObject(GetObjectName(importOptions.usdRootPath, path)); try { // Ensure we have at least one GameObject with the import settings. XformImporter.BuildSceneRoot(scene, go.transform, importOptions); SceneImporter.SavePrefab(go, prefabPath, clipName, importOptions); } finally { GameObject.DestroyImmediate(go); } }
/// <summary> /// Applies the contents of this USD file to a foreign root object. /// </summary> /// <remarks> /// The idea here is that one may have many animation clips, but only a single GameObject in /// the Unity scenegraph. /// </remarks> public void SetTime(double time, UsdAsset foreignRoot, bool saveMeshUpdates) { var scene = GetScene(); if (scene == null) { Debug.LogWarning("Null scene from GetScene() at " + UnityTypeConverter.GetPath(transform)); return; } // Careful not to update any local members here, if this data is driven from a prefab, we // dont want those changes to be baked back into the asset. time += foreignRoot.m_usdTimeOffset; float usdTime = (float)(scene.StartTime + time * scene.Stage.GetTimeCodesPerSecond()); if (usdTime > scene.EndTime) { return; } if (usdTime < scene.StartTime) { return; } scene.Time = usdTime; var options = new SceneImportOptions(); foreignRoot.StateToOptions(ref options); PrepOptionsForTimeChange(ref options); if (foreignRoot.m_lastPrimMap == null) { foreignRoot.m_lastPrimMap = new PrimMap(); options.importHierarchy = true; } if (m_usdVariabilityCache) { if (m_lastAccessMask == null) { m_lastAccessMask = new AccessMask(); scene.IsPopulatingAccessMask = true; } } else { m_lastAccessMask = null; } if (m_debugPrintVariabilityCache && m_lastAccessMask != null && !scene.IsPopulatingAccessMask) { var sb = new System.Text.StringBuilder(); foreach (var kvp in m_lastAccessMask.Included) { sb.AppendLine(kvp.Key); foreach (var member in kvp.Value) { sb.AppendLine(" ." + member.Name); } sb.AppendLine(); } Debug.Log(sb.ToString()); } scene.AccessMask = m_lastAccessMask; SceneImporter.ImportUsd(foreignRoot.gameObject, scene, foreignRoot.m_lastPrimMap, options); scene.AccessMask = null; if (m_lastAccessMask != null) { scene.IsPopulatingAccessMask = false; } }