Skip to content

Commit c439628

Browse files
havesscopybara-github
authored andcommitted
When parsing USD, infer gravity from stage metadata if UsdPhysicsScene missing or undefined.
PiperOrigin-RevId: 813705210 Change-Id: I13741af6dc87ecd9efb83219e978f5f06c72d021
1 parent b1ae44d commit c439628

File tree

1 file changed

+50
-10
lines changed

1 file changed

+50
-10
lines changed

src/experimental/usd/usd_to_mjspec.cc

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstddef>
1717
#include <map>
1818
#include <memory>
19+
#include <optional>
1920
#include <string>
2021
#include <vector>
2122

@@ -51,6 +52,7 @@
5152
#include <pxr/usd/usdGeom/cylinder.h>
5253
#include <pxr/usd/usdGeom/gprim.h>
5354
#include <pxr/usd/usdGeom/mesh.h>
55+
#include <pxr/usd/usdGeom/metrics.h>
5456
#include <pxr/usd/usdGeom/plane.h>
5557
#include <pxr/usd/usdGeom/primvar.h>
5658
#include <pxr/usd/usdGeom/primvarsAPI.h>
@@ -383,20 +385,55 @@ mjsMesh* ParseUsdMesh(mjSpec* spec, const pxr::UsdPrim& prim, mjsGeom* geom,
383385
return mesh;
384386
}
385387

388+
void SetGravityAttributes(
389+
mjSpec* spec, const pxr::UsdStageRefPtr stage,
390+
std::optional<pxr::GfVec3f> gravity_direction = std::nullopt,
391+
std::optional<float> gravity_magnitude = std::nullopt) {
392+
// Parse gravity and gravity direction.
393+
if (!gravity_direction.has_value()) {
394+
TfToken up_axis = pxr::UsdGeomGetStageUpAxis(stage);
395+
if (up_axis == pxr::UsdGeomTokens->y) {
396+
gravity_direction = pxr::GfVec3f(0, -1, 0);
397+
} else if (up_axis == pxr::UsdGeomTokens->z) {
398+
gravity_direction = pxr::GfVec3f(0, 0, -1);
399+
} else {
400+
mju_error("Invalid stage up axis token %s", up_axis.GetString().c_str());
401+
}
402+
}
403+
404+
if (!gravity_magnitude.has_value()) {
405+
gravity_magnitude = 9.81f / pxr::UsdGeomGetStageMetersPerUnit(stage);
406+
}
407+
408+
pxr::GfVec3f gravity = gravity_direction.value() * gravity_magnitude.value();
409+
410+
spec->option.gravity[0] = gravity[0];
411+
spec->option.gravity[1] = gravity[1];
412+
spec->option.gravity[2] = gravity[2];
413+
}
414+
386415
void ParseUsdPhysicsScene(mjSpec* spec,
387416
const pxr::UsdPhysicsScene& physics_scene) {
388-
// Parse gravity and gravity direction.
389-
pxr::GfVec3f gravity_direction;
390-
physics_scene.GetGravityDirectionAttr().Get(&gravity_direction);
417+
std::optional<pxr::GfVec3f> gravity_direction = std::nullopt;
418+
std::optional<float> gravity_magnitude = std::nullopt;
419+
auto stage = physics_scene.GetPrim().GetStage();
391420

392-
float gravity_magnitude;
393-
physics_scene.GetGravityMagnitudeAttr().Get(&gravity_magnitude);
421+
// Parse gravity and gravity direction.
422+
auto gravity_direction_attr = physics_scene.GetGravityDirectionAttr();
423+
if (gravity_direction_attr.HasAuthoredValue()) {
424+
pxr::GfVec3f authored_gravity_dir;
425+
gravity_direction_attr.Get(&authored_gravity_dir);
426+
gravity_direction = authored_gravity_dir;
427+
}
394428

395-
gravity_direction *= gravity_magnitude;
429+
auto gravity_magnitude_attr = physics_scene.GetGravityMagnitudeAttr();
430+
if (gravity_magnitude_attr.HasAuthoredValue()) {
431+
float authored_gravity_magnitude;
432+
gravity_magnitude_attr.Get(&authored_gravity_magnitude);
433+
gravity_magnitude = authored_gravity_magnitude;
434+
}
396435

397-
spec->option.gravity[0] = gravity_direction[0];
398-
spec->option.gravity[1] = gravity_direction[1];
399-
spec->option.gravity[2] = gravity_direction[2];
436+
SetGravityAttributes(spec, stage, gravity_direction, gravity_magnitude);
400437

401438
// Early exit if theres no MjcPhysicsSceneAPI applied.
402439
if (!physics_scene.GetPrim().HasAPI<pxr::MjcPhysicsSceneAPI>()) {
@@ -1724,6 +1761,10 @@ mjSpec* mj_parseUSDStage(const pxr::UsdStageRefPtr stage) {
17241761
if (!root->physics_scene.IsEmpty()) {
17251762
mujoco::usd::ParseUsdPhysicsScene(
17261763
spec, pxr::UsdPhysicsScene::Get(stage, root->physics_scene));
1764+
} else {
1765+
// If there is no physics scene we still need to infer the gravity vector
1766+
// from the stage up axis and units per meter metadata.
1767+
mujoco::usd::SetGravityAttributes(spec, stage);
17271768
}
17281769

17291770
if (!root->keyframes.empty()) {
@@ -1754,4 +1795,3 @@ MJAPI mjSpec* mj_parseUSD(const char* identifier, const mjVFS* vfs, char* error,
17541795
auto stage = pxr::UsdStage::Open(identifier);
17551796
return mj_parseUSDStage(stage);
17561797
}
1757-

0 commit comments

Comments
 (0)