diff --git a/src/engine/engine_io.c b/src/engine/engine_io.c index d14647e5..0381e613 100644 --- a/src/engine/engine_io.c +++ b/src/engine/engine_io.c @@ -803,8 +803,19 @@ void mj_deleteModel(mjModel* m) { // size of buffer needed to hold model int mj_sizeModel(const mjModel* m) { - return sizeof(int)*(4+getnint()) + sizeof(mjOption) + - sizeof(mjVisual) + sizeof(mjStatistic) + m->nbuffer; + int size = ( + sizeof(int)*(4+getnint()) + + sizeof(mjOption) + + sizeof(mjVisual) + + sizeof(mjStatistic)); + +MJMODEL_POINTERS_PREAMBLE(m) +#define X(type, name, nr, nc) \ + size += sizeof(type)*(m->nr)*(nc); + MJMODEL_POINTERS +#undef X + + return size; } diff --git a/test/engine/engine_io_test.cc b/test/engine/engine_io_test.cc index 6539930c..4ccebcce 100644 --- a/test/engine/engine_io_test.cc +++ b/test/engine/engine_io_test.cc @@ -18,7 +18,11 @@ #include #include +#include #include +#include +#include +#include #include #include @@ -47,6 +51,36 @@ mjModel PartialModel(const mjModel* m) { return partial_model; } +TEST_F(EngineIoTest, VerifySizeModel) { + constexpr char xml[] = R"( + + + + + + + + + )"; + + std::array error; + mjModel* model = LoadModelFromString(xml, error.data(), error.size()); + ASSERT_THAT(model, NotNull()) << "Failed to load model: " << error.data(); + + std::filesystem::path temp_file = ( + std::filesystem::temp_directory_path() / "model.mjb"); + + mj_saveModel(model, temp_file.string().c_str(), NULL, 0); + + std::uintmax_t file_size = std::filesystem::file_size(temp_file); + int model_size = mj_sizeModel(model); + + std::filesystem::remove(temp_file); + mj_deleteModel(model); + + EXPECT_EQ(file_size, model_size); +} + TEST_F(EngineIoTest, MakeDataFromPartialModel) { constexpr char xml[] = R"(