Add mjmMaterial and mjmFrame to C API.

PiperOrigin-RevId: 606191307
Change-Id: Iaf43f81522029002b28bba14ea046b1c968ab2e7
This commit is contained in:
Alessio Quaglino
2024-02-12 02:55:00 -08:00
committed by Copybara-Service
parent 4b8363de6d
commit 4e5b194e88
9 changed files with 192 additions and 54 deletions
+23 -6
View File
@@ -115,10 +115,24 @@ mjmLight* mjm_addLight(mjmBody* bodyspec, void* defspec) {
// add frame to body
void* mjm_addFrame(mjmBody* bodyspec, void* parentframe) {
mjCFrame* parentframeC = static_cast<mjCFrame*>(parentframe);
mjCFrame* frameC = reinterpret_cast<mjCBody*>(bodyspec->element)->AddFrame(parentframeC);
return frameC;
mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) {
mjCFrame* parentframeC = 0;
if (parentframe) {
parentframeC = reinterpret_cast<mjCFrame*>(parentframe->element);
}
mjCBody* body = reinterpret_cast<mjCBody*>(bodyspec->element);
mjCFrame* frameC = body->AddFrame(parentframeC);
return &frameC->spec;
}
// Add material to model.
mjmMaterial* mjm_addMaterial(void* model, void* defspec) {
mjCModel* modelC = static_cast<mjCModel*>(model);
mjCDef* def = static_cast<mjCDef*>(defspec);
mjCMaterial* material = modelC->AddMaterial(def);
return &material->spec;
}
@@ -246,8 +260,11 @@ mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) {
// set frame
void mjm_setFrame(mjElement dest, void* frame) {
mjCFrame* frameC = static_cast<mjCFrame*>(frame);
void mjm_setFrame(mjElement dest, mjmFrame* frame) {
if (!frame) {
return;
}
mjCFrame* frameC = reinterpret_cast<mjCFrame*>(frame->element);
mjCBase* baseC = reinterpret_cast<mjCBase*>(dest);
baseC->SetFrame(frameC);
}
+36 -2
View File
@@ -87,6 +87,15 @@ typedef struct _mjmBody { // body specification
} mjmBody;
typedef struct _mjmFrame { // frame specification
mjElement element; // internal, do not modify
double pos[3]; // position
double quat[4]; // orientation
mjmOrientation alt; // alternative orientation
mjString info; // message appended to compiler errors
} mjmFrame;
typedef struct _mjmJoint { // joint specification
mjElement element; // internal, do not modify
mjString name; // name
@@ -256,6 +265,22 @@ typedef struct _mjmLight { // light specification
} mjmLight;
typedef struct _mjmMaterial { // material specification
mjElement element; // internal, do not modify
mjString name; // name
mjString classname; // class name
mjString texture; // name of texture (empty: none)
bool texuniform; // make texture cube uniform
float texrepeat[2]; // texture repetition for 2D mapping
float emission; // emission
float specular; // specular
float shininess; // shininess
float reflectance; // reflectance
float rgba[4]; // rgba
mjString info; // message appended to compiler errors
} mjmMaterial;
typedef struct _mjmEquality { // equality specification
mjElement element; // internal, do not modify
mjString name; // name
@@ -415,7 +440,10 @@ MJAPI mjmCamera* mjm_addCamera(mjmBody* body, void* defspec);
MJAPI mjmLight* mjm_addLight(mjmBody* body, void* defspec);
// Add frame to body.
MJAPI void* mjm_addFrame(mjmBody* body, void* parentframe);
MJAPI mjmFrame* mjm_addFrame(mjmBody* body, mjmFrame* parentframe);
// Add material to model.
MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
// Add equality to model.
MJAPI mjmEquality* mjm_addEquality(void* model, void* defspec);
@@ -475,7 +503,7 @@ MJAPI const double* mjm_getDouble(mjDouble source, int* size);
MJAPI void mjm_setDefault(mjElement element, void* defspec);
// Set frame.
MJAPI void mjm_setFrame(mjElement dest, void* frame);
MJAPI void mjm_setFrame(mjElement dest, mjmFrame* frame);
// Compute quat and inertia from body->fullinertia.
MJAPI const char* mjm_setFullInertia(mjmBody* body, double quat[4], double inertia[3]);
@@ -486,6 +514,9 @@ MJAPI const char* mjm_setFullInertia(mjmBody* body, double quat[4], double inert
// Default body attributes.
MJAPI void mjm_defaultBody(mjmBody& body);
// Default frame attributes.
MJAPI void mjm_defaultFrame(mjmFrame& frame);
// Default joint attributes.
MJAPI void mjm_defaultJoint(mjmJoint& joint);
@@ -501,6 +532,9 @@ MJAPI void mjm_defaultCamera(mjmCamera& camera);
// Default light attributes.
MJAPI void mjm_defaultLight(mjmLight& light);
// Default material attributes.
MJAPI void mjm_defaultMaterial(mjmMaterial& material);
// Default equality attributes.
MJAPI void mjm_defaultEquality(mjmEquality& equality);
+24
View File
@@ -38,6 +38,16 @@ void mjm_defaultBody(mjmBody& body) {
// default frame attributes
void mjm_defaultFrame(mjmFrame& frame) {
memset(&frame, 0, sizeof(mjmFrame));
mju_zero3(frame.pos);
mjuu_setvec(frame.quat, 1, 0, 0, 0);
frame.alt.axisangle[0] = frame.alt.xyaxes[0] = frame.alt.zaxis[0] = frame.alt.euler[0] = mjNAN;
}
// default joint attributes
void mjm_defaultJoint(mjmJoint& joint) {
memset(&joint, 0, sizeof(mjmJoint));
@@ -157,6 +167,20 @@ void mjm_defaultLight(mjmLight& light) {
// Default material attributes.
void mjm_defaultMaterial(mjmMaterial& material) {
memset(&material, 0, sizeof(mjmMaterial));
material.texuniform = false;
material.texrepeat[0] = material.texrepeat[1] = 1;
material.emission = 0;
material.specular = 0.5;
material.shininess = 0.5;
material.reflectance = 0;
material.rgba[0] = material.rgba[1] = material.rgba[2] = material.rgba[3] = 1;
}
// default equality attributes
void mjm_defaultEquality(mjmEquality& equality) {
memset(&equality, 0, sizeof(mjmEquality));
+5 -5
View File
@@ -667,8 +667,8 @@ void mjCModel::DeleteMaterial(std::vector<T*>& list, std::string_view name) {
template <class T>
static void DeleteTexture(std::vector<T*>& list, std::string_view name = "") {
for (T* plist : list) {
if (name.empty() || plist->texture == name) {
plist->texture.clear();
if (name.empty() || plist->get_texture() == name) {
plist->del_texture();
}
}
}
@@ -869,12 +869,12 @@ void mjCModel::IndexAssets(bool discard) {
mjCMaterial* pmat = materials[i];
// find texture by name
if (!pmat->texture.empty()) {
mjCBase* m = FindObject(mjOBJ_TEXTURE, pmat->texture);
if (!pmat->texture_.empty()) {
mjCBase* m = FindObject(mjOBJ_TEXTURE, pmat->texture_);
if (m) {
pmat->texid = m->id;
} else {
throw mjCError(pmat, "texture '%s' not found in material %d", pmat->texture.c_str(), i);
throw mjCError(pmat, "texture '%s' not found in material %d", pmat->texture_.c_str(), i);
}
}
}
+56 -13
View File
@@ -1175,19 +1175,42 @@ void mjCBody::Compile(void) {
// initialize frame
mjCFrame::mjCFrame(mjCModel* _model, mjCFrame* _frame) {
mjm_defaultFrame(spec);
compiled = false;
model = _model;
frame = _frame ? _frame : NULL;
mju_zero3(pos);
mjuu_setvec(quat, 1, 0, 0, 0);
PointToLocal();
CopyFromSpec();
}
void mjCFrame::PointToLocal() {
spec.element = (mjElement)this;
spec.info = (mjString)&info;
}
void mjCFrame::CopyFromSpec() {
*static_cast<mjmFrame*>(this) = spec;
mju_copy3(pos, spec.pos);
mju_copy4(quat, spec.quat);
mju_copy4(alt_.axisangle, alt.axisangle);
mju_copy(alt_.xyaxes, alt.xyaxes, 6);
mju_copy3(alt_.zaxis, alt.zaxis);
mju_copy3(alt_.euler, alt.euler);
}
void mjCFrame::Compile() {
if (compiled) {
return;
}
const char* err = alt.Set(quat, model->degree, model->euler);
CopyFromSpec();
const char* err = alt_.Set(quat, model->degree, model->euler);
if (err) {
throw mjCError(this, "orientation specification error '%s' in site %d", err, id);
}
@@ -3264,32 +3287,52 @@ void mjCTexture::Compile(const mjVFS* vfs) {
// initialize defaults
mjCMaterial::mjCMaterial(mjCModel* _model, mjCDef* _def) {
// set defaults
texture.clear();
mjm_defaultMaterial(spec);
// clear internal
spec_texture_.clear();
texid = -1;
texuniform = false;
texrepeat[0] = texrepeat[1] = 1;
emission = 0;
specular = 0.5;
shininess = 0.5;
reflectance = 0;
rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1;
// reset to default if given
if (_def) {
_def->material.CopyFromSpec();
*this = _def->material;
}
// set model, def
model = _model;
def = (_def ? _def : (_model ? _model->defaults[0] : 0));
// point to local (needs to be after defaults)
PointToLocal();
// in case this camera is not compiled
CopyFromSpec();
}
void mjCMaterial::PointToLocal() {
spec.element = (mjElement)this;
spec.name = (mjString)&name;
spec.classname = (mjString)&classname;
spec.texture = (mjString)&spec_texture_;
spec.info = (mjString)&info;
}
void mjCMaterial::CopyFromSpec() {
*static_cast<mjmMaterial*>(this) = spec;
texture_ = spec_texture_;
texture = (mjString)&texture_;
}
// compiler
void mjCMaterial::Compile(void) {
// nothing to do for now
CopyFromSpec();
}
+25 -14
View File
@@ -305,18 +305,26 @@ class mjCBody : public mjCBase, private mjmBody {
//------------------------- class mjCFrame ---------------------------------------------------------
// Describes a coordinate transformation relative to its parent
class mjCFrame : public mjCBase {
class mjCFrame : public mjCBase, private mjmFrame {
friend class mjCBase;
friend class mjCBody;
friend class mjCGeom;
friend class mjCJoint;
friend class mjCSite;
friend class mjCCamera;
friend class mjCLight;
friend class mjCModel;
public:
double pos[3]; // frame position
double quat[4]; // frame orientation
mjCAlternative alt; // alternative orientation specification
mjmFrame spec;
using mjCBase::info;
void CopyFromSpec(void);
void PointToLocal(void);
private:
bool compiled; // frame already compiled
mjCAlternative alt_;
mjCFrame(mjCModel* = 0, mjCFrame* = 0); // constructor
void Compile(void); // compiler
@@ -931,27 +939,30 @@ class mjCTexture : public mjCBase {
//------------------------- class mjCMaterial ------------------------------------------------------
// Describes a material for rendering
class mjCMaterial : public mjCBase {
class mjCMaterial : public mjCBase, private mjmMaterial {
friend class mjCDef;
friend class mjCModel;
friend class mjXWriter;
public:
// variables set by user
std::string texture; // name of texture (empty: none)
bool texuniform; // make texture cube uniform
float texrepeat[2]; // texture repetition for 2D mapping
float emission; // emission
float specular; // specular
float shininess; // shininess
float reflectance; // reflectance
float rgba[4]; // rgba
mjmMaterial spec;
using mjCBase::name;
using mjCBase::classname;
using mjCBase::info;
void CopyFromSpec();
void PointToLocal();
std::string get_texture() { return texture_; }
void del_texture() { texture_.clear(); }
private:
mjCMaterial(mjCModel* = 0, mjCDef* = 0); // constructor
void Compile(void); // compiler
int texid; // id of material
std::string texture_;
std::string spec_texture_;
};