From 705ec6d7fba8ff6f37c74a85c795e0bee3bf874a Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Tue, 5 Aug 2025 07:01:52 -0700 Subject: [PATCH] Adds built-in superellipsoid mesh. PiperOrigin-RevId: 791196831 Change-Id: I1d864f6e620870f016377a4d9e2e26d1a23fd77e --- doc/XMLreference.rst | 9 + doc/includes/references.h | 1 + include/mujoco/mjspec.h | 1 + python/mujoco/introspect/enums.py | 7 +- python/mujoco/specs.cc | 9 + python/mujoco/specs_test.py | 8 +- src/user/user_api.cc | 24 +++ src/user/user_mesh.cc | 62 +++++++ src/user/user_objects.h | 1 + src/xml/xml_native_reader.cc | 259 ++++++++++++++------------- test/user/testdata/makemesh.xml | 2 + unity/Runtime/Bindings/MjBindings.cs | 7 +- 12 files changed, 253 insertions(+), 137 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 87879764..7e3e1afd 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -1348,6 +1348,15 @@ The full list of processing steps applied by the compiler to each mesh is as fol **nvert**: integer >= 3: The number vertices in the polygon. |br| **radius**: real in [0, 1]: The radius of the top face. + :at-val:`supersphere` (resolution, e, n) + A generalization of a sphere, also known as a superellipsoid (we use "supersphere" since semiaxis rescaling is + performed by the :ref:`scale` attribute). If the **n** and **e** parameters are both 1, the + shape is a sphere. See `here `__ for the definition of superspheres. + + **resolution** integer >= 4: The discretization of both major and minor radii. + |br| **e**: real >= 0: The "east-west" exponent. + |br| **n**: real >= 0: The "north-south" exponent. + :at-val:`supertorus` (resolution, radius, s, t) A generalization of a torus with major radius of 1 and given minor radius. If the **s** and **t** parameters are both 1, the shape is a torus. See `here `__ for details regarding diff --git a/doc/includes/references.h b/doc/includes/references.h index 6cb4f586..97e6c302 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -1789,6 +1789,7 @@ typedef enum mjtMeshBuiltin_ { // type of built-in procedural mesh mjMESH_BUILTIN_SPHERE, // sphere mjMESH_BUILTIN_HEMISPHERE, // hemisphere mjMESH_BUILTIN_CONE, // cone + mjMESH_BUILTIN_SUPERSPHERE, // supersphere mjMESH_BUILTIN_SUPERTORUS, // supertorus mjMESH_BUILTIN_WEDGE, // wedge mjMESH_BUILTIN_PLATE, // plate diff --git a/include/mujoco/mjspec.h b/include/mujoco/mjspec.h index d0a9f2d2..222c4fd0 100644 --- a/include/mujoco/mjspec.h +++ b/include/mujoco/mjspec.h @@ -75,6 +75,7 @@ typedef enum mjtMeshBuiltin_ { // type of built-in procedural mesh mjMESH_BUILTIN_SPHERE, // sphere mjMESH_BUILTIN_HEMISPHERE, // hemisphere mjMESH_BUILTIN_CONE, // cone + mjMESH_BUILTIN_SUPERSPHERE, // supersphere mjMESH_BUILTIN_SUPERTORUS, // supertorus mjMESH_BUILTIN_WEDGE, // wedge mjMESH_BUILTIN_PLATE, // plate diff --git a/python/mujoco/introspect/enums.py b/python/mujoco/introspect/enums.py index 00ce1084..def37a49 100644 --- a/python/mujoco/introspect/enums.py +++ b/python/mujoco/introspect/enums.py @@ -801,9 +801,10 @@ ENUMS: Mapping[str, EnumDecl] = dict([ ('mjMESH_BUILTIN_SPHERE', 1), ('mjMESH_BUILTIN_HEMISPHERE', 2), ('mjMESH_BUILTIN_CONE', 3), - ('mjMESH_BUILTIN_SUPERTORUS', 4), - ('mjMESH_BUILTIN_WEDGE', 5), - ('mjMESH_BUILTIN_PLATE', 6), + ('mjMESH_BUILTIN_SUPERSPHERE', 4), + ('mjMESH_BUILTIN_SUPERTORUS', 5), + ('mjMESH_BUILTIN_WEDGE', 6), + ('mjMESH_BUILTIN_PLATE', 7), ]), )), ('mjtBuiltin', diff --git a/python/mujoco/specs.cc b/python/mujoco/specs.cc index b6d804c8..3094a28b 100644 --- a/python/mujoco/specs.cc +++ b/python/mujoco/specs.cc @@ -1041,6 +1041,15 @@ PYBIND11_MODULE(_specs, m) { } }, py::arg("nedge"), py::arg("radius")); + mjsMesh.def( + "make_supersphere", + [](raw::MjsMesh* self, int resolution, double e, double n) { + double params[3] = {static_cast(resolution), e, n}; + if (mjs_makeMesh(self, mjMESH_BUILTIN_SUPERSPHERE, params, 3)) { + throw pybind11::value_error(mjs_getError(mjs_getSpec(self->element))); + } + }, + py::arg("resolution"), py::arg("e"), py::arg("n")); mjsMesh.def( "make_supertorus", [](raw::MjsMesh* self, int resolution, double radius, double s, diff --git a/python/mujoco/specs_test.py b/python/mujoco/specs_test.py index 65c25cd3..602778f2 100644 --- a/python/mujoco/specs_test.py +++ b/python/mujoco/specs_test.py @@ -502,17 +502,21 @@ class SpecsTest(absltest.TestCase): mesh = spec.add_mesh(name='sphere') mesh.make_sphere(subdivision=2) - mesh = spec.add_mesh(name='supertoroid') + mesh = spec.add_mesh(name='supertorus') mesh.make_supertorus(resolution=10, radius=0.5, s=1, t=1) + mesh = spec.add_mesh(name='supersphere') + mesh.make_supersphere(resolution=20, e=2, n=1) + model = spec.compile() - self.assertEqual(model.nmesh, 6) + self.assertEqual(model.nmesh, 7) self.assertEqual(model.mesh_vertnum[0], 25 * 25) self.assertEqual(model.mesh_vertnum[1], 10) self.assertEqual(model.mesh_vertnum[2], 7) self.assertEqual(model.mesh_vertnum[3], 2 * (4 + 1) * (4 + 2) + 2) self.assertEqual(model.mesh_vertnum[4], 2 + 10 * 4**2) self.assertEqual(model.mesh_vertnum[5], 100) + self.assertEqual(model.mesh_vertnum[6], 20 * (20 -1) + 2) def test_compile_errors_with_line_info(self): spec = mujoco.MjSpec() diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 8aaa58a2..5b25d542 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -542,6 +542,30 @@ int mjs_makeMesh(mjsMesh* mesh, mjtMeshBuiltin builtin, double* params, int npar return 0; } + case mjMESH_BUILTIN_SUPERSPHERE: { + if (nparams != 3) { + m->SetError(mjCError(0, "Supersphere mesh type requires 3 parameters")); + return -1; + } + int res = static_cast(params[0]); + if (res < 3) { + m->SetError(mjCError(0, "Supersphere resolution must be greater than 2")); + return -1; + } + double e = params[1]; + if (e < 0) { + m->SetError(mjCError(0, "Supersphere 'e' cannot be negative")); + return -1; + } + double n = params[2]; + if (n < 0) { + m->SetError(mjCError(0, "Supersphere 'n' cannot be negative")); + return -1; + } + meshC->MakeSupersphere(res, e, n); + return 0; + } + case mjMESH_BUILTIN_SUPERTORUS: { if (nparams != 4) { m->SetError(mjCError(0, "Supertorus mesh type requires 4 parameters")); diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 26608368..28141de7 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -2292,6 +2292,68 @@ void mjCMesh::MakeSphere(int subdiv, bool make_faces) { +// make a mesh of a supersphere +void mjCMesh::MakeSupersphere(int res, double e, double n) { + // allocate vertices and faces + int nvert = (res - 1) * res + 2; + int nface = 2 * res * (res - 1); + std::vector vert; + vert.reserve(3 * nvert); + std::vector face; + face.reserve(3 * nface); + + // south pole + vert.insert(vert.end(), {0.0f, 0.0f, -1.0f}); + + // rings + for (int i = 1; i < res; i++) { + double v = -mjPI/2 + i * mjPI / res; + for (int j = 0; j < res; j++) { + double u = -mjPI + j * 2 * mjPI / res; + vert.push_back(aux_c(v, n) * aux_c(u, e)); + vert.push_back(aux_c(v, n) * aux_s(u, e)); + vert.push_back(aux_s(v, n)); + } + } + + // north pole + vert.insert(vert.end(), {0.0f, 0.0f, 1.0f}); + + // south pole faces + for (int j = 0; j < res; j++) { + int v2 = 1 + j; + int v3 = 1 + (j + 1) % res; + face.insert(face.end(), {0, v3, v2}); + } + + // ring faces + for (int i = 0; i < res - 2; i++) { + for (int j = 0; j < res; j++) { + int v1 = 1 + i * res + j; + int v2 = 1 + i * res + (j + 1) % res; + int v4 = 1 + (i + 1) * res + j; + int v3 = 1 + (i + 1) * res + (j + 1) % res; + face.insert(face.end(), {v1, v2, v4}); + face.insert(face.end(), {v2, v3, v4}); + } + } + + // north pole faces + int north_pole_idx = nvert - 1; + int last_ring_start_idx = 1 + (res - 2) * res; + for (int j = 0; j < res; j++) { + int v1 = last_ring_start_idx + j; + int v2 = last_ring_start_idx + (j + 1) % res; + face.insert(face.end(), {v1, v2, north_pole_idx}); + } + + // save vertices and faces + mjs_setFloat(spec.uservert, vert.data(), vert.size()); + mjs_setInt(spec.userface, face.data(), face.size()); +} + + + // make a mesh of a torus (subsumed by supertorus, kept for reference only) void mjCMesh::MakeTorus(int res, double radius) { // allocate vertices and faces diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 4ab174c0..16d70763 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -1055,6 +1055,7 @@ class mjCMesh: public mjCMesh_, private mjsMesh { void MakeSphere(int subdiv, bool make_faces); void MakeTorus(int res, double radius); void MakeSupertorus(int res, double radius, double s, double t); + void MakeSupersphere(int res, double e, double n); void MakeWedge(int resolution[2], double fov[2], double gamma); void MakeRect(int resolution[2]); void MakeCone(int nedge, double radius); diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index b0e28972..d2de7d74 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -557,24 +557,24 @@ const mjMap TFAuto_map[3] = { // joint type const int joint_sz = 4; const mjMap joint_map[joint_sz] = { - {"free", mjJNT_FREE}, - {"ball", mjJNT_BALL}, - {"slide", mjJNT_SLIDE}, - {"hinge", mjJNT_HINGE} + {"free", mjJNT_FREE}, + {"ball", mjJNT_BALL}, + {"slide", mjJNT_SLIDE}, + {"hinge", mjJNT_HINGE} }; // geom type const mjMap geom_map[mjNGEOMTYPES] = { - {"plane", mjGEOM_PLANE}, - {"hfield", mjGEOM_HFIELD}, - {"sphere", mjGEOM_SPHERE}, - {"capsule", mjGEOM_CAPSULE}, - {"ellipsoid", mjGEOM_ELLIPSOID}, - {"cylinder", mjGEOM_CYLINDER}, - {"box", mjGEOM_BOX}, - {"mesh", mjGEOM_MESH}, - {"sdf", mjGEOM_SDF} + {"plane", mjGEOM_PLANE}, + {"hfield", mjGEOM_HFIELD}, + {"sphere", mjGEOM_SPHERE}, + {"capsule", mjGEOM_CAPSULE}, + {"ellipsoid", mjGEOM_ELLIPSOID}, + {"cylinder", mjGEOM_CYLINDER}, + {"box", mjGEOM_BOX}, + {"mesh", mjGEOM_MESH}, + {"sdf", mjGEOM_SDF} }; @@ -617,267 +617,268 @@ const mjMap texrole_map[texrole_sz] = { // integrator type const int integrator_sz = 4; const mjMap integrator_map[integrator_sz] = { - {"Euler", mjINT_EULER}, - {"RK4", mjINT_RK4}, - {"implicit", mjINT_IMPLICIT}, - {"implicitfast", mjINT_IMPLICITFAST} + {"Euler", mjINT_EULER}, + {"RK4", mjINT_RK4}, + {"implicit", mjINT_IMPLICIT}, + {"implicitfast", mjINT_IMPLICITFAST} }; // cone type const int cone_sz = 2; const mjMap cone_map[cone_sz] = { - {"pyramidal", mjCONE_PYRAMIDAL}, - {"elliptic", mjCONE_ELLIPTIC} + {"pyramidal", mjCONE_PYRAMIDAL}, + {"elliptic", mjCONE_ELLIPTIC} }; // Jacobian type const int jac_sz = 3; const mjMap jac_map[jac_sz] = { - {"dense", mjJAC_DENSE}, - {"sparse", mjJAC_SPARSE}, - {"auto", mjJAC_AUTO} + {"dense", mjJAC_DENSE}, + {"sparse", mjJAC_SPARSE}, + {"auto", mjJAC_AUTO} }; // solver type const int solver_sz = 3; const mjMap solver_map[solver_sz] = { - {"PGS", mjSOL_PGS}, - {"CG", mjSOL_CG}, - {"Newton", mjSOL_NEWTON} + {"PGS", mjSOL_PGS}, + {"CG", mjSOL_CG}, + {"Newton", mjSOL_NEWTON} }; // constraint type const int equality_sz = 6; const mjMap equality_map[equality_sz] = { - {"connect", mjEQ_CONNECT}, - {"weld", mjEQ_WELD}, - {"joint", mjEQ_JOINT}, - {"tendon", mjEQ_TENDON}, - {"flex", mjEQ_FLEX}, - {"distance", mjEQ_DISTANCE} + {"connect", mjEQ_CONNECT}, + {"weld", mjEQ_WELD}, + {"joint", mjEQ_JOINT}, + {"tendon", mjEQ_TENDON}, + {"flex", mjEQ_FLEX}, + {"distance", mjEQ_DISTANCE} }; // type for texture const int texture_sz = 3; const mjMap texture_map[texture_sz] = { - {"2d", mjTEXTURE_2D}, - {"cube", mjTEXTURE_CUBE}, - {"skybox", mjTEXTURE_SKYBOX} + {"2d", mjTEXTURE_2D}, + {"cube", mjTEXTURE_CUBE}, + {"skybox", mjTEXTURE_SKYBOX} }; // colorspace for texture const int colorspace_sz = 3; const mjMap colorspace_map[colorspace_sz] = { - {"auto", mjCOLORSPACE_AUTO}, - {"linear", mjCOLORSPACE_LINEAR}, - {"sRGB", mjCOLORSPACE_SRGB} + {"auto", mjCOLORSPACE_AUTO}, + {"linear", mjCOLORSPACE_LINEAR}, + {"sRGB", mjCOLORSPACE_SRGB} }; // builtin type for texture const int builtin_sz = 4; const mjMap builtin_map[builtin_sz] = { - {"none", mjBUILTIN_NONE}, - {"gradient", mjBUILTIN_GRADIENT}, - {"checker", mjBUILTIN_CHECKER}, - {"flat", mjBUILTIN_FLAT} + {"none", mjBUILTIN_NONE}, + {"gradient", mjBUILTIN_GRADIENT}, + {"checker", mjBUILTIN_CHECKER}, + {"flat", mjBUILTIN_FLAT} }; // mark type for texture const int mark_sz = 4; const mjMap mark_map[mark_sz] = { - {"none", mjMARK_NONE}, - {"edge", mjMARK_EDGE}, - {"cross", mjMARK_CROSS}, - {"random", mjMARK_RANDOM} + {"none", mjMARK_NONE}, + {"edge", mjMARK_EDGE}, + {"cross", mjMARK_CROSS}, + {"random", mjMARK_RANDOM} }; // dyn type const int dyn_sz = 6; const mjMap dyn_map[dyn_sz] = { - {"none", mjDYN_NONE}, - {"integrator", mjDYN_INTEGRATOR}, - {"filter", mjDYN_FILTER}, - {"filterexact", mjDYN_FILTEREXACT}, - {"muscle", mjDYN_MUSCLE}, - {"user", mjDYN_USER} + {"none", mjDYN_NONE}, + {"integrator", mjDYN_INTEGRATOR}, + {"filter", mjDYN_FILTER}, + {"filterexact", mjDYN_FILTEREXACT}, + {"muscle", mjDYN_MUSCLE}, + {"user", mjDYN_USER} }; // gain type const int gain_sz = 4; const mjMap gain_map[gain_sz] = { - {"fixed", mjGAIN_FIXED}, - {"affine", mjGAIN_AFFINE}, - {"muscle", mjGAIN_MUSCLE}, - {"user", mjGAIN_USER} + {"fixed", mjGAIN_FIXED}, + {"affine", mjGAIN_AFFINE}, + {"muscle", mjGAIN_MUSCLE}, + {"user", mjGAIN_USER} }; // bias type const int bias_sz = 4; const mjMap bias_map[bias_sz] = { - {"none", mjBIAS_NONE}, - {"affine", mjBIAS_AFFINE}, - {"muscle", mjBIAS_MUSCLE}, - {"user", mjBIAS_USER} + {"none", mjBIAS_NONE}, + {"affine", mjBIAS_AFFINE}, + {"muscle", mjBIAS_MUSCLE}, + {"user", mjBIAS_USER} }; // stage type const int stage_sz = 4; const mjMap stage_map[stage_sz] = { - {"none", mjSTAGE_NONE}, - {"pos", mjSTAGE_POS}, - {"vel", mjSTAGE_VEL}, - {"acc", mjSTAGE_ACC} + {"none", mjSTAGE_NONE}, + {"pos", mjSTAGE_POS}, + {"vel", mjSTAGE_VEL}, + {"acc", mjSTAGE_ACC} }; // data type const int datatype_sz = 4; const mjMap datatype_map[datatype_sz] = { - {"real", mjDATATYPE_REAL}, - {"positive", mjDATATYPE_POSITIVE}, - {"axis", mjDATATYPE_AXIS}, - {"quaternion", mjDATATYPE_QUATERNION} + {"real", mjDATATYPE_REAL}, + {"positive", mjDATATYPE_POSITIVE}, + {"axis", mjDATATYPE_AXIS}, + {"quaternion", mjDATATYPE_QUATERNION} }; // contact data type const mjMap condata_map[mjNCONDATA] = { - {"found", mjCONDATA_FOUND}, - {"force", mjCONDATA_FORCE}, - {"torque", mjCONDATA_TORQUE}, - {"dist", mjCONDATA_DIST}, - {"pos", mjCONDATA_POS}, - {"normal", mjCONDATA_NORMAL}, - {"tangent", mjCONDATA_TANGENT} + {"found", mjCONDATA_FOUND}, + {"force", mjCONDATA_FORCE}, + {"torque", mjCONDATA_TORQUE}, + {"dist", mjCONDATA_DIST}, + {"pos", mjCONDATA_POS}, + {"normal", mjCONDATA_NORMAL}, + {"tangent", mjCONDATA_TANGENT} }; // contact reduction type const int reduce_sz = 4; const mjMap reduce_map[reduce_sz] = { - {"none", 0}, - {"mindist", 1}, - {"maxforce", 2}, - {"netforce", 3} + {"none", 0}, + {"mindist", 1}, + {"maxforce", 2}, + {"netforce", 3} }; // LR mode const int lrmode_sz = 4; const mjMap lrmode_map[lrmode_sz] = { - {"none", mjLRMODE_NONE}, - {"muscle", mjLRMODE_MUSCLE}, - {"muscleuser", mjLRMODE_MUSCLEUSER}, - {"all", mjLRMODE_ALL} + {"none", mjLRMODE_NONE}, + {"muscle", mjLRMODE_MUSCLE}, + {"muscleuser", mjLRMODE_MUSCLEUSER}, + {"all", mjLRMODE_ALL} }; // composite type const mjMap comp_map[mjNCOMPTYPES] = { - {"particle", mjCOMPTYPE_PARTICLE}, - {"grid", mjCOMPTYPE_GRID}, - {"rope", mjCOMPTYPE_ROPE}, - {"loop", mjCOMPTYPE_LOOP}, - {"cable", mjCOMPTYPE_CABLE}, - {"cloth", mjCOMPTYPE_CLOTH} + {"particle", mjCOMPTYPE_PARTICLE}, + {"grid", mjCOMPTYPE_GRID}, + {"rope", mjCOMPTYPE_ROPE}, + {"loop", mjCOMPTYPE_LOOP}, + {"cable", mjCOMPTYPE_CABLE}, + {"cloth", mjCOMPTYPE_CLOTH} }; // composite joint kind const mjMap jkind_map[1] = { - {"main", mjCOMPKIND_JOINT} + {"main", mjCOMPKIND_JOINT} }; // composite rope shape const mjMap shape_map[mjNCOMPSHAPES] = { - {"s", mjCOMPSHAPE_LINE}, - {"cos(s)", mjCOMPSHAPE_COS}, - {"sin(s)", mjCOMPSHAPE_SIN}, - {"0", mjCOMPSHAPE_ZERO} + {"s", mjCOMPSHAPE_LINE}, + {"cos(s)", mjCOMPSHAPE_COS}, + {"sin(s)", mjCOMPSHAPE_SIN}, + {"0", mjCOMPSHAPE_ZERO} }; // mesh type const mjMap meshtype_map[2] = { - {"false", mjINERTIA_VOLUME}, - {"true", mjINERTIA_SHELL}, + {"false", mjINERTIA_VOLUME}, + {"true", mjINERTIA_SHELL}, }; // mesh inertia type const mjMap meshinertia_map[4] = { - {"convex", mjMESH_INERTIA_CONVEX}, - {"legacy", mjMESH_INERTIA_LEGACY}, - {"exact", mjMESH_INERTIA_EXACT}, - {"shell", mjMESH_INERTIA_SHELL} + {"convex", mjMESH_INERTIA_CONVEX}, + {"legacy", mjMESH_INERTIA_LEGACY}, + {"exact", mjMESH_INERTIA_EXACT}, + {"shell", mjMESH_INERTIA_SHELL} }; // mesh builtin type -const int meshbuiltin_sz = 7; +const int meshbuiltin_sz = 8; const mjMap meshbuiltin_map[meshbuiltin_sz] = { - {"none", mjMESH_BUILTIN_NONE}, - {"sphere", mjMESH_BUILTIN_SPHERE}, - {"hemisphere", mjMESH_BUILTIN_HEMISPHERE}, - {"cone", mjMESH_BUILTIN_CONE}, - {"supertorus", mjMESH_BUILTIN_SUPERTORUS}, - {"wedge", mjMESH_BUILTIN_WEDGE}, - {"plate", mjMESH_BUILTIN_PLATE} + {"none", mjMESH_BUILTIN_NONE}, + {"sphere", mjMESH_BUILTIN_SPHERE}, + {"hemisphere", mjMESH_BUILTIN_HEMISPHERE}, + {"cone", mjMESH_BUILTIN_CONE}, + {"supertorus", mjMESH_BUILTIN_SUPERTORUS}, + {"supersphere", mjMESH_BUILTIN_SUPERSPHERE}, + {"wedge", mjMESH_BUILTIN_WEDGE}, + {"plate", mjMESH_BUILTIN_PLATE} }; // flexcomp type const mjMap fcomp_map[mjNFCOMPTYPES] = { - {"grid", mjFCOMPTYPE_GRID}, - {"box", mjFCOMPTYPE_BOX}, - {"cylinder", mjFCOMPTYPE_CYLINDER}, - {"ellipsoid", mjFCOMPTYPE_ELLIPSOID}, - {"square", mjFCOMPTYPE_SQUARE}, - {"disc", mjFCOMPTYPE_DISC}, - {"circle", mjFCOMPTYPE_CIRCLE}, - {"mesh", mjFCOMPTYPE_MESH}, - {"gmsh", mjFCOMPTYPE_GMSH}, - {"direct", mjFCOMPTYPE_DIRECT} + {"grid", mjFCOMPTYPE_GRID}, + {"box", mjFCOMPTYPE_BOX}, + {"cylinder", mjFCOMPTYPE_CYLINDER}, + {"ellipsoid", mjFCOMPTYPE_ELLIPSOID}, + {"square", mjFCOMPTYPE_SQUARE}, + {"disc", mjFCOMPTYPE_DISC}, + {"circle", mjFCOMPTYPE_CIRCLE}, + {"mesh", mjFCOMPTYPE_MESH}, + {"gmsh", mjFCOMPTYPE_GMSH}, + {"direct", mjFCOMPTYPE_DIRECT} }; // flexcomp dof type const mjMap fdof_map[mjNFCOMPDOFS] = { - {"full", mjFCOMPDOF_FULL}, - {"radial", mjFCOMPDOF_RADIAL}, - {"trilinear", mjFCOMPDOF_TRILINEAR} + {"full", mjFCOMPDOF_FULL}, + {"radial", mjFCOMPDOF_RADIAL}, + {"trilinear", mjFCOMPDOF_TRILINEAR} }; // flex selfcollide type const mjMap flexself_map[5] = { - {"none", mjFLEXSELF_NONE}, - {"narrow", mjFLEXSELF_NARROW}, - {"bvh", mjFLEXSELF_BVH}, - {"sap", mjFLEXSELF_SAP}, - {"auto", mjFLEXSELF_AUTO}, + {"none", mjFLEXSELF_NONE}, + {"narrow", mjFLEXSELF_NARROW}, + {"bvh", mjFLEXSELF_BVH}, + {"sap", mjFLEXSELF_SAP}, + {"auto", mjFLEXSELF_AUTO}, }; // flex elastic 2d type const mjMap elastic2d_map[5] = { - {"none", 0}, - {"bend", 1}, - {"stretch", 2}, - {"both", 3}, + {"none", 0}, + {"bend", 1}, + {"stretch", 2}, + {"both", 3}, }; diff --git a/test/user/testdata/makemesh.xml b/test/user/testdata/makemesh.xml index dcdaead8..9394c58e 100644 --- a/test/user/testdata/makemesh.xml +++ b/test/user/testdata/makemesh.xml @@ -2,6 +2,7 @@ + @@ -14,6 +15,7 @@ + diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 951aa60f..9b131bcb 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -502,9 +502,10 @@ public enum mjtMeshBuiltin : int{ mjMESH_BUILTIN_SPHERE = 1, mjMESH_BUILTIN_HEMISPHERE = 2, mjMESH_BUILTIN_CONE = 3, - mjMESH_BUILTIN_SUPERTORUS = 4, - mjMESH_BUILTIN_WEDGE = 5, - mjMESH_BUILTIN_PLATE = 6, + mjMESH_BUILTIN_SUPERSPHERE = 4, + mjMESH_BUILTIN_SUPERTORUS = 5, + mjMESH_BUILTIN_WEDGE = 6, + mjMESH_BUILTIN_PLATE = 7, } public enum mjtBuiltin : int{ mjBUILTIN_NONE = 0,