From 0e8c0b80ebbb693572c058441c8903968e5dde2e Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Wed, 4 Sep 2024 07:24:48 -0700 Subject: [PATCH] add content_type to model in the XML schema. PiperOrigin-RevId: 670961443 Change-Id: I98cd6bb61b50029cdd4f5b31e23d268989d136da --- doc/XMLreference.rst | 5 +++++ doc/XMLschema.rst | 2 +- src/render/render_context.c | 12 ++++++++++-- src/user/user_model.cc | 2 +- src/xml/xml_native_reader.cc | 17 ++++++++++++++--- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index ce5e7be9..f4c90da4 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -1893,6 +1893,11 @@ This element specifies other MJCF models which may be used for :ref:`attachment< :at:`file`: :at-val:`string, required` The file from which the sub-model will be loaded. Note that the sub-model must be a valid MJCF model. +.. _asset-model-content_type: + +:at:`content_type` :at-val:`string, optional` + The file type to be loaded into a model. Currently only text/xml is supported. + .. _body: diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index 098363ac..a7aa3e66 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -244,7 +244,7 @@ | :ref:`model | \* | :class: mjcf-attributes | | ` | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`name` | :ref:`file` | | | | +| | | | :ref:`name` | :ref:`file` | :ref:`content_type` | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | mujoco |br| |L| | | .. table:: | diff --git a/src/render/render_context.c b/src/render/render_context.c index 7d37692e..653ab3ac 100644 --- a/src/render/render_context.c +++ b/src/render/render_context.c @@ -1382,8 +1382,16 @@ void mjr_uploadTexture(const mjModel* m, const mjrContext* con, int texid) { glTexGenfv(GL_T, GL_OBJECT_PLANE, plane); // assign data - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m->tex_width[texid], m->tex_height[texid], 0, - GL_RGB, GL_UNSIGNED_BYTE, m->tex_data + m->tex_adr[texid]); + int type = 0; + if (m->tex_nchannel[texid] == 3) { + type = GL_RGB; + } else if (m->tex_nchannel[texid] == 4) { + type = GL_RGBA; + } else { + mju_error("Number of channels not supported: %d", m->tex_nchannel[texid]); + } + glTexImage2D(GL_TEXTURE_2D, 0, type, m->tex_width[texid], m->tex_height[texid], 0, + type, GL_UNSIGNED_BYTE, m->tex_data + m->tex_adr[texid]); // generate mipmaps glGenerateMipmap(GL_TEXTURE_2D); diff --git a/src/user/user_model.cc b/src/user/user_model.cc index c2e8e548..582c932c 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -1547,7 +1547,7 @@ void mjCModel::SetSizes() { for (int i=0; inrow * hfields_[i]->ncol; // ntexdata - for (int i=0; iwidth * textures_[i]->height; + for (int i=0; inchannel * textures_[i]->width * textures_[i]->height; // nwrap for (int i=0; ipath.size(); diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 99ee8cf7..a8a81ae6 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -258,7 +258,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { {"rgba", "?", "1", "texture"}, {"orm", "?", "1", "texture"}, {">"}, - {"model", "*", "2", "name", "file"}, + {"model", "*", "3", "name", "file", "content_type"}, {">"}, {"body", "R", "11", "name", "childclass", "pos", "quat", "mocap", @@ -3306,11 +3306,22 @@ void mjXReader::Asset(XMLElement* section, const mjVFS* vfs) { // model sub-element else if (name=="model") { - auto filename = modelfiledir_ + ReadAttrFile(elem, "file", vfs).value(); + string content_type; + if (!ReadAttrTxt(elem, "content_type", content_type)) { + content_type = "text/xml"; + } // parse the child + mjSpec* child = nullptr; std::array error; - mjSpec* child = mj_parseXML(filename.c_str(), vfs, error.data(), error.size()); + auto filename = modelfiledir_ + ReadAttrFile(elem, "file", vfs).value(); + + if (content_type == "text/xml") { + child = mj_parseXML(filename.c_str(), vfs, error.data(), error.size()); + } else { + throw mjXError(elem, "unsupported content_type: %s", content_type.c_str()); + } + if (!child) { throw mjXError(elem, "could not parse model file with error: %s", error.data()); }