Skip to content

No Mesh-mesh collision in mujoco-mjxΒ #2759

@boshi-an

Description

@boshi-an

Intro

I am using mujoco-mjx 3.3.4 and found that mesh-mesh collisions are not available. Two meshes will penetrate each other. The mesh-primitive collision is working fine.

Here is a video of the penetration: video

You can reproduce with the code from this dropbox link

My setup

I pre-processed the mesh files so that each stl doesn't contain too many vertices, and all of them are convex.

My xml file:

<mujoco model="stage">
    <option gravity="0 0 -1"/>
    <asset>

        <mesh name="violin_body_1" file="violin/fingerboard-only-decomp-worst/mesh/body_1.stl" />
        <mesh name="violin_body_2" file="violin/fingerboard-only-decomp-worst/mesh/body_2.stl" />
        <mesh name="violin_body_3" file="violin/fingerboard-only-decomp-worst/mesh/body_3.stl" />
        <mesh name="violin_body_4" file="violin/fingerboard-only-decomp-worst/mesh/body_4.stl" />
        <mesh name="violin_visual" file="violin/raw_stl/violin1-coarse.stl"/>

        <mesh name="bow_body_0" file="bow/bow-convex-hull-worst/bow.stl" />

    </asset>
    <worldbody>
        <!-- Ground plane at z=0 -->
        <geom name="ground" type="plane" pos="0 0 -0.3" size="5 5 0.1" rgba="0.8 0.8 0.8 1"/>
        <!-- Side camera -->
        <camera name="front" pos="0 -0.8 0.8" xyaxes="1 0 0 0 1 1"/>
        <!-- <camera name="side" pos="-1.0 0 0.5" xyaxes="0 1 2 1 0 0"/> -->
        
        <!-- Overhead white light -->
        <light name="overhead" pos="0 0 3" dir="0 0 -1" diffuse="1 1 1" specular="0.3 0.3 0.3" />
        
        <!-- Warm side light -->
        <light name="side_warm" pos="3 3 1.5" dir="-1 -1 -0.5" diffuse="1 0.8 0.6" specular="0.2 0.2 0.1" />
        
        <!-- Cool back light -->
        <light name="back_cool" pos="-3 -3 4" dir="1 1 -1" diffuse="0.6 0.8 1" specular="0.1 0.2 0.3" />
        
        <body name="violin_on_stage" pos="0 0 0">

            <geom name="violin_body_1" pos="0 0 0" euler="0 0 0" contype="1" conaffinity="2" type="mesh" mesh="violin_body_1" />
            <geom name="violin_body_2" pos="0 0 0" euler="0 0 0" contype="1" conaffinity="2" type="mesh" mesh="violin_body_2" />
            <geom name="violin_body_3" pos="0 0 0" euler="0 0 0" contype="1" conaffinity="2" type="mesh" mesh="violin_body_3" />
            <geom name="violin_body_4" pos="0 0 0" euler="0 0 0" contype="1" conaffinity="2" type="mesh" mesh="violin_body_4" />

            <freejoint/>
        </body>
        
        <body name="bow_on_stage" pos="0.0 0.3 .2" euler="0 90 0">

            <geom name="bow_body_0" pos="0 0 0" euler="0 0 0" contype="2" conaffinity="1" type="mesh" mesh="bow_body_0" />

            <freejoint/>
        </body>

    </worldbody>
    <visual>
        <global offwidth="1920" offheight="1080"/>
    </visual>
</mujoco>

The dependencies:

Package              Version
-------------------- -----------
absl-py              2.3.1
asttokens            3.0.0
blinker              1.9.0
brax                 0.12.4
build                1.2.2.post1
chex                 0.1.89
click                8.2.1
cloudpickle          3.1.1
coacd                1.0.7
contourpy            1.3.2
cycler               0.12.1
decorator            5.2.1
etils                1.13.0
exceptiongroup       1.3.0
executing            2.2.0
Farama-Notifications 0.0.4
Flask                3.1.1
flask-cors           6.0.1
flax                 0.10.7
fonttools            4.59.0
fsspec               2025.7.0
glfw                 2.9.0
gymnasium            1.2.0
humanize             4.12.3
importlib_resources  6.5.2
ipdb                 0.13.13
ipython              8.37.0
itsdangerous         2.2.0
jax                  0.5.2
jaxlib               0.5.1
jaxopt               0.8.5
jedi                 0.19.2
Jinja2               3.1.6
kiwisolver           1.4.8
markdown-it-py       3.0.0
MarkupSafe           3.0.2
matplotlib           3.10.3
matplotlib-inline    0.1.7
mdurl                0.1.2
mediapy              1.2.4
ml_collections       1.1.0
ml_dtypes            0.5.1
msgpack              1.1.1
mujoco               3.3.4
mujoco-mjx           3.3.4
nest-asyncio         1.6.0
numpy                2.2.6
opt_einsum           3.4.0
optax                0.2.5
orbax-checkpoint     0.11.19
packaging            25.0
parso                0.8.4
pexpect              4.9.0
pillow               11.3.0
pip                  25.1
prompt_toolkit       3.0.51
protobuf             6.31.1
ptyprocess           0.7.0
pure_eval            0.2.3
Pygments             2.19.2
PyOpenGL             3.1.9
pyparsing            3.2.3
pyproject_hooks      1.2.0
python-dateutil      2.9.0.post0
PyYAML               6.0.2
rich                 14.0.0
scipy                1.15.3
setuptools           78.1.1
simplejson           3.20.1
six                  1.17.0
stack-data           0.6.3
tensorboardX         2.6.4
tensorstore          0.1.76
tomli                2.2.1
toolz                1.0.0
traitlets            5.14.3
treescope            0.1.9
trimesh              4.7.0
typing_extensions    4.14.1
wcwidth              0.2.13
Werkzeug             3.1.3
wheel                0.45.1
zipp                 3.23.0

What's happening? What did you expect?

The two bodies penetrated each other. I expect them to have collisions.

Steps for reproduction

Unzip the zip file from the dropbox link.

Run main_mjx.py in the folder.

Minimal model for reproduction

No response

Code required for reproduction

No response

Confirmations

Metadata

Metadata

Assignees

Labels

MJXUsing JAX to run on GPUbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions