Skip to content

Commit 276fcbf

Browse files
ahcordeadlarkin
andauthored
USD to SDF: Added Collisions (#898)
Signed-off-by: Alejandro Hernández <ahcorde@gmail.com> Co-authored-by: Ashton Larkin <42042756+adlarkin@users.noreply.github.com>
1 parent c1afd7f commit 276fcbf

File tree

2 files changed

+159
-29
lines changed

2 files changed

+159
-29
lines changed

usd/src/usd_parser/USDLinks.cc

+115-29
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <ignition/math/Inertial.hh>
5050

5151
#include "sdf/Box.hh"
52+
#include "sdf/Collision.hh"
5253
#include "sdf/Cylinder.hh"
5354
#include "sdf/Geometry.hh"
5455
#include "sdf/Link.hh"
@@ -309,6 +310,7 @@ int ParseMeshSubGeom(const pxr::UsdPrim &_prim,
309310
/// \param[in] _geom sdf geom
310311
/// \param[in] _scale scale mesh
311312
/// \param[in] _usdData metadata of the USD file
313+
/// \param[out] _pose The pose of the parsed mesh
312314
/// \return UsdErrors, which is a list of UsdError objects. An empty list means
313315
/// that no errors occurred when parsing the USD mesh
314316
UsdErrors ParseMesh(
@@ -317,7 +319,8 @@ UsdErrors ParseMesh(
317319
sdf::Visual &_vis,
318320
sdf::Geometry &_geom,
319321
ignition::math::Vector3d &_scale,
320-
const USDData &_usdData)
322+
const USDData &_usdData,
323+
ignition::math::Pose3d &_pose)
321324
{
322325
UsdErrors errors;
323326

@@ -393,6 +396,9 @@ UsdErrors ParseMesh(
393396
{
394397
GetTransform(_prim, _usdData, pose, scale, _link->Name());
395398
}
399+
400+
_pose = pose;
401+
396402
meshGeom.SetScale(scale * _scale);
397403

398404
std::string primName = pxr::TfStringify(_prim.GetPath());
@@ -633,39 +639,119 @@ UsdErrors ParseUSDLinks(
633639
double metersPerUnit = data.second->MetersPerUnit();
634640

635641
if (_prim.IsA<pxr::UsdGeomSphere>())
642+
{
643+
ParseSphere(_prim, geom, _scale, metersPerUnit);
644+
vis.SetName("visual_sphere");
645+
vis.SetGeom(geom);
646+
_link->AddVisual(vis);
647+
}
648+
else if (_prim.IsA<pxr::UsdGeomCylinder>())
649+
{
650+
ParseCylinder(_prim, geom, _scale, metersPerUnit);
651+
vis.SetName("visual_cylinder");
652+
vis.SetGeom(geom);
653+
_link->AddVisual(vis);
654+
}
655+
else if (_prim.IsA<pxr::UsdGeomCube>())
656+
{
657+
ParseCube(_prim, geom, _scale, metersPerUnit);
658+
vis.SetName("visual_box");
659+
vis.SetGeom(geom);
660+
_link->AddVisual(vis);
661+
}
662+
else if (_prim.IsA<pxr::UsdGeomMesh>())
663+
{
664+
ignition::math::Pose3d poseTmp;
665+
errors = ParseMesh(
666+
_prim, &_link.value(), vis, geom, _scale, _usdData, poseTmp);
667+
if (!errors.empty())
636668
{
637-
ParseSphere(_prim, geom, _scale, metersPerUnit);
638-
vis.SetName("visual_sphere");
639-
vis.SetGeom(geom);
640-
_link->AddVisual(vis);
641-
}
642-
else if (_prim.IsA<pxr::UsdGeomCylinder>())
643-
{
644-
ParseCylinder(_prim, geom, _scale, metersPerUnit);
645-
vis.SetName("visual_cylinder");
646-
vis.SetGeom(geom);
647-
_link->AddVisual(vis);
648-
}
649-
else if (_prim.IsA<pxr::UsdGeomCube>())
650-
{
651-
ParseCube(_prim, geom, _scale, metersPerUnit);
652-
vis.SetName("visual_box");
653-
vis.SetGeom(geom);
654-
_link->AddVisual(vis);
669+
errors.emplace_back(UsdError(
670+
sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR,
671+
"Error parsing mesh"));
672+
return errors;
655673
}
656-
else if (_prim.IsA<pxr::UsdGeomMesh>())
674+
}
675+
}
676+
677+
pxr::TfTokenVector schemasCollision = _prim.GetAppliedSchemas();
678+
bool physxCollisionAPIenable = false;
679+
for (const auto & token : schemasCollision)
680+
{
681+
if (std::string(token.GetText()) == "PhysxCollisionAPI")
682+
{
683+
physxCollisionAPIenable = true;
684+
break;
685+
}
686+
}
687+
688+
if (collisionEnabled || physxCollisionAPIenable)
689+
{
690+
sdf::Collision col;
691+
692+
// add _collision extension
693+
std::string collisionName = _prim.GetPath().GetName() + "_collision";
694+
col.SetName(collisionName);
695+
sdf::Geometry colGeom;
696+
697+
ignition::math::Pose3d poseCol;
698+
ignition::math::Vector3d scaleCol(1, 1, 1);
699+
GetTransform(_prim, _usdData, poseCol, scaleCol, _link->Name());
700+
701+
double metersPerUnit = data.second->MetersPerUnit();
702+
703+
if (_prim.IsA<pxr::UsdGeomSphere>())
704+
{
705+
ParseSphere(_prim, colGeom, scaleCol, metersPerUnit);
706+
col.SetGeom(colGeom);
707+
col.SetRawPose(poseCol);
708+
}
709+
else if (_prim.IsA<pxr::UsdGeomCylinder>())
710+
{
711+
ParseCylinder(_prim, colGeom, scaleCol, metersPerUnit);
712+
col.SetGeom(colGeom);
713+
col.SetRawPose(poseCol);
714+
}
715+
else if (_prim.IsA<pxr::UsdGeomCube>())
716+
{
717+
ParseCube(_prim, colGeom, scaleCol, metersPerUnit);
718+
col.SetGeom(colGeom);
719+
col.SetRawPose(poseCol);
720+
}
721+
else if (_prim.IsA<pxr::UsdGeomMesh>())
722+
{
723+
sdf::Visual visTmp;
724+
ignition::math::Pose3d poseTmp;
725+
errors = ParseMesh(
726+
_prim, &_link.value(), visTmp, colGeom, scaleCol, _usdData, poseTmp);
727+
if (!errors.empty())
657728
{
658-
errors = ParseMesh(
659-
_prim, &_link.value(), vis, geom, _scale, _usdData);
660-
if (!errors.empty())
661-
{
662-
errors.emplace_back(UsdError(
663-
sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR,
664-
"Error parsing mesh"));
665-
return errors;
666-
}
729+
errors.emplace_back(UsdError(
730+
sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR,
731+
"Error parsing mesh"));
732+
return errors;
667733
}
734+
col.SetRawPose(poseTmp);
735+
col.SetGeom(colGeom);
736+
}
737+
else if (primType == "Plane")
738+
{
739+
sdf::Plane plane;
740+
colGeom.SetType(sdf::GeometryType::PLANE);
741+
plane.SetSize(ignition::math::Vector2d(100, 100));
742+
colGeom.SetPlaneShape(plane);
743+
744+
ignition::math::Pose3d pose;
745+
ignition::math::Vector3d scale(1, 1, 1);
746+
GetTransform(
747+
_prim, _usdData, pose, scale, pxr::TfStringify(_prim.GetPath()));
748+
col.SetRawPose(pose);
749+
col.SetGeom(colGeom);
750+
}
751+
752+
_link->AddCollision(col);
668753
}
754+
669755
}
670756
return errors;
671757
}

usd/src/usd_parser/USDLinks_TEST.cc

+44
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include "USDLinks.hh"
3636

37+
#include "sdf/Collision.hh"
3738
#include "sdf/Geometry.hh"
3839
#include "sdf/Visual.hh"
3940

@@ -70,6 +71,10 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
7071
auto geom = visual->Geom();
7172
ASSERT_NE(nullptr, geom);
7273
EXPECT_EQ(_type, geom->Type());
74+
auto collision = _link.CollisionByIndex(0);
75+
ASSERT_NE(nullptr, collision);
76+
auto geomCol = collision->Geom();
77+
ASSERT_NE(nullptr, geomCol);
7378
}
7479
};
7580

