Make model editing API public, fixes #364
Still missing: - Detailed documentation. - Python bindings. PiperOrigin-RevId: 641445626 Change-Id: I20e67b707cf1bebae7e0cc94d17f7b76a89171f0
This commit is contained in:
committed by
Copybara-Service
parent
4c3d9461ae
commit
7a06bcfdaf
+351
-20
@@ -15,14 +15,6 @@
|
||||
#ifndef MUJOCO_MUJOCO_H_
|
||||
#define MUJOCO_MUJOCO_H_
|
||||
|
||||
#include <mujoco/mjexport.h>
|
||||
|
||||
|
||||
// this is a C-API
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// header version; should match the library version as returned by mj_version()
|
||||
#define mjVERSION_HEADER 317
|
||||
|
||||
@@ -32,15 +24,21 @@ extern "C" {
|
||||
|
||||
// type definitions
|
||||
#include <mujoco/mjdata.h>
|
||||
#include <mujoco/mjexport.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjmacro.h>
|
||||
#include <mujoco/mjplugin.h>
|
||||
#include <mujoco/mjrender.h>
|
||||
#include <mujoco/mjspec.h>
|
||||
#include <mujoco/mjthread.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjui.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
|
||||
// this is a C-API
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// user error and memory handlers
|
||||
MJAPI extern void (*mju_user_error)(const char*);
|
||||
@@ -97,6 +95,7 @@ MJAPI void mj_deleteVFS(mjVFS* vfs);
|
||||
// deprecated: use mj_copyBufferVFS.
|
||||
MJAPI int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize);
|
||||
|
||||
|
||||
//---------------------------------- Parse and compile ---------------------------------------------
|
||||
|
||||
// Parse XML file in MJCF or URDF format, compile it, return low-level model.
|
||||
@@ -104,6 +103,18 @@ MJAPI int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize);
|
||||
// If error is not NULL, it must have size error_sz.
|
||||
MJAPI mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
||||
|
||||
// Parse spec from XML file.
|
||||
MJAPI mjSpec* mj_parseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
||||
|
||||
// Parse spec from XML string.
|
||||
MJAPI mjSpec* mj_parseXMLString(const char* xml, const mjVFS* vfs, char* error, int error_sz);
|
||||
|
||||
// Compile spec to model.
|
||||
MJAPI mjModel* mj_compile(mjSpec* s, const mjVFS* vfs);
|
||||
|
||||
// Recompile spec to model, preserving the state.
|
||||
MJAPI void mj_recompile(mjSpec* s, const mjVFS* vfs, mjModel* m, mjData* d);
|
||||
|
||||
// Update XML data structures with info from low-level model, save as MJCF.
|
||||
// If error is not NULL, it must have size error_sz.
|
||||
MJAPI int mj_saveLastXML(const char* filename, const mjModel* m, char* error, int error_sz);
|
||||
@@ -111,9 +122,14 @@ MJAPI int mj_saveLastXML(const char* filename, const mjModel* m, char* error, in
|
||||
// Free last XML model if loaded. Called internally at each load.
|
||||
MJAPI void mj_freeLastXML(void);
|
||||
|
||||
// Print internal XML schema as plain text or HTML, with style-padding or .
|
||||
MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
|
||||
int flg_html, int flg_pad);
|
||||
// Copy (possibly modified) model fields back into spec.
|
||||
MJAPI void mj_copyBack(mjSpec* s, const mjModel* m);
|
||||
|
||||
// Save spec to XML string, return 1 on success, 0 otherwise.
|
||||
MJAPI int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int error_sz);
|
||||
|
||||
// Save spec to XML file, return 1 on success, 0 otherwise.
|
||||
MJAPI int mj_saveXML(const mjSpec* s, const char* filename, char* error, int error_sz);
|
||||
|
||||
|
||||
//---------------------------------- Main simulation -----------------------------------------------
|
||||
@@ -221,6 +237,15 @@ MJAPI void mj_setConst(mjModel* m, mjData* d);
|
||||
MJAPI int mj_setLengthRange(mjModel* m, mjData* d, int index,
|
||||
const mjLROpt* opt, char* error, int error_sz);
|
||||
|
||||
// Create empty spec.
|
||||
MJAPI mjSpec* mj_makeSpec(void);
|
||||
|
||||
// Copy spec.
|
||||
MJAPI mjSpec* mj_copySpec(const mjSpec* s);
|
||||
|
||||
// Free memory allocation in mjSpec.
|
||||
MJAPI void mj_deleteSpec(mjSpec* s);
|
||||
|
||||
|
||||
//---------------------------------- Printing ------------------------------------------------------
|
||||
|
||||
@@ -246,6 +271,10 @@ MJAPI void mju_printMat(const mjtNum* mat, int nr, int nc);
|
||||
MJAPI void mju_printMatSparse(const mjtNum* mat, int nr,
|
||||
const int* rownnz, const int* rowadr, const int* colind);
|
||||
|
||||
// Print internal XML schema as plain text or HTML, with style-padding or .
|
||||
MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
|
||||
int flg_html, int flg_pad);
|
||||
|
||||
|
||||
//---------------------------------- Components ----------------------------------------------------
|
||||
|
||||
@@ -510,7 +539,7 @@ MJAPI int mj_version(void);
|
||||
MJAPI const char* mj_versionString(void);
|
||||
|
||||
|
||||
//---------------------------------- Ray collisions ------------------------------------------------
|
||||
//---------------------------------- Ray casting ---------------------------------------------------
|
||||
|
||||
// Intersect multiple rays emanating from a single point.
|
||||
// Similar semantics to mj_ray, but vec is an array of (nray x 3) directions.
|
||||
@@ -852,6 +881,12 @@ MJAPI void mj_warning(mjData* d, int warning, int info);
|
||||
// Write [datetime, type: message] to MUJOCO_LOG.TXT.
|
||||
MJAPI void mju_writeLog(const char* type, const char* msg);
|
||||
|
||||
// Get compiler error message from spec.
|
||||
MJAPI const char* mjs_getError(mjSpec* s);
|
||||
|
||||
// Return 1 if compiler error is a warning.
|
||||
MJAPI int mjs_isWarning(mjSpec* s);
|
||||
|
||||
|
||||
//---------------------------------- Standard math -------------------------------------------------
|
||||
|
||||
@@ -1037,6 +1072,7 @@ MJAPI void mju_transformSpatial(mjtNum res[6], const mjtNum vec[6], int flg_forc
|
||||
const mjtNum newpos[3], const mjtNum oldpos[3],
|
||||
const mjtNum rotnew2old[9]);
|
||||
|
||||
|
||||
//---------------------------------- Quaternions ---------------------------------------------------
|
||||
|
||||
// Rotate vector by quaternion.
|
||||
@@ -1079,6 +1115,7 @@ MJAPI void mju_quatZ2Vec(mjtNum quat[4], const mjtNum vec[3]);
|
||||
// seq[0,1,2] must be in 'xyzXYZ', lower/upper-case mean intrinsic/extrinsic rotations.
|
||||
MJAPI void mju_euler2Quat(mjtNum quat[4], const mjtNum euler[3], const char* seq);
|
||||
|
||||
|
||||
//---------------------------------- Poses ---------------------------------------------------------
|
||||
|
||||
// Multiply two poses.
|
||||
@@ -1166,7 +1203,8 @@ MJAPI int mju_boxQP(mjtNum* res, mjtNum* R, int* index, const mjtNum* H, const m
|
||||
MJAPI void mju_boxQPmalloc(mjtNum** res, mjtNum** R, int** index, mjtNum** H, mjtNum** g, int n,
|
||||
mjtNum** lower, mjtNum** upper);
|
||||
|
||||
//---------------------- Miscellaneous -------------------------------------------------------------
|
||||
|
||||
//---------------------------------- Miscellaneous -------------------------------------------------
|
||||
|
||||
// Muscle active force, prm = (range[2], force, scale, lmin, lmax, vmax, fpmax, fvmax).
|
||||
MJAPI mjtNum mju_muscleGain(mjtNum len, mjtNum vel, const mjtNum lengthrange[2],
|
||||
@@ -1252,7 +1290,7 @@ MJAPI char* mju_strncpy(char *dst, const char *src, int n);
|
||||
MJAPI mjtNum mju_sigmoid(mjtNum x);
|
||||
|
||||
|
||||
//---------------------- Derivatives ---------------------------------------------------------------
|
||||
//---------------------------------- Derivatives ---------------------------------------------------
|
||||
|
||||
// Finite differenced transition matrices (control theory notation)
|
||||
// d(x_next) = A*dx + B*du
|
||||
@@ -1292,7 +1330,8 @@ MJAPI void mjd_subQuat(const mjtNum qa[4], const mjtNum qb[4], mjtNum Da[9], mjt
|
||||
MJAPI void mjd_quatIntegrate(const mjtNum vel[3], mjtNum scale,
|
||||
mjtNum Dquat[9], mjtNum Dvel[9], mjtNum Dscale[3]);
|
||||
|
||||
//---------------------- Plugins -------------------------------------------------------------------
|
||||
|
||||
//---------------------------------- Plugins -------------------------------------------------------
|
||||
|
||||
// Set default plugin definition.
|
||||
MJAPI void mjp_defaultPlugin(mjpPlugin* plugin);
|
||||
@@ -1333,7 +1372,8 @@ MJAPI const mjpResourceProvider* mjp_getResourceProvider(const char* resource_na
|
||||
// If invalid slot number, return NULL.
|
||||
MJAPI const mjpResourceProvider* mjp_getResourceProviderAtSlot(int slot);
|
||||
|
||||
//---------------------- Thread -------------------------------------------------------------------
|
||||
|
||||
//---------------------------------- Threads -------------------------------------------------------
|
||||
|
||||
// Create a thread pool with the specified number of threads running.
|
||||
MJAPI mjThreadPool* mju_threadPoolCreate(size_t number_of_threads);
|
||||
@@ -1353,10 +1393,301 @@ MJAPI void mju_defaultTask(mjTask* task);
|
||||
// Wait for a task to complete.
|
||||
MJAPI void mju_taskJoin(mjTask* task);
|
||||
|
||||
//---------------------- Sanitizer instrumentation helpers -----------------------------------------
|
||||
//
|
||||
// Most MuJoCo users can ignore these functions, the following comments are aimed primarily at
|
||||
// MuJoCo developers.
|
||||
|
||||
//---------------------------------- Attachment ----------------------------------------------------
|
||||
|
||||
// Attach child body to a parent frame, return 0 on success.
|
||||
MJAPI int mjs_attachBody(mjsFrame* parent, const mjsBody* child,
|
||||
const char* prefix, const char* suffix);
|
||||
|
||||
// Attach child frame to a parent body, return 0 on success.
|
||||
MJAPI int mjs_attachFrame(mjsBody* parent, const mjsFrame* child,
|
||||
const char* prefix, const char* suffix);
|
||||
|
||||
// Detach body from mjSpec, remove all references and delete the body, return 0 on success.
|
||||
MJAPI int mjs_detachBody(mjSpec* s, mjsBody* b);
|
||||
|
||||
|
||||
//---------------------------------- Tree elements -------------------------------------------------
|
||||
|
||||
// Add child body to body, return child.
|
||||
MJAPI mjsBody* mjs_addBody(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add site to body, return site spec.
|
||||
MJAPI mjsSite* mjs_addSite(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add joint to body.
|
||||
MJAPI mjsJoint* mjs_addJoint(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add freejoint to body.
|
||||
MJAPI mjsJoint* mjs_addFreeJoint(mjsBody* body);
|
||||
|
||||
// Add geom to body.
|
||||
MJAPI mjsGeom* mjs_addGeom(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add camera to body.
|
||||
MJAPI mjsCamera* mjs_addCamera(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add light to body.
|
||||
MJAPI mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def);
|
||||
|
||||
// Add frame to body.
|
||||
MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe);
|
||||
|
||||
// Delete object corresponding to the given element.
|
||||
MJAPI void mjs_delete(mjsElement* element);
|
||||
|
||||
|
||||
//---------------------------------- Non-tree elements ---------------------------------------------
|
||||
|
||||
// Add actuator.
|
||||
MJAPI mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* def);
|
||||
|
||||
// Add sensor.
|
||||
MJAPI mjsSensor* mjs_addSensor(mjSpec* s);
|
||||
|
||||
// Add flex.
|
||||
MJAPI mjsFlex* mjs_addFlex(mjSpec* s);
|
||||
|
||||
// Add contact pair.
|
||||
MJAPI mjsPair* mjs_addPair(mjSpec* s, mjsDefault* def);
|
||||
|
||||
// Add excluded body pair.
|
||||
MJAPI mjsExclude* mjs_addExclude(mjSpec* s);
|
||||
|
||||
// Add equality.
|
||||
MJAPI mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* def);
|
||||
|
||||
// Add tendon.
|
||||
MJAPI mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* def);
|
||||
|
||||
// Wrap site using tendon.
|
||||
MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendon, const char* name);
|
||||
|
||||
// Wrap geom using tendon.
|
||||
MJAPI mjsWrap* mjs_wrapGeom(mjsTendon* tendon, const char* name, const char* sidesite);
|
||||
|
||||
// Wrap joint using tendon.
|
||||
MJAPI mjsWrap* mjs_wrapJoint(mjsTendon* tendon, const char* name, double coef);
|
||||
|
||||
// Wrap pulley using tendon.
|
||||
MJAPI mjsWrap* mjs_wrapPulley(mjsTendon* tendon, double divisor);
|
||||
|
||||
// Add numeric.
|
||||
MJAPI mjsNumeric* mjs_addNumeric(mjSpec* s);
|
||||
|
||||
// Add text.
|
||||
MJAPI mjsText* mjs_addText(mjSpec* s);
|
||||
|
||||
// Add tuple.
|
||||
MJAPI mjsTuple* mjs_addTuple(mjSpec* s);
|
||||
|
||||
// Add keyframe.
|
||||
MJAPI mjsKey* mjs_addKey(mjSpec* s);
|
||||
|
||||
// Add plugin.
|
||||
MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s);
|
||||
|
||||
// Add default.
|
||||
MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id);
|
||||
|
||||
|
||||
//---------------------------------- Assets --------------------------------------------------------
|
||||
|
||||
// Add mesh.
|
||||
MJAPI mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def);
|
||||
|
||||
// Add height field.
|
||||
MJAPI mjsHField* mjs_addHField(mjSpec* s);
|
||||
|
||||
// Add skin.
|
||||
MJAPI mjsSkin* mjs_addSkin(mjSpec* s);
|
||||
|
||||
// Add texture.
|
||||
MJAPI mjsTexture* mjs_addTexture(mjSpec* s);
|
||||
|
||||
// Add material.
|
||||
MJAPI mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* def);
|
||||
|
||||
|
||||
//---------------------------------- Find and get utilities ----------------------------------------
|
||||
|
||||
// Get spec from body.
|
||||
MJAPI mjSpec* mjs_getSpec(mjsBody* body);
|
||||
|
||||
// Find body in model by name.
|
||||
MJAPI mjsBody* mjs_findBody(mjSpec* s, const char* name);
|
||||
|
||||
// Find child body by name.
|
||||
MJAPI mjsBody* mjs_findChild(mjsBody* body, const char* name);
|
||||
|
||||
// Find mesh by name.
|
||||
MJAPI mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
|
||||
|
||||
// Find frame by name.
|
||||
MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
||||
|
||||
// Get default corresponding to an element.
|
||||
MJAPI mjsDefault* mjs_getDefault(mjsElement* element);
|
||||
|
||||
// Find default in model by class name.
|
||||
MJAPI mjsDefault* mjs_findDefault(mjSpec* s, const char* classname);
|
||||
|
||||
// Get global default from model.
|
||||
MJAPI mjsDefault* mjs_getSpecDefault(mjSpec* s);
|
||||
|
||||
// Get element id.
|
||||
MJAPI int mjs_getId(mjsElement* element);
|
||||
|
||||
// Return body's first child of given type.
|
||||
MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
||||
|
||||
// Return body's next child of the same type; return NULL if child is last.
|
||||
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
||||
|
||||
|
||||
//---------------------------------- Attribute setters ---------------------------------------------
|
||||
|
||||
// Copy text to string.
|
||||
MJAPI void mjs_setString(mjString* dest, const char* text);
|
||||
|
||||
// Split text to entries and copy to string vector.
|
||||
MJAPI void mjs_setStringVec(mjStringVec* dest, const char* text);
|
||||
|
||||
// Set entry in string vector.
|
||||
MJAPI mjtByte mjs_setInStringVec(mjStringVec* dest, int i, const char* text);
|
||||
|
||||
// Append text entry to string vector.
|
||||
MJAPI void mjs_appendString(mjStringVec* dest, const char* text);
|
||||
|
||||
// Copy int array to vector.
|
||||
MJAPI void mjs_setInt(mjIntVec* dest, const int* array, int size);
|
||||
|
||||
// Append int array to vector of arrays.
|
||||
MJAPI void mjs_appendIntVec(mjIntVecVec* dest, const int* array, int size);
|
||||
|
||||
// Copy float array to vector.
|
||||
MJAPI void mjs_setFloat(mjFloatVec* dest, const float* array, int size);
|
||||
|
||||
// Append float array to vector of arrays.
|
||||
MJAPI void mjs_appendFloatVec(mjFloatVecVec* dest, const float* array, int size);
|
||||
|
||||
// Copy double array to vector.
|
||||
MJAPI void mjs_setDouble(mjDoubleVec* dest, const double* array, int size);
|
||||
|
||||
// Set plugin attributes.
|
||||
MJAPI void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes);
|
||||
|
||||
|
||||
//---------------------------------- Attribute getters ---------------------------------------------
|
||||
|
||||
// Get string contents.
|
||||
MJAPI const char* mjs_getString(const mjString* source);
|
||||
|
||||
// Get double array contents and optionally its size.
|
||||
MJAPI const double* mjs_getDouble(const mjDoubleVec* source, int* size);
|
||||
|
||||
|
||||
//---------------------------------- Spec utilities ------------------------------------------------
|
||||
|
||||
// Set active plugins.
|
||||
MJAPI void mjs_setActivePlugins(mjSpec* s, void* activeplugins);
|
||||
|
||||
// Set element's default.
|
||||
MJAPI void mjs_setDefault(mjsElement* element, mjsDefault* def);
|
||||
|
||||
// Set element's enlcosing frame.
|
||||
MJAPI void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
||||
|
||||
// Resolve alternative orientations to quat, return error if any.
|
||||
MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
||||
const mjsOrientation* orientation);
|
||||
|
||||
// Compute quat and diag inertia from full inertia matrix, return error if any.
|
||||
MJAPI const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]);
|
||||
|
||||
|
||||
//---------------------------------- Element initialization ---------------------------------------
|
||||
|
||||
// Default spec attributes.
|
||||
MJAPI void mjs_defaultSpec(mjSpec* spec);
|
||||
|
||||
// Default orientation attributes.
|
||||
MJAPI void mjs_defaultOrientation(mjsOrientation* orient);
|
||||
|
||||
// Default body attributes.
|
||||
MJAPI void mjs_defaultBody(mjsBody* body);
|
||||
|
||||
// Default frame attributes.
|
||||
MJAPI void mjs_defaultFrame(mjsFrame* frame);
|
||||
|
||||
// Default joint attributes.
|
||||
MJAPI void mjs_defaultJoint(mjsJoint* joint);
|
||||
|
||||
// Default geom attributes.
|
||||
MJAPI void mjs_defaultGeom(mjsGeom* geom);
|
||||
|
||||
// Default site attributes.
|
||||
MJAPI void mjs_defaultSite(mjsSite* site);
|
||||
|
||||
// Default camera attributes.
|
||||
MJAPI void mjs_defaultCamera(mjsCamera* camera);
|
||||
|
||||
// Default light attributes.
|
||||
MJAPI void mjs_defaultLight(mjsLight* light);
|
||||
|
||||
// Default flex attributes.
|
||||
MJAPI void mjs_defaultFlex(mjsFlex* flex);
|
||||
|
||||
// Default mesh attributes.
|
||||
MJAPI void mjs_defaultMesh(mjsMesh* mesh);
|
||||
|
||||
// Default height field attributes.
|
||||
MJAPI void mjs_defaultHField(mjsHField* hfield);
|
||||
|
||||
// Default skin attributes.
|
||||
MJAPI void mjs_defaultSkin(mjsSkin* skin);
|
||||
|
||||
// Default texture attributes.
|
||||
MJAPI void mjs_defaultTexture(mjsTexture* texture);
|
||||
|
||||
// Default material attributes.
|
||||
MJAPI void mjs_defaultMaterial(mjsMaterial* material);
|
||||
|
||||
// Default pair attributes.
|
||||
MJAPI void mjs_defaultPair(mjsPair* pair);
|
||||
|
||||
// Default equality attributes.
|
||||
MJAPI void mjs_defaultEquality(mjsEquality* equality);
|
||||
|
||||
// Default tendon attributes.
|
||||
MJAPI void mjs_defaultTendon(mjsTendon* tendon);
|
||||
|
||||
// Default actuator attributes.
|
||||
MJAPI void mjs_defaultActuator(mjsActuator* actuator);
|
||||
|
||||
// Default sensor attributes.
|
||||
MJAPI void mjs_defaultSensor(mjsSensor* sensor);
|
||||
|
||||
// Default numeric attributes.
|
||||
MJAPI void mjs_defaultNumeric(mjsNumeric* numeric);
|
||||
|
||||
// Default text attributes.
|
||||
MJAPI void mjs_defaultText(mjsText* text);
|
||||
|
||||
// Default tuple attributes.
|
||||
MJAPI void mjs_defaultTuple(mjsTuple* tuple);
|
||||
|
||||
// Default keyframe attributes.
|
||||
MJAPI void mjs_defaultKey(mjsKey* key);
|
||||
|
||||
// Default plugin attributes.
|
||||
MJAPI void mjs_defaultPlugin(mjsPlugin* plugin);
|
||||
|
||||
|
||||
//---------------------------------- Sanitizer instrumentation -------------------------------------
|
||||
|
||||
// Most users can ignore these functions, the following comments are primarily for developers.
|
||||
//
|
||||
// When built and run under address sanitizer (asan), mj_markStack and mj_freeStack are instrumented
|
||||
// to detect leakage of mjData stack frames. When the compiler inlines several callees that call
|
||||
|
||||
Reference in New Issue
Block a user