USD Export: Armature export improvements.
Now including the root prim in the skinned mesh skeleton relationship path. Also, added logic to avoid nesting SkelRoot prims in the USD, as such nesting causes skeleton binding to fail as well as crashes in Create. Now iterating over the deform groups of the evaluated mesh when setting joint weights and indices, to ensure the vertex group data is valid.
This commit is contained in:
parent
e2a783f8eb
commit
85172cb5e1
|
@ -22,12 +22,47 @@
|
|||
|
||||
namespace blender::io::usd {
|
||||
|
||||
bool USDSkelRootWriter::is_under_skel_root() const
|
||||
{
|
||||
pxr::SdfPath parent_path(usd_export_context_.usd_path);
|
||||
|
||||
parent_path = parent_path.GetParentPath();
|
||||
|
||||
if (parent_path.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::UsdPrim prim = usd_export_context_.stage->GetPrimAtPath(parent_path);
|
||||
|
||||
while (prim.IsValid()) {
|
||||
if (prim.IsA<pxr::UsdSkelRoot>()) {
|
||||
return true;
|
||||
}
|
||||
prim = prim.GetParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::UsdGeomXformable USDSkelRootWriter::create_xformable() const
|
||||
{
|
||||
pxr::UsdSkelRoot root =
|
||||
/* Create a UsdSkelRoot primitive, unless this prim is already
|
||||
beneath a UsdSkelRoot, in which case create an Xform. */
|
||||
|
||||
pxr::UsdGeomXformable root;
|
||||
|
||||
if (is_under_skel_root()) {
|
||||
root =
|
||||
(usd_export_context_.export_params.export_as_overs) ?
|
||||
pxr::UsdSkelRoot(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
|
||||
pxr::UsdSkelRoot::Define(usd_export_context_.stage, usd_export_context_.usd_path);
|
||||
pxr::UsdGeomXform(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
|
||||
pxr::UsdGeomXform::Define(usd_export_context_.stage, usd_export_context_.usd_path);
|
||||
}
|
||||
else {
|
||||
root =
|
||||
(usd_export_context_.export_params.export_as_overs) ?
|
||||
pxr::UsdSkelRoot(usd_export_context_.stage->OverridePrim(usd_export_context_.usd_path)) :
|
||||
pxr::UsdSkelRoot::Define(usd_export_context_.stage, usd_export_context_.usd_path);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ class USDSkelRootWriter : public USDTransformWriter {
|
|||
protected:
|
||||
/* Override to create UsdSkelRoot prim. */
|
||||
pxr::UsdGeomXformable create_xformable() const override;
|
||||
|
||||
/* Rturns true if the prim to be created is
|
||||
* already unde a USD SkeRoot. */
|
||||
bool is_under_skel_root() const;
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -136,6 +136,10 @@ void USDSkinnedMeshWriter::do_write(HierarchyContext &context)
|
|||
return;
|
||||
}
|
||||
|
||||
if (strlen(usd_export_context_.export_params.root_prim_path) != 0) {
|
||||
skel_path = std::string(usd_export_context_.export_params.root_prim_path) + skel_path;
|
||||
}
|
||||
|
||||
usd_skel_api.CreateSkeletonRel().SetTargets(pxr::SdfPathVector({pxr::SdfPath(skel_path)}));
|
||||
|
||||
if (pxr::UsdAttribute geom_bind_attr = usd_skel_api.CreateGeomBindTransformAttr()) {
|
||||
|
@ -186,7 +190,7 @@ void USDSkinnedMeshWriter::write_weights(const Object *ob,
|
|||
|
||||
std::vector<int> group_to_bone_idx;
|
||||
|
||||
for (bDeformGroup *def = (bDeformGroup *)ob->defbase.first; def; def = def->next) {
|
||||
for (const bDeformGroup *def = (const bDeformGroup *)mesh->vertex_group_names.first; def; def = def->next) {
|
||||
|
||||
int bone_idx = -1;
|
||||
/* For now, n-squared search is acceptable. */
|
||||
|
|
Loading…
Reference in New Issue