@@ -89,6 +94,13 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
8994
sdf::usd::ParseUSDLinks(
9095
boxLinkGeometry, "/box/box_link", linkSDF, usdData, scale);
9196

97+
const auto boxLinkCollision = stage->GetPrimAtPath(
98+
pxr::SdfPath("/box/box_link/box_visual/collision"));
99+
ASSERT_TRUE(boxLinkCollision);
100+
101+
sdf::usd::ParseUSDLinks(
102+
boxLinkCollision, "/box/box_link", linkSDF, usdData, scale);
103+
92104
ASSERT_TRUE(linkSDF);
93105
checkLink(linkSDF.value(), "box_link", 1.0,
94106
ignition::math::Vector3d(0.1666, 0.1666, 0.1666),
@@ -111,6 +123,14 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
111123
cylinderLinkGeometry, "/cylinder/cylinder_link",
112124
linkCylinderSDF, usdData, scale);
113125

126+
const auto cylinderLinkCollision = stage->GetPrimAtPath(
127+
pxr::SdfPath("/cylinder/cylinder_link/cylinder_visual/collision"));
128+
EXPECT_TRUE(cylinderLinkCollision);
129+
130+
sdf::usd::ParseUSDLinks(
131+
cylinderLinkCollision, "/cylinder/cylinder_link",
132+
linkCylinderSDF, usdData, scale);
133+
114134
checkLink(linkCylinderSDF.value(), "cylinder_link", 1.7,
115135
ignition::math::Vector3d(0.1458, 0.1458, 0.125),
116136
1u, sdf::GeometryType::CYLINDER);
@@ -131,6 +151,14 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
131151
sphereLinkGeometry, "/sphere/sphere_link",
132152
linkSphereSDF, usdData, scale);
133153

