diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc
index 720c6132..2c35b11b 100644
--- a/src/xml/xml_native_writer.cc
+++ b/src/xml/xml_native_writer.cc
@@ -252,6 +252,7 @@ void mjXWriter::OneJoint(XMLElement* elem, mjCJoint* pjoint, mjCDef* def) {
// write geom
void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) {
double unitq[4] = {1, 0, 0, 0};
+ double mass = 0;
// regular
if (!writingdefaults) {
@@ -260,6 +261,9 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) {
if (mjGEOMINFO[pgeom->type]) {
WriteAttr(elem, "size", mjGEOMINFO[pgeom->type], pgeom->size, def->geom.size);
}
+ if (mjuu_defined(pgeom->_mass)) {
+ mass = pgeom->GetVolume() * def->geom.density;
+ }
// mesh geom
if (pgeom->type==mjGEOM_MESH) {
@@ -308,7 +312,6 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) {
WriteAttr(elem, "fluidcoef", 5, pgeom->fluid_coefs, def->geom.fluid_coefs);
WriteAttrKey(elem, "shellinertia", meshtype_map, 2, pgeom->typeinertia, def->geom.typeinertia);
if (mjuu_defined(pgeom->_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 bb4e650c..84c7722d 100644
--- a/test/xml/xml_native_writer_test.cc
+++ b/test/xml/xml_native_writer_test.cc
@@ -684,6 +684,31 @@ TEST_F(XMLWriterTest, OverwritesDensity) {
mj_deleteModel(model);
}
+TEST_F(XMLWriterTest, SaveDefaultMass) {
+ static constexpr char xml[] = R"(
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )";
+ mjModel* model = LoadModelFromString(xml);
+ EXPECT_THAT(model, NotNull());
+ std::string content = SaveAndReadXml(model);
+ EXPECT_THAT(content, HasSubstr("mass=\"1\""));
+ mj_deleteModel(model);
+}
+
TEST_F(XMLWriterTest, UsesTwoSpaces) {
static constexpr char xml[] = R"(