Esempio n. 1
0
        static void PopulateSkelCache(ref HierInfo skelRootInfo, UsdSkelCache skelCache)
        {
            //
            // Populate the UsdSkelCache.
            //
            var skelRoot = new UsdSkelRoot(skelRootInfo.prim);

            if (!skelRoot)
            {
                return;
            }

            if (!skelCache.Populate(skelRoot))
            {
                Debug.LogWarning("Failed to populate skel cache: " + skelRootInfo.prim.GetPath());
                return;
            }

            try {
                var binding = new UsdSkelBindingVector();
                if (!skelCache.ComputeSkelBindings(skelRoot, binding))
                {
                    Debug.LogWarning("ComputeSkelBindings failed: " + skelRootInfo.prim.GetPath());
                    return;
                }
                skelRootInfo.skelBindings = binding;
            } catch {
                Debug.LogError("Failed to compute binding for SkelRoot: " + skelRootInfo.prim.GetPath());
            }
        }
Esempio n. 2
0
        static void ReadModelInfo(ref HierInfo info)
        {
            if (!info.prim)
            {
                return;
            }

            var modelApi = new UsdModelAPI(info.prim);

            if (!modelApi)
            {
                return;
            }

            var kindTok = new TfToken();

            if (!modelApi.GetKind(kindTok))
            {
                return;
            }

            if (KindRegistry.IsA(kindTok, KindTokens.assembly))
            {
                info.isAssembly = true;
            }
            else if (!modelApi.IsModel() || modelApi.IsGroup())
            {
                return;
            }

            var modelInfo = new VtDictionary();

            if (!modelApi.GetAssetInfo(modelInfo))
            {
                return;
            }

            info.isModel = true;

            var valName       = modelInfo.GetValueAtPath("name");
            var valVersion    = modelInfo.GetValueAtPath("version");
            var valIdentifier = modelInfo.GetValueAtPath("identifier");

            if (valIdentifier != null && !valIdentifier.IsEmpty())
            {
                info.modelAssetPath = UsdCs.VtValueToSdfAssetPath(valIdentifier).GetAssetPath().ToString();
            }

            if (valName != null && !valName.IsEmpty())
            {
                info.modelName = UsdCs.VtValueTostring(valName);
            }

            if (valVersion != null && !valVersion.IsEmpty())
            {
                info.modelVersion = UsdCs.VtValueTostring(valVersion);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// If there is a Payload authored on this prim, expose it so the user can change the
        /// load state.
        /// </summary>
        static void AddPayload(GameObject go, HierInfo info, SceneImportOptions options)
        {
            var pl = go.GetComponent <UsdPayload>();

            if (!info.hasPayload)
            {
                if (pl)
                {
                    Component.DestroyImmediate(pl);
                }
                return;
            }

            if (!pl)
            {
                pl = go.AddComponent <UsdPayload>();
                pl.SetInitialState(options.payloadPolicy == PayloadPolicy.LoadAll);
            }
        }
Esempio n. 4
0
            public void Execute(int index)
            {
                HierInfo info = new HierInfo();

                info.prim = scene.Stage.GetPrimAtPath(paths[index]);

                if (!info.prim)
                {
                    info.prim = null;
                    return;
                }

                info.isVisible  = HierarchyBuilder.IsVisible(info.prim);
                info.isInstance = info.prim.IsInstance();
                HierarchyBuilder.ReadModelInfo(ref info);
                HierarchyBuilder.ReadSkeleton(ref info);
                info.hasPayload = info.prim.GetPrimIndex().HasPayload();

                result[index] = info;
            }
Esempio n. 5
0
        /// <summary>
        /// Exposes model root and asset metadata. The game object is primarily a tag which is useful
        /// for smart selection of models instead of geometry.
        /// </summary>
        static void AddModelRoot(GameObject go, HierInfo info)
        {
            if (info.isAssembly)
            {
                var asm = go.GetComponent <UsdAssemblyRoot>();
                if (!asm)
                {
                    go.AddComponent <UsdAssemblyRoot>();
                }
            }
            else if (info.isModel)
            {
                var mdl = go.GetComponent <UsdModelRoot>();
                if (!mdl)
                {
                    mdl = go.AddComponent <UsdModelRoot>();
                }

                mdl.m_modelAssetPath = info.modelAssetPath;
                mdl.m_modelName      = info.modelName;
                mdl.m_modelVersion   = info.modelVersion;
            }
            else
            {
                // If these tags were added previously, remove them.
                var mdl = go.GetComponent <UsdModelRoot>();
                if (mdl)
                {
                    Component.DestroyImmediate(mdl);
                }

                var asm = go.GetComponent <UsdAssemblyRoot>();
                if (asm)
                {
                    Component.DestroyImmediate(asm);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Given an array of bone names (HierInfo.skelJoints), creates GameObjects under unityRoot.
        /// </summary>
        static void ExpandSkeleton(HierInfo info,
                                   GameObject unityRoot,
                                   SdfPath usdRoot,
                                   UsdPrim prim,
                                   PrimMap map,
                                   SceneImportOptions options)
        {
            foreach (var joint in info.skelJoints)
            {
                var        path     = joint;
                GameObject parentGo = null;
                if (!map.TryGetValue(path.GetParentPath(), out parentGo))
                {
                    // This will happen when the joints are discontinuous, for example:
                    //
                    //   Foo/Bar
                    //   Foo/Bar/Baz/Qux
                    //
                    // Baz is implicitly defined, which is allowed by UsdSkel.
                    CreateAncestors(path, map, unityRoot, usdRoot, options, out parentGo);
                    if (!parentGo)
                    {
                        Debug.LogException(new Exception("Failed to create ancestors for " + path + " for prim: " +
                                                         prim.GetPath()));
                        continue;
                    }
                }

                Transform child = parentGo.transform.Find(path.GetName());
                if (!child)
                {
                    child = new GameObject(path.GetName()).transform;
                    child.SetParent(parentGo.transform, worldPositionStays: false);
                }

                map[path] = child.gameObject;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// If HierInfo represents a UsdSkelRoot, reads the associated skelton joints into the
        /// skelJoints member.
        /// </summary>
        static void ReadSkeletonJoints(ref HierInfo skelRootInfo)
        {
            if (skelRootInfo.prim == null)
            {
                return;
            }

            var skelRoot = new UsdSkelRoot(skelRootInfo.prim);

            if (!skelRoot)
            {
                return;
            }

            var processed = new HashSet <SdfPath>();

            foreach (UsdSkelBinding binding in skelRootInfo.skelBindings)
            {
                var skel = binding.GetSkeleton();

                if (!skel)
                {
                    continue;
                }

                // If the same skeleton is referenced multiple times, only process it once.
                if (processed.Contains(skel.GetPath()))
                {
                    continue;
                }
                processed.Add(skel.GetPath());

                var jointsAttr = skel.GetJointsAttr();
                if (!jointsAttr)
                {
                    continue;
                }

                var vtJoints = jointsAttr.Get();
                if (vtJoints.IsEmpty())
                {
                    continue;
                }
                var vtStrings = UsdCs.VtValueToVtTokenArray(vtJoints);
                var joints    = UnityTypeConverter.FromVtArray(vtStrings);

                var skelPath = skel.GetPath();
                skelRootInfo.skelJoints = new SdfPath[joints.Length];

                for (int i = 0; i < joints.Length; i++)
                {
                    var jointPath = new SdfPath(joints[i]);
                    if (joints[i] == "/")
                    {
                        skelRootInfo.skelJoints[i] = skelPath;
                        continue;
                    }
                    else if (jointPath.IsAbsolutePath())
                    {
                        Debug.LogException(new Exception("Unexpected absolute joint path: " + jointPath));
                        jointPath = new SdfPath(joints[i].TrimStart('/'));
                    }
                    skelRootInfo.skelJoints[i] = skelPath.AppendPath(jointPath);
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Map all UsdPrims and build Unity GameObjects, reconstructing the parent relationship.
        /// </summary>
        /// <remarks>
        /// When forceRebuild is true, game objects will be destroyed and recreated. If buildHierarchy
        /// is false, the primMap will be populated, but missing game objects will not be created.
        /// </remarks>
        static public PrimMap BuildGameObjects(Scene scene,
                                               GameObject unityRoot,
                                               SdfPath usdRoot,
                                               IEnumerable <SdfPath> paths,
                                               PrimMap map,
                                               SceneImportOptions options)
        {
            map[usdRoot] = unityRoot;

            // Like all GameObjects imported from USD, ensure the root has a UsdPrimSource.
            if (unityRoot.GetComponent <UsdPrimSource>() == null)
            {
                var ua = unityRoot.AddComponent <UsdPrimSource>();
                ua.m_usdPrimPath = usdRoot.ToString();
            }

            Profiler.BeginSample("Build Object Lists");
            var hierInfo = BuildObjectLists(scene, unityRoot, usdRoot, map, options);

            Profiler.EndSample();

            // TODO: Should recurse to discover deeply nested instancing.
            // TODO: Generates garbage for every prim, but we expect few masters.
            if (options.importPointInstances || options.importSceneInstances)
            {
                Profiler.BeginSample("Build Masters");
                foreach (var masterRootPrim in scene.Stage.GetMasters())
                {
                    var goMaster = FindOrCreateGameObject(unityRoot.transform,
                                                          masterRootPrim.GetPath(),
                                                          unityRoot.transform,
                                                          map,
                                                          options);

                    goMaster.hideFlags = HideFlags.HideInHierarchy;
                    goMaster.SetActive(false);
                    map.AddMasterRoot(masterRootPrim.GetPath(), goMaster);
                    try {
                        var info = new HierInfo();
                        info.prim = masterRootPrim;
                        ReadModelInfo(ref info);
                        AddModelRoot(goMaster, info);
                        AddVariantSet(goMaster, masterRootPrim);
                    } catch (Exception ex) {
                        Debug.LogException(new Exception("Error processing " + masterRootPrim.GetPath(), ex));
                    }

                    foreach (var usdPrim in masterRootPrim.GetDescendants())
                    {
                        var       parentPath = usdPrim.GetPath().GetParentPath();
                        Transform parentXf   = null;
                        if (parentPath == masterRootPrim.GetPath())
                        {
                            parentXf = goMaster.transform;
                        }
                        else
                        {
                            parentXf = map[parentPath].transform;
                        }

                        var goPrim = FindOrCreateGameObject(parentXf,
                                                            usdPrim.GetPath(),
                                                            unityRoot.transform,
                                                            map,
                                                            options);
                        ApplySelfVisibility(goPrim, usdPrim);

                        if (usdPrim.IsInstance())
                        {
                            map.AddInstanceRoot(usdPrim.GetPath(), goPrim, usdPrim.GetMaster().GetPath());
                        }

                        try {
                            var info = new HierInfo();
                            info.prim = usdPrim;
                            ReadModelInfo(ref info);
                            AddModelRoot(goPrim, info);
                            AddVariantSet(goPrim, usdPrim);
                        } catch (Exception ex) {
                            Debug.LogException(new Exception("Error processing " + usdPrim.GetPath(), ex));
                            continue;
                        }
                    }
                }
                Profiler.EndSample();
            }

            if (options.importSkinning)
            {
                Profiler.BeginSample("Expand Skeletons");
                foreach (var info in hierInfo)
                {
                    if (info.skelJoints == null || info.skelJoints.Length == 0)
                    {
                        continue;
                    }

                    try {
                        ExpandSkeleton(info, unityRoot, usdRoot, info.prim, map, options);
                    } catch (Exception ex) {
                        Debug.LogException(new Exception("Error expanding skeleton at " + info.prim.GetPath(), ex));
                    }
                }
                Profiler.EndSample();
            }

            return(map);
        }
Esempio n. 9
0
        static void ReadSkeleton(ref HierInfo info)
        {
            if (info.prim == null)
            {
                return;
            }

            var skelRoot = new UsdSkelRoot(info.prim);

            if (!skelRoot)
            {
                return;
            }

            var skelRel = info.prim.GetRelationship(UsdSkelTokens.skelSkeleton);

            if (!skelRel)
            {
                return;
            }

            SdfPathVector targets = skelRel.GetForwardedTargets();

            if (targets == null || targets.Count == 0)
            {
                return;
            }

            var skelPrim = info.prim.GetStage().GetPrimAtPath(targets[0]);

            if (!skelPrim)
            {
                return;
            }

            var skel = new UsdSkelSkeleton(skelPrim);

            if (!skel)
            {
                return;
            }

            var jointsAttr = skel.GetJointsAttr();

            if (!jointsAttr)
            {
                return;
            }

            var vtJoints = jointsAttr.Get();

            if (vtJoints.IsEmpty())
            {
                return;
            }
            var vtStrings = UsdCs.VtValueToVtTokenArray(vtJoints);
            var joints    = UnityTypeConverter.FromVtArray(vtStrings);

            var skelPath = skelPrim.GetPath();

            info.skelJoints = new SdfPath[joints.Length];

            for (int i = 0; i < joints.Length; i++)
            {
                var jointPath = new SdfPath(joints[i]);
                if (joints[i] == "/")
                {
                    info.skelJoints[i] = skelPath;
                    continue;
                }
                else if (jointPath.IsAbsolutePath())
                {
                    Debug.LogException(new Exception("Unexpected absolute joint path: " + jointPath));
                    jointPath = new SdfPath(joints[i].TrimStart('/'));
                }
                info.skelJoints[i] = skelPath.AppendPath(jointPath);
            }
        }