Add basic site support to Mjcf SdfFileFormat plugin.

We will still need to tag these with a custom API schema to ease round-tripping but that will follow creation of such a schema.

PiperOrigin-RevId: 746421793
Change-Id: I2df2209b4bc90d763718fb4bea8158b8598755c6
This commit is contained in:
Sam Haves
2025-04-11 05:26:59 -07:00
committed by Copybara-Service
parent 440ce5eb7a
commit 446a8f1742
5 changed files with 214 additions and 55 deletions
@@ -29,12 +29,26 @@
#define EXPECT_PRIM_VALID(stage, path) \
EXPECT_TRUE((stage)->GetPrimAtPath(SdfPath(path)).IsValid());
#define EXPECT_PRIM_IS_A(stage, path, type) \
{ \
EXPECT_TRUE((stage)->GetPrimAtPath(SdfPath(path)).IsA<type>()); \
}
#define EXPECT_PRIM_KIND(stage, path, kind) \
{ \
pxr::TfToken prim_kind; \
pxr::UsdModelAPI::Get(stage, SdfPath(path)).GetKind(&prim_kind); \
EXPECT_EQ(kind, prim_kind); \
}
#define EXPECT_PRIM_PURPOSE(stage, path, purpose) \
{ \
pxr::TfToken prim_purpose; \
pxr::UsdGeomImageable::Get(stage, SdfPath(path)) \
.GetPurposeAttr() \
.Get(&prim_purpose); \
EXPECT_EQ(prim_purpose, purpose); \
}
namespace mujoco {
pxr::SdfLayerRefPtr LoadLayer(const std::string& xml);
@@ -36,9 +36,14 @@
#include <pxr/usd/usd/modelAPI.h>
#include <pxr/usd/usd/prim.h>
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usdGeom/capsule.h>
#include <pxr/usd/usdGeom/cube.h>
#include <pxr/usd/usdGeom/cylinder.h>
#include <pxr/usd/usdGeom/mesh.h>
#include <pxr/usd/usdGeom/primvar.h>
#include <pxr/usd/usdGeom/primvarsAPI.h>
#include <pxr/usd/usdGeom/sphere.h>
#include <pxr/usd/usdGeom/tokens.h>
PXR_NAMESPACE_OPEN_SCOPE
// clang-format off
@@ -383,5 +388,52 @@ TEST_F(MjcfSdfFileFormatPluginTest, TestKindAuthoring) {
EXPECT_PRIM_KIND(stage, "/test/root/tet", pxr::KindTokens->subcomponent);
}
static constexpr char kSiteXml[] = R"(
<mujoco model="test">
<worldbody>
<site type="box" name="box_site"/>
<body name="ball">
<site type="sphere" name="sphere_site"/>
<site type="capsule" name="capsule_site"/>
<site type="cylinder" name="cylinder_site"/>
<site type="ellipsoid" name="ellipsoid_site"/>
<geom type="sphere" size="1 1 1"/>
</body>
</worldbody>
</mujoco>
)";
TEST_F(MjcfSdfFileFormatPluginTest, TestSitePrimsAuthored) {
pxr::SdfLayerRefPtr layer = LoadLayer(kSiteXml);
auto stage = pxr::UsdStage::Open(layer);
EXPECT_PRIM_VALID(stage, "/test/box_site");
EXPECT_PRIM_IS_A(stage, "/test/box_site", pxr::UsdGeomCube);
EXPECT_PRIM_VALID(stage, "/test/ball/ball/sphere_site");
EXPECT_PRIM_IS_A(stage, "/test/ball/ball/sphere_site", pxr::UsdGeomSphere);
EXPECT_PRIM_VALID(stage, "/test/ball/ball/capsule_site");
EXPECT_PRIM_IS_A(stage, "/test/ball/ball/capsule_site", pxr::UsdGeomCapsule);
EXPECT_PRIM_VALID(stage, "/test/ball/ball/cylinder_site");
EXPECT_PRIM_IS_A(stage, "/test/ball/ball/cylinder_site",
pxr::UsdGeomCylinder);
EXPECT_PRIM_VALID(stage, "/test/ball/ball/ellipsoid_site");
EXPECT_PRIM_IS_A(stage, "/test/ball/ball/ellipsoid_site", pxr::UsdGeomSphere);
}
TEST_F(MjcfSdfFileFormatPluginTest, TestSitePrimsPurpose) {
pxr::SdfLayerRefPtr layer = LoadLayer(kSiteXml);
auto stage = pxr::UsdStage::Open(layer);
EXPECT_PRIM_PURPOSE(stage, "/test/box_site", pxr::UsdGeomTokens->guide);
EXPECT_PRIM_PURPOSE(stage, "/test/ball/ball/sphere_site",
pxr::UsdGeomTokens->guide);
EXPECT_PRIM_PURPOSE(stage, "/test/ball/ball/capsule_site",
pxr::UsdGeomTokens->guide);
EXPECT_PRIM_PURPOSE(stage, "/test/ball/ball/cylinder_site",
pxr::UsdGeomTokens->guide);
EXPECT_PRIM_PURPOSE(stage, "/test/ball/ball/ellipsoid_site",
pxr::UsdGeomTokens->guide);
}
} // namespace
} // namespace mujoco