From 02656532c2ef7ebb1f7e45158fc6a01a856fd61e Mon Sep 17 00:00:00 2001
From: Robin Alazard
Date: Fri, 2 May 2025 03:46:34 -0700
Subject: [PATCH] Fix Mesh PhysicsCollisionAPI by accounting for how it's
referenced/instanced.
Because we introduce an additional parent scope when referencing a `Mesh` prim (required for instancing), we need to create an `over` prim that allows to actually operate on the to-be-referenced Mesh.
PiperOrigin-RevId: 753941355
Change-Id: I829be9e82fe650802afcbc46f4b2f4c81eb53bd1
---
.../usd/plugins/mjcf/mujoco_to_usd.cc | 16 ++++++---
.../usd/plugins/mjcf/mjcf_file_format_test.cc | 34 ++++++++++++++++++-
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc
index d4da714a..b89abc3c 100644
--- a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc
+++ b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc
@@ -66,7 +66,6 @@ using TfStaticData = pxr::TfStaticData;
// clang-format off
TF_DEFINE_PRIVATE_TOKENS(kTokens,
- // Xform ops
((body, "Body"))
((body_name, "mujoco:body_name"))
((geom, "Geom"))
@@ -89,7 +88,8 @@ TF_DEFINE_PRIVATE_TOKENS(kTokens,
((outputsRgb, "outputs:rgb"))
((inputsMetallic, "inputs:metallic"))
(repeat)
- );
+ ((sourceMesh, pxr::UsdGeomTokens->Mesh))
+ );
// Using to satisfy TF_REGISTRY_FUNCTION macro below and avoid operating in PXR_NS.
using pxr::TfEnum;
@@ -330,7 +330,7 @@ class ModelWriter {
pxr::SdfPath subcomponent_path =
CreatePrimSpec(data_, parent_path, name, pxr::UsdGeomTokens->Xform);
pxr::SdfPath mesh_path =
- CreatePrimSpec(data_, subcomponent_path, pxr::UsdGeomTokens->Mesh,
+ CreatePrimSpec(data_, subcomponent_path, kTokens->sourceMesh,
pxr::UsdGeomTokens->Mesh);
mesh_paths_[*mesh->name] = subcomponent_path;
@@ -600,7 +600,15 @@ class ModelWriter {
// Reference the mesh asset written in WriteMeshes.
AddPrimReference(data_, subcomponent_path, mesh_paths_[*geom->meshname]);
- return subcomponent_path;
+ // We want to use instancing with meshes, and it requires creating a parent
+ // scope to be referenced, with the Mesh prim as a child.
+ // To be able to actually manipulate the Mesh prim, we need to create and
+ // return the corresponding `over` prim as a child of the referencing prim.
+ pxr::SdfPath over_mesh_path =
+ CreatePrimSpec(data_, subcomponent_path, kTokens->sourceMesh,
+ pxr::UsdGeomTokens->Mesh, pxr::SdfSpecifierOver);
+
+ return over_mesh_path;
}
pxr::SdfPath WriteSiteGeom(const mjsSite *site,
diff --git a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc
index fb2a1a65..abdf6a23 100644
--- a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc
+++ b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc
@@ -612,6 +612,9 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestPhysicsRigidBody) {
TEST_F(MjcfSdfFileFormatPluginTest, TestPhysicsColliders) {
static constexpr char kXml[] = R"(
+
+
+
@@ -636,6 +639,11 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestPhysicsColliders) {
+
+
+