From 253abad210823254f0f238ef3ad4cc8d975372d3 Mon Sep 17 00:00:00 2001 From: Robin Alazard Date: Fri, 2 May 2025 08:34:28 -0700 Subject: [PATCH] Add MeshCollisionAPI to collider Meshes with convexHull approximation. PiperOrigin-RevId: 754014642 Change-Id: I44cff505a2b9b7120a38f8c896b2c6560ce51c43 --- .../usd/plugins/mjcf/mujoco_to_usd.cc | 15 +++++++++++++++ .../usd/plugins/mjcf/mjcf_file_format_test.cc | 16 +++++++++++----- 2 files changed, 26 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 b89abc3c..ef5e9f71 100644 --- a/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc +++ b/src/experimental/usd/plugins/mjcf/mujoco_to_usd.cc @@ -883,6 +883,21 @@ class ModelWriter { model_->geom_conaffinity[geom_id] != 0)) { ApplyApiSchema(data_, geom_path, pxr::UsdPhysicsTokens->PhysicsCollisionAPI); + // For meshes, also apply PhysicsMeshCollisionAPI and set the + // approximation attribute. + if (geom->type == mjGEOM_MESH) { + ApplyApiSchema(data_, geom_path, + pxr::UsdPhysicsTokens->PhysicsMeshCollisionAPI); + + // Note: MuJoCo documentation states that for collision purposes, meshes + // are always replaced with their convex hulls. Therefore, we set the + // approximation attribute to convexHull explicitly. + pxr::SdfPath approximation_attr = CreateAttributeSpec( + data_, geom_path, pxr::UsdPhysicsTokens->physicsApproximation, + pxr::SdfValueTypeNames->Token, pxr::SdfVariabilityUniform); + SetAttributeDefault(data_, approximation_attr, + pxr::UsdPhysicsTokens->convexHull); + } } mjsDefault *spec_default = mjs_getDefault(geom->element); 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 abdf6a23..22b8ac52 100644 --- a/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc +++ b/test/experimental/usd/plugins/mjcf/mjcf_file_format_test.cc @@ -45,7 +45,9 @@ #include #include #include +#include #include +#include PXR_NAMESPACE_OPEN_SCOPE // clang-format off @@ -675,7 +677,7 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestPhysicsColliders) { // // body_3/body_3 [rigidbody] // body_3/body_3/body_3_col [] <-- Intermediate prim for mesh instancing - // body_3/body_3/body_3_col/Mesh [collider] + // body_3/body_3/body_3_col/Mesh [collider, mesh collider] // ground [collider] (Static collider) EXPECT_PRIM_VALID(stage, "/test/ground"); @@ -753,13 +755,17 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestPhysicsColliders) { pxr::UsdPhysicsRigidBodyAPI); EXPECT_PRIM_API_NOT_APPLIED(stage, "/test/body_3/body_3/body_3_col", pxr::UsdPhysicsCollisionAPI); - // body_3/body_3/body_3_col/Mesh [collider] + // body_3/body_3/body_3_col/Mesh [collider, mesh collider] EXPECT_PRIM_VALID(stage, "/test/body_3/body_3/body_3_col/Mesh"); - EXPECT_PRIM_API_NOT_APPLIED( - stage, "/test/body_3/body_3/body_3_col/Mesh", - pxr::UsdPhysicsRigidBodyAPI); + EXPECT_PRIM_API_NOT_APPLIED(stage, "/test/body_3/body_3/body_3_col/Mesh", + pxr::UsdPhysicsRigidBodyAPI); EXPECT_PRIM_API_APPLIED(stage, "/test/body_3/body_3/body_3_col/Mesh", pxr::UsdPhysicsCollisionAPI); + EXPECT_PRIM_API_APPLIED(stage, "/test/body_3/body_3/body_3_col/Mesh", + pxr::UsdPhysicsMeshCollisionAPI); + ExpectAttributeEqual( + stage, "/test/body_3/body_3/body_3_col/Mesh.physics:approximation", + pxr::UsdPhysicsTokens->convexHull); } } // namespace