diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 0b1e357a..766650a4 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -667,22 +667,22 @@ void mjCModel::IndexAssets(void) { } // find mesh by name - if (!pgeom->mesh.empty()) { - mjCBase* m = FindObject(mjOBJ_MESH, pgeom->mesh); + if (!pgeom->meshname.empty()) { + mjCBase* m = FindObject(mjOBJ_MESH, pgeom->meshname); if (m) { - pgeom->meshid = m->id; + pgeom->mesh = (mjCMesh*)m; } else { - throw mjCError(pgeom, "mesh '%s' not found in geom %d", pgeom->mesh.c_str(), i); + throw mjCError(pgeom, "mesh '%s' not found in geom %d", pgeom->meshname.c_str(), i); } } // find hfield by name - if (!pgeom->hfield.empty()) { - mjCBase* m = FindObject(mjOBJ_HFIELD, pgeom->hfield); + if (!pgeom->hfieldname.empty()) { + mjCBase* m = FindObject(mjOBJ_HFIELD, pgeom->hfieldname); if (m) { - pgeom->hfieldid = m->id; + pgeom->hfield = (mjCHField*)m; } else { - throw mjCError(pgeom, "hfield '%s' not found in geom %d", pgeom->hfield.c_str(), i); + throw mjCError(pgeom, "hfield '%s' not found in geom %d", pgeom->hfieldname.c_str(), i); } } } @@ -1515,10 +1515,10 @@ void mjCModel::CopyTree(mjModel* m) { m->geom_conaffinity[gid] = pg->conaffinity; m->geom_condim[gid] = pg->condim; m->geom_bodyid[gid] = pg->body->id; - if (pg->meshid>=0) { - m->geom_dataid[gid] = pg->meshid; - } else if (pg->hfieldid>=0) { - m->geom_dataid[gid] = pg->hfieldid; + if (pg->mesh) { + m->geom_dataid[gid] = pg->mesh->id; + } else if (pg->hfield) { + m->geom_dataid[gid] = pg->hfield->id; } else { m->geom_dataid[gid] = -1; } @@ -2710,9 +2710,9 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { // mark meshes that need convex hull for (int i=0; imeshid>=0 && geoms[i]->type==mjGEOM_MESH && + if (geoms[i]->mesh && geoms[i]->type==mjGEOM_MESH && (geoms[i]->contype || geoms[i]->conaffinity)) { - meshes[geoms[i]->meshid]->set_needhull(true); + geoms[i]->mesh->set_needhull(true); } } diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index b503778f..74f8825e 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -1317,7 +1317,7 @@ mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) { fluid[i] = 0; } density = 1000; // water density (1000 kg / m^3) - mesh.clear(); + meshname.clear(); fitscale = 1; material.clear(); rgba[0] = rgba[1] = rgba[2] = 0.5f; @@ -1333,8 +1333,8 @@ mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) { mjuu_setvec(inertia, 0, 0, 0); body = 0; matid = -1; - meshid = -1; - hfieldid = -1; + mesh = nullptr; + hfield = nullptr; // reset to default if given if (_def) { @@ -1360,12 +1360,11 @@ double mjCGeom::GetVolume(void) { // get from mesh if (type==mjGEOM_MESH || type==mjGEOM_SDF) { - if (meshid<0 || meshid>=(int)model->meshes.size()) { - throw mjCError(this, "invalid meshid in mesh geom '%s' (id = %d)", name.c_str(), id); + if (mesh->id<0 || !((std::size_t) mesh->id <= model->meshes.size())) { + throw mjCError(this, "invalid mesh id in mesh geom '%s' (id = %d)", name.c_str(), id); } - mjCMesh* pmesh = model->meshes[meshid]; - return pmesh->GetVolumeRef(typeinertia); + return mesh->GetVolumeRef(typeinertia); } // compute from geom shape @@ -1416,12 +1415,11 @@ void mjCGeom::SetInertia(void) { // get from mesh if (type==mjGEOM_MESH || type==mjGEOM_SDF) { - if (meshid<0 || meshid>=(int)model->meshes.size()) { - throw mjCError(this, "invalid meshid in mesh geom '%s' (id = %d)", name.c_str(), id); + if (mesh->id<0 || !((std::size_t) mesh->id <= model->meshes.size())) { + throw mjCError(this, "invalid mesh id in mesh geom '%s' (id = %d)", name.c_str(), id); } - mjCMesh* pmesh = model->meshes[meshid]; - double* boxsz = pmesh->GetInertiaBoxPtr(typeinertia); + double* boxsz = mesh->GetInertiaBoxPtr(typeinertia); inertia[0] = mass*(boxsz[1]*boxsz[1] + boxsz[2]*boxsz[2]) / 3; inertia[1] = mass*(boxsz[0]*boxsz[0] + boxsz[2]*boxsz[2]) / 3; inertia[2] = mass*(boxsz[0]*boxsz[0] + boxsz[1]*boxsz[1]) / 3; @@ -1488,7 +1486,7 @@ double mjCGeom::GetRBound(void) { switch (type) { case mjGEOM_HFIELD: - hsize = model->hfields[hfieldid]->size; + hsize = hfield->size; return sqrt(hsize[0]*hsize[0] + hsize[1]*hsize[1] + mjMAX(hsize[2]*hsize[2], hsize[3]*hsize[3])); @@ -1509,7 +1507,7 @@ double mjCGeom::GetRBound(void) { case mjGEOM_MESH: case mjGEOM_SDF: - aamm = model->meshes[meshid]->aamm(); + aamm = mesh->aamm(); haabb[0] = mju_max(fabs(aamm[0]), fabs(aamm[3])); haabb[1] = mju_max(fabs(aamm[1]), fabs(aamm[4])); haabb[2] = mju_max(fabs(aamm[2]), fabs(aamm[5])); @@ -1638,12 +1636,12 @@ void mjCGeom::ComputeAABB(void) { double aamm[6]; // axis-aligned bounding box in (min, max) format switch (type) { case mjGEOM_HFIELD: - aamm[0] = -model->hfields[hfieldid]->size[0]; - aamm[1] = -model->hfields[hfieldid]->size[1]; - aamm[2] = -model->hfields[hfieldid]->size[3]; - aamm[3] = model->hfields[hfieldid]->size[0]; - aamm[4] = model->hfields[hfieldid]->size[1]; - aamm[5] = model->hfields[hfieldid]->size[2]; + aamm[0] = -hfield->size[0]; + aamm[1] = -hfield->size[1]; + aamm[2] = -hfield->size[3]; + aamm[3] = hfield->size[0]; + aamm[4] = hfield->size[1]; + aamm[5] = hfield->size[2]; break; case mjGEOM_SPHERE: @@ -1665,7 +1663,7 @@ void mjCGeom::ComputeAABB(void) { case mjGEOM_MESH: case mjGEOM_SDF: - mjuu_copyvec(aamm, model->meshes[meshid]->aamm(), 6); + mjuu_copyvec(aamm, mesh->aamm(), 6); break; case mjGEOM_PLANE: @@ -1711,12 +1709,12 @@ void mjCGeom::Compile(void) { } // check mesh - if ((type==mjGEOM_MESH || type==mjGEOM_SDF) && meshid<0) { + if ((type==mjGEOM_MESH || type==mjGEOM_SDF) && !mesh) { throw mjCError(this, "mesh geom '%s' (id = %d) must have valid meshid", name.c_str(), id); } // check hfield - if ((type==mjGEOM_HFIELD && hfieldid<0) || (type!=mjGEOM_HFIELD && hfieldid>=0)) { + if ((type==mjGEOM_HFIELD && !hfield) || (type!=mjGEOM_HFIELD && hfield)) { throw mjCError(this, "hfield geom '%s' (id = %d) must have valid hfieldid", name.c_str(), id); } @@ -1783,25 +1781,25 @@ void mjCGeom::Compile(void) { } // mesh: accumulate frame, fit geom if needed - if (meshid!=-1) { + if (mesh) { // check for inapplicable fromto if (mjuu_defined(fromto[0])) { throw mjCError(this, "fromto cannot be used with mesh geom '%s' (id = %d)", name.c_str(), id); } - // get associated mesh - mjCMesh* pmesh = model->meshes[meshid]; + // save reference in case this is not an mjGEOM_MESH + mjCMesh* pmesh = mesh; // fit geom if type is not mjGEOM_MESH double meshpos[3]; if (type!=mjGEOM_MESH && type!=mjGEOM_SDF) { - pmesh->FitGeom(this, meshpos); + mesh->FitGeom(this, meshpos); // remove reference to mesh - mesh.clear(); - meshid = -1; + meshname.clear(); + mesh = nullptr; } else { - mjuu_copyvec(meshpos, pmesh->GetPosPtr(typeinertia), 3); + mjuu_copyvec(meshpos, mesh->GetPosPtr(typeinertia), 3); } // apply geom pos/quat as offset @@ -1815,12 +1813,12 @@ void mjCGeom::Compile(void) { // set hfield sizes in geom.size if (type==mjGEOM_HFIELD) { - size[0] = model->hfields[hfieldid]->size[0]; - size[1] = model->hfields[hfieldid]->size[1]; - size[2] = 0.5*(0.5*model->hfields[hfieldid]->size[2] + - model->hfields[hfieldid]->size[3]); + size[0] = hfield->size[0]; + size[1] = hfield->size[1]; + size[2] = 0.5*(0.5*hfield->size[2] + + hfield->size[3]); } else if (type==mjGEOM_MESH || type==mjGEOM_SDF) { - const double* aamm = model->meshes[meshid]->aamm(); + const double* aamm = mesh->aamm(); size[0] = mju_max(fabs(aamm[0]), fabs(aamm[3])); size[1] = mju_max(fabs(aamm[1]), fabs(aamm[4])); size[2] = mju_max(fabs(aamm[2]), fabs(aamm[5])); diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 505e13f3..9641626c 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -36,6 +36,7 @@ class mjCGeom; class mjCSite; class mjCCamera; class mjCLight; +class mjCHField; class mjCFlex; // defined in user_mesh class mjCMesh; // defined in user_mesh class mjCSkin; // defined in user_mesh @@ -397,8 +398,8 @@ class mjCGeom : public mjCBase { mjtNum fluid_switch; // whether ellipsoid-fluid model is active mjtNum fluid_coefs[5]; // tunable ellipsoid-fluid interaction coefs mjtNum fluid[mjNFLUID]; // compile-time fluid-interaction parameters - std::string hfield; // hfield attached to geom - std::string mesh; // mesh attached to geom + 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 @@ -423,8 +424,8 @@ class mjCGeom : public mjCBase { void ComputeAABB(void); // compute axis-aligned bounding box int matid; // id of geom's material - int meshid; // id of geom's mesh (-1: none) - int hfieldid; // id of geom's hfield (-1: none) + mjCMesh* mesh; // geom's mesh + mjCHField* hfield; // geom's hfield double mass; // mass double inertia[3]; // local diagonal inertia double aabb[6]; // axis-aligned bounding box (center, size) diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 7863afaa..bd438c5e 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -1525,8 +1525,8 @@ void mjXReader::OneGeom(XMLElement* elem, mjCGeom* pgeom) { ReadAttr(elem, "solimp", mjNIMP, pgeom->solimp, text, false, false); ReadAttr(elem, "margin", 1, &pgeom->margin, text); ReadAttr(elem, "gap", 1, &pgeom->gap, text); - ReadAttrTxt(elem, "hfield", pgeom->hfield); - ReadAttrTxt(elem, "mesh", pgeom->mesh); + ReadAttrTxt(elem, "hfield", pgeom->hfieldname); + ReadAttrTxt(elem, "mesh", pgeom->meshname); ReadAttr(elem, "fitscale", 1, &pgeom->fitscale, text); ReadAttrTxt(elem, "material", pgeom->material); ReadAttr(elem, "rgba", 4, pgeom->rgba, text); diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 63d22b72..0e7d281f 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -347,7 +347,7 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) { // mesh geom if (pgeom->type==mjGEOM_MESH || pgeom->type==mjGEOM_SDF) { - mjCMesh* pmesh = model->meshes[pgeom->meshid]; + mjCMesh* pmesh = pgeom->mesh; // write pos/quat if there is a difference if (!SameVector(pgeom->pos, pmesh->GetPosPtr(pgeom->typeinertia), 3) || @@ -403,10 +403,10 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) { // hfield and mesh attributes if (pgeom->type==mjGEOM_HFIELD) { - WriteAttrTxt(elem, "hfield", pgeom->hfield); + WriteAttrTxt(elem, "hfield", pgeom->hfieldname); } if (pgeom->type==mjGEOM_MESH || pgeom->type==mjGEOM_SDF) { - WriteAttrTxt(elem, "mesh", pgeom->mesh); + WriteAttrTxt(elem, "mesh", pgeom->meshname); } // userdata diff --git a/src/xml/xml_urdf.cc b/src/xml/xml_urdf.cc index dab94fa8..74b7075b 100644 --- a/src/xml/xml_urdf.cc +++ b/src/xml/xml_urdf.cc @@ -573,7 +573,7 @@ mjCGeom* mjXURDF::Geom(XMLElement* geom_elem, mjCBody* pbody, bool collision) { // set fields pmesh->set_file(meshfile); pmesh->name = meshname; - pgeom->mesh = meshname; + pgeom->meshname = meshname; pmesh->set_scale(meshscale); }