diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc
index 436e4fbb..1b55e4dd 100644
--- a/src/xml/xml_native_writer.cc
+++ b/src/xml/xml_native_writer.cc
@@ -290,7 +290,8 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) {
WriteAttr(elem, "gap", 1, &pgeom->gap, &def->geom.gap);
WriteAttr(elem, "gap", 1, &pgeom->gap, &def->geom.gap);
if (mjuu_defined(pgeom->_mass)) {
- WriteAttr(elem, "mass", 1, &pgeom->mass, &def->geom.mass);
+ double mass = pgeom->GetVolume() * def->geom.density;
+ WriteAttr(elem, "mass", 1, &pgeom->mass, &mass);
} else {
WriteAttr(elem, "density", 1, &pgeom->density, &def->geom.density);
}
diff --git a/test/xml/xml_native_writer_test.cc b/test/xml/xml_native_writer_test.cc
index 4f2e95ca..b5c4c5ed 100644
--- a/test/xml/xml_native_writer_test.cc
+++ b/test/xml/xml_native_writer_test.cc
@@ -214,6 +214,23 @@ TEST_F(XMLWriterTest, WritesMass) {
mj_deleteModel(model);
}
+TEST_F(XMLWriterTest, ZeroMass) {
+ static constexpr char xml[] = R"(
+
+
+
+
+
+
+
+ )";
+ mjModel* model = LoadModelFromString(xml);
+ std::string saved_xml = SaveAndReadXml(model);
+ EXPECT_THAT(saved_xml, Not(HasSubstr("density")));
+ EXPECT_THAT(saved_xml, HasSubstr("mass=\"0\""));
+ mj_deleteModel(model);
+}
+
TEST_F(XMLWriterTest, OverwritesDensity) {
static constexpr char xml[] = R"(