Compare commits

...

2086 Commits

Author SHA1 Message Date
chenlin ac4f431ff5 Fix MuJoCo WASM loader imports
build / setup (compute matrix) (push) Has been cancelled
build / ${{ matrix.label }} (push) Has been cancelled
build / macos-15-arm64-studio (push) Has been cancelled
build / ubuntu-24.04-clang-18-studio (push) Has been cancelled
build / ubuntu-24.04-gcc-14-studio (push) Has been cancelled
build / windows-2025-ninja-studio (push) Has been cancelled
build / ubuntu-24.04-clang-18-wasm (push) Has been cancelled
build / ubuntu-24.04-clang-18-mjx (push) Has been cancelled
2026-08-19 17:04:30 +08:00
Yuval Tassa 3dd2bc3b52 Studio: Improve UI state saving and restoration
- Load settings prior to first frame so dockspace layout restores reliably.
- Save settings on exit in App::~App().
- Persist and restore open/closed state of collapsible sections.

PiperOrigin-RevId: 966657100
Change-Id: I64fb5d02912bb36d096d7ac26ce8e0de03e6617b
2026-08-18 10:03:13 -07:00
Google DeepMind a4f0afc012 Import Warp v1.16.0
PiperOrigin-RevId: 966641228
Change-Id: I3b55b6c607a4a09eb714304db27e62ed391c7f56
2026-08-18 09:36:06 -07:00
Michael Moss 021c804bf8 Update dependencies ahead of the 3.12.0 release.
PiperOrigin-RevId: 966530808
Change-Id: Idbab4c60a6aef063c02a0ec6de6176033f52fac1
2026-08-18 05:16:27 -07:00
Michael Moss 62f05c1e6f Cast mjx objtype_data lookup keys to int for pybind11 v1.18 compatibility.
PiperOrigin-RevId: 966503691
Change-Id: Ic1465aa8e13697d140a993a42294f661f1d1fb15
2026-08-18 04:01:55 -07:00
Hana Joo e3590b7449 Add pyrefly suppressions
PiperOrigin-RevId: 966501583
Change-Id: I942ec198b369fb4a2f430070ee1002e7ad2d0c9d
2026-08-18 03:55:35 -07:00
Michael Moss 06aa6c075f Cast mjx dict/set lookup enums to int for pybind11 v1.18 compatibility.
PiperOrigin-RevId: 966094569
Change-Id: I014226016df9d519f250d0fc25045064cd94cb1e
2026-08-17 11:47:46 -07:00
Taylor Howell 8847823721 update doc/mjwarp/update_types.py
PiperOrigin-RevId: 966037324
Change-Id: Iabc84fe3a871d6fdf8b6619ee048ac0273462d55
2026-08-17 10:09:11 -07:00
Haroon Qureshi 26aaeb035f Update FilamentRenderer to use mjrf primitives directly.
Removes the dependency on the SceneBridge.

PiperOrigin-RevId: 965964920
Change-Id: I7c9ff52c9f26b778fe1d017fbf12d5af38ce67c1
2026-08-17 07:45:29 -07:00
Kyle Bayes ec506dbde3 Add support to return variable distances in mjc_ccd. This is a no-op change.
PiperOrigin-RevId: 965949465
Change-Id: I099fe1b5dfd722958c339429ddffe33fb66759d2
2026-08-17 07:09:07 -07:00
Michael Moss 6c28e59d02 Remove float enum equality tests in preparation for pybind update.
PiperOrigin-RevId: 965938517
Change-Id: I57d395476358972b9005c7fd871ca89686320242
2026-08-17 06:42:04 -07:00
Yuval Tassa 3c823c5470 Fix inconsistent bullet indentation in changelog admonitions.
PiperOrigin-RevId: 965935062
Change-Id: I9f99ce00571d0062496383e345212beea914d52b
2026-08-17 06:33:18 -07:00
Yuval Tassa c232938233 Move the Simulation panel into the platform toolkit.
PiperOrigin-RevId: 965914672
Change-Id: Ib349b77055c57453780818dd4d8f48899b7024d5
2026-08-17 05:40:26 -07:00
Yuval Tassa 0fa066237a Zero out off-diagonal entries in Cholesky factorization when diagonal is below threshold.
PiperOrigin-RevId: 965909091
Change-Id: If13bf8089b16eb3e21bcc22f75d6ac1366407b36
2026-08-17 05:24:37 -07:00
Michael Moss bbdda5dda5 Update MuJoCo version to 3.12.0 in preparation for breaking changes release.
PiperOrigin-RevId: 965899864
Change-Id: I4fb90e357bed3d7f2f8d86e500aed53646c4b1ea
2026-08-17 05:01:33 -07:00
Copybara-Service 4c993fb238 Merge pull request #3432 from VihaanAgarwal:fix/convex-inertia-unreferenced-mesh
PiperOrigin-RevId: 965896711
Change-Id: I3254a621ef7689544130fd0ce43b86c0261f52b1
2026-08-17 04:52:41 -07:00
Yuval Tassa 90ac80707d Step the timestep and solver tolerances on a well-tempered log ladder
The timestep, the solver tolerances, and impratio span several orders of
magnitude, where a linear +/- step is useless. Add ImGui_LogStepper, whose
buttons walk a "well-tempered" logarithmic ladder of round numbers that
closes each decade on a power of ten (see WellTemperedStep). It lays out
like ImGui's own InputScalar stepper -- field, then the - / + buttons, then
the label.

Apply it to the timestep, Tolerance, the LS/Noslip/CCD/Sleep tolerances,
and Imp Ratio. Strictly-positive quantities for which zero is meaningful
(the tolerances) take a zero_below floor: the ladder's bottom rung is 0, so
stepping down snaps to zero and stepping up off zero returns to the floor.
The timestep and impratio, which never want zero, leave it unset.

PiperOrigin-RevId: 965888812
Change-Id: I823e60913ecb2be2cade96baa5bf7de9e2334d5a
2026-08-17 04:30:54 -07:00
Yuval Tassa ba3f8cf180 Improvements to object launcher.
PiperOrigin-RevId: 965834305
Change-Id: Ied8cea0e8eff8002d14f63b9ddea25f78a9a2985
2026-08-17 02:16:11 -07:00
Yuval Tassa 2f1843f4a7 Redesign the dcmotor controller: setpoint inputs, torque-space gains.
The dcmotor input block is any subset of the canonical list [pos, vel,
ff, voltage], selected with input="pos vel ff voltage" and recorded as
mjtCtrlInput bits in actuator_ctrlspec like pid. Tokens are required in
canonical order: the attribute denotes a set, the block always packs
canonically, and accepting permutations invites reading the string as a
layout choice. The mode flag in gainprm[8] is retired (reserved,
written 0).

Controller gains are now in torque space, as for pid: the controller
commands tau = kp*(q*-l) + kd*(v*-ldot) + ki*x_I + tau_ff over the
present inputs (absent setpoints frozen at zero) and converts to drive
voltage V = R/K * tau + K*ldot. The second term compensates back-EMF,
as the current loop of a real torque-mode driver does (torque commands
are current commands): commanded torque is delivered exactly until a
limit binds, and the torque-speed envelope emerges from the Vmax clamp.
The map uses the nameplate R: thermal resistance growth is not
compensated, so a hot motor under-delivers by R/R(T). A stateless
setpoint dcmotor now matches <pid> exactly, for any K and R; the old
back-EMF droop remains available as the physical behavior of the raw
voltage path. Voltage-space datasheet gains convert by K/R. Controller
inputs require a positive motor constant (the map divides by K), and
controller gains require a controller input.

ff and voltage are distinct inputs, different in kind: ff is a torque
feedforward added to the controller output, uniform with pid's ff
(feedforward in the actuator's output space), while voltage is the raw
terminal voltage of the physical device, injected downstream of the
controller and its Vmax clamp, unclamped (ctrlrange bounds it if
desired). input="voltage" is the default: the plain voltage-commanded
motor, whose behavior is unchanged by this commit. The integrator
always accumulates position error; the old velocity mode's integral
term, ki*(int(u)dt - theta), which tracked the integral of the velocity
command, is retired without replacement, keeping ki mode-independent --
commanded integrated velocity belongs to an integrator activation
state, not to controller gains. slewmax rate-limits the first controller
input -- position setpoint (rad/s), velocity setpoint (rad/s^2) or torque
feedforward (N*m/s), each a real driver feature (reference ramping,
ramped-velocity and ramped-torque input modes); the raw voltage input
is never rate-limited and slewmax requires a controller input.

input="none" selects the empty signature: the actuator owns no controls
at all (nu = 0 is now legal with actuators present) and is purely
passive -- LuGre friction, cogging and back-EMF braking as passive
joint forces. This exists because auxiliary dynamic states (the LuGre
bristle) attach to actuators, not joints. The terminal voltage is
identically zero, i.e. a shorted motor (dynamic braking); motorconst=0
decouples the electrical branch. mjINPUT_NONE is a distinct enum value
because ctrlspec = 0 means "unset, use the type default". History and
delay require an input; the controller voltage override and input read
in mj_fwdActuation are gated on a nonempty block.

The analytic velocity derivative of the controller becomes
dV/dw = -kd*R/K + K, whose second term cancels the back-EMF bias
exactly: the net damping of an unclipped torque-mode motor is -kd, and
of a voltage-mode or passive motor -K^2/R. Viewers label inputs via
mj_actuatorInputName: pos, vel, ff, voltage.

The dcmotor LaTeX design doc is updated accordingly: torque-space
units, the tau->V map and its saturation-generated envelope, the
input-block pipeline figure, and a Passive Operation section.

PiperOrigin-RevId: 965795351
Change-Id: Ibc308ca21bd6bad014e77f950ee08feaad449b73
2026-08-17 00:43:48 -07:00
Yuval Tassa 11fa4a5b45 Remove the redundant phong_2d reflection material
PiperOrigin-RevId: 965538926
Change-Id: I02a99016d5e69130e3827e898343b656f399ddfb
2026-08-16 07:56:51 -07:00
Yuval Tassa 68918d4f4d Fix textures over-tiling on meshes in Filament.
PiperOrigin-RevId: 965535047
Change-Id: I56177b7ac91591ba516bf96e317f57357539e776
2026-08-16 07:38:42 -07:00
Yuval Tassa 3178db50b9 Fix box-box SAT collider code for GCC's pedantic mode.
Also add a detailed architectural comment that might be useful in future.

PiperOrigin-RevId: 965500329
Change-Id: Ia6a2a9137f07f726838b0acb28039a394db0efa2
2026-08-16 04:58:30 -07:00
Yuval Tassa 86e9860106 Rewrite box-box collision: SAT + polygon clipping + true edge-edge contacts.
Replaces the box-box collider's manifold generation and post-filtering with a
single structured implementation, and deletes the accumulated repair logic it
obsoletes. Net 319 lines out of the engine.

Algorithm:
- The separating-axis test keeps the closed-form support evaluation and chooses
  the axis of maximum separation among the 15 candidates by plain argmax.
  Edge-cross axes whose cross product has norm below rounding are skipped: in
  the nearly-parallel regime their direction is cancellation noise, previously
  the source of arbitrary-normal contacts with box-scale spurious depth. A
  winning edge axis within eight degrees of the best face axis is replaced by
  that face unless it is better by five percent (ODE's classic fudge): resting
  stacks otherwise flip between the edge and face contact codes by rounding
  noise from step to step, thrashing the solver warm start until the stack
  explodes. The substitution runs after the search rather than filtering during
  it, so a worse non-aliasing edge cannot steal the contact the substitution
  meant to give to the face.
- Face contacts clip the incident face against the reference face's side planes
  (Sutherland-Hodgman). Depth is measured along the reference normal only,
  never as a Euclidean distance between unrelated points. Contact position is
  midway between the surfaces along the normal, so its distance to either box
  is bounded by half the contact depth. Every surviving vertex of the clipped
  polygon becomes a contact, so the manifold is the actual contact patch, at
  most eight points as before.
- Edge contacts use the closest-point pair between the two supporting edge
  segments. A near-zero axis component makes the support-corner sign ambiguous;
  both signs are enumerated and the closest witness pair wins.
- Margin is an acceptance band throughout: SAT early-out and clip acceptance.
- The rounding thresholds are stated per precision. The separation tests are
  the ones that cost correctness: comparing exactly against the margin reports
  a pair overlapping by less than the rounding error of its own support
  evaluation as separated, and the boxes pass through each other. Over 239k
  overlapping pairs that is eight misses under mjUSESINGLE and none in double;
  the collider this replaces misses the same eight. Slack proportional to the
  summed half-sizes leaves five, which overlap by 7e-9 to 3e-8 of their own
  scale, below single-precision epsilon, where the boxes are not distinguishable
  from touching. Erring toward contact is the safe direction: the driver already
  excludes a contact whose distance reaches the margin.

Deleted: the conditional acceptance cascade keyed on how many points earlier
generators emitted, the u/v clamping that fabricated contacts from out-of-range
projections, the outside-box removal filter and its missing-fallback hole,
exact-floating-point deduplication, and the edge-path depth clamp. The
structure makes those bug classes unrepresentable rather than filtered: depth
is a projection by construction. Every reported depth is the exact support
overlap along the contact's own normal, verified over 246k overlapping poses to
within two ulps; the face preference costs direction, not depth, deviating from
the minimum-translation axis by at most 8.1 degrees and 5.3% of its depth.

The previous implementation is preserved verbatim as mjc_BoxBoxLegacy in
test/engine/boxbox_legacy.c, a static library that only the box-box tests link,
so the claims above are measured rather than asserted. It needs no private
engine symbols. Three tests compare against it:

- NearAlignedManifoldIsExact sweeps the relative angle of a resting pair across
  the regime where the edge-cross axes degenerate into noise, pinning the full
  clipped polygon and a contact normal equal to the face normal exactly, where
  the previous collider drifts off it.
- AlignedTowerStands settles a twenty-box tower, which comes to rest four
  million times quieter than under the previous collider, which never settles
  and eventually topples.
- ShallowOverlapSurvivesRounding pins a pair overlapping by 7e-8 of its scale,
  reported as separated under mjUSESINGLE without slack on the separation tests.

On stacks of plates across aspect ratios from 4:1 to 25:1, five layouts each,
the collider settles into a tight band of 1e-4 to 3e-4 while the previous one
intermittently blows up to as much as 2.6e-2.

engine_collision_box_fuzz_test.cc cross-validates randomized poses against
GJK/EPA on identical box meshes and against a spherical-Fibonacci support
sweep, with hard gates per sample: no phantom penetration, no missed contact at
zero margin, no contact deeper than the true depth, contacts within half their
own depth of both boxes, and one normal per manifold. Both invocations run in
about a second.

EdgeContactAtDepthBound's tolerance widens to the five percent design band; the
three-orders-of-magnitude depth bug it pins is still caught, the deviation
being 0.13 percent of the depth.

The 100-box pile benchmark steps about 7% faster with 1.6% fewer contacts.

PiperOrigin-RevId: 965114952
Change-Id: Ie98cdcce8d1aed3ff2da938cb29703fd9c241258
2026-08-15 01:45:56 -07:00
Sam Haves cc7fb98cf4 Add texture coordinates to primitive shape types.
PiperOrigin-RevId: 964882123
Change-Id: I17723d21f29b3fe28e171de5c3d2bea1f55a94c2
2026-08-14 14:11:23 -07:00
Haroon Qureshi 4929f2cd99 Disable/revert recent refection changes.
PiperOrigin-RevId: 963586393
Change-Id: I65449cfcae4d50664f87296fa69d1660adf60c91
2026-08-12 12:08:00 -07:00
Matija Kecman fca913b4f5 Optimize and robustify asset prefetching and material loading.
- Parallelize asset prefetching (max 4 workers) with retry logic and on-screen error banner, replacing silent failures and cryptic WASM out-of-bounds crashes with explicit missing-file errors.
- Support binary Uint8Array/ArrayBuffer in C++ asset registry via typed_memory_view, preventing Embind string coercion from corrupting binary shader packages into ASCII text.
- Automatically glob .mat files in CMake instead of maintaining a manual list.
- Add missing reflection materials to prefetch arrays.
- Disable caching for index.html in web server so template/script updates apply on normal page reload without stale cache issues, the file is small so caching had a negligible upside.
- Add null resource and payload validation in ObjectManager::LoadMaterial before constructing Filament materials.

PiperOrigin-RevId: 963364509
Change-Id: I7de79df6a5cede4e54683415ee193f1c5a665286
2026-08-12 04:38:35 -07:00
Google DeepMind fb03be0e4f #usd Update third_party/mujoco and third_party/py/mujoco to USD v26
Update USD dependency module paths, includes, Python imports, and plugin registration configurations across third_party/mujoco and third_party/py/mujoco from USD v23 to USD v26.

PiperOrigin-RevId: 963260526
Change-Id: I3778608cb03c8903d0f545c76ae91effba3ec364
2026-08-12 00:26:53 -07:00
Sam Haves dbc10c743b Introduce Tracy profiling infrastructure and macros (internal)
Add public mjprofile.h header with MJ_PROFILE_* macros that get compiled out if Tracy is not enabled.
Integrate Tracy into engine macro timers and build configurations.

PiperOrigin-RevId: 962329763
Change-Id: Iac9d8f9ff0d909beea212a7aa8a6a3dcb512010f
2026-08-10 13:20:14 -07:00
Alessio Quaglino b924ac66bd Add continuous-collision infrastructure for deformables
The discrete collision pipeline generates contact points at a configuration;
this module prices gaps along trajectories: differentiable vertex-triangle,
edge-edge and vertex-geom distance kernels with closest-point barycentrics,
swept-volume candidate generation over the flex bounding-volume hierarchy,
per-pair gap evaluation with the gradient's vertex weights, and a conservative
advancement that bounds each contact pair's time of impact.

Engine-internal, with no consumer in this change: it is the groundwork for
continuous-contact (IPC-style) solvers for flex, which will arrive as callers.
The mjcPair type carries the geometric identity of a candidate pair only;
solver state (multipliers, ages) and cached linearizations belong to the
consumer. The two lengths the module needs -- the standoff cap and the
detection band -- are caller-supplied parameters, not constants.

Flex-flex pairs measure their gap at the midsurface rather than skin-to-skin:
where mesh geometry is tighter than the combined radii (a string threaded
through a hem) a skin gap is permanently negative and the pair would be
discarded as invalid, losing CCD coverage exactly where tunneling is likeliest.
The broad phase adds the radii back into its reach, so detection range is
unchanged.

Tests cover the distance kernels, the geom sharp features, the pair gap with
its gradient checked by central differences at every involved vertex, the
conservative advancement (the analytic cap on a crossing sweep, the
conservative closing-rate bound, the small-motion early-out), and candidate
generation on stacked cloths (pairs within reach found, distant ones not).

PiperOrigin-RevId: 962197295
Change-Id: I90e017f4580a288b2a7d341830077fc273c9acde
2026-08-10 09:27:23 -07:00
Matija Kecman f1c8d3a58f Renamed the notion of handler classes to plugin classes in the Studio Python API
This change refactors the Python API to use the term "plugins" instead of "handlers" for classes containing decorated handler methods. The term handler is still used for an annotated method of a plugin class that handles a specific message type. Also improved some documentation.

PiperOrigin-RevId: 962150099
Change-Id: I34a8cc410cd784b088605490cfa3baccea5c9e71
2026-08-10 07:50:36 -07:00
Kyle Bayes ab1af24911 Compute correct witness point info for multicontact.
PiperOrigin-RevId: 962132590
Change-Id: I6594dc02ad93b1ec63a32157535f1d95b54d1058
2026-08-10 07:09:20 -07:00
Kyle Bayes 0dac756d53 Initialize height field object in mjc_HFieldElem.
PiperOrigin-RevId: 962018078
Change-Id: Ibfdbb45110d3406b40b5ddc36da19606bdd4878a
2026-08-10 02:07:19 -07:00
Hana Joo 0aad65868d suppress pyrefly errors in mujoco
Startblock:
  * // Put other blockers before this line to avoid churning.
  * has lgtm
  * is approved
  * and then
  * all comments are resolved
  * and then
PiperOrigin-RevId: 961854282
Change-Id: I9d323a8ef9f36ffe69cc62d449849eac82dc6858
2026-08-09 15:45:36 -07:00
Yuval Tassa d6dc966c04 Support planar reflections on physically based materials.
PiperOrigin-RevId: 961670546
Change-Id: Ifa69b8251c5f3fae6a76427f13df9c688370c741
2026-08-09 02:03:28 -07:00
Copybara-Service cb4259e4e4 Merge pull request #3465 from shi-eric:shi-eric/mjx-warp-cache-ffi-callables
PiperOrigin-RevId: 961136122
Change-Id: Ia468812e0557bb4efb7866f7130dab5d1cea673f
2026-08-07 14:59:07 -07:00
Yuval Tassa 9c765e7ba1 Fix formatting in the changelog.
PiperOrigin-RevId: 961105326
Change-Id: I52e522e16fb8ad8b8a96d32e3de70608363f3805
2026-08-07 13:55:10 -07:00
Copybara-Service e144090273 Merge pull request #3466 from smallquail:flex-implicit-contact
PiperOrigin-RevId: 960804180
Change-Id: Ic3eb203ca0d9cf19c9043b46127db342678d94f9
2026-08-07 02:36:26 -07:00
Yuval Tassa dca295dde2 Composite Filament planar reflections as Fresnel-weighted specular.
PiperOrigin-RevId: 960554436
Change-Id: Ife6f5c760993ad185e9421cd7b3ce7fd06fffc90
2026-08-06 16:07:30 -07:00
Baruch Tabanpour 5e3464f475 Fix #3435. Add token to ensure sequential calls for mjx-warp refit and render.
PiperOrigin-RevId: 960553589
Change-Id: I76caca5a82dd7f96b39e51c5b67b7382ebd1726d
2026-08-06 16:05:47 -07:00
Eric Shi ab4fe36121 Cache MJX-Warp FFI callables
Equivalent JAX retraces rebuilt flattened wrapper functions, causing
Warp to register a new FFI callable for every trace.

Reuse callables with matching structural configurations while keeping
distinct shim functions isolated. This keeps Warp's registry and graph
cache effective without changing callback lifetime.

Document the structural key and lock scope so future changes preserve
the cache's intended boundaries.

Signed-off-by: Eric Shi <ershi@nvidia.com>
2026-08-06 19:49:45 +00:00
Taylor Howell a1d772c9ad Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 960411406
Change-Id: I687b06586881d1915bab1bf8ebab6473e6ef29db
2026-08-06 11:24:34 -07:00
Yuval Tassa b3f8f91ec5 Include the environment in Filament planar reflections.
PiperOrigin-RevId: 960321393
Change-Id: Ia5855f9906ae91dd656d9f9ca233c0f379a49831
2026-08-06 08:37:24 -07:00
Kyle Bayes 35342f403f Check if geoms are separated in GJK after an early exit. Fix #3383.
PiperOrigin-RevId: 960316577
Change-Id: I328322e0b1bd14089defb26e9dc35a264642b4d6
2026-08-06 08:27:05 -07:00
Alessio 2a3554c8a3 Integrate passive flex contact implicitly
Contact of a flex with `passive` collisions enabled was applied as an
explicit spring of fixed stiffness 1e4, which the timestep bounds: any
stiffness worth having oscillates faster than the step can resolve, so
the force was too soft to keep sheets apart and interpenetration was
routine.

Carry its curvature in the effective metric M + K instead, alongside the
flex's own stretch and bending stiffness. The contact block k*J^T*J is
appended to the per-vertex candidate list already assembled for the flex
stencils, so it costs additional entries in an existing matrix rather
than a new one, and the accompanying shift -h*K*v is what damps the
stiff modes. At a 2 ms timestep this holds roughly 50x the stiffness an
explicit force of the same step could.

With the timestep no longer setting the bound, the stiffness is chosen
as a natural frequency scaled by the participating vertex mass rather
than left at a fixed 1e4, so one value suits models of any scale.

Passive handling is scoped to contacts whose every dof is a flex vertex
carried by the metric: flex against flex, flex against itself, and flex
against static geometry, which contributes no dofs of its own. For those
the Hessian is assembled in full. Contact with a body that can move
would have that body's dofs dropped from it, and is left on the
constraint solver.

The feature now requires an integrator whose constraint solve runs in
that metric, and is rejected with an error otherwise.

Add model/flex/drape.xml as the example model, replacing sphere_passive,
whose contacts no longer demonstrated the feature.
2026-08-06 15:38:05 +01:00
Sam Haves 39e4458806 Update USD support in MuJoCo to Newton USD schemas v0.4.0.
See changelog for more info.

PiperOrigin-RevId: 960284190
Change-Id: I89a84b1efbc22c89ee99db7436851ef27a325176
2026-08-06 07:17:39 -07:00
Haroon Qureshi 63b779042c Split Renderer class into explicit "classic" and "filament" classes.
PiperOrigin-RevId: 960272089
Change-Id: I9494472b7b8e838a75beaf0cd68e5ce4b42a80a4
2026-08-06 06:52:37 -07:00
Kyle Bayes 7f305abd71 Add minor improvements to x_k norm in GJK.
PiperOrigin-RevId: 960266053
Change-Id: I0e774617cd8ed7a189caee97f6139f6fd206d39e
2026-08-06 06:36:45 -07:00
Sam Haves 6fe04aa8d3 Remove custom mujoco.texture format.
PiperOrigin-RevId: 960257562
Change-Id: I318c84d82576d405f0a5d8510acd5bab5f08c9af
2026-08-06 06:13:54 -07:00
Matija Kecman 84950fa371 MuJoCo Web Viewer: Implement parallel chunked model downloading and in-place model reloading.
This change introduces parallel chunked downloading for large model files (.mjb) directly into WASM linear memory, enables model loading without full page reloads and reduces memory overhead.

Key changes:
- Implement a chunked model endpoint in the Python web server to support range requests.
- Add parallel chunked fetching in the frontend with retry logic and a single-fetch fallback.
- Increase initial WASM memory to 3 GB to accommodate large models and prevent heap fragmentation.
- Support in-place model reloading in the C++ client, including texture cache invalidation when the Filament context is recreated.
- Display a model download progress bar and model parsing/loading banner to the UI.
- Fixes model drag and drop (caused by typo in sessionId, corrected to session_id).

PiperOrigin-RevId: 960249236
Change-Id: Icac89e6a4ca099882aaf9b111744c1b6ab0cc6c1
2026-08-06 05:51:43 -07:00
Yuval Tassa 7fd2061f5c Change default light softness from 0 to 0.2.
PiperOrigin-RevId: 960218397
Change-Id: I58f211f5a275f8f19254424facd02c14eaa8c668
2026-08-06 04:28:17 -07:00
Yuval Tassa ed13bf5647 Mocap bodies are the weld root of their own kinematic subtree.
PiperOrigin-RevId: 960212286
Change-Id: Ibeff129c3110576c8846c76ba6ab756f23c0fa2e
2026-08-06 04:10:34 -07:00
Yuval Tassa 0accc5b3c7 Emit dm_control's schema.xml from mjcf.schema
PiperOrigin-RevId: 959934262
Change-Id: I75b96a0fbad2aa4acefbd1ea650ad08205c78576
2026-08-05 16:31:15 -07:00
Sam Haves 596b6f433d Add args field to mjResource for decoder and encoder arguments.
Add an optional `const char* args` field to `mjResource` to allow passing
resource arguments/hints (such as requested channel count or encoding options)
to resource decoders and encoders.

PiperOrigin-RevId: 959774058
Change-Id: Icc41a2bb3895fef24f98c5fa9a77cdad092a6bc7
2026-08-05 11:31:35 -07:00
Kyle Bayes 83e621d771 Implement mesh extrema in a 3x3x3 grid corresponding to each feature of a unit cube. These are used as seeds for a better initial point in mesh hill climbing with up to a 2x speedup in mjc_Convex.
PiperOrigin-RevId: 959645299
Change-Id: I032ae534704e0cc440ddb7691fd21a29a359f521
2026-08-05 07:22:48 -07:00
Alessio Quaglino 1362a8bded Move BVH active visualization flag reset after early return check in MuJoCo collision driver.
This avoids unnecessarily resetting the bvh_active flags when the collision driver returns early due to disabled constraints, disabled contacts, or having fewer than two bodies/flexes.

PiperOrigin-RevId: 959531283
Change-Id: I85caf054b06e3be1018d710f9ab762627fc3356a
2026-08-05 02:41:46 -07:00
Yuval Tassa f9a00bd5b5 Add light softness: spotlight edge softness for physically-based rendering.
The new spotlight attribute softness (real in [0, 1], default 0) is the
fraction of the cone, measured inward from the cutoff, over which
intensity falls to zero. It is used by physically-based lighting models;
the Phong model's corresponding knob remains exponent.

The filament renderer previously hardcoded the inner cone angle to 0,
making the entire beam penumbra: the shader attenuates by the squared
smoothstep ((cos(theta) - cos(outer)) / (cos(inner) - cos(outer)))^2, so
a cutoff-25 spot delivered its rated candela only exactly on-axis and
about a third of it averaged over the light pool, with the deficit
shrinking as the cutoff widens. The inner angle is now
(1 - softness) * cutoff, so at the default the light delivers its full
intensity everywhere inside the cone and illuminance follows E = I/d^2
independent of the cutoff. Setting softness to 1 reproduces the previous
appearance exactly (verified bit-identical), which is the migration path
for models tuned against the old behavior.

The filament light type also changes from FOCUSED_SPOT to SPOT. With
intensity given in candela and the cone set at build time the two types
produce identical output (FOCUSED_SPOT's power-conserving rescale only
applies when the cone changes after the intensity is set), but SPOT
guarantees that candela never rescales with cone angle should the cone
ever become runtime-editable.

Verified with headless renders under a linear tone mapper against an
equal-candela point light at cutoffs 25/45/80: softness 0 gives
spot/point luminance ratio 1.000 at all sampled angles inside the cone;
softness 0.2 is flat over the inner 80% of the cone; softness 1 matches
the previous renderer with zero linear-pixel difference. XML round-trip
and the [0, 1] compile-time check verified. Introspect and wasm bindings
regenerated.

PiperOrigin-RevId: 959334706
Change-Id: I0f0729781899880de1729ea9b3d8c055d715a025
2026-08-04 18:11:48 -07:00
Yuval Tassa 92261d9095 Fix test breakage under float32
PiperOrigin-RevId: 959249928
Change-Id: Ibcf7dbe41e184be0c23a8d14af54ea6bde5b8de3
2026-08-04 15:04:09 -07:00
Alessio Quaglino 63c7175ed5 Adjust rotEPS for single precision in mju_mat2Rot.
This change defines rotEPS as 1e-6f when mjUSESINGLE is defined, and 1e-9 otherwise. With the larger epsilon for single precision, the algorithm converges in fewer iterations, allowing the test assertion for maximum iterations to be simplified to a constant 150.

PiperOrigin-RevId: 959070496
Change-Id: I4f6fae056cd71955d3921c01a9929af2cdd81fac
2026-08-04 09:38:28 -07:00
Matija Kecman b3ef7a8c2f Simplify MuJoCo Studio viewer selection and unify model flags.
This change removes the ViewerMode enum and instead infers whether to launch the Web Viewer or Native Viewer based on the graphics mode (gfx) setting. Specifically, setting gfx to "web" or "webgl" will now launch the Web Viewer (in future "webgpu" would also launch the Web Viewer).

Additionally, this unifies command-line flags across studio scripts and samples by replacing the --mjcf flag with --model (with positional argument fallback) and standardizing absl flags usage. --model is a better name since formats like .mjz and .mjb are also supported by this argument.

PiperOrigin-RevId: 959058940
Change-Id: If4e0ace664ddc6e45cb681d168679148e8c4901d
2026-08-04 09:14:07 -07:00
Haroon Qureshi 0a10860257 Classic rendering mode works with wayland now.
PiperOrigin-RevId: 959036941
Change-Id: I31231c644e8a535918e4ace5d44f84b9b7da78bc
2026-08-04 08:29:04 -07:00
Yuval Tassa 9553926158 Save flex node coordinates in the new nodecoord attribute.
Interpolated flexes with pinned nodes could not be reloaded after saving:
pinned nodes share their parent body, and their positions within it lived
only in mjsFlex.node, which had no MJCF attribute. On reload the pinned
nodes collapsed onto the parent body origin, degenerating the trilinear
interpolation grid ("flex grid rotation R0 is not orthonormal"). This
made model/flex/strain.xml and gripper_trilinear.xml fail to round-trip.

Add flex/nodecoord, real(3*nnode), the node analog of flex/vertex: local
node coordinates within the corresponding body frames. The reader picks
it up from the regenerated schema tables; the writer emits it with the
precision-aware WriteVector, since VectorToString ignores the XML
precision setting and truncating node coordinates to 6 digits while body
positions carry 17 fails the R0 orthonormality check at full precision.

Add a WritesPinnedFlexNodes round-trip regression test, and remove the
two write-read sweep exclusions documenting this bug. The removed
substring filter "strain" was also matching core_constraint, silently
excluding that entire testdata directory from the sweep; its ~40 models
are now covered and pass.

PiperOrigin-RevId: 959025281
Change-Id: I2fed28c01491c5a8431e813102a423d12b659911
2026-08-04 08:04:27 -07:00
Yuval Tassa 574b6bd6bf More schema-related cleanup.
- Declare every nonzero default; make the defaults cross-check total.
- Skip default-valued attributes in the hand-written writer paths.
- Fix type facts on hand-read elements, found by the dm_control diff.

PiperOrigin-RevId: 958999733
Change-Id: I3064ccc6ae1f049c20f273abc234cd02990a8b7e
2026-08-04 07:05:41 -07:00
Copybara-Service 10793e539e Merge pull request #3451 from smallquail:flex-geometric-stiffness
PiperOrigin-RevId: 958995742
Change-Id: Ibb60c3112b6dbc2373a5cd98df0477d639a5a001
2026-08-04 06:56:37 -07:00
Yuval Tassa 3d1d133a48 In the compile sample, copy the error message before deleting the spec that owns it.
PiperOrigin-RevId: 958970071
Change-Id: I1e8e367f26fde4778747020ab61f26105d70d690
2026-08-04 05:44:59 -07:00
Yuval Tassa 1e3c8f3f91 Add XSD schema.
Fixes #6, #3237, #3410

PiperOrigin-RevId: 958922477
Change-Id: Ia68e10be06d7c880b6a095edcc79572ee8b6f50e
2026-08-04 03:32:24 -07:00
Yuval Tassa 2544c34997 Clean up new schema code.
- Declare the full child lists of the body-alias elements.
- Verify read-table coverage: every generated row array must be consumed.
- Fix stale attribute facts on hand-read elements.

PiperOrigin-RevId: 958685667
Change-Id: I4a914f3136a5078eb8ca24aa4e162d55afafd923
2026-08-03 18:15:39 -07:00
Taylor Howell f848b185d3 update mjx make_data and put_data docstrings for njmax
PiperOrigin-RevId: 958526560
Change-Id: Iaeff307e4d09c9193134fc29689aeedfdcaa9d53
2026-08-03 12:49:29 -07:00
Kyle Bayes 0bfa4e984c Fix latent bug in multiccd so that we can never write more contacts than what the buffer space allows.
PiperOrigin-RevId: 958505449
Change-Id: I77cb1142405df5107be46ca0dbef6effc690028d
2026-08-03 12:07:00 -07:00
Taylor Howell 382af63dc3 update mjx for naccdmax
PiperOrigin-RevId: 958479874
Change-Id: If0f48f2f372955f2948cb286966f5fce52c3f0ba
2026-08-03 11:20:34 -07:00
Saran Tunyasuvunakool b0c3486249 Tweak URL printout in terminal when launching the web viewer.
PiperOrigin-RevId: 958422471
Change-Id: I2d637c615015915eb01b65bb0bad22749886a372
2026-08-03 09:41:25 -07:00
Yuval Tassa d33f297b56 Zero out stale lambda coordinate in S3D in GJK.
PiperOrigin-RevId: 958414972
Change-Id: Ia21f8959a990c18b9d67959be5b2adeb1d3fa1dd
2026-08-03 09:25:46 -07:00
Copybara-Service eb049fb287 Merge pull request #3450 from teerthsharma:topo/hullgraph-inverse-map
PiperOrigin-RevId: 958414730
Change-Id: I4a7f8fdde77513a3267e07e46a13144592e73ff0
2026-08-03 09:24:33 -07:00
Yuval Tassa 8a643f4e2b Format some more files in user/
PiperOrigin-RevId: 958383817
Change-Id: I17fcdbf32967ec5a5c4d2552823ef5100faaea3b
2026-08-03 08:17:01 -07:00
Alessio 5497994763 Add the geometric term to the flex stretch stiffness
K_stretch was the Gauss-Newton Hessian of the stretch force, not its Jacobian.
With elongation e_a = L_a^2 - L0_a^2 and force f = -sum_ab M_ab e_a grad(e_b)/2,

  K = 2 sum_ab M_ab (s_a d_a)(s_b d_b)^T + sum_a Me_a (Laplacian_a (x) I3)

and only the first term was there. The second is proportional to the edge
tension Me_a = sum_b M_ab e_b, so it vanishes at rest and grows with strain:
the operator was first-order correct and no more. Finite-differencing it
against -d(qfrc_passive)/dq on a mesh dilated by 5% gives 7.8% of the force
scale; with the term it is exact to roundoff.

Add only the tensile part. The geometric block is Me_a*[[I,-I],[-I,I]] over the
edge's two vertices, which is positive semi-definite exactly when Me_a >= 0; a
compressed edge would make K indefinite, and both consumers -- the CG
constraint solver and the PCG in mjd_effSolve -- require SPD. The clamp is
structural, so no eigendecomposition is needed, and it is confined to the
operator: mj_flexPassiveStretch keeps the full Me_a, so no force changes.

Both the matrix-free operator and the CSR assembly the effective metric builds
from are updated, since they must agree.

This changes how flexes with elastic2d="stretch" integrate under the implicit
integrators and the effective metric -- bag.xml moves, poncho.xml is
bit-identical because bending energy is quadratic and has no geometric term.
The interpolated-flex path still uses its Gauss-Newton approximation, which
FlexInterpDerivativesDeformed asserts.
2026-08-03 16:16:23 +01:00
Alessio Quaglino 7927e908a3 Fix flex bending frame transformation when parent body is rotated.
PiperOrigin-RevId: 958362895
Change-Id: I0f6ba12a441bd7daa54292bfe2c70f0d836b008d
2026-08-03 07:28:52 -07:00
Copybara-Service 2c8d7b565d Merge pull request #3252 from devshahofficial:devshahofficial/studio-filament-source-build
PiperOrigin-RevId: 958356099
Change-Id: If4e68babdc6c68d7dd05ced7197a1869db4a0625
2026-08-03 07:12:38 -07:00
teerthsharma 747d36da91 Remap convex hull graph ids with an inverse table
Signed-off-by: Teerth Sharma <teerths57@gmail.com>
2026-08-03 18:08:09 +05:30
Yuval Tassa b475bb6f36 Move schema related generated files into their own directory
PiperOrigin-RevId: 958296165
Change-Id: I48cacc72c7df5994f5f816489ba069a5813845a1
2026-08-03 04:23:56 -07:00
Yuval Tassa 5e99ca6cb8 Table-driven attribute writing: rebase the writer on the shared rows.
The writer consumes the same generated rows as the reader.
mjXWriter::WriteAttrTable drives the mechanical attributes of an
element from its mjXAttr rows: each bound field is compared against
the class default at the same offset -- the default object is the same
struct type, so the rows carry no comparison values -- and attributes
equal to their default are skipped. A null default object means the
element has no defaults, and every defined value is written.
Ranged-arity rows write with trailing-default trimming, which the
reader makes round-trip exact by refilling from the same default.
Call sites upcast to the private mjs base (the friend declarations
permit it; mjCMesh gains the friendship its siblings had); the
comparison object is def->X().spec, a freshly-defaulted struct for
the sections, or zero-initialized for size, whose spec defaults (-1,
auto) are resolved by compilation.

Converted: pair, geom, site, joint, camera, light, material, the
equality family, both tendon types (the fixed rows are the spatial
rows without appearance attributes -- exactly the tag difference), the
actuator, flex with its three sub-elements, mesh, skin, option, the
six visual sub-sections, statistic and size. The remnants keep names,
files, resolved reference strings (the mjC classes null their private
base's string pointers; resolved names live behind accessors), and the
writing=custom policies the schema declares: compile directives never
saved (fromto, springdamper, fitscale), type-dependent lengths and
attributes (sizes, joint pos/axis/limited, shellinertia), and
alternatives (mass/density, fovy-versus-intrinsics, the plugin-gated
gain/bias family). Compiler keeps its write-if-nonzero policy;
keyframe keeps its model-sized vectors.

Saved files are canonical: attributes follow schema declaration order
with remnants trailing, and sections follow the schema's dependency
order (statistic before visual, deformable before the contact and
equality sections that name flexes, tendon before the equality
constraints that name tendons, custom demoted to the data tail).
Uniform behavior fixes fall out: default-equal positionals are
dropped, dynprm is trimmed like every other ranged vector, and mesh
material -- read into the spec but never written -- now survives
save/load round trips. Changelog entries ride along.

Verified: full suite, doc_test, and the two-tier A/B harness --
saved XML reorders attributes, and every corpus model reloads to a
byte-identical binary.
PiperOrigin-RevId: 958255003
Change-Id: I5fe7346014450db88b2f3f8680a8f616f7d31266
2026-08-03 02:27:22 -07:00
Yuval Tassa 760477f406 Add .clang-format to user/, format user_composite
PiperOrigin-RevId: 958225464
Change-Id: Iad7eb52dbecf7585f98375c90863ca707c494590
2026-08-03 01:22:00 -07:00
Yuval Tassa 4278c7b0cd Table-driven attribute reading: rebase the reader on generated rows.
Every mechanical attribute read in MJCF now derives from mjcf.schema.
generate_read_table.py emits typed mjXAttr rows (mjcf_read_table.inc,
doc_test-gated) binding each attribute to its spec struct field; field
offsets are offsetof() expressions, so binding mistakes are compile
errors, and the field's C type -- parsed from the headers -- selects the
row kind, so mjtNum-versus-double is decided by the struct, not the
schema. mjXReader::ReadAttrTable is the generic loop; its static core
also serves the section parsers and records XML-authored fields via
mjs_setAuthored for attach conflict resolution. Row kinds cover
strings, string lists, numeric scalars and vectors (exact and ranged),
enums (int- and byte-width), bitwise flag sets, bools, unbounded typed
vectors, fixed char arrays, and identity constants declared by 'set'.
The rows are inline variables, and carry the writing=custom flag,
because the writer will share them.

The keyword maps the rows reference are generated too: the ~48
hand-written mjMap tables become mjcf_map.h, one map and size constant
per enum as C++17 inline variables, retiring the hand-maintained
extern block in xml_base.h. Map names follow the schema enum names
(fluid->fluidshape, TFAuto->FalseTrueAuto, FAuto->FalseAuto,
joint->jointtype, geom->geomtype, jac->jacobian); all maps are
key-order- and value-identical to the hand tables they replace, and
bool_map is hand-emitted (the bool type is built in, not a schema
enum).

The OneX() parsers reduce to genuine irregulars, schema-marked as
reading=custom: orientation alternatives, file attributes (VFS and
asset-dir context), the actuator shorthand remappings and per-type
input maps, springlength's one-value copy, mesh builtin construction,
hfield elevation, texture cube files, flexcomp seeding, the memory
suffix parse, and the flag bit families. All 41 sensors that are pure
identity-plus-references -- including the frame family and insidesite
-- dispatch through a generated tag table; frame-sensor
objtype/reftype vocabulary tightens from the full mju_str2Type
namespace to the documented body/xbody/geom/site/camera subset, so an
invalid keyword now fails at parse time instead of compile time. The
equality family and both tendon types read shared group rows; the
twelve actuator shorthands share the general rows, with per-tag
legality enforced by the schema check. Sections bind non-mjs structs,
the visual sub-sections reaching their anonymous sub-structs through
member paths declared by an element-level field= facet.

Latent irregularities surfaced by the migration and preserved via
schema declarations or remnants: key's name is set even when absent,
eulerseq and gridlayout are fixed char arrays (chars[n], arity in
characters), gridlayout's length-must-match-gridsize stays a
value-conditional remnant, and constructor-style elements (tendon
wraps, asset model, replicate, attach) are annotated as such -- their
attributes are arguments, not field writes.

Two coherence tests guard the schema against the C sources: every
schema enum constant must be a member of the C enum it claims, and
every C member must be a keyword, a count sentinel, or a documented
exemption; and generate_default_table.py emits one row per defaulted
attribute (mjcf_default_table.inc), compared by SchemaDefaultsTest
against a freshly-constructed spec -- the schema cannot disagree with
the C default-constructors without failing the suite.

Verified: doc_test regenerates and diffs every artifact; the full
suite; and an A/B harness compiling the model corpus against the
pre-migration reader -- saved XML and binary models are byte-identical.
PiperOrigin-RevId: 958075724
Change-Id: I9715fe4deeb438eec988fd5084d74ba8b466b10b
2026-08-02 17:24:45 -07:00
Yuval Tassa 790f8fac30 Generate the MJCF grammar table and enforce its constraints.
The hand-written MJCF[] table in xml_native_reader.cc is replaced by
mjcf_table.inc, emitted from mjcf.schema by generate_mjcf_table.py and
checked for freshness by doc_test. nMJCF is now self-sizing. The two
tables are identical as trees of (tag, cardinality, attribute-set);
within-row attribute order changes where the schema factors shared
groups and projects default-context rows, and top-level rows follow
the schema's dependency order -- neither affects validation, which is
set-based, nor XMLschema.rst, whose generator orders sections itself
(regenerated here, reading the .inc instead of the reader source).

The schema's constraint declarations become enforcement: the emitter
writes a companion MJCF_constraints[] array (row-indexed into MJCF[]),
and mjXSchema::Check evaluates each element's constraints after its
attribute check, with uniform messages derived from the declaration:
"at most one of 'fovy', 'sensorsize' can be specified", "attributes
'reftype', 'refname' must be specified together", and so on.
Multi-attribute bundles render as ('site1', 'site2').

Fifteen hand-written co-occurrence checks across fourteen elements are
deleted -- connect/weld semantics mixing and completeness, the actuator
transmission mutex, camera fovy/sensorsize, light directional/type,
inertial fullinertia-versus-orientation, rangefinder and the distance
family, contact's matching criteria, user-sensor pairing, the frame
family's reftype/refname, size memory exclusivities, mesh builtin
exclusions, and attach body/frame (newly declared). Tests assert the
uniform messages.

Two findings along the way: sensorsize-requires-resolution is a
value-level compiler rule (positive resolution), not a presence rule --
a presence constraint would be wrong and is not declared; and Size()'s
nstack/njmax range checks tested the spec value before assignment, so
they never validated the parsed value -- now they do.

Verified by compiling all 81 models in the model/ corpus.

PiperOrigin-RevId: 958064622
Change-Id: I802cf5c0aee08a62926e36a281320ff9e34c0668
2026-08-02 16:30:02 -07:00
Yuval Tassa 3f8db4c17a Add mjcf.schema and its declarative schema language.
The complete MJCF surface in one hand-maintained file: 144 elements, 8
shared attribute groups, 47 enums, 1,497 typed attributes with
defaults, the presence-constraint inventory previously visible only as
hand-written reader checks, and the save policies previously visible
only as hand-written writer logic.

The language is a small IDL: elements bound to their mjSpec structs,
typed attributes with arities and defaults, enum keyword sets with C
bindings, reusable and variant groups, explicit name/reference
namespaces (id<ns>/ref<ns>, following dm_control's
identifier/reference model), child cardinalities, presence constraints
(exclusive/together/requires/oneof over attribute bundles), bitwise
flag sets, identity constants (set field = CONST), fixed char arrays
(chars[n], arity counting characters), numeric range facets, and two
escape hatches: reading=custom (no typed binding is generated; both
reading and saving are hand-written) and writing=custom (the binding
drives the reader, the save policy is hand-written).
doc/generate/mjcf_schema.py is the dependency-free parser and semantic
validator; errors report file:line; 55 unit tests. The language is
documented by the cheat-sheet legend at the top of the schema file.

The schema was bootstrapped by extraction from the sources of record --
the MJCF[] table, the mjMap keyword tables, the ~660 ReadAttr*/MapValue
call sites, mjspec.h struct fields, and the default-constructors in
user_init.c and engine_init.c -- then hand-curated. Same-tag elements
that differ by context are distinct declarations carrying an xml=
facet; worldbody, frame and replicate carry alias=body, mirroring
mjXSchema::NameMatch. The top-level order is by dependency, what a
saved file should read like: front matter, declarations before use,
the tree, the sections that reference it, the data tail.
PiperOrigin-RevId: 958060695
Change-Id: Ie10fd9f0ef202a3626f4d635d02c8731a4d287df
2026-08-02 16:10:14 -07:00
Yuval Tassa fb07a9ca50 Fix missing contacts for deeply penetrating boxes.
When penetration exceeds a box's smallest half-size, the midpoint
between the contact surfaces can land outside both boxes. The outside-
box filter in mjc_BoxBox then removed every contact of the manifold,
returning nothing for a visibly overlapping pair, letting boxes fall
through each other. Fixes #1800.

If the filter would remove all contacts, restore the penetrating ones.
This is strictly additive: configurations where any contact survives
the filter are unchanged.

The removed midpoints are bitwise-identical to the witness midpoints
computed by mj_geomDistance for these configurations, so the positions
follow the engine-wide contact position convention; re-anchoring them
onto a box surface would not.

Fixes #1800

PiperOrigin-RevId: 957867315
Change-Id: Ia9c858661d4badeb2a832d25455e33402936011d
2026-08-02 01:34:59 -07:00
Yuval Tassa 8655446f25 Fix spurious deep contacts in box-box collision.
In the edge-edge path of the box-box collider, when line clipping yields
no points, the corner generators accept points whose projection
parameters are out of range and clamp them into the valid range. The
depth of such a point is the Euclidean distance between two unrelated
points, mixing lateral offset into penetration depth, and on the
penetrating side it is admitted with no margin check. For thin boxes
meeting edge-to-face within margin, this produced a contact with
penetration three orders of magnitude larger than the boxes' true
separation, exploding resting stacks.

No contact can penetrate deeper than the support-interval overlap along
the separating axis, which the SAT stage has already computed. Enforce
this bound on all points emitted by the edge-edge path. The bound
carries margin plus relative and size-scaled slack covering rounding
error: the depth of the deepest legitimate point is algebraically equal
to the bound, so an exact comparison would drop real contacts. The
slack is precision-dependent: in mjUSESINGLE builds the two
computations of the same overlap disagree by tens of ulps, and slack
calibrated for double precision rejects real single-precision contacts.

Differential fuzzing against the nativeccd oracle over 200k random
near-contact thin-box configurations, in both precisions: impossibly
deep contacts drop from 1018 to 4 (worst excess from 2.5x the bounding
diameter to 0.001x), with no legitimate shallow-penetration contact
lost.

PiperOrigin-RevId: 957628830
Change-Id: Iaa1f10742f91c55bf831296cba0936eb50ea09b0
2026-08-01 07:48:32 -07:00
Matija Kecman b389b28b87 Support parsing .mjz files in the Studio parser module
PiperOrigin-RevId: 957616406
Change-Id: I582d23039b4aec745e0525392c062102f4d9ae25
2026-08-01 06:47:01 -07:00
Copybara-Service 2bb152b77b Merge pull request #3445 from giusenso:fix/actuator-velocity-index
PiperOrigin-RevId: 957597256
Change-Id: I10a1c85fb49f00d60aa65d0cbdedc110423adb95
2026-08-01 05:10:55 -07:00
Yuval Tassa 279df98cd0 Add the pid actuator: setpoint inputs, integral action, slew rate limiting.
<pid kp kv|dampratio [ki imax] [slewmax]> is a PID controller with real position and velocity setpoint inputs on a single force output, plus an optional feedforward input. With a zero velocity setpoint it reproduces <position> bit-exactly; the input signature is any subset of [pos, vel, ff], selected with input="..." and recorded as mjtCtrlInput bits in
actuator_ctrlspec; absent setpoint inputs are fixed at zero, so the control vector contains no inert entries.

kp and kv are single-sourced in the affine bias parameters (biasprm[1,2]) with no gainprm mirror: every consumer of the position-servo shape
(dampratio conversion, inheritrange, qDeriv) reads one location, which is what makes the bit-exact <position> parity possible. Controller state uses dyntype 'pid' with slot-gated activations in the order [slew, integral], following the dcmotor slot idiom: slewmax (dynprm[1]) rate limits the effective position setpoint through an activation holding it;
ki (gainprm[0]) integrates the position error -- wrapped on rotational transmissions -- with anti-windup clamping of the integrand at imax (dynprm[0]). Both features require the pos input. Servo input unpacking is shared with the dcmotor controller (unpackServoInputs); per-input ranges are exposed as posrange/velrange/ffrange.

This subsumes the functionality of the mujoco.pid plugin with proper activation state: correct under all integrators, visible to keyframes, act sensors and reset. Migration: kp/ki/kd map to kp/ki/kv, plugin imax is in force units (divide by ki), slewmax carries over; the single ctrl becomes input="pos".

PiperOrigin-RevId: 957588898
Change-Id: Id2786836ca6e76f58e5b5cc8323fc23be0a53784
2026-08-01 04:28:43 -07:00
Yuval Tassa 7bc1aa9b05 Add Filament lighting and shadow features and fixes.
- Add a hidden directional light to Filament scenes with no lights to work around soft shadow blackout bug.
- Respect quality/shadowsize as default shadow map resolution.
- Interpret light/bulbradius in correct units for each shadow type and update XML reference docs.
- Support updating the shadow map resolution of live Filament lights.
- Clamp light intensities to non-negative values in the Filament debug panel.

PiperOrigin-RevId: 957305808
Change-Id: Ic7a3430aaa3b117be7fbb7ace836d68e54cdf65a
2026-07-31 13:28:01 -07:00
Matija Kecman 0ca53dacf8 Update SDL2 copybara transformations
PiperOrigin-RevId: 957294480
Change-Id: Ied7131cafe83b11379e275ab4287609674251db5
2026-07-31 13:04:33 -07:00
Yuval Tassa e295b31c60 Improve wireframe rendering support in Filament renderer and Studio.
- Draw complete wireframes in the Filament renderer.
- Bind the 'W' key to toggle the wireframe render flag in Studio.

PiperOrigin-RevId: 957230911
Change-Id: Ib583c81ddcfa834686c7cf01d2b12842479993ea
2026-07-31 11:00:38 -07:00
Matija Kecman 6c78c98418 MuJoCo Web Viewer: update code to support the web viewer
PiperOrigin-RevId: 957147035
Change-Id: Ibe5d68b2654a7faac23c297d4f492929209c078d
2026-07-31 08:09:38 -07:00
Matija Kecman a1e90c24b3 MuJoCo Web Viewer: top-level web_viewer.py component
PiperOrigin-RevId: 957119030
Change-Id: If6c8265dfa62f9a6378898644935ee335f3fa8b2
2026-07-31 08:09:05 -07:00
Matija Kecman f8344301e9 MuJoCo Web Viewer: server component
PiperOrigin-RevId: 957086932
Change-Id: Idcac876206a2df7e962481c12c2fc74ff9997948
2026-07-31 08:08:32 -07:00
Yuval Tassa e9197e1e9d Use logarithmic sliders in the object launcher.
Projectile parameters are positive scale factors, best adjusted
multiplicatively. Replace the input boxes with logarithmic sliders
spanning 0.1x to 10x the seeded default, which sits at the geometric
midpoint of the range; mass spans 0.1x to 100x since heavy projectiles
are a common want. Ctrl+Click still allows typing values outside the
slider range, and each slider gets a reset button restoring its
default. Adds an ImGui_SliderLog widget operating on mjtNum.

PiperOrigin-RevId: 957071873
Change-Id: Id46eae28f73308d98681ccbeb2764c949f98f9d9
2026-07-31 08:08:00 -07:00
Copybara-Service de26b05861 Merge pull request #3439 from smallquail:flex-metric-blocks
PiperOrigin-RevId: 957063540
Change-Id: I86e7b2ec92c7b2acd1f1f7140e3b8a7578c48dbf
2026-07-31 08:07:22 -07:00
Matija Kecman f1f52a92b8 Add headless EGL/OSMesa OpenGL UI context rendering for web viewer
PiperOrigin-RevId: 957060514
Change-Id: I8a0df22255c5a938d18e172c638a8c83dfe64b1b
2026-07-31 04:36:14 -07:00
Yuval Tassa 47e1b1bd1f Seed object launcher defaults from model statistics.
PiperOrigin-RevId: 957053250
Change-Id: Iba103877136c31bf1310f2b55bd8cfc5593a87ec
2026-07-31 04:14:10 -07:00
Yuval Tassa 0f90722c1a Arm the object launcher by opening its window.
The launch key binding was gated behind a checkbox because it stayed
active with the plugin window closed. Condition it on the window being
open instead: the arming state is visible, so the checkbox is redundant
and the press-proof chord can relax to plain Enter. Text fields and
dialogs are unaffected: plugin chords are not checked while ImGui
captures the keyboard, and built-in shortcuts dispatch first.

PiperOrigin-RevId: 956796864
Change-Id: I4e5b2bdcaafbcc1b1ba113dd37ef8314b3ade49e
2026-07-30 16:26:17 -07:00
Yuval Tassa 24297edfda Add close button to Studio plugin windows.
Plugin windows could only be closed from the Plugins menu. Pass the
plugin's active flag to ImGui::Begin so the window gets a close button
that writes the same persisted state as the menu toggle. Skip the
update callback while the window is collapsed.

PiperOrigin-RevId: 956795070
Change-Id: I61cb5c26e7af935b6bb296f1b89142a72b0daca1
2026-07-30 16:22:52 -07:00
Matija Kecman 4dd70d2367 MuJoCo Web Viewer: add web client containing code that runs in the browser
PiperOrigin-RevId: 956698568
Change-Id: Ia4bebcb25b488d255994018da03e9115187b890c
2026-07-30 13:17:48 -07:00
Haroon Qureshi 8b78378868 Add mjv_camera2GLCamera to mujoco.h.
PiperOrigin-RevId: 956698065
Change-Id: I36856d7142bb5e798c5a90c19609288ddd7c4aac
2026-07-30 13:16:37 -07:00
Yuval Tassa a3425c72a7 Ignore unsupported light types in the classic renderer.
The classic renderer supports only directional and spot lights, but initLights() set GL light colors for every scene light before dispatching on type, and the render passes enabled GL light slots without filtering. Since no position was ever set for unsupported types (mjLIGHT_POINT, mjLIGHT_IMAGE), OpenGL's default eye-space position turned them into phantom headlights with the model light's diffuse color, washing out the scene. A cast-shadow image light additionally triggered a full shadow pass with an unset light projection.

Filter all light setup and enable sites on a shared type predicate, so unsupported light types contribute nothing. The no-lights ambient fallback now applies when no supported lights are present.

PiperOrigin-RevId: 956696548
Change-Id: Ic29763df7f9330f21d94f14501ae2559fd460f2b
2026-07-30 13:13:42 -07:00
Taylor Howell b46d76683d Import Warp v1.15.0
PiperOrigin-RevId: 956678131
Change-Id: I09a672b7335a85a17c95773ffc29eb9272744986
2026-07-30 12:39:05 -07:00
Yuval Tassa 98ecadcdf2 Add reset buttons to Studio sliders.
Slider rows in the joints and controls tabs could only be reset through
a hidden right-click context menu. Replace it with a visible reset
button at the right edge of each row, disabled while the value is at
its reset target so the button column doubles as a modified indicator.
Rows split the remaining width equally between slider and label, and
labels clip at the button column. Adds an ImGui_ResetButton widget.

PiperOrigin-RevId: 956627705
Change-Id: I9c178f6cd1cc806c7ffd6f531acf7f2d470d9346
2026-07-30 11:10:26 -07:00
Haroon Qureshi e662350357 Simple window class for python.
PiperOrigin-RevId: 956544312
Change-Id: I52d0e2f555592bed3889f05a1406e7633eb6d468
2026-07-30 08:39:09 -07:00
Giuseppe Sensolini Arrà a670a6ac10 Merge branch 'google-deepmind:main' into fix/actuator-velocity-index 2026-07-30 16:53:10 +02:00
Haroon Qureshi 58a54ef474 Move resource provider registration into a separate library.
PiperOrigin-RevId: 956506812
Change-Id: I9acde018e282171f41e0f8c756cd02b39c35dc67
2026-07-30 07:19:08 -07:00
Yuval Tassa 6c86e12567 Make the selection outline occlusion-aware in the filament renderer.
PiperOrigin-RevId: 956489408
Change-Id: I948493587eb154cac6e0fc31d5df987967405ff8
2026-07-30 06:38:18 -07:00
Yuval Tassa 60889f5e85 Add favicon to MuJoCo Live.
PiperOrigin-RevId: 956476524
Change-Id: I3f33cd09764e1236999b7d269045a2f8c2a8236e
2026-07-30 06:09:12 -07:00
Taylor Howell 82471cbdfb MuJoCo Warp documentation: Large scenes initialize trees asleep
![docs](https://screenshot-v2.corp.google.com/image/222i7rtheo5eg.png)

PiperOrigin-RevId: 956462670
Change-Id: I0c6f211126e5d86bfacebff49591c17cb503b062
2026-07-30 05:34:13 -07:00
Matija Kecman c2e95b4161 Add StatePayload and serialization helpers for web viewer
PiperOrigin-RevId: 956400340
Change-Id: Ibe049afe10eca85e5fb6d718a78863a641b864bb
2026-07-30 03:01:23 -07:00
Taylor Howell 6a7a723093 MuJoCo Warp documentation: Per-world assets
PiperOrigin-RevId: 956399999
Change-Id: I8d951e5e52e16442325c66cc33ac693bf68939e3
2026-07-30 03:00:29 -07:00
Giuseppe Sensolini 4c2653273c Fix actuator_velocity indexing in the LuGre bristle update.
mj_nextActivation indexed actuator_velocity with the actuator id, but the
array is laid out by output address. The two coincide only when all
preceding actuators are single-output, so a DC motor placed after a
multi-output SO3 actuator integrated its bristle state with another
actuator's velocity, while act_dot (computed in mj_fwdActuation with the
correct velocity) disagreed with the actual evolution of the state.
Fixes DCMotorTest.LuGreBristleVelocityOrderInvariance.
2026-07-29 17:48:05 +02:00
Giuseppe Sensolini f95d50c12f Add regression test for LuGre bristle velocity indexing.
The DC motor's LuGre bristle state must integrate the velocity of its own
transmission, so actuator ordering cannot affect it. The test places a
multi-output SO3 actuator before the DC motor, making the motor's actuator
id and output address diverge, and requires the bristle state to match the
motor-first ordering. Currently fails: the exact ZOH update in
mj_nextActivation reads actuator_velocity[actuator_id] instead of the
motor's own actuator_velocity[outadr], so the bristle integrates the SO3
actuator's velocity.
2026-07-29 17:48:05 +02:00
Yuval Tassa fba29294d3 Update lighting and visual settings in the fridge door model.
PiperOrigin-RevId: 955888127
Change-Id: I1af5a2d4cf2a6fb3325b04b4cb6fd4cceeb92d60
2026-07-29 08:08:46 -07:00
Yuval Tassa 6a4a289c3e Open macOS file dialogs in the directory of the seeded path.
OpenFileDialog and SaveFileDialog hardcoded the user's Documents directory
and placed the full seed path in the name field. Studio seeds dialogs with
the current model's path, so File > Open now starts in the model's
directory with the filename pre-filled, falling back to Documents when no
path is available. Also avoids passing a potentially non-NUL-terminated
string_view to stringWithUTF8String.

PiperOrigin-RevId: 955869713
Change-Id: I7563f2cb2e39089883d5e37a3d259055c26e146c
2026-07-29 07:25:15 -07:00
Yuval Tassa 5800dfc929 Improve Studio help window with fixes, completions, and task grouping.
Fix, complete, and group Studio's help window by task.

PiperOrigin-RevId: 955869367
Change-Id: I5ae7b3661dd80a1273d8c9fecee303c361c102c3
2026-07-29 07:24:11 -07:00
Michael Moss 22f4a286f3 Update deprecated node 20 to node 24.
PiperOrigin-RevId: 955851551
Change-Id: I03dcfaa29e39c6b0b685982d3a12c4da82adf1ba
2026-07-29 06:42:30 -07:00
Alessio 55d13aec5f Replace the flex metric factorization with a block preconditioner
Every step, the flex block of the implicit effective metric M + K was
factorized by sparse Cholesky, because K depends on the configuration. On
model/flex/bag.xml, added here, that is roughly half the step, against a
comparable share for the constraint solve it exists to accelerate.

Keep only the metric's per-vertex 3x3 diagonal blocks, prefactored. Neither
consumer needs the exact inverse: the CG constraint solver only wants a
preconditioner, and qacc_smooth can come from an iterative solve using those
blocks. They are O(n) to build and to apply, but weaker, so CG runs about twice
the iterations and qacc_smooth becomes an iteration rather than a direct solve.
Net, the bag model steps roughly twice as fast.

The preconditioner, by metric state. Inactive, meaning no flex elasticity or an
explicit integrator: M^-1, unchanged. Bending only (nefmK == 0): M^-1 plus the
exact constant bending factor from mj_setConst on the dofs it covers,
unchanged; that factor is built at model compile time and costs nothing per
step. Per-step stiffness: M^-1 plus the 3x3 blocks, where before it was a
per-step sparse Cholesky, or, when M couples across the flex block, an inner
PCG of up to 50 iterations run once per outer CG iteration.

Only models carrying per-step stretch stiffness change in wall-clock. Both
ponchos hold their timing and take slightly fewer CG iterations than before,
because the preconditioner is now symmetric: it applies M^-1 and the covered
blocks to disjoint sets of dofs, where previously the two overlapped and the
operator was not symmetric, which PCG requires.

mjd_effSolve is the accurate solve of (M + K)x = b; what used to carry that
name only preconditions and is now mjd_effPrec. Its CG guarded the division by
pAp with mjMINVAL, an absolute floor on a quantity that scales with the square
of the right-hand side, so a small b aborted the solve while the curvature was
healthy: four flex models were quietly left short of tolerance. For an SPD
metric the guard is positivity, and with that the same solves converge. The qacc_smooth call site in
mj_fwdAcceleration is textually unchanged but now reaches the iterative solve,
which converges on opt.tolerance rather than a hardcoded threshold, floored in
mjUSESINGLE builds where the squared target is unreachable in float. Reaching
the iteration cap names the ill-conditioned flex stiffness and then reports it
through mjWARN_INERTIA, rather than returning an under-converged result.
Covered dofs are located by walking the covered rows of the stiffness matrix,
as they need not be 3-aligned from dof 0: any joint declared before a flexcomp
shifts them.

mjData.efm_L_rownnz, efm_L_rowadr and efm_L_colind described the sparsity of
the deleted factorization and are removed: left NULL with nonzero mjxmacro
extents they made the Python bindings hand back uninitialized arrays.
efm_active loses the value 2 for the same reason, nothing selects a solve path
on preconditioner exactness any more. Both are recorded under breaking changes.

model/flex/bag.xml is added because no shipped model carried per-step stretch
stiffness. The ponchos are bending-only and trampoline.xml uses an explicit
integrator, so the metric never activates there. It is excluded from
WriteReadCompareTest: stretch stiffness amplifies rest geometry that XML rounds
on save.
2026-07-29 14:36:15 +01:00
VihaanAgarwal 95f05402f1 Fix segfault on a mesh with convex inertia that no geom references
needhull_ was only set while iterating geoms, so a mesh whose inertia is
computed from its convex hull never got one unless some geom pointed at
it. mjCMesh::ComputeVolume and ComputeInertia then read graph_[1] and
GraphFaces() off a null pointer and the compiler crashed.

Whether a mesh needs its hull for inertia is a property of the mesh, not
of any geom, so move that condition out of the geom loop and apply it to
every mesh.

Fixes #3431
2026-07-29 06:18:08 +05:30
Michael Moss 559c2af751 Update MuJoCo Studio icons to have less padding.
PiperOrigin-RevId: 955416676
Change-Id: Ieb13b3ed37f5495a647a6ff58099150a79ba02ee
2026-07-28 12:53:25 -07:00
Copybara-Service d400914e97 Merge pull request #3437 from smallquail:flex-rotation-fix
PiperOrigin-RevId: 955127380
Change-Id: Ie31ab56f7d64dd1a2266828c0fcd3683b55768a5
2026-07-28 02:17:23 -07:00
Alessio d895888da4 Use the inlined mji_ 3x3 helpers throughout engine_derivative.c
Convert the four remaining mju_mulMat{,T}{Vec,Mat}3 call sites in this
file to their inlined mji_ equivalents, so the file is consistent after
the review change to the stretch paths. Aliasing is unaffected: the
inlined variants mark the result restrict, and every call already
required a distinct result (the public versions overwrite res while
reading vec).
2026-07-28 09:14:26 +01:00
Alessio a6743d8e0d Address review: blank line, and use the inlined mji_ 3x3 helpers
Per review on #3437: add the missing blank line above the new comment
block, and use the internal inlined mji_mulMat{,T}{Vec,Mat}3 helpers
rather than the public mju_ ones, matching fe9dc584. Six call sites in
the two stretch paths; pre-existing mju_ calls elsewhere in the file are
left alone.
2026-07-28 09:09:38 +01:00
Michael Moss 1db801460b Update MuJoCo version to 3.11.1 following the 3.11.0 release
PiperOrigin-RevId: 954833728
Change-Id: I1c006cdd72072c6821d7b3c28d8ac320de19b8c5
2026-07-27 14:35:26 -07:00
Michael Moss b85fdca54f Update changelog for the 3.11.0 release.
PiperOrigin-RevId: 954795939
Change-Id: I357468dd9072a5d1bab5af2529039e4924db12ed
2026-07-27 13:22:37 -07:00
Matija Kecman ca5337161d Export netimgui files in MuJoCo Copybara configuration for use with the upcoming Web Viewer
PiperOrigin-RevId: 954769526
Change-Id: I4cdee083082f7d55c2babd5e664ec0283a2aaf63
2026-07-27 12:33:41 -07:00
Alessio 55b43414dd Fix stretch stiffness basis for flexes in rotated parent bodies
The implicit effective metric assembles the stretch stiffness from
world-space edge vectors, but a flex vertex body's slide dofs are
expressed in its parent body's frame. When that frame is rotated the
assembled operator is therefore not the Jacobian of the passive stretch
force, which mj_flexPassiveStretch already maps into the dof frame with
xmat^T. The metric is then inconsistent with the force it linearizes:
implicit integration loses its stability guarantee, and models that the
same flex handles comfortably in an unrotated frame diverge.

Apply the matching change of basis in both places that build or apply the
stretch stiffness: mjd_flexStretch_mul rotates the input dof vector into
world and the scattered result back, and mjd_flexStiff_assemble sandwiches
each 3x3 block as R_bi^T * blk * R_bj. Both are no-ops when the parent is
unrotated. Bending needs no change: its blocks are isotropic, and
R^T (q I) R = q I.

This completes the fix in fe9dc584, which covered the passive force paths
and the interp (trilinear) derivative but not the standard stretch one.

On a mesh flex inside a body with a 90-degree rotation, the metric's
directional agreement with the force Jacobian goes from cos = 0.57 to
cos = 1.0, and a hanging sheet that previously reached 176% strain
settles at 0.87%.
2026-07-27 20:08:31 +01:00
Yuval Tassa c7b6e0b8dd Fix the array size of biasprm in mjsActuator specification.
Note mjNBIAS == mjNGAIN, this change is a no-op.

PiperOrigin-RevId: 954712145
Change-Id: I096246e5d060596c4025ea4c23e8e9e887c8cd50
2026-07-27 10:45:29 -07:00
Matija Kecman e4d0a88ffd Refactor viewer loop and shutdown handling to support conditional rendering and clean exits.
This change introduces a get_frame method to the viewer protocol, replacing the previous is_running check. This allows the viewer loop to skip rendering and lifecycle events when no active frame is ready (for example, when no browser is connected to the web viewer).

Additionally, this change:
- Adds a shutdown hook to ViewerHandle to wait for the viewer to cleanly release resources before exiting.
- Implements an ExitEvent handler in the viewer protocol to stop the run loop.
- Adds an http_port configuration option for the web viewer.
- Prevents double-closing in the viewer.

PiperOrigin-RevId: 954603868
Change-Id: Iaba7d131dc94191de51150464514dd10fa7834b0
2026-07-27 06:55:17 -07:00
Matija Kecman e23b504201 Change how ImGui clip rect scaling and scissor computation works in imgui_bridge to fix flickering and clipping errors in the web viewer
Avoid mutating ImGui draw lists in place by scaling clip rects locally during scissor computation instead of calling ScaleClipRects. This prevents clip rects from growing exponentially on persistent draw lists, such as streamed remote UI. Additionally, clamp the scaled clip rects to the viewport boundaries to prevent Filament's scissor test from rejecting out-of-bounds rects, while avoiding resetting to full-window scissors which would disable clipping.

The draw geometry is now immutable in the Update function (ImGui texture state is still mutated).

PiperOrigin-RevId: 954277141
Change-Id: Ifdf6866bb4eabaca44b020ea40acc246428b4f0b
2026-07-26 13:35:03 -07:00
Copybara-Service 0ae308c50c Merge pull request #3421 from mmossg:fork_main
PiperOrigin-RevId: 953956612
Change-Id: Idf457a84f8541c5a51946c5e649b3aab441441fe
2026-07-25 14:42:28 -07:00
Michael Moss 59d84a714d Update dependencies ahead of the 3.11.0 release (retry).
Also updates MuJoCo files needed to address changes in Filament.
- "build with clang on windows" patch to sync context lines, remove some
  upstream conflicts, disable Clang thread-safety attribute errors, and
  allow running on MSYS2.
- Skip building Filament samples.
- Add missing <string_view> to material_manager.cc.
2026-07-24 15:27:31 +00:00
Michael Moss 28bea62d78 Fix git apply and re-enable cmake cache on Windows.
This forces git to treat the current directory as the git checkout to apply the
patch to, which avoids issues where a non-git checkout (e.g. from an unpacked
cached tarball) can cause git to find a higher-level git checkout and try to
apply the patches there, which then fails when the files to patch aren't found.

PiperOrigin-RevId: 953377327
Change-Id: I86f51d4e2823b64c825070139479089c7f30e53e
2026-07-24 08:21:48 -07:00
Sam Haves dd4d0585ee Fix missing timer end calls on early returns in collision and actuation
PiperOrigin-RevId: 953348565
Change-Id: I64b563e29b2d620df46d50d12dde9215885f41d6
2026-07-24 07:05:45 -07:00
Matija Kecman 91d78346e1 Replace the Studio parser module with a pure Python implementation
PiperOrigin-RevId: 953181335
Change-Id: I1d2ce6f27f50aa4c30cce6d43caed80186ddef42
2026-07-23 23:52:56 -07:00
Michael Moss a9f56dabc2 Fix Windows CMake patch application and add more logging.
PiperOrigin-RevId: 953024686
Change-Id: I5527f52b7473e74a9203916d866a6a91c01a06c9
2026-07-23 16:44:24 -07:00
Alessio Quaglino fe9dc58477 Fix flexcomp instability when parent body has non-identity quaternion
Fast path in mj_flexPassiveInterp, mj_flexPassiveBendInterp, and
mj_flexPassiveStretch assumed body slide joints are world-aligned
(J = I). When parent body has a non-identity quaternion, joint axes
are rotated (J = R_body), causing wrong force mapping and instability
(NaN/Inf in QACC).

Fix: project world-frame forces onto body local frame via
mju_mulMatTVec3(R_body^T, force) before adding to qfrc_spring/damper.
Also fix the derivative paths:
- mjd_flexInterp_kernel fast path: R^T * K_rot * R * vec
- mjd_flexStiff_assemble (CSR): R_bi^T * K_rot_block * R_bj

The CSR-assembled stiffness matrix is the actual path used by the
implicit CG solver (mj_flexCG gate). The test uses solver="CG" to
activate this path; without it, flex stiffness is integrated
explicitly and no derivative fix can help.

Ported from GitHub PR https://github.com/google-deepmind/mujoco/pull/3379
Original author: Devansh (https://github.com/devansh0703)
Fixes https://github.com/google-deepmind/mujoco/issues/3364

PiperOrigin-RevId: 952789284
Change-Id: If924f7160dd16c0cc88170d80e6e605da0fe2e04
2026-07-23 09:02:21 -07:00
Michael Moss b04a18a00a Fix backslash escaping in KOKORO_GFILE_DIR on Windows.
This var was missing from the "clean up" step for all the path vars, causing
the cmake cache lookups to silently fail due to path mismatch.

PiperOrigin-RevId: 952410036
Change-Id: I5c542e821317497e899de95e5c62d76f88836e60
2026-07-22 16:59:14 -07:00
Copybara-Service c214e81627 Merge pull request #3418 from winklemad:fix/minimize-xtol-accepted-candidate
PiperOrigin-RevId: 952380184
Change-Id: Ied4ab1bfc91dbb55dbd9d2f2e64ab2288513c50e
2026-07-22 15:57:46 -07:00
Michael Moss 3429373b96 Rollback filament dependency updates and patches.
PiperOrigin-RevId: 952196997
Change-Id: I0c4284823bb642e847bc73d4732bcce6a72455c8
2026-07-22 10:23:50 -07:00
Michael Moss c0d1c399af Update patch context in filament-allow-clang-windows.patch.
PiperOrigin-RevId: 952161543
Change-Id: Ia832f692f1f42e905a6cf66365731d5714297db9
2026-07-22 09:19:02 -07:00
Haroon Qureshi e1f6953efa Remove ModelObjects as a dependency on ModelDecorations.
Also allow users to Clear() the decorations explicitly.

PiperOrigin-RevId: 952152025
Change-Id: Ieb21d59986b127b4646c8c5721d33920d14dff85
2026-07-22 09:01:26 -07:00
Sam Haves 1a5af23558 Add <stem>/model.xml search path to mjz_decoder.
PiperOrigin-RevId: 952128127
Change-Id: I8a514297d84026a6028b2416e43df9b5a2a92bbb
2026-07-22 08:11:56 -07:00
Haroon Qureshi b6ab11dc6b Rename LightManager to ModelLights and RenderableManager to ModelRenderables.
This better reflects the purpose of these classes.

PiperOrigin-RevId: 952123609
Change-Id: Ib14c54c3d9b137258ebc706590aca3b2e80015fe
2026-07-22 08:03:32 -07:00
Michael Moss 8c0a73482c Remove unversioned tarball fallback from FindOrFetch.cmake.
PiperOrigin-RevId: 952098246
Change-Id: Id3030fde3045223857711b3e8cce7e671490f8c7
2026-07-22 07:08:04 -07:00
Haroon Qureshi ed7ba6027f Move SceneDecorator to support module.
Also rename it to ModelDecorations.

PiperOrigin-RevId: 952088857
Change-Id: I476d616ec950962f781614e39b75d3d59fdcfcd1
2026-07-22 06:48:33 -07:00
Haroon Qureshi ba9a65031b Allow mesh data to be reuploaded without having to recreate the mesh.
Splits mjrfMeshData into config+data parts.

PiperOrigin-RevId: 952042545
Change-Id: I19a572a0f591fa0d33bbc2c32b974efc075310f4
2026-07-22 04:56:30 -07:00
Google DeepMind d3166cb630 Fix cylinder bias stack overrun in XML parsing
PiperOrigin-RevId: 952016771
Change-Id: I49657d41ad96a6bd1f7f9d5e6b6491c5a229d244
2026-07-22 03:53:45 -07:00
Matija Kecman 0b1ed5b356 platform/ux: general C++ platform UX updates & spec adjustments.
* Enhances ImGui dialogs to support keyboard shortcuts (Enter/Escape) and filters.
* Adjusts GUI layouts for simulation speed and compiler settings.
* Exposes additional model fields in the XML spec generator.

PiperOrigin-RevId: 951988061
Change-Id: I4927c12a8882ba4e91e6098355ec2f5db35c2747
2026-07-22 02:46:30 -07:00
Michael Moss 782c00bc49 Update dependencies ahead of the 3.11.0 release.
PiperOrigin-RevId: 951974346
Change-Id: Ie2b7a357442705e7d37d824463f7feb120a212e7
2026-07-22 02:13:00 -07:00
Matija Kecman e0224c6440 studio: share ImGui and ImPlot contexts across python child extension modules.
Each pybind extension module holds its own copy of the ImGui/ImPlot globals (extension modules are loaded RTLD_LOCAL), so the viewer that owns the contexts must share the pointers explicitly. Without this, client plotting GUIs and user plotting scripts (e.g. the implot sample) crash on null context pointers.

PiperOrigin-RevId: 951917287
Change-Id: I639a173c2ae9f1af4feaf57aff7b5c81854b7393
2026-07-21 23:41:20 -07:00
winklemad 72c9f2af63 Fix least_squares xtol result 2026-07-22 08:17:25 +05:30
Copybara-Service 91bb075108 Merge pull request #3250 from gholmes829:fix/accumulate-inertia-com-frame-order
PiperOrigin-RevId: 951758696
Change-Id: I99f3502b15b84e2fffc58f4b608844148479ca3e
2026-07-21 16:21:08 -07:00
Yuval Tassa 2b30c6bc0f Update MuJoCo contributing guidelines regarding PR imports.
Updates CONTRIBUTING.md to suggest that contributors who do not require Git authorship attribution let maintainers know in the PR, which allows for faster direct incorporation of changes.

PiperOrigin-RevId: 951751097
Change-Id: I521f1ad1978987c71a90e85c1bed71392a07ee7b
2026-07-21 16:06:04 -07:00
Yuval Tassa a7e6114ed7 improve aspect ratios in embedded videos
PiperOrigin-RevId: 951714570
Change-Id: I71b3705d9bb7bceca7f9f7d69344acb4f8f91239
2026-07-21 14:57:26 -07:00
Sam Haves 1f1bfa9e4e Documentation pass for model editing, model encoding, and mjz.
PiperOrigin-RevId: 951665744
Change-Id: I1dfe3b40f451cca686431c263815039a9c38efc8
2026-07-21 13:27:00 -07:00
Yuval Tassa 259e6c4dc6 Fix MSVC ASan compilation by avoiding GCC/Clang specific stack instrumentation
PiperOrigin-RevId: 951656966
Change-Id: I51294e6a95c39f4037e8feb2aee45e69cb51beb0
2026-07-21 13:09:23 -07:00
gholmes829 0e1e0c7f96 Fix COM frame composition in mjCBody::AccumulateInertia 2026-07-21 15:02:14 -05:00
Yuval Tassa 8ccd2b6db5 Update changelog regarding Python free threading support.
Also fix #3231

PiperOrigin-RevId: 951614688
Change-Id: I7d2e6238c1d593efe289e0a9b72717b8dd9e42d0
2026-07-21 11:49:35 -07:00
Yuval Tassa 072e963fa0 Add SO3 transmission and native orientation actuator.
https://youtu.be/17XpwnqyCXs

New transmission type mjTRN_SO3: a relative orientation, targeting a ball
joint or a site+refsite pair. It is the first transmission with more than
one force output: its length is the norm of the expmap vector of the
relative rotation and its moment axes are the 3 rows of the
relative rotational Jacobian, without projecting onto per-actuator gears.

New force law mjGAIN_SO3/mjBIAS_SO3: a geodesic PD servo, force =
kp * log(q_current^-1 * q_target) - kv * velocity, exact for arbitrary axis
combinations with a unique equilibrium at every commanded orientation.
Error, moment rows and velocity all live in the child frame (joint or
site): the right-difference error is the gradient of the geodesic
potential in that frame. The parent-frame (left) error is not: driving
child-frame torques with it pumps energy at large angles, settling into
steady-spinning limit cycles (the SO3LargeAngleConvergence test). The
integrator variant stores the 3D orientation setpoint in act (actnum = 3,
re-anchored to a bounded representative at integration time). Exposed in
MJCF as <orientation joint=|site=+refsite= kp kv|dampratio>, or via
<general gaintype="so3" biastype="so3">.

The setpoint input has two charts: an expmap target (3 controls, default)
or a quaternion target (4 controls) -- <orientation input="quat">, the
first actuator with different input and output widths. The signature is
recorded in a new per-actuator field actuator_ctrlspec (mjtCtrlChart),
whose meaning is scoped by the gain type the way gain/bias parameters are;
ctrlnum is derived from it at compile time and remains the layout
authority. An explicit field rather than width inference or a prm slot:
width-as-chart cannot express same-width signatures (upcoming servo input
subsets), and prm slots are the input_mode pattern this stack retires.
The force law normalizes the commanded quaternion, making it scale- and
antipodally-invariant. The all-zero ctrl still maps to the identity via
mju_normalize4, but it is a degenerate point (a nudge of any component
commands a half-turn), so quat inputs reset to the identity quaternion:
new mj_resetCtrl sets neutral ctrl values (zero, except qw = 1), called
by mj_resetData and the viewers' Clear All. The quat chart is
restricted to dyntype 'none': integrating a quaternion setpoint linearly
is not meaningful on the manifold. New mjsActuator.ctrlspec field carries
the signature through the spec and XML round-trip.

Actuator sensors (actuatorpos/vel/frc) now report one value per force
output; dim = 3 on an SO3 actuator.

As the first actuator with nu != nactuator, this commit also makes the
viewers multi-input aware: the control sliders in simulate and studio,
which indexed per-actuator arrays by control index (out of bounds on
this model class), are generated per control and labeled with the
actuator name plus an input suffix ("orient/qw"), via the new
introspection helper mj_actuatorInputName -- the single source of truth
for input names, extended by each new multi-input type (quaternion
components are w-first: qw, qx, qy, qz). Slider ranges now honor a
defined ctrlrange even when ctrllimited is false: range is the UI hint,
limited is the clamp -- wrapped and expmap setpoints are unbounded but
still want finite sliders, while quat components are truly bounded.

The rotational demo model is orientation.xml under
test/engine/testdata/actuation/, upgraded to a three-way contrast:
per-axis wrapped servos vs an expmap-commanded vs a quat-commanded
orientation actuator, on identical checker-textured boxes. It is loaded
by the mixed-axis contrast and input-name tests, and doubles as the
viewer test model (slider groups of 3 independent, 3 grouped, 4 grouped).

PiperOrigin-RevId: 951607063
Change-Id: If235dba8e2f2ca72672e7c62531a27e967c6a373
2026-07-21 11:36:13 -07:00
Haroon Qureshi a8545ac7cc Improve flex rendering.
RenderableManager is responsible for rendering the "skinned" flexes
which represent the correct "final" look of a flex. This now includes
1D flexes which are rendered as a sequence of capsules (similar to
tendons).

SceneDecorator is responsible for rendering the debug (unskinned)
versions of flexes. This includes the vertices (small spheres for each
vertex), edges (thin cynlinders for each edge), and faces (triangles
for each face, including sublayers).

PiperOrigin-RevId: 951595046
Change-Id: Iebc6fd7a747a602813b6457333bd9fa5915e28d3
2026-07-21 11:15:37 -07:00
Copybara-Service 7bfa10e1e2 Merge pull request #3354 from Nas01010101:fix/ktx-classic-renderer-skip
PiperOrigin-RevId: 951520219
Change-Id: Ib6a1a8c553140e2e6c99055a579facf51e0d7f5a
2026-07-21 09:01:02 -07:00
Yuval Tassa 426cb5481d Fix sparse-path rotational Jacobian misalignment in mj_jacSum
PiperOrigin-RevId: 951341459
Change-Id: I18bc27765b3147a5eb520e3026317e9a5a2dfc30
2026-07-21 02:02:12 -07:00
Copybara-Service a1f38c8e6e Merge pull request #3396 from teerthsharma:topo/linear-island-scratch
PiperOrigin-RevId: 951110709
Change-Id: I0c9c96365a5667172c1d676026ab797b7f8e8137
2026-07-20 16:16:35 -07:00
teerthsharma 57faf5f63a Credit linear-memory island discovery
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:43 +05:30
teerthsharma 7ae4f22693 Restore flex island invariants in comments
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:43 +05:30
teerthsharma cdda847191 Restore static-constraint island diagnostic
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:43 +05:30
teerthsharma 8d9f230514 Export disjoint-set island helpers directly
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:42 +05:30
teerthsharma d9c8bcbc8f Remove temporary island benchmark
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:42 +05:30
teerthsharma 5d91d878c2 Benchmark and expose disjoint-set islands
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:42 +05:30
teerthsharma ba2782140f Revert unvalidated island topology cache
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:42 +05:30
teerthsharma bc32db7f25 Cache island topology data
Store island topology in `mjData` so repeated island solves can reuse stable connect/weld equality partitions. Add cache invalidation checks for active equality changes and cover the fast path with an island regression test.

Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:42 +05:30
teerthsharma 03203e2f32 Update engine_island.c
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:41 +05:30
teerthsharma 52ddcbc81a Build native islands directly from constraint incidence
Signed-off-by: teerthsharma <teerths57@gmail.com>
2026-07-20 22:27:41 +05:30
Copybara-Service 5ea4c3a58c Merge pull request #3406 from devshahofficial:agent/pr3157-attach-mjcwrap
PiperOrigin-RevId: 950890116
Change-Id: I95331186f166e84b94c3fcac555c9d446a421010
2026-07-20 09:39:43 -07:00
Yuval Tassa a264d0bc8b Add geom adhesion: contacts that pull, via translated friction cones.
https://youtu.be/GioWwB36XHI

The new geom attribute adhesion (units of force, signed; pair-level
override) translates the contact friction cone along its normal so
that the force origin lies strictly inside it. Consequences: each
contact can pull with up to the given force before breaking, and the
tangential friction budget becomes mu*(f_N + adhesion) -- the
Mohr-Coulomb yield condition with cohesion c = mu*adhesion -- so
lightly-squeezed grasps retain a guaranteed friction floor.

A translated cone factors exactly into {constant attractive force}
+ {original cone}, so no solver kernels change. The implementation is
this factorization: a constant attraction along contact normals
accumulated into the new mjData.qfrc_adhesion (summed into
qfrc_passive), plus a bias of adhesive contact rows' reference
acceleration (aref += R*adhesion), which makes resting penetration
exactly independent of adhesion. Contacts of adhesive pairs remain
active throughout the gap zone, producing rows with positive violation
whose reference acceleration pulls: a tether that resists pull-off
smoothly, captures objects released within the band into steady
contact, and detaches at the specified force. Adhesion values of the
two geoms combine by sum; explicit pairs override.

mj_contactForce reports the net interface force (cone force minus the
adhesive pull), whose normal component can now be negative. Negative
adhesion is allowed and produces a repulsive offset (air hockey).

PiperOrigin-RevId: 950858148
Change-Id: I879c08eba7ae501e5c0f8c2f807167344da4c2bc
2026-07-20 08:35:45 -07:00
Michael Moss b942c9f922 Update MuJoCo version to 3.11.0 in preparation for breaking changes release.
PiperOrigin-RevId: 950824721
Change-Id: Icc06b10ea69f5dd84e100eb75233f1598c2cbf88
2026-07-20 07:26:25 -07:00
Matija Kecman 8196ca17f8 studio: catch KeyboardInterrupt in samples and format imports.
* Adds exception handler block to simulator samples to allow clean Ctrl+C exits.
* Formats import statements inside code generator validator.

PiperOrigin-RevId: 950821976
Change-Id: I283533d87619d5d9b54d9bec970cdefe538fd752
2026-07-20 07:20:07 -07:00
Michael Moss a62bf19e64 Re-enable ccache, which appears unrelated to the test failures.
PiperOrigin-RevId: 950745972
Change-Id: I5544a2f6421d8c1b897df03a5438458ebd744c40
2026-07-20 04:15:09 -07:00
Yuval Tassa 1a33ca4ae5 Release docs auto-generation scripts and test
PiperOrigin-RevId: 950744854
Change-Id: Ibcd9d6bd3e6ec50d5d6753b8c9516f7d31f19e5b
2026-07-20 04:12:10 -07:00
Hana Joo 78946ca94e Adding type suppressions for pyrefly
PiperOrigin-RevId: 950703735
Change-Id: I6b6d5826a0dd1f4c0a1cbb2a46aee944cd60d884
2026-07-20 02:40:02 -07:00
Haroon Qureshi 00abc5465f Function for converting mjvCamera to mjrCamera.
PiperOrigin-RevId: 950677018
Change-Id: I189c2415a1f773beed0d8f0ea0dcb9c646ea260f
2026-07-20 01:40:41 -07:00
Yuval Tassa 6f487086a5 Add MUJOCO_ENABLE_LTO CMake option to make LTO configurable. Fixes #3374, #2904
PiperOrigin-RevId: 950629900
Change-Id: If4b3755f0e8653efbd9e6a4134140dd96b1f743d
2026-07-19 23:46:15 -07:00
Kyle Bayes 3990305373 Add docstrings to mjCPair.
PiperOrigin-RevId: 950397298
Change-Id: I84a7df05c16cd71ef7d087f3f63e9f129ed775a8
2026-07-19 07:38:57 -07:00
Yuval Tassa 9bf03e6056 improve wording in changelog
PiperOrigin-RevId: 949807312
Change-Id: I9de37cfd61f6e0eb67b0b18101d69d7abd66b7ca
2026-07-17 16:07:59 -07:00
Yuval Tassa a04b0c5b97 Add boolean flags for gravity compensation and surface velocity in mjModel.
These fields (`flg_gravcomp` and `flg_surfacevel`) replace the fast-path checks originally guarded by `ngravcomp` and (recently) `nsurfacevel`. Since the engine uses these integers only as flags (zero vs non-zero), migrating them to actual booleans makes them writeable from the Python bindings at runtime without violating size/dimension constraints.

The legacy integer field `ngravcomp` is marked as deprecated and will be removed in a future release.

PiperOrigin-RevId: 949779204
Change-Id: Ifab1f026063a4239302e6ad689663b611b59dda8
2026-07-17 15:05:26 -07:00
Sam Haves ebd4abae03 Add model.xml fallback search path to mjz decoder
PiperOrigin-RevId: 949690037
Change-Id: I93978c1f9ded12c69ffe321fe1f85721db32f555
2026-07-17 12:02:33 -07:00
Kyle Bayes e3293a5f29 Add fields for flex collisions in threaded narrowphase.
PiperOrigin-RevId: 949651632
Change-Id: I09dfa85eb57b9c3a97850c35f51d1d2872852704
2026-07-17 10:48:51 -07:00
Yuval Tassa 135b482c9d Copybara import of the project:
--
7f117fa7a7060b36687e7544e8d7393d14a1fa90 by Yuval Tassa <tassa@google.com>:

Handle clang AST loc nodes with elided 'line' in introspect codegen.

Apple's math.h (included directly by mujoco.h) contains an anonymous union
whose clang-JSON 'loc' lacks the 'line' key (clang elides it when unchanged
from the previous node), crashing AstProcessor._make_anonymous_key with a
KeyError during bindings regeneration on macOS. glibc's math.h has no such
union, so this never bites on Linux.

Fall back to an offset-based key for line-less nodes; these system-header
structs are never referenced by MuJoCo types, so the key only needs to be
unique.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3411 from yuvaltassa:introspect-loc-fallback 7f117fa7a7060b36687e7544e8d7393d14a1fa90
PiperOrigin-RevId: 949626713
Change-Id: I9d99b427885ede18b075db6d4e507aa8bc0d049a
2026-07-17 10:02:30 -07:00
Yuval Tassa 56a93979e0 Interpret position and intvelocity setpoints on 3D rotational transmissions (ball joints, site+refsite) on the circle. The force uses the setpoint representative nearest the current length for smooth tracking beyond pi.
- Wrapping in force path is local; act is re-anchored at integration time.
- Remove hardcoded `actrange` for intvelocity actuators.

PiperOrigin-RevId: 949566477
Change-Id: I349fdf17eedfbb2174d698cc1a6a91d52810b4a3
2026-07-17 07:49:30 -07:00
Michael Moss 9331c1cd9b Disable ccache to see if it fixes random test crash issues.
PiperOrigin-RevId: 949521487
Change-Id: I3b1f6c46ee015ad134a1c16a9bbc6edfd001659a
2026-07-17 05:59:02 -07:00
Copybara-Service b75470a1e0 Merge pull request #3387 from bd-pmorais:pmorais/renderer-live-mat-texid
PiperOrigin-RevId: 949427127
Change-Id: I607af41aefdefd6d22602889e6982d64df8b380b
2026-07-17 01:23:40 -07:00
devshahofficial 3e1dffc286 Fix attached tendon wrap model pointers 2026-07-16 15:00:57 -07:00
Michael Moss 54bf99f116 Remove Mac x86 from the build matrix.
PiperOrigin-RevId: 949055238
Change-Id: Ibef3e13df065a184fc787c47df8641d35d2a25d2
2026-07-16 10:47:58 -07:00
Alessio Quaglino cadf3bdedd Add changelog entry for effective metric flex elasticity.
Add a changelog entry documenting that flex elasticity (stretch, bending,
interpolation stiffness) is now integrated implicitly inside the CG
constraint solver via an effective metric, replacing the previous post-hoc
CG correction.

PiperOrigin-RevId: 948963146
Change-Id: Id9c2a2920aabd0776f630b2f3a1ab30a214d9bf2
2026-07-16 07:34:50 -07:00
Pedro Morais 03e484116d Reflect mjvgeom texture field changes in the filament renderer 2026-07-16 10:29:00 -04:00
Yuval Tassa 0ce5e98916 Use mj_id2name in viewer code where appropriate.
PiperOrigin-RevId: 948945088
Change-Id: I5635c71fd285b128618592699ca64ce8c0f35e31
2026-07-16 06:51:19 -07:00
Yuval Tassa a77dff84a4 Apply unsymmetrized fluid derivatives to standalone free bodies in implicitfast.
PiperOrigin-RevId: 948899583
Change-Id: Icfb5a713f89a94e597c7607e9aa10a9e151dc2aa
2026-07-16 04:47:56 -07:00
Haroon Qureshi eeda4d0984 Use body center-of-mass (subtree_com) instead of lookat point for tracking cameras.
PiperOrigin-RevId: 948850032
Change-Id: I439946ac1ea7f8556c3132540d82f633a7c4a5f5
2026-07-16 02:39:45 -07:00
Haroon Qureshi 3b63fbc6ba Correctly apply visibility state from mjvOption.
PiperOrigin-RevId: 948792559
Change-Id: Ic0357c7841519e8e5c903b45f045831745f0b2b3
2026-07-16 00:24:04 -07:00
Yuval Tassa f841b67c17 Fix some changelog links
PiperOrigin-RevId: 948651115
Change-Id: Ibc915ddc71d884cee9f89eaa5dcaf498a833c57a
2026-07-15 18:05:59 -07:00
Yuval Tassa 4787c8094c Add geom surfacevel: zero-dof conveyors, treadmills and turntables.
https://www.youtube.com/watch?v=PdSdrqhSiZA

The new geom attribute surfacevel (6 numbers: linear and angular velocity in the geom's local frame, angular about the geom frame origin) specifies the velocity of the geom's surface material relative to the geom frame. The relative surface velocity of the two geoms is added to the tangential contact rows of efc_vel in mj_referenceConstraint, so friction drives touching bodies toward the motion of the surface: objects on a conveyor are transported at belt speed, turntables impart omega x r with torsional spin-up for condim >= 4, and surface velocities compose with each other and with body motion. The component along the contact normal is projected out: probe experiments showed that velocity-space emission chatters mass-independently and ingestion merely deepens penetration; normal-direction effects belong to force-space features.

surfacevel is interpreted in the geom frame as authored: for mesh geoms, whose compiled frame absorbs the mesh centering and principal-axes transform, the compiler re-expresses the authored value in the compiled frame.

No special interaction with sleeping: objects being transported do not fall asleep because they are moving; objects at rest on an active surface may sleep like any other resting object.

Includes showcase models (model/surfacevel/): a luggage carousel whose ring is a spinning square-profile supertorus fed by a cascade of belts with matched spinning end rollers, bags dropping in and circulating indefinitely; and a treadmill with a passive humanoid.

PiperOrigin-RevId: 948647785
Change-Id: I0c6559a91cc7ece1237eb8ac2e51986e7342d962
2026-07-15 17:58:17 -07:00
Copybara-Service 97eb1e5d0c Merge pull request #3403 from rkothari3:docs-simulate-shortcuts
PiperOrigin-RevId: 948571230
Change-Id: Ibbd151e9f2143c3e41cda1b6ee4873f088595084
2026-07-15 15:14:29 -07:00
Alessio Quaglino ea230a950c Implicit flex elasticity in the CG constraint solver via an effective metric
This CL replaces the post-hoc implicit flex correction (`flexInterp_cgsolve`) with a **linearly-implicit effective metric** `M̃ = M + (h² + h·damping)·K` carried by the CG constraint solver itself. Contact/friction forces and implicit flex elasticity are now computed against one consistent metric, instead of the solver seeing `M` and a post-solve correction changing `qacc` behind its back.

Gate (unchanged semantics): `solver="CG"` + implicit/implicitfast integrator + pyramidal cones + flex stiffness present. Newton and PGS are untouched. `solver="CG"` remains the user-facing contract — the factorization is an implementation detail of the preconditioner.

### What's in the metric

- **mjData `efm_*`** (arena, efc-like lifetime/skip semantics; built in `mj_fwdPosition`, value-refreshed in `mj_fwdVelocity`): the per-step stiffness CSR `efm_B_*`, its reverse-Cholesky factor `efm_dofid` + `efm_L_*` (nested-dissection ordered, separators-first for the reverse factorization), and the smooth-force shift `efm_c = h·K·qvel`.
- **`mjd_flexStiff_assemble`** now assembles stretch (Gauss–Newton), standard dim-2 bending, and — via the cached corotated stiffness `d->flexelem_krot` — interp stiffness (all node bodies on simple sliders: point Jacobian is I₃, `flex_centered` not required; fixed nodes drop like pins) into one dof-level CSR. `mjd_effMulAdd`/`mjd_effSolve` apply the metric, with matrix-free operator fallbacks where assembly does not apply.
- **mjModel `efm0_*`** (`nefm0dof`/`nefm0L`): the constant part of the metric factor — currently the dim-2 bending factor, computed once in `mj_setConst` — so bending-only models pay zero per-step factorization cost. Naming mirrors mjData's `efm_*` with the standard `0`-suffix (reference/constant) idiom, and is deliberately not bending-specific: future constant contributors extend it without renames.
- The solver consumes the metric through pre-shifted `qfrc_smooth` and the metric products `Ma`/`Mv`/`Mgrad`; `qacc_smooth` becomes the unconstrained minimizer of the implicit dynamics, which makes the no-constraint shortcut and the warmstart choice consistent by construction.
- **`mj_inverse` adds `B·qacc − c`**, making inverse dynamics discrete-consistent with the gated forward dynamics — exact, since the gated path has no qDeriv term (new test `ForwardTest.GatedFlexInverseConsistency`).

### Performance

All numbers: ms/step over the same 2000-step window, models as shipped on each side (old code with the old model settings vs this CL with the new ones).

The new solver path activates on exactly two shipped models — the ponchos, the only flex models that need an implicit integrator (poncho on Euler degenerates to >200 ms/step). For them, this CL trades speed for consistency: the implicit bending solve now runs inside every solver iteration, where the contact solve can see the stiffness, instead of once after the solve. Solver iterations drop because the curvature is visible, but each iteration pays for the implicit solve:

| model | before | after | solver iters/step |
|---|---|---|---|
| poncho | 2.47 | 3.30 (1.33×) | 16.8 → 11.8 |
| poncho_edgeequality | 1.96 | 2.72 (1.39×) | 13.2 → 10.0 |

What that price buys: contact forces consistent with the implicit elasticity (previously the post-hoc correction changed `qacc` after the constraint solve), discrete-consistent inverse dynamics, and the removal of the post-hoc special case from the integration path. Raising poncho's timestep from 2 to 5 ms leaves its per-step cost nearly flat, so the consistency price can be recovered by taking fewer steps where accuracy allows.

Every other flex model was measured stable on Euler at its shipped timestep and switches to it (these models predate the post-hoc integrator; implicit was never load-bearing for them). They end up equal or faster than before: bunny_multicell 0.47 → 0.40, trampoline 0.28 → 0.25, plate 1.02 → 0.99, pancake 0.34 → 0.33.

Finally, the per-step factorization makes configurations practical that the old code could only integrate explicitly: implicit stretch elasticity (`elastic2d="stretch"`/`"both"`, dim-3 solids) and factorized interp stiffness. No before/after exists for these — stock has no implicit treatment of stretch at all.

### Behavior changes

- With the post-hoc correction deleted, interp/bending models running `solver="Newton"` (or elliptic cones, or islands) now integrate flex elasticity **explicitly** (previously: post-hoc implicit). Affects e.g. `gripper_trilinear` (stable, and faster, but different semantics). Follow-up options: Newton-side metric support, or a documented fallback.
- With the gate on, `mj_forward` outputs are timestep-dependent for gated models (they answer the linearly-implicit discrete problem); `qacc_smooth` and `mj_inverse` change accordingly. Non-gated models are bit-identical (full suite green throughout).

### Validation

- 1737/1737 tests, including new: `FlexStretchDerivatives` (FD-validated GN operator), `FlexStiffAssemble`/`FlexStiffAssembleInterp` (CSR ≡ operators), `GatedFlexInverseConsistency` (fails pre-change), equivalence tests vs the old post-hoc treatment (bending matches to 2e-11).
- Fingerprint discipline throughout: bending-only models bit-exact across every refactor; permutation/kernel changes verified iteration-identical.

### Known follow-ups (not in this CL)

3×3-block sparse Cholesky kernel (the numeric factorization is index-bound; projected ~3× on the factor); mjModel persistence of the factor's symbolic pattern (rest-pose ND makes sizes compile-time); the general effective-metric mode (all solvers, all PSD-safe force classes, behind an enable flag).

PiperOrigin-RevId: 948561856
Change-Id: I8b8e32ebd0428042af71647d0470d10773bf6daf
2026-07-15 14:57:42 -07:00
Yuval Tassa f0fa3d8260 Remove midpoint integration, superseded by free-body gyroscopic derivatives.
The gyroscopic (bias) derivatives applied to standalone free bodies by the
implicitfast integrator provide comparable stability for spinning bodies,
with none of midpoint's restrictions: they apply under contacts, fluid
forces and constraints, and preserve the linear force-velocity relation
required by discrete-time inverse dynamics. The invdiscrete flag reverts to
its original single meaning and no longer affects forward dynamics.

Restore implicitfast coverage in the DiscreteInverseMatch test, removed
when midpoint made discrete inverse dynamics untestable.

Add implicit gyroscopic (bias) derivatives for free bodies in implicitfast.

The implicitfast integrator drops the RNE (bias) derivative to stay on the
symmetric Cholesky path, so fast-spinning free bodies integrate gyroscopic
forces explicitly and can gain energy. Symmetrizing the gyroscopic Jacobian
is not an option: its stabilizing content is the antisymmetric part, and
adding only the symmetric part is destabilizing.

Instead, exploit the fact that for a standalone free body the 6x6 block of
M - h*D is decoupled from the rest of the system (qDeriv sparsity is
tree-local): after the global solve, rebuild the block with the exact bias
derivative in closed form (mjd_freeBias_vel) and re-solve it with dense
unsymmetric LU, overwriting the block's rows of qacc. For lone spinning
bodies this makes implicitfast match implicit to rounding, at ~150ns per
eligible body: cheaper than the midpoint machinery it will replace.
Eligibility is structural only; contacts, fluid and constraints need no
gating. The same block is mirrored in discrete inverse dynamics
(mj_discreteAcc), making invdiscrete exact for spinning free bodies.

PiperOrigin-RevId: 948472495
Change-Id: I813ef3d98c7b399881bc8603b9f9208cfb02eb58
2026-07-15 12:07:44 -07:00
Pedro Morais 0a6b631d4b Make change non-breaking per haroonq's feedback 2026-07-15 11:53:22 -04:00
Haroon Qureshi b2106db52f Update studio to use mjv_moveCamera.
PiperOrigin-RevId: 948361631
Change-Id: I4fd548ad6c604bd61a8716afcc8203abe1476320
2026-07-15 08:51:31 -07:00
Yuval Tassa d507e92198 Preparation for MIMO actuators: split actuator counts: nu (inputs), nactuator (objects), nout (outputs).
An actuator now owns a block of consecutive controls
(actuator_ctrladr/ctrlnum, width defined by the actuator type) and a block
of consecutive force outputs (actuator_outadr/outnum, width defined by the
transmission type). Force outputs are the scalars of actuation space: one
force, length, velocity and moment row each. nout = dim(actuator_force) is
derived from transmission types; all current types have width 1, so all
three counts coincide for every existing model and behavior is bit-exact.

Array re-keying: ctrlrange/ctrllimited by nu; forcerange/forcelimited/gear/
acc0/length0/lengthrange and the moment row structure by nout; everything
else per actuator. The mjModel actuator block is re-sorted by size key.

Layout-breaking, not behavior-breaking: saved .mjb files are invalidated
(size list changed) and recompilation is required.

PiperOrigin-RevId: 948351772
Change-Id: Icbc196ffa083cb1eaa6f1a3710869c89d8f62540
2026-07-15 08:30:20 -07:00
Kyle Bayes 06f12a9372 Set max in hill climbing support. When imax is the optimal index then this reduces from three iterations down to one.
PiperOrigin-RevId: 948334160
Change-Id: Ia12fbc853fc65f70c525a617cfdced6e98d30dca
2026-07-15 07:50:52 -07:00
Haroon Qureshi 52317058ba Add pan/tilt motions to mjv_moveCamera.
PiperOrigin-RevId: 948308546
Change-Id: I2724b889759e652ed50d03bf97f3c7125cd0eb56
2026-07-15 06:50:15 -07:00
Haroon Qureshi 1e85ce176f Migrate filament header documentation to docs.
PiperOrigin-RevId: 948294877
Change-Id: I6e110bbdc4d2e329a243f1b96d560698174de26b
2026-07-15 06:14:40 -07:00
Yuval Tassa b60609d2a1 Add links to numbered changelog entries.
PiperOrigin-RevId: 948257078
Change-Id: I7c9747debade178a94020cdf43ad1c3613a5c29a
2026-07-15 04:34:44 -07:00
Yuval Tassa 64d4b3bdb2 Fix changlelog item numbering
PiperOrigin-RevId: 948228547
Change-Id: I26eebaa4c8f4c0f30718b6e4391cf990a85bc30f
2026-07-15 03:25:32 -07:00
Haroon Qureshi fa36015bae Remove unneeded mjvScene argument from mjv_moveCamera.
PiperOrigin-RevId: 948204736
Change-Id: Ic9b116ce439b3153764af67c449a824aec1994dc
2026-07-15 02:26:04 -07:00
Copybara-Service 6c78c8664e Merge pull request #3340 from devshahofficial:devshahofficial/mjr-renderer-info
PiperOrigin-RevId: 948183711
Change-Id: I28b256eca22e86ec0ba05a4fa26458d678aca130
2026-07-15 01:37:11 -07:00
Yuval Tassa c69ef03083 Add zero-iteration early exit to the primal solvers, certified by the duality gap.
The primal cost has curvature of at least M in every zone, making it strongly
convex in the M-norm and bounding the suboptimality of any point by the
Fenchel duality gap at its constraint forces:

  cost(qacc) - cost* <= 0.5*grad'*M^-1*grad

Since M's factorization always exists, this certificate is evaluable before
the solver does any work: one triangular solve and one dot product. When the
warmstarted solution is already certified to satisfy the tolerance, CG and
Newton now return with zero iterations; for Newton this skips building and
factorizing the Hessian. If the certificate declines, Newton gets a second
exit after factorization: the Newton decrement, checked before the first
line search.

Because the gap bounds cost suboptimality, stiff constraints can convert it
into force errors of order sqrt(2*gap*stiffness). Newton solutions are
characteristically force-accurate, so Newton zero-iteration exits also
require the gradient criterion, preserving constraint-force accuracy at
rest; CG solutions are characteristically cost-accurate and exit on the gap
alone.

On a settling pile of 50 boxes (300 dofs, ~200 contacts), end-to-end time
per step drops 13% over a settle-then-rest run and 27% in the quiescent
limit, with Newton iterations falling from 0.98 to 0.40 per step.

Tests: WarmstartZeroIterations sweeps solver/cone/jacobian on a settled box,
asserting zero iterations, forward/inverse consistency, and agreement with a
tolerance=0 control solve from the same state. WarmstartZeroIterationsIslands
checks per-island exits with a kicked box next to a settled one.
RefsiteConservesMomentum now requests an exact solve (tolerance=0), since it
asserts momentum conservation tighter than the solver tolerance contract.
PiperOrigin-RevId: 947993735
Change-Id: I2fd855774bff619709b2c386f1ba2714286e0821
2026-07-14 17:24:08 -07:00
rkothari3 2fe87a4833 docs: add full keyboard and mouse shortcut reference for simulate
The F1 overlay lists only the most common commands, and there was no
complete shortcut list anywhere in the docs. Add one to the simulate
section, derived from the shortcut declarations in simulate.cc,
simulate.h, mjVISSTRING and mjRNDSTRING.

Fixes #3306
2026-07-14 14:01:25 -04:00
Yuval Tassa 1e66efd114 Add the Newton decrement as a termination criterion of the Newton solver.
After an accepted line-search step, the solver has already rebuilt the gradient
and Hessian and solved for the next search direction, so the Newton decrement
0.5*g'*H^-1*g -- the quadratic model's predicted cost improvement of the next
iteration -- costs one dot product. Terminating when it falls below tolerance
avoids running one more iteration only to observe a correspondingly small
actual improvement.

This is a C port of Alain's proposal in MJWarp:
https://github.com/google-deepmind/mujoco_warp/pull/1520

PiperOrigin-RevId: 947768034
Change-Id: I94e5c71a4e2b4a7775611edd1dad254bba2633b4
2026-07-14 10:30:18 -07:00
Kyle Bayes 2444defc63 Support arbitrary large meshes in multiccd by reusing EPA memory.
PiperOrigin-RevId: 947709621
Change-Id: Idc4f168434b9d0a8555c0bed989adb0e99770a78
2026-07-14 08:48:25 -07:00
Yuval Tassa 0afafacfc5 Add fixed-size 6x6 dense LU factorization with benchmark.
mju_factorLU6/mju_solveLU6: same algorithm as mju_factorLU/mju_solveLU
with compile-time size, allowing full unrolling. At n=6, factor+solve is
25% faster than the runtime-sized version (93 vs 124 ns), and fixed-size
LU factorization is faster than generic dense Cholesky (55 vs 61 ns):
at this size, runtime-n loop overhead outweighs Cholesky's 2x flop
advantage. See new lu_benchmark_test. Results agree with the generic
version to rounding, not bitwise: the compiler may fuse (FMA) the
unrolled version differently.

Also add two DenseLU tests: a pivoting-required matrix with zero
diagonal, and fixed-vs-generic agreement.

PiperOrigin-RevId: 947705056
Change-Id: I24c54c9510964aa376886e9dd721890eda9889d3
2026-07-14 08:38:19 -07:00
Copybara-Service b7af32ac87 Merge pull request #3363 from ebms03:fix-resolve-plugin-segfault
PiperOrigin-RevId: 947628510
Change-Id: Ied0fcd3bb30267a133f1c6f6d6799c9236bc6845
2026-07-14 05:47:35 -07:00
Yuval Tassa 23cc383372 internal change
PiperOrigin-RevId: 947585050
Change-Id: Iaf9b60523b06d3cfd513ec661296eb39f4709442
2026-07-14 03:59:35 -07:00
Yuval Tassa 0ce8f7b06b Replace functionally opaque Viscous Pause with functionally transparent "Viscous posing mode" toggle.
PiperOrigin-RevId: 947527204
Change-Id: I122a9730fa22ac9e8809762046a89fb0a774d827
2026-07-14 01:50:13 -07:00
Michael Moss 3c6080b1c0 Add a CMake deps cache to improve build reliability and speed.
PiperOrigin-RevId: 947522108
Change-Id: I4aa11c08c5ee47a8ab0fc023038d84b46775c9b6
2026-07-14 01:38:03 -07:00
Yuval Tassa 796b803ecf Calibrate float32 tolerances for several engine tests.
PiperOrigin-RevId: 947501998
Change-Id: I939aaf3db7d8b7cbd04d7bb4885d10e0191e579a
2026-07-14 00:51:48 -07:00
Yuval Tassa 6afe13573b Fix single-precision (mjUSESINGLE) CMake builds.
PiperOrigin-RevId: 947367737
Change-Id: If2b56c9d4b4c214c858f6d8b588443f6bd4896ee
2026-07-13 19:02:26 -07:00
ebms03 07c14a7c1a Update user_model_test.cc
typo
2026-07-13 20:46:07 +02:00
ebms03 fc5ed199a6 Update user_model_test.cc
Remove trailing whitespace
2026-07-13 17:03:51 +02:00
ebms03 fb4686d049 Update CMakeLists.txt
Remove trailing whitespace
2026-07-13 16:58:55 +02:00
Copybara-Service 9b053d68e9 Merge pull request #3395 from google-deepmind:dependabot/pip/mjx/pip-26.1.2
PiperOrigin-RevId: 946997660
Change-Id: I3edb881bcdbd6f9b089be164da77b14060f4a334
2026-07-13 06:13:22 -07:00
Yuval Tassa dddb2767c6 Include gap in body_margin, fixing mid-phase pruning of in-gap contacts.
The mid-phase BVH descent filter prunes body pairs using body_margin,
which was compiled as the max over geom margins, excluding gap. Broadphase
and the leaf-level test both use margin+gap, so any multi-geom body relying
on gap could silently lose its in-gap contacts when raw AABBs don't
overlap. Single-geom bodies take the leaf-leaf path and were unaffected.

PiperOrigin-RevId: 946967548
Change-Id: I6d92baa296f1a83be68b4dbfd64a96d1c7efd3c4
2026-07-13 05:04:55 -07:00
Yuval Tassa f5f9d9efb7 Fix bug in mesh normal scaling for nonuniform mesh scales.
PiperOrigin-RevId: 946937791
Change-Id: I1b8a0ad4d573842ef9f76572dea25668dd319b52
2026-07-13 03:57:00 -07:00
Google DeepMind fbf031a7d5 Replace functionally opaque Viscous Pause with functionally transparent "Viscous posing mode" toggle.
PiperOrigin-RevId: 946298154
Change-Id: Ia06dd6346ac1002000f2d0b1cf9498ffb0d5f8bd
2026-07-11 13:47:48 -07:00
Haroon Qureshi 94132c75c7 Remove dead code.
PiperOrigin-RevId: 946289927
Change-Id: I4dc493b522f33c281511a8e6ad407e734e50734f
2026-07-11 13:13:32 -07:00
Yuval Tassa 724a6c6623 Replace functionally opaque Viscous Pause with functionally transparent "Viscous posing mode" toggle.
PiperOrigin-RevId: 946286636
Change-Id: I3e542b12bb57c67f3f194d7bcfdffe39de4f2b94
2026-07-11 13:00:59 -07:00
Yuval Tassa 892d889793 Fix numerical instability in elliptic contact line search.
Reformulate the cost difference calculation (`ellipticCostDif`) to use mathematically equivalent formulas that avoid subtracting large, nearly equal values (cancellation errors) in single precision at high normal forces.

This is a C port of Alain's formulation in MJWarp:
https://github.com/google-deepmind/mujoco_warp/pull/1512

Also adds an integration test (`EllipticLineSearchPrecisionDiagnostics`) that reproduces the precision issue under large normal forces in the sliding regime, and asserts that the solver does not produce large negative improvements in either precision. This test failed before the change.

PiperOrigin-RevId: 946137815
Change-Id: Ia8fc1c4823b5fee770140c8989b9465737d22ad7
2026-07-11 03:04:33 -07:00
Yuval Tassa 4a03a61734 Fix engine_util_sparse_test on MSVC
error C2466: cannot allocate an array of constant size 0

PiperOrigin-RevId: 945988439
Change-Id: Iceb4c536665a4bb42a603a17c41b083a4b6abeea
2026-07-10 18:28:23 -07:00
dependabot[bot] bc3f17107e Bump pip from 26.1 to 26.1.2 in /mjx
Bumps [pip](https://github.com/pypa/pip) from 26.1 to 26.1.2.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/26.1...26.1.2)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: 26.1.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 20:38:40 +00:00
Yuval Tassa d6650f84e5 Remove engine_util_container and its test.
PiperOrigin-RevId: 945701044
Change-Id: I6ca3d4fc87cdcd9e3fc14ee49b3aa441a70cd8bd
2026-07-10 07:26:05 -07:00
Yuval Tassa 0cb3fad654 Add missing tests to cmake
PiperOrigin-RevId: 945700668
Change-Id: If501d188562d0ff5e50b3fc6950f05f0d9a4a040
2026-07-10 07:24:50 -07:00
Yuval Tassa e6452e2c88 Rename testspeed argument npoolthread to nenginethread.
PiperOrigin-RevId: 945698744
Change-Id: Ida6d5ab24c88441fb05c778e8507d6369eb74f1c
2026-07-10 07:19:21 -07:00
Yuval Tassa ff629889da Increase default sleep_tolerance from 1e-4 to 1e-3.
PiperOrigin-RevId: 945696845
Change-Id: I77caa0b6c0966da986451ff9eee5aecaf4e30106
2026-07-10 07:14:37 -07:00
Haroon Qureshi 40feb498a1 Clear material instance assignments at start of frame.
PiperOrigin-RevId: 945623848
Change-Id: I983efa6a14d25e2cb0f46b8bd529086d84247a50
2026-07-10 03:56:52 -07:00
Taylor Howell f6f80cd0a0 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 945593266
Change-Id: Ic08842caabb92bc32974892ffae98e3295827094
2026-07-10 02:37:52 -07:00
Copybara-Service cb28d0c7d1 Merge pull request #3381 from tkelestemur:tarik/mjx-warp-put-model-nworld
PiperOrigin-RevId: 945578693
Change-Id: I873e4f47551d02f506d3af37040e1014fa0edb61
2026-07-10 02:02:02 -07:00
Yuval Tassa 2f650a7beb Studio: extract TimelineScrubberGui and add it to the toolbar.
The code for the timeline scrubber widget has been moved from `App::ModelOptionsGui` into a new method `App::TimelineScrubberGui`. This new method is now called in both `App::ModelOptionsGui` and `App::ToolBarGui`, replacing the thread count slider in the toolbar.

PiperOrigin-RevId: 945565640
Change-Id: I6d5cab0b2397e8b32a2b335e8a709bb9e19bdb48
2026-07-10 01:26:48 -07:00
Sam Haves dc7581acfa Add pluggable resource writing to MuJoCo
Extend mjpResourceProvider with an optional write callback (write)
so that mj_encode, mj_saveXML, and mj_saveModel can write to any
registered provider.

PiperOrigin-RevId: 945202741
Change-Id: I37903425260932e555f4a8c2392c4ff8c2e6cc06
2026-07-09 10:47:48 -07:00
Pedro Morais d43c3ed426 Move texture block copy out of render context so it can be modified online via mjmodel 2026-07-09 11:08:43 -04:00
Michael Moss bdeb7e7c4d Revert addition of Clang-19 and 20 from Linux Compilers matrix.
PiperOrigin-RevId: 945098838
Change-Id: I1bd4aa48f52a7555c581096e4e3ebb45fbf9408e
2026-07-09 07:12:40 -07:00
Google DeepMind faf0dabc32 Fix damper kv inheritance from default classes in XML native reader
Ensured dampers correctly read inherited values from gainprm[2].

PiperOrigin-RevId: 945086959
Change-Id: I10900f3ad057036115da88ad6d649d3d058e7373
2026-07-09 06:44:22 -07:00
Kyle Bayes ac29b596fb Autogenerate src files for doc line numbers.
PiperOrigin-RevId: 945067341
Change-Id: I8980a6157e06d1c1e21c6aa45a389b2cca09a363
2026-07-09 05:50:55 -07:00
Michael Moss f04b0fcd3d Update the GitHub Linux Compilers matrix.
PiperOrigin-RevId: 945004453
Change-Id: I939bfd0d4ac55397d65bea207b05d60be3ac8238
2026-07-09 03:00:19 -07:00
Saran Tunyasuvunakool ce3fc0ccfb Replace history slider with a custom timeline scrubber.
Introduces a new timeline widget in the Studio UI, replacing the previous integer slider for simulation history. The new widget displays the current and maximum simulation times, formatted with appropriate units (µs, ms, s), alongside the actual step number, and allows scrubbing through the history via a custom-drawn spine and knob.

This change also modifies the history recording logic to record every solver step rather than only every rendered frame. This enables the step forward/backward buttons to navigate exactly 1 solver step at a time.

This change also fixes `SimHistory::SetIndex()` range checks in `sim_history.cc` to clamp `offset_` against `1 - size_` (`Size()`) rather than total vector capacity (`history_.size()`).

PiperOrigin-RevId: 944671699
Change-Id: Iaa34668a1e257e5c0c1840c827370d81c4935b3d
2026-07-08 13:35:07 -07:00
Omar Rayyan 040872fd65 Copybara import of the project:
--
a5221e754c88580d103bfc7bfaf1ed32927ca499 by omar rayyan <olr7742@nyu.edu>:

Fix .mjz loading in simulate

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3384 from omarrayyann:fix-mjz-simulate a5221e754c88580d103bfc7bfaf1ed32927ca499
PiperOrigin-RevId: 944573851
Change-Id: Ifba77ee9f9b97a7d8c0b0a47ac82d390a273672b
2026-07-08 10:30:54 -07:00
Yuval Tassa 18147c50c8 Studio: Only show PAUSE overlay when info overlay is active.
PiperOrigin-RevId: 944428518
Change-Id: I8ba9bc24795ad4d3e35884c88cef12a0df910dec
2026-07-08 04:48:30 -07:00
Alessio Quaglino fb6d1cf18f Support pinned flex vertices with bending
The flexcomp compiler previously rejected pins on dim-2 flexes with
bending (elastic2d bend/both). Allow them: mj_flexPassiveBend treats a
pinned vertex (body without 3 free slide dofs) as static -- zero
velocity, and no bending force applied to it (the reaction is carried
by the pin) -- while its position still enters every neighbor's
bending force, which is exactly what the pin constrains.

PiperOrigin-RevId: 944410969
Change-Id: Ib0a69c8d5fb6f64d3e2a76af3b6b2c7be1898191
2026-07-08 04:02:31 -07:00
Tarik Kelestemur 4e5778433b Add batch_sizes model batching for MJX Warp 2026-07-07 18:06:30 -04:00
devshahofficial d23ff84c59 Add renderer info query API 2026-07-07 11:44:46 -07:00
Haroon Qureshi c4c2cad503 Implement SceneDecorator class.
Helper class that creates "decor" renderables using an mjvScene.

PiperOrigin-RevId: 943915073
Change-Id: Iae1efbe376dc21430387b10d7200451187522828
2026-07-07 08:41:03 -07:00
Haroon Qureshi 4ab8617429 Get mjrfContext from the ModelObjects.
PiperOrigin-RevId: 943888955
Change-Id: Icfe6230e531a100ad5a09efe582977fd3de8f076
2026-07-07 07:44:47 -07:00
Taylor Howell 6608f1affa MJX Data.where. Fixes #3377
PiperOrigin-RevId: 943875492
Change-Id: I963e4ad052ce9184a7548a468aa4aea722d10469
2026-07-07 07:15:36 -07:00
Haroon Qureshi 6d02ee4756 Merge GetRenderable and GetSelectedRenderable
PiperOrigin-RevId: 943844092
Change-Id: Ia3888ea6c289d491ddb2fba0ea4f5799c367ef2c
2026-07-07 07:15:10 -07:00
Taylor Howell 641c1cf11b update MJX with nvmax
PiperOrigin-RevId: 943836220
Change-Id: I7092b5ed005a48a10812f3280709c50691aa497e
2026-07-07 07:14:47 -07:00
Kyle Bayes 8df03f860c Remove latent bugs in GJK code.
PiperOrigin-RevId: 943831655
Change-Id: Id6f93325610f429bea02923363e1903bb854c61f
2026-07-07 07:14:19 -07:00
Kyle Bayes 62e80eee38 Convert clip and sign operations to branchless one-liners.
Testing on 50 million random doubles we have branchless clip is 1.14x faster than the branched version and branchless sign is 2.27x faster than the branched version.

PiperOrigin-RevId: 943812426
Change-Id: If8003a602365601a31bec1d8b080c44d16000a4e
2026-07-07 04:27:26 -07:00
Matija Kecman ee28b334ef Add a Studio example for rendering time-delayed ghost overlays.
This example demonstrates how to use Studio's `extra_geoms` feature to render semi-transparent, time-delayed copies of the model's geoms, creating a "ghost" effect.

PiperOrigin-RevId: 943672439
Change-Id: I8ae640672945b55dd25dd3d444f52d0b2fa7f0f8
2026-07-06 22:25:04 -07:00
Matija Kecman 8079ab3d4d Refactor Viewer to be a base class owning the communication with the simulation, handler registry, core visualization objects and the render function
ViewerApp is simplified, interacting with the endpoint and handlers through the Viewer instance. This change makes it possible to write simulation viewers without using the UI/UX provided by ViewerApp (which should be renamed StudioApp)

PiperOrigin-RevId: 943642660
Change-Id: Id8eb3d4e6a27ceda93833367fec4699fa6bc838e
2026-07-06 20:50:29 -07:00
Sam Haves ae58855c15 Change compile sample to use mj_parse and mj_encode as input/output.
There is a single remaining exception for mjb as it's a special case by bypassing mjSpec.

PiperOrigin-RevId: 943556676
Change-Id: Iaf480ea6d2d42a6007b35c23435b25c9eb24ead0
2026-07-06 16:35:14 -07:00
Sam Haves 19e175c063 Fix MJZ decoder Windows path separator issue
On Windows, std::filesystem::path::string() returns backslashes while
zip entries use forward slashes. This caused lookup mismatches making
MJZ decoding fail on Windows with 'could not decode content'.

Use generic_string() (which always returns forward slashes) for all
path operations used in zip entry lookups, and normalize the archive
name at construction time.

PiperOrigin-RevId: 943538265
Change-Id: I50cafff82fd7f5f315ccfc890f660e138e4448a2
2026-07-06 15:53:20 -07:00
Yuval Tassa 528e791d6e Add context menus to joint/control sliders for resetting values.
PiperOrigin-RevId: 942950247
Change-Id: I5d1c011f85d7d9abe6b19a699bb34af803998627
2026-07-05 15:55:52 -07:00
Yuval Tassa 1ea2d884d2 Change mju_round to use standard round() function.
PiperOrigin-RevId: 942873144
Change-Id: I3fd0d630643c104ff464d619387ff36582c2a5d8
2026-07-05 10:48:13 -07:00
Matija Kecman 4cb14bef47 Resolve string-based type annotations in message handlers.
When `from __future__ import annotations` is active or forward references are used as strings, type annotations are not directly class objects. This change uses `get_type_hints` to resolve these string annotations to their actual types, ensuring correct validation of message handler signatures.

PiperOrigin-RevId: 942608060
Change-Id: Ic2b214ee85e835616cc3a18ec2699eba6deebb6a
2026-07-04 16:03:26 -07:00
Yuval Tassa 4a9364082e Fix data race lazy-init spin lock deadlock on Windows.
PiperOrigin-RevId: 942556300
Change-Id: Iffe7a3e71c0f6273603e2ada14bf8d924b0ee6cf
2026-07-04 12:07:34 -07:00
Yuval Tassa 11f1da0c44 Migrate types in mjs structs.
PiperOrigin-RevId: 942546629
Change-Id: I46f2b24b53a43361fdc67dc32f2af1c0ce8b1de8
2026-07-04 11:27:27 -07:00
Yuval Tassa 315bcfbf3a Remove mjData.qM
PiperOrigin-RevId: 942520660
Change-Id: I422358e299ca0fcfe4c49cd0ee90c014a4c319d7
2026-07-04 09:38:45 -07:00
Yuval Tassa 7c6f519879 Remove legacy factorI/solveLD and clean up benchmarks/tests
Deletes mj_factorI_legacy and mj_solveLD_legacy from the engine and headers.
Updates factorI, solveLD, and inertia benchmarks to remove legacy targets
and only benchmark CSR.
Rewrites engine_core_smooth_test to verify CSR solver against mj_mulM
instead of legacy solver.

PiperOrigin-RevId: 942507341
Change-Id: I4281decb7018cfa3e46cb446efd5fe1179f6ae1f
2026-07-04 08:34:30 -07:00
Haroon Qureshi 10d6c01dce Increase filament buffer sizes.
PiperOrigin-RevId: 942496954
Change-Id: I9e53bf48b7c56cf76992140fc372d88c6d2a9752
2026-07-04 07:43:45 -07:00
Matija Kecman bdc9e9cce3 Fix bug where backspace intended for an imgui widget reset the environment
PiperOrigin-RevId: 942496281
Change-Id: I8c5d315d22a7c01dbe69f19833964f25141e9663
2026-07-04 07:40:27 -07:00
Haroon Qureshi c665f0b59e Disable spec editor when no spec is available.
PiperOrigin-RevId: 942493527
Change-Id: I90e1a0049b9cc9a82a5ede3a4a74a41425d5bee3
2026-07-04 07:29:06 -07:00
Yuval Tassa 38f0ff3caa Improvements to testspeed
Support named CLI flags, physics overrides, and refactor global state.

  - **Named CLI Flags**: Replaced standard positional arguments with named flags (`--nstep`, `--nthread`, `--noisestd`, `--noiserate`, `--npoolthread`) and preserved Google-wide flags compatibility (via custom argv compacting and InitGoogle).
  - **Physics Option Overrides**: Added support for configuring loaded model settings directly from the command line (`--solver`, `--cone`, `--jacobian`, `--integrator`, `--iterations`, `--tolerance`, `--sleep_tolerance`, `--noslip_iterations`).
  - **Encapsulated Thread State**: Consolidated loose global variables and per-thread rollout statistics arrays into a single data structure, `RolloutRunner runner`, simplifying mutli-threaded data boundaries.
  - **Readable Physics Options Printing**: Logged configured non-default options dynamically prior to rollout. Enums and active bitmask flags (e.g. disableflags/enableflags) are decoded into friendly strings (e.g., `Sleep : Enabled`).
  - **Tests & Docs**: Added testspeed_test.sh running testspeed over dominos.xml to check all overrides, registered shell test target in BUILD and CMakeLists.txt, and updated samples.rst documentation.

PiperOrigin-RevId: 942285912
Change-Id: Idb966fadfa0ccba0f1862f9d62bf83458b61939a
2026-07-03 16:52:40 -07:00
Matija Kecman 7c0d527005 Support extra_geoms argument
PiperOrigin-RevId: 942283363
Change-Id: I7e0c3aa845c0d2ae1c4390fd5cc01d6ff2741720
2026-07-03 16:39:22 -07:00
Matija Kecman 16f2276fe2 Increase priority of ViewerApp ModelEvent handler
PiperOrigin-RevId: 942274710
Change-Id: Ib894420e2d8f1e57a1da2d953c944316a1ff42ae
2026-07-03 16:02:14 -07:00
Yuval Tassa 7e9ac58ff9 Migrate mjd_inverseFD mass Jacobian from qM to M
PiperOrigin-RevId: 942268237
Change-Id: I0ecfe161867ce9930cd6366d778077df2cd3197f
2026-07-03 15:35:52 -07:00
Saran Tunyasuvunakool 4b345457a8 Add a test to check that GIL remains disabled under free-threaded Python.
Also add manual `Py_GIL_DISABLED` macro definition in CMakeLists as well, since there are some STATIC libraries that aren't getting it automatically through pybind11. As originally proposed in PR #3259.

Co-authored-by: Devansh Raulo <151062727+devansh0703@users.noreply.github.com>
PiperOrigin-RevId: 942216446
Change-Id: I9ef5f457491ae776c452912fbfa8617b8509d47c
2026-07-03 12:11:58 -07:00
Taylor Howell 17feb4a64e Update Studio to close window
PiperOrigin-RevId: 942216322
Change-Id: I96b4665016df0acb0c5dec9caae27eeb9a87f874
2026-07-03 12:11:01 -07:00
Yuval Tassa 5618666a7d Add body/simple attribute to control simple body optimization.
PiperOrigin-RevId: 942164766
Change-Id: I1e83bb99b6a1955917eb9b2e9bed0dc7b8e6a161
2026-07-03 09:09:30 -07:00
Haroon Qureshi 4ecfe5c1f3 Add FontGlobalScale binding.
PiperOrigin-RevId: 942113414
Change-Id: Id87ce552e717d118574befd00dac65ca71e3ba0d
2026-07-03 06:24:40 -07:00
Yuval Tassa 14c0b0c92b Recompute sameframe flags in mj_setConst.
The `body_sameframe`, `geom_sameframe`, and `site_sameframe` flags are now recomputed within `mj_setConst` based on the current model geometry. This allows these flags to be updated if the model's body/geom/site frames are modified after the initial compilation. Tests are added to verify the correct recomputation and its effect on forward kinematics. The compiler also checks that its initial computation matches the result of `mj_setConst`.

Fixes #3029, #1628.

PiperOrigin-RevId: 941758649
Change-Id: I7b995f8c67ad305bca5b52732436ba578c905d73
2026-07-02 10:49:00 -07:00
Matija Kecman 0dfa4b509a Refactor Studio customization and message dispatch to use decorator-based handlers
This change replaces fixed callback protocols (e.g., ViewerGuiHook, ViewerUpdateHook, SimEventHandler) with a general-purpose, priority-based message and event handling mechanism.

Key changes:
- Handler decorator and registry: Introduced the `@messages.handler(priority=...)` decorator and `HandlerRegistry` (`handler_registry.py`). Methods marked as handlers are automatically discovered and dispatched by priority (CRITICAL, USER, LIBRARY, INTERNAL) or method resolution order.
- Local lifecycle events: Added `ViewerAppInitEvent`, `BuildGuiEvent`, and `UpdateEvent` to `messages.py`. Custom GUI rendering and per-frame update logic can now be implemented as standard event handlers without needing separate interface protocols.
- Streamlined launch and app APIs: Replaced individual hook and handler arguments in `launch_passive`, `ViewerApp`, and `ViewerHandle` with unified `viewer_handlers` and `sim_handlers` lists.
- Module restructuring: Extracted simulation-side message handling and `ViewerHandle` from `sim_app.py` into a dedicated `viewer_handle.py` module, removing `sim_app.py`.
- Sample updates: Migrated existing examples (such as `implot.py`) to use the new handler pattern and lifecycle events.

PiperOrigin-RevId: 941729322
Change-Id: I93e7c0edf0a13a8dc854f9e2083451f7c25a1825
2026-07-02 09:14:41 -07:00
Haroon Qureshi 1ca64b441b Add binding for DockSpaceOverMainViewport.
PiperOrigin-RevId: 941727670
Change-Id: Idfecadf5a44b237f8c72493a7294bddfcd948ae5
2026-07-02 09:09:51 -07:00
Yuval Tassa 2d283b5e9d Allow self-attach in MJCF
PiperOrigin-RevId: 941676717
Change-Id: I9ff8fc89716bc14b438a41e2b4075bbe5fdb83cf
2026-07-02 06:51:46 -07:00
Yuval Tassa cdc35dec38 Reformat MJCF array in xml_native_reader.cc.
Undo mistaken auto-format of the schema table, revert it to be more human-readable.

PiperOrigin-RevId: 941628625
Change-Id: Ifc51996da9a7df9d1a03392a0ade256fb8b1c151
2026-07-02 04:45:46 -07:00
Taylor Howell c3adb50898 _realloc_island
PiperOrigin-RevId: 941618362
Change-Id: Idef1deb0ff4976de42aa585993988ae3363cd1fc
2026-07-02 04:21:43 -07:00
Yuval Tassa 0e58c48504 Clean up MJCF attach code.
PiperOrigin-RevId: 941603845
Change-Id: I94f275e2073b1eb81cfabdc0bed80021c6f15b1c
2026-07-02 03:45:39 -07:00
Yuval Tassa f8462a156d Refine line search convergence criteria.
The line search now requires a negative cost (improvement) in addition to a small derivative to declare convergence, preventing premature termination when no actual improvement has been made.

Follows the proposal in github.com/google-deepmind/mujoco_warp/pull/1471

PiperOrigin-RevId: 941579503
Change-Id: I8fcd20f7b959e50d77cd5d6de0a3c6d95f86b9e1
2026-07-02 02:56:24 -07:00
Haroon Qureshi fb259a5edd Implement RenderableManager.
Similar to LightManager, the RenderableManager manages
renderables based on an mjModel and its mjData.

PiperOrigin-RevId: 941510745
Change-Id: I97b44cc857f136aa7c90ceb85a42e299fc759b73
2026-07-02 00:03:05 -07:00
Yuval Tassa c6c3ec3149 Add "frame" attribute to <attach> element.
The `<attach>` element now supports a "frame" attribute, allowing users to specify either a "body" or a "frame" to attach to, but not both. The XML parser has been updated to handle this new attribute and the mutual exclusivity constraint.

PiperOrigin-RevId: 941245904
Change-Id: I4c0edeed5f3a9e456aed96c373b1647fe79841d9
2026-07-01 12:49:55 -07:00
Taylor Howell 1f6cf4035c Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 941234486
Change-Id: Ie5d8cc0c9975e66f9a81bb6a86e33f640a5d19e3
2026-07-01 12:27:10 -07:00
Georg Ostrovski bb80b55ae1 Fix data race in mju_getLogConfigPtr lazy init
The lazy init of log_config used a single atomic flag (env_checked) with
a load-then-store pattern, allowing two threads to both enter the init
path and concurrently write to the non-atomic log_config.topics field.

Replace with a two-phase atomic init: an atomic exchange on
env_init_claimed ensures exactly one thread enters the init, while
env_init_done (with acquire/release semantics) signals completion and
provides the happens-before edge that makes log_config writes visible to
other threads.

Also adds mj_atomic_exchange_bool to engine_crossplatform.h (both MSVC
and GCC/Clang variants).

PiperOrigin-RevId: 941202181
Change-Id: I59b6801c7b4b8b0e1647d82d2aeb534a90fb66fb
2026-07-01 11:24:36 -07:00
Matija Kecman 6e8a79c657 Refactor Studio implot sample to use a new message passing and launch APIs
Deleted async examples since they add noise and are not particularly useful

PiperOrigin-RevId: 941117641
Change-Id: I4f621801f652e0b410a7acf905cda58143dc3fb0
2026-07-01 08:42:30 -07:00
Saran Tunyasuvunakool a07ae6f849 Make MuJoCo Python bindings compatible with free-threading.
Introduce a new header `gil.h` defining `MutexLockIfGilDisabled` to support thread-safety in both standard and free-threaded CPython builds.

Protect critical shared states and registries:
- Guard global Python callback pointers in `callbacks.cc` using a mutex. Move `gil_scoped_acquire` into local blocks around refcount modifications to prevent `longjmp` from bypassing destructors.
- Protect raw pointer maps in `structs_wrappers.cc` with static mutexes.
- Replace TOCTOU race in `mjcb_time` initialization with thread-safe `std::call_once`.
- Add synchronization to lazy indexer array cache initialization in `indexers.cc` and `indexer_xmacro.h`.
- Protect vector mutations in `StructListBase::PopulateUpTo` in `structs.h` with a mutex.
- Revert unnecessary atomic changes to threadpool counters.
- Declare free-threading compatibility by passing `pybind11::mod_gil_not_used()` to all extension modules.

Fixes #3259
Fixes #3256
Fixes #2978

PiperOrigin-RevId: 941101502
Change-Id: Iec4ce58afcbc75d4b0be6a9a21fc8a47854242e3
2026-07-01 08:08:42 -07:00
Matija Kecman cab191755a Add MuJoCo Studio threaded/passive launch function
PiperOrigin-RevId: 941043766
Change-Id: I5b75d0a2b183d402e8ce221883c2734255e87f0f
2026-07-01 05:50:32 -07:00
Matija Kecman f73e1b6865 Add sim_app.py and viewer_app.py to Studio.
- `sim_app.py` provides a SimEventHook and a Handle class for the simulation process to interact with the viewer, including sending state snapshots and processing viewer events.

- `viewer_app.py` implements the main viewer application logic, handling user input, building the Dear ImGui GUI, and managing communication with the simulation process. It also includes hooks for custom viewer behavior.

PiperOrigin-RevId: 940994701
Change-Id: I82786872cd885b15454843b3a4d1160ff0b4be2b
2026-07-01 03:50:55 -07:00
Matija Kecman a1b0d2c933 Add a Viewer-to-Sim Snapshot channel and convert relevant messages.
The ViewerEndpoint can now send Snapshot messages to the SimEndpoint. The SimEndpoint has a new method, `get_viewer_snapshots`, to retrieve these. Thsi channel will be used for UI state needed for the simulation (e.g., `MjOption` and `StepControl`).

PiperOrigin-RevId: 940981799
Change-Id: Ib9bd6ad848cd5479bc49492a34fddd82569cb09f
2026-07-01 03:21:17 -07:00
Michael Moss 2012646711 Don't do a shallow clone, to avoid "fast-forward" push confusion.
PiperOrigin-RevId: 940727059
Change-Id: Id3c6c7c6a3fa1288ed091e49afc073b74f0bbd9c
2026-06-30 16:43:35 -07:00
Matija Kecman 58d6910afa Refactor StepControl and GUI to return change status.
StepControl methods SetSpeed, SetNoiseParameters, and SetPauseState now return a boolean indicating whether the state was actually changed. The GUI functions NoiseGui and StepControlGui also return a boolean reflecting if any parameters were modified. Noise parameters are now directly managed by StepControl rather than being stored in UxState. The StepControlEvent message has been expanded to include all step control parameters. Keyboard event handling has been slightly refactored to better align with event-based updates.

PiperOrigin-RevId: 940656342
Change-Id: I3701623a2fdcfc4c084b5db0ae19048669040de4
2026-06-30 14:21:00 -07:00
Matija Kecman f4b2f76def Updates NativeViewer instantiations in sample scripts to pass a ViewerConfig object
PiperOrigin-RevId: 940654165
Change-Id: I984cb296593e992dd0d99ca44b43c54de4c3e96d
2026-06-30 14:17:02 -07:00
Matija Kecman 3a623aaf33 Internal change.
PiperOrigin-RevId: 940601733
Change-Id: I83855569f85012173c3edf167eca78d236f6cdea
2026-06-30 12:38:11 -07:00
Taylor Howell 1810051d16 MuJoCo Warp documentation: Large scenes
PiperOrigin-RevId: 940590426
Change-Id: I006e245b54cd4165928927bee76f44d730bdd895
2026-06-30 12:14:48 -07:00
Google DeepMind 095608ef5f Make a bindings.h header file with the declarations, so that other projects can reuse the declared structs.
Add parseXMLString overload that supports passing in an MjVFS.

PiperOrigin-RevId: 940579266
Change-Id: I8294988bc4279e80795fab21024f64562a9e6743
2026-06-30 11:57:50 -07:00
Haroon Qureshi e2d7955437 Enable status bar by default for python studio.
PiperOrigin-RevId: 940557724
Change-Id: I0a4c96a53a0bcfcb5677515705c874d12bfd300d
2026-06-30 11:18:24 -07:00
Matija Kecman 7a84022092 Add ImGui bindings for Docking and window size constraints
PiperOrigin-RevId: 940470346
Change-Id: I731eedd0bd04afbd0c526ed8b27e6fb804596d20
2026-06-30 08:32:46 -07:00
Yuval Tassa 584ccd73d5 Improve error/warning display in studio.
PiperOrigin-RevId: 940299502
Change-Id: I8b13e2f984627a638a01b52f7dadca43f2c2ca80
2026-06-30 01:12:22 -07:00
devshahofficial 7fada46855 Improve Filament Studio source builds 2026-06-29 13:37:20 -07:00
Martin Schuck 407be2fc0b Copybara import of the project:
--
83a17d2844770fc2bbff37eda73b82df56076414 by Martin Schuck <martin.schuck@tum.de>:

Fix overflow cast

--
d12211c6665e1d791f77338daf8c62fa2374e3c8 by Martin Schuck <martin.schuck@tum.de>:

Prevent skipping warnings from cached jax functions by clearning the cache before invokation

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3369 from amacati:fix.overflow_cast d12211c6665e1d791f77338daf8c62fa2374e3c8
PiperOrigin-RevId: 939914544
Change-Id: I0ab6e9ad1e7c45f352d2f49642049ad930955f0b
2026-06-29 10:45:40 -07:00
Sam Haves 4e1795b9a4 Add special case support for MJB and TXT files to mj_encode.
PiperOrigin-RevId: 939875974
Change-Id: I57fc753871b348a7f6342aca0a892e74acb74173
2026-06-29 09:32:50 -07:00
Sam Haves d83ef0b6b9 Change mj_encode return type to 64-bit (mjtSize)
This supports encoding files larger than 2GB.

PiperOrigin-RevId: 939828697
Change-Id: If60d36c61475ced20b4eb58408ffb37e25bf3db7
2026-06-29 07:41:52 -07:00
Taylor Howell 1e04c568e8 Studio launcher
PiperOrigin-RevId: 939814201
Change-Id: If3fb1a1a9f9114835452fce63f39931db7818db3
2026-06-29 07:07:54 -07:00
Yuval Tassa 7c706b273a Report nnz(J) for CG solver.
PiperOrigin-RevId: 939806054
Change-Id: Icb2955511e33be046a4665fb39bce2546d6d4e3d
2026-06-29 06:49:23 -07:00
Matija Kecman e0bb2b0665 Introduce message and endpoint abstractions for MuJoCo Studio communication.
-   `messages.py`: Defines base classes for `Message`, `Snapshot`, and `Event`, along with `SnapshotChannel` and `EventChannel` protocols. It also includes concrete message types for state, reset, model, perturbation, pause state, and exit events.
-   `endpoints.py`: Provides `ViewerEndpoint` and `SimEndpoint` classes to manage message routing between the simulation and the viewer via the defined channels. A `make_endpoints` function is included to create both endpoints.

PiperOrigin-RevId: 939659912
Change-Id: I61a52a7d25431bc4ed38a184813882145eb421d1
2026-06-29 00:24:15 -07:00
Matija Kecman f594778813 Refactor viewer initialization and protocol.
Introduced a ViewerConfig dataclass to encapsulate common viewer window parameters. The NativeViewer now accepts a ViewerConfig and no longer requires a model at initialization. The Viewer protocol has been updated to include a close method (renamed from stop) and an upload_image method. Added checks for None models/data in studio event handling.

PiperOrigin-RevId: 939631378
Change-Id: Ibc07d0e775efa0d79ce5552ee52102e943a9b290
2026-06-28 23:07:02 -07:00
Haroon Qureshi 79f6deac99 Update bounds when updating the mesh.
PiperOrigin-RevId: 938628053
Change-Id: Ibd3d952d62614fc1eb049893937e6fb2d661da56
2026-06-26 09:25:06 -07:00
Yuval Tassa c7b1171846 Improvements to studio profiler
PiperOrigin-RevId: 938503994
Change-Id: I3a12647feea4c761dd8f8ba239f92355ceccfba1
2026-06-26 03:49:08 -07:00
Taylor Howell 56a182e67c Import Warp v1.14.0
PiperOrigin-RevId: 938464395
Change-Id: Iac99c53566e2e62f6e75f5e0904100919043b463
2026-06-26 02:03:42 -07:00
Haroon Qureshi 07e292bc6b Make mjrf types opaque in header.
PiperOrigin-RevId: 938409081
Change-Id: I8b9680dcb04f56aadf9ffd601b08025fc624c656
2026-06-25 23:41:49 -07:00
ems 99a5b2e2be fix: prevent segfault in ResolvePlugin when instance is missing 2026-06-25 23:23:22 +02:00
Haroon Qureshi 2a5345ba8c Add type attributes to help codegen.
PiperOrigin-RevId: 937935655
Change-Id: I14883a98b7b9b4bcc3dea8b60d839138c14ea444
2026-06-25 06:00:33 -07:00
Yuval Tassa 463b0fb27f Add ImGui overlay utility and PAUSE/realtime overlays to Studio.
PiperOrigin-RevId: 937834952
Change-Id: I3f3a0500a89b34e2e03b2fe88344b928edeafe8f
2026-06-25 01:45:01 -07:00
Yuval Tassa b6a0db7a17 Add Atkinson Hyperlegible Mono font support
PiperOrigin-RevId: 937799904
Change-Id: I89e4652cc45afdd9a55b3042395c4a56c70289fb
2026-06-25 00:16:39 -07:00
Haroon Qureshi 4b8a8fae92 Move code_builder.py to a common location.
PiperOrigin-RevId: 937332995
Change-Id: I2f03581cc47d96337bb637f30c678060207333fd
2026-06-24 07:44:40 -07:00
Yuval Tassa 0402bae176 Replicate the controls from the toolbar into the collapsible options sections and provides an option to hide the toolbar.
PiperOrigin-RevId: 937290592
Change-Id: I08f1f4880fd0b06123e817cb9ae7a3281daa8063
2026-06-24 06:09:24 -07:00
Haroon Qureshi 3d09a46d61 Use bulbradius as the vsm_blur_width as well.
PiperOrigin-RevId: 937286692
Change-Id: I03502da45951f90979b8f8d58915c80656a5eac7
2026-06-24 06:00:31 -07:00
Matija Kecman 38956ed95c Handle None values for model and data in StepControl.advance.
The `StepControl.advance` method now checks if the provided `model` or `data` Python objects are `None` before attempting to cast them to `MjModelWrapper` or `MjDataWrapper`, passing `nullptr` to the underlying C++ function if they are `None`.

This fixes an oversight in the python bindings, C++ code already supported null models.

PiperOrigin-RevId: 937243996
Change-Id: Ie67b8603517e7390fb54bfefbfed79ccf7b2bc5e
2026-06-24 04:18:29 -07:00
Haroon Qureshi a3039224ba Add attributes for codegen assistance.
PiperOrigin-RevId: 937219243
Change-Id: If3a0830b7020d52ef346d97886a90950941f4908
2026-06-24 03:17:03 -07:00
Haroon Qureshi 3e33f93ddc Remove unused material instances before rendering frame.
Also ensure material texture hashes are unique so that the material
cleanup works correctly.

PiperOrigin-RevId: 937206048
Change-Id: Ibed53457ee271f4faae3bcac5fb479b5ce9fc352
2026-06-24 02:46:33 -07:00
Haroon Qureshi 29b49991a2 Rename mjrf_getSamplerType to mjrf_getTextureSamplerType.
PiperOrigin-RevId: 937193469
Change-Id: I56f856e257fa1cf99b643f794139ef85817a0bb9
2026-06-24 02:18:07 -07:00
Yuval Tassa 080668df42 Add "(default)" to conflict warnings in user resolver.
When reporting conflicts between parent and child elements during attachment, the warning message now indicates if a value is derived from the default rather than being explicitly authored in the XML. This improves clarity in conflict resolution warnings.

PiperOrigin-RevId: 936724265
Change-Id: I68c677b19020c19bf0260f5b3b77fe6ca3661bb9
2026-06-23 09:44:29 -07:00
Haroon Qureshi 5637f74327 Add plugin for adding mjvGeoms to the scene.
PiperOrigin-RevId: 936709560
Change-Id: I69a01fc50e2d4b013d260d524515719c434bbf5f
2026-06-23 09:16:41 -07:00
Haroon Qureshi 557a2241f4 Add PreStep and PostStep plugin callbacks.
PiperOrigin-RevId: 936665884
Change-Id: Ie04562b02bfd61a62f9de77b3cef0fff534bf547
2026-06-23 07:49:29 -07:00
Haroon Qureshi 94a912d349 Allow plugins to request loading models by path.
PiperOrigin-RevId: 936638157
Change-Id: If594c6a9abac5eb0d62e7d6dce4dc2f558989969
2026-06-23 06:50:41 -07:00
Yuval Tassa c499f7f2b0 Add Nesterov momentum with O'Donoghue-Candès restarts to PGS solver (~2x speedup)
Benchmark on `2humanoid100.xml` (nefc=1785, nv=654):

```
Convergence at fixed iteration count (mean relative error vs Newton):
  20 iters: 2.98e-03 vs 1.54e-02 (5.2x better)
  40 iters: 8.14e-05 vs 2.60e-03 (32x better)
  80 iters: 1.17e-07 vs 1.77e-04 (1500x better)

Pipeline throughput (tolerance=1e-8, islands disabled):
  Nesterov: 243 steps/s, 46 iters/step
  Baseline: 151 steps/s, 95 iters/step
  Solver speedup: 1.8x, overall step speedup: 1.6x

Pipeline throughput (tolerance=1e-8, islands enabled):
  Nesterov: 306 steps/s, 442 iters/step
  Baseline: 175 steps/s, 966 iters/step
  Solver speedup: 2.1x, overall step speedup: 1.7x
```

PiperOrigin-RevId: 936610759
Change-Id: I2978e8bd545971d9151005623967e5cf0ad125cc
2026-06-23 05:52:14 -07:00
Haroon Qureshi 5cef2472d5 Remove custom step_fn for StepControl::Advance.
PiperOrigin-RevId: 936609234
Change-Id: I606cf4d71d856cbd260900d63b22c719974c977d
2026-06-23 05:49:20 -07:00
Taylor Howell 027cfd1201 simplify camera projection sensor
PiperOrigin-RevId: 936571266
Change-Id: I5647e61fcc81ba6eb482dd95d3c40438f478bb18
2026-06-23 04:17:38 -07:00
Haroon Qureshi da2f0ebd7b Add prestep/poststep callbacks to StepControl.
PiperOrigin-RevId: 936567801
Change-Id: I62d4d657791fe68101e63c2050adb63929128acf
2026-06-23 04:07:26 -07:00
Haroon Qureshi 7f66f42568 Make Renderer own the scenes.
PiperOrigin-RevId: 936547976
Change-Id: Iec87426a9ae255cdbd3efadc7b602d4183679c81
2026-06-23 03:15:48 -07:00
Haroon Qureshi 2800a682e4 Remove unused render_flags parameters.
PiperOrigin-RevId: 936528056
Change-Id: Iae8545ec1d71bc7d5a20c46394104fb1db369d5d
2026-06-23 02:29:25 -07:00
Haroon Qureshi 7a00c1f3e0 Factor out AstProcessor into its own library.
PiperOrigin-RevId: 936518263
Change-Id: I597ef4382e7ddc953f8daedd4f5123d71f0e8a42
2026-06-23 02:08:57 -07:00
Yuval Tassa 5d043d8f72 Minor tweaks to studio GUI style parameters.
PiperOrigin-RevId: 936508032
Change-Id: I93806ba3d0569b5ee01e95384f7f835a201b8253
2026-06-23 01:46:31 -07:00
Kyle Bayes 0fd7bea973 Modernize struct and enum style in MuJoCo headers.
PiperOrigin-RevId: 936485706
Change-Id: I31864acc4bd44573127d3d04c6b1a23f9d9c4cbc
2026-06-23 00:48:11 -07:00
Yuval Tassa afccd36dd4 Add threading support to PGS
PiperOrigin-RevId: 936252614
Change-Id: I6762245cc2dbdb95568f0a927c26b575dc494b51
2026-06-22 14:29:17 -07:00
Michael Moss 5700829122 Update MuJoCo version to 3.10.1 following the 3.10.0 release
PiperOrigin-RevId: 936044969
Change-Id: If0ebcc192419302da01741ebabb2b7dd3d7f7baf
2026-06-22 07:25:02 -07:00
Michael Moss 28009f9105 Update changelog for the 3.10.0 release.
PiperOrigin-RevId: 936044016
Change-Id: I4b6e3205819b7bd0469415fe0b57990b68309d1b
2026-06-22 07:22:23 -07:00
Yuval Tassa e2528cbd93 Rename "Stats" window to "Info" and remove "Stats" dock.
PiperOrigin-RevId: 936026479
Change-Id: I72e4f2cba6df255d5446faedc81727b39ef735bc
2026-06-22 06:38:03 -07:00
Michael Moss 4b1320a5f9 Patch Abseil to verify compiler support for std::source_location.
PiperOrigin-RevId: 936018935
Change-Id: I2cabbdf497dbb67452c27fc5ed02c56e6884f3d4
2026-06-22 06:16:36 -07:00
Kyle Bayes 1490336955 Change LoadModelFromString to return a smart pointer, add MakeData, and update tests to have C++ RAII clean up model and data.
PiperOrigin-RevId: 935980153
Change-Id: I41d25bfab4935494dc984168820cb7cad123cadf
2026-06-22 04:19:01 -07:00
Michael Moss 34d142ee50 Force Abseil's SourceLocation implementation for compatibility with clang 13/14.
PiperOrigin-RevId: 935926249
Change-Id: I063544e37eb735d0461a20c2ede7e23ea28d23bc
2026-06-22 02:02:00 -07:00
Yuval Tassa bf59ca6a1b Make the info overlay position fixed (bottom left)
PiperOrigin-RevId: 935868629
Change-Id: I26b8d50f276b05c9869ea0f6cc5c3033ab6ef2f9
2026-06-21 23:39:55 -07:00
Yuval Tassa d5db39c762 Fix various bugs related to value bounds in studio UI.
PiperOrigin-RevId: 935855305
Change-Id: I14b41fc751dc04d35beada0dd5d1f0bfddf9af34
2026-06-21 23:01:57 -07:00
Yuval Tassa 916695e794 Fix step timing diagnostics and make compiler errors transient in simulate.
PiperOrigin-RevId: 935675994
Change-Id: I7bc26291fb061e712187e0a6205723fda65b5f46
2026-06-21 11:08:01 -07:00
Michael Moss 3b08f39747 Update dependencies ahead of the 3.10.0 release.
PiperOrigin-RevId: 935674769
Change-Id: I4ad9c7494f499bc1016b99df78053337db439309
2026-06-21 11:02:27 -07:00
Michael Moss 3cb05726c4 Add MuJoCo Studio icons to the Mac and Windows apps.
PiperOrigin-RevId: 935655979
Change-Id: I4cb34a5592959c24764e8c63db0cac055d5c5dfb
2026-06-21 09:40:01 -07:00
Michael Moss 929d9abeb4 Add action to sync live branch on each release.
PiperOrigin-RevId: 935649160
Change-Id: Ic36b06fef1865ecee63f12faba0eb5d49914362b
2026-06-21 09:07:00 -07:00
Anas ce025f0ec3 render: skip textures the classic renderer can't upload
KTX textures crash the classic OpenGL renderer and the Python viewer with
"Number of channels not supported: 1": mjCTexture::LoadKTX stores the file as
an opaque single-channel blob for the Filament renderer, and mjr_uploadTexture
aborts via mju_error because the classic path only handles 3- or 4-channel
textures.

Skip textures the classic renderer can't upload (nchannel not 3 or 4) with a
warning instead of aborting, so the model still loads and the other textures
render. LoadKTX and the Filament path are unchanged. The guard also covers the
cube/skybox path, which previously over-read a single-channel blob as RGB.

Add a render_test.py regression test that builds a model with a KTX texture and
constructs an MjrContext; it aborts before this change and passes after.

Addresses #3343.
2026-06-21 01:49:23 -04:00
Kevin Zakka a8eaccd2b6 Copybara import of the project:
--
6ab68a057443f038a3d844807f205b1c99cab944 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Fix pickle code-execution vulnerability in sysid loaders

Serialize signal_mapping as JSON so the trajectory and time series loaders can use allow_pickle=False, preventing arbitrary code execution from untrusted .npz files.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3353 from kevinzakka:sysid-disable-pickle-load 6ab68a057443f038a3d844807f205b1c99cab944
PiperOrigin-RevId: 935400242
Change-Id: Iecd907174441fbcfd02c106b912a7ff375c9098c
2026-06-20 15:10:54 -07:00
Yuval Tassa 2cacf17071 Defer texture destruction in ImguiBridge to prevent use-after-free.
PiperOrigin-RevId: 935327326
Change-Id: I12a148b71abbe50581c7977a1f6dc5e220c40e81
2026-06-20 09:46:52 -07:00
Yuval Tassa 9ac0b283dc Menu reorg in studio
- Added "Info" and "Profiler" to the "View" menu.
- Deleted the obsolete "Charts" menu entirely
- Removed the "Stats" toggle item from the "Help" menu.

PiperOrigin-RevId: 935314037
Change-Id: I01ee30cbba5c1b4aa54c2940b0265401cc965c07
2026-06-20 08:43:09 -07:00
Saran Tunyasuvunakool 6039d4680a Modify the UI appearance of MuJoCo Studio.
PiperOrigin-RevId: 935247135
Change-Id: I4c35cf2f0cdfa36aa6d3c65c52a752edab266531
2026-06-20 03:34:21 -07:00
Kevin Zakka b1e3753a1a Fix typo in github username in changelog.
PiperOrigin-RevId: 935244857
Change-Id: I33159f2caa765be585e46cb1b8ccc8e37f103de3
2026-06-20 03:22:50 -07:00
Haroon Qureshi d93c102190 Move mjrfilament.h to mujoco/include.
PiperOrigin-RevId: 934931460
Change-Id: I63bf34b3a7197b277ea7a5caf3d84d840f6210a1
2026-06-19 08:01:05 -07:00
Michael Moss f663139256 Fix CMake error caused by relative RPATH.
PiperOrigin-RevId: 934847161
Change-Id: I7dce4161a8d8076d2d2c1c7b3234844733c5e8b0
2026-06-19 03:59:56 -07:00
Michael Moss 976476c482 Fix Windows build with MSVC.
PiperOrigin-RevId: 934812811
Change-Id: I45381b180d9120d8bfab5b10f50accf617607f8c
2026-06-19 02:24:32 -07:00
Haroon Qureshi 71721ed8e6 Merge generate scripts into a single script.
PiperOrigin-RevId: 934787488
Change-Id: I1e4d5870a7f4b339fa0de60271211fdffe80a3d8
2026-06-19 01:17:22 -07:00
Michael Moss 0dc37fd77b Add RPATH to fix mujoco_studio library loading error on Linux.
PiperOrigin-RevId: 934768602
Change-Id: I0b54ee1b3ed1a1ed85bcc88b36443539056275b1
2026-06-19 00:21:48 -07:00
Haroon Qureshi 4ec843d70d Use int instead of mjtGeom for public API.
PiperOrigin-RevId: 934766146
Change-Id: Iefaf32834ecbe12fe03c932ff593153277fc8f48
2026-06-19 00:13:32 -07:00
Michael Moss 492585ca7a Enable MuJoCo Studio build and packaging on Windows.
Also:
- Patched Filament to support building with Clang, so the default MuJoCo build
  mode doesn't need to change. This should probably be upstreamed.
- Added missing Windows deps to MuJoCo Platform CMake config.
- Updated Studio CMake config to fix unresolved symbols issues on Windows.
PiperOrigin-RevId: 934612701
Change-Id: I3a34a5d274e1452c9cfef0e2868f2788b4b0c7e8
2026-06-18 16:50:31 -07:00
Michael Moss e7ef6528b7 Enable MuJoCo Studio build and packaging on macos.
Also:
- Packages MuJoCo Studio as MuJoCoStudio.app in the MuJoCo.dmg.
- Fixes a Filament compile issue.
- Patches libwebp to fix compile error related to universal builds and forces
  it to build as static.
- Removes the separate, obsolete "build_studio" step.
PiperOrigin-RevId: 934564785
Change-Id: I50c83283b5e138062e37d53926a5a77fdf99dbfa
2026-06-18 15:03:20 -07:00
Michael Moss 8db92ab4a9 Enable building Studio (Linux only) as a component of the main MuJoCo build.
And remove the separate, conditional (and hacky) "build_studio" step.

PiperOrigin-RevId: 934375150
Change-Id: I46514d0f33c17bb29625b818cdde3a285fd2c439
2026-06-18 08:44:16 -07:00
Michael Moss 1f8c6f1183 Add licenses for third-party dependencies brought in by Studio.
PiperOrigin-RevId: 934300272
Change-Id: I7be1fccb4a80ea86803696699f53687f7d37da91
2026-06-18 05:51:06 -07:00
Yuval Tassa e2afec9153 Make decorations lit, Rename unlit_decor material to decor.
PiperOrigin-RevId: 933693797
Change-Id: I37128b528296d978d4917ec65316d8d99ce017bb
2026-06-17 06:43:37 -07:00
Haroon Qureshi 037bdfa519 Add edge and vertex rendering for flexes.
PiperOrigin-RevId: 933675465
Change-Id: Ice3c3a35820588c732b73f1dbad22e346acc4046
2026-06-17 05:56:18 -07:00
Yuval Tassa e76afa7160 Reduce the opacity of the Filament selection outline.
PiperOrigin-RevId: 933665589
Change-Id: Ic55785568c0129c2f145bedc0cde7ec4bdc05dcf
2026-06-17 05:29:04 -07:00
Yuval Tassa cedaa47d61 Migrate tests to use MockWarningHandler for warning interception.
PiperOrigin-RevId: 933656759
Change-Id: Ia21514c302799034bf598445933dd90427284737
2026-06-17 05:06:57 -07:00
Yuval Tassa 38c3388046 Fix rotation Jacobian offset in mj_jacSum sparse path.
PiperOrigin-RevId: 933640368
Change-Id: Ib30acd651b6022b0835e07b3f3b01e648791a511
2026-06-17 04:24:00 -07:00
Yuval Tassa cffb077c4b Register atexit handler to clear GlobalModel.
PiperOrigin-RevId: 933624252
Change-Id: Ib214514ac5390137dbf1034d113ff8aa9e9cdeb1
2026-06-17 03:44:08 -07:00
Yuval Tassa 410c73168c Add policies for global attribute conflict resolution upon attach
For example when loading parent_merge.xml:

```
WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge'
timestep: parent has 0.005, child has 0.002, taking the minimum
iterations: parent has 50, child has 100, taking the maximum
flag 'Damper': added from child
```

When loading parent_error.xml:

```
XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error'
timestep: parent has 0.005, child has 0.002
iterations: parent has 50, child has 100
Element 'attach', line 10
```
PiperOrigin-RevId: 933620810
Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
2026-06-17 03:36:10 -07:00
Michael Moss 30357c38a3 Silence C++20 deprecation warnings in MuJoCo Python enums.
PiperOrigin-RevId: 933618689
Change-Id: I7cd99ed47748a56990bef9e390a6c9072d5a6c0a
2026-06-17 03:28:40 -07:00
Kyle Bayes 386b45fb75 Add tolerance to upper > lower bound check on first iteration of EPA.
PiperOrigin-RevId: 933615381
Change-Id: I175d3b97fa65f71a8f1cc34da5f6b9a23ab856d2
2026-06-17 03:19:19 -07:00
Copybara-Service f6fb4af091 Merge pull request #3350 from kevinzakka:ci-ccache-header-fix
PiperOrigin-RevId: 933605716
Change-Id: Ia2f58f4a2b3240b18dc7f3f4bce7be8dd30e7f0e
2026-06-17 02:57:15 -07:00
Haroon Qureshi 6294e77907 Do not render flexes/skins with no geometry.
PiperOrigin-RevId: 933604372
Change-Id: I80169ff09ec6908d101b5f10bbf8aa1a6e8b8249
2026-06-17 02:54:11 -07:00
Kevin Zakka ffd95cf656 CI: drop system_headers from Python-binding ccache sloppiness
CMake adds the imported mujoco target's include dir as -isystem, so with
system_headers sloppiness ccache stopped hashing the public MuJoCo headers.
A header-only change (new mjData field, new enum value) then went undetected
and ccache reused objects compiled against the old struct layout, yielding an
ABI-mismatched binding: wrong field offsets (garbage in struct/pickle tests),
stale mjENABLESTRING/mjNENABLE, and mjSpec-vs-mjData signature mismatches.

Removing system_headers makes ccache hash these headers and recompile on
change. The mtime/ctime flags stay (they absorb pip's per-run temp-dir churn
without affecting content detection).
2026-06-16 23:45:18 -07:00
Haroon Qureshi e1711529f2 Add RGBA8 support to RenderTarget::ReadColorPixels.
PiperOrigin-RevId: 933521511
Change-Id: Ic279fb8f86615cc4cfddef6ac27a502b22bafd79
2026-06-16 23:30:04 -07:00
Yuval Tassa 6f8bb5ef55 Refactor compiler warning handling.
Compiler warnings are now accumulated in a vector of strings within the mjSpec object. New API functions `mjs_numWarnings` and `mjs_getWarning` are added to access these warnings. The compiler's log handler now chains warnings to the global log handler, ensuring they are still displayed immediately. Call sites in `mj_loadXML`, `mj_compile`, and the Python and WASM bindings have been updated to use the new warning API.

PiperOrigin-RevId: 933361650
Change-Id: I47cab98a460c57b0898c0a1a43fce2a5b9648eb1
2026-06-16 16:28:33 -07:00
nas 55c6332f20 Copybara import of the project:
--
8ce7d8199ace95d0f429b0ca9169d290d167cee1 by Anas <anaselghoudane@gmail.com>:

Use box midpoint to choose finite-difference direction in jacobian_fd

When bounds are provided, `jacobian_fd` chooses each coordinate's
finite-difference direction so the perturbation steps away from the nearer
bound. It compared `x` against `0.5 * (bounds[1] - bounds[0])`, which is half
the box *width*, not the box midpoint. For bounds that are not centered on the
origin this selects the wrong direction, and at the lower bound the perturbation
steps outside the box.

Compare against the midpoint `0.5 * (bounds[0] + bounds[1])` instead. Adds a
regression test checking that all residual evaluations stay within an off-center
box when `x` is at the lower bound; it fails before this change and passes after.

--
cfa085484c30df808362898e322de8adc6660b59 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Expand jacobian_fd bounds test and avoid midpoint overflow

Use the distributive form `0.5*lo + 0.5*hi` instead of
`0.5*(lo+hi)` to avoid overflow for extreme bound values.

Expand the single-case test into a parameterized subTest covering
all four boundary positions (lower/upper of positive and negative
off-center boxes), and rename it to `test_jacobian_fd_respects_bounds`.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3301 from Nas01010101:fix/minimize-fd-box-midpoint cfa085484c30df808362898e322de8adc6660b59
PiperOrigin-RevId: 933224876
Change-Id: I833cfe3324876cdeb7ca680c23d1d8a4d16adcf1
2026-06-16 12:06:34 -07:00
Copybara-Service 167901cec4 Merge pull request #3347 from kevinzakka:fix-dependabot-esbuild-usdcore
PiperOrigin-RevId: 933129237
Change-Id: I6864bd002ea48955b8c11332c40ac6891ba6659d
2026-06-16 09:25:30 -07:00
Kyle Bayes 0eec09dd60 Add runtime assertions to mji functions.
PiperOrigin-RevId: 933106771
Change-Id: I523cdceb89c90611f27983731c49fd4887034431
2026-06-16 08:36:32 -07:00
Kyle Bayes d9b677b49b Refactor remaining primitive and convex collision code to use mjPreContact instead of mjContact. Introduce internal struct mjcPair in engine_collision_driver.c for readability and extensibility for flex objects. This is a no-op.
PiperOrigin-RevId: 933105275
Change-Id: Id862b01774df63dcdb42629a5b7dd12019f12ffd
2026-06-16 08:33:09 -07:00
Kyle Bayes b469144a81 Modify mjc_FlexSDF to support mjPreContact directly.
PiperOrigin-RevId: 933068825
Change-Id: I328d64bb05270067ce146908b0df3ca83f10ed9b
2026-06-16 07:04:16 -07:00
Yuval Tassa 55d7ff49ec Fix broken link in docs.
PiperOrigin-RevId: 933054777
Change-Id: Ic862992051200bff1b742025926961a7c2087ffa
2026-06-16 06:24:16 -07:00
Yuval Tassa 8efb396b26 Reorder and adjust GUI physics options.
PiperOrigin-RevId: 933007222
Change-Id: Ia6944744112baa309de165144179ad96d914a734
2026-06-16 04:06:35 -07:00
Haroon Qureshi c0fa33f97f Rename mjrFilamentConfig to mjrfContextConfig.
PiperOrigin-RevId: 932996526
Change-Id: Ia81ee074471ab4ff41e0829fa5ba70203599fdb6
2026-06-16 03:36:22 -07:00
Haroon Qureshi ecee1e0c53 Rename nattributes to num_attributes for consistency.
PiperOrigin-RevId: 932973447
Change-Id: Idbf9a52c89e24f34ae360d1617cb72dfaa92aa4e
2026-06-16 02:40:13 -07:00
Kevin Zakka c44acdeb59 Bump vite to 8 to patch esbuild Dependabot alerts 2026-06-15 18:15:35 -07:00
Kevin Zakka 351f1ee2ba Bump usd-core to 25.11 to patch remaining Dependabot alert 2026-06-15 18:14:02 -07:00
Copybara-Service 8e13f3b54d Merge pull request #3332 from kevinzakka:fix-dependabot-pip-hashes
PiperOrigin-RevId: 932719862
Change-Id: I3627eaad46bf7f92ab927bb610c44d640a473adb
2026-06-15 16:04:37 -07:00
Kevin Zakka 936d040022 Bump usd-core to 25.8 to patch critical Dependabot alert 2026-06-15 08:53:04 -07:00
Kevin Zakka b1725b4fc9 Bump pinned pip dependencies to patch Dependabot alerts 2026-06-15 08:53:04 -07:00
Copybara-Service c9ba1e452d Merge pull request #3338 from devshahofficial:devshahofficial/filament-emissive-factors
PiperOrigin-RevId: 932483570
Change-Id: If8ff968d2650551118a38ea4837063796bd85f66
2026-06-15 08:45:48 -07:00
Copybara-Service eb6c2eea91 Merge pull request #3331 from kevinzakka:fix-dependabot-security-alerts
PiperOrigin-RevId: 932472549
Change-Id: Ib0830dfefca386ae338f427d675a9d5e148efd2e
2026-06-15 08:21:26 -07:00
Yuval Tassa 60b5cac066 Switch MJX DataJAX from legacy qM format to CSR M format
Switch MJX DataJAX to use the CSR-format `M` as its primary sparse inertia representation, matching MuJoCo C `mjData.M`. This allows both `mjData.qM` and `mjModel.mapM2M` to be deleted in the future.

PiperOrigin-RevId: 932433465
Change-Id: I194ffbfdba0cdd9c718277ee0d5de7ac20f2b06f
2026-06-15 06:52:45 -07:00
Michael Moss 3317921999 Add Studio assets into the python packaging.
PiperOrigin-RevId: 932432607
Change-Id: Id5122f3655c519f185b5647f3fb92f3ed54ba82c
2026-06-15 06:50:33 -07:00
Haroon Qureshi 7472440dbd Make mjrfilament.h conform to C standards.
PiperOrigin-RevId: 932424719
Change-Id: I1f8d8d91041ea1c2b77010761404bf0e519bcc29
2026-06-15 06:33:18 -07:00
Yuval Tassa 4e10f20be6 Fix set_to_muscle() to accept tuple arguments.
Correct argument types for timeconst and range parameters in pybind11
python bindings from C arrays to std::array.

Fixes #3282, #3282, #3318

Thanks to @Abzaek for original PRs

PiperOrigin-RevId: 932423401
Change-Id: Ic30ba076913693f5c0e545789690e8b0fa444390
2026-06-15 06:29:43 -07:00
Haroon Qureshi b1f4656d1a Parse all headers for possible functions.
Allows other files (e.g. mjrfilament) to define functions that
will be added to the introspection output.

PiperOrigin-RevId: 932403177
Change-Id: Ie2d2c6be67f0706463fdec4fc498364125e05dad
2026-06-15 05:39:54 -07:00
Matija Kecman 81bc303a8f Add an async example using multi threading
PiperOrigin-RevId: 932400523
Change-Id: I6649dfd3a657ce11b7dc6cf130f01be8a85a095c
2026-06-15 05:34:08 -07:00
Haroon Qureshi 9e45ce9801 Use num_ prefix consistently in API.
PiperOrigin-RevId: 932391786
Change-Id: I71c7f300fdb84ce1129ea3da6336df2fcffc5712
2026-06-15 05:08:34 -07:00
Matija Kecman 7c22920720 Improve async example and remove Network demo code
- Move SimToView and ViewToSim dataclasses from async.py to viewer_protocol.py (adding a user_data field) to consolidate IPC protocol definitions.
  - Remove the simulated Network class and latency UI controls from async.py to simplify the example and focus on core multiprocessing communication.
  - Use parser.parse() in main() for cleaner and more direct MuJoCo model loading.
  - Add cancel_join_thread() to multiprocessing queues and a join timeout to prevent atexit handlers from blocking during process shutdown.

PiperOrigin-RevId: 932327625
Change-Id: If91777dba934814b3f9faa17f9055869920575d7
2026-06-15 02:31:07 -07:00
Haroon Qureshi 2a210da0f7 Add more types to known types for generator.
PiperOrigin-RevId: 932327432
Change-Id: Ia62d2679f75d786c868f9d576af40a344b675508
2026-06-15 02:30:20 -07:00
devshahofficial 7646a56e82 Fix Filament emissive material factors 2026-06-13 15:58:30 -07:00
Yuval Tassa 67a1ea6dca Track authored flags for global attributes
PiperOrigin-RevId: 931585539
Change-Id: Ifdc8c59de6c5a553daf6e0af09d8192aff6b0610
2026-06-13 02:58:32 -07:00
Haroon Qureshi 0ea9c7cb3a Expose function for determining if tendons should be drawn using a catenary.
PiperOrigin-RevId: 931170146
Change-Id: Ia3352a3e2bdc5e4df932e9d476e1e34200b62df1
2026-06-12 08:45:22 -07:00
Michael Moss 4bb02e299d Resolve Studio assets path dynamically.
PiperOrigin-RevId: 931162732
Change-Id: Ib44a74790facfa797ca2c4f107edb0062a89c117
2026-06-12 08:26:24 -07:00
Haroon Qureshi 2c125dd447 Add Update function to LightManager.
PiperOrigin-RevId: 931152006
Change-Id: I6fe5d4ab0dbc8032fe84fd12968666d755d1d7d5
2026-06-12 07:58:43 -07:00
Haroon Qureshi 01d5be61e3 Move ModelObjects and LightManager to filament/support.
PiperOrigin-RevId: 931136854
Change-Id: I3ce3b7265c5d3c9a49fa84be46e87a76c6e2c8b5
2026-06-12 07:18:07 -07:00
Michael Moss 1ae561407a Minor cleanup to avoid unwanted files in mjx packaging.
PiperOrigin-RevId: 931118601
Change-Id: I94adedd0b29370e652140bb91f1488722eb61c55
2026-06-12 06:26:42 -07:00
Yuval Tassa f27503509e Fix GCC truncation warnings in Python bindings errors.h
Widen mju_error_msg buffer from 1024 to 2048 and replace strncpy with
snprintf to avoid -Wformat-truncation and -Wstringop-truncation.

PiperOrigin-RevId: 930982013
Change-Id: I0fcd726e5ed1ad28594bd4ef55b8b1ae72020043
2026-06-12 00:31:17 -07:00
Haroon Qureshi a37389ccfb Split SceneObjects out from ModelObjects.
PiperOrigin-RevId: 930960334
Change-Id: I7958a8240a90e2eb7fb87e58e5bea561459a7695
2026-06-11 23:36:10 -07:00
Yuval Tassa 8d42473ed0 Fix GCC -Wstringop-truncation in test fixture
Widen err_msg buffer in MjuErrorMessageFrom to 2048 and use snprintf
instead of strncpy to avoid truncation warnings.

PiperOrigin-RevId: 930932293
Change-Id: Iea43d28cf209356d66cf16be48e750e947242b14
2026-06-11 22:25:12 -07:00
Kevin Zakka 8aa111fe0f Bump wasm dev dependencies to patch npm audit vulnerabilities 2026-06-11 17:51:49 -07:00
Kevin Zakka 426aecc4bc Bump doc deps and restrict lint workflow permissions 2026-06-11 17:51:08 -07:00
Yuval Tassa a070535c65 Fix GCC -Wformat-truncation error in legacy log adapter
Widen snprintf buffer from 1024 to 2048 bytes in mju_defaultLogHandler
to avoid truncation warning when formatting "func: subject".

PiperOrigin-RevId: 930823501
Change-Id: I0b2246f23c44e983bea76976b684d2efdfdff29c
2026-06-11 17:23:43 -07:00
Yuval Tassa 58f6d52491 Introduce new logging API, fixes #858
PiperOrigin-RevId: 930744288
Change-Id: I6ec1203b55c031390f3eef23192e2337508ce886
2026-06-11 14:36:57 -07:00
Yuval Tassa a2abaf7aef Render perturbation box as a wireframe.
PiperOrigin-RevId: 930707140
Change-Id: Iab3577c8b45a235870f57001d38b6b1cd8acd170
2026-06-11 13:31:16 -07:00
Matija Kecman 37084a5c0b Release GIL in MuJoCo Studio Python bindings.
This change adds py::gil_scoped_release to various functions in the parser, renderer, sim and ux modules of the MuJoCo Studio Python bindings. This allows other Python threads to execute while these C++ functions, which can sometimes be time-consuming, are running. The two heaviest operations Present() (rendering) and Advance() (physics) now both release the GIL in C++.

PiperOrigin-RevId: 930645361
Change-Id: Ib239fb54edc7ac0d8b1d94bec8c57a447d5f4d27
2026-06-11 11:32:09 -07:00
Michael Moss ab17ff5552 Add Python Studio CMake configs and integrate into python build and packaging
PiperOrigin-RevId: 930532579
Change-Id: I2c4b51664475cc8fba92d70d072528843aa03f0c
2026-06-11 08:03:44 -07:00
Michael Moss 41ac783d3a Add ImGui context sharing for UI rendering in Python MuJoCo Studio
PiperOrigin-RevId: 930507935
Change-Id: I7615931f9a71793b049e8b6b442be6a2d726f0b2
2026-06-11 07:10:41 -07:00
Michael Moss 684eccc146 Removed unused constexpr variables in ImPlot Python bindings
PiperOrigin-RevId: 930500399
Change-Id: I95bc9c4b580700d75a48d0784d611913956c0431
2026-06-11 06:53:10 -07:00
Michael Moss fbdf8a6215 Add Copybara rule to transform header paths under experimental.
PiperOrigin-RevId: 930498813
Change-Id: I18d4cdad18cd1f2e23c8ba48ebf2d2e5a3b54168
2026-06-11 06:49:08 -07:00
Matija Kecman 018fbc3223 Release GIL in native viewer.
Adds py::gil_scoped_release no_gil; to mujoco::studio::Viewer methods to release the Python GIL during C++ execution.

PiperOrigin-RevId: 930482271
Change-Id: I590794109418516ec5d9e8b536085560a1d36314
2026-06-11 06:13:45 -07:00
Matija Kecman d068c96d00 Expose ImGuiInputTextFlags_WordWrap to Python.
PiperOrigin-RevId: 930466666
Change-Id: Ic0d5bb39125c3a3986fe28f09d5ba8776c7fc2c7
2026-06-11 05:33:23 -07:00
Haroon Qureshi 96781fa793 Move filament renderer out of experimental into src/render/filament.
Also:
- renames the main header file to mjrfilament.h.
- moves filament_util under a "support" folder.
PiperOrigin-RevId: 930448415
Change-Id: Iad89756aaf1ddf4c3e67e1afc3a13776f71fa20f
2026-06-11 04:43:20 -07:00
Kevin Zakka 1aaced190a Copybara import of the project:
--
3439d8a5cd745dfd2776593916eead65cb456afc by Kevin Zakka <kevinarmandzakka@gmail.com>:

Respect an explicit CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF

The default-LTO guard checked the value rather than whether it was DEFINED, so an
explicit -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF (used in CI to cut build time)
was silently flipped back ON. Check DEFINED instead; default-on for Release is
preserved when the caller makes no choice.

--
bd15d1b264e5ab9594669b58fa1e0388d0a16f6b by Kevin Zakka <kevinarmandzakka@gmail.com>:

Speed up CI

~10x faster on the POSIX jobs (~45m -> ~4-5m) and ~2x overall wall-clock.

- Build Studio/Filament and WASM only in their dedicated canary jobs, not in
  every matrix job (WASM uses emcc, which ignores the host compiler).
- Compiler matrix -> build_matrix.json with core/extended tiers: PRs build the
  core set, pushes to main run the full sweep.
- ccache across build jobs (studio cache keyed on the Filament pin); fix the
  Python-bindings build so ccache hits (CCACHE_BASEDIR).
- Disable IPO/LTO on POSIX (it was silently on); keep it on Windows where /GL-off
  exposes a latent test bug and build time is not the bottleneck.
- Run ctest in parallel on POSIX (~2x); uv for Python installs (~29s -> ~8s).
- Move MJX (compiler-independent) to a single dedicated job.
- Restrict GITHUB_TOKEN to contents: read; bump actions off deprecated Node20.

--
c0618ab7aef524b238e0a30f2f23c50c4ce0c9b1 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Build the gcc jobs with LTO off too

Restores LTO-off for gcc (recovering the build-time win). That surfaces known
gcc-12 -Wrestrict false positives in libstdc++ <char_traits> at -O3; two clean,
behavior-preserving rewrites in the XML writer avoid them. Confirmed gcc-12 and
gcc-14 build clean with LTO off (PR #3325).

--
2c38da0f48f77635e58e4b7931b86d60f3c253c7 by Kevin Zakka <kevinarmandzakka@gmail.com>:

Respect explicit IPO=OFF in the Simulate and Sample options too

Apply the same DEFINED check as cmake/MujocoOptions.cmake to the simulate/ and
sample/ subprojects (which carry identical copies of the guard) to keep the three
in sync, as the internal import requires. Since the guard now honors =OFF, stop
forcing IPO=OFF on the tiny samples/simulate CI builds so they keep their default
LTO and don't expose the gcc -Werror false positives that -O3-without-LTO triggers.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3315 from google-deepmind:speed-up-ci 2c38da0f48f77635e58e4b7931b86d60f3c253c7
PiperOrigin-RevId: 930008698
Change-Id: Ic41dc87881833c95f2ebfc0602de1ed438db3d4f
2026-06-10 12:27:14 -07:00
Kyle Bayes 6957966c7d Terminate early without contact in EPA if upper < lower on first iteration.
PiperOrigin-RevId: 929828707
Change-Id: Ide1106c14ae6eb003a9bbc238609b4bfdde221b0
2026-06-10 07:02:00 -07:00
Google DeepMind 711aa9fcd8 Fix typo in window size check.
Corrected the comparison from `max_window_width != window_height_` to `max_window_height != window_height_` when checking if the window dimensions have changed.

PiperOrigin-RevId: 929825452
Change-Id: I4ae46502495e16f86c19d4efabe8c048d708789b
2026-06-10 06:55:17 -07:00
Kyle Bayes 118baada7c Remove engine threading fallback.
PiperOrigin-RevId: 929825049
Change-Id: Iff959f8d22ed082ff470c3eec426351964c2e89d
2026-06-10 06:54:19 -07:00
Michael Moss 6f6a72f66b CMake updates for Studio integration
PiperOrigin-RevId: 929809674
Change-Id: Iabe670ced44f09fc1ea6d8dcde4b3c9ea4ad270a
2026-06-10 06:20:50 -07:00
Matija Kecman edbe6a6f74 Fix memory and resource leaks in failing resource provider open callbacks
When an mjpResourceProvider's open callback returns 0 (failure), MuJoCo does
not invoke the corresponding close callback. Previously, several resource
provider implementations allocated heap memory or system file handles before
encountering an error, failing to clean them up before returning 0. This change addresses these leaks across the codebase and clarifies the API contract.

PiperOrigin-RevId: 929803942
Change-Id: Ib7344033726895cdf037a8d9356ffc183c78c2d3
2026-06-10 06:08:17 -07:00
Michael Moss c31e94cee6 Support nested packages (needed for Studio extensions).
PiperOrigin-RevId: 929802580
Change-Id: I680a1a851256fb6b0cd576db928c241890076ce6
2026-06-10 06:04:22 -07:00
Kyle Bayes 2c5b8cae6c Correct projected origin on face when the magnitude of face->v becomes very small in EPA.
PiperOrigin-RevId: 929768876
Change-Id: I5daf0203e998aa1489d9ce4c78cbf0764a8963e3
2026-06-10 04:48:18 -07:00
Michael Moss aa494e45d4 Remove builds using GCC 10 and 11, which are EOL years ago.
PiperOrigin-RevId: 929355762
Change-Id: Ia9a28cccdad966ea24b1eb326fdde0116c4f57c2
2026-06-09 12:59:17 -07:00
Haroon Qureshi ecb15a8d9e Cache the render targets.
PiperOrigin-RevId: 929230223
Change-Id: I06571687ba0153c6ee8631685d1d37052419d2ac
2026-06-09 09:11:19 -07:00
Haroon Qureshi b083ae487e Introduce outline render passes and shader.
Use the jump flood algorithm to render an outline around selected
objects. This requires using custom post-processing shaders and
render passes which is managed by a new "Outliner" class.

PiperOrigin-RevId: 929212147
Change-Id: Ie6f475c7c677df7b0d4fc030a8e9520ff9dd03af
2026-06-09 08:31:49 -07:00
Haroon Qureshi e6e5229126 Format header to conform to style guide.
Also moves some types to the mjrender.h header.

PiperOrigin-RevId: 929189125
Change-Id: I19e5598210898c0defb663c60d7ecfb9a19bcd38
2026-06-09 07:43:16 -07:00
Michael Moss 991c131d59 Remove workaround for obsolete GitHub Windows image (from 2024).
PiperOrigin-RevId: 929179278
Change-Id: Ia50305679f5736fce5e3a41a1cbe0379e4afa7de
2026-06-09 07:22:36 -07:00
Matija Kecman 4be41d7b0b Add graphics modes list to viewer protocol
PiperOrigin-RevId: 929157105
Change-Id: I75586c37bc94666800f7822654225bad0717e51c
2026-06-09 06:29:04 -07:00
Adrian Collister 6f0246baf3 Add test for Flex contact and touch sensors.
The test verifies that contact sensors on subtrees and touch sensors on sites correctly register contacts involving Flex components.

PiperOrigin-RevId: 929109418
Change-Id: I1865311a6da838d75ef33989ac7f3c2d975cdbff
2026-06-09 04:29:40 -07:00
Taylor Howell 763e713d1b Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 929061622
Change-Id: I53892a819c3727b1f04db943839606ec1f477df1
2026-06-09 02:28:29 -07:00
Copybara-Service 58a8c6ee56 Merge pull request #3323 from mhasek:mhasek/fix_mjwarp_data_sync_mismatch
PiperOrigin-RevId: 929043537
Change-Id: I99c6c67bc02c45dc3a432a585aebac1621757d6d
2026-06-09 01:47:11 -07:00
Yuval Tassa e349ea5834 Remove MJAPI from templated function declaration.
PiperOrigin-RevId: 928849785
Change-Id: I35ba63f599ba12a5d2bdb0d694240e39ca7d4174
2026-06-08 17:08:17 -07:00
Yuval Tassa 986d73c062 Fix non-unit normals in mesh convex hull compiler.
PiperOrigin-RevId: 928777934
Change-Id: I43d7adcf4c5781b57f0af9805a8ce01ebc2e3872
2026-06-08 14:40:11 -07:00
Haroon Qureshi ae2e8aa940 Rename mjrRenderTargetConfig to mjrfRenderTargetConfig.
This rename was overlooked in the previous commit which updated
the prefixes for all filament-specific render objects.

PiperOrigin-RevId: 928710590
Change-Id: I0ff09cb077f7d5643371d43a43fc992352e6d85d
2026-06-08 12:33:27 -07:00
Matija Kecman 66c0131840 Internal change
PiperOrigin-RevId: 928689775
Change-Id: Idfbbafe44b74acf36ff82a72eabf026d4226d47c
2026-06-08 11:50:55 -07:00
Haroon Qureshi 2fcd135179 Remove layer mask from public API.
Instead, use materials to determine the layer mask of an object.

This hides the details/complexities of how layers are used
to render different passes from the user and will allow the
renderer to do more advanced rendering passes.

PiperOrigin-RevId: 928682525
Change-Id: I1f53dc8d12d2e574de6528977f55e79f896c6e42
2026-06-08 11:37:47 -07:00
Haroon Qureshi 982e3be9ef Add mjrfCallback type.
PiperOrigin-RevId: 928640487
Change-Id: Iebf470caafe924a976e4a1b39b0c47727e22195b
2026-06-08 10:26:40 -07:00
Adrian Collister 74d1459a4a Enable contact sensors to work with Flex.
The sensor engine now correctly retrieves body IDs for contacts involving Flex elements by using mj_flexBody when a geom ID is -1. This allows contact sensors to detect and report forces/torques on bodies involved in Flex contacts.

PiperOrigin-RevId: 928607416
Change-Id: Ia815e1b3345bcfb393c9c4a829dc98959f2da50c
2026-06-08 09:31:42 -07:00
Yuval Tassa 828052e6f4 CG solver: Replace PRP+ with Hager-Zhang update
Replace the Polak-Ribière-Plus (PRP+) conjugate direction update with the Hager-Zhang  formula in `mj_solPrimal`.

While this change has negligible effect under float64, it leads to a significant 17.5% throughput speedup over PRP+ under float32 (measured via `engine_cg_convergence_test`). This performance gain is driven by:
* A 9.4% reduction in CG iterations per step.
* A 12.1% reduction in line search evaluations per step.

The full output of the comparison is

```
================================================================
1/4: HZ + float64
================================================================

CG Convergence: 2humanoid100.xml
  1000 Newton steps, 100 evaluation points
  nv = 654, nq = 756
  metric: ||qacc_cg - qacc_newton|| / ||qacc_newton||

  Warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  3.8532e-01 |  1.4285e+00 |       5.00 |    22368
      10 |  2.0809e-01 |  9.9315e-01 |      10.00 |    44591
      20 |  6.4977e-02 |  2.3410e-01 |      20.00 |    89417
      40 |  5.2839e-03 |  2.1916e-02 |      40.00 |   180984
      80 |  3.9709e-05 |  3.0010e-04 |      80.00 |   364241
     160 |  3.2498e-09 |  3.5480e-08 |     160.00 |   730131
  -------+-------------+-------------+------------+---------

  No warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  9.0740e-01 |  5.0045e+00 |       5.00 |    22123
      10 |  3.9506e-01 |  2.1927e+00 |      10.00 |    44879
      20 |  1.2496e-01 |  6.8911e-01 |      20.00 |    90341
      40 |  1.2846e-02 |  6.9533e-02 |      40.00 |   182869
      80 |  1.0288e-04 |  8.6457e-04 |      80.00 |   368312
     160 |  5.9820e-09 |  5.0903e-08 |     160.00 |   738479
  -------+-------------+-------------+------------+---------

  Tolerance sweep (iterations = 100, warmstart):
         Tol |    Mean Err |     Max Err | Mean Iters |  Max Iters |   Solver us | LS evals
  -----------+-------------+-------------+------------+------------+-------------+---------
       1e-04 |  1.1297e-02 |  8.9331e-02 |      34.88 |         51 |   131002.94 |    12052
       1e-06 |  1.0907e-03 |  7.7468e-03 |      50.87 |         72 |   184172.44 |    16700
       1e-08 |  1.1485e-04 |  1.0085e-03 |      66.82 |         91 |   232189.34 |    20194
       1e-10 |  1.1357e-05 |  8.1547e-05 |      81.97 |        100 |   276114.42 |    23264
       1e-12 |  3.7695e-06 |  2.8592e-05 |      90.47 |        100 |   299526.58 |    24964
           0 |  3.5019e-06 |  2.8592e-05 |     100.00 |        100 |  2062208.36 |   456276
  -----------+-------------+-------------+------------+------------+-------------+---------
  Total solver time: 3185214.08 us, avg time per iter: 74.9445 us

  Pipeline mode (consecutive mj_step, tolerance = 1e-8):
  1000 steps, nv = 654
  Steps/s          : 380
  us/step (total)  : 2630.0
  us/step (constr) : 2103.7  (80.0%)
  CG iters/step    : 63.28
  LS evals/step    : 190.75
  us/iter          : 33.24

================================================================
2/4: PRP+ + float64
================================================================

CG Convergence: 2humanoid100.xml
  1000 Newton steps, 100 evaluation points
  nv = 654, nq = 756
  metric: ||qacc_cg - qacc_newton|| / ||qacc_newton||

  Warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  3.8533e-01 |  1.4285e+00 |       5.00 |    22228
      10 |  2.0808e-01 |  9.9315e-01 |      10.00 |    44873
      20 |  6.4978e-02 |  2.3410e-01 |      20.00 |    89349
      40 |  5.2895e-03 |  2.1916e-02 |      40.00 |   179827
      80 |  4.0188e-05 |  3.0010e-04 |      80.00 |   363740
     160 |  3.2891e-09 |  3.5480e-08 |     160.00 |   733905
  -------+-------------+-------------+------------+---------

  No warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  9.0740e-01 |  5.0045e+00 |       5.00 |    22590
      10 |  3.9506e-01 |  2.1927e+00 |      10.00 |    45093
      20 |  1.2496e-01 |  6.8911e-01 |      20.00 |    90393
      40 |  1.2846e-02 |  6.9533e-02 |      40.00 |   182422
      80 |  1.0288e-04 |  8.6457e-04 |      80.00 |   367264
     160 |  5.9811e-09 |  5.0903e-08 |     160.00 |   739556
  -------+-------------+-------------+------------+---------

  Tolerance sweep (iterations = 100, warmstart):
         Tol |    Mean Err |     Max Err | Mean Iters |  Max Iters |   Solver us | LS evals
  -----------+-------------+-------------+------------+------------+-------------+---------
       1e-04 |  1.1325e-02 |  8.9941e-02 |      34.95 |         52 |   129456.81 |    12060
       1e-06 |  1.0910e-03 |  7.7469e-03 |      50.85 |         72 |   181004.51 |    16687
       1e-08 |  1.1488e-04 |  1.0085e-03 |      66.83 |         91 |   228183.13 |    20189
       1e-10 |  1.1401e-05 |  8.1547e-05 |      81.98 |        100 |   269635.40 |    23259
       1e-12 |  3.8040e-06 |  2.8592e-05 |      90.52 |        100 |   293811.25 |    24967
           0 |  3.5543e-06 |  2.8592e-05 |     100.00 |        100 |  2051927.47 |   456000
  -----------+-------------+-------------+------------+------------+-------------+---------
  Total solver time: 3154018.57 us, avg time per iter: 74.1895 us

  Pipeline mode (consecutive mj_step, tolerance = 1e-8):
  1000 steps, nv = 654
  Steps/s          : 382
  us/step (total)  : 2616.6
  us/step (constr) : 2091.8  (79.9%)
  CG iters/step    : 63.57
  LS evals/step    : 193.35
  us/iter          : 32.91

================================================================
3/4: HZ + float32
================================================================

CG Convergence: 2humanoid100.xml
  1000 Newton steps, 100 evaluation points
  nv = 654, nq = 756
  metric: ||qacc_cg - qacc_newton|| / ||qacc_newton||

  Warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  3.6748e-01 |  1.2281e+00 |       5.00 |    19239
      10 |  2.0034e-01 |  6.8689e-01 |      10.00 |    39001
      20 |  6.1972e-02 |  1.9859e-01 |      20.00 |    80112
      40 |  4.0704e-03 |  1.5797e-02 |      40.00 |   168211
      80 |  2.4380e-05 |  1.5803e-04 |      79.45 |   347735
     160 |  7.7413e-07 |  4.4732e-06 |     157.27 |   704210
  -------+-------------+-------------+------------+---------

  No warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  9.3385e-01 |  4.9648e+00 |       5.00 |    19272
      10 |  3.6117e-01 |  1.9618e+00 |      10.00 |    37982
      20 |  9.7490e-02 |  5.1451e-01 |      20.00 |    76502
      40 |  9.5924e-03 |  5.5088e-02 |      40.00 |   162782
      80 |  6.7689e-05 |  5.1113e-04 |      79.91 |   344281
     160 |  1.5541e-06 |  7.6955e-06 |     157.30 |   697076
  -------+-------------+-------------+------------+---------

  Tolerance sweep (iterations = 100, warmstart):
         Tol |    Mean Err |     Max Err | Mean Iters |  Max Iters |   Solver us | LS evals
  -----------+-------------+-------------+------------+------------+-------------+---------
       1e-04 |  1.5891e-02 |  1.2929e-01 |      32.56 |         50 |   136254.00 |    10980
       1e-06 |  1.5719e-03 |  1.0990e-02 |      47.42 |         68 |   193566.00 |    15418
       1e-08 |  1.6260e-04 |  1.0680e-03 |      62.70 |         86 |   252661.00 |    20162
       1e-10 |  1.5664e-05 |  1.0999e-04 |      78.10 |        100 |   311535.00 |    24509
       1e-12 |  2.8152e-06 |  1.5236e-05 |      90.39 |        100 |   356814.00 |    27902
           0 |  2.4989e-06 |  1.5025e-05 |      99.05 |        100 |  1980580.00 |   436825
  -----------+-------------+-------------+------------+------------+-------------+---------
  Total solver time: 3231410.00 us, avg time per iter: 78.7726 us

  Pipeline mode (consecutive mj_step, tolerance = 1e-8):
  1000 steps, nv = 654
  Steps/s          : 349
  us/step (total)  : 2862.7
  us/step (constr) : 2379.3  (83.1%)
  CG iters/step    : 61.97
  LS evals/step    : 199.01
  us/iter          : 38.39

================================================================
4/4: PRP+ + float32
================================================================

CG Convergence: 2humanoid100.xml
  1000 Newton steps, 100 evaluation points
  nv = 654, nq = 756
  metric: ||qacc_cg - qacc_newton|| / ||qacc_newton||

  Warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  3.6753e-01 |  1.2281e+00 |       5.00 |    19052
      10 |  2.0028e-01 |  6.8689e-01 |      10.00 |    38761
      20 |  6.1737e-02 |  1.9863e-01 |      20.00 |    79937
      40 |  4.0915e-03 |  1.5821e-02 |      39.99 |   168159
      80 |  2.4360e-05 |  1.5808e-04 |      79.59 |   348385
     160 |  7.8367e-07 |  4.1549e-06 |     157.04 |   700760
  -------+-------------+-------------+------------+---------

  No warmstart (tolerance = 0):
   Iters |    Mean Err |     Max Err | Mean Iters | LS evals
  -------+-------------+-------------+------------+---------
       5 |  9.3385e-01 |  4.9648e+00 |       5.00 |    19494
      10 |  3.6117e-01 |  1.9618e+00 |      10.00 |    38480
      20 |  9.7485e-02 |  5.1451e-01 |      20.00 |    77213
      40 |  9.5904e-03 |  5.5078e-02 |      40.00 |   162472
      80 |  6.7647e-05 |  5.1087e-04 |      79.87 |   342990
     160 |  1.4979e-06 |  7.2291e-06 |     157.92 |   699052
  -------+-------------+-------------+------------+---------

  Tolerance sweep (iterations = 100, warmstart):
         Tol |    Mean Err |     Max Err | Mean Iters |  Max Iters |   Solver us | LS evals
  -----------+-------------+-------------+------------+------------+-------------+---------
       1e-04 |  1.5998e-02 |  1.3172e-01 |      32.49 |         50 |   135111.00 |    10953
       1e-06 |  1.5878e-03 |  1.1052e-02 |      47.33 |         67 |   190914.00 |    15418
       1e-08 |  1.5901e-04 |  1.0680e-03 |      62.65 |         84 |   250609.00 |    20215
       1e-10 |  1.5953e-05 |  1.1116e-04 |      78.01 |        100 |   307067.00 |    24562
       1e-12 |  2.8520e-06 |  1.5174e-05 |      90.27 |        100 |   353010.00 |    27931
           0 |  2.5161e-06 |  1.5129e-05 |      99.39 |        100 |  1999478.00 |   438790
  -----------+-------------+-------------+------------+------------+-------------+---------
  Total solver time: 3236189.00 us, avg time per iter: 78.9045 us

  Pipeline mode (consecutive mj_step, tolerance = 1e-8):
  1000 steps, nv = 654
  Steps/s          : 298
  us/step (total)  : 3352.8
  us/step (constr) : 2832.0  (84.5%)
  CG iters/step    : 68.43
  LS evals/step    : 226.33
  us/iter          : 41.39
```

PiperOrigin-RevId: 928590104
Change-Id: I1a96730f50f444d6141d8978feb3519009daf320
2026-06-08 08:54:07 -07:00
Haroon Qureshi 7e790879ef Fix namespace for filament-specific "mjrf" API.
PiperOrigin-RevId: 928582582
Change-Id: Idc312607b2f063d8ace8d5cc79bfbc8ac588d13f
2026-06-08 08:37:52 -07:00
Alessio Quaglino 7a7dc7ccad Add support for loading 1D flex components from OBJ line segments.
The obj_decoder plugin is updated to parse line segments ('l') from OBJ files and represent them as degenerate triangles. The user_flexcomp compiler now supports flex dimensions of 1, using these parsed line segments to define the 1D flex elements. The compile sample's error reporting is also improved.

PiperOrigin-RevId: 928566870
Change-Id: I6920729d1b1d5aeb391401c3245ebb1d4784c190
2026-06-08 08:03:30 -07:00
Kyle Bayes ac7f198536 Tune constants for nativeccd to perform better with single precision.
PiperOrigin-RevId: 928549147
Change-Id: Ic28c60f73e92bb1b9578c56f790b6cda94875907
2026-06-08 07:21:17 -07:00
Yuval Tassa a0f014593b Support float32 in mujoco.rollout Python wrapper and tests.
- Update rollout.py to use mujoco.MJTNUM_DTYPE instead of np.float64.
- Update rollout_test.py to use DTYPE for all state/control/sensor arrays to avoid copies and type mismatches.

PiperOrigin-RevId: 928539946
Change-Id: Iee2250c049de799cb0e23ffe5558fe6eea8b3fd8
2026-06-08 06:59:22 -07:00
Haroon Qureshi 116cfe9c70 Remove initial width/height arguments.
The ValidateSwapChains function will correctly set up swap chains
before any render calls, negating the need to have something done
in the constructor.

PiperOrigin-RevId: 928529339
Change-Id: Ie584d57f649730adc092f8683f18697892a5a14f
2026-06-08 06:34:40 -07:00
Kyle Bayes 318880126f Provide better dedupe logic in multiccd in edge collision case.
PiperOrigin-RevId: 928519426
Change-Id: I67531d1c346b1b38c098eaf32c3b13fa7d0c8eaf
2026-06-08 06:07:31 -07:00
Yuval Tassa 6c33e16bf1 Canonicalize mjVisual macros to include type and dimension.
PiperOrigin-RevId: 928506110
Change-Id: If5d031f9d87892f13486ae9ccde23c16131212de
2026-06-08 05:30:57 -07:00
Haroon Qureshi da5500c202 Implement additional draw modes:
- Default rendering but without textures.
- Island coloring based on sleep state.
- Selected object highlighting.

PiperOrigin-RevId: 928482603
Change-Id: I5eda1307bc6e71a4b0b2933b5b941e945cb9de75
2026-06-08 04:29:27 -07:00
Haroon Qureshi 543165a6cc Expose hsv2rgb as internally public function.
PiperOrigin-RevId: 928464175
Change-Id: I57ef75f28663b0da89b9af7bf730d82b965093bf
2026-06-08 03:44:50 -07:00
Copybara-Service a36758c26b Merge pull request #3322 from mhasek:mhasek/add_light_and_mat_prop_to_mjx_model
PiperOrigin-RevId: 928464101
Change-Id: I066caa1b0d45700160909d7452138e557af6b365
2026-06-08 03:42:53 -07:00
Haroon Qureshi b17b5f7918 Expose mjv_flexBodyIdAndPoint as a helper function.
Use the above in studio rather than a custom implementation.

PiperOrigin-RevId: 928432476
Change-Id: I99d772c4baf7260abbf9ac8f6d8032704f1ba769
2026-06-08 02:28:39 -07:00
Yuval Tassa ea2d785e0a Improve quality of maxhullvert coarse convex hulls using Qhull's Q9 option.
PiperOrigin-RevId: 928417339
Change-Id: I59ecd454f063f2e32e1c3ce08eb4a18506ddf8c8
2026-06-08 01:56:24 -07:00
Haroon Qureshi 0093210173 Remove hard-coded render target formats.
The formats are defined in the config.

PiperOrigin-RevId: 928412818
Change-Id: I20ea72214d8e1484723793d8a3f89cdcb4b617b1
2026-06-08 01:45:24 -07:00
Copybara-Service d79520dc87 Merge pull request #3299 from tkelestemur:tarik/mjx-warp-nested-dataclass-methods
PiperOrigin-RevId: 928341876
Change-Id: I0c89bcbbd95a14fadbf33d7785bf212c2c074c99
2026-06-07 22:50:49 -07:00
Mustafa Hasekioglu b4135b571f fix island disable fields dimension mismatch 2026-06-06 16:18:52 -04:00
Mustafa Hasekioglu 994cfa0e4a update mjx model and shims 2026-06-06 14:39:01 -04:00
Taylor Howell 2e43279ac3 MuJoCo Warp documentation: remove parallel linesearch
PiperOrigin-RevId: 927417172
Change-Id: I43f72ec0be89e9370b6e7699a8080d8ecf02b4ab
2026-06-05 12:05:58 -07:00
Kevin Zakka 5fe916045c Replace strncpy with memcpy for gridlayout initialization.
memcpy is more appropriate here as the source and destination buffers have the same size, ensuring the entire buffer is copied.

PiperOrigin-RevId: 927395770
Change-Id: Idbe9dade3160f593060fae5783743b28c0452695
2026-06-05 11:25:49 -07:00
Haroon Qureshi 511cf27ff8 Move segmentation coloring logic into renderer.
PiperOrigin-RevId: 927300828
Change-Id: I994c5742ec30993d2245df167042e72820f91ac7
2026-06-05 07:57:59 -07:00
Copybara-Service fdd82ac420 Merge pull request #3287 from kevinzakka:sysid-issue-3284-fixes
PiperOrigin-RevId: 927249817
Change-Id: I63db037d24238dd0ce82ffe157a2e1bb33c9314a
2026-06-05 05:56:46 -07:00
Taylor Howell 2a4af3246e Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 927227210
Change-Id: Ic72c58524c8e91e6fff44b4cab7f4a0f7de2bb33
2026-06-05 04:56:58 -07:00
Yuval Tassa d80a847bae Move CompareModel to a separate library.
PiperOrigin-RevId: 927174846
Change-Id: Ia8b8b2c8593133d8910399be755e614282bf3252
2026-06-05 02:44:53 -07:00
Yuval Tassa 5ce9a0ad0b Split large parameterized tests into dedicated files.
PiperOrigin-RevId: 927159897
Change-Id: Ib0e11727c49195bc03d190b736c01b14c10268fe
2026-06-05 02:07:47 -07:00
Haroon Qureshi 8fbacf2883 Introduce MaterialManager to allow sharing of material instances.
PiperOrigin-RevId: 927139826
Change-Id: I923a24f28ab7af3a8c854286f064e851b9fd494e
2026-06-05 01:17:37 -07:00
btaba 7078f38163 Update generate_warp_types.py 2026-06-04 12:28:38 -07:00
Kevin Zakka 2b9960a617 Address reviewer feedback. 2026-06-04 09:53:17 -07:00
Kevin Zakka ab4102ea42 Add opt-in cond(J^T J) check to sysid optimize().
Pass check_conditioning=True to FD the Jacobian at the starting point
and warn if cond(J^T J) suggests numerical ill-conditioning.
2026-06-04 09:53:17 -07:00
Kevin Zakka d75b709892 Forward x_scale through the sysid mujoco backend.
mujoco.minimize.least_squares now supports x_scale natively, so the
sysid wrapper becomes a thin pass-through. 'jac' is adaptive per
iteration (was static at x0).
2026-06-04 09:53:17 -07:00
Kevin Zakka 5ae677f026 Warn and rescue sysid parameters that start at a box bound.
ParameterDict.move_off_bounds() shifts at-bound values into the interior;
optimize() warns when any non-frozen component starts at a bound.
2026-06-04 09:53:17 -07:00
Kyle Bayes 66156c7d9a Update tolerances on engine_collision_gjk_test.cc to run with single precision.
PiperOrigin-RevId: 926681633
Change-Id: I14f7b756fd3cf7b8f797b5f7b917efba00006b88
2026-06-04 07:37:15 -07:00
Copybara-Service dadd624255 Merge pull request #3244 from google-deepmind:dependabot/npm_and_yarn/wasm/postcss-8.5.10
PiperOrigin-RevId: 926661082
Change-Id: Ic0d56385914f82aca61268a0372a6163388378f3
2026-06-04 06:48:02 -07:00
Michael Moss a2f08767cf Workaround for CMake "subproject language bug" triggered by recent Filament change.
PiperOrigin-RevId: 926623512
Change-Id: I4aefd6b13bc55881a7013a0f2b7d48ce0b78bd7c
2026-06-04 05:06:09 -07:00
Haroon Qureshi 53ac994759 Add missing files.
PiperOrigin-RevId: 926123240
Change-Id: I59b9baaa106ef12a9bf3c7a6399558753c2c5415
2026-06-03 10:27:41 -07:00
Google DeepMind 36f5c4899c Remove the usage of Texture::setImage that uses FaceOffsets
PiperOrigin-RevId: 926092842
Change-Id: I8010804c6dda89d41ebaf650af776505e5c5ed34
2026-06-03 09:47:37 -07:00
Tarik Kelestemur b4dd8e2d9c Emit TileSet methods in MJX Warp codegen 2026-06-03 12:31:23 -04:00
Haroon Qureshi 4d70b18048 Manage reflections at the scene level.
Renderables may be created/destroyed frequently causing issues with
the underlying RenderTargets used for reflections. Instead, use a
ReflectionManager (associated with a Scene) to manage the RenderTargets.

PiperOrigin-RevId: 926072766
Change-Id: I56c70000183417a92ab9297bc6fec5779f484cbd
2026-06-03 09:18:32 -07:00
Kevin Zakka 25afa6b732 Fix wasm OOM on large models: 32mb stack, raise MAXIMUM_MEMORY to 4gb.
PiperOrigin-RevId: 926060014
Change-Id: I8c4e152321737b1f4cc963f3c6c424af2fe951b4
2026-06-03 08:59:05 -07:00
Tarik Kelestemur 319b3975a0 Merge remote-tracking branch 'origin/main' into tarik/mjx-warp-nested-dataclass-methods
# Conflicts:
#	mjx/mujoco/mjx/warp/types.py
2026-06-03 11:36:53 -04:00
Kevin Zakka 0897e3aec1 Skip the prefetcher when the URL scheme isn't fetchable.
Drag-and-drop uploads go through Module.loadFile and never reached the prefetcher. This is a guard for future provider schemes (e.g., vfs) that shouldn't be passed to fetch().

PiperOrigin-RevId: 926042158
Change-Id: I119d5b1a7512f8e84bb4c752414797593a1e98cd
2026-06-03 08:23:19 -07:00
Yuval Tassa 45d5f2ed5f Improve link in light/directional docs
PiperOrigin-RevId: 926006386
Change-Id: Idfd3eae6c127f29919587ae88aa4291c290e2944
2026-06-03 07:12:04 -07:00
Kyle Bayes 558366f364 Always normalize in planeNormal to reduce rounding errors in single precision.
PiperOrigin-RevId: 926002329
Change-Id: I682f3b90249e60838c2432231b3181e57c565c28
2026-06-03 07:04:12 -07:00
Taylor Howell 5d231c64cd Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 925939529
Change-Id: Idb92c2d50d5be9df7b6e91113b576e9c706847ca
2026-06-03 04:41:10 -07:00
Haroon Qureshi 4cfdf5f34b Bind materials before rendering reflection passes.
PiperOrigin-RevId: 925911124
Change-Id: I134d29424233ccbf57f56e7379e8830662a57836
2026-06-03 03:31:03 -07:00
Haroon Qureshi 0fe2064847 Cleanup Renderable API.
Add function for getting the material. Remove unused/unneeded functions.

PiperOrigin-RevId: 925847769
Change-Id: Iefaf9112b7419830eb2dc4d1323e9c27725c4b16
2026-06-03 01:06:21 -07:00
Yuval Tassa 7b9b88060e Refactor mj_fullM. This change is part of the deprecation of mjData.qM.
PiperOrigin-RevId: 925669464
Change-Id: I4889c66591bc1df4c31135a13776052aad491f7a
2026-06-02 17:22:55 -07:00
Matija Kecman 49211a05c5 Add support for custom physics step functions in StudioApp.
This change allows users to provide an optional `step_fn` callable to `StudioApp.update` and `StudioApp.update_from_viewer`. When provided, this function is called to advance the physics simulation instead of the default `step_control.advance`.

PiperOrigin-RevId: 925439890
Change-Id: Ia833503f6dd0c22fb8d75af6c5f06757496853e5
2026-06-02 10:27:52 -07:00
Matija Kecman 0e4749501c Allow custom step function in StepControl::Advance.
The StepControl::Advance method now accepts an optional std::function to be used instead of mj_step. This allows for custom simulation logic to be executed within the stepping loop. The Python bindings for StepControl::advance have been updated to support passing a Python callable as the custom step function.

PiperOrigin-RevId: 925393132
Change-Id: Id2820c4b55cbdfee6b01adc2395e99a990d4e7a3
2026-06-02 09:20:06 -07:00
Kyle Bayes 3a5626bc27 Align GJK internal memory to avoid misalignment segfaults when compiled as single precision. This is effectively a no-op under double precision.
PiperOrigin-RevId: 925389982
Change-Id: I7117779669965ebf72cb77ccbece419acf9b1b96
2026-06-02 09:15:26 -07:00
Copybara-Service 15cbc8fb55 Merge pull request #3156 from andrewkaufman:newton-schemas
PiperOrigin-RevId: 925328794
Change-Id: If45b8659ea9b88785660331bca5ee837ac172f67
2026-06-02 07:06:59 -07:00
Matija Kecman 4cf4a5665d Configure Copybara export for Dear ImGui and ImPlot Python bindings
Following the export declarations in Dear ImGui and ImPlot METADATA, this change updates MuJoCo's Copybara configuration (copy.bara.sky) to export and transform the Python bindings. `//third_party/dear_imgui/google/py` exports to `python/mujoco/experimental/dear_imgui` and `//third_party/implot/google/py` exports to  `python/mujoco/experimental/implot`.

PiperOrigin-RevId: 925293624
Change-Id: Ie6e32d247a6f7fc24bb36ae7060f2075d8efeb26
2026-06-02 05:32:22 -07:00
Yuval Tassa 062b0f1ea6 Remove deprecated mju_{error,warning}_{i,s} functions.
PiperOrigin-RevId: 925204136
Change-Id: Ia877d08a135092db8037d04e6a237e81325a1d7c
2026-06-02 01:59:05 -07:00
Kyle Bayes ad23db5942 Guard againsts NaNs in engine_collision_gjk_test.cc.
PiperOrigin-RevId: 924844839
Change-Id: I98d5acd8ee97881ebd17f7ba7a40fb378ca1fb2d
2026-06-01 12:17:42 -07:00
Tarik Kelestemur c80d8fb35d Stabilize MJX Warp types codegen 2026-06-01 10:45:22 -04:00
Tarik Kelestemur f97b9f6e3b TileSet MJX codegen fix 2026-06-01 10:22:54 -04:00
Copybara-Service e7ed648cac Merge pull request #3278 from tkelestemur:tarik/mjx-light-active-public-api
PiperOrigin-RevId: 924570592
Change-Id: I86d506e9f03d3230eaaca7061f6794ecdbfe164f
2026-06-01 02:15:20 -07:00
Alessio Quaglino 91c92279d2 Enable interior nodes for interpolated flex shell mode.
Previously shell mode required cellcount=1 along at least one axis. This CL
adds support for cellcount > 1 in all three axes by pinning interior grid nodes
to the parent body and reconstructing their positions from boundary nodes via
Transfinite Interpolation (TFI).

PiperOrigin-RevId: 924314800
Change-Id: I8c2438f4866dd4133feed65f535a1ab69f0c9188
2026-05-31 10:36:01 -07:00
Yuval Tassa 4548e81e4d Rename efc_diagApprox -> efc_diagA.
The field now stores either an approximate or exact diagonal of the constraint matrix A, so the name is made more general.

PiperOrigin-RevId: 924244954
Change-Id: I62b2f76531fb88b7b3bf96e6769940197596702b
2026-05-31 04:54:11 -07:00
Yuval Tassa cd6db9ebe2 Improve CG solver precision and stability under float32 via line search refactor
Fixes #2313

This CL combines two complementary improvements to the Conjugate Gradient (CG) solver, significantly improving numerical precision, stability, and efficiency, particularly in single precision (float32).

1. Line Search Cost Evaluation Refactor: Previously, solver improvement was calculated by subtracting absolute costs: cost(alpha) - cost(0). In highly converged states or single precision, this is susceptible to catastrophic cancellation. We refactor PrimalSearch to compute the cost delta directly, dramatically improving precision.

2. Improved Solver Termination Condition: Near the float32 precision limit, line search deltas can occasionally be slightly negative due to numerical noise. Previously, any value below m->opt.tolerance (including negative values) triggered termination, halting the solver and locking in destabilizing steps. We update the termination condition to require positive improvement (0 < improvement < m->opt.tolerance), allowing the solver to continue iterating and recover stability.

Together, these changes yield substantial improvements, see reduced tolerances herein.

PiperOrigin-RevId: 924229669
Change-Id: Ic0bbefaed090f3a8b1e79ab8d45422c3e86fb56c
2026-05-31 04:00:09 -07:00
Yuval Tassa 4358a102cd Add manual test for CG converence
Also add MJTOL_SCALE to fixture to allow tests to be run with zero tolerance. This is useful when assesing the impact of code changes (A/B comparison of failure values)

PiperOrigin-RevId: 924219083
Change-Id: Ifdd09ac850904ca8dd79179930ce738a4b37d284
2026-05-31 03:15:54 -07:00
Tarik Kelestemur 9bd8daf53b Minimize generated WARP types diff 2026-05-30 16:29:27 -04:00
Tarik Kelestemur f8a12a827f Merge origin/main into light_active PR 2026-05-30 16:24:27 -04:00
Taylor Howell 50e823e91c Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 923922783
Change-Id: I0b407347a70a0e2024aae7ed5bab1592dc40a074
2026-05-30 07:44:29 -07:00
Taylor Howell b9c7a4b81a Import NVIDIA/warp 1.13.0 from GitHub.
PiperOrigin-RevId: 923878216
Change-Id: If9df5e0672e956eb62874fb6f4f74ba3a02977b3
2026-05-30 04:48:08 -07:00
Yuval Tassa 3a6e0ee9b3 Reduce effect of infinite planes on center and extent statistics
PiperOrigin-RevId: 923868757
Change-Id: I3630d29f05a19e0767549284abbe8a8d9386894b
2026-05-30 04:12:07 -07:00
Yuval Tassa d7e872b6f9 Add UI control for MuJoCo threadpool size.
PiperOrigin-RevId: 923860258
Change-Id: I11dc5d7904f1c3657d7e1dd2b0e3c7864c0c7ead
2026-05-30 03:41:38 -07:00
Yuval Tassa 96bf8aea81 Move island-specific sparse matrices from arena to stack.
PiperOrigin-RevId: 923850345
Change-Id: I9683d7554b15b7cd8c45a8dce7814640aa266452
2026-05-30 03:09:46 -07:00
Yuval Tassa 5d782a2bb8 Fix memory overallocation in sparse primal solvers.
PiperOrigin-RevId: 923586079
Change-Id: I8d484b840063c0a7a8a79c5bdc9074a57d2ee55f
2026-05-29 13:51:47 -07:00
Copybara-Service ffe1eadd7e Merge pull request #3294 from kevinzakka:mujoco-minimize-x-scale
PiperOrigin-RevId: 923519000
Change-Id: I4a8fa1f031428cf41d194d17ea4c41975f93f745
2026-05-29 11:34:36 -07:00
Haroon Qureshi f63b92da5e Clear draw queue instead of failing if rendering skipped.
PiperOrigin-RevId: 923420183
Change-Id: I34aac76810a7bf0e4a0394ebe27b45a8fc32f110
2026-05-29 08:09:15 -07:00
Yuval Tassa 8eaf174a88 Change "Num threads" UI element to a slider.
PiperOrigin-RevId: 923378753
Change-Id: Ie5f53faf6ad90e0e1a1148f004b1867a57e6fb5e
2026-05-29 06:30:38 -07:00
Kyle Bayes c7d340be4f Cap box<->box collisions.
PiperOrigin-RevId: 923312868
Change-Id: I801d76cf1d1d7b9ed1535d3e3c723a5e8af4162a
2026-05-29 03:52:57 -07:00
Copybara-Service 46d2405b42 Merge pull request #3288 from davidhozic:fix/strchr-const-char
PiperOrigin-RevId: 923297843
Change-Id: I13b07c6cf0f611a8b3ee797dac94b35ce8d9deb4
2026-05-29 03:16:33 -07:00
Copybara-Service 9af965f241 Merge pull request #3120 from Ashutosh0x:fix/safe-overflow-msvc
PiperOrigin-RevId: 923296001
Change-Id: I037dcc55c91d6eb68b3e63b34a0e059c796b5116
2026-05-29 03:12:40 -07:00
Yuval Tassa df6942eb39 Support float32 precision for mjtNum in Python bindings.
PiperOrigin-RevId: 922959317
Change-Id: I384b3bdeabdc4d3f66c71cae41dabfaf51387be7
2026-05-28 13:56:58 -07:00
Kyle Bayes b612d352d4 Fix GitHub Actions for threading.
PiperOrigin-RevId: 922926969
Change-Id: I968e6b130b6125dbc0ec65ba913d04292270b563
2026-05-28 12:57:16 -07:00
Google DeepMind 9436972a22 Import NVIDIA/warp 1.13.0 from GitHub.
PiperOrigin-RevId: 922893824
Change-Id: Ib91ffb03257c614c48feda096822f723323be54d
2026-05-28 11:51:39 -07:00
Kyle Bayes b935d4153c Add new mju_threadpool API function, and delete old threading API.
PiperOrigin-RevId: 922838541
Change-Id: Id9f7e0fb298ffde61fcc49a802dc78971858ce51
2026-05-28 10:11:44 -07:00
Ashutosh0x 50ec8e84de test: intercept mju_warning in overflow regression test 2026-05-28 21:46:15 +05:30
Copybara-Service a22fc2423a Merge pull request #3295 from tkelestemur:tarik/fix-mjx-codegen-python311
PiperOrigin-RevId: 922794565
Change-Id: Ibd42328d739d3882e5c418cf69fc9787572cdb4a
2026-05-28 08:44:28 -07:00
Taylor Howell cae5a608d5 Import NVIDIA/warp 1.13.0 from GitHub.
PiperOrigin-RevId: 922749092
Change-Id: Ide815e4224e64af69e7c3a58102508bc81d22770
2026-05-28 07:00:59 -07:00
Alessio Quaglino 4c381635e1 Add mjs_makeFlex to the MuJoCo C and Python APIs.
- Add mjs_makeFlex C API that wraps mjCFlexcomp::Make(), creating
  a flex with auto-generated bodies, joints, and equality constraints
  from parameters (type, dim, dof, count, cellcount, spacing, scale,
  radius, mass, inertiabox, equality, rigid, flatskin, elastic2d,
  pos, quat, origin, file, vfs).
- Add Python binding body.make_flex() in specs.cc with keyword args.
- Refactor flex_spec_provision.py to use make_flex() instead of XML
  string templating + separate spec + attach. Eliminates textwrap
  dependency.
- Merge user_flexcomp into user_model BUILD target to resolve
  circular dependency.

PiperOrigin-RevId: 922725304
Change-Id: Ice13787c45f3173407fec659f9590a6453bc65dd
2026-05-28 05:59:20 -07:00
Sam Haves b9fb817af8 Lexically normalize resource path in mjz_decoder resource provider.
PiperOrigin-RevId: 922654438
Change-Id: Ieb46230a2aba46a5e711bc5b24aec982f71e56ca
2026-05-28 02:56:45 -07:00
Copybara-Service f755d718d3 Merge pull request #3293 from kevinzakka:studio-live-parallel-prefetch
PiperOrigin-RevId: 922417778
Change-Id: Ia839747c4af0e705962308dc84e9a7c3926fc910
2026-05-27 16:47:18 -07:00
Tarik Kelestemur 106f1c5dbb fix mjx codegen and rerun 2026-05-27 17:50:31 -04:00
Tarik Kelestemur cf1b28d19a address btaba's review 2026-05-27 17:37:33 -04:00
Kevin Zakka aa4a43da17 Address reviewer feedback: default x_scale=None, drop TRF qualifier. 2026-05-27 12:55:14 -07:00
Kyle Bayes 4035c66428 Fix multiccd edge bug that occurs in certain situations.
PiperOrigin-RevId: 922251109
Change-Id: I74c08ae49d5dfd2a41b2dcd28eb9f2b5ba113216
2026-05-27 11:32:45 -07:00
Alessio Quaglino f6c85287bf Optimize mj_flex performance.
Two performance optimizations for interpolated flex objects:

1. Hoist loop-invariant stride calculations in `mju_cellLookup` out of nested loops.
   This reduces multiplications from 16 to 6 (linear) and 54 to 12 (quadratic)
   per vertex.

2. Extract and consolidate optimized 3D interpolation logic into a new
   reusable utility `mju_evalBasisArray` in `engine_util_misc.c`. This function
   uses nested loops and precomputed 1D shape functions to avoid expensive
   dynamic `phi` calls and branching, and leverages stack-buffered outputs to
   eliminate compiler pointer-aliasing barriers. We propagate this optimization
   to both kinematics (`mju_interpolate3D`) and constraint setup
   (`engine_core_constraint.c`).

Together these changes yield a ~50% overall speedup in `mj_fwdKinematics` for interpolated flexes with ~10k vertices in the collision meshes and ~10 nodes in the deformation grid.

PiperOrigin-RevId: 922198093
Change-Id: I9c804e65cd532e2f9ac6e9a71d01c30cd64186fa
2026-05-27 10:05:30 -07:00
Google DeepMind af4be63cd8 Add xmacros for MjSpec.
PiperOrigin-RevId: 922169069
Change-Id: I01426596e49196996dfa324d5ab3849a90de2e3a
2026-05-27 09:12:35 -07:00
Haroon Qureshi 36ea0c466f Support multiscene, multiview rendering.
Update Renderable so that it can switch its own draw states (material
instance, shadow casting, reflection textures, etc.) per render request.
This allows us to use the same Renderable with different effects from
different views within the same frame.

PiperOrigin-RevId: 922102817
Change-Id: I1cf02fddb7a00345a741db1bee88e716517765f4
2026-05-27 06:54:58 -07:00
Matija Kecman c0b8aa9dec Make studio python more like studio C++
- C++ Platform UX: Added a "Copy Camera" button to copy XML camera definitions to clipboard.
  - C++ Platform UX: Extracted `SetSpeedIndex` and `GetExpectedLabelWidth` into reusable platform helpers.
  - C++ Platform UX: Fixed combo box widths and removed auto-hide tab bar flag from dockspace.
  - C++ Studio App: Deduplicated label width and speed index logic by adopting platform helpers.
  - C++ Studio App: Updated the toolbar layout to use a 2-column table.
  - Python Bindings: Added pybind definitions for `set_camera_index`, `set_speed_index`, and `camera_to_string`.
  - Python Studio App: Aligned toolbar UI with C++ using a 2-column table and fixed immediate theme switching.
  - Python Studio App: Added a Help menu displaying the MuJoCo version and Stats toggle.
  - Python Events: Added `-`/`=` shortcuts for simulation speed and `Esc`/`[`/`]` shortcuts for camera selection.

PiperOrigin-RevId: 922097319
Change-Id: Iec74afe37bf5c7a1ebf1cab4141e47fff5fe9274
2026-05-27 06:42:59 -07:00
Ashutosh0x 0607dc450c security: fix integer overflow in safeAddToBufferSize on MSVC
The MSVC fallback path in safeAddToBufferSize() performed unchecked
arithmetic (type_size*nr*nc) on attacker-controlled values read from
.mjb binary model files. This could cause integer overflow, leading
to an undersized heap allocation followed by a heap buffer overflow
when data is copied into the buffer.

The fix adds manual overflow detection using SIZE_MAX/INTPTR_MAX
comparisons, matching the behavior of the existing __builtin_*_overflow
path used on GCC/Clang.

Also adds a regression test that crafts a binary model buffer with
overflow-inducing size fields and asserts safe rejection.
2026-05-27 17:01:01 +05:30
Michael Moss 79aeceeaa3 Update MuJoCo version to 3.10.0 following the 3.9.0 release
PiperOrigin-RevId: 922027849
Change-Id: I52dd7fb5eeb962c2670ab5dbbe7ce192ac9332c5
2026-05-27 03:50:22 -07:00
Michael Moss 237c17e485 Update changelog for the 3.9.0 release.
PiperOrigin-RevId: 922002472
Change-Id: I92489261c59cff10b29def784698868e67aa43da
2026-05-27 02:47:19 -07:00
Alessio Quaglino f6cd0234fd Change tactile sensor normal component to report penetration depth.
The normal component of the tactile sensor now reports the maximum penetration depth at each taxel, instead of a derived normal force. The depth is negated so that positive values indicate penetration.

PiperOrigin-RevId: 921980899
Change-Id: Ide4103c0aff465e25a81cfdda650f6a0e2da9e0b
2026-05-27 02:00:34 -07:00
Kevin Zakka c12dc23852 Add x_scale to mujoco.minimize.least_squares.
Per-parameter scaling via change of variables z = x / D. Supports
'jac' (adaptive D_i = 1/||J(:,i)|| per iteration, matches scipy's TRF),
explicit array, or a positive scalar. Default 1.0 is a no-op.
2026-05-26 17:06:09 -07:00
Kevin Zakka 249e9c08b8 MuJoCo Live: pre-fetch model assets in parallel before compilation.
The prefetcher asks mju_getXMLDependencies for the transitive asset
list, fetches every URL with Promise.all, and primes the bytes into the
WASM-side FetchCache. When the compiler runs, every resource it opens
is already in memory. Cold-load on a typical Menagerie model drops from
~9 s to ~2 s.
2026-05-26 16:01:48 -07:00
Kevin Zakka 6f9725a1da Make mju_getXMLDependencies read XMLs through the resource provider.
The function called tinyxml2's LoadFile directly, which only works on
the OS file system. Reading through mju_openResource lets it work
against any registered backend (VFS, HTTP, github:, ...).
2026-05-26 16:01:48 -07:00
Michael Moss 583aa5ad4f Update dependencies ahead of the 3.9.0 release.
PiperOrigin-RevId: 921512490
Change-Id: Iac2e4e52dde5ca7aeda62f033fcc03aadcaeb904
2026-05-26 09:30:49 -07:00
Taylor Howell d63a89f896 MJX documentation: update feature parity section
PiperOrigin-RevId: 921452813
Change-Id: Ic33c20688b9875e0d2be8563377a1e009da51fa6
2026-05-26 07:23:24 -07:00
Copybara-Service e03bf07134 Merge pull request #3230 from google-deepmind:dependabot/pip/mjx/pytest-9.0.3
PiperOrigin-RevId: 921431196
Change-Id: Ie23587578d88a1d3d909e50b68108a2ee7934d09
2026-05-26 06:32:39 -07:00
David Hozic 998f9960f9 Revert indexer_xmacro.h change 2026-05-26 14:51:48 +02:00
David Hozic 57e27f94f3 Fix compilation error 2026-05-26 14:50:11 +02:00
David Hozic da0bf9af17 Fix incorrect type for Python view of MjModel/tex_adrr 2026-05-26 14:48:03 +02:00
Yuval Tassa 393c1e4217 Migrate mjtByte to mjtBool for boolean-valued fields.
PiperOrigin-RevId: 921408093
Change-Id: Icb00457836359779f0f72fc02d6a7c0dc9f6bd23
2026-05-26 05:35:49 -07:00
Copybara-Service 3cabb2eb8e Merge pull request #3257 from google-deepmind:dependabot/pip/mjx/pip-26.1
PiperOrigin-RevId: 921402236
Change-Id: I40e4f10e72deb3b4195b9520305b7da220fbe08a
2026-05-26 05:20:14 -07:00
Taylor Howell ddff7e3e2e MuJoCo Warp documentation: update feature parity section
PiperOrigin-RevId: 921334977
Change-Id: I1c20e30cde81ae18830cae894ac5aee99ac0dcb8
2026-05-26 02:37:05 -07:00
Yuval Tassa 7667e7110e Introduce mjtBool for boolean types.
PiperOrigin-RevId: 920201340
Change-Id: I3b19c11a00357e06a1df08b8819832955c37f9ff
2026-05-23 09:13:54 -07:00
Baruch Tabanpour 466d068089 MuJoCo Studio: Support Ctrl+Option+Left Click Drag for perturbation
Support Ctrl+Option+Left Click Drag (maps to Ctrl+Alt+Left Click Drag in the application) to apply point force perturbations (translation) on the robot in the WebGL live viewer. This matches the Mac experience in the native MuJoCo simulate app and provides a fallback for Mac users where Right Click is difficult to trigger.

PiperOrigin-RevId: 919767954
Change-Id: I4a1d1c05784a8257d13f64f738af5b4841a615b3
2026-05-22 11:14:46 -07:00
Saran Tunyasuvunakool 5c21c8d28b Minor restyling of the loading screen.
PiperOrigin-RevId: 919744412
Change-Id: I3e4aa0b59d100ac85e8f915d7d733b2b3ea1ecea
2026-05-22 10:26:04 -07:00
Yuval Tassa ab0e0091d5 Standardize "DO NOT EDIT" comments in generated files.
PiperOrigin-RevId: 919718422
Change-Id: I2cba07d75d37d45f3f30b23d049c944b080248ad
2026-05-22 09:34:45 -07:00
Kyle Bayes 8469198ba5 Remove multiccd enable flag from mjSpec Colab.
PiperOrigin-RevId: 919716011
Change-Id: I746271990db1e213fee33b38e639db78bbf97a1a
2026-05-22 09:29:26 -07:00
Haroon Qureshi 8ae51e104d Move DrawTextAt from imgui_bridge to imgui_widgets.
PiperOrigin-RevId: 919508805
Change-Id: Ie311b88164d8c2ff7a8452ec2f1b8be7e7d9770e
2026-05-22 00:52:54 -07:00
Haroon Qureshi 3499adacae Store skin and flex meshes separately.
PiperOrigin-RevId: 919490079
Change-Id: I45473ee59e22465732fb4b470a94c2944fed9c37
2026-05-22 00:09:49 -07:00
Haroon Qureshi 88b8b58429 Add support for transparent PBR materials.
PiperOrigin-RevId: 919477028
Change-Id: I75cc311fc73dd5fe26b72ba8d49fd421fda455e3
2026-05-21 23:35:53 -07:00
Baruch Tabanpour 5b73846a1e Upgrade MuJoCo Live loading screen
PiperOrigin-RevId: 919112273
Change-Id: I0ffdf908e32d4197e007ebcc2d9f5136b59cf6b3
2026-05-21 10:03:40 -07:00
Yuval Tassa 15d27b363f Compile-time size assertions for MuJoCo basic types
PiperOrigin-RevId: 919107499
Change-Id: I07fcba4f33c77a2a1e68528dba6d399af94d0220
2026-05-21 09:55:04 -07:00
Matija Kecman 585be6cee5 Fix wireframe rendering
PiperOrigin-RevId: 919100432
Change-Id: I2931d793ab9639bdaaad11f6d77a77aa14e43b8a
2026-05-21 09:41:59 -07:00
Yuval Tassa 88a293b5e4 Update docs to correctly reference mjtype.h
PiperOrigin-RevId: 919071817
Change-Id: I829de7a22a49e6df604b0acf601a13f67ef5fbab
2026-05-21 08:44:11 -07:00
Yuval Tassa 2810edd27a Rename mjtnum.h to mjtype.h, move enum types to mjtype.h
PiperOrigin-RevId: 919020039
Change-Id: I441295c0baa0b7456f78239fbd5478d32ffc07c1
2026-05-21 06:43:29 -07:00
Kyle Bayes ad96acfb16 Add internal mj_narrowphase for batch processing of potential geom pair collisions.
PiperOrigin-RevId: 918988042
Change-Id: I871dcdf42f8105e2c8a57e275a3775ea46c69e65
2026-05-21 05:16:35 -07:00
Saran Tunyasuvunakool 7c47a89cd0 Add asset file download indicator to the loading screen.
This provides visual feedback to the user while loading large models.

PiperOrigin-RevId: 918708877
Change-Id: I77ea475cce6d9718e6cf8b33cb72b3f524a6ee63
2026-05-20 16:26:40 -07:00
Kyle Bayes 7174d33f08 Introduce mjPreContact, a minimal struct passed into the collision functions.
PiperOrigin-RevId: 918533795
Change-Id: I2b5af05c1479b25d5c2cfdc690321a26fce6ede6
2026-05-20 10:47:46 -07:00
Haroon Qureshi 53b3137a12 Separate Light management into a separate class.
PiperOrigin-RevId: 918508291
Change-Id: I9cadc1b612006a0450f8a2fd9088d56cc2e610a3
2026-05-20 10:01:15 -07:00
Sam Haves fa8ac7a516 Implement mjz encoder.
PiperOrigin-RevId: 918493808
Change-Id: I150d182ff27801d829537a8001a0b3a04c1a0499
2026-05-20 09:32:51 -07:00
Haroon Qureshi 57d2c49316 Track size/scale separately for renderables.
PiperOrigin-RevId: 918476985
Change-Id: I414b1abe2f9b3a3a7549ab5195971127d5598c36
2026-05-20 08:54:28 -07:00
Yuval Tassa 6aa738e75b Add Expand/Collapse All buttons to XML schema documentation.
PiperOrigin-RevId: 918454244
Change-Id: Idcd2cec39ccaf90fd2d6265aaa364dd6bfb79254
2026-05-20 08:06:11 -07:00
Yuval Tassa 7b83f96e49 Prevent visited docs links from changing color.
PiperOrigin-RevId: 918445755
Change-Id: I4884c7f349ef39fab2678ba68eae422e6140b0a2
2026-05-20 07:48:24 -07:00
Tarik Kelestemur 0482bbcca8 Expose MJX light_active model field 2026-05-19 23:54:48 -04:00
Matija Kecman dd37ae16fc Fix studio python samples when running on CRD
* Changed window.cc to not pass `SDL_WINDOW_OPENGL` for headless opengl graphics modes since this requests a [GLX visual](https://tronche.com/gui/x/xlib/window/visual-types.html#Visual) but CRD's virtual X11 display has no GLX visuals causing window creation to fail with "Couldn't find matching GLX visual".

* Changed `TryLoadEgl` so it fails if `eglBindAPI(EGL_OPENGL_API)` does not return true, causing `CreateFilamentPlatform` to fallback to OSMesa on CRD.

PiperOrigin-RevId: 918029935
Change-Id: Id88338811949b1402578de19bc4d31f4ee1783c1
2026-05-19 14:28:09 -07:00
Yuval Tassa bdf00966f9 Add compiler timing diagnostics to mjsCompiler, printed by compile.cc
For example, `compile mujoco_menagerie/robotis_op3/scene.xml` now outputs

```
Compile 1 (cold cache):
  total:      317.2 ms
  assets:     284.8 ms (wall clock)
    load:     616.1 ms
    hull:      26.4 ms
    poly:     137.8 ms
    inert:    177.8 ms
    bvh:      568.2 ms
    octr:       1.6 ms
    tex:       25.3 ms
  other:       32.4 ms

Compile 2 (warm cache):
  total:       79.9 ms
  assets:      54.5 ms (wall clock)
    load:     888.5 ms
    hull:       0.0 ms
    poly:       0.0 ms
    inert:      0.0 ms
    bvh:        0.0 ms
    octr:       0.0 ms
    tex:       21.4 ms
  other:       25.3 ms
```

PiperOrigin-RevId: 917850214
Change-Id: Iaec86230bec0faf2e47820e20cbff61de5b2621e
2026-05-19 08:28:47 -07:00
Yuval Tassa f712eed4ce Allow flex sleeping
PiperOrigin-RevId: 917817500
Change-Id: Ia3bd5e52e7c2eaa3f70c81352d82c130b1d357f6
2026-05-19 07:15:27 -07:00
Haroon Qureshi ddc4c54d16 Update CMakeLists.txt
PiperOrigin-RevId: 917775846
Change-Id: Iebc63a3c7a1956f6d37771319ae0f2817f5edcc5
2026-05-19 05:24:13 -07:00
Haroon Qureshi a205b7afdb Move ImguiBridge from filament compat library to platform ux.
PiperOrigin-RevId: 917751897
Change-Id: I6578c35d49cdd9627fa8b3fa7956d56da7e2c678
2026-05-19 04:17:43 -07:00
Haroon Qureshi 303c1bd0aa Make MjrFilamentRenderer an internal detail of compat library.
Renames MjrFilamentRenderer to CompatContext and makes it an
internal detail of the compatibility layer.  This allows us to
remove all legacy functions from the mjrf namespace, making
them available only in the compatibility layer.

Update studio to use non-legacy mjrf APIs. This requires it to
use some of the compat helper classes. These will be refactored
in the future to make them reusable components.

PiperOrigin-RevId: 917730783
Change-Id: Ic8f68e6e75059f7d394ea3266a346cbd6c1fcaed
2026-05-19 03:26:04 -07:00
Copybara-Service a1056676a0 Merge pull request #3276 from dparikh79:fix/3275-boxqp-symmetric-lower-matvec
PiperOrigin-RevId: 917279467
Change-Id: If4117b1e2147679336becb558e0f87621555dfc7
2026-05-18 09:36:01 -07:00
Yuval Tassa 71d1014e70 Add mjENBL_DIAGEXACT for exact constraint diagonal. Fixes #2472
PiperOrigin-RevId: 916932908
Change-Id: Id23ac39b5cd996afc52990719a4e07c0cc7de600
2026-05-17 16:47:54 -07:00
Alessio Quaglino 66d764a116 Scale flex warp constraint by thickness^3.
Warp is not a true stretch mode but a parasitic shear mode so it should be scaled like bending (~thickness^3) rather than stretching (~thickness). The thickness parameter can therefore be used to set the stretch to warp stiffness ratio of the strain constraints.

PiperOrigin-RevId: 916900311
Change-Id: I52e54210fbb2a6d309abc1f084934830adce3423
2026-05-17 14:33:12 -07:00
Alessio Quaglino 8a20ce24d3 Refactor shell stiffness computation to use pure membrane modes plus an explicit warp mode.
PiperOrigin-RevId: 916879634
Change-Id: Ib706909521b4f503b13904a34b0e29aefd4fa433
2026-05-17 13:00:08 -07:00
Yuval Tassa a897805683 Improve test comparing forward and inverse dynamics mismatch
PiperOrigin-RevId: 916864072
Change-Id: I9952c7dd1bde2033dfe1380552f2c4b6b7344b26
2026-05-17 12:03:20 -07:00
Yuval Tassa 04042d8bf3 Move square root of Delassus matrix from stack to arena
PiperOrigin-RevId: 916852244
Change-Id: I4379553f808d0b238a1421606f806ea2d0a33d7c
2026-05-17 11:21:55 -07:00
Dhruvil 71072c025d Honor lower-triangle contract for H in mju_boxQP.
mju_boxQP documents that only the lower triangle of the Hessian H is
read, but the gradient and search-direction updates inside
mju_boxQPoption still called the dense mju_mulMatVec, which reads the
upper triangle as well. This violated the documented contract and
prevented callers from safely leaving the upper triangle uninitialized.

Add a file-local mulMatVecSym helper that computes res = H*vec while
reading only the lower triangle of H (mirroring the convention of the
existing mulVecMatVecSym quadratic-form helper), and use it in place of
mju_mulMatVec in both call sites. Extend the BoxQP test suite with
UpperTrianglePoisoned, which fills the strict upper triangle of H with
NaN and verifies that the solver produces the same result as on the
clean symmetric input.

Reported by @lshdlut.

Fixes #3275
2026-05-17 13:56:53 -04:00
Saran Tunyasuvunakool 2345663efb Change title to "MuJoCo Live" and respect system colour scheme.
PiperOrigin-RevId: 916183118
Change-Id: I760be720cb001038e993383a5e523a2de8496a7c
2026-05-15 14:26:48 -07:00
Haroon Qureshi b540909f18 Ensure swap chains are resized appropriately.
The swap chain dimensions are a union of all render request
viewport sizes that use the swap chain.

PiperOrigin-RevId: 916078573
Change-Id: If26a9e1486006ed346227120a361773bfa23f292
2026-05-15 10:43:52 -07:00
Alessio Quaglino 71ddeb3efc Add fast path for flex derivative computation in centered flexes.
Introduce a fast path in mj_addFlexDerivatives for centered flexes where all nodes are attached to bodies with only 3 translational DOFs and no DOF-contributing ancestors. This allows for a direct scatter of K*vec, avoiding the overhead of sparse Jacobian construction and multiplication.

PiperOrigin-RevId: 916063477
Change-Id: I824728a5bdc3b975b04b46ecf22994922e307a8c
2026-05-15 10:13:22 -07:00
Haroon Qureshi d5872acec8 Use RGB8 for segmentation colors.
PiperOrigin-RevId: 916061579
Change-Id: I0c1270cb71a9a4476a54b3bf6049981ed30f229f
2026-05-15 10:10:35 -07:00
Saran Tunyasuvunakool a03191b9e8 Add a github: resource provider scheme to MuJoCo Live.
This resolves to https://raw.githubusercontent.com/... under the hood.

PiperOrigin-RevId: 916050807
Change-Id: I1630e29a5b5aad0e39cdd8aa4cfc1ff1a71f19d9
2026-05-15 09:48:22 -07:00
Haroon Qureshi 99b01b9f87 Make wireframe rendering a draw mode.
PiperOrigin-RevId: 916042943
Change-Id: Ifbf0033bfc0607c7808d90423648deb0296056a3
2026-05-15 09:30:55 -07:00
Alessio Quaglino 093b92acc1 Add bounds check for cached node indices in passive mesh.
The global node indices stored in face_gidx are now checked to ensure they are within the valid range of node numbers, raising an error if any index is out of bounds.

PiperOrigin-RevId: 916025763
Change-Id: I1d2dcb11603137c337493541066b62b2ed2854c0
2026-05-15 08:50:49 -07:00
Kyle Bayes a0c4c62654 Update thread_performance_test.cc.
PiperOrigin-RevId: 916025277
Change-Id: Icc000e5f81b79e0239359638d0eabc3e2ecd00e6
2026-05-15 08:47:48 -07:00
Alessio Quaglino 9fb548cadb Optimize flex bending edge computation by caching face states.
In `mj_flexPassive`, precompute and cache face positions, global indices, and corotational quaternions for all faces. This avoids redundant calls to `mju_flexGatherFaceState` for each bending edge, as each face can be part of multiple bending edges. This gives a 3-4x speedup in mj_passive.

PiperOrigin-RevId: 915912918
Change-Id: I3e1c00cf2d989f85398a0750a0faf359249cfe01
2026-05-15 03:32:01 -07:00
Haroon Qureshi 766f519576 Move some scene settings into render request struct.
Reflections, shadows, and post-processing can be specified per render
request rather than per scene.

PiperOrigin-RevId: 915910030
Change-Id: I8ce773b42870aa76a2d8219347ca1cafaec1a97b
2026-05-15 03:23:25 -07:00
Alessio Quaglino 0ad77f1ddf Optimize flexedge velocity computation.
Skip flexedge velocity calculation for rigid and interpolated flexes, as they are not used in those cases. The computation is now done per-flex, only for the edges within each non-rigid, non-interpolated flex.

PiperOrigin-RevId: 915907396
Change-Id: I0beb1f98f0115c83da13fed184e89101f57563ab
2026-05-15 03:16:09 -07:00
Alessio Quaglino 7ca1bc6a56 Precompute rotated stiffness matrix before CG in implicit flex integrator.
This gives a 3x speedup in implicitfast.

Also cleanup old code that was used in the dense factorization of the stiffness matrix before we switched to CG.

PiperOrigin-RevId: 915900315
Change-Id: Id6973c4bfd7d371a43ec6db982703969b23a3550
2026-05-15 02:58:06 -07:00
Haroon Qureshi 85bf2b9660 Move GetMaterialType into material module.
PiperOrigin-RevId: 915895534
Change-Id: Ic7e9d52374131aa93445f90cf2208f6c93d123f4
2026-05-15 02:45:31 -07:00
Taylor Howell 072125c49c MJX (impl='warp'): nconmax -> naconmax
PiperOrigin-RevId: 915407157
Change-Id: Ie43c06164d6d942c2a4bb60b3d09fcb5c4c87a35
2026-05-14 06:52:45 -07:00
Haroon Qureshi 9c372fbbea Minor cleanup to scene_geom_util.
PiperOrigin-RevId: 915367694
Change-Id: Ia20c3ba050d9f364da5c26f0812bf9a9c5763cd6
2026-05-14 04:54:28 -07:00
Haroon Qureshi c587cea0f7 Add flex to shapes test scene.
PiperOrigin-RevId: 915363027
Change-Id: Icb0bf26374396a3929eeec30807fcf78b683ee94
2026-05-14 04:40:06 -07:00
Saran Tunyasuvunakool e47809d50d Refactor MuJoCo Live to separate out HTML, CSS, and JS components.
PiperOrigin-RevId: 915340338
Change-Id: Ic62b9d640af9967a59a77fa59a3556b916d5a24c
2026-05-14 03:39:42 -07:00
Yuval Tassa c56d662d27 Update link to Newton physics engine in changelog.
PiperOrigin-RevId: 915262716
Change-Id: I801267e760b8b5eeb534f71b4789e5a7fb8c35b1
2026-05-14 00:01:06 -07:00
Saran Tunyasuvunakool f7e00d041e Add commit hash and remove "Upload File" button from MuJoCo Live.
PiperOrigin-RevId: 914909503
Change-Id: I084d888eb5093b4278e758697bff43ff941c79d0
2026-05-13 09:34:47 -07:00
Saran Tunyasuvunakool 9230b34fed Exclude CMake install steps for Emscripten.
Install steps aren't needed for WASM builds, and are causing issues with EXPORT relating to lodepng and miniz.

PiperOrigin-RevId: 914891405
Change-Id: If653fe7449b0166ad6762a3fad6b95e02f3532b1
2026-05-13 08:55:26 -07:00
Taylor Howell e1f5534b5f Fix tactile sensor body validation.
PiperOrigin-RevId: 914870657
Change-Id: I57565b4975e0cd7eb1b1ffa199e451a5c5bc0a6e
2026-05-13 08:11:36 -07:00
Yuval Tassa 17fbc0aeef Update colors and legend in margin/gap figure.
PiperOrigin-RevId: 914857514
Change-Id: Ida36393bd4cd706bf81b8b7000ddd34f088fc936
2026-05-13 07:43:41 -07:00
Alessio Quaglino 955ae3f3c0 Fix sign error in flex interp implicit integration.
The flex interp stiffness matrix is Negative Semi-Definite (NSD). When forming the RHS for implicit integration, the term involving the velocity and stiffness should be added, not subtracted. A new test is added to ensure energy stability for flex interp stretch stiffness with the implicitfast integrator.

PiperOrigin-RevId: 914845245
Change-Id: Iaaf0914909128e64e195f17cc5f2f344a8a43bc2
2026-05-13 07:15:20 -07:00
Sam Haves fc2237dad8 Merge branch 'main' into newton-schemas 2026-05-13 09:57:59 -04:00
Haroon Qureshi 69a1087e9e Disable window resizing on load as it breaks on some platforms.
PiperOrigin-RevId: 914774489
Change-Id: I9aea71b386de93f4d2fc3da5310dd7a3018c8c1c
2026-05-13 03:59:46 -07:00
Alessio Quaglino 35cdc779e6 Add implicit bending stiffness for standard flex.
Standard flex (flex_interp=0) with thin-plate bending treated bending forces purely explicitly. This caused contact-induced vertex vibrations and non-physical energy injection for flat resting sheets, because the solver treated each vertex as an independent mass during contact and contact normals are orthogonal to stretch constraints.

Fix: extend the existing preconditioned CG solver to include the constant bending stiffness K_bend in the implicit operator via matrix-free mat-vec.
PiperOrigin-RevId: 914774020
Change-Id: I45e0d6749abb6f873566203bccae956514b2576b
2026-05-13 03:58:16 -07:00
Yuval Tassa 7bfdbad80b Make PGS solver constraint visitation order time-independent.
PiperOrigin-RevId: 914741347
Change-Id: I7889a42543e9a9f3ff883e25ee9eafaceedc29e1
2026-05-13 02:34:30 -07:00
Saran Tunyasuvunakool 99e626096f Fix miniz include.
PiperOrigin-RevId: 914519929
Change-Id: I0dc00ef3f4518571165e4be0e85016511e0cdd60
2026-05-12 15:51:27 -07:00
Yuval Tassa a4e49f2dff Margin and gap redesign (breaking change)
PiperOrigin-RevId: 914329812
Change-Id: I905665e4c1965bdb8b90587e5b1277cfbfe5cce0
2026-05-12 09:43:43 -07:00
Saran Tunyasuvunakool 7f5be412a0 Put miniz in MujocoDependencies.cmake.
PiperOrigin-RevId: 914322421
Change-Id: I3f6e821164eede979802c51a6f8ee00d3346d585
2026-05-12 09:27:00 -07:00
Haroon Qureshi 58abf3d4ae Fix dependency between FilamentContext and SceneView.
Removes the DoRender and DoReadPixels functions which allowed
FilamentContext to "call" SceneView functions even though
SceneView depended on FilamentContext.

Adds a mjrf_setClearColor function so that we no longer rely
on SceneView setting the clear color.

PiperOrigin-RevId: 914253362
Change-Id: I33c1cc9dfc7cb2f4c3cc855a600cccb0c54ae31c
2026-05-12 06:37:51 -07:00
Haroon Qureshi 3f3ff85a59 Enable backface culling by default.
Disable only for geom types that need it (planes and triangles).

PiperOrigin-RevId: 914211570
Change-Id: Id95e32924122789111f561d922110128b3f56c77
2026-05-12 04:41:10 -07:00
Haroon Qureshi 5339d9154e Ensure faces for meshes are correctly oriented.
This is in preparation for a future CL that will disable backface culling.

PiperOrigin-RevId: 914136370
Change-Id: Ie8db1268faaa306c3f3356efc5e1305d791cf525
2026-05-12 01:27:31 -07:00
Alessio Quaglino f9f1db1e0a Replace the banded Cholesky solver for implicit flex interpolation
with a preconditioned Conjugate Gradient (CG) solver that operates
on the full system matrix.

The previous approach extracted flex DOFs into a reduced banded system,
factored it separately, and overwrote the global solve. This required
precomputed bandwidth (makeFlexBandwidth), parent-joint detection,
coupling corrections, and a FlexInterpContext struct — and only worked
for standalone flex trees without parent joints.

The new CG solver uses the already-factored global system (M - h*qDeriv)
as a preconditioner and adds the flex stiffness contribution via
matrix-free products (mjd_flexInterp_mulKD/mulK). This handles any
kinematic configuration — including flexes attached to articulated
chains or with parent joints — without sparsity pattern restrictions.

Before (`bunny_multicell`):
```
 Simulation time      : 50.80 s
 Steps per second     : 197
 Realtime factor      : 0.20 x
 Time per step        : 5080.3 µs

 CG iters / step      : 3.16
 Contacts / step      : 31.04
 Constraints / step   : 124.15
 Degrees of freedom   : 178
 Dynamic memory usage : 0.4% of 100M
```

After:
```
 Simulation time      : 9.52 s
 Steps per second     : 1051
 Realtime factor      : 1.05 x
 Time per step        : 951.7 µs

 CG iters / step      : 3.21
 Contacts / step      : 30.90
 Constraints / step   : 123.61
 Degrees of freedom   : 178
 Dynamic memory usage : 0.3% of 100M
```

PiperOrigin-RevId: 913758038
Change-Id: If5aa617b2d535c86aec9bd71c9e0003a2b38bdd7
2026-05-11 10:11:51 -07:00
Haroon Qureshi 5d818306ef Save/restore window size in UX settings.
PiperOrigin-RevId: 913695007
Change-Id: I3366b11a5de53292d4ffe0e4c46f866381624788
2026-05-11 07:44:09 -07:00
Haroon Qureshi 465e574c42 Test scene for shape generators.
PiperOrigin-RevId: 913694536
Change-Id: I49a2a3a4f918f9b80650ce884d3d442581e60d6b
2026-05-11 07:42:56 -07:00
Yuval Tassa ff4a5673f8 Delete testspeed_test.sh
This shell test was extremely slow (taking up to 26 minutes under ASAN). In any case the compilation pipeline takes one kick-the-tires step, so the RecompileCompare test effectively does the same thing.

PiperOrigin-RevId: 913646840
Change-Id: If659705b88d0ac64722f88ddf2ae377932e5ef0f
2026-05-11 05:25:59 -07:00
Copybara-Service 044f294c7c Merge pull request #3243 from thowell:readthedocs
PiperOrigin-RevId: 913616905
Change-Id: I41452fc8823b96c8d15b8909b17fb13e69bf1f15
2026-05-11 03:54:33 -07:00
Michael Moss 28548ce51c Update MuJoCo version to 3.9.0 following the 3.8.1 release
PiperOrigin-RevId: 913596257
Change-Id: Ib8b27fd2224e38560a209054c1d508a9bba21bbf
2026-05-11 02:58:56 -07:00
Alessio Quaglino df59e7d0f1 Fix mj_makeConstraint error for flex trilinear vs trilinear contacts.
The coordinates for flex interpolation are now computed using the absolute values of the vertex weights. The sign of the first vertex weight is then applied to the resulting barycentric weights. This correctly handles cases where the flex is both the first and the second entity in the contact pair.

PiperOrigin-RevId: 913590928
Change-Id: I970b35fba3d209e13b5b33bb5f945e3c6a43d487
2026-05-11 02:45:27 -07:00
Michael Moss 688209574d Update changelog for the 3.8.1 release.
PiperOrigin-RevId: 913578392
Change-Id: I7367ff9044fd52039cec8dd492b37df2153a6d7f
2026-05-11 02:14:58 -07:00
Alessio Quaglino 5ee8bd7b9c Rotate undeformed normals before using them in the bending passive forces.
The normal jump residual in flex elasticity calculations now rotates the rest-frame normal jump into the current frame using the face's corotational quaternion before subtracting the jump from the current normal difference.

PiperOrigin-RevId: 913242127
Change-Id: Ia62b28ecccd59e79225737d8225ef4131b333c96
2026-05-10 03:00:11 -07:00
Michael Moss cb5a9caa5c Update dependencies ahead of the 3.8.1 release.
PiperOrigin-RevId: 913212199
Change-Id: I97e5a2367010c492e6277a8c333ae8eb8155f7f2
2026-05-10 00:51:43 -07:00
Haroon Qureshi 4e2064b26f Fix skin/flex rendering by setting size to 1 (not 0).
PiperOrigin-RevId: 912993245
Change-Id: Ib81f58bd8d474decea469cafa40d57f053eee516
2026-05-09 08:39:14 -07:00
Haroon Qureshi b9a1fad99b Fix segmentation/depth rendering.
PiperOrigin-RevId: 912674769
Change-Id: Iba525679630e7996bc27d916e61e5a265a147061
2026-05-08 13:40:37 -07:00
Taylor Howell fefbc2c407 mujoco introspect 2026-05-08 20:23:30 +01:00
Alessio Quaglino fa912dffa0 Add flex arrays to CompareModel check.
Due to a bug, all flex mjModel fields were previously ignored.

PiperOrigin-RevId: 912546202
Change-Id: Ica95ecfcbbe366fd81de6e8f7d83ed57a7d23033
2026-05-08 08:47:51 -07:00
Alessio Quaglino 8cef5bb978 Add configurable octree max depth for meshes.
The maximum depth of the octree used for SDF generation can now be specified in the mesh definition via `mjsMesh::octree_maxdepth`. The default value is 6.

PiperOrigin-RevId: 912494999
Change-Id: I6d828d1d3999b99d1210a6829a05b04fac591e1f
2026-05-08 06:35:45 -07:00
Yuval Tassa 531a571dda studio: replace separate Solver and Performance charts with a unified Profiler, bound to F3
Combines the "Solver" and "Performance" chart windows into a single "Profiler" window for better ergonomics and visual layout:
- Unified Dashboard: Groups the Solver block (Counts & Convergence) and the Performance block (Dimensions & CPU Time) in a single viewable window that scales cleanly without vertical scrollbars.
- Adaptive Stacking: Uses ImGui grouping so each block internally stacks its charts vertically, but tiles side-by-side horizontally when the window is stretched wide.
- Default Docking & Width: Integrates the Profiler into the default dockspace layout attached to the right of the main viewable area, with an optimized initial width scaling factor of 0.42.
- Shortcut and Menus: Adds a toggle shortcut bound to `F3`, updates the Help Shortcuts overlay, and replaces old separate entries in the Charts menu.

PiperOrigin-RevId: 912491435
Change-Id: I1f9215e5498866a01ce48b6aeb4a7461191fa01d
2026-05-08 06:25:31 -07:00
Haroon Qureshi 395a002801 Small usability fixes.
- allow reloading of files that failed to load
- clear errors on successful reload

PiperOrigin-RevId: 912458744
Change-Id: Ie6af87508f10e83461bc998c99c9c66e2d58312e
2026-05-08 04:50:13 -07:00
Yuval Tassa 2ad01960c6 Studio UI tweaks
- RHS: Make Inspector be focused by default.
- RHS: Remove Noise pane, put the functionality in the Controls pane.
- Improve Frame and Label dropdowns.

PiperOrigin-RevId: 912434712
Change-Id: I2ee5b647febfc4a90a0cf9387b1d416f5a0dd4a1
2026-05-08 03:33:16 -07:00
Michael Moss 3ef083eecc Allow the Studio build script to be run outside the git checkout.
PiperOrigin-RevId: 912421771
Change-Id: Ie355d2f59cd43166ab06aa49349d87a0f5f9151c
2026-05-08 02:51:53 -07:00
Sam Haves b7b96d2acc Remove explicit mjz linking from studio.
PiperOrigin-RevId: 912157162
Change-Id: Ie5a229836cfe2c4af1b2f3cc9de9f03623b5d815
2026-05-07 14:35:18 -07:00
Sam Haves f4ab9aa93d Make miniz a PRIVATE dependency of mujoco in CMake.
PiperOrigin-RevId: 912068267
Change-Id: I5d4f3bbd294c6d4fcc519ae4f36f13005d51f9b7
2026-05-07 11:33:18 -07:00
Sam Haves 3e960ba3d3 Fix mjcPhysics doc link in changelog.
PiperOrigin-RevId: 912053636
Change-Id: Ie711995e171ae9dc97766a82902ba6917b08cd79
2026-05-07 11:07:04 -07:00
Sam Haves eddfbcfc50 Move mjz_decoder out of experimental to xml/mjz.
Since the mjz format is just an archive for MJCF assets this seems like a sensible place. The upcoming mjz encoder will also need to make use of the full precision XML utility that is local to src/xml.

PiperOrigin-RevId: 912044746
Change-Id: I6a9fef24b1c3fec5b5edc3a8d4c8e22584273264
2026-05-07 10:52:03 -07:00
Haroon Qureshi 5f36cb9e64 Add/cleanup documentation.
PiperOrigin-RevId: 912014433
Change-Id: I8f05d482e07ed58588f5847d470e5420e5c09f3a
2026-05-07 09:52:04 -07:00
Haroon Qureshi 730ecceda1 Add SDF support.
PiperOrigin-RevId: 912007379
Change-Id: I89ebf6bbabca08656932d028b27f1fbe48178986
2026-05-07 09:37:18 -07:00
Haroon Qureshi abea65b0be Simplify materials.
Merge shading model, material params, and material textures into a
single "mjrMaterial" type.

Remove redundant decor_line material.

PiperOrigin-RevId: 911960222
Change-Id: Icce3772a8ea48467dfd610799c0c2f2ba752323e
2026-05-07 07:51:15 -07:00
Haroon Qureshi d5c5a989f2 Use viewport instead of width/height.
PiperOrigin-RevId: 911942457
Change-Id: I2d6d52a8bb6b1b10d69956cce9e5d7f62e7d1f1c
2026-05-07 07:06:35 -07:00
Sam Haves ec50260e26 Add mjs_getOriginSpec to retrieve the original spec of an element.
The new function mjs_getOriginSpec returns the mjSpec that was used to define a given mjsElement. Unlike mjs_getSpec, this value remains constant even after the element has been attached to a different model.

PiperOrigin-RevId: 911930951
Change-Id: Ia9cd79d9dfabc513d6121eadcffc5d41075224c9
2026-05-07 06:33:28 -07:00
Haroon Qureshi 8b06fe4c16 Remove invalid dlfcn.h include.
PiperOrigin-RevId: 911924226
Change-Id: Id5c05745ee8dbdd4e5518e8c6ff5feb0b9972bb5
2026-05-07 06:13:08 -07:00
Haroon Qureshi 364c716f08 Rename TextureTarget to SamplerType.
PiperOrigin-RevId: 911918372
Change-Id: If711d5909499b68316acd10a2de3a2d83436e18d
2026-05-07 05:56:07 -07:00
Haroon Qureshi 75f1b81df7 Missing file in CMakeLists.txt
PiperOrigin-RevId: 911913781
Change-Id: I080298ff26fa2d7a3646f80ed15396bbe868c76b
2026-05-07 05:42:52 -07:00
Sam Haves 034167f4cd Fix MjVfs changelog item accidentally placed in last release
PiperOrigin-RevId: 911908806
Change-Id: I44514152c2084ca39d8ef218d9f00de66448c3ac
2026-05-07 05:28:29 -07:00
Haroon Qureshi f2da6cabdf Add API function for querying frame stats.
Replaces the current GetFrameRate function.

PiperOrigin-RevId: 911897360
Change-Id: I4199ba9ce40d1d8bc37b551fa7058d964186641d
2026-05-07 04:57:30 -07:00
Haroon Qureshi e1b27afcda Merge math_util and model_util and rename to filament_util.
Move filament_util to the main folder so as to indicate that
these utilities can be used by anyone and aren't internal to
the filament renderer implementation.

PiperOrigin-RevId: 911884375
Change-Id: Ieb58184263bdac7e44a07f1e44a4649c68c6bf77
2026-05-07 04:20:28 -07:00
Haroon Qureshi 7ade42ca88 Internal changes.
PiperOrigin-RevId: 911871922
Change-Id: I82452ffb4c96dca0206d2284193e0756e3dc830e
2026-05-07 03:49:14 -07:00
Haroon Qureshi 607970a900 Remove dependency between SceneBridge and ObjectManager.
PiperOrigin-RevId: 911824153
Change-Id: Ie87d6d9e77b0b3f68a41a0c7d13a36fb2029e4c2
2026-05-07 01:55:52 -07:00
Haroon Qureshi 8e214e5133 Move imgui_editor into filament library.
PiperOrigin-RevId: 911808107
Change-Id: I14318b1c7396e2eaf0df9d6afcc5298de01bcfa4
2026-05-07 01:19:30 -07:00
Haroon Qureshi 39c891e358 Add function for creating Renderable meshes from mjtGeom types.
The Renderable class now internally knows which built-in meshes
to use for a given geom type. It gets these meshes from the
ObjectManager which now stores the collection of built-ins based
on the nstack/nslice/nquad quality arguments.

PiperOrigin-RevId: 911782530
Change-Id: I6698ec3964a5c657f6a9495809cc795eec2e346f
2026-05-07 00:13:01 -07:00
Alessio Quaglino 0c05215e18 Reduce flex stiffness and bending memory size to the exact amount needed.
PiperOrigin-RevId: 911774147
Change-Id: I3b18eba23e75ec91ece8342945f25e0cd7c63a1a
2026-05-06 23:53:19 -07:00
Haroon Qureshi b6aac76cc4 Pass filament::Engine instead of FilamentContext
for textures, meshes, and render targets.

PiperOrigin-RevId: 911770834
Change-Id: I081458e118f0e91091d6d4df7b760e9dbb321672
2026-05-06 23:44:39 -07:00
Yuval Tassa 0f53f55853 Add checks for degenerate meshes in convex hull computation.
Fixes #3260

PiperOrigin-RevId: 911610731
Change-Id: I9efd15eee1bb5cb13639fd733a49535a147c3401
2026-05-06 16:25:13 -07:00
Sam Haves a501731089 Update multiccd default in mjcPhysics.
PiperOrigin-RevId: 911410939
Change-Id: Ia20b5be87f85c4662b71994dd824d90c6b98b3ed
2026-05-06 10:21:48 -07:00
Haroon Qureshi 2aa2131057 Refactor how render requests are generated.
Get the camera and drawmode from the bridges rather than recalculating
it unecessarily.

PiperOrigin-RevId: 911406470
Change-Id: Ia295846bb80105a2b0ad5da21912ca82b25e04bd
2026-05-06 10:13:37 -07:00
Haroon Qureshi 2b67fe3c3a Remove direct dependency between SceneBridge and ImguiBridge.
PiperOrigin-RevId: 911366540
Change-Id: I05c348ea6b1d08c034f2bb26e4c770079073c61d
2026-05-06 08:57:23 -07:00
dependabot[bot] 6b898395f1 Bump pip from 25.2 to 26.1 in /mjx
Bumps [pip](https://github.com/pypa/pip) from 25.2 to 26.1.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/25.2...26.1)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: '26.1'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-06 15:52:40 +00:00
Taylor Howell 9ffd50ce6a Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 911361969
Change-Id: I2dd1223a4279b3df2f11adc4f44778b8d153e599
2026-05-06 08:47:54 -07:00
Yuval Tassa 6376e67070 Extract AVX code from engine_util_blas.c into engine_util_blas_avx.h
PiperOrigin-RevId: 911274884
Change-Id: Iaac2789f9538f669c49b497d1e60947a783368d3
2026-05-06 05:25:53 -07:00
Sam Haves 579a27e9d2 Make mjSpec related getter/find utilities take const parameters.
PiperOrigin-RevId: 910848529
Change-Id: I1c966a6299fe47317cbf0bfb8f8b835cbcd4ed65
2026-05-05 12:35:56 -07:00
Alessio Quaglino d249c882d5 Fix gcc errors due to restrict.
PiperOrigin-RevId: 910814591
Change-Id: I6858b1a36e21c6d47df803f49ceaed62c8e56248
2026-05-05 11:38:55 -07:00
Yuval Tassa 5c156ebf15 Refactor sparse constraint Jacobian supernode computation.
- Compute efc_J_rowsuper incrementally in mj_addConstraint instead of post-hoc via mju_superSparse.
- Better exploitation of supernodes in A matrix pipeline: precount and fill skip redundant chain traversals for supernode rows.
- Redundant B_rowsuper computation via mju_superSparse is eliminated (indentical to efc_J_rowsuper).

PiperOrigin-RevId: 910787825
Change-Id: I6eda9996659602b7051ee1090aeedb862603c84e
2026-05-05 10:57:31 -07:00
Alessio Quaglino d933b195ee Implement bending forces for interpolated flex shells.
This change adds a new passive force computation for flexes with elastic2d="bend" and dof="trilinear". The bending energy is based on the squared difference of normals between adjacent face elements at their shared edge midpoint. The edge data is precomputed during model compilation and stored in flex_bending.

PiperOrigin-RevId: 910772638
Change-Id: I3b12c7b7f1ba6ac1875df495d89e8cfec921ca80
2026-05-05 10:33:18 -07:00
Haroon Qureshi a692283db3 Add functions to create context and render.
Rename mjrf_render to mjrf_renderScene to avoid naming collision.
This function is will be removed in a future CL.

PiperOrigin-RevId: 910764245
Change-Id: If4d05e806a9699570ca4bbc882f28bfdd05dbd8d
2026-05-05 10:20:04 -07:00
Yuval Tassa 9f972aa42e Use cinematic cameras by default in cards.xml and leaves.xml
PiperOrigin-RevId: 910687282
Change-Id: I382c06f36d79fdd36a8299c36460ca74cf277aae
2026-05-05 07:54:23 -07:00
Haroon Qureshi 24ce1eff10 Update compat library to use public functions.
There are still a few places where the compat library is downcasting
to the internal types due to limitations in the public APIs.

PiperOrigin-RevId: 910646480
Change-Id: I1ccb6714db08a2010d9535f59338e5eba06d1d35
2026-05-05 06:33:04 -07:00
Alessio Quaglino b9c1877ecb Project out rigid body modes from flex strain equality constraints.
Modify EigendecomposeStiffness to project out rigid body translations and rotations from the stiffness matrix eigenvectors. This prevents "ghost damping" from rigid body modes being incorrectly constrained. Update hollow_vs_solid.xml with solimp parameters for edge constraints. Adjust engine_core_constraint_test.cc to reflect the reduced number of equality constraints due to the projection.

PiperOrigin-RevId: 910631207
Change-Id: Ibaaa59bc030cfc6ae657d8f0d1b2a51002cc8d4e
2026-05-05 06:01:15 -07:00
Haroon Qureshi d168eb2d7d Expose several functions in the public C API.
PiperOrigin-RevId: 910629209
Change-Id: I8623309e348c72350703f6874a887592f0607bba
2026-05-05 05:56:02 -07:00
Yuval Tassa 4ed69b5ce7 Randomize PGS constraint visitation order.
Total testspeed runtime for `2humanoids100.xml` reduced by 19.6% (49.5 -> 39.8s).

PiperOrigin-RevId: 910608140
Change-Id: Ided0ae5bdb8e4e8196f84e08354a9ae8cfa5b626
2026-05-05 05:10:26 -07:00
Haroon Qureshi 88bff84cbb Add API functions for creating and destroying objects.
Also provide a header-only C++ library that wraps created objects into
unique_ptrs.

PiperOrigin-RevId: 910607824
Change-Id: I0427f6dedab6aa299b3128031b055bd4d0c8e497
2026-05-05 05:08:25 -07:00
Haroon Qureshi de030f4664 Allow SceneView to read configuration from mjModel directly.
PiperOrigin-RevId: 910548865
Change-Id: I4db045e76cd36012810c75b9d150c6c5f5746488
2026-05-05 02:52:18 -07:00
Haroon Qureshi 68fdc439e4 Use mjrTextureTarget type instead of filament type.
PiperOrigin-RevId: 910547104
Change-Id: I3e8aa30a72b9b5ec8c45e8fa6bac18353ce7b485
2026-05-05 02:47:53 -07:00
Yuval Tassa a5de6506eb Add backlinks from tech note to dcmotor docs.
PiperOrigin-RevId: 910543352
Change-Id: I171c34a793f23b09feeb46ab7b02ebe7900902ba
2026-05-05 02:38:38 -07:00
Copybara-Service bc8c1f826c Merge pull request #3235 from tkelestemur:mjx-warp-segmentation
PiperOrigin-RevId: 910401768
Change-Id: I015bd05d9d823db5efb92f660c707a67ddca6591
2026-05-04 20:42:32 -07:00
Yuval Tassa 767c607f58 Add mju_sym2dense, document future breakage of mj_fullM
PiperOrigin-RevId: 910242375
Change-Id: Ibfbdef9cfb66088723499ea257da09aee0d80938
2026-05-04 14:25:53 -07:00
Baruch Tabanpour a51a7bf062 Open-source MJX-Warp codegen to make external contribution easier.
PiperOrigin-RevId: 910200635
Change-Id: I0218f8e281413803500c98fc29d0589c4e90d6b1
2026-05-04 13:14:28 -07:00
Taylor Howell 0aeea2e4f6 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 910110405
Change-Id: Ia20c749e07b0d92613948313d38161e9f9a074b9
2026-05-04 10:33:21 -07:00
Yuval Tassa 25751a7b98 Add dense LU factorization and solve functions.
PiperOrigin-RevId: 909290647
Change-Id: I77ae2352b20abf96ef7b48ae32b03a1f4098604e
2026-05-02 13:27:04 -07:00
Alessio Quaglino dbd451138c Add flex_bendingadr to mjModel.
PiperOrigin-RevId: 909088123
Change-Id: If062335d0aa3702c1e0b082dd9e29c3be0e76ea6
2026-05-02 00:13:39 -07:00
Alessio Quaglino b2feed63e4 Skip implicit solver if there are strain constraints.
PiperOrigin-RevId: 908890994
Change-Id: Ieb05a162142edac14269ec6a509fc507c9146ac5
2026-05-01 14:10:00 -07:00
Sam Haves 723b8b1ea6 Introduce explicit VFS in Python MjVfs
This change introduces MjVFS, an explicit object to mirror the C mjVFS. This is meant to replace the MjSpec.assets dict. This latter while convenient guides users towards harmful authoring patterns with respect to data duplication and spec attachment workflows. Making VFS management explicit should encourage better memory usage and allow us to make better compile time optimizations.

From this change, `spec.assets` is deprecated. However we will temporarily support backwards compatibility due to the wide spread usage. An error will be thrown if calling code tries to use a spec that uses both the assets dict and the new MjVfs.

PiperOrigin-RevId: 908772050
Change-Id: I77c6d0369307fc300c954768fed17401261e18da
2026-05-01 09:34:17 -07:00
Yuval Tassa 910b3336ed Restrict midpoint integration to unconstrained free bodies in implicitfast
PiperOrigin-RevId: 908750768
Change-Id: I9a45a160ac757cc82bfe54871609956769988369
2026-05-01 08:41:47 -07:00
Alessio Quaglino 8287d9d152 Fix insidesite sensor for massless flex parent bodies.
mjSENS_INSIDESITE uses xipos to test containment, but for massless flex
parent bodies xipos equals the static body frame origin and does not
track the actual flex position.

Fix: in the INSIDESITE sensor case, when the object is a massless body
with positive subtree mass (i.e., a flex parent), use subtree_com
instead of xipos. This correctly reflects the mass-weighted centroid of
the flex child bodies without changing the global semantics of xipos.
PiperOrigin-RevId: 908745144
Change-Id: I527f0efb7b419345188411c9da883505156ebeea
2026-05-01 08:27:04 -07:00
Yuval Tassa f7d31e06f0 Refactor utility functions for block extraction.
PiperOrigin-RevId: 908744392
Change-Id: I8d1323946870c90d5e37b1853697fb35d5291e11
2026-05-01 08:24:38 -07:00
Copybara-Service 3367b64a8e Merge pull request #3225 from devshahofficial:fix/renderer-del-init-failure
PiperOrigin-RevId: 908640282
Change-Id: I4f474423f94ec785598ed9c2d5b74eba3d927697
2026-05-01 03:17:02 -07:00
Haroon Qureshi ee3ac5b349 Expose Renderable settings in mjrRenderableParams.
PiperOrigin-RevId: 908587103
Change-Id: Ic0e19a7fb3535bf32782b85d2da0049ec4ac8ec7
2026-05-01 00:19:28 -07:00
Haroon Qureshi 0399bfd058 Allow custom getProcAddress for glad resolution.
PiperOrigin-RevId: 908587023
Change-Id: Idc4dcc5ee8d2d67f83486ca2ff4667f2b4b283eb
2026-05-01 00:18:26 -07:00
Alessio Quaglino 7d54123303 Make flex vert0 rotation-invariant for interpolated flexes.
The `vert0` array, used for parametric vertex coordinates in flexes, is now computed in the flex's local, unrotated frame when using interpolation. This ensures that the parametric coordinates are independent of the flex's initial orientation. A new test confirms that `flex_vert0` is identical for an unrotated and a rotated flex grid.

PiperOrigin-RevId: 908196464
Change-Id: I47d6bcc2bc5df581479d485480e0e947ec6d3ffd
2026-04-30 08:41:01 -07:00
Yuval Tassa 22ca5fe0df studio: improve behavior of help window
PiperOrigin-RevId: 908132295
Change-Id: Iac0aead82a575dffbe35e3be8ba06af13986d1a2
2026-04-30 06:21:10 -07:00
Alessio Quaglino e71bd3db8e Refactor flex passive forces into dedicated functions.
The code for computing passive forces for flex elements is moved into new static functions `mj_flexPassiveInterp`, `mj_flexPassiveBend`, and `mj_flexPassiveStretch`. This improves the structure of `mj_springdamper`.

PiperOrigin-RevId: 907671516
Change-Id: I6d1e781bbd370331ae645a954b78092ecb1925b9
2026-04-29 10:50:54 -07:00
Sam Haves e552a5f80d Expose more filament render settings via XML custom fields
PiperOrigin-RevId: 907659170
Change-Id: I0d8ca1ec058d40ed072db09c370f48b1e79ca6b3
2026-04-29 10:26:51 -07:00
Alessio Quaglino 9c6a4f76eb Add 2D membrane elasticity for interpolated flex shell mode
When elastic2d="stretch" is set on an interpolated flexcomp, treat the bounding box boundary as membrane elements rather than volumetric cells. This computes plane-stress stiffness over the boundary faces and updates the runtime force/derivative kernels accordingly.

Interior vertex tracking (moving vertices that follow the deforming shell) is not yet implemented so all mesh vertices need to be on the bounding box surface or the background grid should have no interior nodes (i.e. cellcount should be 1 on at least one axis).

PiperOrigin-RevId: 907654080
Change-Id: I51b90e2f6a1d1b036f9604e42de20e377dc5d3f9
2026-04-29 10:17:21 -07:00
Sam Haves 517c113656 Add Rendering differences section to MjWarp documentation.
PiperOrigin-RevId: 907644012
Change-Id: I6d79792e4cb4088a89cb3f995f3bddf9b0aada15
2026-04-29 09:58:14 -07:00
Yuval Tassa cae70086da Scale UI style sizes by DPI.
PiperOrigin-RevId: 907630627
Change-Id: Ia6dc35ce00e9764a454f4021250089b0d9a94073
2026-04-29 09:31:33 -07:00
Haroon Qureshi 4e7b2f2124 Allow dimensions to be specified when creating a render target.
PiperOrigin-RevId: 907622395
Change-Id: I0f806f4d77afa6a178a20d36dae3e96b81359494
2026-04-29 09:14:10 -07:00
Haroon Qureshi 7e848e9406 Add mjr_sceneParams for creating Scene objects.
PiperOrigin-RevId: 907589621
Change-Id: If7537cf6fbac6d6418ac2bf8315714ada969511d
2026-04-29 07:58:42 -07:00
Yuval Tassa 52e90bf55d Fix high-DPI window size in Studio.
PiperOrigin-RevId: 907585586
Change-Id: Ie7db20f5242d89926a4a34ffed3a6e39698defd3
2026-04-29 07:48:12 -07:00
Sam Haves a2cd7aa52f Make mjz_decoder threadsafe.
PiperOrigin-RevId: 907574530
Change-Id: Ie292ff10dfa515e4ddc9dad1459e44c3ba9eeabe
2026-04-29 07:19:13 -07:00
Haroon Qureshi e745538ad6 Use FilamentContext for creating objects (instead of filament::Engine).
PiperOrigin-RevId: 907568857
Change-Id: If7b1b55bac9ef56dde43dc56b45c2c1034149dac
2026-04-29 07:04:46 -07:00
Tarik Kelestemur 5a51f4795d Merge branch 'google-deepmind:main' into mjx-warp-segmentation 2026-04-29 09:28:08 -04:00
Yuval Tassa 9796345888 Add font scaling to studio, bound to CTRL+MINUS/PLUS
PiperOrigin-RevId: 907491215
Change-Id: I144467c3ff0e3d11f4a5bfb6ed2b1e4e88b8693d
2026-04-29 03:42:07 -07:00
Sam Haves d92fe0810c Add MjSpec.encode method.
PiperOrigin-RevId: 907177387
Change-Id: I65800298798037c4a0c0cd79ec86706be67db51e
2026-04-28 14:22:41 -07:00
Haroon Qureshi ace90c00b9 Remove deleted file.
PiperOrigin-RevId: 906944517
Change-Id: I8471d1014888cc03632df631b47080618694f4a4
2026-04-28 06:34:47 -07:00
Haroon Qureshi 5751b09ff6 Initial pass at exposing the new mjr APIs.
Moves all internal types and structs to the "public"
render_context_filament.h header file.

PiperOrigin-RevId: 906929736
Change-Id: I7e7c315fb99a3601b09841073eaeec795718b999
2026-04-28 06:00:03 -07:00
Yuval Tassa 647af382c1 Add per-island PGS solver dispatch.
Total testspeed runtime for `2humanoids100.xml` reduced by 27.6% (63.4 -> 49.5s) due to early termination on small islands

PiperOrigin-RevId: 906910915
Change-Id: If55ad468c3680ef44eda7000455a77f8003b3122
2026-04-28 05:13:54 -07:00
Haroon Qureshi 00fff8c780 Update APIs to use opaque handle types instead of concrete types.
PiperOrigin-RevId: 906895053
Change-Id: Id61d437ea814e038f25d92375eb747a6c6775c32
2026-04-28 04:40:46 -07:00
Haroon Qureshi 32aeb377b5 Move filament::Skybox object management into SceneView.
ModelObjects no longer directly manages any filament objects.

PiperOrigin-RevId: 906873925
Change-Id: Iaa317cbeb9c5236745a5f0d04a740985bec54a5c
2026-04-28 03:56:01 -07:00
Yuval Tassa 6f275b79c6 Studio: toolbar cosmetic improvements
- Remove hard-coded button sizes (48×32) from toolbar icons; buttons now use default ImGui sizing, matching the existing copy-camera button.
- Remove the Unload button (available via menu).
- Add ImGui_ColorButtonEx widget with per-corner rounding via ImDrawFlags, enabling segmented button-group visuals.
- Use segmented rounding for the pause/viscous/play triplet: rounded-left, square, rounded-right.
- Make pause and play buttons 40% wider than the viscous button for emphasis.
- Replace the theme combo dropdown with a cycling button.
- Reduce toolbar height from 48px to 34px and vertically center content via WindowPadding.
- Zero out table CellPadding in the toolbar for precise vertical centering.
- Remove the speed combo's inflated vertical padding.

PiperOrigin-RevId: 906853958
Change-Id: I6e4ec7243adb9e0f1f06f8779fa896a6865c46c7
2026-04-28 03:12:55 -07:00
Yuval Tassa 25a9114705 No-op refactor of PGS and NoSlip solvers in preparation for island support.
PiperOrigin-RevId: 906826882
Change-Id: I2003097e1bb81ebabda3a7075f1f8200d4d5ff95
2026-04-28 02:11:30 -07:00
Alessio Quaglino e6354b4368 Add flex_interp to the MJX Model.
PiperOrigin-RevId: 906518134
Change-Id: If716e7e67827a6659fb72a6064809910fe99944f
2026-04-27 13:33:17 -07:00
Matija Kecman 9cd89eec2f Make Studio's monitoring charts responsive and full-window
* **Dynamic Full-Window Scaling**: Charts in the Performance and Solver panels now expand to fill the entire pane, automatically arranging side-by-side or stacked based on window orientation to eliminate scrollbars.

  * **Responsive Decorators**: Added reusable C++ ImPlot helper functions that auto-hide titles, legends, and tick labels when the plot surface is small.

  * **Cleaner Visualization**: Refined chart titles (e.g., "CPU msec vs frame", "Convergence vs iter") and removed redundant axis labels for improved scannability.

These changes were based on the plot behavior of //third_party/mujoco/src/experimental/py/sample/implot.py This is an incremental improvement, we can make the plots even nicer in future.

PiperOrigin-RevId: 906351914
Change-Id: I8cb19c19bf807f0107c717066250a71bcf7e325f
2026-04-27 07:42:56 -07:00
Yuval Tassa 2e3205229c Studio: various panel usability improvements
- Reorder Physics section, move Actuator Groups to end.
- Rename "Physics Settings" → "Physics", "Rendering Settings" → "Rendering".
- Reduce IndentSpacing from 20 to 6.
- Reduce FramePadding Y from 6 to 2 for narrower buttons and popups.
- Remove explicit Unindent/Indent overrides in Rendering and Visibility Groups
  sections so buttons are naturally indented under their tree nodes.
- Dynamically adjust convergence and counts plot X-axis limits based on actual
  solver iterations instead of hardcoded 20.

PiperOrigin-RevId: 906244477
Change-Id: Ic3e6e6e793395158c8cb6692af885884ca3f7f50
2026-04-27 03:11:51 -07:00
Matija Kecman 3a5a48b9f9 Fix texture ID collisions in ImguiBridge
Texture IDs were assigned using textures_.size() + 1, which is not monotonic: after erasures the map shrinks and previously used IDs can be reassigned to new textures. This causes multiple ImGui images to reference the same underlying Filament texture, rendering them all with the same pixel data. This fix replaces the size-based scheme with a monotonically increasing counter (next_tex_id_) that never reuses IDs.

PiperOrigin-RevId: 906214496
Change-Id: I5a388861ad9565c8e00e27b39cc9c76c9750ca1e
2026-04-27 01:59:28 -07:00
Tarik Kelestemur 1009478de9 Merge branch 'google-deepmind:main' into mjx-warp-segmentation 2026-04-26 21:36:32 -04:00
Haroon Qureshi b643f50b2a Rename IndexType USHORT/UINT to U16/U32.
PiperOrigin-RevId: 906026433
Change-Id: I0016c1923560fc8517e5388ed6068d54b84d5923
2026-04-26 14:55:55 -07:00
Google DeepMind 521d152ec5 Enable Warp execution on CPU devices in MJX.
This change modifies the Warp JAX FFI to register callbacks for both CUDA and CPU platforms, allowing Warp kernels to be launched on CPU devices. MJX's io.py is updated to allow Warp to use CPU devices if no CUDA GPU is available. Tests are adjusted to no longer skip when CUDA GPUs are absent. A minor fix for sorting precision in test_util.py is also included.

Kristian Hartikainen
 - https://github.com/google-deepmind/mujoco/pull/2948

Github issue - https://github.com/google-deepmind/mujoco/issues/2947

PiperOrigin-RevId: 906018844
Change-Id: I9c026b4a4e2a0276d5d3af3954fd027cf75b6d7a
2026-04-26 14:19:34 -07:00
Haroon Qureshi 8f32f6e72e Rename enum values to match type name.
PiperOrigin-RevId: 906014884
Change-Id: I0f37ab0a0a910724723fb9f7e477b64643ca05fc
2026-04-26 14:03:59 -07:00
Haroon Qureshi 2fa2db7ae0 Re-enable spotlights in wasm builds.
PiperOrigin-RevId: 905917482
Change-Id: Iaadd2b2ccf3be91ec2edfb8ecfd40db32909dd4e
2026-04-26 07:34:17 -07:00
Matija Kecman 82eab11a88 Remove deprecated Fonts->Build() and clean up ImGui texture lifecycle
* Remove the explicit io.Fonts->Build() call from InitImGui, which was deprecated in Dear ImGui v1.92.0. With ImGuiBackendFlags_RendererHasTextures already set, the font atlas is now built lazily by ImGui and communicated to backends via the ImTextureStatus_WantCreate protocol.

* Add proper texture shutdown in ~ImguiBridge by iterating ImGui::GetPlatformIO().Textures and destroying all tracked textures, per the //third_party/dear_imgui/docs/BACKENDS.md instructions.

* Remove the "OK but missing" and "WantUpdates but missing" texture recovery hacks from Update(). These handled a state where ImGui thought textures were alive but the Filament-side storage had been torn down. With proper destruction acknowledgement (SetStatus(Destroyed) + SetTexID(Invalid)), ImGui will now transition destroyed textures to WantCreate on the next frame, and the normal creation path handles it cleanly.

PiperOrigin-RevId: 905886622
Change-Id: Ic449eeaf083740a67eae9c637fb53546a6192b28
2026-04-26 05:19:26 -07:00
Yuval Tassa 2f2d00daed Fix issues in changelog.
PiperOrigin-RevId: 905663581
Change-Id: Ic5146db3282e303b2a5676e77e27dea3100bf072
2026-04-25 15:00:35 -07:00
Haroon Qureshi 4eb987ad25 Fix uninitialized value.
PiperOrigin-RevId: 905169930
Change-Id: I8df07e8731e8eb1847bc43388f26654d28bcef4c
2026-04-24 12:37:48 -07:00
dependabot[bot] 3050493dab Bump postcss from 8.5.6 to 8.5.10 in /wasm
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.6 to 8.5.10.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.10)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-24 17:40:45 +00:00
Michael Moss 2b7cc28afa Update MuJoCo version to 3.8.1 following the 3.8.0 release
PiperOrigin-RevId: 905108575
Change-Id: Ief1f9c6f34559e7a5ccc60dcceec589316bcdf9e
2026-04-24 10:37:50 -07:00
Michael Moss 34d69ad4cb Update changelog for the 3.8.0 release.
PiperOrigin-RevId: 905086535
Change-Id: Id5b32348465b9fa756a8d60234f5c300ded7a27b
2026-04-24 09:56:24 -07:00
Michael Moss 2f5e5d3da1 Add documentation for mjpDecoder.
PiperOrigin-RevId: 905048609
Change-Id: I6342673cdc53b80406ad77fc95cb8bb5790a5df6
2026-04-24 08:38:31 -07:00
Haroon Qureshi a2ee85f477 Fix wasm flickering.
Always execute the engine in non-threading (wasm) builds.
And stop rendering if any beginFrame call returns false.

PiperOrigin-RevId: 905000139
Change-Id: I0a6f06a07a8fc0ab0251a67be13a9d170d4a905d
2026-04-24 06:42:38 -07:00
Michael Moss a04cf1b2b3 Mention Python 3.14 in the changelog.
PiperOrigin-RevId: 904898900
Change-Id: I5ba3d619b496cd038f8614df924fe9cec38b56f9
2026-04-24 02:26:48 -07:00
Saran Tunyasuvunakool 1465d8b6ce Initial implementation of MuJoCo Live.
This is a combination of minor tweaks to the existing Studio WASM application, CMake cleanup to make it buildable, and integration with GitHub Actions for deployment.

The new features added are drag-and-drop, model specification through `?model=` URL parameter, HTTP and HTTPS resource provider, and a user-visible loading message while the model is loading.

PiperOrigin-RevId: 904594610
Change-Id: I3a73b1ca0fcd6fc9ba192469942b2dab010a9308
2026-04-23 12:56:12 -07:00
Alessio Quaglino 4eba85093a Add new flex_node fields to MJX.
PiperOrigin-RevId: 904576383
Change-Id: Ie0cb8e0f25bdeadbecc2ea229835b0f2a2957254
2026-04-23 12:16:09 -07:00
Taylor Howell f0b6120771 update .readthedocs.yml 2026-04-23 19:52:55 +01:00
Haroon Qureshi c52d3d0789 Split out the compatibility classes from the filament renderer.
The filament library provides APIs for creating the low-level
objects such as meshes and textures. The compat library provides
the high-level compatibility layer between mjvScene and the core
library.

PiperOrigin-RevId: 904504900
Change-Id: Ida1aecab4b9a8aefbbf6b0a0c4ba7ff164864b8e
2026-04-23 09:52:45 -07:00
Michael Moss 15f61679bf Update next MuJoCo version to 3.8.0 for pending breaking changes.
PiperOrigin-RevId: 904496070
Change-Id: I0b8b01cbcf27f28ac80dbc283bc63090f745f403
2026-04-23 09:33:15 -07:00
Michael Moss e5a38431af Update dependencies ahead of the 3.8.0 release.
PiperOrigin-RevId: 904477783
Change-Id: I58a9749d16241fb37c0fbb848fcaf383b28a658d
2026-04-23 08:46:16 -07:00
Matija Kecman 2b211e1ce6 Detect wayland sessions and report a clear error prompting users to switch to X11 or choose a different graphics mode
PiperOrigin-RevId: 904460146
Change-Id: I9324f403cb09787833c06f863ac157059eea60e7
2026-04-23 08:02:29 -07:00
Haroon Qureshi 8a87a1efbf Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904459745
Change-Id: I9369bec34e72dc973df45f844fcf1a6cb08b26b1
2026-04-23 08:01:46 -07:00
Haroon Qureshi 2bc97d8408 Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904458866
Change-Id: Id9ca27b698e0e40469524ba4454ab9721a65e785
2026-04-23 07:59:19 -07:00
Haroon Qureshi ead7b1f65e Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904457841
Change-Id: I023ffe87eee0a190006dea72ced8748725490098
2026-04-23 07:56:27 -07:00
Haroon Qureshi 3d13d43c9c Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904456797
Change-Id: I759b1430a43c7072ed9750d084679d02f0c9cb6e
2026-04-23 07:53:34 -07:00
Haroon Qureshi 4345a2a09f Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904440645
Change-Id: I0b9a0c6bd61170ace1a3ea7fb54fb70b615c346b
2026-04-23 07:14:46 -07:00
Haroon Qureshi c1c7643fad Rename types to conform to mjr naming conventions.
PiperOrigin-RevId: 904438811
Change-Id: I77fe14592a4460234e0aff473ee3f530e652bca9
2026-04-23 07:13:00 -07:00
Haroon Qureshi fa33310750 Fix use-after-release issue.
PiperOrigin-RevId: 904351356
Change-Id: Ie6a574763b2ee0ffc0cf5537d8ccdfe87ab1b477
2026-04-23 03:23:55 -07:00
Haroon Qureshi e1794b3d1c Add missing files.
PiperOrigin-RevId: 904346200
Change-Id: I63f4e8741098d5da9403c05ca13419c670743848
2026-04-23 03:10:54 -07:00
Haroon Qureshi 57ad7463b1 Use separate SceneView for main scene and UX.
Refactor FilamentContext to allow multiple render requests to
be submitted onto a single RenderTarget. The main scene and the
ux scene are then submitted as two separate requests that share
the same target, resulting in a single, composited render.

PiperOrigin-RevId: 904324801
Change-Id: I7c47ec4f8d159320612fa33384c01e8db3414daa
2026-04-23 02:23:23 -07:00
Haroon Qureshi c41ed42407 Split the core filament context from the mjr_ API compatibility layer.
PiperOrigin-RevId: 904305762
Change-Id: I462068a847a21be8ad7f3f1a8889f6b5b2aa2d5f
2026-04-23 01:39:12 -07:00
Michael Moss e8ebc994d2 Add 3.14 to the supported Python versions.
PiperOrigin-RevId: 904301647
Change-Id: I30a75bec09068494be060e6ad046badf968d4241
2026-04-23 01:27:34 -07:00
dependabot[bot] 90da796468 Bump pytest from 8.3.3 to 9.0.3 in /mjx
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.3 to 9.0.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.3...9.0.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-23 08:24:37 +00:00
Michael Moss 4b3f3aee6b Add hashes for 3.14 wheels to Python build requirements.
PiperOrigin-RevId: 904299450
Change-Id: I6ac356d1fa9ae4965bd57d24ae11adac8d875a6c
2026-04-23 01:22:21 -07:00
Tarik Kelestemur 22f4458b1c Merge branch 'google-deepmind:main' into mjx-warp-segmentation 2026-04-22 13:19:55 -04:00
Alessio Quaglino a891782553 Clean-up flex assumptions.
Do not allow a mix of `elastic2d != none` with `dof = trilinear` since the latter assumes 3d elasticity.

Also, do not assume that `flex_interp > 0` in the engine. This will enable to use, e.g., `flex_interp = -1` to mean a linear surface finite element instead of a 3d finite element which is currently identified with `flex_interp = 1`.

PiperOrigin-RevId: 903852035
Change-Id: Ia6290b4a05e9e510ffb7f36d141cd525b40d3110
2026-04-22 08:01:34 -07:00
Matej Aleksandrov 863a084d7f Adjust refcount expectations for Python 3.14
PiperOrigin-RevId: 903813225
Change-Id: Ieb529f2a850e697b643e5023554341c0718ac0e1
2026-04-22 06:33:48 -07:00
Sam Haves 4cfebcc32b Add mj_containsFileVFS and mj_containsBufferVFS functions.
PiperOrigin-RevId: 903785790
Change-Id: I013b37a177284f8440179c4ae5c6221e0f572b49
2026-04-22 05:27:15 -07:00
Taylor Howell c3fddf5dc1 Update doc/mjwarp/update_types.py
PiperOrigin-RevId: 903289569
Change-Id: I7e05736c54fa72dc0c89152f49cf3d9ee6e5492d
2026-04-21 10:03:42 -07:00
Alessio Quaglino ba149aa043 Fix flexcomp strain constraints with rotated grids.
The reference node positions and the positions used for computing stiffness eigenvectors were previously stored in world frame. However, the runtime expects these quantities in the unrotated local frame. This caused non-zero constraint residuals and simulation instability when the grid was rotated — either by the parent body's initial orientation, or by the flexcomp's own frame attributes.

Rather than tracking each rotation source individually, this change extracts the total grid rotation directly from the cell geometry. All node positions are then un-rotated before computing the stiffness matrix.

PiperOrigin-RevId: 903232388
Change-Id: If877af89025ce1e61a76b38c29403d593d892749
2026-04-21 08:02:11 -07:00
Sam Haves da01bd37a2 Remove modelfiledir_ from compiled assets, use owning spec modelfiledir instead.
Previously specs that were attached to some parent spec would resolve its asset paths relative to the modelfiledir of the parent spec. This means path resolution would change depending on the source of the parent spec. Instead, this change makes asset file path resolution relative to the "owning spec" i.e. the spec where the asset was created.

This enables workflows such as loading a parent spec via resource provider, then loading a child spec via `from_zip` or in memory providing `spec.assets` and resolution will work as intended.

PiperOrigin-RevId: 903207910
Change-Id: Ia58020ab372a3ceadf31e804d145e2ae53d8e5f9
2026-04-21 07:00:05 -07:00
Kyle Bayes 3325971840 Add mj_maxContact API function.
PiperOrigin-RevId: 903135055
Change-Id: I5f103c7d51f97e327c923bc567002ace835f5517
2026-04-21 04:03:22 -07:00
Kyle Bayes bc5883e82f Update multiccd documentation.
PiperOrigin-RevId: 902779253
Change-Id: I767cd0a230b78efe2a71f83e5f2f134268997dcb
2026-04-20 12:53:17 -07:00
Kyle Bayes 6cb6e5a93f Enable multiccd by default.
PiperOrigin-RevId: 902752921
Change-Id: I8e2085ff17db0ac0db1641b8837415c458e5eca4
2026-04-20 12:00:10 -07:00
Haroon Qureshi 8e7787ad09 Use function for applying transforms to multimesh Renderables.
PiperOrigin-RevId: 902712241
Change-Id: I5bfdab8bce12ffb1a1f030ae0a32a61e9b8157e1
2026-04-20 10:39:44 -07:00
Alessio Quaglino 188196603d Fix flexcomp empty cell detection that was causing missing cells.
The previous implementation only checked whether grid cells contained mesh vertices to determine occupancy. For coarse meshes with large faces, most cells were incorrectly marked empty and pruned—even cells fully inside the object volume. This change improves the algorithm by:

- Marking cells that overlap with any mesh element's AABB as non-empty.
- For surface meshes, running a flood-fill from the grid boundary through non-overlapping cells to identify truly exterior cells. This preserves empty interior cells, preventing incorrect pruning of the object's core.
- For volumetric meshes, defaulting to element-AABB overlap detection directly.

Limitations for non-watertight meshes: If the mesh contains holes larger than the grid cell size, the flood-fill will leak into the interior. In this case, all non-element cells (including interior ones) will be marked as empty.

PiperOrigin-RevId: 902675331
Change-Id: I5a84303a33d5ca7436213e7ce9aca3806c9f5a0f
2026-04-20 09:27:40 -07:00
Haroon Qureshi 476e2e909e Allow Transforms to be set directly on Renderable.
Also allow multiple Meshes to be assigned at once rather than one at a
time.

This simplifies both the usage and implementation of Renderable.

PiperOrigin-RevId: 902665683
Change-Id: I23ff365a54fd6a3814ed3452b1e094ae9f698a1b
2026-04-20 09:06:14 -07:00
Yuval Tassa b2281883dd Improve slider precision and range clamping, fixes #3206
Add clamping to slider values in both ImGui widgets and mjUI to ensure they remain within the defined min/max ranges, preventing potential floating point inaccuracies from causing values to slightly exceed the bounds.

PiperOrigin-RevId: 902660458
Change-Id: Ia153ae7907f07b890f2b5ac2e3a4be93ecae7bd3
2026-04-20 08:54:11 -07:00
Yuval Tassa a8a5afc8dc Cache benchmark data in engine_util_sparse_benchmark_test
PiperOrigin-RevId: 902651349
Change-Id: I760e3f696b37699366c40c3c93a74e2b1b35678e
2026-04-20 08:29:56 -07:00
Alessio Quaglino 2d12dee025 Add dof="2d" option to flexcomp for in-plane deformations.
PiperOrigin-RevId: 902620719
Change-Id: Ib06d3f7b9439e1d90a8373a4289ade0c327e72e4
2026-04-20 07:14:40 -07:00
Haroon Qureshi cad734ae70 Introduce Trs type.
Combines a translation, rotation, and size into a single struct.

PiperOrigin-RevId: 902620586
Change-Id: I628bfdedebde8c83239215efe0bee4a338eabd06
2026-04-20 07:13:52 -07:00
Alessio Quaglino 35f7db8e91 Add StringToVector<std::string> overload for char*.
This overload allows `StringToVector` to accept a `char*` argument when parsing into a `std::vector<std::string>`, by converting the `char*` to `std::string` before processing.

PiperOrigin-RevId: 902611443
Change-Id: I2048918f915c1bac74522f368ea28f23ca9a6885
2026-04-20 06:48:59 -07:00
Haroon Qureshi 86ad41b9c2 Use RenderableParams for creating Renderables.
PiperOrigin-RevId: 902569516
Change-Id: Id233a5ef7fe86ce5902ce2552d8d0fec6ce860b7
2026-04-20 04:51:18 -07:00
Alessio Quaglino 508e581ba9 Optimize flex by pinning nodes in empty cells.
This change introduces an optimization for flexcomp objects defined by a mesh. It identifies grid cells that do not contain any mesh vertices and marks them as empty. Nodes that are exclusively part of empty cells are pinned, preventing them from moving. Stiffness computations are skipped for empty cells, reducing computational cost. The total mass is now distributed only among the non-pinned nodes.

PiperOrigin-RevId: 902565735
Change-Id: Id0a9a685536d5e18a3e42124a25ab08ff3a918f2
2026-04-20 04:41:17 -07:00
Alessio Quaglino fa7b36d111 Fix undefined reference errors for StringToVector with GCC and LTO.
This CL addresses link failures when building MuJoCo with GCC and Link Time Optimization (LTO) enabled:
- Declared the `StringToVector<std::string>(const std::string&)` specialization in `user_util.h` to prevent the compiler from incorrectly trying to instantiate the general template.
- Added an explicit instantiation for `StringToVector<unsigned char>(char*)` in `user_util.cc` to provide the definition needed by its `const std::string&` counterpart.

PiperOrigin-RevId: 902557141
Change-Id: I27b585cf1deb276d4150a5cbe6cf7e59c323a20a
2026-04-20 04:17:14 -07:00
Haroon Qureshi eb31027a7c Simplify RenderTarget creation.
Remove the RenderTargetTextureType enum and, instead, create
RenderTargets directly from pixel formats.

PiperOrigin-RevId: 902536708
Change-Id: I2683aa9db23c011212087d93df0260ad27621170
2026-04-20 03:27:52 -07:00
Yuval Tassa e6d77650f7 Refactor mju_combineSparse to eliminate temporary buffers.
Combine sparse vectors in-place by first counting total `nnz` and then working backwards from the end. This removes the need for temporary buffers in `mju_combineSparse` and its callers and speeds up the function by ~10%.

PiperOrigin-RevId: 902530210
Change-Id: I4f48c327103552ab968d3915399c6067367bec9f
2026-04-20 03:10:18 -07:00
Alessio Quaglino 3230cf99f9 Change flex constraints to eigenmodes of the stiffness matrix.
This provides a reduction from 26 to 18 constraints for trilinear and from 162 to 75 for quadratic. The assembly of the constraints becomes trivial. In total the speedup for a trilinear 3x3x3 grid is about 3x.

PiperOrigin-RevId: 902502398
Change-Id: I764772c7adef78da5a644f64701f842d36e4b543
2026-04-20 02:02:44 -07:00
Haroon Qureshi bf9be2c312 Remove MeshPtr type alias.
PiperOrigin-RevId: 902502036
Change-Id: I5bd0c185f204518f0cd0d9189741c17c24b51eb6
2026-04-20 02:01:34 -07:00
Yuval Tassa a04c2b1b4a Consolidate stack allocation calls in primal solvers down from 30 to 2 (dense) or 6 (sparse). Preparation for atomic allocation calls in threaded mode.
PiperOrigin-RevId: 902496039
Change-Id: I39df011951713505c4743c7475d74856ddbdf4f9
2026-04-20 01:47:30 -07:00
Matija Kecman cf3f6ccf1f Make file search deterministic in FindFileInPath.
Collect all entries from the recursive directory iterator, sort them, and then check for the filename. This ensures that if multiple files with the same name exist in different subdirectories, the one found is always the same, regardless of the filesystem's directory iteration order.

PiperOrigin-RevId: 902487291
Change-Id: Ia4c45cd2e3cab4a4e3825c267fc47c3134f99f76
2026-04-20 01:27:40 -07:00
Haroon Qureshi f3f12bfad6 Manage dynamic meshes (skins, flexes) in model_objects.
Simplifies Renderable as it no longer has the option of owning
any Meshes. Instead, the ModelObjects owns the Meshes for
flex and skin geom (just like it owns all the other mjModel
Meshes).

PiperOrigin-RevId: 902485912
Change-Id: I8b9f9d394de6c46f7e25aa4b3885a374aad05294
2026-04-20 01:23:47 -07:00
Yuval Tassa 6bf31cf68a Update Windows build notes.
PiperOrigin-RevId: 902480947
Change-Id: I69f099b3d7eabd6513a62e74e5ef697a5062e7b5
2026-04-20 01:13:17 -07:00
Tarik Kelestemur 8262280f5f Clean up MJX segmentation rendering 2026-04-19 13:12:52 -04:00
Alessio Quaglino 3d45a33190 Refactor flex strain constraints to be per-cell.
Each mjEQ_FLEXSTRAIN equality now represents a single cell within a flex. This allows for more efficient sparse Jacobian computation by only considering the degrees of freedom of the nodes within each specific cell. This change gives a speedup of about 10x on a 3x3x3 model.

PiperOrigin-RevId: 902164069
Change-Id: I78eedf1d5cf39b8989fe9863c22d164922fc0efb
2026-04-19 07:21:18 -07:00
Tarik Kelestemur fa8b6311a2 Merge branch 'main' of https://github.com/google-deepmind/mujoco into mjx-warp-segmentation 2026-04-17 15:56:21 -04:00
Tarik Kelestemur 5c41d1b86e Merge branch 'tarik/mjx-warp-segmentation' of github.com:tkelestemur/mujoco into tarik/mjx-warp-segmentation 2026-04-17 15:55:12 -04:00
Taylor Howell a9e61966b5 Import of Warp v1.12.1 from https://github.com/nvidia/warp.
PiperOrigin-RevId: 901388190
Change-Id: Id2c5f1bc2ba9050af2c3b7597d84b9525ffa5766
2026-04-17 11:22:44 -07:00
Alessio Quaglino b16383dfaf Use banded solver for implicit flex integration.
The flex interpolation stiffness matrix within the implicit/implicitfast solvers is now built and factorized in a banded format instead of a dense one. This involves:
-   Calculating the bandwidth based on the sparsity of the mass/damping matrix and the connectivity within flex cells.
-   Allocating and populating a banded matrix `H`.
-   Using `mju_cholFactorBand` and `mju_cholSolveBand` for factorization and solving.
This change improves performance for flexes with many DOFs but local coupling.

PiperOrigin-RevId: 901297952
Change-Id: I3efe06353d1903ea65ab30dc49685cede228bb68
2026-04-17 08:00:07 -07:00
Alessio Quaglino 6c7ed66781 Implement multi-cell finite element method for interpolated flexes.
This change introduces a `flex_cellcount` field to `mjModel` to specify the number of cells in each dimension for interpolated flexes. The stiffness computation, passive force calculation, and Jacobian derivatives are updated to operate on a per-cell basis, significantly improving performance by localizing computations to the nodes within each cell.

PiperOrigin-RevId: 901216393
Change-Id: Ic23132e609de11e71bb7fef8d1f139daad2ec264
2026-04-17 04:13:19 -07:00
Haroon Qureshi 8415dff307 Merge Material into Renderable.
Allows the Renderable to update its own MaterialInstances whenever
Material textures or parameters are modified.  Each Renderable now
also knows how it is intended to be used (i.e. scene objects or ux)
which allows it to correctly pick the underlying filament::Material
to use.

PiperOrigin-RevId: 901161990
Change-Id: Ic280731d39c272c50d6ad100cec7116e683cbc79
2026-04-17 01:59:02 -07:00
Matija Kecman c23b5e8420 Fix WASM build issues, improve test coverage and improve cmake files
* Ensure compiler.usethread=0 is set before compilation in single-threaded WASM builds
* Explicitly enable exceptions for the single-threaded WASM module
* Test the single-threaded module in addition to the multi-threaded module in internal and external CI
* Consolidate wasm/tests/CMakeLists.txt into wasm/CMakeLists.txt, fixing the single-threaded benchmark test build which was missing shared linker flags

PiperOrigin-RevId: 901149728
Change-Id: If4946e29e5116610782d218906cf3f5940c1cdd0
2026-04-17 01:29:40 -07:00
Matija Kecman f91ce9a627 Remove window dependency from PipGui
PiperOrigin-RevId: 901115560
Change-Id: I85183a91fd07682f17f43fcfad593dececdde28c
2026-04-17 00:11:59 -07:00
Yuval Tassa 506aa79ad8 Add Human-700 to model gallery
PiperOrigin-RevId: 900755246
Change-Id: I655c21c21f9b858c907e593d50c26698d90bcfbb
2026-04-16 09:02:08 -07:00
Tarik Kelestemur 01a043f20b mjx segmentation 2026-04-16 10:52:03 -04:00
Haroon Qureshi 1117e7db39 Move DrawMode into its own header file.
PiperOrigin-RevId: 900656695
Change-Id: I4db6f0f74c2109752efe40bc37c7104505139049
2026-04-16 04:44:22 -07:00
Kyle Bayes 56e98cc16c Improve AABB bounds in makeAAMM.
MODEL           BEFORE(ns)   AFTER(ns)
boxmesh.xml     874645       744822
box.xml         808226       786226
ellipsoid.xml   1477609      1436058
mixed.xml       1492063      1404848

PiperOrigin-RevId: 900626282
Change-Id: I3df5a6cd8a4cb2e3b9ded1b40a5310a4c14ec624
2026-04-16 03:25:18 -07:00
Haroon Qureshi 5a0809efaf Remove dependency on Texture from ObjectManager.
ObjectManger now manages low-level filament Texture and
Material objects directly. Moves the IBL Texture to the
SceneBridge class.

PiperOrigin-RevId: 900626110
Change-Id: Idd39464bfb324188dd54975a500954d4ebb29006
2026-04-16 03:24:21 -07:00
Haroon Qureshi a6b98e5a78 Keep track of the vertex attributes in a Mesh.
PiperOrigin-RevId: 900583030
Change-Id: I5b1ff5ad7b698e3e68fd06f44f2c5d3399d08504
2026-04-16 01:41:56 -07:00
Tarik Kelestemur d39b2f4f9d mjx segmentation 2026-04-15 18:22:46 -04:00
devshahofficial 564007204c Fix AttributeError in Renderer.__del__ on partial construction.
If Renderer.__init__ raises before the rendering contexts are assigned
(e.g. width > offwidth raises ValueError, or MjrContext construction
fails), __del__ calls close() which accesses self._gl_context and
self._mjr_context unconditionally, raising AttributeError. This masks
the real __init__ failure with a noisy "Exception ignored in..." message
during garbage collection.

Pre-initialize both attributes to None at the top of __init__ so that
close() is safe on a partially-constructed instance. Add a regression
test that captures sys.unraisablehook and asserts that __del__ raises
nothing when __init__ fails via the width > offwidth path.

Fixes #3213.
2026-04-15 12:15:24 -07:00
Haroon Qureshi eacbce95f4 Fix CMakeLists file.
gui_view was renamed imgui_bridge

PiperOrigin-RevId: 900208849
Change-Id: I305a8a90306038c236256c21d04d2bad7144d83a
2026-04-15 09:37:06 -07:00
Kyle Bayes d9b3faf8f4 Remove thread_local EPA data in favor of using mjData stack.
PiperOrigin-RevId: 900201369
Change-Id: I82fbe9bf0ef9ea117c2124353d876dd42a57fb3a
2026-04-15 09:19:57 -07:00
Matija Kecman 7ac30a39fe Fix mj_loadXML hang in single-threaded WASM builds
The top-level CMakeLists.txt unconditionally added -pthread for all Emscripten builds, but PTHREAD_POOL_SIZE was only set when MUJOCO_WASM_THREADS=ON. This gave the ST build a live pthread runtime with zero pre-spawned workers, causing CompileMeshesAndTextures to deadlock when it tried to spawn a ThreadPool on the main thread.

Fix by making -pthread conditional on MUJOCO_WASM_THREADS. Without -pthread, hardware_concurrency() returns 0 and the existing nthread < 2 guards naturally select the serial compilation path.

PiperOrigin-RevId: 900191420
Change-Id: I0481b81fc6f7cccb52c7d7592dcf9dd317b5bad1
2026-04-15 08:57:04 -07:00
Haroon Qureshi e047f1101a Rename GuiView to ImguiBridge.
PiperOrigin-RevId: 900186368
Change-Id: Ie8f08d081dbc9a2b5638b5e799788e81891c908a
2026-04-15 08:44:00 -07:00
Yuval Tassa a2d0e33c0f 2-3x speedup of sparse matrix squaring.
Split symbolic and numeric phases for sparse `M'*diag*M` computation. Microseconds per call for the monolithic vs the split approach for the 100_humanoids and 2humanoid100 models:

```
+-------+------+----------+------------+---------+
| Model | Arch | Col (µs) | Split (µs) | Speedup |
+-------+------+----------+------------+---------+
| 2H100 | x86  | 238.3    | 74.5       | 3.2x    |
+-------+------+----------+------------+---------+
|       | ARM  | 111.6    | 53.2       | 2.1x    |
+-------+------+----------+------------+---------+
| 100H  | x86  | 1325.3   | 656.2      | 2.0x    |
+-------+------+----------+------------+---------+
|       | ARM  | 594.8    | 306.6      | 1.9x    |
+-------+------+----------+------------+---------+
```

PiperOrigin-RevId: 900154308
Change-Id: Ia6e9b8e196e2ed37b723a0faf60e9731303a9619
2026-04-15 07:19:41 -07:00
Haroon Qureshi 62cffb1536 Update GuiView to use SceneView and Renderables.
PiperOrigin-RevId: 900145167
Change-Id: I613c9fe171e97f8a4cd08c0c63e9706e09cbd202
2026-04-15 06:56:16 -07:00
Yuval Tassa 8f3ed662eb Hoist solver stack allocations out of iteration loop
PiperOrigin-RevId: 900085248
Change-Id: I2bde8fafc8a4801a92c39aa9a13af0ea7475843d
2026-04-15 04:23:08 -07:00
Haroon Qureshi f24f9ef44d Allow submeshes to be set when adding meshes to a Renderable.
Also add support for blend order.

PiperOrigin-RevId: 900061778
Change-Id: I601757a8672fed23e45defd4cdbe4e9526ea3b70
2026-04-15 03:25:55 -07:00
Matija Kecman 9289905c9a Make StepControlGui a reusable component and refactor/simplify the implementation
PiperOrigin-RevId: 900045404
Change-Id: I9976ece042710ddce0a7c5d99a6ac85a0ef06d2f
2026-04-15 02:48:11 -07:00
Haroon Qureshi d913e0b1e9 Add ReadPixels function to RenderTarget.
PiperOrigin-RevId: 900017779
Change-Id: I0632b66124632558ea19157e4ca319e4b0d10617
2026-04-15 01:39:54 -07:00
Michael Moss 4a98cc8bff Update MuJoCo version to 3.7.1 following the 3.7.0 release
PiperOrigin-RevId: 899835826
Change-Id: Ibe247b921e7dad7184acef69ee3199fec79c6e24
2026-04-14 16:49:03 -07:00
Taylor Howell 8bf11166b1 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 899731493
Change-Id: Ib563023047e85db1aff56e78724dc28d769ef91e
2026-04-14 12:55:31 -07:00
Alessio Quaglino 5724158593 Refactor flex stiffness storage to support variable sizes.
This change introduces `nflexstiffness` and `flex_stiffnessadr` to allow flex stiffness matrices to have sizes other than the fixed 21 per element. Higher-order flexes can now store larger stiffness matrices based on their number of nodes. The `flex_stiffnessadr` array provides the starting index for each flex's stiffness data within the `flex_stiffness` array.

PiperOrigin-RevId: 899632263
Change-Id: Ie49182c46c3777acf0c6b492345edfcf62fb5e44
2026-04-14 09:39:00 -07:00
Haroon Qureshi 08bb6e66f1 Small fixes to decor rendering.
Use an unlit material for decorative elements and do not render them
in the reflection pass.

PiperOrigin-RevId: 899560291
Change-Id: I3b035d556432c850ce8240e0c4c4c2d6645d7bf2
2026-04-14 06:50:51 -07:00
Michael Moss 72cb2b210d Update changelog for the 3.7.0 release.
PiperOrigin-RevId: 899497703
Change-Id: Ib9ec75550615dc245bc66af60c877e8adae17e67
2026-04-14 04:10:38 -07:00
Haroon Qureshi aef0589442 Allow Light objects to be image based lights.
PiperOrigin-RevId: 899488765
Change-Id: I3b56fc6499404bb011f9361c03dba23b736ad4bc
2026-04-14 03:49:26 -07:00
Haroon Qureshi fd5a7004f8 Remove Drawable abstraction.
Instead, use a set of functions to create/update a Renderable
from an mjvGeom.

This completely isolates mjvScene/mjvGeom from SceneView,
making SceneView a more general purpose class.

PiperOrigin-RevId: 899475268
Change-Id: I48a3a45bc8fff3e1f514847c7a1ca8ab3a1ff16e
2026-04-14 03:13:55 -07:00
Michael Moss 171e6dc177 Automated rollback of PiperOrigin-RevId: 899009633.
*** Original change description ***

Add protocols for authoring simulation environments. This is for preview only, we discourage users from using this in production code.

PiperOrigin-RevId: 899425542
Change-Id: Ifb6c5d3b762789d821bfa9826f5d6d983e8af7d3
2026-04-14 01:16:35 -07:00
Haroon Qureshi 82e021fcda Fix UI material; it no longer requires featureLevel 0.
PiperOrigin-RevId: 899400551
Change-Id: I7a2d42cd5342ed079599eef50e85c50aa340aecc
2026-04-14 00:13:47 -07:00
Google DeepMind 8135465779 Remove usages of texture2D and other FL0 features that are obsolete due to FL0 now going through spirv-cross.
This is an early upload of https://github.com/google/filament/pull/9867 and necessary material changes

Original PR commits:
FL0 materials are always compile via spirv-cross
postfx materials now support sRGB emulation in FL0

PiperOrigin-RevId: 899262890
Change-Id: I52c002d60790d84269674c1f0d0c5f7d6a58000c
2026-04-13 17:31:29 -07:00
Yuval Tassa 412cee2059 Add Jdot correction for connect and weld constaints
Measured reduction in constraint violations before/after this change:

| Model | Correction ON (Avg Viol) | Correction OFF (Avg Viol) | Reduction |
| :--- | :--- | :--- | :--- |
| `jdotv_connect_2d.xml` | 3.959e-4 | 1.699e-3 | **76.7%** |
| `jdotv_connect_3d.xml` | 1.399e-3 | 5.493e-3 | **74.5%** |
| `jdotv_weld_3d.xml` | 9.472e-3 | 1.148e-2 | **17.5%** |

PiperOrigin-RevId: 899137525
Change-Id: Ic3e33764ebd64239bab916289c23d80c3da0b51b
2026-04-13 12:48:03 -07:00
Yuval Tassa 0c337799bd Implement midpoint integrator for free bodies.
PiperOrigin-RevId: 899043541
Change-Id: I0bb38f6ad94e189b45ab16777a04ad6fefc6adf7
2026-04-13 10:58:49 -07:00
Copybara-Service d9b5d8babb Merge pull request #3216 from tkelestemur:mjx-render-batched-unpackers
PiperOrigin-RevId: 899017204
Change-Id: I7409a00cff81a1d24afe2ca50ec14c2f25c103ea
2026-04-13 10:58:20 -07:00
Sam Haves 7ae07d8157 URDF parsing no longer strips filepaths by default.
This default forces users to use the `spec.assets` dictionary or to do other filepath gymnastics when loading URDF. Instead we encourage users to just modify file paths directly if necessary.

PiperOrigin-RevId: 899009853
Change-Id: I4bb84606a95b65be79ccc77ccbe78062d6de8773
2026-04-13 10:57:52 -07:00
Tom Erez f55aeb04fa Add protocols for authoring simulation environments. This is for preview only, we discourage users from using this in production code.
PiperOrigin-RevId: 899009633
Change-Id: I2de08c5cc4ece69fa135f3fd02df7542bf66d7d0
2026-04-13 10:57:25 -07:00
Yuval Tassa c004d144d1 Correct DC motor derivative calculation and enforce actearly.
PiperOrigin-RevId: 898983657
Change-Id: I008529eacf3e400696d26bd3a52a4cf4c1c12225
2026-04-13 10:56:58 -07:00
Haroon Qureshi bc83c24a4d Rename Renderables to Renderable.
PiperOrigin-RevId: 898904688
Change-Id: I5e52708e4f745ef1d0e4281a7fa1aa29b660bb6a
2026-04-13 10:56:30 -07:00
Haroon Qureshi b38aa0fa23 Move Material into Renderables.
PiperOrigin-RevId: 898873853
Change-Id: I3ef13e44c16334c52ea6f08dbc44fde23096ef4c
2026-04-13 10:55:59 -07:00
Haroon Qureshi 126d5b67e3 Remove ModelObjects and ObjectManager members from Drawable.
Split up the Update function into parts and allow SceneBridge
to call them individually, passing in the ModelObjects or
ObjectManager as needed.

PiperOrigin-RevId: 898851732
Change-Id: I25c6bf920b85caa7b2ddee045475f11fb7a8bac8
2026-04-13 10:55:30 -07:00
Michael Moss 45c6137ec2 Update dependencies ahead of the 3.7.0 release.
PiperOrigin-RevId: 898652802
Change-Id: I74668a5116e8d1b81b61c5b5e94680d08f72bc33
2026-04-13 10:55:01 -07:00
Yuval Tassa 239aa1f856 Minor updates to documentation across multiple sections.
PiperOrigin-RevId: 898652783
Change-Id: Idb671910c18ed3406722b8a1307f97ae9a194139
2026-04-13 10:54:28 -07:00
Tom Erez c08d181d52 Add protocols for authoring simulation environments. This is for preview only, we discourage users from using this in production code.
PiperOrigin-RevId: 897908600
Change-Id: Ib2fa1ca8527665a99a8f31e9320afb5f54c31035
2026-04-13 10:50:26 -07:00
Tom Erez bd4ee537b8 Add protocols for authoring simulation environments. This is for preview only, we discourage users from using this in production code.
PiperOrigin-RevId: 897857927
Change-Id: I82ce0a23465429e7025334e83ba00dfbe5085649
2026-04-13 17:19:19 +00:00
Yuval Tassa f114ea8038 Optimize mj_tendonBias by computing Jdot * qvel directly
PiperOrigin-RevId: 897628283
Change-Id: Iee26a95d6aaa379730b89be14746308742111e2d
2026-04-10 04:57:55 -07:00
Yuval Tassa 025ba59fab Implement sparse Jacobian time derivative
PiperOrigin-RevId: 897609541
Change-Id: Ic86b6026cfc369c584d3edfe12a9a2fd14cc4357
2026-04-10 04:08:06 -07:00
Alessio Quaglino 6b724616c0 Prevent deletion from an attached mjSpec.
This change disallows calling `mjs_delete` on an mjSpec that has been attached to another mjSpec via `mjs_attach`. Attempting to delete an element from an attached spec will now result in an error. The Python bindings for `mjSpec.delete` have been updated to raise a ValueError when this occurs.

PiperOrigin-RevId: 897266695
Change-Id: Ic0670125a3028191ec50eca890f02b5910ec8b03
2026-04-09 13:14:00 -07:00
Sam Haves a744b366fb Include obj and stl decoder plugins as sources in CMake builds.
This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.

PiperOrigin-RevId: 897114719
Change-Id: Iee914cc5e05798186f384a67901f1cf86bc2f887
2026-04-09 07:58:28 -07:00
Yuval Tassa 81720071b8 Changes to dcmotor:
- Remove `lugre:viscous`, should now be added directly to actuator `damping`. Trying to do this for the user was incompatible with default inheritance (compounding instead of overriding).
- Move voltage limiting from the `saturation` to the `controller` attribute.
- Fix indexing issues in default inheritance.

PiperOrigin-RevId: 897087642
Change-Id: I5388c2633e15c7e223992e7eb5d6a28db75a6438
2026-04-09 06:52:45 -07:00
Haroon Qureshi 26fb65c7a7 Expose Drawable Material allowing users to manipulate it directly.
PiperOrigin-RevId: 897079632
Change-Id: Iec51ab30dc087562b8e6a464e122525f144e73a9
2026-04-09 06:34:53 -07:00
Haroon Qureshi f6baacfa86 Remove ObjectManager dependency from Material.
PiperOrigin-RevId: 897056556
Change-Id: Ic02239d7a411b52333b48a069292b21afb547b19
2026-04-09 05:34:18 -07:00
Tarik Kelestemur 1c310ca7be keep render util test setup
Restore the existing Warp/CUDA-gated render_util test setup so the review change stays minimal while preserving the new batched shape coverage.

Made-with: Cursor
2026-04-09 08:14:15 -04:00
Haroon Qureshi edc807895f Split SceneView into two parts: SceneView and SceneBridge.
SceneView owns the filament Scene, View, and Camera objects.
is responsible for rendering the Scene (to which Entities
have been added).

SceneBridge takes the mjvScene as an input and updates the
corresponding light and drawable Entities in the SceneView.

PiperOrigin-RevId: 897007401
Change-Id: I3ec245f5bd48c3654672b11a55fb011f113454cc
2026-04-09 03:32:57 -07:00
Kyle Bayes 229d821915 Enable multiccd for golden data.
PiperOrigin-RevId: 896996806
Change-Id: I7f842d25b4497e135831879e4ac1b268d0307aa6
2026-04-09 03:07:01 -07:00
Tom Power cc0933af8b Add com_pos to Mujoco Warp shims.
PiperOrigin-RevId: 896969879
Change-Id: Idc3eb067a8473251a98404525df0c8c134ac2032
2026-04-09 02:12:17 -07:00
Tom Power 05e26e961c Refactor: Expose flex-related fields directly on mjx.Model.
PiperOrigin-RevId: 896958292
Change-Id: I94b32048e69d2b6844db0911f037318d5fbf4a6a
2026-04-09 01:43:00 -07:00
Sam Haves f2461f9ce6 Modify mj_PLUGIN_LIB_INIT to support multiple plugins in the same compilation unit.
Previously on MSVC we used DllMain to register plugins, you cannot have multiple definitions of DllMain in a single unit so you would get errors if you tried to register two plugins. This modifies the implementation to insert a function pointer into the C runtime initialization instead.

PiperOrigin-RevId: 896612678
Change-Id: I07732147b955d741c836acff6da986db0e9b9eff
2026-04-08 11:35:16 -07:00
Tarik Kelestemur de39128114 fix render batching 2026-04-08 14:09:45 -04:00
Yuval Tassa 33fd2fe40e Improve mju_addToSclSparseInc with two-pointer loop.
Profiling `leaves.xml` with contacts disabled, this function takes up most of the time (in the implicit integrator). Total `testspeed` run time:

BEFORE: 18.5s
AFTER: 16.5
PiperOrigin-RevId: 896525902
Change-Id: I57f4a984d178956a2902212deb857bf53f53f01b
2026-04-08 08:49:15 -07:00
Google DeepMind 8191bf1e41 Update MuJoCo README with a link to mjswan.
Add a note about mjswan, which extends the JavaScript/WebAssembly bindings with real-time policy control and interactive features. Requested by tatsuki.

PiperOrigin-RevId: 896513129
Change-Id: I984a41d281ffa1ad307f0b3db909140a201dd717
2026-04-08 08:21:34 -07:00
Yuval Tassa 0e04436d51 Remove `mjWARN_VGEOMFULL, handle visual geom buffer full warnings in mjvScene`.
PiperOrigin-RevId: 896483023
Change-Id: I6dde2c20d8e8e229cf95e1f002dd10525d3376e6
2026-04-08 07:17:53 -07:00
Yuval Tassa 5a2cc6cee3 Improve torque-speed Figure (3b) in dcmotor.pdf
PiperOrigin-RevId: 896453507
Change-Id: I3973b173db9035b71d69bc2c9dea990689d06a1c
2026-04-08 06:04:57 -07:00
Haroon Qureshi c6a434a408 Move flex/skin Mesh creation into ModelObjects.
PiperOrigin-RevId: 896419032
Change-Id: Ib0f0cd0c80c9f630127f2f72dbaed7c644046663
2026-04-08 04:38:10 -07:00
Haroon Qureshi 87b0ea785e Move UpdateMeshData into model_objects.cc.
PiperOrigin-RevId: 896346482
Change-Id: Id57586d652faca75d07ccfe0cee72e97afc823fc
2026-04-08 01:48:38 -07:00
Haroon Qureshi 49b45bd993 Merge vertex_util into math_util.
PiperOrigin-RevId: 896071837
Change-Id: Ieec0e4b4b11988805219739a84f413871ae34f1b
2026-04-07 13:53:27 -07:00
Haroon Qureshi f7fd5fc58b Rename RenderTargetAndTextures to RenderTarget.
Also rename render_target_util to render_target.

PiperOrigin-RevId: 896033907
Change-Id: I123cf98dc308f7cc4916f7b79dcc59a05564022d
2026-04-07 12:30:39 -07:00
Yuval Tassa 382474bb9d Minor improvements to dcmotor
PiperOrigin-RevId: 895907301
Change-Id: Ia50a6d06c1ede9894cc71f375db837d104f0211e
2026-04-07 08:11:13 -07:00
Haroon Qureshi b61d304126 Rename buffer_util to mesh.
PiperOrigin-RevId: 895897940
Change-Id: Ic6d4315fd6429efda81d24168548271a1a1f03c5
2026-04-07 07:49:38 -07:00
Haroon Qureshi a3c9115d1e Use MeshData struct for creating Meshes.
Consolidate all Vertex and Index buffer creation inside the
Mesh class. Users now set data pointers in the MeshData
from which the Mesh class will create the filament buffers.

PiperOrigin-RevId: 895871213
Change-Id: Ie086fcb5c31adf90e54cba168b03501e21720726
2026-04-07 06:41:36 -07:00
Matija Kecman 9f3babd60c Group platform components into descriptive subfolders
PiperOrigin-RevId: 895832492
Change-Id: I6cc56b0e4b002b2998579cde95f4b88dfbd88184
2026-04-07 04:58:32 -07:00
Haroon Qureshi 6273331d82 Define a struct that can be used to create a Mesh.
A future change will update all callers to use this
method for creating Meshes after which we will remove
the constructor that takes explicit filament objects.

PiperOrigin-RevId: 895807063
Change-Id: I50833817961ae57fbb9ed6b875c1ef286b9fdd26
2026-04-07 03:58:21 -07:00
Haroon Qureshi 28d8ddcbeb Rename FilamentBuffers class to Mesh.
Update the Mesh class so that it manages the lifetime of the
vertex and index buffers.

PiperOrigin-RevId: 895794022
Change-Id: I5eda578b8b7ed7f918e792f6181ec724729b5215
2026-04-07 03:24:40 -07:00
Copybara-Service 6de35648d1 Merge pull request #3165 from thowell:mjwarp_per_world_meshes_doc
PiperOrigin-RevId: 893971099
Change-Id: I57d44bf8f793356601ec6bde129a459ff114b91c
2026-04-03 02:35:45 -07:00
Alessio Quaglino 0e3306b62d Add useful flex arrays to MJX API.
This enables using name2id for flexes.

PiperOrigin-RevId: 893923892
Change-Id: I7c2a71791e26fa2280cfa75fd66db328f4599b0b
2026-04-03 00:13:29 -07:00
Sam Haves db011b5100 Add condition to team notification of github actions that it's from 'main'
PiperOrigin-RevId: 893437916
Change-Id: I0c0b22747e4e4cac23ad0f44cf8b667863cc79ae
2026-04-02 04:42:39 -07:00
Taylor Howell e9de329e4e Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 892971818
Change-Id: Ibce0c41294a4fcf2825a246a9533e8927fdc7e82
2026-04-01 09:33:20 -07:00
Yuval Tassa 70a7647ad9 Add <dcmotor> actuator and related docs and tests.
PiperOrigin-RevId: 892927987
Change-Id: I38ed6412801341ba03ddf5fe7b93a6081df24d37
2026-04-01 07:50:23 -07:00
Haroon Qureshi 6da210c794 Rename texture_util to texture.
PiperOrigin-RevId: 892868713
Change-Id: I113132dc9e4535e94d48c4e71520acb159e2e216
2026-04-01 05:14:47 -07:00
Haroon Qureshi 565e46da42 Update GuiView to use Texture class.
PiperOrigin-RevId: 892866156
Change-Id: I2a2e9ef51df51472b675d69edcf2d5ba291721ea
2026-04-01 05:06:08 -07:00
Haroon Qureshi 9fa9193a62 Split Texture creation into two structs.
TextureConfig describes the properties of the texture (e.g.
width, height, pixel format, etc.).  TextureData contains
the binary payload of the texture.

PiperOrigin-RevId: 892854578
Change-Id: I604b926ac38ff1050cac8fdf9ec767b789c0798e
2026-04-01 04:32:22 -07:00
Haroon Qureshi 95666da039 Introduce a Texture class that wraps filament::Texture.
PiperOrigin-RevId: 892839636
Change-Id: I3c08fba0a514cfb758ec2842d8510c6d88300874
2026-04-01 03:52:05 -07:00
Haroon Qureshi 6d32038417 Move all texture creation functions into texture_util.
PiperOrigin-RevId: 892838123
Change-Id: I84a536b111c3d6b5391513d6623c2e9a4d02f3df
2026-04-01 03:47:51 -07:00
Taylor Howell 0b54638df4 Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 892794388
Change-Id: Ic681071dc68bfaecaaab4e131c1c464dca99f9b5
2026-04-01 01:54:01 -07:00
Andrew Kaufman 792f53c823 USD : Adopt newton-usd-schemas & deprecate MjcPhysics equivalents 2026-03-31 10:44:59 -07:00
Andrew Kaufman facebe5aa1 Build : Fetch newton-usd-schemas from GitHub 2026-03-31 10:41:01 -07:00
dependabot[bot] 1640d6a4bc Copybara import of the project:
--
9a748c86e78009393be8ef2f586c5637ac6225d9 by dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>:

Bump pip from 24.3.1 to 26.0 in /python

Bumps [pip](https://github.com/pypa/pip) from 24.3.1 to 26.0.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/24.3.1...26.0)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: '26.0'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3064 from google-deepmind:dependabot/pip/python/pip-26.0 9a748c86e78009393be8ef2f586c5637ac6225d9
PiperOrigin-RevId: 892327253
Change-Id: I0cf41d08a1ffeb3238cddd5a3fcf39388810d9b7
2026-03-31 07:28:29 -07:00
Haroon Qureshi d4103939e4 Correctly compute bounding boxes for meshes.
Enable culling when bounding box is available.

PiperOrigin-RevId: 892289875
Change-Id: I124426b6e7e72f4d9a1486320d72d6eb032e0828
2026-03-31 05:58:11 -07:00
Haroon Qureshi 06d6bda5bb Factor out mjModel-specific objects from ObjectManager.
All objects that are specific to the mjModel (meshes, textures, etc.)
are now managed by a ModelObjects class which is owned by the SceneView
and not the FilamentContext.

PiperOrigin-RevId: 892250776
Change-Id: Iddad66fd3ab1a60c4becdcb5d0c935ed9ea8ad90
2026-03-31 04:16:51 -07:00
Michael Moss 51b2f52296 Workaround for TypeScript 'outFile' is deprecated errors.
PiperOrigin-RevId: 892241799
Change-Id: Ibe028d453f35f5e03bdf66418bc4b45c20e807d3
2026-03-31 03:55:06 -07:00
Haroon Qureshi bcaa0a8e6a Use mjrf functions from within other mjrf functions.
PiperOrigin-RevId: 892234323
Change-Id: I70ff01121764b552da84bdcc9b01527ae138dfea
2026-03-31 03:37:26 -07:00
Copybara-Service ab7b78caa9 Merge pull request #3200 from StafaH:render_doc_update
PiperOrigin-RevId: 891839705
Change-Id: I79874c769a1399e3ca71ec42b7389055b5b5fb88
2026-03-30 12:10:11 -07:00
Peter Hawkins 47264877a1 [JAX] Replace jnp.clip(..., a_min=..., a_max=...) with jnp.clip(..., min=..., max=...).
a_min and a_max are deprecated parameter names to jax.numpy.clip.

PiperOrigin-RevId: 891786675
Change-Id: Icc06efe0381c0db06f4aeb16f281a4d01ea37539
2026-03-30 10:28:24 -07:00
Yuval Tassa 5107c31c06 Add missing API documentation entries.
PiperOrigin-RevId: 891658745
Change-Id: I7fa4f0535e72eaaf8964ce3f1bcf4bf87486580a
2026-03-30 05:13:31 -07:00
Mustafa Haiderbhai 5e677f1091 Update mjwarp render doc after flex rendering improvements 2026-03-27 13:01:16 -04:00
Haroon Qureshi e4f4044659 Move material multipliers to calling function.
PiperOrigin-RevId: 890457829
Change-Id: Icb4151a792321aadd3958d479ef02f29ae4a2afc
2026-03-27 08:06:57 -07:00
Haroon Qureshi e17e3bfd82 Remove ObjectManager dependency from Light.
PiperOrigin-RevId: 890454094
Change-Id: Idb609ad6d8ed7df714cad7b0aca997fee73ab96d
2026-03-27 07:57:43 -07:00
Haroon Qureshi 75bbf03cfb Add PBR test model.
PiperOrigin-RevId: 890431107
Change-Id: Ib3b5fa775daa93b4c798483df226585441ea5c61
2026-03-27 07:05:08 -07:00
Haroon Qureshi b31e15fbb8 Remove ObjectManager dependency from GuiView.
PiperOrigin-RevId: 890407310
Change-Id: I9548ee698fbd02d967581200ba2f6ec31e0f7a7c
2026-03-27 06:01:56 -07:00
Haroon Qureshi 1c2100e27c Refactor FilamentContext to prepare for upcoming changes.
Separate out the parts of the FilamentContext initialization that
depends on the mjModel into a separate Init function.

PiperOrigin-RevId: 890373341
Change-Id: I06b524668cd60dad804d437958f4f6606c46200b
2026-03-27 04:26:10 -07:00
Haroon Qureshi d597b23e5e Remove mjModel dependency from builtins.
PiperOrigin-RevId: 890372546
Change-Id: I1d6b99998e42c1d80072a04f5e57eaf5b4d49791
2026-03-27 04:24:09 -07:00
Haroon Qureshi f7fb23084d Remove mjrContext from FilamentContext.
Setting values in the mjrContext is only useful for the classic
renderer.

PiperOrigin-RevId: 890345656
Change-Id: Ie3d34dc260d13f74b569dcf575e88dde894d652b
2026-03-27 03:13:17 -07:00
Yuval Tassa 9f5fc99711 Convert monolithic RecompileCompare and WriteReadCompare tests into test suites, one test per file.
PiperOrigin-RevId: 890149850
Change-Id: Ib3e8c032a7b43b4a3f85e7a922e25987050cd77c
2026-03-26 18:21:49 -07:00
Haroon Qureshi 0021564035 Remove unused member variable.
PiperOrigin-RevId: 889775964
Change-Id: I8464d381158875c22437633dfbb548c10dc89462
2026-03-26 05:18:01 -07:00
Haroon Qureshi a25b9376f0 Remove unused variable.
PiperOrigin-RevId: 889771550
Change-Id: I8b89e6ccf0a896461b9ddadc23f57e003ea7f8da
2026-03-26 05:07:28 -07:00
Michael Moss f28e727a57 Ignore new tsc deprecation warning from emscripten.
PiperOrigin-RevId: 889322248
Change-Id: I70be60506a8ecbc0dde0f64f5a31c075a804706e
2026-03-25 10:38:57 -07:00
Yuval Tassa c000724a53 Update references.h
PiperOrigin-RevId: 889270962
Change-Id: I0d4295b936e00c55846ea4f6e13f7c25c36c5c6b
2026-03-25 08:59:15 -07:00
Haroon Qureshi 07fc5bc736 Fix build.
PiperOrigin-RevId: 889270417
Change-Id: I4052639054f98c1775357797a80b3049e31b18c7
2026-03-25 08:58:04 -07:00
Haroon Qureshi 4fce53c31f Detect KTX files as image/ktx.
PiperOrigin-RevId: 889260070
Change-Id: I93a505bca3da87d05c71fe302f9e7ac31806ab90
2026-03-25 08:32:28 -07:00
Sam Haves 10c5f5d066 Add comments to mjpEncoder member functions.
PiperOrigin-RevId: 889233466
Change-Id: Ia08ae7ef9bd554cea2f82270e8f150db3e01bf69
2026-03-25 07:33:10 -07:00
Haroon Qureshi 1bfd68cbba Adds function for creating the filament Platform based on the renderer
configuration.

PiperOrigin-RevId: 889226229
Change-Id: Ia5bcdc16e9861e39c49422c2d5fccee23e477af6
2026-03-25 07:15:58 -07:00
Alessio Quaglino c49bc7c7c0 Warn when a non-rigid flex has no constraints or passive forces.
Add a warning in user_model.cc if a flex is not rigid and has no edge equality constraints or passive forces (edge stiffness, edge damping, or vertex damping). Such flexes would not affect the simulation. A test case is added to verify the warning.

PiperOrigin-RevId: 889215981
Change-Id: I481128e1456921b632719547c676d201fdfbe931
2026-03-25 06:50:30 -07:00
Haroon Qureshi fd3ce4fe92 Implement reflective surfaces.
Reflective surfaces (planes) use a custom shader to blend their
texture with a texture that contains the reflected image. The
reflected image is rendered to a texture as a separate render
pass in the SceneView.

Because reflective textures are generated after the preparation
phase, additional functions are needed to reapply the texture
to the drawable.

PiperOrigin-RevId: 889213413
Change-Id: I7bad39d62e3e5ba38cf6ac667fec5b87bfa7b2a2
2026-03-25 06:43:46 -07:00
Haroon Qureshi 02b0b40b1c Add reflective materials.
A future CL will implement reflective surfaces and make use of these materials.

PiperOrigin-RevId: 889200524
Change-Id: Icbe5c0c390f89789ed0f5d5c6058a2ef31105608
2026-03-25 06:10:59 -07:00
Haroon Qureshi c61d239ac6 Use model name for window title.
PiperOrigin-RevId: 889193934
Change-Id: Ief9ade9e239c14da1d824d9bc8aa95dc0a71b65f
2026-03-25 05:53:47 -07:00
Haroon Qureshi 4df2fc2490 Ensure decoder has an error string.
We use that error buffer to check for errors.

PiperOrigin-RevId: 889193796
Change-Id: I1f7575321a57301b4ae5002d0c488bbb16a30b26
2026-03-25 05:52:46 -07:00
Sam Haves f5d3ce3451 Introduce mjpEncoder plugin architecture
Add a new mjpEncoder plugin type mirroring the existing mjpDecoder pattern.
Encoders serialize an mjSpec + mjModel to an mjResource for a given format.

New API functions:
- mjp_registerEncoder: globally register an encoder
- mjp_defaultEncoder: zero-initialize an encoder struct
- mjp_findEncoder: look up an encoder by filename extension or content type

The mjfEncode callback takes (mjSpec*, mjModel*, mjVFS*, mjResource*) and
returns 0 on success. Writing to mjResource keeps symmetry with the decoder
reading from mjResource and leaves the door open for writable resource providers.

PiperOrigin-RevId: 889187898
Change-Id: I180771b2255b91dea188ac5e2cdc3a8f0fb85364
2026-03-25 05:35:39 -07:00
Alessio Quaglino 2d33b50243 Parallelize tactile sensor computation.
The computation of tactile sensor values for each taxel is now parallelized using the MuJoCo threadpool when the number of taxels exceeds a threshold. Each thread processes a batch of taxels, accumulating forces from all colliding geoms.

PiperOrigin-RevId: 888606457
Change-Id: I98abf3e98a7318fc14080054bea7093ab46e8b8b
2026-03-24 05:21:08 -07:00
Alessio Quaglino f4e3469239 Add test for geom and mesh plugin attributes.
This test verifies that geom.plugin and mesh.plugin are accessible and can be assigned a plugin instance.

PiperOrigin-RevId: 888576511
Change-Id: Id17885de5fdf1f4543ac195a8b04bb01139d1bfa
2026-03-24 03:59:35 -07:00
Kyle Bayes 5c0de1f84d Remove model and data from ccd object. Each geom gets a copy of pos and mat, which is editable without modifying mjData.
PiperOrigin-RevId: 888028695
Change-Id: Ic9bbea4bcd7c2dbe62326798eab73d14da0aaa13
2026-03-23 04:51:53 -07:00
Haroon Qureshi babcfd6575 Add class to manage resources for a RenderTarget.
PiperOrigin-RevId: 888016283
Change-Id: I4959e63e95fad4f75a7a04fabf0879f0b9238f9f
2026-03-23 04:17:53 -07:00
Michael Moss 5664b9e89e Update pybind to 3.0.2.
PiperOrigin-RevId: 887980078
Change-Id: I2eb5284e878180293553e20c94dae853c380805c
2026-03-23 02:44:19 -07:00
Yuval Tassa 4b1667e4ce Fix documentation links
PiperOrigin-RevId: 886920783
Change-Id: Ie1ab433aeaaa668a103a684cbb30ef5375c6211b
2026-03-20 12:26:56 -07:00
Yuval Tassa 510d75f4cf Allow actuators to add damping and armature to joint and tendon transmissions.
PiperOrigin-RevId: 886899849
Change-Id: I02200ee0d4f7c96096d8188b95f823b566562a30
2026-03-20 11:41:15 -07:00
Copybara-Service f7bd6d15f7 Merge pull request #3164 from Balint-H:unity/passive-resubmit
PiperOrigin-RevId: 886821338
Change-Id: I2b733732fcc17223aad4299713f5528b597f03e8
2026-03-20 09:05:07 -07:00
Yuval Tassa c348bc9f4c Disable clang-format for MuJoCo public headers and engine source.
PiperOrigin-RevId: 886720463
Change-Id: I7c89fa99bee0598dcf48807bfbd61ee8bf8fa9b8
2026-03-20 05:06:15 -07:00
Michael Moss 904744bd72 Fix --gc-sections linking error on github macos-15-x86_64.
This forces `CMAKE_REQUIRED_FLAGS` to be treated as a string instead of list,
so none of the args get dropped when passed through `check_c_source_compiles`.

PiperOrigin-RevId: 886717366
Change-Id: I6314f9bfabd9d62bdcad5070c8801c453c381b79
2026-03-20 04:57:54 -07:00
Michael Moss 02d1d3d503 Fix call_guard usage inside .def_property calls.
See also [PR #5533](https://github.com/pybind/pybind11/pull/5533).

PiperOrigin-RevId: 886714838
Change-Id: I8c98461098ccf4958fb18bdcb5acc293c988c258
2026-03-20 04:50:50 -07:00
Yuval Tassa 9fa3f6f77e Enable float32 testing for most MuJoCo engine and user tests.
PiperOrigin-RevId: 886697701
Change-Id: I4a96fae03ea18494c3fcef8eb17b3b6f0863e9b7
2026-03-20 04:05:06 -07:00
Copybara-Service cab4b73f41 Merge pull request #3184 from MatiasManevi:single-thread-npm
PiperOrigin-RevId: 886334046
Change-Id: If054286ac11f2b0e13e770922c049e334d136ab1
2026-03-19 13:05:52 -07:00
Haroon Qureshi 6134fe48d9 Enable shadows depending on render settings.
PiperOrigin-RevId: 886236214
Change-Id: I6999e52ff3d9fc0734082312a77d6c033b69a24b
2026-03-19 09:59:50 -07:00
Haroon Qureshi eae31f0b3c Use model's num_quads for generating planes.
PiperOrigin-RevId: 886228541
Change-Id: I693f85edd84e4e1b1db6a932d4479888426bcae4
2026-03-19 09:44:53 -07:00
Michael Moss 779f6e8403 Save some CMake logs for debugging.
PiperOrigin-RevId: 886222847
Change-Id: Iaa641c334b3e90f594c6a19a29beefcf6eb7a3f4
2026-03-19 09:32:41 -07:00
Haroon Qureshi 7c63bcc8f3 Move Render logic into the Scene/Gui View classes.
This is in preparation for an upcoming change.

PiperOrigin-RevId: 886203890
Change-Id: I91eba35b394898d942f66f75e947c450b924a973
2026-03-19 08:50:41 -07:00
Taylor Howell 57bdf89d07 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 885715192
Change-Id: I13fcb8312c1515bb1bd2d6cdfd0d256e37cb74de
2026-03-18 11:58:25 -07:00
Kyle Bayes eec6e43a73 Bit compress face vertices in EPA to reduce memory needed. The parameter ccd_iteration is only supported to 1000, so we only need 10 bits for vertex index.
PiperOrigin-RevId: 885690198
Change-Id: I4c6af170ddc86316d3e9cfaf7ca7e0e4fac8a416
2026-03-18 11:10:14 -07:00
MatiasManevi b1c7ae1c19 Restore PTHREAD flag 2026-03-18 13:13:05 -03:00
MatiasManevi 9561decf64 Remove PTHREAD flag 2026-03-18 13:04:04 -03:00
MatiasManevi b35a5bab5e Shorten mv instruction 2026-03-18 12:10:08 -03:00
Alessio Quaglino e57d95e68f Remove vertcollide attribute from flex contact.
The `vertcollide` attribute in flex and flexcomp contact specifications has been removed since the next mjWarp release will support flex collisions. This attribute was previously used to enable vertex-based collisions by adding sphere geoms at flex vertices. The functionality associated with this attribute has been deprecated and removed from the XML parser, documentation, and internal data structures. Affected example XML files have also been updated.

PiperOrigin-RevId: 885595503
Change-Id: I6a78975f1bc540c09ea8b5306ff3be0962b7ab24
2026-03-18 07:59:57 -07:00
MatiasManevi 65d8d26af6 Add newline 2026-03-18 11:50:06 -03:00
MatiasManevi b694e9e951 Change caution for note 2026-03-18 11:49:19 -03:00
MatiasManevi aa07cdde5c Add documentation 2026-03-18 11:48:11 -03:00
MatiasManevi 8b7951c20c Add single threaded version 2026-03-18 11:18:41 -03:00
Sam Haves ef78f07ffb Automated g4 rollback of changelist 885555524.
*** Reason for rollback ***

Rolling back obj/stl decoder inclusion as sources due to broken windows build.

*** Original change description ***

Include obj and stl decoder plugins as sources in CMake builds.

This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.

***

PiperOrigin-RevId: 885576586
Change-Id: I31e6fa4d10697862f7d800d0d771ca752747e36d
2026-03-18 07:18:19 -07:00
Sam Haves 15ca42ff68 Include obj and stl decoder plugins as sources in CMake builds.
This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.

PiperOrigin-RevId: 885555524
Change-Id: I20aa5b6c55b678398345d49cb1c47667ae2bebcf
2026-03-18 06:23:26 -07:00
Matija Kecman f1715e67bd Fix studio web so that single file xml model can be loaded in a single-threaded wasm build
model_holder.cc modified to disable multi-threaded compilation for WASM builds. index.html `animate()` function modified so the animation rendering loop executes asynchronously with async/await calls. These changes are sufficient to make xml files without references work (e.g., humanoid.xml), more work is needed to make the vfs work so multi-file models can load.

PiperOrigin-RevId: 885537402
Change-Id: I3469cae48e7268073be334b99bf907c5ed8c27a7
2026-03-18 05:31:29 -07:00
Haroon Qureshi b0c48ba846 Planes should not receive shadows when rendered from behind.
Also refactors Renderables a bit to allow for additional use-cases.

PiperOrigin-RevId: 885527587
Change-Id: I4b17e097256de0356151a6d087bc01f11e3071b7
2026-03-18 05:05:21 -07:00
Haroon Qureshi 3f77daa27a Support wireframe rendering.
PiperOrigin-RevId: 885508978
Change-Id: I97216a120f4fede62924819cfb5cef5693adc7f8
2026-03-18 04:13:24 -07:00
Haroon Qureshi bc1f9513be Add flag for software rendering.
This flag is currently unused.

PiperOrigin-RevId: 885453938
Change-Id: Ia2112410ff12c7b18ad154f18887d4d795bafa3d
2026-03-18 01:48:15 -07:00
Tom Erez 60be42e83c Replace autowrap C# binding generator with introspect-based codegen.
This CL replaces the header-parsing autowrap system for generating
MuJoCo C# bindings (MjBindings.cs) with a new generator that uses
the mujoco.introspect module. The new generator reads pre-parsed
API data from introspect's enums, functions, and structs modules
instead of parsing C headers directly.

Changes:
- New: generate_cs_bindings.py in third_party/py/mujoco/codegen/
- Updated: genrule in unity/mujoco/BUILD to use codegen
- Updated: MjBindings.cs regenerated from codegen
- Removed: entire autowrap/ directory (9 files)
- Removed: transitional validate_codegen.py

The validate test continues to verify that the genrule output
matches the checked-in MjBindings.cs.

PiperOrigin-RevId: 885206129
Change-Id: Ib9fb883a2242dd2c039033eadee7a4a6ac91ed55
2026-03-17 14:19:49 -07:00
Yuval Tassa 206e245353 Internal change.
PiperOrigin-RevId: 885152209
Change-Id: I56941ba443fe3daad02eff39d6dbcaa9615df41b
2026-03-17 12:29:37 -07:00
Copybara-Service c0ab1cc130 Merge pull request #3178 from thowell:mjwarp_docs_mjlab_distributed_training_link_update
PiperOrigin-RevId: 885051946
Change-Id: Ib2473764a0d02924d73acccf59fc7a1236f5d8d1
2026-03-17 09:03:32 -07:00
Yuval Tassa 9d3ee5a948 Improve ASAN poisoning logic in mj_freeStack.
When freeing a stack frame, only poison the newly-freed memory region
`[old_top, new_top)` instead of the entire region `[limit, top)`. The old
code redundantly re-poisoned already-poisoned memory on every
`mj_freeStack` call.

Benchmarking `engine_forward_test` under ASAN:
- Before: 99.3s
- After:  75.6s  (~24% faster)

PiperOrigin-RevId: 885035750
Change-Id: Ib195661ca337d13c5ff6094bcc107c4c0a617b9b
2026-03-17 08:26:39 -07:00
Matija Kecman c420a6e1ca Fix resizing the window when running single threaded
This was affecting code running in the browser using WASM

PiperOrigin-RevId: 884921901
Change-Id: I13e634452275927f58a63179cdf140780852be2f
2026-03-17 03:32:35 -07:00
Matija Kecman 4be4a539c4 Fix "Selected backend not supported in this build" error when running using WASM
PiperOrigin-RevId: 884908229
Change-Id: I5515d1ffe8e7a4fd1f3c1eeee11a7f24196be780
2026-03-17 02:57:45 -07:00
Haroon Qureshi 9a0dd7d32d Make planes semi-transparent from behind.
PiperOrigin-RevId: 884896612
Change-Id: I00cc53e539fd1abccb43c7c6b89a7e063cb4848c
2026-03-17 02:27:34 -07:00
Taylor Howell 9d8004f60d mujoco warp documentation: update mjlab distributed training link 2026-03-16 20:26:34 +00:00
Yuval Tassa efae9157a7 Polynomial stiffness and damping https://youtu.be/aKa3ZlEF9_Y
PiperOrigin-RevId: 884607673
Change-Id: If8088dbf37fed1055304778a7eb84dec52cba920
2026-03-16 13:25:25 -07:00
Alessio Quaglino aec1b45dce Remove unnecessary const from grad parameter in strain Jacobian functions.
The `grad` parameter in `volumetric_dSdx` and `invariant_dSdx` is not modified, but the `const` qualifier was inconsistent with how the array was being passed, requiring an unnecessary cast. Removing the `const` simplifies the function signatures and calls.

PiperOrigin-RevId: 884598322
Change-Id: Icac8071aa8e838057dd39c979c23a4f47e1dc22d
2026-03-16 13:04:00 -07:00
Alessio Quaglino ac2730ab80 Change flex strain constraints for trilinear to a more stable formulation.
This change improves trilinear flex elements by using reduced integration for volumetric quantities (strain trace and volume ratio) at the element center, while adding full integration for shear components at 8 Gauss points and removing the second strain invariant from the constraints, which is negligible for small strains. This reduced integration "B-bar" technique is standard in finite element analysis and prevents artificial stiffness that can occur when low-order elements are nearly incompressible. The constraint count per trilinear element changes from 24 to 26 compared to using invariants. For quadratic elements, the full 27 quadrature point are used resulting in 162 constraints.

PiperOrigin-RevId: 884570752
Change-Id: Ib74ece8f4712c2c81fbfd784524fcac52a2c80e5
2026-03-16 12:05:16 -07:00
Sam Haves a5098a068a Update changelog for upcoming release.
PiperOrigin-RevId: 884479074
Change-Id: I086420505a047406c6bc36fc293c9722d9b41405
2026-03-16 09:23:13 -07:00
Yuval Tassa 1f2587fe3e Make preprocessor checks for ADDRESS_SANITIZER compatible with GCC
PiperOrigin-RevId: 884468086
Change-Id: I5742f023689fd8cc1747df1af5f0a9687a0e77ac
2026-03-16 09:03:52 -07:00
Taylor Howell bb38a34869 Skip shared dofs for contact constraints
PiperOrigin-RevId: 884455239
Change-Id: I7ee36a13c28be88e12380b4790f150ad62f268c1
2026-03-16 08:36:58 -07:00
Yuval Tassa eca5758bf9 Define ADDRESS_SANITIZER portably using standard compiler macros
Use `__SANITIZE_ADDRESS__` (GCC) and `__has_feature(address_sanitizer)` (Clang)
to define ADDRESS_SANITIZER when the toolchain doesn't provide it natively.

Fixes #3160

PiperOrigin-RevId: 884447485
Change-Id: I48ef51bca8f5c5f15f62089e73cd8fa649723636
2026-03-16 08:18:11 -07:00
Taylor Howell 63bab26536 MuJoCo Warp documentation: CCD margin
PiperOrigin-RevId: 884410781
Change-Id: I61171639503ce2a08c79c0e99ed5ebc09c36bf63
2026-03-16 06:49:32 -07:00
Yuval Tassa c651a0daeb Merge friction and limit constraint counting into instantiation functions.
PiperOrigin-RevId: 884379952
Change-Id: I23605f3e5ada0ed0fbdcf3e1903f54788700e2d3
2026-03-16 05:23:20 -07:00
Yuval Tassa a47a18dd28 Rollback of 1cda1e7a8c, fixes #3163
Note this change re-opens issue #2472

PiperOrigin-RevId: 884378131
Change-Id: Ifefc345f1a296e5245cbb10047bb678ffea3598f
2026-03-16 05:17:43 -07:00
Yuval Tassa 55f5ac0a1d Remove mj_jacDifPairCount by incorporating the counting into mj_jacDifPair
PiperOrigin-RevId: 884366070
Change-Id: I7490ca205a315bc661414e32c91ad1ec753a8fe7
2026-03-16 04:44:59 -07:00
Yuval Tassa 50dfc255b8 Fix pybind11 v3.0 compatibility in callbacks.cc
PiperOrigin-RevId: 884074529
Change-Id: I20e7a8d6f6069895afbc3e18d0612f3b2edfaeb7
2026-03-15 12:46:11 -07:00
Baruch Tabanpour 7324864366 Add random seed to SensorTest to prevent flakiness.
PiperOrigin-RevId: 884055306
Change-Id: Ia053d2661ed30835e66a145659c1e1b7275ab251
2026-03-15 11:23:44 -07:00
Haroon Qureshi 28def7d25d Internal changes.
PiperOrigin-RevId: 883932254
Change-Id: Ic93097dde6425e7de00001b8d74ecc61adcde321
2026-03-15 03:38:34 -07:00
Kyle Bayes 88ba8ffdbc Remove const qualifier on mjData in mjfCollision type as mjData is non-const in mjc_SDF via mjpPlugin.
PiperOrigin-RevId: 883225786
Change-Id: I5fecaa1d575b340a6510212db7b3e7db48f361cc
2026-03-13 10:21:53 -07:00
Google DeepMind 7ec4fe2c50 Refactor: Update MuJoCo WASM README structure
Reorganize the README to clearly separate the "User Guide" (including npm installation) from the "Build from source" instructions.

Also added npm install instruction.

PiperOrigin-RevId: 883180811
Change-Id: I874b101c941d3a2fbff8995fb7e4d104e6f4fec2
2026-03-13 08:34:38 -07:00
Haroon Qureshi b18657acde Remove unused flag.
PiperOrigin-RevId: 883113888
Change-Id: I098669f8a873694903159649567bc2f68397f955
2026-03-13 05:37:47 -07:00
Copybara-Service 910fbbb111 Merge pull request #3141 from ocadotechnology:recompile-release-gil
PiperOrigin-RevId: 883109831
Change-Id: I75c22ec071aae8f78b8354de40d8f58e8e952a50
2026-03-13 05:25:45 -07:00
Matija Kecman 86aae0f5a5 Use user::ThreadPool for actuator lengthrange calculation in addition to mesh and texture compilation
PiperOrigin-RevId: 883099169
Change-Id: Id6832c2ca0b8f45e2f428615ae54df4b8bb6f434
2026-03-13 04:54:57 -07:00
Balint-H ce0356b78f Update relevant test for passive spring/damper settings 2026-03-12 16:32:41 +00:00
Copybara-Service 1704f51df6 Merge pull request #3174 from MatiasManevi:fix-wasm-package
PiperOrigin-RevId: 882626629
Change-Id: Iecb61e39f3e994d7b64cec9492ae35e6a1194f9c
2026-03-12 09:14:51 -07:00
Haroon Qureshi 7f437810fd Move MjrRect pybind11 definition to structs.cc.
mjrRect is a common type that will be re-used across different
rendering APIs, not just mjr_ APIs.

PiperOrigin-RevId: 882620060
Change-Id: I7f77ac9298c52c454d94c46379ff5270fd833f26
2026-03-12 09:00:39 -07:00
Balint Hodossy 035fb5acc7 Merge branch 'google-deepmind:main' into unity/passive-resubmit 2026-03-12 15:52:46 +00:00
MatiasManevi a07763f13b Restore npm pack 2026-03-12 11:42:29 -03:00
MatiasManevi 8c3e70998d Fix npm publish command to work with OIDC 2026-03-12 11:39:59 -03:00
Google DeepMind b294d15558 Add from_xml_string to MuJoCo WASM bindings.
This change introduces new functions to load an `mjModel` from an XML string. Two overloads are provided: one that creates a temporary VFS and one that uses a MjVFS arg.

Also updated other places where `from_xml_string` should be used: demos, readme, etc.

PiperOrigin-RevId: 882581762
Change-Id: I8428196f8f56ae9630fcd4f0bb6763cdc1c43da0
2026-03-12 07:35:47 -07:00
Google DeepMind df0bc58578 Add aliases for MjModel loading functions and expose string constants as properties.
Introduces `from_xml_path` and `from_binary_path` as more idiomatic aliases for `mj_loadXML` and `mj_loadModel` respectively. Refactors the binding of `mj*STRING` constants. Instead of exposing `get_mj*STRING` functions, these constants are now available as properties on the `Module` object. Runtime getters are added via EM_ASM to lazily call the underlying C++ functions.

PiperOrigin-RevId: 882566011
Change-Id: Id3bd5c23704fd122af30a50aed089bd3143fbc96
2026-03-12 06:58:50 -07:00
Copybara-Service a62501f305 Merge pull request #3168 from MatiasManevi:npm-workflow-dispatch
PiperOrigin-RevId: 882559989
Change-Id: Ia02f38e632dcd3064433b44f6e14427aa3b36735
2026-03-12 06:43:37 -07:00
Haroon Qureshi b62aed86f9 Recreate swap chain when the window size changes.
PiperOrigin-RevId: 882521107
Change-Id: I0d29d2e323e7830256c24eead439b3f2eb55de40
2026-03-12 04:56:50 -07:00
Copybara-Service 4d0c4666db Merge pull request #3169 from MatiasManevi:npm-pkg-name
PiperOrigin-RevId: 882503732
Change-Id: I20494c3258ba39f382483e82934964472603aa17
2026-03-12 04:07:12 -07:00
Haroon Qureshi 16d618e7b9 Ensure we have a valid vfs when loading a spec.
PiperOrigin-RevId: 882503274
Change-Id: Iddbd6f00c0344bb34d68bb72a640c0a8e81076a2
2026-03-12 04:06:05 -07:00
Copybara-Service 99af6fb9a5 Merge pull request #3167 from MatiasManevi:npm-auth-mechanism
PiperOrigin-RevId: 882500557
Change-Id: Iaa81896c82bac7bf332eefce950ed38c6d4f489d
2026-03-12 03:59:43 -07:00
Sam Haves 3601b063dc Modify mjCMesh vert_ field to be vector<float> instead of vector<double>.
PiperOrigin-RevId: 882162404
Change-Id: Ia97439420f284d594f5cb1a91cd0fb640ac8dff0
2026-03-11 13:15:32 -07:00
MatiasManevi c1586cc86f Change package name to scoped 2026-03-11 15:22:36 -03:00
MatiasManevi bf51c3389a Configure publish npm manual dispatch 2026-03-11 15:17:02 -03:00
Copybara-Service de3b9d3426 Merge pull request #3166 from MatiasManevi:npm-package-repo
PiperOrigin-RevId: 882092397
Change-Id: Ib4eba5a31816d35469415e8a90b4fd9f6562f363
2026-03-11 10:43:13 -07:00
MatiasManevi eda9bbbbd4 Remove workflow dispatch 2026-03-11 14:29:12 -03:00
Haroon Qureshi ad57721e2c Add missing state.
PiperOrigin-RevId: 882072832
Change-Id: I6ad75af67edc7672350c775c1a560e3db6d16969
2026-03-11 10:06:43 -07:00
MatiasManevi f6434110bb Add the required OIDC permissions for trusted published 2026-03-11 13:36:09 -03:00
Sam Haves ecc22667fa Correct polygon winding order for all meshes not only when loaded from a file.
PiperOrigin-RevId: 882053060
Change-Id: I94ee81838fa4074a1a890de4f282eca45ee9e820
2026-03-11 09:25:27 -07:00
MatiasManevi 44848de05b chore: run npm pkg fix to normalize repository URL 2026-03-11 13:24:06 -03:00
Haroon Qureshi db9ab94555 Refactor parts of the toolbar GUI into the GUI library.
PiperOrigin-RevId: 882024591
Change-Id: I3ac73247973666f4d60e9d8d028d20d3ef709bcc
2026-03-11 08:23:12 -07:00
Michael Moss 6d70e66810 Update MuJoCo version from 3.6.0 to 3.7.0 following the 3.6.0 release
PiperOrigin-RevId: 881995135
Change-Id: I0c1a3b4a22c4c7cfada580b49a2cacde64cc84f3
2026-03-11 07:09:24 -07:00
Haroon Qureshi ed2f34baa0 Fix logic for looking up root model within an archive.
PiperOrigin-RevId: 881976329
Change-Id: I7771b84ff0aed83d55ee830deb2f92357355eb88
2026-03-11 06:18:14 -07:00
Taylor Howell 00707ddb89 mujoco warp documentation: per-world meshes 2026-03-11 13:15:08 +00:00
Haroon Qureshi df02fe4bc0 BodyAddChild PopupContext needs to happen immediately upon triggering it.
PiperOrigin-RevId: 881955422
Change-Id: I03675431d78c93550ff2ad6d562daf1a0e3d0d08
2026-03-11 05:20:39 -07:00
Kyle Bayes acf7f030a6 Remove const qualifier from mjData in mj_geomDistance. The function mj_geomDistance will require data stack space as nativeccd memory is determined from opt.ccd_iterations.
PiperOrigin-RevId: 881946592
Change-Id: I524b9fa41018a581e58647d44de6ca3db4c6608b
2026-03-11 04:55:44 -07:00
Copybara-Service 64ee2d041f Merge pull request #3105 from NandiniDhanrale:fix/vfs-move-3098
PiperOrigin-RevId: 881946056
Change-Id: Ide041ff1dcdae00133251d928936920b47cf6c0d
2026-03-11 04:53:57 -07:00
Taylor Howell 6d1c3343af Update MJX documentation reference to MJWarp viewer
PiperOrigin-RevId: 881941624
Change-Id: Ieafb85f5b543a3d9212b33191579c1f7a7c09d16
2026-03-11 04:42:45 -07:00
Bálint Hodossy 87ebe69c00 Remove stale comment 2026-03-11 09:59:54 +00:00
Bálint Hodossy 6e6655ee19 Reapply removal of the passive option
Co-authored-by: joanllobera <joan.llobera@gmail.com>
2026-03-11 09:56:25 +00:00
Michael Moss 3cada28be7 Update changelog for 3.6.0 release.
PiperOrigin-RevId: 881671049
Change-Id: I28a1a3341e6f01d916b35ee9fb3a6c12c627fe89
2026-03-10 16:21:14 -07:00
Sam Haves 6890e133c0 Add mjs_getCompiler C API and compiler property to Python spec elements.
PiperOrigin-RevId: 881488083
Change-Id: I3aa1c0562bf2fd27057b8056048e3156fc1b067c
2026-03-10 09:57:36 -07:00
robin.moss 0c9083723c fix: release the gil when calling compile in spec.recompile
The pybind for recompile was not releasing the GIL when it called mj_recompile, this can caused deadlocks with the
asset loading threads. For example if a resource provider was trying to call Python.

To resolve this the GIL is release just for the mj_recompile.

Addresses: https://github.com/google-deepmind/mujoco/issues/3118
2026-03-10 15:44:01 +00:00
Haroon Qureshi d6aac2041e Make filament-opengl the default graphics mode for studio.
PiperOrigin-RevId: 881362074
Change-Id: Iaa42ddf915b8b146775b2cf0263152b94c586c49
2026-03-10 04:59:03 -07:00
Alessio Quaglino f1b305632c Allow mesh with octrees in mjc_distance.
PiperOrigin-RevId: 881355677
Change-Id: I8da9f7c92d6e76f16a5d82e7d16488211a8a65b7
2026-03-10 04:41:34 -07:00
Michael Moss 955d6c0b02 Update MuJoCo version from 3.5.1 to 3.6.0 prior to next release.
The next release will include breaking changes, so this bumps the major
version to reflect that.

PiperOrigin-RevId: 881351265
Change-Id: I970c68a0211651c07fcb8109ebd0b138196cf50a
2026-03-10 04:30:07 -07:00
Alessio Quaglino 713b5524bc Introduces a new "strain" equality mode (flex_edgeequality = 3) for flexcomps with trilinear interpolation. This mode enforces constraints on the three invariants of the Green-Lagrange strain tensor at 8 Gauss quadrature points within each flex element, resulting in 24 equality constraints per flexcomp.
Also fixes a bug when attaching a flex with constraints.

PiperOrigin-RevId: 881349765
Change-Id: I8e6df8239488bfdc87d7e5b473568975e38c737e
2026-03-10 04:26:07 -07:00
Haroon Qureshi fe6c81ed93 Internal changes.
PiperOrigin-RevId: 881291880
Change-Id: I9b43470802651b823507ee2691ba5216126d72ab
2026-03-10 01:56:10 -07:00
Sam Haves dade2d8c3e MJX: Use content-hash for np.ndarray pytree metadata fields
Previously mjx dataclasses would return np.ndarray as bytes for jax tracing to hash since they are not inherently hashable. This meant that any tracing that was cached would hold on to a copy of the numpy arrays in the dataclass. Children such as mjx.Model that store large numpy arrays would end up duplicating that data 3+ times in some cases.

This eliminates O(N * array_size) memory duplication across N cached
pytree traces, saving a lot of memory on models with heavy mesh/texture data.

PiperOrigin-RevId: 880985898
Change-Id: I58d4e91fda4112e4c633818f92907d20138e962a
2026-03-09 12:35:16 -07:00
Alessio Quaglino 84f09f3fa6 Add mesh_normalnum to MJX API.
PiperOrigin-RevId: 880957335
Change-Id: Ib3c37afa593c888ec109f520947958a5d47b0be2
2026-03-09 11:34:10 -07:00
Copybara-Service 3a99f6110e Merge pull request #3084 from Ashutosh0x:fix/mingw-stat-localtime
PiperOrigin-RevId: 880906196
Change-Id: I98027e80e9882620cb184766c14110478178ce53
2026-03-09 09:54:10 -07:00
Yuval Tassa 1e1eb48261 No-op refactor of flex interpolation factorization and solve in mj_implicitSkip.
PiperOrigin-RevId: 880867833
Change-Id: I2ab8ce5a027742af07ef0256bc4cdee62289282e
2026-03-09 08:20:24 -07:00
Copybara-Service 79d14035f9 Merge pull request #3158 from mar-yan24:mark-flexcompFix
PiperOrigin-RevId: 880857702
Change-Id: Ic1ad4068312c9a02728ce7f49abb38dea3b97a46
2026-03-09 07:57:21 -07:00
Copybara-Service 3510537bcb Merge pull request #3027 from Adityakk9031:#2982
PiperOrigin-RevId: 880846172
Change-Id: I5b0ccda4b481c079a6bb640ab19756c3fd4b4b26
2026-03-09 07:26:58 -07:00
Copybara-Service 9362031644 Merge pull request #3112 from LouRohanNV:fixUsdEqualities
PiperOrigin-RevId: 880843178
Change-Id: I23e817364772abab6cea9a0b92f7681b1372c2db
2026-03-09 07:19:09 -07:00
Copybara-Service cc9a474ed8 Merge pull request #3148 from LouRohanNV:usd-visual-prim-mesh-inertia
PiperOrigin-RevId: 880822823
Change-Id: Ib1fe2e4b500f64f44e306eb6adacf8b1c5e39ceb
2026-03-09 06:22:17 -07:00
Sam Haves ed0d7ba29f Move STL handling to a mjpDecoder.
PiperOrigin-RevId: 880820344
Change-Id: Ib3a714dd9698335433e518ed6af17d7b8407a8fb
2026-03-09 06:15:04 -07:00
Kyle Bayes 330c36c99b Fix issue in GJK where the tolerance for x_norm was set too low.
PiperOrigin-RevId: 880735671
Change-Id: I324e37e8677d3c7feeb4b8bcf065a2a0122326b6
2026-03-09 02:14:52 -07:00
Taylor Howell 1370a54007 Update changelog with tendon Jacobian changes and memory improvements for tendon Jacobian and actuator moment fields
PiperOrigin-RevId: 880378857
Change-Id: I761bd209c66f41fc39c9aeaf9832dcb95d7d624c
2026-03-08 03:05:48 -07:00
Taylor Howell 32ace6d303 MuJoCo Warp documentation: box-box collisions
PiperOrigin-RevId: 880376073
Change-Id: Ia7f285ff7bfaf5472790a559294e905749575402
2026-03-08 01:55:32 -08:00
Mark Yang 95724d1ec2 Fix vfs load for mesh gmeshs type 2026-03-07 21:45:12 -05:00
Baruch Tabanpour 6bc6c11c49 Add naccdmax to mjx io.
PiperOrigin-RevId: 879780258
Change-Id: I24f9d0b3205577322bebadc3d03796c8dcadde48
2026-03-06 13:02:55 -08:00
Lou Rohan a1bc4f219f Parse UsdPhysicsJoint enabled attr to set equality->active 2026-03-05 15:45:30 -06:00
Lou Rohan 42ee943ec5 Fix USD equality decoding
- handle when body0 or body1 are the default prim/world
- add site-based equalities to the constrainst list so they aren't skipped
- support connect constraints by checking for spherical joints
2026-03-05 13:31:32 -06:00
Taylor Howell 6a0ebac4b1 Update MJX feature parity documentation
PiperOrigin-RevId: 879098992
Change-Id: Ie82749921e373f4c7d032dc8ff77a7022a9e8ae6
2026-03-05 09:07:02 -08:00
Alessio Quaglino 8dc5cc4c70 Skip tangential components in tactile sensor if mesh has only normals.
PiperOrigin-RevId: 879036130
Change-Id: Ic4184dd535700c5099768dabf5009ba96b218542
2026-03-05 06:35:41 -08:00
Copybara-Service fce504beea Merge pull request #3129 from LouRohanNV:UsdContactExcludes
PiperOrigin-RevId: 879028113
Change-Id: I8798761bf40a8e60ef9aba83337bcabd96813cb9
2026-03-05 06:15:59 -08:00
Haroon Qureshi 45c7376ab4 Set actuator limits correctly.
PiperOrigin-RevId: 879012913
Change-Id: I3f03d09a98236ae9a4dc069564d14437ff5d0a2b
2026-03-05 05:35:14 -08:00
Haroon Qureshi 35c0a25cf4 No-op implementation for mjr_ functions.
This can be useful, e.g. writing tests that don't depend on rendering.

PiperOrigin-RevId: 879012859
Change-Id: Ifb8d7d5bb06a2456c1b4543f0bf4945fe8155039
2026-03-05 05:34:19 -08:00
Copybara-Service f1bcac2952 Merge pull request #2893 from joanllobera:fix/passive-attribute-droped
PiperOrigin-RevId: 878958794
Change-Id: I2d1fe080bd02b5c3e685cefbf36d45821cdfb46d
2026-03-05 03:18:10 -08:00
Haroon Qureshi aef44210cb Rename render to render/classic.
This will allow us to add additional renderers to the `render` folder.

PiperOrigin-RevId: 878913300
Change-Id: I205ae41250cbbcded406ad303d4e801d4cff892e
2026-03-05 01:43:21 -08:00
Haroon Qureshi 5506fbf506 Rename member history_ to sim_history_.
PiperOrigin-RevId: 878906079
Change-Id: I1327f0216bc5042e62c598f2b7f15f6a26c192dc
2026-03-05 01:23:39 -08:00
Copybara-Service 870f9fea24 Merge pull request #3150 from kevinzakka:fix/principal-point-frustum-sign
PiperOrigin-RevId: 878610460
Change-Id: I82e1c30c9c263a9981c619d6a401b417f95c39a2
2026-03-04 12:22:39 -08:00
Copybara-Service b129248be4 Merge pull request #3142 from kevinzakka:simulate-fix
PiperOrigin-RevId: 878575288
Change-Id: Ib3f820d84b0b9bfa25141e4360ddc339abbf0d50
2026-03-04 11:09:19 -08:00
Taylor Howell df3c8a2c28 Update MJX documentation headers
PiperOrigin-RevId: 878568549
Change-Id: I8951211b39bf306082fd8c6631c2afddbf34951d
2026-03-04 10:53:59 -08:00
Sam Haves b25f8433fe Refactor USD connect and weld equality decoding to align with MuJoCo's relpose semantics.
The relpose in mujoco represents the anchor in body1 space and the relative orientation of body2 in body1 space. Previously we were computing it as the relative position of body2 from body1 space.

Further, we now properly account for the setting of strictly the anchor and not the relpos by setting localPos0 *only*.

PiperOrigin-RevId: 878506356
Change-Id: I83fc7e97cd1a891e17f0bb091f8950b581be0e01
2026-03-04 08:34:09 -08:00
Haroon Qureshi 8ddb5ff97b Re-add ${CMAKE_ARGS} to script which was removed by mistake.
PiperOrigin-RevId: 878491532
Change-Id: Idc2a3b17617ca2b44f279c97d8d56917f6c1bf54
2026-03-04 07:56:49 -08:00
Lou Rohan 1378ab6d58 Fix indentation 2026-03-04 09:55:59 -06:00
Haroon Qureshi 64597f45d3 Move function that parses the graphics mode from a string into graphics_mode.cc.
PiperOrigin-RevId: 878482669
Change-Id: I8b713bc740c5711b9c7cc9ea63c21bad42cd2943
2026-03-04 07:30:23 -08:00
Haroon Qureshi c70b05e037 Make Renderer more self-contained.
The Renderer should configure the context and flip the image when
in classic mode and not rely on the Window to do so.

PiperOrigin-RevId: 878480986
Change-Id: I1af899107647469659662abd85527cdf66f507f4
2026-03-04 07:26:34 -08:00
Alessio Quaglino 15d8fc13b9 Add user sensor visualization in simulate. This is triggered when the product of sensor_intprm[0] and sensor_intprm[1] is equal to the sensor data dimension divided by 3 (the RGB channels).
PiperOrigin-RevId: 878473154
Change-Id: Icb3d7e9b766c49e3a9abe3f8bceea57e18e43328
2026-03-04 07:09:01 -08:00
Alessio Quaglino 4e83e813d7 Update tactile sensor docs.
PiperOrigin-RevId: 878468033
Change-Id: I0f36589877f3a93b596a9f848468f11a1ada9dfb
2026-03-04 06:52:48 -08:00
Haroon Qureshi 20efb8ee8d Add missing files.
PiperOrigin-RevId: 878445886
Change-Id: Ied34a5517c3aefc0985bef100431081a4cbfb640
2026-03-04 05:51:36 -08:00
Haroon Qureshi 13d164063c Remove separate targets for classic and filament renderer.
The platform::Renderer now supports both implementations at
runtime.

PiperOrigin-RevId: 878427862
Change-Id: I2997c197c6eddbe177c77b435cc5848fd80f1839
2026-03-04 04:56:15 -08:00
Haroon Qureshi 84682a46b0 Refactor spec editing logic into its own class.
The SpecEditor improves spec editing by keeping
track of what's being edited and how it changes
over time.

PiperOrigin-RevId: 878410011
Change-Id: I7c323eeb30178dad31946095a727a21b3955f19a
2026-03-04 04:01:56 -08:00
Haroon Qureshi 73f73d94f7 Merge renderer+offscreen mode into unified graphics mode.
Allow Studio app to switch between graphics modes dynamically.

PiperOrigin-RevId: 878396966
Change-Id: I666fe3d2452de5404b9be2bd1d017eabec789aef
2026-03-04 03:19:58 -08:00
Kevin Zakka 77ce80bc63 Fix swapped vertical frustum bounds for cameras with principal point offset.
The frustum_top and frustum_bottom assignments in mjv_updateCamera used
the wrong elements of the zver array, causing the principal point cy
offset to be applied with an inverted sign. This shifted the rendered
image vertically by 2*cy pixels.
2026-03-04 01:03:55 -08:00
Kyle Bayes 8ab791fdf7 Don't produce mesh polygon data unless graph data is present. This fixes some nondeterminism in the compiler.
Repro instructions (note compiler cache and threading must be enabled):

Assume we have a cube.stl mesh containing face data and the following XML:

<mujoco>
  <asset>
    <mesh name="cube" file="cube.stl"/>
    <mesh name="unused" file="cube.stl"/>
  </asset>
  <worldbody>
    <geom type="mesh" mesh="cube"/>
  </worldbody>
</mujoco>

Suppose Thread A processes "cube" and Thread B processes "unused". Thread A will generate the mesh hull and will generate polygon data from faces from qhull. Thread B will NOT generate the mesh hull and will generate polygon data from faces coming from mesh file. Thread A beats Thread B to caching the mesh.

When "unused" is later pulled from the cache it gets the polygon data that was generated from "cube" which is not the same that was generated from "unused".

PiperOrigin-RevId: 878336494
Change-Id: I275b09b44490c54b2a5f09d91d0cc047026090f2
2026-03-04 00:36:48 -08:00
Baruch Tabanpour a8d6b0c848 Fix extra dim for depth, matches rgb output shape.
PiperOrigin-RevId: 878098932
Change-Id: Ifcc4ba39dbee1beeea88fda44c3d20b88179705e
2026-03-03 13:26:41 -08:00
Lou Rohan b1908c475c Call ParseMjcPhysicsMeshCollisionAPI() on visual prims that have an inertia attribute 2026-03-03 15:13:23 -06:00
Kyle Bayes 490c1f4126 Refactor mj_collideGeoms.
PiperOrigin-RevId: 878091736
Change-Id: I738c2e5a21036d859b7b163cb000dc516b63a878
2026-03-03 13:11:14 -08:00
Sam Haves 91d3565cd5 Move OBJ handling to a mjpDecoder.
PiperOrigin-RevId: 878041994
Change-Id: I6e7f6876e65fd2184ff5637d4268644cefcabecf
2026-03-03 11:22:02 -08:00
Google DeepMind 0974612338 Reformat README.md for better readability.
Wrap long lines to 80 characters.

PiperOrigin-RevId: 877983563
Change-Id: I10db94397eb3c2db070734ae78073073eefa0184
2026-03-03 09:21:18 -08:00
Copybara-Service c94a5f3bad Merge pull request #3117 from MatiasManevi:wasm-npm-package
PiperOrigin-RevId: 877896112
Change-Id: If12a71df7faab1cb779011b216d86c939a510edd
2026-03-03 05:35:35 -08:00
Taylor Howell ace8e52407 MuJoCo Warp documentation: Physics callbacks
PiperOrigin-RevId: 877837005
Change-Id: Ic2a44b75790ca43548245889c17ce2df8d9d4ac8
2026-03-03 02:38:44 -08:00
Kevin Zakka 327f05a567 Fix macOS crash on viewer close (NSScreen main-thread assertion)
Hiding the dock icon after the viewer window closes triggers an
asynchronous screen/dock reconfiguration via SkyLight. Without
draining the main run loop, the resulting NSScreen invalidation
notification is dispatched to a GCD worker thread, which hits
NSScreen's main-thread assertion and crashes the process.

Drain the main NSRunLoop briefly after setActivationPolicy: so the
reconfiguration is processed on the main thread.
2026-03-02 12:48:38 -08:00
Kevin Zakka 6f52631a2a Fix process hang on viewer close in launch_passive
WaitForAtomicNoGil spins until the render loop consumes a pending
set_texts/set_figures/set_images request (atomic == expected). If the
user closes the viewer window after a request is submitted but before
the render loop consumes it, the render loop exits and the atomic is
never updated. The calling thread spins forever, preventing the
process from terminating.

Check exitrequest inside the spin loop so the wait bails out once the
viewer is shutting down.
2026-03-02 12:21:34 -08:00
MatiasManevi 07fdf1f465 Cleanup wasm package script 2026-03-02 15:20:44 -03:00
Kyle Bayes a06c091157 Fix repeated call to restrict pointer.
PiperOrigin-RevId: 877451707
Change-Id: I4849ccb8562ea1926173209da9934c11de64a109
2026-03-02 10:03:19 -08:00
Kyle Bayes d00ddea269 Merge mjc_ccdIteration into mjc_penetration.
PiperOrigin-RevId: 877432442
Change-Id: I6bffb36522f9e4f0e7b1023003e70df064e1ebb7
2026-03-02 09:17:56 -08:00
Alessio Quaglino bf74d01d93 Add collisions between flexes and SDF geoms.
The flex-SDF algorithm uses the same logic as mesh-SDF. Previous to this change, the flex was instead colliding with the convex hull of the mesh generated automatically with marching cubes from the SDF.

PiperOrigin-RevId: 876420302
Change-Id: I3bf6552b6b8e108ba4c4209bbcf10fe5f2b2fd90
2026-02-27 14:35:27 -08:00
Alessio Quaglino c2e67ab507 Refactor Mesh-SDF collision to use farthest point sampling and mjMAXCONPAIR.
Deleted MAXMESHPNT farthest point sampling instead of sorting by penetration distance is now used to select the best contact points, up to mjMAXCONPAIR. Deleted MAXSDFFACE, the BVH traversal now directly calls a function to process each leaf face against the SDF, instead of collecting face indices and processing them in a separate loop. This reduces memory by removing the need to store all intersecting face indices.

PiperOrigin-RevId: 876296914
Change-Id: I8068d634e2a01ffa9357d0c5381219d097e97abe
2026-02-27 09:42:16 -08:00
Baruch Tabanpour 67b6ab0589 Update mjx-warp docs.
PiperOrigin-RevId: 875966048
Change-Id: I333e8562f3db333f6c64af67cee1f735cb21232d
2026-02-26 17:26:31 -08:00
Baruch Tabanpour 07cda5a3c4 Refactor MJX warp RenderContext, get rid of brittle pytree owner pattern.
PiperOrigin-RevId: 875901011
Change-Id: I2ba0734d9ca001ff91361aab6412fe370919344b
2026-02-26 14:49:32 -08:00
Haroon Qureshi 07d7bc95e3 Expose vsm blur width parameter.
PiperOrigin-RevId: 875733943
Change-Id: Ic8cb423104d2e62ce295f6a2ab6fd67d548910a6
2026-02-26 08:23:30 -08:00
Sam Haves b71cdfb4ec Fix documentation describing relpose for weld equality.
The documentation incorrectly claimed the position elements in relpose described body2 relative to body1 when it instead is meant to describe the position of the anchor relative to body1.

PiperOrigin-RevId: 875722437
Change-Id: Ib3b1fd9d14976623b08511068ea9e11746a28b02
2026-02-26 07:53:59 -08:00
Alessio Quaglino 47a750d4a6 Restore mesh-SDF collisions.
This CL rolls back the change from changelist 794576123 since the previous version was more robust and stable. Compared to the original algorithm, this changes handles degenerate and very large triangles as well.

BEGIN_PUBLIC
Restore mesh-SDF collisions.
END_PUBIC

PiperOrigin-RevId: 875716983
Change-Id: If0de41dc7bbd60460779821d2338cf2d661f40d5
2026-02-26 07:39:34 -08:00
Sam Haves 0ec836b281 Rollback of Move OBJ handling to a mjpDecoder.
PiperOrigin-RevId: 875705083
Change-Id: I21403d84abd56ef72de915bddc724fe3efa506e6
2026-02-26 07:04:39 -08:00
Haroon Qureshi 55d7226b06 Improve error handling of spec editor compilation.
PiperOrigin-RevId: 875703124
Change-Id: Idf4a90a48d75185ad03e4469cee9098104751d67
2026-02-26 06:59:31 -08:00
Copybara-Service 19b583a421 Merge pull request #3134 from kevinzakka:sensoracc-rnepost
PiperOrigin-RevId: 875703097
Change-Id: I564c1afa1cc1f88a712984c6714611056f6e26eb
2026-02-26 06:58:48 -08:00
Haroon Qureshi 137a504625 Add imgui stdlib target.
PiperOrigin-RevId: 875686702
Change-Id: Ie8ba8349c70da3313a1896b14a30d076f2068368
2026-02-26 06:13:38 -08:00
Haroon Qureshi a9675fbaa6 Add an Editor panel.
The editor panel allows you to add, remove, and modify spec elements
as well as recompiling and loading the spec.

Also includes utilities for handling vertically split panels.

PiperOrigin-RevId: 875658785
Change-Id: I18b10971d587db5eb1e65a033e1dc042faac7f1d
2026-02-26 04:51:02 -08:00
Yuval Tassa 7232ec3b47 Refactor constraint tree iteration and island assignment.
- Simplified constraint tree discovery with a unified iterator.
- Filling in a new `efc_tree` array to avoid calling tree discovery again in the constraint phase.
- Implemented dof skipping in the dense case for efficiency.

PiperOrigin-RevId: 875440387
Change-Id: Id44a5a6fe2a80edaaf30935506a023a307e21303
2026-02-25 18:48:59 -08:00
Haroon Qureshi b7e192e514 Expose VSM EL options.
PiperOrigin-RevId: 875368470
Change-Id: Ic6e05c82b57ffa3b1ff49baf4e3cd2c9480c9ba2
2026-02-25 15:36:55 -08:00
Kevin Zakka 43cde9716c Fix mj_sensorAcc returning zero after mj_step1 by clearing flg_rnepost in mj_step2.
Fixes #3133.
2026-02-25 14:04:33 -08:00
Haroon Qureshi 42d843a0fd Separate mjModel/mjData ImGui table helper from mjSpec ImGui table helper.
There are enough differences between how the two are structured that
having separate implementations makes things easier to implement
despite some minor code duplication.

PiperOrigin-RevId: 875287973
Change-Id: Id49e089e5e1944291ce79e79f8cb71d048a942cc
2026-02-25 12:37:31 -08:00
Taylor Howell 53fadd9d63 Improve nJmom by counting number of dofs for slidercrank and site transmissions
PiperOrigin-RevId: 875233737
Change-Id: I2cf3afad7e29e176a4f5a917dd35cfad99b2b0a3
2026-02-25 10:41:24 -08:00
Sam Haves b907ffedaa Move OBJ handling to a mjpDecoder.
PiperOrigin-RevId: 875194599
Change-Id: I2cccc683d69a217f1817e70d16bc1815e366d00c
2026-02-25 09:13:09 -08:00
Haroon Qureshi abdea379af Allow the shadow type and map size to be configured in data.
PiperOrigin-RevId: 875179785
Change-Id: I638c8c8c9e45dd58f393684a09f2ab4871911f7a
2026-02-25 08:35:01 -08:00
Yuval Tassa 0c66585e39 Fix typos and minor corrections in MuJoCo documentation and comments.
PiperOrigin-RevId: 875163889
Change-Id: Ic604d6235bf9cb999058f191e3ee41e47ec1a567
2026-02-25 07:56:31 -08:00
MatiasManevi 7dd76bcbd7 Merge branch 'main' into wasm-npm-package 2026-02-25 12:05:20 -03:00
Google DeepMind 940cab2508 Rename MuJoCo WASM output artifacts to mujoco.*.
This change updates the Emscripten build to output files named `mujoco.js`, `mujoco.wasm`, and `mujoco.d.ts` instead of `mujoco_wasm.*`. The internal CMake target name remains `mujoco_wasm` to avoid conflicts. The package name in `package.json` is also updated to `mujoco`. New enum tests are added.

PiperOrigin-RevId: 875140314
Change-Id: Ie03e0d1db2d03dd8582d5bfcb260b3d33549c2c9
2026-02-25 06:50:37 -08:00
Haroon Qureshi 757758dd2e Rename all filament mjr_ functions to mjrf_.
Rename stubs.cc to mjr_compat.cc. This library acts like a
"compatibility layer" that allows the filament renderer to
be implemented behind the mjr API.

PiperOrigin-RevId: 875114054
Change-Id: I5c47581cacbcadff4c78d2ad15728cc1c3a394ad
2026-02-25 05:43:50 -08:00
Alessio Quaglino 22e3217fc0 Replace TriangleMeshDistance with custom BVH-based SDF computation.
The `mjCOctree::ComputeSdfCoeffs` function has been replaced by `mjCOctree::ComputeSdf`. The new implementation removes the dependency on the `triangle_mesh_distance` library. Instead, it uses a provided `mjCBoundingVolumeHierarchy` to perform closest point queries on the mesh. The signed distance is computed by finding the closest triangle face via the BVH and determining the sign based on the dot product of the vector from the closest point on the triangle to the octree vertex and the triangle's normal.

Optional Laplacian smoothing has been added to the SDF coefficients. This helps smooth out potential discontinuities at octree level boundaries.

PiperOrigin-RevId: 875093374
Change-Id: I6fa53243a2dda107ccf255bc6b876ca5a4554d4f
2026-02-25 04:47:46 -08:00
Taylor Howell 52ed96bc3a Move tendon sparsity fields from mjData to mjModel
PiperOrigin-RevId: 875087590
Change-Id: I1a5489d2d2011795ee38b09d547e68acd72e3cc7
2026-02-25 04:32:11 -08:00
Matija Kecman 253494739a Read the clear color from the model if available
PiperOrigin-RevId: 875079722
Change-Id: Id5a9c359d19f46d1c0bb5fbf5043db0ee4b1b9b6
2026-02-25 04:09:27 -08:00
Kyle Bayes 84205f7dd0 Isolate libccd logic in mjc_penetration.
PiperOrigin-RevId: 875073780
Change-Id: I71bd39695aa667110fffff47f34cd98faa562cc6
2026-02-25 03:53:34 -08:00
Kyle Bayes cd8bfb90c3 Improve polygon creation logic in compiler.
PiperOrigin-RevId: 875070301
Change-Id: I06e851f3450035fff68b99997406d6ea471ce3b8
2026-02-25 03:40:07 -08:00
Taylor Howell d0fc1c2c83 MuJoCo Warp documentation: SDF plugins
PiperOrigin-RevId: 875063400
Change-Id: Iefa014e3c046a965722c633df0b19771ab481375
2026-02-25 03:16:54 -08:00
Haroon Qureshi ae7efead09 Show MuJoCo version in the help menu.
PiperOrigin-RevId: 875061430
Change-Id: I4d4ce32eebd8ca4af4622e9b4d1cd50d180d0b96
2026-02-25 03:11:13 -08:00
Yuval Tassa 27dc92b056 Fix typo in modeling.rst.
PiperOrigin-RevId: 875053694
Change-Id: Idb6d09d2713f2cc2a09d2b0912a227fe9ac9396a
2026-02-25 02:51:26 -08:00
Yuval Tassa 40e0007849 Restructure numeric constants table in API docs
Break the monolithic numeric constants table into 6 sub-grouped tables:
Version, Engine constants, Array sizes, Visualization, Rendering, UI constants.

Fix stale values: mjMAXUITEXT (500->300), mjMAXUIMULTI (20->35),
mjMAXUIEDIT (5->7), mjMAXUIRECT (15->25).

Add missing constants: mjMAXLIGHT, mjMAXMATERIAL.

Fix placeholder description for mjMAXFLEXNODES.

PiperOrigin-RevId: 875010581
Change-Id: Id47846de4d98b62cb96087b72ecd28358d5db9c7
2026-02-25 00:54:35 -08:00
Google DeepMind a83fa7299d Add support for loading XML models with VFS in WASM bindings.
PiperOrigin-RevId: 874756898
Change-Id: If2c30aef4c690cf0852587261ca32a3b91448621
2026-02-24 13:09:20 -08:00
MatiasManevi bad7e29d3b Cleanup readme and publish step 2026-02-24 17:16:21 -03:00
MatiasManevi c17eb431cb Move publish step to sh file 2026-02-24 17:04:12 -03:00
Alessio Quaglino 09c7633a76 Add caching for flex stiffness computation.
This change introduces methods to cache and load the computed stiffness matrix and nodal masses for flex elements. The cache key is generated based on material properties (Young's modulus, Poisson's ratio), interpolation order, and the bounding box of the flex. This avoids redundant expensive computations when compiling models with identical flex definitions.

PiperOrigin-RevId: 874689771
Change-Id: I6d1e299baf294a984b507e2a2602b2c068610536
2026-02-24 10:45:23 -08:00
MatiasManevi 1db1dfe6a0 Remove empty lines 2026-02-24 15:08:57 -03:00
MatiasManevi 3bbb548991 Add memory management section to readme 2026-02-24 15:04:18 -03:00
Copybara-Service f383e60721 Merge pull request #3130 from MatiasManevi:fix-wasm-demo
PiperOrigin-RevId: 874640066
Change-Id: Ib869283e36343f41cb13cce7405aca3a1584b76e
2026-02-24 09:04:11 -08:00
Google DeepMind 94acdb33bd Fix Impl.CPP memory leaks due to mjModel/mjData not clearing from pytree.
PiperOrigin-RevId: 874622402
Change-Id: I38a00633dea77d940e4b0422f93e9456ad84daf9
2026-02-24 08:17:06 -08:00
Haroon Qureshi 1d6ff2cece Display Bodies as a tree in Spec Explorer.
Display all other elements under "Elements" or "Assets" group.

Show properties for mjSpec, mjModel, and mjData for selected
elements.

PiperOrigin-RevId: 874614195
Change-Id: I128c2bec844983ac5d35a3a0b1e58b8a5b0109cb
2026-02-24 07:57:44 -08:00
Alessio Quaglino 5fc580a8ba Refactor SDF coefficient computation into mjCOctree.
The logic for computing Signed Distance Function (SDF) coefficients using TriangleMeshDistance is moved from `mjCPlugin::Make` in `user_mesh.cc` to a new method `mjCOctree::ComputeSdfCoeffs` in `user_objects.cc`. This encapsulates the SDF computation within the octree class.

PiperOrigin-RevId: 874572414
Change-Id: Ia2365c9c4527a252ff1d1bb43fe2c2593761e471
2026-02-24 06:03:59 -08:00
MatiasManevi c791f950cb Enable COOP/COEP headers for wasm Vite dev servers 2026-02-23 18:41:47 -03:00
MatiasManevi f27b8d3d70 Move notes into example application section 2026-02-23 18:13:44 -03:00
MatiasManevi f989d40d89 Merge wasm readme for package 2026-02-23 18:11:20 -03:00
MatiasManevi 12c2e98a61 Modify npm package keywords 2026-02-23 17:42:44 -03:00
MatiasManevi c6564b1f79 Change package name and artefacts 2026-02-23 17:40:29 -03:00
Sam Haves 82e92cbcaa Remove PluginTest and make MujocoTest load plugins.
MujocoTest now loads plugins from MUJOCO_PLUGIN_DIR if set.
PluginTest is removed; all tests use MujocoTest directly.
testspeed binary loads plugins from MUJOCO_PLUGIN_DIR.

This is in preparation for moving common asset format parsing (obj, msh, stl, etc.) where we will always want to load those plugins.

PiperOrigin-RevId: 874194428
Change-Id: Id90805a9ba5de4627911b56d8b9c4ab4e1b29310
2026-02-23 12:15:22 -08:00
Lou Rohan e895820e24 Check for the UsdPhysicsFilteredPairsAPI in the body parsing function 2026-02-23 12:51:02 -06:00
Lou Rohan 4fe8f73e44 Add USD parsing for contact excludes
- Contact excludes use the UsdPhysicsFilteredPairsAPI schema. Body1 is the body with the schema, body2 is contained in the list of filtered targets within the schema.
2026-02-23 12:44:48 -06:00
Taylor Howell 6ec808e2ce Fix attach for spatial tendon. Fixes #3119.
PiperOrigin-RevId: 874067521
Change-Id: If8d415278dde2bccf269cc90e8c176e3d7edefa6
2026-02-23 07:38:43 -08:00
Michael Moss a043df6bdf Update supported Python versions and remove obsolete 3.9 references.
PiperOrigin-RevId: 874063785
Change-Id: Ia4b2956b632aae5f0211fa766b6d413edcba8fe2
2026-02-23 07:29:47 -08:00
Taylor Howell 37e993f67e Improve upper bound for nJmom by computing maximum number of dofs for tendon transmissions
PiperOrigin-RevId: 874057077
Change-Id: I83736719cc2d91a899cd5997ea4a91d21cf06c9e
2026-02-23 07:11:31 -08:00
Taylor Howell 2bf9539234 MJX put_data with impl='warp'
PiperOrigin-RevId: 874017611
Change-Id: I23a25727d41cd888d90f2ea15b2b534eba5583be
2026-02-23 05:20:07 -08:00
Yuval Tassa ba0a5fe4db Fix section underline length in MJWarp docs
PiperOrigin-RevId: 873954878
Change-Id: I40b668b24d04721d8fd4bb61bb5ac7b902ea31f1
2026-02-23 02:25:10 -08:00
Taylor Howell 6b9e0b9e15 MJX API documentation: add Any to exclude-members
PiperOrigin-RevId: 873954713
Change-Id: Iafbdb571c4e5b0491d7d91159e84874c58c01a71
2026-02-23 02:24:06 -08:00
Yuval Tassa 9d6d9089e5 Improve solver parameter documentation, in particular for frictional constraints.
PiperOrigin-RevId: 873364458
Change-Id: Ie4da21abc2ee54d9eaaefc81b3d2624a520ad96e
2026-02-21 09:14:56 -08:00
Taylor Howell c428f675e7 MuJoCo Warp documentation: Update installation instructions
PiperOrigin-RevId: 873032865
Change-Id: I7f75de9ed0d9239b47bc80b321f213aa4014fda6
2026-02-20 12:45:23 -08:00
Baruch Tabanpour 0f36b0fc2e Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 872969263
Change-Id: Ic890cb53c32593c158a1f3926906b492c7f85348
2026-02-20 10:29:13 -08:00
Baruch Tabanpour e5a236774d Add has_side_effect for pmap bvh refit in mjx-warp.
PiperOrigin-RevId: 872934001
Change-Id: If48cab439718b9e783c4b1da4fb1b1a08521a602
2026-02-20 09:21:43 -08:00
Haroon Qureshi 7d4b615edb Use correct WIN32 define, not WINDOWS.
PiperOrigin-RevId: 872866601
Change-Id: I35bb5cc0fdef80cf816a63bb7fc1619ef424c0d0
2026-02-20 06:10:00 -08:00
Alessio Quaglino f9a39413cf Fix: Include ancestor DOFs in flex interpolation factorization.
The reduced dense factorization for flex interpolation now considers all DOFs in the kinematic chain of the body containing the flex, using mj_bodyChain, instead of only the DOFs directly associated with that body. This is necessary for correctly handling pinned flexes when their parent body is part of a larger kinematic structure.

PiperOrigin-RevId: 872854468
Change-Id: Idbe9fb459084dde9e8eb1076c70dbb685c1b0bdb
2026-02-20 05:30:54 -08:00
Haroon Qureshi 8c9ba9bcf5 Disable plugin on windows.
PiperOrigin-RevId: 872845569
Change-Id: I4d80c80a47358a2882b2c63c2d655fe374afe65d
2026-02-20 05:00:04 -08:00
Haroon Qureshi f71e215c9a Include missing header.
PiperOrigin-RevId: 872835150
Change-Id: I670bddb907b594788bda143c5175bbcb4b427903
2026-02-20 04:23:59 -08:00
Haroon Qureshi 0083cf7fa8 Refactor the projectile launcher into a plugin.
Add a simple GUI for it that allows users to enable/disable
the key binding as well as control some parameters.

PiperOrigin-RevId: 872816645
Change-Id: I8abb2803e17b4f6195d447220c436d4701b24db8
2026-02-20 03:19:53 -08:00
Haroon Qureshi 28ad603f6b Use templates and macros to reduce boilerplate.
PiperOrigin-RevId: 872805912
Change-Id: I6fc1abe283bc809a95d660abc072906b0810aaeb
2026-02-20 02:42:52 -08:00
Copybara-Service a79747334b Merge pull request #3116 from StafaH:render_doc_fix
PiperOrigin-RevId: 872799423
Change-Id: Iafd5f05264043cb2060f147c4c047ba849b28475
2026-02-20 02:22:32 -08:00
Haroon Qureshi f0bf403254 Add a delete button to the highlighted element.
PiperOrigin-RevId: 872795277
Change-Id: I63afa9c87b425ebed5d20126e9909ad95532d559
2026-02-20 02:09:36 -08:00
Haroon Qureshi 82694b520b Re-apply changes that were accidentally deleted.
PiperOrigin-RevId: 872782055
Change-Id: If2f403835cd2d90c88abe9ed82380dfca5b3d9c8
2026-02-20 01:27:57 -08:00
Matija Kecman 8f56d5eefa Minor style fixes
PiperOrigin-RevId: 872669434
Change-Id: I794173b9fad3a286cbf57d246b2f8672412a0e20
2026-02-19 19:16:31 -08:00
Matija Kecman ca0552c83b Cleanup Studio toolbar
PiperOrigin-RevId: 872618794
Change-Id: I2e8f99dc47937416c8516ed1df7821369211b12f
2026-02-19 16:34:38 -08:00
Alessio Quaglino 8ba68cee3e Limit the number of flex contacts per collision pair.
This change introduces a filter for flex-related contacts, ensuring that no more than mjMAXCONPAIR contacts are kept for each geom-flex, flex-flex, flex internal, and flex self-collision pair. The contacts are sorted using farthest-point sampling:

- Starts with the deepest penetrating contact
- Iteratively selects the contact farthest from already-selected contacts
- Produces a spatially distributed set of contacts

PiperOrigin-RevId: 872593388
Change-Id: I50b233a0dc66da6a297852c258ba514f131c8f23
2026-02-19 15:32:17 -08:00
Taylor Howell fe50efd41a Sparse tendon Jacobian update for MuJoCo Warp
PiperOrigin-RevId: 872550625
Change-Id: Ifc5afacb048bec36ef6455072b188396db958002
2026-02-19 13:52:25 -08:00
Baruch Tabanpour 86bca81d18 Update mjx docs and changelog.
PiperOrigin-RevId: 872535000
Change-Id: I51b05a22ac553c34b436de63f43c7efca6607724
2026-02-19 13:18:10 -08:00
Baruch Tabanpour 62a32386d6 Add pmap support for mjx-warp render.
PiperOrigin-RevId: 872533248
Change-Id: I828303866c31d33d2367dd9fba4eb42028c67540
2026-02-19 13:14:22 -08:00
Taylor Howell 84431fbf7e Improved upper bound for nJten
PiperOrigin-RevId: 872479828
Change-Id: I750d56320d6ace6145475d378cb9d0c30919438d
2026-02-19 11:09:25 -08:00
Taylor Howell 9efe41c0c1 Remove dense code path for tendon Jacobian
PiperOrigin-RevId: 872444531
Change-Id: I6180101abc49469a72aee8bec5726e1e94f142ec
2026-02-19 09:53:49 -08:00
Haroon Qureshi 10524c28dd Track and restore viscous pause state every frame.
PiperOrigin-RevId: 872382150
Change-Id: I96bddcfb2a0a204c6505e9795dfff97f09834855
2026-02-19 07:06:38 -08:00
MatiasManevi a9edc5dd89 Add publish workflow and minimal npm package for WASM 2026-02-19 10:00:17 -03:00
Copybara-Service cdc1f266c6 Merge pull request #3114 from thowell:lint
PiperOrigin-RevId: 872331279
Change-Id: I26848d48e3f66f29f32a9a03ab38f373123abd1d
2026-02-19 04:31:19 -08:00
Mustafa Haiderbhai 3c5986fe50 Minor edit to MJWarp batch rendering documentation 2026-02-19 07:20:31 -05:00
Haroon Qureshi ab80bd0916 Allow model holder to release ownership of mujoco structs.
PiperOrigin-RevId: 872242489
Change-Id: I055f54f4e111cc78c489c12d9ae5c02cfb57169d
2026-02-19 00:06:07 -08:00
Baruch Tabanpour ccd282b036 Update MJX docs with MJX-Warp.
PiperOrigin-RevId: 872083735
Change-Id: Id09b82d1f6e7a69ec34353ba35a63edb5eae1046
2026-02-18 16:02:57 -08:00
Baruch Tabanpour 3c858f871b Keep render_util arg order consistent between mujoco_warp and mjx-warp.
PiperOrigin-RevId: 872055868
Change-Id: Ic5b4bdedbdb353dc0b1385cf555261a86407cfdb
2026-02-18 14:57:06 -08:00
Copybara-Service 57c2316b9e Merge pull request #3080 from kevinzakka:fix-fusestatic-camera-light-crash
PiperOrigin-RevId: 872054304
Change-Id: I9eab499002077afa46b236e8eae13100285f362c
2026-02-18 14:53:30 -08:00
Mustafa Haiderbhai 59bc4fb88e Fix typo and improve wording in render doc 2026-02-18 15:19:00 -05:00
Baruch Tabanpour 485e2eb028 Fix bug in mjx-warp render vmap.
PiperOrigin-RevId: 871901512
Change-Id: Ifc25e98ffd89284cc6db9248bcca352bb8811e7e
2026-02-18 09:10:34 -08:00
Copybara-Service 7d3e1abb21 Merge pull request #3083 from Ashutosh0x:fix/mingw-linker-stack
PiperOrigin-RevId: 871828475
Change-Id: I8abe526a81b9c1f51307729b5dde01aad809ff97
2026-02-18 05:59:41 -08:00
Copybara-Service 42514920c4 Merge pull request #3111 from StafaH:main
PiperOrigin-RevId: 871825088
Change-Id: I1e9c4a559a19427753cfdbacc7c7254ad0cb9c6c
2026-02-18 05:48:03 -08:00
Haroon Qureshi fdf6f1017c Remove enable_keyboard flag.
PiperOrigin-RevId: 871823567
Change-Id: I1e307f366106aa542a66b68b8e057b35c25134c9
2026-02-18 05:43:33 -08:00
Taylor Howell bb0b5ca521 lint 2026-02-18 12:43:31 +00:00
Taylor Howell 8541128853 Update _get_data_into_warp. Fixes #3109
PiperOrigin-RevId: 871790690
Change-Id: I225579f7559ca5c1de92af6606d02ff763f9f4d1
2026-02-18 04:04:29 -08:00
ashutosh0x 50349dc685 Fix MinGW stack flag syntax and Python binding crashes
- Detect linker type (lld-link vs ld) and use the appropriate stack flag: /STACK:16777216 for lld-link, --stack,16777216 for MinGW ld

- Filter out stack-related flags from Python binding modules to prevent crashes when loading MuJoCo as a DLL in Python

Fixes #3011
2026-02-18 14:22:59 +05:30
Haroon Qureshi 6b197e198a Reset free camera when loading a new model.
PiperOrigin-RevId: 871622663
Change-Id: I1f1a4681752f7436c7bc7adbe64dcea286c5620c
2026-02-17 20:08:02 -08:00
Kevin Zakka fa43e2c03b Fix tracking camera detaching when toggling visualization flags, fixes #3108
Toggling visualization flags via keyboard shortcuts (e.g., C for contact points, F for contact forces) causes the SECT_RENDERING event handler to unconditionally re-evaluate the camera selection, which can reset a tracking camera to free mode. This particularly affects users of mujoco.viewer who set tracking cameras programmatically.

Guard the camera update logic so it only runs when the camera selector itself is changed, not when other items in the rendering section are modified.

PiperOrigin-RevId: 871600340
Change-Id: Ia6ef2a1617c6cdc18c7d10b4b099a8f2c620a824
2026-02-17 18:59:33 -08:00
Baruch Tabanpour f6129596a6 Save depth images in visualize_render.py
PiperOrigin-RevId: 871454618
Change-Id: If844e2c4af10e271536c4e6a36e760e8d4d50374
2026-02-17 12:55:39 -08:00
Mustafa Haiderbhai b7875df580 Fixes 2026-02-17 14:54:26 -05:00
Sam Haves 448e221690 Raise ValueError if adding a spec results in a duplicate name.
PiperOrigin-RevId: 871397807
Change-Id: I50742efe7ba194ed3b1fe916f05e35b7fb2d7ec0
2026-02-17 10:54:47 -08:00
Taylor Howell af802a5386 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 871338519
Change-Id: I6ef9b4a4c3b623a87f4c43efa798b6757ac534ae
2026-02-17 08:48:20 -08:00
Taylor Howell 4d256c0ff1 MuJoCo Warp documentation: nccdmax / naccdmax
PiperOrigin-RevId: 871221522
Change-Id: Ia4e5c9a700b809815bd40af048762bfecde9231a
2026-02-17 03:12:50 -08:00
Haroon Qureshi 767e52fb5b Fire projectiles when hitting "Ctrl+Shift+Enter".
PiperOrigin-RevId: 871215312
Change-Id: Ie22699d5446a49ea6997594b2800cf72840554c1
2026-02-17 02:53:31 -08:00
Haroon Qureshi 4ce9fb53ee Re-enable MJZ support.
Disabled on Windows until we can make plugins work correctly.

PiperOrigin-RevId: 871214280
Change-Id: I831238704c2807e70f4347989d642a189764e53c
2026-02-17 02:51:14 -08:00
Alessio Quaglino 8024124572 Use stack allocation for temporary flex rigidity storage in mj_setConst. Fixes #3081
PiperOrigin-RevId: 871200819
Change-Id: Ifbc1c0bd62261325a06a246cb2adb1106c02f829
2026-02-17 02:16:07 -08:00
Haroon Qureshi 989b6e63c7 Add ability to delete bodies.
PiperOrigin-RevId: 871200603
Change-Id: I08bc786ca8106ef13cfcbe89e8cc42e9ad2c99d5
2026-02-17 02:14:54 -08:00
Mustafa Haiderbhai 911124f2c6 Add batch rendering to readme 2026-02-17 00:21:10 -05:00
Haroon Qureshi 8f2799a34b Move renderer.py and gl_context.py into a submodule.
PiperOrigin-RevId: 870789311
Change-Id: Iaa0fcc764a770eeb4570a6a189a5ad032d41d64c
2026-02-16 02:41:35 -08:00
Taylor Howell 66a413419a Reorder Option fields
PiperOrigin-RevId: 870779423
Change-Id: Ie356725810a820e910396abd9daef0f9c9f94abc
2026-02-16 02:18:23 -08:00
Copybara-Service 160e601ba1 Merge pull request #3085 from Ashutosh0x:fix/windows-zero-alloc
PiperOrigin-RevId: 870765044
Change-Id: I91b6a6096fe58200f8b36fda62838046a9ee08fe
2026-02-16 01:47:04 -08:00
Nandini Dhanrale c45f13d3a9 Fix VFS use-after-move crash by using stable handles for mjVFS
Root cause: resources and default mount stored pointers tied to the public mjVFS object address. If mjVFS was moved after initialization, resource close/read paths could dereference stale pointers and crash.\n\nThis change stores a stable internal mjVFS handle inside VFS and points resources/default mount to that stable handle. It also tracks the current public owner pointer and rebinds it in Upcast so lifecycle operations (including self-destruct cleanup) target the current mjVFS address after moves.\n\nAdds regression test UserVfsTest.MoveVfsAfterOpenResource, which opens a resource, moves mjVFS, then reads/closes/deletes successfully.
2026-02-16 12:40:13 +05:30
Saran Tunyasuvunakool 2efca34f58 Fix mjpython after breakage from 496f6b47fc.
PiperOrigin-RevId: 870253531
Change-Id: Icfbfaed41d4cdd3f8472c37a254cb7b1f2a32d7b
2026-02-14 14:32:42 -08:00
Baruch Tabanpour 538c131415 Last bits of mjx-warp render codegen.
PiperOrigin-RevId: 869900622
Change-Id: If86942fddc45b9d71505d7fc4e2345dc120ccab2
2026-02-13 14:55:26 -08:00
Baruch Tabanpour bbfe7fe0e2 Update mjx-warp render with partial codegen.
PiperOrigin-RevId: 869874195
Change-Id: I71a16a6c192873786a09211dc4d326c3a4115ad9
2026-02-13 13:50:07 -08:00
Saran Tunyasuvunakool faf55f7020 Fix header_test.cc.
C++ standard says the argument to alignof must be a type. Clang and GCC are permissive but MSVC isn't.

PiperOrigin-RevId: 869823902
Change-Id: I7e113ce62a60cc9be499e8580846a5258deea001
2026-02-13 11:43:45 -08:00
Baruch Tabanpour fb47ff01cd initial implementation of mjx-warp render.
PiperOrigin-RevId: 869822624
Change-Id: Ic20db1dcc2e7287752b273c4ad986066cceccad9
2026-02-13 11:40:55 -08:00
Matija Kecman 1808079c62 Implement viscous pause in Studio
Viscous pause is like pause but the simulation continues with zero gravity, high viscosity and passive springs disabled. It is useful to move things like cabinets with shelves---just move the shelf and the drawers come along as well.

* Updated the simulation control widgets
* Added Ctrl-space shortcut to toggle play/viscous pause

PiperOrigin-RevId: 869810053
Change-Id: Icf649e1f2631c2a64a5d2f25af9537b6a12bdf2c
2026-02-13 11:11:15 -08:00
Saran Tunyasuvunakool 5274e5f720 Clean up X macros and usages for mjOption, mjStatistic, and mjVisual.
* Replace various MJOPTION_ macros with a single MJOPTION_FIELDS.
* Use XVEC macro to denote vector members where there is a mixture of
  vector and scalar members in a given struct type.
* Split up MJVISUAL_FIELDS into separate macros for each substruct.
* Modify engine_print.c and Python bindings struct.h/cc to use the
  new X macros.

PiperOrigin-RevId: 869760513
Change-Id: Idac4fe9aa99f0258e7c79802ca9023a0d4486e2d
2026-02-13 09:10:36 -08:00
Haroon Qureshi 6d8b6028e2 Tweak default lighting and specularity for non-PBR scenes.
Most "classic" objects looked washed out. To "revert" to the old look, you can add the following to your XML files:

```
<custom>
    <numeric name="filament.phong.specular_multiplier" data="0.1"/>
    <numeric name="filament.fallback.scene_light_intensity" data="100000.0"/>
    <numeric name="filament.fallback.environment_light_intensity" data="10000.0"/>
</custom>
```

PiperOrigin-RevId: 869725829
Change-Id: Icab0cedaa27915400497745db886c393709c14b1
2026-02-13 07:37:36 -08:00
Taylor Howell 5903d4826f Sparse ten_J and ten_J_colind
PiperOrigin-RevId: 869712136
Change-Id: Id2979684aa0c39552cb8453852483cbac55f0ea3
2026-02-13 06:57:22 -08:00
Yuval Tassa 277f469239 Update sensor delay documentation to use "period" instead of "interval".
PiperOrigin-RevId: 869711956
Change-Id: I981c04aea58b5ce8a1cf8f2cdceba841e7729ccb
2026-02-13 06:56:15 -08:00
Matias Manevi bf39b1172f Copybara import of the project:
--
b1734da56e293b50e7bd0cc8b9a8ee5677aa70ec by MatiasManevi <manevimatias@gmail.com>:

Improve wording for WASM Windows support status

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3095 from MatiasManevi:wasm-readme b1734da56e293b50e7bd0cc8b9a8ee5677aa70ec
PiperOrigin-RevId: 869699309
Change-Id: I2780d2406139e33eeb5521f509245d29b69a61ab
2026-02-13 06:17:27 -08:00
ashutosh0x 04e5df08a9 Update mju_malloc to return NULL for zero-sized allocations 2026-02-13 19:22:05 +05:30
Michael Moss 84f254f7c7 Update benchmark dep and add workaround for Clang breakage.
PiperOrigin-RevId: 869687267
Change-Id: If4ce7a107b1489b30475d8778e7347503298dbbe
2026-02-13 05:39:24 -08:00
Michael Moss 42958aab81 Update MuJoCo version from 3.5.0 to 3.5.1 following the 3.5.0 release
PiperOrigin-RevId: 869654894
Change-Id: I9cacaf4cbb70ad17faa24c3c30ec38ffe91b5deb
2026-02-13 03:54:25 -08:00
Saran Tunyasuvunakool 496f6b47fc In mjpython, check the result of Py_InitializeFromConfig.
This is to properly handle the case where the interpreter wants to exit immediately, e.g. when `mjpython --version` is run.

Currently, we call `PyGILState_Ensure` regardless of the result of `Py_InitializeFromConfig` resulting in a segfault, as in issue #2870.

PiperOrigin-RevId: 869652555
Change-Id: I3a898279eb8aa25afbaece904cfdcc4fdcc92972
2026-02-13 03:44:58 -08:00
Taylor Howell 881544c0c5 Modify MuJoCo Warp dev version check
PiperOrigin-RevId: 869311325
Change-Id: I2f34bd932d7998d37b96b36e5d561f734567b8d5
2026-02-12 11:39:28 -08:00
Michael Moss 716ae107c6 Update dependencies and changelog ahead of the 3.5.0 release.
PiperOrigin-RevId: 869221912
Change-Id: I77aa1f898009c5d24218434863d0588ddf8a058b
2026-02-12 08:08:14 -08:00
Michael Moss 16c58b9951 Fix RC file syntax error for pedantic compilers. Fixes #839
PiperOrigin-RevId: 869211177
Change-Id: I42a0dacde6ca6652df1803033c2b96a7c7076616
2026-02-12 07:40:06 -08:00
Yuval Tassa 54b8b68b23 Prepare changelog for release
PiperOrigin-RevId: 869124525
Change-Id: I7ea6f3c1cf163e98b1bc0b8ed87f8e44afd59ab5
2026-02-12 03:16:34 -08:00
Yuval Tassa 14116336e0 Clarify time argument semantics in delayed actuator/sensor reads.
PiperOrigin-RevId: 869123314
Change-Id: Ib36ef6cfc8d12d1b8a9c98eadc144953447fc444
2026-02-12 03:12:45 -08:00
Yuval Tassa c54f1fe380 Use semantic versioning.
PiperOrigin-RevId: 869102767
Change-Id: I8b01b9343289d4ad7d15bcc3634a28e661308a90
2026-02-12 02:11:20 -08:00
Yuval Tassa a8cf4e012d Add Colab link for System Identification toolbox.
PiperOrigin-RevId: 869091889
Change-Id: Ib5ec2e451c7037cc92b4cb1a9c58d05f0049b298
2026-02-12 01:41:40 -08:00
Haroon Qureshi 8e5436c335 Make phong-shading multipliers configurable.
PiperOrigin-RevId: 869080920
Change-Id: I4eb7311b54270d596c09a01d6725c1efb931de4b
2026-02-12 01:09:30 -08:00
Kevin Zakka 2396a2541c Copybara import of the project:
--
4cabc9c52dc07ea2d64a3de6dbd58e47a2ad023c by Kevin Zakka <kevinarmandzakka@gmail.com>:

Add system identification tutorial and fix template packaging

- Add sysid tutorial notebook (sysid.ipynb)
- Include HTML templates in package-data to fix TemplateNotFound errors
  when pip installing mujoco[sysid]

COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3092 from kevinzakka:sysid-notebook 4cabc9c52dc07ea2d64a3de6dbd58e47a2ad023c
PiperOrigin-RevId: 868900119
Change-Id: I53c4cc94b5fb6f864c5cee589af9dfad9bfc8744
2026-02-11 16:43:08 -08:00
Yuval Tassa 6af0d4c823 Replace margin/gap max with sum.
PiperOrigin-RevId: 868842521
Change-Id: Ia4a4ca5c6821c5a7b3ba7b0af7f71d981c2866c1
2026-02-11 14:22:27 -08:00
Google DeepMind 336e1026a4 Sparse ten_J and ten_J_colind memory
PiperOrigin-RevId: 868834376
Change-Id: Iec92d9e09e3134666895e54a78cb02439d74a4de
2026-02-11 14:05:43 -08:00
Yuval Tassa b466829482 Fix implicit integrator derivatives when actuator force is clamped.
The derivatives of actuator velocity with respect to generalized velocities were incorrectly computed when the actuator force was limited by `forcerange`. This CL adds a check to zero out these derivatives when the actuator force is at its upper or lower limit, as the force is no longer a function of velocity in this clamped state.

PiperOrigin-RevId: 868818281
Change-Id: I89742a3f04989dd11f9cfada107200015b1472a7
2026-02-11 13:31:07 -08:00
Taylor Howell d011285380 Sparse ten_J and ten_J_colind memory
PiperOrigin-RevId: 868800229
Change-Id: Id83f9fd40dd9bece06fd99753e4202eea17ca884
2026-02-11 12:45:50 -08:00
Taylor Howell 94e834bf4f Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 868759523
Change-Id: I83a9f014840e66d7775a3684aa2e59ec5a077191
2026-02-11 11:14:24 -08:00
Yuval Tassa 883ba2134d Add System Identification toolbox to changelog.
PiperOrigin-RevId: 868759286
Change-Id: I7845c0858a9ba8188f02b84259306f2638823267
2026-02-11 11:13:27 -08:00
Adrian Collister d881e9e374 Change tex_adr type to mjtSize.
Adds a test which verifies that we can index into the texture buffer at offsets larger than can be represented by a 32-bit signed int.

PiperOrigin-RevId: 868756646
Change-Id: Ibc1a2b269fce41aec370611b0aab77803837e7a8
2026-02-11 11:09:36 -08:00
Yuval Tassa 2b5afce4aa Fix island graph construction for multi-tree constraints, fixes #3073
Replace dynamically-sized edge list with a dense ntree×ntree adjacency matrix for deduplication and a flat CSR representation.

PiperOrigin-RevId: 868728432
Change-Id: Iebe97a0870740e5465549b967bbde0c81e658269
2026-02-11 10:05:32 -08:00
ashutosh0x c962188655 Fix zero-sized allocation crash on Windows
On Windows, _aligned_malloc(0) returns NULL, which MuJoCo interprets as a fatal out-of-memory error. This causes crashes on models with empty arrays.

Ensure a minimum allocation of 64 bytes for any 0-sized request.

Fixes #2992
2026-02-11 22:33:28 +05:30
ashutosh0x 2ab76ec4f5 Fix MinGW stat redefinition and thread-safe localtime
- Guard #define stat _stat with !defined(__MINGW32__) to avoid conflicts with MinGW's own POSIX-compliant stat implementation

- Replace _MSC_VER check with defined(_WIN32) for localtime_s to allow all Windows compilers including MinGW to use the secure function

Fixes #3038, #3037
2026-02-11 22:32:21 +05:30
Google DeepMind cc5d544d15 Update typos in sysid/README.md
PiperOrigin-RevId: 868690171
Change-Id: Iffc71fb7bad73e18be767429600936014095ed9e
2026-02-11 08:25:56 -08:00
Copybara-Service e9de358bfc Merge pull request #3076 from yurekami:fix/plugin-symlink-loading
PiperOrigin-RevId: 868602117
Change-Id: Ice4d7991f46dad45736864baebd7378cc24e9d4f
2026-02-11 04:13:41 -08:00
Copybara-Service 91751a506b Merge pull request #3082 from aftersomemath:sysid-pr2
PiperOrigin-RevId: 868599752
Change-Id: Ifb57f34857d542b542b8ac9f047397c651f8008b
2026-02-11 04:06:44 -08:00
Yuval Tassa 7f74487a26 Fix implicit integrator derivatives for actearly actuators.
The derivative calculation for actuator velocity in implicit integrators now correctly accounts for the `actearly` flag, using the next activation value when `actearly` is true.

PiperOrigin-RevId: 868598722
Change-Id: Ia180afb15b31a718170aeaf9d4ac514bb9e6073b
2026-02-11 04:03:46 -08:00
Levi Burner e89dae359e sysid: named ic construction, bug fixes, docstrings, README, more tests
Co-authored-by: Kevin Zakka <kevinarmandzakka@gmail.com>
2026-02-11 00:22:56 -05:00
Haroon Qureshi 730d494b7f Focus default camera on the model if available.
PiperOrigin-RevId: 868407477
Change-Id: Iac37bcfe8657dededeeecc70db3e4ac18f8ef151
2026-02-10 18:17:33 -08:00
Sam Haves 6715a0ceaa Expose mju resource functions to public header.
Many of these functions are useful when writing a custom decoder.

PiperOrigin-RevId: 868321921
Change-Id: I7e0dd285e0559b6f486acf8cbf4376ff8d91943d
2026-02-10 14:31:41 -08:00
Baruch Tabanpour 210cf86486 Use kernel cache dir per mjx-warp test fixture.
PiperOrigin-RevId: 868259579
Change-Id: I9f1346899591ca603ad2e34949d22b78c464c2ad
2026-02-10 12:10:28 -08:00
Alessio Quaglino 419b96cb91 Reduce simulation steps in MjCollisionTest.PinchingSucceeds.
PiperOrigin-RevId: 868229821
Change-Id: I781955a8f06ca2338baa713ff6a3448b4743b35e
2026-02-10 11:05:10 -08:00
Copybara-Service 3ec09f7296 Merge pull request #3079 from aftersomemath:sysid-pr
PiperOrigin-RevId: 868229512
Change-Id: I790bc08fc8b0745583a2f92d9ee2c5a19ba558ea
2026-02-10 11:04:12 -08:00
Baruch Tabanpour 3c107b3047 Add stage_in and stage_out for MJX-Warp.
PiperOrigin-RevId: 868180029
Change-Id: I0d1b17b6023d32498766b5d1d9e5624bd31cda3d
2026-02-10 09:19:09 -08:00
Copybara-Service 7ef3ae6ad1 Merge pull request #3061 from LouRohanNV:fixUsdMaterialInterfaces
PiperOrigin-RevId: 868177637
Change-Id: I2de8f2af3b5fc126d103256b1ea00c5f8c7a8955
2026-02-10 09:12:10 -08:00
Yuval Tassa 4fa062c7e5 Update unreleased MuJoCo version from 3.4.1 to 3.5.0.
PiperOrigin-RevId: 868169291
Change-Id: I8041842811f5f664c80116993315f50d549b5575
2026-02-10 08:52:04 -08:00
Alessio Quaglino e16ee4fcb4 Fix flex-parent coupling in implicit integrator.
The implicit integrator was not correctly accounting for the off-diagonal coupling terms between flex and non-flex (parent) degrees of freedom in the mass matrix. This change extracts these coupling terms during the factorization step and applies a correction to the flex forces before solving for the flex accelerations, ensuring that the parent accelerations influence the flex dynamics. A new test verifies that the implicit integrator now matches Euler for small timesteps in a model with flex-parent coupling.

PiperOrigin-RevId: 868098126
Change-Id: Ia8cccd7dd428cd0c0898e1663a7e41017a2311b2
2026-02-10 05:35:48 -08:00
Kevin Zakka f570ab52a8 Fix segfault in FuseStatic when body contains cameras or lights
FuseStatic deletes static (joint-less) bodies and reassigns their
children to the parent body. Geoms and sites were reassigned, but
cameras and lights were not, leaving dangling body pointers that
crash in mjCCamera::Compile() / mjCLight::Compile().

Add camera and light reassignment in FuseStatic and FuseReindex.
2026-02-09 14:56:51 -08:00
Sam Haves e93a69ea01 Add MjcPhysicsEqualityConnectAPI to MjcPhysics for equality/connect parsing.
PiperOrigin-RevId: 867736241
Change-Id: I2d4e9abcb14280dcfbbf63ff5f888fb57350cfb6
2026-02-09 13:02:42 -08:00
Alessio Quaglino 0041fdcbb0 Add implicit stiffness for flex_interp to mj_implicitSkip.
PiperOrigin-RevId: 867706885
Change-Id: Ic94c65b618a415609bffe3d69a86f9034f2d2400
2026-02-09 11:54:27 -08:00
Yuval Tassa c1b3b3063e Fix gravcomp being ignored for movable bodies without joints. Fixes #3066
PiperOrigin-RevId: 867679545
Change-Id: I8c16d3a4c93d121fcc30cab5179ba44fe49aaa19
2026-02-09 10:55:07 -08:00
Google DeepMind b637d7eb76 Call kinematics in case of state mismatch in get_data_into with CPP backend.
PiperOrigin-RevId: 867667583
Change-Id: Ieec5ff86f6768c11459795068abf17f69bd26f3c
2026-02-09 10:29:27 -08:00
Kevin Zakka a1f2b87548 Ignore sysid tests. 2026-02-09 09:58:34 -08:00
Kevin Zakka 146a5c08f7 System identification toolbox for MuJoCo.
This resulted from a lengthy collaboration with @kevinzakka, @jonathanembleyriches, @nimrod-gileadi, @gizemozd, @quagla, and @yuval.
2026-02-09 12:12:24 -05:00
Haroon Qureshi be93e8eeb2 Give Resource Providers a chance to load files.
File resolution only checks local file system. Resource providers may still
be able to load from a path even if it is not resolved.

PiperOrigin-RevId: 867534134
Change-Id: I802566136b965ad839393f56a4d4924dda2e1973
2026-02-09 04:23:44 -08:00
Haroon Qureshi 8557cf201b Allow root models to be in a subfolder.
PiperOrigin-RevId: 867217045
Change-Id: Iae6f7c7f137c2b229b52d93aacea1a4c9e06003e
2026-02-08 08:08:09 -08:00
Yuval Tassa ed15493aef Reorganize changelog
PiperOrigin-RevId: 867201472
Change-Id: I5841bd10656546db7c544ff910ed2983ce88415e
2026-02-08 06:48:14 -08:00
Yuval Tassa d680b3d234 Rename "delay" buffer functions to "history" buffers.
The functions and associated tests related to managing time-stamped data buffers have been renamed from `mju_delay*` to `mju_history*` to better reflect their general purpose beyond just handling delays.

PiperOrigin-RevId: 866978339
Change-Id: I8655e91bce783287ad2adc412d13a1c39aa2c322
2026-02-07 14:10:16 -08:00
yurekami 3497b7658c fix: resolve symlinks when loading plugin libraries
Use stat() instead of d_type to check if a file is a regular file
when scanning for plugin libraries. This allows symlinked plugins
to be loaded, which is common in ROS 2 workspaces built with
colcon build --symlink-install.

The stat() approach also handles filesystems that report DT_UNKNOWN
for d_type (e.g., NFS, XFS), making the code more robust.

Fixes #3072
2026-02-07 02:45:22 -08:00
Alessio Quaglino e6639f1e29 Apply prefix/suffix to flex material names.
PiperOrigin-RevId: 866518766
Change-Id: I5f042f52a27d2a6c66fe9642bccc73328fe14603
2026-02-06 10:32:32 -08:00
Saran Tunyasuvunakool 74d657a777 Add X macros for mjVisual and mjStatistic.
PiperOrigin-RevId: 866502731
Change-Id: I7cfaf3cd96512d93c801b7611eedb71689e21a5b
2026-02-06 09:53:22 -08:00
Yuval Tassa 6419534bad Add actuator and sensor delays. Fixes #1004
PiperOrigin-RevId: 866478839
Change-Id: Id21a6da0f98454c8fa39ea5af8a5e213d6eae497
2026-02-06 08:47:36 -08:00
Yuval Tassa 84fa527723 Add delay buffer utilities to engine_util_misc.
PiperOrigin-RevId: 866450284
Change-Id: I86d6dd6a6f7519640f75ca405fb60a12e8619c86
2026-02-06 07:22:34 -08:00
Haroon Qureshi 60b5b1d59d Fix include path.
PiperOrigin-RevId: 866348008
Change-Id: Ie67fc38ac108810c1ecbefbb8d26c394d988956b
2026-02-06 01:52:03 -08:00
Haroon Qureshi 3e8a81383a Move mjSpec/mjModel/mjData management into a separate class.
PiperOrigin-RevId: 866327584
Change-Id: I72f6ec656e193f67dee22214fe01c517432f87e5
2026-02-06 00:51:15 -08:00
Haroon Qureshi eb7aaa2868 Internal changes.
PiperOrigin-RevId: 866317956
Change-Id: Ic92c0f9b7005198025e388f83dff630253240b3b
2026-02-06 00:22:31 -08:00
Sam Haves c63ba211e5 Refactor MjcPhysics EqualityJointAPI polynomial coefficients.
The single array attribute `mjc:polycoef` has been replaced by five individual double attributes: `mjc:coef0`, `mjc:coef1`, `mjc:coef2`, `mjc:coef3`, and `mjc:coef4`.

PiperOrigin-RevId: 865947359
Change-Id: If9d14a77b0a06e5dc712eeadd6e9402411570706
2026-02-05 07:56:11 -08:00
Sam Haves 7b0b3cf8e3 Set CMAKE_INSTALL_RPATH for USD decoder plugin.
PiperOrigin-RevId: 865918418
Change-Id: If56b83925301b8d02411c35ae5906901a8dd97f8
2026-02-05 06:37:18 -08:00
Alessio Quaglino 6afd742f43 Fix trilinear flexcomp with unused vertices.
Fix a crash and dimension mismatch issue in user_flexcomp when dealing with interpolated="true" meshes that contain unused vertices. Previously, vertbody would correspond only to used vertices while vert included all vertices, leading to assertions or out-of-bounds access. Also enable node pinning for interpolated meshes.

PiperOrigin-RevId: 865881995
Change-Id: Id150f00f22b5f48896ffbffddf03c57b252de8c0
2026-02-05 04:41:02 -08:00
Taylor Howell a52180069c MuJoCo Warp documentation: Options update
PiperOrigin-RevId: 865820928
Change-Id: I36fd4c52ad8bcb9cc8ecae7c93410023a4e56ed0
2026-02-05 01:47:51 -08:00
Sam Haves a6a639003f Fix number of textures in BM_CompileManyTextures to 100.
PiperOrigin-RevId: 865475996
Change-Id: I63fd1e8b9aaff9536a9609d8f8390f8c9473785e
2026-02-04 10:35:20 -08:00
Baruch Tabanpour d07f39b4a0 Add graph mode to MJX, in preparation of supporting staged graph capture.
PiperOrigin-RevId: 865380826
Change-Id: I840b48027e1142f87eb745d0d19b0cd3e87904b2
2026-02-04 06:38:13 -08:00
Haroon Qureshi b37caf6d0c Show save dialog (instead of open dialog) as needed.
PiperOrigin-RevId: 865374467
Change-Id: I599333659b12b05b7c779115fa397302f4978751
2026-02-04 06:20:01 -08:00
Haroon Qureshi 1a0fe29c41 Make missing decoder non-failing.
Otherwise, if you try to open a random file in studio, it will crash.

PiperOrigin-RevId: 865372002
Change-Id: I96d3121b6de792daaff53155ea2436ac3f6668db
2026-02-04 06:12:54 -08:00
Kyle Bayes 1a9ca3239a Replace comma operator with semi-colon.
PiperOrigin-RevId: 865353927
Change-Id: I3498d8dc17f96caf8fa1975613ed6a815d2f20e7
2026-02-04 05:14:17 -08:00
Haroon Qureshi c2ede20d08 Move model_, data_, and spec_ into private accessors.
This is in preparation for an upcoming change.

PiperOrigin-RevId: 865332731
Change-Id: I74041b3caf5de841f583f76682e1ced049557202
2026-02-04 04:02:52 -08:00
Haroon Qureshi 0add985a15 Handle null camera and vis_option.
PiperOrigin-RevId: 865088406
Change-Id: I4a3bf7f6cb696de1461bc53fd5d77b941ea0c0c5
2026-02-03 16:06:06 -08:00
Haroon Qureshi 1bd72428f1 Perform ImGui calls only when a context is available.
PiperOrigin-RevId: 865072901
Change-Id: I4b35d953df2f686d2f02f8e0aede7109729b5e04
2026-02-03 15:29:44 -08:00
Haroon Qureshi 144a8a9e85 Make EGL utils conditional on EGL.h.
PiperOrigin-RevId: 865064686
Change-Id: I3728de6e49e4c36d76b410c2458767f74df069c9
2026-02-03 15:09:51 -08:00
Haroon Qureshi feb3abcccf Fix paths.
PiperOrigin-RevId: 864933655
Change-Id: I44f34b47fe4f6725de59c6565f6b2b557b80eaa6
2026-02-03 10:16:19 -08:00
Taylor Howell 0ec7259e5c MuJoCo Warp documentation: Options
PiperOrigin-RevId: 864932415
Change-Id: I54fc7e8972ea38da783c5537fdfa62644f180e51
2026-02-03 10:14:22 -08:00
Haroon Qureshi ef8e6802ef Move EGL initialization into a separate class.
Initialize the EGL context in the Renderer when using the classic
rendering engine with no window.

PiperOrigin-RevId: 864884976
Change-Id: Ic6cc4637855a361e41f3bfb4b738c012ec93711f
2026-02-03 08:12:35 -08:00
Haroon Qureshi 7ec8b6e341 Pause sim when loading an empty model.
PiperOrigin-RevId: 864855430
Change-Id: Ib8c2b0949ee6fda8dd1490017e146d792119e840
2026-02-03 06:49:58 -08:00
Haroon Qureshi 34add7bb32 Removing trailing newline in zenity file dialogs.
PiperOrigin-RevId: 864842389
Change-Id: Ie4cc61a91732fcde0ef2c7eba927aede217b2e6d
2026-02-03 06:15:37 -08:00
Haroon Qureshi e82253e86c Prevent file dialog from reopening after being dismissed.
PiperOrigin-RevId: 864842269
Change-Id: I91819a3418875fe06dbed0cf7777e1dc7d358079
2026-02-03 06:14:35 -08:00
Haroon Qureshi 1a2bca4986 Use runtime enum for the renderer backend instead of preprocessor macros.
TESTED:
  studio:vulkan
  studio:vulkan --offscreen_mode=true
  studio:opengl
  studio:opengl_egl
  studio:classic
  studio:classic --offscreen_mode=true
  studio:server
  robot_sim/frontend:debug_server
  pyviewer:example
  pyviewer:example --define=mujoco_gl=vulkan
PiperOrigin-RevId: 864768322
Change-Id: I4478e0115b3807060d60d98b4ddfd63da9389aac
2026-02-03 02:13:15 -08:00
Taylor Howell 24e5b966c3 MuJoCo Warp documentation: remove beta software warning.
PiperOrigin-RevId: 864761934
Change-Id: I56afaf9bf9e86ed3ea34ff576230d3b3bc4bf28a
2026-02-03 01:56:35 -08:00
Alessio Quaglino a54c9f1d78 Specialized box and capsule collision primitives for stable 2D flex interactions.
PiperOrigin-RevId: 864500749
Change-Id: I52aed6e29569477a8a0b6b5eb55ad483f1077c0e
2026-02-02 13:36:42 -08:00
Sam Haves 8344dba11e Remove special USD handling from simulate CMakeLists.
USD support is now enabled via plugin.

PiperOrigin-RevId: 864491943
Change-Id: Ib0a80413821b0f398ff05bf87c8fb79e93a811e6
2026-02-02 13:15:48 -08:00
Sam Haves 49b4790877 Enable multithreading for texture compilation, use new user ThreadPool for compilation.
PiperOrigin-RevId: 864449279
Change-Id: I5dd053ab0b1f14d81e1f68296eadc59cd5b8d698
2026-02-02 11:35:41 -08:00
Sam Haves f0d5ed73b2 Restore cache capacity after BM_CompileManyTextures benchmark.
The BM_CompileManyTextures benchmark temporarily sets the MuJoCo cache capacity to 0. This change ensures that the original cache capacity is restored after the benchmark completes, preventing side effects on other tests.

PiperOrigin-RevId: 864332653
Change-Id: I5f756e30d4922d5e6f9b70d19ba9d0e31cde9259
2026-02-02 06:43:05 -08:00
Sam Haves 683b1b5d38 Create threadpool for src/user and primarily compiler usage.
PiperOrigin-RevId: 864328236
Change-Id: Iffaa9b8e6eacdb038020af9d6ad82d7cb7a6c941
2026-02-02 06:31:00 -08:00
Haroon Qureshi b7a46d04b6 Implement OS-specific file dialogs.
PiperOrigin-RevId: 864235878
Change-Id: I709fc52c0c467f317694ba0772572a448c45de35
2026-02-02 01:33:40 -08:00
Yuval Tassa 815dbb996e Use body_weldid to find the first movable body in a chain.
PiperOrigin-RevId: 863774053
Change-Id: I8df96d5af7cc80d78a6f35560c3c31bed8be550e
2026-01-31 17:16:36 -08:00
Google DeepMind 7418d86eda Enable Emscripten threading for MuJoCo WASM builds.
PiperOrigin-RevId: 863309872
Change-Id: I2edabb386f3abc74e507d0419b136b1586d01241
2026-01-30 10:58:18 -08:00
Lou Rohan c6e982cfac Add support for USD material interfaces
- use GetValueProducingAttributes() for improved input resolution.
- use std::filesystem  to avoid leaking file handles
2026-01-30 10:28:13 -06:00
Haroon Qureshi b073cd2ca4 Refactor mjVFS and resource management.
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.

This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.

PiperOrigin-RevId: 863248779
Change-Id: I8bcbd5445814ba1e72c6d7b80ad6a054f5f1df57
2026-01-30 08:20:53 -08:00
Haroon Qureshi 9da834c12c Tweak status bar layout.
PiperOrigin-RevId: 863184918
Change-Id: Ibff6c71e6004f4dd2ad2b49cc889d2f9c2dfd41e
2026-01-30 05:07:11 -08:00
Haroon Qureshi e35c981f48 Add uv offsets to autogenerated 2D uv coordinates.
The original render_gl3.c code does the following:

```
mjr_setf4(plane, 0.5*scl[0], 0, 0, -0.5);
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
mjr_setf4(plane, 0, -0.5*scl[1], 0, -0.5);
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane);
```

The 4th component of the GL_OBJECT_PLANE function effectively
describes a UV-offset for the generates uvs. In our filament
implementation, we had overlooked this 4th component.

PiperOrigin-RevId: 863181644
Change-Id: I60688117ea2019257da683cdda0c7d389dd5af1e
2026-01-30 04:55:31 -08:00
Google DeepMind f022faadf7 Revert 42b81966b7 due to GitHub failures
PiperOrigin-RevId: 862869742
Change-Id: I9c56c8e15b609c9a67e6c90542722e7326d8fe2c
2026-01-29 13:17:49 -08:00
Google DeepMind 63de5c51ee Fix line numbers in named access tests link.
The link to the named access tests in `tests/bindings_test.ts` was incorrectly formatted.

PiperOrigin-RevId: 862786877
Change-Id: Idf10d75638e55b7d3b0312c765a977274d014857
2026-01-29 10:08:44 -08:00
Taylor Howell 1381e8adee Add mjMINAWAKE to constants.cc
PiperOrigin-RevId: 862784740
Change-Id: I309fca497027cd8cb7cee6c998fc34d0cb5e94fd
2026-01-29 10:04:43 -08:00
Yuval Tassa 55f300b78c Fix typo
PiperOrigin-RevId: 862781462
Change-Id: I88844e2148e821ec92e37aa8aab3554c132a4d43
2026-01-29 09:57:09 -08:00
Yuval Tassa 883e69d7b1 Minor improvements to collision sensor documentation.
PiperOrigin-RevId: 862767431
Change-Id: I53861430e7868b23e37be9694f195a2dd3685db4
2026-01-29 09:22:23 -08:00
Google DeepMind 42b81966b7 Add a test for compiling XML with multiple assets from VFS.
PiperOrigin-RevId: 862767395
Change-Id: I6d51b5630a0d5033231a555c3b9297ae18dc429f
2026-01-29 09:21:11 -08:00
Sam Haves f434578d30 USD decoder improvements: Support actuators targeting tendons and improve side site index handling.
Adds support for mjTRN_TENDON actuators in the USD decoder. Modifies the tendon path parsing to correctly handle side site indices, allowing -1 to signify no side site for a given path element.

PiperOrigin-RevId: 862755621
Change-Id: I18b13b160e3d1c27945d0972a69012d6307131e9
2026-01-29 08:51:02 -08:00
Google DeepMind d2efc0e154 Add object-based accessors for mjData in WASM bindings.
PiperOrigin-RevId: 862736608
Change-Id: I0618e9d2af37e377bad1aead1b3fd1a12334df35
2026-01-29 07:55:56 -08:00
Google DeepMind 59c5017073 Improve error messages for named/indexed lookups in WASM bindings.
PiperOrigin-RevId: 862682001
Change-Id: I6381af64b724de0ab5aee43cdc89ce463b590cf1
2026-01-29 04:53:54 -08:00
Haroon Qureshi f6796f36b2 Only update GuiView::UpdateRenderable (which calls imGui::EndFrame
internally) when we want to render the GUI to the same target as the
scene.

PiperOrigin-RevId: 862647358
Change-Id: If3656032b74a168b804dfa34ef3eb97c9817c2c0
2026-01-29 02:54:44 -08:00
Taylor Howell 57b5ebc92b MuJoCo Warp documentation: height field collision overflow
PiperOrigin-RevId: 862454467
Change-Id: Iaccc44aa0c57faf6ad2dbc62f2b727cea2e4980d
2026-01-28 16:55:10 -08:00
Haroon Qureshi 86f82d18a2 Temporarily disable mjz support.
PiperOrigin-RevId: 862383413
Change-Id: I32927f59852e149b7aaf8b5225f35020532eb7f9
2026-01-28 13:58:41 -08:00
Taylor Howell 8889c13fa7 MuJoCo Warp documentation: Inertia matrix factorization
PiperOrigin-RevId: 862290080
Change-Id: I7acd30f1fff5cca95ca1139f71710cab5c493561
2026-01-28 10:18:50 -08:00
Yuval Tassa c5925e7b0e Improve wording in changelog
PiperOrigin-RevId: 862288773
Change-Id: I2dcd09ed1fb929396218ee32e99242d9be508b3b
2026-01-28 10:15:11 -08:00
Yuval Tassa 510cbceda5 Add missing space after comma
PiperOrigin-RevId: 862235154
Change-Id: I60ad15fcc918accf52abeced7e22a5a1d599df82
2026-01-28 07:53:18 -08:00
Haroon Qureshi a050b64635 Update minimum CMake version for miniz.
PiperOrigin-RevId: 862226233
Change-Id: I8612260e65f9f1c4192325a90bcfc6bac71585c0
2026-01-28 07:28:09 -08:00
Matija Kecman 0eff7acf80 Improve filament gui
* Added color to widgets which have changed from their initial values and the ability to revert to their initial values by clicking with the right mouse button
* Added some reasonable range limits, which are especially useful for drag widgets

PiperOrigin-RevId: 862220411
Change-Id: I1d2c61d8889d5ec29890d81b5f97af576cb5c611
2026-01-28 07:09:01 -08:00
Haroon Qureshi 40f2fe0977 CMakeLists for mjz.
PiperOrigin-RevId: 862214752
Change-Id: I498a1f0092adc9e94016bf23589403296bffb4f7
2026-01-28 06:53:06 -08:00
Yuval Tassa 1d44f7a0d0 Minor fix to changelog
PiperOrigin-RevId: 862213255
Change-Id: I20017785aca047efaead582f84a1ba9769411d41
2026-01-28 06:48:39 -08:00
Haroon Qureshi 2fd9b5e92f Partial roll back VFS refactor due internal breakages
PiperOrigin-RevId: 862210191
Change-Id: Ia15a345a267bcef4b593d507d54f1668da0c0611
2026-01-28 06:40:11 -08:00
Yuval Tassa 19ff06155a Refactor sensor computation into per-sensor functions.
PiperOrigin-RevId: 862180688
Change-Id: I9f3f4da8ca8abed778965fd3970171276ee4570d
2026-01-28 05:04:59 -08:00
Yuval Tassa 1d2d0b1c37 Remove batching optimization from GEOM* sensors
PiperOrigin-RevId: 861938606
Change-Id: Ibb135a4d99cab9ce23a04f844f7c730e8f3b31c8
2026-01-27 16:44:10 -08:00
Yuval Tassa 5fb47df197 Add mjData flags marking lazily evaluated pipeline stages
PiperOrigin-RevId: 861763477
Change-Id: Ib613c56949264573a16306800658f868d2aa7665
2026-01-27 09:45:06 -08:00
Alessio Quaglino ba32568138 Move flex vertex-edge adjacency to mjModel.
PiperOrigin-RevId: 861717037
Change-Id: I2ad8090b0318cb04b43d13966cb42260c82ef930
2026-01-27 07:41:47 -08:00
Haroon Qureshi 669e9b7484 Add an "offscreen" mode that allows users to render studio to a texture
then uses SDL to blit the texture into the window.

PiperOrigin-RevId: 861697047
Change-Id: Ib949b4ade0c79d867ba74ce013bc2b6fa2571f56
2026-01-27 06:48:16 -08:00
Yuval Tassa dce2ed00ea Change not required, issue was addressed in e48da1e38c
PiperOrigin-RevId: 861680910
Change-Id: Iea5c7190bf826c9254eb1bd2f78b0098073cba20
2026-01-27 06:03:04 -08:00
Yuval Tassa e787f8717d Change not required, issue was addressed in e48da1e38c
PiperOrigin-RevId: 861680071
Change-Id: I374f091cd2686737e53234ca0edc8703897fbd4a
2026-01-27 06:01:14 -08:00
Haroon Qureshi 75715ab966 Update logic for dealing with file dialogs.
This in preparation for an upcoming change that uses native file dialogs instead
of our very basic ImGui file dialog.

PiperOrigin-RevId: 861671041
Change-Id: I9b00c05efdda5e37ffe15048a2ccf66f6eca89d9
2026-01-27 05:31:01 -08:00
Haroon Qureshi ad482a57bb Add a headless OpenGL renderer target.
PiperOrigin-RevId: 861642051
Change-Id: Ie0b880a2d3d85205dcd41bca5dc270efd35b7767
2026-01-27 04:08:33 -08:00
Haroon Qureshi fe16255602 Add mjz support to studio.
PiperOrigin-RevId: 861627355
Change-Id: Iafd291965ca78d03fdc1efe0e40dabcd4f2dacc4
2026-01-27 03:22:58 -08:00
Haroon Qureshi 32a4412e2b First-pass implementation of a spec loader for zipped assets.
PiperOrigin-RevId: 861625990
Change-Id: I65cf601cd9aa3aab4915a5a247dda00a6a9aa3db
2026-01-27 03:18:30 -08:00
Haroon Qureshi e43ed60d29 Allow GUI to be rendered to texture as well.
Update SetFrameBuffer to allow users to customize which swap chain
(window or offscreen) to use for rendering both the main mjvScene
as well as the GUI.

PiperOrigin-RevId: 861624061
Change-Id: Ife7bfc447afb007016300438fc5f88a8e4cfa0f6
2026-01-27 03:12:05 -08:00
Haroon Qureshi 0ddbb46fa1 Refactor mjVFS and resource management.
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.

This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.

PiperOrigin-RevId: 861550939
Change-Id: I070eb4bcc2982466c8f368f7918005538baa5185
2026-01-26 23:53:29 -08:00
Matija Kecman e977b0d660 Fix GIL deadlock in Python viewer methods
Removed the GIL lock in set_figures, clear_figures, set_texts, clear_texts, set_images, and clear_images

PiperOrigin-RevId: 861245200
Change-Id: I52f21d82f9813752c7cb357213c24ea6188583db
2026-01-26 10:11:16 -08:00
Yuval Tassa 5fc6ed4eda Make XML schema dropdown titles clickable links.
PiperOrigin-RevId: 861182944
Change-Id: I01fec8f102a87f8daf65ad5ba5ed3a09c0022cd0
2026-01-26 07:26:27 -08:00
Yuval Tassa 7f8084ae1d Rename XML reference icons to avoid anchor issues.
Before this change:
`https://mujoco.readthedocs.io/en/latest/XMLreference.html#body-site-m`

After this change:
`https://mujoco.readthedocs.io/en/latest/XMLreference.html#body-site`

PiperOrigin-RevId: 861180069
Change-Id: I6f15906c8be463825248487021f9f46fc82a95da
2026-01-26 07:16:08 -08:00
Alessio Quaglino 54ace777c1 Add convenient plugin assignment in Python bindings.
PiperOrigin-RevId: 861168536
Change-Id: I274fbf3460d475434f837ab58bf5e2b0988369fd
2026-01-26 06:37:31 -08:00
Haroon Qureshi bdb553ff8a Add a ModelPlugin that can be used to load and update models.
PiperOrigin-RevId: 861077626
Change-Id: I3ef4989cfbfff3632c5915c00ebda1e7a48716e8
2026-01-26 01:24:43 -08:00
Alessio Quaglino e933081ff1 Optimize flexvert Jacobian computation.
The dense Jacobian arrays `J0_dense` and `J1_dense` are now zeroed only once before the vertex loop. Inside the loop, only the entries that were actually used are zeroed out after being added to the sparse Jacobian, allowing for efficient reuse of the dense arrays across all vertices.

PiperOrigin-RevId: 860799056
Change-Id: Ia61daae5eeb2f4dbc0c5d8c0064622a881e92b7a
2026-01-25 05:22:44 -08:00
Yuval Tassa e48da1e38c Fix __muloti4 linker error on Clang 13
Add `-rtlib=compiler-rt` linker flags for the Clang 13 CI build.

Clang 13 generates calls to __muloti4 (a 128-bit overflow-checked multiplication intrinsic) for signed 64-bit multiplication with overflow detection. This symbol is provided by LLVM's compiler-rt but is missing from GNU's libgcc, which is the default runtime library on Ubuntu.

Related issues:

- https://github.com/llvm/llvm-project/issues/14841
- https://github.com/abseil/abseil-cpp/issues/841
- https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=244169

PiperOrigin-RevId: 860529686
Change-Id: If58dc0328aa1dd87aef8ea02da555f57ad96b02c
2026-01-24 08:15:56 -08:00
Alessio Quaglino e9c61694e1 Align flex_vert0 to the XY plane during model initialization if dim=2.
PiperOrigin-RevId: 860435368
Change-Id: Ida616e1e69c224f7c0dbad2a10dd59e64cbadf49
2026-01-24 00:50:01 -08:00
Alessio Quaglino 769109630f Move flexvert_J and flexedge_J sparsity pattern to mjModel.
PiperOrigin-RevId: 860392796
Change-Id: Ie1264f2df5bf04b5794a3c7d8ad1a92524a6a567
2026-01-23 22:00:14 -08:00
Alessio Quaglino 7da271c687 Add vertex equality option.
PiperOrigin-RevId: 860299454
Change-Id: I7befd8e5f4c8bac6d74684a96a9cc3cee9ae1e29
2026-01-23 16:30:05 -08:00
Yuval Tassa a5de40b400 Replace mjtSize with size_t for size calculations in engine.
Use unsigned size_t instead of signed mjtSize for size multiplications to avoid Clang's overflow-checking intrinsic. This is semantically correct as size calculations are inherently unsigned.

PiperOrigin-RevId: 860213177
Change-Id: I837aa6556335478969d4977492d0f231419f020a
2026-01-23 12:35:13 -08:00
Yuval Tassa 68537e1e32 Replace mjtSize with size_t for size calculations.
Use unsigned size_t instead of signed mjtSize for size multiplications to avoid Clang's overflow-checking intrinsic. This is semantically correct as size calculations are inherently unsigned.

PiperOrigin-RevId: 860172221
Change-Id: I3b6cb720db8771b8f266f1927e2980ac7514538b
2026-01-23 10:51:43 -08:00
Yuval Tassa 30b903b6c0 Migrate mjModel size fields from int to mjtSize.
This change updates all size-related members within the `mjModel` struct from `int` to `mjtSize`. This allows MuJoCo to handle models with a larger number of elements. Corresponding changes were made to macros, function signatures, and I/O routines to accommodate the new `mjtSize` type.

PiperOrigin-RevId: 860144595
Change-Id: I701c6d607715d240766b6210a9773cd9e4258c59
2026-01-23 09:41:49 -08:00
Taylor Howell 4a64017a5f Add documentation for MJX API
PiperOrigin-RevId: 860108133
Change-Id: I85469efcfe49d320ef8b89c9d174f33499a22b31
2026-01-23 07:53:17 -08:00
Google DeepMind c55c9a7bf1 Replace printf with mju_error in WASM bindings.
PiperOrigin-RevId: 860099912
Change-Id: Ia6a24da9301099aa976bb7a38beb9da15074a43d
2026-01-23 07:26:13 -08:00
Sam Haves 2582a83ac3 Add equalityJointAPI to mjcPhysics.
PiperOrigin-RevId: 860081702
Change-Id: Ifd961dcb2a8e0f5d885e9e9dadc0153b03cb5f4d
2026-01-23 06:28:29 -08:00
Google DeepMind e1992e62d7 Add mj_loadBinary binding to WASM.
This change adds an Emscripten binding for loading binary MuJoCo models (`.mjb`) from the virtual filesystem. The new binding, `mj_loadBinary`, takes a filename and an `MjVFS` object, enabling the loading of models that reference assets within the VFS.

PiperOrigin-RevId: 859740455
Change-Id: I9f9d8bbba0b57422e2356867e4282a1b04566475
2026-01-22 13:08:00 -08:00
Google DeepMind 61f13cd8f1 Add custom Emscripten binding for mj_saveModel.
Also adds support to unpack nullable string args

PiperOrigin-RevId: 859702186
Change-Id: Ia9e10f447ecf17b1dd74dd64d988790107a438a6
2026-01-22 11:36:13 -08:00
Taylor Howell 5ae6b5fe31 Fix MjSpec.add_texture gridlayout argument to accept strings and character lists
PiperOrigin-RevId: 859599919
Change-Id: If785f36010a7437b354ec0ce7db30c2b7ec69fe6
2026-01-22 07:28:16 -08:00
Haroon Qureshi bab468703c Display error message when requested file does not exist.
PiperOrigin-RevId: 859583121
Change-Id: Id9969e486499a70769e325161c3cd2c204006d9a
2026-01-22 06:34:35 -08:00
Matija Kecman 98593259e7 Internal change
PiperOrigin-RevId: 859578296
Change-Id: If4dd4ca68ab9750693e5f6ff20ea0c78d6b93464
2026-01-22 06:20:47 -08:00
Alessio Quaglino 54dd623650 Add vertex-based flex constraints (dim=2).
PiperOrigin-RevId: 859552050
Change-Id: I61d4b9dc40f041c5b930e5f8810a803e8bccb87a
2026-01-22 04:54:53 -08:00
Haroon Qureshi 2cc2e579f1 Refactor model loading APIs.
There are three ways to load a model: from a file, from a buffer, or an
"empty" model. Instead of overloading a single function to do all three,
provide three separate functions.

Also disable model loading functions that will not work for emscripten.

PiperOrigin-RevId: 859051341
Change-Id: I71557d31d0e7c9c6882895c36116d300f19e255d
2026-01-21 05:25:08 -08:00
Haroon Qureshi e2180ff744 First-pass of a plugin system for GUI elements.
Refactor filament's debug drawing to be one such plugin.

PiperOrigin-RevId: 859002002
Change-Id: Ibe9000dec19fce648eef6d57170ce435b9a8c6ff
2026-01-21 02:47:09 -08:00
Haroon Qureshi bf05bb1885 Make quit button work.
PiperOrigin-RevId: 858624789
Change-Id: Ibdd572b60273424f3b7e9bb6a9d117d2a0538227
2026-01-20 09:28:48 -08:00
Haroon Qureshi a0accc493a Fix camera select logic.
PiperOrigin-RevId: 858599199
Change-Id: I25f1a74ac145c73bb225d6df8e86aa82d88ebb4b
2026-01-20 08:18:29 -08:00
Taylor Howell 23c56ec4bb mjSpec python bindings for add functions: accept size with 1, 2, or 3 parameters
PiperOrigin-RevId: 858494291
Change-Id: I8a02dcac1d2419fbc728607907425b401cf66da4
2026-01-20 02:39:04 -08:00
Haroon Qureshi de47cf0e6f Don't mipmap sRGB textures.
PiperOrigin-RevId: 858148054
Change-Id: Ic115b7431901549e1c636eb20414641c37cf3e8a
2026-01-19 05:26:27 -08:00
Matija Kecman 654b393060 Add a boxing utility which can surround a bunch of UI and render it in a box.
The ImGui table API cell padding variables can be used to adjust the positioning of the UI in the box.

PiperOrigin-RevId: 858137824
Change-Id: I1ce1519c0abd67bc5fafc30f9a18dfcf18c2a313
2026-01-19 04:48:50 -08:00
Taylor Howell d173ee5bee MuJoCo Warp documentation: option-ccd-iterations -> option-ccd_iterations
PiperOrigin-RevId: 858100397
Change-Id: I358875ba56e6769fda75dba72377286c40771716
2026-01-19 02:42:04 -08:00
Sam Haves 799f8a300e Add parsing benchmark simulating many textures.
PiperOrigin-RevId: 857883857
Change-Id: Ia428ff8aeba4fbaae67a6337d0856cd2b19af2e6
2026-01-18 11:17:45 -08:00
Aditya kumar singh 84c8cf432c Fix Frame Issue in mjCBody::AccumulateInertia 2026-01-18 17:25:49 +05:30
Taylor Howell bb4df33adf Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 857298931
Change-Id: Icbaddaea8140198c3673124d5994a01d3c92ed69
2026-01-16 14:11:39 -08:00
Taylor Howell 9ba545b8b0 MuJoCo Warp documentation: Memory.
PiperOrigin-RevId: 857148640
Change-Id: I7f21bebb2186a5dd4287a8d2ee9b430f823b9051
2026-01-16 07:13:38 -08:00
Haroon Qureshi 77d1ac10fe Fix scaling issues on HDPI monitors.
PiperOrigin-RevId: 857024487
Change-Id: I7d3db9ff754374053bcd33ba93c7466253afb58c
2026-01-16 01:17:38 -08:00
Sam Haves c08e1d9e6e Add MjcEqualityAPI as a base class for MuJoCo constraints and MjcEqualityWeldAPI for representing weld constraints.
This change introduces two new USD API schema:
* MjcEqualityAPI - base API for representing MuJoCo equality constraints in USD, this will typically be applied to joints such as UsdPhysicsFixedJoint.
* MjcEqualityWeldAPI - extends MjcEqualityAPI for MuJoCo's weld equality constraints with an attribute for torqueScale.

The usd_decoder is updated to parse UsdPhysicsFixedJoints and convert the new schema attributes into the appropriate mjsEquality data fields.

PiperOrigin-RevId: 856723634
Change-Id: I0982fd3168b643f8e91d87bb5ae5933e526b63a1
2026-01-15 10:44:27 -08:00
Taylor Howell d86acd7e12 MuJoCo Warp documentation: Warmstart.
PiperOrigin-RevId: 856608941
Change-Id: Iae1bd0a3916d98affff4d5dbb442f9d951622e52
2026-01-15 04:50:27 -08:00
Haroon Qureshi c92746641d Implement picture-in-picture mode.
Adds a new window that allows the user to display one or more renders from
the different cameras in the scene.

PiperOrigin-RevId: 856607089
Change-Id: I7268ffd3ef62b9b4d62ce8d004fdbbec92b42af4
2026-01-15 04:42:27 -08:00
Sam Haves d816b38f4c mjcPhysics MjcTendon path now has an indices attribute to allow repeated sites in tendon path.
Since relationships in USD can only contain a single instance of a path, it was previously impossible to have a tendon path that visits the same wrap target more than once. This is a fairly common occurence when dealing with tendons that have pulleys.

With this change, if mjc:path:indices is not defined then the behaviour is as it was and the mjc:path is considered to be ordered. If it is authored then the parser will use the indices into mjc:path as the order. This mirrors other similar concepts in USD such as face vertex indices.

PiperOrigin-RevId: 856339887
Change-Id: I6b9503973de377acdb0689be168c16e4aa19b70b
2026-01-14 13:24:28 -08:00
Haroon Qureshi 42c565d860 Use a dedicated swap chain for offscreen rendering.
PiperOrigin-RevId: 856320260
Change-Id: I3076827baf075282651e4308db74b163a5709935
2026-01-14 12:31:54 -08:00
Alessio Quaglino e56b31e98f Reduce flexedge_J size from nflexedge x nv to the effective sparse size.
PiperOrigin-RevId: 856290141
Change-Id: Ide297d1b6f0e3aa07e3e20bf9ab44b6501097695
2026-01-14 11:18:41 -08:00
Google DeepMind cbc1136502 Roll back VFS refactor due internal breakages
PiperOrigin-RevId: 856273160
Change-Id: I4097e05ed4e48ebee05b4347d0f227d4f39c1b09
2026-01-14 10:38:29 -08:00
Google DeepMind c996f288e1 Add code generation for mjModel named accessors.
Most of it is done leveraging existing X Macros (indexers.h, indexer_xmacro.h) used for python bindings already.

PiperOrigin-RevId: 856205245
Change-Id: Ic72443999065040af3042bbf3f9f68c5b70d309d
2026-01-14 07:31:29 -08:00
Yuval Tassa cc4c2bc398 Improve wording in changelog.
PiperOrigin-RevId: 856204666
Change-Id: I6ccf2ea727210e4695fff8d56ff7de10b9ebd73c
2026-01-14 07:29:10 -08:00
Haroon Qureshi 5a7abfe8a0 Set cleared memory back to nullptr.
PiperOrigin-RevId: 856188793
Change-Id: Iab33171b07f0d2a48d19986e145b832d1037d596
2026-01-14 06:38:45 -08:00
Yuval Tassa f3ad0eff2b Fix body category check for mocap body descendants in visualization.
PiperOrigin-RevId: 856179240
Change-Id: I29f4758fee0ff3b16d0b9f452c28e640b5558993
2026-01-14 06:06:55 -08:00
Haroon Qureshi d387578783 Refactor mjVFS and resource management.
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.

This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.

PiperOrigin-RevId: 856166919
Change-Id: Id723d612ffc0bff020705cf19ef95fbf24676840
2026-01-14 05:19:57 -08:00
Yuval Tassa e50e2e9691 Correct dimensions for constraint-related quantities in documentation.
PiperOrigin-RevId: 856159539
Change-Id: I83f0414a78239cae9c91bb51b16f5e2549891517
2026-01-14 04:54:03 -08:00
Yuval Tassa 218226fc95 Breaking change: Add surface normal output to MuJoCo raycast functions.
PiperOrigin-RevId: 855781592
Change-Id: Id96b1ca7eaf722e260cc69d7706c28dc51f52d92
2026-01-13 10:22:21 -08:00
Google DeepMind 37762e3f70 Add support for vfs assets in mj_compile function to MuJoCo WASM.
Regarding mj_compile VFS argument:
I was encountering a memory error when using `std::optional<MjVFS>` with `mj_compile` (because vfs should be an optional argument of the function). This is likely because `MjVFS` doesn't have copy/move constructors, which are required for types used with `std::optional`, causing issues with memory management when std::optional copies the MjVFS object.
To solve this and to make vfs an optional argument to `mj_compile`, I replaced `mj_compile_wrapper` with two overloaded functions. This avoids using `std::optional<MjVFS>` and resolves the memory issue, while still allowing mj_compile to be called with or without the vfs argument from JavaScript.

But what if we instead add those copy/move constructors so it works with `std::optional`?:
While making `MjVFS` copyable or movable would theoretically allow it to work with std::optional, it's not a feasible approach in this case.
The MjVFS struct manages file data in memory, allocating buffers when files are added and freeing them when `mj_deleteVFS` is called in its destructor. A copy would require a deep copy of the entire virtual filesystem, but MuJoCo does not provide a public API function (like a  "mj_copyVFS") to do this. Implementing a deep copy manually would be complex and fragile. A shallow copy would result in multiple MjVFS objects pointing to the same memory, leading to double-free errors when their destructors run.
Given these constraints, MjVFS cannot safely be made copyable. The approach of providing two overloaded C++ functions is better.

PiperOrigin-RevId: 855740541
Change-Id: Ia08b6db8868ad245f07145db3fb0322cb9f737cb
2026-01-13 08:36:48 -08:00
Yuval Tassa 7e21f18fd3 Document compiler/usethread fix.
PiperOrigin-RevId: 855735924
Change-Id: I5b638ccf2a74194b363cf7c6436f78c1c3d9b0e1
2026-01-13 08:21:27 -08:00
Alessio Quaglino a49576e469 Move flexedge sparse Jacobian indices to mjModel.
PiperOrigin-RevId: 855718305
Change-Id: Ic136f4efa6735b934288f65c332d71ee8b0f6da5
2026-01-13 07:33:17 -08:00
Google DeepMind 09a6fb7d4d #mjspec Enforce that material textures array is always of length mjNTEXROLE.
PiperOrigin-RevId: 855684213
Change-Id: Id8a3734c75841dfb91bd2252114249f08461b7f2
2026-01-13 05:55:09 -08:00
Copybara-Service a93db89d43 Merge pull request #2945 from hartikainen:instsance-typo
PiperOrigin-RevId: 855677085
Change-Id: Ifc1efc4163f1ef475b687436064026f0924841bf
2026-01-13 05:34:00 -08:00
Baruch Tabanpour 1f83bbf69d Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 855445232
Change-Id: I34c9337378c8e0c0e6f92252b1af4cfac4524018
2026-01-12 17:08:17 -08:00
Haroon Qureshi 071cb83fe7 Strip the prefix correctly.
PiperOrigin-RevId: 855297807
Change-Id: Ic182f64c451077386fdba8bfe34e8da6364b9f60
2026-01-12 10:59:20 -08:00
Sam Haves 7e45bbb51c Add urdf file extension case to mj_parse.
fixes #3004

PiperOrigin-RevId: 855249634
Change-Id: I6c21d0ada4fe482059f64e96d413796f5c1c66ce
2026-01-12 08:59:00 -08:00
Taylor Howell 013268c283 Documentation: Pair-wise colliders.
PiperOrigin-RevId: 855245724
Change-Id: Iffad5dc426350040f730dc1a7b9766f079ef949e
2026-01-12 08:47:45 -08:00
Yuval Tassa 1cda1e7a8c Prevent degenerate body inverse weights in constraints.
Fixes #2472

PiperOrigin-RevId: 855223971
Change-Id: I646207f82353b7099aab9e220888fe11a4cd3d6d
2026-01-12 07:43:14 -08:00
Yuval Tassa f0e1d8ce2c Fix typo in XML reference: damping -> damper.
PiperOrigin-RevId: 855198029
Change-Id: I2cc2b833e8a7fad8c63d1eb7b3febdd54d0c9056
2026-01-12 06:13:20 -08:00
Google DeepMind a6a9a85007 Implement get_data_into_cpp and make_data_cpp.
PiperOrigin-RevId: 855192298
Change-Id: I9f9fd07094c40b9df1b645c2c893bb2605941e32
2026-01-12 05:54:29 -08:00
Yuval Tassa 5979c5aa03 Fix link in changelog.
PiperOrigin-RevId: 855183695
Change-Id: I9ef63fe03f3b68707ff7eec1813403a08b0a8074
2026-01-12 05:22:14 -08:00
Haroon Qureshi cb9a9c159c Remove getdir from mjpResourceProvider.
All known implementations were effectively the same as the default fallback. It was just adding unneeded complexity. Removing this now will help with upcoming improvements to resource providers.

PiperOrigin-RevId: 855163273
Change-Id: I529fc18d0d03a8dc676c909ec9e4b1da1454d414
2026-01-12 04:07:42 -08:00
Yuval Tassa d7e4038be8 Expose mj_copyData in Python bindings.
This allows calling `mujoco.mj_copyData(dest, model, src)` to copy data between existing `mjData` instances.

PiperOrigin-RevId: 855150139
Change-Id: If122cb7acf590846e25ee15f9770c3c087147169
2026-01-12 03:21:15 -08:00
Taylor Howell 1d482047d1 MuJoCo Warp documentation: How to fix simulation runtime warnings?
PiperOrigin-RevId: 855149274
Change-Id: Iccfb85f1ec836cb06235d21d23e913f77a816487
2026-01-12 03:17:13 -08:00
Yuval Tassa a26f09accf Standardize function docstring style in MuJoCo API.
Updates function comments to consistently use a semicolon (`;`) before describing the return value and to use the imperative form "return" instead of "returns".

Also fix error in docstring of `mjp_registerResourceProvider`

PiperOrigin-RevId: 854888532
Change-Id: I311239a2770ded5febece9958ae4e94c1e522600
2026-01-11 09:00:35 -08:00
Sam Haves 8abedf263e Add checks for nullptr content_type and extension in mjpDecoder registration.
PiperOrigin-RevId: 854365689
Change-Id: I025f5ab844dd4cf19f7d5f223430e27fd23a0924
2026-01-09 15:32:23 -08:00
Sam Haves a5dc57c0c3 Move OpenUSD parsing to usd_decoder
Add usd_decoder to mujoco/plugin.
  - Previously was src/experimental/usd/usd_to_mjspec.cc, now that same spec is returned by the plugin.

PiperOrigin-RevId: 854350962
Change-Id: Ia980190a557c50ce8197980922a2594b613859b4
2026-01-09 14:48:29 -08:00
Sam Haves 64a2345c07 Fix usethread check to enable multithreaded mesh compilation.
PiperOrigin-RevId: 854260636
Change-Id: I18d1f47a1ef7f8abcce14e0351b9523fbbac8be6
2026-01-09 11:00:17 -08:00
Haroon Qureshi 9e9314a4a4 Ensure parsing always has a valid VFS.
Explicitly free allocated memory for local resources. (Upcoming
changes to `mju_closeResource` will not work for local resources.)

PiperOrigin-RevId: 854254013
Change-Id: I5cbb8264b590327767d5500f0c2a32ebe036bc4f
2026-01-09 10:45:48 -08:00
Sam Haves e37c2268a6 Release gil when compiling spec.
When compiling with threading, we will block the main thread anyways waiting for all threads to complete.

PiperOrigin-RevId: 854230560
Change-Id: Ief689d381afaa3aacc5d712a8df0cb4b6762251c
2026-01-09 09:50:15 -08:00
Haroon Qureshi 45e164bf8f Refactor 'ParseXML' and 'ParseSpecFromString' to use a shared helper function.
This allows us to remove the special "LoadModelFromString" resource provider.

PiperOrigin-RevId: 854207845
Change-Id: I6d00f2ab99b4351866e1d39dbeed96f29aaaf915
2026-01-09 08:40:40 -08:00
Haroon Qureshi 398e3dcf15 Use mj_parseXMLString instead of a test-specific LoadFromModelString.
This removes the need for a custom mjResourceProvider, but does require
reimplementing part of mj_loadXML in the fixture.

PiperOrigin-RevId: 854170820
Change-Id: Ib455cc5cdb5138213eb7e996dc32ac156f22a859
2026-01-09 06:34:27 -08:00
Haroon Qureshi 2c4f710cf4 Ensure resource providers are correctly initialized.
PiperOrigin-RevId: 854095105
Change-Id: I028265d7f51e6ab178f4f3a1d801ba773093214f
2026-01-09 02:07:24 -08:00
Sam Haves ce74475c39 Delete VFS created from assets dict before throwing error.
PiperOrigin-RevId: 853838173
Change-Id: Id0dd33b69657813275d1f42db54fae222c337791
2026-01-08 12:13:55 -08:00
Taylor Howell 310ac0c5ac MuJoCo Warp documentation: When To Use MJWarp?
PiperOrigin-RevId: 853830564
Change-Id: I9208e9a2f2781efbedc7846f5c13036ef83d5770
2026-01-08 11:54:57 -08:00
Taylor Howell 166fa17a1c MuJoCo Warp documentation: inertia matrix automatic sparsity.
PiperOrigin-RevId: 853805011
Change-Id: I8c0040f3b2b08d8615f1fbf559cdc9841e33438a
2026-01-08 10:47:27 -08:00
Sam Haves 2f2f9a30ba When loading models use mj_parse instead of mj_parseXML, and allow non-xml file types.
PiperOrigin-RevId: 853730923
Change-Id: I1c107daafd558bedb99338779c8174ee3e4d07e2
2026-01-08 07:22:51 -08:00
Yuval Tassa 1f4bb39b53 Fix typo in comment.
PiperOrigin-RevId: 853703158
Change-Id: Ic123f9273b99eeede1d76d3da20b5b5e9f898dcd
2026-01-08 05:56:29 -08:00
Taylor Howell ab939683bc MuJoCo Warp documentation: Why are numerical results from MJWarp and MuJoCo different?.
PiperOrigin-RevId: 853696967
Change-Id: I0cf8539e341d2aa1cfd07ac75de18128ce9beb3b
2026-01-08 05:34:23 -08:00
Haroon Qureshi 765bd54c7c Move GlobalModel class and functionality into its own file.
We'll need some of this functionality for tests.

PiperOrigin-RevId: 853652149
Change-Id: Ib924d886b73784a0f370285e0b82b2ed833e3e77
2026-01-08 03:08:12 -08:00
Yuval Tassa 8f5eb1e4f4 Improve bounds checking in engine_util_solve.c.
Add checks to ensure `snprintf` does not write beyond the allocated log buffer size, preventing buffer overflows.

Fixes #2661, #2673

PiperOrigin-RevId: 853643867
Change-Id: Ibdc47810158466dc961767284ac297df98916dac
2026-01-08 02:44:38 -08:00
ShanningZhuang a92574837e Fix XML loading in wasm demo app. Fixes #2960
PiperOrigin-RevId: 853635752
Change-Id: I20226de32f3141d40ec56956451f91ec7299e727
2026-01-08 02:18:42 -08:00
Copybara-Service 07deca990a Merge pull request #3006 from thowell:mujoco_warp_docs_modifying_fields
PiperOrigin-RevId: 853619026
Change-Id: I5a5348e1cdbee22e40b516cf8ed649645f54bf6f
2026-01-08 01:32:50 -08:00
Copybara-Service f4beb95212 Merge pull request #2990 from google-deepmind:mjwarp_doc_batched_model_field_warning
PiperOrigin-RevId: 853420667
Change-Id: I540b36611485054851e497c8f74302ac0fbedd36
2026-01-07 14:46:36 -08:00
Taylor Howell f703a0e023 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 853350801
Change-Id: Idb19c2865b94f4740daf8bc52ed3e7665a109d51
2026-01-07 11:42:11 -08:00
Yuval Tassa 608115ab95 Add output attribute to camera elements.
This attribute allows specifying the intended output types (e.g., RGB, depth, normal) for each camera in the XML. The output types are stored as bit flags in `mjModel`.

PiperOrigin-RevId: 853316261
Change-Id: I1ad2e94102593cf402756f8f4c80509371ca86d2
2026-01-07 10:22:27 -08:00
Sam Haves 3c93d6b979 Move cache creation into lambda initializer to avoid data race.
PiperOrigin-RevId: 853295269
Change-Id: Ic1c8f3d2fec876070da432f8b709b341f3c6cc0a
2026-01-07 09:29:54 -08:00
Matija Kecman e1261ba5f1 Fix perturbation rendering in webdemo
PiperOrigin-RevId: 853290958
Change-Id: Ifcea1091633597171c5268d5ee091bea3ddee45b
2026-01-07 09:18:45 -08:00
Yuval Tassa 775c0698c3 MJCF schema: use responsive grids for attributes
PiperOrigin-RevId: 853263519
Change-Id: I79cb6e6208061d9546f0dca7a941838caa6b1a91
2026-01-07 08:00:16 -08:00
Alessio Quaglino 5febca9eeb Remove gainprm trailing dimension in test_actuator_shortname.
PiperOrigin-RevId: 853243753
Change-Id: Ia46df64a2308ef0bbc94a396f0732e221e174ea0
2026-01-07 06:59:50 -08:00
Yuval Tassa 5be6f262b2 Fix legend call in MuJoCo tutorial notebook. Fixes #2447
PiperOrigin-RevId: 853220360
Change-Id: I1920af5fd01bcf654c7d9d11d8dd1c2f637ef748
2026-01-07 05:42:45 -08:00
Haroon Qureshi 9743c2d385 Use mjResourceProvider instead of custom LoadAsset callbacks.
PiperOrigin-RevId: 853172824
Change-Id: I60ef1207611c4da119cc3f0a7819088cffca6e4f
2026-01-07 03:03:23 -08:00
Yuval Tassa 4830f5a79e Add missing documentation for the asset cache.
Also improve `compile` sample timing logic and documentation.

PiperOrigin-RevId: 852855741
Change-Id: I9b2798208198ca68cf4cee9c968772954ada91c5
2026-01-06 11:07:42 -08:00
Copybara-Service 4a21b0ee01 Merge pull request #2831 from DavidPL1:fix-sample-compile-exitcodes
PiperOrigin-RevId: 852832955
Change-Id: Iddc7c9366f6e81800ed48a0790336db7dfa3e9d1
2026-01-06 10:18:43 -08:00
Yuval Tassa 3868ed0382 Improve XML schema usability
PiperOrigin-RevId: 852820889
Change-Id: I04eea45161f9e71f9ccf49afad57ff28fd099b35
2026-01-06 09:51:36 -08:00
Yuval Tassa fa044fe0e5 Use the word "primal" for things that relate to both Newton and CG.
PiperOrigin-RevId: 852634373
Change-Id: I2c7641bb92d9c01252f861b9c36e72ef6ddc6e98
2026-01-05 23:56:57 -08:00
Taylor Howell fa70f73691 fix generate_spec_bindings.py
PiperOrigin-RevId: 852414826
Change-Id: I50ddba2d238866ba313338040f020ff3a645e1e4
2026-01-05 12:42:26 -08:00
Taylor Howell 90449f7521 Update codegen for mjSpec add functions to add typed arguments and docstring.
PiperOrigin-RevId: 852351892
Change-Id: If785accdf8c9e48dd9924c54942856c1e00fd031
2026-01-05 10:14:49 -08:00
Taylor Howell 47ea0e76ae mujoco warp documentation: update modifying fields 2026-01-04 14:00:53 +00:00
Taylor Howell fba2021091 MuJoCo Warp documentation: Modifying fields.
PiperOrigin-RevId: 851709416
Change-Id: I48071a9dddd79b1e765f8ae170594d4687615877
2026-01-03 10:49:09 -08:00
Taylor Howell 28f14b3258 MuJoCo Warp documentation: Update Batched Model Fields code example.
PiperOrigin-RevId: 851699741
Change-Id: I30d98db7ee6bfe2104408fb0f84e472da649887b
2026-01-03 09:57:11 -08:00
Haroon Qureshi e3ddb126f5 Fix target name; should be PLATFORM not STUDIO.
(This was caused by a bad merge on my end.)

PiperOrigin-RevId: 851315742
Change-Id: Ifd5afa7f6cbd566ef2c15603e91a7360ea65c86a
2026-01-02 06:03:13 -08:00
Haroon Qureshi b9fa8ee6e9 Move all specialized rendering logic into Renderer class.
(We may consider splitting this class up into specialized subclasses at a later date.)

PiperOrigin-RevId: 851290789
Change-Id: Iee00b8e906eeb911de5799f784475ac6916ab55b
2026-01-02 04:25:07 -08:00
Taylor Howell 14e90f3897 MuJoCo Warp documentation: Array shapes.
PiperOrigin-RevId: 850969970
Change-Id: I41dce50644c9a6521e0bab9c84fea63f78e7a6ce
2026-01-01 02:46:48 -08:00
Yuval Tassa 451f40fa87 Link to Rust bindings in README.
fixes #2857

PiperOrigin-RevId: 850003287
Change-Id: I8ed1727206fb1a6a7655e61c37492eab8103d555
2025-12-29 03:57:23 -08:00
Matija Kecman 9f674b04a9 Fix ground plane rendering when using filament backend
PiperOrigin-RevId: 848473849
Change-Id: I096b20c6a5538ff95396bdf09f84ed5f2d3015ed
2025-12-24 01:25:51 -08:00
Yuval Tassa 70bc7be4bc Add additional data fields that can be reported by rangefinder sensors.
PiperOrigin-RevId: 848316991
Change-Id: Idbf7ba81b4da711a22c23302c8782ab2b0b98d82
2025-12-23 15:33:00 -08:00
Yuval Tassa f2e9097ed6 Change mjsCamera.resolution type from float to int.
Resolution is inherently an integer quantity (pixels).

PiperOrigin-RevId: 848276456
Change-Id: I92ee1aa88fd552fd42cb3871442f020f26d6fa6a
2025-12-23 13:14:32 -08:00
Yuval Tassa 9d646e6548 Extend rangefinder sensor to support cameras.
PiperOrigin-RevId: 848255889
Change-Id: I6e1a9ed13d29d2242558625a47e24e47ad6e87db
2025-12-23 12:04:49 -08:00
Yuval Tassa 4a871990e9 Fix mismatched signature in engine_ray.c
PiperOrigin-RevId: 847834144
Change-Id: Ib42008880f495cf7f3b9e0fd2394a4df64c66ad4
2025-12-22 11:41:23 -08:00
Yuval Tassa b28b5db680 Add mj_multiRayNormal for multi-ray casting with normal computation (not exposed in public header)
PiperOrigin-RevId: 847821078
Change-Id: I616441d3460406a92a10731d1a086af6163e96ad
2025-12-22 11:02:58 -08:00
Yuval Tassa 7fddeeaff6 Minor fixes to mj_multiRay
PiperOrigin-RevId: 847780959
Change-Id: I3588415f215bd5f1592bec6678a5bae45d5f0980
2025-12-22 08:52:36 -08:00
Haroon Qureshi a3e66cd5df Combine performance charts; add fullscreen mode.
PiperOrigin-RevId: 847751915
Change-Id: I819eb8d36224ddba38ef8532a038a2ef350890c8
2025-12-22 07:08:20 -08:00
Yuval Tassa 223ba99ec2 Add mju_rayFlexNormal (not exposed in public header)
PiperOrigin-RevId: 847746174
Change-Id: Ia8f597d296bf6a3eed9bd48b1c39b2ff2b5fcf90
2025-12-22 06:49:22 -08:00
Yuval Tassa c7f5766345 Add frustum visualization for orthographic cameras.
PiperOrigin-RevId: 847698917
Change-Id: I13633e8ba2d4718b127a5838c404ab74c6180e3d
2025-12-22 03:43:54 -08:00
Yuval Tassa 158525269b Refactor camera intrinsic parameter handling.
Move logic from parser to compiler.

PiperOrigin-RevId: 847689906
Change-Id: I844746081973205e1b33a3845add842e8b8c3c07
2025-12-22 03:08:18 -08:00
Yuval Tassa b77977a962 Update Programming/simulation chapter.
PiperOrigin-RevId: 847424298
Change-Id: Icc6efb05dee5e67a5813ed04caa15a5703e59aee
2025-12-21 08:16:39 -08:00
Yuval Tassa b8a4ac5d48 Refactor camera orthographic attribute to projection enum.
PiperOrigin-RevId: 847069028
Change-Id: I7f686fe654e9b56519cab8bd2f37c9cc40091d3f
2025-12-20 03:28:29 -08:00
Sam Haves 44c8ef890d When building with USD enabled, add functionality that automatically registers the mujoco USD plugins.
PiperOrigin-RevId: 846767370
Change-Id: Ieedbe127353623c11150551c1409d340dbc57421
2025-12-19 09:39:03 -08:00
Sam Haves 3d9c195e3c Fix rpath for usd target shared libs.
PiperOrigin-RevId: 846759676
Change-Id: I5b2a73b3f997d4d0d447e051c43069ae7418a7ec
2025-12-19 09:14:45 -08:00
Yuval Tassa 849a650143 Refactor mju_cholUpdateSparse to use a dense accumulator, 1.5-2x function speedup.
PiperOrigin-RevId: 846754379
Change-Id: Ie599658db2907a26095072d97d07b99a693050dc
2025-12-19 08:57:45 -08:00
Sam Haves 2935af23f0 Add MJAPI to Get/SetUsdPrimPathUserValue declarations.
PiperOrigin-RevId: 846745363
Change-Id: I31f0af0675578a3dd63db7c56d9258206e19471d
2025-12-19 08:31:26 -08:00
Sam Haves 9e150fe82c Add separate build step for OpenUSD to third_party_deps.
This will fetch and call the build_usd.py build helper for OpenUSD and build within the MuJoCo _deps folder. Simplifying the build process for MuJoCo with USD. Users can still provide their own USD build, but must now do so via pxr_DIR.

PiperOrigin-RevId: 846735578
Change-Id: I0da7eb2da6465e2d518084340e762bf370adb6d5
2025-12-19 08:00:15 -08:00
Yuval Tassa 76e0a78b32 Use two-step sparse Cholesky in Newton solver.
17% overall speedup for `100_humanoids.xml` as measured by `testspeed`

PiperOrigin-RevId: 846723342
Change-Id: Ibc41487bfc576c992f14853640d0b6000f5b47b2
2025-12-19 07:20:09 -08:00
Yuval Tassa 45b0153067 Refactor sparse Cholesky factorization into symbolic and numeric phases.
The new symbolic function is a generalization of the function it replaces. In this CL it takes two unused temp arrays. The actual change in behavior happens in the followup.

New benchmark test output below ("L" is 2 humanoids and 100 free objects, "XL" is 100 humanoids). Note that `symbolic` is only ever called once per Newton iteration, while `numeric` is sometimes called multiple times (when the rank-1 update fails), hence timing them separately is valuable.

```
Benchmark               Time(ns)        CPU(ns)     Iterations
--------------------------------------------------------------
BM_old_L_mean              84382          84703          19547  11.807k items/s
BM_symbolic_L_mean         16345          16381          88414  61.055k items/s
BM_numeric_L_mean          10986          10994         120000  90.999k items/s
BM_old_XL_mean           1241208        1244212           1200  803.924 items/s
BM_symbolic_XL_mean       130917         131042          12720  7.631k items/s
BM_numeric_XL_mean         77004          76767          21116  13.029k items/s
```

PiperOrigin-RevId: 846704054
Change-Id: Ib0c365724d63bf2b81606ca5353756a6496c3a26
2025-12-19 06:11:55 -08:00
Haroon Qureshi d1fd11bccd Refactor SaveScreenshot into a more useful RenderToTexture function.
Removes a few unused functions from helpers library.

PiperOrigin-RevId: 846661437
Change-Id: I815ffe1990098dedb71f694af088d85294f9c7de
2025-12-19 03:33:59 -08:00
Haroon Qureshi 522ff1cd80 Allow ImGui uploaded images to be resized or destroyed.
PiperOrigin-RevId: 846354598
Change-Id: I86882813ab607945fffc763122248e167be856a8
2025-12-18 11:42:19 -08:00
Sam Haves b5b654f00c Correctly handle segmentation and ID_COLOR flag in filament.
PiperOrigin-RevId: 846319715
Change-Id: I244ae52c34079b79d3179fafdf6aa506cc89e1ff
2025-12-18 10:14:13 -08:00
Sam Haves 05e1c452c7 Add VFS parameter to mjpDecoder decoding function.
PiperOrigin-RevId: 846242734
Change-Id: I317e11e6fcd965f66416abcf690a3a65d043e9ee
2025-12-18 06:38:40 -08:00
Haroon Qureshi bebdd62943 Allow studio to search for models in predetermined search paths.
A future CL will allow users to specify search paths in their settings.

PiperOrigin-RevId: 846240293
Change-Id: I1a1a4027d0fc85004a12fe01a406f50fd929f3e4
2025-12-18 06:32:24 -08:00
Haroon Qureshi 7190bd4912 Add flag for depth rendering.
PiperOrigin-RevId: 846203691
Change-Id: I5ec494446bcfc1f7c81536a87dd24f9967973563
2025-12-18 04:36:26 -08:00
Yuval Tassa 47e35e632f Add a test for equivalence of different solvers.
PiperOrigin-RevId: 845777469
Change-Id: I76a162b71bea349cca3472001360181654a5d571
2025-12-17 08:21:52 -08:00
Taylor Howell e95f46f84a MuJoCo Warp documentation: sparse Jacobians.
PiperOrigin-RevId: 845342391
Change-Id: I2167faca8a0a70e2c56a8cc329c09b1b9243e44c
2025-12-16 10:43:00 -08:00
Yuval Tassa 08b4b4144d Add tests for mju_cholUpdate and mju_cholUpdateSparse.
PiperOrigin-RevId: 845229292
Change-Id: Ide1406f85e49fe5a5b339bedff7ff6dd8099e5e8
2025-12-16 05:59:40 -08:00
Yuval Tassa 2b9940bc67 Add private function mju_fillInt
PiperOrigin-RevId: 845217293
Change-Id: I604372ab7ea7f4d47d9427d36dc8cd78e60d84ca
2025-12-16 05:16:50 -08:00
Google DeepMind 477a14dcb2 Add WASM binding for mj_compile.
It does not support model assets management via VFS yet.

PiperOrigin-RevId: 844864882
Change-Id: I422d7896ed024fc6f5c3fa923a58cdc9059f3bee
2025-12-15 11:58:26 -08:00
Sam Haves eef71832db Remove usage of usdImaging tokens to avoid needing to build imaging.
PiperOrigin-RevId: 844768270
Change-Id: Iba0a03646e56d9be5accf754f97ec37db8055425
2025-12-15 07:44:18 -08:00
Taylor Howell 8e39d50496 mujoco warp documentation: batched model fields graph capture warning 2025-12-15 15:34:02 +00:00
Haroon Qureshi 52ca07e210 Decoder decode function should take a non-const pointer to mjResource.
This is because mjcReadResource requires a non-const pointer.

PiperOrigin-RevId: 844737328
Change-Id: I88d217aa85a66023f6b222437403c136448cabfe
2025-12-15 06:04:05 -08:00
Taylor Howell f0572c735a MuJoCo Warp documentation: Collision sensors.
PiperOrigin-RevId: 844695759
Change-Id: I98cc6f127527a8d05b02cf5b06038bba2d03fae0
2025-12-15 03:37:10 -08:00
Taylor Howell b64b527e13 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 844675206
Change-Id: I02f75561eac3520d7107708dcece10cc82c106cd
2025-12-15 02:30:16 -08:00
Yuval Tassa ccbfc6c8bf Improve line search initialization logic and first Newton step acceptance.
PiperOrigin-RevId: 844316808
Change-Id: I0a7639a486c75f122db7f8b8c0df42ef810f060c
2025-12-14 01:50:52 -08:00
Matija Kecman e7077b5a05 Fix testspeed argument count check
PiperOrigin-RevId: 844128965
Change-Id: I3089c7e71efde1ee6fe7c24903d634ed44dfd6eb
2025-12-13 11:20:02 -08:00
Yuval Tassa e3a860de69 Update function signatures in engine_util_spatial.h to appease fussy GCC
PiperOrigin-RevId: 843752024
Change-Id: I041efe6acc5a4a44488bb9ec09101681d47c37c5
2025-12-12 10:47:31 -08:00
Taylor Howell 942c2622ee MuJoCo Warp documentation: update flex feature parity.
PiperOrigin-RevId: 843711786
Change-Id: Ie392452b02d4894f04e826b74b558b2f7e9342d8
2025-12-12 08:59:37 -08:00
Haroon Qureshi 43bcbb158c Load last saved GUI configuration on first load.
Also save theme to the configuration.

PiperOrigin-RevId: 843710929
Change-Id: I7ce9ce0f026d2cb5f79addf6c16c9b540bf11954
2025-12-12 08:56:53 -08:00
Yuval Tassa 499291e5c2 Fix aliasing issues in engine_core_smooth.c
PiperOrigin-RevId: 843699660
Change-Id: I21d4ed09284624ce80fcd5b1d572b9084e95e1f1
2025-12-12 08:25:06 -08:00
Haroon Qureshi 3da421afaa First-pass implementation of web-based studio app.
PiperOrigin-RevId: 843685213
Change-Id: I2642a21d5573ef548eece0eb9a2c634e4881eec5
2025-12-12 07:42:42 -08:00
Yuval Tassa 157d261701 Fix aliasing issues in engine_collision_primitive.c
PiperOrigin-RevId: 843665186
Change-Id: I76cd479991f6083495e7ad95c2f57a8ef8fde925
2025-12-12 06:36:34 -08:00
Yuval Tassa 9fc37a3be4 Fix aliasing violations in engine_collision_box.c
PiperOrigin-RevId: 843647612
Change-Id: If8ad12c058a30ec475b9eb47d315019edbb8a7bb
2025-12-12 05:35:42 -08:00
Yuval Tassa 600f0f20bc Introduce private header engine_inline.h exploiting restrict and avoiding loops and copies in some commonly used utility functions.
PiperOrigin-RevId: 843635464
Change-Id: I3b0553eea98424ccc7def77e3769e2994f3e9014
2025-12-12 04:49:29 -08:00
Haroon Qureshi a0a56065e0 Use hex values instead of u8 string literals.
PiperOrigin-RevId: 843583709
Change-Id: Ib55cfd472de2f83b0455ebf95f6826c887f6dd70
2025-12-12 01:45:13 -08:00
Haroon Qureshi e07adc387a Update themes to differentiate from default dear_imgui themes and add a classic theme that's similar to simulate.
PiperOrigin-RevId: 843313013
Change-Id: Id01841097f32a5b01acd8fcf59392a73acad8f27
2025-12-11 11:46:12 -08:00
Matija Kecman 3c19b63ed3 Refactor texture.data to be handled using py::bytes
PiperOrigin-RevId: 843226742
Change-Id: I7ab920da3c387467b1fced27f557c6edd1af4bce
2025-12-11 08:06:12 -08:00
Haroon Qureshi 87d333c64a Allow MJB and XML content to be loaded directly.
PiperOrigin-RevId: 843180720
Change-Id: Id4f2bf81507b971dfbbf250d775d7fdfc76517df
2025-12-11 05:41:43 -08:00
Yuval Tassa 1ff74ba810 Change the type of state signature arguments from unsigned int to int
PiperOrigin-RevId: 843162492
Change-Id: I51d3324f088e8055898e115bdd32267c5950a412
2025-12-11 04:34:36 -08:00
Yuval Tassa fe0a11d58d Change Filament background color to black.
PiperOrigin-RevId: 843152096
Change-Id: I2ef87ffffb9cc8662fa6353c6d38f1046f21b34b
2025-12-11 03:56:34 -08:00
Haroon Qureshi caec236b2f Make mj_loadModelBuffer a public API.
PiperOrigin-RevId: 843105390
Change-Id: I4058471b4cf64995dd5ab43e9c8c24e322004b62
2025-12-11 01:24:17 -08:00
Taylor Howell d0cf2a3ca5 MuJoCo Warp documentation: named access / bind.
PiperOrigin-RevId: 842689646
Change-Id: I5b7920dd5df5838497943da20da4aa61a68f0ec2
2025-12-10 06:01:22 -08:00
Taylor Howell f150e72b34 MuJoCo Warp documentation: Tutorial notebook.
PiperOrigin-RevId: 842685107
Change-Id: I354ab983b1f0061eb168d1ce86c12d974e5bb35e
2025-12-10 05:43:50 -08:00
Yuval Tassa 6bcb22730d Minor clean-up of some visualization code.
Move mjvGeom acquire/release into helper functions, where possible.

PiperOrigin-RevId: 842675435
Change-Id: Ie5aaf206927251e79b20cc4101a7017645d5dd4b
2025-12-10 05:09:53 -08:00
Google DeepMind 11f0997edf Internal change.
PiperOrigin-RevId: 842636101
Change-Id: I5fc8e1f5e4caee9d909963ebe396572b13b455b7
2025-12-10 02:58:38 -08:00
Haroon Qureshi 9c1b8d8cfb Enable font loading for wasm builds.
PiperOrigin-RevId: 842627994
Change-Id: I347f79ec668f31a8bbc4d26638a045e29084d715
2025-12-10 02:31:46 -08:00
Yuval Tassa f06aa45ea6 Consolidate ray normal functions.
PiperOrigin-RevId: 842300829
Change-Id: Ic5e921084710cb044a4f49ea9b566d277838aaa1
2025-12-09 10:36:10 -08:00
Yuval Tassa 85e6f6de3c Ignore unsupported light types in GL3 renderer.
PiperOrigin-RevId: 842271116
Change-Id: I632f7ed8e2a6488d5a8eb228928e26c8fcbdff66
2025-12-09 09:22:29 -08:00
Yuval Tassa 32d7b87ba7 Improve studio 2D plots
PiperOrigin-RevId: 842260702
Change-Id: I4644b69da92b9d015eb2d140b98f68c05d31a222
2025-12-09 08:56:51 -08:00
Yuval Tassa 5b1fa666fb Add mj_rayHfieldNormal (not exposed in public header)
PiperOrigin-RevId: 842259581
Change-Id: I27d6c46024d55addbc22eed276331e2ef5acfa7d
2025-12-09 08:53:47 -08:00
Haroon Qureshi 7553541b4b Use public mj_parseXml function.
PiperOrigin-RevId: 842245812
Change-Id: I26e1f992f82050a36373ee3a3f2c97c399b4e788
2025-12-09 08:14:32 -08:00
Haroon Qureshi 97eb307ce9 First pass at mjSpec Explorer and Properties windows.
Displays the list of bodies and joints from the mjSpec and displays
values for the selected element.

Functionality is very limited and a bit non-intuitive. However, we want
to get this into our users hands to start getting feedback.

PiperOrigin-RevId: 842228895
Change-Id: I2491cd5e0acaf622110e0f6b8406919024d3607a
2025-12-09 07:28:26 -08:00
Yuval Tassa c064abc3da Change row-flipping logic for heightfields.
Move row-flipping logic from `mjCModel::CopyBack` to `mjXWriter`.

PiperOrigin-RevId: 842220322
Change-Id: I6fb09db6c9e8689f6e435f82f58dd3e7c4314478
2025-12-09 07:02:21 -08:00
Haroon Qureshi 925c533580 Move playback speed control to the toolbar.
Initialize playback speed based on the model's global.realtime setting.

Adjust layout and tweak colours of the status and tool bars.

PiperOrigin-RevId: 842214796
Change-Id: Iff9cda74178df28a0787693242fee81e011014fc
2025-12-09 06:47:38 -08:00
Yuval Tassa cc914c9ec7 Modify studio keyboard bindings to conform to MuJoCo API.
PiperOrigin-RevId: 842197387
Change-Id: I6ee9b1f5050cb4a8c2f67253f37481c61c91fdbd
2025-12-09 05:53:14 -08:00
Google DeepMind 1483aefe5f Make actuator_length, cdof and cdof_dot public.
PiperOrigin-RevId: 842182467
Change-Id: Id14a1c8266e13a6f95e1c87ea07da993b614b62e
2025-12-09 04:57:42 -08:00
Yuval Tassa f65c1cdfd1 Add mj_raySdfNormal (not exposed in public header)
PiperOrigin-RevId: 842178540
Change-Id: I5d2db555e9b6c0fa0daaa8bc14c7781663e4c94e
2025-12-09 04:43:39 -08:00
Matija Kecman bf49fe3daa Enable reading textures from spec in Python
PiperOrigin-RevId: 842151742
Change-Id: I477d118cc7e2385d29b395b192fa89e9facb9c3e
2025-12-09 03:08:32 -08:00
Haroon Qureshi e1e2248925 Internal changes only.
PiperOrigin-RevId: 842099953
Change-Id: Ia11feec323504976cdc3e6d7170435b74ed33fcd
2025-12-09 00:18:06 -08:00
Haroon Qureshi 99a90cb649 Don't do GUI rendering when rendering to texture.
PiperOrigin-RevId: 842089364
Change-Id: Iaecebdc677e946c7fc618395205097462a56f2d1
2025-12-08 23:44:50 -08:00
Yuval Tassa 735b31fc89 Fix triangle lighting in native renderer.
PiperOrigin-RevId: 841796563
Change-Id: I778e0e02aa8b4033531d4fadc091610418ab909e
2025-12-08 09:27:04 -08:00
Taylor Howell 15145c0098 MuJoCo Warp documentation: Compilation.
PiperOrigin-RevId: 841761913
Change-Id: Ic1b1942a47299db48c424ad1f9e3709b05acc55e
2025-12-08 07:50:23 -08:00
Haroon Qureshi e238b65843 Support both 3 and 4 channel images and use a safer way to assign IDs to images.
PiperOrigin-RevId: 841727607
Change-Id: I319db4291ecee27f4ceb7b7e952c6f68e7f8b96d
2025-12-08 05:55:00 -08:00
Gabe Oppenheimer 96e376451c Update MuJoCo version from 3.4.0 to 3.4.1 following the 3.4.0 release
PiperOrigin-RevId: 840914696
Change-Id: Iffabc70dd174384ba1c535cafcd34982ff8e5712
2025-12-05 16:15:56 -08:00
Gabe Oppenheimer e55fff5dea CI issues resolved, we're going ahead with the 3.4.0 release.
PiperOrigin-RevId: 840763554
Change-Id: Ib50b00ec43d8713821f98a131fb19640810ea777
2025-12-05 09:37:40 -08:00
Haroon Qureshi fcdacd0690 Fix crash when using image-based textures.
Image lights are not normal lights, so use nullptr as a placeholder.
Add checks for nullness when iterating over the lights.

PiperOrigin-RevId: 840695579
Change-Id: I092515ae814523e85f4f5ce87b2bac2241f4ea35
2025-12-05 06:08:13 -08:00
Haroon Qureshi 6e7b2ba4c3 Reuse renderable entity instead of recreating every frame.
PiperOrigin-RevId: 840680350
Change-Id: Ie26862f8993c4b1cf071ee867d89bcc8182d3dd2
2025-12-05 05:10:12 -08:00
Haroon Qureshi f18c9996e6 Allow uploading textures for use with ImGui.
PiperOrigin-RevId: 840669528
Change-Id: I7c5854d966dd024cd492953f86bca961cfaf88b8
2025-12-05 04:31:32 -08:00
Matija Kecman e93786c161 Fix WebGL rendering for the webdemo
PiperOrigin-RevId: 840640628
Change-Id: I4bac3bf634e66da01174927bf6096bc1df642e10
2025-12-05 02:39:54 -08:00
Taylor Howell 4e84671a15 MuJoCo Warp documentation: Determinism.
PiperOrigin-RevId: 840630917
Change-Id: Ie5f3ac34cee8812f20d6ae4fa6004385c5b048e0
2025-12-05 02:09:26 -08:00
Baruch Tabanpour fc109f0ab5 Small fix to testspeed
PiperOrigin-RevId: 840607453
Change-Id: If913866cc0a3d4d3e6c39c7b5948fa167678ccad
2025-12-05 01:28:33 -08:00
Gabe Oppenheimer 237a5e5c55 Revert the changelog to unreleased state, the 3.4.0 release will be delayed due to internal issues with CI.
PiperOrigin-RevId: 840362346
Change-Id: Ic0fb5d6d521c5abc1b98d5242416eac6c7d056c8
2025-12-04 12:53:02 -08:00
Haroon Qureshi 6ed9f2be7a Removed unused font uploading functionality.
Font textures are handled directly through ImGui.

PiperOrigin-RevId: 840259537
Change-Id: I5b6b0dc5d2c1c7066b4a23f0106de34285f40e6c
2025-12-04 08:38:58 -08:00
Haroon Qureshi da36e822a8 Allow material default classes to define texture layers.
PiperOrigin-RevId: 840254100
Change-Id: I59f67fc4d1485cf80bbc005d1b35cda6224248ed
2025-12-04 08:22:55 -08:00
Haroon Qureshi 5ee8b646f7 Move Style and Layout configuration to shared GUI library.
PiperOrigin-RevId: 840246253
Change-Id: Ic4664b62e86e70fd6780cd9eb885978064c5f585
2025-12-04 08:02:16 -08:00
Haroon Qureshi 5f59104877 Properly handle PBR materials where no color texture is provided.
In this case, we'll use the mujoco material color which is then multiplied with a white fallback texture.

PiperOrigin-RevId: 840244521
Change-Id: I2134f45dcbaed7db268e5278ca8ac5429488943d
2025-12-04 07:57:24 -08:00
Haroon Qureshi 680e9a6b79 Update studio build script and instructions.
Mujoco studio now works on Windows and MacOS.

PiperOrigin-RevId: 840235447
Change-Id: I66d3430d5d994de2eb13ee08ad3051c6c7187e12
2025-12-04 07:27:37 -08:00
Haroon Qureshi c5cd276e1f Cleanup model loading flow.
Inlines the platform::LoadMujocoModel into the App class which simplifies
the logic and allows us to correctly display loading errors.

Also updates shortcuts:

Load Model (Ctrl+L) -> Open File (Ctrl+O)
Reload Model (Ctrl+R) -> Reload Model (Ctrl+L)

PiperOrigin-RevId: 840232553
Change-Id: I957d29046ae681d2aeb69310c3a2eec64d042d49
2025-12-04 07:20:02 -08:00
Haroon Qureshi 8823e9fedf Improve imgui texture management.
Keep track of all textures and recreate them as needed. This makes imgui
textures robust to render context reinitialization.

PiperOrigin-RevId: 840228061
Change-Id: Ia4ac35ff93a41ac74020f334adc438df4b030f7c
2025-12-04 07:05:14 -08:00
Haroon Qureshi 54070fc71b Disable bent normals by default.
PiperOrigin-RevId: 840216781
Change-Id: Icf24d73939fa138da46e2da7aa69a6574e6f98ec
2025-12-04 06:28:53 -08:00
Sam Haves a942fd4875 Make filament segmentation shader distinct colors optional.
Previously we were computing at material update time a color for the geom based of it's
segid. This made segids unrecoverable from the resulting buffer. With this change
we allow SceneView creators to specify if they want the segmentation buffer to be purely
for visualization with distinct colors.

PiperOrigin-RevId: 840016870
Change-Id: I5920f248ace0901023e6545c7d8dd2b23f9aa397
2025-12-03 19:26:20 -08:00
Tom Power 4a6b9456aa Set default headlight intensity to zero if there are no physical lights in the scene.
PiperOrigin-RevId: 839962392
Change-Id: I086d8135604982c42381a9b49cec53773c7fa362
2025-12-03 16:31:11 -08:00
Sam Haves 8507b62556 Cache the rendering mode used to allow headless segmentation rendering.
This also moves the read call into the frame, per the recommendation in the filament documentation. We also don't need to flush and wait for the engine twice, just defer to the end of readPixels.

PiperOrigin-RevId: 839953612
Change-Id: I52205147794440322ca976c52fb4905207c21473
2025-12-03 16:06:39 -08:00
Haroon Qureshi 14513a04c2 Wait until previous render is finished before submitting another request.
PiperOrigin-RevId: 839707507
Change-Id: Ib39538540ff6080d197c2ea853b7273cc56084e7
2025-12-03 05:01:44 -08:00
Haroon Qureshi e409538831 Ensure window scale is initialized on creation.
PiperOrigin-RevId: 839699437
Change-Id: I99e477ac49b56726b77389306aec49c895e160fa
2025-12-03 04:29:52 -08:00
Yuval Tassa 55664b63e1 Fix broken cross-references in mjwarp/index.rst
PiperOrigin-RevId: 839194214
Change-Id: Ia1aca7331bc5d77fb4ef6ce7efefc3d55a1d99b3
2025-12-02 03:56:05 -08:00
Gabe Oppenheimer 951257ad54 Fix: Update changelog formatting
PiperOrigin-RevId: 839126146
Change-Id: Ifa349b6fd013e4c23fd96b988eacaa7c9d44532c
2025-12-02 00:26:56 -08:00
Yuval Tassa e095bb6d41 Improve rendering of dynamics pipeline schematic
PiperOrigin-RevId: 838865159
Change-Id: I225e94508be7edb8f8217ec5abb2f609cbb39ae5
2025-12-01 11:36:01 -08:00
Gabe Oppenheimer b663b7602b Final preparations for the v3.4.0 release
PiperOrigin-RevId: 838824676
Change-Id: Icb5a825cb41be4d0730f4a6729b63531d649066f
2025-12-01 10:06:33 -08:00
Haroon Qureshi 448fc0e4d5 Report the actual GPU framerate rather than the main thread submit rate when using the filament renderer.
PiperOrigin-RevId: 838775463
Change-Id: If66644d284a4a9e0263cf31bfbd1785b18e0209b
2025-12-01 08:02:38 -08:00
Yuval Tassa 4896e698f6 Update "mjModel changes" section in simulation.rst
PiperOrigin-RevId: 838768328
Change-Id: I5c09186e52115df37e9412495ecc7dceddb2ed8a
2025-12-01 07:40:09 -08:00
Yuval Tassa 19e2d0ae2f Add mj_fwdKinematics and a table improving documentation of the MuJoCo computation pipeline structure.
PiperOrigin-RevId: 838768130
Change-Id: I1a22d5cdca7db704ba4cea1667fcbecb16b87005
2025-12-01 07:39:00 -08:00
Google DeepMind 4c40d5938e Add type hints to tuple constants in codegen/generators/constants.py.
`tuple` is better than `list`  for constants if we don't expect they get modified by other parts of the code

PiperOrigin-RevId: 838748519
Change-Id: Ic950a78be7ad7518361c046d7e4542607070d3a2
2025-12-01 06:37:03 -08:00
Yuval Tassa d3c858ed32 Make table shadows visible in dark theme, add a table type with smaller text.
Add a light box-shadow to docutils tables (excluding mjcf-attributes) when in dark mode or auto mode with dark preference, so that the table boundaries are visible against the dark background.

PiperOrigin-RevId: 838741947
Change-Id: Ic788f9669ea65d290f927927b389fcb51227a55a
2025-12-01 06:13:39 -08:00
Haroon Qureshi 94fb10bf3d Internal changes
PiperOrigin-RevId: 838741176
Change-Id: I9def07b3f7e963d2787d71019d303ba1eb75622c
2025-12-01 06:11:15 -08:00
Haroon Qureshi 9b7134b15b Add OSX and WIN32 support for getting the native window pointer.
PiperOrigin-RevId: 838720433
Change-Id: Id7123bcf456d0c2d32e67b204564fe8c495004cd
2025-12-01 04:57:24 -08:00
Yuval Tassa ad24889bb9 Add mj_rayMeshNormal (not exposed in public header)
PiperOrigin-RevId: 838707353
Change-Id: If31d2454e0668f750bcba21ee42f81ef962e9097
2025-12-01 04:13:52 -08:00
Haroon Qureshi 139a5b6494 Rename toolbox to platform.
PiperOrigin-RevId: 838701951
Change-Id: I339eafd35d919710cb47bb04e9a8e29f92739513
2025-12-01 03:58:34 -08:00
Haroon Qureshi c6b587b515 Use cmake FILE(COPY) for deploying custom CMakeLists.txt.
PiperOrigin-RevId: 838696575
Change-Id: I3c61bda9d1d89185f257797c2e0c0f4ef2c7cb95
2025-12-01 03:37:37 -08:00
Haroon Qureshi fe74ea2e7b Match definition with declaration.
PiperOrigin-RevId: 838682770
Change-Id: I537ae9652dc64a02d2e3de8ddda351102d3cec35
2025-12-01 02:49:18 -08:00
Haroon Qureshi a7e62a6755 Set visual studio working directory to the bin directory.
PiperOrigin-RevId: 838681802
Change-Id: I764809d2145688c8a353907dc599a604ae944d0b
2025-12-01 02:45:53 -08:00
Haroon Qureshi ea78d83363 Use working directory if no HOME path specified.
PiperOrigin-RevId: 838680600
Change-Id: I8869da40042bb0b4edcbfe1e626c3188d0631c5e
2025-12-01 02:42:14 -08:00
Matija Kecman 69179ead48 Internal change.
PiperOrigin-RevId: 837829087
Change-Id: I110f2f9d1dff2aff8bcad7ac22ea8ed82323185f
2025-11-28 06:36:01 -08:00
Yuval Tassa 7caa3d6703 Add names to some sensors in sleep test XML.
PiperOrigin-RevId: 837611931
Change-Id: Ib077765d795037bdd0d32d19e1c7d5bf9b256d51
2025-11-27 14:09:21 -08:00
Yuval Tassa 8f9250472e Improve names of Free camera control modes.
PiperOrigin-RevId: 837605181
Change-Id: I01b65706fc4f9857df4d025cd3f4587d24ee5af5
2025-11-27 13:34:09 -08:00
Yuval Tassa 2ea403575e studio: invert mouse scroll direction for camera zoom.
PiperOrigin-RevId: 837603911
Change-Id: I193a1abc0a3317aa998e7f82b9ce4b282ae7a913
2025-11-27 13:28:24 -08:00
Yuval Tassa dc5c2faf91 Cosmetic cleanup in engine_collision_sdf.c
PiperOrigin-RevId: 837554740
Change-Id: Ic962af6a2c5f9f4c7edd48cbdf110ed11bc5e378
2025-11-27 09:24:56 -08:00
Google DeepMind 8a5c52d395 Use a dedicated function for wrapper struct names
This change introduces a `wrapper_struct_name` function in `structs.py` to consistently generate the name of the C++ wrapper struct from a C struct name. All call sites in `functions.py` and `structs.py` that previously used `common.capitalize` for this purpose now call `wrapper_struct_name`.

PiperOrigin-RevId: 837544242
Change-Id: Ibe5fea8294283dae63bb8d064fd8beb8cfd3f2fe
2025-11-27 08:42:33 -08:00
Matias Manevi 9ca1598b23 Refactor MuJoCo WASM struct codegen.
PiperOrigin-RevId: 837530063
Change-Id: I57518b2fbb536f356a5e15839d8e17f455bccde9
2025-11-27 07:42:41 -08:00
Haroon Qureshi 5163dfa823 Move UX drawing functions into a shared library.
PiperOrigin-RevId: 837528296
Change-Id: I153a000cde424254384cf168606f32f7925ca076
2025-11-27 07:34:51 -08:00
Haroon Qureshi 23825a5bcf Implement sensor chart.
PiperOrigin-RevId: 837498928
Change-Id: I84b5911a44fe60a96b3ef34d514eb39702be7402
2025-11-27 05:38:24 -08:00
Haroon Qureshi 406062efaf Remove TODO (charts have been implemented).
PiperOrigin-RevId: 837151123
Change-Id: Iae37fdf4ed143e0523a1e4244e3a897211a5751b
2025-11-26 09:13:58 -08:00
Haroon Qureshi 9274a0014a Fix UV scaling.
PiperOrigin-RevId: 837147525
Change-Id: If54d069ddb3fec0852f1941788cb03d5604a252f
2025-11-26 09:01:56 -08:00
Matija Kecman 05f194c412 Reorganization of the WASM bindings.cc template
* Move all bindings into a single EMSCRIPTEN_BINDINGS block
* Move all auto generated bindings line to the start of the block
* Alphabetically sort the constants binding lines

PiperOrigin-RevId: 837142009
Change-Id: I218a37dbc0ca6c6f16a455718889c08fe1b41d56
2025-11-26 08:43:51 -08:00
Haroon Qureshi c7e0c01e80 Prevent decorative elements from casting shadows.
PiperOrigin-RevId: 837112208
Change-Id: I4ecc110eec1a2166df7a07d8bb9ec37df36b7c89
2025-11-26 07:27:41 -08:00
Haroon Qureshi 0425355efc Use a switch statement for handling geometry types.
PiperOrigin-RevId: 837097811
Change-Id: Ic473f9da3d4189430e98670afdae7bb3cca5ccbc
2025-11-26 06:40:41 -08:00
Haroon Qureshi aa25075ea4 Implement triangle geoms.
PiperOrigin-RevId: 837079122
Change-Id: If7aa0904c6f3e7c62477b75b17d67259fe2bdabb
2025-11-26 05:33:04 -08:00
Haroon Qureshi ed69fe85f1 Only build fonts when using filament backend.
PiperOrigin-RevId: 837054382
Change-Id: I7ef3b6b954738776f266533f4c48ac4e3c43b4bf
2025-11-26 04:00:34 -08:00
Kyle Bayes ae24034f24 Refactor hfield-convex collision code. This should be a no-op.
PiperOrigin-RevId: 837045492
Change-Id: I82851615c7f69774da83cab361316e5a6e9982c6
2025-11-26 03:26:56 -08:00
Haroon Qureshi fcad41a5b1 Implement solver stats charts.
PiperOrigin-RevId: 837045292
Change-Id: I1dfe1e10bb6d62f4d994a82c9b645b471fca5500
2025-11-26 03:25:45 -08:00
Matija Kecman 011166a13a Update the studio/README.md to summarize platform support.
PiperOrigin-RevId: 837038187
Change-Id: I00882e0a9882947af7c684e2d5521356ad1468ce
2025-11-26 02:58:05 -08:00
Haroon Qureshi 4ce0ee2011 Update texture handling due to recent ImGui upgrade.
PiperOrigin-RevId: 837030453
Change-Id: I042c4a7df7dc6c7e07c40eb5f32e5031e5b1d60a
2025-11-26 02:36:02 -08:00
Taylor Howell f2823836a6 Updates for MuJoCo Warp documentation.
PiperOrigin-RevId: 837027234
Change-Id: Idf7a69b14ce23d5ac5ed36367a14c77a00276846
2025-11-26 02:26:13 -08:00
Yuval Tassa a9fe8340bf Remove extraneous colons in XMLreference
PiperOrigin-RevId: 837017632
Change-Id: Ie89adf4fd3725cfa4b8eb0bcddedd4fa886ed8fb
2025-11-26 01:56:28 -08:00
Haroon Qureshi a1579ac3e1 Use static_cast instead of reinterpret_cast.
PiperOrigin-RevId: 836990495
Change-Id: I276b5d83e18cc87364f8f2cae0c585b6673c738e
2025-11-26 00:25:32 -08:00
Haroon Qureshi d940b2b7f9 Update versions of imgui and implot.
PiperOrigin-RevId: 836844278
Change-Id: If0a522fcb7637df9cd422df6cb5bef641e675b0b
2025-11-25 16:08:13 -08:00
Google DeepMind c07e3cb8a8 Internal changes only.
PiperOrigin-RevId: 836814927
Change-Id: I18bde7ae47b5c106ab9c85e434a8b491c8d79d04
2025-11-25 14:36:57 -08:00
Matija Kecman 181dcab6be Combine markers and content and reorganize parts of the WASM template file
PiperOrigin-RevId: 836729951
Change-Id: Ib3bb25a23325cfbd84fd0439243db37ca8236bf3
2025-11-25 10:40:44 -08:00
Gabe Oppenheimer b6e162d6fa Update MuJoCo version from 3.3.8 to 3.4.0
PiperOrigin-RevId: 836719207
Change-Id: I28cbc90cee42aebfb5a4201561289ef6747cdc83
2025-11-25 10:16:02 -08:00
Google DeepMind 6e59f61c70 Make WASM codegen output to be alphabetically ordered.
PiperOrigin-RevId: 836680575
Change-Id: I7ddb7267c0db4911b2e84528f948dee6fccdf81d
2025-11-25 08:29:30 -08:00
Taylor Howell 6208730744 MuJoCo Warp documentation: Option.contact_sensor_maxmatch information.
PiperOrigin-RevId: 836670031
Change-Id: I29b11784998d3461ad1d460a6c23cad66df22202
2025-11-25 07:58:08 -08:00
Taylor Howell 5d7b2bd7ca MuJoCo Warp documentation: update information about setting both nconmax and naconmax.
PiperOrigin-RevId: 836666389
Change-Id: I766c717d4c6b98f4383fa396fd9cceaac4b5b561
2025-11-25 07:45:06 -08:00
Taylor Howell 893882171e MuJoCo Warp documentation: Does MJWarp work with multiple GPUs?.
PiperOrigin-RevId: 836642204
Change-Id: I559642b2cb902a704257e7e0344f768b690678a1
2025-11-25 06:26:55 -08:00
Haroon Qureshi d8712808b9 Allow users to access mjrContext.
PiperOrigin-RevId: 836641787
Change-Id: I2f2aee30a047336d1adbe33b7996fee3ec845213
2025-11-25 06:25:14 -08:00
Haroon Qureshi f28bcc4346 Allow binding to arbitrary textures.
PiperOrigin-RevId: 836625847
Change-Id: If02ea708f49bdfd9be5be7d9a273340ba2f082f0
2025-11-25 05:26:04 -08:00
Haroon Qureshi 589e013d9b Fonts should have const data.
PiperOrigin-RevId: 836624808
Change-Id: I984c94cc34ef22b875ddda87c59893aa7f38a8a3
2025-11-25 05:22:54 -08:00
Taylor Howell bdaec5758b Generate MuJoCo Warp documentation with modified types.py.
PiperOrigin-RevId: 836617034
Change-Id: Ia925b88679744267b34504b146fa712d4195eda4
2025-11-25 04:54:01 -08:00
Kyle Bayes b98379372e Refactor epaWitness.
PiperOrigin-RevId: 836597852
Change-Id: Ib75dae07bda47764f937f32a9476ef3266f02056
2025-11-25 03:44:57 -08:00
Haroon Qureshi 9b0f8dd963 Update CMakeLists.txt to add/remove files.
PiperOrigin-RevId: 836591285
Change-Id: I17745ad5055b861721c10daec33adc1f6f11ea32
2025-11-25 03:18:57 -08:00
Yuval Tassa 888d3a7b07 Add mj_copyState
PiperOrigin-RevId: 836588419
Change-Id: I7609e121dc0ac697d4d015d4244bdd5962650def
2025-11-25 03:10:30 -08:00
Haroon Qureshi eac8e60037 Merge Physics functionality into App.
The Physics class is no longer needed. This makes Studio similar to
other toolbox-based apps (like web demo and python viewer) which
manage their own mjModel and mjData instances.

PiperOrigin-RevId: 836588076
Change-Id: I3f695b49bf6a7bba1a2b639d3d75d0c996582f06
2025-11-25 03:09:21 -08:00
Haroon Qureshi 67b09f9afb Refactor simulation state history tracking into a SimHistory class.
PiperOrigin-RevId: 836578736
Change-Id: I94a852b2d2a36cdd081371f25385dbb466dd8d4b
2025-11-25 02:38:09 -08:00
Haroon Qureshi 6d9d59cb98 Move pause handling into StepControl.
Also moves perturbation handling up to the App.

Combined, this makes Physics::Update only about advancing the StepControl and resonding to its Status.

PiperOrigin-RevId: 836569506
Change-Id: I148c787f0e1c18baac3e3038ee6ad0e337eb92a8
2025-11-25 02:08:08 -08:00
Google DeepMind 711a388b3d Sort and generate optional struct bindings in WASM.
PiperOrigin-RevId: 836273537
Change-Id: I2af2401969a4780f593df86dc9336adcc285fd1b
2025-11-24 10:18:09 -08:00
Google DeepMind 217317ccba Change WASM generators from classes to functions.
PiperOrigin-RevId: 836257289
Change-Id: I7a3c1d7bb545353a3d278330582e33c0551792cb
2025-11-24 09:36:36 -08:00
Taylor Howell 1c910875d2 MuJoCo Warp documentation: Differentiability.
PiperOrigin-RevId: 836250165
Change-Id: I40c21674c896ed4108f17192f16aaaf2664f03be
2025-11-24 09:13:28 -08:00
Taylor Howell 2ca56179a7 Add Frequently Asked Questions: Learning frameworks to MuJoCo Warp documentation.
PiperOrigin-RevId: 836231961
Change-Id: If3d00e7dfb9ebe49a034ea8936d2ac1dd33d0979
2025-11-24 08:14:53 -08:00
Taylor Howell cb391962ca MuJoCo Warp documentation: Orientation representation.
PiperOrigin-RevId: 836127570
Change-Id: I0f381e57cfb53e1cb623f9c4178d258dfc1f75b6
2025-11-24 02:03:41 -08:00
Kyle Bayes a105042734 Tidy up primitive support functions.
PiperOrigin-RevId: 835329730
Change-Id: I5ad5e85b5e8284bf5e3769ab504686b7859a6ea4
2025-11-21 13:00:49 -08:00
Taylor Howell a359780ca1 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 835230315
Change-Id: Ifa4f8f66c4e3de1a3074f0897daf93f88e469f06
2025-11-21 08:17:49 -08:00
Kyle Bayes bb488fec29 Remove MPR from comment.
PiperOrigin-RevId: 835224192
Change-Id: I659231b30d4c00d9bf586f0efdac138331862df7
2025-11-21 07:58:26 -08:00
Yuval Tassa f8b92410d4 Add test explaining body_rootid and body_weldid semantics
PiperOrigin-RevId: 835197910
Change-Id: If85ca80d3b576e2469cf0d9900441ddb9fd64462
2025-11-21 06:25:22 -08:00
Matija Kecman 7e6cb642a3 Improve formatting of percent real time selection
PiperOrigin-RevId: 835192366
Change-Id: I17057f61b96d6380dea6156dcef867b1845e6abf
2025-11-21 06:05:53 -08:00
Haroon Qureshi a2002eb3d7 Various UX improvements including:
- Add Toolbar and StatusBar.
- Reconfigure sections into Settings and Inspector groupings.
- Use docking for Settings/Inspector panels.
- Rename "Free" camera to "Tumble"; add WASD-based free camera.
- More dynamic layout of table-based elements.
- Remove "non-classic" UX mode.
- Switch to light mode by default.

PiperOrigin-RevId: 835174573
Change-Id: I1855caa79f00002e44ed2516631675727bdcb9f6
2025-11-21 04:58:20 -08:00
Yuval Tassa ae8272787f Rollback of 7cb2e31f4b
PiperOrigin-RevId: 834865905
Change-Id: Iade490754ca30a97f696bcb09525f9b4c37dbeff
2025-11-20 12:30:48 -08:00
Yuval Tassa c2e9bfa3e8 Clarify semantic of body_rootid and body_weldid
PiperOrigin-RevId: 834827589
Change-Id: I562e0aa374ce59d8b769e8d003e4c63ee434a1fc
2025-11-20 10:54:59 -08:00
Yuval Tassa 7cb2e31f4b Annotate GlobalModel for LSAN
PiperOrigin-RevId: 834784936
Change-Id: I9381a062956df6cd7724402b72c2d2a2d8c49998
2025-11-20 09:03:48 -08:00
Matija Kecman ee8dbd4347 Simplify enum WASM bindings generator
PiperOrigin-RevId: 834725472
Change-Id: I278447145cd8dcdd145f0d50bc3bae649ea2b440
2025-11-20 05:52:02 -08:00
Matija Kecman a0d49ade1b More simplification to functions.py in WASM bindings
PiperOrigin-RevId: 834643175
Change-Id: Iff873f6f0916e0039ff6a44468afd9b4d8f98f37
2025-11-20 01:06:29 -08:00
Matija Kecman 102f382c9d Rename uppercase_first_letter to capitalize
Also rename `lowercase_first_letter` to `decapitalize`

PiperOrigin-RevId: 834622292
Change-Id: I1cfbda1be782ff40dd3fc0726601cc6b1f427345
2025-11-19 23:54:02 -08:00
Matija Kecman 48ecddbe3b Simplify functions.py in WASM bindings generation
PiperOrigin-RevId: 834470193
Change-Id: I3c26d65ea8812fd6a4c78264fbce8353bac6fb2f
2025-11-19 15:35:45 -08:00
Alessio Quaglino a0cb97eb4d Improve attach docs.
PiperOrigin-RevId: 834366494
Change-Id: I9086097990f09e848d0b76d9c22f4fd2bbd70718
2025-11-19 11:08:36 -08:00
Yuval Tassa d1317fd1a5 Add ray normal computation for primitives (currently private)
PiperOrigin-RevId: 834294539
Change-Id: I176f13a8f91dede589338fc44e099a16bac0b580
2025-11-19 08:01:02 -08:00
Yuval Tassa 86a77ff8eb Change mjtSize from uint64_t to int64_t.
This change makes `mjtSize` a signed, rather than unsigned 64-bit integer. While sizes are non-negative, the type promotion rules for unsigned integers can lead to unituitive downstream bugs, and 8 billion terabytes are enough bytes.

PiperOrigin-RevId: 834292964
Change-Id: Iea9c47c2a5d80fde63851a543d59ed0549db0f01
2025-11-19 07:55:54 -08:00
Google DeepMind 49394d57d9 Rename WASM binding wrapper functions and reorder generated code.
PiperOrigin-RevId: 834265965
Change-Id: I58e7d572dcae4f1ca262ae5d876fcd8353af183c
2025-11-19 06:26:03 -08:00
Google DeepMind 10fe5ff07f Generate MjVisual, MjModel, MjData and MjSpec structs declaration
PiperOrigin-RevId: 834264723
Change-Id: Id33d7568a1f9f0cfb1271cf9dd2d8713c00eee34
2025-11-19 06:22:28 -08:00
Taylor Howell 07d8bd5b80 MuJoCo Warp documentation: Add note about nconmax and njmax not being parsed from XML.
PiperOrigin-RevId: 834247810
Change-Id: Iadee0f1713c9322cab781aabfe86954c145932ba
2025-11-19 05:23:12 -08:00
Alessio Quaglino 3aa973894c Fast flex: Interpolate contact points directly.
For each contact point, we used to first compute the vertex weights on a triangle and then add a contact point per vertex using the flex interpolation (trilinear or quadratic), obtaining the total weight by multiplying the vertex weight and the basis function value at that vertex. After this change, each contact point is added directly by evaluating the basis function directly a the point.

PiperOrigin-RevId: 834218909
Change-Id: Ic0fdb03fc0ef5478798c293df99204fd33116fd1
2025-11-19 03:40:17 -08:00
Haroon Qureshi a2fd5fdd4a Move profiler logic into a separate class.
PiperOrigin-RevId: 834200782
Change-Id: Ida050a5c055237c4e0a0c725a1277c9239a89538
2025-11-19 02:35:35 -08:00
Yuval Tassa e18e35f967 Fix normal only for libccd during hfield collisions.
PiperOrigin-RevId: 833933161
Change-Id: I3a4ff044276d9c7305154da09b440168f0f22305
2025-11-18 12:55:56 -08:00
Haroon Qureshi 7569ac960d Create material instances for each draw call rather than for each clip rect.
This fixes a bug where the wrong instance was being used in some cases.

PiperOrigin-RevId: 833818151
Change-Id: If8b0cb90017ee0b89cde98a5ae64c36704c7338c
2025-11-18 08:16:55 -08:00
Alessio Quaglino 62872fecd1 Reduce size of mjsTexture.gridlayout (was 13, should be 12)
PiperOrigin-RevId: 833764817
Change-Id: I2655a729d38a8871be2024492ce2a971fc8a0372
2025-11-18 04:49:05 -08:00
Alessio Quaglino 971e73ab04 Remove unused argument from mj_vertBodyWeight.
PiperOrigin-RevId: 833744032
Change-Id: I26049003b1f45f8cac60c7ebc0b5abca5526177f
2025-11-18 03:28:25 -08:00
Haroon Qureshi 8077a6819c Add support for OpenSans and font-awesome fonts.
PiperOrigin-RevId: 833666932
Change-Id: I5f0207c3331705b9078a1297b3e7b2a8d363ad60
2025-11-17 23:14:47 -08:00
Taylor Howell 695e4c4038 MuJoCo Warp documentation: Command line scripts.
PiperOrigin-RevId: 833405216
Change-Id: I8c1850ea59e2640f14c5be7e09c90aea29622831
2025-11-17 10:46:43 -08:00
Taylor Howell bc169d82c1 Fix MJX plane_cylinder docstring.
PiperOrigin-RevId: 833394724
Change-Id: I80df8bf35bceb97a18a0c4c2f37fab71e31011c2
2025-11-17 10:21:09 -08:00
Haroon Qureshi e882399eb0 Use mjTHREADLOCAL macro instead of intrinsic.
Fixes #2927.

PiperOrigin-RevId: 833336768
Change-Id: I62bfdc7018853fc8459e03ba079fc6a15e97c7d0
2025-11-17 07:50:02 -08:00
Matija Kecman 85b6194f91 Add a README with instructions for how to build and run MuJoCo Studio externally
PiperOrigin-RevId: 833336577
Change-Id: Ib5f5ef33abe820796559a9da352360f57ea64bc8
2025-11-17 07:49:00 -08:00
Matija Kecman 12e24d66f6 Add steps to build MuJoCo Studio to Github actions
PiperOrigin-RevId: 833325371
Change-Id: I8c7253f3dfabe3e7b6538b602af220310d5aea89
2025-11-17 07:11:07 -08:00
Matija Kecman 8eca9926dc Fix various MuJoCo Studio build issues on Windows, MacOS and Linux
PiperOrigin-RevId: 833313973
Change-Id: I7ec181374e0bb49c32420d025044c31f6fc3c657
2025-11-17 06:35:43 -08:00
Yuval Tassa a66cf303f8 Clean up ray functions
PiperOrigin-RevId: 833299985
Change-Id: I30aabe889ccc5900ff0e50a578e98e176d3effa4
2025-11-17 05:47:44 -08:00
Matias Manevi 53e254b715 Generate using declarations for anonymous structs in WASM bindings.
PiperOrigin-RevId: 832359379
Change-Id: Ie5913c584c5605f512dbe423524a829043179b6f
2025-11-14 10:03:12 -08:00
Haroon Qureshi 999344c998 Use the path of the loaded model as the base path for all further load/save operations.
PiperOrigin-RevId: 832358035
Change-Id: I44fdf8cd31d755087ebd5ec9f84f5faabe5d0702
2025-11-14 10:00:43 -08:00
Matias Manevi a36f452250 Refactor MuJoCo WASM bindings functions code generation and auto-generate functions requiring argument boundchecks.
PiperOrigin-RevId: 832333773
Change-Id: Id2e1a59e8d366baa2ee044d693f76aadcd1dfd32
2025-11-14 08:51:18 -08:00
Haroon Qureshi 3f69deb328 Correctly initialize mjrContext before creation.
PiperOrigin-RevId: 832233427
Change-Id: I5e7301637e73a739f141d4a3207b27ae1676f6b6
2025-11-14 02:41:56 -08:00
Haroon Qureshi 83363f41ee Fix arrow positioning.
PiperOrigin-RevId: 832233204
Change-Id: I10b780c261bf5c0b4891309559fa7aab4d47d32c
2025-11-14 02:40:31 -08:00
Haroon Qureshi 6c15c711ee Make mjv_cameraFrame and mjv_cameraFrustum public.
PiperOrigin-RevId: 832187804
Change-Id: I74d05d7fe03bc81bd05a823c7c9791bca12e3079
2025-11-14 00:03:18 -08:00
Kristian Hartikainen e17e58c6b5 Fix instsance -> instance 2025-11-13 20:11:10 +00:00
Matija Kecman 86ac3a5e28 Update the WASM bindings README
* Removed the caution callout since some internal CI has been implemented.
* Added to clarify the state of bindings build process on Windows.
* Fixed the formatting of a note callout in the Testing section.

PiperOrigin-RevId: 831899135
Change-Id: I9f105b91e924368c8e84da7114e1b1d3e48c185a
2025-11-13 09:47:31 -08:00
Matija Kecman b0e75b7103 Refactor Github actions so that all build steps are implemented as functions in a separate build_steps.sh file.
This reduces the amount to yaml we need to know/write and makes the steps reusable in a clearer way than yaml anchors. Also Made sure that bash commands are executed with -xe set to log the command before executing and to fail the script on the first failing command.

PiperOrigin-RevId: 831823786
Change-Id: I7410c13decb914ef079ac4dd19a49481c452f3ec
2025-11-13 05:56:53 -08:00
Kyle Bayes 8b9fa2674c Use std::vector instead of array in MJCF schema.
PiperOrigin-RevId: 831787681
Change-Id: I8093b8b10260daecb830e49319eda798e2dd2da5
2025-11-13 03:41:54 -08:00
Matija Kecman 26c1622ac8 Internal change
PiperOrigin-RevId: 831782555
Change-Id: I1dda7700e1c1def21c0b0879a5452ddf96d45aa8
2025-11-13 03:22:47 -08:00
Yuval Tassa 042c5223a6 Change mj_sizeModel return type to mjtSize.
PiperOrigin-RevId: 831768095
Change-Id: I079fbadc403b32a3ce8a73fe21b2cd66391401c3
2025-11-13 02:32:18 -08:00
Kyle Bayes a168b3ef7f Refactor hill climbing support function.
PiperOrigin-RevId: 831754211
Change-Id: I77c89c52fde86183b8e2e61a1fc71764119f208e
2025-11-13 01:47:27 -08:00
Silvia Cruciani 727347813f Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 831416862
Change-Id: I9ffe9698a3cd4a173189a804998ce8afc16b91f2
2025-11-12 09:18:32 -08:00
Matija Kecman 4722925ff4 Add a github actions job which quickly determines if the WASM build is broken by only testing on one platform
PiperOrigin-RevId: 831395855
Change-Id: I1128ae39b50e0d9d4338b8ea768b2850699aef22
2025-11-12 08:17:22 -08:00
Yuval Tassa b8512b9d1f Fix bug related to sleeping static children of mocap bodies.
PiperOrigin-RevId: 831376685
Change-Id: I8891a1d7dc6efc037e9ade5c7e8dd5c35c7e455e
2025-11-12 07:20:03 -08:00
Haroon Qureshi 7b52d3034e Fix crash if Renderer is destroyed without having been Init'ed.
PiperOrigin-RevId: 831375559
Change-Id: Ia1d0334e32dbbd0582d4f75723867d6ea47bf9da
2025-11-12 07:15:39 -08:00
Haroon Qureshi 28c536bd93 Remove support for custom fonts for OSS project for now.
PiperOrigin-RevId: 831294808
Change-Id: I3f366ceafc1181e0624d1b26ef09fd64ed6275b4
2025-11-12 02:30:23 -08:00
Tom Power 52478e15c3 Fix issue where contact pairs supported by C back-end are unsupported by MJX:C
PiperOrigin-RevId: 831288268
Change-Id: Ied69be2d69a4cf0c8190bfaf8b6428e1dd8c8a70
2025-11-12 02:09:21 -08:00
Yuval Tassa 414d6d80ac Update model memory footprint reporting in mj_printModel.
PiperOrigin-RevId: 831015711
Change-Id: I7cb5aba019ed99e239b6fadbaf162cbd6fd9d9fb
2025-11-11 12:08:22 -08:00
Yuval Tassa bc83bfb076 Restructure AAMM storage for improved cache locality in broadphase, ~35% speedup (of broadphase).
PiperOrigin-RevId: 831007564
Change-Id: I1a72ca02f5a50194bb7770d5765c6140adde1852
2025-11-11 11:46:08 -08:00
Matias Manevi fa79276290 Remove destructors from Mjs wrapper structs.
PiperOrigin-RevId: 831001833
Change-Id: I54550737a4c1cb504bf62b9bfed12d7a70434233
2025-11-11 11:31:21 -08:00
Google DeepMind 6d261528e0 Enhance error reporting in WASM codegen generators.
In `structs.py`, a `RuntimeError` is now raised when an anonymous struct is encountered but is not present in `STRUCTS_TO_BIND`.

PiperOrigin-RevId: 830978376
Change-Id: Id64720a12c3cce313bd513a40a74ddf57718a7d1
2025-11-11 10:38:39 -08:00
Google DeepMind 8e4a5901c3 Rename internal lists of skipped functions in constants.py.
PiperOrigin-RevId: 830976939
Change-Id: I833ef4c98107e19822f5e96c7541d294e129ac6c
2025-11-11 10:35:22 -08:00
Matias Manevi 54661ab140 Fully generate Emscripten bindings for MuJoCo functions.
PiperOrigin-RevId: 830975595
Change-Id: Ie4d0d16c80f490abaa5ae8218628ac1b3d32c0ef
2025-11-11 10:32:04 -08:00
Google DeepMind ff037f2e78 Make Emscripten binding module names consistent
PiperOrigin-RevId: 830902834
Change-Id: I64e004559cbfdb14fb84bc548f05b1ab49e94d4d
2025-11-11 07:20:45 -08:00
Google DeepMind 5b859327cc Remove unused manually added structs from WASM bindings.
PiperOrigin-RevId: 830901766
Change-Id: If0104a59f7e06a96733feb31f1ce9a93ba3fde42
2025-11-11 07:17:37 -08:00
Haroon Qureshi aa7cf15cc4 Set textures before assigning a material.
PiperOrigin-RevId: 830899288
Change-Id: I42029157e7be006d4dc18d0c84e27bf908af6f47
2025-11-11 07:10:18 -08:00
Yuval Tassa 22c0b68903 Improve logic and documentation for sleeping sensors
PiperOrigin-RevId: 830891115
Change-Id: Ife8309b165c085b54c9f668d825d69ed12a9a8f0
2025-11-11 06:45:56 -08:00
Matias Manevi 3e167e0f0b Correctly format constructor initializer lists in struct wrappers.
PiperOrigin-RevId: 830887996
Change-Id: Ibe663fcc17571ad1fd62d70249687c917653618e
2025-11-11 06:38:19 -08:00
Matias Manevi 75774b2a35 Simplify struct header generation by merging the internal _build_struct_header_internal function into build_struct_header
PiperOrigin-RevId: 830878041
Change-Id: I6867984ac6ec091daaf2172fbde0e6ac6f38d1f3
2025-11-11 06:03:13 -08:00
Haroon Qureshi 1b2206fc50 Do not generate mipmaps for textures loaded from KTX files.
PiperOrigin-RevId: 830874812
Change-Id: Ie9dccc52acd5ffd26e5d4f3597f3834f81ebebcb
2025-11-11 05:51:36 -08:00
Haroon Qureshi 2261733aa4 Toggle profiler window using F3.
PiperOrigin-RevId: 830869956
Change-Id: I396f89f95672096f59b909b9415be2168aac6473
2025-11-11 05:33:57 -08:00
Haroon Qureshi 1fbea85ef0 Remove redundant call to GenerateMipMaps.
The Create?Textures will generate the mipmaps themselves if needed.

PiperOrigin-RevId: 830868294
Change-Id: I295e0dac12bc7c31a98242256721f46467f883d6
2025-11-11 05:27:58 -08:00
Haroon Qureshi 4a5a36f3fc Display error when loading model.
PiperOrigin-RevId: 830862449
Change-Id: Iab1e8786d79d55db9a15a788ecb37e0b0418111c
2025-11-11 05:04:48 -08:00
Haroon Qureshi b3deb9dd12 Do not reset camera_id if no tracking object is set.
Otherwise, we can never incrementally move beyond a free camera.

PiperOrigin-RevId: 830845627
Change-Id: I07e8639f79efcdae451999ca07b91a41360752ca
2025-11-11 04:03:35 -08:00
Matija Kecman 88e75cd7e6 Remove implot from toolbox/window.cc
PiperOrigin-RevId: 830842619
Change-Id: I39d13508423ad0ba1e12349ceaccab2425d28243
2025-11-11 03:51:38 -08:00
Yuval Tassa 23023edc52 Fix bug in schema
PiperOrigin-RevId: 830819693
Change-Id: I9fd047975895f4a376d28b7eee2c0d38344ce864
2025-11-11 02:28:52 -08:00
Kyle Bayes 39f0321a68 Clean up NativeCCD testing models.
PiperOrigin-RevId: 830733959
Change-Id: Ie7f71c36d2efafd37aecef54ca4897cebd6d091f
2025-11-10 21:31:02 -08:00
Taylor Howell bfcceb583e Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 830506734
Change-Id: I857bf59a34a46bd61fc24953fd6f10b2157febb7
2025-11-10 10:35:00 -08:00
Yuval Tassa f8cef22992 Change mjWarp admonition class from attention to warning
PiperOrigin-RevId: 830452799
Change-Id: I26d7163b4c738a6accd70784863cc2dbdc410927
2025-11-10 08:23:05 -08:00
Taylor Howell e464e173da Update conf.py: "warp only fields" custom section.
PiperOrigin-RevId: 830452471
Change-Id: Ib90afedacf760b3d0584e7d0dd81cdd9e3e35dc9
2025-11-10 08:21:45 -08:00
Yuval Tassa 1c6a05de98 Snap Y-axis range to nice decimal bounds in gl2 figures.
PiperOrigin-RevId: 830355030
Change-Id: I2e9f145fb8c626dd671d286560c8334202586c6b
2025-11-10 03:01:30 -08:00
Matija Kecman 4e46db8903 Refactor WASM binding directory structure
* All tests moved into wasm/codegen/tests folder
* Merged wasm/codegen/helpers/ into wasm/codegen/generators/

PiperOrigin-RevId: 829471173
Change-Id: I2dbc5d9351771817ec260c7ddf87c31e66a9eabe
2025-11-07 09:37:26 -08:00
Matija Kecman 44220fcc51 Refactor WASM bindings in preparation for codegen directory structure update
PiperOrigin-RevId: 829459535
Change-Id: I4045e163a6e7fcee9d9585131d1e5e30f0b50b89
2025-11-07 09:02:43 -08:00
Google DeepMind 59debb50b1 Add SLEEP to EnableBit enum.
This change exposes the `mjENBL_SLEEP` flag from MuJoCo's `mjtEnableBit` in MJX's `EnableBit` type.

PiperOrigin-RevId: 829446801
Change-Id: Ia95b31a3488ecba0431646c889e10a5ae5fb60e8
2025-11-07 08:22:45 -08:00
Matija Kecman 2cd99e2ec6 Update the enums_test.ts using the generation script
PiperOrigin-RevId: 829445412
Change-Id: I8da1f019a4f4ad2278399a2c82d3096ef234240c
2025-11-07 08:18:10 -08:00
Taylor Howell 883836848a Fix box-box distance computation.
PiperOrigin-RevId: 829431553
Change-Id: I9e28bc8eb7687c3c83e5ff68c65e93d8a07378a9
2025-11-07 07:37:03 -08:00
Matija Kecman 45b079cfe8 Various minor cleanups in WASM bindings generation code
PiperOrigin-RevId: 829430835
Change-Id: Iadb0e4f8a197da69e093eccfd75d07cf6db5faaf
2025-11-07 07:34:41 -08:00
Matija Kecman 80a91cfbea Internal change
PiperOrigin-RevId: 829417225
Change-Id: Ib2304c6a40fb7a2a9fed900a587b9f7ed4b3103a
2025-11-07 06:49:00 -08:00
Matias Manevi 6fb4394701 Refactor array initialization for mjData and mjvScene in MuJoCo WASM bindings.
PiperOrigin-RevId: 829406147
Change-Id: Ib93c49e938086fb277e4959ade1f25e6ced5c70d
2025-11-07 06:12:14 -08:00
Yuval Tassa 8734cab366 Add sleeping documentation
https://youtu.be/vct493lGQ8Q

PiperOrigin-RevId: 829390353
Change-Id: I92f85a03be0bb585d2d8e29de1ed1a2e848f247f
2025-11-07 05:12:42 -08:00
Yuval Tassa 769f37b653 Implement sleeping in engine
PiperOrigin-RevId: 829361787
Change-Id: I6f64d8e25c4248cf32c18cd94d37ff5def78946e
2025-11-07 03:33:07 -08:00
Sergei Lebedev 1e0226d360 Ignore pytype errors produced with --use-functools-partial-overlay
PiperOrigin-RevId: 829338416
Change-Id: I1867bd18a7c57e2faf0f121d89dfc4129c5f31b8
2025-11-07 02:08:04 -08:00
Yuval Tassa 252a0d73df Add sleep related data structures
PiperOrigin-RevId: 829055431
Change-Id: I1ccbd77a57044a754ae7db611b4c2c0010fbda53
2025-11-06 12:10:55 -08:00
Baruch Tabanpour 3080e3424f Update mjx-warp ffi, prepare for render.
PiperOrigin-RevId: 829027266
Change-Id: Ifca30885fb6302e8ce61f949fdc0f56674bbe9e4
2025-11-06 11:04:44 -08:00
Baruch Tabanpour fa062768f4 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 829017789
Change-Id: I2756e349297cd0ae53a63a38fb203e2fd2d5cb99
2025-11-06 10:42:32 -08:00
Matija Kecman 7dfd92098f Simplified struct field handling in the WASM bindings
PiperOrigin-RevId: 829003969
Change-Id: I139f9c0dad96e1664b1bd054f09fcdf58aff260e
2025-11-06 10:10:18 -08:00
Matias Manevi 06ecdd6ba1 Refactor: Generate all struct bindings within the codegen.
PiperOrigin-RevId: 828973537
Change-Id: I3f371d2f88e1cd9b1bb5c0a9c6a5ace7a21673fb
2025-11-06 08:49:48 -08:00
Haroon Qureshi 2c2773e36d Include third_party_deps cmake files.
PiperOrigin-RevId: 828957097
Change-Id: I2aeea2ae9e2621c8c62a34095af6ea8fd0797f08
2025-11-06 08:02:28 -08:00
Google DeepMind b807d5f852 Remove MjVFS from generated Emscripten bindings.
PiperOrigin-RevId: 828943991
Change-Id: I681079854c71059392518c328a4488bb47127433
2025-11-06 07:20:11 -08:00
Sam Haves 8051f40817 During mj_parse, if mju_openResource fails pass a resource with only the filename to decoders.
This enables decoders to leverage their own file resolution systems. For example: USD can compose a stage (scene) from memory, via a file on disk, or via custom asset resolver.

Passing it through to the decoder reduces the need for custom resource providers that wrap these other resolution systems.

This will also enable a fun, but likely niche usecase where the decoder does procedural generation and does not have to be backed by a resource. See the tests for an example of this.

PiperOrigin-RevId: 828939899
Change-Id: Ic319a685332d91198a4ae926867c834bf7f7f724
2025-11-06 07:06:06 -08:00
Taylor Howell 89fec8f7b2 MuJoCo Warp documentation: Performance Tuning.
PiperOrigin-RevId: 828908430
Change-Id: Iece454fce7dea71df2a5b6f60d81b611c5a3730d
2025-11-06 05:20:19 -08:00
Baruch Tabanpour d0f32a7fe6 Modify mjx.Model tex_data type.
PiperOrigin-RevId: 828606695
Change-Id: I708dcf8e75766bf16d339999a9e8c70c8f65fd0c
2025-11-05 13:33:11 -08:00
Baruch Tabanpour c34ac712a0 Import warp-lang 1.10.0.
PiperOrigin-RevId: 828583884
Change-Id: Ia1c6d8c41fa0785360b85287cab562228fcc80cf
2025-11-05 12:35:25 -08:00
Google DeepMind 3577c98f82 Refactor Emscripten bindings generation for MuJoCo structs.
PiperOrigin-RevId: 828550215
Change-Id: Iab0bf3a9fbaca4d7774f89a4d8977e762aa57629
2025-11-05 11:14:29 -08:00
Google DeepMind 8104235f8e Generate wrappers for anonymous structs within mjVisual.
PiperOrigin-RevId: 828548681
Change-Id: I07f8b407157b91ac24b38604b20826541e20e23e
2025-11-05 11:10:52 -08:00
Google DeepMind c3858f267a Change default values of WrappedFieldData string fields to empty strings.
PiperOrigin-RevId: 828547058
Change-Id: I0dc0f993cd93a8feab3f1a53b7ee6c47266093e0
2025-11-05 11:07:29 -08:00
Google DeepMind ff0ae09bc4 Remove debug printing functionality from WASM codegen.
PiperOrigin-RevId: 828545426
Change-Id: I136e6290c7ffdd4c2029aaf72cb90e0fc3cc7a9f
2025-11-05 11:03:28 -08:00
Haroon Qureshi 01b0ea5b7d Use webgl backend in emscripten builds.
(Also only display the model name if its a file.)

PiperOrigin-RevId: 828498906
Change-Id: I7def85992f413b321c115ea63db2af057f5fd372
2025-11-05 09:17:34 -08:00
Haroon Qureshi 8b7eb097db Remove Sync and Scene functions from Renderer.
PiperOrigin-RevId: 828481721
Change-Id: Id0399139653b0ec27f0d365437e62cadefadfe6c
2025-11-05 08:33:28 -08:00
Taylor Howell 17d36d8e75 MuJoCo Warp documentation: `naconmax`.
PiperOrigin-RevId: 828478607
Change-Id: I90e8b95cf5b869ba60a731b3d2ee962c411da943
2025-11-05 08:24:25 -08:00
Haroon Qureshi 30a99de3b9 Remove dependencies on mjvScene for interactions.
Interactions (like moving the camera or mouse picking) no longer depend
on needing an mjvScene. Instead, everything is done relative to the
camera directly.

This duplicates some code in engine_vis_visualize which we will try to
resolve and recombine at a future time.

PiperOrigin-RevId: 828461259
Change-Id: If26329c1a7c37516f0213b18056c3e31760f60ae
2025-11-05 07:33:42 -08:00
Yuval Tassa 2245210e87 Fix formatting error in the 3.3.6 changelog
PiperOrigin-RevId: 828455246
Change-Id: I6cd08f7819bde27c32ddd1ff56cbd9b23b92134d
2025-11-05 07:17:47 -08:00
Yuval Tassa d5e953e707 Use sphinx.ext.extlinks for GitHub issue and PR links.
Added `sphinx.ext.extlinks` to the Sphinx configuration and defined `extlinks` for `:issue:` and `:pr:` roles, pointing to the MuJoCo GitHub repository. Updated `changelog.rst` to use these new roles, replacing `:github:issue:` and `:github:pull:` which are currently failing.

Also fix a formatting bug in the 3.3.7 changelog

PiperOrigin-RevId: 828403002
Change-Id: I7f0134e4dd555fc59a3fee090338de56aababe1c
2025-11-05 04:12:08 -08:00
Google DeepMind fe1b6b7c80 Refactor: Group autogenerated structs source in bindings.cc
This change modifies the code generation for structs in `bindings.cc`. Instead of placing each struct's constructor and member functions under individual markers, all autogenerated struct source code is now grouped together under a single `// {{ AUTOGENNED_STRUCTS_SOURCE }}` marker. This improves the organization of the generated file and simplifies the template.

Future work would move the rest of the structs into this pattern

PiperOrigin-RevId: 828390272
Change-Id: Iee9d0e8766db86b2c1d4296a37ac7a8e6e05428b
2025-11-05 03:26:09 -08:00
Google DeepMind 5b00b033af Refactor struct dependency sorting to use wrapped field data.
The `sort_structs_by_dependency` function now takes a dictionary of `WrappedStructData` and uses the pre-computed `typename` within `WrappedFieldData` for dependency analysis, instead of re-introspecting the AST. This change also includes populating the `typename` in various `WrappedFieldData` generation methods.

PiperOrigin-RevId: 828389481
Change-Id: Ie97c1a66e5e69bd148a928fda26afdaa09f56687
2025-11-05 03:23:35 -08:00
Matija Kecman 29c1a3a0a5 Cleanup WASM bindings generators so they all have a similar interface
PiperOrigin-RevId: 827965451
Change-Id: I657fc4d3a480fbc62124c84fe9ddc0900a91183f
2025-11-04 07:32:32 -08:00
Matija Kecman 776fc32eb4 Cleanup WASM bindings struct generation
PiperOrigin-RevId: 827949686
Change-Id: I4115e397f64963244e3c30a7eaff5be7534aadf2
2025-11-04 06:44:02 -08:00
Matija Kecman 4b79a58fa0 Add convenience methods to CodeBuilder and cleanup some WASM bindings code generation
PiperOrigin-RevId: 827916844
Change-Id: Ie382f2a5af3d7e3ec2c81cde5d6b768835da2365
2025-11-04 05:02:59 -08:00
Adrian Collister 740afe22b3 Append warnings to model compile errors.
PiperOrigin-RevId: 827903480
Change-Id: I2ad17bf4cea0dae0ab803fbb7baa9bd70eef303d
2025-11-04 04:15:07 -08:00
Matija Kecman 34e5eecba5 Autogenerate more of mjVFS and mjvGeom WASM bindings
PiperOrigin-RevId: 827898643
Change-Id: I95f9eaa129f663cbeb3606d286c2080c47cfbcc4
2025-11-04 04:00:13 -08:00
Matija Kecman f808632cf8 Rename WASM bindings function helper file
PiperOrigin-RevId: 827897836
Change-Id: Ifb13ebaf54dacabc2a3ed8a8ea4244ecea2a8f41
2025-11-04 03:57:03 -08:00
Matija Kecman 12a31674a3 Consolidate WASM bindings struct generator helper files into helpers/structs.py
PiperOrigin-RevId: 827889180
Change-Id: I5f8bf0e25d1af7b21b554672bd438bbcd04e62be
2025-11-04 03:23:24 -08:00
Matija Kecman 9b71fc728d Consolidate WASM bindings test files
PiperOrigin-RevId: 827888382
Change-Id: I4ded54cd49182de0b4243770e2507038ad6fac7a
2025-11-04 03:19:35 -08:00
Matija Kecman 2018b8c494 Disable WASM bindings benchmarks on Github CI
Updated the wasm/README.md to describe how to manually run the benchmark tests.

PiperOrigin-RevId: 827881670
Change-Id: I1d524851d9f3f8182ecbfcc649bb9a5a61d716ae
2025-11-04 03:00:29 -08:00
Matija Kecman 3d59b20b65 Simplified struct code generation for WASM bindings
PiperOrigin-RevId: 827878780
Change-Id: I97ab732eb11c63a6aaf7fa95add0b51bc0a56525
2025-11-04 02:51:11 -08:00
Matija Kecman c22d94e470 Various minor cleanups to WASM code generation
* Add newline function to code_builder
* Remove type aliases which made jump to definition less ergonomic
* Add types to constants

PiperOrigin-RevId: 827863199
Change-Id: Ib4390d398926466ecce491a3d0ebe308ed5e0cbe
2025-11-04 02:07:27 -08:00
Matija Kecman 10130297c0 Consolidate WASM bindings into a single C++ file.
PiperOrigin-RevId: 827850819
Change-Id: I23e099d4e72557d79354339953246ac4eeee7ca3
2025-11-04 01:37:32 -08:00
Sam Haves 7d7648f7ed Update UsdWriter to write any parts of MjSpec that are not from USD to the EditTarget.
This enables two workflows:
1) Users that parsed some other format into MjSpec, or built it programmatically can export animated USD easily with as minimal as possible interaction with USD.

2) Creating a spec from USD, then modifying the spec, should not cause a duplication of data when writing to USD.

PiperOrigin-RevId: 827627520
Change-Id: I02c8c14a18569547710e54f3704d52ac0bf70ce6
2025-11-03 13:29:46 -08:00
Yuval Tassa abc02b736e Minor fixes to viewer diagnostics
- When `mjData.nefc` was 0 (solver not run at all), we were plotting the stale diagnostics from the last run; now fixed.
- In the case where islands were used, the semantic of the plotted diagnostic `sqrt_nnz` (square root of Hessian nonzeros) is changed. It used to be the sum of square roots of solver nonzeros per island, it is now the square root of the sum of all nonzeros in all islands. The semantic `sqrt(sum(nnz_i))` was found to be more consistent than `sum(sqrt(nnz_i))`, in the sense that switching islanding on/off leads to smaller changes and is more in line with the interpretation of islanding as [block-diagonalization](https://mujoco.readthedocs.io/en/3.3.7/computation/#constraint-islands).

PiperOrigin-RevId: 827624908
Change-Id: I5fc86364ead585a4752a6d44823fb75cf6c7c318
2025-11-03 13:23:05 -08:00
Baruch Tabanpour 501e561563 Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 827602811
Change-Id: I42f96098df4665de60065409b454688f92e976d1
2025-11-03 12:24:28 -08:00
Sam Haves 9319956a16 Modify mujoco_to_usd to operate on SdfLayer intead of SdfAbstractData.
Since we don't do any on demand data loading for USD and always convert everything it should be safe to use the SdfLayer API instead of the SdfAbstractData API. This enables other codepaths such as the USD writer class to reuse the same logic to generate USD specification from an mjSpec.

PiperOrigin-RevId: 827431722
Change-Id: I60a581e0c9577164a4a66229ea9dcb8912afcf74
2025-11-03 04:16:37 -08:00
Alessio Quaglino 3a7aa84e53 Add quadratic stiffness to flex.
PiperOrigin-RevId: 827409919
Change-Id: I3dff8ea49fb1726fec4acf5b91138d6d52c4bfba
2025-11-03 03:01:38 -08:00
Taylor Howell d4f13b4abc Update mjwarp/index.rst.
PiperOrigin-RevId: 827397313
Change-Id: I427a0476eb1530b53539d787c0b79aaf45f889d5
2025-11-03 02:18:56 -08:00
Yuval Tassa ad49733db2 Improve error message for insufficient arena memory in _realloc_con_efc.
PiperOrigin-RevId: 826845370
Change-Id: I09467dd44a6f9f01b89ff6c1d74cde493e84eb1c
2025-11-01 05:54:56 -07:00
Taylor Howell f604588a36 Update theme_overrides_mjwarp.css to not render return type information.
PiperOrigin-RevId: 826821680
Change-Id: I2d8a08755631b85f910051ea395ae9081d4e3759
2025-11-01 03:59:42 -07:00
Erik Frey fbb95d5e8c Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 826571491
Change-Id: I294abc5aa3714345ab295636d12428293ea69285
2025-10-31 11:47:29 -07:00
Matias Manevi 4086261714 Add JavaScript bindings and WASM support
Co-authored-by: Matija Kecman <matijak@google.com>
Co-authored-by: Sebastian Noreña Rendón <sebas.norena@creativa77.com.ar>
Co-authored-by: Kyle Bayes <kylebayes@google.com>
PiperOrigin-RevId: 826479070
Change-Id: I25acf36e6c20b091d8492e10798d028ae66f6733
2025-10-31 07:21:18 -07:00
Sam Haves 57f7145806 Create mjpDecoder, mj_parse, and mju_decodeResource
- plugin system similar to mjpResourceProvider, but instead of loading a resource it converts an existing mjResource into an mjSpec.
  - The returned spec is then composed into the referencing spec.
  - This enables different file types to generate arbitrary specs, and allows us to separate format parsing from compilation code.

Follow up CLs will move some of the logic in src/engine for PNG, USD, KTX, OBJ loading into decoders.

The mj_parse function MjSpec from a given file, it's a more generic version of mj_parseXML.

In it's implementation, mj_parse as opposed to mj_parseXML will look for any registered decoder and
not assume we are striclty dealing with MJCF.

PiperOrigin-RevId: 826149497
Change-Id: I0ece26904280cb94bd5ded6dd5a565c539d60254
2025-10-30 12:54:40 -07:00
Matija Kecman f2badc05ac Add JavaScript bindings and WASM support
Co-authored-by: Matija Kecman <matijak@google.com>
Co-authored-by: Sebastian Noreña Rendón <sebas.norena@creativa77.com.ar>
Co-authored-by: Kyle Bayes <kylebayes@google.com>
PiperOrigin-RevId: 826109484
Change-Id: I327fd54122762bd2e239cc31c602a3eb73051c26
2025-10-30 11:11:52 -07:00
Matias Manevi 76e64d96bb Add JavaScript bindings and WASM support
Co-authored-by: Matija Kecman <matijak@google.com>
Co-authored-by: Sebastian Noreña Rendón <sebas.norena@creativa77.com.ar>
Co-authored-by: Kyle Bayes <kylebayes@google.com>
PiperOrigin-RevId: 826094938
Change-Id: Id2658a187bc078056f4410c71202696753319e64
2025-10-30 10:38:16 -07:00
Taylor Howell 10f4b36fb7 MuJoCo Warp documentation: Beta software.
PiperOrigin-RevId: 825958166
Change-Id: I1e90d78d7413956cfa84711336be26a23a18e5aa
2025-10-30 03:37:22 -07:00
Alessio Quaglino 37563a050e Remove obsolete docs references to convexhull.
Fixes #2912.

PiperOrigin-RevId: 825679563
Change-Id: I8ee14415fb1eb64ece5cf4f3c07d016126025364
2025-10-29 13:17:48 -07:00
Taylor Howell 3df784fc84 Updates for MuJoCo Warp documentation.
PiperOrigin-RevId: 825489001
Change-Id: I6ec4a0433f96da05befeb2b76793763e50a893d8
2025-10-29 04:42:46 -07:00
Google DeepMind d769440924 Store asset keys relative to the MJCF. This CL fixes cases when loading a spec with "from_zip" that fails on zipped folders that contain a root directory.
PiperOrigin-RevId: 825484553
Change-Id: I79c6f542edbd3ffd167d0b5cecc704c32c8d6824
2025-10-29 04:24:09 -07:00
Alessio Quaglino 010d919244 Add __setattr__ to _MjBindModel and _MjBindData.
This allows setting attributes with bind using a list of mjSpec objects as arguments.

PiperOrigin-RevId: 825456920
Change-Id: Ie6af956feab0a805175d7aaecf26e071401fbf05
2025-10-29 02:55:08 -07:00
Haroon Qureshi 80eb511620 Remove dependency on Window, Physics, and Renderer classes.
PiperOrigin-RevId: 825137441
Change-Id: I099a518ca9618698401d0330a6ef08278168f88e
2025-10-28 11:42:17 -07:00
Haroon Qureshi 4620b9f23a Merge HandleMouseEvents and HandleKeyboardEvents back into app.cc.
PiperOrigin-RevId: 825081195
Change-Id: I36445b8c452b15ca26056a52fd1844cf77083c0a
2025-10-28 09:44:42 -07:00
Baruch Tabanpour d001bd6525 Add naconmax, deprecation warning for nconmax.
PiperOrigin-RevId: 825018530
Change-Id: I344b296ac4353592d65a85b826850eaa7df5d39a
2025-10-28 06:59:01 -07:00
Alessio Quaglino 2bdea1a0aa Use "/" as default prefix during attach if not specified.
The user can recover the old behavior by passing prefix="".

This enables to attach children with default and save a valid result to XML.

PiperOrigin-RevId: 825011185
Change-Id: Id20c2589da928bf92b77bdb01cfba73dfc1d2f52
2025-10-28 06:40:34 -07:00
Alessio Quaglino 1bfa8b6fa6 Do not add bodies at mesh points for quadratic flex interpolation.
PiperOrigin-RevId: 825001743
Change-Id: Ica085b947fb1c3f56251bceaa6a228f364535d3e
2025-10-28 06:13:27 -07:00
Haroon Qureshi 3b79d3f14b Set flags directly on Renderer class.
This removes a dependency on mjvScene from the App class.

PiperOrigin-RevId: 824983816
Change-Id: I20dd411e6359ee411f9b0b86d4442c090ba4bd5c
2025-10-28 05:24:05 -07:00
Haroon Qureshi 7ba0d96d77 Use mjvCamera directly for generating camera string.
PiperOrigin-RevId: 824982264
Change-Id: I0d8760bb27153849c8f4dacb10aa3162f29c2f6e
2025-10-28 05:18:58 -07:00
Yuval Tassa e1a73f9c4c Add early exit in mj_xfrcAccumulate using mju_isZeroByte
`xfrc_applied` mostly contains user perturbations which are rare. It is very often identically zero and for large arrays `mju_isZeroByte` is significantly faster than `mju_isZero`.

PiperOrigin-RevId: 824975356
Change-Id: Iadb1d300d68cf12de00c14a0665bd89924a2d7e0
2025-10-28 04:59:14 -07:00
Taylor Howell 017788b9d6 MuJoCo Warp documentation: Parallel Linesearch.
PiperOrigin-RevId: 824937806
Change-Id: I95b416f7b0380099aa6ea4200a27acfc2b2c6bb7
2025-10-28 03:01:07 -07:00
Haroon Qureshi a16805f8ee Add CMakeLists.txt files for new (experimental) code.
This includes the filament, toolbox, and studio projects.

Adds a MUJOCO_BUILD_STUDIO option to enable building of the `studio` app (disabled by default).

Adds a MUJOCO_USE_FILAMENT to allow the studio app to use the filament rendering backend. A separate MUJOCO_USE_FILAMENT_VULKAN flag can be used to enable vulkan rendering.

PiperOrigin-RevId: 824602367
Change-Id: I26d46c16211ae2118f96c163c4194fea5b5a15a9
2025-10-27 11:26:14 -07:00
Taylor Howell be055840b4 Add Batched Model Fields section to MuJoCo Warp documentation.
PiperOrigin-RevId: 824596731
Change-Id: Ic2fc96df6f8d9639286f08ec86c5cdca64fc03d8
2025-10-27 11:12:43 -07:00
Taylor Howell 3b11e31572 MuJoCo Warp documentation: Add nworld, nconmax, and njmax section and update introduction.
PiperOrigin-RevId: 824579564
Change-Id: I2f2b81d95e061168646fce12f7c6f7a1268385e9
2025-10-27 10:33:45 -07:00
Haroon Qureshi dbaf35d42c Add CMake configurations for new third_party dependencies.
Adds targets for dear_imgui, implot, filament, sdl2, and webp. These
targets are not currently used.

PiperOrigin-RevId: 824554405
Change-Id: Ibebdd50752d251852a945b6abc230e2c6e65fae9
2025-10-27 09:36:52 -07:00
Copybara-Service d971e5c2df Merge pull request #2908 from davidhozic:doc/fix-comments
PiperOrigin-RevId: 824546229
Change-Id: I9961e7f39d0549ff8b15a1007fb20832a0014bbd
2025-10-27 09:16:01 -07:00
Copybara-Service 23c3001a4c Merge pull request #2875 from google-deepmind:dependabot/pip/mjx/pip-25.2
PiperOrigin-RevId: 824514263
Change-Id: Ifeb956547e23722ea486e1e6da9a953826038626
2025-10-27 07:42:09 -07:00
Taylor Howell 85e9cff0c1 Update mj_geomDistance: don't flip geoms for nativeccd.
PiperOrigin-RevId: 824463375
Change-Id: Ic9c4cac916129b88575e0366e1b95353ce716ca2
2025-10-27 04:48:36 -07:00
Baruch Tabanpour 8c5154c9a3 Fix testspeed for mjx-warp.
PiperOrigin-RevId: 823691704
Change-Id: If90f6137915de134fdda3c7616bc810555c25d87
2025-10-24 15:47:14 -07:00
Saran Tunyasuvunakool 49a3caf84c Modify SimulationState proto to correspond to mj_getState.
PiperOrigin-RevId: 823494487
Change-Id: Ib284e3165ca691f5b690a376f7b28e51122e1bc4
2025-10-24 05:51:07 -07:00
Alessio Quaglino ec8ad21cb5 Normalize triangle coordinates such that their sum rather their norm is one.
This ensures that at e.g. the barycenter of the triangle each vertex has weight 1/3, as one would expect with barycentric coordinates, rather than 1/sqrt(3). This makes it consistent to the finite element interpolation used in the passive elastic forces.

PiperOrigin-RevId: 823458736
Change-Id: Ia5c02cba186a80612de38402f791695c33e991ab
2025-10-24 03:42:55 -07:00
Google DeepMind 7bf065c75b Implement equivalents to mj_getState, mj_setState and mj_stateSize in mjx
PiperOrigin-RevId: 823158825
Change-Id: I06bbf603f61ef2de8f83f32a211e8d468e0b7c5c
2025-10-23 13:09:51 -07:00
Haroon Qureshi 99c18f07d3 Increase buffer size.
The smaller size is a warning/error on some targets:

```
error: ‘ bytes’ directive output may be truncated writing 6 bytes into a region of size between 0 and 15
```
PiperOrigin-RevId: 823047552
Change-Id: Id66b5828cf84a512dffc452753f1881deb685584
2025-10-23 08:16:54 -07:00
Haroon Qureshi 1fd9b47fea Prefix assets path with "assets/".
PiperOrigin-RevId: 823044312
Change-Id: I0bde4428bd1992d6d4356e107dac471fa7cdecc6
2025-10-23 08:07:33 -07:00
Sam Haves 18e60369f3 If building simulate with USD support remove the no-deprecated warning due to deprecated header usage in USD.
PiperOrigin-RevId: 822807399
Change-Id: I2765f4a7260b5ac8b3ef5894c1c5ce7a3a745baf
2025-10-22 17:56:43 -07:00
Sam Haves febe75d54b Add tendon.cpp to mjcPhysics CMake
PiperOrigin-RevId: 822694422
Change-Id: Ic2f7c7a3b85526d49eb98c19118e6936ccb4e0f7
2025-10-22 12:30:16 -07:00
Sam Haves ae33724de1 Set info string on wrap instead of tendon when wrapping a prim in the path.
PiperOrigin-RevId: 822688877
Change-Id: I04f5f5576cc0ed43e0ec77d5fccb19d2d23d7349
2025-10-22 12:13:53 -07:00
Sam Haves c060385505 Add section in mjcPhysics documentation for MjcTendon.
PiperOrigin-RevId: 822602481
Change-Id: Icf2b3accd323ee9506ca1838c9a2bfc0f0d159c7
2025-10-22 08:35:54 -07:00
Haroon Qureshi f217a8f987 Implement FetchPackage; a simple wrapper around FindOrFetch.
FetchPackage calls FindOrFetch, but sets USE_SYSTEM_PACKAGE to OFF
(i.e. do not find, just fetch). It also sets EXCLUDE_FROM_ALL.

PiperOrigin-RevId: 822565180
Change-Id: I70476f57b8d3371cefd02e840add279423913f3f
2025-10-22 06:43:51 -07:00
Sam Haves 160b9480f9 Add support for tendons to mjcPhysics.
PiperOrigin-RevId: 822230926
Change-Id: I232a9fbfb473186ac742d210458ff0221a561126
2025-10-21 12:30:12 -07:00
Sam Haves ac2cd5dfd6 Add support for querying of MjsTendon path from Python.
Fixes #2670

PiperOrigin-RevId: 822215254
Change-Id: Ice5a264e54f963776093511c6e4ac830aae6d4f8
2025-10-21 11:51:24 -07:00
Saran Tunyasuvunakool 2f65e23779 Add mj_extractState as a public API function.
This function allows the caller to extract a subset of components of a state previously obtained via `mj_getState` without having to first write it back into `mjData`.

PiperOrigin-RevId: 822165077
Change-Id: I6433261f4f5ec2e8d024bb7dee8f7dbf1e62666c
2025-10-21 10:01:22 -07:00
Kyle Bayes 25f5be82ff Provide option to disable keyboard events for SDL.
PiperOrigin-RevId: 822154396
Change-Id: Ie4c8537de2c4b01437aae00ed6d6af1a8f419a73
2025-10-21 09:36:16 -07:00
Taylor Howell 9e1ed0720b Revert PDF documentation update to .readthedocs.yml.
PiperOrigin-RevId: 822102488
Change-Id: I223757e80c00421c2ea37c3b30718c93b0a3cee8
2025-10-21 07:09:57 -07:00
Alessio Quaglino 056945df20 Enable frames to create the same children as bodies.
PiperOrigin-RevId: 822097998
Change-Id: I8477d8abe2d6f711421126825fd94d39af1a4e07
2025-10-21 06:57:01 -07:00
Sam Haves 09682ade4b Fix mjcPhysics island flag default.
PiperOrigin-RevId: 822088739
Change-Id: If3a87976dd319502160fd886a1823c12d72bebf1
2025-10-21 06:27:28 -07:00
Yuval Tassa 64add36adb Update documentation to be compatible with PDF generation
PiperOrigin-RevId: 822081040
Change-Id: I935b08751109e973398bc61c21f7217408983494
2025-10-21 06:02:53 -07:00
Alessio Quaglino 01d1ac34e0 Add quadratic interpolation to flex.
PiperOrigin-RevId: 822055781
Change-Id: Ibc252ac560de666b0b28f868e46b88d3ed92f67d
2025-10-21 04:36:36 -07:00
Joan Llobera 1a9469765f small syntax fixes 2025-10-21 10:58:17 +02:00
Sam Haves 59f14485e0 Move mjCWrap type to mjsWrap.
PiperOrigin-RevId: 821851540
Change-Id: I53382a8a21312a96aea46eec130f43e7cad70f92
2025-10-20 16:28:41 -07:00
David Hozic b19644bec9 Fix spelling errors 2025-10-21 01:21:47 +02:00
Matija Kecman 88ac02dad3 Add UI to visualize the State
PiperOrigin-RevId: 821641514
Change-Id: I41fd5602d0d52162b374149fb0080f6c387d7847
2025-10-20 07:32:41 -07:00
Haroon Qureshi e75c5aa83c Fix various include paths.
PiperOrigin-RevId: 821564663
Change-Id: Ic84489b7f3e1ba97810f60049dcf2f4a4d31edcf
2025-10-20 02:55:22 -07:00
Taylor Howell 36bed9a9da MuJoCo documentation in PDF format. Fixes #2736, #470.
PiperOrigin-RevId: 820682295
Change-Id: Ib9d6d53594c99a7e80af0fd3f1273ce44f831afd
2025-10-17 07:29:17 -07:00
Taylor Howell 85b5230dc0 MuJoCo Warp API documentation.
PiperOrigin-RevId: 820672892
Change-Id: I1339bdc4772560e69aa2c4b615825e7faffbe2ba
2025-10-17 06:59:19 -07:00
Taylor Howell bd8c921475 Update doc/conf.py.
PiperOrigin-RevId: 820636602
Change-Id: I20d8b44f9b933f14a72cb6e394be149bb459c552
2025-10-17 04:38:10 -07:00
Taylor Howell fdc0e64e5c Update .readthedocs.yml.
PiperOrigin-RevId: 820614563
Change-Id: I76d10cbb3cbcd55ab5a84ce74ab2cc3c3cc4ecaf
2025-10-17 03:13:46 -07:00
Joan Llobera 36bb957db1 cut extra long line to make sure it passes the syntax checks 2025-10-17 10:42:27 +02:00
Joan Llobera 92cb306ba5 removed Passive, added Damper and Spring objects 2025-10-17 09:58:07 +02:00
Joan Llobera 0001fe221c Revert "redid the global settings according to suggested guidelines"
This reverts commit 655b961c89.
2025-10-17 09:42:40 +02:00
Alessio Quaglino ff7c94de8a Add quadratic interpolation to mju_interpolate3D.
PiperOrigin-RevId: 820252349
Change-Id: I983175eb51d7e1a81da06c0911326fcb8f5fe764
2025-10-16 08:48:20 -07:00
Haroon Qureshi 87adb7e5d6 Use the ImGui OpenGL3 backend.
PiperOrigin-RevId: 820249390
Change-Id: I43fc85bf75a2c01b76218a2ff67a1526ee9e2bdb
2025-10-16 08:39:51 -07:00
Andrea Gesmundo 2893c3344c Allow mjx.ray to exclude multiple bodies.
PiperOrigin-RevId: 820236386
Change-Id: I41229fa52043d844d116b540d60053628d1a842b
2025-10-16 08:03:46 -07:00
Taylor Howell 2fc8306e3d Update .readthedocs.yml.
PiperOrigin-RevId: 820223836
Change-Id: If0567dc022cea8133773c89d738841de2945b049
2025-10-16 07:26:05 -07:00
Alessio Quaglino ffdfe542cf Add mju_interpolate3D.
This is a more general API in preparation of a higher interpolation order

PiperOrigin-RevId: 820174741
Change-Id: I81bd52ab44e0485d72579e21d1c8a48a1b35ec3f
2025-10-16 04:39:24 -07:00
Gabe Oppenheimer 48f10bfcb6 Update MuJoCo to v3.3.8 following the 3.3.7 release.
PiperOrigin-RevId: 819919328
Change-Id: Ib34f959f6f8efd83362d49e784aa8e0594036899
2025-10-15 14:39:05 -07:00
Kyle Bayes 8cbfc42767 Fix issue with zero size cache.
PiperOrigin-RevId: 819773517
Change-Id: Iff1523e17ffbd1dff02bee71db896c64bd8b565c
2025-10-15 08:46:00 -07:00
Yuval Tassa 5715cebbb9 MSAN: Don't clear mjData.sensordata in mj_resetData
This is strictly an out array and should not be read before it is written to. This change improves MSAN coverage of engine code.

PiperOrigin-RevId: 819767673
Change-Id: I57500c8147f4774d326cf87ea3bac5420e4dd54d
2025-10-15 08:31:03 -07:00
Taylor Howell 99d93124f0 Update .readthedocs.yml.
PiperOrigin-RevId: 819751628
Change-Id: Idf88c9169c63b80e6ae608b6e89911adbc7cb0b4
2025-10-15 07:47:07 -07:00
Matija Kecman fec7a576ad Revert the Eigen3 version due to an [upstream bug in Eigen](https://gitlab.com/libeigen/eigen/-/issues/2986)
PiperOrigin-RevId: 819709602
Change-Id: I948daf46419547a598b23810c2c4a7adca74fb05
2025-10-15 05:47:03 -07:00
Haroon Qureshi 9174c87203 Minor fixes.
PiperOrigin-RevId: 819680566
Change-Id: Ie2480eab3c974227268222190fdb84ed671303f2
2025-10-15 04:07:36 -07:00
Baruch Tabanpour 0d4f6231be Make JAX-Warp FFI more robust. Prepare for warp-lang 1.10. Fix #2894
PiperOrigin-RevId: 819381906
Change-Id: I1f16abcbe02884445725c3087aa97af941131533
2025-10-14 13:48:43 -07:00
Alessio Quaglino b6f25ca623 Check mjs_getName return value in XML parser. Fixes #2898.
PiperOrigin-RevId: 819351410
Change-Id: I0807d71328068f6388991ae15274c7d61b4d3e53
2025-10-14 12:40:28 -07:00
Taylor Howell 67960543a0 Updates for MJX viewer to help avoid graph recapture when impl='warp'.
PiperOrigin-RevId: 819312078
Change-Id: I2f94eff9720fac8d06017123a51770d39743f2d6
2025-10-14 11:14:59 -07:00
Haroon Qureshi f1d45bd542 Fix minor formatting issues and use nullptr consistently.
PiperOrigin-RevId: 819178621
Change-Id: I3f6bfb6888075188d49e32110af2074b07c6b918
2025-10-14 06:15:57 -07:00
Gabe Oppenheimer f7708954cb Update changelog to version 3.3.7 and reformat lists.
We won't be bumping the minor version until the next release.

PiperOrigin-RevId: 818748607
Change-Id: I34d0ac8836eeb6512f8dde112980f49f17125400
2025-10-13 11:16:16 -07:00
Gabe Oppenheimer ae1febd83f Automated g4 rollback of changelist 818694877.
*** Reason for rollback ***

BEGIN_PUBLIC
Holding off on a minor version bump until the next release.

*** Original change description ***

#mujoco update the version to 3.4.0 ahead of the 3.4.0 release.

Bump the version to 3.4.0 ahead of the next release.

***

PiperOrigin-RevId: 818748143
Change-Id: I722e9beb80c61a48bd997da6a1840777a81d5036
2025-10-13 11:14:42 -07:00
Gabe Oppenheimer 27e8736fc7 This CL updates the changelog to mark the release of MuJoCo 3.4.0. It also updates the versions of Eigen3, Abseil, and benchmark used in the CMake build.
PiperOrigin-RevId: 818719010
Change-Id: I865b0f647003d579af9d6c87fa081c4f7cbe34d0
2025-10-13 10:13:01 -07:00
Gabe Oppenheimer 02d2d4d49a Bump the version to 3.4.0 ahead of the next release.
PiperOrigin-RevId: 818694877
Change-Id: I42e261956a0219e549bec6a54cbf330a74f02f9f
2025-10-13 09:22:49 -07:00
Yuval Tassa bbeb0b95a7 Reset contact efc_address in mj_clearEfc, fixes #2869
The truth is that all these solver-related values should be moved out of `mjContact` altogether, but that can be done in a future followup.

PiperOrigin-RevId: 818624976
Change-Id: I5b9e63927098cdf26b9f8acfdd9d86e75d6ce331
2025-10-13 06:18:41 -07:00
Joan Llobera 655b961c89 redid the global settings according to suggested guidelines 2025-10-13 14:50:08 +02:00
Haroon Qureshi 9b7e7e471d Add line and linebox geom primitives.
PiperOrigin-RevId: 818570050
Change-Id: If02873dd878a23b442368ce69bc024e0310e9d02
2025-10-13 02:59:13 -07:00
Haroon Qureshi 66a1c22cae Label all bodies, not just selected bodies, when mjLABEL_BODY is set.
An earlier refactor incorrectly assumed that only selected bodies needed
labels.

PiperOrigin-RevId: 818568645
Change-Id: I7aea07c5342673dd589e1891d0db1f2b0c489fe4
2025-10-13 02:54:34 -07:00
Taylor Howell d9399d6f84 Update doc/conf.py.
PiperOrigin-RevId: 818544892
Change-Id: I4bb14309ebb4abe9eca1a61fa91b1bba6992a1e5
2025-10-13 01:47:09 -07:00
Yuval Tassa a7fe06c717 Further simplification to mj_crb
PiperOrigin-RevId: 818241421
Change-Id: I67dd2a60f415eb17b41f5ee553939118ab124123
2025-10-12 01:43:30 -07:00
Yuval Tassa 12f0e3df9a Quick return for static bodies in mj_object{Velocity,Acceleration}
PiperOrigin-RevId: 818238459
Change-Id: I340a2f61439db2a149cc64a5fee543680fdcad0f
2025-10-12 01:25:05 -07:00
Kyle Bayes 9e0885a4fa Handle exceptions in VFS C API.
PiperOrigin-RevId: 817688877
Change-Id: Ia2e306fe4cd1848eb5731212aa4e959080a9d377
2025-10-10 10:03:36 -07:00
Haroon Qureshi b63252e4bb Render labels for any geom with a label, not just label geoms.
PiperOrigin-RevId: 817686605
Change-Id: I030626dd942e50eef33e0de7e9d0f314fd2f457d
2025-10-10 09:58:21 -07:00
Taylor Howell 5f55e96810 Fix _get_data_into_warp.
PiperOrigin-RevId: 817681130
Change-Id: Iceb622e5655021ac25388ec28f1f78fe61f58ddc
2025-10-10 09:44:35 -07:00
Matija Kecman 624ae0ac26 Silence warning/error relating to not using a const-ref in a for loop.
PiperOrigin-RevId: 817652277
Change-Id: Ia700c67fe2c163c7a1e6e35fbbaed632cca213c3
2025-10-10 08:22:11 -07:00
Haroon Qureshi ff7c613c79 Initial implementation of the filament rendering backend for mujoco.
This is intended as a drop-in replacement for mjr_render to enable high
quality, physically-based rendering (PBR) using the filament render engine.

This is a work-in-progress and, as such, some features may be missing. This
is also a code-only drop; build files (including instructions on how to
generate the filament materials) will be provided at a later date.

This library is intended to be run with the experimental studio app.

PiperOrigin-RevId: 817593684
Change-Id: Ib9cd14c1881e4897c1111275bd749aa38ebb5317
2025-10-10 05:01:39 -07:00
Matija Kecman bd68f0c6cc Update CMake to use C++20
PiperOrigin-RevId: 817573868
Change-Id: I22c98515763623d7411fd12910cf88cdaa336e6e
2025-10-10 03:54:47 -07:00
Matija Kecman 59a5a7bf5f Improve error messages in LoadMujocoModel
PiperOrigin-RevId: 817565307
Change-Id: I367298cdf77d26b6f8deb5c6a0d5c3cab1e4d065
2025-10-10 03:24:50 -07:00
Taylor Howell 38af2e2d00 Export mujoco_warp/pyproject.toml.
PiperOrigin-RevId: 817541914
Change-Id: I271f66c26699c1c9d15133420e189d5c525deae6
2025-10-10 02:02:57 -07:00
Baruch Tabanpour 192da87475 Remove _full_compat from MJX io.
PiperOrigin-RevId: 817337868
Change-Id: Ic61b8d57937452371b85416c624ff2672c908aac
2025-10-09 14:26:19 -07:00
Erik Frey 50e163748d Use correct tile sizes in 3p mujoco_warp now that launch_tiled bugs are fixed.
PiperOrigin-RevId: 817310391
Change-Id: I652509ba8d6dcd514b264eb450952e6980e48f1e
2025-10-09 13:18:45 -07:00
Taylor Howell a9632a9825 MuJoCo Warp feature parity documentation.
PiperOrigin-RevId: 817123818
Change-Id: I21e4fd64943d68ffd714a1d84309ed5085764d6a
2025-10-09 04:33:24 -07:00
Haroon Qureshi abe88202d0 Remove redundant flags argument.
PiperOrigin-RevId: 817115667
Change-Id: I4e5096206d7c24f5861e1bb9e8049149803dceeb
2025-10-09 04:07:43 -07:00
Alessio Quaglino 98682ae284 Do not modify mesh position when fitting a geom to the mesh AABB.
Also, unify the meaning of fitting a geom to an AABB: it now means to find the smallest geom such that its AABB contains the mesh AABB.

Fixes #2881.

PiperOrigin-RevId: 817097544
Change-Id: I883c686feffa803bd16ba461db24a474dfec7712
2025-10-09 03:05:00 -07:00
Sam Haves 3a299c49ca Remove use of usdaFileFormat from mjcf_file_format.
Previously this was just used for the USDA file format token, which we can confidently just construct ourselves.

Since [this PR in OpenUSD](https://github.com/PixarAnimationStudios/OpenUSD/commit/5bb9ad1fb2a034e1f9b48c7db936f296b5b78e25) the file lives in a different place now and public usage will be deprecated anyways.

PiperOrigin-RevId: 816801204
Change-Id: I42e92d2af52b0f9ff0a679ecb96f3d2dbf623531
2025-10-08 11:54:44 -07:00
Joan Llobera cfd487c315 BUGFIX: when parsing a unity scene with mujoco element,s the mujoco package generates a value for the attribute "passive", but the attribute has been droped, it is not valid anymore in unity 3.3.6
this makes old mujoco scenes that work in unity not work anymore when upgrading the mujoco version.
2025-10-08 16:50:22 +02:00
Haroon Qureshi 1335ec87e4 Move font assets data targets into toolbox library.
PiperOrigin-RevId: 816654994
Change-Id: Ic56fab2b0af0c8d85682f8b233342a0d088d5cca
2025-10-08 05:09:42 -07:00
Haroon Qureshi 8e4932170a Remove unused params.
PiperOrigin-RevId: 816654011
Change-Id: Ib26bc90dcda167e8acf1feaa3b015acb5aa7aceb
2025-10-08 05:05:59 -07:00
Haroon Qureshi e7e331b11e Update sensor decor elements to be of type mjOBJ_SENSOR.
PiperOrigin-RevId: 816640568
Change-Id: I838608c0482ec1ee499fe9598ddb33aa6c5331e9
2025-10-08 04:17:40 -07:00
Haroon Qureshi 7b9f6a5cc1 Invert early-out checks to reduce nesting.
PiperOrigin-RevId: 816606107
Change-Id: I325d3f4695cdeb189694088d8a81b198d65f96ea
2025-10-08 02:21:14 -07:00
Baruch Tabanpour b56cf98e41 Import google-deepmind/mujoco_warp from GitHub. Update MJX io.py.
PiperOrigin-RevId: 816431884
Change-Id: I54881e7e350fbe5b2be1833e66745894b122f374
2025-10-07 16:43:30 -07:00
Saran Tunyasuvunakool f83ee3fd73 Update mujoco_warp.
Also remove mujoco_warp tests and test data from this repo.

PiperOrigin-RevId: 816239754
Change-Id: Ie89ef043d40bb43d1e1150acd33b5f4cbf162ab8
2025-10-07 09:50:21 -07:00
Haroon Qureshi fbab761627 Cleanup how different rendering backends are selected.
PiperOrigin-RevId: 816169098
Change-Id: I915aa45fa3a6d45a5178d3ff7bfdd0f1b1e01789
2025-10-07 17:48:23 +01:00
Taylor Howell fd9b989bf8 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 816099854
Change-Id: I6302a97c2f5d4594a08ebf4bc53a180b804360e6
2025-10-07 17:47:55 +01:00
Yuval Tassa 414888b716 Mark some mjData fields as mutable.
PiperOrigin-RevId: 815819490
Change-Id: I1a62fda556b4197aec451f2747c69f34bab13220
2025-10-06 11:43:38 -07:00
Yuval Tassa 52eff3da0f Fix mismatched argument format in mju_mulInertVec declaration.
PiperOrigin-RevId: 815818142
Change-Id: Id9caa581962705095f227a113505fc3e3ddd1054
2025-10-06 11:40:32 -07:00
Yuval Tassa ab9575d8a6 Refactor and speed up mj_crb and add a benchmark.
This is a no-op "prefactor" of `mj_crb` to reduce the number of lines changed in the upcoming sleeping CL. The main change here is that `mj_crb` now avoids accessing the model and data pointer repeatedly, but instead has the input and output pointers explicitly declared as local variables. A benchmark test found a healthy **14% perf bump** due to two changes:
- Adding `restrict` to `mju_mulInertVec`
- The function-local pointers.

Adding `restrict` to the local pointers had no effect. Note that `mj_crb` is not a particularly expensive function so these speed bumps are not significant per se, but rather indicative of possible future gains with these techniques.

```
Benchmark                Time(ns)        CPU(ns)     Iterations
---------------------------------------------------------------

ORGINAL BASELINE
BM_CRB_BASELINE_mean         4325           4348         993200  230.052k items/s

BASELINE + RESTRICT
BM_CRB_BASELINE_mean         4057           4090        1186150  244.573k items/s

LOCAL POINTERS + RESTRICT
BM_CRB_mean                  3772           3800        1001750  263.209k items/s
```

PiperOrigin-RevId: 815798225
Change-Id: Iffdf57b544e8e10562807c617f73ca4ccd1c614f
2025-10-06 10:54:01 -07:00
Taylor Howell b75af81c75 Update .readthedocs.yml.
PiperOrigin-RevId: 815776443
Change-Id: I6637a7d303232ca41840e80e27b6dd9d6b6d803c
2025-10-06 10:07:55 -07:00
Taylor Howell 9e5c5b110d Update .readthedocs.yml.
PiperOrigin-RevId: 815693650
Change-Id: Ibeb1ceab983768b4af5759d9654ea857faa2db64
2025-10-06 06:15:51 -07:00
Taylor Howell e10853e52e MuJoCo Warp basic usage and minimal example documentation.
PiperOrigin-RevId: 815654625
Change-Id: Ifa90a7469ef827777317bd3c4cda216130a5c7e9
2025-10-06 04:03:36 -07:00
Yuval Tassa 431f96572e Remove unused mjOption.apirate.
PiperOrigin-RevId: 815633571
Change-Id: Ib98f3eb2df47f96fa1fe6e987a3a0cd23a9479f6
2025-10-06 02:51:17 -07:00
Haroon Qureshi a849fedcd2 Separate mjv_addGeoms into separate functions for each category.
PiperOrigin-RevId: 815607891
Change-Id: I16b29061c7e2229146bd0e0152721bca40fa4fd1
2025-10-06 01:30:26 -07:00
Taylor Howell 680f880b03 Remove unused functions from collision_convex.py.
PiperOrigin-RevId: 815605363
Change-Id: Ia1978a2e84cedd3c4382164562d672d1d6f20c43
2025-10-06 01:21:47 -07:00
Sam Haves e4704cd28b Create list_dependencies sample to list all dependencies for an MCJF file.
PiperOrigin-RevId: 814816067
Change-Id: Idc6232e5d1ef1ff0318aeacd0e3d4b4a5a303485
2025-10-03 13:47:28 -07:00
Baruch Tabanpour 6ae9cc8061 Fix #2508.
PiperOrigin-RevId: 814761747
Change-Id: Ic3d1ed359f377799126987c3640b7e534e764c6b
2025-10-03 11:17:14 -07:00
Baruch Tabanpour d321ba7642 Bump warp-lang version.
PiperOrigin-RevId: 814757185
Change-Id: Ia3ee1fd731bf19b621a8816fdb7ce670f2bc035c
2025-10-03 11:05:48 -07:00
Yuval Tassa 6e6253c4d5 Remove redundant line in types.py
PiperOrigin-RevId: 814749110
Change-Id: Ic335e3ffc724a62a2d0660295afdfeb288f6c96a
2025-10-03 10:43:52 -07:00
Yuval Tassa 18779ab54a Clean up engine_core_util
PiperOrigin-RevId: 814709359
Change-Id: If4ec66808e7de51e16b772afdb8485fa4ff30030
2025-10-03 08:48:11 -07:00
Sam Haves b5c35f87fc Add material parsing path for colliders instead of strictly visual gprims.
PiperOrigin-RevId: 814692421
Change-Id: If92a36d0382f60e0d92c7d90320dec51c20ea739
2025-10-03 07:52:55 -07:00
Taylor Howell 709caa0628 Update .readthedocs.yml.
PiperOrigin-RevId: 814687463
Change-Id: Ia319c9bb77cb954d71b7afd27eedf33a65aeb5d1
2025-10-03 07:34:50 -07:00
Haroon Qureshi 24679b47e4 Separate out site and geom frame construction.
PiperOrigin-RevId: 814677737
Change-Id: I623f9d1e23ac6b3076a577e97911f7ec73492f52
2025-10-03 06:56:53 -07:00
Taylor Howell 9f796c3e70 Add missing constants to Python bindings.
PiperOrigin-RevId: 814663674
Change-Id: Ib5abb561a8b950cc6db86b4786ab01cd3326de78
2025-10-03 06:06:22 -07:00
Taylor Howell 53360f51a9 Update .readthedocs.yml to install MuJoCo Warp in order to generate API documentation. Additionally, mirror mujoco_warp/pyproject.toml in mjx/mujoco/mjx/third_party/mujoco_warp.
PiperOrigin-RevId: 814656860
Change-Id: Ie4c0e9076c90b598dedc65a3e9793ed3d2375c37
2025-10-03 05:39:45 -07:00
Kyle Bayes 50920450d2 Update box geom docs.
PiperOrigin-RevId: 814646973
Change-Id: I6ef294c2b740ca2ebbf2501974120d13d08bf56e
2025-10-03 05:00:26 -07:00
Taylor Howell 33a30480f8 Updates for MJX viewer related to Warp backend.
PiperOrigin-RevId: 814604809
Change-Id: I1cdb135f8f01b399163ece7415b09fd977ce7ad8
2025-10-03 02:25:24 -07:00
Haroon Qureshi 493d73062c Misc cleanup to addFrameGeoms.
PiperOrigin-RevId: 814582959
Change-Id: I2546bf1c13334628d379ad24737de095085e1b1f
2025-10-03 01:14:32 -07:00
Baruch Tabanpour 8eacacfd13 Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 814423562
Change-Id: Ibf441f161e25c51c494de84b0d263b32af76545c
2025-10-02 16:08:26 -07:00
Sam Haves 32e08f9507 Expose userfacenormal to mjsMesh
PiperOrigin-RevId: 814253177
Change-Id: I644974feea0722f03e7c3b01be7b702dba233f0a
2025-10-02 08:53:42 -07:00
Sam Haves 6320b95957 Add mju_getXMLDependencies that given an MJCF file returns filepaths to all of it's dependencies.
PiperOrigin-RevId: 814203235
Change-Id: Ib5c2e2f4dd42224a768c88d76473544190c72bc0
2025-10-02 06:14:48 -07:00
Taylor Howell 7e16ecaa25 Updates for testspeed.cc ctrl noise.
PiperOrigin-RevId: 814192687
Change-Id: I0498c8efc8e71cd578e6b9d40ffa1411447d3e43
2025-10-02 05:37:48 -07:00
Haroon Qureshi 6ed2ceaa83 Add non-decorative elements before decorative elements.
PiperOrigin-RevId: 814165875
Change-Id: Iab09e2fe1fa129b0c19760c969b5639e690a95d9
2025-10-02 03:59:06 -07:00
Kyle Bayes 91257896c0 Implement faster mju_isZeroByte.
PiperOrigin-RevId: 814148714
Change-Id: Iaf5ed9d3502eaaaee8d46a986f2db00811ae0707
2025-10-02 02:53:53 -07:00
Taylor Howell 401bf431b8 Modify Simulate::InjectNoise to set target of exponential decay to value from key_ctrl if a valid key is provided as input.
PiperOrigin-RevId: 813819040
Change-Id: I79508039b17fb3484b71ae0d19614c32adacfa10
2025-10-01 10:46:29 -07:00
Yuval Tassa edbdb5195c Change MuJoCo engine source code function-spacing convention from 3 blank lines to 2
PiperOrigin-RevId: 813754244
Change-Id: I6836e41c3b021cb727e922c25c60f629b9814c93
2025-10-01 07:58:17 -07:00
Sam Haves c439628f82 When parsing USD, infer gravity from stage metadata if UsdPhysicsScene missing or undefined.
PiperOrigin-RevId: 813705210
Change-Id: I13741af6dc87ecd9efb83219e978f5f06c72d021
2025-10-01 05:19:31 -07:00
Haroon Qureshi b1ae44d10f Refactor duplicated frame drawing logic into a utility function.
PiperOrigin-RevId: 813675737
Change-Id: I7f9094852f26b2ddc08534bf87cf2f71476d99ec
2025-10-01 03:36:14 -07:00
Haroon Qureshi f9d0bedb44 Minor cleanup: Move geom-related functions together.
PiperOrigin-RevId: 813661319
Change-Id: I6cdf74ff57f39f932ddd39268f15f1128ddf1df4
2025-10-01 02:46:45 -07:00
Haroon Qureshi 328a4ab293 Merge geomsExhausted into acquireGeom.
PiperOrigin-RevId: 813347956
Change-Id: I07bd566388383cc5c49e675f5b85fffb379ef6d1
2025-09-30 11:19:53 -07:00
Kyle Bayes de0ae73da7 Fix broken "building from source" link on Mujoco's README.
PiperOrigin-RevId: 813338644
Change-Id: I5a1e198556914619823ae180a63afac7450b3d6d
2025-09-30 10:59:10 -07:00
Sam Haves 4d590afdad Instead of caching PNGImage results, cache mjCTexture and mjCHField assets.
PiperOrigin-RevId: 813307632
Change-Id: I9de8b46423f57240d22811571d0533b010ee1e2b
2025-09-30 09:44:45 -07:00
Haroon Qureshi 59d0676dcc Remove redundant checks for exhausted geoms.
PiperOrigin-RevId: 813284297
Change-Id: I565c517bef782ba07ff323e206b75f6f905e5809
2025-09-30 08:44:17 -07:00
Sam Haves 2dc533b63b Allow flipping textures with any number of channels and user provided pixel data.
PiperOrigin-RevId: 813256285
Change-Id: I0d49885dc483ab8f093b2566ec4bef355575505e
2025-09-30 07:28:13 -07:00
Kyle Bayes bdccbcc60a Add multiccd fields to MJX and add simplex box-mesh model.
PiperOrigin-RevId: 813190617
Change-Id: Idc450da59d6420825077a642719525750f6551ec
2025-09-30 03:40:29 -07:00
Haroon Qureshi 70d03adc71 Store the status of the scene in the scene itself.
PiperOrigin-RevId: 813119377
Change-Id: Iebff9e7796ca9809ea22902522982bfd96eeba06
2025-09-30 00:06:00 -07:00
Haroon Qureshi fc8979ed4a Add test for checking exhausted geoms.
PiperOrigin-RevId: 812776271
Change-Id: Ic9456ab201610a69237182ac22147e3d3e240308
2025-09-29 07:18:12 -07:00
Sam Haves c31f11824e Add hfields to cache_hits benchmark.
PiperOrigin-RevId: 812759213
Change-Id: I155c2db58811dd1efa56a6361fd39aac669b63e7
2025-09-29 06:22:24 -07:00
Haroon Qureshi b17f4b26dc Add more scene golden tests.
PiperOrigin-RevId: 812708484
Change-Id: Icba94b128c89097703611ac4f6974f6d1cb19b4d
2025-09-29 03:19:48 -07:00
Haroon Qureshi 6a7566872a Functions for printing the contents of mjvScene.
PiperOrigin-RevId: 812699642
Change-Id: Iafff53c952c952624129ff01a8c1b0aa5d38eec5
2025-09-29 02:47:17 -07:00
Haroon Qureshi e1c7e19780 Add rendering flags to the studio UI.
PiperOrigin-RevId: 812649785
Change-Id: I47c6f974b7336bdd63c088ccfd06b5835e77ebff
2025-09-28 23:58:33 -07:00
Kyle Bayes 8de86c9944 Remove margin name from geomdist sensors.
PiperOrigin-RevId: 811775910
Change-Id: I4d265d4ad0206ea2d92c6c4b659f509a17f12baa
2025-09-26 05:24:12 -07:00
Yuval Tassa 9a5acbd662 Clarify subtree definition and self-collision matching in contact sensor docs.
PiperOrigin-RevId: 811731260
Change-Id: Ib890c59f67489de7d482cb239c146a9d565b6027
2025-09-26 02:34:56 -07:00
Yuval Tassa e51459f949 Break out struct initialization functions into engine_init.c.
PiperOrigin-RevId: 811598048
Change-Id: Ia832a8268e2209a5a264bbf79aa00dda487206bc
2025-09-25 19:22:27 -07:00
Yuval Tassa fe8384b6c5 Visualize joint and tendon limits by re-coloring.
PiperOrigin-RevId: 811590674
Change-Id: I5b65f2294a4bcda3c321fb51ebf29501bd0d416d
2025-09-25 19:02:26 -07:00
Alessio Quaglino c3bc793331 Add meshdir changelog item.
PiperOrigin-RevId: 811572927
Change-Id: I5aa3f5d8012781d39bd11fd4caa97f5d42577af3
2025-09-25 18:00:51 -07:00
Sam Haves 922aebbeed Provide explicit argument for asset cache ID.
This will allow assets to cache compiled results with different parameters. For example, we could cache both an RGB version of a texture and a Mono version.

PiperOrigin-RevId: 811341377
Change-Id: Ifd6a4ff88661a2b38be47c02d6a666de2c202885
2025-09-25 07:24:12 -07:00
dependabot[bot] cb7ebe6898 Bump pip from 24.3.1 to 25.2 in /mjx
Bumps [pip](https://github.com/pypa/pip) from 24.3.1 to 25.2.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/24.3.1...25.2)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: '25.2'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 22:40:20 +00:00
Haroon Qureshi 0baac58999 Remove redundant ngeoms check.
PiperOrigin-RevId: 810787607
Change-Id: I5d04b1d7f5f8ad758960a46ff08cc47d2887e851
2025-09-24 02:21:35 -07:00
Yuval Tassa d9650b68b0 Remove unused private functions
PiperOrigin-RevId: 810776310
Change-Id: I1c67c5efe07c4ca23b04122548b674719be927f7
2025-09-24 01:48:54 -07:00
Sam Haves e3377ceca3 Add cache hit benchmark to parsing benchmarks.
PiperOrigin-RevId: 810495543
Change-Id: I8c10806a091f870266f2c1194b39159c1f3105e0
2025-09-23 10:40:12 -07:00
Yuval Tassa d71d42a374 Add private function mju_isZeroByte to check for byte-wise zero.
PiperOrigin-RevId: 810456282
Change-Id: I877d0f9225e7a783ed7ff12ce54f4ed0a7889793
2025-09-23 08:49:43 -07:00
Haroon Qureshi bb0878417e Automated g4 rollback of changelist 810355812.
*** Reason for rollback ***

mjv_makeScene does not call mjv_defaultScene directly.  Instead, it calls mjv_freeScene which calls mjv_defaultScene.  However, mjv_freeScene attempts to free pointers if they are not NULL and if you don't call mjv_defaultScene then you'll have garbage data in those pointers.

*** Original change description ***

Remove redundant mjv_defaultScene call since its called by mjv_makeScene

***

PiperOrigin-RevId: 810442645
Change-Id: Ica50493d6769a0afb086f9ead99d731cdf0d75d9
2025-09-23 08:05:40 -07:00
Yuval Tassa 33b09e0822 Stop using stack allocation for catenary drawing
PiperOrigin-RevId: 810434095
Change-Id: Iee8c01ff721c2af216c5725fc9eaf6267b2e5284
2025-09-23 07:37:34 -07:00
Haroon Qureshi 09e6723dab Remove unnecessary stack mark/free in engine_vis_visualize.c
PiperOrigin-RevId: 810391913
Change-Id: Id02f4dadba7ef08f60bb7726470082f45c5761c5
2025-09-23 04:53:50 -07:00
Matija Kecman bf918ccf40 Remove redundant mjv_defaultScene call since its called by mjv_makeScene
PiperOrigin-RevId: 810355812
Change-Id: I2bc112e24c3adaca616604ebc5c1e3e3c494eb59
2025-09-23 02:35:05 -07:00
David Leins 2d1b5f1ed0 Adds missing failure exit codes for sample compile 2025-09-23 10:14:47 +02:00
Erik Frey 6aa06d2f43 Add _all_fields to MjOption, MjModel, MjData for struct introspection.
PiperOrigin-RevId: 810066486
Change-Id: I807104fc955a505512287f63b7c184a29c0d150e
2025-09-22 10:27:21 -07:00
Taylor Howell a5ed4ee223 MuJoCo Warp API documentation.
PiperOrigin-RevId: 810016913
Change-Id: Id4c309919068f7329cd35a2e0b63dc97c42343c3
2025-09-22 08:06:55 -07:00
Taylor Howell d616f11508 Remove references to deprecated nconmax and njmax.
PiperOrigin-RevId: 809987304
Change-Id: I4109497fe108234dd77011d61eb3ef833e6ae111
2025-09-22 06:28:41 -07:00
Taylor Howell 4bbe4e5ebc Zero actuator_velocity if actuation is disabled.
PiperOrigin-RevId: 809986353
Change-Id: Ie9fecda80864fef3377074042fd7829af8d03d64
2025-09-22 06:24:43 -07:00
Haroon Qureshi 6eea3d8ec0 Initial implementation of toolbox-based "Studio" app.
PiperOrigin-RevId: 809966748
Change-Id: Ic6333259ca1d112a2e42d47ccc44326bfcea3bdd
2025-09-22 05:02:31 -07:00
Haroon Qureshi 7fc6b29afd Replace PREPARE_NEXT_GEOM and FINISH_GEOM macros with functions.
PiperOrigin-RevId: 809940866
Change-Id: I1d45eede9ddf8606e7fd2a8caa2ed0224b0e24a7
2025-09-22 03:21:13 -07:00
Haroon Qureshi d9da8e2570 Replace RETURN_IF_GEOMS_EXHAUSTED macro with inlined code.
PiperOrigin-RevId: 809919921
Change-Id: Icf2afbd4168ebb18577b5915afa9d457001259d6
2025-09-22 02:03:19 -07:00
Yuval Tassa 4f27ab3467 Remove erroneous trailing backslash from xmacro.
PiperOrigin-RevId: 809763857
Change-Id: I9a3c8787d8b91fe21e00eca27331664b2e1ebfba
2025-09-21 14:15:10 -07:00
Yuval Tassa d55da23235 Simplify mj_comPos, avoid stack allocation
PiperOrigin-RevId: 809762290
Change-Id: I87824279ff5f7049b1f06b900d4d3e33f5fafe0f
2025-09-21 14:06:22 -07:00
Tom Erez 0141c6b8b7 Include reference to the State API in the mujoco-py migration guide.
PiperOrigin-RevId: 809349546
Change-Id: I4d48223962e6b89e3844c779e9499932c7b72945
2025-09-20 01:20:19 -07:00
Google DeepMind 0e1104768a No public description
PiperOrigin-RevId: 809083979
Change-Id: I5c6641b73c76153c15f5cdf858b788e1433acc81
2025-09-19 10:10:45 -07:00
Google DeepMind 26ea20a21f No public description
PiperOrigin-RevId: 809074980
Change-Id: Ib3e3522addceddba6a057cfef80fcbd30a420b3d
2025-09-19 09:49:07 -07:00
Alessio Quaglino 77e025ea98 Move meshdir and texturedir to mjsCompiler.
For backwards compatibility in the Python bindings, both `spec.compiler.meshdir` and `spec.meshdir` are now allowed.

Fixes #2834.

PiperOrigin-RevId: 809060113
Change-Id: Ie23f1c5dd57de43568312a8e062906f4013bb474
2025-09-19 09:05:44 -07:00
Yuval Tassa 681f5767b2 Remove -Wno-extra-semi, add workaround for mjSORT confusing some IDEs
PiperOrigin-RevId: 808689636
Change-Id: Ia091fb597c171a33842e62690d06f32614fbe4eb
2025-09-18 12:28:09 -07:00
Baruch Tabanpour 60cb976e82 Add assertion for leading dims in MJX-Warp.
PiperOrigin-RevId: 808624659
Change-Id: I259f9cd753bdffbe465ae807ec957f123e8d589e
2025-09-18 09:52:44 -07:00
Kyle Bayes eb96dd556c Reduce ccd_iterations from 50 to 35.
PiperOrigin-RevId: 808610578
Change-Id: I8755f9ba2902bf0805b7ded07ee6e048e404a31f
2025-09-18 09:16:52 -07:00
Yuval Tassa 4b8454b79c Add semicolons after mjSORT macro calls.
PiperOrigin-RevId: 808587320
Change-Id: I9fd290b9a2b615647135f1250e87af8ea9bb81f6
2025-09-18 08:13:46 -07:00
Peter Hawkins 0e61a4ac5e Remove jaxlib.hlo_helpers.
This module has been deprecated for many months and its replacement is jax.ffi.

PiperOrigin-RevId: 808567797
Change-Id: I5b4f4eee5e65ccd86e597c5761e68c36292b6209
2025-09-18 07:18:23 -07:00
Matija Kecman f9f3dd3c1d Fix ImGui input processing
PiperOrigin-RevId: 808555760
Change-Id: Ie443143d9c058058b99786e44f27715b05c9f8ed
2025-09-18 06:42:16 -07:00
Haroon Qureshi d7500e0dec Split START macro into two parts: one for control flow and one for assignment.
PiperOrigin-RevId: 808497167
Change-Id: I4d78426af69d98f57600cb7fd76edaf5b20b0039
2025-09-18 03:23:12 -07:00
Haroon Qureshi 6f5a7576f9 Move simlib into experimental folder and rename it toolbox.
Also:
- update the namespace to `toolbox` (instead of `filament`)
- Add copyright notices to all files
PiperOrigin-RevId: 808474353
Change-Id: Id1fe86c5d183c8e91bec8509b6c0830b5fe84c1c
2025-09-18 02:15:23 -07:00
Rishi Krishnan 8e9eb2fa38 Update MuJoCo's version number following the 3.3.6 release.
PiperOrigin-RevId: 808180152
Change-Id: I23de64cb0968b94c489b29622e4308d16513793a
2025-09-17 09:13:04 -07:00
Copybara-Service 9af1f55862 Merge pull request #2713 from vidurvij-apptronik:vidur/remove-installing-glfw3-headers
PiperOrigin-RevId: 808125077
Change-Id: If87b65d2d8607f153dfd66fbfa9a6ca39c98845f
2025-09-17 06:17:42 -07:00
Yuval Tassa 7eab0117f7 Don't smooth tracking camera motion
PiperOrigin-RevId: 808110613
Change-Id: Ib8631e5ace6db7c7bb780f26b79a72e26e72f451
2025-09-17 05:25:17 -07:00
Kyle Bayes 9740705510 Add cache functions to Python bindings.
PiperOrigin-RevId: 807813218
Change-Id: Ieab2843d92e79c07bc9f98196db51297a456dedb
2025-09-16 13:02:59 -07:00
Taylor Howell f2fcd05b1b Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 807766737
Change-Id: I1c22361ffa61f27fd8e0fd534b96488531761916
2025-09-16 11:08:56 -07:00
Yuval Tassa 52da7586dc Clean up includes in src/engine
PiperOrigin-RevId: 807726978
Change-Id: I02800deb79bfb3c328d941861ded9d817e8f6e32
2025-09-16 09:36:44 -07:00
Alessio Quaglino 5bbda2186d Make the Octree interpolation continuous.
This is done by detecting the hanging nodes and compute the function at those location by interpolating the corresponding coarse vertices.

PiperOrigin-RevId: 807700228
Change-Id: I27dcb85361ca445c2099dd07b280cae5c92d3131
2025-09-16 08:15:26 -07:00
Taylor Howell 04380890d5 MuJoCo Warp documentation.
PiperOrigin-RevId: 807693732
Change-Id: I6a49e195eb9f9ac2d562f1aa4745c1206e069caf
2025-09-16 07:56:41 -07:00
Matija Kecman afbefc38a6 Ensure noise is injected when the simulation is paused and a single step is manually requested
PiperOrigin-RevId: 807688008
Change-Id: I8de9706c633565d6d6944b58d34de9da1037a837
2025-09-16 07:35:42 -07:00
Rishi Krishnan eacad44a1a Update changelog for 3.3.6 release
PiperOrigin-RevId: 807337529
Change-Id: I48bffe879a462a68ad0e55a75a8461bf3a98e97b
2025-09-15 12:27:46 -07:00
Kyle Bayes ac4874226c Support NULL in dir parameter in mj_addFileVFS.
Fixes #2839.

PiperOrigin-RevId: 807208005
Change-Id: I8def3b1e388dc19fa2fa8a92d53abef30dee5b88
2025-09-15 06:00:13 -07:00
Copybara-Service dd398f47b9 Merge pull request #2850 from google-deepmind:cmake
PiperOrigin-RevId: 807207617
Change-Id: I3e54ea0c79560bcf283b16ee9ee5772ae8e99a8c
2025-09-15 05:58:59 -07:00
Taylor Howell 155d6c686a remove UpdateCMakeMinimumRequired.cmake 2025-09-15 13:30:56 +01:00
Taylor Howell 85a7ac8e82 Merge pull request #2851 from traversaro/patch-43
[cmake branch] Refactor cmake_minimum_required handling in dependencies
2025-09-15 05:26:58 -07:00
Silvio Traversaro ea856a4c31 Refactor cmake_minimum_required handling in dependencies
Removed PATCH_COMMAND for cmake_minimum_required updates and added checks for CMAKE_POLICY_VERSION_MINIMUM.
2025-09-15 13:44:10 +02:00
Taylor Howell 0ddb840395 add comments explaining patches 2025-09-15 12:28:38 +01:00
Taylor Howell c79b2d064b add description of file utility 2025-09-15 12:17:41 +01:00
Taylor Howell 1b7e508f17 add copyright header 2025-09-15 12:16:15 +01:00
Taylor Howell 83a619c5b7 patch for cmake_minimum_required version 2025-09-15 11:40:08 +01:00
Alessio Quaglino 4fc69fa64d Ensure that the Octree is balanced.
This means that two adjacent nodes can only have at most one level of refinement difference.

Note: This is a small breaking change for mjWarp since the order of the children was flipped.
PiperOrigin-RevId: 806299445
Change-Id: Ia326a31c7a8162ae02d70c868d87779198e805be
2025-09-12 08:34:15 -07:00
Google DeepMind 2287b9f815 Don't prepend meshdir to asset paths in MjSpec.to_zip.
PiperOrigin-RevId: 806287351
Change-Id: I9afc8251f9cbced9ecd370b39cec6aeff424514b
2025-09-12 07:54:16 -07:00
Alessio Quaglino 7e048b7535 Refactor: Convert mjCOctree::MakeOctree from recursive to iterative.
The octree construction is now performed using a breadth-first search with a `std::deque` to manage tasks. A new `OctreeTask` struct encapsulates the state for each node to be processed, and a helper function `Subdivide` is introduced for subdividing the Octree nodes.

Also reduce the number of (center, size) to (min, max) conversion for the bounding box representation in order to avoid duplicated vertices in the Octree due to floating point errors.

PiperOrigin-RevId: 806214441
Change-Id: Iff9015ebe4705522db743c478cef5acf1a7312b7
2025-09-12 03:22:17 -07:00
Yuval Tassa f61f89bf54 Update use of absl::MutexLock in fixture.cc
PiperOrigin-RevId: 806203271
Change-Id: Ia058d117aedb12c1014912bf5ff192fcc9782964
2025-09-12 02:46:22 -07:00
Taylor Howell 89152fb39e Import NVIDIA/warp from GitHub.
PiperOrigin-RevId: 806000657
Change-Id: I5127baf8d212c5fc7bd597c843957f4b279d52db
2025-09-11 15:06:55 -07:00
Haroon Qureshi ad5f07e060 Extract functions from mjv_updateCamera for calculating frames and frustums.
PiperOrigin-RevId: 805770746
Change-Id: Id2a6022a2ee2e8b1a783debf54b470a9df81051a
2025-09-11 04:10:59 -07:00
Haroon Qureshi 017e7d5a73 Add light ids.
PiperOrigin-RevId: 805755907
Change-Id: I92a1b1ea4ce1495c2746fd518f33ab2d1ad81399
2025-09-11 03:20:44 -07:00
Google DeepMind da2fad4530 Catch RuntimeErrors when importing warp.
PiperOrigin-RevId: 805586914
Change-Id: Ica3ca016c8056316d1d2f052e4d3481f578a8aad
2025-09-10 17:53:41 -07:00
Rishi Krishnan 4b18009f47 Revert Eigen version
PiperOrigin-RevId: 805395095
Change-Id: I9c8184f2e667dd7595a6211626be606878f9c04f
2025-09-10 09:34:06 -07:00
Rishi Krishnan 6ec5f8b9c2 Update Mujoco Deps in preperation for the 3.3.6 release
PiperOrigin-RevId: 805007266
Change-Id: I9332d0b8439f8941b9dc9889c1e27d54e9a70b99
2025-09-09 12:01:53 -07:00
Alessio Quaglino 9d5063799f Resize keyframes also at the start of compilation.
Previously, it was assumed that attaching was the last operation performed on the mjSpec, so keyframes resulted in the incorrect size. In order to prevent information loss, we now only allow the resize function to expand the keyframe array, since attach should never remove a degree of freedom.

PiperOrigin-RevId: 804917828
Change-Id: Icfacd207ced1c6aac600d514f8d9065ceff2d347
2025-09-09 08:16:32 -07:00
Sam Haves 3b738ebb67 In USD exporting docs change NVIDIA mujoco-usd-converter to Newton.
PiperOrigin-RevId: 804866989
Change-Id: I9ee060a85a0671e4ca07654a48d791b456a6e1f9
2025-09-09 05:39:07 -07:00
Kyle Bayes ea660f4c13 Expose minimal asset cache API.
PiperOrigin-RevId: 803126923
Change-Id: Iabf63802572f7cb86864b5ece85f44b3f15a4ec0
2025-09-04 12:18:36 -07:00
Michiel Blokzijl 02a535b44f Update https://pypi.org/project/glfw/ to 2.9.0.
This ensures that Python bindings build also uses GLFW 3.4, similar to C/C++
MuJoCo.

The hashes are from https://pypi.org/project/glfw/2.9.0/#files.

PiperOrigin-RevId: 802536702
Change-Id: Ie9cfc17a5f9146fe6731681115f7aaa98fcb323e
2025-09-03 07:01:53 -07:00
Alessio Quaglino 767996ab17 Transform inputs to global before calling rayMesh in SDF collisions.
PiperOrigin-RevId: 802523399
Change-Id: I889b020e4e721fbf471992f5c87446df601ba766
2025-09-03 06:12:34 -07:00
Yuval Tassa 7a93e22514 Refactor MJMODEL_POINTERS into category-specific macros.
PiperOrigin-RevId: 802089588
Change-Id: Id3443f88e8243c5167a23b6e42eb32a32f88e8d3
2025-09-02 04:41:50 -07:00
Haroon Qureshi 8d884585dd Add target relative mouse motion actions.
PiperOrigin-RevId: 802072880
Change-Id: I1ff204594a126f8e50df4c703709f70ec4dd458c
2025-09-02 03:39:49 -07:00
Michiel Blokzijl ee777f74d3 Explain how to build Python and C/C++ sources from the same codebase.
The previous instructions use a pre-built binary from MuJoCo and do not cover
the use-case of building C/C++ and Python bindings from the same codebase.

PiperOrigin-RevId: 802060401
Change-Id: I6d0b9c7c2269ff596ac706b716ff6c95b42c5d99
2025-09-02 02:51:49 -07:00
Alessio Quaglino 8acd83f317 Add passive collision mode for flexes.
PiperOrigin-RevId: 801754907
Change-Id: I4147af2ee2596519d42cb9a03cf8d5488f0bc3e8
2025-09-01 04:13:58 -07:00
Yuval Tassa b9900db00e Extract memory allocation functions and core utilities
PiperOrigin-RevId: 801745499
Change-Id: Iaf05c3430769d3115743d8ab020d13148cb2eb59
2025-09-01 03:38:25 -07:00
Yuval Tassa 5d598a49a2 Documentation bug fixes.
PiperOrigin-RevId: 801283863
Change-Id: I85bb11f4970bd6206f99a91cee04c2b99f73c576
2025-08-30 11:03:43 -07:00
Yuval Tassa b092563cab Remove mjDSBL_PASSIVE, split it into mjDSBL_SPRING and mjDSBL_DAMPING.
PiperOrigin-RevId: 800870384
Change-Id: I273e0ceec090901e2620febb67e57914928e94bb
2025-08-29 06:06:28 -07:00
Saran Tunyasuvunakool 0eea5d6dbd Add libwayland-dev and libxkbcommon-dev to GitHub Actions YAML.
PiperOrigin-RevId: 800462182
Change-Id: I771df8af3f827f0fe7f2d9975eb6fd04940f17dc
2025-08-28 07:40:38 -07:00
Michiel Blokzijl 508d22f794 Update the GLFW dependency used by MuJoCo to 3.4.
This makes it possible to build open-source MuJoCo with Wayland support out of
the box.

Currently, it is necessary to run cmake with -DGLFW_USE_WAYLAND=ON and ensure
cmake can find the "ECM" package somehow (a dependency of the 3.3.6 version of
GLFW), for which there is no automated fetching setup. As this is no longer a
dependency of GLFW it seems to make more sense to update GLFW to make out of the
box builds on Wayland.

PiperOrigin-RevId: 800456607
Change-Id: Iffdf1d65319bfb134e580faceb63ac3bed7b9c84
2025-08-28 07:24:26 -07:00
Yuval Tassa b1c94c3761 Add printing of block-diagonalized matrices
PiperOrigin-RevId: 800345520
Change-Id: I4996c5a7509cb451744d3e428a975cceee845ea5
2025-08-28 00:54:39 -07:00
Baruch Tabanpour ba47402853 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 800210640
Change-Id: I06d05ee2560f54d975458f0e13b37157c088c33b
2025-08-27 16:11:11 -07:00
Tom Power 79f2bbc727 Fix memory error when placing images in viewport
PiperOrigin-RevId: 800148735
Change-Id: I1c12ef23b0af9538b285d032460cf832eb48bf49
2025-08-27 13:20:45 -07:00
vidurvij-apptronik 28aa33b673 expose glfw 2025-08-27 12:00:37 -05:00
Yuval Tassa 643dc5bf4f Update USD schema formatting
PiperOrigin-RevId: 800018484
Change-Id: I7677cd099415af1271c7475d80a660653199b984
2025-08-27 07:02:50 -07:00
Haroon Qureshi ed6fa7fe09 Remove unused mjMOUSE_SELECT option.
PiperOrigin-RevId: 799957524
Change-Id: I69d091781dc2a2e4a762d2255d04fc411295602a
2025-08-27 03:19:04 -07:00
Yuval Tassa 7443e685ac Allow contact sensor subtree1/subtree2 to be any body.
PiperOrigin-RevId: 799632590
Change-Id: If9cd6c5a3a5f83d89ae024a8f64232ab1f1d603a
2025-08-26 11:00:39 -07:00
Baruch Tabanpour 9eaa31af2f Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 799614257
Change-Id: Ie05d4dd7c45308ed5e8010c3eca4b68f552335ea
2025-08-26 10:17:11 -07:00
Taylor Howell 1ac51cf2a5 Update comment in engine_forward_test.cc.
PiperOrigin-RevId: 799550233
Change-Id: I75840bdcb94d4b10962f1fff5a225a6fe5bc0672
2025-08-26 07:12:51 -07:00
Yuval Tassa debfdf011e Add some missing Nullable annotations.
PiperOrigin-RevId: 799527319
Change-Id: If84a3b2f19243ea9cf8b114d1421879d8186eb1d
2025-08-26 05:52:01 -07:00
Yuval Tassa ec94bb49aa Make constraint island discovery on by default.
Also fix latent bug in mjData serialization.

PiperOrigin-RevId: 799505349
Change-Id: I299e7cc8133fa2ec0b339a7ff3d02543e06778b1
2025-08-26 04:27:24 -07:00
Taylor Howell 4cf5c37211 Fix spelling in engine_forward_test.cc.
PiperOrigin-RevId: 799147728
Change-Id: If5e734ba31961d459281f7cb5edea7c370c1f2fd
2025-08-25 09:15:48 -07:00
Yuval Tassa 2b45b39ce5 Move mjtConstraint from mjmodel.h to mjdata.h.
PiperOrigin-RevId: 798987338
Change-Id: I3117742de7eb3c16366f266fe0c0651262717cb4
2025-08-24 23:45:14 -07:00
Yuval Tassa d77ecb3f06 Move mjtConstraintState from mjmodel.h to mjdata.h.
This is the correct location, this enum is only used in `mjData`, not `mjModel`.

PiperOrigin-RevId: 798860951
Change-Id: I48b9a2afc831bd9a6966cc9586429fd03605bdd2
2025-08-24 12:37:54 -07:00
Yuval Tassa 1c1bb14e1c Order fields in mjxmacro like in mjmodel and mjdata headers, add tests.
PiperOrigin-RevId: 798848000
Change-Id: Id1a41f6a0a4e3e6f3bb197f096061bd1d72a4b51
2025-08-24 11:17:30 -07:00
Yuval Tassa 7479312218 Use LaTeX macros for prettier uppercase subscripts in documentation.
PiperOrigin-RevId: 798547203
Change-Id: I039886fd15ee022de780a19d0ad6e17d01c306f4
2025-08-23 05:39:36 -07:00
Yuval Tassa a230aa60c5 Improve mj_addM and associated test
- Updated docs to clarify that only the lower triangle is touched
- The function was unnecessarily adding the upper triangle in the sparse case
- The test used an unnecessarily large model and stepping it leading to timeouts under ASAN

PiperOrigin-RevId: 798528736
Change-Id: I592cc17dfb62379bb0cd6b332a8eb7e8b0ef6355
2025-08-23 03:56:47 -07:00
Google DeepMind a64a26c3ae No public description
PiperOrigin-RevId: 798355907
Change-Id: I3a225e3200cbc60ccc3d93f21694a606a7ab296a
2025-08-22 15:04:46 -07:00
Yuval Tassa 93c5665730 Add some missing Nullable annotations.
PiperOrigin-RevId: 798298579
Change-Id: I773eda7deca10c820345a33835716072e0b9af5a
2025-08-22 12:15:02 -07:00
Sam Haves 1fb1810b07 Add ability to specify a material assignment to a mesh asset.
This extends both the spec and the XML definition to allow specification of a material name on a mesh. This material acts as a fallback in the case that the referencing geom element does not specify a material of it's own.

PiperOrigin-RevId: 798232378
Change-Id: Iaf300c727732744ea1b613e64334ee505ac6e209
2025-08-22 09:11:31 -07:00
Google DeepMind 42d8454555 Internal change.
PiperOrigin-RevId: 798190254
Change-Id: Ie3a3b6e074511991cc6ccb35f2c26c6d9ae7ccd8
2025-08-22 06:41:49 -07:00
Haroon Qureshi debbd7c916 Fix cast; should be mjtGeom not mjtMouse.
PiperOrigin-RevId: 798177495
Change-Id: I5d95446dd7f7f84052b60cb378acdd856c1e4d50
2025-08-22 05:47:49 -07:00
Google DeepMind ecfe65242f Add nullable attribute to AST nodes for function parameters in API introspection. Fixes #309
This change introduces an `nullable` flag to `ArrayType`, `PointerType`, and `FunctionParameterDecl`. The code generation process now parses function comments from `mujoco.h` to identify parameters marked as "Nullable" and sets this flag accordingly.

PiperOrigin-RevId: 797870883
Change-Id: Ic7cac5a7a9c14177fbf97b8655c5c4809d4ef683
2025-08-21 12:35:10 -07:00
vidurvij-apptronik df6b503101 Update simulate library name in python cmake 2025-08-21 14:34:12 -05:00
vidurvij-apptronik b88ec4df73 Fix SimulateDependecies 2025-08-21 14:10:44 -05:00
Baruch Tabanpour 3dec35a91e Do not update qacc_warmstart at the end of the solver call; instead, update it at the same time as all other state variables. This change makes mj_forward idempotent.
PiperOrigin-RevId: 797826112
Change-Id: Ibc51624adc3ec42c265958bf77696b33231431c1
2025-08-21 10:44:05 -07:00
Yuval Tassa 2f28473bc1 Remove transposed Jacobian fields from mjData
No longer computed unconditionally, only ad-hoc where required.

PiperOrigin-RevId: 797753297
Change-Id: I2030fc342c98ff33575b0526dd72e2110c4fcb74
2025-08-21 07:21:24 -07:00
Yuval Tassa 5fe4224ae7 Compute sparse Jacobian transpose inside solver.
PiperOrigin-RevId: 797745776
Change-Id: I2ec429120d0c6eb51bec340619ab178389482e69
2025-08-21 06:55:48 -07:00
Yuval Tassa f71053243e Replace std::array with C-style array for error buffer in GJK tests.
PiperOrigin-RevId: 797730796
Change-Id: I228c58e163c8c6d1426a88c1a6f447c4a56a34e6
2025-08-21 06:03:53 -07:00
Yuval Tassa 174a50442d Allow transposing of sparse sub-matrices whose first row is > 0
PiperOrigin-RevId: 797728559
Change-Id: I3c825118dae198333d357d2e4f248d00b0f5d8ce
2025-08-21 05:56:33 -07:00
Yuval Tassa c7a82c32dc Do not update qacc_warmstart at the end of the solver call; instead, update it at the same time as all other state variables. This change makes mj_forward idempotent.
See changelog herein for motivation and discussion.

PiperOrigin-RevId: 797392841
Change-Id: If50e9f09e1d07e8363169d3589c32097aeca2432
2025-08-20 11:30:13 -07:00
Baruch Tabanpour bf04103b6f Import google-deepmind/mujoco_warp from GitHub.
#MIGRATION_3P_PY_MUJOCO_WARP__DEFAULT

  - 19dde09e179dbbaf4d07084185074f6a774b3255 update derivative.py by Taylor Howell <taylorhowell@google.com>
  - 04bc115c3766e974ef000cca16d40bacb92c01d2 fix _ray_hfield by Taylor Howell <taylorhowell@google.com>
  - 7fcbf8ddba08c9b9d33b0fdd4dd3fe39e40a0bd7 Use sparsity structures in `mjModel` rather than `mjData` by Yuval Tassa <6387526+yuvaltassa@users.noreply.github.com>
  - bfd2e4fe3cb5ba5dee97445ddc1d072344f443ec Fix override for enums (#617) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - f4dbf5345bd5dcae60c415361dd425605b672e5c Add keyframe selection to viewer (#616) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - 0e7edf9e8fd337502586929b2e4dd3d51201f462 add prunning to multiccd by Kyle Bayes <42924292+kbayes@users.noreply.github.com>
  - 791c30237cbdecf876bc53ac0b3dcff8b8b1317d format by Kyle Bayes <42924292+kbayes@users.noreply.github.com>
  - 7a7bae6c1390df3f29058e90f25f9ed5caab3fb1 Fix override in viewer and testspeed (#620) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - 9e230c229c7dd721fbf6fa5fe69fc98717895500 add + 0.0 by Taylor Howell <taylorhowell@google.com>
  - 8a70a5e8839b84c11601bf1a98f9e7d1d31603f1 Update the test_cost unit test to test more properties (#... by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - cf317c60845b24ddba4b6814dbac9eba32b4c8b0 parallel linesearch with log scale for step sizes (#575) by Taylor Howell <taylorhowell@google.com>
  - b73e4edbc0d331d1e4f15c006d4535cc59595e70 add better reporting (#600) by adenzler-nvidia <116633880+adenzler-nvidia@users.noreply.github.com>
  - 007ad0b204ed4d48584024cce4676ac25a5695b5 Optimization: Fusing kernels around update_gradient_JTDAJ... by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - 640a89fcf452b9564508cacdeb30ecef3a83aede Adding static to broadphase filter (#621) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - daca09ff3261db2713abc912191d6cf76437b8b7 Add reporting of converged worlds in testspeed (#619) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - 33830bddd95a7f0d3febe1b090398ddadeb86ee2 Fix call to benchmark from asv (#627) by Kenny-Vilella <163487060+Kenny-Vilella@users.noreply.github.com>
  - 382eb65f7bb45798698f4025a980287ab1ec84c7 Update flex_bending dimensions (#628) by Alessio Quaglino <102665781+quagla@users.noreply.github.com>
  - c56b8875439cfaa93c1393f0a6e2ad057e029064 contact sensor maxforce reduction (#602) by Taylor Howell <taylorhowell@google.com>
  - 4f731941cb9dea397d4f71cf8151100b83eae576 A few airspeed velocity improvements. (#626) by Erik Frey <misc@fawx.com>

PiperOrigin-RevId: 797054114
Change-Id: I380e0b9446f94202b2389e2a760d6de5f0ec5af7
2025-08-19 16:01:28 -07:00
Baruch Tabanpour fd96de330e Updates to Playground for warp.
PiperOrigin-RevId: 797037846
Change-Id: I3828b48aead8a7534a4e8cd735c96017353daa3b
2025-08-19 15:12:31 -07:00
Vidur edb17909a7 Update cmake 2025-08-18 14:00:38 -05:00
Sam Haves 4bad134ba2 Add proper handling of MJCF asset/mesh/texturedir compiler attributes to USD plugin.
This allows the MJCF SdfFileFormat plugin to load MJCF files that specify assetdir, meshdir, or texturedir attributes. This is specifically important for resolver implementations that fetch assets into a local cache.

PiperOrigin-RevId: 796509754
Change-Id: Ib2b0c9cf9d6a3351ceea49d90c882edf94d0b880
2025-08-18 11:38:32 -07:00
Yuval Tassa 424226b640 Refactor mj_mulM to use CSR structure
PiperOrigin-RevId: 796450207
Change-Id: I2a9d567732614674547c7ae02ff0d3d4bbf1b654
2025-08-18 09:09:29 -07:00
Alessio Quaglino c2ff60e630 Decrease time step in shell examples.
Also add bending damping.

PiperOrigin-RevId: 796446515
Change-Id: I4744003caf6146e5e00614a6016d1a6dfc42cca7
2025-08-18 09:00:10 -07:00
Sam Haves eed43f6982 Add section to OpenUSD/Exporting docs linking to mujoco-usd-converter.
PiperOrigin-RevId: 796420566
Change-Id: I47728e3900720d732162c06f96a231a75d8bc931
2025-08-18 07:44:40 -07:00
Yuval Tassa 7c10a62f21 Improve island visualization colors and logic.
- Make island visualization off by default
- Give it the keyboard shortcut 'N'
- Use HSV island coloring

PiperOrigin-RevId: 796375514
Change-Id: I3cc8d6f8142412c771b2b8e57e82e70000727770
2025-08-18 05:03:41 -07:00
Alessio Quaglino b66175eba6 Bending stiffness for curved shells in flex.
PiperOrigin-RevId: 796361841
Change-Id: I105ea235fe2a8e1bcbde67276d77fa92eed214a1
2025-08-18 04:13:18 -07:00
Yuval Tassa 972ffd7b90 Improve mj_fullM documentation, add clarifying test.
PiperOrigin-RevId: 796134559
Change-Id: I85ab3680d3545ccf83d0d3af8a7c21cb36e96d4e
2025-08-17 11:02:14 -07:00
Yuval Tassa 6b41fbe72a Use CSR matrices for dof-dof index mappings
PiperOrigin-RevId: 795895311
Change-Id: I1000e0ee98906ef35990e73236e85d6354487b82
2025-08-16 13:06:32 -07:00
Yuval Tassa c0096b51a4 Move ntree to mjModel allocator sizes
PiperOrigin-RevId: 795855203
Change-Id: Idab185294d53dced9ebf073b782969dc5643b95a
2025-08-16 09:16:41 -07:00
Yuval Tassa 1447711037 Rename spec to sig in state-related API functions.
(to avoid confusion with mjSpec)

PiperOrigin-RevId: 795848898
Change-Id: I0b64eb85f5c7a3ee889a746c751d9f5561650277
2025-08-16 08:38:25 -07:00
Yuval Tassa 5a24eb2d34 Add error reporting to model loading in engine tests, where missing
PiperOrigin-RevId: 795844607
Change-Id: I4163c53c05796c2e3036af28a98f58c15bb1c99c
2025-08-16 08:11:49 -07:00
Yuval Tassa bbb70d98a4 Add utility functions for mapping between sparse matrix patterns.
PiperOrigin-RevId: 795543910
Change-Id: I92be3afc3cd90020027737fffdba18c45e25f825
2025-08-15 11:22:35 -07:00
Google DeepMind 931036adda Always try to find the skybox texture, even if there are no materials in the MJCF. Fixes #2412
Before the fix this only occured if the MJCF contained 0 materials.

PiperOrigin-RevId: 795510952
Change-Id: I0a36c275e6006f80dc9a5ba6b9c6040ce21187c9
2025-08-15 09:53:37 -07:00
Yuval Tassa b566ef2883 Ignore geoms with tiny mass in inertiafromgeom computation. Fixes #2754
PiperOrigin-RevId: 795475978
Change-Id: I02b5db9e2ac7ec556cb0a0ec6dbe4214ba9128d7
2025-08-15 07:57:02 -07:00
Yuval Tassa 977f94e9df Delete sparsity structures from mjData, use the ones in mjModel
PiperOrigin-RevId: 795067950
Change-Id: If4f52e40ac49f7c6986b33ef9c8b534199dfd21a
2025-08-14 09:13:02 -07:00
Yuval Tassa 7eb13777f8 Put sparsity structures in mjModel, don't use them yet.
PiperOrigin-RevId: 795032051
Change-Id: I75c69e881980ff9c308acf00bb3a65f4b2ef12f5
2025-08-14 07:37:42 -07:00
Yuval Tassa f077fd00a9 Compute sparse matrix sizes before making the mjModel in the compiler.
PiperOrigin-RevId: 794998215
Change-Id: Ib7d0a2479b18cc8b3168c0656d3c4be0eff43a0f
2025-08-14 05:51:17 -07:00
Taylor Howell 0ba31e2c1f MJX safe division. Fixes #2776, #2568, #2657.
PiperOrigin-RevId: 794997676
Change-Id: I3100af7c1987a8435b29cc68c4e5c624dc573986
2025-08-14 05:49:12 -07:00
Alessio Quaglino 07e7417d26 Add prefix to asset paths when appending specs.
PiperOrigin-RevId: 794966246
Change-Id: I4825a11cc3234e6f403340dd997742cea0e2183b
2025-08-14 03:48:56 -07:00
Baruch Tabanpour 1763fa537a Add ten_length as MJX public field and warp tendon function call to MJX.
PiperOrigin-RevId: 794869371
Change-Id: I733da169b0092e3165478324697d7aa3569eca8b
2025-08-13 21:54:18 -07:00
Google DeepMind d3ff929bc6 Add ten_length as MJX public field and warp tendon function call to MJX.
PiperOrigin-RevId: 794813523
Change-Id: Ic5684788eca5a3f4fd86193ec5d035d40b3aad35
2025-08-13 18:09:22 -07:00
Baruch Tabanpour d7e925bd8a Add ten_length as MJX public field and warp tendon function call to MJX.
PiperOrigin-RevId: 794801198
Change-Id: I970ce665339c75910a767a1b24d8ac9c2bd68b1d
2025-08-13 17:27:16 -07:00
Baruch Tabanpour 1a7ec97b07 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 794774483
Change-Id: I2d8d623bbdfe9f28d4ab96bfc3c9128caa9fe86c
2025-08-13 16:08:03 -07:00
Alessio Quaglino eff4dda189 Suffix asset names when attaching specs.
PiperOrigin-RevId: 794717786
Change-Id: I02abe06ca3c43138e91e61f4acf87a26b3faf7fc
2025-08-13 13:43:16 -07:00
Alessio Quaglino dcdf0a9c5c Use mj_rayMesh for computing an inexact SDF for mesh-SDF collisions.
PiperOrigin-RevId: 794576123
Change-Id: I3c688056a5ed617a0787ccf1f4aa683f9409040f
2025-08-13 07:50:06 -07:00
Alessio Quaglino cc52d0242b Do not strip the path when compiling an mjSpec.
The path has already been stripped while parsing. This will enable prefixes that contain a `/` while attaching.

Also use `spec.meshdir` for asset paths in `spec.to_zip()`.

PiperOrigin-RevId: 794573523
Change-Id: Ic36bb641c3d72848399006cf718afd8542e91ed4
2025-08-13 07:43:25 -07:00
Baruch Tabanpour 6a9e68a542 Update MJX-W testspeed.
PiperOrigin-RevId: 794549657
Change-Id: I0ea12274da77704be30301d33228066bb8952fef
2025-08-13 06:24:19 -07:00
Baruch Tabanpour da9037e2b0 Fix bug in MJX contact sensor.
PiperOrigin-RevId: 794011199
Change-Id: I709a8bd9d07bec980aa60abd0346d946b037cbbd
2025-08-12 02:24:14 -07:00
Taylor Howell 0a02e7b722 Fix MJX test_sensor_contact.
PiperOrigin-RevId: 793598137
Change-Id: I543e93d3f998e5932342de80d816c30d74a0deaa
2025-08-11 05:04:13 -07:00
Yuval Tassa 84ba12e7b3 Clean up and standardize mj_printFormattedData
PiperOrigin-RevId: 793087071
Change-Id: I99d45ccf6591af02ee26e7f800bfbcc872336eb1
2025-08-09 14:03:13 -07:00
Alessio Quaglino ca4ca173ab Fix oct_distance return value.
PiperOrigin-RevId: 792924045
Change-Id: I42b8d0adaae7282d5c4e787fd1c85162720e977b
2025-08-09 00:33:38 -07:00
Rishi Krishnan ed3ff15870 Update MuJoCo's version number following the 3.3.5 release.
PiperOrigin-RevId: 792806341
Change-Id: Ic68ecceacc48ddbd6b0c741ae8f0791551e1b4dd
2025-08-08 16:45:12 -07:00
Rishi Krishnan 3152458a6b Update Mujoco Deps in preperation for the 3.3.5 release
PiperOrigin-RevId: 792755404
Change-Id: I9776bb5e5bf2a891e0fa0fbf486875727e1d13b4
2025-08-08 14:07:00 -07:00
Yuval Tassa 249b0cd87d Improve field order and comments in mjdata.h
PiperOrigin-RevId: 792642328
Change-Id: I59330e228a111edec9e86d93d5cdf646b0fab00e
2025-08-08 08:52:35 -07:00
Kyle Bayes 50fa598d93 Update x_norm in tetrahedron case in GJK.
This check is never called due to the fallback to gjkIntersection, however it's needed for debugging when disabling the fallback.

PiperOrigin-RevId: 792623394
Change-Id: I7178d9afae697bd22984688e89fd1865d3c6a37f
2025-08-08 07:52:00 -07:00
Yuval Tassa 19781b60a1 Fix a gcc-related compilation error.
PiperOrigin-RevId: 792592986
Change-Id: I6bd49d3c739a58f9b611fe24594bd3f11e757c5b
2025-08-08 06:00:17 -07:00
Yuval Tassa 8b5213c557 Cleanup: extract local functions in compiler for setting datatype and needstage
PiperOrigin-RevId: 792566070
Change-Id: I22d397758f5e8b35899c9461543989e352bd2b96
2025-08-08 04:11:14 -07:00
Yuval Tassa 3c6e4f1ece Clean up engine_core_smooth.c
PiperOrigin-RevId: 792564094
Change-Id: I47b3f1953db5402acc49dac373a039c9c0bf1ad9
2025-08-08 04:05:13 -07:00
Alessio Quaglino 92d77819fd Note the mjs parsing error in the changelog.
PiperOrigin-RevId: 792336077
Change-Id: I09cd2eb310c6e2bc74051419f6d69f5db1081cec
2025-08-07 15:40:23 -07:00
Baruch Tabanpour 45476483f6 Fix race condition in warp tests.
PiperOrigin-RevId: 792285453
Change-Id: Ic7616054025ca5c1211ef49e408ee283d8082796
2025-08-07 13:28:32 -07:00
Baruch Tabanpour 9b9b7030e7 Copy mjwarp viewer s.t. MJX users can debug models effectively.
PiperOrigin-RevId: 792258628
Change-Id: I3b2b5d10414934866d5c647f30fe88e9cd1a8756
2025-08-07 12:15:32 -07:00
Baruch Tabanpour 9e5fdd6983 Add warp graph capture and allow graph conditional.
PiperOrigin-RevId: 792208987
Change-Id: I139ff1db734b66734d588c3e7fe73426659cb484
2025-08-07 10:10:56 -07:00
Baruch Tabanpour 4533129103 Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 792201820
Change-Id: Ib7f4a1c28c8e48f91f00878c49e2aafdc169ba9e
2025-08-07 09:54:13 -07:00
Baruch Tabanpour bb4aeb44f1 Import NVIDIA/warp from GitHub.
#MIGRATION_3P_PY_WARP__DEFAULT

  - 23f1a48c1acbc1aa1f353423ec5f9182560c565d Upgrade to libmathdx 0.2.2 (GH-809) by Zach Corse <zcorse@nvidia.com>
  - a5b978abc2995c875498111d3cd4d307e621fe1f Fix GH-822 adj_tile_sum with shared tiles by Gilles Daviet <gdaviet@nvidia.com>
  - 4cd0fda5978c550665b54235b8f19cf87b844989 Disable parallel test execution for MJWarp by Eric Shi <ershi@nvidia.com>
  - 7408f297d03e7ed605f6d31fcfdaa288a9058ece Fix the OpenGL Renderer Box Colors (GH-810) by Christopher Crouzet <ccrouzet@nvidia.com>
  - 1f3f589ba6732a3272f9e1fe8cc2a292864df4cb Fix rendering of meshes with different scales (GH-828) by Eric Heiden <eheiden@nvidia.com>
  - a317a3d064f3518429e48858c5a99c7270934b5d Add a config file by Eric Shi <ershi@nvidia.com>
  - 61848a5f12b1b1b1275a7a57ae734318e1cbb7d6 Resolve GH-832 "Fix bsr_from_triplets prune_numerical_zer... by Gilles Daviet <gdaviet@nvidia.com>
  - f9fc3a1b9b3a69beee57766554ea10036ebe64b7 Extend the OpenGL example to show how to use ImGui (GH-833) by Tobias Widmer <twidmer@nvidia.com>
  - bd2ca117a003736d95ec9938764a93eea10086fb Add flag to enable support for mac os - it avoids OpenGL ... by Tobias Widmer <twidmer@nvidia.com>
  - 3c6388890e7a18c0164504b68b53ccb60859cbc0 Fix hashing of static expressions ([GH-830], partially re... by Eric Heiden <eheiden@nvidia.com>
  - 74cac74e57f4b9d90f77cbe0b2b01f1f5ac84c67 fix box-box collision by Zhenggehan <gehan.zheng@vanderbilt.edu>
  - 5d93b757c1febd64ff3e273e6c8225202391b5cc Remove a redundant assignment for query_b in box collision by Zhenggehan <gehan.zheng@vanderbilt.edu>
  - 486422dc20d5665d9622115eb34fc5a7b9ef831d Add missing changelog entries for GH-822 and GH-809 by Zach Corse <zcorse@nvidia.com>
  - 52be82e7bded3a496fbba04fb90e31b0c5512950 Add a missing changelog entry for GH-839 by Eric Shi <ershi@nvidia.com>
  - b266b6a1497dd910cb23cbc4f0c03035005da8a1 GitLab jobs now use the R570 runners by Eric Shi <ershi@nvidia.com>
  - 7368bf7d630c58ca9999f5284076cd5c0e9f2dc3 Fix potential issues in bitonic tile_sort ([GH-836]) by Kenny Vilella <kvilella@nvidia.com>
  - 31621ff99b90927e608f56c5165d8b6332ec5b2f Fix for wp.tile_min() when tile thread block includes emp... by Zach Corse <zcorse@nvidia.com>
  - 569b5a2b3672e0501958e6a3fbc6901df8800c49 Add more ImGui helper functions GH-844 by Tobias Widmer <twidmer@nvidia.com>
  - a5a746a14254ae8ef89197c6d1988e3d33013683 Arbitrary size blocks and tile-based computations in warp... by Gilles Daviet <gdaviet@nvidia.com>
  - 6ef9436700acb9f80cf7f3a6a34618a5e2da0a3d Fix `adj_div(scalar, vec/mat/quat)` by Christopher Crouzet <christopher@crouzet.pm>
  - 0044654bb97a9de8c75629e52fa04a04fa632c21 Fix miscellaneous issues with adjoints by Christopher Crouzet <christopher@crouzet.pm>
  - 42e374713557e3a1a85f23286ff1b02334eb15ea Fix the Possible Dead Loop in wp_balance_coloring (GH-816) by Anka Chen <ankac@nvidia.com>
  - b39954ece68e67c124e1ff856fd189cc366debb8 Graph-capturable linear solvers (GH-843) by Gilles Daviet <gdaviet@nvidia.com>
  - b2a9133d0125c2b973c8f0dbafaa31830e2af0ef Expose `array.ptr` in kernels (GH-819) by Gilles Daviet <gdaviet@nvidia.com>
  - 3fa6c9b19c9f4774bd3f61f102a0867136563804 Fix wrong version passed to cuDeviceGetUuid by Eric Shi <ershi@nvidia.com>
  - 195fd4e0ccb83ed7cfd74b716a6d33bfc9a35217 Add new publication: GeoWarp framework for geomechanics by Eric Shi <ershi@nvidia.com>
  - 514e8b5a8f6a80a5a6aa230d9d0f23e3f2e9aa9a Add edit page link on right sidebar by Eric Shi <ershi@nvidia.com>
  - 178e8430911b77b44bf1b0cd543f0304423c2ef2 Fix positioning of changelog entry of MR !1438 by Gilles Daviet <gdaviet@nvidia.com>
  - 907cbd4b572a937b8b1c9a5fbd4bc21976304596 Use latest clang for builds in CI/CD by Eric Shi <ershi@nvidia.com>
  - 649d206616735ec923d7a6bc1631bb03f4abcc6a Handle CUDA 12.8 + Thor combination by Eric Shi <ershi@nvidia.com>
  - 8775c618ec9b1a8efd91f18b48ef6acd15caad92 Allow arr = wp.array(dtype=MyStruct...) in kernels GH-853 by Tobias Widmer <twidmer@nvidia.com>
  - d3d0bdc67854c74045499253fa556369337925b8 Fix default PTX architecture selection to include only su... by Eric Shi <ershi@nvidia.com>
  - 0e2b1f9cd28db7fe366647b39a09e2f43ebc236b Fixed the Bug of Missing Cloth-body Contact in VBD Integr... by Anka Chen <ankac@nvidia.com>
  - 70479a95722e50ab6a32c477a238b801b0db5d4b warp.fem: leverage tiles to sum over quadrature points (G... by Gilles Daviet <gdaviet@nvidia.com>
  - 2446e4c06a1d6d50ab825f6991d402f7959745c2 Add Warp stuctured array NumPy interop examples to docs (... by Zach Corse <zcorse@nvidia.com>
  - bac82151b4cc46659f5278df9749cfd1d994ca61 Refactor some tests to reduce recompilation cost by Eric Shi <ershi@nvidia.com>
  - c0cc239b5fe457c8aedca636e7d2e3f32f060a62 Fix debug mode compilation (GH-856) by Alain Denzler <adenzler@nvidia.com>
  - 906495b742f583b5c5a524a23ffc7112b542286a Fix typo in wp.fem nodal field DG gradient by Gilles Daviet <gdaviet@nvidia.com>
  - 476765315edf7268274f8862af540a7ddb68ce4f Reenable parallel execution of mjwarp GitLab job by Eric Shi <ershi@nvidia.com>
  - 8f2bcfc503e82ad492dabc6cdbd9103495f0ff17 Disable Blackwell job by Eric Shi <ershi@nvidia.com>
  - 531e822b1939be95edb11c56db310c0ac4701e17 Support initializing fixed-size arrays in kernels by Christopher Crouzet <christopher@crouzet.pm>
  - 52f7f53f247302c666e73490e33228d0172e08b6 Support fixed-size arrays with structs as `dtype` by Christopher Crouzet <christopher@crouzet.pm>
  - af038bddb408acd76fe009fb0b548ec0da68b74b Fix keyword arguments not being reported by Christopher Crouzet <christopher@crouzet.pm>
  - 1bd4fac0637cd1eed3abc9af14699b5c9e05b35c JAX FFI graph capture using Warp (GH-848) by Lukasz Wawrzyniak <lwawrzyniak@nvidia.com>
  - ff63d5073ae453d04aa8f78dcf9ed90bf7d70e5b Split `assign_copy` tests by Christopher Crouzet <christopher@crouzet.pm>
  - 62daadda34f794bcb8c8ece4fe40c95224005b26 Add `wp.matrix_from_rows/cols()` to Python's API by Christopher Crouzet <christopher@crouzet.pm>
  - a19818854f716629028186a24815629cb5513145 Add support for negative indexing by Christopher Crouzet <christopher@crouzet.pm>
  - f440c5b15766943623870b8e887efe78bb9f9d62 Implement a slice object by Christopher Crouzet <christopher@crouzet.pm>
  - e26f23207acf09449deeeea7db2168d2123804cf Add support for slicing vec/quat/transform by Christopher Crouzet <christopher@crouzet.pm>
  - 28907cdfcae397d0e32b6f34d302d178677308e0 Add `wp.matrix_get/set_col()` to Python's API by Christopher Crouzet <christopher@crouzet.pm>
  - 303c0ac8b680f788700e3974aba161042fef449b Add support for slicing matrices by Christopher Crouzet <christopher@crouzet.pm>
  - bbc79c3dbcc9b37b00b9d61094c920e93515a2b1 Implement adjoints for slice indexing by Christopher Crouzet <christopher@crouzet.pm>
  - c1e872f74f886592490771fe37e410f7b3905701 Update the hash with the config for `assign_copy` by Christopher Crouzet <christopher@crouzet.pm>
  - b978cf94a87f66e90e418dda3c05d7c864b52849 Symmetrize operators by Christopher Crouzet <christopher@crouzet.pm>
  - fd71d280d7a9d390bd7b322519ade06be62ac875 Fix a documented return type by Christopher Crouzet <christopher@crouzet.pm>
  - 57fd611636f804cdaec3c8b69a0271f7717b770d Add a doc section for indexing/slicing by Christopher Crouzet <christopher@crouzet.pm>
  - 6aa03089a96ff18792fbc2a3cbf50e205cea7783 Reduce the code size by Christopher Crouzet <christopher@crouzet.pm>
  - 6c6c6e738972b25e69d171f6801b717ca921664b Fix wrong macros being used by Christopher Crouzet <christopher@crouzet.pm>
  - 43be725152909f6434f9bf6aa0cdcf5e77bcd8c8 Add post-loop checks by Christopher Crouzet <christopher@crouzet.pm>
  - 16a6a575ce6bee368b056a70c9d5bec8c6f1a409 Work around GH-637 in wp.fem integrands by Gilles Daviet <gdaviet@nvidia.com>
  - 637bafffb90d495b222bf1c79d7173f60aa1871c Resolve function return types for wp.map() and wp.tile_ma... by Zach Corse <zcorse@nvidia.com>
  - 18849b08e0809ccb357d22a6601139b9c3277cd2 Publish macos dev wheel to artifactory by Eric Shi <ershi@nvidia.com>
  - de7481a377d0380e13208a7261996daba69fd9ba Tentative fix for bsr_mm asv regression from c5fdbc20 by Gilles Daviet <gdaviet@nvidia.com>
  - eba4be3cf12ac3accdd0d48a265d0f8766ed8c99 Reenable Blackwell GitLab job by Eric Shi <ershi@nvidia.com>
  - ee012fe62c8cb47b498ac430652c234368d41723 GH-870 Detect and warn about long file paths in Windows by Gilles Daviet <gdaviet@nvidia.com>
  - fe5785431d4423a1faef64f2c810fa5ac18265d1 Reduce error messages when CUDA driver is not found by Eric Shi <ershi@nvidia.com>
  - e5904c3d78e9e77174ab84527575a06c3c9d9265 Clarify Python vs. Warp scope execution of @wp.func funct... by Eric Shi <ershi@nvidia.com>
  - b4ca2187d15f8b2c4220dc89b953670ab1b99913 Compile time improvements by Eric Shi <ershi@nvidia.com>
  - 3a07ca72d155ff8666fc68a7c51a8690d8fef19e Add a documentation section about indexed arrays by Christopher Crouzet <christopher@crouzet.pm>
  - 248fd07b67395323098231e64169e3d1c8216d89 Namespace the remaining warp-clang symbols by Christopher Crouzet <christopher@crouzet.pm>
  - c6af3501853d30bd059f3ac1c9c9a9057f72247b Fix adding superfluous inactive nodes to tet function spa... by Gilles Daviet <gdaviet@nvidia.com>
  - 62ac48861731a1800ad46548dc254d94362bdd18 Use usd-core==25.5.1 for Windows jobs to avoid failures by Eric Shi <ershi@nvidia.com>
  - 5d1c2ba11cb6a11c4e89b4f47980f3063e3e63fc Add support for `IntEnum`, `IntFlag` inside Warp kernels ... by Eric Heiden <eheiden@nvidia.com>
  - a4aba20a00e3d267d178a49b2ee145b82966f166 Update Warp version to 1.8.1 by Eric Shi <ershi@nvidia.com>

PiperOrigin-RevId: 792191632
Change-Id: I227d605677c925ca5e7fa64948ef884ef25fa5ad
2025-08-07 09:27:46 -07:00
Alessio Quaglino eb1da7c43d Compute the interpolation coefficients per vertex rather than per node.
PiperOrigin-RevId: 792124681
Change-Id: Ib0e18d0b59f09c7e3bdb2ef9940a9b7327b92cd3
2025-08-07 06:03:11 -07:00
Alessio Quaglino 781242ae95 Avoid duplicated vertices in the SDF octree.
Before: nnode: 42777, nvert: 342216
After: nnode: 42777, nvert: 77588
PiperOrigin-RevId: 792115571
Change-Id: I17913ed3d22f22a0370dc4cbd2b833a0f5983cda
2025-08-07 05:27:01 -07:00
Alessio Quaglino 840108cf7c Refactor octree in preparation for continuous interpolation.
PiperOrigin-RevId: 792092644
Change-Id: I096ca0989210a00ae0b4556498d96212755d23c7
2025-08-07 04:06:03 -07:00
Saran Tunyasuvunakool 4e67fe79f3 Fix use of DYLD_FALLBACK_LIBRARY_PATH in mjpython.
According to `man dyld`, the default value for DYLD_FALLBACK_LIBRARY_PATH changed in late 2023. In newer binaries, if DYLD_FALLBACK_LIBRARY_PATH is not set, dyld will use /usr/local/lib and /usr/lib as fallback. If it is set, these locations will not be used as lookup paths unless explicitly added.

Fixes #2781

PiperOrigin-RevId: 791897707
Change-Id: I00d7e80bfbd5e5d7dbf2f601eaad4d9b0e1030f3
2025-08-06 16:53:25 -07:00
Baruch Tabanpour fb5792b420 Add back warp as an optional dep.
PiperOrigin-RevId: 791896458
Change-Id: I614d4d766d2c2d1ad79d5c3db9bbcbf5778f2183
2025-08-06 16:50:08 -07:00
Baruch Tabanpour 9b149f334f Add warp-lang requirements back.
PiperOrigin-RevId: 791872106
Change-Id: I74bc5069f0f356538b6ce4dde4bac0a47e1cf5f5
2025-08-06 15:41:38 -07:00
Alessio Quaglino 132f90b17f Validate mjs_setFrame dest parameter and raise an error if null.
PiperOrigin-RevId: 791742890
Change-Id: I926e6dfb08aa66fac2816b805e156074c37dce99
2025-08-06 10:19:01 -07:00
Saran Tunyasuvunakool 21a7ac7dd9 Change the license field in pyproject.toml to SPDX string.
According to the deprecation warning, support for the old way of declaring the license will be removed from setuptools on 2026-Feb-18.

PiperOrigin-RevId: 791716539
Change-Id: Iaf9ec55f9425380b017bd7ea370cd481ed01aa8f
2025-08-06 09:11:14 -07:00
Saran Tunyasuvunakool 2e60d05887 Update Kokoro script to use CUDA 12.8 and manylinux_2_28.
PiperOrigin-RevId: 791714944
Change-Id: I66850eda0395d913c2c706dbc79625a2f682c380
2025-08-06 09:06:53 -07:00
Saran Tunyasuvunakool e45150747a Import qhull/qhull from GitHub.
#MIGRATION_3P_QHULL__DEFAULT

  - 49bbade5bc43b2267334bb30926f838e7fa7a903 Remove tools from CMake exported targets (#152) by StefanBruens <stefan.bruens@rwth-aachen.de>
  - 62ccc56af071eaa478bef6ed41fd7a55d3bb2d80 Cmake improvements (#158) by Cristian Le <github@lecris.me>

PiperOrigin-RevId: 791673333
Change-Id: Ib231db3cd58988faf4d5288a2ddf761a106080c8
2025-08-06 07:00:26 -07:00
Alessio Quaglino 49f45a93c8 Guard against division by zero when calculating pressure in tactile sensor.
PiperOrigin-RevId: 791641958
Change-Id: I457bc7f55c0b03e14b9c3944935866ede14f1d51
2025-08-06 05:07:12 -07:00
Taylor Howell 3821ff1dcf Fix MJX contact sensor.
PiperOrigin-RevId: 791317188
Change-Id: I97e2020f99742d9bb3cb798d4b5354b51fdda2e2
2025-08-05 12:12:12 -07:00
Yuval Tassa 784c7a419b Improve builtin hemisphere docs
PiperOrigin-RevId: 791271829
Change-Id: I391215b5388f4e9e2a17198dbcdbd0c605fda4b4
2025-08-05 10:25:45 -07:00
Yuval Tassa fde479736e Finalize built-in mesh example model and documentation
PiperOrigin-RevId: 791227350
Change-Id: Ibdcdb8a4ee5b3f78c9ae93e1db2a9a2f9d55a80c
2025-08-05 08:32:51 -07:00
Yuval Tassa 2f4375dda3 Add font_scale option to Renderer
PiperOrigin-RevId: 791213051
Change-Id: I22efd8d09637edbd9a4861132dfff3b46e9340bc
2025-08-05 07:50:20 -07:00
Yuval Tassa 705ec6d7fb Adds built-in superellipsoid mesh.
PiperOrigin-RevId: 791196831
Change-Id: I1d864f6e620870f016377a4d9e2e26d1a23fd77e
2025-08-05 07:02:52 -07:00
Sam Haves e74cee652f Add README to mjcPhysics.
PiperOrigin-RevId: 791183563
Change-Id: I4383dcab12128a745e435ac7f2cea52cccc4ce60
2025-08-05 06:18:37 -07:00
Yuval Tassa a5d4d1000e Add built-in supertoroid mesh.
PiperOrigin-RevId: 791180080
Change-Id: I3a70f50ff4a52a1bd4b88fc30334a574895145b4
2025-08-05 06:06:43 -07:00
Kyle Bayes e543ba95c5 Fix comments in meshNormals.
PiperOrigin-RevId: 791169316
Change-Id: I540f06a56862774ae0feb666ab38762853cb1c36
2025-08-05 05:27:41 -07:00
Yuval Tassa 996f0040fd Add built-in sphere mesh.
PiperOrigin-RevId: 791162850
Change-Id: I573a414727e79f1a495e0f2282b2faff48ab3443
2025-08-05 05:05:05 -07:00
Yuval Tassa 5220767457 Add built-in hemisphere mesh.
PiperOrigin-RevId: 791148546
Change-Id: Ic9ff0c9b0f5fa4fd22d5f7f848f150cf74d378ba
2025-08-05 04:16:24 -07:00
Yuval Tassa a5a6379f83 Add built-in cone mesh type.
Also delete `prism` type since it is subsumed by cone.

PiperOrigin-RevId: 790992343
Change-Id: I7a9c6f2a4377489173acd64b23086c748d2cee8e
2025-08-04 19:35:32 -07:00
Baruch Tabanpour 4a91c34239 Modify warp-lang deps.
PiperOrigin-RevId: 790925317
Change-Id: I1db6c1820270722afa6a3475a1088d1553571295
2025-08-04 16:00:24 -07:00
Baruch Tabanpour 5e6bde07ab Patch fix to pyproject.toml for internal CI.
PiperOrigin-RevId: 790786985
Change-Id: I3f70896857296519ff6984c1b85056e671794808
2025-08-04 09:47:22 -07:00
Yuval Tassa 7b9f5bdae7 Fix bug in raycast to hfield. Fixes #2765
PiperOrigin-RevId: 790784429
Change-Id: Ib2319722796ed510afed960bbf5cebc86cf185a9
2025-08-04 09:40:59 -07:00
Kyle Bayes f2a2afeb03 Fix address bug in meshEdgeNormals in doing edge multiccd with meshes.
PiperOrigin-RevId: 790731924
Change-Id: Ia475b1f01731518166f229c25ebffd1fbf7c7939
2025-08-04 07:03:14 -07:00
Alessio Quaglino 7baaa39846 Add SDF geom to test/testdata/model.xml.
Also, when a mesh has both an octree and a bvh, render only the octree.

PiperOrigin-RevId: 790680831
Change-Id: Iaf3896933f6728af4db1eaa83ff5b06558ab0d19
2025-08-04 03:53:51 -07:00
Alessio Quaglino 100b1a06fd Decrease opacity of taxels with zero value.
This prevents the taxels from being occluded by the convex hull for meshes that do not provide face connectivity.

PiperOrigin-RevId: 790420616
Change-Id: I543fd7b52e4625d921b6b5b5b77b4720020df42a
2025-08-03 08:36:39 -07:00
Alessio Quaglino 80befd64ae Do not cull mjGEOM_TRIANGLE.
PiperOrigin-RevId: 789723631
Change-Id: I8a5aaa78a9fe63458c07b823c7550846c14413b1
2025-08-01 05:28:30 -07:00
Sam Haves 3d537c85ef Fix mjcPhysics typo in USD docs.
PiperOrigin-RevId: 789385654
Change-Id: Ib15450e81258e3d202d8123c0c43f8421ebefed6
2025-07-31 10:23:53 -07:00
Baruch Tabanpour 7ea92c65ec Fix to github CI.
PiperOrigin-RevId: 789380763
Change-Id: I8e2679a70e8bf443e373f57a0a78ed68b70e60a6
2025-07-31 10:10:26 -07:00
Baruch Tabanpour 47bc16a37c Add mujoco_warp as an implementation in mjx.
PiperOrigin-RevId: 789366860
Change-Id: I84b49e744552092434df49d855f1052b04291b87
2025-07-31 09:33:35 -07:00
Sam Haves 700da7c5bd Add initial documentation for experimental OpenUSD support in MuJoCo.
PiperOrigin-RevId: 789365870
Change-Id: I19cce03ec2ffc28cdf4252bfd02c8b5163bb5ba2
2025-07-31 09:30:50 -07:00
Yuval Tassa 32c7d3f085 Tag nullable arguments in main header. Fixes #309
Nullable arguments will be added to the `introspect` datastructures in a future change.

PiperOrigin-RevId: 789350522
Change-Id: I0bfd12fab5121f94b937264570f907593b63cf64
2025-07-31 08:39:16 -07:00
Matija Kecman ee63b82e1c Fix the format string when printing uintptr_t
PiperOrigin-RevId: 789333383
Change-Id: I32b190ffa6579a93970650df58865083aa0a18ab
2025-07-31 07:50:45 -07:00
Matija Kecman 23fa7c00d5 Remove usage of size_t types in mjModel, use mjtSize (uint64_t) instead to improve portabilty of MJB files to WASM.
PiperOrigin-RevId: 789321991
Change-Id: Ic25fab876c347fc75f5ca24cad09e8fd972f035f
2025-07-31 07:08:33 -07:00
Sam Haves 4c288c19ac Remove physics schema authoring toggle from MJCF SdfFileFormat plugin.
PiperOrigin-RevId: 789321573
Change-Id: Ib29bb426f8598a58f7b34c048b154fa8ada589ef
2025-07-31 07:07:18 -07:00
Alessio Quaglino 9f64338b37 Clarify principal point description in documentation.
PiperOrigin-RevId: 789314970
Change-Id: I2b5beca1599d40acb00406aee7dbcea928da4433
2025-07-31 06:40:54 -07:00
Sam Haves b5368a3385 Add displayColor authoring to site geometry when converting MJCF to USD.
PiperOrigin-RevId: 789311878
Change-Id: I70027cd5d8d02f4ee26043f3b9fb03311e38984b
2025-07-31 06:28:42 -07:00
Bogdan Graur 82cf27992d Initialize variables in copyM2Sparse
PiperOrigin-RevId: 788875024
Change-Id: I87068a3878e0b6bc5227bb61e84c07e75e448eea
2025-07-30 06:16:17 -07:00
Alessio Quaglino 51babec9c5 Move tactile sensor to the engine.
PiperOrigin-RevId: 788863133
Change-Id: I3172ebb7641fa8146469da25cba7db794760e7b1
2025-07-30 05:27:44 -07:00
Alessio Quaglino 89f4789085 Add mjs_makeMesh to create a builtin mesh.
PiperOrigin-RevId: 788538127
Change-Id: I999733399a1a0da07b0f915f34d31364ab8b3b52
2025-07-29 11:31:18 -07:00
Yuval Tassa 46dc67b7eb Add function mjs_sensorDim to user API.
Note: change to (unreleased) contact sensor mjSpec API
PiperOrigin-RevId: 788507423
Change-Id: Ie639afb7ed01dc3f7bab43a3e812e8e0b0c67d07
2025-07-29 10:20:27 -07:00
Yuval Tassa a771fc6c09 Increase mjNSENS to 3
PiperOrigin-RevId: 788468705
Change-Id: Id22f131bebb6accc9a29c9aa285efa75fa8b2c16
2025-07-29 08:38:13 -07:00
Alessio Quaglino 4575089f48 Prevent ray casting from stopping at the SDF bounding box.
The SDF value of the closest point on the bounding box is added to the distance from the bounding box when the query point is outside of it.

PiperOrigin-RevId: 788377943
Change-Id: Id8e489a1d112918c484f5615223d557f2d14b822
2025-07-29 03:10:02 -07:00
Sam Haves a04e0385e4 Add USD content type support in MJCF.
PiperOrigin-RevId: 788075561
Change-Id: If37cc254cab0411454de7663e0b3ff9f2b263281
2025-07-28 10:53:49 -07:00
Vidur d13329ed1d adding build interfaces to the linked directories 2025-07-23 12:53:38 -05:00
Vidur Vij af87c6d7a0 Pull request changes 2025-07-18 12:39:07 -05:00
Vidur b2300684d8 Remove unused variable definition 2025-07-01 18:36:11 -05:00
Vidur 4c7c68e518 add glfw3 install back to cmake 2025-07-01 18:17:21 -05:00
Vidur ef8da59cb3 Merge branch 'original/main' into vidur/remove-installing-glfw3-headers 2025-07-01 16:27:15 -05:00
Vidur 641d95313a Remove installing glfw3 headers 2025-07-01 16:25:07 -05:00
Vidur 35fdc279fe Merge main branch from mujoco 2025-06-03 13:00:27 -05:00
vidurvij-apptronik bf3843210f Merge branch 'google-deepmind:main' into vidur/3.3.0-2 2025-03-24 11:19:07 -05:00
vidurvij-apptronik 9dd05d3b65 Update SimulateDependencies.cmake 2024-10-28 09:25:54 -05:00
vidurvij-apptronik 832229a846 Update CMakeLists.txt 2024-10-28 09:25:38 -05:00
vidurvij-apptronik f6e4666624 Updating simulation cmake to install headers and so file if requested using a flag. 2024-10-23 14:59:33 -05:00
1163 changed files with 362086 additions and 48085 deletions
+361 -237
View File
@@ -5,11 +5,28 @@
#
# We set CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF here to reduce build time.
# It is highly recommended that this is set to ON for production builds.
#
# Build speed notes:
# * The compiler matrix lives in build_matrix.json. Pull requests build the
# representative "core" subset; pushes to main run the full compiler sweep.
# (See generate_matrix() in build_steps.sh.)
# * Studio/Filament and WASM are NOT built in the main matrix - they are covered
# by the dedicated `studio` and `wasm` jobs below. WASM in particular is built
# with emcc, which ignores the host compiler, so building it per-compiler added
# no coverage.
# * ccache is used to wrap the compiler. PR branches fall back to main's cache, so
# the expensive (and pinned) Filament build is restored rather than recompiled.
# TODO(matijak): Consider switching Windows to Ninja builds only, this configures slightly faster
# and brings Windows in line with other OSes. Also we wouldn't need to specify the --config option
# in the build step because Ninja doesn't support multiple configurations (unlike MSBuild).
name: build
on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/README.md"
@@ -18,277 +35,180 @@ on:
- "doc/**"
- "**/README.md"
# Limit the default GITHUB_TOKEN to read-only. No job here writes via the token:
# checkout reads the repo; ccache/cache and upload-artifact use their own backend
# tokens; the chat notification uses a secret webhook.
permissions:
contents: read
jobs:
# Compute the build matrix based on the event: PRs get the "core" representative
# compiler set, pushes to main get the full sweep.
setup:
name: "setup (compute matrix)"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- uses: actions/checkout@v6
- name: Generate build matrix
id: generate
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
run: bash ./.github/workflows/build_steps.sh generate_matrix
mujoco:
needs: setup
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
label: "ubuntu-24.04-gcc-14"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-14
-DCMAKE_CXX_COMPILER:STRING=g++-14
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-24.04
label: "ubuntu-24.04-gcc-13"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-13
-DCMAKE_CXX_COMPILER:STRING=g++-13
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-gcc-12"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-12
-DCMAKE_CXX_COMPILER:STRING=g++-12
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-gcc-11"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-11
-DCMAKE_CXX_COMPILER:STRING=g++-11
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-gcc-10"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-10
-DCMAKE_CXX_COMPILER:STRING=g++-10
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-24.04
label: "ubuntu-24.04-clang-18"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-24.04
label: "ubuntu-24.04-clang-17"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-17
-DCMAKE_CXX_COMPILER:STRING=clang++-17
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-24.04
label: "ubuntu-24.04-clang-16"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-16
-DCMAKE_CXX_COMPILER:STRING=clang++-16
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-clang-15"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-15
-DCMAKE_CXX_COMPILER:STRING=clang++-15
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-clang-14"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-14
-DCMAKE_CXX_COMPILER:STRING=clang++-14
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
label: "ubuntu-22.04-clang-13"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-13
-DCMAKE_CXX_COMPILER:STRING=clang++-13
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: macos-15
label: "macos-15-arm64"
cmake_args: >-
-G Ninja
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: macos-15-large
label: "macos-15-x86_64"
cmake_args: >-
-G Ninja
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: windows-2025
label: "windows-2025"
cmake_args: >-
-DCMAKE_SYSTEM_VERSION="10.0.26100.0"
cmake_build_args: "-- -m"
tmpdir: "C:/Temp"
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: "${{ matrix.label }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: >
sudo apt-get update && sudo apt-get install
libgl1-mesa-dev
libxinerama-dev
libxcursor-dev
libxrandr-dev
libxi-dev
ninja-build
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Prepare macOS
if: ${{ runner.os == 'macOS' }}
run: brew install ninja
- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
with:
python-version: "3.11"
# uv makes the dependency install much faster, with a cross-run cache. POSIX
# only: Windows stays on pip (it is not a Python-setup bottleneck, and this
# keeps the venv activate fixup path untouched there).
- name: Install uv
if: ${{ runner.os != 'Windows' }}
uses: astral-sh/setup-uv@v8.2.0
with:
enable-cache: true
cache-dependency-glob: "python/build_requirements*.txt"
- name: Prepare Python
shell: bash
run: |
repo="${PWD}"
cd ${{ matrix.tmpdir }}
python -m venv venv
if [[ $RUNNER_OS == "Windows" ]]; then
mkdir venv/bin
fixpath="$(s="$(cat venv/Scripts/activate | grep VIRTUAL_ENV=)"; echo "${s:13:-1}")"
sed -i "s#$(printf "%q" "${fixpath}")#$(cygpath "${fixpath}")#g" venv/Scripts/activate
ln -s ../Scripts/activate venv/bin/activate
fi
source venv/bin/activate
python -m pip install --upgrade --require-hashes -r "${repo}/python/build_requirements.txt"
python -m pip install --upgrade --require-hashes -r "${repo}/python/build_requirements_usd.txt"
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ./.github/workflows/build_steps.sh prepare_python
# ccache dramatically speeds up warm rebuilds. The key is the matrix label so
# each compiler gets its own cache; the action's restore-keys let PR branches
# fall back to main's cache. ccache on Windows/MSVC is finicky and Windows
# isn't the bottleneck, so we skip it there.
- name: Setup ccache
if: ${{ runner.os != 'Windows' }}
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ matrix.label }}
max-size: "1.5G"
- name: Configure MuJoCo
run: >
mkdir build &&
cd build &&
cmake ..
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
-DCMAKE_INSTALL_PREFIX:STRING=${{ matrix.tmpdir }}/mujoco_install
-DMUJOCO_BUILD_EXAMPLES:BOOL=OFF
${{ matrix.cmake_args }}
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ./.github/workflows/build_steps.sh configure_mujoco
- name: Upload CMake Configure Log
if: always()
uses: actions/upload-artifact@v7
with:
name: cmake-configure-log-${{ matrix.label }}
path: build/CMakeFiles/CMakeConfigureLog.yaml
retention-days: 5
- name: Build MuJoCo
working-directory: build
run: cmake --build . --config=Release ${{ matrix.cmake_build_args }}
- name: Copy in the correct VC runtime DLLs (workaround for actions/runner-images#10004)
if: ${{ runner.os == 'Windows' }}
working-directory: build
shell: powershell
run: |
Copy-Item (Join-Path `
((Get-ChildItem -Directory `
-Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Redist\MSVC\14.*" |
Sort -Descending | Select-Object -First 1).FullName
) 'x64\Microsoft.VC143.CRT\*.dll') "bin\Release"
env:
CMAKE_BUILD_ARGS: ${{ matrix.cmake_build_args }}
run: bash ../.github/workflows/build_steps.sh build_mujoco
- name: Test MuJoCo
working-directory: build
run: ctest -C Release --output-on-failure .
run: bash ../.github/workflows/build_steps.sh test_mujoco
- name: Install MuJoCo
working-directory: build
run: cmake --install .
run: bash ../.github/workflows/build_steps.sh install_mujoco
- name: Copy plugins (POSIX)
if: ${{ runner.os != 'Windows' }}
working-directory: build
run: mkdir -p ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp lib/libactuator.* ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp lib/libelasticity.* ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp lib/libsensor.* ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp lib/libsdf_plugin.* ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh copy_plugins_posix
- name: Copy plugins (Windows)
if: ${{ runner.os == 'Windows' }}
working-directory: build
run: mkdir -p ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp bin/Release/actuator.dll ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp bin/Release/elasticity.dll ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin &&
cp bin/Release/sensor.dll ${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh copy_plugins_window
- name: Configure samples
working-directory: sample
run: >
mkdir build &&
cd build &&
cmake ..
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
${{ matrix.cmake_args }}
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../.github/workflows/build_steps.sh configure_samples
- name: Build samples
working-directory: sample/build
run: cmake --build . --config=Release ${{ matrix.cmake_build_args }}
- name: Configure simulate
working-directory: simulate
run: >
mkdir build &&
cd build &&
cmake ..
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
${{ matrix.cmake_args }}
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../.github/workflows/build_steps.sh configure_simulate
- name: Build simulate
working-directory: simulate/build
run: cmake --build . --config=Release ${{ matrix.cmake_build_args }}
env:
CMAKE_BUILD_ARGS: ${{ matrix.cmake_build_args }}
run: bash ../../.github/workflows/build_steps.sh build_simulate
- name: Make Python sdist
shell: bash
working-directory: python
run: >
source ${{ matrix.tmpdir }}/venv/bin/activate &&
./make_sdist.sh
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh make_python_sdist
- name: Build Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: python/dist
run: >
source ${{ matrix.tmpdir }}/venv/bin/activate &&
MUJOCO_PATH="${{ matrix.tmpdir }}/mujoco_install"
MUJOCO_PLUGIN_PATH="${{ matrix.tmpdir }}/mujoco_install/mujoco_plugin"
MUJOCO_CMAKE_ARGS="-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF ${{ matrix.cmake_args }}"
pip wheel -v --no-deps mujoco-*.tar.gz
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../../.github/workflows/build_steps.sh build_python_bindings
- name: Install Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: python/dist
run: >
source ${{ matrix.tmpdir }}/venv/bin/activate &&
pip install --no-index mujoco-*.whl
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../../.github/workflows/build_steps.sh install_python_bindings
- name: Test Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
env:
MUJOCO_GL: disable
run: >
source ${{ matrix.tmpdir }}/venv/bin/activate &&
pytest -v --pyargs mujoco
- name: Package MJX
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: mjx
run:
source ${{ matrix.tmpdir }}/venv/bin/activate &&
python -m build .
- name: Install MJX
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: mjx
run:
source ${{ matrix.tmpdir }}/venv/bin/activate &&
pip install --require-hashes -r requirements.txt &&
pip install --no-index dist/mujoco_mjx-*.whl
- name: Test MJX
if: ${{ runner.os != 'Windows' }}
shell: bash
run:
source ${{ matrix.tmpdir }}/venv/bin/activate &&
pytest -n auto -v -k 'not IntegrationTest' --pyargs mujoco.mjx
TMPDIR: ${{ matrix.tmpdir }}
run: bash ./.github/workflows/build_steps.sh test_python_bindings
# MJX (mujoco.mjx) is covered by the dedicated `mjx` job below; it is
# compiler-independent so it does not need to run in every matrix job.
- name: Notify team chat
shell: bash
env:
@@ -298,26 +218,230 @@ jobs:
CHATMSG_AUTHOR_EMAIL: ${{ github.event.head_commit.author.email }}
CHATMSG_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
CHATMSG_JOB_ID: ${{ matrix.label }}
if: ${{ failure() && github.event_name == 'push' && env.GCHAT_API_URL != '' }}
run: |
CHATMSG="$(cat <<-'EOF' | python3
import json
import os
env = lambda x: os.getenv(x, '')
data = dict(
result=env('JOB_URL'),
job=env('CHATMSG_JOB_ID'),
commit=env('GITHUB_SHA')[:6],
name=env('CHATMSG_AUTHOR_NAME').replace('```', ''),
email=env('CHATMSG_AUTHOR_EMAIL'),
msg=env('CHATMSG_COMMIT_MESSAGE').replace('```', '')
)
text = '<{result}|*FAILURE*>: job `{job}` commit `{commit}`\n```Author: {name} <{email}>\n\n{msg}```'.format(**data)
print(json.dumps({'text' : text}))
EOF
)" &&
if: failure() && github.ref_name == 'main' && github.event_name == 'push' && env.GCHAT_API_URL != ''
run: bash ./.github/workflows/build_steps.sh notify_team_chat
curl "$GCHAT_API_URL&threadKey=$GITHUB_SHA&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" \
-X POST \
-H "Content-Type: application/json" \
--data-raw "${CHATMSG}"
# This job quickly determines if MuJoCo Studio is broken. It is the only place
# Filament is compiled in CI, so ccache here is what keeps the long pole short.
studio:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
label: "ubuntu-24.04-clang-18-studio"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
# gcc canary: Filament is compiler-dependent and historically finicky on
# gcc, so keep one gcc Studio build even though the matrix no longer does.
- os: ubuntu-24.04
label: "ubuntu-24.04-gcc-14-studio"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-14
-DCMAKE_CXX_COMPILER:STRING=g++-14
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
- os: windows-2025
label: "windows-2025-ninja-studio"
cmake_args: >-
-G Ninja
-DCMAKE_SYSTEM_VERSION=10.0.26100.0
- os: macos-15
label: "macos-15-arm64-studio"
cmake_args: >-
-G Ninja
-DCMAKE_CXX_FLAGS="-Wno-error=deprecated-declarations"
-DMUJOCO_HARDEN:BOOL=ON
name: "${{ matrix.label }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Prepare Windows (setup MSVC)
if: ${{ runner.os == 'Windows' }}
uses: ilammy/msvc-dev-cmd@v1
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: bash ./.github/workflows/build_steps.sh prepare_linux
# Key the cache on the Filament pin: hashing cmake/third_party_deps/filament.cmake
# captures BOTH the pinned commit hash and the FILAMENT_* build flags, so bumping
# either starts a fresh cache namespace instead of restoring stale artifacts.
# (Correctness does not depend on this: ccache is content-addressed on the full
# compiler invocation, so changing any build flag forces a recompile regardless.)
- name: Setup ccache
if: ${{ runner.os != 'Windows' }}
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ matrix.label }}-filament-${{ hashFiles('cmake/third_party_deps/filament.cmake') }}
restore-keys: ${{ matrix.label }}-filament-
max-size: "2.0G"
- name: Configure Studio
env:
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ./.github/workflows/build_steps.sh configure_studio
- name: Build Studio
run: bash ./.github/workflows/build_steps.sh build_studio
- name: Notify team chat
shell: bash
env:
GCHAT_API_URL: ${{ secrets.GCHAT_API }}
JOB_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
CHATMSG_AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
CHATMSG_AUTHOR_EMAIL: ${{ github.event.head_commit.author.email }}
CHATMSG_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
CHATMSG_JOB_ID: ${{ matrix.label }}
if: failure() && github.ref_name == 'main' && github.event_name == 'push' && env.GCHAT_API_URL != ''
run: bash ./.github/workflows/build_steps.sh notify_team_chat
# This job quickly determines if WASM bindings are broken.
wasm:
name: "ubuntu-24.04-clang-18-wasm"
runs-on: ubuntu-24.04
env:
label: "ubuntu-24.04-clang-18-wasm"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
steps:
- uses: actions/checkout@v6
- name: Setup Node.js for WASM bindings
uses: actions/setup-node@v6
with:
node-version: '24.x'
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ env.label }}
max-size: "1.5G"
# For convenience run multiple build_steps functions in a single step.
- name: Prepare, Build and Test WASM bindings
env:
CMAKE_ARGS: ${{ env.cmake_args }}
run: |
bash ./.github/workflows/build_steps.sh npm_ci
bash ./.github/workflows/build_steps.sh setup_emsdk
bash ./.github/workflows/build_steps.sh build_test_wasm
- name: Notify team chat
shell: bash
env:
GCHAT_API_URL: ${{ secrets.GCHAT_API }}
JOB_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
CHATMSG_AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
CHATMSG_AUTHOR_EMAIL: ${{ github.event.head_commit.author.email }}
CHATMSG_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
CHATMSG_JOB_ID: ${{ env.label }}
if: failure() && github.ref_name == 'main' && github.event_name == 'push' && env.GCHAT_API_URL != ''
run: bash ./.github/workflows/build_steps.sh notify_team_chat
# MJX (mujoco.mjx) is pure JAX/XLA and compiler-independent: it imports the
# mujoco Python package only as a reference, so its tests run once here instead
# of in every matrix job. MuJoCo is built WITHOUT the C++ test suite (MJX does
# not need it) to keep the build lean.
mjx:
name: "ubuntu-24.04-clang-18-mjx"
runs-on: ubuntu-24.04
env:
TMPDIR: "/tmp"
CMAKE_ARGS: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
-DMUJOCO_BUILD_TESTS:BOOL=OFF
steps:
- uses: actions/checkout@v6
- name: Prepare Linux
run: bash ./.github/workflows/build_steps.sh prepare_linux
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install uv
uses: astral-sh/setup-uv@v8.2.0
with:
enable-cache: true
cache-dependency-glob: "python/build_requirements*.txt"
- name: Prepare Python
run: bash ./.github/workflows/build_steps.sh prepare_python
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ubuntu-24.04-clang-18-mjx
max-size: "1.0G"
- name: Configure MuJoCo
run: bash ./.github/workflows/build_steps.sh configure_mujoco
- name: Build MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh build_mujoco
- name: Install MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh install_mujoco
- name: Copy plugins
working-directory: build
run: bash ../.github/workflows/build_steps.sh copy_plugins_posix
- name: Make Python sdist
working-directory: python
run: bash ../.github/workflows/build_steps.sh make_python_sdist
- name: Build Python bindings
working-directory: python/dist
run: bash ../../.github/workflows/build_steps.sh build_python_bindings
- name: Install Python bindings
working-directory: python/dist
run: bash ../../.github/workflows/build_steps.sh install_python_bindings
- name: Package MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh package_mjx
- name: Install MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh install_mjx
- name: Test MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh test_mjx
- name: Notify team chat
shell: bash
env:
GCHAT_API_URL: ${{ secrets.GCHAT_API }}
JOB_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
CHATMSG_AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
CHATMSG_AUTHOR_EMAIL: ${{ github.event.head_commit.author.email }}
CHATMSG_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
CHATMSG_JOB_ID: "ubuntu-24.04-clang-18-mjx"
if: failure() && github.ref_name == 'main' && github.event_name == 'push' && env.GCHAT_API_URL != ''
run: bash ./.github/workflows/build_steps.sh notify_team_chat
+69
View File
@@ -0,0 +1,69 @@
{
"comment": "Build matrix for build.yml. 'tier' controls when an entry runs: 'core' runs on every pull_request and push; 'extended' runs only on push to main (full compiler sweep). See generate_matrix() in build_steps.sh.",
"include": [
{
"os": "ubuntu-24.04",
"label": "ubuntu-24.04-gcc-14",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=gcc-14 -DCMAKE_CXX_COMPILER:STRING=g++-14 -DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed",
"tmpdir": "/tmp",
"tier": "core"
},
{
"os": "ubuntu-24.04",
"label": "ubuntu-24.04-gcc-13",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=gcc-13 -DCMAKE_CXX_COMPILER:STRING=g++-13 -DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed",
"tmpdir": "/tmp",
"tier": "extended"
},
{
"os": "ubuntu-22.04",
"label": "ubuntu-22.04-gcc-12",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=gcc-12 -DCMAKE_CXX_COMPILER:STRING=g++-12 -DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed",
"tmpdir": "/tmp",
"tier": "core"
},
{
"os": "ubuntu-24.04",
"label": "ubuntu-24.04-clang-18",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=clang-18 -DCMAKE_CXX_COMPILER:STRING=clang++-18 -DMUJOCO_HARDEN:BOOL=ON",
"tmpdir": "/tmp",
"tier": "core"
},
{
"os": "ubuntu-24.04",
"label": "ubuntu-24.04-clang-17",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=clang-17 -DCMAKE_CXX_COMPILER:STRING=clang++-17 -DMUJOCO_HARDEN:BOOL=ON",
"tmpdir": "/tmp",
"tier": "extended"
},
{
"os": "ubuntu-24.04",
"label": "ubuntu-24.04-clang-16",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=clang-16 -DCMAKE_CXX_COMPILER:STRING=clang++-16 -DMUJOCO_HARDEN:BOOL=ON",
"tmpdir": "/tmp",
"tier": "extended"
},
{
"os": "ubuntu-22.04",
"label": "ubuntu-22.04-clang-15",
"cmake_args": "-G Ninja -DCMAKE_C_COMPILER:STRING=clang-15 -DCMAKE_CXX_COMPILER:STRING=clang++-15 -DMUJOCO_HARDEN:BOOL=ON",
"tmpdir": "/tmp",
"tier": "extended"
},
{
"os": "macos-15",
"label": "macos-15-arm64",
"cmake_args": "-G Ninja -DMUJOCO_HARDEN:BOOL=ON",
"tmpdir": "/tmp",
"tier": "core"
},
{
"os": "windows-2025",
"label": "windows-2025",
"cmake_args": "-DCMAKE_SYSTEM_VERSION=\"10.0.26100.0\"",
"cmake_build_args": "-- -m",
"tmpdir": "C:/Temp",
"tier": "core"
}
]
}
+430
View File
@@ -0,0 +1,430 @@
#!/bin/bash
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# TODO(matijak): Make all cmake commands run from the top-level directory, and
# consider making the builds parallel.
# Wrap the compiler with ccache when it is available (set up by ccache-action in
# CI). This makes warm rebuilds - including the expensive, pinned Filament build -
# much faster. ccache is content-addressed on the full compiler invocation, so
# changing a flag or source forces a recompile: a stale object is never reused.
# Guarded by `command -v` so the script still works locally without ccache.
CCACHE_ARGS=""
if command -v ccache >/dev/null 2>&1; then
CCACHE_ARGS="-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
fi
# Emit the build matrix for build.yml as a step output. On pull_request we run
# only the representative "core" compiler set; on push (e.g. to main) we run the
# full compiler sweep. Tiers are defined in build_matrix.json.
generate_matrix() {
echo "Generating build matrix for event '${GITHUB_EVENT_NAME}'..."
local file=".github/workflows/build_matrix.json"
local matrix
if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
matrix="$(jq -c '{include: [.include[] | select(.tier == "core") | del(.tier)]}' "${file}")"
else
matrix="$(jq -c '{include: [.include[] | del(.tier)]}' "${file}")"
fi
echo "matrix=${matrix}" >> "${GITHUB_OUTPUT}"
echo "${matrix}" | jq .
}
prepare_linux() {
echo "Preparing Linux..."
sudo apt-get update && sudo apt-get install \
libgl1-mesa-dev \
libwayland-dev \
libxinerama-dev \
libxcursor-dev \
libxkbcommon-dev \
libxrandr-dev \
libxi-dev \
ninja-build
}
prepare_python() {
echo "Preparing Python..."
repo="${PWD}"
pushd "${TMPDIR}" > /dev/null
python -m venv venv
if [[ $RUNNER_OS == "Windows" ]]; then
mkdir venv/bin
fixpath="$(s="$(cat venv/Scripts/activate | grep VIRTUAL_ENV=)"; echo "${s:13:-1}")"
sed -i "s#$(printf "%q" "${fixpath}")#$(cygpath "${fixpath}")#g" venv/Scripts/activate
ln -s ../Scripts/activate venv/bin/activate
fi
source venv/bin/activate
# Install build deps with uv when available (set up by setup-uv in CI on
# POSIX) - much faster than pip. Fall back to pip otherwise (e.g. Windows,
# local dev). The venv is still created by `python -m venv`, so pip stays
# available for later steps (pip wheel / python -m build).
if command -v uv > /dev/null 2>&1; then
uv pip install --require-hashes -r "${repo}/python/build_requirements.txt"
uv pip install --require-hashes -r "${repo}/python/build_requirements_usd.txt"
else
python -m pip install --upgrade --require-hashes -r "${repo}/python/build_requirements.txt"
python -m pip install --upgrade --require-hashes -r "${repo}/python/build_requirements_usd.txt"
fi
popd > /dev/null
}
npm_ci() {
echo "Installing NPM dependencies for WASM bindings..."
pushd wasm
npm ci
popd
}
setup_emsdk() {
echo "Setting up Emscripten..."
git clone https://github.com/emscripten-core/emsdk.git
./emsdk/emsdk install 4.0.10
./emsdk/emsdk activate 4.0.10
# Force installing emscripten's typescript dependencies. This is a
# workaround for the github update to a newer typescript, which gives an
# error on the deprecated `--outFile` flag.
pushd emsdk/upstream/emscripten
npm i
popd
}
configure_mujoco() {
echo "Configuring MuJoCo..."
# Disable IPO/LTO to cut build time. Skip this on Windows: turning off MSVC's
# whole-program optimization (/GL) exposes a latent heap corruption in
# SetConstTest.SleepingNotAllowed (a real bug worth a separate investigation),
# and Windows build time is not a CI bottleneck.
local ipo_off="-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF"
if [[ "${RUNNER_OS}" == "Windows" ]]; then
ipo_off=""
fi
mkdir build &&
cd build &&
cmake .. \
-DCMAKE_BUILD_TYPE:STRING=Release \
${ipo_off} \
-DCMAKE_INSTALL_PREFIX:STRING=${TMPDIR}/mujoco_install \
-DMUJOCO_BUILD_EXAMPLES:BOOL=OFF \
${CCACHE_ARGS} \
${CMAKE_ARGS}
}
build_mujoco() {
echo "Building MuJoCo..."
cmake --build . --config=Release ${CMAKE_BUILD_ARGS}
}
test_mujoco() {
echo "Testing MuJoCo..."
# ctest defaults to serial. The suite is ~1650 independent tests that use
# unique temp files (mkstemp / testing::TempDir) and declare no RUN_SERIAL /
# RESOURCE_LOCK, so running them in parallel is safe and ~2x faster on POSIX.
# Windows is kept serial conservatively: parallel-safety on the Windows file
# system is unverified and its test time is not a CI bottleneck.
if [[ "${RUNNER_OS}" == "Windows" ]]; then
ctest -C Release --output-on-failure .
else
local ncpu
ncpu="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo "${NUMBER_OF_PROCESSORS:-2}")"
ctest -C Release --output-on-failure --parallel "${ncpu}" .
fi
}
install_mujoco() {
echo "Installing MuJoCo..."
cmake --install .
}
copy_plugins_posix() {
echo "Copying plugins..."
mkdir -p ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp lib/libactuator.* ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp lib/libelasticity.* ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp lib/libsensor.* ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp lib/libsdf_plugin.* ${TMPDIR}/mujoco_install/mujoco_plugin
}
copy_plugins_window() {
echo "Copying plugins..."
mkdir -p ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp bin/Release/actuator.dll ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp bin/Release/elasticity.dll ${TMPDIR}/mujoco_install/mujoco_plugin &&
cp bin/Release/sensor.dll ${TMPDIR}/mujoco_install/mujoco_plugin
}
configure_samples() {
echo "Configuring samples..."
# Samples are tiny, so they keep the default IPO/LTO: disabling it saves no
# meaningful build time and would expose the same gcc -Werror false positives
# that -O3-without-LTO triggers (see configure_mujoco).
mkdir build &&
cd build &&
cmake .. \
-DCMAKE_BUILD_TYPE:STRING=Release \
-Dmujoco_ROOT:STRING=${TMPDIR}/mujoco_install \
${CCACHE_ARGS} \
${CMAKE_ARGS}
}
configure_simulate() {
echo "Configuring simulate..."
# See configure_samples: keep the default IPO/LTO for this small build.
mkdir build &&
cd build &&
cmake .. \
-DCMAKE_BUILD_TYPE:STRING=Release \
-Dmujoco_ROOT:STRING=${TMPDIR}/mujoco_install \
${CCACHE_ARGS} \
${CMAKE_ARGS}
}
build_simulate() {
echo "Building simulate..."
cmake --build . --config=Release ${CMAKE_BUILD_ARGS}
}
configure_studio() {
echo "Configuring Studio..."
cmake -B build \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF \
-DUSE_STATIC_LIBCXX=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DMUJOCO_BUILD_EXAMPLES=OFF \
-DMUJOCO_BUILD_SIMULATE=OFF \
-DMUJOCO_BUILD_STUDIO=ON \
-DMUJOCO_BUILD_TESTS=OFF \
-DMUJOCO_TEST_PYTHON_UTIL=OFF \
-DMUJOCO_WITH_USD=OFF \
-DMUJOCO_USE_FILAMENT=ON \
${CCACHE_ARGS} \
${CMAKE_ARGS}
echo "Configuring Studio... DONE"
}
build_studio() {
echo "Building Studio..."
cmake --build build --config=Release --target mujoco_studio --parallel
echo "Building Studio... DONE"
}
make_python_sdist() {
echo "Making Python sdist..."
source ${TMPDIR}/venv/bin/activate &&
./make_sdist.sh
}
build_python_bindings() {
echo "Building Python bindings..."
source ${TMPDIR}/venv/bin/activate
# pip unpacks the sdist into a randomized temp dir every run, so the absolute
# source/include paths differ each time and defeat ccache (0% hit, full
# recompile). CCACHE_BASEDIR rewrites absolute paths under it to paths relative
# to the (also-in-temp) build cwd, cancelling the random component so objects
# hash identically across runs. CCACHE_SLOPPINESS ignores timestamp/path noise.
#
# Do NOT add system_headers here: CMake adds the imported mujoco target's
# include dir (MUJOCO_PATH/include) as -isystem, so ccache would treat the
# public MuJoCo headers as system headers and skip hashing them. A change that
# lives only in those headers (a new mjData field, a new enum value) would then
# go undetected and ccache would reuse an object compiled against the old struct
# layout, producing an ABI-mismatched binding (wrong field offsets, stale
# mjNENABLE, signature mismatch). The mtime/ctime flags are kept: they handle the
# temp-dir churn without affecting header content detection.
export CCACHE_BASEDIR="${TMPDIR}"
export CCACHE_SLOPPINESS="time_macros,include_file_mtime,include_file_ctime,pch_defines,locale"
MUJOCO_PATH="${TMPDIR}/mujoco_install" \
MUJOCO_PLUGIN_PATH="${TMPDIR}/mujoco_install/mujoco_plugin" \
MUJOCO_CMAKE_ARGS="-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF ${CCACHE_ARGS} ${CMAKE_ARGS}" \
pip wheel -v --no-deps mujoco-*.tar.gz
}
install_python_bindings() {
echo "Installing Python bindings..."
source ${TMPDIR}/venv/bin/activate &&
pip install --no-index mujoco-*.whl
}
test_python_bindings() {
echo "Testing Python bindings..."
source ${TMPDIR}/venv/bin/activate &&
pytest -v --pyargs mujoco
}
build_test_wasm() {
echo "Building and testing WASM bindings..."
source emsdk/emsdk_env.sh
export PATH="$(pwd)/node_modules/.bin:$PATH"
echo "Build MuJoCo with Emscripten (Multi-Threaded)..."
emcmake cmake -B build_wasm_mt \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF \
-DMUJOCO_WASM_THREADS=ON \
${CCACHE_ARGS} \
$WASM_CMAKE_ARGS
cmake --build build_wasm_mt --parallel $(nproc)
echo "Run bindings tests for Multi-Threaded version..."
npm run test --prefix ./wasm
echo "Moving Multi-Thread version under mt subfolder..."
mkdir -p wasm/dist/mt
mv wasm/dist/mujoco.* wasm/dist/mt/
echo "Build MuJoCo with Emscripten (Single-Threaded)..."
emcmake cmake -B build_wasm_st \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF \
-DMUJOCO_WASM_THREADS=OFF \
${CCACHE_ARGS} \
$WASM_CMAKE_ARGS
cmake --build build_wasm_st --parallel $(nproc)
echo "Run bindings tests for Single-Threaded version..."
npm run test --prefix ./wasm
}
package_wasm() {
echo "Publishing WASM bindings..."
cp wasm/package.npm.json wasm/dist/package.json
cp wasm/README.md wasm/dist/README.md
VERSION="${VERSION:-${GITHUB_REF#refs/tags/}}"
npm --prefix wasm/dist version "${VERSION}" --no-git-tag-version
npm pack --dry-run ./wasm/dist
npm publish ./wasm/dist --access public --provenance
}
package_mjx() {
echo "Packaging MJX..."
source ${TMPDIR}/venv/bin/activate &&
python -m build .
}
install_mjx() {
echo "Installing MJX..."
source ${TMPDIR}/venv/bin/activate
# The MJX requirements (jax, jaxlib, scipy, ...) are a big install; use uv when
# available. Keep pip for the local --no-index wheel.
if command -v uv > /dev/null 2>&1; then
uv pip install --require-hashes -r requirements.txt
else
pip install --require-hashes -r requirements.txt
fi
pip install --no-index dist/mujoco_mjx-*.whl
}
test_mjx() {
echo "Testing MJX..."
source ${TMPDIR}/venv/bin/activate &&
pytest -n auto -v -k 'not IntegrationTest' --pyargs mujoco.mjx
}
notify_team_chat() {
CHATMSG="$(cat <<-'EOF' | python3
import json
import os
env = lambda x: os.getenv(x, '')
data = dict(
result=env('JOB_URL'),
job=env('CHATMSG_JOB_ID'),
commit=env('GITHUB_SHA')[:6],
name=env('CHATMSG_AUTHOR_NAME').replace('```', ''),
email=env('CHATMSG_AUTHOR_EMAIL'),
msg=env('CHATMSG_COMMIT_MESSAGE').replace('```', '')
)
text = '<{result}|*FAILURE*>: job `{job}` commit `{commit}`\n```Author: {name} <{email}>\n\n{msg}```'.format(**data)
print(json.dumps({'text' : text}))
EOF
)" &&
curl "$GCHAT_API_URL&threadKey=$GITHUB_SHA&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD" \
-X POST \
-H "Content-Type: application/json" \
--data-raw "${CHATMSG}"
}
build_mujoco_live() {
echo "Setting up Emscripten SDK..."
source emsdk/emsdk_env.sh
echo "Building Filament tools, targeting host platform..."
cmake -S . -B build_host -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_STATIC_LIBCXX=OFF \
-DMUJOCO_BUILD_STUDIO=ON \
-DMUJOCO_USE_FILAMENT=ON \
-DMUJOCO_BUILD_TESTS=OFF \
-DMUJOCO_BUILD_EXAMPLES=OFF \
-DMUJOCO_BUILD_SIMULATE=OFF
cmake --build build_host --target matc resgen cmgen mujoco_filament_assets -j$(nproc)
echo "Building WASM app..."
emcmake cmake -S . -B build_wasm -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DMUJOCO_BUILD_STUDIO=ON \
-DMUJOCO_USE_FILAMENT=ON \
-DMUJOCO_BUILD_TESTS_WASM=OFF \
-DMUJOCO_NATIVE_BUILD_DIR=$(pwd)/build_host
cmake --build build_wasm --target mujoco_studio -j$(nproc)
}
# Discover functions defined in this script by finding identifiers followed by
# "()" and capturing the identifier as a valid function name.
VALID_FUNCTIONS=()
while IFS= read -r func_name; do
VALID_FUNCTIONS+=("$func_name")
done < <(grep -E '^[[:alnum:]_]+\(\)' "$0" | sed 's/().*$//')
# Exit with an error if the requested function is not found.
if [[ ! " ${VALID_FUNCTIONS[*]} " =~ " ${1} " ]]; then
echo "Usage: $0 {$(IFS='|'; echo "${VALID_FUNCTIONS[*]}")}, got '$1'"
exit 1
fi
# Set options to print the commands being run, and cause the script to exit with
# an error code if any command fails. Note we do this just before executing
# the requested function to avoid cluttering the output with the above command
# discovery code.
set -xe
# Execute the requested function.
"$1"
+23
View File
@@ -0,0 +1,23 @@
# Run pre-commit hooks on files changed in the PR only.
name: lint
on:
pull_request:
permissions:
contents: read
jobs:
pre-commit:
name: pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: pre-commit/action@v3.0.1
with:
extra_args: --from-ref ${{ github.event.pull_request.base.sha }} --to-ref ${{ github.event.pull_request.head.sha }}
+58
View File
@@ -0,0 +1,58 @@
name: live
on:
push:
branches:
- live
permissions:
contents: read
pages: write
id-token: write
jobs:
build-and-upload-artifacts:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Prepare Linux
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Setup Emscripten
run: bash ./.github/workflows/build_steps.sh setup_emsdk
- name: Build MuJoCo Live
env:
CC: clang-18
CXX: clang++-18
run: bash ./.github/workflows/build_steps.sh build_mujoco_live
- name: Prepare files for GitHub Pages
run: |
mkdir -p dist/bin
cp -r build_wasm/bin/* dist/bin/
cp src/experimental/studio/live.html dist/index.html
cp src/experimental/studio/live.css dist/live.css
cp src/experimental/studio/live.js dist/live.js
cp src/experimental/studio/favicon.ico dist/favicon.ico
COMMIT_HASH=$(git rev-parse HEAD 2>/dev/null || true)
if [ -n "$COMMIT_HASH" ]; then
sed -i "s/__COMMIT_HASH_PLACEHOLDER__/$COMMIT_HASH/g" dist/index.html
fi
- name: Upload GitHub Pages artifacts
uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy-pages:
needs: build-and-upload-artifacts
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+50
View File
@@ -0,0 +1,50 @@
name: publish-wasm
on:
push:
tags:
- '[0-9]*.[0-9]*.[0-9]*'
workflow_dispatch:
inputs:
tag_version:
description: 'Release tag version to deploy'
required: true
default: '0.0.0'
permissions:
id-token: write
contents: read
jobs:
publish:
name: Publish MuJoCo WASM package
runs-on: ubuntu-24.04
env:
VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.tag_version || github.ref_name }}
steps:
- uses: actions/checkout@v6
- name: Setup Node.js for WASM bindings
uses: actions/setup-node@v6
with:
node-version: '24.x'
- name: Prepare Linux
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Install NPM Dependencies for WASM bindings
run: bash ./.github/workflows/build_steps.sh npm_ci
- name: Setup Emscripten for WASM bindings
run: bash ./.github/workflows/build_steps.sh setup_emsdk
- name: Build WASM bindings
run: bash ./.github/workflows/build_steps.sh build_test_wasm
- name: Package WASM bindings
env:
VERSION: ${{ env.VERSION }}
run: bash ./.github/workflows/build_steps.sh package_wasm
+28
View File
@@ -0,0 +1,28 @@
name: update-live
on:
release:
types: [published] # Trigger when publishing releases ...
workflow_dispatch: # or manually (updates to main HEAD).
permissions:
contents: write
jobs:
merge-branch:
runs-on: ubuntu-latest
steps:
- name: Checkout MuJoCo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fast-forward the live branch
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
git fetch origin main:refs/remotes/origin/main
REF_NAME="origin/main"
else
REF_NAME="${{ github.ref_name }}"
fi
git push origin ${REF_NAME}:refs/heads/live
+5
View File
@@ -37,3 +37,8 @@ MUJOCO_LOG.TXT
# Clang cache
.cache/
# JavaScript bindings build
wasm/**/dist/
**/node_modules/
+7
View File
@@ -0,0 +1,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: \.patch$
- id: end-of-file-fixer
+37 -6
View File
@@ -3,16 +3,47 @@
version: 2
# TODO(robotics-simulation): pdf format fails to build on readthedocs
# formats:
# - pdf
build:
os: ubuntu-20.04
os: ubuntu-24.04
tools:
python: "3.10"
python: "3.12"
apt_packages:
- libgl-dev
jobs:
create_environment:
# install uv
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- uv venv $READTHEDOCS_VIRTUALENV_PATH
# install doc requirements
- |
UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH \
uv pip install \
-r doc/requirements.txt \
pip setuptools absl-py
# generate and install doc-only mujoco stubs (no C build required)
- python doc/make_mujoco_stubs.py python/mujoco_doc
- |
UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH \
uv pip install --no-deps python/mujoco_doc
# install mjx and mujoco_warp (mujoco dep satisfied by stubs above)
- UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv pip install -e mjx
- |
find mjx/mujoco/mjx/third_party/mujoco_warp -type f -exec \
sed -i 's/mujoco\.mjx\.third_party\.mujoco_warp/mujoco_warp/g' {} \;
- python doc/mjwarp/update_types.py mjx/mujoco/mjx/third_party/mujoco_warp/_src/types.py
- |
UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH \
uv pip install mjx/mujoco/mjx/third_party/mujoco_warp
install:
- "true" # skip default install
sphinx:
builder: html
configuration: doc/conf.py
fail_on_warning: false
python:
install:
- requirements: doc/requirements.txt
+131 -36
View File
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.16)
set(MUJOCO_CMAKE_MIN_REQ "3.16")
cmake_minimum_required(VERSION ${MUJOCO_CMAKE_MIN_REQ})
# Make CMAKE_C_VISIBILITY_PRESET work properly.
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
@@ -28,7 +29,7 @@ set(MSVC_INCREMENTAL_DEFAULT ON)
project(
mujoco
VERSION 3.3.5
VERSION 3.12.0
DESCRIPTION "MuJoCo Physics Simulator"
HOMEPAGE_URL "https://mujoco.org"
)
@@ -38,32 +39,70 @@ enable_language(CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
option(MUJOCO_BUILD_EXAMPLES "Build samples for MuJoCo" ON)
option(MUJOCO_BUILD_SIMULATE "Build simulate library for MuJoCo" ON)
option(MUJOCO_BUILD_TESTS "Build tests for MuJoCo" ON)
option(MUJOCO_TEST_PYTHON_UTIL "Build and test utility libraries for Python bindings" ON)
option(MUJOCO_WITH_USD "Build with OpenUSD" OFF)
if(NOT EMSCRIPTEN)
option(MUJOCO_BUILD_EXAMPLES "Build samples for MuJoCo" ON)
option(MUJOCO_BUILD_SIMULATE "Build simulate library for MuJoCo" ON)
option(MUJOCO_BUILD_STUDIO "Build studio library for MuJoCo" OFF)
option(MUJOCO_BUILD_TESTS "Build tests for MuJoCo" ON)
option(MUJOCO_TEST_PYTHON_UTIL "Build and test utility libraries for Python bindings" ON)
option(MUJOCO_WITH_USD "Build with OpenUSD" OFF)
option(MUJOCO_USE_FILAMENT "Use filament rendering" OFF)
# Allows filament renderer to be used with mjr API; disables src/render to prevent conflicts.
option(MUJOCO_USE_FILAMENT_MJR_COMPAT "Use filament mjr compatibility layer" OFF)
endif()
# Option to provide a path to an existing USD build directory or to Houdini HFS directory.
set(USD_DIR "" CACHE PATH "Path to an existing USD build directory.")
set(HOUDINI_HFS_DIR "" CACHE PATH "Path to Houdini HFS directory to build USD plugins against.")
if(USD_DIR)
if(EXISTS "${USD_DIR}")
# If the path is provided, set MUJOCO_WITH_USD to ON and add the path to CMAKE_PREFIX_PATH.
set(MUJOCO_WITH_USD ON CACHE BOOL "Build with OpenUSD" FORCE)
list(PREPEND CMAKE_PREFIX_PATH "${USD_DIR}")
message(STATUS "Using custom USD build directory: ${USD_DIR}")
else()
message(WARNING "Invalid path provided for USD_DIR: ${USD_DIR}")
if(EMSCRIPTEN)
option(MUJOCO_BUILD_TESTS_WASM "Build tests for WASM bindings" ON)
option(MUJOCO_BUILD_STUDIO "Build studio for MuJoCo (WASM)" OFF)
option(MUJOCO_USE_FILAMENT "Use filament rendering" OFF)
option(MUJOCO_WASM_THREADS "Build with multi-threading support" ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -O3 -fexceptions")
if(MUJOCO_WASM_THREADS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()
elseif(HOUDINI_HFS_DIR)
if(EXISTS "${HOUDINI_HFS_DIR}")
set(MUJOCO_WITH_USD ON CACHE BOOL "Build with OpenUSD" FORCE)
message(STATUS "Building Mujoco USD against Houdini HFS: ${HOUDINI_HFS_DIR}")
# Filament uses the WASM variable (not EMSCRIPTEN) to identify web builds.
# Without this, it falls into the LINUX path and tries to compile with
# futex, X11, Vulkan, etc.
if(MUJOCO_USE_FILAMENT)
set(WASM ON CACHE BOOL "Filament WASM mode" FORCE)
endif()
# Automatically generate host tool imports for Filament cross-compilation.
# When WASM is true, Filament hardcodes the path to:
# ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake
# So we write our file with that exact name and set IMPORT_EXECUTABLES_DIR
# to point at CMAKE_BINARY_DIR (which is ../../ relative to filament-src).
set(MUJOCO_NATIVE_BUILD_DIR "${PROJECT_SOURCE_DIR}/build-host" CACHE PATH "Path to native build directory containing host tools")
find_program(MATC_EXE matc PATHS "${MUJOCO_NATIVE_BUILD_DIR}/bin" NO_DEFAULT_PATH)
find_program(RESGEN_EXE resgen PATHS "${MUJOCO_NATIVE_BUILD_DIR}/bin" NO_DEFAULT_PATH)
find_program(CMGEN_EXE cmgen PATHS "${MUJOCO_NATIVE_BUILD_DIR}/bin" NO_DEFAULT_PATH)
if(MATC_EXE AND RESGEN_EXE AND CMGEN_EXE)
message(STATUS "Found host tools in ${MUJOCO_NATIVE_BUILD_DIR}/bin")
set(IMPORT_EXECUTABLES_FILE "${CMAKE_BINARY_DIR}/ImportExecutables-Release.cmake")
file(WRITE "${IMPORT_EXECUTABLES_FILE}"
"add_executable(matc IMPORTED)\n"
"set_property(TARGET matc PROPERTY IMPORTED_LOCATION \"${MATC_EXE}\")\n"
"add_executable(resgen IMPORTED)\n"
"set_property(TARGET resgen PROPERTY IMPORTED_LOCATION \"${RESGEN_EXE}\")\n"
"add_executable(cmgen IMPORTED)\n"
"set_property(TARGET cmgen PROPERTY IMPORTED_LOCATION \"${CMGEN_EXE}\")\n"
)
# Filament's WASM path resolves: ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake
# FILAMENT = _deps/filament-src, so ../../ resolves to CMAKE_BINARY_DIR.
set(IMPORT_EXECUTABLES_DIR "../../" CACHE PATH "" FORCE)
else()
message(WARNING "Host tools (matc, resgen, cmgen) not found in ${MUJOCO_NATIVE_BUILD_DIR}/bin. WASM build of Studio might fail.")
endif()
endif()
if(APPLE AND (MUJOCO_BUILD_EXAMPLES OR MUJOCO_BUILD_SIMULATE))
if(APPLE AND (MUJOCO_BUILD_EXAMPLES OR MUJOCO_BUILD_SIMULATE OR MUJOCO_USE_FILAMENT))
# NOTE: OBJC* languages are proactively enabled when using Filament to
# workaround a CMake bug triggered by Filament recently adding:
# set(EXTRA_LANGS OBJC OBJCXX)
# See also: https://gitlab.kitware.com/cmake/cmake/-/work_items/24104
enable_language(OBJC)
enable_language(OBJCXX)
endif()
@@ -73,16 +112,18 @@ include(MujocoMacOS)
include(MujocoDependencies)
set(MUJOCO_HEADERS
include/mujoco/mjassert.h
include/mujoco/mjdata.h
include/mujoco/mjexport.h
include/mujoco/mjmacro.h
include/mujoco/mjmodel.h
include/mujoco/mjplugin.h
include/mujoco/mjrender.h
include/mujoco/mjrfilament.h
include/mujoco/mjsan.h
include/mujoco/mjspec.h
include/mujoco/mjthread.h
include/mujoco/mjtnum.h
include/mujoco/mjspecmacro.h
include/mujoco/mjtype.h
include/mujoco/mjui.h
include/mujoco/mjvisualize.h
include/mujoco/mjxmacro.h
@@ -96,7 +137,14 @@ else()
set(MUJOCO_RESOURCE_FILES "")
endif()
add_library(mujoco SHARED ${MUJOCO_RESOURCE_FILES})
# Emscripten does not support SHARED libs
if(NOT EMSCRIPTEN)
find_package(Threads REQUIRED)
add_library(mujoco SHARED ${MUJOCO_RESOURCE_FILES})
else()
add_library(mujoco STATIC ${MUJOCO_RESOURCE_FILES})
endif()
target_include_directories(
mujoco
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
@@ -104,16 +152,34 @@ target_include_directories(
PRIVATE src
)
add_subdirectory(plugin/elasticity)
add_subdirectory(plugin/actuator)
add_subdirectory(plugin/sensor)
add_subdirectory(plugin/sdf)
if(NOT EMSCRIPTEN)
add_subdirectory(plugin/elasticity)
add_subdirectory(plugin/actuator)
add_subdirectory(plugin/sensor)
add_subdirectory(plugin/sdf)
endif()
add_subdirectory(plugin/obj_decoder)
add_subdirectory(plugin/stl_decoder)
add_subdirectory(src/engine)
add_subdirectory(src/user)
add_subdirectory(src/xml)
add_subdirectory(src/render)
add_subdirectory(src/thread)
add_subdirectory(src/ui)
add_subdirectory(src/xml/mjz)
if(NOT EMSCRIPTEN AND NOT MUJOCO_USE_FILAMENT_MJR_COMPAT)
add_subdirectory(src/render/classic)
add_subdirectory(src/ui)
endif()
add_subdirectory(src/render/noop)
if(MUJOCO_USE_FILAMENT)
add_subdirectory(src/render/filament)
add_subdirectory(src/experimental/filament)
endif()
if(EMSCRIPTEN)
add_subdirectory(wasm)
endif()
target_compile_definitions(mujoco PRIVATE _GNU_SOURCE CCD_STATIC_DEFINE MUJOCO_DLL_EXPORTS -DMC_IMPLEM_ENABLE)
if(MUJOCO_ENABLE_AVX_INTRINSICS)
@@ -143,6 +209,10 @@ target_link_libraries(
tinyxml2
)
if(NOT EMSCRIPTEN)
target_link_libraries(mujoco PRIVATE Threads::Threads)
endif()
set_target_properties(
mujoco PROPERTIES VERSION "${mujoco_VERSION}" PUBLIC_HEADER "${MUJOCO_HEADERS}"
)
@@ -197,13 +267,36 @@ if(MUJOCO_BUILD_SIMULATE)
add_subdirectory(simulate)
endif()
if(MUJOCO_BUILD_STUDIO)
add_subdirectory(src/experimental/platform)
add_subdirectory(src/experimental/studio)
endif()
if(MUJOCO_BUILD_EXAMPLES)
add_subdirectory(sample)
endif()
if(MUJOCO_WITH_USD)
target_compile_definitions(mujoco PUBLIC mjUSEUSD)
include(third_party_deps/openusd)
get_filename_component(USD_INSTALL_ROOT "${pxr_DIR}/lib" ABSOLUTE)
install(
DIRECTORY ${USD_INSTALL_ROOT}/
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
if(APPLE)
set_target_properties(mujoco PROPERTIES
BUILD_RPATH "${USD_INSTALL_ROOT}"
INSTALL_RPATH "@loader_path")
elseif(UNIX)
set_target_properties(mujoco PROPERTIES
BUILD_RPATH "${USD_INSTALL_ROOT}"
INSTALL_RPATH "$ORIGIN")
endif()
add_subdirectory(src/experimental/usd)
add_subdirectory(plugin/usd_decoder)
endif()
if(BUILD_TESTING AND MUJOCO_BUILD_TESTS)
@@ -214,10 +307,12 @@ if(BUILD_TESTING AND MUJOCO_BUILD_TESTS)
endif()
endif()
if(NOT (APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS))
if(NOT EMSCRIPTEN AND NOT (APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS))
set(MUJOCO_TARGETS mujoco)
# Install the libraries.
install(
TARGETS mujoco
TARGETS ${MUJOCO_TARGETS}
EXPORT ${PROJECT_NAME}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime
+7 -3
View File
@@ -72,7 +72,7 @@ How to submit a good enhancement suggestion:
### Contributing code
- Except for small and straightforward bugfixes, please get in touch with us
- Except for small and straightforward bug fixes, please get in touch with us
before you start working on a contribution so that we can help and possibly
guide you. Coordinating up front makes it much easier to avoid frustration later
on.
@@ -105,11 +105,15 @@ achieve multiple things.
- Respond to reviewers. Please be responsive to any questions and comments.
- If you are not concerned with having your contribution attributed to you via
Git authorship, please let us know in the PR. It is significantly easier
for us to directly incorporate changes rather than going through the
full pull request import process. This will get your changes merged more
quickly.
Once you have met all the requirements, your code will be merged.
Thanks for improving MuJoCo!
### Community guidelines
This project follows Google's
+11 -7
View File
@@ -84,7 +84,7 @@ Users who wish to build MuJoCo from source should consult the [build from
source] section of the documentation. However, note that the commit at
the tip of the `main` branch may be unstable.
### Python (>= 3.9)
### Python (>= 3.10)
The native Python bindings, which come pre-packaged with a copy of MuJoCo, can
be installed from [PyPI] via:
@@ -98,6 +98,12 @@ Note that Pre-built Linux wheels target `manylinux2014`, see
information such as building the bindings from source, see the [Python bindings]
section of the documentation.
## Versioning
We aim to release MuJoCo in the first week of each month. Our versioning
standards changed to modified Semantic Versioning in 3.5.0,
see [versioning](VERSIONING.md) for details.
## Contributing
We welcome community engagement: questions, requests for help, bug reports and
@@ -131,20 +137,18 @@ These packages give users of various languages access to MuJoCo functionality:
DeepMind's related environment stack, includes
[PyMJCF](https://github.com/google-deepmind/dm_control/blob/main/dm_control/mjcf/README.md),
a module for procedural manipulation of MuJoCo models.
- [JavaScript bindings and WebAssembly support](/wasm/README.md) (inspired [stillonearth](https://github.com/stillonearth) and [zalo](https://github.com/zalo)'s community projects; [mjswan](https://github.com/ttktjmt/mjswan) extends these with real-time policy control, interactive force
application, and more).
- [C# bindings and Unity plug-in](https://mujoco.readthedocs.io/en/stable/unity.html)
#### Third-party bindings:
- **WebAssembly**: [mujoco_wasm](https://github.com/zalo/mujoco_wasm) by [@zalo](https://github.com/zalo) with contributions by
[@kevinzakka](https://github.com/kevinzakka), based on the [emscripten build](https://github.com/stillonearth/MuJoCo-WASM) by
[@stillonearth](https://github.com/stillonearth).
:arrow_right: [Click here](https://zalo.github.io/mujoco_wasm/) for a live demo of MuJoCo running in your browser.
- **MATLAB Simulink**: [Simulink Blockset for MuJoCo Simulator](https://github.com/mathworks-robotics/mujoco-simulink-blockset)
by [Manoj Velmurugan](https://github.com/vmanoj1996).
- **Swift**: [swift-mujoco](https://github.com/liuliu/swift-mujoco)
- **Java**: [mujoco-java](https://github.com/CommonWealthRobotics/mujoco-java)
- **Julia**: [MuJoCo.jl](https://github.com/JamieMair/MuJoCo.jl)
- **Rust**: [MuJoCo-rs](https://github.com/davidhozic/mujoco-rs)
### Converters
@@ -190,7 +194,7 @@ copy of the License at https://www.apache.org/licenses/LICENSE-2.0.
This is not an officially supported Google product.
[build from source]: https://mujoco.readthedocs.io/en/latest/programming#building-mujoco-from-source
[build from source]: https://mujoco.readthedocs.io/en/latest/programming#building-from-source
[Getting Started]: https://mujoco.readthedocs.io/en/latest/programming#getting-started
[Unity]: https://unity.com/
[releases page]: https://github.com/google-deepmind/mujoco/releases
+56 -52
View File
@@ -6,7 +6,8 @@ possible in your code contributions.
### Scope of this guide
Most of this guide involves C/C++ code. For Python, jump to the section [below](#python-code). For MuJoCo C/C++, code has three main categories:
Most of this guide involves C/C++ code. For Python, jump to the section
[below](#python-code). For MuJoCo C/C++, code has three main categories:
1. **C code:** MuJoCo's core codebase. It consists of public headers under
`include/` and C source files and internal headers under `src/`. This style
@@ -81,70 +82,70 @@ are required.
#### Braces
- MuJoCo uses
[attached K&R braces](https://en.wikipedia.org/wiki/Indentation_style#Variant:_mandatory_braces),
including for one-line blocks:
- MuJoCo uses
[attached K&R braces](https://en.wikipedia.org/wiki/Indentation_style#Variant:_mandatory_braces),
including for one-line blocks:
```C
// transpose matrix
void mju_transpose(mjtNum* res, const mjtNum* mat, int nr, int nc) {
for (int i=0; i < nr; i++) {
for (int j=0; j < nc; j++) {
res[j*nr+i] = mat[i*nc+j];
```c
// transpose matrix
void mju_transpose(mjtNum* res, const mjtNum* mat, int nr, int nc) {
for (int i=0; i < nr; i++) {
for (int j=0; j < nc; j++) {
res[j*nr+i] = mat[i*nc+j];
}
}
}
}
```
```
- Brace-less single line statements are allowed outside of `engine/` code, for
similar, repeated blocks, that do not contain flow control statements (`return`,
`continue`, etc.). For an example of this exception, inspect the [`mjCModel`
destructor](https://github.com/google-deepmind/mujoco/search?q=repo%3Adeepmind%2Fmujoco+filename%3Auser_model.cc).
- Brace-less single line statements are allowed with the exception of `return`
and `break` statements. For an example of this exception, inspect the
[`mjCModel` destructor](https://github.com/google-deepmind/mujoco/search?q=repo%3Adeepmind%2Fmujoco+filename%3Auser_model.cc).
- Unattached braces are allowed in `if/else` blocks, when inserting a comment
before the `else`:
- Unattached braces are allowed in `if/else` blocks, when inserting an
explanatory comment above the `else`:
```C
// rotate vector by quaternion
void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]) {
// null quat: copy vec
if (quat[0] == 1 && quat[1] == 0 && quat[2] == 0 && quat[3] == 0) {
mju_copy3(res, vec);
```c
// rotate vector by quaternion
void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]) {
// null quat: copy vec
if (quat[0] == 1 && quat[1] == 0 && quat[2] == 0 && quat[3] == 0) {
mju_copy3(res, vec);
}
// regular processing
else {
mjtNum mat[9];
mju_quat2Mat(mat, quat);
mju_mulMatVec3(res, mat, vec);
}
}
// regular processing
else {
mjtNum mat[9];
mju_quat2Mat(mat, quat);
mju_mulMatVec3(res, mat, vec);
}
}
```
```
#### Spacing
- MuJoCo encourages judicious use of spacing around operators to promote
readability. For example below, note the lack of spaces around the
multiplication operator, and the aligning spaces in the second and fourth
assignments:
- MuJoCo encourages judicious use of spacing around operators to promote
readability. For example below, note the lack of spaces around the
multiplication operator, and the aligning spaces in the second and fourth
assignments:
```C
// time-derivative of quaternion, given 3D rotational velocity
void mju_derivQuat(mjtNum res[4], const mjtNum quat[4], const mjtNum vel[3]) {
res[0] = 0.5*(-vel[0]*quat[1] - vel[1]*quat[2] - vel[2]*quat[3]);
res[1] = 0.5*( vel[0]*quat[0] + vel[1]*quat[3] - vel[2]*quat[2]);
res[2] = 0.5*(-vel[0]*quat[3] + vel[1]*quat[0] + vel[2]*quat[1]);
res[3] = 0.5*( vel[0]*quat[2] - vel[1]*quat[1] + vel[2]*quat[0]);
}
```
```c
// time-derivative of quaternion, given 3D rotational velocity
void mju_derivQuat(mjtNum res[4], const mjtNum quat[4], const mjtNum vel[3]) {
res[0] = 0.5*(-vel[0]*quat[1] - vel[1]*quat[2] - vel[2]*quat[3]);
res[1] = 0.5*( vel[0]*quat[0] + vel[1]*quat[3] - vel[2]*quat[2]);
res[2] = 0.5*(-vel[0]*quat[3] + vel[1]*quat[0] + vel[2]*quat[1]);
res[3] = 0.5*( vel[0]*quat[2] - vel[1]*quat[1] + vel[2]*quat[0]);
}
```
- Spaces are required around comparison operators.
- Spaces are required around comparison operators.
- Spaces are not allowed around operators in array subscripts `[]` or in
variable initialisation in `for` loops. For example, inspect the
`mju_transpose` implementation above.
- Spaces are not allowed around operators in array subscripts `[]` or in
variable initialisation in `for` loops. For example, inspect the
`mju_transpose` implementation above.
- Three blank lines are required between function implementations in source files.
- Two blank lines are required between function implementations in source
files.
#### Variable declarations
@@ -161,4 +162,7 @@ helping us to complete the migration are very welcome.
### [Python code](#python-code)
For Python code, run `pyink foo.py` to adhere to Google's [Python style guide](https://google.github.io/styleguide/pyguide.html). For sorting and cleaning imports, run `isort foo.py`. Both `pyink` and `isort` can be pip installed via `pip install pyink isort`.
For Python code, run `pyink foo.py` to adhere to Google's
[Python style guide](https://google.github.io/styleguide/pyguide.html). For
sorting and cleaning imports, run `isort foo.py`. Both `pyink` and `isort` can
be pip installed via `pip install pyink isort`.
+75
View File
@@ -0,0 +1,75 @@
# MuJoCo Versioning
MuJoCo uses custom semantic versioning from 3.5.0 onwards, see below.
### The problem with Semantic Versioning
The common definition of traditional [Semantic Versioning](https://semver.org/)
is
```
1. MAJOR: breaking changes
2. MINOR: new features
3. PATCH: bug fixes
```
With strict adherence to this definition, most MuJoCo releases are `MAJOR`. This
is because MuJoCo has a very large API surface, especially when considering
[MJCF](https://mujoco.readthedocs.io/en/stable/XMLreference.html) and the
related
[mjSpec](https://mujoco.readthedocs.io/en/stable/programming/modeledit.html)
API. Furthermore, the numerical properties of physics state integration mean
that despite being deterministic, numerical reproducibility across versions is
almost guaranteed to
[not hold](https://mujoco.readthedocs.io/en/stable/computation/index.html#reproducibility).
## From 3.5.0 – semantic versioning
From 3.5.0 onwards MuJoCo uses well-defined versioning with the following
semantics.
### MuJoCo versioning semantics
```
1. SUPERMAJOR: breaking changes and/or significant new features
2. MAJOR: breaking changes, possibly new features
3. MINOR_OR_PATCH: new features or bug fixes
```
`MINOR_OR_PATCH` guarantees API backward compatibility, but may or may not
introduce new features; to find out, read the
[changelog](https://mujoco.readthedocs.io/en/stable/changelog.html), which will
detail the nature of the changes. The changelog will also detail pure
ABI-breaking changes, for example removing an unused attribute from a public
struct. Such changes are considered MINOR. As explained
[here](https://mujoco.readthedocs.io/en/stable/computation/index.html#reproducibility),
numerical reproducibility is *never* guaranteed.
Additionally:
- `mj_versionString()` works as before, returning e.g. `"4.2.1"`.
- `mj_version()` works as before, returning an integer. The corresponding
header constant `mjVERSION_HEADER` is calculated from the components as:
```
mjVERSION = (SUPERMAJOR * 1e6) + (MAJOR * 1e3) + MINOR_OR_PATCH
```
For example, 4.2.1 would be `4002001`.
## Prior to 3.5.0 – no semantics
Until 3.5.0, versioning was a sequence of increasing numbers with no
well-defined semantic, with the exception of major versions introducing
significant new features, like
[3.0.0](https://mujoco.readthedocs.io/en/stable/changelog.html#version-3-0-0-october-18-2023)'s
introduction of the JAX-based
[MJX](https://mujoco.readthedocs.io/en/stable/mjx.html) branch. Additionally:
- The function
[`const char* mj_versionString()`](https://mujoco.readthedocs.io/en/stable/APIreference/APIfunctions.html#mj-versionstring)
returns the version in the form of a string, for example `"3.2.7"`.
- The function
[`int mj_version()`](https://mujoco.readthedocs.io/en/stable/APIreference/APIfunctions.html#mj-version)
returns an integer equal to the version digits concatenated,
for example for "3.2.7" we'd have `mjVERSION = 327`.
+165 -77
View File
@@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#.rst:
# FindOrFetch
# ----------------------
@@ -23,6 +23,7 @@
# [LIBRARY_NAME [name]]
# [GIT_REPO [repo]]
# [GIT_TAG [tag]]
# [CUSTOM_CMAKE [path]]
# [PATCH_COMMAND [cmd] [args]]
# [TARGETS [targets]]
# [EXCLUDE_FROM_ALL])
@@ -42,6 +43,9 @@
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
# - ``GIT_TAG`` tag reference when fetching the library from the git
# repository. Ignored if ``USE_SYSTEM_PACKAGE`` is ``ON``.
# - ``CUSTOM_CMAKE`` path to a custom CMakeLists.txt file to be used when
# fetching the library from the git repository. Ignored if
# ``USE_SYSTEM_PACKAGE`` is ``ON``.
# - ``PATCH_COMMAND`` Specifies a custom command to patch the sources after an
# update. See https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add
# for details on the parameter.
@@ -56,85 +60,169 @@
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variables to
# override this macro behaviour.
if(COMMAND FindOrFetch)
return()
endif()
macro(FindOrFetch)
if(NOT FetchContent)
include(FetchContent)
endif()
# Parse arguments.
set(options EXCLUDE_FROM_ALL)
set(one_value_args
USE_SYSTEM_PACKAGE
PACKAGE_NAME
LIBRARY_NAME
GIT_REPO
GIT_TAG
)
set(multi_value_args PATCH_COMMAND TARGETS)
cmake_parse_arguments(
_ARGS
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
# Check if all targets are found.
if(NOT _ARGS_TARGETS)
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
endif()
set(targets_found TRUE)
message(CHECK_START
"mujoco::FindOrFetch: checking for targets in package `${_ARGS_PACKAGE_NAME}`"
)
foreach(target ${_ARGS_TARGETS})
if(NOT TARGET ${target})
message(CHECK_FAIL "target `${target}` not defined.")
set(targets_found FALSE)
break()
if(NOT COMMAND FindOrFetch)
macro(FindOrFetch)
if(NOT FetchContent)
include(FetchContent)
endif()
endforeach()
# If targets are not found, use `find_package` or `FetchContent...` to get it.
if(NOT targets_found)
if(${_ARGS_USE_SYSTEM_PACKAGE})
message(CHECK_START
"mujoco::FindOrFetch: finding `${_ARGS_PACKAGE_NAME}` in system packages..."
)
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
message(CHECK_PASS "found")
else()
message(CHECK_START
"mujoco::FindOrFetch: Using FetchContent to retrieve `${_ARGS_LIBRARY_NAME}`"
)
FetchContent_Declare(
${_ARGS_LIBRARY_NAME}
GIT_REPOSITORY ${_ARGS_GIT_REPO}
GIT_TAG ${_ARGS_GIT_TAG}
GIT_SHALLOW FALSE
PATCH_COMMAND ${_ARGS_PATCH_COMMAND}
UPDATE_DISCONNECTED TRUE
)
if(${_ARGS_EXCLUDE_FROM_ALL})
FetchContent_GetProperties(${_ARGS_LIBRARY_NAME})
if(NOT ${${_ARGS_LIBRARY_NAME}_POPULATED})
FetchContent_Populate(${_ARGS_LIBRARY_NAME})
add_subdirectory(
${${_ARGS_LIBRARY_NAME}_SOURCE_DIR} ${${_ARGS_LIBRARY_NAME}_BINARY_DIR}
EXCLUDE_FROM_ALL
# Parse arguments.
set(options EXCLUDE_FROM_ALL)
set(one_value_args
USE_SYSTEM_PACKAGE
PACKAGE_NAME
LIBRARY_NAME
GIT_REPO
GIT_TAG
CUSTOM_CMAKE
)
set(multi_value_args PATCH_COMMAND TARGETS)
cmake_parse_arguments(
_ARGS
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
# Check if all targets are found.
if(NOT _ARGS_TARGETS)
message(FATAL_ERROR "mujoco::FindOrFetch: TARGETS must be specified.")
endif()
set(targets_found TRUE)
message(CHECK_START
"mujoco::FindOrFetch: checking for targets in package `${_ARGS_PACKAGE_NAME}`"
)
foreach(target ${_ARGS_TARGETS})
if(NOT TARGET ${target})
message(CHECK_FAIL "target `${target}` not defined.")
set(targets_found FALSE)
break()
endif()
endforeach()
# If targets are not found, use `find_package` or `FetchContent...` to get it.
if(NOT targets_found)
if(${_ARGS_USE_SYSTEM_PACKAGE})
message(CHECK_START
"mujoco::FindOrFetch: finding `${_ARGS_PACKAGE_NAME}` in system packages..."
)
find_package(${_ARGS_PACKAGE_NAME} REQUIRED)
message(CHECK_PASS "found")
else()
set(USE_LOCAL_TARBALL FALSE)
if(MUJOCO_CMAKE_DEP_CACHE)
# Try to find versioned library tarball.
set(TARBALL_PATH "${MUJOCO_CMAKE_DEP_CACHE}/${_ARGS_LIBRARY_NAME}-${_ARGS_GIT_TAG}.tar.gz")
if(EXISTS "${TARBALL_PATH}")
set(USE_LOCAL_TARBALL TRUE)
endif()
endif()
if(_ARGS_PATCH_COMMAND)
set(_WRAPPED_PATCH_COMMAND ${CMAKE_COMMAND} -E env GIT_CEILING_DIRECTORIES=${CMAKE_BINARY_DIR} ${_ARGS_PATCH_COMMAND})
else()
set(_WRAPPED_PATCH_COMMAND)
endif()
set(FETCHCONTENT_QUIET OFF)
if(USE_LOCAL_TARBALL)
message(STATUS "mujoco::FindOrFetch: Using package cache for ${_ARGS_LIBRARY_NAME}: ${TARBALL_PATH}")
FetchContent_Declare(
${_ARGS_LIBRARY_NAME}
URL ${TARBALL_PATH}
PATCH_COMMAND ${_WRAPPED_PATCH_COMMAND}
)
else()
message(STATUS "mujoco::FindOrFetch: Using FetchContent for ${_ARGS_LIBRARY_NAME}: ${_ARGS_GIT_REPO}")
FetchContent_Declare(
${_ARGS_LIBRARY_NAME}
GIT_REPOSITORY ${_ARGS_GIT_REPO}
GIT_TAG ${_ARGS_GIT_TAG}
GIT_SHALLOW FALSE
PATCH_COMMAND ${_WRAPPED_PATCH_COMMAND}
UPDATE_DISCONNECTED TRUE
)
endif()
else()
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
if(${_ARGS_EXCLUDE_FROM_ALL})
FetchContent_GetProperties(${_ARGS_LIBRARY_NAME})
if(NOT ${${_ARGS_LIBRARY_NAME}_POPULATED})
FetchContent_Populate(${_ARGS_LIBRARY_NAME})
if(NOT "${_ARGS_CUSTOM_CMAKE}" STREQUAL "")
file(COPY
"${_ARGS_CUSTOM_CMAKE}"
DESTINATION "${${_ARGS_LIBRARY_NAME}_SOURCE_DIR}"
)
endif()
add_subdirectory(
${${_ARGS_LIBRARY_NAME}_SOURCE_DIR} ${${_ARGS_LIBRARY_NAME}_BINARY_DIR}
EXCLUDE_FROM_ALL
)
endif()
else()
FetchContent_MakeAvailable(${_ARGS_LIBRARY_NAME})
endif()
message(CHECK_PASS "Done")
endif()
message(CHECK_PASS "Done")
else()
message(CHECK_PASS "found")
endif()
else()
message(CHECK_PASS "found")
endif()
endmacro()
endmacro()
endif()
#.rst:
# FetchPackage
# ----------------------
#
# Fetches a package from a Git repository in order to satisfy dependencies.
#
# FetchPackage([PACKAGE_NAME [name]]
# [GIT_REPO [repo]]
# [GIT_TAG [tag]]
# [PATCH_COMMAND [cmd] [args]]
# )
#
# The command has the following parameters:
#
# Arguments:
# - ``PACKAGE_NAME`` name of the package.
# - ``GIT_REPO`` git repository to fetch the library from.
# - ``GIT_TAG`` tag reference when fetching the library from the git repo.
# - ``CUSTOM_CMAKE`` path to a custom CMakeLists.txt file to be used when
# fetching the library from the git repository.
# - ``PATCH_COMMAND`` Specifies a custom command to patch the sources after an
# update. See https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add
# for details on the parameter.
# - ``TARGETS`` (optional) list of targets to be satisfied. If any of these
# targets are not currently defined, this macro will attempt to fetch the
# package. If not specified, the package name will be used as the target.
#
# Note: This is a wrapper around FindOrFetch that sets EXCLUDE_FROM_ALL and
# USE_SYSTEM_PACKAGE to OFF.
if(NOT COMMAND FetchPackage)
function(FetchPackage)
cmake_parse_arguments(
_ARGS
"EXCLUDE_FROM_ALL"
"PACKAGE_NAME;GIT_REPO;GIT_TAG;CUSTOM_CMAKE"
"PATCH_COMMAND;TARGETS"
${ARGN}
)
if(NOT _ARGS_TARGETS)
set(_ARGS_TARGETS ${_ARGS_PACKAGE_NAME})
endif()
FindOrFetch(
PACKAGE_NAME ${_ARGS_PACKAGE_NAME}
LIBRARY_NAME ${_ARGS_PACKAGE_NAME}
GIT_REPO ${_ARGS_GIT_REPO}
GIT_TAG ${_ARGS_GIT_TAG}
CUSTOM_CMAKE ${_ARGS_CUSTOM_CMAKE}
PATCH_COMMAND ${_ARGS_PATCH_COMMAND}
TARGETS ${_ARGS_TARGETS}
USE_SYSTEM_PACKAGE OFF
EXCLUDE_FROM_ALL
)
endfunction()
endif()
+80 -30
View File
@@ -35,34 +35,33 @@ set(MUJOCO_DEP_VERSION_ccd
CACHE STRING "Version of `ccd` to be fetched."
)
set(MUJOCO_DEP_VERSION_qhull
c7bee59d068a69f427b1273e71cdc5bc455a5bdd
d1c2fc0caa5f644f3a0f220290d4a868c68ed4f6
CACHE STRING "Version of `qhull` to be fetched."
)
set(MUJOCO_DEP_VERSION_miniz
d10b03cc73475af673df40f06e5cefd1d5f940d9
CACHE STRING "Version of `miniz` to be fetched."
)
set(MUJOCO_DEP_VERSION_Eigen3
81044ec13df7608d0d9d86aff2ef9805fc69bed1
ea13a98decd497a8c5588fb5de71b57bcf10d864
CACHE STRING "Version of `Eigen3` to be fetched."
)
set(MUJOCO_DEP_VERSION_abseil
76bb24329e8bf5f39704eb10d21b9a80befa7c81 # LTS 20250512.0
5650e9cf76d3be4318d5fa3af38ee483ddfd5e4a # LTS 20260526.0
CACHE STRING "Version of `abseil` to be fetched."
)
set(MUJOCO_DEP_VERSION_gtest
52eb8108c5bdec04579160ae17225d66034bd723 # v1.17.0
063de7e9578f82b369302001269680b4b1553359 # v1.18.0
CACHE STRING "Version of `gtest` to be fetched."
)
set(MUJOCO_DEP_VERSION_benchmark
049f6e79cc3e8636cec21bbd94ed185b4a5f2653
834a61fc65e8b7885fcf177f1230ae4b897118fa
CACHE STRING "Version of `benchmark` to be fetched."
)
set(MUJOCO_DEP_VERSION_TriangleMeshDistance
2cb643de1436e1ba8e2be49b07ec5491ac604457
CACHE STRING "Version of `TriangleMeshDistance` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_lodepng)
mark_as_advanced(MUJOCO_DEP_VERSION_MarchingCubeCpp)
mark_as_advanced(MUJOCO_DEP_VERSION_tinyxml2)
@@ -73,7 +72,6 @@ mark_as_advanced(MUJOCO_DEP_VERSION_Eigen3)
mark_as_advanced(MUJOCO_DEP_VERSION_abseil)
mark_as_advanced(MUJOCO_DEP_VERSION_gtest)
mark_as_advanced(MUJOCO_DEP_VERSION_benchmark)
mark_as_advanced(MUJOCO_DEP_VERSION_TriangleMeshDistance)
include(FetchContent)
include(FindOrFetch)
@@ -106,7 +104,11 @@ if(NOT TARGET lodepng)
add_library(lodepng STATIC ${LODEPNG_HEADERS} ${LODEPNG_SRCS})
target_compile_options(lodepng PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(lodepng PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
target_include_directories(lodepng PUBLIC ${lodepng_SOURCE_DIR})
if(NOT EMSCRIPTEN)
target_include_directories(lodepng PUBLIC ${lodepng_SOURCE_DIR})
else()
target_include_directories(lodepng PUBLIC $<BUILD_INTERFACE:${lodepng_SOURCE_DIR}> $<INSTALL_INTERFACE:include>)
endif()
endif()
endif()
@@ -125,6 +127,10 @@ if(NOT TARGET marchingcubecpp)
endif()
set(QHULL_ENABLE_TESTING OFF)
# Patch changes in https://github.com/qhull/qhull/pull/173.patch
set(QHULL_PATCH_COMMAND
git --git-dir=. -c core.autocrlf=false -c core.whitespace=cr-at-eol apply --verbose --whitespace=fix --ignore-space-change ${mujoco_SOURCE_DIR}/cmake/qhull-support-emscripten.patch
)
findorfetch(
USE_SYSTEM_PACKAGE
@@ -140,6 +146,7 @@ findorfetch(
TARGETS
qhull
EXCLUDE_FROM_ALL
PATCH_COMMAND ${QHULL_PATCH_COMMAND}
)
# MuJoCo includes a file from libqhull_r which is not exported by the qhull include directories.
# Add it to the target.
@@ -168,6 +175,11 @@ findorfetch(
target_compile_options(tinyxml2 PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(tinyxml2 PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
# update cmake_minimum_required version for compatibility with newer version of cmake
if(NOT DEFINED CMAKE_POLICY_VERSION_MINIMUM)
set(CMAKE_POLICY_VERSION_MINIMUM ${MUJOCO_CMAKE_MIN_REQ})
set(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED ON)
endif()
findorfetch(
USE_SYSTEM_PACKAGE
OFF
@@ -183,23 +195,29 @@ findorfetch(
tinyobjloader
EXCLUDE_FROM_ALL
)
if(NOT TARGET trianglemeshdistance)
FetchContent_Declare(
trianglemeshdistance
GIT_REPOSITORY https://github.com/InteractiveComputerGraphics/TriangleMeshDistance.git
GIT_TAG ${MUJOCO_DEP_VERSION_TriangleMeshDistance}
)
FetchContent_GetProperties(trianglemeshdistance)
if(NOT trianglemeshdistance_POPULATED)
FetchContent_Populate(trianglemeshdistance)
include_directories(${trianglemeshdistance_SOURCE_DIR})
endif()
if(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED)
unset(CMAKE_POLICY_VERSION_MINIMUM)
unset(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED)
endif()
set(ENABLE_DOUBLE_PRECISION ON)
# build ccd in single precision when MuJoCo is built with mjUSESINGLE
if(CMAKE_C_FLAGS MATCHES "mjUSESINGLE")
set(ENABLE_DOUBLE_PRECISION OFF)
else()
set(ENABLE_DOUBLE_PRECISION ON)
endif()
set(CCD_HIDE_ALL_SYMBOLS ON)
# Patch changes in https://github.com/danfis/libccd/pull/83.patch
set(CCD_PATCH_COMMAND
git --git-dir=. -c core.autocrlf=false -c core.whitespace=cr-at-eol apply --verbose --whitespace=fix --ignore-space-change ${mujoco_SOURCE_DIR}/cmake/ccd-support-emscripten.patch
)
# update cmake_minimum_required version for compatibility with newer version of cmake
if(NOT DEFINED CMAKE_POLICY_VERSION_MINIMUM)
set(CMAKE_POLICY_VERSION_MINIMUM ${MUJOCO_CMAKE_MIN_REQ})
set(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED ON)
endif()
findorfetch(
USE_SYSTEM_PACKAGE
OFF
@@ -214,7 +232,12 @@ findorfetch(
TARGETS
ccd
EXCLUDE_FROM_ALL
PATCH_COMMAND ${CCD_PATCH_COMMAND}
)
if(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED)
unset(CMAKE_POLICY_VERSION_MINIMUM)
unset(CMAKE_POLICY_VERSION_MINIMUM_LOCALLY_DEFINED)
endif()
target_compile_options(ccd PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(ccd PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
@@ -229,7 +252,28 @@ if(WIN32)
endif()
endif()
if(MUJOCO_BUILD_TESTS)
if(DEFINED BUILD_TESTS)
set(_OLD_BUILD_TESTS "${BUILD_TESTS}")
set(_BUILD_TESTS_WAS_DEFINED TRUE)
else()
set(_BUILD_TESTS_WAS_DEFINED FALSE)
endif()
set(BUILD_TESTS OFF)
fetchpackage(
PACKAGE_NAME miniz
GIT_REPO https://github.com/richgel999/miniz.git
GIT_TAG ${MUJOCO_DEP_VERSION_miniz}
TARGETS miniz
)
if(_BUILD_TESTS_WAS_DEFINED)
set(BUILD_TESTS "${_OLD_BUILD_TESTS}")
else()
unset(BUILD_TESTS)
endif()
unset(_BUILD_TESTS_WAS_DEFINED)
if(MUJOCO_BUILD_TESTS OR MUJOCO_BUILD_STUDIO OR MUJOCO_USE_FILAMENT)
set(ABSL_PROPAGATE_CXX_STD ON)
# This specific version of Abseil does not have the following variable. We need to work with BUILD_TESTING
@@ -239,6 +283,9 @@ if(MUJOCO_BUILD_TESTS)
CACHE INTERNAL "Build tests."
)
set(ABSL_PATCH_COMMAND
git --git-dir=. -c core.autocrlf=false -c core.whitespace=cr-at-eol apply --verbose --whitespace=fix --ignore-space-change ${mujoco_SOURCE_DIR}/cmake/abseil-cpp-source_location.patch
)
set(ABSL_BUILD_TESTING OFF)
findorfetch(
USE_SYSTEM_PACKAGE
@@ -254,12 +301,17 @@ if(MUJOCO_BUILD_TESTS)
TARGETS
absl::core_headers
EXCLUDE_FROM_ALL
PATCH_COMMAND
${ABSL_PATCH_COMMAND}
)
set(BUILD_TESTING
${BUILD_TESTING_OLD}
CACHE BOOL "Build tests." FORCE
)
endif()
if(MUJOCO_BUILD_TESTS)
# Avoid linking errors on Windows by dynamically linking to the C runtime.
set(gtest_force_shared_crt
@@ -292,9 +344,7 @@ if(MUJOCO_BUILD_TESTS)
"sed"
"-i"
"-e"
"s/-std=c++11/-std=c++14/g"
"-e"
"s/HAVE_CXX_FLAG_STD_CXX11/HAVE_CXX_FLAG_STD_CXX14/g"
"s/-Wformat=2/-Wformat/g"
"${CMAKE_BINARY_DIR}/_deps/benchmark-src/CMakeLists.txt"
)
endif()
+8 -11
View File
@@ -18,20 +18,17 @@ include(CheckCSourceCompiles)
# linker.
function(get_mujoco_extra_link_options OUTPUT_VAR)
if(MSVC)
set(EXTRA_LINK_OPTIONS /OPT:REF /OPT:ICF=5)
set(EXTRA_LINK_OPTIONS /OPT:REF /OPT:ICF=5 /STACK:16777216)
else()
set(EXTRA_LINK_OPTIONS)
if(WIN32)
set(CMAKE_REQUIRED_FLAGS "-fuse-ld=lld-link")
check_c_source_compiles("int main() {}" SUPPORTS_LLD)
if(SUPPORTS_LLD)
set(EXTRA_LINK_OPTIONS
${EXTRA_LINK_OPTIONS}
-fuse-ld=lld-link
-Wl,/OPT:REF
-Wl,/OPT:ICF
)
check_c_source_compiles("int main() {}" SUPPORTS_LLD_LINK)
if(SUPPORTS_LLD_LINK)
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -fuse-ld=lld-link -Wl,/STACK:16777216 -Wl,/OPT:REF -Wl,/OPT:ICF)
else()
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -Wl,--stack,16777216)
endif()
else()
set(CMAKE_REQUIRED_FLAGS "-fuse-ld=lld")
@@ -46,12 +43,12 @@ function(get_mujoco_extra_link_options OUTPUT_VAR)
endif()
endif()
set(CMAKE_REQUIRED_FLAGS ${EXTRA_LINK_OPTIONS} "-Wl,--gc-sections")
set(CMAKE_REQUIRED_FLAGS "${EXTRA_LINK_OPTIONS} -Wl,--gc-sections")
check_c_source_compiles("int main() {}" SUPPORTS_GC_SECTIONS)
if(SUPPORTS_GC_SECTIONS)
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -Wl,--gc-sections)
else()
set(CMAKE_REQUIRED_FLAGS ${EXTRA_LINK_OPTIONS} "-Wl,-dead_strip")
set(CMAKE_REQUIRED_FLAGS "${EXTRA_LINK_OPTIONS} -Wl,-dead_strip")
check_c_source_compiles("int main() {}" SUPPORTS_DEAD_STRIP)
if(SUPPORTS_DEAD_STRIP)
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} -Wl,-dead_strip)
+16 -4
View File
@@ -15,10 +15,14 @@
# Global compilation settings
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_EXTENSIONS OFF)
if(EMSCRIPTEN)
set(CMAKE_C_EXTENSIONS ON)
else()
set(CMAKE_C_EXTENSIONS OFF)
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # For LLVM tooling
if(NOT CMAKE_CONFIGURATION_TYPES)
@@ -104,8 +108,16 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang
endif()
endif()
if(NOT CMAKE_INTERPROCEDURAL_OPTIMIZATION AND (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug"))
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
# Provide a user-facing option to control Link-Time Optimization (LTO/IPO).
# When ON (the default), LTO is enabled for non-Debug builds unless the caller
# has already set CMAKE_INTERPROCEDURAL_OPTIMIZATION explicitly.
# Users can disable LTO entirely with -DMUJOCO_ENABLE_LTO=OFF.
option(MUJOCO_ENABLE_LTO "Enable Link-Time Optimization (LTO) for non-Debug builds." ON)
if(MUJOCO_ENABLE_LTO)
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION AND (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug"))
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
endif()
include(MujocoHarden)
+7 -2
View File
@@ -80,11 +80,13 @@ function(
_bin_dir
_lib_dir
)
get_filename_component(_bin_dir_abs "${_bin_dir}" ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
get_filename_component(_lib_dir_abs "${_lib_dir}" ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
file(
RELATIVE_PATH
_rel_path
${_bin_dir}
${_lib_dir}
${_bin_dir_abs}
${_lib_dir_abs}
)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(${_output_var}
@@ -100,6 +102,9 @@ function(
endfunction()
function(target_add_rpath)
if(WIN32)
return()
endif()
set(_options USE_LINK_PATH)
set(_oneValueArgs INSTALL_NAME_DIR INSTALL_DIRECTORY)
set(_multiValueArgs TARGETS LIB_DIRS DEPENDS)
+23
View File
@@ -0,0 +1,23 @@
diff --git a/absl/base/options.h b/absl/base/options.h
--- a/absl/base/options.h
+++ b/absl/base/options.h
@@ -99,6 +99,6 @@
// the source location type is an alias of std::source_location type, use the
// feature macro ABSL_USES_STD_SOURCE_LOCATION.
//
-#define ABSL_OPTION_USE_STD_SOURCE_LOCATION 2
+#define ABSL_OPTION_USE_STD_SOURCE_LOCATION 0
// ABSL_OPTION_USE_STD_ORDERING
diff --git a/absl/base/config.h b/absl/base/config.h
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -543,5 +543,7 @@
#ifdef __has_include
#if __has_include(<source_location>)
-#define ABSL_HAVE_STD_SOURCE_LOCATION 1
+#if !defined(__clang__) || ABSL_HAVE_BUILTIN(__builtin_source_location)
+#define ABSL_HAVE_STD_SOURCE_LOCATION 1
+#endif
#endif
#else
+22
View File
@@ -0,0 +1,22 @@
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1407080..b4dea44 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -49,9 +49,14 @@ target_include_directories(ccd PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
if(NOT WIN32)
- find_library(LIBM_LIBRARY NAMES m)
- if(NOT LIBM_LIBRARY)
- message(FATAL_ERROR "Could NOT find required library LibM")
+ if (EMSCRIPTEN)
+ set(LIBM_LIBRARY "-lm")
+ message("Subtitute LibM with emscripten -lm")
+ else()
+ find_library(LIBM_LIBRARY NAMES m)
+ if(NOT LIBM_LIBRARY)
+ message(FATAL_ERROR "Could NOT find required library LibM")
+ endif()
endif()
target_link_libraries(ccd "${LIBM_LIBRARY}")
if(BUILD_SHARED_LIBS)
+543
View File
@@ -0,0 +1,543 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 016e5ec5d..d2a6aae37 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,12 +11,7 @@ cmake_minimum_required(VERSION 3.22.1)
# Unsupported environment
# ==================================================================================================
-# Filament does not support MSYS2-based environment on Windows. See issue #9968.
-if(DEFINED ENV{MSYSTEM})
- message(FATAL_ERROR
- "MSYS2 Subsystem detected($ENV{MSYSTEM}). "
- "Filament does not support MSYS2-based environment on Windows.")
-endif()
+
# ==================================================================================================
# Toolchain configuration
@@ -264,57 +259,59 @@ if (WIN32)
# __declspec(dllexport) in front of each functions).
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
- # The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
- # global method here:
- if (${USE_STATIC_CRT})
- add_compile_options(
- $<$<CONFIG:>:/MT>
- $<$<CONFIG:Debug>:/MTd>
- $<$<CONFIG:Release>:/MT>
- )
- else()
- add_compile_options(
- $<$<CONFIG:>:/MD>
- $<$<CONFIG:Debug>:/MDd>
- $<$<CONFIG:Release>:/MD>
- )
- endif()
-
- # TODO: Figure out why pdb generation messes with incremental compilaton.
- # IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Z7")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
-
- # In RELEASE, also generate PDBs.
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
-
- # In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
- # Instead generate debug info directly inside obj files.
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
-
- # Special settings when building on CI.
- if (${FILAMENT_WINDOWS_CI_BUILD})
- set(LinkerFlags
- CMAKE_SHARED_LINKER_FLAGS_DEBUG
- CMAKE_EXE_LINKER_FLAGS_DEBUG
- CMAKE_MODULE_LINKER_FLAGS_DEBUG
+ if (MSVC)
+ # The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
+ # global method here:
+ if (${USE_STATIC_CRT})
+ add_compile_options(
+ $<$<CONFIG:>:/MT>
+ $<$<CONFIG:Debug>:/MTd>
+ $<$<CONFIG:Release>:/MT>
)
- foreach(LinkerFlag ${LinkerFlags})
- # The /debug flag outputs .pdb files, which we don't need on CI.
- string(REPLACE "/debug" "" ${LinkerFlag} ${${LinkerFlag}})
-
- # The /INCREMENTAL flag outputs .ilk files for incremental linking. These are huge, and
- # we don't need them on CI.
- string(REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" ${LinkerFlag} ${${LinkerFlag}})
- endforeach()
-
- # We turn off compile-time optimizations for CI, as options that speed up the compile-time
- # (e.g. /MP) might increase memory usage, leading to instabilities on limited CI machines.
- option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" OFF)
- else()
- option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" ON)
+ else()
+ add_compile_options(
+ $<$<CONFIG:>:/MD>
+ $<$<CONFIG:Debug>:/MDd>
+ $<$<CONFIG:Release>:/MD>
+ )
+ endif()
+
+ # TODO: Figure out why pdb generation messes with incremental compilaton.
+ # IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Z7")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
+
+ # In RELEASE, also generate PDBs.
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
+
+ # In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
+ # Instead generate debug info directly inside obj files.
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
+
+ # Special settings when building on CI.
+ if (${FILAMENT_WINDOWS_CI_BUILD})
+ set(LinkerFlags
+ CMAKE_SHARED_LINKER_FLAGS_DEBUG
+ CMAKE_EXE_LINKER_FLAGS_DEBUG
+ CMAKE_MODULE_LINKER_FLAGS_DEBUG
+ )
+ foreach(LinkerFlag ${LinkerFlags})
+ # The /debug flag outputs .pdb files, which we don't need on CI.
+ string(REPLACE "/debug" "" ${LinkerFlag} ${${LinkerFlag}})
+
+ # The /INCREMENTAL flag outputs .ilk files for incremental linking. These are huge, and
+ # we don't need them on CI.
+ string(REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" ${LinkerFlag} ${${LinkerFlag}})
+ endforeach()
+
+ # We turn off compile-time optimizations for CI, as options that speed up the compile-time
+ # (e.g. /MP) might increase memory usage, leading to instabilities on limited CI machines.
+ option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" OFF)
+ else()
+ option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" ON)
+ endif()
endif()
if (MSVC)
@@ -361,7 +358,7 @@ endif()
# Detect use of the clang-cl.exe frontend, which does not support all of clangs normal options
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
- message(FATAL_ERROR "Building with Clang on Windows is no longer supported. Use MSVC 2019 instead.")
+ message(WARNING "Building with Clang on Windows is experimental (re-enabled by patch).")
endif()
endif()
@@ -393,7 +390,7 @@ if (APPLE AND NOT IOS)
endif()
set(CXX_STANDARD "-std=c++20")
-if (WIN32)
+if (MSVC)
set(CXX_STANDARD "/std:c++20")
endif()
@@ -787,9 +784,14 @@ function(combine_static_libs TARGET OUTPUT DEPS)
endforeach()
if (WIN32)
+ if (MSVC)
+ set(AR_COMMAND "${CMAKE_AR}" /nologo /out:temp.lib ${DEPS_FILES})
+ else()
+ set(AR_COMMAND "${CMAKE_AR}" rcs temp.lib ${DEPS_FILES})
+ endif()
add_custom_command(
TARGET ${TARGET} POST_BUILD
- COMMAND lib.exe /nologo /out:temp.lib ${DEPS_FILES}
+ COMMAND ${AR_COMMAND}
COMMAND "${CMAKE_COMMAND}" -E rename temp.lib ${OUTPUT}
COMMENT "Combining ${target} dependencies into single shared library"
VERBATIM
diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt
index c334d0a9f..9f8004e3d 100644
--- a/filament/CMakeLists.txt
+++ b/filament/CMakeLists.txt
@@ -808,6 +808,9 @@ else()
-Wover-aligned
-Werror
)
+ if (WIN32)
+ list(APPEND FILAMENT_WARNINGS -Wno-error=cast-function-type-mismatch -Wno-error=unused-variable -Wno-error=microsoft-unqualified-friend)
+ endif()
endif()
target_compile_options(${TARGET} PRIVATE
diff --git a/filament/backend/CMakeLists.txt b/filament/backend/CMakeLists.txt
index 78c05dd22..4f8c0bf3d 100644
--- a/filament/backend/CMakeLists.txt
+++ b/filament/backend/CMakeLists.txt
@@ -525,6 +525,10 @@ else()
)
endif()
+if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ list(APPEND FILAMENT_WARNINGS -Wno-error=cast-function-type-mismatch -Wno-error=unused-variable -Wno-error=microsoft-unqualified-friend)
+endif()
+
if (APPLE)
# Turn on Automatic Reference Counting.
target_compile_options(${TARGET} PRIVATE "-fobjc-arc")
diff --git a/filament/backend/src/CommandStream.cpp b/filament/backend/src/CommandStream.cpp
index 7146800f6..d7973ffd4 100644
--- a/filament/backend/src/CommandStream.cpp
+++ b/filament/backend/src/CommandStream.cpp
@@ -57,7 +57,7 @@ static void printParameterPack(io::ostream& out, const FIRST& first, const REMAI
printParameterPack(out, rest...);
}
-static UTILS_NOINLINE UTILS_UNUSED std::string_view extractMethodName(std::string_view command) noexcept { // NOLINT(*-exception-escape)
+UTILS_UNUSED static UTILS_NOINLINE std::string_view extractMethodName(std::string_view command) noexcept { // NOLINT(*-exception-escape)
constexpr char startPattern[] = "::Command<&filament::backend::Driver::";
auto pos = command.rfind(startPattern);
auto end = command.rfind('(');
diff --git a/filament/backend/src/opengl/platforms/PlatformWGL.cpp b/filament/backend/src/opengl/platforms/PlatformWGL.cpp
index 318430289..8664ea3cf 100644
--- a/filament/backend/src/opengl/platforms/PlatformWGL.cpp
+++ b/filament/backend/src/opengl/platforms/PlatformWGL.cpp
@@ -251,7 +251,7 @@ Platform::SwapChain* PlatformWGL::createSwapChain(uint32_t width, uint32_t heigh
// WS_POPUP was chosen for the window style here after some experimentation.
// For some reason, using other window styles resulted in corrupted pixel buffers when using
// readPixels.
- RECT rect = {0, 0, width, height};
+ RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, WS_POPUP, FALSE);
width = rect.right - rect.left;
height = rect.bottom - rect.top;
diff --git a/libs/ibl/src/CubemapIBL.cpp b/libs/ibl/src/CubemapIBL.cpp
index 60f83174d..1deb01857 100644
--- a/libs/ibl/src/CubemapIBL.cpp
+++ b/libs/ibl/src/CubemapIBL.cpp
@@ -56,7 +56,7 @@ static float3 hemisphereImportanceSampleDggx(float2 u, float a) { // pdf = D(a)
return { sinTheta * std::cos(phi), sinTheta * std::sin(phi), cosTheta };
}
-static float3 UTILS_UNUSED hemisphereCosSample(float2 u) { // pdf = cosTheta / F_PI;
+UTILS_UNUSED static float3 hemisphereCosSample(float2 u) { // pdf = cosTheta / F_PI;
const float phi = 2.0f * (float) F_PI * u.x;
const float cosTheta2 = 1 - u.y;
const float cosTheta = std::sqrt(cosTheta2);
@@ -64,7 +64,7 @@ static float3 UTILS_UNUSED hemisphereCosSample(float2 u) { // pdf = cosTheta /
return { sinTheta * std::cos(phi), sinTheta * std::sin(phi), cosTheta };
}
-static float3 UTILS_UNUSED hemisphereUniformSample(float2 u) { // pdf = 1.0 / (2.0 * F_PI);
+UTILS_UNUSED static float3 hemisphereUniformSample(float2 u) { // pdf = 1.0 / (2.0 * F_PI);
const float phi = 2.0f * (float) F_PI * u.x;
const float cosTheta = 1 - u.y;
const float sinTheta = std::sqrt(1 - cosTheta * cosTheta);
@@ -128,7 +128,7 @@ static float3 UTILS_UNUSED hemisphereUniformSample(float2 u) { // pdf = 1.0 / (2
* | |
* +--------------------------------------------+
*/
-static float3 UTILS_UNUSED hemisphereImportanceSampleDCharlie(float2 u, float a) { // pdf = DistributionCharlie() * cosTheta
+UTILS_UNUSED static float3 hemisphereImportanceSampleDCharlie(float2 u, float a) { // pdf = DistributionCharlie() * cosTheta
const float phi = 2.0f * (float) F_PI * u.x;
const float sinTheta = std::pow(u.y, a / (2 * a + 1));
@@ -144,7 +144,7 @@ static float DistributionGGX(float NoH, float linearRoughness) {
return (a * a) / ((float) F_PI * f * f);
}
-static float UTILS_UNUSED DistributionAshikhmin(float NoH, float linearRoughness) {
+UTILS_UNUSED static float DistributionAshikhmin(float NoH, float linearRoughness) {
float a = linearRoughness;
float a2 = a * a;
float cos2h = NoH * NoH;
@@ -153,7 +153,7 @@ static float UTILS_UNUSED DistributionAshikhmin(float NoH, float linearRoughness
return 1.0f / ((float) F_PI * (1 + 4 * a2)) * (sin4h + 4 * std::exp(-cos2h / (a2 * sin2h)));
}
-static float UTILS_UNUSED DistributionCharlie(float NoH, float linearRoughness) {
+UTILS_UNUSED static float DistributionCharlie(float NoH, float linearRoughness) {
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
float a = linearRoughness;
float invAlpha = 1 / a;
@@ -176,7 +176,7 @@ static float Visibility(float NoV, float NoL, float a) {
return 0.5f / (GGXV + GGXL);
}
-static float UTILS_UNUSED VisibilityAshikhmin(float NoV, float NoL, float /*a*/) {
+UTILS_UNUSED static float VisibilityAshikhmin(float NoV, float NoL, float /*a*/) {
// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
return 1 / (4 * (NoL + NoV - NoL * NoV));
}
@@ -634,7 +634,7 @@ void CubemapIBL::diffuseIrradiance(JobSystem& js, Cubemap& dst, const std::vecto
}
// Not importance-sampled
-static float2 UTILS_UNUSED DFV_NoIS(float NoV, float roughness, size_t numSamples) {
+UTILS_UNUSED static float2 DFV_NoIS(float NoV, float roughness, size_t numSamples) {
float2 r = 0;
const float linearRoughness = roughness * roughness;
const float3 V(std::sqrt(1 - NoV * NoV), 0, NoV);
@@ -832,7 +832,7 @@ static float2 DFV_Multiscatter(float NoV, float linearRoughness, size_t numSampl
return r * (4.0f / numSamples);
}
-static float UTILS_UNUSED DFV_LazanyiTerm(float NoV, float linearRoughness, size_t numSamples) {
+UTILS_UNUSED static float DFV_LazanyiTerm(float NoV, float linearRoughness, size_t numSamples) {
float r = 0;
const float cosThetaMax = (float) std::cos(81.7 * F_PI / 180.0);
const float q = 1.0f / (cosThetaMax * pow6(1.0f - cosThetaMax));
@@ -958,7 +958,7 @@ static float DFV_Charlie_Uniform(float NoV, float linearRoughness, size_t numSam
* +---------------------------------------+
*
*/
-static float UTILS_UNUSED DFV_Charlie_IS(float NoV, float linearRoughness, size_t numSamples) {
+UTILS_UNUSED static float DFV_Charlie_IS(float NoV, float linearRoughness, size_t numSamples) {
float r = 0.0;
const float3 V(std::sqrt(1 - NoV * NoV), 0, NoV);
for (size_t i = 0; i < numSamples; i++) {
diff --git a/libs/ibl/src/CubemapSH.cpp b/libs/ibl/src/CubemapSH.cpp
index 5d22cb804..f8adccc71 100644
--- a/libs/ibl/src/CubemapSH.cpp
+++ b/libs/ibl/src/CubemapSH.cpp
@@ -685,7 +685,7 @@ void CubemapSH::renderPreScaledSH3Bands(JobSystem& js,
// Only used for debugging
// -----------------------------------------------------------------------------------------------
-float UTILS_UNUSED CubemapSH::Legendre(ssize_t l, ssize_t m, float x) {
+UTILS_UNUSED float CubemapSH::Legendre(ssize_t l, ssize_t m, float x) {
// evaluate an Associated Legendre Polynomial P(l,m,x) at x
float pmm = 1.0;
if (m > 0) {
@@ -711,7 +711,7 @@ float UTILS_UNUSED CubemapSH::Legendre(ssize_t l, ssize_t m, float x) {
}
// Only used for debugging
-float UTILS_UNUSED CubemapSH::TSH(int l, int m, const float3& d) {
+UTILS_UNUSED float CubemapSH::TSH(int l, int m, const float3& d) {
if (l==0 && m==0) {
return 1 / (2*sqrt(F_PI));
} else if (l==1 && m==-1) {
@@ -734,7 +734,7 @@ float UTILS_UNUSED CubemapSH::TSH(int l, int m, const float3& d) {
return 0;
}
-void UTILS_UNUSED CubemapSH::printShBase(std::ostream& out, int l, int m) {
+UTILS_UNUSED void CubemapSH::printShBase(std::ostream& out, int l, int m) {
if (l<3 && std::abs(m) <= l) {
const char* d = nullptr;
float c = 0;
diff --git a/libs/imageio/src/ImageEncoder.cpp b/libs/imageio/src/ImageEncoder.cpp
index 9f83c6c62..6593581e3 100644
--- a/libs/imageio/src/ImageEncoder.cpp
+++ b/libs/imageio/src/ImageEncoder.cpp
@@ -867,39 +867,39 @@ const uint32_t DDS_FOURCC_DX10 = 0x30315844; // "DX10"
#pragma pack(push, 1)
struct DDS_PIXELFORMAT {
- uint32_t UTILS_UNUSED dwSize;
+ UTILS_UNUSED uint32_t dwSize;
uint32_t dwFlags;
- uint32_t UTILS_UNUSED dwFourCC;
- uint32_t UTILS_UNUSED dwRGBBitCount;
- uint32_t UTILS_UNUSED dwRBitMask;
- uint32_t UTILS_UNUSED dwGBitMask;
- uint32_t UTILS_UNUSED dwBBitMask;
- uint32_t UTILS_UNUSED dwABitMask;
+ UTILS_UNUSED uint32_t dwFourCC;
+ UTILS_UNUSED uint32_t dwRGBBitCount;
+ UTILS_UNUSED uint32_t dwRBitMask;
+ UTILS_UNUSED uint32_t dwGBitMask;
+ UTILS_UNUSED uint32_t dwBBitMask;
+ UTILS_UNUSED uint32_t dwABitMask;
};
struct DDS_HEADER {
- uint32_t UTILS_UNUSED dwSize;
+ UTILS_UNUSED uint32_t dwSize;
uint32_t dwFlags;
- uint32_t UTILS_UNUSED dwHeight;
- uint32_t UTILS_UNUSED dwWidth;
- uint32_t UTILS_UNUSED dwPitchOrLinearSize;
- uint32_t UTILS_UNUSED dwDepth;
- uint32_t UTILS_UNUSED dwMipMapCount;
- uint32_t UTILS_UNUSED dwReserved1[11];
- DDS_PIXELFORMAT UTILS_UNUSED ddspf;
- uint32_t UTILS_UNUSED dwCaps;
- uint32_t UTILS_UNUSED dwCaps2;
- uint32_t UTILS_UNUSED dwCaps3;
- uint32_t UTILS_UNUSED dwCaps4;
- uint32_t UTILS_UNUSED dwReserved2;
+ UTILS_UNUSED uint32_t dwHeight;
+ UTILS_UNUSED uint32_t dwWidth;
+ UTILS_UNUSED uint32_t dwPitchOrLinearSize;
+ UTILS_UNUSED uint32_t dwDepth;
+ UTILS_UNUSED uint32_t dwMipMapCount;
+ UTILS_UNUSED uint32_t dwReserved1[11];
+ UTILS_UNUSED DDS_PIXELFORMAT ddspf;
+ UTILS_UNUSED uint32_t dwCaps;
+ UTILS_UNUSED uint32_t dwCaps2;
+ UTILS_UNUSED uint32_t dwCaps3;
+ UTILS_UNUSED uint32_t dwCaps4;
+ UTILS_UNUSED uint32_t dwReserved2;
};
struct DDS_HEADER_DXT10 {
uint32_t dxgiFormat;
- uint32_t UTILS_UNUSED resourceDimension;
- uint32_t UTILS_UNUSED miscFlag;
- uint32_t UTILS_UNUSED arraySize;
- uint32_t UTILS_UNUSED miscFlags2;
+ UTILS_UNUSED uint32_t resourceDimension;
+ UTILS_UNUSED uint32_t miscFlag;
+ UTILS_UNUSED uint32_t arraySize;
+ UTILS_UNUSED uint32_t miscFlags2;
};
#pragma pack(pop)
diff --git a/libs/utils/include/utils/StructureOfArrays.h b/libs/utils/include/utils/StructureOfArrays.h
index 7ee9da70b..956aa8ec0 100644
--- a/libs/utils/include/utils/StructureOfArrays.h
+++ b/libs/utils/include/utils/StructureOfArrays.h
@@ -742,7 +742,7 @@ typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
IteratorValue const& rhs, std::index_sequence<Is...>) {
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue const& rhs)
- auto UTILS_UNUSED l = { (soa->elementAt<Is>(index) = std::get<Is>(rhs.elements), 0)... };
+ UTILS_UNUSED auto l = { (soa->elementAt<Is>(index) = std::get<Is>(rhs.elements), 0)... };
return *this;
}
@@ -751,7 +751,7 @@ template<size_t... Is>
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
Structure const& rhs, std::index_sequence<Is...>) {
- auto UTILS_UNUSED l = {(soa->template elementAt<Is>(index) = std::get<Is>(rhs), 0)...};
+ UTILS_UNUSED auto l = {(soa->template elementAt<Is>(index) = std::get<Is>(rhs), 0)...};
return *this;
}
@@ -760,7 +760,7 @@ template<size_t... Is>
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
Structure&& rhs, std::index_sequence<Is...>) noexcept {
- auto UTILS_UNUSED l = {(soa->template elementAt<Is>(index) = std::move(std::get<Is>(rhs)), 0)...};
+ UTILS_UNUSED auto l = {(soa->template elementAt<Is>(index) = std::move(std::get<Is>(rhs)), 0)...};
return *this;
}
@@ -770,7 +770,7 @@ typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
IteratorValue&& rhs, std::index_sequence<Is...>) noexcept {
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue&& rhs) noexcept
- auto UTILS_UNUSED l = {
+ UTILS_UNUSED auto l = {
(soa->elementAt<Is>(index) = std::move(std::get<Is>(rhs.elements)), 0)... };
return *this;
}
diff --git a/libs/utils/include/utils/compiler.h b/libs/utils/include/utils/compiler.h
index f678e36e7..3f1b94cf3 100644
--- a/libs/utils/include/utils/compiler.h
+++ b/libs/utils/include/utils/compiler.h
@@ -228,7 +228,7 @@
// AND multi-threading is enabled (UTILS_HAS_THREADING is not 0).
// This prevents compile failures on single-threaded targets or builds where standard
// annotations are disabled by default in the platform's standard library headers.
-#if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && UTILS_HAS_THREADING
+#if defined(_LIBCPP_VERSION) && defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && UTILS_HAS_THREADING && !defined(_WIN32)
#define UTILS_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x))
#else
#define UTILS_THREAD_ANNOTATION_ATTRIBUTE(x)
diff --git a/libs/utils/src/CallStack.cpp b/libs/utils/src/CallStack.cpp
index 644df0c97..dda872816 100644
--- a/libs/utils/src/CallStack.cpp
+++ b/libs/utils/src/CallStack.cpp
@@ -92,7 +92,7 @@ void CallStack::update(size_t ignore) noexcept {
update_gcc(ignore);
}
-void CallStack::update_gcc(size_t UTILS_UNUSED ignore) noexcept {
+void CallStack::update_gcc(UTILS_UNUSED size_t ignore) noexcept {
// reset the object
ssize_t size = 0;
@@ -141,7 +141,7 @@ CString CallStack::demangleTypeName(const char* mangled) {
// ------------------------------------------------------------------------------------------------
template <typename Stream>
-Stream& printCallStack(Stream& stream, CallStack const& UTILS_UNUSED callstack) {
+Stream& printCallStack(Stream& stream, UTILS_UNUSED CallStack const& callstack) {
#if HAS_EXECINFO
size_t const size = callstack.getFrameCount();
char buf[1024];
diff --git a/third_party/getopt/src/getopt.c b/third_party/getopt/src/getopt.c
index cf2984af0..1dacef630 100644
--- a/third_party/getopt/src/getopt.c
+++ b/third_party/getopt/src/getopt.c
@@ -1,5 +1,6 @@
#ifdef _WIN32
#include <windows.h>
+#include <io.h>
#else
#include <unistd.h>
#endif
diff --git a/third_party/spirv-cross/CMakeLists.txt b/third_party/spirv-cross/CMakeLists.txt
index 8e5129c8b..761911083 100644
--- a/third_party/spirv-cross/CMakeLists.txt
+++ b/third_party/spirv-cross/CMakeLists.txt
@@ -20,7 +20,11 @@
#
cmake_minimum_required(VERSION 3.10)
-set(CMAKE_CXX_STANDARD 11)
+if (WIN32)
+ set(CMAKE_CXX_STANDARD 17)
+else()
+ set(CMAKE_CXX_STANDARD 11)
+endif()
set(CMAKE_CXX_EXTENSIONS OFF)
# Avoid a warning if parent project sets VERSION in project().
diff --git a/third_party/spirv-cross/tnt/CMakeLists.txt b/third_party/spirv-cross/tnt/CMakeLists.txt
index 4cb9bdccb..086bec67a 100644
--- a/third_party/spirv-cross/tnt/CMakeLists.txt
+++ b/third_party/spirv-cross/tnt/CMakeLists.txt
@@ -37,7 +37,11 @@ endif()
# -DCMAKE_CXX_COMPILE_FLAGS
# However, we require the C++11 dialect.
if (NOT "${MSVC}")
- set(spirv-compiler-options ${spirv-compiler-options} -std=c++11 -Wall -Wextra -Werror -Wshadow)
+ if (WIN32)
+ set(spirv-compiler-options ${spirv-compiler-options} -std=c++17 -Wall -Wextra -Werror -Wshadow)
+ else()
+ set(spirv-compiler-options ${spirv-compiler-options} -std=c++11 -Wall -Wextra -Werror -Wshadow)
+ endif()
set(spirv-compiler-defines ${spirv-compiler-defines} __STDC_LIMIT_MACROS)
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
diff --git a/tools/cmgen/src/cmgen.cpp b/tools/cmgen/src/cmgen.cpp
index 722e5737c..288be3ce9 100644
--- a/tools/cmgen/src/cmgen.cpp
+++ b/tools/cmgen/src/cmgen.cpp
@@ -131,7 +131,7 @@ static void outputSh(std::ostream& out, const std::unique_ptr<filament::math::fl
size_t numBands);
static void outputBinarySh(std::ostream& out, const std::unique_ptr<filament::math::float3[]>& sh,
size_t numBands);
-static void UTILS_UNUSED outputSpectrum(std::ostream& out,
+UTILS_UNUSED static void outputSpectrum(std::ostream& out,
const std::unique_ptr<filament::math::float3[]>& sh, size_t numBands);
static void saveImage(const std::string& path, ImageEncoder::Format format, const Image& image,
const std::string& compression);
@@ -846,7 +846,7 @@ void outputBinarySh(std::ostream& out,
}
-void UTILS_UNUSED outputSpectrum(std::ostream& out,
+UTILS_UNUSED void outputSpectrum(std::ostream& out,
const std::unique_ptr<filament::math::float3[]>& sh, size_t numBands) {
// We assume a symetrical function (i.e. m!=0 terms are zero)
for (ssize_t l = 0; l < numBands; l++) {
+8
View File
@@ -0,0 +1,8 @@
diff --git a/cmake/cpu.cmake b/cmake/cpu.cmake
--- a/cmake/cpu.cmake
+++ b/cmake/cpu.cmake
@@ -121,3 +121,3 @@
# Explicitly disable SIMD.
- if(SIMD_DISABLE_FLAGS)
+ if(SIMD_DISABLE_FLAGS AND NOT APPLE)
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
+30
View File
@@ -0,0 +1,30 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0423820..c5295c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -360,6 +360,7 @@ if (NOT DEFINED CMAKE_BUILD_WITH_INSTALL_RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
endif ()
+if (NOT EMSCRIPTEN)
add_library(${qhull_SHAREDR} SHARED
${libqhullr_SOURCES}
src/libqhull_r/qhull_r-exports.def)
@@ -420,7 +421,7 @@ set_target_properties(${qhull_SHAREDP} PROPERTIES
if(UNIX)
target_link_libraries(${qhull_SHAREDP} m)
endif(UNIX)
-
+endif (NOT EMSCRIPTEN)
# ---------------------------------------
# Define static libraries qhullstatic (non-reentrant) and qhullstatic_r (reentrant)
# ---------------------------------------
@@ -475,7 +476,7 @@ if(NOT ${BUILD_STATIC_LIBS})
set_target_properties(${qhull_STATICR} PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(${qhull_CPP} PROPERTIES EXCLUDE_FROM_ALL TRUE)
endif()
-if(NOT ${BUILD_SHARED_LIBS})
+if(NOT ${BUILD_SHARED_LIBS} AND NOT EMSCRIPTEN)
set_target_properties(${qhull_SHARED} PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(${qhull_SHAREDR} PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(${qhull_SHAREDP} PROPERTIES EXCLUDE_FROM_ALL TRUE)
@@ -0,0 +1,28 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_atkinson_hyperlegible_mono
154d50362016cc3e873eb21d242cd0772384c8f9
CACHE STRING "Tag/version of `atkinson_hyperlegible_mono` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_atkinson_hyperlegible_mono)
include(FindOrFetch)
fetchpackage(
PACKAGE_NAME atkinson_hyperlegible_mono
GIT_REPO https://github.com/googlefonts/atkinson-hyperlegible-next-mono.git
GIT_TAG ${MUJOCO_DEP_VERSION_atkinson_hyperlegible_mono}
CUSTOM_CMAKE "${CMAKE_SOURCE_DIR}/cmake/third_party_deps/atkinson_hyperlegible_mono/CMakeLists.txt"
)
@@ -1,4 +1,4 @@
# Copyright 2023 DeepMind Technologies Limited
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,6 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
mujoco_test(thread_pool_test)
mujoco_test(thread_queue_test)
# Data-only package.
@@ -0,0 +1,28 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_atkinson_hyperlegible_next
5d633f80fc654ef5fffa7cfc257528685158dcef
CACHE STRING "Tag/version of `atkinson_hyperlegible_next` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_atkinson_hyperlegible_next)
include(FindOrFetch)
fetchpackage(
PACKAGE_NAME atkinson_hyperlegible_next
GIT_REPO https://github.com/googlefonts/atkinson-hyperlegible-next.git
GIT_TAG ${MUJOCO_DEP_VERSION_atkinson_hyperlegible_next}
CUSTOM_CMAKE "${CMAKE_SOURCE_DIR}/cmake/third_party_deps/atkinson_hyperlegible_next/CMakeLists.txt"
)
@@ -0,0 +1,15 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Data-only package.
+28
View File
@@ -0,0 +1,28 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_dear_imgui
913a3c60561bb07e8fd410ec7d4a8f6f485defd6
CACHE STRING "Tag/version of `dear_imgui` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_dear_imgui)
include(FindOrFetch)
fetchpackage(
PACKAGE_NAME dear_imgui
GIT_REPO https://github.com/ocornut/imgui.git
GIT_TAG ${MUJOCO_DEP_VERSION_dear_imgui}
CUSTOM_CMAKE "${CMAKE_SOURCE_DIR}/cmake/third_party_deps/dear_imgui/CMakeLists.txt"
)
@@ -0,0 +1,77 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_library(dear_imgui STATIC)
set(MUJOCO_DEAR_IMGUI_SOURCE_DIR "${dear_imgui_SOURCE_DIR}" CACHE INTERNAL "")
target_include_directories(dear_imgui
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}
)
target_sources(dear_imgui
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui.h
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui.cpp
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui_internal.h
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui_draw.cpp
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui_tables.cpp
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui_widgets.cpp
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/imgui_demo.cpp
)
function(mujoco_add_dear_imgui_sdl2_backend)
if(TARGET dear_imgui_SDL2 OR NOT TARGET SDL2::SDL2-static)
return()
endif()
add_library(dear_imgui_SDL2 STATIC)
target_include_directories(dear_imgui_SDL2
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}
)
target_sources(dear_imgui_SDL2
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp
)
target_link_libraries(dear_imgui_SDL2
SDL2::SDL2-static
)
endfunction()
# SDL2 backend. Filament uses base dear_imgui without SDL2; platform calls this
# helper again after SDL2 is pulled in.
mujoco_add_dear_imgui_sdl2_backend()
# OpenGL3 backend
add_library(dear_imgui_OpenGL3 STATIC)
target_include_directories(dear_imgui_OpenGL3
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}
)
target_sources(dear_imgui_OpenGL3
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/backends/imgui_impl_opengl3.h
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
)
# stdlib
add_library(dear_imgui_stdlib STATIC)
target_include_directories(dear_imgui_stdlib
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}
)
target_sources(dear_imgui_stdlib
PUBLIC
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/misc/cpp/imgui_stdlib.h
${MUJOCO_DEAR_IMGUI_SOURCE_DIR}/misc/cpp/imgui_stdlib.cpp
)
+83
View File
@@ -0,0 +1,83 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_filament
3bcc2a252bfefc31353f6097bb9bc238032571e0
CACHE STRING "Tag/version of `filament` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_filament)
include(FindOrFetch)
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)
# Filament's ShaderMinifier.cpp uses strlen without including <cstring>, and
# PostProcessManager.h uses std::optional without including <optional>.
set(CMAKE_CXX_FLAGS_OLD "${CMAKE_CXX_FLAGS}")
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FI cstring /FI optional")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include cstring -include optional")
endif()
# Filament generates deprecated warnings on MacOS.
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations")
endif()
set(FILAMENT_ENABLE_EXPERIMENTAL_GCC_SUPPORT ON)
set(FILAMENT_SKIP_SDL2 ON)
set(FILAMENT_SKIP_SAMPLES ON)
set(FILAMENT_USE_EXTERNAL_ABSL ON)
set(FILAMENT_USE_EXTERNAL_BENCHMARK ON)
set(FILAMENT_USE_EXTERNAL_GTEST ON)
if(WIN32)
set(USE_STATIC_CRT OFF)
add_compile_definitions(WIN32)
endif()
set(FILAMENT_PATCH_COMMAND
git --git-dir=. -c core.autocrlf=false -c core.whitespace=cr-at-eol apply --verbose --whitespace=fix --ignore-space-change ${mujoco_SOURCE_DIR}/cmake/filament-allow-clang-windows.patch
)
# MuJoCo fetches Abseil before Filament is configured. Filament's
# FILAMENT_USE_EXTERNAL_ABSL path calls find_package(absl), which can otherwise
# discover an unrelated package-manager Abseil config and collide with the
# targets already created by MuJoCo's fetched Abseil.
if(DEFINED CMAKE_DISABLE_FIND_PACKAGE_absl)
set(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_WAS_DEFINED TRUE)
set(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_OLD "${CMAKE_DISABLE_FIND_PACKAGE_absl}")
else()
set(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_WAS_DEFINED FALSE)
endif()
set(CMAKE_DISABLE_FIND_PACKAGE_absl TRUE)
fetchpackage(
PACKAGE_NAME filament
GIT_REPO https://github.com/google/filament.git
GIT_TAG ${MUJOCO_DEP_VERSION_filament}
PATCH_COMMAND ${FILAMENT_PATCH_COMMAND}
)
if(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_WAS_DEFINED)
set(CMAKE_DISABLE_FIND_PACKAGE_absl "${MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_OLD}")
else()
unset(CMAKE_DISABLE_FIND_PACKAGE_absl)
endif()
unset(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_WAS_DEFINED)
unset(MUJOCO_CMAKE_DISABLE_FIND_PACKAGE_ABSL_OLD)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}")
+28
View File
@@ -0,0 +1,28 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_font_awesome
a8386aae19e200ddb0f6845b5feeee5eb7013687
CACHE STRING "Tag/version of `font_awesome` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_font_awesome)
include(FindOrFetch)
fetchpackage(
PACKAGE_NAME font_awesome
GIT_REPO https://github.com/FortAwesome/Font-Awesome.git
GIT_TAG ${MUJOCO_DEP_VERSION_font_awesome}
CUSTOM_CMAKE "${CMAKE_SOURCE_DIR}/cmake/third_party_deps/font_awesome/CMakeLists.txt"
)
@@ -0,0 +1,15 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Data-only package.
+28
View File
@@ -0,0 +1,28 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_implot
ec7306ceb99d19ff193eb30dc74fa3598f5e7dc6
CACHE STRING "Tag/version of `implot` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_implot)
include(FindOrFetch)
fetchpackage(
PACKAGE_NAME implot
GIT_REPO https://github.com/epezent/implot.git
GIT_TAG ${MUJOCO_DEP_VERSION_implot}
CUSTOM_CMAKE "${CMAKE_SOURCE_DIR}/cmake/third_party_deps/implot/CMakeLists.txt"
)
@@ -0,0 +1,33 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_library(implot STATIC)
target_include_directories(implot
PUBLIC
${implot_SOURCE_DIR}
)
target_sources(implot
PUBLIC
${implot_SOURCE_DIR}/implot.h
${implot_SOURCE_DIR}/implot_internal.h
${implot_SOURCE_DIR}/implot.cpp
${implot_SOURCE_DIR}/implot_items.cpp
${implot_SOURCE_DIR}/implot_demo.cpp
)
target_link_libraries(implot
dear_imgui
)
+38
View File
@@ -0,0 +1,38 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_libwebp
v1.6.0
CACHE STRING "Tag/version of `libwebp` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_libwebp)
include(FindOrFetch)
set(LIBWEBP_PATCH_COMMAND
git --git-dir=. -c core.autocrlf=false -c core.whitespace=cr-at-eol apply --verbose --whitespace=fix --ignore-space-change ${mujoco_SOURCE_DIR}/cmake/libwebp-apple-float16.patch
)
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)
fetchpackage(
PACKAGE_NAME libwebp
GIT_REPO https://github.com/webmproject/libwebp.git
GIT_TAG ${MUJOCO_DEP_VERSION_libwebp}
TARGETS webp
PATCH_COMMAND ${LIBWEBP_PATCH_COMMAND}
)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD})
+38
View File
@@ -0,0 +1,38 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Find OpenUSD package. The user can either provide pxr_DIR to use their own
# OpenUSD installation or they can build external_dependencies.
#
# We use QUIET here to provide a better error message when pxr is not found.
find_package(pxr
QUIET
HINTS "${CMAKE_BINARY_DIR}/_deps/openusd-build"
)
if(NOT pxr_FOUND)
message(FATAL_ERROR
"-----------------------------------------------------------\n"
"USD Configuration Error:\n${pxr_NOT_FOUND_MESSAGE}\n"
"If you have built USD yourself, provide -Dpxr_DIR=your_pxr_install_dir' \n"
"Otherwise you can build cmake/third_party_deps/openusd:\n"
"cd ~/mujoco\n"
"cmake -Bcmake/third_party_deps/openusd/build cmake/third_party_deps/openusd -DBUILD_USD=True\n"
"cmake --build cmake/third_party_deps/openusd/build\n"
"cmake -Bbuild -S. -DMUJOCO_WITH_USD=True\n"
"cmake --build build\n"
"cmake --install build"
"-----------------------------------------------------------"
)
endif()
@@ -0,0 +1,51 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION "3.16")
project(openusd-dependency)
include(ExternalProject)
set(DEPS_DIR ${CMAKE_BINARY_DIR}/../../../../build/_deps)
ExternalProject_Add(openusd
GIT_REPOSITORY https://github.com/PixarAnimationStudios/USD.git
GIT_TAG v25.11
PREFIX openusd
BUILD_IN_SOURCE 0
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
SOURCE_DIR ${DEPS_DIR}/openusd-src
BINARY_DIR ${DEPS_DIR}/openusd-build
INSTALL_DIR ${DEPS_DIR}/openusd-build
BUILD_COMMAND python3 ${DEPS_DIR}/openusd-src/build_scripts/build_usd.py
--build-shared
--no-examples
--no-tools
--no-ptex
--no-prman
--no-openimageio
--no-opencolorio
--no-alembic
--no-draco
--no-materialx
--no-tutorials
--no-tests
--no-docs
--no-imaging
--no-python
--no-usdValidation
<INSTALL_DIR>
)
+28
View File
@@ -0,0 +1,28 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MUJOCO_DEP_VERSION_sdl2
98d1f3a45aae568ccd6ed5fec179330f47d4d356
CACHE STRING "Version of `SDL2` to be fetched."
)
mark_as_advanced(MUJOCO_DEP_VERSION_sdl2)
include(FindOrFetch)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
fetchpackage(
PACKAGE_NAME sdl2
GIT_REPO https://github.com/libsdl-org/SDL.git
GIT_TAG ${MUJOCO_DEP_VERSION_sdl2}
)
+5 -5
View File
@@ -1,6 +1,6 @@
1 VERSIONINFO
FILEVERSION 3,3,5,0
PRODUCTVERSION 3,3,5,0
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEOS 0x4
FILETYPE 0x1
{
@@ -9,9 +9,9 @@ FILETYPE 0x1
BLOCK "040904b0"
{
VALUE "ProductName", "MuJoCo"
VALUE "ProductVersion", "3.3.5"
VALUE "ProductVersion", "3.12.0"
VALUE "FileDescription", "MuJoCo"
VALUE "FileVersion", "3.3.5"
VALUE "FileVersion", "3.12.0"
VALUE "InternalName", "mujoco.dll"
VALUE "OriginalFilename", "mujoco.dll"
VALUE "CompanyName", "Google DeepMind"
@@ -20,6 +20,6 @@ FILETYPE 0x1
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409 0x04B0
VALUE "Translation", 0x0409, 0x04B0
}
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

+27
View File
@@ -0,0 +1,27 @@
MUJOCO ICON "mujoco_studio.ico"
1 VERSIONINFO
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEOS 0x4
FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "ProductName", "MuJoCo Studio"
VALUE "ProductVersion", "3.12.0"
VALUE "FileDescription", "MuJoCo Studio"
VALUE "FileVersion", "3.12.0"
VALUE "InternalName", "mujoco_studio.exe"
VALUE "OriginalFilename", "mujoco_studio.exe"
VALUE "CompanyName", "Google DeepMind"
VALUE "LegalCopyright", "Copyright 2026 DeepMind Technologies Limited."
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409, 0x04B0
}
}
+5 -5
View File
@@ -1,8 +1,8 @@
MUJOCO ICON "mujoco.ico"
1 VERSIONINFO
FILEVERSION 3,3,5,0
PRODUCTVERSION 3,3,5,0
FILEVERSION 3,12,0,0
PRODUCTVERSION 3,12,0,0
FILEOS 0x4
FILETYPE 0x1
{
@@ -11,9 +11,9 @@ FILETYPE 0x1
BLOCK "040904b0"
{
VALUE "ProductName", "MuJoCo"
VALUE "ProductVersion", "3.3.5"
VALUE "ProductVersion", "3.12.0"
VALUE "FileDescription", "MuJoCo"
VALUE "FileVersion", "3.3.5"
VALUE "FileVersion", "3.12.0"
VALUE "InternalName", "simulate.exe"
VALUE "OriginalFilename", "simulate.exe"
VALUE "CompanyName", "Google DeepMind"
@@ -22,6 +22,6 @@ FILETYPE 0x1
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409 0x04B0
VALUE "Translation", 0x0409, 0x04B0
}
}
+8
View File
@@ -9,6 +9,9 @@
Functions
=========
.. tip::
Clicking on a function name below will take you to the source implementation in the GitHub repository.
The main header `mujoco.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mujoco.h>`_ exposes a
large number of functions. However the functions that most users are likely to need are a small fraction.
@@ -25,6 +28,8 @@ API function can be classified as:
- :ref:`Ray casting<Raycollisions>`.
- :ref:`Printing<Printing>` of various quantities.
- :ref:`Virtual file system<Virtualfilesystem>`, used to load assets from memory.
- :ref:`Asset cache<Assetcache>`, used to speed up model compilation.
- :ref:`Resources<Resources>`, interfacing with resource providers to load assets.
- :ref:`Initialization<Initialization>` of data structures.
- :ref:`Error and memory<Errorandmemory>`.
- :ref:`Miscellaneous<Miscellaneous>` functions.
@@ -33,10 +38,12 @@ API function can be classified as:
- :ref:`Abstract interaction<Interaction>`: mouse control of cameras and perturbations.
- :ref:`Abstract Visualization<Visualization-api>`.
- :ref:`OpenGL rendering<OpenGLrendering>`.
- :ref:`Filament rendering<FilamentRenderingApi>`.
- :ref:`UI framework<UIframework>`.
- **Threads, Plugins, Derivatives**
- :ref:`Derivatives<Derivatives-api>`.
- :ref:`Signed Distance Functions<Signeddistancefunction>`.
- :ref:`Thread<Thread>` |-| -related functions.
- :ref:`Plugin<Plugins-api>` |-| -related functions.
@@ -52,6 +59,7 @@ API function can be classified as:
- :ref:`Attachment<Attachment>`.
- :ref:`Tree elements<AddTreeElements>`.
- :ref:`Non-tree elements<AddNonTreeElements>`.
- :ref:`Set actuator parameters<Setactuatorparameters>`.
- :ref:`Assets<AddAssets>`.
- :ref:`Find and get utilities<FindAndGetUtilities>`.
- :ref:`Attribute setters<AttributeSetters>`.
+152 -58
View File
@@ -32,10 +32,14 @@ you are simulating multiple models in parallel, they use the same set of callbac
mju_user_error
~~~~~~~~~~~~~~
This is called from within the main error function :ref:`mju_error`. When installed, this function overrides the default
error processing. Once it prints error messages (or whatever else the user wants to do), it must **exit** the program.
MuJoCo is written with the assumption that mju_error will not return. If it does, the behavior of the software is
undefined.
.. deprecated::
Use :ref:`mju_setLogHandler` instead. See :ref:`siLogHandler`.
Called by the default log handler when a fatal error occurs. If installed, this function overrides the default error
processing. It may ``longjmp`` out or return. MuJoCo is written with the assumption that error handlers will not
return; if they do, the behavior of the software is undefined.
If a custom log handler is installed via :ref:`mju_setLogHandler`, this callback is not consulted.
.. code-block:: C
@@ -47,8 +51,11 @@ undefined.
mju_user_warning
~~~~~~~~~~~~~~~~
This is called from within the main warning function :ref:`mju_warning`. It is similar to the error handler, but instead
it must return without exiting the program.
.. deprecated::
Use :ref:`mju_setLogHandler` instead. See :ref:`siLogHandler`.
Called by the default log handler when a warning occurs. If a custom log handler is installed via
:ref:`mju_setLogHandler`, this callback is not consulted.
.. code-block:: C
@@ -185,9 +192,9 @@ mjcb_time
~~~~~~~~~
Installing this callback enables the built-in profiler, and keeps timing statistics in ``mjData.timer``. The return type
is mjtNum, while the time units are up to the user. :ref:`simulate.cc <saSimulate>` assumes the unit is 1 millisecond.
In order to be useful, the callback should use high-resolution timers with at least microsecond precision. This is
because the computations being timed are very fast.
is mjtNum, while the time units are up to the user. Both :ref:`simulate.cc <saSimulate>` and the ``mjTOPIC_TIME_STP``
informational :ref:`topic <mjtLogTopic>` assume the unit is 1 millisecond. In order to be useful, the callback should
use high-resolution timers with at least microsecond precision.
.. code-block:: C
@@ -368,10 +375,41 @@ Numeric constants
^^^^^^^^^^^^^^^^^
Many integer constants were already documented in the primitive types above. In addition, the header files define
several other constants documented here. Unless indicated otherwise, each entry in the table below is defined in
`mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_. Note that some extended key
codes are defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_ which are not
shown in the table below. Their names are in the format ``mjKEY_XXX``. They correspond to GLFW key codes.
several other constants documented here. Note that some extended key codes are defined in
`mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_ which are not shown below. Their
names are in the format ``mjKEY_XXX``. They correspond to GLFW key codes.
.. _glNumericVersion:
Version
~~~~~~~
Defined in `mujoco.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mujoco.h>`_.
.. list-table::
:widths: 2 1 8
:header-rows: 1
* - symbol
- value
- description
* - ``mjVERSION_HEADER``
- 3012000
- The version of the MuJoCo headers. This is an integer calculated from the version string "S.M.P"
using the formula ``(S * 1e6) + (M * 1e3) + P``. For example, version 4.2.1 is represented as 4002001.
The API function :ref:`mj_version` returns a number with the same meaning
but for the compiled library. See
`VERSIONING.md <https://github.com/google-deepmind/mujoco/blob/main/VERSIONING.md>`__ for details.
.. _glNumericEngine:
Engine constants
~~~~~~~~~~~~~~~~
Defined in `mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_ unless
indicated otherwise.
.. list-table::
:widths: 2 1 8
@@ -384,6 +422,7 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- 1E-15
- The minimal value allowed in any denominator, and in general any mathematical operation where 0 is not allowed.
In almost all cases, MuJoCo silently clamps smaller values to mjMINVAL.
Defined in `mjtype.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtype.h>`_.
* - ``mjPI``
- :math:`\pi`
- The value of :math:`\pi`. This is used in various trigonometric functions, and also for conversion from degrees
@@ -414,13 +453,36 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- 50
- The maximum depth of each body and mesh bounding volume hierarchy. If this large limit is exceeded, a warning
is raised and ray casting may not be possible. For a balanced hierarchy, this implies 1E15 bounding volumes.
* - ``mjMAXFLEXNODES``
- 27
- The maximum number of nodes in a trilinear flex element.
* - ``mjMINAWAKE``
- 10
- The minimum number of timesteps that must pass after a tree is awoken, before it is allowed to go back to sleep.
.. _glNumericSizes:
Array sizes
~~~~~~~~~~~
Defined in `mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_. These constants
correspond to array sizes which we have not fully settled. There may be reasons to increase them in the future, so as to
accommodate extra parameters needed for more elaborate computations. This is why we maintain them as symbolic constants
that can be easily changed, as opposed to the array size for representing quaternions for example -- which has no reason
to change.
.. list-table::
:widths: 2 1 8
:header-rows: 1
* - symbol
- value
- description
* - ``mjNEQDATA``
- 11
- The maximal number of real-valued parameters used to define each equality constraint. Determines the size of
``mjModel.eq_data``. This and the next five constants correspond to array sizes which we have not fully settled.
There may be reasons to increase them in the future, so as to accommodate extra parameters needed for more
elaborate computations. This is why we maintain them as symbolic constants that can be easily changed, as opposed
to the array size for representing quaternions for example -- which has no reason to change.
``mjModel.eq_data``.
* - ``mjNDYN``
- 10
- The maximal number of real-valued parameters used to define the activation dynamics of each actuator.
@@ -433,6 +495,11 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- 10
- The maximal number of real-valued parameters used to define the bias of each actuator.
Determines the size of ``mjModel.actuator_biasprm``.
* - ``mjNPOLY``
- 2
- The number of nonlinear polynomial coefficients for joint and tendon stiffness and damping.
Determines the size of ``mjModel.{jnt,tendon}_{stiffness,damping}poly``. See
:ref:`polynomial forces<gePolynomial>`.
* - ``mjNFLUID``
- 12
- The number of per-geom fluid interaction parameters required by the ellipsoidal model.
@@ -445,7 +512,7 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- The maximal number of real-valued parameters used to define the impedance of each scalar constraint.
Determines the size of all ``mjModel.XXX_solimp`` fields.
* - ``mjNSENS``
- 2
- 3
- The number of sensor parameters.
Determines the size of ``mjModel.sensor_intprm``.
* - ``mjNSOLVER``
@@ -458,74 +525,104 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
- The number of islands for which solver statistics can be stored in ``mjData.solver``. This array is
used to store diagnostic information about each iteration of the constraint solver.
The actual number of islands for which the solver was run is given by ``mjData.nsolver_island``.
.. _glNumericVisualization:
Visualization
~~~~~~~~~~~~~
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
.. list-table::
:widths: 2 1 8
:header-rows: 1
* - symbol
- value
- description
* - ``mjNGROUP``
- 6
- The number of geom, site, joint, tendon and actuator groups whose rendering can be enabled and disabled via
:ref:`mjvOption`.
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
* - ``mjMAXLIGHT``
- 100
- The maximum number of lights in a scene.
* - ``mjMAXOVERLAY``
- 500
- The maximal number of characters in overlay text for rendering.
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
* - ``mjMAXLINE``
- 100
- The maximal number of lines per 2D figure (:ref:`mjvFigure`).
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
* - ``mjMAXLINEPNT``
- 1001
- The maximal number of points in each line in a 2D figure. Note that the buffer ``mjvFigure.linepnt`` has length
``2*mjMAXLINEPNT`` because each point has X and Y coordinates.
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
* - ``mjMAXPLANEGRID``
- 200
- The maximal number of grid lines in each dimension for rendering planes.
Defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
.. _glNumericRendering:
Rendering
~~~~~~~~~
Defined in `mjrender.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_.
.. list-table::
:widths: 2 1 8
:header-rows: 1
* - symbol
- value
- description
* - ``mjNAUX``
- 10
- Number of auxiliary buffers that can be allocated in mjrContext.
Defined in `mjrender.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_.
* - ``mjMAXTEXTURE``
- 1000
- Maximum number of textures allowed.
Defined in `mjrender.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_.
* - ``mjMAXTHREAD``
- 128
- Maximum number OS threads that can be used in a thread pool.
Defined in `mjthread.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjthread.h>`_.
* - ``mjMAXMATERIAL``
- 1000
- Maximum number of materials with textures.
.. _glNumericUI:
UI constants
~~~~~~~~~~~~
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
.. list-table::
:widths: 2 1 8
:header-rows: 1
* - symbol
- value
- description
* - ``mjMAXUISECT``
- 10
- Maximum number of UI sections.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUIITEM``
- 200
- Maximum number of items per UI section.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUITEXT``
- 500
- 300
- Maximum number of characters in UI fields 'edittext' and 'other'.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUINAME``
- 40
- Maximum number of characters in any UI name.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUIMULTI``
- 20
- 35
- Maximum number of radio and select items in UI group.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUIEDIT``
- 5
- 7
- Maximum number of elements in UI edit list.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjMAXUIRECT``
- 15
- 25
- Maximum number of UI rectangles.
Defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
* - ``mjVERSION_HEADER``
- 335
- The version of the MuJoCo headers; changes with every release. This is an integer equal to 100x the software
version, so 210 corresponds to version 2.1. Defined in mujoco.h. The API function :ref:`mj_version` returns a
number with the same meaning but for the compiled library.
.. _Macros:
@@ -597,17 +694,13 @@ mjPLUGIN_LIB_INIT
.. code-block:: C
#define mjPLUGIN_LIB_INIT \
static void _mjplugin_dllmain(void); \
mjEXTERNC int __stdcall mjDLLMAIN(void* hinst, unsigned long reason, void* reserved) { \
if (reason == 1) { \
_mjplugin_dllmain(); \
} \
return 1; \
} \
static void _mjplugin_dllmain(void)
#define mjPLUGIN_LIB_INIT(n) \
static void _mj_init_##n(void) __attribute__((constructor)); \
static void _mj_init_##n(void)
Register a plugin as a dynamic library. See :ref:`plugin registration<exRegistration>` for more details.
Register a plugin before `main()` is called. This macro takes a unique identifier `n` as an argument that is used to avoid
name collisions between different plugin initialization functions. See :ref:`plugin registration<exRegistration>` for
more details.
.. _tyXMacro:
@@ -616,7 +709,8 @@ X Macros
^^^^^^^^
The X Macros are not needed in most user projects. They are used internally to allocate the model, and are also
available for users who know how to use this programming technique. See the header file `mjxmacro.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`_ for the actual definitions. They are
available for users who know how to use this programming technique. See the header files `mjxmacro.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`_ and `mjspecmacro.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspecmacro.h>`_ for the actual definitions. They are
particularly useful in writing MuJoCo wrappers for scripting languages, where dynamic structures matching the MuJoCo
data structures need to be constructed programmatically.
+720 -44
View File
@@ -4,13 +4,16 @@ Types
MuJoCo defines a large number of types:
- Two :ref:`primitive types<tyPrimitive>`.
- Four :ref:`primitive types<tyPrimitive>`: :ref:`mjtNum<mjtNum>`, :ref:`mjtByte<mjtByte>`, :ref:`mjtBool<mjtBool>`, and
:ref:`mjtSize<mjtSize>`.
- :ref:`C enum types<tyEnums>` used to define categorical values. These can be classified as:
- Enums used in :ref:`mjModel<tyModelEnums>`.
- Enums used in :ref:`mjData<tyDataEnums>`.
- Enums for abstract :ref:`visualization<tyVisEnums>`.
- Enums used by the :ref:`openGL renderer<tyRenderEnums>`.
- Enums used by the :ref:`classic renderer<tyRenderEnums>`.
- Enums used by the :ref:`filament renderer<tyFilamentRenderEnums>`.
- Enums used by the :ref:`mjUI<tyUIEnums>` user interface package.
- Enums used by :ref:`engine plugins<tyPluginEnums>`.
- Enums used for :ref:`procedural model manipulation<tySpecEnums>`.
@@ -18,7 +21,7 @@ MuJoCo defines a large number of types:
Note that the API does not use these enum types directly. Instead it uses ints, and the documentation/comments state
that certain ints correspond to certain enum types. This is because we want the API to be compiler-independent, and
the C standard does not dictate how many bytes must be used to represent an enum type. Nevertheless, for improved
readiblity, we recommend using these types when calling API functions which take them as arguments.
readability, we recommend using these types when calling API functions which take them as arguments.
- :ref:`C struct types<tyStructure>`. These can be classified as:
@@ -31,7 +34,8 @@ MuJoCo defines a large number of types:
- :ref:`Auxiliary struct types<tyAuxStructure>`, also used by the engine.
- Structs for collecting :ref:`simulation statistics<tyStatStructure>`.
- Structs for :ref:`abstract visualization<tyVisStructure>`.
- Structs used by the :ref:`openGL renderer<tyRenderStructure>`.
- Structs used by the :ref:`classic renderer<tyRenderStructure>`.
- Structs used by the :ref:`filament renderer<tyFilamentRenderStructure>`.
- Structs used by the :ref:`UI framework<tyUIStructure>`.
- Structs used for :ref:`procedural model manipulation<tySpecStructure>`.
- Structs used by :ref:`engine plugins<tyPluginStructure>`.
@@ -46,7 +50,7 @@ MuJoCo defines a large number of types:
Primitive types
---------------
The two types below are defined in `mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`__.
The three types below are defined in `mjtype.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtype.h>`__.
.. _mjtNum:
@@ -63,7 +67,7 @@ double-precision version will always be available. Thus it is safe to write user
However, our preference is to write code that works with either single or double precision. To this end we provide math
utility functions that are always defined with the correct floating-point type.
Note that changing ``mjUSESINGLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
Note that changing ``mjUSESINGLE`` in ``mjtype.h`` will not change how the library was compiled, and instead will
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
changed by the user.
@@ -84,13 +88,41 @@ changed by the user.
mjtByte
^^^^^^^
Byte type used to represent boolean variables.
Byte type used to represent small integers and binary data.
.. code-block:: C
typedef unsigned char mjtByte;
.. _mjtBool:
mjtBool
^^^^^^^
Boolean type used to represent true/false values.
.. code-block:: C
#ifndef __cplusplus
typedef _Bool mjtBool;
#else
typedef bool mjtBool;
#endif
.. _mjtSize:
mjtSize
^^^^^^^
Size type used to represent buffer sizes.
.. code-block:: C
typedef int64_t mjtSize;
.. _tyEnums:
Enum types
@@ -103,7 +135,7 @@ All enum types use the ``mjt`` prefix.
Model
^^^^^
The enums below are defined in `mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`__.
The enums below are defined in `mjtype.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtype.h>`__.
.. _mjtDisableBit:
@@ -154,6 +186,16 @@ elements. These values are used in ``m->geom_type`` and ``m->site_type``.
.. mujoco-include:: mjtGeom
.. _mjtProjection:
mjtProjection
~~~~~~~~~~~~~
Type of camera projection. Used in ``m->cam_projection``.
.. mujoco-include:: mjtProjection
.. _mjtCamLight:
mjtCamLight
@@ -305,6 +347,26 @@ Actuator bias types. These values are used in ``m->actuator_biastype``.
.. mujoco-include:: mjtBias
.. _mjtCtrlChart:
mjtCtrlChart
~~~~~~~~~~~~
Orientation input charts of so3 actuators. These values are used in ``m->actuator_ctrlspec``.
.. mujoco-include:: mjtCtrlChart
.. _mjtCtrlInput:
mjtCtrlInput
~~~~~~~~~~~~
Input bitflags of servo-family (pd, dcmotor) actuators. These values are used in ``m->actuator_ctrlspec``.
.. mujoco-include:: mjtCtrlInput
.. _mjtObj:
mjtObj
@@ -316,26 +378,6 @@ MuJoCo object types. These are used, for example, in the support functions :ref:
.. mujoco-include:: mjtObj
.. _mjtConstraint:
mjtConstraint
~~~~~~~~~~~~~
Constraint types. These values are not used in mjModel, but are used in the mjData field ``d->efc_type`` when the list
of active constraints is constructed at each simulation time step.
.. mujoco-include:: mjtConstraint
.. _mjtConstraintState:
mjtConstraintState
~~~~~~~~~~~~~~~~~~
These values are used by the solver internally to keep track of the constraint states.
.. mujoco-include:: mjtConstraintState
.. _mjtSensor:
mjtSensor
@@ -377,6 +419,26 @@ Types of data fields returned by contact sensors.
.. mujoco-include:: mjtConDataField
.. _mjtRayDataField:
mjtRayDataField
~~~~~~~~~~~~~~~
Data fields returned by rangefinder sensors.
.. mujoco-include:: mjtRayDataField
.. _mjtCamOutBit:
mjtCamOutBit
~~~~~~~~~~~~
Camera output type bitflags. These are used in ``m->cam_output``.
.. mujoco-include:: mjtCamOutBit
.. _mjtSameFrame:
mjtSameFrame
@@ -388,6 +450,27 @@ last argument to :ref:`mj_local2global`.
.. mujoco-include:: mjtSameFrame
.. _mjtSleepPolicy:
mjtSleepPolicy
~~~~~~~~~~~~~~
Sleep policy associated with a tree. The compiler automatically chooses between ``NEVER`` and ``ALLOWED``, but the user
can override this choice. Only the user can set the ``INIT`` policy (initialized as asleep).
.. mujoco-include:: mjtSleepPolicy
.. _mjtLRMode:
mjtLRMode
~~~~~~~~~
Mode for actuator length range computation. Used in ``mjLROpt.mode``.
.. mujoco-include:: mjtLRMode
.. _mjtFlexSelf:
mjtFlexSelf
@@ -413,7 +496,7 @@ Formulas used to combine SDFs when calling mjc_distance and mjc_gradient.
Data
^^^^
The enums below are defined in `mjdata.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`__.
The enums below are defined in `mjtype.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtype.h>`__.
@@ -428,6 +511,27 @@ State component elements as integer bitflags and several convenient combinations
.. mujoco-include:: mjtState
.. _mjtConstraint:
mjtConstraint
~~~~~~~~~~~~~
Constraint types. These values are not used in mjModel, but are used in the mjData field ``d->efc_type`` when the list
of active constraints is constructed at each simulation time step.
.. mujoco-include:: mjtConstraint
.. _mjtConstraintState:
mjtConstraintState
~~~~~~~~~~~~~~~~~~
These values are used by the solver internally to keep track of the constraint states.
.. mujoco-include:: mjtConstraintState
.. _mjtWarning:
mjtWarning
@@ -450,6 +554,42 @@ Timer types. The number of timer types is given by ``mjNTIMER`` which is also th
.. mujoco-include:: mjtTimer
.. _mjtSleepState:
mjtSleepState
~~~~~~~~~~~~~
Sleep state of an object.
.. mujoco-include:: mjtSleepState
.. _tyLogEnums:
Logging
~~~~~~~
.. _mjtLogLevel:
mjtLogLevel
"""""""""""
Log message severity level.
.. mujoco-include:: mjtLogLevel
.. _mjtLogTopic:
mjtLogTopic
"""""""""""
Topic identifiers for informational messages. Used with :ref:`mju_info` for topic-based filtering.
Topic 0 (``mjTOPIC_NONE``) always passes through the default handler's filter. Other topics must be enabled in
the :ref:`mjLogConfig` bitmask. Since topics are 1-indexed, the bitmask for topic ``t`` is ``(1 << (t - 1))``.
.. mujoco-include:: mjtLogTopic
.. _tyVisEnums:
@@ -616,6 +756,79 @@ These are the possible font types.
.. mujoco-include:: mjtFont
.. _mjrPixelFormat:
mjrPixelFormat
~~~~~~~~~~~~~~
These are the possible values:
.. mujoco-include:: mjrPixelFormat
.. _mjrVertexAttributeUsage:
mjrVertexAttributeUsage
~~~~~~~~~~~~~~~~~~~~~~~
These are the possible values:
.. mujoco-include:: mjrVertexAttributeUsage
.. _mjrVertexAttributeType:
mjrVertexAttributeType
~~~~~~~~~~~~~~~~~~~~~~
These are the possible values:
.. mujoco-include:: mjrVertexAttributeType
.. _mjrIndexType:
mjrIndexType
~~~~~~~~~~~~
These are the possible values:
.. mujoco-include:: mjrIndexType
.. _mjrMeshPrimitiveType:
mjrMeshPrimitiveType
~~~~~~~~~~~~~~~~~~~~
There are the possible values:
.. mujoco-include:: mjrMeshPrimitiveType
.. _tyFilamentRenderEnums:
Filament Rendering
^^^^^^^^^^^^^^^^^^
The enums below are defined in `mjrfilament.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrfilament.h>`__.
.. _mjrGraphicsApi:
mjrGraphicsApi
~~~~~~~~~~~~~~
The underlying graphics API to use for Filament rendering.
.. mujoco-include:: mjrGraphicsApi
.. _mjrDrawMode:
mjrDrawMode
~~~~~~~~~~~
High-level control for how to draw objects in the scene for Filament rendering.
.. mujoco-include:: mjrDrawMode
.. _tyUIEnums:
@@ -736,6 +949,45 @@ Type of orientation specifier.
.. mujoco-include:: mjtOrientation
.. _mjtMeshInertia:
mjtMeshInertia
~~~~~~~~~~~~~~
Type of mesh inertia computation.
.. mujoco-include:: mjtMeshInertia
.. _mjtMeshBuiltin:
mjtMeshBuiltin
~~~~~~~~~~~~~~
Type of built-in procedural mesh.
.. mujoco-include:: mjtMeshBuiltin
.. _mjtConflict:
mjtConflict
~~~~~~~~~~~
Conflict resolution mode for attach.
.. mujoco-include:: mjtConflict
.. _mjtCTimer:
mjtCTimer
~~~~~~~~~
Compiler timing categories, used in :ref:`mjs_getTimer`. Top-level timers (``TOTAL``, ``ASSETS``) measure wall-clock
time. Asset sub-timers measure CPU time summed across all assets; with multi-threaded compilation their sum can exceed
the ``ASSETS`` wall-clock time.
.. mujoco-include:: mjtCTimer
.. _tyPluginEnums:
@@ -763,7 +1015,7 @@ Struct types
------------
The three central struct types for physics simulation are :ref:`mjModel`, :ref:`mjOption` (embedded in :ref:`mjModel`)
and :ref:`mjData`. An introductory discussion of these strucures can be found in the :ref:`Overview<ModelAndData>`.
and :ref:`mjData`. An introductory discussion of these structures can be found in the :ref:`Overview<ModelAndData>`.
.. _mjModel:
@@ -833,6 +1085,15 @@ MJCF element :ref:`statistic <statistic>`. One instance of it is embedded in mjM
.. mujoco-include:: mjStatistic
.. _mjPreContact:
mjPreContact
~~~~~~~~~~~~
This is the data structure holding information about one contact filled out by a narrowphase collision detector.
.. mujoco-include:: mjPreContact
.. _mjContact:
mjContact
@@ -876,26 +1137,45 @@ Options for configuring the automatic :ref:`actuator length-range computation<CL
.. mujoco-include:: mjLROpt
.. _mjTask:
.. _mjCache:
mjTask
~~~~~~
mjCache
~~~~~~~
This is a representation of a task to be run asynchronously inside of an :ref:`mjThreadPool` . It is created in the
:ref:`mju_threadPoolEnqueue` method of the :ref:`mjThreadPool` and is used to join the task at completion.
Asset cache used by the compiler to avoid repeated slow recompilation. See :ref:`Asset cache<Assetcache>`.
.. mujoco-include:: mjTask
.. mujoco-include:: mjCache
.. _mjThreadPool:
mjThreadPool
.. _tyLogStructure:
Logging
^^^^^^^
.. _mjLogMessage:
mjLogMessage
~~~~~~~~~~~~
This is the data structure of the threadpool. It can only be constructed programmatically, and does not
have an analog in MJCF. In order to enable multi-threaded calculations, a pointer to an existing :ref:`mjThreadPool`
should be assigned to the ``mjData.threadpool``.
Structured log message passed to :ref:`mjfLogHandler` callbacks. Contains the severity level, optional topic for
info messages, a one-line subject, an optional multi-line body, and optional source location (function name, file
name, line number).
.. mujoco-include:: mjLogMessage
.. _mjLogConfig:
mjLogConfig
~~~~~~~~~~~
Configuration for the default log handler. Controls whether messages are printed to the console and/or written to
a log file (default: ``MUJOCO_LOG.TXT``). The ``logto_file`` field enables file logging, while ``logfile`` specifies
the file path. The ``topics`` field is a bitmask of :ref:`mjtLogTopic` values: bit ``(topic - 1)`` enables
that topic. Topic 0 (``mjTOPIC_NONE``) always passes through.
.. mujoco-include:: mjLogConfig
.. mujoco-include:: mjThreadPool
.. _tyStatStructure:
@@ -1047,6 +1327,27 @@ This structure specifies a rectangle.
.. mujoco-include:: mjrRect
.. _mjrVertexAttribute:
mjrVertexAttribute
~~~~~~~~~~~~~~~~~~
This structure specifies the attributes for a single vertex.
.. mujoco-include:: mjrVertexAttribute
.. _mjrRendererInfo:
mjrRendererInfo
~~~~~~~~~~~~~~~
This structure contains information about the available renderer and its current context.
.. mujoco-include:: mjrRendererInfo
.. _mjrContext:
mjrContext
@@ -1057,6 +1358,273 @@ This structure contains the custom OpenGL rendering context, with the ids of all
.. mujoco-include:: mjrContext
.. _tyFilamentRenderStructure:
Filament Rendering
^^^^^^^^^^^^^^^^^^
The names of these struct types are prefixed with ``mjrf``. They are defined in
`mjrfilament.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrfilament.h>`__.
There are seven key types defined by this API: :ref:`mjrfContext<mjrfContext>`, :ref:`mjrfTexture<mjrfTexture>`,
:ref:`mjrfMesh<mjrfMesh>`, :ref:`mjrfLight<mjrfLight>`, :ref:`mjrfRenderable<mjrfRenderable>`,
:ref:`mjrfScene<mjrfScene>`, and :ref:`mjrfRenderTarget<mjrfRenderTarget>`.
Each object is created using a `create` function and destroyed using a `destroy` function, e.g. `mjrf_createTexture` and
`mjrf_destroyTexture`. All objects require a :ref:`Context<mjrfContext>` in order to be created (with the exception of
the :ref:`Context<mjrfContext>` object itself). Additionally, the `create` functions accept a pointer to a configuration
struct (e.g. `mjrTextureConfig`) which describes the parameters for the object to be created. Each of these structs has
a corresponding `default` function (e.g. `mjrf_defaultTextureConfig`) which can be used to initialize the struct to
default values. The default values are assumed to be `0` or `NULL` unless otherwise specified.
.. _mjrfContext:
mjrfContext
~~~~~~~~~~~
The Context is the main entry point for the filament rendering library. It manages all the core filament objects that
are responsible for the rendering of an image. All other objects (e.g. Textures, Meshes, Scenes, etc.) need a Context in
order to be created.
Otherwise, the main function to use with the Context is :ref:`mjrf_render()<mjrf_render>` which performs the actual
rendering of an image.
Filament uses a separate thread for rendering. However, despite that, this API is not thread-safe; calls are expected to
be made from a single thread. Due to the asynchronous nature of filament, some APIs provide handles or callbacks to
signal when an operation is complete. (Note: for WASM builds, filament does not use a separate thread.)
There are two key differences between the :ref:`mjrfContext<mjrfContext>` and the classic :ref:`mjrContext<mjrContext>`.
Firstly, the filament context will manage the underlying graphics context itself. This means users do not need to
initialize EGL or similar libraries beforehand. Secondly, the filament context is independent of a MuJoCo model. That
means you can use a single :ref:`mjrfContext<mjrfContext>` instance to render images for multiple models.
.. _mjrfContextConfig:
mjrfContextConfig
~~~~~~~~~~~~~~~~~
Parameters for creating :ref:`filament graphics context<mjrfContext>`.
.. mujoco-include:: mjrfContextConfig
.. _mjrfTexture:
mjrfTexture
~~~~~~~~~~~
A texture is a 2D or 3D (cubemap) image that adds visual detail to a rendered model, such as color or bumpiness, without
increasing geometric complexity. A texture is simply a memory buffer holds pixel data, as well as metadata such as the
dimensions of the image or the format of the pixels (e.g. 8-bit RGB).
.. _mjrfTextureConfig:
mjrfTextureConfig
~~~~~~~~~~~~~~~~~
Parameters for creating a :ref:`texture<mjrfTexture>`.
.. mujoco-include:: mjrfTextureConfig
.. _mjrfTextureData:
mjrfTextureData
~~~~~~~~~~~~~~~
Binary data payload for a :ref:`texture<mjrfTexture>`.
.. mujoco-include:: mjrfTextureData
.. _mjrfMesh:
mjrfMesh
~~~~~~~~
A mesh describes the surface geometry of an object to be rendered. It is defined as a collection of vertices (i.e. a
VertexBuffer), a set of indices (i.e. an IndexBuffer) that describes the order in which the vertices should be
processed, and a primitive type that defined how the vertices are to be interpreted (e.g. triangles, lines, etc.) when
rendering the surface.
Filament does not directly support normals. Instead, it encodes the normal, tangent, and bitangent into a 4-component
quaternion describing the "orientation" of the vertex. Ideally, you should preprocess your assets to generate this data
offline, but we will compute it on the fly if needed (at a performance cost).
Vertex data may or may not be interleaved. Interleaved data assumes that the attributes are packed in the order
specified in the attributes array, with no padding in-between. Additionally, the `data` pointer for each attribute is
assumed to point to the first element of that type. For non-interleaved data, each attribute is assumed to be stored in
a separate array.
Additionally, the bounds of the mesh should be computed in order to allow the filament renderer to perform frustum-based
culling. Alternatively, the bounds can be computed at runtime (though there is a small performance cost). If no bounds
are provided (or calculated), then frustum culling will not be performed.
.. _mjrfMeshConfig:
mjrfMeshConfig
~~~~~~~~~~~~~~~~~
Parameters for creating a :ref:`mesh<mjrfMesh>`.
.. mujoco-include:: mjrfMeshConfig
.. _mjrfMeshData:
mjrfMeshData
~~~~~~~~~~~~
Binary data for a :ref:`mesh<mjrfMesh>`.
.. mujoco-include:: mjrfMeshData
.. _mjrfScene:
mjrfScene
~~~~~~~~~
A Scene is a collection of :ref:`Lights<mjrfLight>` and :ref:`Renderables<mjrfRenderable>` that describes what is to be
rendered.
.. _mjrfSceneParams:
mjrfSceneParams
~~~~~~~~~~~~~~~
Parameters for creating a :ref:`scene<mjrfScene>`.
.. mujoco-include: mjrfSceneParams
.. _mjrfLight:
mjrfLight
~~~~~~~~~
A light is a source of illumination. (Without lights, a rendered image will be completely black.) There are several
different types of lights such as directional, spot, point, and image lights.
The primary light in a scene is the image light (also sometimes known as the environment light). This is a light that
"surrounds" the entire scene and is defined as a 3D texture. Each "pixel" of the cubemap is interpreted as the color of
projected into the scene from a particular direction.
The texture used for image-based lighting can be generated using filament's `cmgen` tool. The tool should be configured
to output a KTX file from your source image. This tool calculates additional data (i.e. the spherical harmonics) and
encodes that information into the KTX file.
Directional lights are the next most common type of light and is usually used to simulate the sun; a uniformly colored
light that is emitted in a single direction.
Filament only supports a single image and directional light. You can define as many point or spot lights as you want.
Each light source (except image based lights) may or may not cast shadows. Each shadow-casting light incurs a
performance cost.
.. _mjrfLightParams:
mjrfLightParams
~~~~~~~~~~~~~~~
Parameters for creating a :ref:`light<mjrfLight>`.
.. mujoco-include:: mjrfLightParams
.. _mjrfRenderable:
mjrfRenderable
~~~~~~~~~~~~~~
A renderable is a single object that is to be drawn. It is defined as a combination of a :ref:`mjrfMesh<mjrfMesh>`
(i.e. the shape or surface geometry, as described above) and a :ref:`mjrfMaterial<mjrfMaterial>` (i.e. a description of
how the surface interacts with lights to product the final visual appearance).
.. _mjrfRenderableParams:
mjrfRenderableParams
~~~~~~~~~~~~~~~~~~~~
Parameters for creating a :ref:`renderable<mjrfRenderable>`.
.. mujoco-include:: mjrfRenderableParams
.. _mjrfMaterial:
mjrfMaterial
~~~~~~~~~~~~
Materials describe the properties of the surface of a renderable, effectively dictating how the surface interacts with
lights to produce a final pixel color in the output image. Different lighting models will be applied to the surface
depending on the values of the material properties. There there are three lighting models currently supported:
1. Metallic-roughness (PBR): this is the preferred model for rendering models based standard
metallic-roughness workflows.
2. Specular-glossiness (non-PBR): this is a legacy model designed to be compatible with classic
:ref:`mjr<Rendering>` renderer, though it is not 100% identical.
3. Unlit: this model ignores lighting and is used for rendering UX or decorative elements like
contact forces and labels.
.. mujoco-include:: mjrfMaterial
.. _mjrfRenderTarget:
mjrfRenderTarget
~~~~~~~~~~~~~~~~
A RenderTarget is a memory buffer that holds the results of a rendering operation. (This is an alternative to rendering
directly to the screen.)
.. _mjrfRenderTargetConfig:
mjrfRenderTargetConfig
~~~~~~~~~~~~~~~~~~~~~~
Parameters for creating a :ref:`render target<mjrfRenderTarget>`.
.. mujoco-include:: mjrfRenderTargetConfig
.. _mjrfRenderRequest:
mjrfRenderRequest
~~~~~~~~~~~~~~~~~
A single rendering operation.
.. mujoco-include:: mjrfRenderRequest
.. _mjrfReadPixelsRequest:
mjrfReadPixelsRequest
~~~~~~~~~~~~~~~~~~~~~
A single pixel read operation.
.. mujoco-include:: mjrfReadPixelsRequest
.. _mjrfFrameStats:
mjrfFrameStats
~~~~~~~~~~~~~~
Information about a single frame of rendering.
.. mujoco-include:: mjrfFrameStats
.. _tyUIStructure:
User Interface
@@ -1190,6 +1758,16 @@ Compiler options.
.. mujoco-include:: mjsCompiler
.. _mjsAuthored:
mjsAuthored
~~~~~~~~~~~
Authored tracking bitmasks for ``mjModel`` structs.
.. mujoco-include:: mjsAuthored
.. _mjsBody:
mjsBody
@@ -1527,6 +2105,16 @@ triggered by the compiler and the engine during various phases of the computatio
.. mujoco-include:: mjpPlugin
.. _mjSDF:
mjSDF
~~~~~
Data structure used by the :ref:`Signed Distance Functions<Signeddistancefunction>` API for computing distances and
gradients between SDF geoms.
.. mujoco-include:: mjSDF
.. _mjpResourceProvider:
mjpResourceProvider
@@ -1537,6 +2125,29 @@ used for opening and reading resources.
.. mujoco-include:: mjpResourceProvider
.. _mjpDecoder:
mjpDecoder
~~~~~~~~~~~~~~~~~~~
This data structure defines a decoder. It contains a set of callbacks used for decoding :ref:`mjResource`
into :ref:`mjSpec`.
.. mujoco-include:: mjpDecoder
.. _mjpEncoder:
mjpEncoder
~~~~~~~~~~~~~~~~~~~
This data structure defines an encoder. It contains a set of callbacks used for encoding of :ref:`mjSpec` and
:ref:`mjModel` into :ref:`mjResource`.
.. mujoco-include:: mjpEncoder
.. _tyFunction:
Function types
@@ -1625,11 +2236,31 @@ mjfCollision
.. code-block:: C
typedef int (*mjfCollision)(const mjModel* m, const mjData* d,
mjContact* con, int g1, int g2, mjtNum margin);
mjPreContact* con, int g1, int g2, mjtNum margin);
This is the function type of the callbacks in the collision table :ref:`mjCOLLISIONFUNC`.
.. _tyLogCallbacks:
Log Callbacks
^^^^^^^^^^^^^
.. _mjfLogHandler:
mjfLogHandler
~~~~~~~~~~~~~
.. code-block:: C
typedef void (*mjfLogHandler)(const mjLogMessage*);
This is the function type of the log handler callback installed via :ref:`mju_setLogHandler`. The handler receives
all errors, warnings and informational messages as structured :ref:`mjLogMessage` data. It must be thread-safe.
It must not call :ref:`mju_error` from within the callback.
.. _tyUICallbacks:
UI Callbacks
@@ -1665,7 +2296,10 @@ mjfOpenResource
typedef int (*mjfOpenResource)(mjResource* resource);
This callback is for opeing a resource; returns zero on failure.
This callback is for opening a resource; returns zero on failure. Note that
if this callback returns zero, the ``close`` callback will not be called.
Therefore, the ``open`` callback is responsible for cleaning up any allocated
memory or resources before returning zero to avoid memory leaks.
.. _mjfReadResource:
@@ -1714,6 +2348,48 @@ This callback is for checking if a resource was modified since it was last read.
Returns positive value if the resource was modified since last open, 0 if resource was not modified,
and negative value if inconclusive.
.. _mjfDecode:
mjfDecode
~~~~~~~~~
.. code-block:: C
typedef mjSpec* (*mjfDecode)(mjResource* resource, const mjVFS* vfs);
This callback is given an opened resource, and is responsible for decoding it into a :ref:`mjSpec`.
Ownership of the resource and the returned spec is responsibility of the caller.
When decoding fails, the callback should return NULL.
.. _mjfCanDecode:
mjfCanDecode
~~~~~~~~~~~~
.. code-block:: C
typedef int (*mjfCanDecode)(const mjResource* resource);
This callback is given an opened resource, and is responsible for returning true if the resource can
be decoded by the :ref:`mjpDecoder<mjpDecoder>`.
.. _mjfEncode:
mjfEncode
~~~~~~~~~
.. code-block:: C
typedef mjtSize (*mjfEncode)(const mjSpec* s, const mjModel* m, const mjVFS* vfs,
mjResource* resource);
This callback populates the :ref:`mjResource<mjResource>` `data` member with bytes representing the
given spec in the format associated with the owning plugin. This may be called with the associated
compiled :ref:`mjModel`.
.. _tyNotes:
File diff suppressed because it is too large Load Diff
+239 -31
View File
@@ -23,6 +23,13 @@ Initialize an empty VFS, :ref:`mj_deleteVFS` must be called to deallocate the VF
Add file to VFS. The directory argument is optional and can be NULL or empty. Returns 0 on success,
2 on name collision, or -1 when an internal error occurs.
*Nullable:* ``directory``
.. _Assetcache:
The asset cache is a mechanism for caching assets (e.g. textures, meshes, etc.) to avoid repeated slow recompilation.
The following methods provide way to control the capacity of the cache or to disable it altogether.
.. _Parseandcompile:
The key function here is :ref:`mj_loadXML`. It invokes the built-in parser and compiler, and either returns a pointer to
@@ -40,7 +47,7 @@ If compilation fails, :ref:`mj_compile` returns ``NULL``; the error can be read
Recompile spec to model, preserving the state. Like :ref:`mj_compile`, this function compiles an :ref:`mjSpec` to an
:ref:`mjModel`, with two differences. First, rather than returning an entirely new model, it will
reallocate existing :ref:`mjModel` and :ref:`mjData` instances in-place. Second, it will preserve the
:ref:`integration state<geIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
:ref:`integration state<siIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
newly added or removed degrees of freedom. This allows the user to continue simulation with the same model and data
struct pointers while editing the model programmatically.
@@ -65,6 +72,16 @@ the required size. XML saving automatically compiles the spec before saving.
Save spec to XML file, return 0 on success, -1 otherwise. XML saving requires that the spec first be compiled.
.. _mj_encode:
Encode :ref:`mjSpec` or :ref:`mjModel` to a file. The output format is determined by the file extension
(case insensitive) or ``content_type``. Returns the number of bytes written on success, -1 on failure.
For detailed documentation, supported output formats (``.xml``, ``.mjb``, ``.txt``, ``.mjz``), and custom encoder
plugins, see :ref:`Model Encoding & Saving <meSaving>`.
*Nullable:* ``s``, ``m``, ``vfs``, ``error``
.. _Mainsimulation:
These are the main entry points to the simulator. Most users will only need to call :ref:`mj_step`, which computes
@@ -162,13 +179,15 @@ This function is triggered automatically if the following sensors are present in
It is also triggered for :ref:`user sensors<sensor-user>` of :ref:`stage<sensor-user-needstage>` "acc".
The computed force arrays ``cfrc_int`` and ``cfrc_ext`` currently suffer from a know bug, they do not take into account
the effect of spatial tendons, see :github:issue:`832`.
the effect of spatial tendons, see :issue:`832`.
.. _mj_constraintUpdate:
Compute ``efc_state``, ``efc_force``, ``qfrc_constraint``, and (optionally) cone Hessians.
If ``cost`` is not ``NULL``, set ``*cost = s(jar)`` where ``jar = Jac*qacc - aref``.
*Nullable:* ``cost``
.. _Support:
These are support functions that need access to :ref:`mjModel` and :ref:`mjData`, unlike the utility functions which do
@@ -177,18 +196,92 @@ computations, and are documented in more detail below.
.. _mj_stateSize:
Returns the number of :ref:`mjtNum` |-| s required for a given state specification. The bits of the integer ``spec``
Returns the number of :ref:`mjtNum` |-| s required for a given state signature. The bits of the integer ``sig``
correspond to element fields of :ref:`mjtState`.
.. _mj_getState:
Copy concatenated state components specified by ``spec`` from ``d`` into ``state``. The bits of the integer
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
Copy concatenated state components specified by ``sig`` from ``d`` into ``state``. The bits of the integer
``sig`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``sig`` is invalid.
.. _mj_extractState:
Extract into ``dst`` the subset of components specified by ``dstsig`` from a state ``src`` previously obtained via
:ref:`mj_getState` with components specified by ``srcsig``. Fails with :ref:`mju_error` if the bits set in ``dstsig``
is not a subset of the bits set in ``srcsig``.
.. _mj_setState:
Copy concatenated state components specified by ``spec`` from ``state`` into ``d``. The bits of the integer
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
Copy concatenated state components specified by ``sig`` from ``state`` into ``d``. The bits of the integer
``sig`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``sig`` is invalid.
.. _mj_readCtrl:
Read the control value for an actuator at a given time, taking delays into account. If no history buffer exists, return
``mjData.ctrl[id]``. If a history buffer exists (:ref:`nsample<actuator-general-nsample>` > 0), read from the delay
buffer at ``time - actuator_delay[id]`` using the requested interpolation order:
- ``interp = 0``: Zero-order hold (piecewise constant)
- ``interp = 1``: Piecewise Linear
- ``interp = 2``: Cubic Spline (Catmull-Rom)
- ``interp = -1``: Use the actuator's :ref:`interp<actuator-general-interp>` value.
Constant extrapolation is used outside of buffer bounds.
Note that the subtraction of the delay changes the semantic of the ``time`` argument from "time at which values were
pushed into the delay buffer" to "time at which values come out of the delay buffer". See :ref:`Delays<CDelay>` for
details.
.. _mj_readSensor:
Read a sensor value at a given time, taking delays into account. If no history buffer exists, return a pointer to the
sensor's slice of ``mjData.sensordata``. If a history buffer exists (:ref:`nsample<sensor-nsample>` > 0), read from the
history buffer at ``time - sensor_delay[id]``. Note that the subtraction of the delay changes the semantic of the
``time`` argument from "time at which values were pushed into the delay buffer" to "time at which values come out of the
delay buffer". See :ref:`Delays<CDelay>` for details.
**Return value semantics:**
- If no history buffer exists (:ref:`nsample<sensor-nsample>` = 0), returns a pointer to the sensor's slice of
``mjData.sensordata``.
- If a history buffer exists (:ref:`nsample<sensor-nsample>` > 0) and the requested time matches a stored sample
(always true for ``interp = 0``), returns a pointer to the data in the history buffer.
- If interpolation is required (``interp = 1 or 2``), returns ``NULL`` and writes the interpolated result to
``result`` (must be of size ``dim``).
**Interpolation:**
- ``interp = 0``: Zero-order hold (piecewise constant)
- ``interp = 1``: Piecewise Linear
- ``interp = 2``: Cubic Spline (Catmull-Rom)
- ``interp = -1``: Use the value in :ref:`interp<sensor-interp>`
Constant extrapolation is used outside of buffer bounds.
**Usage:**
.. code-block:: C
// read sensor 0 of data size `dim` at time t
mjtNum result[dim];
const mjtNum* ptr = mj_readSensor(m, d, 0, t, result, /* interp = */ 1);
const mjtNum* data = ptr ? ptr : result;
.. _mj_initCtrlHistory:
Initialize the history buffer for an actuator with custom values. The ``times`` array specifies the timestamps for each
sample (must be length :ref:`nsample<actuator-general-nsample>`), and ``values`` specifies the control values. If
``times`` is ``NULL``, the existing timestamps in the buffer are used, and only the values are updated.
See :ref:`Delays<CDelay>` for details.
.. _mj_initSensorHistory:
Initialize the history buffer for a sensor with custom values. The ``times`` array specifies the timestamps for each
sample (must be length :ref:`nsample<sensor-nsample>`), and ``values`` specifies the sensor values (must be of size
``nsample * dim``). If ``times`` is ``NULL``, the existing timestamps in the buffer are used.
The ``phase`` argument sets the user slot, which stores the last computation time for interval sensors.
See :ref:`Delays<CDelay>` for details.
.. _mj_mulJacVec:
@@ -212,11 +305,15 @@ center-of-mass but aligned with the world frame. The minimal :ref:`pipeline stag
computations to be consistent with the current generalized positions ``mjData.qpos`` are :ref:`mj_kinematics` followed
by :ref:`mj_comPos`.
*Nullable:* ``jacp``, ``jacr``
.. _mj_jacBody:
This and the remaining variants of the Jacobian function call mj_jac internally, with the center of the body, geom or
site. They are just shortcuts; the same can be achieved by calling mj_jac directly.
*Nullable:* ``jacp``, ``jacr``
.. _mj_jacDot:
This function computes the time-derivative of an end-effector kinematic Jacobian computed by :ref:`mj_jac`.
@@ -224,6 +321,8 @@ The minimal :ref:`pipeline stages<piStages>` required for computation to be
consistent with the current generalized positions and velocities ``mjData.{qpos, qvel}`` are
:ref:`mj_kinematics`, :ref:`mj_comPos`, :ref:`mj_comVel` (in that order).
*Nullable:* ``jacp``, ``jacr``
.. _mj_angmomMat:
This function computes the ``3 x nv`` angular momentum matrix :math:`H(q)`, providing the linear mapping from
@@ -245,23 +344,17 @@ Returns the smallest signed distance between two geoms and optionally the segmen
Returned distances are bounded from above by ``distmax``. |br| If no collision of distance smaller than ``distmax`` is
found, the function will return ``distmax`` and ``fromto``, if given, will be set to (0, 0, 0, 0, 0, 0).
.. admonition:: different (correct) behavior under `nativeccd`
:class: note
*Nullable:* ``fromto``
As explained in :ref:`Collision Detection<coDistance>`, distances are inaccurate when using the
:ref:`legacy CCD pipeline<coCCD>`, and its use is discouraged.
.. admonition:: different (correct) behavior under `nativeccd`
:class: note
.. _mj_fullM:
Convert sparse inertia matrix ``M`` into full (i.e. dense) matrix.
|br| ``dst`` must be of size ``nv x nv``, ``M`` must be of the same size as ``mjData.qM``.
As explained in :ref:`Collision Detection<coDistance>`, distances are inaccurate when using the
:ref:`legacy CCD pipeline<coCCD>`, and its use is discouraged.
.. _mj_mulM:
This function multiplies the joint-space inertia matrix stored in mjData.qM by a vector. qM has a custom sparse format
that the user should not attempt to manipulate directly. Alternatively one can convert qM to a dense matrix with
mj_fullM and then user regular matrix-vector multiplication, but this is slower because it no longer benefits from
sparsity.
This function multiplies the joint-space inertia matrix stored in ``mjData.M`` by a vector.
.. _mj_applyFT:
@@ -302,16 +395,18 @@ rays from a single point.
.. _mj_ray:
Intersect ray ``(pnt+x*vec, x >= 0)`` with visible geoms, except geoms in bodyexclude.
Intersect ray ``pnt+x*vec, x >= 0`` with geoms.
Return geomid and distance (x) to nearest surface, or -1 if no intersection.
- Return distance ``x`` to nearest surface, or -1 if no intersection.
- If ``geomid`` is not NULL, write the id of the intersected geom or -1 if not intersection.
- If ``normal`` is not NULL, write the surface normal at the intersection point. The normal always points **out of the
geometry**, regardless of the ray's direction (i.e., including rays hitting the surface from the inside).
- Exclude geoms in body with id ``bodyexclude``, use -1 to include all bodies.
- ``geomgroup`` is an array of length :ref:`mjNGROUP<glNumericVisualization>`, where 1 means the group should be included. Pass
NULL to skip geom group exclusion.
- If ``flg_static`` is 0, static geoms will be excluded.
geomgroup is an array of length mjNGROUP, where 1 means the group should be included. Pass geomgroup=NULL to skip
group exclusion.
If flg_static is 0, static geoms will be excluded.
bodyexclude=-1 can be used to indicate that all bodies are included.
*Nullable:* ``geomgroup``, ``geomid``, ``normal``
.. _Interaction:
@@ -332,6 +427,11 @@ The functions in this section implement abstract visualization. The results are
also be used by users wishing to implement their own renderer, or hook up MuJoCo to advanced rendering tools such as
Unity or Unreal Engine. See :ref:`simulate<saSimulate>` for illustration of how to use these functions.
.. _FilamentRenderingApi:
Rendering functions using the Filament rendering engine. These functions are prefixed with ``mjrf``. See
:ref:`Filament Rendering<tyFilamentRenderStructure>` for an overview of the core types and their uses.
.. _OpenGLrendering:
These functions expose the OpenGL renderer. See :ref:`simulate<saSimulate>` for an illustration
@@ -348,7 +448,7 @@ each corresponding to one item. The last (unused) item has its type set to -1, t
after the end of the last used section. There is also another version of this function
(:ref:`mjui_addToSection<mjui_addToSection>`) which adds items to a specified section instead of adding them at the end
of the UI. Keep in mind that there is a maximum preallocated number of sections and items per section, given by
:ref:`mjMAXUISECT<glNumeric>` and :ref:`mjMAXUIITEM<glNumeric>`. Exceeding these maxima results in low-level errors.
:ref:`mjMAXUISECT<glNumericUI>` and :ref:`mjMAXUIITEM<glNumericUI>`. Exceeding these maxima results in low-level errors.
.. _mjui_update:
@@ -378,6 +478,102 @@ time, while :ref:`mjui_update` is called only when changes in the UI take place.
.. _Errorandmemory:
.. _mju_error:
Main error function. The error message is dispatched to the active log handler (see :ref:`mju_setLogHandler`).
Errors are always fatal: if the handler returns, the process is terminated with ``exit(EXIT_FAILURE)``. Handlers
wishing to recover must ``longjmp`` or otherwise transfer control before returning.
.. _mju_warning:
Main warning function; returns to caller. The warning message is dispatched to the active log handler.
.. _mju_clearHandlers:
Clear all user handlers and restore defaults. Resets the legacy error/warning/memory callbacks to ``NULL``, restores
the default log handler, and resets the log configuration to its defaults (console and file output enabled, all info
topics disabled).
.. _mju_setLogHandler:
Set the active global log handler. Returns the previous handler (which is never ``NULL``), intended for save/restore
or callback chaining. If ``handler`` is ``NULL``, the default handler is restored. The handler receives all errors,
warnings and informational messages as a structured :ref:`mjLogMessage`. See :ref:`siLogHandler` for usage examples.
.. _mju_getLogConfig:
Get the current default handler configuration. See :ref:`mjLogConfig`.
.. _mju_setLogConfig:
Set the default handler configuration. Controls console output, file output, and info topic filtering.
See :ref:`mjLogConfig`.
Example usage (disabling file output):
.. code-block:: C
mjLogConfig config = mju_getLogConfig();
config.logto_file = false;
mju_setLogConfig(config);
.. _mju_info:
Log an informational message with optional topic filtering. The ``topic`` argument is a :ref:`mjtLogTopic` value.
Topic 0 (``mjTOPIC_NONE``) always passes through. Other topics must be enabled in the default handler configuration
via :ref:`mju_setLogConfig`. Note that topic filtering is implemented in the default handler; custom handlers
receive all info messages regardless.
.. _mju_message:
Dispatch a structured :ref:`mjLogMessage` to the active log handler. This is the primary entry point for emitting
log messages with full control over all fields. The convenience functions :ref:`mju_error`, :ref:`mju_warning`, and
:ref:`mju_info` are thin wrappers that populate an ``mjLogMessage`` and call this function.
The ``subject`` field is a one-line summary (up to 1024 bytes, inline in the struct). The ``body`` field is an
optional ``const char*`` pointer to multi-line detail text, owned by the caller. When ``body`` is ``NULL``, only the
subject line is printed.
The default handler formats the output as follows:
.. code-block:: text
LEVEL FUNC (FILE:LINE) TIME: SUBJECT
BODY
where:
- ``LEVEL`` is ``ERROR``, ``WARNING``, ``INFO``, or ``DEBUG``.
- ``FUNC`` is present when the ``func`` field is set.
- ``(FILE:LINE)`` is present when the ``file`` and ``line`` fields are set.
- ``TIME`` is present when the ``timestamp`` field is set or file logging is active.
- ``SUBJECT`` is the contents of the ``subject`` field.
- ``BODY`` follows on the next line(s), printed raw without indentation or separators, only if non-NULL.
The default handler appends a trailing blank line after ``ERROR``, ``WARNING``, and ``INFO`` messages for visual
separation. ``DEBUG`` messages are printed compactly without a trailing blank line.
Example usage:
.. code-block:: C
mjLogMessage msg = {
.level = mjLOG_INFO,
.timestamp = true,
.body = " height: 0.001 m\n velocity: 0.000 m/s\n bounces: 47",
};
snprintf(msg.subject, sizeof(msg.subject), "The ball has come to rest");
mju_message(&msg);
This produces:
.. code-block:: text
INFO Mon Jun 9 15:04:05 2026: The ball has come to rest
height: 0.001 m
velocity: 0.000 m/s
bounces: 47
.. _Standardmath:
The "functions" in this section are preprocessor macros replaced with the corresponding C standard library math
@@ -614,7 +810,7 @@ outputs of derivative functions are the trailing rather than leading arguments.
Compute finite-differenced discrete-time transition matrices.
Letting :math:`x, u` denote the current :ref:`state<gePhysicsState>` and :ref:`control<geInput>`
Letting :math:`x, u` denote the current :ref:`state<siPhysicsState>` and :ref:`control<siInput>`
vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor
values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`
:ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing.
@@ -654,12 +850,13 @@ These matrices and their dimensions are:
termination. Of course, this means that :ref:`solver iterations<option-iterations>` should be small, to not tread
water at the minimum. This method and the one described above can and should be combined.
*Nullable:* ``A``, ``B``, ``D``, ``C``
.. _mjd_inverseFD:
Finite differenced continuous-time inverse-dynamics Jacobians.
Letting :math:`x, a` denote the current :ref:`state<gePhysicsState>` and acceleration vectors in an mjData instance, and
Letting :math:`x, a` denote the current :ref:`state<siPhysicsState>` and acceleration vectors in an mjData instance, and
letting :math:`f, s` denote the forces computed by the inverse dynamics (``qfrc_inverse``), the function
:ref:`mj_inverse` computes :math:`(x,a) \rightarrow (f,s)`. :ref:`mjd_inverseFD` computes seven associated Jacobians
using finite-differencing. These matrices and their dimensions are:
@@ -675,7 +872,7 @@ using finite-differencing. These matrices and their dimensions are:
``DsDq``, :math:`\partial s / \partial q`, ``nv x nsensordata``
``DsDv``, :math:`\partial s / \partial v`, ``nv x nsensordata``
``DsDa``, :math:`\partial s / \partial a`, ``nv x nsensordata``
``DmDq``, :math:`\partial M / \partial q`, ``nv x nM``
``DmDq``, :math:`\partial M / \partial q`, ``nv x nC``
- All outputs are optional (can be NULL).
- All outputs are transposed relative to Control Theory convention (i.e., column major).
@@ -693,10 +890,14 @@ using finite-differencing. These matrices and their dimensions are:
- The Runge-Kutta 4th-order integrator (``mjINT_RK4``) is not supported.
- The noslip solver is not supported.
*Nullable:* ``DfDq``, ``DfDv``, ``DfDa``, ``DsDq``, ``DsDv``, ``DsDa``, ``DmDq``
.. _mjd_subQuat:
Derivatives of :ref:`mju_subQuat` (quaternion difference).
*Nullable:* ``Da``, ``Db``
.. _mjd_quatIntegrate:
Derivatives of :ref:`mju_quatIntegrate`.
@@ -718,3 +919,10 @@ to the inputs. Below, :math:`\bar q` denotes the pre-modified quaternion:
Note that derivatives depend only on :math:`h` and :math:`v` (in fact, on :math:`s = h v`).
All outputs are optional.
*Nullable:* ``Dquat``, ``Dvel``, ``Dscale``
.. _Resources:
Resources are the interface between :ref:`resource providers <exProvider>` and MuJoCo model compilation code.
These functions provide the means to query the resource provider and obtain resources.
+63
View File
@@ -0,0 +1,63 @@
Building
========
.. WARNING:: OpenUSD support is currently experimental and subject to frequent change.
MuJoCo must be built against a pre-built USD library, we provide a utility to do so but you may also bring your own USD
libraries.
The following instructions assume that you have cloned MuJoCo into ``~/mujoco`` and have a build directory at
``~/mujoco/build``.
.. _usdBuildingUSD:
Building USD
------------
If you have a pre-built USD library, you can skip this section.
MuJoCo provides a CMake project that simplifies the process of building USD. It will download and build USD with only
the necessary features enabled.
.. code-block:: bash
cd ~/mujoco
cmake -Bcmake/third_party_deps/openusd/build cmake/third_party_deps/openusd
cmake --build cmake/third_party_deps/openusd/build
If you want to customize the build process, you can use USD's ``build_usd.py`` script. It's recommended to use a
separate installation directory that exists outside of the cloned repository directory.
.. code-block:: bash
git clone https://github.com/PixarAnimationStudios/OpenUSD
python OpenUSD/build_scripts/build_usd.py /path/to/my_usd_install_dir
.. _usdEnablingUSD:
Enabling USD
------------
If USD was built with the third_party_deps/openusd CMake project, you can enable USD support with the MUJOCO_WITH_USD
flag.
.. code-block:: bash
cd ~/mujoco
cmake -Bbuild -S. -DMUJOCO_WITH_USD=True
cmake --build build -j 64
Otherwise, if you have a pre-built USD library, you must also pass the pxr_DIR flag.
.. code-block:: bash
cd ~/mujoco
cmake -Bbuild -S. -DMUJOCO_WITH_USD=True -Dpxr_DIR=/path/to/my_usd_install_dir
cmake --build build -j 64
If we now run :ref:`simulate.cc <saSimulate>`, we will be able to drag and drop USD files.
.. code-block:: bash
simulate
+26
View File
@@ -0,0 +1,26 @@
Exporting
=========
.. WARNING:: OpenUSD support is currently experimental and subject to frequent change.
Currently, exporting MuJoCo scenes to OpenUSD format is an area of active development. The primary method for exporting
is expected to be through the Python API.
USDExporter
-----------
At the moment the only way to export USD from MuJoCo is to use the existing USDExporter in :doc:`../python`.
We are working on native support for writing simulations as animations to existing USD scenes, please check back here
for updates.
mujoco-usd-converter
--------------------
To convert existing MJCF assets to USD following strong authoring guidelines we recommend the `Newton
mujoco-usd-converter <https://github.com/newton-physics/mujoco-usd-converter>`__. These assets will have no reference to
the original MJCF assets but will use the :doc:`mjcPhysics <mjcPhysics>` schemas to enable faithful representation of
the source assets.
When opened, these assets should be similar to the ones generated by the :doc:`MJCF file format plugin
<mjcf_file_format_plugin>`, but there will not be any runtime overhead from converting MJCF to USD.
+29
View File
@@ -0,0 +1,29 @@
Importing
=========
.. WARNING:: OpenUSD support is currently experimental and subject to frequent change.
MuJoCo can load assets from OpenUSD files (``.usd``, ``.usda``, ``.usdc``, ``.usdz``). This allows you to incorporate
assets and scenes defined in USD into your MuJoCo simulations.
USD in MJCF
-----------------------------
If you have built mujoco with USD enabled, you can reference USD assets from MJCF via the ``<model`` tag with content
type ``text/usd``.
.. code-block:: xml
:caption: example.xml
<mujoco>
<asset>
<model file="chair.usdz" name="chair" content_type="text/usd"/>
</asset>
<worldbody>
...
</worldbody>
</mujoco>
In this example the ``<model file="chair.usdz"/>`` line in ``<asset>`` tells MuJoCo to load and process the USD file.
+63
View File
@@ -0,0 +1,63 @@
OpenUSD
===========
.. toctree::
:hidden:
building
mjcPhysics
mjcf_file_format_plugin
importing
exporting
.. WARNING:: OpenUSD support is currently experimental and subject to frequent change.
Introduction
------------
This chapter describes MuJoCo's support for `OpenUSD <https://openusd.org/release/intro.html>`__. USD (Universal Scene
Description) is an open-source framework developed by Pixar for describing 3D scenes. MuJoCo's integration allows users
to leverage USD's rich ecosystem and tooling.
What is OpenUSD?
----------------
USD is a high-performance, extensible system for describing, composing, simulating, and collaborating on 3D data.
Originally developed by Pixar Animation Studios, USD is now used across various industries, including visual effects,
animation, gaming, and robotics, to streamline complex 3D workflows. It provides a common language for different
software applications to exchange 3D scene information.
Why do we care about OpenUSD?
-----------------------------
Integrating USD with MuJoCo offers several advantages:
* **Interoperability:** USD is supported by a wide range of 3D content creation tools (e.g., Houdini, Maya, Blender).
This allows MuJoCo users to easily import scenes and assets created in these tools.
* **Rich Scene Description:** USD provides a powerful and flexible way to represent complex scenes, including
geometry, materials, lighting, and hierarchies.
* **Collaboration:** USD's layering and composition features enable powerful and efficient
non-destructive authoring pipelines.
USD support overview
------------------------------------------------------
* **Import:** You can load USD assets (specifically ``.usd``, ``.usda``, ``.usdc``, ``.usdz`` files) into MuJoCo via
MJCF or dragging and dropping into :ref:`simulate.cc <saSimulate>`.
* **Schemas:** MuJoCo primarily uses the standard `UsdPhysics
<https://openusd.org/dev/api/usd_physics_page_front.html>`__ schemas for representing physics properties.
* **Extensions:** Custom :doc:`mjcPhysics` schemas are provided to cover MuJoCo-specific features not available in
``UsdPhysics``.
* **MJCF File Format Plugin:** A :doc:`mjcf_file_format_plugin` allows treating MJCF files as USD layers in any native USD
application.
* **Export:** MuJoCo scenes can be exported to USD.
Where do I learn more about USD?
------------------------------------------
* `Remedy's Book of USD <https://remedy-entertainment.github.io/USDBook>`__: Friendly introduction to USD.
* `Official OpenUSD Documentation <https://openusd.org/release/intro.html>`__: Official documentation for API and
implementation details.
* `Pixar's USD Introduction <https://graphics.pixar.com/usd/release/index.html>`__: Simple example usage of USD.
* `NVIDIA's USD Resources <https://developer.nvidia.com/usd>`__: Set of USD resources primarily concerned with asset
structure.
+107
View File
@@ -0,0 +1,107 @@
mjcPhysics
==========
.. WARNING:: OpenUSD support is currently experimental and subject to frequent change.
The ``mjcPhysics`` `schema <https://openusd.org/release/api/_usd__page__generating_schemas.html>`__ allows for detailed
specification of a MuJoCo simulation environment directly within a USD file. The aim is not to replace `UsdPhysics
<https://openusd.org/release/api/usd_physics_page_front.html>`__, but to extend existing concepts and create new types
only where is necessary.
The schema can be use `codeless <https://openusd.org/dev/api/_usd__page__generating_schemas.html#Codeless_Schemas>`__,
or can be built with its C++ bindings. We've pre-generated `the code
<https://github.com/google-deepmind/mujoco/tree/main/src/experimental/usd/mjcPhysics>`__ via `usdGenSchema
<https://openusd.org/dev/api/_usd__page__generating_schemas.html>`_ for internal MuJoCo usage, but it should also work
outside of MuJoCo.
API Schemas
-----------
MjcSceneAPI
^^^^^^^^^^^
This API schema provides global options for the MuJoCo simulation. It is an
amalgamation of the ``<option>``, ``<option/flag>`` and ``<compiler>`` elements in
MJCF. Users should apply this to an existing
`UsdPhysicsScene <https://openusd.org/dev/api/class_usd_physics_scene.html>`__
prim.
Key attributes include:
- **mjc:option**: Attributes in this namespace map to the ``<option>`` element.
- **mjc:flag**: Attributes in this namespace map to the ``<option/flag>`` element.
- **mjc:compiler**: Attributes in this namespace map to the ``<compiler>`` element.
MjcSiteAPI
^^^^^^^^^^
This API class is used to define a MuJoCo site, it can be applied to
`UsdGeomSphere <https://openusd.org/dev/api/class_usd_geom_sphere.html>`__,
`UsdGeomCapsule <https://openusd.org/dev/api/class_usd_geom_capsule.html>`__,
`UsdGeomCylinder <https://openusd.org/dev/api/class_usd_geom_cylinder.html>`__, and
`UsdGeomCube <https://openusd.org/dev/api/class_usd_geom_cube.html>`__.
MjcImageableAPI
^^^^^^^^^^^^^^^
This API class provides attributes for strictly visual entities in MuJoCo, in
MuJoCo terms we would quantify these has having ``contype = conaffinity = 0``.
MjcCollisionAPI
^^^^^^^^^^^^^^^
This API class is applied to prims that represent collision geometry and should
be applied alongside
`UsdPhysicsCollisionAPI <https://openusd.org/dev/api/class_usd_physics_collision_a_p_i.html>`__.
MjcMeshCollisionAPI
^^^^^^^^^^^^^^^^^^^
This API class is applied to prims that represent mesh collision geometry and
should be applied alongside
`UsdPhysicsMeshCollisionAPI <https://openusd.org/dev/api/class_usd_physics_mesh_collision_a_p_i.html>`__.
MjcJointAPI
^^^^^^^^^^^
This API class is applied to `UsdPhysicsJoint <https://openusd.org/dev/api/class_usd_physics_joint.html>`__ prims,
adding extra attributes to fully describe MuJoCo joints.
MjcMaterialAPI
^^^^^^^^^^^^^^
This API class provides attributes for physical materials and is an extension of `UsdPhysicsMaterialAPI
<https://openusd.org/dev/api/class_usd_physics_material_a_p_i.html>`__
Type Schemas
------------
MjcActuator
^^^^^^^^^^^
This class represents a MuJoCo actuator, which is responsible for applying force to a transmission target joint, body,
or site specific via a `relationship <https://openusd.org/dev/api/class_usd_relationship.html>`__.
We do not use the existing `UsdPhysicsDriveAPI <https://openusd.org/dev/api/class_usd_physics_drive_a_p_i.html>`__ as it
is closer to a runtime construct and the concepts do not map very closely.
MjcKeyframe
^^^^^^^^^^^
This type holds tensor values representing simulator state at specific time values.
In MJCF this is the ``<keyframe>`` element and has a ``time`` attribute. In USD we map the time attribute to
`timeSamples <https://openusd.org/release/tut_xforms.html>`__ instead.
The order of the values in the keyframes should map to the depth first ordered traversal of rigidbodies in the composed
stage.
MjcTendon
^^^^^^^^^
This type represents both fixed and spatial tendons.
In MJCF this is the ``<tendon>`` element. The tendon path is represented by the ordered list of targets in the
``mjc:path`` relationship attribute. In MJCF we can specify attributes such as ``sidesite`` and ``divisor`` on
path targets; but in USD we cannot attach data to relationship attributes as elegantly, so these become indexed
array attributes such as ``mjc:sideSites`` and ``mjs:path:divisors``.
+87
View File
@@ -0,0 +1,87 @@
File Format Plugin
=========================
What is an SdfFileFormat plugin?
--------------------------------
In the OpenUSD framework, ``Sdf`` stands for Scene Description Foundations. It's the underlying layer that handles the
serialization and composition of scene data. A ``SdfFileFormat`` plugin is a component that teaches USD how to read and
write a specific file format.
By default, USD comes with plugins for its own formats (``.usda``, ``.usdc``, ``.usdz``) and the community has created
several plugin extension such as the `Adobe File Format Plugins
<https://github.com/adobe/USD-Fileformat-plugins/tree/main>`__.
The MJCF ``SdfFileFormat`` plugin allows USD-aware applications to directly understand and interact with MuJoCo's native
``.xml`` (MJCF) files as if they were native USD files.
What does it enable?
------------------------
This plugin enables:
1. **Referencing MJCF files in USD:** Using standard USD composition arcs (like references, payloads) to include an
MJCF file directly within a larger USD scene. For example, you can place a MuJoCo robot defined in an ``.xml`` file
into a room scene modeled in USD.
2. **Load MJCF files in USD tools:** Tools like ``usdview`` or other USD-based
applications can open, inspect, and render MJCF files, translating the MJCF elements into USD prims and attributes
on the fly.
3. **Convert MJCF to USD:** The plugin can be used as a basis for converting MJCF files to persistent
USD files (e.g., ``.usda`` or ``.usdc``).
Essentially, it makes MJCF a first-class citizen in the USD ecosystem.
Usage
------------------
1. **Installation:** refer to :doc:`building`.
2. **Referencing in a USD file (e.g., ``.usda``):**
.. code-block:: usd
:caption: example.usda
#usda 1.0
(
upAxis = "Z"
)
def Xform "world"
{
def "robot" (
prepend references = @./my_robot.xml@
)
{
}
}
In this example, ``my_robot.xml`` is an MJCF file in the same directory. USD will use the plugin to load and
interpret its contents.
3. **Opening in usdview:**
.. code-block:: bash
usdview my_robot.xml
If the plugin is correctly set up, ``usdview`` will render the robot defined in the MJCF file.
4. **Using in Python (with USD API):**
.. code-block:: python
from pxr import Usd
# Load an MJCF file as a USD stage
stage = Usd.Stage.Open('my_robot.xml')
if stage:
print(f"Successfully opened {stage.GetRootLayer().identifier}")
# You can now inspect the stage as any other USD stage
for prim in stage.TraverseAll():
print(prim.GetPath())
else:
print("Failed to open MJCF file")
This plugin significantly enhances the interoperability between MuJoCo and USD-based workflows, allowing
seamless integration of physics assets defined in MJCF into broader 3D environments.
+2364 -577
View File
File diff suppressed because it is too large Load Diff
+6776 -1687
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+80
View File
@@ -0,0 +1,80 @@
/**
* This script hides Sphinx auto-generated attribute links from the
* "On this page" sidebar.
* Adapted for the Furo theme.
* Uses a MutationObserver to wait for Furo's JavaScript to create the
* sidebar before attempting to modify it.
*/
function hideAttributesFromTOC() {
// Furo's "On this page" sidebar container has the class .toc-tree
const tocContainerSelector = '.toc-tree';
// Step 1: Find all attribute definitions and collect their IDs.
const attributeDefs = document.querySelectorAll('dl.py.attribute');
if (attributeDefs.length === 0) {
return false; // No attributes on this page, nothing to do.
}
const attributeIds = new Set();
attributeDefs.forEach(def => {
const term = def.querySelector('dt');
if (term && term.id) {
attributeIds.add(term.id);
}
});
if (attributeIds.size === 0) {
return false; // No attribute IDs found.
}
// Step 2: Find the sidebar container.
const tocContainer = document.querySelector(tocContainerSelector);
if (!tocContainer) {
// Container not found yet. The observer will try again.
return false;
}
// Step 3: Get all links within that sidebar.
const tocLinks = tocContainer.querySelectorAll('a');
if (tocLinks.length === 0) {
return false; // Container found, but it's empty. Let's wait.
}
// Step 4: Iterate through the links and hide the ones that match.
let hiddenCount = 0;
tocLinks.forEach(link => {
const href = link.getAttribute('href');
if (href && href.startsWith('#')) {
const linkId = href.substring(1);
if (attributeIds.has(linkId)) {
// In Furo, the link is inside a list item (<li>) which we need to hide.
const listItem = link.closest('li');
if (listItem && listItem.style.display !== 'none') {
console.log(`Hiding sidebar link for: #${linkId}`);
listItem.style.display = 'none';
hiddenCount++;
}
}
}
});
// If we successfully hid the links, we can stop observing.
if (hiddenCount > 0) {
return true; // Signal success
}
// If we found the container but didn't hide anything, maybe it's not fully
// rendered. Let the observer run a few more times. A better approach might be
// needed if this fails, but for most cases, this is sufficient.
return false;
}
// Use a MutationObserver to wait for the page to be dynamically built.
const observer = new MutationObserver((mutations, obs) => {
// We only need to run our function once successfully.
if (hideAttributesFromTOC()) {
obs.disconnect(); // Stop observing once the task is done.
}
});
// Start observing the entire document body for added/removed nodes.
observer.observe(document.body, {childList: true, subtree: true});
+2075 -884
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -72,7 +72,7 @@ body coordinates are
g_{V, i} = \quad &- 8 \beta \pi r_{eq}^3 \omega_i \\
\end{aligned}
One can also affect these forces by specifing a non-zero :ref:`wind<option-wind>`, which is a 3D vector subtracted
One can also affect these forces by specifying a non-zero :ref:`wind<option-wind>`, which is a 3D vector subtracted
from the body linear velocity in the fluid dynamics computation.
.. _flEllipsoid:
@@ -357,7 +357,7 @@ of symmetry because under this assumption the kinetic energy greatly simplifies
.. math::
2 \mathcal{T} = m_{A, x} v_x^2 + m_{A, y} v_y^2 + m_{A, z} v_z^2 +
I_{A, x} \omega_x^2 + I_ {A, y} \omega_y^2 + I_{A, y} \omega_z^2
I_{A, x} \omega_x^2 + I_ {A, y} \omega_y^2 + I_{A, z} \omega_z^2
For convenience we introduce the added-mass vector :math:`\mathbf{m}_A = \{m_{A, x}, m_{A, y}, m_{A, z}\}` and added-moment of
@@ -429,7 +429,7 @@ bagheri2016`. See screen capture of the
We derive a formula for :math:`\mathbf{f}_\text{D}` based on two surfaces :math:`A^\text{proj}_\mathbf{v}` and
:math:`A_\text{max}`. The first, :math:`A^\text{proj}_\mathbf{v}`, is the cylindrical projection of the body onto a
plane normal to the velocity :math:`\mathbf{v}`. The second is the maximum projected surface
:math:`A_\text{max} = 4 \pi r_{max} r_{min}`.
:math:`A_\text{max} = \pi r_{max} r_{mid}`.
.. math::
\mathbf{f}_\text{D} = - \rho~ \big[ C_{D, \text{blunt}} ~ A^\text{proj}_\mathbf{v} ~ +
@@ -541,7 +541,7 @@ onto the surface. The lift force per unit length can be computed with the Kutta
:math:`\mathbf{f}_K / L = \rho \Gamma_\text{K} \times \mathbf{v}`.
In order to extend the lift force equation to three-dimensional motions, we consider the normal
:math:`\mathbf{n}_{s, \mathbf{v}} = \{\frac{r_y r_z}{r_x}v_x, \frac{r_z r_x}{r_y}v_y, \frac{r_x r_x}{r_z}v_z\}`
:math:`\mathbf{n}_{s, \mathbf{v}} = \{\frac{r_y r_z}{r_x}v_x, \frac{r_z r_x}{r_y}v_y, \frac{r_x r_y}{r_z}v_z\}`
to the cross-section of the body which generates the body's projection :math:`A^\text{proj}_\mathbf{v}` onto a plane
normal to the velocity given in the :ref:`lemma<flProjection>` above and the corresponding unit vector
:math:`\hat{\mathbf{n}}_{s, \mathbf{v}}`.
+734 -264
View File
File diff suppressed because it is too large Load Diff
+59
View File
@@ -24,6 +24,7 @@ import sys
sys.path.insert(0, os.path.abspath('../'))
sys.path.append(os.path.abspath('ext'))
sys.path.insert(0, os.path.abspath('../mjx/mujoco/mjx/third_party'))
from sphinxcontrib import katex # pylint: disable=g-import-not-at-top
from sphinxcontrib import youtube # pylint: disable=g-import-not-at-top,unused-import
@@ -42,10 +43,15 @@ master_doc = 'index'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx.ext.extlinks',
'sphinxcontrib.bibtex',
'sphinxcontrib.katex',
'sphinxcontrib.youtube',
'sphinx_copybutton',
'sphinx_design',
'sphinx_favicon',
'sphinx_reredirects',
'sphinx_toolbox.collapse',
@@ -54,6 +60,52 @@ extensions = [
'mujoco_include',
]
napoleon_custom_sections = [('warp only fields', 'attributes')]
# Links to GitHub issues and pull requests.
extlinks = {
'issue': (
'https://github.com/google-deepmind/mujoco/issues/%s',
'issue #%s',
),
'pr': ('https://github.com/google-deepmind/mujoco/pull/%s', 'PR #%s'),
'commit': ('https://github.com/google-deepmind/mujoco/commit/%s', '%s'),
}
# MuJoCo Warp documentation
napoleon_google_docstring = True
autodoc_class_signature = 'separated'
add_module_names = False
toc_object_entries_show_parents = 'hide'
default_role = 'literal'
# Suppress warnings from docstrings with RST formatting issues
def setup(app):
import logging
class SphinxWarningFilter(logging.Filter):
def filter(self, record):
msg = record.getMessage()
# e.g. qpos0: qpos values at default pose (*, nq)
if 'Inline emphasis start-string' in msg:
return False
# e.g. see `name` for details
if 'Inline interpreted text' in msg:
return False
# e.g. multi-line definition without trailing blank line
if 'Definition list ends without a blank line' in msg:
return False
# e.g. mjsactuator_ reference in C++ docstrings
if 'Unknown target name' in msg:
return False
return True
for handler in logging.getLogger('sphinx').handlers:
handler.addFilter(SphinxWarningFilter())
# GitHub-related options
github_username = 'google-deepmind'
github_repository = 'mujoco'
@@ -117,6 +169,7 @@ SHARED_CSS_VARIABLES = {
# font-stack--monospace used in code blocks, Inconsolata fits in 100 chars.
html_theme_options = {
'light_css_variables': {
'color-brand-visited': 'var(--color-brand-content)',
'font-stack--monospace': 'Inconsolata,Consolas,ui-monospace,monospace',
'at-color': '#830b2b',
'at-val-color': '#bc103e',
@@ -131,6 +184,7 @@ html_theme_options = {
'wy-nav-side-background-color': '#0053d6',
},
'dark_css_variables': {
'color-brand-visited': 'var(--color-brand-content)',
'at-color': '#ffaab7',
'at-val-color': '#ff95a6',
'body-color': '#14234b',
@@ -163,9 +217,11 @@ html_static_path = [
]
html_css_files = [
'theme_overrides.css',
'theme_overrides_mjwarp.css',
]
html_js_files = [
'linenumbers.js',
'onthispage_mjwarp.js',
]
favicons = [
@@ -206,6 +262,9 @@ latex_macros = r"""
\def \ari {a_{{\rm ref},i}}
\def \aui {a_{0,i}}
\def \aci {a_{1,i}}
\def \nv {n_{\scriptscriptstyle V}}
\def \nc {n_{\scriptscriptstyle C}}
\def \nq {n_{\scriptscriptstyle Q}}
"""
# Translate LaTeX macros to KaTeX and add to options for HTML builder
+227 -10
View File
@@ -28,14 +28,131 @@ body[data-theme="dark"] {
}
}
.schema-small {
font-size: 93%;
/* Make table shadows visible in dark theme. */
body[data-theme="dark"] table.docutils:not(.mjcf-attributes) {
box-shadow: 0 0.2rem 0.5rem rgba(255, 255, 255, 0.15);
}
@media (prefers-color-scheme: dark) {
body[data-theme="auto"] table.docutils:not(.mjcf-attributes) {
box-shadow: 0 0.2rem 0.5rem rgba(255, 255, 255, 0.15);
}
}
.caption-small {
font-size: 85%;
}
.table-small {
font-size: 93%;
}
.small-centered {
font-size: 93%;
}
.table-pairwise {
font-size: 85%;
}
.pairwise-toggles {
display: flex;
align-items: center;
gap: 1.5em;
margin-bottom: 0.75em;
}
.pairwise-toggle-item {
display: flex;
align-items: center;
gap: 0.5em;
}
.pairwise-switch {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
}
.pairwise-switch input {
opacity: 0;
width: 0;
height: 0;
}
.pairwise-slider {
position: absolute;
cursor: pointer;
inset: 0;
background-color: #ccc;
transition: 0.3s;
border-radius: 20px;
}
.pairwise-slider:before {
content: "";
position: absolute;
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
.pairwise-switch input:checked + .pairwise-slider {
background-color: var(--secondary-header-color, #123693);
}
.pairwise-switch input:checked + .pairwise-slider:before {
transform: translateX(16px);
}
.multiccd-off,
.multiccd-native,
.multiccd-legacy {
display: none;
margin: 0;
}
.multiccd-off {
display: inline;
}
.multiccd-enabled .multiccd-off {
display: none;
}
.multiccd-enabled.nativeccd-enabled:not(.margin-enabled) .multiccd-native {
display: inline;
}
.multiccd-enabled:not(.nativeccd-enabled) .multiccd-legacy,
.multiccd-enabled.nativeccd-enabled.margin-enabled .multiccd-legacy {
display: inline;
}
.margin-show {
display: none;
}
.margin-enabled .margin-hide {
display: none;
}
.margin-enabled .margin-show {
display: inline;
}
.small-centered td, .small-centered th,
.table-pairwise td, .table-pairwise th {
text-align: center !important;
vertical-align: middle !important;
border: 2px solid var(--color-table-border) !important;
}
.sidebar-brand-text {
display: none;
}
@@ -80,11 +197,6 @@ h4 {
padding: 6px;
}
/* Don't change color of visited links.
.rst-content a.reference:visited {
color: var(--rst-content-a-color);
} */
.rst-content code, .rst-content tt {
font-size: 90%;
padding: inherit;
@@ -193,15 +305,21 @@ table.aligntop > tbody {
/* Alternate row colors. */
table.docutils:not(.mjcf-attributes) > tbody > tr.row-odd {
table.docutils:not(.mjcf-attributes):not(.no-stripes) > tbody > tr.row-odd {
background-color: var(--row-odd-background-color);
}
/* Disable alternating colors for tables with .no-stripes class */
table.docutils.no-stripes > tbody > tr {
background-color: transparent !important;
}
/* MJCF attributes table. */
table.mjcf-attributes {
border-style: none;
margin-left: 0;
margin-right: 0;
margin-bottom: 0.2em;
width: 100%;
box-shadow: none;
}
@@ -262,8 +380,32 @@ dt .at {
display: none;
}
.admonition p:not(.admonition-title) {
margin-left: 0.5em;
/* Better Furo Admonition Alignment */
.admonition {
padding: 0.5rem 1rem !important; /* Standardize body padding */
}
/* Align the title text perfectly with the body text */
.admonition .admonition-title {
display: flex;
align-items: center;
margin-left: -0.25rem; /* Pulls the title slightly left to balance the icon */
padding-bottom: 0.25rem;
}
/* Align admonition bullets with section-level bullets. The margin is set here
rather than inherited from ul.simple, which docutils drops from any list
holding a multi-paragraph item. */
.admonition > ul {
margin-left: 24px;
padding-left: 0.1em;
margin-top: 0;
margin-bottom: 0;
}
/* (Optional) Drop the background color for a cleaner look */
body {
--color-admonition-background: transparent;
}
/* Reduce top and bottom margins around displayed KaTeX equations */
@@ -283,3 +425,78 @@ dt .at {
details summary {
font-weight: 600;
}
/* ==========================================================================
Schema display styling (.schema-small)
Used in: XMLreference.rst (dropdowns + grids)
========================================================================== */
/* Base: smaller font for compact display */
.schema-small {
font-size: 93%;
}
/* Dropdown styling: compact margins and padding */
.schema-small details.sd-dropdown {
margin-bottom: 0.15em !important;
margin-top: 0 !important;
}
.schema-small .sd-card-header,
.schema-small .sd-card-body {
padding: 0.25em 0.5em !important;
}
.schema-small .sd-summary-text {
font-size: 0.9em;
margin: 0 !important;
}
/* Dropdown hierarchy: left border visualization */
.schema-small .sd-dropdown,
.schema-small > .sd-dropdown,
.schema-small details.sd-dropdown {
border-left: 2px solid #5671cf;
}
body[data-theme="dark"] .schema-small .sd-dropdown,
body[data-theme="dark"] .schema-small > .sd-dropdown,
body[data-theme="dark"] .schema-small details.sd-dropdown {
border-left-color: #7b93e8;
}
@media (prefers-color-scheme: dark) {
body[data-theme="auto"] .schema-small .sd-dropdown,
body[data-theme="auto"] .schema-small > .sd-dropdown,
body[data-theme="auto"] .schema-small details.sd-dropdown {
border-left-color: #7b93e8;
}
}
/* Link styling: prevent visited color change */
.schema-small a:visited {
color: var(--color-brand-primary) !important;
}
/* Grid styling: compact rows for attribute lists */
.schema-small .sd-row {
row-gap: 0 !important;
--sd-gutter-x: 0.5rem !important;
--sd-gutter-y: 0 !important;
}
.schema-small .sd-col,
.schema-small [class*="sd-col-"] {
padding-top: 0 !important;
padding-bottom: 0.1em !important;
}
.schema-small .sd-container-fluid {
padding: 0 !important;
}
/* Remove paragraph margin inside grid items */
.schema-small .sd-container-fluid .sd-col p,
.admonition .sd-container-fluid .sd-col p {
margin-bottom: 0 !important;
}
+147
View File
@@ -0,0 +1,147 @@
/*
* ===================================================================
* Unified Documentation Layout
*
* Creates a consistent two-column layout for class attributes and
* function/method parameters. Includes aggressive overrides to resolve
* conflicts with `theme_overrides.css`.
* ===================================================================
*/
/*
* Part 1: Class-Wide Attribute Alignment Grid
* -------------------------------------------
* This section creates a single grid for all attributes within a class,
* ensuring their names and descriptions are perfectly aligned.
*/
/* The container for all class members becomes the main grid. */
dl.py.class > dd {
display: grid;
grid-template-columns: auto 1fr;
column-gap: 0.5ch;
align-items: baseline;
}
/* This makes each attribute's <dl> transparent to the grid, promoting its
* <dt> and <dd> children to become direct grid items. This is the key
* to achieving the unified alignment.
*/
dl.py.attribute {
display: contents;
}
/* Other class members (main docstring, methods) must span both columns
* to avoid breaking the attribute grid layout.
*/
dl.py.class > dd > p,
dl.py.class > dd > dl:not(.py.attribute) {
grid-column: 1 / -1;
}
dl.py.class > dd > p { margin-bottom: 1rem; }
dl.py.class > dd > dl:not(.py.attribute) { margin-top: 1.5rem; }
/*
* Part 2: Parameter & Return Value Layout
* ---------------------------------------
* This section applies a similar two-column grid to the parameters
* inside functions and methods for a consistent appearance.
*/
/* Target the inner list of parameters to avoid grabbing the main heading. */
dl.py.function .field-list > dd > dl,
dl.py.method .field-list > dd > dl {
display: grid;
grid-template-columns: auto 1fr;
column-gap: 0.5ch;
align-items: baseline;
margin-bottom: 0.4rem;
}
/*
* Part 3: Common Styling for Grid Content
* ---------------------------------------
* These rules reset default styling for elements within our new grids.
*/
/* Reset margins on all description blocks (<dd>) within our custom grids. */
dl.py.attribute > dd,
dl.py.function .field-list > dd > dl > dd,
dl.py.method .field-list > dd > dl > dd {
margin: 0;
padding: 0;
}
/* Add vertical spacing between attribute rows. */
dl.py.attribute > dd {
padding-bottom: 0.4rem;
}
/* Force the main description paragraph of an attribute to stay on one line. */
dl.py.attribute > dd > p {
display: inline;
margin: 0;
}
/*
* Part 4: Specific Styling for Attribute Type Highlight
* -----------------------------------------------------
* This styles the highlighted box for an attribute's type.
*/
/* The container for the type information. */
dl.py.attribute > dd > dl.field-list {
display: flex;
align-items: center;
margin-top: 0.4rem;
}
/* Reset its children. */
dl.py.attribute > dd > dl.field-list > dt,
dl.py.attribute > dd > dl.field-list > dd {
margin: 0;
padding: 0;
}
/* The highlight box itself - reverted to a simple implementation. */
dl.py.attribute > dd > dl.field-list > dd {
font-family: monospace;
font-size: 90%;
}
/*
* Part 5: Aggressive Theme Overrides
* ----------------------------------
* These rules use `!important` to forcefully win conflicts with
* `theme_overrides.css` and ensure our layout is not broken.
*/
/* CONFLICT FIX: Forcefully remove left margins that break our grids. */
dl.py.attribute > dd,
dl.py.attribute > dd > dl.field-list > dd,
dl.py.function .field-list > dd > dl > dd,
dl.py.method .field-list > dd > dl > dd {
margin-left: 0 !important;
}
/* CONFLICT FIX: Remove the double colon rendered by the theme. */
.field-list > dt::after {
content: "" !important;
}
/* CONFLICT FIX: Hide unwanted labels ("TYPE:", "Return type:") and return value. */
dl.py.attribute > dd > dl.field-list > dt,
dl.py.function .field-list > dt[class*="return-type"],
dl.py.method .field-list > dt[class*="return-type"],
dl.py.function .field-list > dt[class*="return-type"] + dd,
dl.py.method .field-list > dt[class*="return-type"] + dd {
display: none !important;
}
/* Remove the underline from all links. */
a {
text-decoration: none !important;
}
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
pdflatex -interaction=nonstopmode -jobname=dcmotor dcmotor.tex 2>&1 | grep -E '(Error|Output written)' && \
bibtex dcmotor 2>&1 | grep -v '^$' && \
pdflatex -interaction=nonstopmode -jobname=dcmotor dcmotor.tex 2>&1 | grep -E '(Error|Output written)' && \
pdflatex -interaction=nonstopmode -jobname=dcmotor dcmotor.tex 2>&1 | grep -E '(Error|Output written)' && \
rm -f *.{aux,log,out,bbl,blg} && \
mv dcmotor.pdf ../_static/
File diff suppressed because it is too large Load Diff
+82
View File
@@ -0,0 +1,82 @@
@article{dewit95,
author = {Canudas de Wit, C. and Olsson, H. and {\AA}str{\"o}m, K. J. and Lischinsky, P.},
title = {{A New Model for Control of Systems with Friction}},
journal = {IEEE Transactions on Automatic Control},
volume = {40},
number = {3},
pages = {419--425},
year = {1995},
month = mar,
}
@article{lugre_revisited,
author = {{\AA}str{\"o}m, K. J. and Canudas de Wit, C.},
title = {{Revisiting the LuGre Friction Model}},
journal = {IEEE Control Systems Magazine},
volume = {28},
number = {6},
pages = {101--114},
year = {2008},
month = dec,
}
@techreport{dahl68,
author = {Dahl, P.},
title = {{A Solid Friction Model}},
institution = {The Aerospace Corporation},
address = {El Segundo, CA},
number = {TOR-0158(3107-18)-1},
year = {1968},
}
@book{hughes2019,
author = {Hughes, Austin and Drury, Bill},
title = {{Electric Motors and Drives: Fundamentals, Types and Applications}},
edition = {5th},
publisher = {Newnes},
year = {2019},
}
@book{tedrake2024,
author = {Tedrake, Russ},
title = {{Underactuated Robotics: Algorithms for Walking, Running,
Swimming, Flying, and Manipulation}},
publisher = {MIT},
year = {2024},
note = {Course notes for MIT 6.832, \url{https://underactuated.mit.edu}},
}
@article{isaaclab2025,
author = {Mittal, Mayank and Yu, Calvin and Yu, Qinxi and Liu, Jingzhou
and Rudin, Nikita and Hoeller, David and Yuan, Jia Lin
and Singh, Ritvik and Guo, Yunrong and Mazhar, Hammad
and Mandlekar, Ajay and Babich, Buck and State, Gavriel
and Hutter, Marco and Garg, Animesh},
title = {{Isaac Lab: A Unified and Modular Framework for Robot Learning}},
journal = {arXiv preprint arXiv:2502.11048},
year = {2025},
}
@article{stribeck1902,
author = {Stribeck, R.},
title = {{Die wesentlichen Eigenschaften der Gleit- und Rollenlager}},
journal = {Zeitschrift des Vereines Deutscher Ingenieure},
volume = {46},
pages = {1341--1348, 1432--1438, 1463--1470},
year = {1902},
}
@misc{maxon_formulas,
author = {{Maxon Motor AG}},
title = {{Key Information on Maxon DC Motors and Maxon EC Motors}},
howpublished = {\url{https://www.maxongroup.com}},
year = {2024},
note = {{Maxon} Academy Technical Notes},
}
@misc{simscape_dcmotor,
author = {{MathWorks}},
title = {{DC Motor --- Simscape Electrical Block Reference}},
howpublished = {\url{https://www.mathworks.com/help/sps/ref/dcmotor.html}},
year = {2024},
}
+39 -6
View File
@@ -37,6 +37,9 @@ _STRUCT_END_REGEX_2 = re.compile(r'^}\s+(?P<token>mj\w+);')
# Precompiled regex for matching a C enum ending.
_ENUM_END_REGEX = re.compile(r'^}\s+(?P<token>mj\w+);')
# Precompiled regex for matching a C type with a nullable annotation.
_NULLABLE_REGEX = re.compile(r'(?P<leading_space>\s*)Nullable:\s*(?P<args>.*)')
@dataclasses.dataclass
class ApiDefinition:
@@ -68,7 +71,7 @@ class ApiState:
return self._state
def export_definition(self):
return ApiDefinition(self.token, self._state, self.code, self._start,
return ApiDefinition(self.token, self._state, self.code, self._start, # pyrefly: ignore[bad-argument-type]
self._end, self.section, self.doc)
def start(self, state):
@@ -112,7 +115,9 @@ def read(lines: List[str]) -> Dict[str, ApiDefinition]:
if stripped_functions:
s.code = f'{s.code}{line}'
else:
s.code = f'{s.code}{line[6:]}'
decl = line.replace('MJAPI ', '')
decl = decl[6:] if decl.startswith(' ' * 6) else decl
s.code = f'{s.code}{decl}'
s.token = token
s.start('FUNCTION')
if _is_function_end(line):
@@ -120,14 +125,28 @@ def read(lines: List[str]) -> Dict[str, ApiDefinition]:
s.end()
continue
elif line.startswith('//'):
s.doc = f'{s.doc}{line[3:]}'
if len(line) > 3 and line[3].isupper():
s.doc += '\n'
comment = line[3:]
match = re.match(_NULLABLE_REGEX, comment)
if match:
groups = match.groupdict()
args = [
f'``{arg.strip()}``'
for arg in groups['args'].split(',')
if arg.strip()
]
comment = f'{groups["leading_space"]}*Nullable:* {", ".join(args)}'
s.doc = f'{s.doc}{comment}'
else:
s.end()
if s.state == 'FUNCTION':
if stripped_functions:
s.code = f'{s.code}{line}'
else:
s.code = f'{s.code}{line[6:]}'
decl = line.replace('MJAPI ', '')
decl = decl[6:] if decl.startswith(' ' * 6) else decl
s.code = f'{s.code}{decl}'
if _is_function_end(line):
api[s.token] = s.export_definition()
s.end()
@@ -161,6 +180,12 @@ def read(lines: List[str]) -> Dict[str, ApiDefinition]:
s.start('STRUCT')
s.code = f'{s.code}{line}'
match = _STRUCT_END_REGEX_1.search(line)
if match is not None:
s.token = match.group('token')
api[s.token] = s.export_definition()
s.end()
if line.startswith('//'):
s.doc = f'{s.doc}{line[3:]}'
s.start('DOC')
@@ -170,7 +195,9 @@ def read(lines: List[str]) -> Dict[str, ApiDefinition]:
if stripped_functions:
s.code = f'{s.code}{line}'
else:
s.code = f'{s.code}{line[6:]}'
decl = line.replace('MJAPI ', '')
decl = decl[6:] if decl.startswith(' ' * 6) else decl
s.code = f'{s.code}{decl}'
s.token = token
s.start('FUNCTION')
if _is_function_end(line):
@@ -188,7 +215,13 @@ def _find_section(line) -> Optional[str]:
def _find_function_start(line, stripped) -> Optional[str]:
if (line.startswith('MJAPI') and 'extern' not in line) or stripped:
if (
'extern' not in line
and 'typedef' not in line
and '#define' not in line
and '_DEBUG_' not in line
and not line.startswith('//')
) or stripped:
match = _FUNCTION_REGEX.search(line)
if match is not None:
return match.group('token')
+1 -1
View File
@@ -87,7 +87,7 @@ class MuJoCoApiGeneratorTest(parameterized.TestCase):
def test_multi_line_doc(self):
self.assertEqual(_API['mj_other_function'].doc,
'My other function\nThis one has multiple lines\n')
'My other function\n\nThis one has multiple lines\n')
def test_multi_line_function(self):
self.assertEqual(_API['mj_other_function'].start, 9)
+104
View File
@@ -0,0 +1,104 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates API for APIReference.rst."""
import sys
from typing import Dict
import os
import sys
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
sys.path.insert(0, os.path.join(_REPO_ROOT, 'doc', 'ext'))
import header_reader
_HEADER_FILES = [
'include/mujoco/mjassert.h',
'include/mujoco/mjdata.h',
'include/mujoco/mjexport.h',
'include/mujoco/mjmacro.h',
'include/mujoco/mjmodel.h',
'include/mujoco/mjplugin.h',
'include/mujoco/mjrender.h',
'include/mujoco/mjrfilament.h',
'include/mujoco/mjspec.h',
'include/mujoco/mjspecmacro.h',
'include/mujoco/mjtype.h',
'include/mujoco/mjui.h',
'include/mujoco/mjvisualize.h',
'include/mujoco/mjxmacro.h',
'include/mujoco/mujoco.h',
]
def generate_reference_header(
api: Dict[str, header_reader.ApiDefinition]) -> str:
"""Generates the reference header file used by APIRererence.rst."""
source = """
// Copyright 2022 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// DO NOT EDIT. THIS FILE IS AUTOMATICALLY GENERATED.
// Error: C reference not found
// NOLINTBEGIN\n\n""".lstrip()
for value in api.values():
if value.c_type != 'FUNCTION':
source = f'{source}{value.code}'
source = f"""{source}
//----------------------------- MJAPI FUNCTIONS --------------------------------
"""
for value in api.values():
if value.c_type == 'FUNCTION':
source = f'{source}{value.code}'
source = f'{source}// NOLINTEND\n'
return source
def read_headers() -> Dict[str, header_reader.ApiDefinition]:
"""Reads API header files and generates a mapping between C tokens and C header definitions."""
api = {}
for header in _HEADER_FILES:
filepath = os.path.join(_REPO_ROOT, header)
with open(filepath, 'r', encoding='utf-8') as file:
api.update(header_reader.read(file.readlines()))
return api
def main() -> None:
if len(sys.argv) > 1:
sys.exit('Too many command-line arguments.')
sys.stdout.buffer.write(generate_reference_header(read_headers()).encode('utf-8'))
if __name__ == '__main__':
main()
+226
View File
@@ -0,0 +1,226 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates the default-value check table from src/xml/mjcf.schema.
The schema declares attribute defaults, but the defaults that act live in
the C default-constructors (mjs_default*, mj_defaultOption, ...). This
emits src/xml/generated/mjcf_default_table.inc: one row per defaulted attribute,
binding the declared values to the field they describe, consumed by
SchemaDefaultsTest, which compares every row against a freshly-constructed
spec -- so a schema default that disagrees with the C defaults is a test
failure, not documentation drift. Checked in and gated by
test/doc/doc_test.py.
"""
import os # pylint: disable=unused-import
import sys
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import generate_read_table
import mjcf_schema
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
# kind codes shared with the test
KIND_BY_CTYPE = {'double': 0, 'float': 1, 'int': 2,
'mjtByte': 3, 'mjtBool': 3, 'mjtNum': 4}
_HEADER = '''\
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_default_table.py; test/doc/doc_test.py checks
// freshness.
//
// One row per bound numeric schema attribute -- total coverage, whether or
// not a default is declared. SchemaDefaultsTest compares every row against a
// freshly-constructed spec: declared values must match the C
// default-constructors, values beyond ndecl must be zero, and rows marked
// unset must hold the mjNAN sentinel. A nonzero constructor default with no
// schema declaration is therefore a test failure: the schema cannot silently
// under-declare. Rows are {attr, offset, kind, len, ndecl, unset, values};
// kind: 0=double 1=float 2=int 3=byte 4=mjtNum.
// clang-format off
struct mjXDefaultEntry {
const char* attr;
int offset;
int kind;
int len;
int ndecl;
int unset;
double value[8];
};
struct mjXDefaultTable {
const char* structname;
const mjXDefaultEntry* entries;
int n;
};
'''
def _values(schema, attr):
"""(ndecl, [C value expressions]) for an attribute's declared default."""
default = attr.default
if attr.type == 'enum':
constants = dict(schema.enums[attr.target].items)
return 1, [f'(double){constants[default]}']
if attr.type == 'bool':
return 1, ['1' if default == 'true' else '0']
values = default if isinstance(default, tuple) else (default,)
return len(values), [repr(v) for v in values]
# fields whose constructor default is the mjNAN "unset" sentinel, not a value;
# the schema deliberately declares no default and the test asserts the NaN
UNSET_SENTINELS = {
('mjsBody', 'ipos'), ('mjsBody', 'fullinertia'),
('mjsGeom', 'mass'), ('mjsGeom', 'fromto'),
('mjsSite', 'fromto'),
('mjStatistic', 'meaninertia'), ('mjStatistic', 'meanmass'),
('mjStatistic', 'meansize'), ('mjStatistic', 'extent'),
('mjStatistic', 'center'),
}
def collect(schema, structs):
"""struct key -> list of row tuples, deduplicated across elements.
Emits a row for every bound numeric attribute. An attribute with a declared
default contributes its values; an undeclared one contributes an all-zero
expectation (or the unset flag for UNSET_SENTINELS), so the test enforces
that every nonzero constructor default is declared in the schema. A declared
row replaces an undeclared row for the same field; two declared rows must
agree.
"""
tables = {}
seen = {}
for element in schema.elements.values():
if not element.spec:
continue
sub = element.facets.get('field')
key = f'{element.spec}.{sub}' if sub else element.spec
fields = structs.get(key)
if fields is None:
continue
prefix = f'{sub}.' if sub else ''
for attr in schema.expanded_attrs(element):
if attr.type in ('string', 'file', 'chars', 'ref', 'id', 'flags'):
continue
field = attr.facets.get('field', attr.name)
entry = fields.get(field)
if entry is None:
if 'reading' in attr.facets or attr.default is None:
continue # custom lowering with no direct binding
raise ValueError(f'{element.name}.{attr.name}: no field '
f'{element.spec}.{field}')
ctype, dim = entry
if ctype not in KIND_BY_CTYPE and not ctype.startswith('mjt'):
if attr.default is None:
continue # not a numeric field: nothing to compare
raise ValueError(f'{element.name}.{attr.name}: default bound to '
f'field {field} ({ctype})')
if ctype.endswith('*'):
continue # vector pointers have no in-place default
kind = KIND_BY_CTYPE.get(ctype, 2) # other mjt enums are int-sized
length = dim if dim is not None else '1'
unset = 1 if (key, field) in UNSET_SENTINELS else 0
if attr.default is None:
ndecl, values = 0, []
else:
if unset:
raise ValueError(f'{element.name}.{attr.name}: declared default '
'on an unset-sentinel field')
ndecl, values = _values(schema, attr)
if ndecl > 8:
raise ValueError(f'{element.name}.{attr.name}: {ndecl} default '
'values exceed the row capacity')
row = (attr.name, f'(int)offsetof({element.spec}, {prefix}{field})',
kind, str(length), ndecl, unset, values)
prior = seen.get((key, field))
if prior is not None:
prior_row, prior_declared = prior
declared = attr.default is not None
if declared and prior_declared and prior_row[4:] != row[4:]:
raise ValueError(f'{element.name}.{attr.name}: conflicting '
f'defaults for {key}.{field}')
if not declared or prior_declared:
continue # keep the existing (declared or equivalent) row
tables[key][tables[key].index(prior_row)] = row
seen[(key, field)] = (row, True)
continue
seen[(key, field)] = (row, attr.default is not None)
tables.setdefault(key, []).append(row)
return tables
def generate() -> str:
"""Generates the mjcf_default_table.inc content as a string."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
structs = generate_read_table.parse_spec_structs(
generate_read_table.SPEC_H_PATH, generate_read_table.MODEL_H_PATH)
tables = collect(schema, structs)
out = [_HEADER]
for key in sorted(tables):
array = 'kDefaults_' + key.replace('.', '_')
out.append(f'static const mjXDefaultEntry {array}[] = {{')
for attr, offset, kind, length, ndecl, unset, values in tables[key]:
vals = ', '.join(values) if values else '0'
out.append(f' {{"{attr}", {offset}, {kind}, {length}, {ndecl}, {unset}, '
f'{{{vals}}}}},')
out.append('};')
out.append('')
out.append('static const mjXDefaultTable kDefaultTables[] = {')
for key in sorted(tables):
array = 'kDefaults_' + key.replace('.', '_')
root = key.split('.')[0]
out.append(f' {{"{root}", {array}, '
f'(int)(sizeof({array}) / sizeof({array}[0]))}},')
out.append('};')
out.append('static const int kDefaultTablesN = '
'(int)(sizeof(kDefaultTables) / sizeof(kDefaultTables[0]));')
out.append('// clang-format on')
return '\n'.join(out) + '\n'
def main() -> int:
if len(sys.argv) > 2:
sys.exit('usage: generate_default_table.py [output.inc]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as file:
file.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+394
View File
@@ -0,0 +1,394 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates dm_control's schema.xml dialect from mjcf.schema.
dm_control's PyMJCF library builds its element classes from a hand-maintained
schema.xml; this emitter replaces that file with a generated one so the MJCF
facts live in one place. The element surface is deliberately frozen to what
dm_control supports today: new MJCF elements are listed in EXCLUDED_ELEMENTS
and not emitted, while attributes of supported elements are emitted in full
from the schema, so keyword sets, arities and defaults can no longer drift.
The dialect is dm_control's: a nested element tree (one node per context,
recursion expressed with recursive="true"), attribute types keyword / array /
int / float / string / identifier / reference / basepath / file, and element
flags repeated / on_demand / namespace. Facts PyMJCF needs that mjcf.schema
deliberately does not model -- attach-merge conflict policy, on-demand
construction, and dm_control's namespace grouping -- are carried as overlay
tables below, harvested once from the hand-maintained file.
The generated file is checked in as src/xml/generated/dmcontrol_schema.xml
and gated by test/doc/doc_test.py; dm_control vendors it at pin bumps.
"""
import sys
from xml.sax import saxutils
import os
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import mjcf_schema
import generate_xsd
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
# elements dm_control does not support; the surface is frozen, so new MJCF
# elements are added here rather than emitted (sensor_contact is excluded
# because PyMJCF cannot handle its multi-keyword data attribute)
EXCLUDED_ELEMENTS = {
'pid', 'dcmotor', 'replicate', 'frame', 'attach', 'model',
'sensor_contact',
}
# (parent element, child element) pairs excluded in that context only
EXCLUDED_CHILDREN = {('worldbody', 'plugin')}
# PyMJCF attach-merge policy: (element, attribute) -> conflict_behavior
# (None = conflict_allowed with no behavior). Harvested from dm_control.
CONFLICTS = {
('compiler', 'assetdir'): None,
('compiler', 'meshdir'): None,
('compiler', 'texturedir'): None,
('map', 'zfar'): 'max',
('map', 'znear'): 'min',
('mujoco', 'model'): None,
('option', 'ccd_iterations'): 'max',
('option', 'ccd_tolerance'): 'min',
('option', 'iterations'): 'max',
('option', 'ls_iterations'): 'max',
('option', 'ls_tolerance'): 'min',
('option', 'noslip_iterations'): 'max',
('option', 'noslip_tolerance'): 'min',
('option', 'sdf_initpoints'): 'max',
('option', 'sdf_iterations'): 'max',
('option', 'timestep'): 'min',
('option', 'tolerance'): 'min',
('size', 'memory'): 'max_bytes',
('size', 'nconmax'): 'max',
('size', 'njmax'): 'max',
}
# (parent, tag) pairs PyMJCF exposes as singletons even where MJCF admits
# repetition (repeated sections merge at load): the flag is API surface
# (root.option.timestep vs a list view), harvested from the hand file
SINGLETONS = {
('body', 'freejoint'), ('body', 'inertial'),
('compiler', 'lengthrange'),
('composite', 'geom'), ('composite', 'site'), ('composite', 'skin'),
('default', 'adhesion'), ('default', 'camera'), ('default', 'cylinder'),
('default', 'damper'), ('default', 'equality'), ('default', 'general'),
('default', 'geom'), ('default', 'intvelocity'), ('default', 'joint'),
('default', 'light'), ('default', 'material'), ('default', 'mesh'),
('default', 'motor'), ('default', 'muscle'), ('default', 'orientation'),
('default', 'pair'), ('default', 'position'), ('default', 'site'),
('default', 'tendon'), ('default', 'velocity'),
('mujoco', 'actuator'), ('mujoco', 'asset'), ('mujoco', 'compiler'),
('mujoco', 'contact'), ('mujoco', 'custom'), ('mujoco', 'default'),
('mujoco', 'deformable'), ('mujoco', 'equality'),
('mujoco', 'extension'), ('mujoco', 'keyframe'), ('mujoco', 'option'),
('mujoco', 'sensor'), ('mujoco', 'size'), ('mujoco', 'statistic'),
('mujoco', 'tendon'), ('mujoco', 'visual'), ('mujoco', 'worldbody'),
('option', 'flag'),
('visual', 'global'), ('visual', 'headlight'), ('visual', 'map'),
('visual', 'quality'), ('visual', 'rgba'), ('visual', 'scale'),
}
# elements PyMJCF constructs on demand rather than eagerly
ON_DEMAND = {'inertial', 'freejoint'}
# dm_control groups some identifier namespaces more coarsely than the
# schema's id<ns> targets; keyed by element name
NAMESPACE_OVERRIDES = {
'exclude': 'contact',
'flex': 'deformable',
'flexcomp': 'flexcomp',
'instance': 'plugin',
'pair': 'contact',
}
# per-context namespaces: the same schema element namescopes differently by
# parent (dm_control's asset skin lives in 'skin', deformable skin in
# 'deformable')
CONTEXT_NAMESPACE = {('deformable', 'skin'): 'deformable'}
# attributes that are PyMJCF identifiers although the schema types them as
# plain strings (composite prefixes namescope the generated elements)
IDENTIFIER_OVERRIDES = {('composite', 'prefix')}
# the same grouping applied to reference targets
REF_NS_MAP = {'instance': 'plugin', 'flex': 'deformable',
'skin': 'deformable', 'pair': 'contact', 'exclude': 'contact'}
# compiler directory attributes are PyMJCF basepaths
BASEPATHS = {'meshdir': 'mesh', 'texturedir': 'texture', 'assetdir': 'asset'}
# path namespace for file-typed attributes, by owning element. In MJCF, meshdir
# is the base directory for meshes, heightfields, and skins.
FILE_NS = {'mesh': 'mesh', 'texture': 'texture', 'hfield': 'mesh',
'skin': 'mesh'}
def _format_number(value):
"""Format a numeric default the shortest exact way: 2.0 -> '2'."""
if isinstance(value, float) and value == int(value) and abs(value) < 1e15:
return str(int(value))
return repr(value)
def _fmt_default(attr):
"""Format a declared default the way dm_control's file writes values."""
d = attr.default
if d is None:
return None
if isinstance(d, tuple):
return ' '.join(_format_number(v) for v in d)
if isinstance(d, (int, float)):
return _format_number(d)
return str(d)
class _Emitter:
"""Emits the dm_control schema tree by walking mjcf.schema from mujoco."""
def __init__(self, schema):
self.schema = schema
self.dims = generate_xsd.parse_dims()
self.lines = []
self.ref_namespaces = set() # (element, attr, ns) of emitted references
self.id_namespaces = set() # namespaces populated by emitted elements
def out(self, indent, text):
self.lines.append(' ' * indent + text)
def resolve(self, bound):
if isinstance(bound, str):
return self.dims[bound]
return bound
def element_namespace(self, element, parent):
"""Returns the dm_control namespace for an element.
Any identifier-typed attribute makes the element identified (their
parser accepts any; default's identifier is 'class', not 'name').
Args:
element: The mjcf.schema element to inspect.
parent: Optional name of the parent element context.
Returns:
The string namespace name, or None.
"""
if (parent, element.name) in CONTEXT_NAMESPACE:
return CONTEXT_NAMESPACE[(parent, element.name)]
if element.name in NAMESPACE_OVERRIDES:
return NAMESPACE_OVERRIDES[element.name]
for a in self.schema.expanded_attrs(element):
if a.type == 'id' or (element.name, a.name) in IDENTIFIER_OVERRIDES:
return a.target if a.type == 'id' else element.name
return None
def attr_parts(self, element, attr, attr_names):
"""Returns the type-describing XML attribute string for one attribute.
Args:
element: The owning element.
attr: The mjcf.schema attribute.
attr_names: Set of attribute names for the element.
Returns:
A formatted XML attribute string.
"""
lo, hi = attr.arity.lo, self.resolve(attr.arity.hi)
# sensor-style object references are typed by a sibling attribute; the
# schema leaves these as strings (the target kind is value-dependent),
# but PyMJCF's attachment namespacing needs the dynamic reference
if attr.name == 'objname' and 'objtype' in attr_names:
return 'type="reference" reference_namespace="attrib:objtype"'
if attr.name == 'refname' and 'reftype' in attr_names:
return 'type="reference" reference_namespace="attrib:reftype"'
if (element.name, attr.name) in IDENTIFIER_OVERRIDES:
return 'type="identifier"'
if element.name == 'mujoco' and attr.name == 'model':
return 'type="string"' # the model's own name, not a reference
if attr.name in BASEPATHS and element.name == 'compiler':
return f'type="basepath" path_namespace="{BASEPATHS[attr.name]}"'
if attr.type == 'file':
ns = FILE_NS.get(element.name)
ns_part = f' path_namespace="{ns}"' if ns else ''
return f'type="file"{ns_part}'
if attr.type == 'enum':
keywords = ' '.join(k for k, _ in self.schema.enums[attr.target].items)
return f'type="keyword" valid_values={saxutils.quoteattr(keywords)}'
if attr.type == 'bool':
return 'type="keyword" valid_values="false true"'
if attr.type == 'id':
return 'type="identifier"'
if attr.type == 'ref':
ns = REF_NS_MAP.get(attr.target, attr.target)
self.ref_namespaces.add((element.name, attr.name, ns))
return f'type="reference" reference_namespace="{ns}"'
if attr.type in ('string', 'chars', 'flags'):
# flags (multi-keyword) attributes are opaque strings to PyMJCF
return 'type="string"'
if attr.type in ('double', 'float', 'int'):
base = 'int' if attr.type == 'int' else 'float'
if (lo, hi) == (1, 1):
return f'type="{base}"'
size = f' array_size="{hi}"' if hi is not None else ''
return f'type="array" array_type="{base}"{size}'
raise ValueError(f'{element.name}.{attr.name}: unmapped type {attr.type}')
def emit_attr(self, indent, element, attr, attr_names):
"""Emits a single <attribute .../> XML element.
Args:
indent: Indentation level in spaces.
element: The owning element.
attr: The mjcf.schema attribute.
attr_names: Set of attribute names for the element.
"""
parts = [f'<attribute name="{attr.name}"',
self.attr_parts(element, attr, attr_names)]
if attr.facets.get('required'):
parts.append('required="true"')
default = _fmt_default(attr)
if default is not None:
parts.append(f'default={saxutils.quoteattr(default)}')
behavior = CONFLICTS.get((element.name, attr.name), 'ABSENT')
if behavior != 'ABSENT':
parts.append('conflict_allowed="true"')
if behavior is not None:
parts.append(f'conflict_behavior="{behavior}"')
self.out(indent, ' '.join(parts) + '/>')
def emit_element(self, element, tag, card, projected, indent, ancestry,
parent=None):
"""Emits one element node.
Self-recursion is expressed dm_control's way: the full definition
carries recursive="true" and lists no self-child -- their parser links
children[name] back to the element itself. Non-self cycles cannot occur
on the emitted surface (frame and replicate are excluded), which the
ancestry assertion enforces.
Args:
element: The mjcf.schema element to emit.
tag: XML element tag name.
card: Cardinality string ('!', '?', '*', 'R').
projected: Whether defaults are projected.
indent: Current indentation level in spaces.
ancestry: Set of parent element names in current stack.
parent: Optional name of parent element.
"""
assert (
element.name not in ancestry
or (element.name == 'default' and parent == 'default')
), f'unexpected cycle at {element.name}'
self_recursive = any(c.name == element.name for c in element.children())
# the top-level default is a singleton in PyMJCF (root.default.geom...)
# while nested defaults are repeated: one recursive spec cannot carry
# both flags, so the top node is emitted unflagged with an explicit
# nested recursive+repeated copy, exactly dm_control's historical shape
top_default = element.name == 'default' and parent == 'mujoco'
parts = [f'<element name="{tag}"']
if self_recursive and not top_default:
parts.append('recursive="true"')
if (card in ('*', 'R') and not top_default and
(parent, tag) not in SINGLETONS):
parts.append('repeated="true"')
if element.name in ON_DEMAND:
parts.append('on_demand="true"')
ns = self.element_namespace(element, parent)
if ns:
self.id_namespaces.add(ns)
if ns and ns != tag:
# the parser defaults an identified element's namespace to its name
parts.append(f'namespace="{ns}"')
head = ' '.join(parts) + '>'
self.out(indent, head)
attrs = self.schema.expanded_attrs(element)
if projected:
attrs = [a for a in attrs if a.name not in ('name', 'class')
and not a.facets.get('nodefault')]
attr_names = {a.name for a in attrs}
if attrs:
self.out(indent + 2, '<attributes>')
for attr in attrs:
self.emit_attr(indent + 4, element, attr, attr_names)
self.out(indent + 2, '</attributes>')
children = []
for child in element.children():
if child.name == element.name:
if top_default:
# the nested recursive+repeated copy of the default subtree
children.append((element, tag, child.card, projected))
continue # otherwise self-recursion is the recursive flag
target = self.schema.elements[child.name]
child_tag = target.xml_name()
if element.name == 'mujoco' and child.name == 'body':
target, child_tag = self.schema.elements['worldbody'], 'worldbody'
if (target.name in EXCLUDED_ELEMENTS or
(element.name, target.name) in EXCLUDED_CHILDREN):
continue
child_projected = (projected or
(element.name == 'default' and
not child.name.startswith('default_') and
child.name != 'default'))
if projected and child.name == 'plugin':
continue
children.append((target, child_tag, child.card, child_projected))
if children:
self.out(indent + 2, '<children>')
for target, child_tag, card_, child_projected in children:
self.emit_element(target, child_tag, card_, child_projected,
indent + 4, ancestry | {element.name},
parent=element.name)
self.out(indent + 2, '</children>')
self.out(indent, '</element>')
def generate(self):
"""Generate the full schema XML as a string."""
self.out(0, '<!-- Generated by generate_dmcontrol.py from mjcf.schema;')
self.out(0, ' do not edit by hand. The element surface is frozen to')
self.out(0, ' what dm_control supports (see EXCLUDED_ELEMENTS);')
self.out(0, ' attribute facts follow mjcf.schema. -->')
self.emit_element(self.schema.elements['mujoco'], 'mujoco', '!',
False, 0, frozenset())
dangling = {r for r in self.ref_namespaces
if r[2] not in self.id_namespaces}
if dangling:
raise ValueError('references into namespaces no emitted element '
f'populates: {sorted(dangling)}')
return '\n'.join(self.lines) + '\n'
def generate():
"""Generate the dmcontrol_schema.xml content as a string."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
return _Emitter(schema).generate()
def main():
"""CLI entry point: generate dmcontrol_schema.xml to stdout or a file."""
if len(sys.argv) > 2:
sys.exit('usage: generate_dmcontrol.py [output.xml]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as f:
f.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+170
View File
@@ -0,0 +1,170 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates functions API for APIreference.rst."""
import re
import sys
import os
import sys
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
sys.path.insert(0, _SCRIPT_DIR)
import generate_api_header
_FUNCTIONS_OVERRIDE = 'doc/APIreference/functions_override.rst'
_RST_SECTION_REGEX = re.compile(r'^\.\. (?P<section>_[A-Z].+):')
_RST_FUNCTION_REGEX = re.compile(r'^\.\. _(?P<function>mj.+):')
rst_to_section = {
'_Parseandcompile': ['Parse and compile', ''],
'_Mainsimulation': ['Main simulation', ''],
'_Support': ['Support', ''],
'_Components': ['Components', ''],
'_Subcomponents': ['Sub components', ''],
'_Raycollisions': ['Ray casting', ''],
'_Printing': ['Printing', ''],
'_Virtualfilesystem': ['Virtual file system', ''],
'_Assetcache': ['Asset cache', ''],
'_Resources': ['Resources', ''],
'_Initialization': ['Initialization', ''],
'_Errorandmemory': ['Error and memory', ''],
'_Miscellaneous': ['Miscellaneous', ''],
'_Interaction': ['Interaction', ''],
'_Visualization-api': ['Visualization', ''],
'_OpenGLrendering': ['OpenGL rendering', ''],
'_FilamentRenderingApi': ['Filament rendering', ''],
'_UIframework': ['UI framework', ''],
'_Derivatives-api': ['Derivatives', ''],
'_Signeddistancefunction': ['Signed Distance Functions', ''],
'_Plugins-api': ['Plugins', ''],
'_Thread': ['Threads', ''],
'_Standardmath': ['Standard math', ''],
'_Vectormath': ['Vector math', ''],
'_Sparsemath': ['Sparse math', ''],
'_Quaternions': ['Quaternions', ''],
'_Poses': ['Poses', ''],
'_Decompositions': ['Decompositions / Solvers', ''],
'_Attachment': ['Attachment', ''],
'_AddTreeElements': ['Tree elements', ''],
'_AddNonTreeElements': ['Non-tree elements', ''],
'_Setactuatorparameters': ['Set actuator parameters', ''],
'_AddAssets': ['Assets', ''],
'_FindAndGetUtilities': ['Find and get utilities', ''],
'_AttributeSetters': ['Attribute setters', ''],
'_AttributeGetters': ['Attribute getters', ''],
'_SpecUtilities': ['Spec utilities', ''],
'_ElementInitialization': ['Element initialization', ''],
'_ElementCasting': ['Element casting', ''],
}
def generate() -> str:
"""Generates functions.rst."""
rst_str = ''
api = generate_api_header.read_headers()
filepath = os.path.join(_REPO_ROOT, _FUNCTIONS_OVERRIDE)
with open(filepath, 'r', encoding='utf-8') as file:
current_section = None
current_function = None
for line in file:
# Try matching a section.
match = _RST_SECTION_REGEX.search(line)
if match is not None:
current_section = match.group('section')
if current_section in rst_to_section:
current_function = None
else:
current_section = None
continue
# Try matching a function
match = _RST_FUNCTION_REGEX.search(line)
if match is not None:
current_function = match.group('function')
if current_function in api:
api[current_function].doc = ''
current_section = None
else:
current_function = None
continue
# Update section doc.
if current_section is not None:
rst_to_section[current_section][1] += line
# Override doc.
if current_function is not None:
api[current_function].doc += line
# Check that all function sections from the headers are mapped.
mapped_sections = {v[0] for v in rst_to_section.values()}
for token, defn in api.items():
if defn.c_type == 'FUNCTION' and defn.section not in mapped_sections:
raise ValueError(
f'Function {token!r} is in unmapped section {defn.section!r}. '
f'Add an entry to rst_to_section in generate_functions.py.'
)
# Write out RST file.
rst_str += ("""
..
AUTOGENERATED: DO NOT EDIT MANUALLY
""".lstrip())
for section in rst_to_section:
section_title = rst_to_section[section][0]
rst_str += (
f"""
.. {section}:
{section_title}
{'^'*len(section_title)}
{rst_to_section[section][1]}""".lstrip())
for token in api:
if api[token].c_type != 'FUNCTION' or api[token].section != section_title:
continue
doc = api[token].doc.strip()
doc = doc.replace('&nbsp;', '``&nbsp;``')
rst_str += (f"""
.. _{token}:
`{token} <#{token}>`__
{'~'*(2*len(token)+8)}
.. mujoco-include:: {token}
{doc}
""".lstrip())
return rst_str
def main() -> None:
if len(sys.argv) > 1:
sys.exit('Too many command-line arguments.')
sys.stdout.buffer.write(generate().encode('utf-8'))
if __name__ == '__main__':
main()
+112
View File
@@ -0,0 +1,112 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Script to automatically extract and insert MuJoCo source file paths."""
import argparse
import os
import re
import sys
def main():
"""Extracts MuJoCo source file paths and updates linenumbers.js."""
parser = argparse.ArgumentParser(description='Update SRCS in linenumbers.js')
parser.add_argument(
'--src_dir', required=True, help='Path to mujoco src directory')
parser.add_argument(
'--js_file', required=True, help='Path to linenumbers.js file')
parser.add_argument(
'--ref_file', required=True, help='Path to references.h')
parser.add_argument(
'--check', action='store_true',
help='Check if SRCS matches, without updating')
args = parser.parse_args()
with open(args.ref_file, 'r', encoding='utf-8') as f:
ref_content = f.read()
# Extract all mj_... symbols that might be function names
valid_funcs = set(re.findall(r'\bmj[a-zA-Z0-9_]*\b', ref_content))
srcs = []
pattern = re.compile(r'^(const )?[a-zA-Z0-9_*]+\s+(.+)\(.+[{,]$')
for root, _, files in os.walk(args.src_dir):
for f in files:
if f.endswith('.c') or f.endswith('.cc'):
path = os.path.relpath(os.path.join(root, f), args.src_dir)
# Ensure we use forward slashes for Javascript array
path = path.replace('\\', '/')
# Check if it has any function defined in references.h
filepath = os.path.join(root, f)
found = False
with open(filepath, 'r', encoding='utf-8') as cf:
for line in cf:
line = line.strip('\n')
match = pattern.match(line)
key = None
if match:
key = match.group(2).strip()
# edge cases
if 'user_api.cc' in filepath and line.startswith(
'[[nodiscard]] int mj_recompile('):
key = 'mj_recompile'
elif 'engine_io.c' in filepath:
if line.startswith('void mj_freeStack('):
key = 'mj_freeStack'
elif line.startswith('void mj_markStack('):
key = 'mj_markStack'
if key and key in valid_funcs:
found = True
break
if found:
srcs.append(path)
srcs = sorted(srcs)
with open(args.js_file, 'r', encoding='utf-8') as f:
content = f.read()
# Find the const SRCS = [ ... ]; block
js_pattern = re.compile(r'const SRCS = \[\n(.*?)\n\];', re.DOTALL)
match = js_pattern.search(content)
if not match:
sys.exit('Could not find const SRCS = [ in linenumbers.js')
current_srcs_str = match.group(1)
# Generate the new string
new_srcs_str = '\n'.join([f" '{s}'," for s in srcs])
if current_srcs_str == new_srcs_str:
print('SRCS is up to date.')
sys.exit(0)
if args.check:
print('SRCS is not up to date. Please run update_docs to update it.')
sys.exit(1)
# Otherwise, update the file
new_content = content[:match.start(1)] + new_srcs_str + content[match.end(1):]
with open(args.js_file, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f'Updated SRCS in {args.js_file} with {len(srcs)} files.')
if __name__ == '__main__':
main()
+117
View File
@@ -0,0 +1,117 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates the keyword-map header from src/xml/mjcf.schema.
Emits src/xml/generated/mjcf_map.h: one mjMap array and size constant per schema
enum, as C++17 inline variables, so the reader, the writer and the
generated tables share one definition with no extern declarations to
maintain. It is checked in and gated by test/doc/doc_test.py, which
regenerates it from the schema and diffs.
"""
import os # pylint: disable=unused-import
import sys
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import mjcf_schema
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
_GUARD = 'MUJOCO_SRC_XML_GENERATED_MJCF_MAP_H_'
_INCLUDES = '''\
#include <mujoco/mjspec.h>
#include <mujoco/mjtype.h>
#include "user/user_composite.h"
#include "user/user_flexcomp.h"
#include "xml/xml_util.h"'''
_HEADER = f'''\
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_mjcf_map.py; test/doc/doc_test.py checks freshness.
//
// Keyword maps, one per schema enum, shared by the reader, the writer and
// the generated tables. Inline variables: including this header is all a
// translation unit needs.
#ifndef HEADER_GUARD_PLACEHOLDER
#define HEADER_GUARD_PLACEHOLDER
{_INCLUDES}
// clang-format off
// keywords of the built-in bool type (not a schema enum)
inline constexpr mjMap bool_map[] = {{
{{"false", 0}},
{{"true", 1}},
}};
'''
_FOOTER = '''\
// clang-format on
#endif // HEADER_GUARD_PLACEHOLDER
'''
def generate() -> str:
"""Generates the mjcf_map.h content as a string."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
out = []
for enum in schema.enums.values():
width = max(len(key) for key in enum.keywords()) + 3
out.append(f'// enum {enum.name}')
out.append(f'inline constexpr mjMap {enum.name}_map[] = {{')
for key, value in enum.items:
padded = f'"{key}",'.ljust(width + 1)
out.append(f' {{{padded} {value}}},')
out.append('};')
out.append(f'inline constexpr int {enum.name}_sz = {len(enum.items)};')
out.append('')
header = _HEADER.replace('HEADER_GUARD_PLACEHOLDER', _GUARD)
footer = _FOOTER.replace('HEADER_GUARD_PLACEHOLDER', _GUARD)
return header + '\n'.join(out) + footer
def main() -> int:
if len(sys.argv) > 2:
sys.exit('usage: generate_mjcf_map.py [output.h]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as file:
file.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+186
View File
@@ -0,0 +1,186 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates the MJCF[] grammar table from src/xml/mjcf.schema.
The table (src/xml/generated/mjcf_table.inc) is the element tree consumed by the
mjXSchema validator: rows of {name, cardinality, attributes...} with
{"<"}/{">"} nesting markers. It is checked in and gated by
test/doc/doc_test.py, which regenerates it from the schema and diffs.
"""
import sys
import os
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import mjcf_schema
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
_HEADER = '''\
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_mjcf_table.py; test/doc/doc_test.py checks freshness.
//
// The MJCF grammar table consumed by mjXSchema: rows of {name, cardinality,
// attributes...} with {"<"}/{">"} nesting markers. worldbody, frame and
// replicate have no rows: mjXSchema::NameMatch validates them against the
// body row (see the alias= facets in mjcf.schema).
// clang-format off
'''
_WIDTH = 100
def _wrap_row(parts: list[str], indent: int) -> list[str]:
"""One {...}, initializer, wrapped at _WIDTH with hanging indent."""
lines = []
line = ' ' * indent + '{' + parts[0]
for part in parts[1:]:
candidate = f'{line}, {part}'
if len(candidate) + 2 > _WIDTH: # room for "},"
lines.append(line + ',')
line = ' ' * (indent + 4) + part
else:
line = candidate
lines.append(line + '},')
return lines
KIND_CHAR = {'exclusive': 'e', 'together': 't', 'requires': 'r',
'oneof': 'o'}
def _element_constraints(schema, element):
"""Element's own constraints plus those of transitively used groups."""
cons = list(element.constraints())
visited = set()
stack = [m.group for m in element.members
if isinstance(m, mjcf_schema.Use)]
while stack:
name = stack.pop()
if name in visited:
continue
visited.add(name)
group = schema.groups[name]
for member in group.members:
if isinstance(member, mjcf_schema.Constraint):
cons.append(member)
elif isinstance(member, mjcf_schema.Use):
stack.append(member.group)
return cons
def generate() -> str:
"""Generates the C++ grammar table header file contents from mjcf.schema."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
out = []
constraints = []
count = 0
def emit_entry(lines: list[str]):
nonlocal count
out.extend(lines)
count += 1
def visit(element: mjcf_schema.Element, card: str, indent: int,
project: bool):
# a row in default context is the element's defaultable projection
attrs = [a for a in schema.expanded_attrs(element)]
if project:
attrs = [a for a in attrs
if a.name not in ('name', 'class')
and not a.facets.get('nodefault')]
parts = [f'"{element.xml_name()}"', f'"{card}"']
parts += [f'"{a.name}"' for a in attrs]
row_index = count
emit_entry(_wrap_row(parts, indent))
# presence constraints whose attributes all survive in this row
row_attrs = {a.name for a in attrs}
for con in _element_constraints(schema, element):
if all(all(n in row_attrs for n in b) for b in con.bundles):
spec = '|'.join(' '.join(b) for b in con.bundles)
constraints.append(f" {{{row_index}, '{KIND_CHAR[con.kind]}', "
f'"{spec}"}},')
# self-recursion is implied by card R; alias elements (worldbody, frame,
# replicate) have no rows -- mjXSchema::NameMatch admits their tags
# against the body row
children = [c for c in element.children()
if c.name != element.name
and 'alias' not in schema.elements[c.name].facets]
if project:
# plugin configuration is not settable per-class
children = [c for c in children if c.name != 'plugin']
if not children:
return
emit_entry([' ' * indent + '{"<"},'])
for child in children:
decl = schema.elements[child.name]
child_project = project or (
element.name == 'default' and not child.name.startswith('default_'))
visit(decl, child.card, indent + 4, child_project)
if indent == 0:
out.append('')
emit_entry([' ' * indent + '{">"},'])
visit(schema.elements['mujoco'], '!', 0, False)
body = '\n'.join(out)
con_body = '\n'.join(constraints)
return (_HEADER +
'std::vector<const char*> MJCF[] = {\n' + body + '\n};\n'
'// clang-format on\n\n'
'const int nMJCF = sizeof(MJCF) / sizeof(MJCF[0]);\n\n'
'// presence constraints, indexed into MJCF[]; enforced by\n'
'// mjXSchema::Check. spec: attribute bundles, space-joined,\n'
"// '|'-separated; kind: e=exclusive t=together r=requires o=oneof\n"
'// clang-format off\n'
'const mjXConstraintDef MJCF_constraints[] = {\n' + con_body +
'\n};\n'
'// clang-format on\n\n'
'const int nMJCF_constraints = '
'sizeof(MJCF_constraints) / sizeof(MJCF_constraints[0]);\n')
def main() -> int:
if len(sys.argv) > 2:
sys.exit('usage: generate_mjcf_table.py [output.inc]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as file:
file.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+431
View File
@@ -0,0 +1,431 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates keyword maps and typed attribute-read rows from mjcf.schema.
Emits src/xml/generated/mjcf_read_table.inc: per-element mjXAttr row arrays
consumed by mjXReader::ReadAttrTable, plus the kSensorDispatch tag table and
shared group arrays.
Which elements get rows is determined automatically: every schema element with
a bound spec struct and at least one table-drivable attribute is included,
unless it appears in NOT_TABLE_DRIVEN (elements whose OneX() readers have
custom logic). A coverage check in doc_test verifies that every emitted row
array is consumed by the reader or writer, and that NOT_TABLE_DRIVEN names
only elements that exist in the schema.
Field offsets are emitted as offsetof() expressions, so binding mistakes are
compile errors, and the field's C type (parsed from mjspec.h) selects the row
kind, so mjtNum vs double is decided by the struct, not by the schema.
"""
import os # pylint: disable=unused-import
import re
import sys
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import mjcf_schema
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
SPEC_H_PATH = os.path.join(_REPO_ROOT, 'include', 'mujoco', 'mjspec.h')
MODEL_H_PATH = os.path.join(_REPO_ROOT, 'include', 'mujoco', 'mjmodel.h')
# elements with a bound spec whose OneX() reader is NOT table-driven;
# their rows are not emitted. These are the genuinely irregular elements
# whose readers have custom logic that can't be factored into ReadAttrTable.
# If you add a new schema element with a bound spec, either migrate its
# reader to ReadAttrTable (it will be auto-included) or add it here.
NOT_TABLE_DRIVEN = {
# actuator shorthands: read shared rows + per-tag remappings
'motor', 'position', 'velocity', 'intvelocity', 'orientation',
'pid', 'damper', 'cylinder', 'muscle', 'adhesion', 'dcmotor',
'actuator_plugin',
# equality subtypes: read shared equality_base + per-type refs
'connect', 'weld', 'equality_joint', 'equality_tendon',
'equality_flex', 'flexvert', 'flexstrain',
# sensors with custom reading logic
'rangefinder', 'distance', 'user', 'normal', 'fromto',
'sensor_contact', 'sensor_plugin', 'tactile',
# other irregulars
'frame', 'plugin', 'numeric', 'text', 'tuple',
}
# sensors whose whole branch derives from the schema (identity constants +
# references); their arrays are also collected into kSensorDispatch
SENSOR_DISPATCH = [
'touch',
'accelerometer',
'velocimeter',
'gyro',
'force',
'torque',
'magnetometer',
'camprojection',
'jointpos',
'jointvel',
'tendonpos',
'tendonvel',
'actuatorpos',
'actuatorvel',
'actuatorfrc',
'jointactuatorfrc',
'tendonactuatorfrc',
'ballquat',
'ballangvel',
'jointlimitpos',
'jointlimitvel',
'jointlimitfrc',
'tendonlimitpos',
'tendonlimitvel',
'tendonlimitfrc',
'framepos',
'framequat',
'framexaxis',
'frameyaxis',
'framezaxis',
'framelinvel',
'frameangvel',
'framelinacc',
'frameangacc',
'insidesite',
'subtreecom',
'subtreelinvel',
'subtreeangmom',
'e_potential',
'e_kinetic',
'clock',
]
# shared groups emitted as standalone row arrays, for shared OneX() readers:
# group name -> (bound struct, emitted array name)
EMIT_GROUPS = {
'equality_base': ('mjsEquality', 'kEqualityBaseAttrs'),
'sensor_base': ('mjsSensor', 'kSensorBaseAttrs'),
}
# groups whose attributes are hand-read in the OneX() remnant;
# their rows are not emitted
HAND_GROUPS = ['orientation', 'transmission',
'sensor_base'] # read via kSensorBaseAttrs before dispatch
# mjspec.h array-dimension expressions equivalent to a numeric schema bound;
# the expression is emitted as the row length so it tracks the header
DIM_EQUIV = {'mjNPOLY+1': '3'}
# schema scalar/C-type -> mjXAttr kind
KIND_BY_CTYPE = {'mjString*': 'kString', 'int': 'kInt', 'double': 'kDouble',
'mjtNum': 'kNum', 'float': 'kFloat'}
_HEADER = '''\
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// GENERATED FILE, DO NOT EDIT. Generated from src/xml/mjcf.schema by
// doc/generate/generate_read_table.py; test/doc/doc_test.py checks freshness.
//
// Typed attribute rows for table-driven reading (mjXReader::ReadAttrTable),
// one array per migrated element. Rows are {attr, kind, len, exact,
// required, nodefault, handwrite, offset}; keyword maps are defined in
// mjcf_map.h.
// clang-format off
'''
def array_name(element_name):
"""Return the row-array name emitted for an element."""
return f'k{element_name.capitalize()}Attrs'
def _has_table_attrs(schema, element):
"""Check if the element has at least one non-custom table-drivable attr."""
return any('reading' not in attr.facets
for attr in schema.expanded_attrs(element))
def table_driven_elements(schema):
"""Return the list of element names whose readers are table-driven.
An element is table-driven if it has a bound spec struct, at least one
table-drivable attribute, and is not in NOT_TABLE_DRIVEN.
Args:
schema: Parsed schema object.
"""
result = []
for name, element in schema.elements.items():
if not element.spec:
continue
if not _has_table_attrs(schema, element):
continue
if name in NOT_TABLE_DRIVEN:
continue
result.append(name)
return result
def parse_spec_structs(*paths):
"""Parse struct layouts from C headers.
Args:
*paths: Paths to C header files to parse.
Returns:
A dict mapping struct name -> {field: (ctype, dim-or-None)}.
Nested anonymous sub-structs (the mjVisual sections) are exposed as
'Outer.subname' pseudo-structs.
"""
structs = {}
field_re = re.compile(
r'^\s*([\w<>*]+(?:\s*\*)?)\s+(\w+)(\[([^\]]+)\])?\s*;', re.M)
for path in paths:
with open(path, encoding='utf-8') as f:
text = f.read()
for m in re.finditer(r'typedef struct (mj\w+)_ \{(.*?)\n\} \1;', text,
re.S):
name, body = m.group(1), m.group(2)
for sm in re.finditer(r'struct \{(.*?)\} (\w+);', body, re.S):
sub_fields = {}
for fm in field_re.finditer(sm.group(1)):
ctype, fname, _, dim = fm.groups()
sub_fields[fname] = (ctype.replace(' ', ''), dim)
structs[f'{name}.{sm.group(2)}'] = sub_fields
body = re.sub(r'struct \{.*?\} \w+;', '', body, flags=re.S)
fields = {}
for fm in field_re.finditer(body):
ctype, fname, _, dim = fm.groups()
fields[fname] = (ctype.replace(' ', ''), dim)
structs[name] = fields
return structs
def _attr_row(spec, fields, attr, ctx, prefix=''):
"""Return a row tuple for one attribute, or None if it has no row."""
required = 'true' if attr.facets.get('required') else 'false'
nodefault = 'true' if attr.facets.get('nodefault') else 'false'
handwrite = 'true' if attr.facets.get('writing') else 'false'
if attr.type == 'id' and attr.name == 'name':
# names are never settable in default classes
return (f'"{attr.name}"', 'mjXAttr::kName', '1', 'true', required,
'true', 'false', '-1')
if attr.type == 'ref' and attr.target == 'default':
return None # class selection is handled by the section parsers
if attr.type == 'file':
return None # files need VFS/asset-dir context: hand-read in the remnant
field = attr.facets.get('field', attr.name)
entry = fields.get(field)
if entry is None:
raise ValueError(f'{ctx}.{attr.name}: no field {spec}.{field}')
ctype, dim = entry
if attr.type in ('string', 'file', 'ref', 'id'):
if ctype == 'mjStringVec*':
kind, length, exact = 'kStringVec', '1', 'true'
elif ctype != 'mjString*':
raise ValueError(f'{ctx}.{attr.name}: bound to non-string '
f'field {field} ({ctype})')
else:
kind, length, exact = 'kString', '1', 'true'
elif attr.type == 'enum':
if not ctype.startswith('mjt') and ctype != 'int':
raise ValueError(f'{ctx}.{attr.name}: enum bound to '
f'field {field} ({ctype})')
kind = 'kEnumByte' if ctype in ('mjtByte', 'mjtBool') else 'kEnum'
length, exact = '1', 'true'
elif attr.type == 'flags':
if ctype != 'int':
raise ValueError(f'{ctx}.{attr.name}: flags bound to '
f'field {field} ({ctype})')
kind, length, exact = 'kFlags', '1', 'true'
elif attr.type == 'bool':
if ctype in ('mjtBool', 'mjtByte'):
kind, length, exact = 'kBool', '1', 'true'
elif ctype == 'int' or ctype.startswith('mjt'):
# int-typed flag: read through the keyword map (values are 0/1)
row = [f'"{attr.name}"', 'mjXAttr::kEnum', '1', 'true', required,
nodefault, handwrite,
f'(int)offsetof({spec}, {prefix}{field})', 'bool_map', '2']
return tuple(row)
else:
raise ValueError(f'{ctx}.{attr.name}: bool bound to '
f'field {field} ({ctype})')
elif attr.type == 'chars':
if ctype != 'char' or dim is None:
raise ValueError(f'{ctx}.{attr.name}: chars bound to '
f'field {field} ({ctype})')
lo, hi = attr.arity.lo, attr.arity.hi
if str(dim) != str(hi):
raise ValueError(f'{ctx}.{attr.name}: chars arity {hi} vs '
f'field dim {dim}')
kind, length = 'kChars', str(hi)
exact = 'true' if lo == hi else 'false'
elif attr.type in ('double', 'float', 'int') and attr.arity.hi is None:
vec_kinds = {'mjDoubleVec*': 'kDoubleVec', 'mjFloatVec*': 'kFloatVec',
'mjIntVec*': 'kIntVec'}
kind = vec_kinds.get(ctype)
if kind is None:
raise ValueError(f'{ctx}.{attr.name}: unbounded vector '
f'bound to field {field} ({ctype})')
length, exact = '1', 'true'
elif attr.type in ('double', 'float', 'int'):
kind = KIND_BY_CTYPE.get(ctype)
if kind is None or (attr.type == 'int') != (kind == 'kInt'):
raise ValueError(f'{ctx}.{attr.name}: schema type '
f'{attr.type} vs field {field} ({ctype})')
lo, hi = attr.arity.lo, attr.arity.hi
length = str(hi)
declared = dim if dim is not None else '1'
if str(declared) != length:
if DIM_EQUIV.get(str(declared)) == length:
length = str(declared) # emit the expression: it tracks the header
else:
raise ValueError(f'{ctx}.{attr.name}: arity {length} vs '
f'field dim {declared}')
exact = 'true' if lo == hi or (lo == 1 and hi == 1) else 'false'
else:
raise ValueError(f'{ctx}.{attr.name}: kind {attr.type} is '
'not table-drivable yet')
offset = f'(int)offsetof({spec}, {prefix}{field})'
row = [f'"{attr.name}"', f'mjXAttr::{kind}', length, exact,
required, nodefault, handwrite, offset]
if kind in ('kEnum', 'kEnumByte', 'kFlags'):
row += [f'{attr.target}_map', f'{attr.target}_sz']
return tuple(row)
def rows_for(schema, structs, element_name):
"""Return (struct name, list of row tuples) for one table-driven element."""
element = schema.elements[element_name]
if not element.spec:
raise ValueError(f'{element_name}: no bound spec struct')
sub = element.facets.get('field')
key = f'{element.spec}.{sub}' if sub else element.spec
fields = structs.get(key)
if fields is None:
raise ValueError(f'{element_name}: struct {key} not found in headers')
prefix = f'{sub}.' if sub else ''
hand_attrs = set()
for gname in HAND_GROUPS:
if any(isinstance(m, mjcf_schema.Use) and m.group == gname
for m in element.members):
hand_attrs |= {m.name for m in schema.groups[gname].members}
rows = []
for const in element.consts():
entry = fields.get(const.field)
if entry is None:
raise ValueError(f'{element_name}: set {const.field}: no field '
f'{element.spec}.{const.field}')
ctype = entry[0]
if not ctype.startswith('mjt') and ctype != 'int':
raise ValueError(f'{element_name}: set {const.field}: field is {ctype}')
rows.append(('nullptr', 'mjXAttr::kConst', '1', 'true', 'false', 'false',
'false',
f'(int)offsetof({element.spec}, {prefix}{const.field})',
'nullptr', '0', const.value))
for attr in schema.expanded_attrs(element):
if attr.name in hand_attrs or 'reading' in attr.facets:
continue # hand-read in the OneX() remnant
row = _attr_row(element.spec, fields, attr, element_name,
prefix=prefix)
if row is not None:
rows.append(row)
return element.spec, rows
def rows_for_group(schema, structs, group_name, spec):
"""Return list of row tuples for a shared group, bound to the given struct."""
fields = structs.get(spec)
if fields is None:
raise ValueError(f'{group_name}: struct {spec} not in mjspec.h')
rows = []
for attr in schema.groups[group_name].members:
if not isinstance(attr, mjcf_schema.Attr) or 'reading' in attr.facets:
continue
row = _attr_row(spec, fields, attr, group_name)
if row is not None:
rows.append(row)
return rows
def generate():
"""Generate the mjcf_read_table.inc content as a string."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
structs = parse_spec_structs(SPEC_H_PATH, MODEL_H_PATH)
migrated = table_driven_elements(schema)
out = [_HEADER]
for name in migrated:
struct, rows = rows_for(schema, structs, name)
array = array_name(name)
out.append(f'// {name} ({struct})')
out.append(f'inline constexpr mjXAttr {array}[] = {{')
for row in rows:
out.append(' {' + ', '.join(row) + '},')
out.append('};')
out.append(f'inline constexpr int {array}N = '
f'sizeof({array}) / sizeof({array}[0]);')
out.append('')
out.append('// sensors fully described by the schema: dispatch by tag')
out.append('struct mjXSensorEntry { const char* tag; const mjXAttr* rows;'
' int n; };')
out.append('inline constexpr mjXSensorEntry kSensorDispatch[] = {')
for name in SENSOR_DISPATCH:
array = array_name(name)
tag = schema.elements[name].xml_name()
out.append(f' {{"{tag}", {array}, {array}N}},')
out.append('};')
out.append('inline constexpr int kSensorDispatchN = '
'sizeof(kSensorDispatch) / sizeof(kSensorDispatch[0]);')
out.append('')
for gname, (struct, array) in EMIT_GROUPS.items():
rows = rows_for_group(schema, structs, gname, struct)
out.append(f'// group {gname} ({struct})')
out.append(f'inline constexpr mjXAttr {array}[] = {{')
for row in rows:
out.append(' {' + ', '.join(row) + '},')
out.append('};')
out.append(f'inline constexpr int {array}N = '
f'sizeof({array}) / sizeof({array}[0]);')
out.append('')
out.append('// clang-format on')
return '\n'.join(out) + '\n'
def main():
"""CLI entry point: generate mjcf_read_table.inc to stdout or a file."""
if len(sys.argv) > 2:
sys.exit('usage: generate_read_table.py [output.inc]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as file:
file.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+239
View File
@@ -0,0 +1,239 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates MJCF schema using dropdown directives for XMLreference.rst.
Generates XMLschema.rst by reading xml_native_reader.cc and producing
nested dropdown directives with list-table for attributes.
"""
import copy
import sys
import os
# Map symbols to icons:
# ! = required element, can appear only once -> star (prominent, required)
# ? = optional element, can appear only once -> dot (minimal, single)
# * = optional element, can appear many times -> None (no icon, most common)
# R = optional element, can appear many times recursively -> sync (recursive)
SYMBOL_TO_ICON = {
'!': 'star',
'?': 'dot',
'*': None,
'R': 'sync',
}
ELEMENT_ORDER = [
'mujoco',
'option',
'compiler',
'size',
'statistic',
'asset',
'body',
'deformable',
'contact',
'equality',
'tendon',
'actuator',
'sensor',
'keyframe',
'visual',
'default',
'custom',
'extension',
]
# Special display names for elements (when different from the element name)
ELEMENT_DISPLAY_NAME = {
'body': '(world)body',
}
def generate_dropdown(
element_name: str,
symbol: str,
link_name: str,
attributes: list[str],
links: list[str],
level: int,
is_top_level: bool = False,
) -> str:
"""Generate a dropdown directive for an element with its attributes."""
indent = ' ' * level
output = ''
display_name = ELEMENT_DISPLAY_NAME.get(element_name, element_name)
icon = SYMBOL_TO_ICON.get(symbol)
# Element name is a :ref: link. Icon/macro goes on the right side.
# Use |*| for * elements (even though it's empty) for future flexibility.
element_link = f':ref:`{display_name}<{link_name}>`'
if icon:
title = f'{element_link} :octicon:`{icon}`'
else:
title = f'{element_link} |*|'
output += f'{indent}.. dropdown:: {title}\n'
if is_top_level:
output += f'{indent} :open:\n'
output += '\n'
content_indent = indent + ' '
# Responsive grid for attributes (2-3-4-4: mobile-tablet-desktop-large)
if attributes:
output += f'{content_indent}.. grid:: 2 3 4 4\n'
output += f'{content_indent} :gutter: 0\n'
output += '\n'
for attr in attributes:
att_link_name = f'{link_name}-{attr}'
if att_link_name not in links:
raise ValueError(
f'Link for attribute {att_link_name} not found, update'
' XMLreference.rst'
)
output += f'{content_indent} .. grid-item::\n'
output += f'{content_indent} :ref:`{attr}<{att_link_name}>`\n'
output += '\n'
output += '\n'
return output
def generate() -> str:
"""Generates XMLschema.rst by parsing mjcf_table.inc.
The schema is defined in mjcf_table.inc (generated from mjcf.schema) as a
nested structure called MJCF[]. This function parses that structure and
generates nested dropdown directives with list-tables for attributes.
Returns:
RST content with nested dropdown directives for the MJCF schema.
"""
script_dir = os.path.dirname(os.path.abspath(__file__))
repo_root = os.path.dirname(os.path.dirname(script_dir))
filepath = os.path.join(repo_root, 'src', 'xml', 'generated', 'mjcf_table.inc')
xmlfile = os.path.join(repo_root, 'doc', 'XMLreference.rst')
# Collect all link targets from XMLreference.rst for validation.
links = []
with open(xmlfile, 'r', encoding='utf-8') as file:
for line in file:
if line.startswith('.. _'):
links.append(line.strip()[4:-1])
output = """..
DO NOT EDIT. THIS FILE IS AUTOMATICALLY GENERATED.
.. raw:: html
<div class="schema-controls" style="margin-bottom: 1em;">
<button onclick="document.querySelectorAll('.schema-small details').forEach(d => d.open = true)" class="sd-btn sd-btn-outline-primary sd-btn-sm">Expand All</button>
<button onclick="document.querySelectorAll('.schema-small details details').forEach(d => d.open = false)" class="sd-btn sd-btn-outline-secondary sd-btn-sm" style="margin-left: 0.5em;">Collapse All</button>
</div>
"""
with open(filepath, 'r', encoding='utf-8') as file:
to_strip = {' ', '{', '}', '"'}
# Process each top-level element in a specific order for consistent output.
for top_element in ELEMENT_ORDER:
level = 0
element: list[str] = []
parent = ['', '', '', '', ''] # Track parent elements for link names.
found_element = False
file.seek(0)
# Skip to the MJCF schema definition in the C++ source.
for line in file:
if 'std::vector<const char*> MJCF[] = {' in line.strip():
break
# Parse the schema structure.
for line in file:
if line.strip().endswith('};'):
break # End of schema definition.
# Track nesting level using angle brackets in the C++ source.
if '<' in line:
level += 1
continue
if '>' in line:
level -= 1
continue
# Parse element definition from the line.
line_is_done = 1 if '}' in line else 0
line_copy = copy.copy(line)
for item in to_strip:
line_copy = line_copy.replace(item, '')
element += [item for item in line_copy.split(',') if item != '\n']
# Determine if this element belongs to the current top-level element.
outer_level = level == 0 and top_element == 'mujoco'
top_level = level == 1 and element and top_element == element[0]
sub_level = level > 1 and top_element == parent[2]
level_is_correct = outer_level or top_level or sub_level
if found_element and not level_is_correct:
break # Done with this top-level element.
found_element = level_is_correct
# Generate dropdown for completed element definition.
if line_is_done and level_is_correct:
# Link name: top-level uses element name, nested uses parent-child.
link_name = element[0]
if level > 1:
link_name = parent[level] + '-' + element[0]
if link_name not in links:
raise ValueError(
f'Link for element {link_name} not found, update'
' XMLreference.rst'
)
attributes = element[2:] # First two items are name and symbol.
# Adjust indentation level for RST output.
dropdown_level = 0 if level == 0 else (1 if level == 1 else level)
is_top_level = level == 0
output += generate_dropdown(
element[0],
element[1],
link_name,
attributes,
links,
dropdown_level,
is_top_level,
)
# Track parent elements for building nested link names.
if line_is_done:
if level < 4:
parent[level + 1] = element[0]
element = []
# single newline at end of file
return output.rstrip('\n') + '\n'
def main() -> int:
if len(sys.argv) > 1:
sys.exit('Too many command-line arguments.')
sys.stdout.buffer.write(generate().encode('utf-8'))
return 0
if __name__ == '__main__':
main()
+375
View File
@@ -0,0 +1,375 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Generates the published XML Schema (mjcf.xsd) from mjcf.schema.
The XSD is deliberately permissive: it must never reject a legal model.
XSD 1.0 cannot express MJCF's order-insensitive children with per-child
cardinality (xs:all forbids maxOccurs > 1), so every content model is an
unbounded xs:choice, and presence constraints (exclusive/together/requires/
oneof) are not expressible at all. Both are carried as xs:documentation
annotations.
Element tags repeat across contexts with different content (e.g. joint under
body, default and equality), so every element is declared locally inside its
parent's complexType; the named complexTypes carry the schema element names.
Inside <default>, children use projected types (attributes minus name/class
minus nodefault), mirroring the grammar-table projection.
The generated file is checked in as src/xml/generated/mjcf.xsd and gated by
test/doc/doc_test.py, which regenerates it from the schema and diffs.
"""
import os
import re
import sys
from xml.sax.saxutils import escape
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _SCRIPT_DIR)
import mjcf_schema
_REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema')
MJMODEL_H_PATH = os.path.join(_REPO_ROOT, 'include', 'mujoco', 'mjmodel.h')
# schema scalar type -> XSD base type
SCALAR_XSD = {'int': 'xs:int', 'double': 'xs:double', 'float': 'xs:float',
'string': 'xs:string', 'file': 'xs:string'}
_CONSTRAINT_TEXT = {
'exclusive': 'at most one of',
'together': 'together or absent',
'requires': 'first requires second',
'oneof': 'at least one of',
}
def parse_dims():
"""Return {name: value} for the mjN* dimension macros in mjmodel.h."""
with open(MJMODEL_H_PATH, encoding='utf-8') as f:
text = f.read()
return {m.group(1): int(m.group(2))
for m in re.finditer(r'^#define\s+(mjN\w+)\s+(\d+)', text, re.M)}
def _num(value):
"""Format a numeric default the shortest exact way: 2.0 -> '2'."""
if isinstance(value, float) and value == int(value) and abs(value) < 1e15:
return str(int(value))
return repr(value)
def _default_str(attr):
"""Return the attribute default as an XSD default string, or None."""
d = attr.default
if d is None:
return None
if isinstance(d, tuple):
return ' '.join(_num(v) for v in d)
if isinstance(d, (int, float)):
return _num(d)
return str(d)
class _Emitter:
"""Accumulates the XSD document with shared simple types deduped."""
def __init__(self, schema):
self.schema = schema
self.dims = parse_dims()
self.lines = []
self.vector_types = {} # type name -> definition lines
self.emitted = set() # (element name, projected) complexTypes emitted
self.pending = []
def out(self, indent, text):
"""Appends a line of text at the specified indentation level."""
self.lines.append(' ' * indent + text)
def doc(self, indent, texts):
"""Emit an annotation block for the given documentation lines."""
texts = [t for t in texts if t]
if not texts:
return
self.out(indent, '<xs:annotation>')
for t in texts:
self.out(indent + 2, f'<xs:documentation>{escape(t)}</xs:documentation>')
self.out(indent, '</xs:annotation>')
def resolve(self, bound):
"""Resolve an arity bound: int, mjN* macro name, or None."""
if isinstance(bound, str):
return self.dims[bound]
return bound
def vector_type(self, base, lo, hi):
"""Return (and register) the named list type for a vector attribute."""
if hi is None:
name = f'{base}list'
elif lo == hi:
name = f'{base}{hi}'
else:
name = f'{base}{lo}to{hi}'
if name not in self.vector_types:
lines = [f'<xs:simpleType name="{name}">']
if hi is None and lo <= 1:
lines += [f' <xs:list itemType="{SCALAR_XSD[base]}"/>']
else:
lines += [' <xs:restriction>',
' <xs:simpleType>',
f' <xs:list itemType="{SCALAR_XSD[base]}"/>',
' </xs:simpleType>']
if lo == hi:
lines += [f' <xs:length value="{hi}"/>']
else:
if lo > 0:
lines += [f' <xs:minLength value="{lo}"/>']
if hi is not None:
lines += [f' <xs:maxLength value="{hi}"/>']
lines += [' </xs:restriction>']
lines += ['</xs:simpleType>']
self.vector_types[name] = lines
return name
def attr_type(self, attr, ctx):
"""Return (type name or None, inline restriction lines) for an attribute.
A None type name with inline lines means the attribute carries an
anonymous simpleType restriction.
"""
numeric_facets = [f for f in ('min', 'max', 'positive')
if f in attr.facets or attr.facets.get(f)]
if attr.type == 'bool':
return 'kw_bool', []
if attr.type == 'enum':
return f'kw_{attr.target}', []
if attr.type == 'flags':
return f'kwlist_{attr.target}', []
if attr.type in ('string', 'file', 'ref', 'id'):
return 'xs:string', []
if attr.type == 'chars':
lo, hi = attr.arity.lo, attr.arity.hi
lines = ['<xs:simpleType>', ' <xs:restriction base="xs:string">']
if 'pattern' in attr.facets:
lines += [f' <xs:pattern value="{escape(attr.facets["pattern"])}"/>']
elif lo == hi:
lines += [f' <xs:length value="{hi}"/>']
else:
lines += [f' <xs:minLength value="{lo}"/>',
f' <xs:maxLength value="{hi}"/>']
lines += [' </xs:restriction>', '</xs:simpleType>']
return None, lines
# numeric scalars and vectors
base = SCALAR_XSD[attr.type]
lo, hi = attr.arity.lo, self.resolve(attr.arity.hi)
if (lo, hi) == (1, 1):
if not numeric_facets:
return base, []
lines = ['<xs:simpleType>', f' <xs:restriction base="{base}">']
if 'min' in attr.facets:
lines += [f' <xs:minInclusive value="{_num(attr.facets["min"])}"/>']
if 'max' in attr.facets:
lines += [f' <xs:maxInclusive value="{_num(attr.facets["max"])}"/>']
if attr.facets.get('positive'):
lines += [' <xs:minExclusive value="0"/>']
lines += [' </xs:restriction>', '</xs:simpleType>']
return None, lines
if numeric_facets:
raise ValueError(f'{ctx}.{attr.name}: numeric facets on a vector '
'attribute are not supported by the XSD emitter')
return self.vector_type(attr.type, lo, hi), []
def emit_attr(self, indent, attr, ctx):
"""Emit one xs:attribute."""
tname, inline = self.attr_type(attr, ctx)
parts = [f'name="{attr.name}"']
if tname:
parts.append(f'type="{tname}"')
if attr.facets.get('required'):
parts.append('use="required"')
default = _default_str(attr)
if default is not None:
parts.append(f'default="{escape(default)}"')
head = f'<xs:attribute {" ".join(parts)}'
if not inline and not attr.doc:
self.out(indent, head + '/>')
return
self.out(indent, head + '>')
self.doc(indent + 2, [attr.doc])
for line in inline:
self.out(indent + 2, line)
self.out(indent, '</xs:attribute>')
def type_name(self, element_name, projected):
return f'default_{element_name}' if projected else element_name
def constraint_docs(self, element):
"""Presence constraints as documentation lines (not XSD-expressible)."""
import generate_mjcf_table
docs = []
for con in generate_mjcf_table._element_constraints(self.schema, element):
bundles = ['+'.join(b) for b in con.bundles]
docs.append(f'constraint: {_CONSTRAINT_TEXT[con.kind]}: '
f'{", ".join(bundles)}')
return docs
def emit_complex_type(self, name, projected):
"""Emit the complexType for one schema element (possibly projected)."""
element = self.schema.elements[name]
tname = self.type_name(name, projected)
self.out(2, f'<xs:complexType name="{tname}">')
docs = [element.doc] if not projected else []
docs += self.constraint_docs(element)
cards = [f'{c.name} ({c.card})' for c in element.children()]
if cards:
docs.append('children, with cardinality the XSD cannot enforce '
'(? at most one, ! exactly one, * any number, R recursive): '
+ ', '.join(cards))
self.doc(4, docs)
children = list(element.children())
if projected:
children = [c for c in children if c.name != 'plugin']
if children:
self.out(4, '<xs:choice minOccurs="0" maxOccurs="unbounded">')
for child in children:
target = self.schema.elements[child.name]
tag = target.xml_name()
if name == 'mujoco' and child.name == 'body':
# the top-level body is spelled worldbody (mjXSchema::NameMatch)
target = self.schema.elements['worldbody']
tag = 'worldbody'
child_projected = (projected or
(name == 'default' and
not child.name.startswith('default_') and
child.name != 'default'))
ctype = self.type_name(target.name, child_projected)
self.out(6, f'<xs:element name="{tag}" type="{ctype}"/>')
self.queue(target.name, child_projected)
# the include directive is spliced before parsing and may appear
# anywhere; admit it in every content model
self.out(6, '<xs:element name="include" type="include"/>')
self.out(4, '</xs:choice>')
attrs = self.schema.expanded_attrs(element)
if projected:
attrs = [a for a in attrs
if a.name not in ('name', 'class')
and not a.facets.get('nodefault')]
for attr in attrs:
self.emit_attr(4, attr, tname)
self.out(2, '</xs:complexType>')
self.out(0, '')
def queue(self, name, projected):
"""Enqueues an element name and projection flag for processing."""
self.pending.append((name, projected))
def generate(self):
"""Return the complete XSD document as a string."""
schema = self.schema
self.out(0, '<?xml version="1.0" encoding="UTF-8"?>')
self.out(0, '<!-- Generated by generate_xsd.py from mjcf.schema.')
self.out(0, ' Do not edit by hand; see test/doc/doc_test.py.')
self.out(0, '')
self.out(0, ' This schema is deliberately permissive: it never')
self.out(0, ' rejects a legal model, but accepts some models the')
self.out(0, ' parser rejects. Child cardinality and attribute')
self.out(0, ' presence constraints are carried as documentation')
self.out(0, ' annotations. -->')
self.out(0, '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">')
self.out(0, '')
# keyword simple types: bool, then one per schema enum
self.out(2, '<xs:simpleType name="kw_bool">')
self.out(4, '<xs:restriction base="xs:string">')
for kw in ('false', 'true'):
self.out(6, f'<xs:enumeration value="{kw}"/>')
self.out(4, '</xs:restriction>')
self.out(2, '</xs:simpleType>')
self.out(0, '')
flags_targets = set()
for element in schema.elements.values():
for attr in schema.expanded_attrs(element):
if attr.type == 'flags':
flags_targets.add(attr.target)
for enum in schema.enums.values():
self.out(2, f'<xs:simpleType name="kw_{enum.name}">')
self.doc(4, [enum.doc])
self.out(4, '<xs:restriction base="xs:string">')
for kw, _ in enum.items:
self.out(6, f'<xs:enumeration value="{escape(kw)}"/>')
self.out(4, '</xs:restriction>')
self.out(2, '</xs:simpleType>')
if enum.name in flags_targets:
self.out(2, f'<xs:simpleType name="kwlist_{enum.name}">')
self.out(4, f'<xs:list itemType="kw_{enum.name}"/>')
self.out(2, '</xs:simpleType>')
self.out(0, '')
# complexTypes, walked from the root so projections are discovered;
# vector simple types are collected on the way and emitted after
body_mark = len(self.lines)
self.pending = [('mujoco', False)]
while self.pending:
name, projected = self.pending.pop(0)
if (name, projected) in self.emitted:
continue
self.emitted.add((name, projected))
self.emit_complex_type(name, projected)
unreached = set(schema.elements) - {n for n, _ in self.emitted}
if unreached:
raise ValueError(f'elements unreachable from mujoco: {unreached}')
# the include directive: spliced before parsing, not part of mjcf.schema
self.out(2, '<xs:complexType name="include">')
self.doc(4, ['includes another MJCF file; resolved before parsing'])
self.out(4, '<xs:attribute name="file" type="xs:string" use="required"/>')
self.out(2, '</xs:complexType>')
self.out(0, '')
vec_lines = []
for tname in sorted(self.vector_types):
for line in self.vector_types[tname]:
vec_lines.append(' ' + line)
vec_lines.append('')
self.lines[body_mark:body_mark] = vec_lines
self.out(2, '<xs:element name="mujoco" type="mujoco"/>')
self.out(0, '</xs:schema>')
return '\n'.join(self.lines) + '\n'
def generate():
"""Generate the mjcf.xsd content as a string."""
schema = mjcf_schema.parse_file(SCHEMA_PATH)
return _Emitter(schema).generate()
def main():
"""CLI entry point: generate mjcf.xsd to stdout or a file."""
if len(sys.argv) > 2:
sys.exit('usage: generate_xsd.py [output.xsd]')
text = generate()
if len(sys.argv) == 2:
with open(sys.argv[1], 'w', encoding='utf-8') as f:
f.write(text)
else:
sys.stdout.write(text)
return 0
if __name__ == '__main__':
sys.exit(main())
+765
View File
@@ -0,0 +1,765 @@
# Copyright 2026 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Parser for the MJCF schema definition language.
The MJCF grammar is defined in a single hand-edited file (src/xml/mjcf.schema)
written in a small declarative language. This module parses and validates that
language and exposes the result as plain dataclasses, consumed by the
generators in this directory.
Grammar (see designs doc for rationale):
schema := { decl }
decl := enum | group | element
enum := "enum" IDENT [":" IDENT] "{" { key "=" value } "}"
key := IDENT | STRING # XML keyword ("2d" needs quoting)
value := IDENT | NUMBER # C constant name or literal value
group := "group" IDENT ["variant"] "{" { attr | use | constraint } "}"
element := "element" IDENT [":" IDENT] ["(" facet {"," facet} ")"]
"{" { attr | use | child | const | constraint } "}"
const := "set" IDENT "=" IDENT
(field takes the C constant when the element is read; states
what the element's identity implies, e.g. a sensor's type)
attr := IDENT ":" type ["=" default] ["(" facet {"," facet} ")"]
type := scalar ["[" [arity] "]"] | "enum" "<" IDENT ">"
| "flags" "<" IDENT ">" | "id" "<" IDENT ">" | "ref" "<" IDENT ">"
constraint:= verb bundle bundle { bundle }
verb := "exclusive" | "together" | "requires" | "oneof"
bundle := IDENT { "+" IDENT }
(presence constraints over attributes: exclusive = at most one
bundle present, together = all-or-none, requires a b = a needs
b, oneof = at least one bundle complete; a bundle is complete
when all its attributes appear)
scalar := "double" | "float" | "int" | "bool" | "string" | "file"
| "chars"
arity := NUMBER | NUMBER ".." NUMBER | NUMBER ".." IDENT
default := NUMBER | STRING | IDENT | "{" NUMBER {"," NUMBER} "}"
facet := IDENT ["=" (IDENT | STRING | NUMBER)]
child := "child" IDENT card
card := "?" | "!" | "*" | "R"
use := "use" IDENT
Names and references (the dm_control model, namespaces explicit): an
attribute of type id<ns> declares a name in namespace `ns` (e.g. geom name);
an attribute of type ref<ns> holds the name of an object in that namespace
(e.g. an actuator's site). Namespaces exist by virtue of id declarations;
a ref into a namespace nothing declares into is an error.
"""
import dataclasses
import re
import sys
from typing import Any, Optional, Union
# Facets accepted on attributes. Unknown facets are an error: forward
# compatibility is explicit, not silent.
KNOWN_FACETS = frozenset({'field', 'required', 'nodefault', 'pattern',
'reading', 'writing', 'min', 'max', 'positive'})
# Facets accepted on elements. Element names must be unique, but the same XML
# tag means different elements in different contexts (joint under body,
# equality, composite, tendon/fixed); 'xml' gives the tag when it differs from
# the declaration name. 'alias' records the mjXSchema::NameMatch behavior of
# tags validated against another element's row (worldbody, frame, replicate
# all match body): the MJCF[] emitter skips aliased elements, the XSD emitter
# declares them fully. 'field' names the sub-struct of the bound spec that
# this element's attributes live in (the mjVisual sub-sections).
ELEMENT_FACETS = frozenset({'xml', 'alias', 'field'})
# 'file' is a string resolved against asset directories and the VFS
# (the reader's ReadAttrFile); kept distinct for XSD/tooling and bindings.
# 'bool' is a primitive whose XML keywords are exactly "true" and "false".
# 'chars' is text bound to a fixed char array; its arity counts characters,
# not space-separated tokens, and must be bounded.
SCALAR_TYPES = frozenset({'double', 'float', 'int', 'bool', 'string',
'file', 'chars'})
CARDINALITIES = frozenset({'?', '!', '*', 'R'})
class SchemaError(Exception):
"""Parse or validation error, formatted as path:line: message."""
def __init__(self, path: str, line: int, message: str):
super().__init__(f'{path}:{line}: {message}')
self.path = path
self.line = line
self.message = message
@dataclasses.dataclass
class Arity:
"""Token count of a vector attribute: exact, ranged, or unbounded.
`hi` is an int, a symbolic C constant name (e.g. 'mjNREF'), or None for
unbounded. Scalar attributes have arity (1, 1).
"""
lo: int
hi: Union[int, str, None]
def is_scalar(self) -> bool:
return self.lo == 1 and self.hi == 1
@dataclasses.dataclass
class Attr:
"""An attribute declaration in the MJCF schema."""
name: str
type: str # scalar name, 'enum' or 'ref'
target: Optional[str] # enum or ref target name
arity: Arity
default: Union[None, float, str, tuple[float, ...]]
facets: dict[str, Union[bool, str, float]]
doc: Optional[str]
line: int
@dataclasses.dataclass
class Use:
"""A `use` directive referencing a group in the MJCF schema."""
group: str
line: int
@dataclasses.dataclass
class Child:
"""A child element declaration in the MJCF schema."""
name: str
card: str
doc: Optional[str]
line: int
@dataclasses.dataclass
class Const:
"""A constant assignment (`set field = CONST`) in an element declaration."""
field: str # bound C field
value: str # C constant it takes
doc: Optional[str]
line: int
@dataclasses.dataclass
class Constraint:
"""A presence constraint over attributes in the MJCF schema."""
kind: str # exclusive | together | requires | oneof
bundles: list[tuple[str, ...]] # attribute bundles ('+'-joined in source)
doc: Optional[str]
line: int
@dataclasses.dataclass
class Group:
"""An attribute group declaration in the MJCF schema."""
name: str
variant: bool
members: list[Union[Attr, Use, Constraint]]
doc: Optional[str]
line: int
@dataclasses.dataclass
class Element:
"""An XML element declaration in the MJCF schema."""
name: str
spec: Optional[str] # bound mjs struct name, e.g. 'mjsGeom'
facets: dict[str, Union[bool, str, float]]
members: list[Union[Attr, Use, Child, Const, Constraint]]
doc: Optional[str]
line: int
def children(self) -> list[Child]:
return [m for m in self.members if isinstance(m, Child)]
def consts(self) -> list[Const]:
return [m for m in self.members if isinstance(m, Const)]
def constraints(self) -> list[Constraint]:
return [m for m in self.members if isinstance(m, Constraint)]
def xml_name(self) -> str:
return str(self.facets.get('xml', self.name))
@dataclasses.dataclass
class Enum:
"""An enum declaration in the MJCF schema."""
name: str
ctype: Optional[str] # bound C enum type, e.g. 'mjtGeom'
items: list[tuple[str, str]] # (xml keyword, C constant or literal)
doc: Optional[str]
line: int
def keywords(self) -> list[str]:
return [key for key, _ in self.items]
@dataclasses.dataclass
class Schema:
"""Top-level parsed representation of an MJCF schema."""
enums: dict[str, Enum]
groups: dict[str, Group]
elements: dict[str, Element]
path: str
def expanded_attrs(self, element: Element) -> list[Attr]:
"""Element's attributes with `use` groups expanded, in declaration order."""
out = []
for member in element.members:
if isinstance(member, Attr):
out.append(member)
elif isinstance(member, Use):
out.extend(self._group_attrs(member.group))
return out
def _group_attrs(self, name: str) -> list[Attr]:
out = []
for member in self.groups[name].members:
if isinstance(member, Attr):
out.append(member)
elif isinstance(member, Use):
out.extend(self._group_attrs(member.group))
return out
#--------------------------------- lexer ---------------------------------------
# NUMBER must not swallow the first dot of a '..' range: 0..3 lexes as
# NUMBER(0) DOTDOT NUMBER(3) via the (?!\.) lookahead.
_TOKEN_RE = re.compile(r"""
(?P<ws>[ \t]+)
| (?P<comment>\#[^\n]*)
| (?P<newline>\n)
| (?P<string>"[^"\n]*")
| (?P<number>-?(?:\d+(?:\.(?!\.)\d*)?|\.\d+)(?:[eE][+-]?\d+)?)
| (?P<dotdot>\.\.)
| (?P<ident>[A-Za-z_][A-Za-z0-9_]*)
| (?P<punct>[{}()\[\]<>:=,?!*+])
""", re.VERBOSE)
@dataclasses.dataclass
class _Token:
kind: str # 'string' | 'number' | 'dotdot' | 'ident' | punct char | 'eof'
value: str
line: int
def _lex(text: str, path: str) -> tuple[list[_Token], dict[int, str]]:
"""Returns tokens and a map of line number -> trailing comment text."""
tokens = []
comments = {}
line = 1
pos = 0
while pos < len(text):
match = _TOKEN_RE.match(text, pos)
if not match:
raise SchemaError(path, line, f'unexpected character {text[pos]!r}')
kind = match.lastgroup
value = match.group()
if kind == 'newline':
line += 1
elif kind == 'comment':
comments[line] = value[1:].strip()
elif kind == 'punct':
tokens.append(_Token(value, value, line))
elif kind != 'ws':
tokens.append(_Token(kind, value, line)) # pyrefly: ignore[bad-argument-type]
pos = match.end()
tokens.append(_Token('eof', '', line))
return tokens, comments
#--------------------------------- parser --------------------------------------
class _Parser:
"""Recursive-descent parser over the token stream."""
def __init__(self, text: str, path: str):
self.path = path
self.tokens, self.comments = _lex(text, path)
self.pos = 0
def error(self, message: str, line: Optional[int] = None) -> SchemaError:
return SchemaError(self.path, line or self.peek().line, message)
def peek(self) -> _Token:
return self.tokens[self.pos]
def next(self) -> _Token:
token = self.tokens[self.pos]
self.pos += 1
return token
def expect(self, kind: str) -> _Token:
token = self.next()
if token.kind != kind:
raise self.error(f'expected {kind!r}, got {token.value!r}',
line=token.line)
return token
def accept(self, kind: str, value: Optional[str] = None) -> Optional[_Token]:
token = self.peek()
if token.kind == kind and (value is None or token.value == value):
return self.next()
return None
def doc_for(self, line: int) -> Optional[str]:
return self.comments.get(line)
def parse(self) -> Schema:
"""Parses the token stream into a Schema dataclass."""
schema = Schema(enums={}, groups={}, elements={},
path=self.path)
while self.peek().kind != 'eof':
token = self.expect('ident')
if token.value == 'enum':
enum = self.parse_enum(token.line)
self.declare(schema.enums, enum.name, 'enum', token.line)
schema.enums[enum.name] = enum
elif token.value == 'group':
group = self.parse_group(token.line)
self.declare(schema.groups, group.name, 'group', token.line)
schema.groups[group.name] = group
elif token.value == 'element':
element = self.parse_element(token.line)
self.declare(schema.elements, element.name, 'element', token.line)
schema.elements[element.name] = element
else:
raise self.error(
f"expected 'enum', 'group' or 'element', "
f'got {token.value!r}', line=token.line)
return schema
def declare(self, table: dict[str, Any], name: str, what: str, line: int):
"""Ensures declaration names are unique within a table."""
if name in table:
raise self.error(f'duplicate {what} {name!r} '
f'(first declared on line {table[name].line})',
line=line)
def parse_enum(self, line: int) -> Enum:
"""Parses an enum declaration."""
name = self.expect('ident').value
ctype = self.expect('ident').value if self.accept(':') else None
doc = self.doc_for(line)
self.expect('{')
items = []
seen = {}
while not self.accept('}'):
key_token = self.next()
if key_token.kind == 'string':
key = key_token.value.strip('"')
elif key_token.kind == 'ident':
key = key_token.value
else:
raise self.error(f'expected enum keyword, got {key_token.value!r}',
line=key_token.line)
if key in seen:
raise self.error(f'duplicate enum keyword {key!r}',
line=key_token.line)
seen[key] = key_token.line
self.expect('=')
value_token = self.next()
if value_token.kind not in ('ident', 'number'):
raise self.error(f'expected C constant or number, '
f'got {value_token.value!r}', line=value_token.line)
items.append((key, value_token.value))
if not items:
raise self.error(f'enum {name!r} is empty', line=line)
return Enum(name=name, ctype=ctype, items=items, doc=doc, line=line)
def parse_group(self, line: int) -> Group:
"""Parses a group declaration."""
name = self.expect('ident').value
variant = bool(self.accept('ident', 'variant'))
doc = self.doc_for(line)
self.expect('{')
members = []
while not self.accept('}'):
members.append(self.parse_member(allow_child=False))
if not members:
raise self.error(f'group {name!r} is empty', line=line)
return Group(name=name, variant=variant, members=members, doc=doc,
line=line)
def parse_element(self, line: int) -> Element:
"""Parses an element declaration."""
name = self.expect('ident').value
spec = self.expect('ident').value if self.accept(':') else None
facets = self.parse_facets(ELEMENT_FACETS) if self.accept('(') else {}
doc = self.doc_for(line)
self.expect('{')
members = []
while not self.accept('}'):
members.append(self.parse_member(allow_child=True))
return Element(name=name, spec=spec, facets=facets, members=members,
doc=doc, line=line)
CONSTRAINT_VERBS = frozenset({'exclusive', 'together', 'requires', 'oneof'})
def parse_member(self, allow_child: bool) -> Union[Attr, Use, Child, Const,
Constraint]:
"""Parses a member of a group or element."""
token = self.expect('ident')
if token.value == 'use':
return Use(group=self.expect('ident').value, line=token.line)
if token.value in self.CONSTRAINT_VERBS and self.peek().kind == 'ident':
# constraints are single-line constructs
bundles = []
while self.peek().kind == 'ident' and self.peek().line == token.line:
bundle = [self.expect('ident').value]
while self.accept('+'):
bundle.append(self.expect('ident').value)
bundles.append(tuple(bundle))
if len(bundles) < 2:
raise self.error(f'{token.value!r} needs at least two attributes',
line=token.line)
return Constraint(kind=token.value, bundles=bundles,
doc=self.doc_for(token.line), line=token.line)
if token.value == 'set':
if not allow_child:
raise self.error("'set' is not allowed in a group", line=token.line)
field = self.expect('ident').value
self.expect('=')
value = self.expect('ident').value
return Const(field=field, value=value, doc=self.doc_for(token.line),
line=token.line)
if token.value == 'child':
if not allow_child:
raise self.error("'child' is not allowed in a group", line=token.line)
name = self.expect('ident').value
card = self.next()
if card.value not in CARDINALITIES:
raise self.error(f'expected cardinality (? ! * R), '
f'got {card.value!r}', line=card.line)
return Child(name=name, card=card.value, doc=self.doc_for(token.line),
line=token.line)
return self.parse_attr(token)
def parse_attr(self, name_token: _Token) -> Attr:
"""Parses an attribute declaration."""
line = name_token.line
self.expect(':')
attr_type, target, arity = self.parse_type()
default = self.parse_default() if self.accept('=') else None
facets = self.parse_facets() if self.accept('(') else {}
return Attr(name=name_token.value, type=attr_type, target=target,
arity=arity, default=default, facets=facets,
doc=self.doc_for(line), line=line)
def parse_type(self) -> tuple[str, Optional[str], Arity]:
"""Parses an attribute type declaration."""
token = self.expect('ident')
if token.value in ('enum', 'flags', 'ref', 'id'):
self.expect('<')
target = self.expect('ident').value
self.expect('>')
return token.value, target, Arity(1, 1)
if token.value not in SCALAR_TYPES:
raise self.error(f'unknown type {token.value!r}', line=token.line)
return token.value, None, self.parse_arity()
def parse_arity(self) -> Arity:
"""Parses attribute arity specification."""
if not self.accept('['):
return Arity(1, 1)
if self.accept(']'):
return Arity(0, None) # unbounded
lo_token = self.expect('number')
lo = self.parse_int(lo_token)
if not self.accept('dotdot'):
self.expect(']')
return Arity(lo, lo)
hi_token = self.next()
if hi_token.kind == 'number':
hi = self.parse_int(hi_token)
if hi <= lo:
raise self.error(f'arity range [{lo}..{hi}] is not increasing',
line=hi_token.line)
elif hi_token.kind == 'ident':
hi = hi_token.value # symbolic bound, e.g. mjNREF
else:
raise self.error(f'expected arity bound, got {hi_token.value!r}',
line=hi_token.line)
self.expect(']')
return Arity(lo, hi)
def parse_int(self, token: _Token) -> int:
"""Parses an integer value from a token."""
try:
value = int(token.value)
except ValueError:
raise self.error(f'expected integer, got {token.value!r}',
line=token.line) from None
if value < 0:
raise self.error('arity may not be negative', line=token.line)
return value
def parse_default(self) -> Union[float, str, tuple[float, ...]]:
"""Parses default value for an attribute."""
token = self.next()
if token.kind == 'number':
return float(token.value)
if token.kind == 'string':
return token.value.strip('"')
if token.kind == 'ident':
return token.value # enum keyword
if token.kind == '{':
values = [float(self.expect('number').value)]
while self.accept(','):
values.append(float(self.expect('number').value))
self.expect('}')
return tuple(values)
raise self.error(f'expected default value, got {token.value!r}',
line=token.line)
def parse_facets(self, known=KNOWN_FACETS) -> dict[str, Union[bool, str,
float]]:
"""Parses attribute or element facets."""
facets = {}
while True:
token = self.expect('ident')
if token.value not in known:
raise self.error(f'unknown facet {token.value!r}', line=token.line)
if token.value in facets:
raise self.error(f'duplicate facet {token.value!r}', line=token.line)
if self.accept('='):
value_token = self.next()
if value_token.kind == 'string':
facets[token.value] = value_token.value.strip('"')
elif value_token.kind == 'ident':
facets[token.value] = value_token.value
elif value_token.kind == 'number':
facets[token.value] = float(value_token.value)
else:
raise self.error(f'expected facet value, got {value_token.value!r}',
line=value_token.line)
else:
facets[token.value] = True
if self.accept(')'):
return facets
self.expect(',')
#------------------------------- validation ------------------------------------
def _validate(schema: Schema):
"""Semantic checks; raises SchemaError on the first violation."""
path = schema.path
def err(line: int, message: str):
raise SchemaError(path, line, message)
# group use graph: dangling targets and cycles
for group in schema.groups.values():
_check_group_cycle(schema, group.name, [], group.line)
for group in schema.groups.values():
member_names = {m.name for m in group.members
if isinstance(m, Attr)}
for con in [m for m in group.members if isinstance(m, Constraint)]:
for bundle in con.bundles:
for name in bundle:
if name not in member_names:
err(con.line, f'constraint references unknown attribute {name!r}')
if group.variant:
for member in group.members:
if isinstance(member, Use):
err(member.line,
f"variant group {group.name!r} may not contain 'use'")
elif isinstance(member, Attr) and member.facets.get('required'):
err(member.line, f'attribute {member.name!r} in variant group '
f'{group.name!r} may not be required')
containers = list(schema.groups.values()) + list(schema.elements.values())
for container in containers:
for member in container.members:
if isinstance(member, Use) and member.group not in schema.groups:
err(member.line, f'use of undeclared group {member.group!r}')
# namespaces exist by virtue of id<ns> declarations
namespaces = set()
for container in containers:
for member in container.members:
if isinstance(member, Attr) and member.type == 'id':
namespaces.add(member.target)
for element in schema.elements.values():
# element facets
for facet in ('xml', 'alias'):
if facet in element.facets and not isinstance(element.facets[facet], str):
err(element.line, f'element facet {facet!r} requires a name')
alias = element.facets.get('alias')
if alias is not None and alias not in schema.elements:
err(element.line,
f'alias references undeclared element {alias!r}')
# children: dangling targets and duplicates
seen_children = set()
for child in element.children():
if child.name not in schema.elements:
err(child.line, f'child references undeclared element {child.name!r}')
if child.name in seen_children:
err(child.line, f'duplicate child {child.name!r}')
seen_children.add(child.name)
# attributes: duplicates across direct and use-expanded members
seen_attrs = {}
for attr in schema.expanded_attrs(element):
if attr.name in seen_attrs:
err(attr.line if attr.line > seen_attrs[attr.name] else element.line,
f'duplicate attribute {attr.name!r} in element {element.name!r} '
f'(directly or via use)')
seen_attrs[attr.name] = attr.line
# constraints reference the element's own (expanded) attributes
for con in element.constraints():
for bundle in con.bundles:
for name in bundle:
if name not in seen_attrs:
err(con.line, f'constraint references unknown attribute {name!r}')
if con.kind == 'requires' and (
len(con.bundles) != 2 or any(len(b) != 1 for b in con.bundles)):
err(con.line, "'requires' takes exactly two attributes")
# per-attribute checks, wherever the attribute is declared
for container in containers:
for attr in container.members:
if isinstance(attr, Attr):
_validate_attr(schema, attr, namespaces)
def _check_group_cycle(schema: Schema, name: str, stack: list[str], line: int):
"""Recursively checks for cycles in group `use` references."""
if name in stack:
cycle = ' -> '.join(stack + [name])
raise SchemaError(schema.path, line, f'group use cycle: {cycle}')
group = schema.groups.get(name)
if group is None:
return # dangling use is reported separately with its own line
for member in group.members:
if isinstance(member, Use):
_check_group_cycle(schema, member.group, stack + [name], member.line)
def _validate_attr(schema: Schema, attr: Attr, namespaces: set[str]):
"""Validates semantic constraints for a single attribute."""
path = schema.path
def err(message: str):
raise SchemaError(path, attr.line, message)
# target existence
if attr.type in ('enum', 'flags') and attr.target not in schema.enums:
err(f'attribute {attr.name!r} references undeclared enum {attr.target!r}')
if attr.type == 'ref' and attr.target not in namespaces:
err(f'attribute {attr.name!r} references namespace {attr.target!r}, '
f'which no id<{attr.target}> declares')
# arity restrictions
if attr.type in ('file', 'bool') and not attr.arity.is_scalar():
err(f'{attr.type} attribute {attr.name!r} may not be a vector')
if attr.type == 'chars' and not isinstance(attr.arity.hi, int):
err(f'chars attribute {attr.name!r} must declare a bounded length')
# facet payloads
if 'pattern' in attr.facets and attr.type not in ('string', 'chars'):
err("facet 'pattern' requires a text attribute")
numeric = attr.type in ('double', 'float', 'int')
for facet in ('min', 'max'):
if facet in attr.facets and not (
numeric and isinstance(attr.facets[facet], (int, float))):
err(f'facet {facet!r} requires a numeric attribute and value')
if 'min' in attr.facets and 'max' in attr.facets:
if attr.facets['min'] > attr.facets['max']: # pyrefly: ignore[unsupported-operation]
err("facet 'min' cannot be greater than 'max'")
if attr.facets.get('positive') and not numeric:
err("facet 'positive' requires a numeric attribute")
if attr.facets.get('required') and attr.default is not None:
err(f'attribute {attr.name!r} is required and has a default')
# defaults
if attr.default is None:
return
if attr.type == 'enum':
if not isinstance(attr.default, str):
err(f'default for enum attribute {attr.name!r} must be a keyword')
keywords = schema.enums[attr.target].keywords() # pyrefly: ignore[bad-index]
if attr.default not in keywords:
err(f'default {attr.default!r} is not a keyword of enum '
f'{attr.target!r}')
return
if attr.type in ('ref', 'id', 'chars'):
err(f'{attr.type} attribute {attr.name!r} may not have a default')
if attr.type == 'bool':
if attr.default not in ('true', 'false'):
err(f'default for bool attribute {attr.name!r} must be true or false')
return
if attr.type in ('string', 'file'):
if not isinstance(attr.default, str):
err(f'default for {attr.type} attribute {attr.name!r} must be a string')
return
# numeric scalars and vectors
if isinstance(attr.default, str):
err(f'default for numeric attribute {attr.name!r} must be numeric')
n = len(attr.default) if isinstance(attr.default, tuple) else 1
lo, hi = attr.arity.lo, attr.arity.hi
if isinstance(attr.default, tuple) and attr.arity.is_scalar():
err(f'vector default for scalar attribute {attr.name!r}')
if n < lo:
err(f'default for {attr.name!r} has {n} values, arity requires '
f'at least {lo}')
if isinstance(hi, int) and n > hi:
err(f'default for {attr.name!r} has {n} values, arity allows '
f'at most {hi}')
#--------------------------------- entry points --------------------------------
def parse_string(text: str, path: str = '<string>') -> Schema:
"""Parses an MJCF schema from a string."""
schema = _Parser(text, path).parse()
_validate(schema)
return schema
def parse_file(path: str) -> Schema:
"""Parses an MJCF schema from a file path."""
with open(path, 'r', encoding='utf-8') as file:
return parse_string(file.read(), path)
def main() -> int:
"""CLI entry point for checking an MJCF schema file."""
if len(sys.argv) != 2:
sys.exit(f'usage: {sys.argv[0]} <mjcf.schema>')
try:
schema = parse_file(sys.argv[1])
except SchemaError as error:
sys.exit(str(error))
n_attrs = sum(len(schema.expanded_attrs(e))
for e in schema.elements.values())
print(f'{sys.argv[1]}: '
f'{len(schema.elements)} elements, {len(schema.groups)} groups, '
f'{len(schema.enums)} enums, {n_attrs} attributes')
return 0
if __name__ == '__main__':
sys.exit(main())
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 30 KiB

+782
View File
@@ -0,0 +1,782 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="684pt" height="460.8pt" viewBox="0 0 684 460.8" xmlns="http://www.w3.org/2000/svg" version="1.1">
<metadata>
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2026-05-13T13:08:19.517788</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.10.6, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 460.8
L 684 460.8
L 684 0
L 0 0
L 0 460.8
z
" style="fill: none; opacity: 0"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 54.189474 377.242105
L 629.810526 377.242105
Q 659.178947 377.242105 659.178947 347.873684
L 659.178947 300.884211
Q 659.178947 271.515789 629.810526 271.515789
L 54.189474 271.515789
Q 24.821053 271.515789 24.821053 300.884211
L 24.821053 347.873684
Q 24.821053 377.242105 54.189474 377.242105
z
" clip-path="url(#p4466066fda)" style="fill: #8e8e93; opacity: 0.35; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_3">
<path d="M 54.189474 362.557895
L 629.810526 362.557895
Q 644.494737 362.557895 644.494737 347.873684
L 644.494737 300.884211
Q 644.494737 286.2 629.810526 286.2
L 54.189474 286.2
Q 39.505263 286.2 39.505263 300.884211
L 39.505263 347.873684
Q 39.505263 362.557895 54.189474 362.557895
z
" clip-path="url(#p4466066fda)" style="fill: #5b7ea8; opacity: 0.55; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_4">
<path d="M 54.189474 347.873684
L 629.810526 347.873684
Q 629.810526 347.873684 629.810526 347.873684
L 629.810526 300.884211
Q 629.810526 300.884211 629.810526 300.884211
L 54.189474 300.884211
Q 54.189474 300.884211 54.189474 300.884211
L 54.189474 347.873684
Q 54.189474 347.873684 54.189474 347.873684
z
" clip-path="url(#p4466066fda)" style="fill: #e69933; opacity: 0.6; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_5">
<path d="M 124.673684 242.147368
C 144.924035 242.147368 164.347709 234.101819 178.666869 219.782659
C 192.986029 205.463499 201.031579 186.039824 201.031579 165.789474
C 201.031579 145.539123 192.986029 126.115449 178.666869 111.796289
C 164.347709 97.477128 144.924035 89.431579 124.673684 89.431579
C 104.423334 89.431579 84.999659 97.477128 70.680499 111.796289
C 56.361339 126.115449 48.315789 145.539123 48.315789 165.789474
C 48.315789 186.039824 56.361339 205.463499 70.680499 219.782659
C 84.999659 234.101819 104.423334 242.147368 124.673684 242.147368
z
" clip-path="url(#p4466066fda)" style="fill: #8e8e93; opacity: 0.35; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_6">
<path d="M 124.673684 224.526316
C 140.250877 224.526316 155.192165 218.337432 166.206904 207.322693
C 177.221642 196.307955 183.410526 181.366666 183.410526 165.789474
C 183.410526 150.212281 177.221642 135.270993 166.206904 124.256254
C 155.192165 113.241516 140.250877 107.052632 124.673684 107.052632
C 109.096492 107.052632 94.155203 113.241516 83.140465 124.256254
C 72.125726 135.270993 65.936842 150.212281 65.936842 165.789474
C 65.936842 181.366666 72.125726 196.307955 83.140465 207.322693
C 94.155203 218.337432 109.096492 224.526316 124.673684 224.526316
z
" clip-path="url(#p4466066fda)" style="fill: #5b7ea8; opacity: 0.55; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_7">
<path d="M 124.673684 206.905263
C 135.577719 206.905263 146.036621 202.573044 153.746938 194.862727
C 161.457255 187.15241 165.789474 176.693509 165.789474 165.789474
C 165.789474 154.885439 161.457255 144.426537 153.746938 136.71622
C 146.036621 129.005903 135.577719 124.673684 124.673684 124.673684
C 113.769649 124.673684 103.310748 129.005903 95.600431 136.71622
C 87.890114 144.426537 83.557895 154.885439 83.557895 165.789474
C 83.557895 176.693509 87.890114 187.15241 95.600431 194.862727
C 103.310748 202.573044 113.769649 206.905263 124.673684 206.905263
z
" clip-path="url(#p4466066fda)" style="fill: #e69933; opacity: 0.6; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_8">
<path d="M 342 277.389474
C 362.25035 277.389474 381.674025 269.343924 395.993185 255.024764
C 410.312345 240.705604 418.357895 221.281929 418.357895 201.031579
C 418.357895 180.781229 410.312345 161.357554 395.993185 147.038394
C 381.674025 132.719234 362.25035 124.673684 342 124.673684
C 321.74965 124.673684 302.325975 132.719234 288.006815 147.038394
C 273.687655 161.357554 265.642105 180.781229 265.642105 201.031579
C 265.642105 221.281929 273.687655 240.705604 288.006815 255.024764
C 302.325975 269.343924 321.74965 277.389474 342 277.389474
z
" clip-path="url(#p4466066fda)" style="fill: #8e8e93; opacity: 0.35; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_9">
<path d="M 342 259.768421
C 357.577193 259.768421 372.518481 253.579537 383.533219 242.564798
C 394.547958 231.55006 400.736842 216.608772 400.736842 201.031579
C 400.736842 185.454386 394.547958 170.513098 383.533219 159.49836
C 372.518481 148.483621 357.577193 142.294737 342 142.294737
C 326.422807 142.294737 311.481519 148.483621 300.466781 159.49836
C 289.452042 170.513098 283.263158 185.454386 283.263158 201.031579
C 283.263158 216.608772 289.452042 231.55006 300.466781 242.564798
C 311.481519 253.579537 326.422807 259.768421 342 259.768421
z
" clip-path="url(#p4466066fda)" style="fill: #5b7ea8; opacity: 0.55; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_10">
<path d="M 342 242.147368
C 352.904035 242.147368 363.362937 237.815149 371.073254 230.104832
C 378.783571 222.394516 383.115789 211.935614 383.115789 201.031579
C 383.115789 190.127544 378.783571 179.668642 371.073254 171.958325
C 363.362937 164.248008 352.904035 159.915789 342 159.915789
C 331.095965 159.915789 320.637063 164.248008 312.926746 171.958325
C 305.216429 179.668642 300.884211 190.127544 300.884211 201.031579
C 300.884211 211.935614 305.216429 222.394516 312.926746 230.104832
C 320.637063 237.815149 331.095965 242.147368 342 242.147368
z
" clip-path="url(#p4466066fda)" style="fill: #e69933; opacity: 0.6; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_11">
<path d="M 559.326316 309.694737
C 579.576666 309.694737 599.000341 301.649187 613.319501 287.330027
C 627.638661 273.010867 635.684211 253.587192 635.684211 233.336842
C 635.684211 213.086492 627.638661 193.662817 613.319501 179.343657
C 599.000341 165.024497 579.576666 156.978947 559.326316 156.978947
C 539.075965 156.978947 519.652291 165.024497 505.333131 179.343657
C 491.013971 193.662817 482.968421 213.086492 482.968421 233.336842
C 482.968421 253.587192 491.013971 273.010867 505.333131 287.330027
C 519.652291 301.649187 539.075965 309.694737 559.326316 309.694737
z
" clip-path="url(#p4466066fda)" style="fill: #8e8e93; opacity: 0.35; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_12">
<path d="M 559.326316 292.073684
C 574.903508 292.073684 589.844797 285.8848 600.859535 274.870061
C 611.874274 263.855323 618.063158 248.914035 618.063158 233.336842
C 618.063158 217.759649 611.874274 202.818361 600.859535 191.803623
C 589.844797 180.788884 574.903508 174.6 559.326316 174.6
C 543.749123 174.6 528.807835 180.788884 517.793096 191.803623
C 506.778358 202.818361 500.589474 217.759649 500.589474 233.336842
C 500.589474 248.914035 506.778358 263.855323 517.793096 274.870061
C 528.807835 285.8848 543.749123 292.073684 559.326316 292.073684
z
" clip-path="url(#p4466066fda)" style="fill: #5b7ea8; opacity: 0.55; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_13">
<path d="M 559.326316 274.452632
C 570.230351 274.452632 580.689252 270.120413 588.399569 262.410096
C 596.109886 254.699779 600.442105 244.240877 600.442105 233.336842
C 600.442105 222.432807 596.109886 211.973906 588.399569 204.263589
C 580.689252 196.553272 570.230351 192.221053 559.326316 192.221053
C 548.422281 192.221053 537.963379 196.553272 530.253062 204.263589
C 522.542745 211.973906 518.210526 222.432807 518.210526 233.336842
C 518.210526 244.240877 522.542745 254.699779 530.253062 262.410096
C 537.963379 270.120413 548.422281 274.452632 559.326316 274.452632
z
" clip-path="url(#p4466066fda)" style="fill: #e69933; opacity: 0.6; stroke: #aaaaaa; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="text_1">
<!-- No contact -->
<g style="fill: #ffffff" transform="translate(81.313684 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-4e" d="M 628 4666
L 1478 4666
L 3547 763
L 3547 4666
L 4159 4666
L 4159 0
L 3309 0
L 1241 3903
L 1241 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6f" d="M 1959 3097
Q 1497 3097 1228 2736
Q 959 2375 959 1747
Q 959 1119 1226 758
Q 1494 397 1959 397
Q 2419 397 2687 759
Q 2956 1122 2956 1747
Q 2956 2369 2687 2733
Q 2419 3097 1959 3097
z
M 1959 3584
Q 2709 3584 3137 3096
Q 3566 2609 3566 1747
Q 3566 888 3137 398
Q 2709 -91 1959 -91
Q 1206 -91 779 398
Q 353 888 353 1747
Q 353 2609 779 3096
Q 1206 3584 1959 3584
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-20" transform="scale(0.015625)"/>
<path id="DejaVuSans-63" d="M 3122 3366
L 3122 2828
Q 2878 2963 2633 3030
Q 2388 3097 2138 3097
Q 1578 3097 1268 2742
Q 959 2388 959 1747
Q 959 1106 1268 751
Q 1578 397 2138 397
Q 2388 397 2633 464
Q 2878 531 3122 666
L 3122 134
Q 2881 22 2623 -34
Q 2366 -91 2075 -91
Q 1284 -91 818 406
Q 353 903 353 1747
Q 353 2603 823 3093
Q 1294 3584 2113 3584
Q 2378 3584 2631 3529
Q 2884 3475 3122 3366
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6e" d="M 3513 2113
L 3513 0
L 2938 0
L 2938 2094
Q 2938 2591 2744 2837
Q 2550 3084 2163 3084
Q 1697 3084 1428 2787
Q 1159 2491 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1366 3272 1645 3428
Q 1925 3584 2291 3584
Q 2894 3584 3203 3211
Q 3513 2838 3513 2113
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-74" d="M 1172 4494
L 1172 3500
L 2356 3500
L 2356 3053
L 1172 3053
L 1172 1153
Q 1172 725 1289 603
Q 1406 481 1766 481
L 2356 481
L 2356 0
L 1766 0
Q 1100 0 847 248
Q 594 497 594 1153
L 594 3053
L 172 3053
L 172 3500
L 594 3500
L 594 4494
L 1172 4494
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-61" d="M 2194 1759
Q 1497 1759 1228 1600
Q 959 1441 959 1056
Q 959 750 1161 570
Q 1363 391 1709 391
Q 2188 391 2477 730
Q 2766 1069 2766 1631
L 2766 1759
L 2194 1759
z
M 3341 1997
L 3341 0
L 2766 0
L 2766 531
Q 2569 213 2275 61
Q 1981 -91 1556 -91
Q 1019 -91 701 211
Q 384 513 384 1019
Q 384 1609 779 1909
Q 1175 2209 1959 2209
L 2766 2209
L 2766 2266
Q 2766 2663 2505 2880
Q 2244 3097 1772 3097
Q 1472 3097 1187 3025
Q 903 2953 641 2809
L 641 3341
Q 956 3463 1253 3523
Q 1550 3584 1831 3584
Q 2591 3584 2966 3190
Q 3341 2797 3341 1997
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-4e"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(74.804688 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(135.986328 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(167.773438 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(222.753906 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(283.935547 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(347.314453 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(386.523438 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(447.802734 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(502.783203 0)"/>
</g>
</g>
<g id="text_2">
<!-- Inactive contact, -->
<g style="fill: #ffffff" transform="translate(275.23 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-49" d="M 628 4666
L 1259 4666
L 1259 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-69" d="M 603 3500
L 1178 3500
L 1178 0
L 603 0
L 603 3500
z
M 603 4863
L 1178 4863
L 1178 4134
L 603 4134
L 603 4863
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-76" d="M 191 3500
L 800 3500
L 1894 563
L 2988 3500
L 3597 3500
L 2284 0
L 1503 0
L 191 3500
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-65" d="M 3597 1894
L 3597 1613
L 953 1613
Q 991 1019 1311 708
Q 1631 397 2203 397
Q 2534 397 2845 478
Q 3156 559 3463 722
L 3463 178
Q 3153 47 2828 -22
Q 2503 -91 2169 -91
Q 1331 -91 842 396
Q 353 884 353 1716
Q 353 2575 817 3079
Q 1281 3584 2069 3584
Q 2775 3584 3186 3129
Q 3597 2675 3597 1894
z
M 3022 2063
Q 3016 2534 2758 2815
Q 2500 3097 2075 3097
Q 1594 3097 1305 2825
Q 1016 2553 972 2059
L 3022 2063
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-2c" d="M 750 794
L 1409 794
L 1409 256
L 897 -744
L 494 -744
L 750 256
L 750 794
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-49"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(29.492188 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(92.871094 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(154.150391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(209.130859 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(248.339844 0)"/>
<use xlink:href="#DejaVuSans-76" transform="translate(276.123047 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(335.302734 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(396.826172 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(428.613281 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(483.59375 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(544.775391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(608.154297 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(647.363281 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(708.642578 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(763.623047 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(802.832031 0)"/>
</g>
<!-- no force -->
<g style="fill: #ffffff" transform="translate(309.35125 433.242342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-66" d="M 2375 4863
L 2375 4384
L 1825 4384
Q 1516 4384 1395 4259
Q 1275 4134 1275 3809
L 1275 3500
L 2222 3500
L 2222 3053
L 1275 3053
L 1275 0
L 697 0
L 697 3053
L 147 3053
L 147 3500
L 697 3500
L 697 3744
Q 697 4328 969 4595
Q 1241 4863 1831 4863
L 2375 4863
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-72" d="M 2631 2963
Q 2534 3019 2420 3045
Q 2306 3072 2169 3072
Q 1681 3072 1420 2755
Q 1159 2438 1159 1844
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1341 3275 1631 3429
Q 1922 3584 2338 3584
Q 2397 3584 2469 3576
Q 2541 3569 2628 3553
L 2631 2963
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-6e"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(63.378906 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(124.560547 0)"/>
<use xlink:href="#DejaVuSans-66" transform="translate(156.347656 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(191.552734 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(252.734375 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(291.597656 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(346.578125 0)"/>
</g>
</g>
<g id="text_3">
<!-- Active contact, -->
<g style="fill: #ffffff" transform="translate(499.556316 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-41" d="M 2188 4044
L 1331 1722
L 3047 1722
L 2188 4044
z
M 1831 4666
L 2547 4666
L 4325 0
L 3669 0
L 3244 1197
L 1141 1197
L 716 0
L 50 0
L 1831 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-41"/>
<use xlink:href="#DejaVuSans-63" transform="translate(66.658203 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(121.638672 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(160.847656 0)"/>
<use xlink:href="#DejaVuSans-76" transform="translate(188.630859 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(247.810547 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(309.333984 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(341.121094 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(396.101562 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(457.283203 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(520.662109 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(559.871094 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(621.150391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(676.130859 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(715.339844 0)"/>
</g>
<!-- force generated -->
<g style="fill: #ffffff" transform="translate(495.320066 433.242342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-67" d="M 2906 1791
Q 2906 2416 2648 2759
Q 2391 3103 1925 3103
Q 1463 3103 1205 2759
Q 947 2416 947 1791
Q 947 1169 1205 825
Q 1463 481 1925 481
Q 2391 481 2648 825
Q 2906 1169 2906 1791
z
M 3481 434
Q 3481 -459 3084 -895
Q 2688 -1331 1869 -1331
Q 1566 -1331 1297 -1286
Q 1028 -1241 775 -1147
L 775 -588
Q 1028 -725 1275 -790
Q 1522 -856 1778 -856
Q 2344 -856 2625 -561
Q 2906 -266 2906 331
L 2906 616
Q 2728 306 2450 153
Q 2172 0 1784 0
Q 1141 0 747 490
Q 353 981 353 1791
Q 353 2603 747 3093
Q 1141 3584 1784 3584
Q 2172 3584 2450 3431
Q 2728 3278 2906 2969
L 2906 3500
L 3481 3500
L 3481 434
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-64" d="M 2906 2969
L 2906 4863
L 3481 4863
L 3481 0
L 2906 0
L 2906 525
Q 2725 213 2448 61
Q 2172 -91 1784 -91
Q 1150 -91 751 415
Q 353 922 353 1747
Q 353 2572 751 3078
Q 1150 3584 1784 3584
Q 2172 3584 2448 3432
Q 2725 3281 2906 2969
z
M 947 1747
Q 947 1113 1208 752
Q 1469 391 1925 391
Q 2381 391 2643 752
Q 2906 1113 2906 1747
Q 2906 2381 2643 2742
Q 2381 3103 1925 3103
Q 1469 3103 1208 2742
Q 947 2381 947 1747
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-66"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(35.205078 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(96.386719 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(135.25 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(190.230469 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(251.753906 0)"/>
<use xlink:href="#DejaVuSans-67" transform="translate(283.541016 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(347.017578 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(408.541016 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(471.919922 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(533.443359 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(574.556641 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(635.835938 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(675.044922 0)"/>
<use xlink:href="#DejaVuSans-64" transform="translate(736.568359 0)"/>
</g>
</g>
<g id="patch_14">
<path d="M 538.768421 112.926316
L 626.873684 112.926316
Q 635.684211 112.926316 635.684211 104.115789
L 635.684211 27.757895
Q 635.684211 18.947368 626.873684 18.947368
L 538.768421 18.947368
Q 529.957895 18.947368 529.957895 27.757895
L 529.957895 104.115789
Q 529.957895 112.926316 538.768421 112.926316
z
" clip-path="url(#p4466066fda)" style="fill: #333333; opacity: 0.85; stroke: #aaaaaa; stroke-linejoin: miter"/>
</g>
<g id="patch_15">
<path d="M 547.578947 44.791579
C 549.759754 44.791579 551.851535 43.925135 553.393598 42.383072
C 554.935661 40.841008 555.802105 38.749228 555.802105 36.568421
C 555.802105 34.387614 554.935661 32.295834 553.393598 30.75377
C 551.851535 29.211707 549.759754 28.345263 547.578947 28.345263
C 545.39814 28.345263 543.30636 29.211707 541.764297 30.75377
C 540.222233 32.295834 539.355789 34.387614 539.355789 36.568421
C 539.355789 38.749228 540.222233 40.841008 541.764297 42.383072
C 543.30636 43.925135 545.39814 44.791579 547.578947 44.791579
z
" clip-path="url(#p4466066fda)" style="fill: #e69933; stroke: #aaaaaa; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="patch_16">
<path d="M 547.578947 74.16
C 549.759754 74.16 551.851535 73.293556 553.393598 71.751493
C 554.935661 70.209429 555.802105 68.117649 555.802105 65.936842
C 555.802105 63.756035 554.935661 61.664255 553.393598 60.122191
C 551.851535 58.580128 549.759754 57.713684 547.578947 57.713684
C 545.39814 57.713684 543.30636 58.580128 541.764297 60.122191
C 540.222233 61.664255 539.355789 63.756035 539.355789 65.936842
C 539.355789 68.117649 540.222233 70.209429 541.764297 71.751493
C 543.30636 73.293556 545.39814 74.16 547.578947 74.16
z
" clip-path="url(#p4466066fda)" style="fill: #5b7ea8; stroke: #aaaaaa; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="patch_17">
<path d="M 547.578947 103.528421
C 549.759754 103.528421 551.851535 102.661977 553.393598 101.119914
C 554.935661 99.57785 555.802105 97.48607 555.802105 95.305263
C 555.802105 93.124456 554.935661 91.032676 553.393598 89.490612
C 551.851535 87.948549 549.759754 87.082105 547.578947 87.082105
C 545.39814 87.082105 543.30636 87.948549 541.764297 89.490612
C 540.222233 91.032676 539.355789 93.124456 539.355789 95.305263
C 539.355789 97.48607 540.222233 99.57785 541.764297 101.119914
C 543.30636 102.661977 545.39814 103.528421 547.578947 103.528421
z
" clip-path="url(#p4466066fda)" style="fill: #8e8e93; stroke: #aaaaaa; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="text_4">
<!-- Geom -->
<g style="fill: #ffffff" transform="translate(565.2 40.431546) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-47" d="M 3809 666
L 3809 1919
L 2778 1919
L 2778 2438
L 4434 2438
L 4434 434
Q 4069 175 3628 42
Q 3188 -91 2688 -91
Q 1594 -91 976 548
Q 359 1188 359 2328
Q 359 3472 976 4111
Q 1594 4750 2688 4750
Q 3144 4750 3555 4637
Q 3966 4525 4313 4306
L 4313 3634
Q 3963 3931 3569 4081
Q 3175 4231 2741 4231
Q 1884 4231 1454 3753
Q 1025 3275 1025 2328
Q 1025 1384 1454 906
Q 1884 428 2741 428
Q 3075 428 3337 486
Q 3600 544 3809 666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6d" d="M 3328 2828
Q 3544 3216 3844 3400
Q 4144 3584 4550 3584
Q 5097 3584 5394 3201
Q 5691 2819 5691 2113
L 5691 0
L 5113 0
L 5113 2094
Q 5113 2597 4934 2840
Q 4756 3084 4391 3084
Q 3944 3084 3684 2787
Q 3425 2491 3425 1978
L 3425 0
L 2847 0
L 2847 2094
Q 2847 2600 2669 2842
Q 2491 3084 2119 3084
Q 1678 3084 1418 2786
Q 1159 2488 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1356 3278 1631 3431
Q 1906 3584 2284 3584
Q 2666 3584 2933 3390
Q 3200 3197 3328 2828
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-47"/>
<use xlink:href="#DejaVuSans-65" transform="translate(77.490234 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(139.013672 0)"/>
<use xlink:href="#DejaVuSans-6d" transform="translate(200.195312 0)"/>
</g>
</g>
<g id="text_5">
<!-- Margin -->
<g style="fill: #ffffff" transform="translate(565.2 69.799967) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-4d" d="M 628 4666
L 1569 4666
L 2759 1491
L 3956 4666
L 4897 4666
L 4897 0
L 4281 0
L 4281 4097
L 3078 897
L 2444 897
L 1241 4097
L 1241 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-4d"/>
<use xlink:href="#DejaVuSans-61" transform="translate(86.279297 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(147.558594 0)"/>
<use xlink:href="#DejaVuSans-67" transform="translate(186.921875 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(250.398438 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(278.181641 0)"/>
</g>
</g>
<g id="text_6">
<!-- Gap -->
<g style="fill: #ffffff" transform="translate(565.2 99.168388) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-70" d="M 1159 525
L 1159 -1331
L 581 -1331
L 581 3500
L 1159 3500
L 1159 2969
Q 1341 3281 1617 3432
Q 1894 3584 2278 3584
Q 2916 3584 3314 3078
Q 3713 2572 3713 1747
Q 3713 922 3314 415
Q 2916 -91 2278 -91
Q 1894 -91 1617 61
Q 1341 213 1159 525
z
M 3116 1747
Q 3116 2381 2855 2742
Q 2594 3103 2138 3103
Q 1681 3103 1420 2742
Q 1159 2381 1159 1747
Q 1159 1113 1420 752
Q 1681 391 2138 391
Q 2594 391 2855 752
Q 3116 1113 3116 1747
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-47"/>
<use xlink:href="#DejaVuSans-61" transform="translate(77.490234 0)"/>
<use xlink:href="#DejaVuSans-70" transform="translate(138.769531 0)"/>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="p4466066fda">
<rect x="7.2" y="7.2" width="669.6" height="446.4"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

+781
View File
@@ -0,0 +1,781 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="684pt" height="460.8pt" viewBox="0 0 684 460.8" xmlns="http://www.w3.org/2000/svg" version="1.1">
<metadata>
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2026-05-13T13:08:19.427865</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.10.6, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 460.8
L 684 460.8
L 684 0
L 0 0
z
" style="fill: #ffffff"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 54.189474 377.242105
L 629.810526 377.242105
Q 659.178947 377.242105 659.178947 347.873684
L 659.178947 300.884211
Q 659.178947 271.515789 629.810526 271.515789
L 54.189474 271.515789
Q 24.821053 271.515789 24.821053 300.884211
L 24.821053 347.873684
Q 24.821053 377.242105 54.189474 377.242105
z
" clip-path="url(#p60d92c8ec7)" style="fill: #b0bec5; opacity: 0.35; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_3">
<path d="M 54.189474 362.557895
L 629.810526 362.557895
Q 644.494737 362.557895 644.494737 347.873684
L 644.494737 300.884211
Q 644.494737 286.2 629.810526 286.2
L 54.189474 286.2
Q 39.505263 286.2 39.505263 300.884211
L 39.505263 347.873684
Q 39.505263 362.557895 54.189474 362.557895
z
" clip-path="url(#p60d92c8ec7)" style="fill: #7ba4cc; opacity: 0.55; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_4">
<path d="M 54.189474 347.873684
L 629.810526 347.873684
Q 629.810526 347.873684 629.810526 347.873684
L 629.810526 300.884211
Q 629.810526 300.884211 629.810526 300.884211
L 54.189474 300.884211
Q 54.189474 300.884211 54.189474 300.884211
L 54.189474 347.873684
Q 54.189474 347.873684 54.189474 347.873684
z
" clip-path="url(#p60d92c8ec7)" style="fill: #e69933; opacity: 0.6; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_5">
<path d="M 124.673684 242.147368
C 144.924035 242.147368 164.347709 234.101819 178.666869 219.782659
C 192.986029 205.463499 201.031579 186.039824 201.031579 165.789474
C 201.031579 145.539123 192.986029 126.115449 178.666869 111.796289
C 164.347709 97.477128 144.924035 89.431579 124.673684 89.431579
C 104.423334 89.431579 84.999659 97.477128 70.680499 111.796289
C 56.361339 126.115449 48.315789 145.539123 48.315789 165.789474
C 48.315789 186.039824 56.361339 205.463499 70.680499 219.782659
C 84.999659 234.101819 104.423334 242.147368 124.673684 242.147368
z
" clip-path="url(#p60d92c8ec7)" style="fill: #b0bec5; opacity: 0.35; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_6">
<path d="M 124.673684 224.526316
C 140.250877 224.526316 155.192165 218.337432 166.206904 207.322693
C 177.221642 196.307955 183.410526 181.366666 183.410526 165.789474
C 183.410526 150.212281 177.221642 135.270993 166.206904 124.256254
C 155.192165 113.241516 140.250877 107.052632 124.673684 107.052632
C 109.096492 107.052632 94.155203 113.241516 83.140465 124.256254
C 72.125726 135.270993 65.936842 150.212281 65.936842 165.789474
C 65.936842 181.366666 72.125726 196.307955 83.140465 207.322693
C 94.155203 218.337432 109.096492 224.526316 124.673684 224.526316
z
" clip-path="url(#p60d92c8ec7)" style="fill: #7ba4cc; opacity: 0.55; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_7">
<path d="M 124.673684 206.905263
C 135.577719 206.905263 146.036621 202.573044 153.746938 194.862727
C 161.457255 187.15241 165.789474 176.693509 165.789474 165.789474
C 165.789474 154.885439 161.457255 144.426537 153.746938 136.71622
C 146.036621 129.005903 135.577719 124.673684 124.673684 124.673684
C 113.769649 124.673684 103.310748 129.005903 95.600431 136.71622
C 87.890114 144.426537 83.557895 154.885439 83.557895 165.789474
C 83.557895 176.693509 87.890114 187.15241 95.600431 194.862727
C 103.310748 202.573044 113.769649 206.905263 124.673684 206.905263
z
" clip-path="url(#p60d92c8ec7)" style="fill: #e69933; opacity: 0.6; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_8">
<path d="M 342 277.389474
C 362.25035 277.389474 381.674025 269.343924 395.993185 255.024764
C 410.312345 240.705604 418.357895 221.281929 418.357895 201.031579
C 418.357895 180.781229 410.312345 161.357554 395.993185 147.038394
C 381.674025 132.719234 362.25035 124.673684 342 124.673684
C 321.74965 124.673684 302.325975 132.719234 288.006815 147.038394
C 273.687655 161.357554 265.642105 180.781229 265.642105 201.031579
C 265.642105 221.281929 273.687655 240.705604 288.006815 255.024764
C 302.325975 269.343924 321.74965 277.389474 342 277.389474
z
" clip-path="url(#p60d92c8ec7)" style="fill: #b0bec5; opacity: 0.35; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_9">
<path d="M 342 259.768421
C 357.577193 259.768421 372.518481 253.579537 383.533219 242.564798
C 394.547958 231.55006 400.736842 216.608772 400.736842 201.031579
C 400.736842 185.454386 394.547958 170.513098 383.533219 159.49836
C 372.518481 148.483621 357.577193 142.294737 342 142.294737
C 326.422807 142.294737 311.481519 148.483621 300.466781 159.49836
C 289.452042 170.513098 283.263158 185.454386 283.263158 201.031579
C 283.263158 216.608772 289.452042 231.55006 300.466781 242.564798
C 311.481519 253.579537 326.422807 259.768421 342 259.768421
z
" clip-path="url(#p60d92c8ec7)" style="fill: #7ba4cc; opacity: 0.55; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_10">
<path d="M 342 242.147368
C 352.904035 242.147368 363.362937 237.815149 371.073254 230.104832
C 378.783571 222.394516 383.115789 211.935614 383.115789 201.031579
C 383.115789 190.127544 378.783571 179.668642 371.073254 171.958325
C 363.362937 164.248008 352.904035 159.915789 342 159.915789
C 331.095965 159.915789 320.637063 164.248008 312.926746 171.958325
C 305.216429 179.668642 300.884211 190.127544 300.884211 201.031579
C 300.884211 211.935614 305.216429 222.394516 312.926746 230.104832
C 320.637063 237.815149 331.095965 242.147368 342 242.147368
z
" clip-path="url(#p60d92c8ec7)" style="fill: #e69933; opacity: 0.6; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_11">
<path d="M 559.326316 309.694737
C 579.576666 309.694737 599.000341 301.649187 613.319501 287.330027
C 627.638661 273.010867 635.684211 253.587192 635.684211 233.336842
C 635.684211 213.086492 627.638661 193.662817 613.319501 179.343657
C 599.000341 165.024497 579.576666 156.978947 559.326316 156.978947
C 539.075965 156.978947 519.652291 165.024497 505.333131 179.343657
C 491.013971 193.662817 482.968421 213.086492 482.968421 233.336842
C 482.968421 253.587192 491.013971 273.010867 505.333131 287.330027
C 519.652291 301.649187 539.075965 309.694737 559.326316 309.694737
z
" clip-path="url(#p60d92c8ec7)" style="fill: #b0bec5; opacity: 0.35; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_12">
<path d="M 559.326316 292.073684
C 574.903508 292.073684 589.844797 285.8848 600.859535 274.870061
C 611.874274 263.855323 618.063158 248.914035 618.063158 233.336842
C 618.063158 217.759649 611.874274 202.818361 600.859535 191.803623
C 589.844797 180.788884 574.903508 174.6 559.326316 174.6
C 543.749123 174.6 528.807835 180.788884 517.793096 191.803623
C 506.778358 202.818361 500.589474 217.759649 500.589474 233.336842
C 500.589474 248.914035 506.778358 263.855323 517.793096 274.870061
C 528.807835 285.8848 543.749123 292.073684 559.326316 292.073684
z
" clip-path="url(#p60d92c8ec7)" style="fill: #7ba4cc; opacity: 0.55; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="patch_13">
<path d="M 559.326316 274.452632
C 570.230351 274.452632 580.689252 270.120413 588.399569 262.410096
C 596.109886 254.699779 600.442105 244.240877 600.442105 233.336842
C 600.442105 222.432807 596.109886 211.973906 588.399569 204.263589
C 580.689252 196.553272 570.230351 192.221053 559.326316 192.221053
C 548.422281 192.221053 537.963379 196.553272 530.253062 204.263589
C 522.542745 211.973906 518.210526 222.432807 518.210526 233.336842
C 518.210526 244.240877 522.542745 254.699779 530.253062 262.410096
C 537.963379 270.120413 548.422281 274.452632 559.326316 274.452632
z
" clip-path="url(#p60d92c8ec7)" style="fill: #e69933; opacity: 0.6; stroke: #34495e; stroke-width: 1.5; stroke-linejoin: miter"/>
</g>
<g id="text_1">
<!-- No contact -->
<g transform="translate(81.313684 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-4e" d="M 628 4666
L 1478 4666
L 3547 763
L 3547 4666
L 4159 4666
L 4159 0
L 3309 0
L 1241 3903
L 1241 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6f" d="M 1959 3097
Q 1497 3097 1228 2736
Q 959 2375 959 1747
Q 959 1119 1226 758
Q 1494 397 1959 397
Q 2419 397 2687 759
Q 2956 1122 2956 1747
Q 2956 2369 2687 2733
Q 2419 3097 1959 3097
z
M 1959 3584
Q 2709 3584 3137 3096
Q 3566 2609 3566 1747
Q 3566 888 3137 398
Q 2709 -91 1959 -91
Q 1206 -91 779 398
Q 353 888 353 1747
Q 353 2609 779 3096
Q 1206 3584 1959 3584
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-20" transform="scale(0.015625)"/>
<path id="DejaVuSans-63" d="M 3122 3366
L 3122 2828
Q 2878 2963 2633 3030
Q 2388 3097 2138 3097
Q 1578 3097 1268 2742
Q 959 2388 959 1747
Q 959 1106 1268 751
Q 1578 397 2138 397
Q 2388 397 2633 464
Q 2878 531 3122 666
L 3122 134
Q 2881 22 2623 -34
Q 2366 -91 2075 -91
Q 1284 -91 818 406
Q 353 903 353 1747
Q 353 2603 823 3093
Q 1294 3584 2113 3584
Q 2378 3584 2631 3529
Q 2884 3475 3122 3366
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6e" d="M 3513 2113
L 3513 0
L 2938 0
L 2938 2094
Q 2938 2591 2744 2837
Q 2550 3084 2163 3084
Q 1697 3084 1428 2787
Q 1159 2491 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1366 3272 1645 3428
Q 1925 3584 2291 3584
Q 2894 3584 3203 3211
Q 3513 2838 3513 2113
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-74" d="M 1172 4494
L 1172 3500
L 2356 3500
L 2356 3053
L 1172 3053
L 1172 1153
Q 1172 725 1289 603
Q 1406 481 1766 481
L 2356 481
L 2356 0
L 1766 0
Q 1100 0 847 248
Q 594 497 594 1153
L 594 3053
L 172 3053
L 172 3500
L 594 3500
L 594 4494
L 1172 4494
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-61" d="M 2194 1759
Q 1497 1759 1228 1600
Q 959 1441 959 1056
Q 959 750 1161 570
Q 1363 391 1709 391
Q 2188 391 2477 730
Q 2766 1069 2766 1631
L 2766 1759
L 2194 1759
z
M 3341 1997
L 3341 0
L 2766 0
L 2766 531
Q 2569 213 2275 61
Q 1981 -91 1556 -91
Q 1019 -91 701 211
Q 384 513 384 1019
Q 384 1609 779 1909
Q 1175 2209 1959 2209
L 2766 2209
L 2766 2266
Q 2766 2663 2505 2880
Q 2244 3097 1772 3097
Q 1472 3097 1187 3025
Q 903 2953 641 2809
L 641 3341
Q 956 3463 1253 3523
Q 1550 3584 1831 3584
Q 2591 3584 2966 3190
Q 3341 2797 3341 1997
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-4e"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(74.804688 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(135.986328 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(167.773438 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(222.753906 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(283.935547 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(347.314453 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(386.523438 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(447.802734 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(502.783203 0)"/>
</g>
</g>
<g id="text_2">
<!-- Inactive contact, -->
<g transform="translate(275.23 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-49" d="M 628 4666
L 1259 4666
L 1259 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-69" d="M 603 3500
L 1178 3500
L 1178 0
L 603 0
L 603 3500
z
M 603 4863
L 1178 4863
L 1178 4134
L 603 4134
L 603 4863
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-76" d="M 191 3500
L 800 3500
L 1894 563
L 2988 3500
L 3597 3500
L 2284 0
L 1503 0
L 191 3500
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-65" d="M 3597 1894
L 3597 1613
L 953 1613
Q 991 1019 1311 708
Q 1631 397 2203 397
Q 2534 397 2845 478
Q 3156 559 3463 722
L 3463 178
Q 3153 47 2828 -22
Q 2503 -91 2169 -91
Q 1331 -91 842 396
Q 353 884 353 1716
Q 353 2575 817 3079
Q 1281 3584 2069 3584
Q 2775 3584 3186 3129
Q 3597 2675 3597 1894
z
M 3022 2063
Q 3016 2534 2758 2815
Q 2500 3097 2075 3097
Q 1594 3097 1305 2825
Q 1016 2553 972 2059
L 3022 2063
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-2c" d="M 750 794
L 1409 794
L 1409 256
L 897 -744
L 494 -744
L 750 256
L 750 794
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-49"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(29.492188 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(92.871094 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(154.150391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(209.130859 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(248.339844 0)"/>
<use xlink:href="#DejaVuSans-76" transform="translate(276.123047 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(335.302734 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(396.826172 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(428.613281 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(483.59375 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(544.775391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(608.154297 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(647.363281 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(708.642578 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(763.623047 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(802.832031 0)"/>
</g>
<!-- no force -->
<g transform="translate(309.35125 433.242342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-66" d="M 2375 4863
L 2375 4384
L 1825 4384
Q 1516 4384 1395 4259
Q 1275 4134 1275 3809
L 1275 3500
L 2222 3500
L 2222 3053
L 1275 3053
L 1275 0
L 697 0
L 697 3053
L 147 3053
L 147 3500
L 697 3500
L 697 3744
Q 697 4328 969 4595
Q 1241 4863 1831 4863
L 2375 4863
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-72" d="M 2631 2963
Q 2534 3019 2420 3045
Q 2306 3072 2169 3072
Q 1681 3072 1420 2755
Q 1159 2438 1159 1844
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1341 3275 1631 3429
Q 1922 3584 2338 3584
Q 2397 3584 2469 3576
Q 2541 3569 2628 3553
L 2631 2963
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-6e"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(63.378906 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(124.560547 0)"/>
<use xlink:href="#DejaVuSans-66" transform="translate(156.347656 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(191.552734 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(252.734375 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(291.597656 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(346.578125 0)"/>
</g>
</g>
<g id="text_3">
<!-- Active contact, -->
<g transform="translate(499.556316 412.894342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-41" d="M 2188 4044
L 1331 1722
L 3047 1722
L 2188 4044
z
M 1831 4666
L 2547 4666
L 4325 0
L 3669 0
L 3244 1197
L 1141 1197
L 716 0
L 50 0
L 1831 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-41"/>
<use xlink:href="#DejaVuSans-63" transform="translate(66.658203 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(121.638672 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(160.847656 0)"/>
<use xlink:href="#DejaVuSans-76" transform="translate(188.630859 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(247.810547 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(309.333984 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(341.121094 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(396.101562 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(457.283203 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(520.662109 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(559.871094 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(621.150391 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(676.130859 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(715.339844 0)"/>
</g>
<!-- force generated -->
<g transform="translate(495.320066 433.242342) scale(0.16 -0.16)">
<defs>
<path id="DejaVuSans-67" d="M 2906 1791
Q 2906 2416 2648 2759
Q 2391 3103 1925 3103
Q 1463 3103 1205 2759
Q 947 2416 947 1791
Q 947 1169 1205 825
Q 1463 481 1925 481
Q 2391 481 2648 825
Q 2906 1169 2906 1791
z
M 3481 434
Q 3481 -459 3084 -895
Q 2688 -1331 1869 -1331
Q 1566 -1331 1297 -1286
Q 1028 -1241 775 -1147
L 775 -588
Q 1028 -725 1275 -790
Q 1522 -856 1778 -856
Q 2344 -856 2625 -561
Q 2906 -266 2906 331
L 2906 616
Q 2728 306 2450 153
Q 2172 0 1784 0
Q 1141 0 747 490
Q 353 981 353 1791
Q 353 2603 747 3093
Q 1141 3584 1784 3584
Q 2172 3584 2450 3431
Q 2728 3278 2906 2969
L 2906 3500
L 3481 3500
L 3481 434
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-64" d="M 2906 2969
L 2906 4863
L 3481 4863
L 3481 0
L 2906 0
L 2906 525
Q 2725 213 2448 61
Q 2172 -91 1784 -91
Q 1150 -91 751 415
Q 353 922 353 1747
Q 353 2572 751 3078
Q 1150 3584 1784 3584
Q 2172 3584 2448 3432
Q 2725 3281 2906 2969
z
M 947 1747
Q 947 1113 1208 752
Q 1469 391 1925 391
Q 2381 391 2643 752
Q 2906 1113 2906 1747
Q 2906 2381 2643 2742
Q 2381 3103 1925 3103
Q 1469 3103 1208 2742
Q 947 2381 947 1747
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-66"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(35.205078 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(96.386719 0)"/>
<use xlink:href="#DejaVuSans-63" transform="translate(135.25 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(190.230469 0)"/>
<use xlink:href="#DejaVuSans-20" transform="translate(251.753906 0)"/>
<use xlink:href="#DejaVuSans-67" transform="translate(283.541016 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(347.017578 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(408.541016 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(471.919922 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(533.443359 0)"/>
<use xlink:href="#DejaVuSans-61" transform="translate(574.556641 0)"/>
<use xlink:href="#DejaVuSans-74" transform="translate(635.835938 0)"/>
<use xlink:href="#DejaVuSans-65" transform="translate(675.044922 0)"/>
<use xlink:href="#DejaVuSans-64" transform="translate(736.568359 0)"/>
</g>
</g>
<g id="patch_14">
<path d="M 538.768421 112.926316
L 626.873684 112.926316
Q 635.684211 112.926316 635.684211 104.115789
L 635.684211 27.757895
Q 635.684211 18.947368 626.873684 18.947368
L 538.768421 18.947368
Q 529.957895 18.947368 529.957895 27.757895
L 529.957895 104.115789
Q 529.957895 112.926316 538.768421 112.926316
z
" clip-path="url(#p60d92c8ec7)" style="fill: #ffffff; opacity: 0.85; stroke: #34495e; stroke-linejoin: miter"/>
</g>
<g id="patch_15">
<path d="M 547.578947 44.791579
C 549.759754 44.791579 551.851535 43.925135 553.393598 42.383072
C 554.935661 40.841008 555.802105 38.749228 555.802105 36.568421
C 555.802105 34.387614 554.935661 32.295834 553.393598 30.75377
C 551.851535 29.211707 549.759754 28.345263 547.578947 28.345263
C 545.39814 28.345263 543.30636 29.211707 541.764297 30.75377
C 540.222233 32.295834 539.355789 34.387614 539.355789 36.568421
C 539.355789 38.749228 540.222233 40.841008 541.764297 42.383072
C 543.30636 43.925135 545.39814 44.791579 547.578947 44.791579
z
" clip-path="url(#p60d92c8ec7)" style="fill: #e69933; opacity: 0.6; stroke: #34495e; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="patch_16">
<path d="M 547.578947 74.16
C 549.759754 74.16 551.851535 73.293556 553.393598 71.751493
C 554.935661 70.209429 555.802105 68.117649 555.802105 65.936842
C 555.802105 63.756035 554.935661 61.664255 553.393598 60.122191
C 551.851535 58.580128 549.759754 57.713684 547.578947 57.713684
C 545.39814 57.713684 543.30636 58.580128 541.764297 60.122191
C 540.222233 61.664255 539.355789 63.756035 539.355789 65.936842
C 539.355789 68.117649 540.222233 70.209429 541.764297 71.751493
C 543.30636 73.293556 545.39814 74.16 547.578947 74.16
z
" clip-path="url(#p60d92c8ec7)" style="fill: #7ba4cc; opacity: 0.55; stroke: #34495e; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="patch_17">
<path d="M 547.578947 103.528421
C 549.759754 103.528421 551.851535 102.661977 553.393598 101.119914
C 554.935661 99.57785 555.802105 97.48607 555.802105 95.305263
C 555.802105 93.124456 554.935661 91.032676 553.393598 89.490612
C 551.851535 87.948549 549.759754 87.082105 547.578947 87.082105
C 545.39814 87.082105 543.30636 87.948549 541.764297 89.490612
C 540.222233 91.032676 539.355789 93.124456 539.355789 95.305263
C 539.355789 97.48607 540.222233 99.57785 541.764297 101.119914
C 543.30636 102.661977 545.39814 103.528421 547.578947 103.528421
z
" clip-path="url(#p60d92c8ec7)" style="fill: #b0bec5; opacity: 0.35; stroke: #34495e; stroke-width: 1.2; stroke-linejoin: miter"/>
</g>
<g id="text_4">
<!-- Geom -->
<g transform="translate(565.2 40.431546) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-47" d="M 3809 666
L 3809 1919
L 2778 1919
L 2778 2438
L 4434 2438
L 4434 434
Q 4069 175 3628 42
Q 3188 -91 2688 -91
Q 1594 -91 976 548
Q 359 1188 359 2328
Q 359 3472 976 4111
Q 1594 4750 2688 4750
Q 3144 4750 3555 4637
Q 3966 4525 4313 4306
L 4313 3634
Q 3963 3931 3569 4081
Q 3175 4231 2741 4231
Q 1884 4231 1454 3753
Q 1025 3275 1025 2328
Q 1025 1384 1454 906
Q 1884 428 2741 428
Q 3075 428 3337 486
Q 3600 544 3809 666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-6d" d="M 3328 2828
Q 3544 3216 3844 3400
Q 4144 3584 4550 3584
Q 5097 3584 5394 3201
Q 5691 2819 5691 2113
L 5691 0
L 5113 0
L 5113 2094
Q 5113 2597 4934 2840
Q 4756 3084 4391 3084
Q 3944 3084 3684 2787
Q 3425 2491 3425 1978
L 3425 0
L 2847 0
L 2847 2094
Q 2847 2600 2669 2842
Q 2491 3084 2119 3084
Q 1678 3084 1418 2786
Q 1159 2488 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1356 3278 1631 3431
Q 1906 3584 2284 3584
Q 2666 3584 2933 3390
Q 3200 3197 3328 2828
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-47"/>
<use xlink:href="#DejaVuSans-65" transform="translate(77.490234 0)"/>
<use xlink:href="#DejaVuSans-6f" transform="translate(139.013672 0)"/>
<use xlink:href="#DejaVuSans-6d" transform="translate(200.195312 0)"/>
</g>
</g>
<g id="text_5">
<!-- Margin -->
<g transform="translate(565.2 69.799967) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-4d" d="M 628 4666
L 1569 4666
L 2759 1491
L 3956 4666
L 4897 4666
L 4897 0
L 4281 0
L 4281 4097
L 3078 897
L 2444 897
L 1241 4097
L 1241 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-4d"/>
<use xlink:href="#DejaVuSans-61" transform="translate(86.279297 0)"/>
<use xlink:href="#DejaVuSans-72" transform="translate(147.558594 0)"/>
<use xlink:href="#DejaVuSans-67" transform="translate(186.921875 0)"/>
<use xlink:href="#DejaVuSans-69" transform="translate(250.398438 0)"/>
<use xlink:href="#DejaVuSans-6e" transform="translate(278.181641 0)"/>
</g>
</g>
<g id="text_6">
<!-- Gap -->
<g transform="translate(565.2 99.168388) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-70" d="M 1159 525
L 1159 -1331
L 581 -1331
L 581 3500
L 1159 3500
L 1159 2969
Q 1341 3281 1617 3432
Q 1894 3584 2278 3584
Q 2916 3584 3314 3078
Q 3713 2572 3713 1747
Q 3713 922 3314 415
Q 2916 -91 2278 -91
Q 1894 -91 1617 61
Q 1341 213 1159 525
z
M 3116 1747
Q 3116 2381 2855 2742
Q 2594 3103 2138 3103
Q 1681 3103 1420 2742
Q 1159 2381 1159 1747
Q 1159 1113 1420 752
Q 1681 391 2138 391
Q 2594 391 2855 752
Q 3116 1113 3116 1747
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-47"/>
<use xlink:href="#DejaVuSans-61" transform="translate(77.490234 0)"/>
<use xlink:href="#DejaVuSans-70" transform="translate(138.769531 0)"/>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="p60d92c8ec7">
<rect x="7.2" y="7.2" width="669.6" height="446.4"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

+21
View File
@@ -31,3 +31,24 @@
.. |-| unicode:: U+2060
:trim:
..
Macro for icon for required element, can appear only once.
.. |!| replace:: :octicon:`star`
..
Macro for icon for optional element, can appear only once.
.. |?| replace:: :octicon:`dot`
..
Macro for icon for optional element, can appear multiple times (no icon).
.. |*| unicode:: U+200B
:trim:
..
Macro for icon for optional element that can appear recursively.
.. |@| replace:: :octicon:`sync`
+1468 -889
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More