Track authored flags for global attributes
PiperOrigin-RevId: 931585539 Change-Id: Ifdc8c59de6c5a553daf6e0af09d8192aff6b0610
This commit is contained in:
committed by
Copybara-Service
parent
0ea9c7cb3a
commit
67a1ea6dca
+232
-182
@@ -25,17 +25,14 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <mujoco/mujoco.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjplugin.h>
|
||||
#include <mujoco/mjtype.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
#include "engine/engine_plugin.h"
|
||||
#include "engine/engine_support.h"
|
||||
#include "engine/engine_util_errmem.h"
|
||||
#include "engine/engine_util_misc.h"
|
||||
#include <mujoco/mjspec.h>
|
||||
#include "user/user_api.h"
|
||||
@@ -53,6 +50,81 @@ using std::vector;
|
||||
using mujoco::user::FilePath;
|
||||
using tinyxml2::XMLElement;
|
||||
|
||||
|
||||
|
||||
//---------------------------------- helper utilities ----------------------------------------------
|
||||
|
||||
// GetAttrPtr: overload for scalar and pointer fields
|
||||
template <typename T>
|
||||
inline auto GetAttrPtr(T& val) -> std::enable_if_t<!std::is_array_v<T>, decltype(&val)> {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
return val;
|
||||
} else {
|
||||
return &val;
|
||||
}
|
||||
}
|
||||
|
||||
// GetAttrPtr: overload for array fields
|
||||
template <typename T, size_t N>
|
||||
inline T* GetAttrPtr(T (&arr)[N]) { return arr; }
|
||||
|
||||
|
||||
// helper class for reading attributes while recording authored bits
|
||||
struct Reader {
|
||||
Reader(XMLElement* xml_node, const void* elem) : xml_node_(xml_node), elem_(elem) {}
|
||||
|
||||
template <typename T>
|
||||
int operator()(const char* attr, int len, T& data, bool required = false, bool exact = true) {
|
||||
int res = mjXReader::ReadAttr(xml_node_, attr, len, GetAttrPtr(data), text_, required, exact);
|
||||
if (res) mjs_setAuthored(elem_, &data, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator()(const char* attr, T& data, const mjMap* map, int mapsz, bool required = false) {
|
||||
int map_val_temp;
|
||||
bool res = mjXReader::MapValue(xml_node_, attr, &map_val_temp, map, mapsz, required);
|
||||
if (res) {
|
||||
data = static_cast<T>(map_val_temp);
|
||||
mjs_setAuthored(elem_, &data, 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool operator()(const char* attr, int& data, bool required = false) {
|
||||
bool res = mjXUtil::ReadAttrInt(xml_node_, attr, &data, required);
|
||||
if (res) mjs_setAuthored(elem_, &data, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool operator()(const char* attr, mjString* target) {
|
||||
std::string txt_temp;
|
||||
bool res = mjXUtil::ReadAttrTxt(xml_node_, attr, txt_temp);
|
||||
if (res) {
|
||||
mjs_setString(target, txt_temp.c_str());
|
||||
mjs_setAuthored(elem_, target, 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool txt(const char* attr, T& target, void (&set_func)(T&, const char*)) {
|
||||
std::string txt_temp;
|
||||
bool res = mjXUtil::ReadAttrTxt(xml_node_, attr, txt_temp);
|
||||
if (res) {
|
||||
set_func(target, txt_temp.c_str());
|
||||
mjs_setAuthored(elem_, &target, 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void set_node(XMLElement* node) { xml_node_ = node; }
|
||||
|
||||
XMLElement* xml_node_;
|
||||
const void* elem_;
|
||||
std::string text_;
|
||||
};
|
||||
|
||||
void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjsPlugin* p) {
|
||||
std::map<string, string, std::less<> > config_attribs;
|
||||
XMLElement* child = FirstChildElement(elem);
|
||||
@@ -1023,7 +1095,7 @@ void mjXReader::Parse(XMLElement* root, const mjVFS* vfs) {
|
||||
|
||||
for (XMLElement* section = FirstChildElement(root, "option"); section;
|
||||
section = NextSiblingElement(section, "option")) {
|
||||
Option(section, &spec->option);
|
||||
Option(section, spec, &spec->option);
|
||||
}
|
||||
|
||||
for (XMLElement* section = FirstChildElement(root, "size"); section;
|
||||
@@ -1116,73 +1188,49 @@ void mjXReader::Parse(XMLElement* root, const mjVFS* vfs) {
|
||||
|
||||
// compiler section parser
|
||||
void mjXReader::Compiler(XMLElement* section, mjSpec* s) {
|
||||
string text;
|
||||
int n;
|
||||
Reader read(section, s);
|
||||
|
||||
// top-level attributes
|
||||
if (MapValue(section, "autolimits", &n, bool_map, 2)) {
|
||||
s->compiler.autolimits = (n == 1);
|
||||
}
|
||||
ReadAttr(section, "boundmass", 1, &s->compiler.boundmass, text);
|
||||
ReadAttr(section, "boundinertia", 1, &s->compiler.boundinertia, text);
|
||||
ReadAttr(section, "settotalmass", 1, &s->compiler.settotalmass, text);
|
||||
if (MapValue(section, "balanceinertia", &n, bool_map, 2)) {
|
||||
s->compiler.balanceinertia = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "strippath", &n, bool_map, 2)) {
|
||||
s->strippath = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "fitaabb", &n, bool_map, 2)) {
|
||||
s->compiler.fitaabb = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "coordinate", &n, coordinate_map, 2)) {
|
||||
read("autolimits", s->compiler.autolimits, bool_map, 2);
|
||||
read("boundmass", 1, s->compiler.boundmass);
|
||||
read("boundinertia", 1, s->compiler.boundinertia);
|
||||
read("settotalmass", 1, s->compiler.settotalmass);
|
||||
read("balanceinertia", s->compiler.balanceinertia, bool_map, 2);
|
||||
read("strippath", s->strippath, bool_map, 2);
|
||||
read("fitaabb", s->compiler.fitaabb, bool_map, 2);
|
||||
if (int n = 0; MapValue(section, "coordinate", &n, coordinate_map, 2)) {
|
||||
if (n == 1) {
|
||||
throw mjXError(section, "global coordinates no longer supported. To convert existing models, "
|
||||
"load and save them in MuJoCo 2.3.3 or older");
|
||||
}
|
||||
}
|
||||
if (MapValue(section, "angle", &n, angle_map, 2)) {
|
||||
s->compiler.degree = (n == 1);
|
||||
}
|
||||
if (ReadAttrTxt(section, "eulerseq", text)) {
|
||||
if (text.size() != 3) {
|
||||
read("angle", s->compiler.degree, angle_map, 2);
|
||||
if (ReadAttrTxt(section, "eulerseq", read.text_)) {
|
||||
if (read.text_.size() != 3) {
|
||||
throw mjXError(section, "euler format must have length 3");
|
||||
}
|
||||
memcpy(s->compiler.eulerseq, text.c_str(), 3);
|
||||
memcpy(s->compiler.eulerseq, read.text_.c_str(), 3);
|
||||
mjs_setAuthored(s, &s->compiler.eulerseq, 1);
|
||||
}
|
||||
if (ReadAttrTxt(section, "assetdir", text)) {
|
||||
mjs_setString(s->compiler.meshdir, text.c_str());
|
||||
mjs_setString(s->compiler.texturedir, text.c_str());
|
||||
if (ReadAttrTxt(section, "assetdir", read.text_)) {
|
||||
mjs_setString(s->compiler.meshdir, read.text_.c_str());
|
||||
mjs_setString(s->compiler.texturedir, read.text_.c_str());
|
||||
}
|
||||
// meshdir and texturedir take precedence over assetdir
|
||||
string meshdir, texturedir;
|
||||
if (ReadAttrTxt(section, "meshdir", meshdir)) {
|
||||
mjs_setString(s->compiler.meshdir, meshdir.c_str());
|
||||
};
|
||||
if (ReadAttrTxt(section, "texturedir", texturedir)) {
|
||||
mjs_setString(s->compiler.texturedir, texturedir.c_str());
|
||||
}
|
||||
if (MapValue(section, "discardvisual", &n, bool_map, 2)) {
|
||||
s->compiler.discardvisual = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "usethread", &n, bool_map, 2)) {
|
||||
s->compiler.usethread = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "fusestatic", &n, bool_map, 2)) {
|
||||
s->compiler.fusestatic = (n == 1);
|
||||
}
|
||||
MapValue(section, "inertiafromgeom", &s->compiler.inertiafromgeom, TFAuto_map, 3);
|
||||
ReadAttr(section, "inertiagrouprange", 2, s->compiler.inertiagrouprange, text);
|
||||
if (MapValue(section, "alignfree", &n, bool_map, 2)) {
|
||||
s->compiler.alignfree = (n == 1);
|
||||
}
|
||||
if (MapValue(section, "saveinertial", &n, bool_map, 2)) {
|
||||
s->compiler.saveinertial = (n == 1);
|
||||
}
|
||||
read("meshdir", s->compiler.meshdir);
|
||||
read("texturedir", s->compiler.texturedir);
|
||||
read("discardvisual", s->compiler.discardvisual, bool_map, 2);
|
||||
read("usethread", s->compiler.usethread, bool_map, 2);
|
||||
read("fusestatic", s->compiler.fusestatic, bool_map, 2);
|
||||
read("inertiafromgeom", s->compiler.inertiafromgeom, TFAuto_map, 3);
|
||||
read("inertiagrouprange", 2, s->compiler.inertiagrouprange);
|
||||
read("alignfree", s->compiler.alignfree, bool_map, 2);
|
||||
read("saveinertial", s->compiler.saveinertial, bool_map, 2);
|
||||
|
||||
// lengthrange subelement
|
||||
XMLElement* elem = FindSubElem(section, "lengthrange");
|
||||
if (elem) {
|
||||
int n;
|
||||
mjLROpt* opt = &(s->compiler.LRopt);
|
||||
|
||||
// flags
|
||||
@@ -1195,6 +1243,7 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* s) {
|
||||
}
|
||||
|
||||
// algorithm parameters
|
||||
string text;
|
||||
ReadAttr(elem, "accel", 1, &opt->accel, text);
|
||||
ReadAttr(elem, "maxforce", 1, &opt->maxforce, text);
|
||||
ReadAttr(elem, "timeconst", 1, &opt->timeconst, text);
|
||||
@@ -1208,45 +1257,44 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* s) {
|
||||
|
||||
|
||||
// option section parser
|
||||
void mjXReader::Option(XMLElement* section, mjOption* opt) {
|
||||
string text;
|
||||
int n;
|
||||
void mjXReader::Option(XMLElement* section, mjSpec* s, mjOption* opt) {
|
||||
Reader read(section, s);
|
||||
|
||||
// read options
|
||||
ReadAttr(section, "timestep", 1, &opt->timestep, text);
|
||||
ReadAttr(section, "impratio", 1, &opt->impratio, text);
|
||||
ReadAttr(section, "tolerance", 1, &opt->tolerance, text);
|
||||
ReadAttr(section, "ls_tolerance", 1, &opt->ls_tolerance, text);
|
||||
ReadAttr(section, "noslip_tolerance", 1, &opt->noslip_tolerance, text);
|
||||
ReadAttr(section, "ccd_tolerance", 1, &opt->ccd_tolerance, text);
|
||||
ReadAttr(section, "sleep_tolerance", 1, &opt->sleep_tolerance, text);
|
||||
ReadAttr(section, "gravity", 3, opt->gravity, text);
|
||||
ReadAttr(section, "wind", 3, opt->wind, text);
|
||||
ReadAttr(section, "magnetic", 3, opt->magnetic, text);
|
||||
ReadAttr(section, "density", 1, &opt->density, text);
|
||||
ReadAttr(section, "viscosity", 1, &opt->viscosity, text);
|
||||
read("timestep", 1, opt->timestep);
|
||||
read("impratio", 1, opt->impratio);
|
||||
read("tolerance", 1, opt->tolerance);
|
||||
read("ls_tolerance", 1, opt->ls_tolerance);
|
||||
read("noslip_tolerance", 1, opt->noslip_tolerance);
|
||||
read("ccd_tolerance", 1, opt->ccd_tolerance);
|
||||
read("sleep_tolerance", 1, opt->sleep_tolerance);
|
||||
read("gravity", 3, opt->gravity);
|
||||
read("wind", 3, opt->wind);
|
||||
read("magnetic", 3, opt->magnetic);
|
||||
read("density", 1, opt->density);
|
||||
read("viscosity", 1, opt->viscosity);
|
||||
|
||||
ReadAttr(section, "o_margin", 1, &opt->o_margin, text);
|
||||
ReadAttr(section, "o_solref", mjNREF, opt->o_solref, text, false, false);
|
||||
ReadAttr(section, "o_solimp", mjNIMP, opt->o_solimp, text, false, false);
|
||||
ReadAttr(section, "o_friction", 5, opt->o_friction, text, false, false);
|
||||
read("o_margin", 1, opt->o_margin);
|
||||
read("o_solref", mjNREF, opt->o_solref, false, false);
|
||||
read("o_solimp", mjNIMP, opt->o_solimp, false, false);
|
||||
read("o_friction", 5, opt->o_friction, false, false);
|
||||
|
||||
MapValue(section, "integrator", &opt->integrator, integrator_map, integrator_sz);
|
||||
MapValue(section, "cone", &opt->cone, cone_map, cone_sz);
|
||||
MapValue(section, "jacobian", &opt->jacobian, jac_map, jac_sz);
|
||||
MapValue(section, "solver", &opt->solver, solver_map, solver_sz);
|
||||
ReadAttrInt(section, "iterations", &opt->iterations);
|
||||
ReadAttrInt(section, "ls_iterations", &opt->ls_iterations);
|
||||
ReadAttrInt(section, "noslip_iterations", &opt->noslip_iterations);
|
||||
ReadAttrInt(section, "ccd_iterations", &opt->ccd_iterations);
|
||||
ReadAttrInt(section, "sdf_iterations", &opt->sdf_iterations);
|
||||
ReadAttrInt(section, "sdf_initpoints", &opt->sdf_initpoints);
|
||||
read("integrator", opt->integrator, integrator_map, integrator_sz);
|
||||
read("cone", opt->cone, cone_map, cone_sz);
|
||||
read("jacobian", opt->jacobian, jac_map, jac_sz);
|
||||
read("solver", opt->solver, solver_map, solver_sz);
|
||||
read("iterations", opt->iterations);
|
||||
read("ls_iterations", opt->ls_iterations);
|
||||
read("noslip_iterations", opt->noslip_iterations);
|
||||
read("ccd_iterations", opt->ccd_iterations);
|
||||
read("sdf_iterations", opt->sdf_iterations);
|
||||
read("sdf_initpoints", opt->sdf_initpoints);
|
||||
|
||||
// actuatorgroupdisable
|
||||
constexpr int num_bitflags = 31;
|
||||
int disabled_act_groups[num_bitflags];
|
||||
int num_found = ReadAttr(section, "actuatorgroupdisable", num_bitflags, disabled_act_groups,
|
||||
text, false, false);
|
||||
int num_found = read("actuatorgroupdisable", num_bitflags,
|
||||
disabled_act_groups, false, false);
|
||||
for (int i=0; i < num_found; i++) {
|
||||
int group = disabled_act_groups[i];
|
||||
if (group < 0) {
|
||||
@@ -1256,15 +1304,19 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) {
|
||||
throw mjXError(section, "disabled actuator group value cannot exceed 30");
|
||||
}
|
||||
opt->disableactuator |= (1 << group);
|
||||
s->authored.disableactuator |= (1 << group);
|
||||
}
|
||||
|
||||
// read disable sub-element
|
||||
XMLElement* elem = FindSubElem(section, "flag");
|
||||
if (elem) {
|
||||
#define READDSBL(NAME, MASK) \
|
||||
if (MapValue(elem, NAME, &n, enable_map, 2)) { \
|
||||
opt->disableflags ^= (opt->disableflags & MASK); \
|
||||
opt->disableflags |= (n ? 0 : MASK); }
|
||||
int n = 0;
|
||||
#define READDSBL(NAME, MASK) \
|
||||
if (MapValue(elem, NAME, &n, enable_map, 2)) { \
|
||||
opt->disableflags ^= (opt->disableflags & MASK); \
|
||||
opt->disableflags |= (n ? 0 : MASK); \
|
||||
s->authored.disableflags |= MASK; \
|
||||
}
|
||||
|
||||
READDSBL("constraint", mjDSBL_CONSTRAINT)
|
||||
READDSBL("equality", mjDSBL_EQUALITY)
|
||||
@@ -1288,10 +1340,12 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) {
|
||||
READDSBL("multiccd", mjDSBL_MULTICCD)
|
||||
#undef READDSBL
|
||||
|
||||
#define READENBL(NAME, MASK) \
|
||||
if (MapValue(elem, NAME, &n, enable_map, 2)) { \
|
||||
opt->enableflags ^= (opt->enableflags & MASK); \
|
||||
opt->enableflags |= (n ? MASK : 0); }
|
||||
#define READENBL(NAME, MASK) \
|
||||
if (MapValue(elem, NAME, &n, enable_map, 2)) { \
|
||||
opt->enableflags ^= (opt->enableflags & MASK); \
|
||||
opt->enableflags |= (n ? MASK : 0); \
|
||||
s->authored.enableflags |= MASK; \
|
||||
}
|
||||
|
||||
READENBL("override", mjENBL_OVERRIDE)
|
||||
READENBL("energy", mjENBL_ENERGY)
|
||||
@@ -3247,129 +3301,125 @@ void mjXReader::Custom(XMLElement* section) {
|
||||
|
||||
// visual section parser
|
||||
void mjXReader::Visual(XMLElement* section) {
|
||||
string text, name;
|
||||
string name;
|
||||
XMLElement* elem;
|
||||
mjVisual* vis = &spec->visual;
|
||||
int n;
|
||||
Reader read(section, spec);
|
||||
|
||||
// iterate over child elements
|
||||
elem = FirstChildElement(section);
|
||||
while (elem) {
|
||||
// get sub-element name
|
||||
name = elem->Value();
|
||||
read.set_node(elem);
|
||||
|
||||
// global sub-element
|
||||
if (name == "global") {
|
||||
ReadAttrInt(elem, "cameraid", &vis->global.cameraid);
|
||||
if (MapValue(elem, "orthographic", &n, bool_map, 2)) {
|
||||
vis->global.orthographic = (n == 1);
|
||||
}
|
||||
ReadAttr(elem, "fovy", 1, &vis->global.fovy, text);
|
||||
ReadAttr(elem, "ipd", 1, &vis->global.ipd, text);
|
||||
ReadAttr(elem, "azimuth", 1, &vis->global.azimuth, text);
|
||||
ReadAttr(elem, "elevation", 1, &vis->global.elevation, text);
|
||||
ReadAttr(elem, "linewidth", 1, &vis->global.linewidth, text);
|
||||
ReadAttr(elem, "glow", 1, &vis->global.glow, text);
|
||||
ReadAttrInt(elem, "offwidth", &vis->global.offwidth);
|
||||
ReadAttrInt(elem, "offheight", &vis->global.offheight);
|
||||
if (ReadAttr(elem, "realtime", 1, &vis->global.realtime, text)) {
|
||||
read("cameraid", vis->global.cameraid);
|
||||
read("orthographic", vis->global.orthographic, bool_map, 2);
|
||||
read("fovy", 1, vis->global.fovy);
|
||||
read("ipd", 1, vis->global.ipd);
|
||||
read("azimuth", 1, vis->global.azimuth);
|
||||
read("elevation", 1, vis->global.elevation);
|
||||
read("linewidth", 1, vis->global.linewidth);
|
||||
read("glow", 1, vis->global.glow);
|
||||
read("offwidth", vis->global.offwidth);
|
||||
read("offheight", vis->global.offheight);
|
||||
if (read("realtime", 1, vis->global.realtime)) {
|
||||
if (vis->global.realtime <= 0) {
|
||||
throw mjXError(elem, "realtime must be greater than 0");
|
||||
}
|
||||
}
|
||||
if (MapValue(elem, "ellipsoidinertia", &n, bool_map, 2)) {
|
||||
vis->global.ellipsoidinertia = (n == 1);
|
||||
}
|
||||
if (MapValue(elem, "bvactive", &n, bool_map, 2)) {
|
||||
vis->global.bvactive = (n == 1);
|
||||
}
|
||||
read("ellipsoidinertia", vis->global.ellipsoidinertia, bool_map, 2);
|
||||
read("bvactive", vis->global.bvactive, bool_map, 2);
|
||||
}
|
||||
|
||||
// quality sub-element
|
||||
else if (name == "quality") {
|
||||
ReadAttrInt(elem, "shadowsize", &vis->quality.shadowsize);
|
||||
ReadAttrInt(elem, "offsamples", &vis->quality.offsamples);
|
||||
ReadAttrInt(elem, "numslices", &vis->quality.numslices);
|
||||
ReadAttrInt(elem, "numstacks", &vis->quality.numstacks);
|
||||
ReadAttrInt(elem, "numquads", &vis->quality.numquads);
|
||||
read("shadowsize", vis->quality.shadowsize);
|
||||
read("offsamples", vis->quality.offsamples);
|
||||
read("numslices", vis->quality.numslices);
|
||||
read("numstacks", vis->quality.numstacks);
|
||||
read("numquads", vis->quality.numquads);
|
||||
}
|
||||
|
||||
// headlight sub-element
|
||||
else if (name == "headlight") {
|
||||
ReadAttr(elem, "ambient", 3, vis->headlight.ambient, text);
|
||||
ReadAttr(elem, "diffuse", 3, vis->headlight.diffuse, text);
|
||||
ReadAttr(elem, "specular", 3, vis->headlight.specular, text);
|
||||
ReadAttrInt(elem, "active", &vis->headlight.active);
|
||||
read("ambient", 3, vis->headlight.ambient);
|
||||
read("diffuse", 3, vis->headlight.diffuse);
|
||||
read("specular", 3, vis->headlight.specular);
|
||||
read("active", vis->headlight.active);
|
||||
}
|
||||
|
||||
// map sub-element
|
||||
else if (name == "map") {
|
||||
ReadAttr(elem, "stiffness", 1, &vis->map.stiffness, text);
|
||||
ReadAttr(elem, "stiffnessrot", 1, &vis->map.stiffnessrot, text);
|
||||
ReadAttr(elem, "force", 1, &vis->map.force, text);
|
||||
ReadAttr(elem, "torque", 1, &vis->map.torque, text);
|
||||
ReadAttr(elem, "alpha", 1, &vis->map.alpha, text);
|
||||
ReadAttr(elem, "fogstart", 1, &vis->map.fogstart, text);
|
||||
ReadAttr(elem, "fogend", 1, &vis->map.fogend, text);
|
||||
ReadAttr(elem, "znear", 1, &vis->map.znear, text);
|
||||
if (vis->map.znear <= 0) {
|
||||
throw mjXError(elem, "znear must be strictly positive");
|
||||
read("stiffness", 1, vis->map.stiffness);
|
||||
read("stiffnessrot", 1, vis->map.stiffnessrot);
|
||||
read("force", 1, vis->map.force);
|
||||
read("torque", 1, vis->map.torque);
|
||||
read("alpha", 1, vis->map.alpha);
|
||||
read("fogstart", 1, vis->map.fogstart);
|
||||
read("fogend", 1, vis->map.fogend);
|
||||
if (read("znear", 1, vis->map.znear)) {
|
||||
if (vis->map.znear <= 0) {
|
||||
throw mjXError(elem, "znear must be strictly positive");
|
||||
}
|
||||
}
|
||||
ReadAttr(elem, "zfar", 1, &vis->map.zfar, text);
|
||||
ReadAttr(elem, "haze", 1, &vis->map.haze, text);
|
||||
ReadAttr(elem, "shadowclip", 1, &vis->map.shadowclip, text);
|
||||
ReadAttr(elem, "shadowscale", 1, &vis->map.shadowscale, text);
|
||||
ReadAttr(elem, "actuatortendon", 1, &vis->map.actuatortendon, text);
|
||||
read("zfar", 1, vis->map.zfar);
|
||||
read("haze", 1, vis->map.haze);
|
||||
read("shadowclip", 1, vis->map.shadowclip);
|
||||
read("shadowscale", 1, vis->map.shadowscale);
|
||||
read("actuatortendon", 1, vis->map.actuatortendon);
|
||||
}
|
||||
|
||||
// scale sub-element
|
||||
else if (name == "scale") {
|
||||
ReadAttr(elem, "forcewidth", 1, &vis->scale.forcewidth, text);
|
||||
ReadAttr(elem, "contactwidth", 1, &vis->scale.contactwidth, text);
|
||||
ReadAttr(elem, "contactheight", 1, &vis->scale.contactheight, text);
|
||||
ReadAttr(elem, "connect", 1, &vis->scale.connect, text);
|
||||
ReadAttr(elem, "com", 1, &vis->scale.com, text);
|
||||
ReadAttr(elem, "camera", 1, &vis->scale.camera, text);
|
||||
ReadAttr(elem, "light", 1, &vis->scale.light, text);
|
||||
ReadAttr(elem, "selectpoint", 1, &vis->scale.selectpoint, text);
|
||||
ReadAttr(elem, "jointlength", 1, &vis->scale.jointlength, text);
|
||||
ReadAttr(elem, "jointwidth", 1, &vis->scale.jointwidth, text);
|
||||
ReadAttr(elem, "actuatorlength", 1, &vis->scale.actuatorlength, text);
|
||||
ReadAttr(elem, "actuatorwidth", 1, &vis->scale.actuatorwidth, text);
|
||||
ReadAttr(elem, "framelength", 1, &vis->scale.framelength, text);
|
||||
ReadAttr(elem, "framewidth", 1, &vis->scale.framewidth, text);
|
||||
ReadAttr(elem, "constraint", 1, &vis->scale.constraint, text);
|
||||
ReadAttr(elem, "slidercrank", 1, &vis->scale.slidercrank, text);
|
||||
ReadAttr(elem, "frustum", 1, &vis->scale.frustum, text);
|
||||
read("forcewidth", 1, vis->scale.forcewidth);
|
||||
read("contactwidth", 1, vis->scale.contactwidth);
|
||||
read("contactheight", 1, vis->scale.contactheight);
|
||||
read("connect", 1, vis->scale.connect);
|
||||
read("com", 1, vis->scale.com);
|
||||
read("camera", 1, vis->scale.camera);
|
||||
read("light", 1, vis->scale.light);
|
||||
read("selectpoint", 1, vis->scale.selectpoint);
|
||||
read("jointlength", 1, vis->scale.jointlength);
|
||||
read("jointwidth", 1, vis->scale.jointwidth);
|
||||
read("actuatorlength", 1, vis->scale.actuatorlength);
|
||||
read("actuatorwidth", 1, vis->scale.actuatorwidth);
|
||||
read("framelength", 1, vis->scale.framelength);
|
||||
read("framewidth", 1, vis->scale.framewidth);
|
||||
read("constraint", 1, vis->scale.constraint);
|
||||
read("slidercrank", 1, vis->scale.slidercrank);
|
||||
read("frustum", 1, vis->scale.frustum);
|
||||
}
|
||||
|
||||
// rgba sub-element
|
||||
else if (name == "rgba") {
|
||||
ReadAttr(elem, "fog", 4, vis->rgba.fog, text);
|
||||
ReadAttr(elem, "haze", 4, vis->rgba.haze, text);
|
||||
ReadAttr(elem, "force", 4, vis->rgba.force, text);
|
||||
ReadAttr(elem, "inertia", 4, vis->rgba.inertia, text);
|
||||
ReadAttr(elem, "joint", 4, vis->rgba.joint, text);
|
||||
ReadAttr(elem, "actuator", 4, vis->rgba.actuator, text);
|
||||
ReadAttr(elem, "actuatornegative", 4, vis->rgba.actuatornegative, text);
|
||||
ReadAttr(elem, "actuatorpositive", 4, vis->rgba.actuatorpositive, text);
|
||||
ReadAttr(elem, "com", 4, vis->rgba.com, text);
|
||||
ReadAttr(elem, "camera", 4, vis->rgba.camera, text);
|
||||
ReadAttr(elem, "light", 4, vis->rgba.light, text);
|
||||
ReadAttr(elem, "selectpoint", 4, vis->rgba.selectpoint, text);
|
||||
ReadAttr(elem, "connect", 4, vis->rgba.connect, text);
|
||||
ReadAttr(elem, "contactpoint", 4, vis->rgba.contactpoint, text);
|
||||
ReadAttr(elem, "contactforce", 4, vis->rgba.contactforce, text);
|
||||
ReadAttr(elem, "contactfriction", 4, vis->rgba.contactfriction, text);
|
||||
ReadAttr(elem, "contacttorque", 4, vis->rgba.contacttorque, text);
|
||||
ReadAttr(elem, "contactgap", 4, vis->rgba.contactgap, text);
|
||||
ReadAttr(elem, "rangefinder", 4, vis->rgba.rangefinder, text);
|
||||
ReadAttr(elem, "constraint", 4, vis->rgba.constraint, text);
|
||||
ReadAttr(elem, "slidercrank", 4, vis->rgba.slidercrank, text);
|
||||
ReadAttr(elem, "crankbroken", 4, vis->rgba.crankbroken, text);
|
||||
ReadAttr(elem, "frustum", 4, vis->rgba.frustum, text);
|
||||
ReadAttr(elem, "bv", 4, vis->rgba.bv, text);
|
||||
ReadAttr(elem, "bvactive", 4, vis->rgba.bvactive, text);
|
||||
read("fog", 4, vis->rgba.fog);
|
||||
read("haze", 4, vis->rgba.haze);
|
||||
read("force", 4, vis->rgba.force);
|
||||
read("inertia", 4, vis->rgba.inertia);
|
||||
read("joint", 4, vis->rgba.joint);
|
||||
read("actuator", 4, vis->rgba.actuator);
|
||||
read("actuatornegative", 4, vis->rgba.actuatornegative);
|
||||
read("actuatorpositive", 4, vis->rgba.actuatorpositive);
|
||||
read("com", 4, vis->rgba.com);
|
||||
read("camera", 4, vis->rgba.camera);
|
||||
read("light", 4, vis->rgba.light);
|
||||
read("selectpoint", 4, vis->rgba.selectpoint);
|
||||
read("connect", 4, vis->rgba.connect);
|
||||
read("contactpoint", 4, vis->rgba.contactpoint);
|
||||
read("contactforce", 4, vis->rgba.contactforce);
|
||||
read("contactfriction", 4, vis->rgba.contactfriction);
|
||||
read("contacttorque", 4, vis->rgba.contacttorque);
|
||||
read("contactgap", 4, vis->rgba.contactgap);
|
||||
read("rangefinder", 4, vis->rgba.rangefinder);
|
||||
read("constraint", 4, vis->rgba.constraint);
|
||||
read("slidercrank", 4, vis->rgba.slidercrank);
|
||||
read("crankbroken", 4, vis->rgba.crankbroken);
|
||||
read("frustum", 4, vis->rgba.frustum);
|
||||
read("bv", 4, vis->rgba.bv);
|
||||
read("bvactive", 4, vis->rgba.bvactive);
|
||||
}
|
||||
|
||||
// advance to next element
|
||||
|
||||
Reference in New Issue
Block a user