in src/esp/io/URDFParser.cpp [711:816]
bool Parser::parseGeometry(Geometry& geom, const XMLElement* g) {
if (g == nullptr)
return false;
const XMLElement* shape = g->FirstChildElement();
if (!shape) {
ESP_VERY_VERBOSE() << "Geometry tag contains no child element.";
return false;
}
// const std::string type_name = shape->ValueTStr().c_str();
const std::string type_name = shape->Value();
if (type_name == "sphere") {
geom.m_type = GEOM_SPHERE;
if (!shape->Attribute("radius")) {
ESP_VERY_VERBOSE() << "Sphere shape must have a radius attribute";
return false;
} else {
geom.m_sphereRadius = std::stod(shape->Attribute("radius"));
}
} else if (type_name == "box") {
geom.m_type = GEOM_BOX;
if (!shape->Attribute("size")) {
ESP_VERY_VERBOSE() << "Box requires a size attribute";
return false;
} else {
parseVector3(geom.m_boxSize, shape->Attribute("size"));
}
} else if (type_name == "cylinder") {
geom.m_type = GEOM_CYLINDER;
geom.m_capsuleRadius = 0.1;
geom.m_capsuleHeight = 0.1;
if (!shape->Attribute("length") || !shape->Attribute("radius")) {
ESP_VERY_VERBOSE()
<< "Cylinder shape must have both length and radius attributes";
return false;
}
geom.m_capsuleRadius = std::stod(shape->Attribute("radius"));
geom.m_capsuleHeight = std::stod(shape->Attribute("length"));
} else if (type_name == "capsule") {
geom.m_type = GEOM_CAPSULE;
if (!shape->Attribute("length") || !shape->Attribute("radius")) {
ESP_VERY_VERBOSE()
<< "Capsule shape must have both length and radius attributes";
return false;
}
geom.m_capsuleRadius = std::stod(shape->Attribute("radius"));
geom.m_capsuleHeight = std::stod(shape->Attribute("length"));
} else if (type_name == "mesh") {
geom.m_type = GEOM_MESH;
geom.m_meshScale = Mn::Vector3(1.0, 1.0, 1.0);
std::string fn;
if (shape->Attribute("filename")) {
fn = shape->Attribute("filename");
}
if (shape->Attribute("scale")) {
if (!parseVector3(geom.m_meshScale, shape->Attribute("scale"))) {
ESP_VERY_VERBOSE() << "W - Scale should be a vector3, not "
"single scalar. Workaround activated.";
std::string scalar_str = shape->Attribute("scale");
double scaleFactor = std::stod(scalar_str);
if (scaleFactor != 0.0) {
geom.m_meshScale = Mn::Vector3(scaleFactor);
}
}
}
if (fn.empty()) {
ESP_VERY_VERBOSE() << "Mesh filename is empty";
return false;
}
geom.m_meshFileName = fn;
// load the mesh and modify the filename to full path to reference loaded
// asset
bool success = validateMeshFile(geom.m_meshFileName);
if (!success) {
// warning already printed
return false;
}
} else {
if (type_name == "plane") {
geom.m_type = GEOM_PLANE;
if (!shape->Attribute("normal")) {
ESP_VERY_VERBOSE() << "Plane requires a normal attribute";
return false;
} else {
parseVector3(geom.m_planeNormal, shape->Attribute("normal"));
}
} else {
ESP_VERY_VERBOSE() << "Unknown geometry type:" << type_name;
return false;
}
}
return true;
}