154+
const auto sphereLinkCollision = stage->GetPrimAtPath(
155+
pxr::SdfPath("/sphere/sphere_link/sphere_visual/collision"));
156+
EXPECT_TRUE(sphereLinkCollision);
157+
158+
sdf::usd::ParseUSDLinks(
159+
sphereLinkCollision, "/sphere/sphere_link",
160+
linkSphereSDF, usdData, scale);
161+
134162
ASSERT_TRUE(linkSphereSDF);
135163
checkLink(linkSphereSDF.value(), "sphere_link", 2,
136164
ignition::math::Vector3d(0.1, 0.1, 0.1),
@@ -144,6 +172,14 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
144172
sdf::usd::ParseUSDLinks(
145173
capsuleLink, "/capsule/capsule_link", linkCapsuleSDF, usdData, scale);
146174

175+
const auto capsuleLinkCollision = stage->GetPrimAtPath(
176+
pxr::SdfPath("/capsule/capsule_link/capsule_visual/collision"));
177+
EXPECT_TRUE(capsuleLinkCollision);
178+
179+
sdf::usd::ParseUSDLinks(
180+
capsuleLinkCollision, "/capsule/capsule_link",
181+
linkCapsuleSDF, usdData, scale);
182+
147183
checkLink(linkCapsuleSDF.value(), "capsule_link", 1,
148184
ignition::math::Vector3d(0.074154, 0.074154, 0.018769),
149185
0u, sdf::GeometryType::EMPTY);
@@ -157,6 +193,14 @@ TEST(USDLinksTest, LinksNameMassAndDiagonalMoments)
157193
ellipsoidLink, "/ellipsoid/ellipsoid_link",
158194
linkEllipsoidSDF, usdData, scale);
159195

196+
const auto ellipsoidLinkCollision = stage->GetPrimAtPath(
197+
pxr::SdfPath("/ellipsoid/ellipsoid_link/ellipsoid_visual/collision"));
198+
EXPECT_TRUE(ellipsoidLinkCollision);
199+
200+
sdf::usd::ParseUSDLinks(
201+
ellipsoidLinkCollision, "/ellipsoid/ellipsoid_link",
202+
linkEllipsoidSDF, usdData, scale);
203+
160204
checkLink(linkEllipsoidSDF.value(), "ellipsoid_link", 1,
161205
ignition::math::Vector3d(0.068, 0.058, 0.026),
162206
0u, sdf::GeometryType::EMPTY);

0 commit comments

Comments
 (0)