コード例 #1
0
ファイル: UsdAsset.cs プロジェクト: soulhez/usd-unity-sdk
        /// <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);
        }
コード例 #2
0
        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();
            }
        }
コード例 #3
0
        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();
            }
        }
コード例 #4
0
        /// <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);
            }
        }
コード例 #5
0
        /// <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);
            }
        }
コード例 #6
0
        public static GameObject UsdToGameObject(GameObject parent,
                                                 Scene scene,
                                                 SceneImportOptions importOptions)
        {
            try {
                SceneImporter.ImportUsd(parent, scene, new PrimMap(), importOptions);
            } finally {
                scene.Close();
            }

            return(parent);
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        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();
            }
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
ファイル: UsdAsset.cs プロジェクト: soulhez/usd-unity-sdk
        /// <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;
            }
        }