Add mjmDef to C API.
PiperOrigin-RevId: 607310534 Change-Id: I530f32c8fd4340dc1006585259a5e05cb4aa62b8
This commit is contained in:
committed by
Copybara-Service
parent
6f958bc404
commit
414a67640a
+43
-29
@@ -48,8 +48,8 @@ MJAPI void mjm_finalize(mjElement object) {
|
||||
|
||||
|
||||
// add child body to body, return child spec
|
||||
mjmBody* mjm_addBody(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmBody* mjm_addBody(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element)->AddBody(def);
|
||||
return &body->spec;
|
||||
}
|
||||
@@ -57,8 +57,8 @@ mjmBody* mjm_addBody(mjmBody* bodyspec, void* defspec) {
|
||||
|
||||
|
||||
// add site to body, return site spec
|
||||
mjmSite* mjm_addSite(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmSite* mjm_addSite(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
|
||||
mjCSite* site = body->AddSite(def);
|
||||
return &site->spec;
|
||||
@@ -67,8 +67,8 @@ mjmSite* mjm_addSite(mjmBody* bodyspec, void* defspec) {
|
||||
|
||||
|
||||
// add joint to body
|
||||
mjmJoint* mjm_addJoint(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmJoint* mjm_addJoint(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
|
||||
mjCJoint* joint = body->AddJoint(def);
|
||||
return &joint->spec;
|
||||
@@ -86,8 +86,8 @@ mjmJoint* mjm_addFreeJoint(mjmBody* bodyspec) {
|
||||
|
||||
|
||||
// add geom to body
|
||||
mjmGeom* mjm_addGeom(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmGeom* mjm_addGeom(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
|
||||
mjCGeom* geom = body->AddGeom(def);
|
||||
return &geom->spec;
|
||||
@@ -96,8 +96,8 @@ mjmGeom* mjm_addGeom(mjmBody* bodyspec, void* defspec) {
|
||||
|
||||
|
||||
// add camera to body
|
||||
mjmCamera* mjm_addCamera(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmCamera* mjm_addCamera(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
|
||||
mjCCamera* camera = body->AddCamera(def);
|
||||
return &camera->spec;
|
||||
@@ -106,8 +106,8 @@ mjmCamera* mjm_addCamera(mjmBody* bodyspec, void* defspec) {
|
||||
|
||||
|
||||
// add light to body
|
||||
mjmLight* mjm_addLight(mjmBody* bodyspec, void* defspec) {
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjmLight* mjm_addLight(mjmBody* bodyspec, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
|
||||
mjCLight* light = body->AddLight(def);
|
||||
return &light->spec;
|
||||
@@ -138,8 +138,8 @@ mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) {
|
||||
|
||||
|
||||
// add mesh to model
|
||||
mjmMesh* mjm_addMesh(void* model, void* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec) : 0;
|
||||
mjmMesh* mjm_addMesh(void* model, mjmDefault* defspec) {
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCMesh* mesh = modelC->AddMesh(def);
|
||||
return &mesh->spec;
|
||||
@@ -175,9 +175,9 @@ mjmTexture* mjm_addTexture(void* model) {
|
||||
|
||||
|
||||
// add material to model
|
||||
mjmMaterial* mjm_addMaterial(void* model, void* defspec) {
|
||||
mjmMaterial* mjm_addMaterial(void* model, mjmDefault* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCMaterial* material = modelC->AddMaterial(def);
|
||||
return &material->spec;
|
||||
}
|
||||
@@ -185,9 +185,9 @@ mjmMaterial* mjm_addMaterial(void* model, void* defspec) {
|
||||
|
||||
|
||||
// add pair to model
|
||||
mjmPair* mjm_addPair(void* model, void* defspec) {
|
||||
mjmPair* mjm_addPair(void* model, mjmDefault* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCPair* pair = modelC->AddPair(def);
|
||||
return &pair->spec;
|
||||
}
|
||||
@@ -204,9 +204,9 @@ mjmExclude* mjm_addExclude(void* model) {
|
||||
|
||||
|
||||
// add equality to model
|
||||
mjmEquality* mjm_addEquality(void* model, void* defspec) {
|
||||
mjmEquality* mjm_addEquality(void* model, mjmDefault* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCEquality* equality = modelC->AddEquality(def);
|
||||
return &equality->spec;
|
||||
}
|
||||
@@ -214,9 +214,9 @@ mjmEquality* mjm_addEquality(void* model, void* defspec) {
|
||||
|
||||
|
||||
// add tendon to model
|
||||
mjmTendon* mjm_addTendon(void* model, void* defspec) {
|
||||
mjmTendon* mjm_addTendon(void* model, mjmDefault* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCTendon* tendon = modelC->AddTendon(def);
|
||||
return &tendon->spec;
|
||||
}
|
||||
@@ -260,9 +260,9 @@ mjmWrap* mjm_wrapPulley(mjmTendon* tendonspec, double divisor) {
|
||||
|
||||
|
||||
// add actuator to model
|
||||
mjmActuator* mjm_addActuator(void* model, void* defspec) {
|
||||
mjmActuator* mjm_addActuator(void* model, mjmDefault* defspec) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = static_cast<mjCDef*>(defspec);
|
||||
mjCDef* def = defspec ? reinterpret_cast<mjCDef*>(defspec->element) : 0;
|
||||
mjCActuator* actuator = modelC->AddActuator(def);
|
||||
return &actuator->spec;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ mjmKey* mjm_addKey(void* model) {
|
||||
|
||||
|
||||
|
||||
// Add plugin to model.
|
||||
// add plugin to model
|
||||
mjElement mjm_addPlugin(void* model) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCPlugin* plugin = modelC->AddPlugin();
|
||||
@@ -323,6 +323,19 @@ mjElement mjm_addPlugin(void* model) {
|
||||
|
||||
|
||||
|
||||
// add default to model
|
||||
mjmDefault* mjm_addDefault(void* model, const char* classname, int parentid) {
|
||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||
mjCDef* def = modelC->AddDef(classname, parentid);
|
||||
if (def) {
|
||||
return &def->spec;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get objects
|
||||
void* mjm_getModel(mjmBody* bodyspec) {
|
||||
return reinterpret_cast<mjCBody*>(bodyspec->element)->model;
|
||||
@@ -331,8 +344,8 @@ void* mjm_getModel(mjmBody* bodyspec) {
|
||||
|
||||
|
||||
// get default
|
||||
void* mjm_getDefault(mjElement element) {
|
||||
return reinterpret_cast<mjCBase*>(element)->def;
|
||||
mjmDefault* mjm_getDefault(mjElement element) {
|
||||
return &(reinterpret_cast<mjCBase*>(element)->def->spec);
|
||||
}
|
||||
|
||||
|
||||
@@ -381,9 +394,10 @@ int mjm_getId(mjElement element) {
|
||||
|
||||
|
||||
// set default
|
||||
void mjm_setDefault(mjElement element, void* defspec) {
|
||||
void mjm_setDefault(mjElement element, mjmDefault* defspec) {
|
||||
mjCBase* baseC = reinterpret_cast<mjCBase*>(element);
|
||||
baseC->def = static_cast<mjCDef*>(defspec);
|
||||
baseC->def = reinterpret_cast<mjCDef*>(defspec->element);
|
||||
baseC->def->PointToLocal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+35
-14
@@ -641,6 +641,24 @@ typedef struct _mjmKey { // keyframe specification
|
||||
} mjmKey;
|
||||
|
||||
|
||||
typedef struct _mjmDefault { // default specification
|
||||
mjString name; // name
|
||||
mjElement element; // internal, do not modify
|
||||
mjmJoint* joint; // joint defaults
|
||||
mjmGeom* geom; // geom defaults
|
||||
mjmSite* site; // site defaults
|
||||
mjmCamera* camera; // camera defaults
|
||||
mjmLight* light; // light defaults
|
||||
mjmFlex* flex; // flex defaults
|
||||
mjmMesh* mesh; // mesh defaults
|
||||
mjmMaterial* material; // material defaults
|
||||
mjmPair* pair; // pair defaults
|
||||
mjmEquality* equality; // equality defaults
|
||||
mjmTendon* tendon; // tendon defaults
|
||||
mjmActuator* actuator; // actuator defaults
|
||||
} mjmDefault;
|
||||
|
||||
|
||||
//---------------------------------- API functions -------------------------------------------------
|
||||
|
||||
// Create model.
|
||||
@@ -653,25 +671,25 @@ MJAPI void mjm_deleteModel(void* modelspec);
|
||||
MJAPI void mjm_finalize(mjElement object);
|
||||
|
||||
// Add child body to body, return child spec.
|
||||
MJAPI mjmBody* mjm_addBody(mjmBody* body, void* defspec);
|
||||
MJAPI mjmBody* mjm_addBody(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add site to body, return site spec.
|
||||
MJAPI mjmSite* mjm_addSite(mjmBody* body, void* defspec);
|
||||
MJAPI mjmSite* mjm_addSite(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add joint to body.
|
||||
MJAPI mjmJoint* mjm_addJoint(mjmBody* body, void* defspec);
|
||||
MJAPI mjmJoint* mjm_addJoint(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add freejoint to body.
|
||||
MJAPI mjmJoint* mjm_addFreeJoint(mjmBody* body);
|
||||
|
||||
// Add geom to body.
|
||||
MJAPI mjmGeom* mjm_addGeom(mjmBody* body, void* defspec);
|
||||
MJAPI mjmGeom* mjm_addGeom(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add camera to body.
|
||||
MJAPI mjmCamera* mjm_addCamera(mjmBody* body, void* defspec);
|
||||
MJAPI mjmCamera* mjm_addCamera(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add light to body.
|
||||
MJAPI mjmLight* mjm_addLight(mjmBody* body, void* defspec);
|
||||
MJAPI mjmLight* mjm_addLight(mjmBody* body, mjmDefault* def);
|
||||
|
||||
// Add frame to body.
|
||||
MJAPI mjmFrame* mjm_addFrame(mjmBody* body, mjmFrame* parentframe);
|
||||
@@ -680,7 +698,7 @@ MJAPI mjmFrame* mjm_addFrame(mjmBody* body, mjmFrame* parentframe);
|
||||
MJAPI mjmFlex* mjm_addFlex(void* model);
|
||||
|
||||
// Add mesh to model.
|
||||
MJAPI mjmMesh* mjm_addMesh(void* model, void* defspec);
|
||||
MJAPI mjmMesh* mjm_addMesh(void* model, mjmDefault* def);
|
||||
|
||||
// Add height field to model.
|
||||
MJAPI mjmHField* mjm_addHField(void* model);
|
||||
@@ -692,19 +710,19 @@ MJAPI mjmSkin* mjm_addSkin(void* model);
|
||||
MJAPI mjmTexture* mjm_addTexture(void* model);
|
||||
|
||||
// Add material to model.
|
||||
MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
|
||||
MJAPI mjmMaterial* mjm_addMaterial(void* model, mjmDefault* def);
|
||||
|
||||
// Add pair to model.
|
||||
MJAPI mjmPair* mjm_addPair(void* model, void* defspec);
|
||||
MJAPI mjmPair* mjm_addPair(void* model, mjmDefault* def);
|
||||
|
||||
// Add excluded body pair to model.
|
||||
MJAPI mjmExclude* mjm_addExclude(void *model);
|
||||
|
||||
// Add equality to model.
|
||||
MJAPI mjmEquality* mjm_addEquality(void* model, void* defspec);
|
||||
MJAPI mjmEquality* mjm_addEquality(void* model, mjmDefault* def);
|
||||
|
||||
// Add tendon to model.
|
||||
MJAPI mjmTendon* mjm_addTendon(void* model, void* defspec);
|
||||
MJAPI mjmTendon* mjm_addTendon(void* model, mjmDefault* def);
|
||||
|
||||
// Wrap site using tendon.
|
||||
MJAPI mjmWrap* mjm_wrapSite(mjmTendon* tendon, const char* name);
|
||||
@@ -719,7 +737,7 @@ MJAPI mjmWrap* mjm_wrapJoint(mjmTendon* tendon, const char* name, double coef);
|
||||
MJAPI mjmWrap* mjm_wrapPulley(mjmTendon* tendon, double divisor);
|
||||
|
||||
// Add actuator to model.
|
||||
MJAPI mjmActuator* mjm_addActuator(void* model, void* defspec);
|
||||
MJAPI mjmActuator* mjm_addActuator(void* model, mjmDefault* def);
|
||||
|
||||
// Add sensor to model.
|
||||
MJAPI mjmSensor* mjm_addSensor(void* model);
|
||||
@@ -739,11 +757,14 @@ MJAPI mjmKey* mjm_addKey(void* model);
|
||||
// Add plugin to model.
|
||||
MJAPI mjElement mjm_addPlugin(void* model);
|
||||
|
||||
// Add default to model.
|
||||
MJAPI mjmDefault* mjm_addDefault(void* model, const char* classname, int parentid);
|
||||
|
||||
// Get model from body.
|
||||
MJAPI void* mjm_getModel(mjmBody* body);
|
||||
|
||||
// Get default corresponding to an mjElement.
|
||||
MJAPI void* mjm_getDefault(mjElement element);
|
||||
MJAPI mjmDefault* mjm_getDefault(mjElement element);
|
||||
|
||||
// Find body in model by name.
|
||||
MJAPI mjmBody* mjm_findBody(void* modelspec, const char* name);
|
||||
@@ -788,7 +809,7 @@ MJAPI const char* mjm_getString(mjString source);
|
||||
MJAPI const double* mjm_getDouble(mjDoubleVec source, int* size);
|
||||
|
||||
// Set default.
|
||||
MJAPI void mjm_setDefault(mjElement element, void* defspec);
|
||||
MJAPI void mjm_setDefault(mjElement element, mjmDefault* def);
|
||||
|
||||
// Set frame.
|
||||
MJAPI void mjm_setFrame(mjElement dest, mjmFrame* frame);
|
||||
|
||||
+77
-70
@@ -116,9 +116,16 @@ bool mjCComposite::AddDefaultJoint(char* error, int error_sz) {
|
||||
return false;
|
||||
} else {
|
||||
mjCDef jnt;
|
||||
jnt.joint.spec.group = 3;
|
||||
jnt.spec.joint->group = 3;
|
||||
defjoint[(mjtCompKind)i].push_back(jnt);
|
||||
}
|
||||
|
||||
// TODO: push_back might invoke a copy constructor, we undo its effect on pointers here
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
for (int j=0; j<defjoint[(mjtCompKind)i].size(); j++) {
|
||||
defjoint[(mjtCompKind)i][j].PointToLocal();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -137,9 +144,9 @@ void mjCComposite::SetDefault(void) {
|
||||
|
||||
// set all deafult groups to 3
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
def[i].geom.spec.group = 3;
|
||||
def[i].site.spec.group = 3;
|
||||
def[i].tendon.spec.group = 3;
|
||||
def[i].spec.geom->group = 3;
|
||||
def[i].spec.site->group = 3;
|
||||
def[i].spec.tendon->group = 3;
|
||||
}
|
||||
|
||||
// set default joint
|
||||
@@ -153,8 +160,8 @@ void mjCComposite::SetDefault(void) {
|
||||
type==mjCOMPTYPE_CABLE ||
|
||||
(type==mjCOMPTYPE_GRID && tmpdim==1)) {
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
def[i].geom.spec.group = 0;
|
||||
def[i].tendon.spec.group = 0;
|
||||
def[i].spec.geom->group = 0;
|
||||
def[i].spec.tendon->group = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,15 +170,15 @@ void mjCComposite::SetDefault(void) {
|
||||
case mjCOMPTYPE_PARTICLE: // particle
|
||||
|
||||
// no friction with anything
|
||||
def[0].geom.spec.condim = 1;
|
||||
def[0].geom.spec.priority = 1;
|
||||
def[0].spec.geom->condim = 1;
|
||||
def[0].spec.geom->priority = 1;
|
||||
break;
|
||||
|
||||
case mjCOMPTYPE_GRID: // grid
|
||||
|
||||
// hard main tendon fix
|
||||
AdjustSoft(def[mjCOMPKIND_TENDON].equality.spec.solref,
|
||||
def[mjCOMPKIND_TENDON].equality.spec.solimp, 0);
|
||||
AdjustSoft(def[mjCOMPKIND_TENDON].spec.equality->solref,
|
||||
def[mjCOMPKIND_TENDON].spec.equality->solimp, 0);
|
||||
|
||||
break;
|
||||
|
||||
@@ -193,19 +200,19 @@ void mjCComposite::SetDefault(void) {
|
||||
case mjCOMPTYPE_ELLIPSOID:
|
||||
|
||||
// no self-collisions
|
||||
def[0].geom.spec.contype = 0;
|
||||
def[0].spec.geom->contype = 0;
|
||||
|
||||
// soft smoothing
|
||||
AdjustSoft(solrefsmooth, solimpsmooth, 1);
|
||||
|
||||
// soft fix everywhere
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
AdjustSoft(def[i].equality.spec.solref, def[i].equality.spec.solimp, 1);
|
||||
AdjustSoft(def[i].spec.equality->solref, def[i].spec.equality->solimp, 1);
|
||||
}
|
||||
|
||||
// hard main tendon fix
|
||||
AdjustSoft(def[mjCOMPKIND_TENDON].equality.spec.solref,
|
||||
def[mjCOMPKIND_TENDON].equality.spec.solimp, 0);
|
||||
AdjustSoft(def[mjCOMPKIND_TENDON].spec.equality->solref,
|
||||
def[mjCOMPKIND_TENDON].spec.equality->solimp, 0);
|
||||
break;
|
||||
default:
|
||||
// SHOULD NOT OCCUR
|
||||
@@ -219,9 +226,9 @@ void mjCComposite::SetDefault(void) {
|
||||
// make composite object
|
||||
bool mjCComposite::Make(mjCModel* model, mjmBody* body, char* error, int error_sz) {
|
||||
// check geom type
|
||||
if ((def[0].geom.spec.type!=mjGEOM_SPHERE &&
|
||||
def[0].geom.spec.type!=mjGEOM_CAPSULE &&
|
||||
def[0].geom.spec.type!=mjGEOM_ELLIPSOID) &&
|
||||
if ((def[0].spec.geom->type!=mjGEOM_SPHERE &&
|
||||
def[0].spec.geom->type!=mjGEOM_CAPSULE &&
|
||||
def[0].spec.geom->type!=mjGEOM_ELLIPSOID) &&
|
||||
type!=mjCOMPTYPE_PARTICLE && type!=mjCOMPTYPE_CABLE) {
|
||||
return comperr(error, "Composite geom type must be sphere, capsule or ellipsoid", error_sz);
|
||||
}
|
||||
@@ -240,8 +247,8 @@ bool mjCComposite::Make(mjCModel* model, mjmBody* body, char* error, int error_s
|
||||
|
||||
// check spacing
|
||||
if (type==mjCOMPTYPE_GRID || (type==mjCOMPTYPE_PARTICLE && uservert.empty())) {
|
||||
if (spacing < mju_max(def[0].geom.spec.size[0],
|
||||
mju_max(def[0].geom.spec.size[1], def[0].geom.spec.size[2]))) {
|
||||
if (spacing < mju_max(def[0].spec.geom->size[0],
|
||||
mju_max(def[0].spec.geom->size[1], def[0].spec.geom->size[2]))) {
|
||||
return comperr(error, "Spacing must be larger than geometry size",
|
||||
error_sz);
|
||||
}
|
||||
@@ -342,8 +349,8 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int
|
||||
|
||||
// populate vertices and names
|
||||
if (uservert.empty()) {
|
||||
if (spacing < mju_max(def[0].geom.spec.size[0],
|
||||
mju_max(def[0].geom.spec.size[1], def[0].geom.spec.size[2])))
|
||||
if (spacing < mju_max(def[0].spec.geom->size[0],
|
||||
mju_max(def[0].spec.geom->size[1], def[0].spec.geom->size[2])))
|
||||
return comperr(error, "Spacing must be larger than geometry size", error_sz);
|
||||
|
||||
for (int ix=0; ix<count[0]; ix++) {
|
||||
@@ -466,7 +473,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int
|
||||
// add slider joints if none defined
|
||||
if (!add[mjCOMPKIND_PARTICLE]) {
|
||||
for (int i=0; i<3; i++) {
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
jnt->type = mjJNT_SLIDE;
|
||||
mjuu_setvec(jnt->pos, 0, 0, 0);
|
||||
@@ -478,17 +485,17 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int
|
||||
// add user-specified joints
|
||||
else {
|
||||
for (auto defjnt : defjoint[mjCOMPKIND_PARTICLE]) {
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjnt);
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjnt.spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
}
|
||||
}
|
||||
|
||||
// add geom
|
||||
mjmGeom* g = mjm_addGeom(b, def);
|
||||
mjmGeom* g = mjm_addGeom(b, &def[0].spec);
|
||||
mjm_setDefault(g->element, mjm_getDefault(body->element));
|
||||
|
||||
// add site
|
||||
mjmSite* s = mjm_addSite(b, def);
|
||||
mjmSite* s = mjm_addSite(b, &def[0].spec);
|
||||
mjm_setDefault(s->element, mjm_getDefault(body->element));
|
||||
s->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sS%d", prefix.c_str(), i);
|
||||
@@ -544,16 +551,16 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int
|
||||
mju::sprintf_arr(txt2, "%sS%d", prefix.c_str(), v1);
|
||||
|
||||
// create tendon
|
||||
mjmTendon* ten = mjm_addTendon(model, def + mjCOMPKIND_TENDON);
|
||||
mjm_setDefault(ten->element, model->defaults[0]);
|
||||
mjmTendon* ten = mjm_addTendon(model, &def[mjCOMPKIND_TENDON].spec);
|
||||
mjm_setDefault(ten->element, &model->defaults[0]->spec);
|
||||
mjm_setString(ten->name, txt0);
|
||||
ten->group = 4;
|
||||
mjm_wrapSite(ten, txt1);
|
||||
mjm_wrapSite(ten, txt2);
|
||||
|
||||
// add equality constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_TENDON);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_TENDON].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_TENDON;
|
||||
mjm_setString(eq->name1, mjm_getString(ten->name));
|
||||
}
|
||||
@@ -609,14 +616,14 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err
|
||||
b->pos[2] = offset[2];
|
||||
|
||||
// add geom
|
||||
mjmGeom* g = mjm_addGeom(b, def);
|
||||
mjmGeom* g = mjm_addGeom(b, &def[0].spec);
|
||||
mjm_setDefault(g->element, mjm_getDefault(body->element));
|
||||
g->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sG%d_%d", prefix.c_str(), ix, iy);
|
||||
mjm_setString(g->name, txt);
|
||||
|
||||
// add site
|
||||
mjmSite* s = mjm_addSite(b, def);
|
||||
mjmSite* s = mjm_addSite(b, &def[0].spec);
|
||||
mjm_setDefault(s->element, mjm_getDefault(body->element));
|
||||
s->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sS%d_%d", prefix.c_str(), ix, iy);
|
||||
@@ -637,7 +644,7 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err
|
||||
// add slider joint
|
||||
mjmJoint* jnt[3];
|
||||
for (int i=0; i<3; i++) {
|
||||
jnt[i] = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0]);
|
||||
jnt[i] = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjm_setDefault(jnt[i]->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), i, ix, iy);
|
||||
mjm_setString(jnt[i]->name, txt);
|
||||
@@ -666,8 +673,8 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err
|
||||
ten->WrapSite(txt2);
|
||||
|
||||
// add equality constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_TENDON);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_TENDON].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_TENDON;
|
||||
mjm_setString(eq->name1, ten->name.c_str());
|
||||
}
|
||||
@@ -700,9 +707,9 @@ bool mjCComposite::MakeCable(mjCModel* model, mjmBody* body, char* error, int er
|
||||
}
|
||||
|
||||
// check geom type
|
||||
if (def[0].geom.spec.type!=mjGEOM_CYLINDER &&
|
||||
def[0].geom.spec.type!=mjGEOM_CAPSULE &&
|
||||
def[0].geom.spec.type!=mjGEOM_BOX) {
|
||||
if (def[0].spec.geom->type!=mjGEOM_CYLINDER &&
|
||||
def[0].spec.geom->type!=mjGEOM_CAPSULE &&
|
||||
def[0].spec.geom->type!=mjGEOM_BOX) {
|
||||
return comperr(error, "Cable geom type must be sphere, capsule or box", error_sz);
|
||||
}
|
||||
|
||||
@@ -748,14 +755,14 @@ bool mjCComposite::MakeCable(mjCModel* model, mjmBody* body, char* error, int er
|
||||
}
|
||||
|
||||
// add skin
|
||||
if (def[0].geom.spec.type==mjGEOM_BOX) {
|
||||
if (def[0].spec.geom->type==mjGEOM_BOX) {
|
||||
if (skinsubgrid>0) {
|
||||
count[1]+=2;
|
||||
MakeSkin2Subgrid(model, 2*def[0].geom.spec.size[2]);
|
||||
MakeSkin2Subgrid(model, 2*def[0].spec.geom->size[2]);
|
||||
count[1]-=2;
|
||||
} else {
|
||||
count[1]++;
|
||||
MakeSkin2(model, 2*def[0].geom.spec.size[2]);
|
||||
MakeSkin2(model, 2*def[0].spec.geom->size[2]);
|
||||
count[1]--;
|
||||
}
|
||||
}
|
||||
@@ -835,14 +842,14 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN
|
||||
}
|
||||
|
||||
// add geom
|
||||
mjmGeom* geom = mjm_addGeom(body, def);
|
||||
mjmGeom* geom = mjm_addGeom(body, &def[0].spec);
|
||||
mjm_setDefault(geom->element, mjm_getDefault(body->element));
|
||||
mjm_setString(geom->name, txt_geom);
|
||||
if (def[0].geom.spec.type==mjGEOM_CYLINDER ||
|
||||
def[0].geom.spec.type==mjGEOM_CAPSULE) {
|
||||
if (def[0].spec.geom->type==mjGEOM_CYLINDER ||
|
||||
def[0].spec.geom->type==mjGEOM_CAPSULE) {
|
||||
mjuu_zerovec(geom->fromto, 6);
|
||||
geom->fromto[3] = length;
|
||||
} else if (def[0].geom.spec.type==mjGEOM_BOX) {
|
||||
} else if (def[0].spec.geom->type==mjGEOM_BOX) {
|
||||
mjuu_zerovec(geom->pos, 3);
|
||||
geom->pos[0] = length/2;
|
||||
geom->size[0] = length/2;
|
||||
@@ -862,7 +869,7 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN
|
||||
|
||||
// add curvature joint
|
||||
if (!first || strcmp(initial.c_str(), "none")) {
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
jnt->type = (first && strcmp(initial.c_str(), "free")==0) ? mjJNT_FREE : mjJNT_BALL;
|
||||
jnt->damping = jnt->type==mjJNT_FREE ? 0 : jnt->damping;
|
||||
@@ -880,7 +887,7 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN
|
||||
|
||||
// add site at the boundary
|
||||
if (last || first) {
|
||||
mjmSite* site = mjm_addSite(body, def);
|
||||
mjmSite* site = mjm_addSite(body, &def[0].spec);
|
||||
mjm_setDefault(site->element, mjm_getDefault(body->element));
|
||||
mjm_setString(site->name, txt_site);
|
||||
mjuu_setvec(site->pos, last ? length : 0, 0, 0);
|
||||
@@ -991,7 +998,7 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
}
|
||||
|
||||
// add geom
|
||||
mjmGeom* geom = mjm_addGeom(body, def);
|
||||
mjmGeom* geom = mjm_addGeom(body, &def[0].spec);
|
||||
mjm_setDefault(geom->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sG%d", prefix.c_str(), ix1);
|
||||
mjm_setString(geom->name, txt);
|
||||
@@ -1006,7 +1013,7 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
// add main joint
|
||||
for (int i=0; i<2; i++) {
|
||||
// add joint
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJ%d_%d", prefix.c_str(), i, ix1);
|
||||
mjm_setString(jnt->name, txt);
|
||||
@@ -1019,7 +1026,7 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
// add twist joint
|
||||
if (add[mjCOMPKIND_TWIST]) {
|
||||
// add joint
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_TWIST][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_TWIST][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJT%d", prefix.c_str(), ix1);
|
||||
mjm_setString(jnt->name, txt);
|
||||
@@ -1028,8 +1035,8 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
mjuu_setvec(jnt->axis, 1, 0, 0);
|
||||
|
||||
// add constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_TWIST);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_TWIST].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_JOINT;
|
||||
mjm_setString(eq->name1, mjm_getString(jnt->name));
|
||||
}
|
||||
@@ -1037,7 +1044,7 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
// add stretch joint
|
||||
if (add[mjCOMPKIND_STRETCH]) {
|
||||
// add joint
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_STRETCH][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_STRETCH][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJS%d", prefix.c_str(), ix1);
|
||||
mjm_setString(jnt->name, txt);
|
||||
@@ -1046,8 +1053,8 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i
|
||||
mjuu_setvec(jnt->axis, 1, 0, 0);
|
||||
|
||||
// add constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_STRETCH);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_STRETCH].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_JOINT;
|
||||
mjm_setString(eq->name1, mjm_getString(jnt->name));
|
||||
}
|
||||
@@ -1103,7 +1110,7 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro
|
||||
}
|
||||
|
||||
// center geom: two times bigger
|
||||
mjmGeom* geom = mjm_addGeom(body, def);
|
||||
mjmGeom* geom = mjm_addGeom(body, &def[0].spec);
|
||||
mjm_setDefault(geom->element, mjm_getDefault(body->element));
|
||||
geom->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sGcenter", prefix.c_str());
|
||||
@@ -1144,7 +1151,7 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro
|
||||
mjuu_normvec(b->alt.zaxis, 3);
|
||||
|
||||
// add geom
|
||||
mjmGeom* g = mjm_addGeom(b, def);
|
||||
mjmGeom* g = mjm_addGeom(b, &def[0].spec);
|
||||
mjm_setDefault(g->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sG%d_%d_%d", prefix.c_str(), ix, iy, iz);
|
||||
mjm_setString(g->name, txt);
|
||||
@@ -1158,7 +1165,7 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro
|
||||
}
|
||||
|
||||
// add slider joint
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0]);
|
||||
mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjm_setDefault(jnt->element, mjm_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), ix, iy, iz);
|
||||
mjm_setString(jnt->name, txt);
|
||||
@@ -1167,8 +1174,8 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro
|
||||
mjuu_setvec(jnt->axis, 0, 0, 1);
|
||||
|
||||
// add fix constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_JOINT);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_JOINT].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_JOINT;
|
||||
mjm_setString(eq->name1, mjm_getString(jnt->name));
|
||||
|
||||
@@ -1201,8 +1208,8 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro
|
||||
}
|
||||
|
||||
// finalize fixed tendon
|
||||
mjmEquality* eqt = mjm_addEquality(model, def + mjCOMPKIND_TENDON);
|
||||
mjm_setDefault(eqt->element, model->defaults[0]);
|
||||
mjmEquality* eqt = mjm_addEquality(model, &def[mjCOMPKIND_TENDON].spec);
|
||||
mjm_setDefault(eqt->element, &model->defaults[0]->spec);
|
||||
eqt->type = mjEQ_TENDON;
|
||||
mjm_setString(eqt->name1, ten->name.c_str());
|
||||
|
||||
@@ -1237,8 +1244,8 @@ void mjCComposite::MakeShear(mjCModel* model) {
|
||||
ten->name = txt;
|
||||
|
||||
// equality constraint
|
||||
mjmEquality* eq = mjm_addEquality(model, def + mjCOMPKIND_SHEAR);
|
||||
mjm_setDefault(eq->element, model->defaults[0]);
|
||||
mjmEquality* eq = mjm_addEquality(model, &def[mjCOMPKIND_SHEAR].spec);
|
||||
mjm_setDefault(eq->element, &model->defaults[0]->spec);
|
||||
eq->type = mjEQ_TENDON;
|
||||
mjm_setString(eq->name1, txt);
|
||||
}
|
||||
@@ -1495,15 +1502,15 @@ void mjCComposite::MakeCableBones(mjCModel* model, mjmSkin* skin) {
|
||||
// bind pose
|
||||
if (iy==0) {
|
||||
mjm_appendString(skin->bodyname, this_body);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].geom.spec.size[0] : 0);
|
||||
bindpos.push_back(-def[0].geom.spec.size[1]);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0);
|
||||
bindpos.push_back(-def[0].spec.geom->size[1]);
|
||||
bindpos.push_back(0);
|
||||
bindquat.push_back(1); bindquat.push_back(0);
|
||||
bindquat.push_back(0); bindquat.push_back(0);
|
||||
} else {
|
||||
mjm_appendString(skin->bodyname, this_body);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].geom.spec.size[0] : 0);
|
||||
bindpos.push_back(def[0].geom.spec.size[1]);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0);
|
||||
bindpos.push_back(def[0].spec.geom->size[1]);
|
||||
bindpos.push_back(0);
|
||||
bindquat.push_back(1); bindquat.push_back(0);
|
||||
bindquat.push_back(0); bindquat.push_back(0);
|
||||
@@ -1535,15 +1542,15 @@ void mjCComposite::MakeCableBonesSubgrid(mjCModel* model, mjmSkin* skin) {
|
||||
|
||||
// bind pose
|
||||
if (iy==0) {
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].geom.spec.size[0] : 0);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0);
|
||||
bindpos.push_back(-def[0].geom.spec.size[1]);
|
||||
bindpos.push_back(0);
|
||||
} else if (iy==2) {
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].geom.spec.size[0] : 0);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0);
|
||||
bindpos.push_back(def[0].geom.spec.size[1]);
|
||||
bindpos.push_back(0);
|
||||
} else {
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].geom.spec.size[0] : 0);
|
||||
bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0);
|
||||
bindpos.push_back(0);
|
||||
bindpos.push_back(0);
|
||||
}
|
||||
|
||||
+12
-13
@@ -78,8 +78,7 @@ mjCFlexcomp::mjCFlexcomp(void) {
|
||||
|
||||
// make flexcomp object
|
||||
bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz) {
|
||||
def.flex.CopyFromSpec();
|
||||
|
||||
mjmFlex* dflex = def.spec.flex;
|
||||
bool radial = (type==mjFCOMPTYPE_BOX ||
|
||||
type==mjFCOMPTYPE_CYLINDER ||
|
||||
type==mjFCOMPTYPE_ELLIPSOID);
|
||||
@@ -100,7 +99,7 @@ bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz
|
||||
}
|
||||
|
||||
// check spacing
|
||||
double minspace = 2*def.flex.spec.radius + def.flex.spec.margin;
|
||||
double minspace = 2*dflex->radius + dflex->margin;
|
||||
if (!direct) {
|
||||
if (spacing[0]<minspace ||
|
||||
spacing[1]<minspace ||
|
||||
@@ -158,7 +157,7 @@ bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz
|
||||
}
|
||||
|
||||
// get dim and check
|
||||
int dim = def.flex.spec.dim;
|
||||
int dim = dflex->dim;
|
||||
if (dim<1 || dim>3) {
|
||||
return comperr(error, "Invalid dim, must be between 1 and 3", error_sz);
|
||||
}
|
||||
@@ -166,7 +165,7 @@ bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz
|
||||
// force flatskin shading for box, cylinder and 3D grid
|
||||
if (type==mjFCOMPTYPE_BOX || type==mjFCOMPTYPE_CYLINDER ||
|
||||
(type==mjFCOMPTYPE_GRID && dim==3)) {
|
||||
def.flex.spec.flatskin = true;
|
||||
dflex->flatskin = true;
|
||||
}
|
||||
|
||||
// check pin sizes
|
||||
@@ -485,8 +484,8 @@ bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz
|
||||
|
||||
// create edge equality constraint
|
||||
if (equality) {
|
||||
mjmEquality* pe = mjm_addEquality(model, &def);
|
||||
mjm_setDefault(pe->element, model->defaults[0]);
|
||||
mjmEquality* pe = mjm_addEquality(model, &def.spec);
|
||||
mjm_setDefault(pe->element, &model->defaults[0]->spec);
|
||||
pe->type = mjEQ_FLEX;
|
||||
pe->active = true;
|
||||
mjm_setString(pe->name1, name.c_str());
|
||||
@@ -690,7 +689,7 @@ bool mjCFlexcomp::MakeBox(char* error, int error_sz) {
|
||||
double pos[3];
|
||||
|
||||
// set 3D
|
||||
def.flex.spec.dim = 3;
|
||||
def.spec.flex->dim = 3;
|
||||
|
||||
// add center point
|
||||
point.push_back(0);
|
||||
@@ -822,7 +821,7 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
|
||||
}
|
||||
|
||||
// check dim
|
||||
if (def.flex.spec.dim!=2) {
|
||||
if (def.spec.flex->dim!=2) {
|
||||
return comperr(error, "Flex dim must be 2 in for mesh", error_sz);
|
||||
}
|
||||
|
||||
@@ -1034,7 +1033,7 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) {
|
||||
if (entityDim<1 || entityDim>3) {
|
||||
throw mjCError(NULL, "Entity must be 1D, 2D or 3D");
|
||||
}
|
||||
def.flex.spec.dim = entityDim;
|
||||
def.spec.flex->dim = entityDim;
|
||||
|
||||
// read and discard node tags; require range from minNodeTag to maxNodeTag
|
||||
for (size_t i=0; i<numNodes; i++) {
|
||||
@@ -1086,7 +1085,7 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) {
|
||||
if (entityDim<1 || entityDim>3) {
|
||||
throw mjCError(NULL, "Entity must be 1D, 2D or 3D");
|
||||
}
|
||||
def.flex.spec.dim = entityDim;
|
||||
def.spec.flex->dim = entityDim;
|
||||
|
||||
// check section byte size
|
||||
if (nodeend-nodebegin < 52+numNodes*4*8) {
|
||||
@@ -1134,7 +1133,7 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) {
|
||||
}
|
||||
|
||||
// dimensionality must be same as nodes
|
||||
if (entityDim!=def.flex.spec.dim) {
|
||||
if (entityDim!=def.spec.flex->dim) {
|
||||
throw mjCError(NULL, "Inconsistent dimensionality in Elements");
|
||||
}
|
||||
|
||||
@@ -1183,7 +1182,7 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) {
|
||||
}
|
||||
|
||||
// dimensionality must be same as nodes
|
||||
if (entityDim!=def.flex.spec.dim) {
|
||||
if (entityDim!=def.spec.flex->dim) {
|
||||
throw mjCError(NULL, "Inconsistent dimensionality in Elements");
|
||||
}
|
||||
|
||||
|
||||
+44
-13
@@ -471,6 +471,19 @@ mjCDef::mjCDef(void) {
|
||||
name.clear();
|
||||
parentid = -1;
|
||||
childid.clear();
|
||||
mjm_defaultJoint(joint.spec);
|
||||
mjm_defaultGeom(geom.spec);
|
||||
mjm_defaultSite(site.spec);
|
||||
mjm_defaultCamera(camera.spec);
|
||||
mjm_defaultLight(light.spec);
|
||||
mjm_defaultFlex(flex.spec);
|
||||
mjm_defaultMesh(mesh.spec);
|
||||
mjm_defaultMaterial(material.spec);
|
||||
mjm_defaultPair(pair.spec);
|
||||
mjm_defaultEquality(equality.spec);
|
||||
mjm_defaultTendon(tendon.spec);
|
||||
mjm_defaultActuator(actuator.spec);
|
||||
PointToLocal();
|
||||
}
|
||||
|
||||
|
||||
@@ -494,6 +507,28 @@ void mjCDef::PointToLocal() {
|
||||
geom.PointToLocal();
|
||||
site.PointToLocal();
|
||||
camera.PointToLocal();
|
||||
light.PointToLocal();
|
||||
flex.PointToLocal();
|
||||
mesh.PointToLocal();
|
||||
material.PointToLocal();
|
||||
pair.PointToLocal();
|
||||
equality.PointToLocal();
|
||||
tendon.PointToLocal();
|
||||
actuator.PointToLocal();
|
||||
spec.element = (mjElement)this;
|
||||
spec.name = (mjString)&name;
|
||||
spec.joint = &joint.spec;
|
||||
spec.geom = &geom.spec;
|
||||
spec.site = &site.spec;
|
||||
spec.camera = &camera.spec;
|
||||
spec.light = &light.spec;
|
||||
spec.flex = &flex.spec;
|
||||
spec.mesh = &mesh.spec;
|
||||
spec.material = &material.spec;
|
||||
spec.pair = &pair.spec;
|
||||
spec.equality = &equality.spec;
|
||||
spec.tendon = &tendon.spec;
|
||||
spec.actuator = &actuator.spec;
|
||||
}
|
||||
|
||||
|
||||
@@ -1248,7 +1283,6 @@ mjCJoint::mjCJoint(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->joint.CopyFromSpec();
|
||||
*this = _def->joint;
|
||||
}
|
||||
|
||||
@@ -1442,7 +1476,6 @@ mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->geom.CopyFromSpec();
|
||||
*this = _def->geom;
|
||||
}
|
||||
|
||||
@@ -2043,7 +2076,6 @@ mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->site.CopyFromSpec();
|
||||
*this = _def->site;
|
||||
}
|
||||
|
||||
@@ -2185,7 +2217,6 @@ mjCCamera::mjCCamera(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->camera.CopyFromSpec();
|
||||
*this = _def->camera;
|
||||
}
|
||||
|
||||
@@ -2322,7 +2353,6 @@ mjCLight::mjCLight(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->light.CopyFromSpec();
|
||||
*this = _def->light;
|
||||
}
|
||||
|
||||
@@ -2330,14 +2360,18 @@ mjCLight::mjCLight(mjCModel* _model, mjCDef* _def) {
|
||||
model = _model;
|
||||
def = (_def ? _def : (_model ? _model->defaults[0] : 0));
|
||||
|
||||
// point to local
|
||||
PointToLocal();
|
||||
CopyFromSpec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mjCLight::PointToLocal() {
|
||||
spec.element = (mjElement)this;
|
||||
spec.name = (mjString)&name;
|
||||
spec.classname = (mjString)&classname;
|
||||
spec.targetbody = (mjString)&spec_targetbody_;
|
||||
spec.info = (mjString)&info;
|
||||
|
||||
CopyFromSpec();
|
||||
}
|
||||
|
||||
|
||||
@@ -3350,7 +3384,6 @@ mjCMaterial::mjCMaterial(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->material.CopyFromSpec();
|
||||
*this = _def->material;
|
||||
}
|
||||
|
||||
@@ -3409,7 +3442,6 @@ mjCPair::mjCPair(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->pair.CopyFromSpec();
|
||||
*this = _def->pair;
|
||||
}
|
||||
|
||||
@@ -3669,7 +3701,6 @@ mjCEquality::mjCEquality(mjCModel* _model, mjCDef* _def) {
|
||||
|
||||
// reset to default if given
|
||||
if (_def) {
|
||||
_def->equality.CopyFromSpec();
|
||||
*this = _def->equality;
|
||||
}
|
||||
|
||||
@@ -4185,7 +4216,7 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) {
|
||||
CopyFromSpec();
|
||||
|
||||
// point to local (needs to be after defaults)
|
||||
MakePointerLocal();
|
||||
PointToLocal();
|
||||
}
|
||||
|
||||
|
||||
@@ -4196,7 +4227,7 @@ bool mjCActuator::is_actlimited() const { return islimited(actlimited, actrange)
|
||||
|
||||
|
||||
|
||||
void mjCActuator::MakePointerLocal() {
|
||||
void mjCActuator::PointToLocal() {
|
||||
spec.element = (mjElement)this;
|
||||
spec.name = (mjString)&name;
|
||||
spec.classname = (mjString)&classname;
|
||||
|
||||
@@ -534,6 +534,7 @@ class mjCLight : public mjCBase, private mjmLight {
|
||||
mjCLight(mjCModel* = 0, mjCDef* = 0); // constructor
|
||||
void Compile(void); // compiler
|
||||
void CopyFromSpec(void);
|
||||
void PointToLocal(void);
|
||||
|
||||
mjCBody* body; // light's body
|
||||
int targetbodyid; // id of target body; -1: none
|
||||
@@ -1203,7 +1204,7 @@ class mjCActuator : public mjCBase, private mjmActuator {
|
||||
mjCActuator(mjCModel* = 0, mjCDef* = 0); // constructor
|
||||
void Compile(void); // compiler
|
||||
void CopyFromSpec();
|
||||
void MakePointerLocal();
|
||||
void PointToLocal();
|
||||
|
||||
int trnid[2]; // id of transmission target
|
||||
|
||||
@@ -1385,6 +1386,8 @@ class mjCKey : public mjCBase, private mjmKey {
|
||||
// Describes one set of defaults
|
||||
|
||||
class mjCDef {
|
||||
friend class mjXWriter;
|
||||
|
||||
public:
|
||||
mjCDef(void); // constructor
|
||||
void Compile(const mjCModel* model); // compiler
|
||||
@@ -1395,7 +1398,9 @@ class mjCDef {
|
||||
int parentid; // id of parent class
|
||||
std::vector<int> childid; // ids of child classes
|
||||
|
||||
// default objects
|
||||
mjmDefault spec;
|
||||
|
||||
// default objects (TODO: they should become private)
|
||||
mjCJoint joint;
|
||||
mjCGeom geom;
|
||||
mjCSite site;
|
||||
|
||||
+127
-119
@@ -1665,7 +1665,7 @@ void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) {
|
||||
|
||||
|
||||
// site element parser
|
||||
void mjXReader::OneSite(XMLElement* elem, mjmSite& site) {
|
||||
void mjXReader::OneSite(XMLElement* elem, mjmSite* site) {
|
||||
int n;
|
||||
string text, name, classname;
|
||||
std::vector<double> userdata;
|
||||
@@ -1673,30 +1673,30 @@ void mjXReader::OneSite(XMLElement* elem, mjmSite& site) {
|
||||
|
||||
// read attributes
|
||||
if (ReadAttrTxt(elem, "name", name)) {
|
||||
mjm_setString(site.name, name.c_str());
|
||||
mjm_setString(site->name, name.c_str());
|
||||
}
|
||||
if (ReadAttrTxt(elem, "class", classname)) {
|
||||
mjm_setString(site.classname, classname.c_str());
|
||||
mjm_setString(site->classname, classname.c_str());
|
||||
}
|
||||
if (MapValue(elem, "type", &n, geom_map, mjNGEOMTYPES)) {
|
||||
site.type = (mjtGeom)n;
|
||||
site->type = (mjtGeom)n;
|
||||
}
|
||||
ReadAttr(elem, "size", 3, site.size, text, false, false);
|
||||
ReadAttrInt(elem, "group", &site.group);
|
||||
ReadAttr(elem, "pos", 3, site.pos, text);
|
||||
ReadQuat(elem, "quat", site.quat, text);
|
||||
ReadAttr(elem, "size", 3, site->size, text, false, false);
|
||||
ReadAttrInt(elem, "group", &site->group);
|
||||
ReadAttr(elem, "pos", 3, site->pos, text);
|
||||
ReadQuat(elem, "quat", site->quat, text);
|
||||
if (ReadAttrTxt(elem, "material", material)) {
|
||||
mjm_setString(site.material, material.c_str());
|
||||
mjm_setString(site->material, material.c_str());
|
||||
}
|
||||
ReadAttr(elem, "rgba", 4, site.rgba, text);
|
||||
ReadAttr(elem, "fromto", 6, site.fromto, text);
|
||||
ReadAlternative(elem, site.alt);
|
||||
ReadAttr(elem, "rgba", 4, site->rgba, text);
|
||||
ReadAttr(elem, "fromto", 6, site->fromto, text);
|
||||
ReadAlternative(elem, site->alt);
|
||||
if (ReadVector(elem, "user", userdata, text)) {
|
||||
mjm_setDouble(site.userdata, userdata.data(), userdata.size());
|
||||
mjm_setDouble(site->userdata, userdata.data(), userdata.size());
|
||||
}
|
||||
|
||||
// write error info
|
||||
mjm_setString(site.info,
|
||||
mjm_setString(site->info,
|
||||
std::string("line = " + std::to_string(elem->GetLineNum()) + ", column = -1").c_str());
|
||||
}
|
||||
|
||||
@@ -2240,7 +2240,7 @@ void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) {
|
||||
|
||||
|
||||
// make composite
|
||||
void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjCDef* def) {
|
||||
void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) {
|
||||
string text;
|
||||
int n;
|
||||
|
||||
@@ -2326,7 +2326,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjCDef* def) {
|
||||
XMLElement* egeom = FirstChildElement(elem, "geom");
|
||||
if (egeom) {
|
||||
std::string material;
|
||||
mjmGeom& dgeom = comp.def[0].geom.spec;
|
||||
mjmGeom& dgeom = *comp.def[0].spec.geom;
|
||||
if (MapValue(egeom, "type", &n, geom_map, mjNGEOMTYPES)) {
|
||||
dgeom.type = (mjtGeom)n;
|
||||
}
|
||||
@@ -2354,7 +2354,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjCDef* def) {
|
||||
XMLElement* esite = FirstChildElement(elem, "site");
|
||||
if (esite) {
|
||||
std::string material;
|
||||
mjmSite& dsite = comp.def[0].site.spec;
|
||||
mjmSite& dsite = *comp.def[0].spec.site;
|
||||
ReadAttr(esite, "size", 3, dsite.size, text, false, false);
|
||||
ReadAttrInt(esite, "group", &dsite.group);
|
||||
ReadAttrTxt(esite, "material", material);
|
||||
@@ -2379,33 +2379,35 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjCDef* def) {
|
||||
comp.add[kind] = true;
|
||||
|
||||
// get element
|
||||
mjCDef *el = &comp.defjoint[(mjtCompKind)kind].back();
|
||||
mjmDefault* dspec = &comp.defjoint[(mjtCompKind)kind].back().spec;
|
||||
mjmJoint& djoint = *dspec->joint;
|
||||
mjmEquality& dequality = *dspec->equality;
|
||||
|
||||
// particle joint
|
||||
if (MapValue(ejnt, "type", &n, joint_map, joint_sz)) {
|
||||
el->joint.spec.type = (mjtJoint)n;
|
||||
djoint.type = (mjtJoint)n;
|
||||
}
|
||||
ReadAttr(ejnt, "axis", 3, el->joint.spec.axis, text);
|
||||
ReadAttr(ejnt, "axis", 3, djoint.axis, text);
|
||||
|
||||
// solreffix, solimpfix
|
||||
ReadAttr(ejnt, "solreffix", mjNREF, el->equality.spec.solref, text, false, false);
|
||||
ReadAttr(ejnt, "solimpfix", mjNIMP, el->equality.spec.solimp, text, false, false);
|
||||
ReadAttr(ejnt, "solreffix", mjNREF, dequality.solref, text, false, false);
|
||||
ReadAttr(ejnt, "solimpfix", mjNIMP, dequality.solimp, text, false, false);
|
||||
|
||||
// joint attributes
|
||||
MapValue(elem, "limited", &el->joint.spec.limited, TFAuto_map, 3);
|
||||
ReadAttrInt(ejnt, "group", &el->joint.spec.group);
|
||||
ReadAttr(ejnt, "solreflimit", mjNREF, el->joint.spec.solref_limit, text, false, false);
|
||||
ReadAttr(ejnt, "solimplimit", mjNIMP, el->joint.spec.solimp_limit, text, false, false);
|
||||
MapValue(elem, "limited", &djoint.limited, TFAuto_map, 3);
|
||||
ReadAttrInt(ejnt, "group", &djoint.group);
|
||||
ReadAttr(ejnt, "solreflimit", mjNREF, djoint.solref_limit, text, false, false);
|
||||
ReadAttr(ejnt, "solimplimit", mjNIMP, djoint.solimp_limit, text, false, false);
|
||||
ReadAttr(ejnt,
|
||||
"solreffriction", mjNREF, el->joint.spec.solref_friction, text, false, false);
|
||||
"solreffriction", mjNREF, djoint.solref_friction, text, false, false);
|
||||
ReadAttr(ejnt,
|
||||
"solimpfriction", mjNIMP, el->joint.spec.solimp_friction, text, false, false);
|
||||
ReadAttr(ejnt, "stiffness", 1, &el->joint.spec.stiffness, text);
|
||||
ReadAttr(ejnt, "range", 2, el->joint.spec.range, text);
|
||||
ReadAttr(ejnt, "margin", 1, &el->joint.spec.margin, text);
|
||||
ReadAttr(ejnt, "armature", 1, &el->joint.spec.armature, text);
|
||||
ReadAttr(ejnt, "damping", 1, &el->joint.spec.damping, text);
|
||||
ReadAttr(ejnt, "frictionloss", 1, &el->joint.spec.frictionloss, text);
|
||||
"solimpfriction", mjNIMP, djoint.solimp_friction, text, false, false);
|
||||
ReadAttr(ejnt, "stiffness", 1, &djoint.stiffness, text);
|
||||
ReadAttr(ejnt, "range", 2, djoint.range, text);
|
||||
ReadAttr(ejnt, "margin", 1, &djoint.margin, text);
|
||||
ReadAttr(ejnt, "armature", 1, &djoint.armature, text);
|
||||
ReadAttr(ejnt, "damping", 1, &djoint.damping, text);
|
||||
ReadAttr(ejnt, "frictionloss", 1, &djoint.frictionloss, text);
|
||||
|
||||
// advance
|
||||
ejnt = NextSiblingElement(ejnt, "joint");
|
||||
@@ -2419,29 +2421,33 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjCDef* def) {
|
||||
MapValue(eten, "kind", &kind, tkind_map, 2, true);
|
||||
comp.add[kind] = true;
|
||||
|
||||
// get default structs
|
||||
mjmTendon& dtendon = *comp.def[kind].spec.tendon;
|
||||
mjmEquality& dequality = *comp.def[kind].spec.equality;
|
||||
|
||||
// solreffix, solimpfix
|
||||
ReadAttr(eten, "solreffix", mjNREF, comp.def[kind].equality.spec.solref, text, false, false);
|
||||
ReadAttr(eten, "solimpfix", mjNIMP, comp.def[kind].equality.spec.solimp, text, false, false);
|
||||
ReadAttr(eten, "solreffix", mjNREF, dequality.solref, text, false, false);
|
||||
ReadAttr(eten, "solimpfix", mjNIMP, dequality.solimp, text, false, false);
|
||||
|
||||
// tendon attributes
|
||||
std::string material;
|
||||
MapValue(elem, "limited", &comp.def[kind].tendon.spec.limited, TFAuto_map, 3);
|
||||
ReadAttrInt(eten, "group", &comp.def[kind].tendon.spec.group);
|
||||
ReadAttr(eten, "solreflimit", mjNREF, comp.def[kind].tendon.spec.solref_limit, text, false, false);
|
||||
ReadAttr(eten, "solimplimit", mjNIMP, comp.def[kind].tendon.spec.solimp_limit, text, false, false);
|
||||
MapValue(elem, "limited", &dtendon.limited, TFAuto_map, 3);
|
||||
ReadAttrInt(eten, "group", &dtendon.group);
|
||||
ReadAttr(eten, "solreflimit", mjNREF, dtendon.solref_limit, text, false, false);
|
||||
ReadAttr(eten, "solimplimit", mjNIMP, dtendon.solimp_limit, text, false, false);
|
||||
ReadAttr(eten,
|
||||
"solreffriction", mjNREF, comp.def[kind].tendon.spec.solref_friction, text, false, false);
|
||||
"solreffriction", mjNREF, dtendon.solref_friction, text, false, false);
|
||||
ReadAttr(eten,
|
||||
"solimpfriction", mjNIMP, comp.def[kind].tendon.spec.solimp_friction, text, false, false);
|
||||
ReadAttr(eten, "range", 2, comp.def[kind].tendon.spec.range, text);
|
||||
ReadAttr(eten, "margin", 1, &comp.def[kind].tendon.spec.margin, text);
|
||||
ReadAttr(eten, "stiffness", 1, &comp.def[kind].tendon.spec.stiffness, text);
|
||||
ReadAttr(eten, "damping", 1, &comp.def[kind].tendon.spec.damping, text);
|
||||
ReadAttr(eten, "frictionloss", 1, &comp.def[kind].tendon.spec.frictionloss, text);
|
||||
"solimpfriction", mjNIMP, dtendon.solimp_friction, text, false, false);
|
||||
ReadAttr(eten, "range", 2, dtendon.range, text);
|
||||
ReadAttr(eten, "margin", 1, &dtendon.margin, text);
|
||||
ReadAttr(eten, "stiffness", 1, &dtendon.stiffness, text);
|
||||
ReadAttr(eten, "damping", 1, &dtendon.damping, text);
|
||||
ReadAttr(eten, "frictionloss", 1, &dtendon.frictionloss, text);
|
||||
ReadAttrTxt(eten, "material", material);
|
||||
mjm_setString(comp.def[kind].tendon.spec.material, material.c_str());
|
||||
ReadAttr(eten, "rgba", 4, comp.def[kind].tendon.spec.rgba, text);
|
||||
ReadAttr(eten, "width", 1, &comp.def[kind].tendon.spec.width, text);
|
||||
mjm_setString(dtendon.material, material.c_str());
|
||||
ReadAttr(eten, "rgba", 4, dtendon.rgba, text);
|
||||
ReadAttr(eten, "width", 1, &dtendon.width, text);
|
||||
|
||||
// advance
|
||||
eten = NextSiblingElement(eten, "tendon");
|
||||
@@ -2481,6 +2487,7 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) {
|
||||
|
||||
// create out-of-DOM element
|
||||
mjCFlexcomp fcomp;
|
||||
mjmFlex& dflex = *fcomp.def.spec.flex;
|
||||
|
||||
// common properties
|
||||
ReadAttrTxt(elem, "name", fcomp.name, true);
|
||||
@@ -2494,15 +2501,15 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) {
|
||||
ReadAttr(elem, "inertiabox", 1, &fcomp.inertiabox, text);
|
||||
ReadAttrTxt(elem, "file", fcomp.file);
|
||||
if (ReadAttrTxt(elem, "material", material)) {
|
||||
mjm_setString(fcomp.def.flex.spec.material, material.c_str());
|
||||
mjm_setString(dflex.material, material.c_str());
|
||||
}
|
||||
ReadAttr(elem, "rgba", 4, fcomp.def.flex.spec.rgba, text);
|
||||
ReadAttr(elem, "rgba", 4, dflex.rgba, text);
|
||||
if (MapValue(elem, "flatskin", &n, bool_map, 2)) {
|
||||
fcomp.def.flex.spec.flatskin = (n==1);
|
||||
dflex.flatskin = (n==1);
|
||||
}
|
||||
ReadAttrInt(elem, "dim", &fcomp.def.flex.spec.dim);
|
||||
ReadAttr(elem, "radius", 1, &fcomp.def.flex.spec.radius, text);
|
||||
ReadAttrInt(elem, "group", &fcomp.def.flex.spec.group);
|
||||
ReadAttrInt(elem, "dim", &dflex.dim);
|
||||
ReadAttr(elem, "radius", 1, &dflex.radius, text);
|
||||
ReadAttrInt(elem, "group", &dflex.group);
|
||||
|
||||
// pose
|
||||
ReadAttr(elem, "pos", 3, fcomp.pos, text);
|
||||
@@ -2529,30 +2536,30 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) {
|
||||
if (MapValue(edge, "equality", &n, bool_map, 2)) {
|
||||
fcomp.equality = (n==1);
|
||||
}
|
||||
ReadAttr(edge, "solref", mjNREF, fcomp.def.equality.spec.solref, text, false, false);
|
||||
ReadAttr(edge, "solimp", mjNIMP, fcomp.def.equality.spec.solimp, text, false, false);
|
||||
ReadAttr(edge, "stiffness", 1, &fcomp.def.flex.spec.edgestiffness, text);
|
||||
ReadAttr(edge, "damping", 1, &fcomp.def.flex.spec.edgedamping, text);
|
||||
ReadAttr(edge, "solref", mjNREF, fcomp.def.spec.equality->solref, text, false, false);
|
||||
ReadAttr(edge, "solimp", mjNIMP, fcomp.def.spec.equality->solimp, text, false, false);
|
||||
ReadAttr(edge, "stiffness", 1, &dflex.edgestiffness, text);
|
||||
ReadAttr(edge, "damping", 1, &dflex.edgedamping, text);
|
||||
}
|
||||
|
||||
// contact
|
||||
XMLElement* cont = FirstChildElement(elem, "contact");
|
||||
if (cont) {
|
||||
ReadAttrInt(cont, "contype", &fcomp.def.flex.spec.contype);
|
||||
ReadAttrInt(cont, "conaffinity", &fcomp.def.flex.spec.conaffinity);
|
||||
ReadAttrInt(cont, "condim", &fcomp.def.flex.spec.condim);
|
||||
ReadAttrInt(cont, "priority", &fcomp.def.flex.spec.priority);
|
||||
ReadAttr(cont, "friction", 3, fcomp.def.flex.spec.friction, text, false, false);
|
||||
ReadAttr(cont, "solmix", 1, &fcomp.def.flex.spec.solmix, text);
|
||||
ReadAttr(cont, "solref", mjNREF, fcomp.def.flex.spec.solref, text, false, false);
|
||||
ReadAttr(cont, "solimp", mjNIMP, fcomp.def.flex.spec.solimp, text, false, false);
|
||||
ReadAttr(cont, "margin", 1, &fcomp.def.flex.spec.margin, text);
|
||||
ReadAttr(cont, "gap", 1, &fcomp.def.flex.spec.gap, text);
|
||||
ReadAttrInt(cont, "contype", &dflex.contype);
|
||||
ReadAttrInt(cont, "conaffinity", &dflex.conaffinity);
|
||||
ReadAttrInt(cont, "condim", &dflex.condim);
|
||||
ReadAttrInt(cont, "priority", &dflex.priority);
|
||||
ReadAttr(cont, "friction", 3, dflex.friction, text, false, false);
|
||||
ReadAttr(cont, "solmix", 1, &dflex.solmix, text);
|
||||
ReadAttr(cont, "solref", mjNREF, dflex.solref, text, false, false);
|
||||
ReadAttr(cont, "solimp", mjNIMP, dflex.solimp, text, false, false);
|
||||
ReadAttr(cont, "margin", 1, &dflex.margin, text);
|
||||
ReadAttr(cont, "gap", 1, &dflex.gap, text);
|
||||
if (MapValue(cont, "internal", &n, bool_map, 2)) {
|
||||
fcomp.def.flex.spec.internal = (n==1);
|
||||
dflex.internal = (n==1);
|
||||
}
|
||||
MapValue(cont, "selfcollide", &fcomp.def.flex.spec.selfcollide, flexself_map, 5);
|
||||
ReadAttrInt(cont, "activelayers", &fcomp.def.flex.spec.activelayers);
|
||||
MapValue(cont, "selfcollide", &dflex.selfcollide, flexself_map, 5);
|
||||
ReadAttrInt(cont, "activelayers", &dflex.activelayers);
|
||||
}
|
||||
|
||||
// pin
|
||||
@@ -2633,7 +2640,7 @@ void mjXReader::OnePlugin(XMLElement* elem, mjmPlugin* plugin) {
|
||||
void mjXReader::Default(XMLElement* section, int parentid) {
|
||||
XMLElement* elem;
|
||||
string text, name;
|
||||
mjCDef* def;
|
||||
mjmDefault* def;
|
||||
int thisid;
|
||||
|
||||
// create new default, except at top level (already added in mjCModel ctor)
|
||||
@@ -2648,14 +2655,14 @@ void mjXReader::Default(XMLElement* section, int parentid) {
|
||||
}
|
||||
if (parentid>=0) {
|
||||
thisid = (int)model->defaults.size();
|
||||
def = model->AddDef(text, parentid);
|
||||
def = mjm_addDefault(model, text.c_str(), parentid);
|
||||
if (!def) {
|
||||
throw mjXError(section, "repeated default class name");
|
||||
}
|
||||
} else {
|
||||
thisid = 0;
|
||||
def = model->defaults[0];
|
||||
def->name = text;
|
||||
def = &model->defaults[0]->spec;
|
||||
mjm_setString(def->name, text.c_str());
|
||||
}
|
||||
|
||||
// iterate over elements other than nested defaults
|
||||
@@ -2665,34 +2672,34 @@ void mjXReader::Default(XMLElement* section, int parentid) {
|
||||
name = elem->Value();
|
||||
|
||||
// read mesh
|
||||
if (name=="mesh") OneMesh(elem, &def->mesh.spec);
|
||||
if (name=="mesh") OneMesh(elem, def->mesh);
|
||||
|
||||
// read material
|
||||
else if (name=="material") OneMaterial(elem, &def->material.spec);
|
||||
else if (name=="material") OneMaterial(elem, def->material);
|
||||
|
||||
// read joint
|
||||
else if (name=="joint") OneJoint(elem, &def->joint.spec);
|
||||
else if (name=="joint") OneJoint(elem, def->joint);
|
||||
|
||||
// read geom
|
||||
else if (name=="geom") OneGeom(elem, &def->geom.spec);
|
||||
else if (name=="geom") OneGeom(elem, def->geom);
|
||||
|
||||
// read site
|
||||
else if (name=="site") OneSite(elem, def->site.spec);
|
||||
else if (name=="site") OneSite(elem, def->site);
|
||||
|
||||
// read camera
|
||||
else if (name=="camera") OneCamera(elem, &def->camera.spec);
|
||||
else if (name=="camera") OneCamera(elem, def->camera);
|
||||
|
||||
// read light
|
||||
else if (name=="light") OneLight(elem, &def->light.spec);
|
||||
else if (name=="light") OneLight(elem, def->light);
|
||||
|
||||
// read pair
|
||||
else if (name=="pair") OnePair(elem, &def->pair.spec);
|
||||
else if (name=="pair") OnePair(elem, def->pair);
|
||||
|
||||
// read equality
|
||||
else if (name=="equality") OneEquality(elem, &def->equality.spec);
|
||||
else if (name=="equality") OneEquality(elem, def->equality);
|
||||
|
||||
// read tendon
|
||||
else if (name=="tendon") OneTendon(elem, &def->tendon.spec);
|
||||
else if (name=="tendon") OneTendon(elem, def->tendon);
|
||||
|
||||
// read actuator
|
||||
else if (name=="general" ||
|
||||
@@ -2704,21 +2711,22 @@ void mjXReader::Default(XMLElement* section, int parentid) {
|
||||
name=="cylinder" ||
|
||||
name=="muscle" ||
|
||||
name=="adhesion") {
|
||||
OneActuator(elem, &def->actuator.spec);
|
||||
OneActuator(elem, def->actuator);
|
||||
}
|
||||
|
||||
// copy into private attributes
|
||||
mjm_finalize(def->geom.spec.element);
|
||||
mjm_finalize(def->joint.spec.element);
|
||||
mjm_finalize(def->site.spec.element);
|
||||
mjm_finalize(def->camera.spec.element);
|
||||
mjm_finalize(def->light.spec.element);
|
||||
mjm_finalize(def->actuator.spec.element);
|
||||
mjm_finalize(def->material.spec.element);
|
||||
mjm_finalize(def->equality.spec.element);
|
||||
mjm_finalize(def->tendon.spec.element);
|
||||
mjm_finalize(def->flex.spec.element);
|
||||
mjm_finalize(def->pair.spec.element);
|
||||
mjm_finalize(def->joint->element);
|
||||
mjm_finalize(def->geom->element);
|
||||
mjm_finalize(def->site->element);
|
||||
mjm_finalize(def->camera->element);
|
||||
mjm_finalize(def->light->element);
|
||||
mjm_finalize(def->flex->element);
|
||||
mjm_finalize(def->mesh->element);
|
||||
mjm_finalize(def->material->element);
|
||||
mjm_finalize(def->pair->element);
|
||||
mjm_finalize(def->equality->element);
|
||||
mjm_finalize(def->tendon->element);
|
||||
mjm_finalize(def->actuator->element);
|
||||
|
||||
// advance
|
||||
elem = NextSiblingElement(elem);
|
||||
@@ -3066,9 +3074,9 @@ void mjXReader::Asset(XMLElement* section) {
|
||||
name = elem->Value();
|
||||
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// texture sub-element
|
||||
@@ -3248,9 +3256,9 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) {
|
||||
name = elem->Value();
|
||||
|
||||
// get class if specified, otherwise use body
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = (mjCDef*)mjm_getDefault(pbody->element);
|
||||
def = (mjmDefault*)mjm_getDefault(pbody->element);
|
||||
}
|
||||
|
||||
// inertial sub-element
|
||||
@@ -3318,7 +3326,7 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) {
|
||||
else if (name=="site") {
|
||||
// create site and parse
|
||||
mjmSite* site = mjm_addSite(pbody, def);
|
||||
OneSite(elem, *site);
|
||||
OneSite(elem, site);
|
||||
mjm_setFrame(site->element, frame);
|
||||
}
|
||||
|
||||
@@ -3370,9 +3378,9 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) {
|
||||
// body sub-element
|
||||
else if (name=="body") {
|
||||
// read childdef
|
||||
mjCDef* childdef = 0;
|
||||
mjmDefault* childdef = 0;
|
||||
if (ReadAttrTxt(elem, "childclass", text)) {
|
||||
childdef = model->FindDef(text);
|
||||
childdef = &model->FindDef(text)->spec;
|
||||
if (!childdef) {
|
||||
throw mjXError(elem, "unknown default childclass");
|
||||
}
|
||||
@@ -3437,9 +3445,9 @@ void mjXReader::Contact(XMLElement* section) {
|
||||
name = elem->Value();
|
||||
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// geom pair to include
|
||||
@@ -3482,9 +3490,9 @@ void mjXReader::Equality(XMLElement* section) {
|
||||
elem = FirstChildElement(section);
|
||||
while (elem) {
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// create equality constraint and parse
|
||||
@@ -3510,9 +3518,9 @@ void mjXReader::Deformable(XMLElement* section) {
|
||||
name = elem->Value();
|
||||
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// flex sub-element
|
||||
@@ -3546,9 +3554,9 @@ void mjXReader::Tendon(XMLElement* section) {
|
||||
elem = FirstChildElement(section);
|
||||
while (elem) {
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// create equality constraint and parse
|
||||
@@ -3612,9 +3620,9 @@ void mjXReader::Actuator(XMLElement* section) {
|
||||
elem = FirstChildElement(section);
|
||||
while (elem) {
|
||||
// get class if specified, otherwise use default0
|
||||
mjCDef* def = GetClass(elem);
|
||||
mjmDefault* def = GetClass(elem);
|
||||
if (!def) {
|
||||
def = model->defaults[0];
|
||||
def = &model->defaults[0]->spec;
|
||||
}
|
||||
|
||||
// create actuator and parse
|
||||
@@ -4003,12 +4011,12 @@ void mjXReader::Keyframe(XMLElement* section) {
|
||||
|
||||
|
||||
// get defaults class
|
||||
mjCDef* mjXReader::GetClass(XMLElement* section) {
|
||||
mjmDefault* mjXReader::GetClass(XMLElement* section) {
|
||||
string text;
|
||||
mjCDef* def = 0;
|
||||
mjmDefault* def = 0;
|
||||
|
||||
if (ReadAttrTxt(section, "class", text)) {
|
||||
def = model->FindDef(text);
|
||||
def = &model->FindDef(text)->spec;
|
||||
if (!def) {
|
||||
throw mjXError(section, "unknown default class");
|
||||
}
|
||||
|
||||
@@ -64,19 +64,19 @@ class mjXReader : public mjXBase {
|
||||
void OneMaterial(tinyxml2::XMLElement* elem, mjmMaterial* pmaterial);
|
||||
void OneJoint(tinyxml2::XMLElement* elem, mjmJoint* pjoint);
|
||||
void OneGeom(tinyxml2::XMLElement* elem, mjmGeom* pgeom);
|
||||
void OneSite(tinyxml2::XMLElement* elem, mjmSite& site);
|
||||
void OneSite(tinyxml2::XMLElement* elem, mjmSite* site);
|
||||
void OneCamera(tinyxml2::XMLElement* elem, mjmCamera* pcamera);
|
||||
void OneLight(tinyxml2::XMLElement* elem, mjmLight* plight);
|
||||
void OnePair(tinyxml2::XMLElement* elem, mjmPair* ppair);
|
||||
void OneEquality(tinyxml2::XMLElement* elem, mjmEquality* pequality);
|
||||
void OneTendon(tinyxml2::XMLElement* elem, mjmTendon* ptendon);
|
||||
void OneActuator(tinyxml2::XMLElement* elem, mjmActuator* pactuator);
|
||||
void OneComposite(tinyxml2::XMLElement* elem, mjmBody* pbody, mjCDef* def);
|
||||
void OneComposite(tinyxml2::XMLElement* elem, mjmBody* pbody, mjmDefault* def);
|
||||
void OneFlexcomp(tinyxml2::XMLElement* elem, mjmBody* pbody);
|
||||
void OnePlugin(tinyxml2::XMLElement* elem, mjmPlugin* plugin);
|
||||
|
||||
mjXSchema schema; // schema used for validation
|
||||
mjCDef* GetClass(tinyxml2::XMLElement* section); // get default class name
|
||||
mjmDefault* GetClass(tinyxml2::XMLElement* section); // get default class name
|
||||
static void GetXMLPos(tinyxml2::XMLElement* elem, mjCBase* obj); // get xml position
|
||||
|
||||
bool readingdefaults; // true while reading defaults
|
||||
|
||||
@@ -437,6 +437,31 @@ TEST_F(XMLReaderTest, InvalidDoubleOrientation) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(XMLReaderTest, RepeatedDefaultName) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<default>
|
||||
<default class="sphere">
|
||||
<geom type="sphere" size="1"/>
|
||||
</default>
|
||||
<default class="sphere">
|
||||
<geom type="capsule" size="1 1"/>
|
||||
</default>
|
||||
</default>
|
||||
<worldbody>
|
||||
<body>
|
||||
<geom class="sphere"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, IsNull()) << error.data();
|
||||
EXPECT_THAT(error.data(), HasSubstr("repeated default class name"));
|
||||
}
|
||||
|
||||
// ------------------------ test including -------------------------------------
|
||||
|
||||
TEST_F(XMLReaderTest, IncludeTest) {
|
||||
|
||||
@@ -694,6 +694,38 @@ TEST_F(XMLWriterTest, WritesDefaults) {
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(XMLWriterTest, WritesActuatorDefaults) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<default>
|
||||
<default class="position">
|
||||
<position kp="3" kv="4" />
|
||||
</default>
|
||||
<default class="intvelocity">
|
||||
<intvelocity kp="5" kv="6" />
|
||||
</default>
|
||||
</default>
|
||||
<worldbody>
|
||||
<body>
|
||||
<geom size="1"/>
|
||||
<joint name="jnt" type="slide" axis="1 0 0" range="0 2"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<actuator>
|
||||
<position joint="jnt" class="position"/>
|
||||
<intvelocity joint="jnt" actrange="-1 1"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
)";
|
||||
mjModel* model = LoadModelFromString(xml);
|
||||
ASSERT_THAT(model, NotNull());
|
||||
std::string saved_xml = SaveAndReadXml(model);
|
||||
EXPECT_THAT(saved_xml, Not(HasSubstr("mass")));
|
||||
EXPECT_THAT(saved_xml, HasSubstr(
|
||||
"<general biastype=\"affine\" gainprm=\"3 0 0 0 0 0 0 0 0 0\""));
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
TEST_F(XMLWriterTest, WritesDensity) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
|
||||
Reference in New Issue
Block a user