diff --git a/src/user/user_composite.cc b/src/user/user_composite.cc index 806593df..9cc75f58 100644 --- a/src/user/user_composite.cc +++ b/src/user/user_composite.cc @@ -1243,7 +1243,7 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) { mjCSkin* skin = model->AddSkin(); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); skin->name = txt; - skin->material = skinmaterial; + skin->set_material(skinmaterial); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = inflate; skin->group = skingroup; @@ -1845,7 +1845,7 @@ void mjCComposite::MakeSkin2Subgrid(mjCModel* model, mjtNum inflate) { mjCSkin* skin = model->AddSkin(); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); skin->name = txt; - skin->material = skinmaterial; + skin->set_material(skinmaterial); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = inflate; skin->group = skingroup; @@ -1998,7 +1998,7 @@ void mjCComposite::MakeSkin3(mjCModel* model) { mjCSkin* skin = model->AddSkin(); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); skin->name = txt; - skin->material = skinmaterial; + skin->set_material(skinmaterial); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = skininflate; skin->group = skingroup; diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 5da757ba..a6373022 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -1878,7 +1878,7 @@ mjCSkin::mjCSkin(mjCModel* _model) { // clear data file.clear(); - material.clear(); + material_.clear(); rgba[0] = rgba[1] = rgba[2] = 0.5f; rgba[3] = 1.0f; inflate = 0; @@ -1903,7 +1903,7 @@ mjCSkin::mjCSkin(mjCModel* _model) { // destructor mjCSkin::~mjCSkin() { file.clear(); - material.clear(); + material_.clear(); vert.clear(); texcoord.clear(); face.clear(); @@ -2005,11 +2005,11 @@ void mjCSkin::Compile(const mjVFS* vfs) { } // resolve material name - mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material); + mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material_); if (pmat) { matid = pmat->id; - } else if (!material.empty()) { - throw mjCError(this, "unkown material '%s' in skin", material.c_str()); + } else if (!material_.empty()) { + throw mjCError(this, "unkown material '%s' in skin", material_.c_str()); } // set total vertex weights to 0 @@ -2239,7 +2239,7 @@ mjCFlex::mjCFlex(mjCModel* _model) { group = 0; edgestiffness = 0; edgedamping = 0; - material.clear(); + material_.clear(); rgba[0] = rgba[1] = rgba[2] = 0.5f; rgba[3] = 1.0f; @@ -2314,11 +2314,11 @@ void mjCFlex::Compile(const mjVFS* vfs) { } // resolve material name - mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material); + mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material_); if (pmat) { matid = pmat->id; - } else if (!material.empty()) { - throw mjCError(this, "unkown material '%s' in flex", material.c_str()); + } else if (!material_.empty()) { + throw mjCError(this, "unkown material '%s' in flex", material_.c_str()); } // resolve body ids diff --git a/src/user/user_model.cc b/src/user/user_model.cc index d504eabc..7b484944 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -653,8 +653,8 @@ void mjCModel::MakeLists(mjCBody* body) { template void mjCModel::DeleteMaterial(std::vector& list, std::string_view name) { for (T* plist : list) { - if (name.empty() || plist->material == name) { - plist->material.clear(); + if (name.empty() || plist->material_ == name) { + plist->material_.clear(); } } } @@ -775,12 +775,12 @@ void mjCModel::IndexAssets(bool discard) { mjCGeom* pgeom = geoms[i]; // find material by name - if (!pgeom->material.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pgeom->material); + if (!pgeom->material_.empty()) { + mjCBase* m = FindObject(mjOBJ_MATERIAL, pgeom->material_); if (m) { pgeom->matid = m->id; } else { - throw mjCError(pgeom, "material '%s' not found in geom %d", pgeom->material.c_str(), i); + throw mjCError(pgeom, "material '%s' not found in geom %d", pgeom->material_.c_str(), i); } } @@ -822,12 +822,12 @@ void mjCModel::IndexAssets(bool discard) { mjCSkin* pskin = skins[i]; // find material by name - if (!pskin->material.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pskin->material); + if (!pskin->material_.empty()) { + mjCBase* m = FindObject(mjOBJ_MATERIAL, pskin->material_); if (m) { pskin->matid = m->id; } else { - throw mjCError(pskin, "material '%s' not found in skin %d", pskin->material.c_str(), i); + throw mjCError(pskin, "material '%s' not found in skin %d", pskin->material_.c_str(), i); } } } @@ -837,12 +837,12 @@ void mjCModel::IndexAssets(bool discard) { mjCSite* psite = sites[i]; // find material by name - if (!psite->material.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, psite->material); + if (!psite->material_.empty()) { + mjCBase* m = FindObject(mjOBJ_MATERIAL, psite->get_material()); if (m) { psite->matid = m->id; } else { - throw mjCError(psite, "material '%s' not found in site %d", psite->material.c_str(), i); + throw mjCError(psite, "material '%s' not found in site %d", psite->material_.c_str(), i); } } } @@ -852,12 +852,12 @@ void mjCModel::IndexAssets(bool discard) { mjCTendon* pten = tendons[i]; // find material by name - if (!pten->material.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pten->material); + if (!pten->material_.empty()) { + mjCBase* m = FindObject(mjOBJ_MATERIAL, pten->material_); if (m) { pten->matid = m->id; } else { - throw mjCError(pten, "material '%s' not found in tendon %d", pten->material.c_str(), i); + throw mjCError(pten, "material '%s' not found in tendon %d", pten->material_.c_str(), i); } } } @@ -1718,7 +1718,7 @@ void mjCModel::CopyTree(mjModel* m) { copyvec(m->site_size+3*sid, ps->size, 3); copyvec(m->site_pos+3*sid, ps->pos, 3); copyvec(m->site_quat+4*sid, ps->quat, 4); - copyvec(m->site_user+nuser_site*sid, ps->userdata.data(), nuser_site); + copyvec(m->site_user+nuser_site*sid, ps->userdata_.data(), nuser_site); copyvec(m->site_rgba+4*sid, ps->rgba, 4); // determine sameframe @@ -2901,7 +2901,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { if (nuser_site == -1) { nuser_site = 0; for (int i=0; ispec.userdata.size()); + nuser_site = mjMAX(nuser_site, sites[i]->spec_userdata_.size()); } } if (nuser_cam == -1) { @@ -3407,7 +3407,7 @@ bool mjCModel::CopyBack(const mjModel* m) { copyvec(sites[i]->rgba, m->site_rgba+4*i, 4); if (nuser_site) { - copyvec(sites[i]->userdata.data(), m->site_user + nuser_site*i, nuser_site); + copyvec(sites[i]->userdata_.data(), m->site_user + nuser_site*i, nuser_site); } } diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 6db1c8f1..bd539ec7 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -497,7 +497,7 @@ void mjCDef::Compile(const mjCModel* model) { // enforce length of all default userdata arrays joint.userdata.resize(model->nuser_jnt); geom.userdata.resize(model->nuser_geom); - site.userdata.resize(model->nuser_site); + site.userdata_.resize(model->nuser_site); camera.userdata.resize(model->nuser_cam); tendon.userdata.resize(model->nuser_tendon); actuator.userdata.resize(model->nuser_actuator); @@ -1356,7 +1356,7 @@ mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) { density = 1000; // water density (1000 kg / m^3) meshname.clear(); fitscale = 1; - material.clear(); + material_.clear(); rgba[0] = rgba[1] = rgba[2] = 0.5f; rgba[3] = 1.0f; userdata.clear(); @@ -1931,14 +1931,13 @@ mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) { spec.group = 0; mjuu_setvec(spec.quat, 1, 0, 0, 0); mjuu_setvec(spec.pos, 0, 0, 0); - spec.material.clear(); + spec.material = nullptr; spec.rgba[0] = spec.rgba[1] = spec.rgba[2] = 0.5f; spec.rgba[3] = 1.0f; spec.fromto[0] = mjNAN; - spec.userdata.clear(); + spec.userdata = nullptr; // clear internal variables - spec.material.clear(); body = 0; matid = -1; @@ -1960,6 +1959,10 @@ mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) { void mjCSite::CopyFromSpec() { *static_cast(this) = spec; + userdata_ = spec_userdata_; + material_ = spec_material_; + userdata = userdata_.data(); + material = material_.data(); } @@ -1969,11 +1972,11 @@ void mjCSite::Compile(void) { CopyFromSpec(); // resize userdata - if (userdata.size() > model->nuser_site) { + if (userdata_.size() > model->nuser_site) { throw mjCError(this, "user has more values than nuser_site in site '%s' (id = %d)", name.c_str(), id); } - userdata.resize(model->nuser_site); + userdata_.resize(model->nuser_site); // check type if (type<0 || type>=mjNGEOMTYPES) { @@ -3500,7 +3503,7 @@ void mjCEquality::Compile(void) { mjCTendon::mjCTendon(mjCModel* _model, mjCDef* _def) { // tendon defaults group = 0; - material.clear(); + material_.clear(); width = 0.003; limited = 2; range[0] = 0; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 5d0daff3..5fac7b3a 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -390,6 +390,9 @@ class mjCGeom : public mjCBase { bool IsVisual(void) const { return visual_; } void SetNotVisual(void) { visual_ = false; } + void set_material(std::string _material) { material_ = _material; } + std::string& get_material() { return material_; } + // Compute all coefs modeling the interaction with the surrounding fluid. void SetFluidCoefs(void); // Compute the kappa coefs of the added inertia due to the surrounding fluid. @@ -418,7 +421,6 @@ class mjCGeom : public mjCBase { std::string hfieldname; // hfield attached to geom std::string meshname; // mesh attached to geom double fitscale; // scale mesh uniformly - std::string material; // name of material used for rendering std::vector userdata; // user data float rgba[4]; // rgba when material is omitted mjtMeshType typeinertia; // selects between surface and volume inertia @@ -440,6 +442,7 @@ class mjCGeom : public mjCBase { double GetRBound(void); // compute bounding sphere radius void ComputeAABB(void); // compute axis-aligned bounding box + std::string material_; // name of material used for rendering bool visual_; // true: geom does not collide and is unreferenced int matid; // id of geom's material mjCMesh* mesh; // geom's mesh @@ -461,8 +464,8 @@ typedef struct _mjmSite { double size[3]; // geom size for rendering double pos[3]; // position double quat[4]; // orientation - std::string material; // name of material for rendering - std::vector userdata; // user data + char* material; // name of material for rendering + double* userdata; // user data float rgba[4]; // rgba when material is omitted double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid mjCAlternative alt; // alternative orientation specification @@ -478,12 +481,30 @@ class mjCSite : public mjCBase, private mjmSite { public: mjmSite spec; // variables set by user + void set_material(std::string _material) { + spec_material_ = _material; + spec.material = spec_material_.data(); + } + void set_userdata(std::vector _userdata) { + spec_userdata_ = _userdata; + spec.userdata = spec_userdata_.data(); + } + std::vector& get_userdata() { return userdata_; } + std::string& get_material() { return material_; } + // variables computed by 'compile' and 'mjCBody::addSite' private: mjCSite(mjCModel* = 0, mjCDef* = 0); // constructor void Compile(void); // compiler void CopyFromSpec(); // copy spec into attributes + // variable-size data + std::string material_; + std::vector userdata_; + + std::string spec_material_; + std::vector spec_userdata_; + mjCBody* body; // site's body int matid; // material id for rendering }; @@ -573,6 +594,9 @@ class mjCFlex: public mjCBase { friend class mjXWriter; public: + void set_material(std::string _material) { material_ = _material; } + std::string& get_material() { return material_; } + // contact properties int contype; // contact type int conaffinity; // contact affinity @@ -595,7 +619,6 @@ class mjCFlex: public mjCBase { int group; // group for visualizatioh double edgestiffness; // edge stiffness double edgedamping; // edge damping - std::string material; // name of material used for rendering float rgba[4]; // rgba when material is omitted std::vector vertbody; // vertex body names @@ -626,6 +649,7 @@ class mjCFlex: public mjCBase { std::vector evpair; // element-vertex pairs std::vector vertxpos; // global vertex positions mjCBoundingVolumeHierarchy tree; // bounding volume hierarchy + std::string material_; // name of material used for rendering }; @@ -799,9 +823,10 @@ class mjCSkin: public mjCBase { public: std::string get_file() const { return file; } + void set_material(std::string _material) { material_ = _material; } + std::string& get_material() { return material_; } std::string file; // skin file - std::string material; // name of material used for rendering float rgba[4]; // rgba when material is omitted float inflate; // inflate in normal direction int group; // group for visualization @@ -824,6 +849,7 @@ class mjCSkin: public mjCBase { void Compile(const mjVFS* vfs); // compiler void LoadSKN(mjResource* resource); // load skin in SKN BIN format + std::string material_; // name of material used for rendering int matid; // material id std::vector bodyid; // body ids }; @@ -1059,6 +1085,9 @@ class mjCTendon : public mjCBase { friend class mjXWriter; public: + void set_material(std::string _material) { material_ = _material; } + std::string& get_material() { return material_; } + // API for adding wrapping objects void WrapSite(std::string name, int row=-1, int col=-1); // site void WrapGeom(std::string name, std::string side, int row=-1, int col=-1); // geom @@ -1071,7 +1100,6 @@ class mjCTendon : public mjCBase { // variables set by user int group; // group for visualization - std::string material; // name of material for rendering int limited; // does tendon have limits: 0 false, 1 true, 2 auto double width; // width for rendering mjtNum solref_limit[mjNREF]; // solver reference: tendon limits @@ -1092,6 +1120,7 @@ class mjCTendon : public mjCBase { ~mjCTendon(); // destructor void Compile(void); // compiler + std::string material_; // name of material for rendering int matid; // material id for rendering std::vector path; // wrapping objects }; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 6df5e7a5..9e9ba1d5 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -1279,7 +1279,7 @@ void mjXReader::OneFlex(XMLElement* elem, mjCFlex* pflex) { // read attributes ReadAttrTxt(elem, "name", pflex->name); ReadAttr(elem, "radius", 1, &pflex->radius, text); - ReadAttrTxt(elem, "material", pflex->material); + ReadAttrTxt(elem, "material", pflex->get_material()); ReadAttr(elem, "rgba", 4, pflex->rgba, text); if (MapValue(elem, "flatskin", &n, bool_map, 2)) { pflex->flatskin = (n==1); @@ -1381,7 +1381,7 @@ void mjXReader::OneSkin(XMLElement* elem, mjCSkin* pskin) { // read attributes ReadAttrTxt(elem, "name", pskin->name); ReadAttrTxt(elem, "file", pskin->file); - ReadAttrTxt(elem, "material", pskin->material); + ReadAttrTxt(elem, "material", pskin->get_material()); ReadAttrInt(elem, "group", &pskin->group); if (pskin->group<0 || pskin->group>=mjNGROUP) { throw mjXError(elem, "skin group must be between 0 and 5"); @@ -1528,7 +1528,7 @@ void mjXReader::OneGeom(XMLElement* elem, mjCGeom* pgeom) { ReadAttrTxt(elem, "hfield", pgeom->hfieldname); ReadAttrTxt(elem, "mesh", pgeom->meshname); ReadAttr(elem, "fitscale", 1, &pgeom->fitscale, text); - ReadAttrTxt(elem, "material", pgeom->material); + ReadAttrTxt(elem, "material", pgeom->get_material()); ReadAttr(elem, "rgba", 4, pgeom->rgba, text); if (MapValue(elem, "fluidshape", &n, fluid_map, 2)) { pgeom->fluid_switch = (n == 1); @@ -1567,6 +1567,8 @@ void mjXReader::OneSite(XMLElement* elem, mjCSite* site) { int n; string text; mjmSite* psite = &site->spec; + std::vector userdata; + std::string material; // read attributes ReadAttrTxt(elem, "name", site->name); @@ -1578,13 +1580,15 @@ void mjXReader::OneSite(XMLElement* elem, mjCSite* site) { ReadAttrInt(elem, "group", &psite->group); ReadAttr(elem, "pos", 3, psite->pos, text); ReadQuat(elem, "quat", psite->quat, text); - ReadAttrTxt(elem, "material", psite->material); + ReadAttrTxt(elem, "material", material); ReadAttr(elem, "rgba", 4, psite->rgba, text); ReadAttr(elem, "fromto", 6, psite->fromto, text); ReadAlternative(elem, psite->alt); + ReadVector(elem, "user", userdata, text); - // read userdata - ReadVector(elem, "user", psite->userdata, text); + // set variable-size attributes + site->set_userdata(userdata); + site->set_material(material); GetXMLPos(elem, site); } @@ -1773,7 +1777,7 @@ void mjXReader::OneTendon(XMLElement* elem, mjCTendon* pten) { ReadAttrTxt(elem, "name", pten->name); ReadAttrTxt(elem, "class", pten->classname); ReadAttrInt(elem, "group", &pten->group); - ReadAttrTxt(elem, "material", pten->material); + ReadAttrTxt(elem, "material", pten->get_material()); MapValue(elem, "limited", &pten->limited, TFAuto_map, 3); ReadAttr(elem, "width", 1, &pten->width, text); ReadAttr(elem, "solreflimit", mjNREF, pten->solref_limit, text, false, false); @@ -2158,7 +2162,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjCBody* pbody, mjCDef* def) { ReadAttr(egeom, "solimp", mjNIMP, comp.def[0].geom.solimp, text, false, false); ReadAttr(egeom, "margin", 1, &comp.def[0].geom.margin, text); ReadAttr(egeom, "gap", 1, &comp.def[0].geom.gap, text); - ReadAttrTxt(egeom, "material", comp.def[0].geom.material); + ReadAttrTxt(egeom, "material", comp.def[0].geom.get_material()); ReadAttr(egeom, "rgba", 4, comp.def[0].geom.rgba, text); ReadAttr(egeom, "mass", 1, &comp.def[0].geom._mass, text); ReadAttr(egeom, "density", 1, &comp.def[0].geom.density, text); @@ -2167,11 +2171,13 @@ void mjXReader::OneComposite(XMLElement* elem, mjCBody* pbody, mjCDef* def) { // site XMLElement* esite = elem->FirstChildElement("site"); if (esite) { + std::string material; mjmSite& dsite = comp.def[0].site.spec; ReadAttr(esite, "size", 3, dsite.size, text, false, false); ReadAttrInt(esite, "group", &dsite.group); - ReadAttrTxt(esite, "material", dsite.material); + ReadAttrTxt(esite, "material", material); ReadAttr(esite, "rgba", 4, dsite.rgba, text); + comp.def[0].site.set_material(material); } // joint @@ -2249,7 +2255,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjCBody* pbody, mjCDef* def) { ReadAttr(eten, "stiffness", 1, &comp.def[kind].tendon.stiffness, text); ReadAttr(eten, "damping", 1, &comp.def[kind].tendon.damping, text); ReadAttr(eten, "frictionloss", 1, &comp.def[kind].tendon.frictionloss, text); - ReadAttrTxt(eten, "material", comp.def[kind].tendon.material); + ReadAttrTxt(eten, "material", comp.def[kind].tendon.get_material()); ReadAttr(eten, "rgba", 4, comp.def[kind].tendon.rgba, text); ReadAttr(eten, "width", 1, &comp.def[kind].tendon.width, text); @@ -2303,7 +2309,7 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjCBody* pbody) { ReadAttr(elem, "mass", 1, &fcomp.mass, text); ReadAttr(elem, "inertiabox", 1, &fcomp.inertiabox, text); ReadAttrTxt(elem, "file", fcomp.file); - ReadAttrTxt(elem, "material", fcomp.def.flex.material); + ReadAttrTxt(elem, "material", fcomp.def.flex.get_material()); ReadAttr(elem, "rgba", 4, fcomp.def.flex.rgba, text); if (MapValue(elem, "flatskin", &n, bool_map, 2)) { fcomp.def.flex.flatskin = (n==1); diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index da41f82c..98f9f793 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -90,8 +90,8 @@ void mjXWriter::OneFlex(XMLElement* elem, mjCFlex* pflex) { // common attributes WriteAttrTxt(elem, "name", pflex->name); WriteAttr(elem, "radius", 1, &pflex->radius, &defflex.radius); - if (pflex->material != defflex.material) { - WriteAttrTxt(elem, "material", pflex->material); + if (pflex->get_material() != defflex.get_material()) { + WriteAttrTxt(elem, "material", pflex->get_material()); } WriteAttr(elem, "rgba", 4, pflex->rgba, defflex.rgba); WriteAttrKey(elem, "flatskin", bool_map, 2, pflex->flatskin, defflex.flatskin); @@ -204,7 +204,7 @@ void mjXWriter::OneSkin(XMLElement* elem, mjCSkin* pskin) { // write attributes WriteAttrTxt(elem, "name", pskin->name); WriteAttrTxt(elem, "file", pskin->file); - WriteAttrTxt(elem, "material", pskin->material); + WriteAttrTxt(elem, "material", pskin->get_material()); WriteAttrInt(elem, "group", pskin->group, 0); WriteAttr(elem, "rgba", 4, pskin->rgba, mydef.geom.rgba); WriteAttr(elem, "inflate", 1, &pskin->inflate, &zero); @@ -396,8 +396,8 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) { } else { WriteAttr(elem, "density", 1, &pgeom->density, &def->geom.density); } - if (pgeom->material != def->geom.material) { - WriteAttrTxt(elem, "material", pgeom->material); + if (pgeom->get_material() != def->geom.get_material()) { + WriteAttrTxt(elem, "material", pgeom->get_material()); } WriteAttr(elem, "rgba", 4, pgeom->rgba, def->geom.rgba); @@ -444,16 +444,16 @@ void mjXWriter::OneSite(XMLElement* elem, mjCSite* psite, mjCDef* def) { // defaults and regular WriteAttrInt(elem, "group", psite->group, def->site.group); WriteAttrKey(elem, "type", geom_map, mjNGEOMTYPES, psite->type, def->site.type); - if (psite->material != def->site.material) { - WriteAttrTxt(elem, "material", psite->material); + if (psite->get_material() != def->site.get_material()) { + WriteAttrTxt(elem, "material", psite->get_material()); } WriteAttr(elem, "rgba", 4, psite->rgba, def->site.rgba); // userdata if (writingdefaults) { - WriteVector(elem, "user", psite->userdata); + WriteVector(elem, "user", psite->get_userdata()); } else { - WriteVector(elem, "user", psite->userdata, def->site.userdata); + WriteVector(elem, "user", psite->get_userdata(), def->site.get_userdata()); } } @@ -636,8 +636,8 @@ void mjXWriter::OneTendon(XMLElement* elem, mjCTendon* pten, mjCDef* def) { } // spatial only if (!fixed) { - if (pten->material!=def->tendon.material) { - WriteAttrTxt(elem, "material", pten->material); + if (pten->get_material()!=def->tendon.get_material()) { + WriteAttrTxt(elem, "material", pten->get_material()); } WriteAttr(elem, "width", 1, &pten->width, &def->tendon.width); WriteAttr(elem, "rgba", 4, pten->rgba, def->tendon.rgba);