When parsing USD, infer gravity from stage metadata if UsdPhysicsScene missing or undefined.
PiperOrigin-RevId: 813705210 Change-Id: I13741af6dc87ecd9efb83219e978f5f06c72d021
This commit is contained in:
committed by
Copybara-Service
parent
b1ae44d10f
commit
c439628f82
@@ -16,6 +16,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@
|
|||||||
#include <pxr/usd/usdGeom/cylinder.h>
|
#include <pxr/usd/usdGeom/cylinder.h>
|
||||||
#include <pxr/usd/usdGeom/gprim.h>
|
#include <pxr/usd/usdGeom/gprim.h>
|
||||||
#include <pxr/usd/usdGeom/mesh.h>
|
#include <pxr/usd/usdGeom/mesh.h>
|
||||||
|
#include <pxr/usd/usdGeom/metrics.h>
|
||||||
#include <pxr/usd/usdGeom/plane.h>
|
#include <pxr/usd/usdGeom/plane.h>
|
||||||
#include <pxr/usd/usdGeom/primvar.h>
|
#include <pxr/usd/usdGeom/primvar.h>
|
||||||
#include <pxr/usd/usdGeom/primvarsAPI.h>
|
#include <pxr/usd/usdGeom/primvarsAPI.h>
|
||||||
@@ -383,20 +385,55 @@ mjsMesh* ParseUsdMesh(mjSpec* spec, const pxr::UsdPrim& prim, mjsGeom* geom,
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetGravityAttributes(
|
||||||
|
mjSpec* spec, const pxr::UsdStageRefPtr stage,
|
||||||
|
std::optional<pxr::GfVec3f> gravity_direction = std::nullopt,
|
||||||
|
std::optional<float> gravity_magnitude = std::nullopt) {
|
||||||
|
// Parse gravity and gravity direction.
|
||||||
|
if (!gravity_direction.has_value()) {
|
||||||
|
TfToken up_axis = pxr::UsdGeomGetStageUpAxis(stage);
|
||||||
|
if (up_axis == pxr::UsdGeomTokens->y) {
|
||||||
|
gravity_direction = pxr::GfVec3f(0, -1, 0);
|
||||||
|
} else if (up_axis == pxr::UsdGeomTokens->z) {
|
||||||
|
gravity_direction = pxr::GfVec3f(0, 0, -1);
|
||||||
|
} else {
|
||||||
|
mju_error("Invalid stage up axis token %s", up_axis.GetString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gravity_magnitude.has_value()) {
|
||||||
|
gravity_magnitude = 9.81f / pxr::UsdGeomGetStageMetersPerUnit(stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
pxr::GfVec3f gravity = gravity_direction.value() * gravity_magnitude.value();
|
||||||
|
|
||||||
|
spec->option.gravity[0] = gravity[0];
|
||||||
|
spec->option.gravity[1] = gravity[1];
|
||||||
|
spec->option.gravity[2] = gravity[2];
|
||||||
|
}
|
||||||
|
|
||||||
void ParseUsdPhysicsScene(mjSpec* spec,
|
void ParseUsdPhysicsScene(mjSpec* spec,
|
||||||
const pxr::UsdPhysicsScene& physics_scene) {
|
const pxr::UsdPhysicsScene& physics_scene) {
|
||||||
|
std::optional<pxr::GfVec3f> gravity_direction = std::nullopt;
|
||||||
|
std::optional<float> gravity_magnitude = std::nullopt;
|
||||||
|
auto stage = physics_scene.GetPrim().GetStage();
|
||||||
|
|
||||||
// Parse gravity and gravity direction.
|
// Parse gravity and gravity direction.
|
||||||
pxr::GfVec3f gravity_direction;
|
auto gravity_direction_attr = physics_scene.GetGravityDirectionAttr();
|
||||||
physics_scene.GetGravityDirectionAttr().Get(&gravity_direction);
|
if (gravity_direction_attr.HasAuthoredValue()) {
|
||||||
|
pxr::GfVec3f authored_gravity_dir;
|
||||||
|
gravity_direction_attr.Get(&authored_gravity_dir);
|
||||||
|
gravity_direction = authored_gravity_dir;
|
||||||
|
}
|
||||||
|
|
||||||
float gravity_magnitude;
|
auto gravity_magnitude_attr = physics_scene.GetGravityMagnitudeAttr();
|
||||||
physics_scene.GetGravityMagnitudeAttr().Get(&gravity_magnitude);
|
if (gravity_magnitude_attr.HasAuthoredValue()) {
|
||||||
|
float authored_gravity_magnitude;
|
||||||
|
gravity_magnitude_attr.Get(&authored_gravity_magnitude);
|
||||||
|
gravity_magnitude = authored_gravity_magnitude;
|
||||||
|
}
|
||||||
|
|
||||||
gravity_direction *= gravity_magnitude;
|
SetGravityAttributes(spec, stage, gravity_direction, gravity_magnitude);
|
||||||
|
|
||||||
spec->option.gravity[0] = gravity_direction[0];
|
|
||||||
spec->option.gravity[1] = gravity_direction[1];
|
|
||||||
spec->option.gravity[2] = gravity_direction[2];
|
|
||||||
|
|
||||||
// Early exit if theres no MjcPhysicsSceneAPI applied.
|
// Early exit if theres no MjcPhysicsSceneAPI applied.
|
||||||
if (!physics_scene.GetPrim().HasAPI<pxr::MjcPhysicsSceneAPI>()) {
|
if (!physics_scene.GetPrim().HasAPI<pxr::MjcPhysicsSceneAPI>()) {
|
||||||
@@ -1724,6 +1761,10 @@ mjSpec* mj_parseUSDStage(const pxr::UsdStageRefPtr stage) {
|
|||||||
if (!root->physics_scene.IsEmpty()) {
|
if (!root->physics_scene.IsEmpty()) {
|
||||||
mujoco::usd::ParseUsdPhysicsScene(
|
mujoco::usd::ParseUsdPhysicsScene(
|
||||||
spec, pxr::UsdPhysicsScene::Get(stage, root->physics_scene));
|
spec, pxr::UsdPhysicsScene::Get(stage, root->physics_scene));
|
||||||
|
} else {
|
||||||
|
// If there is no physics scene we still need to infer the gravity vector
|
||||||
|
// from the stage up axis and units per meter metadata.
|
||||||
|
mujoco::usd::SetGravityAttributes(spec, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root->keyframes.empty()) {
|
if (!root->keyframes.empty()) {
|
||||||
@@ -1754,4 +1795,3 @@ MJAPI mjSpec* mj_parseUSD(const char* identifier, const mjVFS* vfs, char* error,
|
|||||||
auto stage = pxr::UsdStage::Open(identifier);
|
auto stage = pxr::UsdStage::Open(identifier);
|
||||||
return mj_parseUSDStage(stage);
|
return mj_parseUSDStage(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user