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()); } }
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); } }
/// <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); } }
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; }
/// <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); } } }
/// <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; } }
/// <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); } } }
/// <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); }
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); } }