|
35 | 35 | #include "experimental/usd/kinematic_tree.h"
|
36 | 36 | #include <pxr/base/gf/declare.h>
|
37 | 37 | #include <pxr/base/gf/matrix4d.h>
|
| 38 | +#include <pxr/base/gf/rotation.h> |
38 | 39 | #include <pxr/base/gf/vec3d.h>
|
39 | 40 | #include <pxr/base/tf/token.h>
|
40 | 41 | #include <pxr/base/vt/types.h>
|
@@ -193,6 +194,25 @@ bool MaybeParseGeomPrimitive(const pxr::UsdPrim& prim, T* element,
|
193 | 194 | element->size[0] = scale[0] * radius;
|
194 | 195 | element->size[1] = scale[1] * height / 2.0f;
|
195 | 196 | element->size[2] = 0;
|
| 197 | + |
| 198 | + TfToken axis; |
| 199 | + capsule.GetAxisAttr().Get(&axis); |
| 200 | + |
| 201 | + // Mujoco (and USD) capsules are aligned with Z by default. |
| 202 | + // When USD axis is X or Y, we apply a rotation to align with the Z axis. |
| 203 | + pxr::GfQuatd axis_rot(1.0); |
| 204 | + if (axis == pxr::UsdGeomTokens->x) { |
| 205 | + axis_rot = pxr::GfRotation(pxr::GfVec3d::XAxis(), pxr::GfVec3d::ZAxis()) |
| 206 | + .GetQuat(); |
| 207 | + } else if (axis == pxr::UsdGeomTokens->y) { |
| 208 | + axis_rot = pxr::GfRotation(pxr::GfVec3d::YAxis(), pxr::GfVec3d::ZAxis()) |
| 209 | + .GetQuat(); |
| 210 | + } |
| 211 | + |
| 212 | + pxr::GfQuatd current_rot(element->quat[0], element->quat[1], |
| 213 | + element->quat[2], element->quat[3]); |
| 214 | + pxr::GfQuatd new_rot = current_rot * axis_rot; |
| 215 | + SetDoubleArrFromGfQuatd(element->quat, new_rot); |
196 | 216 | } else if (prim.IsA<pxr::UsdGeomCube>()) {
|
197 | 217 | element->type = mjGEOM_BOX;
|
198 | 218 | auto cube = pxr::UsdGeomCube(prim);
|
@@ -1452,4 +1472,3 @@ mjSpec* mj_parseUSDStage(const pxr::UsdStageRefPtr stage) {
|
1452 | 1472 |
|
1453 | 1473 | return spec;
|
1454 | 1474 | }
|
1455 |
| - |
|
0 commit comments