Add maxhullvert attribute to mjcPhysics MeshCollisionAPI.

PiperOrigin-RevId: 781482346
Change-Id: I0d53f9ad99ac842629243b0375907b2f91bd3b61
This commit is contained in:
Sam Haves
2025-07-10 04:58:20 -07:00
committed by Copybara-Service
parent 243c011ea0
commit e7212d86bc
9 changed files with 69 additions and 1 deletions
@@ -40,7 +40,7 @@ class SdfAssetPath;
/// \class MjcPhysicsMeshCollisionAPI
///
/// API describing a Mujoco mesh collider.
/// API describing a MuJoCo mesh collider.
///
/// For any described attribute \em Fallback \em Value or \em Allowed \em Values
/// below that are text/tokens, the actual token is published and defined in
@@ -173,6 +173,31 @@ class MjcPhysicsMeshCollisionAPI : public UsdAPISchemaBase {
UsdAttribute CreateInertiaAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// --------------------------------------------------------------------- //
// MAXHULLVERT
// --------------------------------------------------------------------- //
/// Sets an upper limit on the number of vertices in the meshes convex hull.
/// The default value of -1 means unlimited.
///
/// | ||
/// | -- | -- |
/// | Declaration | `uniform int mjc:maxhullvert = -1` |
/// | C++ Type | int |
/// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int |
/// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
MJCPHYSICS_API
UsdAttribute GetMaxHullVertAttr() const;
/// See GetMaxHullVertAttr(), and also
/// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
/// If specified, author \p defaultValue as the attribute's default,
/// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
/// the default for \p writeSparsely is \c false.
MJCPHYSICS_API
UsdAttribute CreateMaxHullVertAttr(VtValue const &defaultValue = VtValue(),
bool writeSparsely = false) const;
public:
// ===================================================================== //
// Feel free to add custom code below this line, it will be preserved by
@@ -356,6 +356,10 @@ struct MjcPhysicsTokensType {
///
/// MjcPhysicsJointAPI
const TfToken mjcMargin;
/// \brief "mjc:maxhullvert"
///
/// MjcPhysicsMeshCollisionAPI
const TfToken mjcMaxhullvert;
/// \brief "mjc:mpos"
///
/// MjcPhysicsKeyframe
@@ -245,6 +245,10 @@ class "MjcMeshCollisionAPI" (
displayName = "Inertia"
doc = "Controls how a mesh is used when mass and inertia are inferred from geometry."
)
uniform int mjc:maxhullvert = -1 (
displayName = "Maximum Hull Vertices"
doc = "Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."
)
}
class "MjcActuatorAPI" (
@@ -88,6 +88,17 @@ UsdAttribute MjcPhysicsMeshCollisionAPI::CreateInertiaAttr(
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
UsdAttribute MjcPhysicsMeshCollisionAPI::GetMaxHullVertAttr() const {
return GetPrim().GetAttribute(MjcPhysicsTokens->mjcMaxhullvert);
}
UsdAttribute MjcPhysicsMeshCollisionAPI::CreateMaxHullVertAttr(
VtValue const &defaultValue, bool writeSparsely) const {
return UsdSchemaBase::_CreateAttr(
MjcPhysicsTokens->mjcMaxhullvert, SdfValueTypeNames->Int,
/* custom = */ false, SdfVariabilityUniform, defaultValue, writeSparsely);
}
namespace {
static inline TfTokenVector _ConcatenateAttributeNames(
const TfTokenVector &left, const TfTokenVector &right) {
@@ -104,6 +115,7 @@ const TfTokenVector &MjcPhysicsMeshCollisionAPI::GetSchemaAttributeNames(
bool includeInherited) {
static TfTokenVector localNames = {
MjcPhysicsTokens->mjcInertia,
MjcPhysicsTokens->mjcMaxhullvert,
};
static TfTokenVector allNames = _ConcatenateAttributeNames(
UsdAPISchemaBase::GetSchemaAttributeNames(true), localNames);
@@ -559,6 +559,14 @@ class "MjcMeshCollisionAPI"
displayName = "Inertia"
doc = """Controls how a mesh is used when mass and inertia are inferred from geometry."""
)
uniform int mjc:maxhullvert = -1 (
customData = {
string apiName = "MaxHullVert"
}
displayName = "Maximum Hull Vertices"
doc = """Sets an upper limit on the number of vertices in the meshes convex hull. The default value of -1 means unlimited."""
)
}
class "MjcActuatorAPI"
@@ -89,6 +89,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcLengthRangeMax("mjc:lengthRange:max", TfToken::Immortal),
mjcLengthRangeMin("mjc:lengthRange:min", TfToken::Immortal),
mjcMargin("mjc:margin", TfToken::Immortal),
mjcMaxhullvert("mjc:maxhullvert", TfToken::Immortal),
mjcMpos("mjc:mpos", TfToken::Immortal),
mjcMquat("mjc:mquat", TfToken::Immortal),
mjcOptionActuatorgroupdisable("mjc:option:actuatorgroupdisable",
@@ -222,6 +223,7 @@ MjcPhysicsTokensType::MjcPhysicsTokensType()
mjcLengthRangeMax,
mjcLengthRangeMin,
mjcMargin,
mjcMaxhullvert,
mjcMpos,
mjcMquat,
mjcOptionActuatorgroupdisable,
@@ -360,6 +360,10 @@ class ModelWriter {
WriteUniformAttribute(mesh_path, pxr::SdfValueTypeNames->Token,
MjcPhysicsTokens->mjcInertia, inertia);
WriteUniformAttribute(mesh_path, pxr::SdfValueTypeNames->Int,
MjcPhysicsTokens->mjcMaxhullvert,
mesh->maxhullvert);
}
// NOTE: The geometry data taken from the spec is the post-compilation
+5
View File
@@ -546,6 +546,11 @@ void ParseMjcPhysicsMeshCollisionAPI(
mesh->inertia = mjtMeshInertia::mjMESH_INERTIA_LEGACY;
}
}
auto maxhullvert_attr = mesh_collision_api.GetMaxHullVertAttr();
if (maxhullvert_attr.HasAuthoredValue()) {
maxhullvert_attr.Get(&mesh->maxhullvert);
}
}
void ParseMjcPhysicsGeneralActuatorAPI(mjSpec* spec,
@@ -1440,6 +1440,7 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) {
<mesh name="tet_exact" inertia="exact" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
<mesh name="tet_convex" inertia="convex" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
<mesh name="tet_shell" inertia="shell" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
<mesh name="tet_max_vert" inertia="shell" maxhullvert="12" vertex="0 0 0 1 0 0 0 1 0 0 0 1"/>
</asset>
<worldbody>
<body name="body">
@@ -1447,6 +1448,7 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) {
<geom name="tet_exact" type="mesh" mesh="tet_exact"/>
<geom name="tet_convex" type="mesh" mesh="tet_convex"/>
<geom name="tet_shell" type="mesh" mesh="tet_shell"/>
<geom name="tet_max_vert" type="mesh" mesh="tet_max_vert"/>
</body>
</worldbody>
</mujoco>
@@ -1461,6 +1463,8 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestMjcPhysicsMeshCollisionAPI) {
MjcPhysicsTokens->convex);
ExpectAttributeEqual(stage, "/test/body/tet_shell/Mesh.mjc:inertia",
MjcPhysicsTokens->shell);
ExpectAttributeEqual(stage, "/test/body/tet_max_vert/Mesh.mjc:maxhullvert",
12);
}
TEST_F(MjcfSdfFileFormatPluginTest, TestMassAPIApplied) {