Add ability to specify a material assignment to a mesh asset.
This extends both the spec and the XML definition to allow specification of a material name on a mesh. This material acts as a fallback in the case that the referencing geom element does not specify a material of it's own. PiperOrigin-RevId: 798232378 Change-Id: Iaf300c727732744ea1b613e64334ee505ac6e209
This commit is contained in:
committed by
Copybara-Service
parent
42d8454555
commit
1fb1810b07
@@ -278,6 +278,7 @@ void mjCMesh::PointToLocal() {
|
||||
spec.userface = &spec_face_;
|
||||
spec.usertexcoord = &spec_texcoord_;
|
||||
spec.userfacetexcoord = &spec_facetexcoord_;
|
||||
spec.material = &spec_material_;
|
||||
spec.plugin.plugin_name = &plugin_name;
|
||||
spec.plugin.name = &plugin_instance_name;
|
||||
spec.info = &info;
|
||||
@@ -317,6 +318,7 @@ void mjCMesh::CopyFromSpec() {
|
||||
content_type_ = spec_content_type_;
|
||||
normal_ = spec_normal_;
|
||||
face_ = spec_face_;
|
||||
material_ = spec_material_;
|
||||
ProcessVertices(spec_vert_);
|
||||
texcoord_ = spec_texcoord_;
|
||||
facetexcoord_ = spec_facetexcoord_;
|
||||
@@ -476,6 +478,7 @@ void mjCMesh::CacheMesh(mjCCache* cache, const mjResource* resource) {
|
||||
mesh->polygon_map_ = polygon_map_;
|
||||
mesh->surface_ = surface_;
|
||||
mesh->volume_ = volume_;
|
||||
mesh->material_ = material_;
|
||||
std::copy(boxsz_, boxsz_ + 3, mesh->boxsz_);
|
||||
std::copy(aamm_, aamm_ + 6, mesh->aamm_);
|
||||
std::copy(pos_, pos_ + 3, mesh->pos_);
|
||||
|
||||
+17
-15
@@ -1879,7 +1879,23 @@ void mjCModel::IndexAssets(bool discard) {
|
||||
for (int i=0; i < geoms_.size(); i++) {
|
||||
mjCGeom* geom = geoms_[i];
|
||||
|
||||
// find material by name
|
||||
|
||||
// find mesh by name
|
||||
if (!geom->get_meshname().empty()) {
|
||||
mjCMesh* mesh = static_cast<mjCMesh*>(FindObject(mjOBJ_MESH, geom->get_meshname()));
|
||||
if (mesh) {
|
||||
if (!geom->visual_) {
|
||||
mesh->SetNotVisual(); // reset to true by mesh->Compile()
|
||||
}
|
||||
geom->mesh = (discard && geom->visual_) ? nullptr : mesh;
|
||||
mesh->spec.needsdf |= geom->spec.type == mjGEOM_SDF;
|
||||
} else {
|
||||
throw mjCError(geom, "mesh '%s' not found in geom %d", geom->get_meshname().c_str(), i);
|
||||
}
|
||||
}
|
||||
|
||||
// find material by name, this has to happen after mesh assignment so that if
|
||||
// the geom does not specify a material but the mesh does it can fall back.
|
||||
if (!geom->get_material().empty()) {
|
||||
mjCBase* material = FindObject(mjOBJ_MATERIAL, geom->get_material());
|
||||
if (material) {
|
||||
@@ -1889,20 +1905,6 @@ void mjCModel::IndexAssets(bool discard) {
|
||||
}
|
||||
}
|
||||
|
||||
// find mesh by name
|
||||
if (!geom->get_meshname().empty()) {
|
||||
mjCBase* mesh = FindObject(mjOBJ_MESH, geom->get_meshname());
|
||||
if (mesh) {
|
||||
if (!geom->visual_) {
|
||||
((mjCMesh*)mesh)->SetNotVisual(); // reset to true by mesh->Compile()
|
||||
}
|
||||
geom->mesh = (discard && geom->visual_) ? nullptr : (mjCMesh*)mesh;
|
||||
static_cast<mjCMesh*>(mesh)->spec.needsdf |= geom->spec.type == mjGEOM_SDF;
|
||||
} else {
|
||||
throw mjCError(geom, "mesh '%s' not found in geom %d", geom->get_meshname().c_str(), i);
|
||||
}
|
||||
}
|
||||
|
||||
// find hfield by name
|
||||
if (!geom->get_hfieldname().empty()) {
|
||||
mjCBase* hfield = FindObject(mjOBJ_HFIELD, geom->get_hfieldname());
|
||||
|
||||
@@ -3365,7 +3365,12 @@ void mjCGeom::ComputeAABB(void) {
|
||||
mjuu_copyvec(aabb+3, size, 3);
|
||||
}
|
||||
|
||||
|
||||
const std::string& mjCGeom::get_material() const {
|
||||
if (mesh && spec_material_.empty()) {
|
||||
return mesh->Material();
|
||||
}
|
||||
return spec_material_;
|
||||
}
|
||||
|
||||
// compiler
|
||||
void mjCGeom::Compile(void) {
|
||||
|
||||
@@ -49,9 +49,9 @@ class mjCSite;
|
||||
class mjCCamera;
|
||||
class mjCLight;
|
||||
class mjCHField;
|
||||
class mjCFlex; // defined in user_mesh.h
|
||||
class mjCMesh; // defined in user_mesh.h
|
||||
class mjCSkin; // defined in user_mesh.h
|
||||
class mjCFlex;
|
||||
class mjCMesh;
|
||||
class mjCSkin;
|
||||
class mjCTexture;
|
||||
class mjCMaterial;
|
||||
class mjCPair;
|
||||
@@ -753,7 +753,7 @@ class mjCGeom : public mjCGeom_, private mjsGeom {
|
||||
const std::vector<double>& get_userdata() const { return userdata_; }
|
||||
const std::string& get_hfieldname() const { return spec_hfieldname_; }
|
||||
const std::string& get_meshname() const { return spec_meshname_; }
|
||||
const std::string& get_material() const { return spec_material_; }
|
||||
const std::string& get_material() const;
|
||||
void del_material() { spec_material_.clear(); }
|
||||
|
||||
private:
|
||||
@@ -1029,6 +1029,7 @@ class mjCMesh_ : public mjCBase {
|
||||
std::vector<int> face_; // vertex indices
|
||||
std::vector<int> facenormal_; // normal indices
|
||||
std::vector<int> facetexcoord_; // texcoord indices
|
||||
std::string material_; // mesh fallback material
|
||||
|
||||
std::string spec_content_type_;
|
||||
std::string spec_file_;
|
||||
@@ -1038,6 +1039,7 @@ class mjCMesh_ : public mjCBase {
|
||||
std::vector<int> spec_face_;
|
||||
std::vector<int> spec_facenormal_;
|
||||
std::vector<int> spec_facetexcoord_;
|
||||
std::string spec_material_;
|
||||
|
||||
// used by the compiler
|
||||
bool needreorient_; // needs reorientation
|
||||
@@ -1117,6 +1119,8 @@ class mjCMesh: public mjCMesh_, private mjsMesh {
|
||||
const std::vector<int>& Face() const { return face_; }
|
||||
const std::vector<int>& UserFace() const { return spec_face_; }
|
||||
mjtMeshInertia Inertia() const { return spec.inertia; }
|
||||
const std::string& Material() const { return material_; }
|
||||
|
||||
// setters
|
||||
void SetNeedHull(bool needhull) { needhull_ = needhull; }
|
||||
|
||||
|
||||
@@ -230,9 +230,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
|
||||
{"asset", "*", "0"},
|
||||
{"<"},
|
||||
{"mesh", "*", "16", "name", "class", "content_type", "file", "vertex", "normal",
|
||||
{"mesh", "*", "17", "name", "class", "content_type", "file", "vertex", "normal",
|
||||
"texcoord", "face", "refpos", "refquat", "scale", "smoothnormal",
|
||||
"maxhullvert", "inertia", "builtin", "params"},
|
||||
"maxhullvert", "inertia", "builtin", "params", "material"},
|
||||
{"<"},
|
||||
{"plugin", "*", "2", "plugin", "instance"},
|
||||
{"<"},
|
||||
@@ -1569,6 +1569,11 @@ void mjXReader::OneMesh(XMLElement* elem, mjsMesh* mesh, const mjVFS* vfs) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string material;
|
||||
if (ReadAttrTxt(elem, "material", material)) {
|
||||
mjs_setString(mesh->material, material.c_str());
|
||||
}
|
||||
|
||||
// write error info
|
||||
mjs_setString(mesh->info, ("line " + std::to_string(elem->GetLineNum())).c_str());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user