diff --git a/.clang-format b/.clang-format
index 7606a58a..da5f07f3 100644
--- a/.clang-format
+++ b/.clang-format
@@ -5,6 +5,13 @@
# CoreUObject/Public/VerseVM/.clang-format), with ONE deliberate deviation:
#
# SortIncludes: false
+# LineEnding: LF
+#
+# Epic's config leaves the line ending to whatever the file already has, which
+# on Windows means clang-format preserves the CRLF that core.autocrlf wrote.
+# Pinning it makes the formatter normalise, so a file formatted on Windows and
+# one formatted on Linux are the same bytes. `.gitattributes` pins the same
+# thing for the repository; this is the half that runs before a commit exists.
#
# Epic ships SortIncludes: true, but those engine subsystems have no
# reflection/generated headers. URLab's UPROPERTY modules require the
@@ -62,6 +69,7 @@ IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
Language: Cpp
+LineEnding: LF
NamespaceIndentation: None
PackConstructorInitializers: CurrentLine
PointerAlignment: Left
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index 8416b890..ade140d6 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -6,3 +6,6 @@
# style: adopt Epic clang-format + codegen format-step + repo reformat
1a57be12debd08eb60a2db0a5503b0a64c8ad678
+
+# style: reformat hand-written sources and pin line endings to LF
+3381d8597bbb3106d826d6ffb369a82fce531ffb
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..f7edfed4
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,35 @@
+# Line endings are LF in the repository and LF on checkout, on every platform.
+#
+# Without this, `core.autocrlf=true` (the Windows default) commits CRLF, and a
+# file touched on Windows shows up as changed in its entirety on Linux and in
+# review. Pinning it here rather than asking every contributor to configure
+# their client is what keeps that out of the history.
+* text=auto eol=lf
+
+# Binary, and never to be sniffed for it. Content sniffing gets these right
+# today; saying so outright means it cannot get them wrong after an edit that
+# happens to remove every NUL byte from a header.
+*.png binary
+*.uasset binary
+*.umap binary
+*.stl binary
+*.obj binary
+*.mjb binary
+
+# The emitted MuJoCo document profile.
+#
+# LF-pinned because the drift gate compares generated bytes: on Windows,
+# core.autocrlf would rewrite these on checkout and the next `--check` would
+# report a difference that is nothing but line endings. Marked generated so
+# review tools collapse them and language statistics ignore them.
+Source/URLab/Public/MuJoCo/Gen/** text eol=lf linguist-generated=true
+Source/URLab/Private/MuJoCo/Gen/** text eol=lf linguist-generated=true
+Source/URLabEditor/Private/Tests/MjGenCoverage.gen.cpp text eol=lf linguist-generated=true
+Scripts/regen_ue_profile.ps1 text eol=lf
+Scripts/regen_ue_profile.sh text eol=lf
+
+# Recorded models. These are compared field for field after being loaded back,
+# so any rewriting on checkout would surface as a corrupt golden rather than as
+# the line-ending change it actually was. Pinned rather than left to content
+# sniffing, because a golden is only worth what its bytes are.
+Content/TestData/goldens/*.mjb binary
diff --git a/.gitignore b/.gitignore
index 8dd8005c..f2bc7f79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,7 @@ ThirdParty
*.lo
*.o
*.obj
+!Content/TestData/**/*.obj
# Precompiled Headers
*.gch
@@ -119,6 +120,9 @@ third_party/install/
# submodule checkout itself is tracked via the submodule pointer; only the
# per-build scratch directories inside each submodule are ignored.
third_party/*/src/build/
+# Per-dep build scratch dirs that sit beside src/ rather than inside it
+# (e.g. third_party/MjShim/build/).
+third_party/*/build/
# Python cache
__pycache__/
diff --git a/.gitmodules b/.gitmodules
index 08f5c1a2..65127c63 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,5 +1,7 @@
[submodule "third_party/MuJoCo/src"]
path = third_party/MuJoCo/src
+ # Upstream MuJoCo. The engine is built from it, and the ProtoSpec generator
+ # reads src/xml/mjcf.schema and doc/generate/mjcf_schema.py from it.
url = https://github.com/google-deepmind/mujoco
[submodule "third_party/CoACD/src"]
path = third_party/CoACD/src
diff --git a/Content/Materials/M_MuJoCo_Master.uasset b/Content/Materials/M_MuJoCo_Master.uasset
index f4ee2af3..714a784c 100644
Binary files a/Content/Materials/M_MuJoCo_Master.uasset and b/Content/Materials/M_MuJoCo_Master.uasset differ
diff --git a/Content/TestData/boundary/plugins.xml b/Content/TestData/boundary/plugins.xml
new file mode 100644
index 00000000..30ec0a17
--- /dev/null
+++ b/Content/TestData/boundary/plugins.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/CAPTURE.json b/Content/TestData/goldens/CAPTURE.json
new file mode 100644
index 00000000..546d0130
--- /dev/null
+++ b/Content/TestData/goldens/CAPTURE.json
@@ -0,0 +1,6 @@
+{
+ "mujoco_version": "3.11.1",
+ "mujoco_submodule": "b6683ac13dd353c8d66788a3beea6e84b2eb2dc2",
+ "captured_commit": "8028138e0e5f68fafd2b9b53ff958ad29cb27195",
+ "captured_utc": "2026-08-09"
+}
diff --git a/Content/TestData/goldens/actuators_all.parity.mjb b/Content/TestData/goldens/actuators_all.parity.mjb
new file mode 100644
index 00000000..fee7f6bb
Binary files /dev/null and b/Content/TestData/goldens/actuators_all.parity.mjb differ
diff --git a/Content/TestData/goldens/actuators_all.roundtrip.xml b/Content/TestData/goldens/actuators_all.roundtrip.xml
new file mode 100644
index 00000000..1f8ad48d
--- /dev/null
+++ b/Content/TestData/goldens/actuators_all.roundtrip.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/angle_degrees.parity.mjb b/Content/TestData/goldens/angle_degrees.parity.mjb
new file mode 100644
index 00000000..da79c8fc
Binary files /dev/null and b/Content/TestData/goldens/angle_degrees.parity.mjb differ
diff --git a/Content/TestData/goldens/angle_degrees.roundtrip.xml b/Content/TestData/goldens/angle_degrees.roundtrip.xml
new file mode 100644
index 00000000..8b9cdfd5
--- /dev/null
+++ b/Content/TestData/goldens/angle_degrees.roundtrip.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/assets_meshes.parity.mjb b/Content/TestData/goldens/assets_meshes.parity.mjb
new file mode 100644
index 00000000..0ff61f06
Binary files /dev/null and b/Content/TestData/goldens/assets_meshes.parity.mjb differ
diff --git a/Content/TestData/goldens/assets_meshes.roundtrip.xml b/Content/TestData/goldens/assets_meshes.roundtrip.xml
new file mode 100644
index 00000000..21295176
--- /dev/null
+++ b/Content/TestData/goldens/assets_meshes.roundtrip.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/assets_meshes.scene2.parity.mjb b/Content/TestData/goldens/assets_meshes.scene2.parity.mjb
new file mode 100644
index 00000000..70b8fc8d
Binary files /dev/null and b/Content/TestData/goldens/assets_meshes.scene2.parity.mjb differ
diff --git a/Content/TestData/goldens/defaults_nested.parity.mjb b/Content/TestData/goldens/defaults_nested.parity.mjb
new file mode 100644
index 00000000..b0521689
Binary files /dev/null and b/Content/TestData/goldens/defaults_nested.parity.mjb differ
diff --git a/Content/TestData/goldens/defaults_nested.roundtrip.xml b/Content/TestData/goldens/defaults_nested.roundtrip.xml
new file mode 100644
index 00000000..2d4e3d2f
--- /dev/null
+++ b/Content/TestData/goldens/defaults_nested.roundtrip.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/keyframes_options.parity.mjb b/Content/TestData/goldens/keyframes_options.parity.mjb
new file mode 100644
index 00000000..f80294fb
Binary files /dev/null and b/Content/TestData/goldens/keyframes_options.parity.mjb differ
diff --git a/Content/TestData/goldens/keyframes_options.roundtrip.xml b/Content/TestData/goldens/keyframes_options.roundtrip.xml
new file mode 100644
index 00000000..d9ed125f
--- /dev/null
+++ b/Content/TestData/goldens/keyframes_options.roundtrip.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/macro_composite.parity.mjb b/Content/TestData/goldens/macro_composite.parity.mjb
new file mode 100644
index 00000000..4b931d03
Binary files /dev/null and b/Content/TestData/goldens/macro_composite.parity.mjb differ
diff --git a/Content/TestData/goldens/macro_composite.roundtrip.xml b/Content/TestData/goldens/macro_composite.roundtrip.xml
new file mode 100644
index 00000000..eec657c6
--- /dev/null
+++ b/Content/TestData/goldens/macro_composite.roundtrip.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/macro_flexcomp.parity.mjb b/Content/TestData/goldens/macro_flexcomp.parity.mjb
new file mode 100644
index 00000000..fd1d1ef3
Binary files /dev/null and b/Content/TestData/goldens/macro_flexcomp.parity.mjb differ
diff --git a/Content/TestData/goldens/macro_flexcomp.roundtrip.xml b/Content/TestData/goldens/macro_flexcomp.roundtrip.xml
new file mode 100644
index 00000000..87cc4b4d
--- /dev/null
+++ b/Content/TestData/goldens/macro_flexcomp.roundtrip.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/macro_replicate.parity.mjb b/Content/TestData/goldens/macro_replicate.parity.mjb
new file mode 100644
index 00000000..c9c22772
Binary files /dev/null and b/Content/TestData/goldens/macro_replicate.parity.mjb differ
diff --git a/Content/TestData/goldens/macro_replicate.roundtrip.xml b/Content/TestData/goldens/macro_replicate.roundtrip.xml
new file mode 100644
index 00000000..c9077af9
--- /dev/null
+++ b/Content/TestData/goldens/macro_replicate.roundtrip.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/plugins.roundtrip.xml b/Content/TestData/goldens/plugins.roundtrip.xml
new file mode 100644
index 00000000..66375188
--- /dev/null
+++ b/Content/TestData/goldens/plugins.roundtrip.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/tendons_equality_sensors.parity.mjb b/Content/TestData/goldens/tendons_equality_sensors.parity.mjb
new file mode 100644
index 00000000..d54d911b
Binary files /dev/null and b/Content/TestData/goldens/tendons_equality_sensors.parity.mjb differ
diff --git a/Content/TestData/goldens/tendons_equality_sensors.roundtrip.xml b/Content/TestData/goldens/tendons_equality_sensors.roundtrip.xml
new file mode 100644
index 00000000..05db83d3
--- /dev/null
+++ b/Content/TestData/goldens/tendons_equality_sensors.roundtrip.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/goldens/vx300s.parity.mjb b/Content/TestData/goldens/vx300s.parity.mjb
new file mode 100644
index 00000000..d395fa1c
Binary files /dev/null and b/Content/TestData/goldens/vx300s.parity.mjb differ
diff --git a/Content/TestData/goldens/vx300s.roundtrip.xml b/Content/TestData/goldens/vx300s.roundtrip.xml
new file mode 100644
index 00000000..2a5a3721
--- /dev/null
+++ b/Content/TestData/goldens/vx300s.roundtrip.xml
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/humanoid.xml b/Content/TestData/humanoid.xml
new file mode 100644
index 00000000..a2c4a16f
--- /dev/null
+++ b/Content/TestData/humanoid.xml
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/actuators_all.xml b/Content/TestData/parity/actuators_all.xml
new file mode 100644
index 00000000..310cabfa
--- /dev/null
+++ b/Content/TestData/parity/actuators_all.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/angle_degrees.xml b/Content/TestData/parity/angle_degrees.xml
new file mode 100644
index 00000000..dcdb3808
--- /dev/null
+++ b/Content/TestData/parity/angle_degrees.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/assets_meshes.xml b/Content/TestData/parity/assets_meshes.xml
new file mode 100644
index 00000000..d58e107e
--- /dev/null
+++ b/Content/TestData/parity/assets_meshes.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/checker.png b/Content/TestData/parity/checker.png
new file mode 100644
index 00000000..60912e1b
Binary files /dev/null and b/Content/TestData/parity/checker.png differ
diff --git a/Content/TestData/parity/defaults_nested.xml b/Content/TestData/parity/defaults_nested.xml
new file mode 100644
index 00000000..bb0a279d
--- /dev/null
+++ b/Content/TestData/parity/defaults_nested.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/keyframes_options.xml b/Content/TestData/parity/keyframes_options.xml
new file mode 100644
index 00000000..e0e17482
--- /dev/null
+++ b/Content/TestData/parity/keyframes_options.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/macro_composite.xml b/Content/TestData/parity/macro_composite.xml
new file mode 100644
index 00000000..1586830a
--- /dev/null
+++ b/Content/TestData/parity/macro_composite.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/macro_flexcomp.xml b/Content/TestData/parity/macro_flexcomp.xml
new file mode 100644
index 00000000..41bd13c8
--- /dev/null
+++ b/Content/TestData/parity/macro_flexcomp.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/macro_replicate.xml b/Content/TestData/parity/macro_replicate.xml
new file mode 100644
index 00000000..89a7f536
--- /dev/null
+++ b/Content/TestData/parity/macro_replicate.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/meshA/base.obj b/Content/TestData/parity/meshA/base.obj
new file mode 100644
index 00000000..9cfdae89
--- /dev/null
+++ b/Content/TestData/parity/meshA/base.obj
@@ -0,0 +1,8 @@
+v 0 0 0
+v 0.2 0 0
+v 0.1 0.2 0
+v 0.1 0.07 0.2
+f 1 3 2
+f 1 2 4
+f 2 3 4
+f 3 1 4
diff --git a/Content/TestData/parity/meshB/base.obj b/Content/TestData/parity/meshB/base.obj
new file mode 100644
index 00000000..bc09bfca
--- /dev/null
+++ b/Content/TestData/parity/meshB/base.obj
@@ -0,0 +1,20 @@
+v 0 0 0
+v 0.3 0 0
+v 0.3 0.3 0
+v 0 0.3 0
+v 0 0 0.3
+v 0.3 0 0.3
+v 0.3 0.3 0.3
+v 0 0.3 0.3
+f 1 4 3
+f 1 3 2
+f 5 6 7
+f 5 7 8
+f 1 2 6
+f 1 6 5
+f 2 3 7
+f 2 7 6
+f 3 4 8
+f 3 8 7
+f 4 1 5
+f 4 5 8
diff --git a/Content/TestData/parity/tendons_equality_sensors.xml b/Content/TestData/parity/tendons_equality_sensors.xml
new file mode 100644
index 00000000..6066fe86
--- /dev/null
+++ b/Content/TestData/parity/tendons_equality_sensors.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/parity/trossen_vx300s/LICENSE b/Content/TestData/parity/trossen_vx300s/LICENSE
new file mode 100644
index 00000000..8df4a42c
--- /dev/null
+++ b/Content/TestData/parity/trossen_vx300s/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2023, Trossen Robotics
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Content/TestData/parity/trossen_vx300s/assets/interbotix_black.png b/Content/TestData/parity/trossen_vx300s/assets/interbotix_black.png
new file mode 100644
index 00000000..e7443eb5
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/interbotix_black.png differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_10_gripper_finger.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_10_gripper_finger.stl
new file mode 100644
index 00000000..d6df86be
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_10_gripper_finger.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_1_base.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_1_base.stl
new file mode 100644
index 00000000..5a7efda2
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_1_base.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_2_shoulder.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_2_shoulder.stl
new file mode 100644
index 00000000..dc22aa7e
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_2_shoulder.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_3_upper_arm.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_3_upper_arm.stl
new file mode 100644
index 00000000..111c586e
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_3_upper_arm.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_4_upper_forearm.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_4_upper_forearm.stl
new file mode 100644
index 00000000..8170d21c
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_4_upper_forearm.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_5_lower_forearm.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_5_lower_forearm.stl
new file mode 100644
index 00000000..39581f83
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_5_lower_forearm.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_6_wrist.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_6_wrist.stl
new file mode 100644
index 00000000..ab8423e9
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_6_wrist.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_7_gripper.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_7_gripper.stl
new file mode 100644
index 00000000..043db9ca
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_7_gripper.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_8_gripper_prop.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_8_gripper_prop.stl
new file mode 100644
index 00000000..36099b42
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_8_gripper_prop.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/assets/vx300s_9_gripper_bar.stl b/Content/TestData/parity/trossen_vx300s/assets/vx300s_9_gripper_bar.stl
new file mode 100644
index 00000000..eba3caa2
Binary files /dev/null and b/Content/TestData/parity/trossen_vx300s/assets/vx300s_9_gripper_bar.stl differ
diff --git a/Content/TestData/parity/trossen_vx300s/vx300s.xml b/Content/TestData/parity/trossen_vx300s/vx300s.xml
new file mode 100644
index 00000000..1f9a9064
--- /dev/null
+++ b/Content/TestData/parity/trossen_vx300s/vx300s.xml
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/ros_maps_test.xml b/Content/TestData/ros_maps_test.xml
new file mode 100644
index 00000000..9d81ea2f
--- /dev/null
+++ b/Content/TestData/ros_maps_test.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/TestData/ros_maps_test_ue.xml b/Content/TestData/ros_maps_test_ue.xml
new file mode 100644
index 00000000..cbe95a4a
--- /dev/null
+++ b/Content/TestData/ros_maps_test_ue.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 9b425d53..c2c99a94 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,27 @@

+> ## ⚠️ Beta: this release breaks existing MjArticulation assets
+>
+> `main` is now the **beta**. The component model changed: components no longer
+> mirror the MuJoCo model, they **are** the model, and every element is
+> generated from MuJoCo's own `mjcf.schema`.
+>
+> **Updating the plugin will break MjArticulations you already have.** Their
+> components are the previous generation's classes, and nothing migrates them.
+> Expect to re-import your MJCF rather than to open an existing Blueprint. Back
+> up your project first.
+>
+> **If you are not ready for that, stay on the `alpha` branch**, which is the
+> final pre-beta state and is not going to move under you:
+>
+> ```
+> git checkout alpha # or the v0.5.0-alpha tag, which is frozen
+> ```
+>
+> Re-importing gets you a model that compiles to exactly what stock MuJoCo's
+> own `mj_loadXML` produces, which the previous generation could not promise.
+
UnrealRoboticsLab (URLab) is an Unreal Engine 5 plugin that embeds the
[MuJoCo](https://github.com/google-deepmind/mujoco) physics engine directly into
the editor and runtime. You simulate robots with MuJoCo's accurate contact
@@ -87,7 +108,8 @@ ROS 2 bridging.
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md), and the
[Contributing docs](https://urlab-sim.github.io/UnrealRoboticsLab/contributing/building/)
-for building from source, the codegen, and bumping MuJoCo. Since Unreal projects
+for building from source, regenerating the MuJoCo profile, and bumping
+MuJoCo. Since Unreal projects
cannot use standard CI, each PR should include proof of a local build and passing
tests.
diff --git a/Scripts/build_and_test.ps1 b/Scripts/build_and_test.ps1
index d2d139fc..0ffd7c77 100644
--- a/Scripts/build_and_test.ps1
+++ b/Scripts/build_and_test.ps1
@@ -39,7 +39,7 @@
-Target CustomEditorTargetName
.NOTES
- Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args.
+ Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args, 4 generated-profile drift.
#>
[CmdletBinding()]
@@ -48,7 +48,10 @@ param(
[Parameter(Mandatory = $true)] [string] $Project,
[string] $Target = '',
[string] $Filter = 'URLab',
- [string] $Log = (Join-Path $env:TEMP 'urlab_test.log')
+ # Unique per run. Two runs sharing one path collide on the file lock: the
+ # loser dies outright, and the winner can be left with a truncated or empty
+ # log, which greps to zero failures and reads exactly like a clean pass.
+ [string] $Log = (Join-Path $env:TEMP ('urlab_test_{0}_{1}.log' -f (Get-Date -Format 'yyyyMMdd-HHmmss'), $PID))
)
$ErrorActionPreference = 'Stop'
@@ -66,19 +69,27 @@ $cmd = Join-Path $Engine 'Engine\Binaries\Win64\UnrealEditor-Cmd.exe'
if (-not (Test-Path $bat)) { Write-Error "Build.bat not found: $bat"; exit 3 }
if (-not (Test-Path $cmd)) { Write-Error "UnrealEditor-Cmd not found: $cmd"; exit 3 }
-# --- Codegen drift gate ----------------------------------------------------
-# Refuse to build if codegen output drifted from the committed Source/, or
-# if any drift diagnostic (--strict) fires, or if the clang-AST introspect
-# snapshot is missing (--require-introspect). Skipped silently when Python
-# isn't on PATH — the gate is best-effort locally; CI enforces it strictly.
+# --- Generated-profile drift gate ------------------------------------------
+# Refuse to build if the emitted MuJoCo document profile drifted from what the
+# schema now says. The gate needs the generator and `uv`; when either is absent
+# it cannot run, and it says so rather than passing quietly. A skipped gate and
+# a passing gate are the same exit code, so silence here reads as a green gate
+# in every log and every CI summary that only checks the code.
$pluginRoot = Split-Path -Parent $PSScriptRoot
-$generator = Join-Path $pluginRoot 'Scripts/codegen/generate_ue_components.py'
-$py = (Get-Command python -ErrorAction SilentlyContinue)
-if ($py -and (Test-Path $generator)) {
- Write-Host '>>> Codegen drift gate: python generate_ue_components.py --check --strict --require-introspect'
- & $py.Source $generator --check --strict --require-introspect
+$regen = Join-Path $pluginRoot 'Scripts/regen_ue_profile.ps1'
+$protospec = Join-Path $pluginRoot 'protospec/protospec_gen'
+$gateMissing = @()
+if (-not (Test-Path $regen)) { $gateMissing += "no $regen" }
+if (-not (Test-Path $protospec)) { $gateMissing += "no ProtoSpec generator at $protospec" }
+if (-not (Get-Command uv -ErrorAction SilentlyContinue)) { $gateMissing += 'uv is not on PATH' }
+
+if ($gateMissing.Count -gt 0) {
+ Write-Warning ("Profile drift gate SKIPPED ({0}). The generated MuJoCo profile is NOT checked in this run." -f ($gateMissing -join '; '))
+} else {
+ Write-Host '>>> Profile drift gate: regen_ue_profile.ps1 -Check'
+ & $regen -Check
if ($LASTEXITCODE -ne 0) {
- Write-Error "Codegen drift detected (exit $LASTEXITCODE). Re-run 'python Scripts/codegen/generate_ue_components.py' to regenerate, then re-run this script."
+ Write-Error "Generated profile drift detected (exit $LASTEXITCODE). Re-run 'Scripts/regen_ue_profile.ps1', then re-run this script."
exit 4
}
}
@@ -95,7 +106,21 @@ Write-Host ">>> Building $Target (Win64 Development)..."
# Result: Failed (ActionGraphInvalid). Just the positional target is enough.
$buildArgs = @($Target, 'Win64', 'Development', "-Project=$Project", '-Progress')
$buildOut = & $bat @buildArgs 2>&1
-$buildOut | Select-Object -Last 10 | ForEach-Object { Write-Host $_ }
+
+# The whole build output goes to a file, and what reaches the console is the
+# diagnostics rather than the last ten lines. A failing build is explained by
+# its FIRST error; the tail is whatever the toolchain happened to say
+# afterwards, which on a large generated translation unit is usually a summary
+# that names no file at all.
+$buildLog = "$Log.build.txt"
+$buildOut | Out-File -FilePath $buildLog -Encoding utf8
+$diagnostics = $buildOut | Select-String -Pattern 'error [A-Z]+[0-9]+|error:|fatal error|Result: '
+if ($diagnostics) {
+ $diagnostics | Select-Object -First 40 | ForEach-Object { Write-Host $_ }
+} else {
+ $buildOut | Select-Object -Last 10 | ForEach-Object { Write-Host $_ }
+}
+Write-Host ">>> Full build output: $buildLog"
$buildStatus = if ($buildOut -match 'Result: Succeeded') { 'Succeeded' } else { 'Failed' }
# --- Test ------------------------------------------------------------------
@@ -132,10 +157,15 @@ if ($buildStatus -eq 'Succeeded') {
# runs. The SHA-256 of the log is sufficient for reviewers to verify content
# integrity when they re-run the suite themselves (#37).
$ts = (Get-Date).ToUniversalTime().ToString('yyyy-MM-dd HH:mm:ss') + ' UTC'
-try {
- $gitSha = (git rev-parse --short=8 HEAD 2>$null).Trim()
- $gitBranch = (git rev-parse --abbrev-ref HEAD 2>$null).Trim()
-} catch { $gitSha = 'unknown'; $gitBranch = 'unknown' }
+# Asked of the PLUGIN repository explicitly, not of whatever directory the
+# script happened to be invoked from. The SHA in this block is what ties a gate
+# result to a commit in the record, so it must not depend on the caller's
+# working directory: run from the host project root, a bare `git rev-parse`
+# answers for the wrong repository or for none.
+$gitSha = (git -C $PSScriptRoot rev-parse --short=8 HEAD 2>$null)
+$gitBranch = (git -C $PSScriptRoot rev-parse --abbrev-ref HEAD 2>$null)
+if (-not $gitSha) { $gitSha = 'unknown' } else { $gitSha = $gitSha.Trim() }
+if (-not $gitBranch) { $gitBranch = 'unknown' } else { $gitBranch = $gitBranch.Trim() }
# Strip the engine path down to its last segment (e.g. 'UE_5.7'). The full
# path can contain the user's install root on a non-standard layout.
diff --git a/Scripts/build_and_test.sh b/Scripts/build_and_test.sh
index 8cd8f60d..d8b968d2 100644
--- a/Scripts/build_and_test.sh
+++ b/Scripts/build_and_test.sh
@@ -36,13 +36,16 @@
# --target defaults to Editor derived from the .uproject filename.
# Only override for projects that don't follow UE's naming convention.
#
-# Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args.
+# Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args, 4 generated-profile drift.
set -eu
TARGET=""
FILTER="URLab"
-LOG="/tmp/urlab_test.log"
+# Unique per run. Two runs sharing one path collide on the file lock: the loser
+# dies outright, and the winner can be left with a truncated or empty log, which
+# greps to zero failures and reads exactly like a clean pass.
+LOG="/tmp/urlab_test_$(date +%Y%m%d-%H%M%S)_$$.log"
ENGINE=""
PROJECT=""
@@ -60,7 +63,7 @@ Usage:
--target defaults to Editor derived from the .uproject filename.
-Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args.
+Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args, 4 generated-profile drift.
HELP
exit 3
}
@@ -94,6 +97,32 @@ CMD="$ENGINE/Engine/Binaries/Win64/UnrealEditor-Cmd.exe"
[[ -f "$BAT" ]] || { echo "Build.bat not found: $BAT" >&2; exit 3; }
[[ -x "$CMD" ]] || { echo "UnrealEditor-Cmd not found: $CMD" >&2; exit 3; }
+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+PLUGIN_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
+
+# --- Generated-profile drift gate ------------------------------------------
+# Refuse to build if the emitted MuJoCo document profile drifted from what the
+# schema now says. The gate needs the generator and `uv`; when either is absent
+# it cannot run, and it says so rather than passing quietly. A skipped gate and
+# a passing gate are the same exit code, so silence here reads as a green gate
+# in every log and every CI summary that only checks the code.
+REGEN="$PLUGIN_ROOT/Scripts/regen_ue_profile.sh"
+PROTOSPEC_GEN="$PLUGIN_ROOT/protospec/protospec_gen"
+GATE_MISSING=""
+[[ -f "$REGEN" ]] || GATE_MISSING="no $REGEN"
+[[ -d "$PROTOSPEC_GEN" ]] || GATE_MISSING="${GATE_MISSING:+$GATE_MISSING; }no ProtoSpec generator at $PROTOSPEC_GEN"
+command -v uv >/dev/null 2>&1 || GATE_MISSING="${GATE_MISSING:+$GATE_MISSING; }uv is not on PATH"
+
+if [[ -n "$GATE_MISSING" ]]; then
+ echo "WARNING: profile drift gate SKIPPED ($GATE_MISSING). The generated MuJoCo profile is NOT checked in this run." >&2
+else
+ echo ">>> Profile drift gate: regen_ue_profile.sh --check"
+ if ! bash "$REGEN" --check; then
+ echo "ERROR: generated profile drift detected. Re-run 'Scripts/regen_ue_profile.sh', then re-run this script." >&2
+ exit 4
+ fi
+fi
+
# Truncate the test log up-front so a build failure (or any early exit
# before UnrealEditor-Cmd writes to it) doesn't leave the SHA-256 in the
# summary pointing at a previous run's file.
@@ -105,7 +134,20 @@ echo ">>> Building $TARGET (Win64 Development)..."
# target name it makes UBT's two action-graph passes ambiguous and bails with
# Result: Failed (ActionGraphInvalid). Just the positional target is enough.
BUILD_OUT=$("$BAT" "$TARGET" Win64 Development "-Project=$PROJECT" -Progress 2>&1 || true)
-echo "$BUILD_OUT" | tail -10
+
+# The whole build output goes to a file, and what reaches the console is the
+# diagnostics rather than the last ten lines. A failing build is explained by
+# its FIRST error; the tail is whatever the toolchain happened to say
+# afterwards, which on a large generated translation unit is usually a summary
+# that names no file at all.
+BUILD_LOG="$LOG.build.txt"
+printf '%s\n' "$BUILD_OUT" > "$BUILD_LOG"
+if printf '%s\n' "$BUILD_OUT" | grep -qE 'error [A-Z]+[0-9]+|error:|fatal error'; then
+ printf '%s\n' "$BUILD_OUT" | grep -E 'error [A-Z]+[0-9]+|error:|fatal error|Result: ' | head -40
+else
+ printf '%s\n' "$BUILD_OUT" | tail -10
+fi
+echo ">>> Full build output: $BUILD_LOG"
if echo "$BUILD_OUT" | grep -q "Result: Succeeded"; then
BUILD_STATUS="Succeeded"
else
@@ -142,8 +184,13 @@ fi
# The SHA-256 of the log is sufficient for reviewers to verify content
# integrity when they re-run the suite themselves (#37).
TS=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
-GIT_SHA=$(git rev-parse --short=8 HEAD 2>/dev/null || echo "unknown")
-GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
+# Asked of the PLUGIN repository explicitly, not of whatever directory the
+# script happened to be invoked from. The SHA in this block is what ties a gate
+# result to a commit in the record, so it must not depend on the caller's
+# working directory: run from the host project root, a bare `git rev-parse`
+# answers for the wrong repository or for none.
+GIT_SHA=$(git -C "$SCRIPT_DIR" rev-parse --short=8 HEAD 2>/dev/null || echo "unknown")
+GIT_BRANCH=$(git -C "$SCRIPT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
# Strip the engine path down to its last segment (e.g. 'UE_5.7'). The full
# path can contain the user's install root on a non-standard layout.
@@ -153,8 +200,6 @@ ENGINE_LABEL=$(basename "$ENGINE")
# Third-party dep SHAs from third_party/install//INSTALLED_SHA.txt
# (written by the CMake build scripts). Lets a reviewer verify they're
# comparing against the same binary toolchain. Silent skip if missing.
-SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
-PLUGIN_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
DEPS_LINE=""
for pair in "mj:MuJoCo" "coacd:CoACD" "zmq:libzmq"; do
key="${pair%%:*}"
diff --git a/Scripts/build_and_test_linux.sh b/Scripts/build_and_test_linux.sh
index 496ff029..fddb1f9b 100755
--- a/Scripts/build_and_test_linux.sh
+++ b/Scripts/build_and_test_linux.sh
@@ -40,7 +40,7 @@
# --target defaults to Editor derived from the .uproject filename.
# Only override for projects that don't follow UE's naming convention.
#
-# Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args.
+# Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args, 4 generated-profile drift.
set -eu
@@ -64,7 +64,7 @@ Usage:
--target defaults to Editor derived from the .uproject filename.
-Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args.
+Exit codes: 0 ok, 1 build failed, 2 tests failed, 3 bad args, 4 generated-profile drift.
HELP
exit 3
}
@@ -106,6 +106,24 @@ if pgrep -fa "/UnrealEditor( |$)" >/dev/null 2>&1; then
exit 3
fi
+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+PLUGIN_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
+
+# --- Generated-profile drift gate ------------------------------------------
+# Refuse to build if the emitted MuJoCo document profile drifted from what the
+# schema now says. The generator ships inside the MuJoCo submodule, so this is
+# skipped when the submodule is not checked out: the gate is best-effort
+# locally and enforced in CI.
+REGEN="$PLUGIN_ROOT/Scripts/regen_ue_profile.sh"
+PROTOSPEC_GEN="$PLUGIN_ROOT/protospec/protospec_gen"
+if [[ -f "$REGEN" && -d "$PROTOSPEC_GEN" ]] && command -v uv >/dev/null 2>&1; then
+ echo ">>> Profile drift gate: regen_ue_profile.sh --check"
+ if ! bash "$REGEN" --check; then
+ echo "ERROR: generated profile drift detected. Re-run 'Scripts/regen_ue_profile.sh', then re-run this script." >&2
+ exit 4
+ fi
+fi
+
: > "$LOG"
# --- Build -----------------------------------------------------------------
diff --git a/Scripts/clean_meshes.py b/Scripts/clean_meshes.py
index 33d7c0da..9ac1e693 100644
--- a/Scripts/clean_meshes.py
+++ b/Scripts/clean_meshes.py
@@ -31,22 +31,196 @@
pip install trimesh numpy scipy Pillow networkx
Usage:
- python clean_meshes_trimesh.py
+ python clean_meshes.py [--out-dir DIR] [--allow-external-includes]
+
+Without --out-dir the prepared XML is written beside the input. With it, the
+prepared XML goes to DIR and every asset path inside is re-expressed so it
+still resolves from there, which is how Unreal keeps its prepared copy out of
+the model author's own folders.
+
+ fragments are flattened into one document on the way through, and an
+include whose target is outside the model's own folder is REFUSED unless
+--allow-external-includes is passed. That is the same boundary the Unreal
+reader enforces, asked here because this step runs first: a prepared import
+whose includes were followed by this script would otherwise have its security
+answer decided by a script nobody asked.
+
+Exit status is 0 only when every referenced mesh was prepared. A conversion
+that failed, a source file that was missing, a refused include, or an
+unreadable document exits nonzero with the reason on stderr, because a caller
+that continued anyway would import the unprepared meshes at the wrong scale
+without saying so.
Example:
- python clean_meshes_trimesh.py "path/to/mujoco_menagerie/franka_emika_panda/panda.xml"
+ python clean_meshes.py "path/to/mujoco_menagerie/franka_emika_panda/panda.xml"
"""
import trimesh
import numpy as np
from pathlib import Path
from xml.etree import ElementTree as ET
+import argparse
import os
import sys
import copy
-def clean_mesh(mesh):
+# MuJoCo's own crease threshold: a face whose normal is more than acos(0.8)
+# ~= 36.9 degrees off the vertex normal is not part of that vertex's smooth
+# group (mjCMesh::MakeNormal, src/user/user_mesh.cc). Reused here so the
+# decision about what counts as an edge matches the simulator, even though the
+# representation below is sharper than MuJoCo's own.
+CREASE_DOT = 0.8
+
+
+def split_normals_by_crease(mesh, dot_threshold: float = CREASE_DOT):
+ """Split `mesh`'s vertices into smooth groups, so hard edges shade hard.
+
+ The split is geometric rather than a normal override: a vertex whose faces
+ disagree by more than the threshold is duplicated, once per group of faces
+ that agree. Averaging then happens within a group and never across one, so
+ a box corner stays sharp while a finely tessellated cylinder stays round.
+
+ Done this way on purpose. Assigning `mesh.vertex_normals` directly does hold
+ in memory, but trimesh recomputes normals during GLB export and the override
+ is silently lost -- which looks like a crease split right up until you read
+ the accessor back.
+
+ MuJoCo cannot express this at all: it keeps one normal per vertex and merely
+ subtracts the outlying contributions, so its corners are a compromise. The
+ threshold is still MuJoCo's, so the decision about what counts as an edge
+ matches the simulator even though the representation is sharper.
+ """
+ faces = mesh.faces
+ verts = mesh.vertices
+ raw = np.cross(verts[faces[:, 1]] - verts[faces[:, 0]],
+ verts[faces[:, 2]] - verts[faces[:, 0]])
+ unit = raw / np.maximum(np.linalg.norm(raw, axis=1)[:, None], 1e-20)
+
+ # Faces meeting at each vertex.
+ incident = [[] for _ in range(len(verts))]
+ for fi, tri in enumerate(faces):
+ for vi in tri:
+ incident[vi].append(fi)
+
+ new_verts = []
+ # (vertex, face) -> index into new_verts
+ remap = {}
+ for vi, face_ids in enumerate(incident):
+ if not face_ids:
+ continue
+ # Greedy clustering: a face joins the first group whose running mean it
+ # agrees with, otherwise it starts one. Enough for the shapes a mesh
+ # asset actually has, and it never merges across a real edge.
+ groups = [] # list of [summed_normal, [face ids]]
+ for fi in face_ids:
+ n = unit[fi]
+ for g in groups:
+ mean = g[0] / max(np.linalg.norm(g[0]), 1e-20)
+ if float(np.dot(n, mean)) >= dot_threshold:
+ g[0] = g[0] + n
+ g[1].append(fi)
+ break
+ else:
+ groups.append([n.copy(), [fi]])
+ for g in groups:
+ index = len(new_verts)
+ new_verts.append(verts[vi])
+ for fi in g[1]:
+ remap[(vi, fi)] = index
+
+ new_faces = np.empty_like(faces)
+ for fi, tri in enumerate(faces):
+ for corner, vi in enumerate(tri):
+ new_faces[fi, corner] = remap[(vi, fi)]
+
+ # No custom normals: trimesh's own area-weighted average over the split
+ # geometry is the crease result, and it survives export because nothing
+ # had to be overridden.
+ return trimesh.Trimesh(vertices=np.asarray(new_verts), faces=new_faces,
+ process=False)
+
+
+def collision_mesh_names(root):
+ """Mesh names any COLLIDING geom uses, resolved through the class chain.
+
+ Splitting a vertex so a hard edge shades hard duplicates it. That is what a
+ renderer wants and it is invisible to the physics -- no vertex moves, so the
+ shape and its convex hull are unchanged -- but it does change `nmeshvert`,
+ and a collision mesh has no shading to improve. So the split is confined to
+ meshes only visual geoms use, and everything else is left exactly as MuJoCo
+ would have loaded it.
+
+ Whether a geom collides is `contype`/`conaffinity`, both 1 unless something
+ says otherwise, and in practice a visual geom gets its zeroes from a
+ `` class rather than from the geom. So the chain has to be walked:
+ the geom's own attribute wins, then its class, then that class's parent, up
+ to `main`.
+
+ Conservative on purpose. A mesh whose class cannot be resolved counts as
+ collision, because the cost of being wrong that way is a mesh that shades a
+ little softer, and the cost the other way is a model that no longer matches
+ what MuJoCo would have compiled.
+ """
+ # class name -> (parent class name, geom attributes that class supplies)
+ classes = {}
+
+ def read_defaults(element, parent_name):
+ for default in element.findall("default"):
+ name = default.get("class")
+ if name is None:
+ # An unnamed at the top is MuJoCo's `main`.
+ name = "main" if parent_name is None else parent_name
+ geom = default.find("geom")
+ classes[name] = (parent_name, dict(geom.attrib) if geom is not None else {})
+ read_defaults(default, name)
+
+ read_defaults(root, None)
+
+ def resolve(attr, geom_class, own):
+ """`attr` for a geom in `geom_class`, its own attributes taking priority."""
+ if attr in own:
+ return own[attr]
+ seen = set()
+ name = geom_class
+ while name is not None and name not in seen:
+ seen.add(name)
+ entry = classes.get(name)
+ if entry is None:
+ return None
+ parent, attrs = entry
+ if attr in attrs:
+ return attrs[attr]
+ name = parent
+ return None
+
+ collision = set()
+
+ def walk(element, inherited_class):
+ # `childclass` applies to every descendant that does not name its own.
+ current = element.get("childclass", inherited_class)
+ for child in element:
+ if child.tag == "geom":
+ mesh = child.get("mesh")
+ if mesh:
+ geom_class = child.get("class", current)
+ contype = resolve("contype", geom_class, child.attrib)
+ conaffinity = resolve("conaffinity", geom_class, child.attrib)
+ # Unset means MuJoCo's own 1, which collides.
+ collides = (contype is None or contype.strip() != "0") or (
+ conaffinity is None or conaffinity.strip() != "0"
+ )
+ if collides:
+ collision.add(mesh)
+ walk(child, current)
+
+ for worldbody in root.findall("worldbody"):
+ walk(worldbody, None)
+
+ return collision
+
+
+def clean_mesh(mesh, source_path=None, smooth_normal=False):
"""Clean up a mesh using trimesh."""
print(f" Original: {len(mesh.vertices)} vertices, {len(mesh.faces)} faces")
@@ -71,6 +245,18 @@ def clean_mesh(mesh):
rotation_matrix = trimesh.transformations.rotation_matrix(-np.radians(90), [1, 0, 0])
mesh.apply_transform(rotation_matrix)
+ # Every mesh, not just the ones whose file states no normals. An OBJ that
+ # ships split vertices loses them here regardless: the welding above and the
+ # GLB export both collapse them, so "the file already answered this" is not
+ # a state that survives conversion. Measured on Spot, whose OBJs are flat
+ # and whose GLBs came out averaged across every corner.
+ #
+ # After the transform, never before: applying one invalidates trimesh's
+ # cached normals.
+ if not smooth_normal:
+ mesh = split_normals_by_crease(mesh)
+ print(f" Creased: {len(mesh.vertices)} vertices after splitting hard edges")
+
print(f" Cleaned: {len(mesh.vertices)} vertices, {len(mesh.faces)} faces")
return mesh
@@ -88,7 +274,7 @@ def glb_up_to_date(output_glb: Path, source_path: Path) -> bool:
return mtime > source_path.stat().st_mtime and mtime > _SCRIPT_MTIME
-def convert_mesh(input_path: Path, output_path: Path) -> bool:
+def convert_mesh(input_path: Path, output_path: Path, smooth_normal: bool = False) -> bool:
"""Convert a single mesh file to GLB."""
print(f"\n Converting: {input_path.name} -> {output_path.name}")
@@ -99,7 +285,7 @@ def convert_mesh(input_path: Path, output_path: Path) -> bool:
print(f" x Not a valid mesh: {input_path.name}")
return False
- cleaned_mesh = clean_mesh(mesh)
+ cleaned_mesh = clean_mesh(mesh, input_path, smooth_normal)
# Strip embedded materials/textures to prevent Unreal's Interchange importer
# from creating a Texture2D instead of a StaticMesh.
@@ -145,6 +331,37 @@ def _parse_floats(s: str) -> list:
_MODEL_ROOT_TAGS = ("mujoco", "mujocoinclude")
+class ExternalIncludeError(Exception):
+ """An ```` reaching outside the model's own folder.
+
+ The importer asks before following one of those, because an MJCF document
+ can be someone else's and ```` is a
+ file read the author of the scene never asked for. This preparation step
+ runs BEFORE the reader and flattens the includes itself, so it has to ask
+ the same question or the answer the user gave is decided by a script that
+ never heard it.
+ """
+
+ def __init__(self, include: str, resolved: Path, boundary: Path):
+ super().__init__(
+ f"refused resolving to {resolved}: "
+ f"outside the model's folder {boundary}. Re-run with "
+ "--allow-external-includes to allow it.")
+ self.include = include
+ self.resolved = resolved
+ self.boundary = boundary
+
+
+def _inside(path: Path, boundary: Path) -> bool:
+ """True when ``path`` is ``boundary`` or below it, symlinks resolved."""
+ try:
+ return path.resolve().is_relative_to(boundary.resolve())
+ except (OSError, ValueError):
+ # A path on another drive, or one the OS will not resolve, is outside
+ # by definition; failing closed is the whole point of the check.
+ return False
+
+
def _compiler_dirs(root) -> tuple:
"""Return (meshdir, texturedir, assetdir) declared by any directly
under ``root``. MuJoCo allows several compiler elements; later ones win for a
@@ -184,15 +401,21 @@ def _rewrite_asset_path(elem, src_dir: Path, root_dir: Path,
def _append_expanded(out_parent, elem, src_dir: Path, root_dir: Path,
- meshdir: str, texturedir: str, assetdir: str, visited: set):
+ meshdir: str, texturedir: str, assetdir: str, visited: set,
+ boundary: Path = None):
"""Copy ``elem`` into ``out_parent``, recursively expanding any
descendants in place. Handles both and include roots
- and rewrites asset file= paths to stay valid from root_dir."""
+ and rewrites asset file= paths to stay valid from root_dir.
+
+ ``boundary``, when given, is the directory tree an include may not leave;
+ one that does raises ExternalIncludeError naming it."""
if elem.tag == "include":
inc_file = elem.get("file")
if not inc_file:
return
inc_path = (src_dir / inc_file).resolve()
+ if boundary is not None and not _inside(inc_path, boundary):
+ raise ExternalIncludeError(inc_file, inc_path, boundary)
if inc_path in visited:
print(f" [include] cycle/duplicate skipped: {inc_path}")
return
@@ -205,7 +428,8 @@ def _append_expanded(out_parent, elem, src_dir: Path, root_dir: Path,
imd, itxd, iad = _compiler_dirs(inc_root)
# Splice the included root's children directly into the current parent.
for child in list(inc_root):
- _append_expanded(out_parent, child, inc_dir, root_dir, imd, itxd, iad, visited)
+ _append_expanded(out_parent, child, inc_dir, root_dir, imd, itxd, iad,
+ visited, boundary)
return
# Regular element: shallow-copy attributes, then recurse into children.
@@ -222,10 +446,11 @@ def _append_expanded(out_parent, elem, src_dir: Path, root_dir: Path,
for child in list(elem):
_append_expanded(new_elem, child, src_dir, root_dir,
- meshdir, texturedir, assetdir, visited)
+ meshdir, texturedir, assetdir, visited, boundary)
-def flatten_includes(root, root_dir: Path):
+def flatten_includes(root, src_dir: Path, root_dir: Path = None,
+ boundary: Path = None):
"""Resolve every into a single self-contained tree.
gym-aloha (and many MJCF models) split a robot across fragments
@@ -233,15 +458,39 @@ def flatten_includes(root, root_dir: Path):
Unreal's importer must see one flat document so all //body
content is visible and there is exactly one worldbody. Returns the new root
element (a ). No-op-equivalent for files without includes.
+
+ ``src_dir`` is where the document being flattened lives; ``root_dir`` is
+ where the flattened document will be written, and defaults to ``src_dir``.
+ ``boundary`` is the directory tree includes may not leave, or None to follow
+ them anywhere.
"""
+ if root_dir is None:
+ root_dir = src_dir
md, txd, ad = _compiler_dirs(root)
visited = set()
new_root = ET.Element("mujoco", dict(root.attrib))
for child in list(root):
- _append_expanded(new_root, child, root_dir, root_dir, md, txd, ad, visited)
+ _append_expanded(new_root, child, src_dir, root_dir, md, txd, ad, visited,
+ boundary)
return new_root
+def _rebase_assets(root, src_dir: Path, root_dir: Path):
+ """Re-express every asset ``file=`` so it resolves from ``root_dir``.
+
+ What ``flatten_includes`` does on the way through, for a document that has
+ no includes to flatten. The dir attributes are cleared once the
+ paths carry their own prefixes, so nothing double-prefixes them.
+ """
+ md, txd, ad = _compiler_dirs(root)
+ for elem in root.iter():
+ if elem.tag in _ASSET_FILE_TAGS:
+ _rewrite_asset_path(elem, src_dir, root_dir, md, txd, ad)
+ for comp in root.findall("compiler"):
+ for attr in ("meshdir", "texturedir", "assetdir"):
+ comp.attrib.pop(attr, None)
+
+
def materialize_inline_meshes(root, mesh_base: Path) -> int:
"""Rewrite ```` (MuJoCo's inline-data form)
to ```` by emitting an OBJ next to the rest of the
@@ -315,17 +564,27 @@ def materialize_inline_meshes(root, mesh_base: Path) -> int:
return materialized
-def process_xml(xml_path: Path):
- """Parse MJCF XML, convert meshes, resolve conflicts, write updated XML."""
+def process_xml(xml_path: Path, out_dir: Path = None,
+ allow_external_includes: bool = False) -> bool:
+ """Parse MJCF XML, convert meshes, resolve conflicts, write updated XML.
+
+ Returns True only when every mesh the document references was prepared, and
+ only when every ```` stayed inside the model's own folder unless
+ ``allow_external_includes`` says otherwise.
+ """
if not xml_path.exists():
- print(f"Error: XML file not found: {xml_path}")
- return
+ print(f"Error: XML file not found: {xml_path}", file=sys.stderr)
+ return False
- xml_dir = xml_path.parent
+ xml_dir = xml_path.parent.resolve()
+ root_dir = out_dir.resolve() if out_dir is not None else xml_dir
+ root_dir.mkdir(parents=True, exist_ok=True)
print(f"XML: {xml_path}")
print(f"Dir: {xml_dir}")
+ if root_dir != xml_dir:
+ print(f"Out: {root_dir}")
print("=" * 60)
# Parse XML
@@ -339,10 +598,20 @@ def process_xml(xml_path: Path):
include_count = sum(1 for _ in root.iter("include"))
if include_count:
print(f"Flattening {include_count} fragment(s)...")
- root = flatten_includes(root, xml_dir.resolve())
+ # The model's own folder is the boundary, matching the reader's rule.
+ # Off only when the caller passed the same option the import dialog
+ # shows, so the gate is decided in one place rather than twice.
+ boundary = None if allow_external_includes else xml_dir
+ try:
+ root = flatten_includes(root, xml_dir, root_dir, boundary)
+ except ExternalIncludeError as refused:
+ print(f"Error: {refused}", file=sys.stderr)
+ return False
tree = ET.ElementTree(root)
remaining = sum(1 for _ in root.iter("include"))
print(f" -> {remaining} include(s) remain after flatten")
+ elif root_dir != xml_dir:
+ _rebase_assets(root, xml_dir, root_dir)
# Find meshdir from compiler
meshdir = ""
@@ -351,9 +620,13 @@ def process_xml(xml_path: Path):
if md:
meshdir = md
- mesh_base = xml_dir / meshdir if meshdir else xml_dir
+ mesh_base = root_dir / meshdir if meshdir else root_dir
print(f"Mesh directory: {mesh_base}")
+ # Every mesh this run could not prepare. Non-empty means the caller must
+ # not use the output: the unconverted source would import at its own scale.
+ failures = []
+
# Phase 0: Materialize inline ```` entries.
# These get rewritten to file= entries before Phase 1 runs, so the rest
# of the pipeline treats them like any other on-disk mesh.
@@ -364,6 +637,11 @@ def process_xml(xml_path: Path):
# Collect all mesh elements
mesh_elements = list(root.iter("mesh"))
+ # Which of them a colliding geom uses. Those keep MuJoCo's own vertices.
+ collision_meshes = collision_mesh_names(root)
+ if collision_meshes:
+ print(f"Collision meshes (normals left as authored): {len(collision_meshes)}")
+
# Also convert meshes referenced by
for flexcomp in root.iter("flexcomp"):
file_attr = flexcomp.get("file")
@@ -373,11 +651,15 @@ def process_xml(xml_path: Path):
output_glb = source_path.with_suffix(".glb")
if not glb_up_to_date(output_glb, source_path):
print(f"\n[flexcomp] Converting mesh: {source_path.name} -> {output_glb.name}")
- if not convert_mesh(source_path, output_glb) and output_glb.exists():
- output_glb.unlink()
- print(f"[flexcomp] Removed stale GLB: {output_glb.name}")
+ if not convert_mesh(source_path, output_glb):
+ failures.append(f"flexcomp mesh '{file_attr}' failed to convert")
+ if output_glb.exists():
+ output_glb.unlink()
+ print(f"[flexcomp] Removed stale GLB: {output_glb.name}")
else:
print(f"\n[flexcomp] Mesh up to date: {output_glb.name}")
+ else:
+ failures.append(f"flexcomp mesh not found: {source_path}")
print(f"Found {len(mesh_elements)} mesh assets in XML\n")
@@ -453,7 +735,8 @@ def process_xml(xml_path: Path):
# Copy the source file to the new name
if not source_path.exists():
- print(f" x Source file missing: {source_path} — skipping")
+ print(f" x Source file missing: {source_path}")
+ failures.append(f"mesh source not found: {source_path}")
continue
if not renamed_source.exists() or renamed_source.stat().st_mtime < source_path.stat().st_mtime:
shutil.copy2(str(source_path), str(renamed_source))
@@ -471,6 +754,7 @@ def process_xml(xml_path: Path):
if not actual_source.exists():
print(f"\n x Source not found: {actual_source}")
+ failures.append(f"mesh source not found: {actual_source}")
continue
if glb_up_to_date(output_glb, actual_source):
@@ -479,10 +763,22 @@ def process_xml(xml_path: Path):
continue
print(f"\n[{mesh_name}] {actual_source.name} -> {output_glb.name}")
- if convert_mesh(actual_source, output_glb):
+ # MJCF's own opt-in to one averaged normal per vertex. It defaults to
+ # false, so a model that says nothing gets the crease split.
+ smooth_normal = mesh_el.get("smoothnormal", "false").strip().lower() in ("true", "1")
+
+ # A mesh a colliding geom uses is not split, whatever the document says
+ # about its normals: the split is a shading improvement, and paying for
+ # it with a model that no longer matches MuJoCo's is the wrong trade on
+ # geometry nobody looks at.
+ if mesh_name in collision_meshes:
+ smooth_normal = True
+
+ if convert_mesh(actual_source, output_glb, smooth_normal):
success_count += 1
else:
print(f" x FAILED to convert {actual_source.name}")
+ failures.append(f"mesh '{mesh_name}' failed to convert: {actual_source}")
# Never leave a stale or partial GLB behind: the importer
# prefers .glb over the source mesh, so a leftover here would
# silently ship the very data the conversion just refused to
@@ -491,32 +787,46 @@ def process_xml(xml_path: Path):
output_glb.unlink()
print(f" -> Removed stale GLB: {output_glb.name}")
- # Phase 4: Write updated XML
- output_xml = xml_path.parent / f"{xml_path.stem}_ue.xml"
+ # Phase 4: Write updated XML. Written even when something failed, so the
+ # partial result can be inspected; the exit status is what decides whether
+ # a caller may use it.
+ output_xml = root_dir / f"{xml_path.stem}_ue.xml"
tree.write(str(output_xml), encoding="unicode", xml_declaration=True)
print("\n" + "=" * 60)
print(f"Processed {success_count}/{len(output_plan)} meshes successfully")
print(f"Conflicts resolved: {conflicts_found}")
print(f"Updated XML: {output_xml}")
+
+ if failures:
+ print(f"\n{len(failures)} mesh(es) could not be prepared:", file=sys.stderr)
+ for reason in failures:
+ print(f" - {reason}", file=sys.stderr)
+ return False
+
print(f"\nDrag '{output_xml.name}' into Unreal Content Browser to import.")
+ return True
def main():
- if len(sys.argv) < 2:
- print("Error: No XML file specified")
- print("Usage: python clean_meshes_trimesh.py ")
- print('Example: python clean_meshes_trimesh.py "C:/mujoco_menagerie/franka_emika_panda/panda.xml"')
- return
+ parser = argparse.ArgumentParser(
+ description="Prepare MuJoCo MJCF meshes for Unreal import.")
+ parser.add_argument("xml", type=Path, help="path to the MJCF .xml to prepare")
+ parser.add_argument("--out-dir", type=Path, default=None, dest="out_dir",
+ help="directory to write the prepared _ue.xml into "
+ "(default: beside the input)")
+ parser.add_argument("--allow-external-includes", action="store_true",
+ dest="allow_external_includes",
+ help="follow an whose target is outside the "
+ "model's own folder (refused by default)")
+ args = parser.parse_args()
- xml_path = Path(sys.argv[1])
+ if args.xml.suffix.lower() != ".xml":
+ parser.error(f"expected an .xml file, got '{args.xml.suffix}'")
- if xml_path.suffix.lower() == ".xml":
- process_xml(xml_path)
- else:
- print(f"Error: Expected an .xml file, got '{xml_path.suffix}'")
- print("Usage: python clean_meshes_trimesh.py ")
+ return 0 if process_xml(args.xml, args.out_dir,
+ args.allow_external_includes) else 1
if __name__ == "__main__":
- main()
+ sys.exit(main())
diff --git a/Scripts/codegen/_codegen_checks.py b/Scripts/codegen/_codegen_checks.py
deleted file mode 100644
index e425cbcf..00000000
--- a/Scripts/codegen/_codegen_checks.py
+++ /dev/null
@@ -1,934 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""URLab codegen — drift checks.
-
-Every ``_check_*`` function that scans rules + snapshots for drift
-lives here. The orchestrator imports the dispatcher functions
-(``_emit_drift_diagnostics``, ``_check_*``) and wires them into
-``_phase_diagnostics``.
-
-Dependencies are strictly downward: imports from ``_codegen_core``
-only. No emit logic, no .cpp injection — drift checks read the
-rules + snapshots and route diagnostics through ``_diag_add``.
-"""
-
-from __future__ import annotations
-
-import os
-import re
-from typing import Any, Dict, List, Optional, Sequence, Set, Tuple
-
-from _codegen_core import (
- _diag_add,
- _UE_TYPE_INFO, _UE_TYPE_FAMILY, _ue_type_accepts_units_meta, _KNOWN_UE_UNITS,
- _classify_c_type, _shapes_compatible, _VEC3_CONVERT_FMT,
- schema_attrs, schema_subtype_attrs,
- compute_canon_absorbed,
- _resolve_mjs_field, _resolve_value_map, _value_map_pair,
-)
-
-
-# ---------------------------------------------------------------------------
-# Hand-enum scrape (regex fallback when the libclang scrape didn't run)
-# ---------------------------------------------------------------------------
-
-_HAND_ENUM_RE = re.compile(
- r"enum\s+class\s+(EMj\w+)\s*:\s*uint8\s*\{([^}]*)\}",
- re.DOTALL,
-)
-_HAND_ENUM_MEMBER_RE = re.compile(r"\A\s*(\w+)")
-
-
-def _scan_hand_enums(public_root: str) -> Dict[str, List[str]]:
- """Walk ``public_root`` for every ``.h`` file declaring
- ``enum class EMj* : uint8 { ... }`` and return
- ``{enum_name: [members]}``. Members are stripped of inline
- initialisers, UMETA macros, and comments."""
- out: Dict[str, List[str]] = {}
- for root, _dirs, files in os.walk(public_root):
- for name in files:
- if not name.endswith(".h"):
- continue
- with open(os.path.join(root, name), "r", encoding="utf-8") as f:
- text = f.read()
- for m in _HAND_ENUM_RE.finditer(text):
- enum_name = m.group(1)
- body = m.group(2)
- body = re.sub(r"UMETA\([^)]*\)", "", body)
- body = re.sub(r"//[^\n]*", "", body)
- body = re.sub(r"/\*.*?\*/", "", body, flags=re.DOTALL)
- members: List[str] = []
- for line in body.split(","):
- mm = _HAND_ENUM_MEMBER_RE.match(line)
- if mm:
- members.append(mm.group(1))
- if members:
- out[enum_name] = members
- return out
-
-
-def _hand_enums_from_snapshot(mjspec: Optional[Dict[str, Any]]) -> Dict[str, List[str]]:
- """Pull URLab's hand-rolled ``EMj*`` enums out of the merged
- introspect snapshot when present. Snapshot path produces real
- ENUM_CONSTANT_DECL members from libclang. Regex fallback covers
- the local-dev case where the snapshot wasn't regenerated."""
- if not mjspec:
- return {}
- introspect = mjspec.get("introspect", {}) or {}
- hand_enums = introspect.get("hand_enums") or {}
- out: Dict[str, List[str]] = {}
- for name, entry in hand_enums.items():
- if not isinstance(entry, dict):
- continue
- members = entry.get("members", {})
- if isinstance(members, dict):
- out[name] = list(members.keys())
- return out
-
-
-# ---------------------------------------------------------------------------
-# Drift checks
-# ---------------------------------------------------------------------------
-
-
-def _check_hand_enum_drift(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
- public_root: str,
-) -> None:
- """Cross-check rule-declared UE enum members against the actual
- hand enums AND against MuJoCo's mjt* enums."""
- hand_enums = _hand_enums_from_snapshot(mjspec)
- if not hand_enums:
- hand_enums = _scan_hand_enums(public_root)
- if not hand_enums:
- return
-
- for cat_name, cat_rules in rules.get("categories", {}).items():
- type_enum = cat_rules.get("type_enum_name")
- if not type_enum or type_enum not in hand_enums:
- continue
- members = set(hand_enums[type_enum])
- for sub in cat_rules.get("subtypes", []):
- ev = sub.get("enum_value")
- if ev and ev not in members:
- _diag_add(
- f"[diagnostic] category '{cat_name}' subtype '{sub.get('key')}' "
- f"references enum_value '{type_enum}::{ev}' that does not "
- f"exist in {type_enum} members {sorted(members)}.",
- source="hand_enum_drift",
- )
-
- element_rules = rules.get("element_rules", {})
- mjspec_enums = (mjspec or {}).get("enums", {})
- intentional_skips = rules.get("intentionally_unmapped_mj_enum_values", {})
- for elem, elem_rules in element_rules.items():
- for attr, enum_def in elem_rules.get("xml_enum_attrs", {}).items():
- ue_enum_type = enum_def.get("ue_enum_type") or enum_def.get("ue_enum")
- value_map = enum_def.get("value_map", {})
- if not ue_enum_type or ue_enum_type not in hand_enums:
- continue
- members = set(hand_enums[ue_enum_type])
- for xml_val, mapping in value_map.items():
- pair = _value_map_pair(mapping)
- if pair is None:
- continue
- ue_member, _ = pair
- if ue_member not in members:
- _diag_add(
- f"[diagnostic] element '{elem}' xml_enum '{attr}' "
- f"value_map entry '{xml_val}' maps to "
- f"'{ue_enum_type}::{ue_member}' that does not exist "
- f"in members {sorted(members)}.",
- source="hand_enum_drift",
- )
- from_mj_enum = enum_def.get("from_mj_enum")
- if not from_mj_enum:
- mjs_cast = enum_def.get("mjs_cast", "")
- if mjs_cast.startswith("mjt"):
- from_mj_enum = mjs_cast
- if from_mj_enum and from_mj_enum in mjspec_enums:
- mj_values = mjspec_enums[from_mj_enum]
- covered_mj: set = set()
- for mapping in value_map.values():
- pair = _value_map_pair(mapping)
- if pair is not None:
- covered_mj.add(pair[1])
- skips = set(intentional_skips.get(from_mj_enum, []))
- per_elem = intentional_skips.get("__per_element__", {})
- skips |= set(per_elem.get(f"{elem}.{attr}", []))
- for mj_const in mj_values:
- if mj_const in covered_mj or mj_const in skips:
- continue
- _diag_add(
- f"[diagnostic] {from_mj_enum}::{mj_const} (from "
- f"mjspec snapshot) has no mapping in element "
- f"'{elem}' xml_enum_attrs.{attr}.value_map; new "
- f"MuJoCo enum values silently fall through to the "
- f"default branch at runtime. Add a value_map entry "
- f"or list under 'intentionally_unmapped_mj_enum_values"
- f".{from_mj_enum}'.",
- source="hand_enum_drift",
- )
-
-
-def _check_type_shape_drift(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Cross-check ``type_mappings[attr]`` against the actual C-type
- shape of the corresponding mjs struct field."""
- if not mjspec:
- return
- struct_table = (mjspec.get("introspect") or {}).get("structs", {})
- if not struct_table:
- return
- type_map = rules.get("type_mappings", {})
- unmodeled_mjs = rules.get("intentionally_unmodeled_mjs_fields", {})
- element_rules = rules.get("element_rules", {})
- for cat_name, cat_rules in rules.get("categories", {}).items():
- mjs_struct = cat_rules.get("mjs_struct")
- if not mjs_struct or mjs_struct not in struct_table:
- continue
- fields = {
- f["name"]: (f.get("c_type", ""), f.get("array_dim"))
- for f in struct_table[mjs_struct].get("fields", [])
- }
- skip_fields = set(unmodeled_mjs.get(mjs_struct, []))
- skip_fields |= set(element_rules.get(cat_name, {}).get("exclude_attrs", []))
- for attr, ue_type in type_map.items():
- if attr not in fields or attr in skip_fields:
- continue
- ue_shape = _UE_TYPE_FAMILY.get(ue_type)
- if not ue_shape:
- continue
- c_type, array_dim = fields[attr]
- c_shape = _classify_c_type(c_type, array_dim)
- if c_shape is None or c_shape[0] == "opaque":
- continue
- if not _shapes_compatible(ue_shape, c_shape):
- _diag_add(
- f"[diagnostic] type_mappings['{attr}'] = '{ue_type}' "
- f"(category '{cat_name}') but {mjs_struct}.{attr} is "
- f"'{c_type}' (shape={c_shape}); rule expects "
- f"shape={ue_shape}. UE/C shape mismatch — emitted "
- f"code may overflow, truncate, or fail to compile.",
- source="type_shape_drift",
- )
-
-
-def _check_new_attr_typing(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
-) -> None:
- """Every schema attr that lands as a UPROPERTY but has no explicit
- type_mappings entry silently inherits ``default_type`` ('float').
- Also surfaces type_mappings entries whose UE type does not resolve
- to a known shape — the codegen would otherwise fall back to a
- default emit and hide the typo (e.g. ``TArray``)."""
- type_map = rules.get("type_mappings", {})
- default_type = rules.get("default_type", "float")
- global_excl = set(rules.get("global_exclusions", []))
- intentional_float = set(rules.get("intentionally_default_typed_attrs", []))
- element_rules = rules.get("element_rules", {})
- canonicalizations = rules.get("canonicalizations", {})
-
- def _ue_type_known(ue_type: str) -> bool:
- if ue_type in _UE_TYPE_INFO:
- return True
- if ue_type.startswith("EMj"):
- return True
- if ue_type.startswith("TArray<") and ue_type.endswith(">"):
- inner = ue_type[len("TArray<"):-1]
- return inner in _UE_TYPE_INFO or inner.startswith("EMj") or inner.startswith("U")
- return False
-
- bad_typed: set = set()
- for attr, ue_type in type_map.items():
- if attr.startswith("_"):
- continue
- if not _ue_type_known(ue_type):
- bad_typed.add(attr)
- _diag_add(
- f"[diagnostic] type_mappings['{attr}'] = '{ue_type}' is "
- f"not a recognised UE type. The codegen will fall back "
- f"to default_type ('{default_type}') for downstream "
- f"emits, hiding the typo. Fix the type or add the entry "
- f"to _UE_TYPE_INFO.",
- source="new_attr_typing",
- )
-
- def _collect_attrs(cat_rules: Dict[str, Any]) -> set:
- out: set = set(schema_attrs(schema, cat_rules.get("schema_common_block", "")))
- out |= set(cat_rules.get("schema_common_extra_attrs", []))
- sub_block = cat_rules.get("schema_subtypes_block")
- if sub_block and sub_block in schema:
- block = schema[sub_block]
- if isinstance(block, dict):
- for sub_attrs in block.values():
- if isinstance(sub_attrs, list):
- out |= set(sub_attrs)
- elif isinstance(sub_attrs, dict):
- out |= set(sub_attrs.get("attrs", []))
- elif isinstance(block, list):
- for entry in block:
- if isinstance(entry, dict):
- out |= set(entry.get("attrs", []))
- return out
-
- flagged: set = set()
- for cat_name, cat_rules in rules.get("categories", {}).items():
- elem_rules = element_rules.get(cat_name, {})
- elem_excl = set(elem_rules.get("exclude_attrs", []))
- xml_enum_attrs = set(elem_rules.get("xml_enum_attrs", {}).keys())
- renames = set(elem_rules.get("property_renames", {}).keys())
- collations = set(elem_rules.get("target_collations", {}).keys())
- export_skip = set(elem_rules.get("export_skip_attrs", []))
- common_imports = set()
- for entry in elem_rules.get("common_imports", []):
- if isinstance(entry, str):
- common_imports.add(entry)
- elif isinstance(entry, dict):
- common_imports.add(entry.get("attr"))
- canon_absorbed: set = compute_canon_absorbed(
- elem_rules.get("applies_canonicalizations", []),
- canonicalizations,
- )
- for attr in _collect_attrs(cat_rules):
- if attr in global_excl or attr in elem_excl:
- continue
- if attr in xml_enum_attrs or attr in renames or attr in collations:
- continue
- if attr in canon_absorbed or attr in export_skip or attr in common_imports:
- continue
- if attr in type_map:
- continue
- if attr in flagged or attr in intentional_float:
- continue
- flagged.add(attr)
- _diag_add(
- f"[diagnostic] attr '{attr}' (used by {cat_name}) has no "
- f"type_mappings entry and would fall back to default_type "
- f"('{default_type}'). Pin its UE type in type_mappings, or "
- f"list it under 'intentionally_default_typed_attrs' to "
- f"acknowledge the fallback.",
- source="new_attr_typing",
- )
-
-
-_ATTR_NAME_RE = re.compile(r"^[a-z_][a-z0-9_]*$")
-
-
-def _all_schema_attrs(schema: Dict[str, Any], rules: Dict[str, Any]) -> set:
- """Union of every schema attr observed anywhere in the snapshot."""
- out: set = set()
-
- def _walk(node: Any) -> None:
- if isinstance(node, list):
- for item in node:
- if isinstance(item, str) and _ATTR_NAME_RE.match(item):
- out.add(item)
- else:
- _walk(item)
- elif isinstance(node, dict):
- for k, v in node.items():
- if k in ("obj_attr", "ref_attr") and isinstance(v, str):
- if _ATTR_NAME_RE.match(v):
- out.add(v)
- _walk(v)
-
- _walk(schema)
- for cat_rules in rules.get("categories", {}).values():
- out |= set(cat_rules.get("schema_common_extra_attrs", []))
- return out
-
-
-def _check_orphan_rule_entries(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
-) -> None:
- """Diagnose rule entries that reference attrs no schema element
- uses. Catches stale rules left over from MuJoCo renaming/removing
- an attr."""
- known_attrs = _all_schema_attrs(schema, rules)
- if not known_attrs:
- return
- type_map = rules.get("type_mappings", {})
- for attr in type_map.keys():
- if attr not in known_attrs:
- _diag_add(
- f"[diagnostic] type_mappings['{attr}'] is set but no "
- f"schema element exposes an attr by that name. Dead rule "
- f"entry — remove, or check whether MuJoCo renamed/removed "
- f"the attr.",
- source="orphan_rule",
- )
- PER_ELEM_KEYS = (
- "exclude_attrs",
- "vec3_convert",
- "property_renames",
- "property_meta",
- "property_defaults",
- "export_skip_attrs",
- "mjs_data_packed_attrs",
- )
- for elem, elem_rules in rules.get("element_rules", {}).items():
- for key in PER_ELEM_KEYS:
- block = elem_rules.get(key, {})
- if isinstance(block, dict):
- rule_attrs = list(block.keys())
- elif isinstance(block, list):
- rule_attrs = [
- a if isinstance(a, str) else a.get("attr")
- for a in block
- ]
- else:
- continue
- for attr in rule_attrs:
- if not attr or attr in known_attrs:
- continue
- _diag_add(
- f"[diagnostic] element_rules['{elem}']['{key}'] "
- f"references attr '{attr}', which is not present in "
- f"ANY schema element. Stale rule.",
- source="orphan_rule",
- )
-
-
-def _check_mjxmacro_block_coverage(
- rules: Dict[str, Any],
- mjxmacro: Dict[str, Any],
-) -> None:
- """Bi-directional check between mjxmacro snapshot blocks and
- ``synthetic_categories`` entries. Forward catches new blocks
- upstream URLab doesn't model; reverse catches rule entries
- pointing at vanished blocks."""
- blocks = mjxmacro.get("struct_fields", {})
- synthetic = rules.get("synthetic_categories", {})
- if not blocks and not synthetic:
- return
- block_to_rule: Dict[str, str] = {}
- for key, entry in synthetic.items():
- if not isinstance(entry, dict):
- continue
- mb = entry.get("mjxmacro_block")
- if mb:
- block_to_rule[mb] = key
- for block in blocks:
- if block not in block_to_rule:
- _diag_add(
- f"[diagnostic] mjxmacro struct_fields block '{block}' has "
- f"no synthetic_categories rule entry; the {len(blocks[block])} "
- f"field(s) it declares will not be emitted as a UE struct.",
- source="mjxmacro_block_coverage",
- )
- for block, rule_key in block_to_rule.items():
- if block not in blocks:
- _diag_add(
- f"[diagnostic] synthetic_categories '{rule_key}' references "
- f"mjxmacro_block '{block}' that does not exist in the current "
- f"mjxmacro snapshot — block renamed or removed upstream.",
- source="mjxmacro_block_coverage",
- )
-
-
-# Apply-mode values _emit_synth_apply_methods_cpp understands. Anything
-# else lands as a silent passthrough to vec3_y_flip / unconditional —
-# the diagnostic surfaces typos so a rule author's intent is real.
-_VALID_APPLY_MODES = (
- {"unconditional", "guarded", "pos"}
- | set(_VEC3_CONVERT_FMT.keys())
- | {f"guarded_{k}" for k in _VEC3_CONVERT_FMT.keys()}
- | {"guarded_pos"}
-)
-
-
-def _check_apply_mode_validity(rules: Dict[str, Any]) -> None:
- """Diagnose ``field_apply_to_spec_mode`` values the codegen would
- silently fall back on."""
- synth = rules.get("synthetic_categories", {})
- for cat_name, def_ in synth.items():
- if cat_name.startswith("_") or not isinstance(def_, dict):
- continue
- modes = def_.get("field_apply_to_spec_mode", {})
- if not isinstance(modes, dict):
- continue
- for field, mode in modes.items():
- if mode not in _VALID_APPLY_MODES:
- _diag_add(
- f"[diagnostic] synthetic_categories['{cat_name}']"
- f".field_apply_to_spec_mode['{field}'] = '{mode}' "
- f"is not a recognised apply mode. Expected one of "
- f"{sorted(_VALID_APPLY_MODES)}.",
- source="apply_mode",
- )
-
-
-def _check_embedded_cpp_references(
- rules: Dict[str, Any], mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Diagnose rule entries that name a MuJoCo C symbol the mjspec
- snapshot doesn't carry."""
- if not mjspec or "enums" not in mjspec:
- return
- known_consts: Set[str] = set()
- for members in mjspec["enums"].values():
- if isinstance(members, dict):
- known_consts.update(members.keys())
- if not known_consts:
- return
- for elem, elem_rules in rules.get("element_rules", {}).items():
- for attr, enum_def in elem_rules.get("xml_enum_attrs", {}).items():
- for xml_val, mapping in enum_def.get("value_map", {}).items():
- pair = _value_map_pair(mapping)
- if pair is None:
- continue
- mj_const = pair[1]
- if not isinstance(mj_const, str):
- continue
- if not mj_const.startswith("mj"):
- continue
- if mj_const not in known_consts:
- _diag_add(
- f"[diagnostic] element_rules['{elem}']"
- f".xml_enum_attrs['{attr}'].value_map['{xml_val}'][1]"
- f" = '{mj_const}' is not present in any mjspec enum. "
- f"Likely typo — UE compile would fail with "
- f"'undeclared identifier'.",
- source="embedded_cpp_refs",
- )
- for cat_name, cat_rules in rules.get("categories", {}).items():
- final = cat_rules.get("geom_final_type")
- if not final:
- continue
- fallback = final.get("default_fallback")
- if isinstance(fallback, str) and fallback.startswith("mj") and fallback not in known_consts:
- _diag_add(
- f"[diagnostic] categories['{cat_name}'].geom_final_type"
- f".default_fallback = '{fallback}' is not present in any "
- f"mjspec enum.",
- source="embedded_cpp_refs",
- )
-
-
-def _collect_every_schema_attr(schema: Dict[str, Any]) -> Set[str]:
- """Walk the entire schema tree returning every attr name found.
- Used by ``_check_allowlist_staleness``."""
- out: Set[str] = set()
-
- def walk(node: Any) -> None:
- if isinstance(node, dict):
- for v in node.values():
- if isinstance(v, list) and all(isinstance(s, str) for s in v):
- out.update(v)
- else:
- walk(v)
- elif isinstance(node, list):
- for entry in node:
- walk(entry)
-
- walk(schema)
- return out
-
-
-def _check_allowlist_staleness(
- schema: Dict[str, Any], rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Surface allowlist entries the codebase no longer needs. Covers
- 4 of the 5 ``intentionally_*`` allowlists; the fifth
- (intentionally_unmodeled_compiler_attrs) is policed indirectly via
- _check_compiler_attrs_coverage."""
- unmodeled_elems: Dict[str, str] = rules.get("intentionally_unmodeled_elements", {})
- schema_keys = set(schema.keys())
- for key in unmodeled_elems:
- if key not in schema_keys:
- _diag_add(
- f"[diagnostic] intentionally_unmodeled_elements lists '{key}' "
- f"but the schema no longer carries that top-level element. "
- f"Drop the entry.",
- source="allowlist_staleness",
- )
-
- unmodeled_fields: Dict[str, List[str]] = rules.get("intentionally_unmodeled_mjs_fields", {})
- structs = (mjspec or {}).get("structs", {}) if mjspec else {}
- if structs:
- for struct, fields in unmodeled_fields.items():
- if struct not in structs:
- _diag_add(
- f"[diagnostic] intentionally_unmodeled_mjs_fields names "
- f"struct '{struct}' that is missing from the current "
- f"mjspec snapshot. Drop the entry.",
- source="allowlist_staleness",
- )
- continue
- struct_field_set = set(structs[struct])
- for field in fields or []:
- if field not in struct_field_set:
- _diag_add(
- f"[diagnostic] intentionally_unmodeled_mjs_fields"
- f"['{struct}'] lists '{field}' but the field no "
- f"longer exists on the mjs struct. Drop the entry.",
- source="allowlist_staleness",
- )
-
- default_typed: List[str] = rules.get("intentionally_default_typed_attrs", [])
- every_attr: Set[str] = _collect_every_schema_attr(schema)
- for attr in default_typed:
- if attr not in every_attr:
- _diag_add(
- f"[diagnostic] intentionally_default_typed_attrs lists "
- f"'{attr}' but no schema element carries that attr. "
- f"Drop the entry.",
- source="allowlist_staleness",
- )
-
- unmapped: Dict[str, Any] = rules.get("intentionally_unmapped_mj_enum_values", {})
- mj_enums = (mjspec or {}).get("enums", {}) if mjspec else {}
- if mj_enums:
- for key in unmapped:
- if key.startswith("_") or key == "__per_element__":
- continue
- if key not in mj_enums:
- _diag_add(
- f"[diagnostic] intentionally_unmapped_mj_enum_values "
- f"names mjt enum '{key}' that is missing from the "
- f"current mjspec snapshot. Drop the entry.",
- source="allowlist_staleness",
- )
-
-
-def _check_property_units_validity(
- rules: Dict[str, Any],
-) -> None:
- """Diagnose property_units entries that use an unrecognised UE
- display unit, or target a UE type that UHT rejects Units meta on."""
- for elem, elem_rules in rules.get("element_rules", {}).items():
- units = elem_rules.get("property_units", {})
- if not isinstance(units, dict):
- continue
- for attr, unit in units.items():
- if unit not in _KNOWN_UE_UNITS:
- _diag_add(
- f"[diagnostic] element_rules['{elem}'].property_units"
- f"['{attr}'] = '{unit}' is not a UE-recognised display "
- f"unit. Use one of {sorted(_KNOWN_UE_UNITS)} or extend "
- f"_KNOWN_UE_UNITS in _codegen_core.",
- source="property_units",
- )
-
-
-def _check_compiler_attrs_coverage(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
-) -> None:
- """Diagnose any attribute the MJCF schema lists that
- URLab neither models in FMjCompilerSettings nor explicitly skips."""
- compiler_attrs = schema.get("compiler", {}).get("attrs", [])
- if not compiler_attrs:
- return
- mapped = set(rules.get("compiler_attr_field_map", {}).keys())
- skipped = set(rules.get("intentionally_unmodeled_compiler_attrs", []))
- for attr in compiler_attrs:
- if attr in mapped or attr in skipped:
- continue
- _diag_add(
- f"[diagnostic] is in the MJCF schema "
- f"but URLab does not handle it. Either add a field to "
- f"FMjCompilerSettings + an entry in 'compiler_attr_field_map', "
- f"or add to 'intentionally_unmodeled_compiler_attrs' if the "
- f"flag has no UE-side effect.",
- source="compiler_coverage",
- )
-
-
-def _check_value_map_stale_mj_consts(
- rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Every value_map[*][1] is a literal mj* C constant emitted into
- the generated .cpp; the snapshot cross-check surfaces removed/
- renamed constants before they break the C++ compile."""
- if not mjspec:
- return
- enums = mjspec.get("enums", {})
- if not enums:
- return
- known: set = set()
- for members in enums.values():
- if isinstance(members, dict):
- known.update(members.keys())
- if not known:
- return
- for elem, elem_rules in rules.get("element_rules", {}).items():
- for attr, enum_def in elem_rules.get("xml_enum_attrs", {}).items():
- value_map = enum_def.get("value_map", {})
- for xml_val, mapping in value_map.items():
- pair = _value_map_pair(mapping)
- if pair is None:
- continue
- mj_const = pair[1]
- if not isinstance(mj_const, str) or not mj_const.startswith("mj"):
- continue
- if mj_const not in known:
- _diag_add(
- f"[diagnostic] element '{elem}' xml_enum '{attr}' "
- f"value_map entry '{xml_val}' references "
- f"'{mj_const}', which is NOT in the mjspec "
- f"snapshot's enum members. The generated .cpp "
- f"will fail to compile when the MuJoCo headers "
- f"update.",
- source="value_map_stale",
- )
-
-
-def _check_top_level_elements_coverage(
- schema: Dict[str, Any], rules: Dict[str, Any],
-) -> None:
- """Flag top-level schema elements with no category in rules."""
- categories = rules.get("categories", {})
- known_blocks = {c.get("schema_common_block", "").split(".", 1)[0]
- for c in categories.values()}
- known_blocks.discard("")
- container_keys = {
- "_meta", "actuator_common", "actuator_types", "sensor_common",
- "sensor_types", "sensor_per_type", "sensor_extras",
- "tendon", "equality", "contact",
- "asset", "compiler", "option", "keyframe", "default",
- }
- unmodeled: Dict[str, str] = rules.get("intentionally_unmodeled_elements", {})
- for key in schema:
- if key.startswith("_") or key in container_keys or key in known_blocks:
- continue
- if key in unmodeled:
- continue
- _diag_add(
- f"[diagnostic] schema has top-level element '{key}' but no "
- f"category in codegen_rules.json (rules['categories']). "
- f"Either add a category entry, list '{key}' in "
- f"container_keys, or add an "
- f"'intentionally_unmodeled_elements' entry explaining why "
- f"it's skipped.",
- source="top_level_coverage",
- )
-
-
-def _check_actuator_subtypes_coverage(
- schema: Dict[str, Any], rules: Dict[str, Any],
-) -> None:
- act_cat = rules.get("categories", {}).get("actuator", {})
- known_act_subs = {s.get("key") for s in act_cat.get("subtypes", [])}
- for name in schema.get("actuator_types", {}):
- if name not in known_act_subs:
- _diag_add(
- f"[diagnostic] schema actuator subtype '{name}' has no "
- f"entry in categories.actuator.subtypes. Add a subtype "
- f"+ subtype_setto rule pair so codegen emits the UMj"
- f"{name.title()}Actuator class.",
- source="actuator_subtypes_coverage",
- )
-
-
-def _check_sensor_subtypes_coverage(
- schema: Dict[str, Any], rules: Dict[str, Any],
-) -> None:
- sens_cat = rules.get("categories", {}).get("sensor", {})
- known_sens_subs = {s.get("key") for s in sens_cat.get("subtypes", [])}
- for name in schema.get("sensor_types", []):
- if name not in known_sens_subs:
- _diag_add(
- f"[diagnostic] schema sensor type '{name}' has no entry "
- f"in categories.sensor.subtypes. Add it so the per-sensor "
- f"UMjXSensor subclass is emitted.",
- source="sensor_subtypes_coverage",
- )
-
-
-def _check_setto_param_coverage(
- schema: Dict[str, Any], rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Flag mjs_setTo* parameters with no UE-side mapping AND no
- explicit sentinel default."""
- if not mjspec or "setto_functions" not in mjspec:
- return
- categories = rules.get("categories", {})
- setto_defaults = rules.get("setto_param_defaults", {})
- for cat_name, cat_rules in categories.items():
- setto_block = cat_rules.get("subtype_setto") or {}
- common_attrs = set(schema_attrs(
- schema, cat_rules.get("schema_common_block", "")))
- for sub_key, setto_def in setto_block.items():
- if not isinstance(setto_def, dict):
- continue
- fn_name = setto_def.get("call")
- if not fn_name or fn_name not in mjspec["setto_functions"]:
- continue
- sig = mjspec["setto_functions"][fn_name]
- renames = setto_def.get("param_renames", {})
- fn_defaults = set(setto_defaults.get(fn_name, {}).keys())
- nullable = set(setto_def.get("nullable_params", []))
- inherited = set(setto_def.get("inherit_fields", {}).keys())
- sub_attrs = set(schema_subtype_attrs(schema, cat_name, sub_key))
- schema_attr_set = common_attrs | sub_attrs
- for p in sig.get("params", []):
- pname = p["name"]
- ue_prop = renames.get(pname, pname)
- if (ue_prop in schema_attr_set or pname in fn_defaults
- or pname in nullable or pname in inherited):
- continue
- _diag_add(
- f"[diagnostic] {fn_name} param '{pname}' is not "
- f"in the {cat_name}.{sub_key} schema attrs and "
- f"has no param_renames / setto_param_defaults / "
- f"nullable_params / inherit_fields entry. Codegen "
- f"passes the generic sentinel for it. If MuJoCo added "
- f"this param, decide whether to expose it as a UE "
- f"UPROPERTY (schema attr + type_mapping), pin its "
- f"sentinel, or mark it nullable/inherited.",
- source="setto_param_coverage",
- )
-
-
-def _check_mjs_struct_field_drift(
- schema: Dict[str, Any], rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Flag mjs struct fields with no schema-attr coverage or rule
- binding."""
- if not mjspec or "structs" not in mjspec:
- return
- categories = rules.get("categories", {})
- unmodeled_by_struct: Dict[str, set] = {
- struct: set(fields) for struct, fields in
- rules.get("intentionally_unmodeled_mjs_fields", {}).items()
- }
- for cat_name, cat_rules in categories.items():
- mjs_struct = cat_rules.get("mjs_struct")
- if not mjs_struct or mjs_struct not in mjspec["structs"]:
- continue
- block = cat_rules.get("schema_common_block", "")
- schema_attrs_set = set(schema_attrs(schema, block))
- for sub in cat_rules.get("subtypes", []):
- schema_attrs_set.update(
- schema_subtype_attrs(schema, cat_name, sub.get("key", ""))
- )
- mjs_field_set = set(mjspec["structs"][mjs_struct])
- elem_rules = rules.get("element_rules", {}).get(cat_name, {})
- attr_to_mjs = elem_rules.get("attr_to_mjs_field", {})
- mapped_fields = set(attr_to_mjs.values())
- for coll_def in elem_rules.get("target_collations", {}).values():
- if isinstance(coll_def, dict) and coll_def.get("mjs_field"):
- mapped_fields.add(coll_def["mjs_field"])
- for enum_def in elem_rules.get("xml_enum_attrs", {}).values():
- if isinstance(enum_def, dict) and enum_def.get("mjs_field"):
- mapped_fields.add(enum_def["mjs_field"])
- for packed in elem_rules.get("mjs_data_packed_attrs", {}).values():
- if isinstance(packed, dict):
- mapped_fields.add(packed.get("target") or "data")
- for da in elem_rules.get("mjs_double_vec_attrs", []):
- mapped_fields.add(da)
- if cat_rules.get("type_enum_name"):
- mapped_fields.add("type")
- mapped_fields.add("objtype")
- for conv_list in elem_rules.get("unit_conversion", {}).values():
- for entry in conv_list if isinstance(conv_list, list) else []:
- if isinstance(entry, dict) and entry.get("mjs_field"):
- mapped_fields.add(entry["mjs_field"])
- # Canonicalisation name -> set of mjs struct fields its export
- # block writes. Lets the drift check treat canon-owned fields as
- # covered. Inlined here because this is the only consumer; kept
- # in lock-step with the inline canon emitters in
- # generate_ue_components (_canon_export_*).
- canon_mjs_fields = {
- "body_sleep_policy": {"sleep"},
- "actuator_transmission": {"target", "trntype", "slidersite", "refsite"},
- "fromto_decompose": set(),
- "orientation": {"quat"},
- "spatial_pose": {"pos"},
- }
- for canon in elem_rules.get("applies_canonicalizations", []):
- mapped_fields |= canon_mjs_fields.get(canon, set())
- structural = {
- "element", "info", "userdata", "user", "name", "classname",
- "parent", "frame", "explicitinertial",
- }
- structural |= unmodeled_by_struct.get(mjs_struct, set())
- structural |= mapped_fields
- normalised_schema = {a.replace("_", "").lower()
- for a in schema_attrs_set}
- for mjs_field in mjs_field_set:
- if mjs_field in structural:
- continue
- candidate = mjs_field.replace("_", "").lower()
- if candidate in normalised_schema:
- continue
- stripped = candidate.replace("name", "")
- if stripped in normalised_schema:
- continue
- if candidate.startswith("act") and ("actuator" + candidate[3:]) in normalised_schema:
- continue
- _diag_add(
- f"[diagnostic] {mjs_struct}.{mjs_field} (in mjspec_snapshot) "
- f"has no corresponding schema attr in '{cat_name}'. Either "
- f"add a schema canonicalisation, list it under "
- f"intentionally_unmodeled_mjs_fields, or accept that codegen "
- f"silently skips it.",
- source="mjs_field_drift",
- )
-
-
-def _check_generated_enum_coverage(
- rules: Dict[str, Any], mjspec: Optional[Dict[str, Any]],
-) -> None:
- """Flag generated_enums entries that map fewer mj enum members
- than the snapshot carries."""
- if not mjspec or "enums" not in mjspec:
- return
- for gen_name, gen_def in rules.get("generated_enums", {}).items():
- if gen_name.startswith("_") or not isinstance(gen_def, dict):
- continue
- if gen_def.get("disabled"):
- continue
- for entry in gen_def.get("enums", []):
- if entry.get("disabled"):
- continue
- mj_enum_name = entry.get("from_mj_enum")
- ue_member_from_mj = entry.get("ue_member_from_mj", {})
- exclude = set(entry.get("exclude_mj_members", []))
- if not mj_enum_name:
- continue
- c_enum = mjspec["enums"].get(mj_enum_name, {})
- if not c_enum:
- _diag_add(
- f"[diagnostic] generated_enums['{gen_name}'].{entry.get('ue_name')}: "
- f"from_mj_enum '{mj_enum_name}' not found in the projected mjspec. "
- f"Rebuild the introspect snapshot, or correct the enum name.",
- source="enum_drift",
- )
- continue
- mapped = set(ue_member_from_mj) | exclude
- missing = [m for m in c_enum if m not in mapped]
- if missing:
- _diag_add(
- f"[diagnostic] generated_enums['{gen_name}'].{entry.get('ue_name')}: "
- f"C enum '{mj_enum_name}' has {len(missing)} member(s) with no UE "
- f"mapping: {missing[:5]}{'...' if len(missing) > 5 else ''}. Add to "
- f"ue_member_from_mj or exclude_mj_members.",
- source="enum_drift",
- )
-
-
-def _emit_drift_diagnostics(schema: Dict[str, Any], rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]]) -> None:
- """Run every drift-coverage check. Each helper surfaces one class
- of drift. All diagnostics route through the module-level
- ``_DIAGS_BUFFER.pending`` collector and flush once at the end of
- ``collect_all_writes``."""
- _check_top_level_elements_coverage(schema, rules)
- _check_actuator_subtypes_coverage(schema, rules)
- _check_sensor_subtypes_coverage(schema, rules)
- _check_setto_param_coverage(schema, rules, mjspec)
- _check_mjs_struct_field_drift(schema, rules, mjspec)
- _check_generated_enum_coverage(rules, mjspec)
diff --git a/Scripts/codegen/_codegen_core.py b/Scripts/codegen/_codegen_core.py
deleted file mode 100644
index 0e4cf0f3..00000000
--- a/Scripts/codegen/_codegen_core.py
+++ /dev/null
@@ -1,487 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""URLab codegen — core shared data + helpers.
-
-Dependency root. Owns:
-
-- ``DiagBuffer`` — the diagnostics buffer the orchestrator + checks
- share.
-- ``_UE_TYPE_INFO`` — single source of truth for every UE type
- codegen can emit; ``_UE_TYPE_FAMILY`` and
- ``_UE_TYPES_ACCEPTING_UNITS_META`` are derived views.
-- Naming helpers, schema readers, canon-iteration helpers.
-- The 5-strategy ``_resolve_mjs_field`` chain — the bridge between
- MJCF attr names and the C struct field names MuJoCo picks.
-- ``_resolve_value_map`` — the xml_enum value-map reader.
-- ``FileWrite`` — the data class every emitter produces.
-
-Read-only against rules / schema / snapshot. No file writes, no
-UPROPERTY emission, no .cpp injection. ``generate_ue_components``
-and ``_codegen_checks`` both import from here.
-"""
-
-from __future__ import annotations
-
-import re
-import sys
-from dataclasses import dataclass
-from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence, Set, Tuple
-
-
-# ---------------------------------------------------------------------------
-# Diagnostics
-# ---------------------------------------------------------------------------
-
-@dataclass
-class Diagnostic:
- """A non-fatal codegen warning. Collected by ``_diag_add`` during a
- run and flushed once at the end via ``_diag_flush``."""
- message: str
- source: str = "" # short tag for grouping (e.g. "schema_drift")
-
-
-class DiagBuffer:
- """Collects codegen diagnostics during a run. ``pending`` is the
- queue of unflushed entries; ``fired_count`` survives the flush so
- ``main()`` can check whether ``--strict`` should exit non-zero."""
-
- def __init__(self) -> None:
- self.pending: List[Diagnostic] = []
- self.fired_count: int = 0
-
- def add(self, message: str, *, source: str = "") -> None:
- self.pending.append(Diagnostic(message=message, source=source))
-
- def flush(self) -> None:
- """Print collected diagnostics to stderr, advance ``fired_count``
- by the number flushed, and clear the pending list."""
- if not self.pending:
- return
- print(f"\n--- codegen diagnostics ({len(self.pending)}) ---",
- file=sys.stderr)
- for d in self.pending:
- print(d.message, file=sys.stderr)
- print(
- "(diagnostics are non-fatal; the codegen has emitted what it "
- "can — fix the rules to silence them.)",
- file=sys.stderr,
- )
- self.fired_count += len(self.pending)
- self.pending.clear()
-
- def reset(self) -> None:
- self.pending.clear()
- self.fired_count = 0
-
-
-_DIAGS_BUFFER = DiagBuffer()
-
-
-def _diag_add(message: str, *, source: str = "") -> None:
- _DIAGS_BUFFER.add(message, source=source)
-
-
-def _diag_flush() -> None:
- _DIAGS_BUFFER.flush()
-
-
-def _reset_diags() -> None:
- """Reset the diag buffer between runs so back-to-back invocations
- in the same Python process (test runners, integration shells)
- don't carry stale state."""
- _DIAGS_BUFFER.reset()
-
-
-# ---------------------------------------------------------------------------
-# UE type registry
-# ---------------------------------------------------------------------------
-
-@dataclass(frozen=True)
-class _UEType:
- """Single source of truth for a UE type codegen can emit. Every per-
- type dispatch (default initializer, drift-check shape, UHT Units-meta
- gate) reads this row instead of redeclaring the type universe."""
- default_init: str # C++ initializer (e.g. ``"0.0f"``)
- shape: Tuple[str, Any] # drift-check shape (see _classify_c_type)
- accepts_units_meta: bool # UHT allows Units="..." on this type
-
-
-# Every UE type codegen can target. ``_attr_default_value``,
-# ``_UE_TYPE_FAMILY``, and ``_UE_TYPES_ACCEPTING_UNITS_META`` below are
-# thin views over this dict.
-_UE_TYPE_INFO: Dict[str, _UEType] = {
- "float": _UEType("0.0f", ("scalar", "num"), True),
- "double": _UEType("0.0", ("scalar", "num"), True),
- "int32": _UEType("0", ("scalar", "int"), True),
- "uint8": _UEType("0", ("scalar", "int"), True), # synth-mirror only
- "bool": _UEType("false", ("scalar", "bool"), False),
- "FString": _UEType('TEXT("")', ("scalar", "string"), False),
- "FVector": _UEType("FVector::ZeroVector", ("vec", 3), True),
- "FQuat": _UEType("FQuat::Identity", ("vec", 4), False),
- "FLinearColor": _UEType("FLinearColor::White", ("vec", 4), False),
- "TArray": _UEType("{}", ("array", None), False),
- "TArray": _UEType("{}", ("array", None), False),
-}
-
-
-def _attr_default_value(ue_type: str) -> str:
- info = _UE_TYPE_INFO.get(ue_type)
- if info is not None:
- return info.default_init
- # Unknown types fall through to the default-construct literal — same
- # for novel TArray<...> entries (e.g. TArray) the registry
- # doesn't enumerate.
- return "{}"
-
-
-# UE type → shape for ``_check_type_shape_drift``. Derived from
-# ``_UE_TYPE_INFO`` so the type universe is declared once.
-_UE_TYPE_FAMILY = {k: v.shape for k, v in _UE_TYPE_INFO.items()}
-
-
-_UE_TYPES_ACCEPTING_UNITS_META = {
- k for k, v in _UE_TYPE_INFO.items() if v.accepts_units_meta
-}
-
-
-def _ue_type_accepts_units_meta(ue_type: str) -> bool:
- """UHT enforces 'Units' meta only on numeric scalars + numeric
- structs. Returns False for TArray<...>, FString, FLinearColor,
- FQuat — codegen silently drops the Units meta for those types so
- the build succeeds."""
- info = _UE_TYPE_INFO.get(ue_type)
- return bool(info and info.accepts_units_meta)
-
-
-_DYNAMIC_VEC_TYPES = {
- "mjFloatVec", "mjDoubleVec", "mjIntVec", "mjStringVec",
- "mjFloatVecVec", "mjDoubleVecVec", "mjIntVecVec",
-}
-
-
-_KNOWN_UE_UNITS = {
- # UE5 numeric units the editor knows how to render + (optionally)
- # convert via Display Units preferences.
- "m", "cm", "mm", "km",
- "rad", "deg",
-}
-
-
-@dataclass
-class FileWrite:
- """One file write the codegen would perform. Collected during the
- phase walk; ``apply_writes`` either flushes them to disk, prints
- diffs, or returns the count under ``--check``."""
- path: str
- content: str
-
-
-def override_toggle_name(prop_name: str) -> str:
- """``bOverride_`` is the codegen-emitted toggle field that
- gates whether the corresponding UPROPERTY's value gets written
- back to the mjs struct."""
- return f"bOverride_{prop_name}"
-
-
-# ---------------------------------------------------------------------------
-# Rule-iteration helpers
-# ---------------------------------------------------------------------------
-
-
-def iter_canon_absorbed(elem_canons: Iterable[str],
- canonicalizations: Dict[str, Any]) -> Iterator[str]:
- """Yield every attr absorbed by any canonicalisation in
- ``elem_canons``. Skips unknown canon keys silently — diagnostics
- for those live in the rule-validity drift checks."""
- if not canonicalizations:
- return
- for c in elem_canons:
- cd = canonicalizations.get(c)
- if cd:
- yield from cd.get("absorbs_attrs", ())
-
-
-def compute_canon_absorbed(elem_canons: Iterable[str],
- canonicalizations: Dict[str, Any]) -> Set[str]:
- return set(iter_canon_absorbed(elem_canons, canonicalizations))
-
-
-def iter_category_attrs(attrs: Iterable[str], *,
- global_excl: Set[str],
- elem_excl: Set[str],
- canon_absorbed: Set[str],
- extra_excl: Optional[Set[str]] = None) -> Iterator[str]:
- """Yield attrs that pass the standard codegen exclusion gates plus
- any site-specific ``extra_excl`` set the caller assembles
- (xml_enum_attrs, target-collation-absorbed, etc — these vary per
- emission stage)."""
- for attr in attrs:
- if attr in global_excl or attr in elem_excl or attr in canon_absorbed:
- continue
- if extra_excl is not None and attr in extra_excl:
- continue
- yield attr
-
-
-# ---------------------------------------------------------------------------
-# Schema readers
-# ---------------------------------------------------------------------------
-
-
-def schema_attrs(schema: Dict[str, Any], path: str) -> List[str]:
- """Read an attribute list at a dotted path, e.g.
- ``actuator_common.attrs``. Returns [] if missing."""
- cur: Any = schema
- for piece in path.split("."):
- if isinstance(cur, dict) and piece in cur:
- cur = cur[piece]
- else:
- return []
- if isinstance(cur, list):
- if cur and isinstance(cur[0], str):
- return list(cur)
- attrs: List[str] = []
- for entry in cur:
- if isinstance(entry, dict):
- if "attrs" in entry and isinstance(entry["attrs"], list):
- attrs.extend([str(x) for x in entry["attrs"]])
- else:
- for v in entry.values():
- if isinstance(v, list):
- attrs.extend([str(x) for x in v])
- seen = set()
- out = []
- for a in attrs:
- if a not in seen:
- seen.add(a)
- out.append(a)
- return out
- if isinstance(cur, dict):
- attrs2: List[str] = []
- for v in cur.values():
- if isinstance(v, list):
- attrs2.extend([str(x) for x in v if isinstance(x, str)])
- return attrs2
- return []
-
-
-def schema_subtype_attrs(schema: Dict[str, Any], category: str,
- subtype_key: str) -> List[str]:
- """Look up per-subtype attrs from schema['actuator_types'][key] /
- schema['sensor_types'] (list-of-dict). Returns [] if not found."""
- if category == "actuator":
- block = schema.get("actuator_types", {})
- if isinstance(block, dict):
- entry = block.get(subtype_key)
- if isinstance(entry, list):
- return [str(x) for x in entry]
- if isinstance(entry, dict) and "attrs" in entry:
- return [str(x) for x in entry["attrs"]]
- return []
- if category == "sensor":
- block = schema.get("sensor_types", [])
- if isinstance(block, list):
- for entry in block:
- if isinstance(entry, dict) and entry.get("name") == subtype_key:
- attrs = entry.get("attrs", [])
- return [str(x) for x in attrs] if isinstance(attrs, list) else []
- if isinstance(entry, str) and entry == subtype_key:
- return []
- return []
- return []
-
-
-# ---------------------------------------------------------------------------
-# C-type classifier (drift-check inputs)
-# ---------------------------------------------------------------------------
-
-
-def _classify_c_type(c_type: str, array_dim) -> Optional[tuple]:
- """Reduce an introspect c_type + array_dim down to a comparable
- (shape, dim_or_family) tuple. Shapes:
- ``("scalar", fam)`` — single value, fam ∈ {num,int,bool,string}
- ``("vec", N)`` — fixed-size C array of length N
- ``("array", None)`` — dynamic-length C vec (mjFloatVec, etc.)
- ``("opaque", _)`` — mjsElement* and other spec-internal
- pointers URLab never exposes; returning a
- distinct tag lets the check skip them
- without silently accepting "scalar"
- matches.
- Returns None for genuinely unknown bases so the check stays quiet
- on novel types instead of producing noise.
- """
- ct = c_type.strip()
- base_no_arr = re.sub(r"\s*\[[^\]]*\]\s*", "", ct).strip()
- base_no_ptr = base_no_arr.rstrip(" *").strip()
- if base_no_ptr in _DYNAMIC_VEC_TYPES:
- return ("array", None)
- if base_no_ptr.startswith("mjsElement") or base_no_ptr.endswith("Element"):
- return ("opaque", None)
- if "*" in ct or "mjString" in ct or "std::string" in ct:
- return ("scalar", "string")
- is_array = array_dim is not None and array_dim != 1
- base = base_no_arr
- fam: Optional[str] = None
- if base in ("mjtNum", "float", "double"):
- fam = "num"
- elif base in ("int", "mjtByte", "unsigned char", "uint8_t", "uchar"):
- fam = "int"
- elif base in ("bool", "_Bool", "mjtBool"):
- fam = "bool"
- else:
- return None
- if is_array:
- if array_dim in (3, 4):
- return ("vec", array_dim)
- return ("array", None)
- return ("scalar", fam)
-
-
-def _shapes_compatible(ue_shape: tuple, c_shape: tuple) -> bool:
- """True when ``ue_shape`` can legitimately back ``c_shape``.
-
- A ``TArray`` (array) is shape-compatible with a fixed-size C
- array (vec) because the codegen writes ``prop.Num()`` elements
- into the C array.
- Vec-to-vec requires the dim to match exactly.
- Scalar↔array always mismatches. Opaque C shapes are skipped."""
- if c_shape[0] == "opaque":
- return True
- if ue_shape[0] == c_shape[0]:
- if ue_shape[0] == "vec":
- return ue_shape[1] == c_shape[1]
- return True
- if ue_shape[0] == "array" and c_shape[0] == "vec":
- return True
- return False
-
-
-# ---------------------------------------------------------------------------
-# Vec3 convert format table
-# ---------------------------------------------------------------------------
-#
-# Maps the per-field ``apply_to_spec_mode`` rule values for FVector
-# UPROPERTYs to the per-element write template the synth-struct emitter
-# uses. Each entry is a Python format string with two slots: ``{c}``
-# (the destination C-array expression) and ``{ue}`` (the source UE
-# FVector expression).
-
-_VEC3_CONVERT_FMT = {
- "pos": "{c}[0] = {ue}.X / 100.0; {c}[1] = -{ue}.Y / 100.0; {c}[2] = {ue}.Z / 100.0;",
- "vec3_cm": "{c}[0] = {ue}.X / 100.0; {c}[1] = -{ue}.Y / 100.0; {c}[2] = {ue}.Z / 100.0;",
- "vec3_y_flip": "{c}[0] = {ue}.X; {c}[1] = -{ue}.Y; {c}[2] = {ue}.Z;",
- "passthrough": "{c}[0] = {ue}.X; {c}[1] = {ue}.Y; {c}[2] = {ue}.Z;",
-}
-
-
-# ---------------------------------------------------------------------------
-# mjs-field resolver chain (the 5-strategy bridge)
-# ---------------------------------------------------------------------------
-
-
-def _resolve_direct(attr: str, mjs_fields: Set[str]) -> Optional[str]:
- """``attr`` matches a struct field verbatim (condim -> condim)."""
- return attr if attr in mjs_fields else None
-
-
-def _resolve_name_suffix(attr: str, mjs_fields: Set[str]) -> Optional[str]:
- """``attr + "name"`` matches (mesh -> meshname). MuJoCo's name-
- ref fields uniformly append ``name`` to the schema attr."""
- cand = attr + "name"
- return cand if cand in mjs_fields else None
-
-
-def _resolve_root_name_digits(attr: str, mjs_fields: Set[str]) -> Optional[str]:
- """```` -> ``name`` (body1 ->
- bodyname1)."""
- m = re.match(r"^(.*?)(\d+)$", attr)
- if not m:
- return None
- root, digits = m.group(1), m.group(2)
- for candidate in (f"{root}name{digits}", f"{root}_name{digits}"):
- if candidate in mjs_fields:
- return candidate
- return None
-
-
-def _resolve_underscore_norm(attr: str, mjs_fields: Set[str]) -> Optional[str]:
- """Strip all underscores and look for matching letters
- (solreflimit -> solref_limit). Lossy — only used when nothing
- cleaner fits."""
- norm = attr.replace("_", "")
- for f in mjs_fields:
- if f.replace("_", "") == norm:
- return f
- return None
-
-
-def _resolve_actuator_prefix(attr: str, mjs_fields: Set[str]) -> Optional[str]:
- """Schema ``actuator*`` -> mjs ``act*`` (actuatorfrclimited ->
- actfrclimited). MuJoCo abbreviates the prefix on its struct
- fields even though the XML attr spells it out."""
- if not attr.startswith("actuator"):
- return None
- cand = "act" + attr[len("actuator"):]
- if cand in mjs_fields:
- return cand
- cand_norm = cand.replace("_", "")
- for f in mjs_fields:
- if f.replace("_", "") == cand_norm:
- return f
- return None
-
-
-_MJS_FIELD_RESOLVERS = (
- _resolve_direct,
- _resolve_name_suffix,
- _resolve_root_name_digits,
- _resolve_underscore_norm,
- _resolve_actuator_prefix,
-)
-
-
-def _resolve_mjs_field(attr: str, mjs_fields: set,
- attr_to_mjs_field: Optional[Dict[str, str]] = None) -> str:
- """Pick the correct C field name on a category's mjs struct for a
- given schema attribute. Per-element ``attr_to_mjs_field``
- overrides apply first; otherwise the ``_MJS_FIELD_RESOLVERS``
- chain captures MuJoCo's own naming conventions in priority order.
- Falls back to ``attr`` if nothing matches — the build then
- surfaces the mismatch loudly when the export line tries to access
- ``Element->attr``."""
- if attr_to_mjs_field and attr in attr_to_mjs_field:
- return attr_to_mjs_field[attr]
- if not mjs_fields:
- return attr
- for resolver in _MJS_FIELD_RESOLVERS:
- hit = resolver(attr, mjs_fields)
- if hit is not None:
- return hit
- return attr
-
-
-# ---------------------------------------------------------------------------
-# xml_enum value-map resolver
-# ---------------------------------------------------------------------------
-
-
-def _resolve_value_map(attr: str, enum_def: Dict[str, Any]) -> Dict[str, Sequence[str]]:
- """Return the ``{xml_val -> [UE_enum_member, mj_const]}`` table for
- an xml_enum attr. The rule must carry an explicit ``value_map``."""
- if "value_map" in enum_def:
- return enum_def["value_map"]
- raise RuntimeError(f"xml_enum {attr}: rule is missing value_map")
-
-
-def _value_map_pair(mapping: Any) -> Optional[Tuple[str, str]]:
- """Unpack a ``value_map`` entry into ``(ue_member, mj_const)`` or
- return None when the shape is malformed. The 4 check sites that
- used to inline ``isinstance(mapping, (list, tuple)) and len(mapping)
- >= 2`` route through here so one shape contract covers all of
- them. The corresponding emit-side path raises (see
- ``_emit_xml_enum_export``) — the rule shape contract test
- (test_rule_shape_contract.py::test_xml_enum_attr_value_maps_have_
- correct_shape) is the canonical gate; this helper is the
- runtime fallback for the drift checks."""
- if not isinstance(mapping, (list, tuple)) or len(mapping) < 2:
- return None
- return mapping[0], mapping[1]
diff --git a/Scripts/codegen/_codegen_inject.py b/Scripts/codegen/_codegen_inject.py
deleted file mode 100644
index f11d70d1..00000000
--- a/Scripts/codegen/_codegen_inject.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""URLab codegen — text-injection machinery.
-
-Pure text operations: locate ``// --- CODEGEN__START/END ---``
-marker pairs in a source file, splice a body between them, and emit
-diagnostics when the body has unbalanced braces or the markers are
-missing.
-
-The brace-aware helpers (``_find_matching_brace``,
-``_strip_cpp_braces_in_strings``, ``_check_brace_balance``) live
-here too because the banner-overwrite audit + the brace-balance
-gate both consume them."""
-
-from __future__ import annotations
-
-import os
-import re
-from typing import Dict, List, Optional, Sequence, Tuple
-
-from _codegen_core import _diag_add, FileWrite
-
-
-def _make_tag_pair(tag: str) -> Tuple[str, str]:
- return (f"// --- CODEGEN_{tag}_START ---", f"// --- CODEGEN_{tag}_END ---")
-
-
-def _strip_cpp_braces_in_strings(text: str) -> str:
- """Remove characters that look like braces but live inside a
- string/char literal or comment. Used by ``_check_brace_balance``
- so a diagnostic message containing ``"{"`` doesn't trip the
- balance gate."""
- text = re.sub(r"//[^\n]*", "", text)
- text = re.sub(r"/\*.*?\*/", "", text, flags=re.DOTALL)
- text = re.sub(r'"(?:\\.|[^"\\])*"', '""', text)
- text = re.sub(r"'(?:\\.|[^'\\])*'", "''", text)
- return text
-
-
-def _find_matching_brace(text: str, open_idx: int) -> Optional[int]:
- """Return the index of the ``}`` matching the ``{`` at
- ``open_idx``. Tracks brace depth across string/char literals and
- line/block comments so a nested ``{`` inside a TEXT(...) literal
- doesn't shift the balance. Returns None on EOF / unmatched."""
- if open_idx < 0 or open_idx >= len(text) or text[open_idx] != "{":
- return None
- depth = 1
- i = open_idx + 1
- in_str: Optional[str] = None
- while i < len(text) and depth > 0:
- ch = text[i]
- if in_str is not None:
- if ch == "\\" and i + 1 < len(text):
- i += 2
- continue
- if ch == in_str:
- in_str = None
- i += 1
- continue
- if ch == "/" and i + 1 < len(text) and text[i + 1] == "/":
- nl = text.find("\n", i)
- i = nl if nl != -1 else len(text)
- continue
- if ch == "/" and i + 1 < len(text) and text[i + 1] == "*":
- end = text.find("*/", i + 2)
- i = end + 2 if end != -1 else len(text)
- continue
- if ch in ('"', "'"):
- in_str = ch
- elif ch == "{":
- depth += 1
- elif ch == "}":
- depth -= 1
- if depth == 0:
- return i
- i += 1
- return None
-
-
-def _check_brace_balance(body: str, tag: str, source: str) -> None:
- """Emit a diagnostic when an injected block has an obvious brace
- imbalance."""
- stripped = _strip_cpp_braces_in_strings(body)
- opens = stripped.count("{")
- closes = stripped.count("}")
- if opens != closes:
- _diag_add(
- f"[diagnostic] {source}: injected block for tag "
- f"CODEGEN_{tag} has unbalanced braces (open={opens}, "
- f"close={closes}). The generated .cpp will not compile.",
- source=source,
- )
-
-
-_TAG_PATTERN_CACHE: Dict[str, "re.Pattern[str]"] = {}
-
-
-def _tag_pattern(tag: str) -> "re.Pattern[str]":
- pat = _TAG_PATTERN_CACHE.get(tag)
- if pat is None:
- start, end = _make_tag_pair(tag)
- pat = re.compile(
- r"([ \t]*)(" + re.escape(start) + r")(.*?)([ \t]*)(" + re.escape(end) + r")",
- re.DOTALL,
- )
- _TAG_PATTERN_CACHE[tag] = pat
- return pat
-
-
-def inject_between_tags(file_text: str, tag: str, new_inner: str,
- *, balance_source: Optional[str] = None) -> Tuple[str, bool]:
- """Replace the content between ``// --- CODEGEN__START ---``
- and ``// --- CODEGEN__END ---`` with ``new_inner``. Returns
- (new_text, was_found).
-
- The END marker's leading whitespace is rewritten to match the
- START marker's indent. When ``new_inner`` is empty or
- whitespace-only the block collapses so START + END sit on
- adjacent lines with no stray blank line between them.
-
- When ``balance_source`` is set, emit a diagnostic if the injected
- block has unbalanced braces."""
- pattern = _tag_pattern(tag)
- matched = [False]
-
- def repl(m: re.Match) -> str:
- matched[0] = True
- start_indent = m.group(1)
- trimmed = new_inner.rstrip()
- if trimmed:
- body = "\n" + trimmed + "\n" + start_indent
- else:
- # Empty body: collapse to one newline so START + END sit
- # adjacent (no stray blank line between them).
- body = "\n" + start_indent
- return m.group(1) + m.group(2) + body + m.group(5)
-
- new_text = pattern.sub(repl, file_text)
- if matched[0] and balance_source:
- _check_brace_balance(new_inner, tag, balance_source)
- return new_text, matched[0]
-
-
-def _inject_tags_into_cpp(
- cpp_path: str,
- tagged_bodies: Sequence[Tuple[str, str]],
- writes: List[FileWrite],
- *,
- diag_source: str,
-) -> None:
- """Open ``cpp_path`` once, inject every (tag, body) pair, surface
- a diagnostic for each missing marker pair, append (or update) a
- single FileWrite if any tag actually changed the text.
-
- Phase ordering: earlier phases (e.g. ``_phase_categories``) may have
- queued a FileWrite for the same path. Reading from disk in that case
- would be stale — the later phase would inject into the PRE-cleanup
- text and the post-cleanup IMPORT/EXPORT block would be lost on
- apply. Use the pending write's content when present, and replace
- it in-place so duplicate FileWrites for the same path don't show
- up in ``apply_writes``."""
- pending_idx: Optional[int] = None
- for i in range(len(writes) - 1, -1, -1):
- if writes[i].path == cpp_path:
- pending_idx = i
- break
-
- if pending_idx is not None:
- text = writes[pending_idx].content
- elif os.path.exists(cpp_path):
- with open(cpp_path, "r", encoding="utf-8") as f:
- text = f.read()
- else:
- _diag_add(
- f"[diagnostic] {diag_source}: host .cpp '{cpp_path}' does "
- f"not exist; no blocks injected.",
- source=diag_source,
- )
- return
-
- new_text = text
- for tag, body in tagged_bodies:
- new_text, ok = inject_between_tags(
- new_text, tag, body, balance_source=diag_source,
- )
- if not ok:
- _diag_add(
- f"[diagnostic] {diag_source}: '{cpp_path}' is missing "
- f"the CODEGEN_{tag}_START/END marker pair.",
- source=diag_source,
- )
- if new_text == text:
- return
- if pending_idx is not None:
- writes[pending_idx] = FileWrite(path=cpp_path, content=new_text)
- else:
- writes.append(FileWrite(path=cpp_path, content=new_text))
diff --git a/Scripts/codegen/_vendored/__init__.py b/Scripts/codegen/_vendored/__init__.py
deleted file mode 100644
index 0f5b8bcf..00000000
--- a/Scripts/codegen/_vendored/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Local support modules for URLab codegen.
-
-Currently holds ``ast_nodes.py`` (clang-AST node dataclasses used by
-``build_introspect_snapshot.py``). MuJoCo headers are no longer vendored
-here — ``mjspecmacro.h`` ships in the installed MuJoCo headers and is read
-from ``third_party/install`` like the other headers.
-"""
diff --git a/Scripts/codegen/_vendored/ast_nodes.py b/Scripts/codegen/_vendored/ast_nodes.py
deleted file mode 100644
index f85cc9a7..00000000
--- a/Scripts/codegen/_vendored/ast_nodes.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Lightweight AST-node dataclasses used by ``build_introspect_snapshot.py``
-to project clang.cindex AST cursors into a serialisable shape.
-
-URLab-side rather than pulled from upstream because (a) the upstream
-``clang.cindex`` types don't pickle cleanly across libclang versions and
-(b) the snapshot only needs a small subset of node info. Keeping the
-projection in one place means the schema is auditable from JSON, and
-test fixtures can be hand-built without needing a real libclang install.
-"""
-
-from __future__ import annotations
-
-from dataclasses import dataclass, field, asdict
-from typing import Any, Dict, List, Optional
-
-
-@dataclass
-class CFunctionParam:
- name: str
- c_type: str
- array_dim: Optional[int] = None # None for scalar / pointer
-
- def to_dict(self) -> Dict[str, Any]:
- return asdict(self)
-
-
-@dataclass
-class CFunction:
- name: str
- return_type: str
- params: List[CFunctionParam] = field(default_factory=list)
- doc: str = ""
- file: str = "" # source path
- line: int = 0
-
- def to_dict(self) -> Dict[str, Any]:
- return {
- "name": self.name,
- "return_type": self.return_type,
- "params": [p.to_dict() for p in self.params],
- "doc": self.doc,
- "file": self.file,
- "line": self.line,
- }
-
-
-@dataclass
-class CEnumMember:
- name: str
- value: int
- doc: str = ""
-
-
-@dataclass
-class CEnum:
- name: str
- members: List[CEnumMember] = field(default_factory=list)
- underlying_type: Optional[str] = None
- doc: str = ""
- file: str = ""
- line: int = 0
-
- def to_dict(self) -> Dict[str, Any]:
- return {
- "name": self.name,
- "members": {m.name: m.value for m in self.members},
- "member_docs": {m.name: m.doc for m in self.members if m.doc},
- "underlying_type": self.underlying_type,
- "doc": self.doc,
- "file": self.file,
- "line": self.line,
- }
-
-
-@dataclass
-class CStructField:
- name: str
- c_type: str
- array_dim: Optional[int] = None
- is_pointer: bool = False
- doc: str = ""
-
-
-@dataclass
-class CStruct:
- name: str
- fields: List[CStructField] = field(default_factory=list)
- doc: str = ""
- file: str = ""
- line: int = 0
-
- def to_dict(self) -> Dict[str, Any]:
- return {
- "name": self.name,
- "fields": [
- {
- "name": f.name,
- "c_type": f.c_type,
- "array_dim": f.array_dim,
- "is_pointer": f.is_pointer,
- "doc": f.doc,
- }
- for f in self.fields
- ],
- "doc": self.doc,
- "file": self.file,
- "line": self.line,
- }
-
-
-@dataclass
-class CDefine:
- name: str
- value: str
- doc: str = ""
- file: str = ""
- line: int = 0
-
-
-@dataclass
-class IntrospectSnapshot:
- """Top-level container for the clang-AST scrape output. Serialised
- to ``Scripts/introspect_snapshot.json``. snapshot_version bumps on
- schema-incompatible changes.
-
- ``hand_enums`` mirrors ``enums`` but covers URLab's hand-rolled
- ``EMj*`` enums under ``Source/URLab/Public``. They live in a
- separate field so the MuJoCo mjt* lookup (value_map.mj_const drift
- checks) doesn't accidentally collide with a future EMj* name."""
- snapshot_version: int = 1
- header_hash: str = ""
- functions: Dict[str, CFunction] = field(default_factory=dict)
- enums: Dict[str, CEnum] = field(default_factory=dict)
- structs: Dict[str, CStruct] = field(default_factory=dict)
- defines: Dict[str, CDefine] = field(default_factory=dict)
- hand_enums: Dict[str, CEnum] = field(default_factory=dict)
-
- def to_dict(self) -> Dict[str, Any]:
- return {
- "_meta": {
- "snapshot_version": self.snapshot_version,
- "header_hash": self.header_hash,
- },
- "functions": {n: f.to_dict() for n, f in self.functions.items()},
- "enums": {n: e.to_dict() for n, e in self.enums.items()},
- "structs": {n: s.to_dict() for n, s in self.structs.items()},
- "defines": {
- n: {"value": d.value, "doc": d.doc, "file": d.file, "line": d.line}
- for n, d in self.defines.items()
- },
- "hand_enums": {n: e.to_dict() for n, e in self.hand_enums.items()},
- }
diff --git a/Scripts/codegen/build_introspect_snapshot.py b/Scripts/codegen/build_introspect_snapshot.py
deleted file mode 100644
index b9497567..00000000
--- a/Scripts/codegen/build_introspect_snapshot.py
+++ /dev/null
@@ -1,486 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-clang.cindex-based scrape of MuJoCo headers (mjspec.h + mjmodel.h) into
-``Scripts/codegen/snapshots/introspect_snapshot.json``. The codegen
-consumes this snapshot as its single source of truth for the MuJoCo C
-API surface.
-
-Captures:
-- function signatures (every MJAPI-tagged declaration in the headers)
-- enum decls with values + per-member doc comments
-- struct decls with fields + per-field doc comments + array dims
-- ``#define`` constants (after preprocessor evaluation when literal)
-
-Usage:
- python Scripts/codegen/build_introspect_snapshot.py
- [--mujoco-include /path/to/mujoco/include]
- [--output Scripts/codegen/snapshots/introspect_snapshot.json]
- [--libclang /path/to/libclang.dll] (only if not auto-found)
-
-libclang resolution: respects ``$LIBCLANG_LIBRARY_FILE`` env var; falls
-back to clang.cindex's default search. Set ``--libclang`` to override.
-"""
-
-from __future__ import annotations
-
-import argparse
-import hashlib
-import json
-import os
-import re
-import sys
-from typing import Dict, List
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_PLUGIN_ROOT = os.path.normpath(os.path.join(_HERE, "..", ".."))
-
-# Use the local vendored ast_nodes copy.
-sys.path.insert(0, os.path.join(_HERE, "_vendored"))
-from ast_nodes import ( # noqa: E402
- CFunction,
- CFunctionParam,
- CEnum,
- CEnumMember,
- CStruct,
- CStructField,
- CDefine,
- IntrospectSnapshot,
-)
-
-
-def _header_hash(paths: List[str]) -> str:
- """SHA-256 of the concatenated header content. Lets callers skip
- re-running the snapshot when nothing upstream changed."""
- h = hashlib.sha256()
- for p in sorted(paths):
- if not os.path.exists(p):
- continue
- with open(p, "rb") as f:
- h.update(f.read())
- return h.hexdigest()
-
-
-def _strip_doc(raw: str) -> str:
- """Collapse a libclang raw doc comment into one line, stripping
- leading ``//`` / ``/*`` decoration."""
- if not raw:
- return ""
- out_lines: List[str] = []
- for line in raw.splitlines():
- s = line.strip()
- for prefix in ("///", "//!", "//", "/**", "*/", "*", "/*"):
- if s.startswith(prefix):
- s = s[len(prefix):].strip()
- break
- if s.endswith("*/"):
- s = s[:-2].strip()
- if s:
- out_lines.append(s)
- return " ".join(out_lines)
-
-
-def _walk(tu, mujoco_include: str, snapshot: IntrospectSnapshot) -> None:
- """Visit every cursor in the translation unit. ``mujoco_include`` is
- the include root; we only capture decls whose file lives under it
- (so libc / Windows SDK / TinyXML noise is filtered out)."""
- import clang.cindex as cx # noqa: E402, local-only
-
- plugin_root_norm = os.path.normcase(os.path.abspath(_PLUGIN_ROOT))
-
- def _normalised_path(loc) -> str:
- """Return the location's file as a forward-slash path relative to
- the plugin root, so the snapshot is byte-identical across
- developers (no absolute ``c:\\users\\...`` strings)."""
- if not loc or not loc.file:
- return ""
- abs_path = os.path.normcase(os.path.abspath(loc.file.name))
- if abs_path.startswith(plugin_root_norm):
- rel = os.path.relpath(abs_path, plugin_root_norm)
- return rel.replace("\\", "/")
- return abs_path.replace("\\", "/")
-
- # Filter root mirrors _normalised_path: relative-to-plugin-root with
- # forward slashes.
- mujoco_abs = os.path.normcase(os.path.abspath(mujoco_include))
- if mujoco_abs.startswith(plugin_root_norm):
- norm_root = os.path.relpath(mujoco_abs, plugin_root_norm).replace("\\", "/")
- else:
- norm_root = mujoco_abs.replace("\\", "/")
-
- for cursor in tu.cursor.get_children():
- fp = _normalised_path(cursor.location)
- if not fp.startswith(norm_root):
- continue
-
- kind = cursor.kind
-
- if kind == cx.CursorKind.FUNCTION_DECL:
- params: List[CFunctionParam] = []
- for arg in cursor.get_arguments():
- t = arg.type.spelling
- dim = None
- if "[" in t and "]" in t:
- # e.g. "double [4]" -> dim=4
- try:
- dim_str = t[t.index("[") + 1:t.index("]")]
- if dim_str.strip().isdigit():
- dim = int(dim_str)
- except ValueError:
- pass
- params.append(CFunctionParam(
- name=arg.spelling, c_type=t, array_dim=dim,
- ))
- fn = CFunction(
- name=cursor.spelling,
- return_type=cursor.result_type.spelling,
- params=params,
- doc=_strip_doc(cursor.raw_comment or ""),
- file=fp,
- line=cursor.location.line if cursor.location else 0,
- )
- snapshot.functions[fn.name] = fn
-
- elif kind == cx.CursorKind.ENUM_DECL:
- # Anonymous enums get spelling = "" — skip; we only want
- # named typedef enums. The C tag name is ``mjtJoint_`` but
- # callers reference the typedef ``mjtJoint``; normalise here.
- name = cursor.spelling or cursor.type.spelling
- if not name or name.startswith("(anonymous"):
- continue
- if name.endswith("_"):
- name = name[:-1]
- members: List[CEnumMember] = []
- for child in cursor.get_children():
- if child.kind == cx.CursorKind.ENUM_CONSTANT_DECL:
- members.append(CEnumMember(
- name=child.spelling,
- value=child.enum_value,
- doc=_strip_doc(child.raw_comment or ""),
- ))
- underlying = cursor.enum_type.spelling if cursor.enum_type else None
- snapshot.enums[name] = CEnum(
- name=name, members=members,
- underlying_type=underlying,
- doc=_strip_doc(cursor.raw_comment or ""),
- file=fp,
- line=cursor.location.line if cursor.location else 0,
- )
-
- elif kind == cx.CursorKind.STRUCT_DECL:
- name = cursor.spelling or cursor.type.spelling
- if not name:
- continue
- # Strip trailing underscore from C tag names ("mjsBody_" -> "mjsBody").
- if name.endswith("_"):
- name = name[:-1]
- fields: List[CStructField] = []
- for child in cursor.get_children():
- if child.kind != cx.CursorKind.FIELD_DECL:
- continue
- t = child.type.spelling
- dim = None
- is_ptr = "*" in t
- if "[" in t and "]" in t:
- try:
- dim_str = t[t.index("[") + 1:t.index("]")]
- if dim_str.strip().isdigit():
- dim = int(dim_str)
- except ValueError:
- pass
- fields.append(CStructField(
- name=child.spelling,
- c_type=t,
- array_dim=dim,
- is_pointer=is_ptr,
- doc=_strip_doc(child.raw_comment or ""),
- ))
- snapshot.structs[name] = CStruct(
- name=name, fields=fields,
- doc=_strip_doc(cursor.raw_comment or ""),
- file=fp,
- line=cursor.location.line if cursor.location else 0,
- )
-
- elif kind == cx.CursorKind.MACRO_DEFINITION:
- name = cursor.spelling
- # Skip function-like macros; libclang doesn't expand them.
- # Skip header guards.
- if name.endswith("_H_") or name.startswith("__"):
- continue
- # Extract tokens between the cursor's extent to get the value.
- tokens = list(tu.get_tokens(extent=cursor.extent))
- if len(tokens) < 2:
- continue
- value = " ".join(t.spelling for t in tokens[1:])
- snapshot.defines[name] = CDefine(
- name=name, value=value,
- doc=_strip_doc(cursor.raw_comment or ""),
- file=fp,
- line=cursor.location.line if cursor.location else 0,
- )
-
-
-# ---------------------------------------------------------------------------
-# URLab hand-enum scrape
-#
-# UE hand-rolled ``enum class EMj* : uint8 { ... }`` declarations live in
-# C++ headers that #include CoreMinimal.h + lots of UE machinery libclang
-# can't parse standalone. Extract each enum block via regex (the
-# delimiters are stable), strip the UE-macro surface (UMETA/UENUM/UMETA),
-# and hand the cleaned single-enum source to libclang for AST-level
-# member extraction. That gives us libclang's accuracy on member values
-# without the UE-include hell, and is byte-comparable to the regex
-# scraper that used to live in generate_ue_components.py.
-# ---------------------------------------------------------------------------
-
-_HAND_ENUM_BLOCK_RE = re.compile(
- r"(enum\s+class\s+EMj\w+\s*:\s*uint8\s*\{[^}]*\}\s*;)",
- re.DOTALL,
-)
-_HAND_ENUM_NAME_RE = re.compile(r"enum\s+class\s+(EMj\w+)")
-
-
-_UE_FN_MACRO_RE = re.compile(r"\b(UMETA|UENUM)\s*\(")
-
-
-def _strip_balanced_call(text: str, start: int) -> int:
- """Return the index just past the matching ``)`` for a function-call
- opener at ``start``. Handles nested parens — naive ``[^)]*`` would
- bail on ``UMETA(DisplayName = "Track (Centre of Mass)")``."""
- depth = 1
- i = start + 1
- in_str = None
- while i < len(text) and depth > 0:
- ch = text[i]
- if in_str:
- if ch == "\\" and i + 1 < len(text):
- i += 2
- continue
- if ch == in_str:
- in_str = None
- elif ch in ('"', "'"):
- in_str = ch
- elif ch == "(":
- depth += 1
- elif ch == ")":
- depth -= 1
- i += 1
- return i
-
-
-def _strip_ue_macros_from_enum_block(text: str) -> str:
- """Erase ``UMETA(...)`` and ``UENUM(...)`` function-like macros so a
- plain libclang pass can compile the enum block. Each macro turns
- into the empty string; the surrounding member identifiers + comma
- separators stay intact. Handles nested parens inside the macro
- argument — ``UMETA(DisplayName = "Track (Centre of Mass)")`` etc."""
- out: List[str] = []
- i = 0
- while i < len(text):
- m = _UE_FN_MACRO_RE.search(text, i)
- if not m:
- out.append(text[i:])
- break
- out.append(text[i:m.start()])
- i = _strip_balanced_call(text, m.end() - 1)
- stripped = "".join(out)
- stripped = re.sub(r"//[^\n]*", "", stripped)
- stripped = re.sub(r"/\*.*?\*/", "", stripped, flags=re.DOTALL)
- return stripped
-
-
-def _scrape_hand_enums_via_libclang(
- urlab_source_root: str,
-) -> Dict[str, CEnum]:
- """Walk every .h under ``urlab_source_root`` looking for ``enum class
- EMj* : uint8`` blocks; hand each cleaned block to libclang for
- member + value extraction.
-
- Returns ``{enum_name: CEnum}``. The plugin_root-relative path is
- stamped on each entry so the snapshot stays byte-identical across
- developer machines (no absolute ``c:\\users\\...`` strings)."""
- import clang.cindex as cx # noqa: E402, local-only
-
- plugin_root_norm = os.path.normcase(os.path.abspath(_PLUGIN_ROOT))
- out: Dict[str, CEnum] = {}
- idx = cx.Index.create()
-
- for root, _dirs, files in os.walk(urlab_source_root):
- for name in files:
- if not name.endswith(".h"):
- continue
- path = os.path.join(root, name)
- try:
- with open(path, "r", encoding="utf-8") as f:
- text = f.read()
- except OSError:
- continue
- rel = os.path.relpath(
- os.path.normcase(os.path.abspath(path)),
- plugin_root_norm,
- ).replace("\\", "/")
- for block_match in _HAND_ENUM_BLOCK_RE.finditer(text):
- block = block_match.group(1)
- name_m = _HAND_ENUM_NAME_RE.search(block)
- if not name_m:
- continue
- enum_name = name_m.group(1)
- cleaned = _strip_ue_macros_from_enum_block(block)
- # Compute 1-based source line of the enum's opening
- # ``enum`` keyword (the block_match is anchored on the
- # whole declaration, so its start offset is also the
- # enum's start).
- start_line = text[:block_match.start()].count("\n") + 1
- # UE typedefs uint8 to unsigned char; provide our own
- # typedef so libclang doesn't need any system headers
- # (which on Windows pull in MSVC STL that triggers a
- # "Unexpected compiler version" static_assert).
- tu = idx.parse(
- path=".cpp",
- args=["-x", "c++", "-std=c++17", "-nostdinc",
- "-nostdinc++", "-ferror-limit=0"],
- unsaved_files=[(
- ".cpp",
- "typedef unsigned char uint8;\n" + cleaned + "\n",
- )],
- options=cx.TranslationUnit.PARSE_SKIP_FUNCTION_BODIES,
- )
- # Don't bail on diagnostics — even with errors libclang
- # produces usable ENUM_DECL cursors. The downstream
- # match-by-name + member iteration covers correctness.
- for cursor in tu.cursor.walk_preorder():
- if cursor.kind != cx.CursorKind.ENUM_DECL:
- continue
- if cursor.spelling != enum_name:
- continue
- members: List[CEnumMember] = []
- for child in cursor.get_children():
- if child.kind == cx.CursorKind.ENUM_CONSTANT_DECL:
- members.append(CEnumMember(
- name=child.spelling,
- value=child.enum_value,
- doc="",
- ))
- if not members:
- continue
- out[enum_name] = CEnum(
- name=enum_name,
- members=members,
- underlying_type="uint8",
- doc="",
- file=rel,
- line=start_line,
- )
- break
- return out
-
-
-def main(argv: List[str] | None = None) -> int:
- ap = argparse.ArgumentParser(description=__doc__)
- ap.add_argument("--mujoco-include", default=os.path.join(
- _PLUGIN_ROOT, "third_party", "install", "MuJoCo", "include",
- ))
- ap.add_argument("--output", default=os.path.join(
- _PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "introspect_snapshot.json",
- ))
- ap.add_argument("--libclang", default=None,
- help="path to libclang.dll/.so/.dylib; overrides auto-detect")
- ap.add_argument("--urlab-source-root", default=os.path.join(
- _PLUGIN_ROOT, "Source", "URLab", "Public",
- ), help="root for the EMj* hand-enum libclang scrape; skipped if empty")
- args = ap.parse_args(argv)
-
- try:
- import clang.cindex as cx
- except ImportError:
- print("ERROR: clang.cindex not installed. Run "
- "`uv run --with libclang python build_introspect_snapshot.py` "
- "or `pip install libclang`.", file=sys.stderr)
- return 1
-
- if args.libclang:
- cx.Config.set_library_file(args.libclang)
- elif os.environ.get("LIBCLANG_LIBRARY_FILE"):
- cx.Config.set_library_file(os.environ["LIBCLANG_LIBRARY_FILE"])
-
- mujoco_include = args.mujoco_include
- if not os.path.exists(mujoco_include):
- print(f"ERROR: --mujoco-include not found: {mujoco_include}", file=sys.stderr)
- return 2
-
- mjspec_h = os.path.join(mujoco_include, "mujoco", "mjspec.h")
- mjmodel_h = os.path.join(mujoco_include, "mujoco", "mjmodel.h")
- mjxmacro_h = os.path.join(mujoco_include, "mujoco", "mjxmacro.h")
-
- # mjspecmacro.h ships in the installed MuJoCo headers (post-3.9.0); hashed
- # alongside the others so the snapshot invalidates when it changes.
- mjspecmacro_h = os.path.join(mujoco_include, "mujoco", "mjspecmacro.h")
-
- # Synthesize a small dispatch source that #includes the headers we
- # care about. Letting clang chew on a real .c lets it resolve types
- # without us threading -include flags.
- dispatch_c = "\n".join([
- "#include ",
- "#include ",
- "#include ",
- "#include ",
- ])
- args_clang = [
- "-x", "c",
- "-std=c11",
- f"-I{mujoco_include}",
- "-DMJ_STATIC", # avoid MJAPI dllimport/export linkage attrs
- ]
-
- try:
- idx = cx.Index.create()
- except cx.LibclangError as exc:
- print(f"ERROR: libclang failed to load: {exc}", file=sys.stderr)
- return 3
-
- tu = idx.parse(
- path=".c",
- args=args_clang,
- unsaved_files=[(".c", dispatch_c)],
- options=(cx.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD
- | cx.TranslationUnit.PARSE_SKIP_FUNCTION_BODIES),
- )
- fatal_diags = [d for d in tu.diagnostics if d.severity >= cx.Diagnostic.Error]
- if fatal_diags:
- print(f"libclang errors:", file=sys.stderr)
- for d in fatal_diags[:5]:
- print(f" {d.spelling} ({d.location})", file=sys.stderr)
- return 4
-
- snapshot = IntrospectSnapshot(
- snapshot_version=1,
- header_hash=_header_hash([mjspec_h, mjmodel_h, mjxmacro_h,
- mjspecmacro_h]),
- )
- _walk(tu, mujoco_include, snapshot)
-
- if args.urlab_source_root and os.path.isdir(args.urlab_source_root):
- try:
- snapshot.hand_enums = _scrape_hand_enums_via_libclang(
- args.urlab_source_root,
- )
- except cx.LibclangError as exc:
- print(f"warning: hand-enum libclang scrape skipped: {exc}",
- file=sys.stderr)
-
- out_dict = snapshot.to_dict()
- os.makedirs(os.path.dirname(args.output), exist_ok=True)
- with open(args.output, "w", encoding="utf-8") as f:
- json.dump(out_dict, f, indent=2)
- print(f"wrote {args.output}: "
- f"{len(snapshot.functions)} functions, "
- f"{len(snapshot.enums)} enums, "
- f"{len(snapshot.structs)} structs, "
- f"{len(snapshot.defines)} defines, "
- f"{len(snapshot.hand_enums)} hand_enums, "
- f"header_hash={snapshot.header_hash[:12]}")
- return 0
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
diff --git a/Scripts/codegen/build_mjcf_schema_snapshot.py b/Scripts/codegen/build_mjcf_schema_snapshot.py
deleted file mode 100644
index 634d4484..00000000
--- a/Scripts/codegen/build_mjcf_schema_snapshot.py
+++ /dev/null
@@ -1,594 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Parse the MJCF schema declaration in MuJoCo's ``xml_native_reader.cc``
-and emit ``Scripts/mjcf_schema_snapshot.json`` in URLab's curated shape.
-
-The schema source lives in a single C++ initializer-list array
-``std::vector MJCF[nMJCF]`` and looks like:
-
- {"body", "*", "name", "childclass", "pos", ...},
- {"<"},
- {"inertial", "?", "pos", "mass", ...},
- {"joint", "*", "name", "type", ...},
- ...
- {">"},
-
-This script tokenises that file into (element, occurrence, attrs) tuples
-with parent/child relationships derived from the ``"<"`` / ``">"`` markers,
-then projects the tree onto URLab's hand-curated snapshot shape (the same
-shape codegen_rules.json consumes).
-
-Usage:
- python Scripts/codegen/build_mjcf_schema_snapshot.py
- [--src PATH] (default: third_party/MuJoCo/src/src/xml/xml_native_reader.cc)
- [--output PATH] (default: Scripts/mjcf_schema_snapshot.json)
-"""
-from __future__ import annotations
-
-import argparse
-import datetime as _dt
-import json
-import os
-import re
-import sys
-from dataclasses import dataclass, field
-from typing import Dict, List, Optional
-
-
-# ----------------------------------------------------------------------------
-# Parsing
-# ----------------------------------------------------------------------------
-
-# Matches one C++ initializer block on a line, capturing the comma-separated
-# string list inside the outer braces. We deliberately tolerate any whitespace,
-# trailing commas, and continuation across lines.
-_BLOCK_RE = re.compile(r"\{((?:[^{}]|\{[^}]*\})*?)\}\s*,?", re.DOTALL)
-_STRING_RE = re.compile(r'"([^"\\]*)"')
-
-
-@dataclass
-class SchemaNode:
- name: str
- occurrence: str = "*"
- attrs: List[str] = field(default_factory=list)
- children: List["SchemaNode"] = field(default_factory=list)
-
-
-def _extract_mjcf_block(src_text: str) -> str:
- """Pull out the body of ``std::vector MJCF[nMJCF] = { ... };``."""
- start_marker = "MJCF[nMJCF]"
- i = src_text.find(start_marker)
- if i < 0:
- raise SystemExit(f"could not find '{start_marker}' in source")
- # find the '=' then the opening '{'
- eq = src_text.find("=", i)
- open_brace = src_text.find("{", eq)
- # walk braces to find the matching close
- depth = 0
- j = open_brace
- n = len(src_text)
- while j < n:
- c = src_text[j]
- if c == "{":
- depth += 1
- elif c == "}":
- depth -= 1
- if depth == 0:
- # strip the outermost braces — return body
- return src_text[open_brace + 1:j]
- j += 1
- raise SystemExit("unbalanced braces in MJCF declaration")
-
-
-def _tokenise_blocks(body: str) -> List[List[str]]:
- """Return a flat list of ``[strings...]`` for each ``{...}`` block in the
- MJCF body, in source order. Comments are stripped (``//`` line comments
- and ``/* ... */`` block comments)."""
- # Strip /* ... */
- body = re.sub(r"/\*.*?\*/", "", body, flags=re.DOTALL)
- # Strip // ... to end-of-line
- body = re.sub(r"//[^\n]*", "", body)
-
- blocks: List[List[str]] = []
- for m in _BLOCK_RE.finditer(body):
- inner = m.group(1)
- strings = _STRING_RE.findall(inner)
- if strings:
- blocks.append(strings)
- return blocks
-
-
-def _parse_tree(blocks: List[List[str]]) -> SchemaNode:
- """Build a tree from the flat block list using ``"<"`` / ``">"`` markers."""
- root = SchemaNode(name="__root__")
- # Each entry on the stack is (parent_node, last_added_child_under_it).
- # When we see ``"<"`` we recurse INTO the last child of the current top.
- # When we see ``">"`` we pop back out.
- stack: List[SchemaNode] = [root]
- for block in blocks:
- head = block[0]
- if head == "<":
- # Open scope on the last-added child of the current top.
- top = stack[-1]
- if not top.children:
- # Defensive: malformed input. Fall back to treating the
- # current top itself as the scope.
- stack.append(top)
- else:
- stack.append(top.children[-1])
- continue
- if head == ">":
- stack.pop()
- continue
- # Element declaration: ("name", "occurrence", "attr1", "attr2", ...)
- occ = block[1] if len(block) > 1 else "*"
- attrs = block[2:]
- node = SchemaNode(name=head, occurrence=occ, attrs=list(attrs))
- stack[-1].children.append(node)
- return root
-
-
-def _find_child(parent: SchemaNode, name: str) -> Optional[SchemaNode]:
- for c in parent.children:
- if c.name == name:
- return c
- return None
-
-
-# ----------------------------------------------------------------------------
-# Bucketing into URLab's curated snapshot shape
-# ----------------------------------------------------------------------------
-
-# Top-level worldbody children whose attrs we expose directly. The schema also
-# has these under ; we use the worldbody copy because it carries
-# `name`/`class` which the default copy doesn't.
-_WORLDBODY_DIRECT = [
- "body", "inertial", "joint", "freejoint", "geom", "site",
- "camera", "light",
-]
-
-
-# URLab convention for splitting per-subtype attr lists into "common" (lives
-# on the base UMjActuator / UMjSensor) vs "extras" (lives on the subtype).
-# These are NOT strict intersections — they're the URLab-side curation of
-# "what makes sense as a shared base attr". Without baking them in, new
-# MuJoCo subtypes that don't carry every common attr would shrink the
-# intersection and force the codegen to re-emit common attrs on every
-# subtype.
-#
-# When MuJoCo adds a brand-new attr that should be considered "common" (e.g.
-# a new lifecycle hook on every actuator), extend the list below. The
-# extractor's "added attrs to known elements" warning will surface the
-# candidate.
-_ACTUATOR_COMMON_ATTRS = [
- "name", "class", "group", "nsample", "interp", "delay",
- "ctrllimited", "forcelimited", "actlimited",
- "ctrlrange", "forcerange", "actrange", "lengthrange",
- "gear", "damping", "armature", "cranklength", "user",
-]
-_ACTUATOR_TARGETS = [
- "joint", "jointinparent", "tendon",
- "slidersite", "cranksite", "site", "refsite",
-]
-_SENSOR_COMMON_ATTRS = [
- "name", "nsample", "interp", "delay", "interval",
- "cutoff", "noise", "user",
-]
-
-
-# ----------------------------------------------------------------------------
-# Per-sensor objtype/reftype extraction
-# ----------------------------------------------------------------------------
-#
-# The static MJCF[nMJCF] schema only carries attr lists — not the per-sensor
-# mapping between the XML element name and the mjsSensor objtype/reftype the
-# compiler expects. That logic lives in xml_native_reader.cc's `Sensor()`
-# method (a giant if/else cascade, one branch per sensor type). The codegen
-# scrapes those branches here so rules don't have to hand-list them.
-
-# Inside Sensor(), each "regular" branch follows:
-# if (type == "") {
-# sensor->type = mjSENS_X;
-# sensor->objtype = mjOBJ_Y; // OPTIONAL: literal default
-# ReadAttrTxt(elem, "", objname, true); // OPTIONAL: name source
-# sensor->reftype = mjOBJ_Z; // OPTIONAL
-# ReadAttrTxt(elem, "", refname, true); // OPTIONAL: ref name source
-# }
-#
-# "Computed" branches (rangefinder, distance/normal/fromto, contact, user,
-# plugin) derive objtype/reftype from attribute presence at parse time;
-# those get marked computed=True so codegen rules keep their explicit
-# overrides for them.
-# Matches the open of a sensor branch, capturing the parenthesised condition
-# string. We post-process the condition to pull out every ``type == "NAME"``
-# clause so ``else if (type == "distance" || type == "normal" || type ==
-# "fromto") { ... }`` produces three entries that share the branch body.
-_SENSOR_BRANCH_RE = re.compile(
- r'(?:if|else if)\s*\((?P[^{]*?type\s*==\s*"[^"]+"[^{]*)\)\s*\{',
- re.DOTALL,
-)
-_SENSOR_NAMES_IN_COND_RE = re.compile(r'type\s*==\s*"([^"]+)"')
-_TYPE_LITERAL_RE = re.compile(r'sensor->type\s*=\s*(mjSENS_\w+)\s*;')
-_OBJTYPE_LITERAL_RE = re.compile(r'sensor->objtype\s*=\s*(mjOBJ_\w+)\s*;')
-_REFTYPE_LITERAL_RE = re.compile(r'sensor->reftype\s*=\s*(mjOBJ_\w+)\s*;')
-_OBJTYPE_FROM_XML_RE = re.compile(
- r'ReadAttrTxt\s*\(\s*elem\s*,\s*"objtype"\s*,\s*text'
-)
-_NAME_READ_RE = re.compile(
- r'ReadAttrTxt\s*\(\s*elem\s*,\s*"([^"]+)"\s*,\s*(objname|refname)\b'
-)
-
-
-def _slice_balanced_braces(src: str, open_idx: int) -> str:
- """Given an index pointing AT '{', return the substring up to the
- matching close (exclusive of both braces). Tracks string literals and
- line/block comments so braces inside ``"..."``, ``//`` or ``/* */`` are
- ignored. Returns "" if no matching close found."""
- assert src[open_idx] == "{"
- n = len(src)
- depth = 0
- i = open_idx
- in_str = False
- str_q = ""
- in_line_comment = False
- in_block_comment = False
- while i < n:
- c = src[i]
- c2 = src[i:i+2]
- if in_line_comment:
- if c == "\n":
- in_line_comment = False
- i += 1
- continue
- if in_block_comment:
- if c2 == "*/":
- in_block_comment = False
- i += 2
- continue
- i += 1
- continue
- if in_str:
- if c == "\\":
- i += 2
- continue
- if c == str_q:
- in_str = False
- i += 1
- continue
- if c2 == "//":
- in_line_comment = True
- i += 2
- continue
- if c2 == "/*":
- in_block_comment = True
- i += 2
- continue
- if c in ('"', "'"):
- in_str = True
- str_q = c
- i += 1
- continue
- if c == "{":
- depth += 1
- elif c == "}":
- depth -= 1
- if depth == 0:
- return src[open_idx+1:i]
- i += 1
- return ""
-
-
-# Branches where objtype/reftype are derived from attribute presence at
-# parse time (multiple ReadAttrTxt + sensor->objtype = X ? mjOBJ_A : mjOBJ_B
-# pattern). Codegen rules keep explicit overrides for these; the extractor
-# marks them computed=True so the generated codegen doesn't pretend to know.
-_COMPUTED_OBJTYPE_SENSORS = {
- "rangefinder", "distance", "normal", "fromto", "contact",
- "user", "plugin",
-}
-
-
-def _extract_sensor_per_type(src_text: str) -> Dict[str, Dict[str, object]]:
- """Scrape ``Sensor()``'s per-type if/else cascade. Returns a dict
- keyed by XML element name; each entry has:
-
- objtype: "mjOBJ_X" | "from_xml" | "computed" | None
- reftype: "mjOBJ_Y" | "computed" | None
- obj_attr: "site"/"joint"/.../None (XML attr name carrying objname)
- ref_attr: "camera"/"site"/.../None (XML attr name carrying refname)
- computed: True iff objtype/reftype are derived from attr presence
- """
- # Slice out the Sensor() method body so we don't pick up branches from
- # other methods that happen to share regex shapes.
- sig_re = re.compile(r"void\s+mjXReader::Sensor\s*\(")
- m = sig_re.search(src_text)
- if not m:
- return {}
- open_idx = src_text.find("{", m.end())
- if open_idx < 0:
- return {}
- body = _slice_balanced_braces(src_text, open_idx)
- if not body:
- return {}
-
- result: Dict[str, Dict[str, object]] = {}
- # Some outer branches (distance/normal/fromto, contact, plugin) contain
- # an inner ``if (type == "X")`` that toggles ->type. Those inner matches
- # would otherwise overwrite the outer-branch entry with a stripped-down
- # body. Track the [start, end) of each outer-branch body and skip
- # matches whose '{' falls inside.
- consumed_ranges: List[tuple] = []
- for bm in _SENSOR_BRANCH_RE.finditer(body):
- names = _SENSOR_NAMES_IN_COND_RE.findall(bm.group("cond"))
- if not names:
- continue
- brace_idx = bm.end() - 1
- if brace_idx < 0 or body[brace_idx] != "{":
- continue
- if any(s < brace_idx < e for s, e in consumed_ranges):
- continue
- branch = _slice_balanced_braces(body, brace_idx)
- consumed_ranges.append((brace_idx, brace_idx + 1 + len(branch)))
-
- obj_literal = _OBJTYPE_LITERAL_RE.search(branch)
- ref_literal = _REFTYPE_LITERAL_RE.search(branch)
- obj_from_xml = bool(_OBJTYPE_FROM_XML_RE.search(branch)) and not obj_literal
-
- obj_attr: Optional[str] = None
- ref_attr: Optional[str] = None
- for nm in _NAME_READ_RE.finditer(branch):
- attr, target = nm.group(1), nm.group(2)
- if attr == "objtype":
- continue # the literal "objtype" attr selector, not a name source
- if target == "objname" and obj_attr is None:
- obj_attr = attr
- elif target == "refname" and ref_attr is None:
- ref_attr = attr
-
- # Capture the mjSENS_X assigned in this branch. Multi-name branches
- # (distance/normal/fromto) carry an inner positional switch with
- # one ->type per name. Single-name branches (touch, framepos, ...)
- # have exactly one mjSENS_X.
- mj_types = [m.group(1) for m in _TYPE_LITERAL_RE.finditer(branch)]
- if len(mj_types) == len(names):
- name_to_mj_type = dict(zip(names, mj_types))
- elif mj_types:
- # Single-type branch — every name shares it.
- name_to_mj_type = {n: mj_types[0] for n in names}
- else:
- name_to_mj_type = {n: None for n in names}
-
- # Multi-name branches (distance/normal/fromto share one block,
- # routed inside by `if (type == ...)` to set ->type). All share
- # the same objtype/reftype derivation, so emit one entry per name.
- for name in names:
- computed = name in _COMPUTED_OBJTYPE_SENSORS
- result[name] = {
- "mj_type": name_to_mj_type.get(name),
- "objtype": ("computed" if computed
- else ("from_xml" if obj_from_xml
- else (obj_literal.group(1) if obj_literal else None))),
- "reftype": ("computed" if computed
- else (ref_literal.group(1) if ref_literal else None)),
- "obj_attr": obj_attr,
- "ref_attr": ref_attr,
- "computed": computed,
- }
- return result
-
-
-def _build_snapshot(root: SchemaNode, mujoco_version: str, *,
- src_text: str = "") -> Dict:
- """Walk the parsed MJCF tree and project it onto URLab's curated shape."""
- out: Dict = {
- "_meta": {
- "mujoco_version": mujoco_version,
- "snapshot_date": _dt.date.today().isoformat(),
- "source": "https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc",
- "description": (
- "MJCF schema snapshot, auto-extracted by "
- "Scripts/codegen/build_mjcf_schema_snapshot.py from the "
- "MuJoCo submodule's xml_native_reader.cc."
- ),
- }
- }
-
- mujoco = _find_child(root, "mujoco")
- if mujoco is None:
- raise SystemExit("schema source: no root element")
-
- # There is no explicit ```` declaration in the MJCF[] schema —
- # ```` sits directly under ```` with occurrence "R"
- # (recursive). That body's child list is what the runtime parser uses
- # for both worldbody contents and nested-body contents.
- body = _find_child(mujoco, "body")
-
- # Top-level worldbody-like elements (attrs + children). The body itself
- # is the worldbody schema; geom/joint/inertial/site/camera/light/etc.
- # live underneath it.
- for name in _WORLDBODY_DIRECT:
- node = body if name == "body" else (_find_child(body, name) if body else None)
- if node is None:
- continue
- entry: Dict = {"attrs": list(node.attrs)}
- if node.children:
- entry["children"] = [c.name for c in node.children]
- out[name] = entry
-
- # Actuator section. Each subtype's full attr list lives directly under
- # . URLab's curated shape splits this into:
- # actuator_common.attrs (URLab convention, _ACTUATOR_COMMON_ATTRS above)
- # actuator_common.targets (transmission target attrs, _ACTUATOR_TARGETS)
- # actuator_types[name] (per-subtype EXTRAS only)
- actuator = _find_child(mujoco, "actuator")
- if actuator is not None:
- type_attrs = {c.name: list(c.attrs) for c in actuator.children
- if c.name != "plugin"}
- common_set = set(_ACTUATOR_COMMON_ATTRS)
- targets_set = set(_ACTUATOR_TARGETS)
- out["actuator_common"] = {
- "attrs": list(_ACTUATOR_COMMON_ATTRS),
- "targets": list(_ACTUATOR_TARGETS),
- }
- actuator_types: Dict[str, List[str]] = {}
- for name, attrs in type_attrs.items():
- extras = [a for a in attrs
- if a not in common_set and a not in targets_set]
- actuator_types[name] = extras
- out["actuator_types"] = actuator_types
-
- # Sensor section: per-type attr declarations. URLab tracks:
- # sensor_types = list of names
- # sensor_common = shared attrs (_SENSOR_COMMON_ATTRS, URLab convention)
- # sensor_per_type = per-sensor objtype/reftype/attr defaults scraped
- # from xml_native_reader.cc's Sensor() method body
- sensor = _find_child(mujoco, "sensor")
- if sensor is not None:
- sensor_attrs = {c.name: list(c.attrs) for c in sensor.children}
- out["sensor_types"] = list(sensor_attrs.keys())
- out["sensor_common"] = {"attrs": list(_SENSOR_COMMON_ATTRS)}
- if src_text:
- per_type = _extract_sensor_per_type(src_text)
- # Only emit per-type rows for sensors that exist in the static
- # MJCF schema — keeps the snapshot in sync if MuJoCo adds a
- # parser branch but not a schema entry (or vice versa).
- out["sensor_per_type"] = {
- name: per_type[name] for name in sensor_attrs
- if name in per_type
- }
-
- # Tendon section: spatial vs fixed, plus wrap types.
- tendon = _find_child(mujoco, "tendon")
- if tendon is not None:
- tdict: Dict[str, Dict] = {}
- for sub in tendon.children:
- entry = {"attrs": list(sub.attrs)}
- if sub.children:
- entry["wrap_types"] = [c.name for c in sub.children]
- tdict[sub.name] = entry
- out["tendon"] = tdict
-
- # Equality section.
- equality = _find_child(mujoco, "equality")
- if equality is not None:
- out["equality"] = {c.name: list(c.attrs) for c in equality.children}
-
- # Contact section (pair + exclude).
- contact = _find_child(mujoco, "contact")
- if contact is not None:
- out["contact"] = {c.name: list(c.attrs) for c in contact.children}
-
- # Asset section (mesh / hfield / texture / material / etc.).
- asset = _find_child(mujoco, "asset")
- if asset is not None:
- out["asset"] = {c.name: list(c.attrs) for c in asset.children}
-
- # Compiler section.
- compiler = _find_child(mujoco, "compiler")
- if compiler is not None:
- out["compiler"] = {"attrs": list(compiler.attrs)}
-
- # Option section (top-level attrs + sub-element).
- option = _find_child(mujoco, "option")
- if option is not None:
- opt_entry: Dict[str, List[str]] = {"attrs": list(option.attrs)}
- flag = _find_child(option, "flag")
- if flag is not None:
- opt_entry["flag"] = list(flag.attrs)
- out["option"] = opt_entry
-
- # Keyframe section: -> .
- keyframe = _find_child(mujoco, "keyframe")
- if keyframe is not None:
- key = _find_child(keyframe, "key")
- if key is not None:
- out["keyframe"] = {"key": list(key.attrs)}
-
- # Default section: just the child element names the codegen needs to
- # know about so it can wire UMjDefault sub-component creation.
- default = _find_child(mujoco, "default")
- if default is not None:
- # Filter out nested defaults — only direct element children.
- kids = [c.name for c in default.children
- if c.name not in ("default", "config")]
- out["default"] = {"child_elements": kids}
-
- # Deformable/flexcomp/flex — capture top-level attrs for downstream rules.
- deformable = _find_child(mujoco, "deformable")
- if deformable is not None:
- for c in deformable.children:
- out[c.name] = {"attrs": list(c.attrs)}
- if c.children:
- out[c.name]["children"] = [cc.name for cc in c.children]
- # flexcomp lives under body, not .
- flexcomp = _find_child(body, "flexcomp") if body else None
- if flexcomp is not None:
- out["flexcomp"] = {"attrs": list(flexcomp.attrs)}
- if flexcomp.children:
- out["flexcomp"]["children"] = [c.name for c in flexcomp.children]
-
- return out
-
-
-# ----------------------------------------------------------------------------
-# Main
-# ----------------------------------------------------------------------------
-
-def _detect_mujoco_version(src_path: str) -> str:
- """Read the version from include/mujoco/mujoco.h next to xml_native_reader.cc."""
- # src_path is .../mujoco/src/xml/xml_native_reader.cc
- repo_root = os.path.normpath(os.path.join(os.path.dirname(src_path), "..", ".."))
- header = os.path.join(repo_root, "include", "mujoco", "mujoco.h")
- if not os.path.exists(header):
- return "unknown"
- with open(header, "r", encoding="utf-8") as f:
- head = f.read(4096)
- # MuJoCo encodes the version as MMmmpp (e.g. 3008001 = 3.8.1) — 7 digits
- # for 3.10+, 6 digits before. Parse the last 3 digit pairs as patch/minor/major.
- m = re.search(r"#define\s+mjVERSION_HEADER\s+(\d+)", head)
- if m:
- v = int(m.group(1))
- patch = v % 1000
- minor = (v // 1000) % 1000
- major = v // 1000000
- return f"{major}.{minor}.{patch}"
- return "unknown"
-
-
-def main(argv: Optional[List[str]] = None) -> int:
- here = os.path.dirname(os.path.abspath(__file__))
- plugin_root = os.path.normpath(os.path.join(here, "..", ".."))
- default_src = os.path.join(
- plugin_root, "third_party", "MuJoCo", "src", "src", "xml",
- "xml_native_reader.cc",
- )
- default_output = os.path.join(plugin_root, "Scripts", "codegen", "snapshots", "mjcf_schema_snapshot.json")
-
- ap = argparse.ArgumentParser()
- ap.add_argument("--src", default=default_src,
- help=f"MuJoCo xml_native_reader.cc (default: {default_src})")
- ap.add_argument("--output", default=default_output,
- help=f"Output JSON path (default: {default_output})")
- args = ap.parse_args(argv)
-
- if not os.path.exists(args.src):
- print(f"error: schema source not found: {args.src}", file=sys.stderr)
- return 2
-
- with open(args.src, "r", encoding="utf-8") as f:
- src_text = f.read()
- body = _extract_mjcf_block(src_text)
- blocks = _tokenise_blocks(body)
- root = _parse_tree(blocks)
- version = _detect_mujoco_version(args.src)
- snapshot = _build_snapshot(root, mujoco_version=version, src_text=src_text)
-
- os.makedirs(os.path.dirname(args.output), exist_ok=True)
- with open(args.output, "w", encoding="utf-8") as f:
- json.dump(snapshot, f, indent=2)
- f.write("\n")
- print(f"wrote {args.output}: mujoco_version={version}, top-level keys={len(snapshot) - 1}")
- return 0
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/Scripts/codegen/build_mjxmacro_snapshot.py b/Scripts/codegen/build_mjxmacro_snapshot.py
deleted file mode 100644
index f226da2a..00000000
--- a/Scripts/codegen/build_mjxmacro_snapshot.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-#
-# 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
-"""
-Parse MuJoCo's mjxmacro.h into a machine-readable JSON snapshot.
-
-Output: Scripts/mjxmacro_snapshot.json with mjModel/mjData pointer
-fields grouped by category, plus mjOption / mjStatistic / mjVisual
-field lists for top-level struct codegen.
-
-Each entry carries the C type, field name, outer dimension (e.g.
-``njnt``, ``nv``), and inner stride (e.g. ``1``, ``3``, ``mjNREF``,
-``MJ_M(nuser_jnt)`` for runtime-dimensioned arrays).
-"""
-
-from __future__ import annotations
-
-import json
-import os
-import re
-import sys
-from typing import Any, Dict, List, Optional
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "..", ".."))
-DEFAULT_MJXMACRO = os.path.join(
- PLUGIN_ROOT, "third_party", "install", "MuJoCo", "include", "mujoco", "mjxmacro.h"
-)
-DEFAULT_OUTPUT = os.path.join(PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "mjxmacro_snapshot.json")
-
-# Block names we care about. Categorized so the consumer knows the
-# kind of data (per-element pointer table vs flat struct fields).
-POINTER_BLOCKS_MJMODEL = [
- "MJMODEL_POINTERS_BODY",
- "MJMODEL_POINTERS_JOINT",
- "MJMODEL_POINTERS_DOF",
- "MJMODEL_POINTERS_TREE",
- "MJMODEL_POINTERS_GEOM",
- "MJMODEL_POINTERS_SITE",
- "MJMODEL_POINTERS_CAMERA",
- "MJMODEL_POINTERS_LIGHT",
- "MJMODEL_POINTERS_FLEX",
- "MJMODEL_POINTERS_FLEXVERT",
- "MJMODEL_POINTERS_FLEXEDGE",
- "MJMODEL_POINTERS_FLEXELEM",
- "MJMODEL_POINTERS_FLEXTEXCOORD",
- "MJMODEL_POINTERS_MESH",
- "MJMODEL_POINTERS_SKIN",
- "MJMODEL_POINTERS_HFIELD",
- "MJMODEL_POINTERS_TEXTURE",
- "MJMODEL_POINTERS_MATERIAL",
- "MJMODEL_POINTERS_PAIR",
- "MJMODEL_POINTERS_EXCLUDE",
- "MJMODEL_POINTERS_EQUALITY",
- "MJMODEL_POINTERS_TENDON",
- "MJMODEL_POINTERS_ACTUATOR",
- "MJMODEL_POINTERS_SENSOR",
- "MJMODEL_POINTERS_NUMERIC",
- "MJMODEL_POINTERS_TEXT",
- "MJMODEL_POINTERS_TUPLE",
- "MJMODEL_POINTERS_KEY",
- "MJMODEL_POINTERS_PLUGIN",
- "MJMODEL_POINTERS_NAMES",
- "MJMODEL_POINTERS_PATHS",
-]
-
-POINTER_BLOCKS_MJDATA = [
- "MJDATA_POINTERS_PREAMBLE",
- "MJDATA_POINTERS",
- "MJDATA_ARENA_POINTERS",
- "MJDATA_ARENA_POINTERS_PRIMAL",
- "MJDATA_ARENA_POINTERS_DUAL",
- "MJDATA_ARENA_POINTERS_ISLAND",
- "MJDATA_ARENA_POINTERS_SOLVER",
- "MJDATA_ARENA_POINTERS_CONTACT",
-]
-
-# Flat struct field blocks (no outer dimension — just type + name + size).
-# Lives across both mjxmacro.h (the mjmodel-side struct fields) and
-# mjspecmacro.h (the mjspec-side struct fields).
-STRUCT_FIELD_BLOCKS = [
- "MJOPTION_FIELDS",
- "MJSTATISTIC_FIELDS",
- "MJVISUAL_GLOBAL_FIELDS",
- "MJVISUAL_QUALITY_FIELDS",
- "MJVISUAL_HEADLIGHT_FIELDS",
- "MJVISUAL_MAP_FIELDS",
- "MJVISUAL_SCALE_FIELDS",
- "MJVISUAL_RGBA_FIELDS",
- "MJSCOMPILER_FIELDS",
- "MJSPEC_FIELDS",
-]
-
-# mjspecmacro.h ships in the installed MuJoCo headers (added upstream after
-# 3.9.0; present from our main-pinned build onward), so we read it from the
-# install like mjxmacro.h — no longer vendored.
-DEFAULT_MJSPECMACRO = os.path.join(
- PLUGIN_ROOT, "third_party", "install", "MuJoCo", "include", "mujoco", "mjspecmacro.h"
-)
-
-# Regexes
-_BLOCK_START_RE = re.compile(r"^\s*#define\s+(\w+)\s*(?:\(\s*\w+\s*\))?\s*\\?\s*$")
-# Single source of truth for the X-macro tag set. Accepts X / XVEC / XNV.
-# XNV ("X No Vec") is structurally identical to X (same 4-tuple shape);
-# MuJoCo uses the tag so its own codegen knows to skip the vectorised
-# emission path. URLab doesn't care about that distinction — we just want
-# the entry shape. Add new tags here whenever MuJoCo introduces one;
-# duplicating the list in a sibling regex is the bug class that bit XNV.
-_X_TAG_RE = r"X(?:VEC|NV)?"
-# X-macro entry. Tolerates 4 or 3-tuple forms (pointer vs flat field).
-# Captures parenthesised contents; field split below trims/normalizes.
-_X_ENTRY_RE = re.compile(rf"^\s*{_X_TAG_RE}\s*\(\s*(.*?)\s*\)\s*\\?\s*$")
-
-
-def _strip_comments(text: str) -> str:
- # Drop //... comments + /* ... */ blocks.
- text = re.sub(r"//[^\n]*", "", text)
- text = re.sub(r"/\*.*?\*/", "", text, flags=re.DOTALL)
- return text
-
-
-_BODY_ENTRY_RE = re.compile(rf"^\s*{_X_TAG_RE}\s*\(")
-
-
-def _parse_block_body(lines: List[str], start_idx: int) -> List[str]:
- """Collect the entries of a block starting at ``start_idx``. Returns
- the entry lines as raw strings (each looks like ``X ( ... )`` or
- ``XVEC ( ... )``). Stops at the first non-entry, non-empty line."""
- out: List[str] = []
- i = start_idx
- while i < len(lines):
- line = lines[i]
- stripped = line.strip()
- if not stripped:
- break
- if _BODY_ENTRY_RE.match(stripped):
- out.append(stripped.rstrip("\\").rstrip())
- i += 1
- continue
- break
- return out
-
-
-def _split_csv(tup: str) -> List[str]:
- """Split a comma-separated tuple body that may contain MJ_M(...) calls."""
- parts: List[str] = []
- depth = 0
- cur: List[str] = []
- for ch in tup:
- if ch == "," and depth == 0:
- parts.append("".join(cur).strip())
- cur = []
- continue
- if ch == "(":
- depth += 1
- elif ch == ")":
- depth -= 1
- cur.append(ch)
- if cur:
- parts.append("".join(cur).strip())
- return parts
-
-
-def _parse_pointer_entry(raw: str) -> Optional[Dict[str, Any]]:
- """Parse `X(type, name, outer_dim, stride)` or `XVEC(...)`."""
- m = _X_ENTRY_RE.match(raw)
- if not m:
- return None
- fields = _split_csv(m.group(1))
- if len(fields) == 4:
- ctype, name, outer_dim, stride = fields
- return {
- "type": ctype,
- "name": name,
- "outer_dim": outer_dim,
- "stride": stride,
- }
- return None
-
-
-def _parse_struct_field_entry(raw: str) -> Optional[Dict[str, Any]]:
- """Parse `X(type, name, count)` or `X(name, count)` or `X(name)` or `XVEC(...)`.
-
- mjxmacro flat-struct blocks have a few shapes:
- - `X(type, name, count)` (mjOption)
- - `X(name, count)` (mjStatistic — no type, defaults to mjtNum)
- - `X(type, name)` (mjVisual fields — no explicit count, treated as scalar)
- - `X(name)` (mjVisualQuality/Map/Scale/Rgba — bare field name; type is
- whatever the corresponding ``struct mjVisualX`` member is. URLab
- defaults to mjtNum since these structs are float/int in practice and
- consumers can override via ``field_types``.)
- - `XVEC(type, name, count)` (vec3 / vec5 / etc.)
- """
- m = _X_ENTRY_RE.match(raw)
- if not m:
- return None
- fields = _split_csv(m.group(1))
- is_vec = raw.lstrip().startswith("XVEC")
- if len(fields) == 3:
- ctype, name, count = fields
- elif len(fields) == 2:
- # Could be (type, name) or (name, count). If first token looks
- # like a C type keep it as type; else treat as (name, count) and
- # default type to mjtNum.
- if fields[0] in ("int", "float", "mjtNum", "mjtByte", "char"):
- ctype, name, count = fields[0], fields[1], "1"
- else:
- ctype, name, count = "mjtNum", fields[0], fields[1]
- elif len(fields) == 1:
- # Bare field name — type defaults to mjtNum, scalar.
- ctype, name, count = "mjtNum", fields[0], "1"
- else:
- return None
- return {
- "type": ctype,
- "name": name,
- "count": count,
- "is_vec": is_vec,
- }
-
-
-# Block names from MuJoCo's X-macro headers that we KNOWINGLY do not
-# consume — additions are still flagged at parse time so a new block
-# can't disappear silently, but listed names produce no warning.
-KNOWN_UNCONSUMED_BLOCKS = {
- # Sentinels / size constants — defined as #define X foo without a body.
- "MJMODEL_POINTERS_PREAMBLE",
- "MJMODEL_POINTERS", # meta-aggregator (re-includes all POINTERS_* blocks)
- "MJMODEL_SIZES", # int field counts
- "MJMODEL_INTS",
- "MJMODEL_INTS_PREAMBLE",
- "MJMODEL_INTS_NUMERIC",
- "MJMODEL_FLOATS",
- "MJDATA_VECTOR",
- "MJDATA_SCALAR",
- "MJDATA_SCALAR_PREAMBLE",
-}
-
-
-def parse_mjxmacro(path: str) -> Dict[str, Any]:
- with open(path, "r", encoding="utf-8") as f:
- raw_text = f.read()
- text = _strip_comments(raw_text)
- lines = text.split("\n")
-
- out: Dict[str, Any] = {
- "_meta": {
- "source": os.path.relpath(path, PLUGIN_ROOT),
- "schema_kind": "mjxmacro",
- },
- "mjmodel_pointers": {}, # block_name -> list of entries
- "mjdata_pointers": {},
- "struct_fields": {},
- }
-
- expected = (
- set(POINTER_BLOCKS_MJMODEL) | set(POINTER_BLOCKS_MJDATA)
- | set(STRUCT_FIELD_BLOCKS) | KNOWN_UNCONSUMED_BLOCKS
- )
- seen_blocks: set = set()
-
- i = 0
- while i < len(lines):
- line = lines[i]
- m = _BLOCK_START_RE.match(line)
- if not m:
- i += 1
- continue
- block_name = m.group(1)
- seen_blocks.add(block_name)
- # Collect block body — entries on subsequent lines.
- entries = _parse_block_body(lines, i + 1)
- # Defensive sentinel: a non-entry, non-empty line ended body
- # collection inside an EXPECTED block. The XNV regression was
- # exactly this — surface it so the next new X-tag bumps cause a
- # loud warning rather than silently truncating the snapshot.
- end_idx = i + 1 + len(entries)
- if (block_name in expected and end_idx < len(lines)
- and lines[end_idx].strip()
- and not _BODY_ENTRY_RE.match(lines[end_idx].strip())):
- # If the very next line was also an entry-shaped token we
- # missed (i.e. it has parens), warn loudly.
- tail = lines[end_idx].strip()
- if "(" in tail and tail.endswith(")") or tail.endswith(") \\"):
- print(
- f"warning: body collector stopped INSIDE block "
- f"{block_name} at line {end_idx + 1}: '{tail[:80]}' — "
- f"new X-macro tag? Update _X_TAG_RE in this script.",
- file=sys.stderr,
- )
- if block_name in POINTER_BLOCKS_MJMODEL:
- parsed = [e for e in (_parse_pointer_entry(r) for r in entries) if e]
- out["mjmodel_pointers"][block_name] = parsed
- elif block_name in POINTER_BLOCKS_MJDATA:
- parsed = [e for e in (_parse_pointer_entry(r) for r in entries) if e]
- out["mjdata_pointers"][block_name] = parsed
- elif block_name in STRUCT_FIELD_BLOCKS:
- parsed = [e for e in (_parse_struct_field_entry(r) for r in entries) if e]
- out["struct_fields"][block_name] = parsed
- i += 1
-
- # New-block tripwire: surface any #define block whose name we have
- # never seen before. Catches scenarios like a new
- # MJMODEL_POINTERS_PLUGIN_SUB landing upstream — without this, the
- # snapshot silently drops the block.
- unexpected = {
- b for b in seen_blocks
- if b not in expected and (b.startswith("MJMODEL_") or
- b.startswith("MJDATA_") or
- b.startswith("MJOPTION_") or
- b.startswith("MJSTATISTIC_") or
- b.startswith("MJVISUAL_") or
- b.startswith("MJSCOMPILER_") or
- b.startswith("MJSPEC_"))
- }
- if unexpected:
- print(
- f"warning: parsed {len(unexpected)} unrecognised X-macro "
- f"block(s) — add to POINTER_BLOCKS_MJMODEL/MJDATA, "
- f"STRUCT_FIELD_BLOCKS, or KNOWN_UNCONSUMED_BLOCKS in this "
- f"script: {sorted(unexpected)}",
- file=sys.stderr,
- )
- return out
-
-
-def main() -> int:
- src = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_MJXMACRO
- dst = sys.argv[2] if len(sys.argv) > 2 else DEFAULT_OUTPUT
- if not os.path.isfile(src):
- print(f"error: mjxmacro.h not found at {src}", file=sys.stderr)
- return 1
- snapshot = parse_mjxmacro(src)
- # Track which source each struct-field block came from so a snapshot
- # reader can tell mjmodel-side (mjxmacro.h) blocks apart from mjspec-side
- # (mjspecmacro.h) blocks without re-parsing the headers.
- block_sources: Dict[str, str] = {}
- for block_name in snapshot["struct_fields"]:
- block_sources[block_name] = snapshot["_meta"]["source"]
- # Also fold in mjspecmacro.h (MJSCOMPILER_FIELDS + MJSPEC_FIELDS) from the
- # installed MuJoCo headers — both live in the same ``struct_fields`` dict so
- # synthetic_categories rules can reference either by block name.
- if os.path.isfile(DEFAULT_MJSPECMACRO):
- spec_snapshot = parse_mjxmacro(DEFAULT_MJSPECMACRO)
- spec_rel = os.path.relpath(DEFAULT_MJSPECMACRO, PLUGIN_ROOT)
- for block_name, entries in spec_snapshot["struct_fields"].items():
- snapshot["struct_fields"][block_name] = entries
- block_sources[block_name] = spec_rel
- else:
- # Loud rather than silent — MJSCOMPILER_FIELDS / MJSPEC_FIELDS blocks
- # WILL be missing if the installed headers predate mjspecmacro.h, and
- # that surfaces only as a downstream KeyError much later in
- # generate_ue_components.py.
- print(
- f"warning: mjspecmacro.h not found at {DEFAULT_MJSPECMACRO}; "
- f"MJSCOMPILER_FIELDS + MJSPEC_FIELDS will be absent from the snapshot. "
- f"Rebuild the MuJoCo install (needs a version that ships mjspecmacro.h).",
- file=sys.stderr,
- )
- snapshot["_meta"]["struct_field_sources"] = block_sources
- # Stats for sanity.
- total_model = sum(len(v) for v in snapshot["mjmodel_pointers"].values())
- total_data = sum(len(v) for v in snapshot["mjdata_pointers"].values())
- total_structs = sum(len(v) for v in snapshot["struct_fields"].values())
- print(
- f"parsed mjxmacro.h: {len(snapshot['mjmodel_pointers'])} model blocks "
- f"({total_model} entries), "
- f"{len(snapshot['mjdata_pointers'])} data blocks ({total_data} entries), "
- f"{len(snapshot['struct_fields'])} struct blocks ({total_structs} entries)"
- )
- with open(dst, "w", encoding="utf-8") as f:
- json.dump(snapshot, f, indent=2)
- print(f"wrote {dst}")
- return 0
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
diff --git a/Scripts/codegen/codegen_rules.json b/Scripts/codegen/codegen_rules.json
deleted file mode 100644
index ee017f23..00000000
--- a/Scripts/codegen/codegen_rules.json
+++ /dev/null
@@ -1,1533 +0,0 @@
-{
- "_meta": {
- "description": "Definitive rules for URLab Unreal codegen. Drives generate_ue_components.py: which schema attrs to emit, how to type-map them, which canonicalisations absorb multi-attr clusters, which categories use single-UCLASS or multi-UCLASS or no-subclass layouts, and which mjxmacro pointer fields belong on which view struct.",
- "version": "5.0"
- },
-
- "_doc_transform_widget_policy": "Categories whose Pos/Quat are authored via the UE Transform widget (geom/site/camera/frame/inertial) hide the canon Pos/Quat UPROPERTYs from the Details panel. The UPROPERTYs still exist for the import seed + BP read access, but EditConditionHides keeps them out of the user-facing surface so authoring stays in one place. Per-element _note_hidden entries point at this policy instead of restating it.",
-
- "global_exclusions": [
- "user", "name", "class", "type", "objtype", "reftype"
- ],
- "default_type": "float",
- "_note_property_renames": "Schema attr -> UPROPERTY identifier. Used when the UE-side identifier must differ from the verbatim schema attr (typically to avoid C++ keyword collisions or to keep PascalCase for legacy consumers). qpos/qvel/etc are PascalCase on UMjKeyframe because BP graphs / runtime accessors reference them that way.",
- "property_renames": {
- "qpos": "Qpos",
- "qvel": "Qvel",
- "act": "Act",
- "ctrl": "Ctrl",
- "mpos": "Mpos",
- "mquat": "Mquat",
- "time": "Time",
- "actuatorfrclimited": "ActFrcLimited",
- "actuatorfrcrange": "ActFrcRange",
- "axis": "Axis"
- },
-
- "_note_setto_param_defaults": "Per-(function,param) 'not overridden' values, used ONLY for params MuJoCo treats as genuinely optional — i.e. it guards them with `>= 0` (muscle) or a null pointer, so the sentinel means 'leave the default alone'. Params MuJoCo writes unconditionally by value must NOT appear here (a sentinel would clobber the inherited value); use `inherit_fields` in subtype_setto instead. Values are strings so the codegen drops them verbatim into the generated C++ call without forcing a 1 vs 1.0 vs 1.0f format choice.",
- "setto_param_defaults": {
- "mjs_setToPosition": {"inheritrange": "0.0"},
- "mjs_setToIntVelocity": {"inheritrange": "0.0"},
- "mjs_setToMuscle": {"tausmooth": "0.0"},
- "mjs_setToDCMotor": {"resistance": "0.0", "input_mode": "0"}
- },
-
- "_note_unmodeled_elements": "Top-level MJCF elements that the codegen drift-diagnostic silences. Each entry is the reason it's skipped — change the value to '' to make the diagnostic fire again if you want to revisit.",
- "intentionally_unmodeled_elements": {
- "freejoint": "Handled as a joint subtype (UMjFreeJoint) — the freejoint XML tag maps to the joint category via the parser, not as a top-level category.",
- "light": "URLab doesn't model MJCF as a UE component — UE has its own light primitives that override MJCF light placement.",
- "flex": "Children of . URLab generates flexes via UMjFlexcomp (which expands to a flex at parse time); the direct element is not a UE component.",
- "skin": "Children of . URLab handles skinning via UE skeletal meshes; in MJCF would need a dedicated asset pipeline."
- },
-
- "_note_hand_vs_generated_enums": "URLab keeps every EMj*Type enum hand-rolled. Subtype-driving enums (EMjJointType, EMjGeomType, etc.) must stay hand-rolled because each member drives a UClass subclass — adding one is a product decision, not mechanical. Pure-mapping enums (EMjGainType, EMjBiasType, ...) are mechanically codegenable but live next to their parent UClass; moving them to Generated/ would require include reordering for no functional gain. The hand_enum_drift phase in generate_ue_components.py provides the equivalent forward-maintainability guarantee: any new mjt* value upstream surfaces as a diagnostic instead of a silent runtime fallthrough.",
-
- "_note_compiler_attr_field_map": "MJCF XML attrs URLab honours, mapped to their FMjCompilerSettings field name. The field is hand-rolled in MuJoCo/Utils/MjOrientationUtils.h; the drift check uses this map purely as an allowlist. New MuJoCo compiler flags surface as a diagnostic until added here or to intentionally_unmodeled_compiler_attrs.",
- "compiler_attr_field_map": {
- "angle": "bAngleInDegrees",
- "eulerseq": "EulerSeq",
- "meshdir": "MeshDir",
- "assetdir": "AssetDir",
- "autolimits": "bAutoLimits"
- },
-
- "_note_intentionally_unmodeled_compiler_attrs": " XML attrs that don't affect URLab's UE-side parsing — physics tuning knobs, compiler-only optimisations, paths URLab supersedes with UE asset routing. Listed explicitly so the compiler-coverage diagnostic stays clean while remaining loud on additions.",
- "intentionally_unmodeled_compiler_attrs": [
- "boundmass", "boundinertia", "settotalmass", "balanceinertia",
- "strippath", "coordinate", "fitaabb", "discardvisual",
- "usethread", "fusestatic", "inertiafromgeom", "inertiagrouprange",
- "saveinertial", "texturedir", "alignfree"
- ],
-
- "_note_intentionally_default_typed_attrs": "Attrs that legitimately want default_type ('float') — single scalar floats whose UE shape happens to match the rule fallback. Listed explicitly so the new_attr_typing diagnostic stays clean. Any new MuJoCo XML attr added in a future version that ISN'T a scalar float will surface as a diagnostic.",
- "intentionally_default_typed_attrs": [
- "active", "actuatorgravcomp", "area", "armature", "bias",
- "cranklength", "cutoff", "dampratio", "density", "diameter",
- "force", "fovy", "fpmax", "frictionloss", "fvmax",
- "gain", "gap", "gravcomp", "inheritrange", "ipd",
- "kp", "kv", "lmax", "lmin", "margin",
- "mass", "noise", "output", "radius", "ref",
- "resistance", "solmix", "springref", "tausmooth", "torquescale",
- "vmax", "width"
- ],
-
- "_note_intentionally_unmapped_mj_enum_values": "MuJoCo enum constants the codegen knowingly does NOT expose as URLab enum members. Silences the hand_enum_drift diagnostic. Two scopes: top-level keys are mjt* enum names whose entries apply to EVERY element using that enum (visualizer-only types, sentinel counts, alternative-class subsumption); '__per_element__' carries per-(element, attr) overrides for cases where the same mjt* enum admits a different subset depending on the host (e.g. rejects mjGEOM_PLANE/HFIELD/MESH but accepts them).",
- "intentionally_unmapped_mj_enum_values": {
- "mjtGain": ["mjGAIN_DCMOTOR"],
- "mjtBias": ["mjBIAS_DCMOTOR"],
- "mjtDyn": ["mjDYN_DCMOTOR"],
- "mjtGeom": [
- "mjNGEOMTYPES",
- "mjGEOM_ARROW", "mjGEOM_ARROW1", "mjGEOM_ARROW2",
- "mjGEOM_LINE", "mjGEOM_LINEBOX", "mjGEOM_LABEL", "mjGEOM_TRIANGLE",
- "mjGEOM_FLEX", "mjGEOM_SKIN", "mjGEOM_SDF", "mjGEOM_NONE"
- ],
- "__per_element__": {
- "_note_site_type": "Site exposes Mesh + Hfield. Plane stays omitted because a site is a point/extent surface, not an infinite plane; SDF stays omitted because it carries heavy resource data the spawn-surface UX doesn't need.",
- "site.type": ["mjGEOM_PLANE"]
- }
- },
-
- "_note_intentionally_unmodeled_mjs_fields": "Per-mjsX-struct list of fields URLab knows about but doesn't model via codegen. Silences the mjsX-field-drift diagnostic. Add entries for fields handled by a different UE component, by canon, or that we deliberately skip.",
- "intentionally_unmodeled_mjs_fields": {
- "mjsBody": [
- "inertia", "ipos", "ialt", "mass", "iquat", "fullinertia", "alt",
- "plugin"
- ],
- "mjsFrame": [
- "pos", "quat", "childclass", "alt"
- ],
- "mjsFlex": [
- "solimp", "solmix", "contype", "activelayers", "edgedamping", "elem",
- "size", "passive", "condim", "order", "nodebody",
- "vertbody", "elemtexcoord", "selfcollide", "poisson", "vert", "margin",
- "conaffinity", "damping", "priority", "edgestiffness", "node",
- "solref", "gap", "elastic2d", "young", "friction", "thickness", "internal"
- ],
- "mjsCamera": [
- "intrinsic", "alt"
- ],
- "mjsGeom": [
- "alt", "plugin"
- ],
- "mjsSite": [
- "alt"
- ],
- "mjsActuator": [
- "plugin"
- ],
- "mjsJoint": [
- "align"
- ],
- "mjsSensor": [
- "datatype", "dim", "intprm", "needstage", "objname", "plugin",
- "refname", "reftype"
- ]
- },
-
- "type_mappings": {
- "axis": "FVector",
- "dir": "FVector",
- "size": "TArray",
- "principal": "TArray",
- "focal": "TArray",
- "sensorsize": "TArray",
- "fluidcoef": "TArray",
- "count": "TArray",
- "cellcount": "TArray",
- "spacing": "TArray",
- "scale": "TArray",
- "point": "TArray",
- "element": "TArray",
- "texcoord": "TArray",
- "inertiabox": "float",
- "rigid": "bool",
- "flatskin": "bool",
- "origin": "TArray",
- "dim": "int32",
- "rgba": "FLinearColor",
- "range": "TArray",
- "actuatorfrcrange": "TArray",
- "ctrlrange": "TArray",
- "forcerange": "TArray",
- "actrange": "TArray",
- "lengthrange": "TArray",
- "gear": "TArray",
- "springdamper": "TArray",
- "springlength": "TArray",
- "timeconst": "TArray",
- "motorconst": "TArray",
- "nominal": "TArray",
- "saturation": "TArray",
- "inductance": "TArray",
- "cogging": "TArray",
- "controller": "TArray",
- "thermal": "TArray",
- "lugre": "TArray",
- "stiffness": "TArray",
- "damping": "TArray",
- "friction": "TArray",
- "fullinertia": "TArray",
- "diaginertia": "TArray",
- "resolution": "TArray",
- "focalpixel": "TArray",
- "principalpixel": "TArray",
- "solref": "TArray",
- "solimp": "TArray",
- "solreflimit": "TArray",
- "solimplimit": "TArray",
- "solreffriction": "TArray",
- "solimpfriction": "TArray",
- "gainprm": "TArray",
- "biasprm": "TArray",
- "dynprm": "TArray",
- "polycoef": "TArray",
- "limited": "bool",
- "mocap": "bool",
- "actlimited": "bool",
- "ctrllimited": "bool",
- "forcelimited": "bool",
- "actuatorfrclimited":"bool",
- "actearly": "bool",
- "shellinertia": "bool",
- "fitscale": "double",
- "fitaabb": "bool",
- "discardvisual": "bool",
- "objname": "FString",
- "refname": "FString",
- "gaintype": "FString",
- "biastype": "FString",
- "dyntype": "FString",
- "fluidshape": "FString",
- "site": "FString",
- "joint": "FString",
- "tendon": "FString",
- "actuator": "FString",
- "geom": "FString",
- "geom1": "FString",
- "geom2": "FString",
- "body": "FString",
- "body1": "FString",
- "body2": "FString",
- "site1": "FString",
- "site2": "FString",
- "joint1": "FString",
- "joint2": "FString",
- "tendon1": "FString",
- "tendon2": "FString",
- "mesh": "FString",
- "material": "FString",
- "hfield": "FString",
- "childclass": "FString",
- "texture": "FString",
- "file": "FString",
- "target": "FString",
- "mode": "FString",
- "anchor": "TArray",
- "relpose": "TArray",
- "ctrl": "TArray",
- "qpos": "TArray",
- "qvel": "TArray",
- "act": "TArray",
- "mpos": "TArray",
- "mquat": "TArray",
- "time": "float",
- "group": "int32",
- "contype": "int32",
- "conaffinity": "int32",
- "condim": "int32",
- "priority": "int32",
- "actdim": "int32",
- "nsample": "int32",
- "interp": "int32",
- "interval": "TArray",
- "delay": "float",
- "input": "EMjDcMotorInput"
- },
-
- "canonicalizations": {
- "spatial_pose": {
- "absorbs_attrs": ["pos"],
- "emits_property": {"name": "Pos", "type": "FVector"},
- "import_helper": "MjUtils::ReadVec3InMeters",
- "export_helper": "MjUtils::UEToMjPosition"
- },
- "orientation": {
- "absorbs_attrs": ["quat", "euler", "axisangle", "xyaxes", "zaxis"],
- "emits_property": {"name": "Quat", "type": "FQuat"},
- "import_helper": "MjOrientationUtils::OrientationToMjQuat",
- "export_helper": "MjUtils::UEToMjRotation"
- },
- "actuator_transmission": {
- "_note": "MJCF actuators encode their transmission via one of {joint, tendon, site, body, jointinparent} (the target name) plus optional {slidersite, refsite}. URLab collapses this to a single EMjActuatorTrnType enum + TargetName/SliderSite/RefSite strings. Codegen emits the parse+write blocks inline (no rule-side helper); the UPROPERTY declarations stay hand-side on UMjActuator.",
- "absorbs_attrs": ["joint", "tendon", "site", "body", "jointinparent", "slidersite", "refsite"],
- "emits_property": null
- },
- "body_sleep_policy": {
- "_note": "MJCF body.sleep is one of {'never','allowed','init'} or absent; mjsBody.sleep is the mjtSleepPolicy enum. URLab exposes EMjBodySleepPolicy SleepPolicy (with a Default entry that means 'let the global option decide'). Codegen emits the string<->enum mapping on both sides inline (no rule-side helper); the SleepPolicy UPROPERTY itself stays declared hand-side on UMjBody.",
- "absorbs_attrs": ["sleep"],
- "emits_property": null
- },
- "fromto_decompose": {
- "_note": "MJCF's `fromto` is an alternative form for capsule/cylinder/box/ellipsoid (an XY-XY segment). Decompose at import into Pos/Quat plus a half-length scalar written into size[1] (Y slot, e.g. capsule half-length) or size[2] (Z slot, e.g. box half-height) depending on shape Type. The codegen-owned size TArray is grown as needed.",
- "absorbs_attrs": ["fromto"],
- "emits_property": null,
- "import_helper": "MjUtils::DecomposeFromTo",
- "category_specifics": {
- "geom": {
- "z_slot_check": "(Type == EMjGeomType::Box || Type == EMjGeomType::Ellipsoid)"
- },
- "site": {
- "z_slot_check": "(Type == EMjSiteType::Box || Type == EMjSiteType::Ellipsoid)"
- }
- }
- }
- },
-
- "element_rules": {
- "actuator": {
- "_note_enums": "gaintype/biastype/dyntype are mjtGain/mjtBias/mjtDyn enums on mjsActuator. URLab declares EMjGainType/EMjBiasType/EMjDynType hand-side on UMjActuator; codegen owns the XML<->enum map via xml_enum_attrs. dcmotor 'input' is per-subtype (only on UMjDcMotorActuator) — emitter gates on attr-in-subtype-schema for that case.",
- "common_imports": ["class"],
- "applies_canonicalizations": ["actuator_transmission"],
- "xml_enum_attrs": {
- "gaintype": {
- "ue_property": "GainType",
- "ue_enum_type": "EMjGainType",
- "mjs_field": "gaintype",
- "mjs_cast": "mjtGain",
- "emit_property_decl": true,
- "property_default": "Fixed",
- "value_map": {
- "fixed": ["Fixed", "mjGAIN_FIXED"],
- "affine": ["Affine", "mjGAIN_AFFINE"],
- "muscle": ["Muscle", "mjGAIN_MUSCLE"],
- "user": ["User", "mjGAIN_USER"]
- }
- },
- "biastype": {
- "ue_property": "BiasType",
- "ue_enum_type": "EMjBiasType",
- "mjs_field": "biastype",
- "mjs_cast": "mjtBias",
- "emit_property_decl": true,
- "property_default": "None",
- "value_map": {
- "none": ["None", "mjBIAS_NONE"],
- "affine": ["Affine", "mjBIAS_AFFINE"],
- "muscle": ["Muscle", "mjBIAS_MUSCLE"],
- "user": ["User", "mjBIAS_USER"]
- }
- },
- "dyntype": {
- "ue_property": "DynType",
- "ue_enum_type": "EMjDynType",
- "mjs_field": "dyntype",
- "mjs_cast": "mjtDyn",
- "emit_property_decl": true,
- "property_default": "None",
- "value_map": {
- "none": ["None", "mjDYN_NONE"],
- "integrator": ["Integrator", "mjDYN_INTEGRATOR"],
- "filter": ["Filter", "mjDYN_FILTER"],
- "filterexact": ["FilterExact", "mjDYN_FILTEREXACT"],
- "muscle": ["Muscle", "mjDYN_MUSCLE"],
- "user": ["User", "mjDYN_USER"]
- }
- },
- "input": {
- "ue_property": "input",
- "ue_enum_type": "EMjDcMotorInput",
- "mjs_field": null,
- "value_map": {
- "voltage": ["Voltage", "0"],
- "position": ["Position", "1"],
- "velocity": ["Velocity", "2"]
- }
- }
- }
- },
- "sensor": {
- "_note": "Sensor reads its target name from one of several xor attrs depending on subtype (site for touch/accel/gyro, joint for jointpos, etc.). target_collations collapses them into UE FString TargetName. ReferenceName is direct from 'refname'. ObjType / RefType are EMjObjType enums with their own string<->enum mapping (xml_enum_attrs).",
- "common_imports": ["class"],
- "target_collations": {
- "TargetName": {
- "mjs_field": "objname",
- "absorbs_attrs": ["site", "joint", "tendon", "actuator", "body", "geom", "objname", "camera", "mesh"]
- },
- "ReferenceName": {
- "mjs_field": "refname",
- "absorbs_attrs": ["refname"]
- }
- },
- "xml_enum_attrs": {
- "objtype": {
- "ue_property": "ObjType",
- "ue_enum_type": "EMjObjType",
- "has_override_toggle": false,
- "value_map": {
- "body": ["Body", "mjOBJ_BODY"],
- "xbody": ["XBody", "mjOBJ_XBODY"],
- "joint": ["Joint", "mjOBJ_JOINT"],
- "dof": ["DoF", "mjOBJ_DOF"],
- "geom": ["Geom", "mjOBJ_GEOM"],
- "site": ["Site", "mjOBJ_SITE"],
- "camera": ["Camera", "mjOBJ_CAMERA"],
- "light": ["Light", "mjOBJ_LIGHT"],
- "mesh": ["Mesh", "mjOBJ_MESH"],
- "hfield": ["HField", "mjOBJ_HFIELD"],
- "texture": ["Texture", "mjOBJ_TEXTURE"],
- "material": ["Material", "mjOBJ_MATERIAL"],
- "pair": ["Pair", "mjOBJ_PAIR"],
- "exclude": ["Exclude", "mjOBJ_EXCLUDE"],
- "equality": ["Equality", "mjOBJ_EQUALITY"],
- "tendon": ["Tendon", "mjOBJ_TENDON"],
- "actuator": ["Actuator", "mjOBJ_ACTUATOR"]
- }
- },
- "reftype": {
- "ue_property": "RefType",
- "ue_enum_type": "EMjObjType",
- "has_override_toggle": false,
- "value_map": {
- "body": ["Body", "mjOBJ_BODY"],
- "xbody": ["XBody", "mjOBJ_XBODY"],
- "joint": ["Joint", "mjOBJ_JOINT"],
- "geom": ["Geom", "mjOBJ_GEOM"],
- "site": ["Site", "mjOBJ_SITE"],
- "camera": ["Camera", "mjOBJ_CAMERA"]
- }
- }
- }
- },
- "joint": {
- "_note_axis_pos": "axis: MuJoCo direction vector with opposite Y handedness vs UE; vec3_convert.axis = y_negate flips on import + export. pos: spatial_pose canon emits the Pos UPROPERTY pair + drives SetRelativeLocation on import.",
- "common_imports": ["class"],
- "applies_canonicalizations": ["spatial_pose"],
- "vec3_convert": {"axis": "y_negate"},
- "property_defaults": {"axis": "FVector(0.0f, 0.0f, 1.0f)"},
- "_note_hidden": "Pos is the joint anchor offset — derived from the UE component's RelativeLocation. Axis stays visible as a direction (not a position) and is the user-authored joint hinge direction.",
- "hidden_canon_properties": ["spatial_pose"],
- "_note_property_meta": "Joint fields whose unit semantics shift with the joint Type get a tooltip that spells out the per-type interpretation, so a user reading the Details panel knows whether the number is metres or degrees. UE's Units meta is intentionally NOT used here — a static label would be wrong for the other Type.",
- "property_meta": {
- "axis": "ToolTip=\"Joint axis in the parent body's local frame. Hinge: rotation axis. Slide: translation direction. Ignored for Ball and Free.\"",
- "range": "ToolTip=\"Joint position bounds [min, max]. Hinge/Ball: degrees. Slide: centimetres. Ignored when 'limited' is false.\"",
- "ref": "ToolTip=\"Reference (zero) position. Hinge/Ball: degrees. Slide: centimetres.\"",
- "springref": "ToolTip=\"Equilibrium position for the joint spring. Hinge/Ball: degrees. Slide: centimetres.\"",
- "stiffness": "ToolTip=\"Per-axis spring stiffness. Hinge/Ball: N·m/rad. Slide: N/m.\"",
- "damping": "ToolTip=\"Per-axis damping. Hinge/Ball: N·m·s/rad. Slide: N·s/m.\"",
- "springdamper": "ToolTip=\"Compact spring spec [stiffness, damping]; populated when MJCF used . Overrides stiffness + damping when set.\"",
- "armature": "ToolTip=\"Added rotor inertia for hinges (kg·m²) or added mass for slides (kg). Models reflected inertia of the actuator.\"",
- "frictionloss": "ToolTip=\"Dry-friction loss. Hinge/Ball: N·m. Slide: N.\"",
- "actuatorgravcomp": "ToolTip=\"Gravity compensation factor passed to actuators on this joint. 0 = no compensation, 1 = full gravity cancelled.\"",
- "actuatorfrcrange": "ToolTip=\"Actuator force bounds [min, max] when 'ActFrcLimited' is true. Hinge/Ball: N·m. Slide: N.\"",
- "margin": "ToolTip=\"Contact-detection margin (m). Joints inherit this when computing limit constraints.\"",
- "group": "ToolTip=\"Visualisation group 0–5. MuJoCo viewer uses this to toggle visibility.\""
- },
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "mjs_field": "type",
- "mjs_cast": "mjtJoint",
- "value_map": {
- "hinge": ["Hinge", "mjJNT_HINGE"],
- "slide": ["Slide", "mjJNT_SLIDE"],
- "ball": ["Ball", "mjJNT_BALL"],
- "free": ["Free", "mjJNT_FREE"]
- }
- }
- },
- "_note_unit_conversion": "URLab stores joint range/ref/springref in UE conventions (degrees for hinge/ball, centimetres for slide). MJCF XML carries them in the compiler.angle unit (deg/rad) for angular joints and metres for linear; URLab's spec wrapper sets compiler.degree=false so mjsJoint.range[] must be radians on the wire. The conversions below normalize at the IO boundary so the rest of URLab can treat the UPROPERTYs as UE-native values.",
- "unit_conversion": {
- "range": [
- {"condition": "Type == EMjJointType::Slide",
- "import_op": "m_to_cm", "export_op": "cm_to_m"},
- {"condition": "(Type == EMjJointType::Hinge) || (Type == EMjJointType::Ball)",
- "import_op": "rad_to_deg_if_xml_radians", "export_op": "deg_to_rad"}
- ],
- "ref": [
- {"condition": "Type == EMjJointType::Slide",
- "import_op": "m_to_cm", "export_op": "cm_to_m"},
- {"condition": "(Type == EMjJointType::Hinge) || (Type == EMjJointType::Ball)",
- "import_op": "rad_to_deg_if_xml_radians", "export_op": "deg_to_rad"}
- ],
- "springref": [
- {"condition": "Type == EMjJointType::Slide",
- "import_op": "m_to_cm", "export_op": "cm_to_m"},
- {"condition": "(Type == EMjJointType::Hinge) || (Type == EMjJointType::Ball)",
- "import_op": "rad_to_deg_if_xml_radians", "export_op": "deg_to_rad"}
- ]
- }
- },
- "geom": {
- "_note": "size is codegen-owned TArray; fromto-decomposed half-length is written into size[1]/[2] by the canon. material is codegen-owned for IMPORT (FString -> UE material lookup) but SKIPPED on export because URLab handles materials as UE assets and does not register them in the mjsSpec (mjs_setString on Element->material would reference a non-existent spec entry and fail mj_compile). Orientation cluster absorbed by `orientation`; fromto absorbed by `fromto_decompose`. type is an URLab enum (EMjGeomType); codegen owns the XML<->enum string map via xml_enum_attrs.",
- "common_imports": ["class"],
- "_note_hfield": "hfield references URLab's own hfield actor system, not a mjsHField spec entry. Codegen still imports the string for editor visibility but skips the spec write to avoid 'hfield not found' on compile.",
- "export_skip_attrs": ["material", "hfield"],
- "applies_canonicalizations": ["spatial_pose", "orientation", "fromto_decompose"],
- "_note_sentinel": "fromto-only XML inputs leave the radius slot unset; the canon writes -1.0f as the sentinel and the per-attr size export skips those slots so the parent default's radius is preserved.",
- "sentinel_skip_export": {"size": "-1.0f"},
- "_note_property_units": "Scalar lengths exposed in mjsGeom carry meta=(Units=\"m\") so the editor shows a 'm' suffix or auto-converts to cm/mm when 'Display Units' is enabled. Storage stays raw MJ metres; export path unaffected. size is hidden (Scale3D is canonical) — see hidden_attrs.",
- "property_units": {
- "margin": "m",
- "gap": "m"
- },
- "_note_hidden": "See _doc_transform_widget_policy. size is hidden too — Scale3D is canonical.",
- "hidden_canon_properties": ["spatial_pose", "orientation"],
- "hidden_attrs": ["size"],
- "_note_attr_to_mjs_field": "MuJoCo renames fluidcoef -> fluid_coefs on the mjsGeom struct. shellinertia and fluidshape are handled by xml_enum_attrs below (they need string<->enum + field-rename together).",
- "attr_to_mjs_field": {
- "fluidcoef": "fluid_coefs"
- },
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum_type": "EMjGeomType",
- "mjs_field": "type",
- "mjs_cast": "mjtGeom",
- "value_map": {
- "plane": ["Plane", "mjGEOM_PLANE"],
- "hfield": ["Hfield", "mjGEOM_HFIELD"],
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "capsule": ["Capsule", "mjGEOM_CAPSULE"],
- "ellipsoid": ["Ellipsoid", "mjGEOM_ELLIPSOID"],
- "cylinder": ["Cylinder", "mjGEOM_CYLINDER"],
- "box": ["Box", "mjGEOM_BOX"],
- "mesh": ["Mesh", "mjGEOM_MESH"],
- "sdf": ["SDF", "mjGEOM_SDF"]
- }
- },
- "shellinertia": {
- "_note": "XML attr is bool-ish (true/false). MuJoCo stores it as mjtGeomInertia (mjINERTIA_VOLUME=0 default, mjINERTIA_SHELL=1) in mjsGeom.typeinertia.",
- "ue_property": "ShellInertia",
- "ue_enum_type": "EMjGeomInertia",
- "mjs_field": "typeinertia",
- "mjs_cast": "mjtGeomInertia",
- "value_map": {
- "false": ["Volume", "mjINERTIA_VOLUME"],
- "true": ["Shell", "mjINERTIA_SHELL"]
- }
- },
- "fluidshape": {
- "_note": "XML attr is none/ellipsoid. MuJoCo stores 0.0/1.0 in mjsGeom.fluid_ellipsoid (mjtNum).",
- "ue_property": "FluidShape",
- "ue_enum_type": "EMjFluidShape",
- "mjs_field": "fluid_ellipsoid",
- "mjs_cast": "mjtNum",
- "value_map": {
- "none": ["None", "0.0"],
- "ellipsoid": ["Ellipsoid", "1.0"]
- }
- }
- }
- },
- "site": {
- "_note": "Same as geom: size codegen-owned TArray; material codegen-owned for IMPORT but export-skipped (UE-side materials); orientation + fromto canonicalized. mjsSite.type uses mjtGeom (sites are visual 'geoms'). Site has no bOverride_Type — Type always carries a value (default Sphere).",
- "export_skip_attrs": ["material"],
- "applies_canonicalizations": ["spatial_pose", "orientation", "fromto_decompose"],
- "sentinel_skip_export": {"size": "-1.0f"},
- "_note_hidden": "See _doc_transform_widget_policy. size hidden too — Scale3D is canonical.",
- "hidden_canon_properties": ["spatial_pose", "orientation"],
- "hidden_attrs": ["size"],
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum_type": "EMjSiteType",
- "mjs_field": "type",
- "mjs_cast": "mjtGeom",
- "has_override_toggle": false,
- "value_map": {
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "capsule": ["Capsule", "mjGEOM_CAPSULE"],
- "ellipsoid": ["Ellipsoid", "mjGEOM_ELLIPSOID"],
- "cylinder": ["Cylinder", "mjGEOM_CYLINDER"],
- "box": ["Box", "mjGEOM_BOX"],
- "mesh": ["Mesh", "mjGEOM_MESH"],
- "hfield": ["Hfield", "mjGEOM_HFIELD"]
- }
- }
- }
- },
- "tendon": {
- "common_imports": ["class"],
- "_note_material": "material codegen-owned for IMPORT but export-skipped — URLab handles materials as UE assets, not mjsMaterial spec entries.",
- "export_skip_attrs": ["material"],
- "_note_property_units": "springlength is unambiguously a length in metres. range is intentionally NOT tagged — it can be a length (slide-mode tendon) or an angle (rare hinge-coupled tendon) and labelling it with one unit would be wrong as often as right.",
- "property_units": {
- "springlength": "m"
- }
- },
- "equality": {
- "_note_target_collation": "MJCF equality elements address one or two of {body, site, joint, tendon, flex} per the equality kind. URLab collapses to FString Obj1/Obj2 (hand-declared UPROPERTYs with dynamic GetOptions based on EqualityType). Excluded from codegen so they don't appear as separate UPROPERTYs; target_collations rule emits the import collation + mjs_setString export. site1/site2 stay as their own UPROPERTYs (codegen-owned) so the objtype switch in ExportTo can detect site-mode connects/welds and pick mjOBJ_SITE.",
- "exclude_attrs": ["body1", "body2", "joint1", "joint2", "tendon1", "tendon2", "flex"],
- "target_collations": {
- "Obj1": {
- "absorbs_attrs": ["body1", "site1", "joint1", "tendon1", "flex"],
- "mjs_field": "name1"
- },
- "Obj2": {
- "absorbs_attrs": ["body2", "site2", "joint2", "tendon2"],
- "mjs_field": "name2"
- }
- },
- "_note_data_packed": "mjsEquality has no per-attr fields for anchor/relpose/polycoef/torquescale; they all pack into data[] per the connect/weld/joint/tendon layout (verified via probe_eq_spec.py against the installed MuJoCo). Codegen-emitted exports replace the default per-attr emission with the packed write under the right EqualityType condition. anchor carries a cm_to_m export op so the URLab-side cm convention round-trips into spec metres. relpose is stored opaquely (raw MJ format: metres for the first 3 floats, MuJoCo quat for the last 4) — weld constraints are rare enough that the inconsistency is worth the simpler emitter.",
- "_note_unit_conversion": "anchor is a position offset in body1's local frame; URLab stores it in centimetres (matching every other position UPROPERTY). The unit_conversion below handles the import side (XML m -> UPROPERTY cm); the data-packed export carries its own cm_to_m op so it converts in flight before writing data[0..2].",
- "unit_conversion": {
- "anchor": [
- {"condition": "(EqualityType == EMjEqualityType::Connect) || (EqualityType == EMjEqualityType::Weld)",
- "import_op": "m_to_cm"}
- ]
- },
- "_note_property_units": "anchor is stored in UE centimetres (post unit_conversion). Tagging the field with Units=\"cm\" so the editor shows the suffix that matches the actual stored value — no auto-conversion needed.",
- "property_units": {
- "anchor": "cm"
- },
- "mjs_data_packed_attrs": {
- "anchor": {
- "slot_range": [0, 3],
- "condition": "(EqualityType == EMjEqualityType::Connect) || (EqualityType == EMjEqualityType::Weld)",
- "export_op": "cm_to_m"
- },
- "relpose": {
- "slot_range": [3, 10],
- "condition": "EqualityType == EMjEqualityType::Weld"
- },
- "polycoef": {
- "_note": "polycoef is a 5-element MJCF attribute (default '0 1 0 0 0'). mjsEquality.data layout reserves slots 0..4 for it on joint/tendon equalities; slots 5..10 hold other fields (e.g. weld's torquescale at 10). Capping the slot_range here keeps a TArray longer than 5 entries from overflowing into those slots.",
- "slot_range": [0, 5],
- "condition": "(EqualityType == EMjEqualityType::Joint) || (EqualityType == EMjEqualityType::Tendon)"
- },
- "torquescale": {
- "slot": 10,
- "condition": "EqualityType == EMjEqualityType::Weld"
- }
- }
- },
- "camera": {
- "_note": "MJCF camera.mode is a tracking mode (mjtCamLight subset). URLab declares EMjCameraTrackingMode hand-side; codegen owns the XML<->enum map. NOT to be confused with URLab's EMjCameraMode which is a UE-side render-mode selector (RGB/Depth/Segmentation).",
- "_note_common_imports": "Camera also reads name; the hand-written ImportFromXml has a fallback `if MjName empty -> 'Camera'` that runs AFTER this read.",
- "common_imports": ["name"],
- "applies_canonicalizations": ["spatial_pose", "orientation"],
- "_note_hidden": "See _doc_transform_widget_policy. Intrinsics (fovy, ipd, focal, etc.) stay visible.",
- "hidden_canon_properties": ["spatial_pose", "orientation"],
- "_note_attr_to_mjs_field": "MuJoCo renames a handful of camera attrs between the XML schema and the mjsCamera struct: target -> targetbody (mjString*), projection -> proj (mjtProjection enum), focal -> focal_length, principal -> principal_length. sensorsize auto-resolves to sensor_size via the underscore-normalise heuristic. Without this map the auto-resolver in _resolve_mjs_field can't bridge target/focal/principal and they were silently dropped on export.",
- "attr_to_mjs_field": {
- "target": "targetbody",
- "focal": "focal_length",
- "principal": "principal_length"
- },
- "_note_property_units": "Camera lengths (ipd, focal, principal, sensorsize) stay in raw MJ metres on the UE side; tagging them with Units=\"m\" gives the editor a suffix and lets Display Units convert to mm/cm. fovy is degrees per the MJCF spec. focalpixel / principalpixel are pixel counts (not lengths) and are intentionally untagged.",
- "property_units": {
- "ipd": "m",
- "focal": "m",
- "principal": "m",
- "sensorsize": "m",
- "fovy": "deg"
- },
- "xml_enum_attrs": {
- "mode": {
- "ue_property": "TrackingMode",
- "ue_enum_type": "EMjCameraTrackingMode",
- "mjs_field": "mode",
- "mjs_cast": "mjtCamLight",
- "value_map": {
- "fixed": ["Fixed", "mjCAMLIGHT_FIXED"],
- "track": ["Track", "mjCAMLIGHT_TRACK"],
- "trackcom": ["TrackCom", "mjCAMLIGHT_TRACKCOM"],
- "targetbody": ["TargetBody", "mjCAMLIGHT_TARGETBODY"],
- "targetbodycom": ["TargetBodyCom", "mjCAMLIGHT_TARGETBODYCOM"]
- }
- },
- "projection": {
- "ue_property": "Projection",
- "ue_enum_type": "EMjCameraProjection",
- "mjs_field": "proj",
- "mjs_cast": "mjtProjection",
- "value_map": {
- "orthographic": ["Orthographic", "mjPROJ_ORTHOGRAPHIC"],
- "perspective": ["Perspective", "mjPROJ_PERSPECTIVE"]
- }
- }
- }
- },
- "body": {
- "common_imports": ["name"],
- "applies_canonicalizations": ["spatial_pose", "orientation", "body_sleep_policy"],
- "_note_canon_export_skip": "Body's pos/quat are written by MjSpecWrapper::CreateBody from the UE component transform (the source of truth for body placement). The codegen-emitted spatial_pose/orientation export would overwrite those with the Pos/Quat UPROPERTYs, which are stale for any body not freshly imported from XML. Skip the export side for these two canons.",
- "canon_export_skip": ["spatial_pose", "orientation"],
- "_note_hidden": "See _doc_transform_widget_policy. canon_export_skip routes the write through the UE transform.",
- "hidden_canon_properties": ["spatial_pose", "orientation"],
- "property_meta": {
- "mocap": "DisplayName=\"Driven By Unreal\"",
- "childclass": "GetOptions=\"GetChildClassOptions\""
- }
- },
- "inertial": {
- "applies_canonicalizations": ["spatial_pose", "orientation"],
- "_note_hidden": "See _doc_transform_widget_policy. UMjInertial::RegisterToSpec (hand-rolled) writes ParentBody->ipos/iquat from the UE transform.",
- "hidden_canon_properties": ["spatial_pose", "orientation"]
- },
- "frame": {
- "_note": "Like body: the UE component transform is the source of truth for placement. Codegen imports XML pos/quat into Pos/Quat UPROPERTYs (UE units / UE frame) and the cpp drives SetRelativeLocation/SetRelativeRotation from them. Spec export is skipped for the canon Pos/Quat because MjSpecWrapper::CreateFrame writes pos/quat from the UE transform.",
- "applies_canonicalizations": ["spatial_pose", "orientation"],
- "canon_export_skip": ["spatial_pose", "orientation"],
- "hidden_canon_properties": ["spatial_pose", "orientation"]
- },
- "flexcomp": {
- "_note": "Flexcomp doesn't register via mjs_addX — at spec time UMjFlexcomp builds a tiny standalone MJCF fragment and re-parses it via mj_parseXMLString + mjs_attach (the flexcomp macro is expanded by MuJoCo's XML parser, not the spec API). Codegen still owns the UPROPERTY surface so new MJCF attrs auto-appear; BuildFlexcompXml in MjFlexcomp.cpp reads from those codegen-owned fields. Sub-elements (///) remain hand-rolled because the codegen doesn't have per-sub-element UPROPERTY support yet.",
- "_note_material": "material codegen-owned for IMPORT but export-skipped — URLab handles materials as UE assets, not mjsMaterial spec entries.",
- "export_skip_attrs": ["material"],
- "applies_canonicalizations": ["spatial_pose", "orientation"],
- "canon_export_skip": ["spatial_pose", "orientation"],
- "hidden_canon_properties": ["spatial_pose", "orientation"],
- "property_units": {
- "radius": "m",
- "spacing": "m"
- },
- "xml_enum_attrs": {
- "type": {
- "ue_property": "FlexcompType",
- "ue_enum_type": "EMjFlexcompType",
- "mjs_field": "type",
- "mjs_cast": "int",
- "value_map": {
- "grid": ["Grid", "0"],
- "box": ["Box", "1"],
- "cylinder": ["Cylinder", "2"],
- "ellipsoid": ["Ellipsoid", "3"],
- "square": ["Square", "4"],
- "disc": ["Disc", "5"],
- "circle": ["Circle", "6"],
- "mesh": ["Mesh", "7"],
- "gmsh": ["Gmsh", "8"],
- "direct": ["Direct", "9"]
- }
- },
- "dof": {
- "ue_property": "FlexcompDof",
- "ue_enum_type": "EMjFlexcompDof",
- "mjs_field": "dof",
- "mjs_cast": "int",
- "value_map": {
- "full": ["Full", "0"],
- "radial": ["Radial", "1"],
- "trilinear": ["Trilinear", "2"],
- "quadratic": ["Quadratic", "3"],
- "2d": ["TwoD", "4"]
- }
- }
- }
- },
- "freejoint": {
- },
- "contact_pair": {
- "common_imports": [{"attr": "name", "ue_field": "Name"}],
- "property_units": {
- "margin": "m",
- "gap": "m"
- }
- },
- "contact_exclude": {
- "common_imports": [{"attr": "name", "ue_field": "Name"}]
- },
- "keyframe": {
- "_note": "qpos/qvel/act/ctrl/mpos/mquat target mjsKey's mjDoubleVec* fields (std::vector*) — require ->clear()+->push_back() rather than direct assignment. Codegen emits the import (TArray read) + the mjs_double_vec-style export. RegisterToSpec hand-rolls freejoint-padding for qpos/qvel.",
- "mjs_double_vec_attrs": ["qpos", "qvel", "act", "ctrl", "mpos", "mquat"]
- }
- },
-
- "categories": {
- "actuator": {
- "layout": "single_uclass_per_file",
- "base_class_name": "UMjActuator",
- "base_class_header": "MuJoCo/Components/Actuators/MjActuator.h",
- "subclass_directory_pub": "MuJoCo/Components/Actuators",
- "subclass_directory_priv": "MuJoCo/Components/Actuators",
- "mjs_struct": "mjsActuator",
- "schema_common_block": "actuator_common.attrs",
- "schema_common_extra_attrs": ["gainprm", "biasprm", "dynprm", "gaintype", "biastype", "dyntype", "actdim"],
- "schema_subtypes_block": "actuator_types",
- "type_enum_name": "EMjActuatorType",
- "subtypes": [
- {"key": "general", "enum_value": "Motor", "class_name": "UMjGeneralActuator", "header": "MjGeneralActuator.h"},
- {"key": "motor", "enum_value": "Motor", "class_name": "UMjMotorActuator", "header": "MjMotorActuator.h"},
- {"key": "position", "enum_value": "Position", "class_name": "UMjPositionActuator", "header": "MjPositionActuator.h"},
- {"key": "velocity", "enum_value": "Velocity", "class_name": "UMjVelocityActuator", "header": "MjVelocityActuator.h"},
- {"key": "intvelocity", "enum_value": "IntVelocity","class_name": "UMjIntVelocityActuator", "header": "MjIntVelocityActuator.h"},
- {"key": "damper", "enum_value": "Damper", "class_name": "UMjDamperActuator", "header": "MjDamperActuator.h"},
- {"key": "cylinder", "enum_value": "Cylinder", "class_name": "UMjCylinderActuator", "header": "MjCylinderActuator.h"},
- {"key": "muscle", "enum_value": "Muscle", "class_name": "UMjMuscleActuator", "header": "MjMuscleActuator.h"},
- {"key": "adhesion", "enum_value": "Adhesion", "class_name": "UMjAdhesionActuator", "header": "MjAdhesionActuator.h"},
- {"key": "dcmotor", "enum_value": "DcMotor", "class_name": "UMjDcMotorActuator", "header": "MjDcMotorActuator.h"}
- ],
- "_note_subtype_setto": "Codegen-driven mjs_setTo* call config. Function signatures come from the clang-AST introspect snapshot, projected by _mjspec_from_introspect; the generator emits the call from the signature + the per-subtype config below. NO hand-written C++ literals in this file.",
- "_note_inherit_fields": "MuJoCo's mjs_setTo* write some params UNCONDITIONALLY by value (e.g. gainprm[0] = kp), so there is no sentinel meaning 'unset' — passing one clobbers the value the default class already put on the element via mjs_addActuator. For those params, `inherit_fields` names the C++ expression the generator re-asserts when the UPROPERTY isn't overridden, preserving the inherited value. `nullable_params` are pointer args (double x[1]) MuJoCo skips on nullptr; passing nullptr when unset is MuJoCo's actual 'leave default alone' convention (its own Python binding maps -1 -> nullptr). Muscle/dcmotor are unaffected: muscle guards every param with `>= 0` so the -1.0 sentinel is correct, and dcmotor already passes nullptr for unset arrays.",
- "subtype_setto": {
- "general": null,
- "motor": {"call": "mjs_setToMotor"},
- "position": {"call": "mjs_setToPosition",
- "inherit_fields": {"kp": "Element->gainprm[0]"},
- "nullable_params": ["kv", "dampratio", "timeconst"]},
- "velocity": {"call": "mjs_setToVelocity",
- "inherit_fields": {"kv": "Element->gainprm[0]"}},
- "intvelocity": {"call": "mjs_setToIntVelocity",
- "inherit_fields": {"kp": "Element->gainprm[0]"},
- "nullable_params": ["kv", "dampratio", "timeconst"]},
- "_todo_damper_inherit": "TODO(jonat): decide fidelity vs correctness for damper's inherited kv. MuJoCo's xml_native_reader.cc OneActuator() seeds `double kv = 0` for the damper case (all sibling types seed from the inherited field, e.g. position `kp = actuator->gainprm[0]`), so mj_loadXML SILENTLY DROPS a damper's class-inherited kv to 0 — verified a bug, present in upstream main. URLab's inherit_fields below re-asserts -gainprm[2], so URLab is MORE correct (keeps kv) but DIVERGES from mj_loadXML, which can break UE-vs-bridge sim2sim. Revisit: either match MuJoCo bug-for-bug for fidelity, or upstream a fix (seed `kv = -actuator->gainprm[2]`). See MjActuatorInheritanceTests InheritedDamperKv_Preserved.",
- "damper": {"call": "mjs_setToDamper",
- "inherit_fields": {"kv": "-Element->gainprm[2]"}},
- "cylinder": {"call": "mjs_setToCylinder",
- "inherit_fields": {"timeconst": "Element->dynprm[0]", "bias": "Element->biasprm[0]", "area": "Element->gainprm[0]"}},
- "muscle": {"call": "mjs_setToMuscle",
- "projections": {"scale": "X"}},
- "adhesion": {"call": "mjs_setToAdhesion",
- "inherit_fields": {"gain": "Element->gainprm[0]"}},
- "dcmotor": {"call": "mjs_setToDCMotor",
- "nullable_arrays": true,
- "use_filldouble": true,
- "param_renames": {"input_mode": "input"}}
- }
- },
-
- "sensor": {
- "layout": "single_uclass_per_file",
- "base_class_name": "UMjSensor",
- "base_class_header": "MuJoCo/Components/Sensors/MjSensor.h",
- "subclass_directory_pub": "MuJoCo/Components/Sensors",
- "subclass_directory_priv": "MuJoCo/Components/Sensors",
- "mjs_struct": "mjsSensor",
- "schema_common_block": "sensor_common.attrs",
- "schema_subtypes_block": "sensor_types",
- "type_enum_name": "EMjSensorType",
- "subtypes": [
- {"key": "touch", "enum_value": "Touch", "class_name": "UMjTouchSensor", "header": "MjTouchSensor.h", "fully_emitted": true},
- {"key": "accelerometer", "enum_value": "Accelerometer", "class_name": "UMjAccelerometer", "header": "MjAccelerometer.h", "fully_emitted": true},
- {"key": "velocimeter", "enum_value": "Velocimeter", "class_name": "UMjVelocimeter", "header": "MjVelocimeter.h", "fully_emitted": true},
- {"key": "gyro", "enum_value": "Gyro", "class_name": "UMjGyro", "header": "MjGyro.h", "fully_emitted": true},
- {"key": "force", "enum_value": "Force", "class_name": "UMjForceSensor", "header": "MjForceSensor.h", "fully_emitted": true},
- {"key": "torque", "enum_value": "Torque", "class_name": "UMjTorqueSensor", "header": "MjTorqueSensor.h", "fully_emitted": true},
- {"key": "magnetometer", "enum_value": "Magnetometer", "class_name": "UMjMagnetometer", "header": "MjMagnetometer.h", "fully_emitted": true},
- {"key": "camprojection", "enum_value": "CamProjection", "class_name": "UMjCamProjectionSensor", "header": "MjCamProjectionSensor.h", "fully_emitted": true},
- {"key": "rangefinder", "enum_value": "RangeFinder", "class_name": "UMjRangeFinderSensor", "header": "MjRangeFinderSensor.h",
- "case_body_override": "Element->type = mjSENS_RANGEFINDER; Element->objtype = (ObjType == EMjObjType::Camera) ? mjOBJ_CAMERA : mjOBJ_SITE;",
- "fully_emitted": true},
- {"key": "jointpos", "enum_value": "JointPos", "class_name": "UMjJointPosSensor", "header": "MjJointPosSensor.h"},
- {"key": "jointvel", "enum_value": "JointVel", "class_name": "UMjJointVelSensor", "header": "MjJointVelSensor.h", "fully_emitted": true},
- {"key": "ballquat", "enum_value": "BallQuat", "class_name": "UMjBallQuatSensor", "header": "MjBallQuatSensor.h", "fully_emitted": true},
- {"key": "ballangvel", "enum_value": "BallAngVel", "class_name": "UMjBallAngVelSensor", "header": "MjBallAngVelSensor.h", "fully_emitted": true},
- {"key": "jointlimitpos", "enum_value": "JointLimitPos", "class_name": "UMjJointLimitPosSensor", "header": "MjJointLimitPosSensor.h", "fully_emitted": true},
- {"key": "jointlimitvel", "enum_value": "JointLimitVel", "class_name": "UMjJointLimitVelSensor", "header": "MjJointLimitVelSensor.h", "fully_emitted": true},
- {"key": "jointlimitfrc", "enum_value": "JointLimitFrc", "class_name": "UMjJointLimitFrcSensor", "header": "MjJointLimitFrcSensor.h", "fully_emitted": true},
- {"key": "tendonpos", "enum_value": "TendonPos", "class_name": "UMjTendonPosSensor", "header": "MjTendonPosSensor.h", "fully_emitted": true},
- {"key": "tendonvel", "enum_value": "TendonVel", "class_name": "UMjTendonVelSensor", "header": "MjTendonVelSensor.h", "fully_emitted": true},
- {"key": "tendonlimitpos", "enum_value": "TendonLimitPos", "class_name": "UMjTendonLimitPosSensor", "header": "MjTendonLimitPosSensor.h", "fully_emitted": true},
- {"key": "tendonlimitvel", "enum_value": "TendonLimitVel", "class_name": "UMjTendonLimitVelSensor", "header": "MjTendonLimitVelSensor.h", "fully_emitted": true},
- {"key": "tendonlimitfrc", "enum_value": "TendonLimitFrc", "class_name": "UMjTendonLimitFrcSensor", "header": "MjTendonLimitFrcSensor.h", "fully_emitted": true},
- {"key": "actuatorpos", "enum_value": "ActuatorPos", "class_name": "UMjActuatorPosSensor", "header": "MjActuatorPosSensor.h", "fully_emitted": true},
- {"key": "actuatorvel", "enum_value": "ActuatorVel", "class_name": "UMjActuatorVelSensor", "header": "MjActuatorVelSensor.h", "fully_emitted": true},
- {"key": "actuatorfrc", "enum_value": "ActuatorFrc", "class_name": "UMjActuatorFrcSensor", "header": "MjActuatorFrcSensor.h", "fully_emitted": true},
- {"key": "jointactuatorfrc", "enum_value": "JointActFrc", "class_name": "UMjJointActFrcSensor", "header": "MjJointActFrcSensor.h", "fully_emitted": true},
- {"key": "tendonactuatorfrc","enum_value": "TendonActFrc", "class_name": "UMjTendonActFrcSensor", "header": "MjTendonActFrcSensor.h", "fully_emitted": true},
- {"key": "framepos", "enum_value": "FramePos", "class_name": "UMjFramePosSensor", "header": "MjFramePosSensor.h", "fully_emitted": true},
- {"key": "framequat", "enum_value": "FrameQuat", "class_name": "UMjFrameQuatSensor", "header": "MjFrameQuatSensor.h", "fully_emitted": true},
- {"key": "framexaxis", "enum_value": "FrameXAxis", "class_name": "UMjFrameXAxisSensor", "header": "MjFrameXAxisSensor.h", "fully_emitted": true},
- {"key": "frameyaxis", "enum_value": "FrameYAxis", "class_name": "UMjFrameYAxisSensor", "header": "MjFrameYAxisSensor.h", "fully_emitted": true},
- {"key": "framezaxis", "enum_value": "FrameZAxis", "class_name": "UMjFrameZAxisSensor", "header": "MjFrameZAxisSensor.h", "fully_emitted": true},
- {"key": "framelinvel", "enum_value": "FrameLinVel", "class_name": "UMjFrameLinVelSensor", "header": "MjFrameLinVelSensor.h", "fully_emitted": true},
- {"key": "frameangvel", "enum_value": "FrameAngVel", "class_name": "UMjFrameAngVelSensor", "header": "MjFrameAngVelSensor.h", "fully_emitted": true},
- {"key": "framelinacc", "enum_value": "FrameLinAcc", "class_name": "UMjFrameLinAccSensor", "header": "MjFrameLinAccSensor.h", "fully_emitted": true},
- {"key": "frameangacc", "enum_value": "FrameAngAcc", "class_name": "UMjFrameAngAccSensor", "header": "MjFrameAngAccSensor.h", "fully_emitted": true},
- {"key": "subtreecom", "enum_value": "SubtreeCom", "class_name": "UMjSubtreeComSensor", "header": "MjSubtreeComSensor.h", "fully_emitted": true},
- {"key": "subtreelinvel", "enum_value": "SubtreeLinVel", "class_name": "UMjSubtreeLinVelSensor", "header": "MjSubtreeLinVelSensor.h", "fully_emitted": true},
- {"key": "subtreeangmom", "enum_value": "SubtreeAngMom", "class_name": "UMjSubtreeAngMomSensor", "header": "MjSubtreeAngMomSensor.h", "fully_emitted": true},
- {"key": "insidesite", "enum_value": "InsideSite", "class_name": "UMjInsideSiteSensor", "header": "MjInsideSiteSensor.h", "fully_emitted": true},
- {"key": "distance", "enum_value": "GeomDist", "class_name": "UMjGeomDistSensor", "header": "MjGeomDistSensor.h", "fully_emitted": true},
- {"key": "normal", "enum_value": "GeomNormal", "class_name": "UMjGeomNormalSensor", "header": "MjGeomNormalSensor.h", "fully_emitted": true},
- {"key": "fromto", "enum_value": "GeomFromTo", "class_name": "UMjGeomFromToSensor", "header": "MjGeomFromToSensor.h", "fully_emitted": true},
- {"key": "contact", "enum_value": "Contact", "class_name": "UMjContactSensor", "header": "MjContactSensor.h", "fully_emitted": true},
- {"key": "e_potential", "enum_value": "EPotential", "class_name": "UMjEPotentialSensor", "header": "MjEPotentialSensor.h", "fully_emitted": true},
- {"key": "e_kinetic", "enum_value": "EKinetic", "class_name": "UMjEKineticSensor", "header": "MjEKineticSensor.h", "fully_emitted": true},
- {"key": "clock", "enum_value": "Clock", "class_name": "UMjClockSensor", "header": "MjClockSensor.h", "fully_emitted": true},
- {"key": "tactile", "enum_value": "Tactile", "class_name": "UMjTactileSensor", "header": "MjTactileSensor.h"},
- {"key": "user", "enum_value": "User", "class_name": "UMjUserSensor", "header": "MjUserSensor.h", "fully_emitted": true},
- {"key": "plugin", "enum_value": "Plugin", "class_name": "UMjPluginSensor", "header": "MjPluginSensor.h", "fully_emitted": true}
- ]
- },
-
- "joint": {
- "layout": "single_uclass_per_file",
- "base_class_name": "UMjJoint",
- "base_class_header": "MuJoCo/Components/Joints/MjJoint.h",
- "subclass_directory_pub": "MuJoCo/Components/Joints",
- "subclass_directory_priv": "MuJoCo/Components/Joints",
- "mjs_struct": "mjsJoint",
- "schema_common_block": "joint.attrs",
- "type_enum_name": "EMjJointType",
- "subtypes": [
- {"key": "hinge", "enum_value": "Hinge", "class_name": "UMjHingeJoint", "header": "MjHingeJoint.h", "fully_emitted": true,
- "_note_extra_ctor": "UMjJoint::ExportTo only writes Element->type when bOverride_Type is true. Without this flag set in the subclass ctor, BP-spawned joints fall back to the mjsJoint default (mjJNT_HINGE), silently substituting Ball/Slide joints for Hinge.",
- "extra_constructor": "bOverride_Type = true;"},
- {"key": "slide", "enum_value": "Slide", "class_name": "UMjSlideJoint", "header": "MjSlideJoint.h", "fully_emitted": true,
- "extra_constructor": "bOverride_Type = true;"},
- {"key": "ball", "enum_value": "Ball", "class_name": "UMjBallJoint", "header": "MjBallJoint.h", "fully_emitted": true,
- "extra_constructor": "bOverride_Type = true;"},
- {"key": "free", "enum_value": "Free", "class_name": "UMjFreeJoint", "header": "MjFreeJoint.h"}
- ]
- },
-
- "site": {
- "layout": "multi_uclass",
- "base_class_name": "UMjSite",
- "base_class_header": "MuJoCo/Components/Geometry/MjSite.h",
- "mjs_struct": "mjsSite",
- "schema_common_block": "site.attrs",
- "type_enum_name": "EMjSiteType",
- "subtypes": [
- {"key": "box", "enum_value": "Box", "class_name": "UMjBoxSite"},
- {"key": "sphere", "enum_value": "Sphere", "class_name": "UMjSphereSite"},
- {"key": "capsule", "enum_value": "Capsule", "class_name": "UMjCapsuleSite"},
- {"key": "cylinder", "enum_value": "Cylinder", "class_name": "UMjCylinderSite"},
- {"key": "ellipsoid", "enum_value": "Ellipsoid", "class_name": "UMjEllipsoidSite"}
- ]
- },
-
- "tendon": {
- "layout": "multi_uclass",
- "base_class_name": "UMjTendon",
- "base_class_header": "MuJoCo/Components/Tendons/MjTendon.h",
- "mjs_struct": "mjsTendon",
- "schema_common_block": "tendon.spatial.attrs",
- "type_enum_name": "EMjTendonType",
- "subtypes": [
- {"key": "spatial", "enum_value": "Spatial", "class_name": "UMjSpatialTendon"},
- {"key": "fixed", "enum_value": "Fixed", "class_name": "UMjFixedTendon"}
- ]
- },
-
- "equality": {
- "layout": "multi_uclass",
- "base_class_name": "UMjEquality",
- "base_class_header": "MuJoCo/Components/Constraints/MjEquality.h",
- "mjs_struct": "mjsEquality",
- "schema_common_block": "equality.weld",
- "schema_common_extra_attrs": ["polycoef"],
- "type_enum_name": "EMjEqualityType",
- "_note_objtype_dispatch": "mjsEquality.objtype tells MuJoCo what kind of object name1/name2 refer to. Connect/Weld are dual-mode: site-to-site if site1 was specified, else body-to-body. Codegen emits a switch on EqualityType into the CODEGEN_OBJTYPE_DISPATCH markers in MjEquality.cpp.",
- "objtype_dispatch": {
- "discriminator": "EqualityType",
- "target": "Element->objtype",
- "default": "mjOBJ_UNKNOWN",
- "cases": [
- {"keys": ["Connect", "Weld"], "expr": "!site1.IsEmpty() ? mjOBJ_SITE : mjOBJ_BODY"},
- {"keys": ["Joint"], "expr": "mjOBJ_JOINT"},
- {"keys": ["Tendon"], "expr": "mjOBJ_TENDON"},
- {"keys": ["Flex", "FlexVert", "FlexStrain"], "expr": "mjOBJ_FLEX"}
- ]
- },
- "subtypes": [
- {"key": "connect", "enum_value": "Connect", "class_name": "UMjConnectEquality"},
- {"key": "weld", "enum_value": "Weld", "class_name": "UMjWeldEquality"},
- {"key": "joint", "enum_value": "Joint", "class_name": "UMjJointEquality"},
- {"key": "tendon", "enum_value": "Tendon", "class_name": "UMjTendonEquality"},
- {"key": "flex", "enum_value": "Flex", "class_name": "UMjFlexEquality"},
- {"key": "flexvert", "enum_value": "FlexVert", "class_name": "UMjFlexVertEquality"},
- {"key": "flexstrain", "enum_value": "FlexStrain", "class_name": "UMjFlexStrainEquality"}
- ]
- },
-
- "geom": {
- "layout": "single_uclass_per_file",
- "base_class_name": "UMjGeom",
- "base_class_header": "MuJoCo/Components/Geometry/MjGeom.h",
- "subclass_directory_pub": "MuJoCo/Components/Geometry/Primitives",
- "subclass_directory_priv": "MuJoCo/Components/Geometry/Primitives",
- "mjs_struct": "mjsGeom",
- "schema_common_block": "geom.attrs",
- "type_enum_name": "EMjGeomType",
- "_note_geom_final_type": "Mesh-name export depends on the COMPILE-TIME geom type, which is either the UPROPERTY Type (if overridden) or the Default geom's type (otherwise). Codegen emits the resolution + the conditional mesh-name write into the CODEGEN_GEOM_FINAL_TYPE markers in MjGeom.cpp. The value_map is pulled from element_rules.geom.xml_enum_attrs.type so there's only one source of truth for the XML/UE/mj triplet.",
- "geom_final_type": {
- "xml_enum_ref": "type",
- "override_field": "bOverride_Type",
- "default_lookup": "Default->geom->type",
- "default_fallback": "mjGEOM_MESH",
- "name_field": "MeshName",
- "name_export_for": "mjGEOM_MESH",
- "name_target": "Element->meshname",
- "name_setter": "MjSetStringRaw"
- },
- "subtypes": [
- {"key": "box", "enum_value": "Box", "class_name": "UMjBox", "header": "MjBox.h"},
- {"key": "sphere", "enum_value": "Sphere", "class_name": "UMjSphere", "header": "MjSphere.h"},
- {"key": "capsule", "enum_value": "Capsule", "class_name": "UMjCapsule", "header": "MjCapsule.h"},
- {"key": "cylinder", "enum_value": "Cylinder", "class_name": "UMjCylinder", "header": "MjCylinder.h"},
- {"key": "ellipsoid", "enum_value": "Ellipsoid", "class_name": "UMjEllipsoid", "header": "MjEllipsoid.h", "fully_emitted": true},
- {"key": "plane", "enum_value": "Plane", "class_name": "UMjPlane", "header": "MjPlane.h", "fully_emitted": true},
- {"key": "sdf", "enum_value": "SDF", "class_name": "UMjSdf", "header": "MjSdf.h", "fully_emitted": true}
- ],
- "_note_skipped_subtypes": ["hfield (URLab has its own hfield actor system)", "mesh (existing UMjMeshGeom)"]
- },
-
- "camera": {
- "layout": "no_subclasses",
- "base_class_name": "UMjCamera",
- "base_class_header": "MuJoCo/Components/Sensors/MjCamera.h",
- "mjs_struct": "mjsCamera",
- "schema_common_block": "camera.attrs"
- },
-
- "flexcomp": {
- "_note": "flexcomp doesn't register via mjs_addX — at spec time UMjFlexcomp builds a tiny standalone MJCF fragment and re-parses it via mj_parseXMLString + mjs_attach (the flexcomp macro is expanded by MuJoCo's XML parser, not the spec API). xml_passthrough_emission flips the export side from mjs writes to MJCF attribute-string writes (BuildSchemaAttrsXml), so any new schema attr flows end-to-end without a hand-edit.",
- "layout": "no_subclasses",
- "base_class_name": "UMjFlexcomp",
- "base_class_header": "MuJoCo/Components/Deformable/MjFlexcomp.h",
- "mjs_struct": "mjsFlex",
- "schema_common_block": "flexcomp.attrs",
- "xml_passthrough_emission": true
- },
-
- "body": {
- "layout": "no_subclasses",
- "base_class_name": "UMjBody",
- "base_class_header": "MuJoCo/Components/Bodies/MjBody.h",
- "mjs_struct": "mjsBody",
- "schema_common_block": "body.attrs"
- },
-
- "frame": {
- "_note": "MJCF nests inside / and supplies a coordinate offset that the MuJoCo compiler bakes into the pos/quat of its child elements. UE-side the frame is a USceneComponent with a relative transform; MjFrame::Setup walks children and dispatches RegisterToSpec. The codegen-emitted Import populates Pos/Quat UPROPERTYs from XML — but the source of truth for placement is the UE transform (set via SetRelativeLocation/Rotation in ImportFromXml), so canon export is skipped for spatial_pose/orientation. childclass is codegen-owned (FString -> mjs_setString).",
- "layout": "no_subclasses",
- "base_class_name": "UMjFrame",
- "base_class_header": "MuJoCo/Components/Bodies/MjFrame.h",
- "mjs_struct": "mjsFrame",
- "schema_common_block": "frame.attrs",
- "schema_common_extra_attrs": ["pos", "quat", "axisangle", "euler", "xyaxes", "zaxis", "childclass"]
- },
-
- "inertial": {
- "_note_export": "MJCF has no corresponding mjsInertial struct; the export path writes to ParentBody->{mass,inertia,fullinertia,ipos,iquat} in a hand-rolled UMjInertial::RegisterToSpec. disable_mjs_export_emission suppresses the codegen-emitted Element->* export block so the hand-rolled path stays canonical.",
- "layout": "no_subclasses",
- "base_class_name": "UMjInertial",
- "base_class_header": "MuJoCo/Components/Physics/MjInertial.h",
- "mjs_struct": "mjsInertial",
- "schema_common_block": "inertial.attrs",
- "disable_mjs_export_emission": true
- },
-
- "contact_pair": {
- "layout": "no_subclasses",
- "base_class_name": "UMjContactPair",
- "base_class_header": "MuJoCo/Components/Physics/MjContactPair.h",
- "mjs_struct": "mjsPair",
- "schema_common_block": "contact.pair"
- },
-
- "contact_exclude": {
- "layout": "no_subclasses",
- "base_class_name": "UMjContactExclude",
- "base_class_header": "MuJoCo/Components/Physics/MjContactExclude.h",
- "mjs_struct": "mjsExclude",
- "schema_common_block": "contact.exclude"
- },
-
- "keyframe": {
- "layout": "no_subclasses",
- "_note": "qpos/qvel/etc are mjDoubleVec* on mjsKey, handled by the mjs_double_vec_attrs rule in element_rules.keyframe. Time + the override toggles are codegen-owned. RegisterToSpec hand-rolls the freejoint padding (which post-mutates Element->qpos/qvel after ExportTo).",
- "base_class_name": "UMjKeyframe",
- "base_class_header": "MuJoCo/Components/Keyframes/MjKeyframe.h",
- "mjs_struct": "mjsKey",
- "schema_common_block": "keyframe.key"
- }
- },
-
- "views": {
- "BodyView": {
- "include_blocks": ["MJMODEL_POINTERS_BODY", "MJMODEL_POINTERS_TREE"],
- "data_fields": {
- "xpos": {"index_var": "id", "stride": "3"},
- "xquat": {"index_var": "id", "stride": "4"},
- "xmat": {"index_var": "id", "stride": "9"},
- "cvel": {"index_var": "id", "stride": "6"},
- "cinert": {"index_var": "id", "stride": "10"},
- "xfrc_applied": {"index_var": "id", "stride": "6"}
- }
- },
- "JointView": {
- "include_blocks": ["MJMODEL_POINTERS_JOINT", "MJMODEL_POINTERS_DOF"],
- "derived_index_vars": {
- "qpos_adr": "m->jnt_qposadr[id]",
- "dof_adr": "m->jnt_dofadr[id]"
- },
- "block_index_var": {
- "MJMODEL_POINTERS_JOINT": "id",
- "MJMODEL_POINTERS_DOF": "dof_adr"
- },
- "data_fields": {
- "qpos": {"index_var": "qpos_adr", "stride": "1"},
- "qvel": {"index_var": "dof_adr", "stride": "1"},
- "qacc": {"index_var": "dof_adr", "stride": "1"},
- "xanchor": {"index_var": "id", "stride": "3"},
- "xaxis": {"index_var": "id", "stride": "3"}
- }
- },
- "GeomView": {
- "include_blocks": ["MJMODEL_POINTERS_GEOM"],
- "data_fields": {
- "geom_xpos": {"index_var": "id", "stride": "3"},
- "geom_xmat": {"index_var": "id", "stride": "9"}
- }
- },
- "SiteView": {
- "include_blocks": ["MJMODEL_POINTERS_SITE"],
- "data_fields": {
- "site_xpos": {"index_var": "id", "stride": "3"},
- "site_xmat": {"index_var": "id", "stride": "9"}
- }
- },
- "ActuatorView": {
- "include_blocks": ["MJMODEL_POINTERS_ACTUATOR"],
- "data_fields": {
- "ctrl": {"index_var": "id", "stride": "1"},
- "actuator_force": {"index_var": "id", "stride": "1"},
- "actuator_length":{"index_var": "id", "stride": "1"},
- "actuator_velocity":{"index_var": "id", "stride": "1"},
- "_note_moment": "Per-actuator row of the actuator_moment (nu x nv) matrix. Stride is m->nv, which is a valid stride expression — no bind_override needed.",
- "actuator_moment": {"index_var": "id", "stride": "m->nv"},
- "_note_act": "act lives in d->act indexed by m->actuator_actadr[id]. The adr can be -1 for actuators without an internal activation state; bind_override emits the nullable lookup so consumers can null-check ``act`` directly.",
- "act": {"bind_override": "act = (m->actuator_actadr[id] >= 0) ? d->act + m->actuator_actadr[id] : nullptr;"}
- }
- },
- "TendonView": {
- "include_blocks": ["MJMODEL_POINTERS_TENDON"],
- "data_fields": {
- "ten_length": {"index_var": "id", "stride": "1"},
- "ten_velocity": {"index_var": "id", "stride": "1"}
- }
- },
- "SensorView": {
- "include_blocks": ["MJMODEL_POINTERS_SENSOR"],
- "data_fields": {
- "_note_sensordata": "Bounds-checked slice — the default base+id*stride formula is wrong for sensordata (it would double-multiply adr*dim). bind_override is a verbatim C++ statement the codegen drops inside the BIND marker.",
- "sensordata": {"bind_override": "sensordata = (sensor_adr >= 0 && sensor_adr < m->nsensordata) ? d->sensordata + sensor_adr : nullptr;"}
- }
- }
- },
-
- "_note_editor_option_helpers": "Codegens trivial UMjX::GetYOptions() editor wrappers, injecting them between CODEGEN_EDITOR_OPTIONS_START/END markers inside each host .cpp's #if WITH_EDITOR block. Wrappers with real logic (TransmissionType / EqualityType / GetClassForObjType switches) stay hand-written in the same #if block.",
- "editor_option_helpers": {
- "wrappers": [
- {"class": "UMjActuator", "host_cpp": "MuJoCo/Components/Actuators/MjActuator.cpp",
- "method": "GetSliderSiteOptions", "filter_class": "UMjSite"},
- {"class": "UMjActuator", "host_cpp": "MuJoCo/Components/Actuators/MjActuator.cpp",
- "method": "GetRefSiteOptions", "filter_class": "UMjSite"},
- {"class": "UMjActuator", "host_cpp": "MuJoCo/Components/Actuators/MjActuator.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjBody", "host_cpp": "MuJoCo/Components/Bodies/MjBody.cpp",
- "method": "GetChildClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjGeom", "host_cpp": "MuJoCo/Components/Geometry/MjGeom.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjSite", "host_cpp": "MuJoCo/Components/Geometry/MjSite.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjJoint", "host_cpp": "MuJoCo/Components/Joints/MjJoint.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjContactExclude","host_cpp": "MuJoCo/Components/Physics/MjContactExclude.cpp",
- "method": "GetBodyOptions", "filter_class": "UMjBody"},
- {"class": "UMjContactPair", "host_cpp": "MuJoCo/Components/Physics/MjContactPair.cpp",
- "method": "GetGeomOptions", "filter_class": "UMjGeom"},
- {"class": "UMjSensor", "host_cpp": "MuJoCo/Components/Sensors/MjSensor.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true},
- {"class": "UMjTendon", "host_cpp": "MuJoCo/Components/Tendons/MjTendon.cpp",
- "method": "GetDefaultClassOptions", "filter_class": "UMjDefault", "include_defaults": true}
- ]
- },
-
- "_note_generated_enums": "Banner-mode .h with one or more UENUMs derived from the introspect snapshot's mjt* enums (projected into mjspec.enums by _mjspec_from_introspect). Hand-edits get clobbered on next regen. ``extra_members`` appends URLab-specific values that have no mjt counterpart (e.g. DcMotor).",
- "generated_enums": {
- "MjOptionEnums": {
- "public_header": "MuJoCo/Generated/MjOptionEnums.h",
- "enums": [
- {
- "ue_name": "EMjIntegrator",
- "from_mj_enum": "mjtIntegrator",
- "ue_member_from_mj": {
- "mjINT_EULER": "Euler",
- "mjINT_RK4": "RK4",
- "mjINT_IMPLICIT": "Implicit",
- "mjINT_IMPLICITFAST": "ImplicitFast"
- }
- },
- {
- "ue_name": "EMjCone",
- "from_mj_enum": "mjtCone",
- "ue_member_from_mj": {
- "mjCONE_PYRAMIDAL": "Pyramidal",
- "mjCONE_ELLIPTIC": "Elliptic"
- }
- },
- {
- "ue_name": "EMjSolver",
- "from_mj_enum": "mjtSolver",
- "ue_member_from_mj": {
- "mjSOL_PGS": "PGS",
- "mjSOL_CG": "CG",
- "mjSOL_NEWTON": "Newton"
- }
- }
- ]
- },
- "_note_MjArticulationEnums": "Pure value-mapping enums emitted as MuJoCo/Generated/MjArticulationEnums.h. Components that need them (MjActuator.h, MjGeom.h, MjCameraTypes.h, MjSensor.h, MjFlexcomp.h) include this header.",
- "MjArticulationEnums": {
- "public_header": "MuJoCo/Generated/MjArticulationEnums.h",
- "enums": [
- {
- "ue_name": "EMjGainType",
- "from_mj_enum": "mjtGain",
- "ue_member_from_mj": {
- "mjGAIN_FIXED": "Fixed",
- "mjGAIN_AFFINE": "Affine",
- "mjGAIN_MUSCLE": "Muscle",
- "mjGAIN_DCMOTOR": "DcMotor",
- "mjGAIN_USER": "User"
- }
- },
- {
- "ue_name": "EMjBiasType",
- "from_mj_enum": "mjtBias",
- "ue_member_from_mj": {
- "mjBIAS_NONE": "None",
- "mjBIAS_AFFINE": "Affine",
- "mjBIAS_MUSCLE": "Muscle",
- "mjBIAS_DCMOTOR": "DcMotor",
- "mjBIAS_USER": "User"
- }
- },
- {
- "ue_name": "EMjDynType",
- "from_mj_enum": "mjtDyn",
- "ue_member_from_mj": {
- "mjDYN_NONE": "None",
- "mjDYN_INTEGRATOR": "Integrator",
- "mjDYN_FILTER": "Filter",
- "mjDYN_FILTEREXACT": "FilterExact",
- "mjDYN_MUSCLE": "Muscle",
- "mjDYN_DCMOTOR": "DcMotor",
- "mjDYN_USER": "User"
- }
- },
- {
- "_note_EMjGeomInertia": "No mjt counterpart; MJCF geom inertia kind is parser-side enum string-mapped on import. Pure extra_members.",
- "ue_name": "EMjGeomInertia",
- "extra_members": [
- {"name": "Volume", "value": 0},
- {"name": "Shell", "value": 1}
- ]
- },
- {
- "_note_EMjFluidShape": "URLab-only; MuJoCo fluid shape is a runtime computation, not a public enum. Pure extra_members.",
- "ue_name": "EMjFluidShape",
- "extra_members": [
- {"name": "None", "value": 0},
- {"name": "Ellipsoid", "value": 1}
- ]
- },
- {
- "_note_EMjCameraTrackingMode": "Mirrors mjtCamLight but only the camera-side subset; values come from mjCAMLIGHT_* keyed by URLab member name.",
- "ue_name": "EMjCameraTrackingMode",
- "from_mj_enum": "mjtCamLight",
- "ue_member_from_mj": {
- "mjCAMLIGHT_FIXED": "Fixed",
- "mjCAMLIGHT_TRACK": "Track",
- "mjCAMLIGHT_TRACKCOM": "TrackCom",
- "mjCAMLIGHT_TARGETBODY": "TargetBody",
- "mjCAMLIGHT_TARGETBODYCOM": "TargetBodyCom"
- }
- },
- {
- "ue_name": "EMjCameraProjection",
- "from_mj_enum": "mjtProjection",
- "ue_member_from_mj": {
- "mjPROJ_PERSPECTIVE": "Perspective",
- "mjPROJ_ORTHOGRAPHIC": "Orthographic"
- }
- },
- {
- "ue_name": "EMjObjType",
- "from_mj_enum": "mjtObj",
- "exclude_mj_members": ["mjNOBJECT", "mjOBJ_DEFAULT", "mjOBJ_MODEL"],
- "ue_member_from_mj": {
- "mjOBJ_UNKNOWN": "Unknown",
- "mjOBJ_BODY": "Body",
- "mjOBJ_XBODY": "XBody",
- "mjOBJ_JOINT": "Joint",
- "mjOBJ_DOF": "DoF",
- "mjOBJ_GEOM": "Geom",
- "mjOBJ_SITE": "Site",
- "mjOBJ_CAMERA": "Camera",
- "mjOBJ_LIGHT": "Light",
- "mjOBJ_FLEX": "Flex",
- "mjOBJ_MESH": "Mesh",
- "mjOBJ_SKIN": "Skin",
- "mjOBJ_HFIELD": "HField",
- "mjOBJ_TEXTURE": "Texture",
- "mjOBJ_MATERIAL": "Material",
- "mjOBJ_PAIR": "Pair",
- "mjOBJ_EXCLUDE": "Exclude",
- "mjOBJ_EQUALITY": "Equality",
- "mjOBJ_TENDON": "Tendon",
- "mjOBJ_ACTUATOR": "Actuator",
- "mjOBJ_SENSOR": "Sensor",
- "mjOBJ_NUMERIC": "Numeric",
- "mjOBJ_TEXT": "Text",
- "mjOBJ_TUPLE": "Tuple",
- "mjOBJ_KEY": "Key",
- "mjOBJ_PLUGIN": "Plugin",
- "mjOBJ_FRAME": "Frame"
- }
- },
- {
- "_note_EMjActuatorTrnType": "mjTRN_UNDEFINED has C value 1000 (way out of uint8 range), so it can't be a direct ue_member_from_mj entry. Excluded from the snapshot pass and reintroduced as an extra_member with the next contiguous slot (6).",
- "ue_name": "EMjActuatorTrnType",
- "from_mj_enum": "mjtTrn",
- "exclude_mj_members": ["mjTRN_UNDEFINED"],
- "ue_member_from_mj": {
- "mjTRN_JOINT": "Joint",
- "mjTRN_JOINTINPARENT": "JointInParent",
- "mjTRN_SLIDERCRANK": "SliderCrank",
- "mjTRN_TENDON": "Tendon",
- "mjTRN_SITE": "Site",
- "mjTRN_BODY": "Body"
- },
- "extra_members": [
- {"name": "Undefined", "value": 6}
- ]
- },
- {
- "_note_EMjFlexcompDof": "URLab-only flex-component DoF reduction kind; no mjt counterpart (the MJCF attr is `dof` and parsed string-side). Pure extra_members; matches the pre-migration hand-rolled set.",
- "ue_name": "EMjFlexcompDof",
- "extra_members": [
- {"name": "Full", "value": 0},
- {"name": "Radial", "value": 1},
- {"name": "Trilinear", "value": 2},
- {"name": "Quadratic", "value": 3},
- {"name": "TwoD", "value": 4}
- ]
- }
- ]
- }
- },
-
- "_note_synthetic_categories": "Whole-file banner-mode emission for USTRUCTs mirroring C structs from mjxmacro_block. Hand-edits to generated files get clobbered on next regen. See generate_ue_components.py::_phase_synthetic_categories.",
- "synthetic_categories": {
- "MjStatistic": {
- "ue_struct_name": "FMjStatistic",
- "mjxmacro_block": "MJSTATISTIC_FIELDS",
- "c_struct_type": "mjStatistic",
- "public_header": "MuJoCo/Generated/MjStatistic.h",
- "private_source": "MuJoCo/Generated/MjStatistic.cpp",
- "category_label": "Statistic"
- },
-
- "_note_MjOption": "Codegen-emitted FMjOptionGenerated mirrors mjOption (MJOPTION_FIELDS) with URLab extras (MemoryMB, bEnableMultiCCD, bEnableSleep, SleepTolerance). AMjArticulation::SimOptions and UMjPhysicsEngine::SimOptions point at this struct directly.",
- "MjOption": {
- "ue_struct_name": "FMjOptionGenerated",
- "mjxmacro_block": "MJOPTION_FIELDS",
- "c_struct_type": "mjOption",
- "public_header": "MuJoCo/Generated/MjOptionGenerated.h",
- "private_source": "MuJoCo/Generated/MjOptionGenerated.cpp",
- "category_label": "MjOption",
- "include_directives": [
- "mujoco/mujoco.h",
- "MuJoCo/Generated/MjOptionEnums.h"
- ],
- "field_renames": {
- "timestep": "Timestep",
- "impratio": "Impratio",
- "tolerance": "Tolerance",
- "ls_tolerance": "LsTolerance",
- "noslip_tolerance": "NoslipTolerance",
- "ccd_tolerance": "CCD_Tolerance",
- "sdf_initpoints": "SdfInitPoints",
- "sdf_iterations": "SdfIterations",
- "iterations": "Iterations",
- "ls_iterations": "LsIterations",
- "noslip_iterations": "NoslipIterations",
- "ccd_iterations": "CCD_Iterations",
- "disableflags": "DisableFlags",
- "enableflags": "EnableFlags",
- "disableactuator": "DisableActuator",
- "apirate": "ApiRate",
- "sleep_tolerance": "SleepToleranceMj",
- "rebuild_interval": "RebuildInterval"
- },
- "field_types": {
- "timestep": "float",
- "apirate": "float",
- "integrator": "EMjIntegrator",
- "cone": "EMjCone",
- "solver": "EMjSolver"
- },
- "field_defaults": {
- "Timestep": "0.002",
- "Impratio": "1.0",
- "Tolerance": "1e-8",
- "Iterations": "100",
- "LsIterations": "50",
- "NoslipTolerance": "1e-6",
- "CCD_Tolerance": "1e-6",
- "Gravity": "FVector(0.0f, 0.0f, -981.0f)",
- "Magnetic": "FVector(0.0f, -0.5f, 0.0f)",
- "Integrator": "EMjIntegrator::Euler",
- "Cone": "EMjCone::Pyramidal",
- "Solver": "EMjSolver::Newton"
- },
- "field_apply_to_spec_mode": {
- "gravity": "vec3_cm",
- "wind": "vec3_cm",
- "magnetic": "vec3_y_flip",
- "integrator": "guarded",
- "cone": "guarded",
- "solver": "guarded",
- "noslip_iterations": "guarded",
- "noslip_tolerance": "guarded",
- "ccd_iterations": "guarded",
- "ccd_tolerance": "guarded"
- },
- "_note_skip_vs_exclude": "field_skip_apply: emitted as UPROPERTY but not written to mjOption (apply body skips). exclude_fields: omitted from the struct entirely. exclude_fields takes precedence in iteration, so entries listed in both would be dead — keep them apart.",
- "field_skip_apply": [
- "disableflags", "enableflags", "disableactuator",
- "sdf_initpoints", "sdf_iterations", "sleep_tolerance"
- ],
- "exclude_fields": ["apirate", "rebuild_interval", "o_solref", "o_solimp", "o_friction"],
- "urlab_extra_fields": [
- {
- "name": "MemoryMB",
- "type": "int32",
- "default": "100",
- "meta": "ClampMin=\"1\"",
- "has_override": true
- },
- {
- "name": "bEnableMultiCCD",
- "type": "bool",
- "default": "false",
- "sub_category": "Collision",
- "meta": "ToolTip=\"Enable multi-contact convex collision detection. Useful for flat surfaces (e.g. mesh-mesh) where single-point contact causes sliding or wobbling.\"",
- "has_override": false
- },
- {
- "name": "bEnableSleep",
- "type": "bool",
- "default": "false",
- "sub_category": "Sleep",
- "has_override": false
- },
- {
- "name": "SleepTolerance",
- "type": "float",
- "default": "1e-4f",
- "sub_category": "Sleep",
- "edit_condition": "bEnableSleep",
- "has_override": false
- }
- ],
- "apply_extras_function": "ApplyMjOptionExtras",
- "emit_apply_methods": true
- },
-
- "_note_MjVisualStructs": "Codegen-emitted FMjVisual{Global,Headlight,Quality,Map,Scale,Rgba} parallel to mjVisual sub-blocks.",
- "MjVisualGlobal": {
- "ue_struct_name": "FMjVisualGlobal",
- "mjxmacro_block": "MJVISUAL_GLOBAL_FIELDS",
- "c_struct_type": "mjVisualGlobal",
- "public_header": "MuJoCo/Generated/MjVisualGlobal.h",
- "private_source": "MuJoCo/Generated/MjVisualGlobal.cpp",
- "category_label": "Visual|Global",
- "field_defaults": {
- "Fovy": "45.0f",
- "Ipd": "0.068f",
- "Realtime": "1.0f"
- }
- },
- "MjVisualHeadlight": {
- "ue_struct_name": "FMjVisualHeadlight",
- "mjxmacro_block": "MJVISUAL_HEADLIGHT_FIELDS",
- "c_struct_type": "mjVisualHeadlight",
- "public_header": "MuJoCo/Generated/MjVisualHeadlight.h",
- "private_source": "MuJoCo/Generated/MjVisualHeadlight.cpp",
- "category_label": "Visual|Headlight",
- "field_defaults": {
- "Ambient": "FVector(0.1f, 0.1f, 0.1f)",
- "Diffuse": "FVector(0.4f, 0.4f, 0.4f)",
- "Specular": "FVector(0.5f, 0.5f, 0.5f)",
- "Active": "1"
- }
- },
- "MjVisualQuality": {
- "ue_struct_name": "FMjVisualQuality",
- "mjxmacro_block": "MJVISUAL_QUALITY_FIELDS",
- "c_struct_type": "mjVisualQuality",
- "public_header": "MuJoCo/Generated/MjVisualQuality.h",
- "category_label": "Visual|Quality",
- "_note": "All quality fields are int in mjmodel.h (shadowsize=1024, offsamples=4, numslices=28, numstacks=16, numquads=4). mjxmacro carries no type info for these (bare X(name) form); explicit field_types override.",
- "field_types": {
- "shadowsize": "int32", "offsamples": "int32", "numslices": "int32",
- "numstacks": "int32", "numquads": "int32"
- },
- "field_defaults": {
- "Shadowsize": "1024", "Offsamples": "4", "Numslices": "28",
- "Numstacks": "16", "Numquads": "4"
- }
- },
- "MjVisualMap": {
- "ue_struct_name": "FMjVisualMap",
- "mjxmacro_block": "MJVISUAL_MAP_FIELDS",
- "c_struct_type": "mjVisualMap",
- "public_header": "MuJoCo/Generated/MjVisualMap.h",
- "category_label": "Visual|Map",
- "_note": "All map fields are float scalars in mjVisualMap (force, torque, stiffness, etc.). mjxmacro defaults them to mjtNum (double) which compiles cleanly via implicit conversion."
- },
- "MjVisualScale": {
- "ue_struct_name": "FMjVisualScale",
- "mjxmacro_block": "MJVISUAL_SCALE_FIELDS",
- "c_struct_type": "mjVisualScale",
- "public_header": "MuJoCo/Generated/MjVisualScale.h",
- "category_label": "Visual|Scale",
- "_note": "Same as MjVisualMap — float scalars in mjmodel.h, mjxmacro defaults to mjtNum which compiles fine."
- },
- "MjVisualRgba": {
- "ue_struct_name": "FMjVisualRgba",
- "mjxmacro_block": "MJVISUAL_RGBA_FIELDS",
- "c_struct_type": "mjVisualRgba",
- "public_header": "MuJoCo/Generated/MjVisualRgba.h",
- "category_label": "Visual|Rgba",
- "_note": "Every field is float[4] color in mjVisualRgba. mjxmacro's bare X(name) form drops that info; all_fields_type forces FLinearColor for the UPROPERTY + flips the ApplyTo emit to .R/.G/.B/.A writes.",
- "all_fields_type": "FLinearColor"
- },
- "_note_MjsCompilerOptions": "Mirror of mjsCompiler (MJSCOMPILER_FIELDS in mjspecmacro.h, read from the installed MuJoCo headers). Header-only USTRUCT — no .cpp emission today since URLab parses compiler settings via the legacy FMjCompilerSettings struct in MjOrientationUtils.h. Future migration: route MjArticulation through this struct + an ApplyToSpec method.",
- "MjsCompilerOptions": {
- "ue_struct_name": "FMjsCompilerOptions",
- "mjxmacro_block": "MJSCOMPILER_FIELDS",
- "c_struct_type": "mjsCompiler",
- "public_header": "MuJoCo/Generated/MjsCompilerOptions.h",
- "category_label": "Spec|Compiler",
- "_note_exclude": "LRopt is mjLROpt (nested struct, not mirror-able as a UPROPERTY); meshdir/texturedir are mjString* (different shape — handled by the existing MeshDir/AssetDir on FMjCompilerSettings). eulerseq is a char[3] vec — mirror as FString instead, but skip in ApplyTo since FString -> char[3] needs a copy not a cast.",
- "exclude_fields": ["LRopt", "meshdir", "texturedir"],
- "field_skip_apply": ["eulerseq"],
- "field_types": {"eulerseq": "FString"},
- "field_defaults": {"Eulerseq": "TEXT(\"xyz\")"}
- },
- "_note_MjsSpec": "Mirror of mjSpec top-level fields (MJSPEC_FIELDS in mjspecmacro.h, read from the installed MuJoCo headers). Many entries are NESTED structs (mjsCompiler, mjOption, mjVisual, mjStatistic) — those are exposed via the dedicated FMjsCompilerOptions / FMjOptionGenerated / FMjVisual* / FMjStatistic structs. We only mirror the scalar + string fields here.",
- "MjsSpec": {
- "ue_struct_name": "FMjsSpec",
- "mjxmacro_block": "MJSPEC_FIELDS",
- "c_struct_type": "mjSpec",
- "public_header": "MuJoCo/Generated/MjsSpec.h",
- "category_label": "Spec",
- "_note_exclude": "element/compiler/option/visual/stat are nested structs already exposed via their own synthetic_categories. modelname / comment / modelfiledir / meshdir / texturedir are mjString* — distinct shape. memory is mjtSize (handle separately).",
- "exclude_fields": [
- "element", "compiler", "option", "visual", "stat",
- "modelname", "comment", "modelfiledir", "meshdir", "texturedir",
- "memory", "strippath"
- ]
- }
- }
-}
diff --git a/Scripts/codegen/generate_ue_components.py b/Scripts/codegen/generate_ue_components.py
deleted file mode 100644
index b09d7b74..00000000
--- a/Scripts/codegen/generate_ue_components.py
+++ /dev/null
@@ -1,4318 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-#
-# 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
-"""
-URLab UE component codegen, schema-driven.
-
-Inputs:
- - Scripts/codegen/snapshots/mjcf_schema_snapshot.json (MJCF schema attrs)
- - Scripts/codegen/snapshots/mjxmacro_snapshot.json (mjModel/mjData pointer table)
- - Scripts/codegen/snapshots/introspect_snapshot.json (libclang-scraped C API:
- mjsX struct fields, mjt*
- enums, mjs_setTo* signatures)
- - Scripts/codegen/codegen_rules.json (per-category layout, rules)
-
-Outputs:
- - Component .h / .cpp files in Source/URLab/Public|Private/MuJoCo/Components/
- (single-UCLASS or multi-UCLASS depending on layout)
- - View structs injected into Source/URLab/Public/MuJoCo/Utils/MjBind.h
- - Schema-completeness header at
- Source/URLabEditor/Private/Tests/MjSchemaForTests.h
-
-All emitted text lives between explicit ``// --- CODEGEN_*_START/END ---``
-tags. The generator refuses to inject into a file that does not have
-the right tag pairs. There is no auto-insert fallback.
-
-Usage:
- python generate_ue_components.py # write mode
- python generate_ue_components.py --dry-run # print diffs only
- python generate_ue_components.py --check # exit non-zero if writes would change anything
-"""
-
-from __future__ import annotations
-
-import argparse
-import difflib
-import json
-import os
-import re
-import shutil
-import subprocess
-import sys
-from dataclasses import dataclass, field
-from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple
-
-# Sibling modules. Only names actually consumed by this orchestrator's
-# body are imported here. Test files import private helpers (e.g.
-# _resolve_direct, _classify_c_type, _check_brace_balance) directly from
-# their owning module — the orchestrator is not a re-export surface.
-from _codegen_core import (
- _DIAGS_BUFFER, _diag_add, _diag_flush, _reset_diags,
- _ue_type_accepts_units_meta, _attr_default_value,
- override_toggle_name,
- schema_attrs, schema_subtype_attrs,
- compute_canon_absorbed, iter_category_attrs,
- _VEC3_CONVERT_FMT,
- _resolve_mjs_field, _resolve_value_map,
- FileWrite,
-)
-from _codegen_inject import (
- _find_matching_brace,
- inject_between_tags, _inject_tags_into_cpp,
-)
-from _codegen_checks import (
- _check_hand_enum_drift, _check_type_shape_drift,
- _check_new_attr_typing, _check_orphan_rule_entries,
- _check_mjxmacro_block_coverage, _check_apply_mode_validity,
- _check_embedded_cpp_references,
- _check_allowlist_staleness,
- _check_property_units_validity, _check_compiler_attrs_coverage,
- _check_value_map_stale_mj_consts,
- _emit_drift_diagnostics,
-)
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "..", ".."))
-
-_SNAPSHOT_DIR = os.path.join(PLUGIN_ROOT, "Scripts", "codegen", "snapshots")
-DEFAULT_SCHEMA = os.path.join(_SNAPSHOT_DIR, "mjcf_schema_snapshot.json")
-DEFAULT_MJXMACRO = os.path.join(_SNAPSHOT_DIR, "mjxmacro_snapshot.json")
-DEFAULT_INTROSPECT = os.path.join(_SNAPSHOT_DIR, "introspect_snapshot.json")
-DEFAULT_RULES = os.path.join(SCRIPT_DIR, "codegen_rules.json")
-DEFAULT_PUBLIC_ROOT = os.path.join(PLUGIN_ROOT, "Source", "URLab", "Public")
-DEFAULT_PRIVATE_ROOT= os.path.join(PLUGIN_ROOT, "Source", "URLab", "Private")
-DEFAULT_BIND_H = os.path.join(DEFAULT_PUBLIC_ROOT, "MuJoCo", "Utils", "MjBind.h")
-DEFAULT_TESTS_DIR = os.path.join(PLUGIN_ROOT, "Source", "URLabEditor", "Private", "Tests")
-
-COPYRIGHT_BLOCK = """// Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-//
-// 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.
-//
-// --- LEGAL DISCLAIMER ---
-// UnrealRoboticsLab is an independent software plugin. It is NOT affiliated with,
-// endorsed by, or sponsored by Epic Games, Inc. "Unreal" and "Unreal Engine" are
-// trademarks or registered trademarks of Epic Games, Inc. in the US and elsewhere.
-//
-// This plugin incorporates third-party software: MuJoCo (Apache 2.0),
-// CoACD (MIT), and libzmq (MPL 2.0). See ThirdPartyNotices.txt for details.
-//
-// AUTOGENERATED by Scripts/codegen/generate_ue_components.py
-// Do not edit by hand. Re-run the generator to regenerate.
-"""
-
-
-def _should_emit_xml_enum_at_this_layer(
- attr: str,
- attrs: Sequence[str],
- global_excl: Set[str],
- *,
- apply_canonicalizations: bool,
-) -> bool:
- """Whether this codegen layer owns the xml_enum import/export for
- ``attr``. Two cases fire:
-
- - The attr appears in this layer's attrs list — subtype-specific
- case, e.g. ``dcmotor.input`` fires on the DCMotor subtype's
- emission.
- - The base-class layer (apply_canonicalizations=True) AND the
- attr is in global_exclusions — always-emit-at-base case, e.g.
- ``joint.type`` is globally excluded from per-attr UPROPERTY
- emission but xml_enum_attrs still owns its import/export at
- the base.
- """
- if attr in attrs:
- return True
- return apply_canonicalizations and attr in global_excl
-
-
-# `schema_attrs` and `schema_subtype_attrs` live in `_codegen_core`.
-
-
-# ---------------------------------------------------------------------------
-# Property emission
-# ---------------------------------------------------------------------------
-
-@dataclass
-class EmittedSchema:
- """Output of property-set emission for a given attr list."""
- properties_h: str # UPROPERTY block for header
- imports_cpp: str # ImportFromXml body (between codegen tags)
- exports_cpp: str # ExportTo body (between codegen tags)
-
-
-@dataclass
-class EmissionContext:
- """Cross-cutting rules / element / call-site state threaded through
- ``emit_schema_for_attrs`` and its helpers. Built once via ``from_call``.
-
- Carries every shared computation the property/import/export helpers
- need (canon_absorbed, xml_enum_attr_names, elem_canons, the various
- rule dicts) so the helpers take one ``ctx`` arg instead of 15
- positional parameters."""
- # --- caller-provided ---
- attrs: Sequence[str]
- rules: Dict[str, Any]
- element_name: str
- apply_canonicalizations: bool = True
- mjs_fields: Optional[set] = None
- consumed_by_setto: Optional[set] = None
- mjs_array_caps: Optional[Dict[str, int]] = None
- # --- derived from rules (cached on construct) ---
- global_excl: set = field(default_factory=set)
- type_map: Dict[str, str] = field(default_factory=dict)
- default_type: str = "float"
- renames: Dict[str, str] = field(default_factory=dict)
- elem_rules: Dict[str, Any] = field(default_factory=dict)
- elem_excl: set = field(default_factory=set)
- canonicalizations: Dict[str, Any] = field(default_factory=dict)
- attr_to_mjs_field: Dict[str, str] = field(default_factory=dict)
- # --- derived in from_call but parameterised by apply_canonicalizations ---
- elem_canons: List[str] = field(default_factory=list)
- canon_absorbed: set = field(default_factory=set)
- xml_enum_attr_names: set = field(default_factory=set)
-
- @classmethod
- def from_call(cls,
- attrs: Sequence[str],
- rules: Dict[str, Any],
- element_name: str,
- *,
- apply_canonicalizations: bool = True,
- mjs_fields: Optional[set] = None,
- consumed_by_setto: Optional[set] = None,
- mjs_array_caps: Optional[Dict[str, int]] = None) -> "EmissionContext":
- elem_rules = rules.get("element_rules", {}).get(element_name, {})
- canonicalizations = rules.get("canonicalizations", {})
- # ``elem_canons`` is the raw applied-canon list; the helpers
- # clear it when apply_canonicalizations is False, but
- # ``canon_absorbed`` keeps the raw absorbed set so per-attr
- # emission still excludes them at the subtype layer.
- elem_canons: List[str] = list(
- elem_rules.get("applies_canonicalizations", [])
- )
- canon_absorbed = compute_canon_absorbed(elem_canons, canonicalizations)
- if not apply_canonicalizations:
- elem_canons = []
- return cls(
- attrs=attrs,
- rules=rules,
- element_name=element_name,
- apply_canonicalizations=apply_canonicalizations,
- mjs_fields=mjs_fields,
- consumed_by_setto=consumed_by_setto,
- mjs_array_caps=mjs_array_caps,
- global_excl=set(rules.get("global_exclusions", [])),
- type_map=rules.get("type_mappings", {}),
- default_type=rules.get("default_type", "float"),
- renames=rules.get("property_renames", {}),
- elem_rules=elem_rules,
- elem_excl=set(elem_rules.get("exclude_attrs", [])),
- canonicalizations=canonicalizations,
- attr_to_mjs_field=elem_rules.get("attr_to_mjs_field", {}),
- elem_canons=elem_canons,
- canon_absorbed=canon_absorbed,
- xml_enum_attr_names=set(elem_rules.get("xml_enum_attrs", {}).keys()),
- )
-
-
-
-def _inject_or_diag(
- text: str,
- tag: str,
- body: str,
- *,
- host_path: str,
- host_kind: str,
- block_label: str,
- diag_source: str,
-) -> Tuple[str, bool]:
- """Inject ``body`` between the ``CODEGEN_`` markers in ``text``.
- When the markers are missing AND the body is non-empty, fire a
- diagnostic that names the host kind (e.g. 'subclass header'), the
- path, the tag, and what didn't land. Returns (new_text, ok).
-
- This collapses ~12 near-identical try-inject-then-diag stanzas
- that used to live in the emit_*_class_injection callers."""
- new_text, ok = inject_between_tags(text, tag, body, balance_source=diag_source)
- if not ok and body.strip():
- _diag_add(
- f"[diagnostic] {host_kind} '{host_path}' is missing the "
- f"CODEGEN_{tag}_START/END marker pair; {block_label} was "
- f"NOT injected.",
- source=diag_source,
- )
- return new_text, ok
-
-
-def _guarded_export(toggle: str, body: str,
- extra_cond: Optional[str] = None,
- extra_cond_first: bool = False,
- multiline: bool = False) -> str:
- """Wrap ``body`` in an ``if ({toggle})`` guard and return the indented
- emission.
-
- ``extra_cond=None``: ``if ({toggle}) {body}``
- ``extra_cond`` + first=False: ``if ({toggle} && {extra_cond}) {body}``
- ``extra_cond`` + first=True: ``if (({extra_cond}) && {toggle}) {body}``
-
- ``multiline=True``: emit a braced block. ``body`` is dropped verbatim
- inside the braces (caller controls inner indent — the helper does
- NOT auto-indent each line so existing multi-line bodies migrate
- byte-identically). Use for blocks that were previously hand-rolled
- as ``if ({toggle})\\n{{\\n\\n}}\\n``.
- """
- if extra_cond is None:
- cond = toggle
- elif extra_cond_first:
- cond = f"({extra_cond}) && {toggle}"
- else:
- cond = f"{toggle} && {extra_cond}"
- if multiline:
- return f" if ({cond})\n {{\n{body} }}\n"
- return f" if ({cond}) {body}\n"
-
-
-# `_UEType`, `_UE_TYPE_INFO`, and `_attr_default_value` live in
-# `_codegen_core` (re-exported at the top of this file).
-
-
-def _emit_uproperty(prop_name: str, ue_type: str, category_label: str,
- sub_category: Optional[str] = None,
- extra_meta: Optional[str] = None,
- default_override: Optional[str] = None,
- hide_from_details: bool = False) -> str:
- """Emit the toggle + value UPROPERTY pair for a schema-driven attr.
-
- ``extra_meta`` appends to the value UPROPERTY's meta=() block — used to
- inject ``DisplayName``, ``GetOptions``, etc. via per-attr rules in
- ``codegen_rules.json#element_rules..property_meta.``.
-
- ``hide_from_details=True`` keeps the field as a C++ member (so codegen
- import paths can still seed it and BPs can still read/write it) but
- suppresses the Details-panel widget via
- ``EditCondition="false", EditConditionHides``. Used for properties whose
- canonical authoring surface is the UE Transform widget (Pos/Quat ->
- RelativeLocation/Rotation, size -> RelativeScale3D).
- """
- cat = f"MuJoCo|{category_label}"
- if sub_category:
- cat = f"{cat}|{sub_category}"
- toggle = override_toggle_name(prop_name)
- default = default_override if default_override else _attr_default_value(ue_type)
- if hide_from_details:
- # EditConditionHides on the value also collapses the InlineEditConditionToggle
- # toggle bool above it because UE renders them as a single merged row.
- meta_inner = 'EditCondition="false", EditConditionHides'
- else:
- meta_inner = f'EditCondition="{toggle}"'
- if extra_meta:
- meta_inner = f'{meta_inner}, {extra_meta}'
- return (
- f' UPROPERTY(EditAnywhere, Category = "{cat}", meta=(InlineEditConditionToggle))\n'
- f' bool {toggle} = false;\n'
- f'\n'
- f' UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "{cat}", meta=({meta_inner}))\n'
- f' {ue_type} {prop_name} = {default};\n\n'
- )
-
-
-def _emit_import_line(attr: str, prop_name: str, ue_type: str,
- vec3_convert: Optional[str] = None) -> str:
- toggle = override_toggle_name(prop_name)
- key = f'TEXT("{attr}")'
- if ue_type == "float":
- return f' MjXmlUtils::ReadAttrFloat(Node, {key}, {prop_name}, {toggle});\n'
- if ue_type == "double":
- return f' MjXmlUtils::ReadAttrDouble(Node, {key}, {prop_name}, {toggle});\n'
- if ue_type == "int32":
- return f' MjXmlUtils::ReadAttrInt(Node, {key}, {prop_name}, {toggle});\n'
- if ue_type == "bool":
- return f' MjXmlUtils::ReadAttrBool(Node, {key}, {prop_name}, {toggle});\n'
- if ue_type == "FString":
- return (f' if (MjXmlUtils::ReadAttrString(Node, {key}, {prop_name}))'
- f' {toggle} = true;\n')
- if ue_type == "FVector":
- out = f' MjXmlUtils::ReadAttrVec3(Node, {key}, {prop_name}, {toggle});\n'
- # MuJoCo direction vectors don't carry units but DO use opposite Y
- # handedness vs UE. Apply Y-negate post-read when configured.
- if vec3_convert == "y_negate":
- out += f' if ({toggle}) {prop_name}.Y = -{prop_name}.Y;\n'
- return out
- if ue_type == "FLinearColor":
- return f' MjXmlUtils::ReadAttrColor(Node, {key}, {prop_name}, {toggle});\n'
- if ue_type.startswith("TArray mjs-field name mapper.
-# Each takes (attr, mjs_fields) and returns ``Optional[str]`` — the
-# winning field name, or None to fall through to the next strategy.
-# Order in _MJS_FIELD_RESOLVERS matters: more specific rules first.
-
-
-# The 5-strategy mjs-field resolver chain (+ ``_resolve_mjs_field``)
-# lives in `_codegen_core`.
-
-
-def _emit_export_line(attr: str, prop_name: str, ue_type: str,
- mjs_fields: set | None = None,
- slot_sentinel: str | None = None,
- attr_to_mjs_field: Dict[str, str] | None = None,
- consumed_by_setto: set | None = None,
- vec3_convert: Optional[str] = None,
- array_cap: Optional[int] = None) -> str:
- toggle = override_toggle_name(prop_name)
- # If we have an mjs field set and the attr can't be resolved to one of
- # them, this attr isn't directly assignable on the mjs struct (e.g.
- # actuator subtype params like `kp` live in gainprm[], not Element->kp).
- # Emit either:
- # - nothing (silent) when the attr is consumed by an mjs_setTo* call
- # above us in the same CODEGEN_EXPORT block (no need for noise)
- # - a one-line "(skipped)" marker otherwise (genuinely unhandled,
- # reviewers should know)
- if mjs_fields:
- field = _resolve_mjs_field(attr, mjs_fields, attr_to_mjs_field)
- if field == attr and attr not in mjs_fields and not (
- attr_to_mjs_field and attr in attr_to_mjs_field
- ):
- if consumed_by_setto and attr in consumed_by_setto:
- return ""
- return f' // (skipped: mjs has no field for "{attr}"; hand-roll via mjs_setTo)\n'
- else:
- field = attr_to_mjs_field.get(attr, attr) if attr_to_mjs_field else attr
- if ue_type.startswith("TArray gainprm[6]) doesn't memory-overrun. Dynamic
- # vec destinations (mjFloatVec*, mjDoubleVec*) pass array_cap=None
- # and use the raw prop.Num() — the dynamic vec resizes itself.
- upper = f"FMath::Min({prop_name}.Num(), {array_cap})" if array_cap else f"{prop_name}.Num()"
- if slot_sentinel is not None:
- # Per-slot sentinel guard: skip slots whose value equals the
- # sentinel (used for `size` so fromto-only imports don't
- # clobber the inherited default radius / earlier slots).
- return _guarded_export(toggle,
- f'{{ for (int32 i = 0; i < {upper}; ++i)'
- f' {{ if ({prop_name}[i] != {slot_sentinel}) Element->{field}[i] = {prop_name}[i]; }} }}',
- )
- return _guarded_export(toggle,
- f'{{ for (int32 i = 0; i < {upper}; ++i)'
- f' Element->{field}[i] = {prop_name}[i]; }}',
- )
- if ue_type == "FVector":
- if vec3_convert == "y_negate":
- return _guarded_export(toggle,
- f'{{ Element->{field}[0] = {prop_name}.X;'
- f' Element->{field}[1] = -{prop_name}.Y;'
- f' Element->{field}[2] = {prop_name}.Z; }}',
- )
- return _guarded_export(toggle,
- f'{{ Element->{field}[0] = {prop_name}.X;'
- f' Element->{field}[1] = {prop_name}.Y;'
- f' Element->{field}[2] = {prop_name}.Z; }}',
- )
- if ue_type == "FLinearColor":
- return _guarded_export(toggle,
- f'{{ Element->{field}[0] = {prop_name}.R;'
- f' Element->{field}[1] = {prop_name}.G;'
- f' Element->{field}[2] = {prop_name}.B;'
- f' Element->{field}[3] = {prop_name}.A; }}',
- )
- if ue_type == "FString":
- # MjSetString (Public/MuJoCo/Utils/MjUtils.h) internally skips empty
- # FStrings, so the previous `!X.IsEmpty()` guard collapses into the
- # helper. Toggle-guard stays.
- return _guarded_export(toggle, f'MjSetString(Element->{field}, {prop_name});')
- if ue_type == "bool":
- return _guarded_export(toggle, f'Element->{field} = {prop_name} ? 1 : 0;')
- return _guarded_export(toggle, f'Element->{field} = {prop_name};')
-
-
-# --- unit conversion ----------------------------------------------------------
-# Per-element conversion ops applied to TArray / float UPROPERTYs at
-# the import/export boundary. URLab stores values in UE conventions
-# (degrees for angles, cm for lengths); MuJoCo wants radians / metres.
-#
-# To keep the rules JSON data-only, every operation is a key into this
-# registry. Adding a new conversion means one dict entry — no rules edit.
-# The "if guard" form is used when the conversion only fires conditional on
-# the compiler.angle setting (XML in radians needs rad->deg; XML already in
-# degrees needs nothing).
-_UNIT_CONVERT_OPS = {
- "m_to_cm": {"per_elem": "V *= 100.0f;"},
- "cm_to_m": {"per_elem": "V *= 0.01f;"},
- "deg_to_rad": {"per_elem": "V = FMath::DegreesToRadians(V);"},
- "rad_to_deg": {"per_elem": "V = FMath::RadiansToDegrees(V);"},
- "rad_to_deg_if_xml_radians": {
- "per_elem": "V = FMath::RadiansToDegrees(V);",
- "guard": "!CompilerSettings.bAngleInDegrees",
- },
-}
-
-
-def _emit_unit_conversion_export(
- prop_name: str, mjs_field: str, conversions: Sequence[Dict[str, Any]],
- is_array: bool,
-) -> str:
- """Emit the EXPORT side of a unit_conversion rule: build a temp value
- per-element, apply the conversion, then write to ``Element->mjs_field[i]``
- (array) or ``Element->mjs_field`` (scalar). Replaces the default per-attr
- export emission for attrs that have unit conversion attached.
-
- Array pattern:
- if (bOverride_X)
- {
- for (int32 i = 0; i < X.Num(); ++i)
- {
- float V = X[i];
- if () { }
- else if () { /* optional guard */ }
- Element->{mjs_field}[i] = (mjtNum)V;
- }
- }
-
- Scalar pattern:
- if (bOverride_X)
- {
- float V = X;
- if () { }
- ...
- Element->{mjs_field} = (mjtNum)V;
- }
- """
- toggle = override_toggle_name(prop_name)
- branches: List[str] = []
- indent = " " if is_array else " "
- for entry in conversions:
- op_name = entry.get("export_op")
- if not op_name:
- continue
- op = _UNIT_CONVERT_OPS.get(op_name)
- if op is None:
- raise RuntimeError(f"unit_conversion: unknown export op '{op_name}' (for {prop_name})")
- body = op["per_elem"]
- guard = op.get("guard")
- if guard:
- body = f"if ({guard}) {{ {body} }}"
- condition = entry.get("condition")
- if condition:
- prefix = "else if" if branches else "if "
- branches.append(f"{indent}{prefix} ({condition}) {{ {body} }}")
- else:
- branches.append(f"{indent}{body}")
- if not branches:
- return ""
- inner = "\n".join(branches)
- if is_array:
- body = (
- f" for (int32 i = 0; i < {prop_name}.Num(); ++i)\n"
- f" {{\n"
- f" float V = {prop_name}[i];\n"
- f"{inner}\n"
- f" Element->{mjs_field}[i] = (mjtNum)V;\n"
- f" }}\n"
- )
- else:
- body = (
- f" float V = {prop_name};\n"
- f"{inner}\n"
- f" Element->{mjs_field} = (mjtNum)V;\n"
- )
- return _guarded_export(toggle, body, multiline=True)
-
-
-def _emit_unit_conversion_block(
- prop_name: str, conversions: Sequence[Dict[str, Any]], side: str,
- is_array: bool,
-) -> str:
- """Emit a guarded loop / scalar block that applies per-element
- conversions to a UPROPERTY at import time. ``side`` is "import" or
- "export"; only the matching ``*_op`` is used. ``is_array`` selects
- between ``for (float& V : X)`` and direct ``X`` mutation.
-
- Pattern (array):
- if (bOverride_X)
- {
- if () { for (float& V : X) ; }
- else if () { /* optional guard */ for (float& V : X) ; }
- }
- """
- op_key = "import_op" if side == "import" else "export_op"
- toggle = override_toggle_name(prop_name)
-
- def _apply(per_elem: str) -> str:
- if is_array:
- return f"for (float& V : {prop_name}) {{ {per_elem} }}"
- # Scalar: mutate the UPROPERTY directly. The ops are written in
- # terms of `V`; substitute with the prop name.
- return per_elem.replace("V ", f"{prop_name} ").replace("(V)", f"({prop_name})")
-
- branches: List[str] = []
- for entry in conversions:
- op_name = entry.get(op_key)
- if not op_name:
- continue
- op = _UNIT_CONVERT_OPS.get(op_name)
- if op is None:
- raise RuntimeError(f"unit_conversion: unknown op '{op_name}' (for {prop_name})")
- guard = op.get("guard")
- body = _apply(op["per_elem"])
- if guard:
- body = f"if ({guard}) {{ {body} }}"
- condition = entry.get("condition")
- if condition:
- prefix = "else if" if branches else "if "
- branches.append(f" {prefix} ({condition}) {{ {body} }}")
- else:
- branches.append(f" {body}")
- if not branches:
- return ""
- body_lines = "\n".join(branches)
- return _guarded_export(toggle, f"{body_lines}\n", multiline=True)
-
-
-def _emit_target_collation_import(prop_name: str, absorbs_attrs: Sequence[str]) -> str:
- """Emit import for an mjs name-string field that the schema spells out
- across several xor attrs (e.g. mjsEquality.name1 is one of body1/joint1/
- tendon1/flex depending on the equality type). Sets the UPROPERTY to the
- first non-empty attr.
-
- No bOverride toggle — Obj1/Obj2 are hand-declared UPROPERTYs with
- dynamic GetOptions; their "set-ness" is captured by emptiness.
- """
- lines: List[str] = [f" // target_collation: -> {prop_name}"]
- first = True
- for a in absorbs_attrs:
- if first:
- lines.append(f' {prop_name} = Node->GetAttribute(TEXT("{a}"));')
- first = False
- else:
- lines.append(
- f' if ({prop_name}.IsEmpty()) {prop_name} = Node->GetAttribute(TEXT("{a}"));'
- )
- return "\n".join(lines) + "\n"
-
-
-def _emit_target_collation_export(prop_name: str, mjs_field: str) -> str:
- # MjSetString skips empty FStrings internally; preserves the existing
- # "only write when set" semantics without the explicit guard.
- return f' MjSetString(Element->{mjs_field}, {prop_name});\n'
-
-
-def _emit_double_vec_export(attr: str, prop_name: str, mjs_field: str) -> str:
- """Emit export for an attr whose mjs counterpart is a ``mjDoubleVec*``
- (std::vector*) — used by mjsKey for qpos/qvel/act/ctrl/mpos/mquat.
-
- Delegates to ``MjSetDoubleVec`` (Public/MuJoCo/Utils/MjUtils.h) which
- handles the ``clear() + push_back`` boilerplate. The helper accepts
- a null Dest so we don't need the ``&& Element->X`` guard at the
- call site.
- """
- toggle = override_toggle_name(prop_name)
- return f" if ({toggle}) MjSetDoubleVec(Element->{mjs_field}, {prop_name});\n"
-
-
-def _emit_data_packed_export(attr: str, packed_def: Dict[str, Any],
- ue_type: str, prop_name: str) -> str:
- """Emit ``Element->data[N]`` packed export for an attr that the mjs
- struct can't represent directly (e.g. mjsEquality polycoef -> data[0..10],
- torquescale -> data[10], anchor -> data[0..2]).
-
- packed_def shape:
- {
- "target": "data", // optional, defaults to "data"
- "slot": 7, // single-slot pack (scalar UE prop)
- "slot_range": [0, 11], // range-pack [start, end) (TArray)
- "condition": "EqualityType == ..." // optional gating
- "export_op": "cm_to_m" // optional per-elem unit conversion
- // applied to each element / scalar
- // before writing into data[]
- }
- """
- target = packed_def.get("target", "data")
- condition = packed_def.get("condition")
- toggle = override_toggle_name(prop_name)
-
- export_op_name = packed_def.get("export_op")
- op_body = ""
- if export_op_name:
- op = _UNIT_CONVERT_OPS.get(export_op_name)
- if op is None:
- raise RuntimeError(
- f"mjs_data_packed_attrs '{attr}': unknown export_op '{export_op_name}'"
- )
- op_body = op["per_elem"]
-
- def _wrap(body: str) -> str:
- return _guarded_export(toggle, body,
- extra_cond=condition,
- extra_cond_first=True,
- multiline=True)
-
- if "slot" in packed_def:
- slot = packed_def["slot"]
- if op_body:
- body = (
- f" float V = (float){prop_name};\n"
- f" {op_body}\n"
- f" Element->{target}[{slot}] = (mjtNum)V;\n"
- )
- return _wrap(body)
- body = f" Element->{target}[{slot}] = (mjtNum){prop_name};\n"
- return _wrap(body)
- if "slot_range" in packed_def:
- start, end = packed_def["slot_range"]
- count = end - start
- if not ue_type.startswith("TArray"):
- raise RuntimeError(
- f"mjs_data_packed_attrs '{attr}': slot_range requires UE TArray; got {ue_type}"
- )
- if op_body:
- body = (
- f" for (int32 i = 0; i < {prop_name}.Num() && i < {count}; ++i)\n"
- f" {{\n"
- f" float V = {prop_name}[i];\n"
- f" {op_body}\n"
- f" Element->{target}[{start} + i] = (mjtNum)V;\n"
- f" }}\n"
- )
- return _wrap(body)
- body = (
- f" for (int32 i = 0; i < {prop_name}.Num() && i < {count}; ++i)\n"
- f" Element->{target}[{start} + i] = (mjtNum){prop_name}[i];\n"
- )
- return _wrap(body)
- raise RuntimeError(f"mjs_data_packed_attrs '{attr}': must specify either 'slot' or 'slot_range'")
-
-
-# `_resolve_value_map` lives in `_codegen_core`.
-
-
-def _emit_xml_enum_import(attr: str, enum_def: Dict[str, Any]) -> str:
- """Emit the XML-string -> URLab-enum mapping inside CODEGEN_IMPORT.
-
- enum_def shape:
- {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "value_map": { "hinge": ["Hinge", "mjJNT_HINGE"], ... },
- "has_override_toggle": true // optional, default true; when false the
- // import skips the bOverride_X=true line
- // and the export fires unconditionally
- }
- """
- ue_prop = enum_def["ue_property"]
- value_map: Dict[str, Sequence[str]] = _resolve_value_map(attr, enum_def)
- has_toggle = enum_def.get("has_override_toggle", True)
- ue_enum_type = enum_def.get("ue_enum_type", "")
- lines: List[str] = []
- lines.append(f' {{ // xml_enum: {attr} -> {ue_enum_type or ue_prop}')
- lines.append(f' FString S = Node->GetAttribute(TEXT("{attr}"));')
- lines.append(" S = S.ToLower();")
- # Toggle fires only when a known XML value matched. A typo'd value
- # (e.g. ``type="hindge"``) used to silently set the toggle on the
- # UE-default enum value — misleadingly signalling "user overrode this"
- # while actually masking the typo.
- if has_toggle:
- lines.append(" bool bMatched = false;")
- branches: List[str] = []
- for xml_val, mapping in value_map.items():
- ue_enum_member = mapping[0]
- prefix = "else if " if branches else "if "
- match_assign = " bMatched = true;" if has_toggle else ""
- branches.append(
- f' {prefix}(S == TEXT("{xml_val}")) '
- f'{{ {ue_prop} = {ue_enum_type}::{ue_enum_member};{match_assign} }}'
- )
- lines.extend(branches)
- if has_toggle:
- toggle = override_toggle_name(ue_prop)
- lines.append(f" if (bMatched) {toggle} = true;")
- lines.append(" }")
- return "\n".join(lines) + "\n"
-
-
-def emit_enum_switch(
- discriminator: str,
- enum_name: str,
- cases: Sequence[Tuple[Any, str]],
- *,
- indent: str = " ",
- default_break: bool = False,
- default_body: Optional[str] = None,
-) -> str:
- """Emit ``switch (discriminator) { case Enum::M: ; break; ... }``.
-
- ``cases`` is a sequence of ``(member_or_members, body)`` pairs:
- - When ``member_or_members`` is a ``str``, the case label + body +
- break collapse onto one line: ``case Enum::M: ; break;``.
- - When it is a sequence of strings (multi-key group, e.g. objtype
- dispatch's BODY/XBODY → ``mjOBJ_BODY``), the case labels stack
- and the body / break go on separate indented lines:
- ``case Enum::A:``
- ``case Enum::B:``
- `` ;``
- `` break;``
-
- ``default_break=True`` appends a single-line ``default: break;``.
- ``default_body`` (when set) appends a multi-line ``default:`` arm
- with that body. ``default_break`` is ignored if ``default_body`` is
- given.
-
- All lines are prefixed with ``indent``; case labels use
- ``indent + 4 spaces``; multi-line bodies use ``indent + 8 spaces``.
- Result ends with a trailing newline.
- """
- inner = indent + " "
- body_indent = inner + " "
- lines: List[str] = []
- lines.append(f"{indent}switch ({discriminator})")
- lines.append(f"{indent}{{")
- for members, body in cases:
- if isinstance(members, str):
- lines.append(f"{inner}case {enum_name}::{members}: {body}; break;")
- continue
- for m in members:
- lines.append(f"{inner}case {enum_name}::{m}:")
- lines.append(f"{body_indent}{body};")
- lines.append(f"{body_indent}break;")
- if default_body is not None:
- lines.append(f"{inner}default:")
- lines.append(f"{body_indent}{default_body};")
- lines.append(f"{body_indent}break;")
- elif default_break:
- lines.append(f"{inner}default: break;")
- lines.append(f"{indent}}}")
- return "\n".join(lines) + "\n"
-
-
-def _emit_xml_enum_export(attr: str, enum_def: Dict[str, Any]) -> str:
- """Emit the URLab-enum -> mjt* / mjsField mapping inside CODEGEN_EXPORT.
-
- Gated on ``bOverride_X`` when ``has_override_toggle`` is true (default).
- Unconditional otherwise — needed for categories like site where Type
- always carries a meaningful value with no inheritance semantics.
-
- If ``mjs_field`` is null / missing, the export is empty — used for enums
- that don't have a direct mjs* field counterpart (e.g. dcmotor.input is
- carried to MuJoCo via ``mjs_setToDCMotor``'s ``input_mode`` param, not a
- direct ``Element->input`` write).
- """
- ue_prop = enum_def["ue_property"]
- ue_enum_type = enum_def.get("ue_enum_type", "")
- value_map: Dict[str, Sequence[str]] = _resolve_value_map(attr, enum_def)
- mjs_field = enum_def.get("mjs_field")
- if not mjs_field:
- return ""
- mjs_cast = enum_def.get("mjs_cast", "")
- has_toggle = enum_def.get("has_override_toggle", True)
- indent = " " if has_toggle else " "
- cases: List[Tuple[Any, str]] = []
- for _, mapping in value_map.items():
- if not isinstance(mapping, list) or len(mapping) < 2:
- raise RuntimeError(
- f"xml_enum {attr}: value_map entries must be [UE_enum, mj_const]; got {mapping!r}"
- )
- ue_enum_member, mj_const = mapping[0], mapping[1]
- cast_expr = f"({mjs_cast}){mj_const}" if mjs_cast else mj_const
- cases.append((ue_enum_member, f"Element->{mjs_field} = {cast_expr}"))
- switch_body = emit_enum_switch(
- ue_prop, ue_enum_type, cases,
- indent=indent, default_break=True,
- )
- if has_toggle:
- toggle = override_toggle_name(ue_prop)
- return _guarded_export(toggle, switch_body, multiline=True)
- return switch_body
-
-
-def _canon_property_block(canon_name: str, canon_def: Dict[str, Any],
- category_label: str,
- hide_from_details: bool = False) -> str:
- prop = canon_def.get("emits_property")
- if not prop:
- return ""
- return _emit_uproperty(prop["name"], prop["type"], category_label,
- sub_category=canon_name.replace("_", " ").title(),
- hide_from_details=hide_from_details)
-
-
-# ---------------------------------------------------------------------------
-# Canonicalisation registry
-#
-# Five canonicalisations collapse multiple raw MJCF attrs into one URLab
-# property: spatial_pose (pos -> Pos), orientation (quat/euler/etc -> Quat),
-# fromto_decompose (fromto -> Pos/Quat/size), body_sleep_policy (sleep ->
-# SleepPolicy enum), actuator_transmission (joint/tendon/site/... ->
-# TransmissionType + names). The previous design hard-coded each as an
-# if-branch in _canon_import_block / _canon_export_block; a new rule
-# entry without a matching branch silently dropped its emission. The
-# registry below is the single source of truth.
-# ---------------------------------------------------------------------------
-
-
-def _canon_import_body_sleep_policy(canon_def, element_name) -> str:
- return (
- ' { // canonicalize body.sleep -> EMjBodySleepPolicy + bOverride_SleepPolicy\n'
- ' FString S = Node->GetAttribute(TEXT("sleep"));\n'
- ' S = S.ToLower();\n'
- ' if (S == TEXT("never")) { SleepPolicy = EMjBodySleepPolicy::Never; bOverride_SleepPolicy = true; }\n'
- ' else if (S == TEXT("allowed")) { SleepPolicy = EMjBodySleepPolicy::Allowed; bOverride_SleepPolicy = true; }\n'
- ' else if (S == TEXT("init")) { SleepPolicy = EMjBodySleepPolicy::InitAsleep; bOverride_SleepPolicy = true; }\n'
- ' }\n'
- )
-
-
-def _canon_import_actuator_transmission(canon_def, element_name) -> str:
- return (
- ' { // canonicalize actuator transmission attrs\n'
- ' FString TrnTarget;\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("joint"), TrnTarget))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::Joint;\n'
- ' TargetName = TrnTarget;\n'
- ' }\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("jointinparent"), TrnTarget))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::JointInParent;\n'
- ' TargetName = TrnTarget;\n'
- ' }\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("tendon"), TrnTarget))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::Tendon;\n'
- ' TargetName = TrnTarget;\n'
- ' }\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("site"), TrnTarget))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::Site;\n'
- ' TargetName = TrnTarget;\n'
- ' }\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("body"), TrnTarget))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::Body;\n'
- ' TargetName = TrnTarget;\n'
- ' }\n'
- ' MjXmlUtils::ReadAttrString(Node, TEXT("refsite"), RefSite);\n'
- ' // SliderSite must run AFTER the main-target reads so it\n'
- ' // overrides the transmission type while preserving the\n'
- ' // TargetName captured above (per MJCF: slider-crank carries\n'
- ' // a main target attr PLUS slidersite).\n'
- ' if (MjXmlUtils::ReadAttrString(Node, TEXT("slidersite"), SliderSite))\n'
- ' {\n'
- ' TransmissionType = EMjActuatorTrnType::SliderCrank;\n'
- ' }\n'
- ' }\n'
- )
-
-
-def _canon_import_fromto_decompose(canon_def, element_name) -> str:
- helper = canon_def["import_helper"]
- cat_spec = canon_def.get("category_specifics", {}).get(element_name, {})
- z_slot_check = cat_spec.get("z_slot_check", "false")
- return (
- f' {{ // canonicalize fromto -> Pos/Quat/size half-length\n'
- f' FVector FTPos; FQuat FTQuat; float FTHalf = 0.f;\n'
- f' if ({helper}(Node, FTPos, FTQuat, FTHalf))\n'
- f' {{\n'
- f' Pos = FTPos; bOverride_Pos = true;\n'
- f' Quat = FTQuat; bOverride_Quat = true;\n'
- f' const bool bFTZSlot = {z_slot_check};\n'
- f' const int32 FTSlot = bFTZSlot ? 2 : 1;\n'
- f' while (size.Num() <= FTSlot) {{ size.Add(-1.0f); }}\n'
- f' size[FTSlot] = FTHalf;\n'
- f' bOverride_size = true;\n'
- f' }}\n'
- f' }}\n'
- )
-
-
-def _canon_import_orientation(canon_def, element_name) -> str:
- prop = canon_def.get("emits_property")
- helper = canon_def["import_helper"]
- return (
- f' {{ // canonicalize orientation (quat/euler/axisangle/xyaxes/zaxis)\n'
- f' double TmpQuat[4] = {{1.0, 0.0, 0.0, 0.0}};\n'
- f' if ({helper}(Node, CompilerSettings, TmpQuat))\n'
- f' {{\n'
- f' {prop["name"]} = MjUtils::MjToUERotation(TmpQuat);\n'
- f' {override_toggle_name(prop["name"])} = true;\n'
- f' }}\n'
- f' }}\n'
- )
-
-
-def _canon_import_spatial_pose(canon_def, element_name) -> str:
- prop = canon_def.get("emits_property")
- helper = canon_def["import_helper"]
- return (
- f' {helper}(Node, TEXT("pos"), {prop["name"]}, {override_toggle_name(prop["name"])});\n'
- )
-
-
-def _canon_export_body_sleep_policy(canon_def) -> str:
- return _guarded_export(
- "bOverride_SleepPolicy",
- " Element->sleep = static_cast(static_cast(SleepPolicy));\n",
- multiline=True,
- )
-
-
-def _canon_export_actuator_transmission(canon_def) -> str:
- return (
- ' MjSetString(Element->target, TargetName);\n'
- ' switch (TransmissionType)\n'
- ' {\n'
- ' case EMjActuatorTrnType::Joint: Element->trntype = mjTRN_JOINT; break;\n'
- ' case EMjActuatorTrnType::JointInParent: Element->trntype = mjTRN_JOINTINPARENT; break;\n'
- ' case EMjActuatorTrnType::SliderCrank: Element->trntype = mjTRN_SLIDERCRANK; break;\n'
- ' case EMjActuatorTrnType::Tendon: Element->trntype = mjTRN_TENDON; break;\n'
- ' case EMjActuatorTrnType::Site: Element->trntype = mjTRN_SITE; break;\n'
- ' case EMjActuatorTrnType::Body: Element->trntype = mjTRN_BODY; break;\n'
- ' default: Element->trntype = mjTRN_UNDEFINED; break;\n'
- ' }\n'
- ' if (TransmissionType == EMjActuatorTrnType::SliderCrank && !SliderSite.IsEmpty())\n'
- ' {\n'
- ' MjSetStringRaw(Element->slidersite, SliderSite);\n'
- ' }\n'
- ' if (TransmissionType == EMjActuatorTrnType::Site && !RefSite.IsEmpty())\n'
- ' {\n'
- ' MjSetStringRaw(Element->refsite, RefSite);\n'
- ' }\n'
- )
-
-
-def _canon_export_fromto_decompose(canon_def) -> str:
- # fromto resolves to Pos/Quat/Size on import — those properties carry
- # the values through to export via their own canonicalisations.
- return ""
-
-
-def _canon_export_orientation(canon_def) -> str:
- prop = canon_def.get("emits_property")
- helper = canon_def.get("export_helper")
- return _guarded_export(
- override_toggle_name(prop["name"]),
- f' double TmpQuat[4];\n'
- f' {helper}({prop["name"]}, TmpQuat);\n'
- f' Element->quat[0] = TmpQuat[0]; Element->quat[1] = TmpQuat[1];\n'
- f' Element->quat[2] = TmpQuat[2]; Element->quat[3] = TmpQuat[3];\n',
- multiline=True,
- )
-
-
-def _canon_export_spatial_pose(canon_def) -> str:
- prop = canon_def.get("emits_property")
- helper = canon_def.get("export_helper")
- return _guarded_export(
- override_toggle_name(prop["name"]),
- f' double TmpPos[3];\n'
- f' {helper}({prop["name"]}, TmpPos);\n'
- f' Element->pos[0] = TmpPos[0]; Element->pos[1] = TmpPos[1]; Element->pos[2] = TmpPos[2];\n',
- multiline=True,
- )
-
-
-@dataclass(frozen=True)
-class Canonicalisation:
- """One canonicalisation's import + export emitters. Looked up by
- canon name from `codegen_rules.json[canonicalizations]`. The
- importer takes (canon_def, element_name) and returns C++ text;
- the exporter takes (canon_def) and returns C++ text."""
- name: str
- import_emitter: Callable[[Dict[str, Any], str], str]
- export_emitter: Callable[[Dict[str, Any]], str]
-
-
-_CANONICALISATIONS: Dict[str, Canonicalisation] = {
- c.name: c for c in [
- Canonicalisation("body_sleep_policy",
- _canon_import_body_sleep_policy,
- _canon_export_body_sleep_policy),
- Canonicalisation("actuator_transmission",
- _canon_import_actuator_transmission,
- _canon_export_actuator_transmission),
- Canonicalisation("fromto_decompose",
- _canon_import_fromto_decompose,
- _canon_export_fromto_decompose),
- Canonicalisation("orientation",
- _canon_import_orientation,
- _canon_export_orientation),
- Canonicalisation("spatial_pose",
- _canon_import_spatial_pose,
- _canon_export_spatial_pose),
- ]
-}
-
-
-def _canon_import_block(canon_name: str, canon_def: Dict[str, Any], element_name: str = "") -> str:
- entry = _CANONICALISATIONS.get(canon_name)
- if entry is None:
- _diag_add(
- f"[diagnostic] canonicalization '{canon_name}' has a rule entry "
- f"but no registry entry in _CANONICALISATIONS; per-element XML "
- f"import for absorbed attrs will be silently dropped.",
- source="canon_dispatch",
- )
- return ""
- return entry.import_emitter(canon_def, element_name)
-
-
-def _canon_export_block(canon_name: str, canon_def: Dict[str, Any]) -> str:
- entry = _CANONICALISATIONS.get(canon_name)
- if entry is None:
- _diag_add(
- f"[diagnostic] canonicalization '{canon_name}' has a rule entry "
- f"but no registry entry in _CANONICALISATIONS; per-element mjs "
- f"export for absorbed attrs will be silently dropped.",
- source="canon_dispatch",
- )
- return ""
- return entry.export_emitter(canon_def)
-
-
-# ---------------------------------------------------------------------------
-# Property-block emitters
-#
-# emit_schema_for_attrs used to inline both the canonicalisation property
-# loop and the per-attr property loop. They're factored out here so the
-# orchestration in emit_schema_for_attrs reads as "props + imports +
-# exports" instead of one 400-line function.
-# ---------------------------------------------------------------------------
-
-
-def _emit_canon_property_block(
- elem_canons: List[str],
- canonicalizations: Dict[str, Any],
- category_label: str,
- hidden_canons: Set[str],
-) -> str:
- """Emit canonicalisation-owned UPROPERTY blocks at the top of the
- component so the canonical authoring surface (Pos / Quat / etc)
- appears first in the Details panel."""
- out = ""
- for c in elem_canons:
- cd = canonicalizations.get(c)
- if not cd:
- continue
- out += _canon_property_block(
- c, cd, category_label,
- hide_from_details=(c in hidden_canons),
- )
- return out
-
-
-def _emit_per_attr_property_block(
- attrs: Sequence[str],
- elem_rules: Dict[str, Any],
- type_map: Dict[str, str],
- default_type: str,
- renames: Dict[str, str],
- category_label: str,
- *,
- global_excl: Set[str],
- elem_excl: Set[str],
- canon_absorbed: Set[str],
- xml_enum_attr_names: Set[str],
- hidden_attrs: Set[str],
-) -> str:
- """Emit per-attr UPROPERTY blocks (the bulk of the component's
- Details panel). Attrs handled by xml_enum_attrs are skipped — those
- use a hand-declared URLab enum UPROPERTY; codegen owns only the
- import/export mapping.
-
- ``property_units`` lowers to UE-native ``Units="m"`` meta on numeric
- scalars/structs; on TArray/FString/FLinearColor it lowers to a
- custom ``MjUnit="m"`` meta tag the URLab detail customization reads
- at runtime (UHT rejects Units on those types)."""
- prop_meta: Dict[str, str] = elem_rules.get("property_meta", {})
- property_defaults: Dict[str, str] = elem_rules.get("property_defaults", {})
- property_units: Dict[str, str] = elem_rules.get("property_units", {})
- out = ""
- for attr in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed,
- extra_excl=xml_enum_attr_names):
- ue_type = type_map.get(attr, default_type)
- prop_name = renames.get(attr, attr)
- attr_meta_parts: List[str] = []
- if prop_meta.get(attr):
- attr_meta_parts.append(prop_meta[attr])
- unit = property_units.get(attr) or property_units.get(prop_name)
- if unit:
- if _ue_type_accepts_units_meta(ue_type):
- attr_meta_parts.append(f'Units="{unit}"')
- else:
- attr_meta_parts.append(f'MjUnit="{unit}"')
- out += _emit_uproperty(
- prop_name, ue_type, category_label,
- extra_meta=", ".join(attr_meta_parts) if attr_meta_parts else None,
- default_override=property_defaults.get(attr) or property_defaults.get(prop_name),
- hide_from_details=(attr in hidden_attrs or prop_name in hidden_attrs),
- )
- return out
-
-
-def _emit_xml_enum_property_decls(
- elem_rules: Dict[str, Any],
- category_label: str,
- *,
- apply_canonicalizations: bool,
-) -> str:
- """Emit UPROPERTY decls for xml_enum_attrs entries that opt in via
- ``emit_property_decl: true``. URLab usually hand-declares the
- UE-side enum properties (e.g. ``EMjJointType Type`` in MjJoint.h);
- the codegen-owned path is reserved for cases where the rule author
- wants the decl + initializer to live in the rule JSON. Only fires
- on the BASE class emission (subclasses would shadow the base decl
- and fail UHT).
-
- Per-rule ``property_default`` lets the enum decl take a real
- initializer like ``EMjGainType::Fixed`` instead of the ``{}``
- fallback. A typo'd default (``"Fxed"``) surfaces as a codegen
- diagnostic, not a misleading UHT compile error far downstream."""
- if not apply_canonicalizations:
- return ""
- out = ""
- for attr, enum_def in elem_rules.get("xml_enum_attrs", {}).items():
- if not enum_def.get("emit_property_decl"):
- continue
- ue_prop = enum_def.get("ue_property")
- ue_enum_type = enum_def.get("ue_enum_type")
- if not ue_prop or not ue_enum_type:
- continue
- prop_default = enum_def.get("property_default")
- if prop_default:
- value_map = enum_def.get("value_map", {})
- valid_members = {m[0] for m in value_map.values()
- if isinstance(m, (list, tuple)) and m}
- if valid_members and prop_default not in valid_members:
- _diag_add(
- f"[diagnostic] xml_enum '{attr}' property_default "
- f"'{prop_default}' is not in value_map UE members "
- f"({sorted(valid_members)}); UPROPERTY default will "
- f"fail UHT compile.",
- source="property_default",
- )
- full_default = (
- f"{ue_enum_type}::{prop_default}" if prop_default else None
- )
- out += _emit_uproperty(
- ue_prop, ue_enum_type, category_label,
- extra_meta=enum_def.get("property_meta"),
- default_override=full_default,
- )
- return out
-
-
-def _emit_imports_block(ctx: EmissionContext) -> str:
- """Emit the ``ImportFromXml`` body — every read-from-XML line. Order:
- common imports prefix (name/class), xml_enum imports, per-attr
- imports, canon imports, SetRelativeTransform driver, target-
- collation imports, unit-conversion imports."""
- attrs = ctx.attrs
- elem_rules = ctx.elem_rules
- type_map = ctx.type_map
- default_type = ctx.default_type
- renames = ctx.renames
- global_excl = ctx.global_excl
- elem_excl = ctx.elem_excl
- canon_absorbed = ctx.canon_absorbed
- elem_canons = ctx.elem_canons
- canonicalizations = ctx.canonicalizations
- apply_canon = ctx.apply_canonicalizations
- xml_enum_attr_names = ctx.xml_enum_attr_names
-
- imports = ""
-
- # 2a) Common imports prefix (name / class) — emits at the top.
- _COMMON_IMPORT_FIELDS = {"name": "MjName", "class": "MjClassName"}
- common_imports_list = elem_rules.get("common_imports", []) if apply_canon else []
- if common_imports_list:
- common_block = ""
- for entry in common_imports_list:
- if isinstance(entry, str):
- attr = entry
- ue_field = _COMMON_IMPORT_FIELDS.get(attr, attr)
- else:
- attr = entry["attr"]
- ue_field = entry.get("ue_field", _COMMON_IMPORT_FIELDS.get(attr, attr))
- common_block += (
- f' MjXmlUtils::ReadAttrString(Node, TEXT("{attr}"), {ue_field});\n'
- )
- imports = common_block + imports
-
- # 3a) XML enum imports first (downstream emission can depend on the
- # resolved enum value, e.g. fromto_decompose reads Type).
- xml_enum_attrs: Dict[str, Any] = elem_rules.get("xml_enum_attrs", {})
- for attr, enum_def in xml_enum_attrs.items():
- if _should_emit_xml_enum_at_this_layer(
- attr, attrs, global_excl, apply_canonicalizations=apply_canon,
- ):
- imports += _emit_xml_enum_import(attr, enum_def)
-
- # 3b) Per-attr imports.
- vec3_convert_map: Dict[str, str] = elem_rules.get("vec3_convert", {})
- for attr in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed,
- extra_excl=xml_enum_attr_names):
- ue_type = type_map.get(attr, default_type)
- prop_name = renames.get(attr, attr)
- imports += _emit_import_line(attr, prop_name, ue_type,
- vec3_convert=vec3_convert_map.get(attr))
-
- # 3c) Canon imports run AFTER per-attr so canons (fromto) can
- # override individual slots.
- for c in elem_canons:
- cd = canonicalizations.get(c)
- if cd:
- imports += _canon_import_block(c, cd, element_name=ctx.element_name)
-
- # 3d) Drive the UE component transform from the codegen-owned
- # Pos/Quat UPROPERTYs.
- if apply_canon:
- if "spatial_pose" in elem_canons:
- imports += " if (bOverride_Pos) SetRelativeLocation(Pos);\n"
- if "orientation" in elem_canons:
- imports += " if (bOverride_Quat) SetRelativeRotation(Quat);\n"
-
- # 4c) Target-collation imports.
- target_collations: Dict[str, Any] = elem_rules.get("target_collations", {})
- if apply_canon:
- for prop_name, coll_def in target_collations.items():
- imports += _emit_target_collation_import(
- prop_name, coll_def.get("absorbs_attrs", [])
- )
-
- # 4d) Unit-conversion imports.
- unit_conversions: Dict[str, Any] = elem_rules.get("unit_conversion", {})
- for attr, conv_list in unit_conversions.items():
- if attr not in attrs and not apply_canon:
- continue
- prop_name = renames.get(attr, attr)
- ue_type = type_map.get(attr, default_type)
- is_array = ue_type.startswith("TArray")
- imports += _emit_unit_conversion_block(
- prop_name, conv_list, side="import", is_array=is_array,
- )
-
- return imports
-
-
-def _emit_exports_block(ctx: EmissionContext) -> str:
- """Emit the ``ExportTo`` body — every write-back-to-mjs line. Order:
- canon exports, xml_enum exports, per-attr exports, data-packed
- exports, target-collation exports, unit-conversion exports, double-
- vec exports."""
- attrs = ctx.attrs
- elem_rules = ctx.elem_rules
- type_map = ctx.type_map
- default_type = ctx.default_type
- renames = ctx.renames
- global_excl = ctx.global_excl
- elem_excl = ctx.elem_excl
- canon_absorbed = ctx.canon_absorbed
- elem_canons = ctx.elem_canons
- canonicalizations = ctx.canonicalizations
- apply_canon = ctx.apply_canonicalizations
- xml_enum_attr_names = ctx.xml_enum_attr_names
- mjs_fields = ctx.mjs_fields
- mjs_array_caps = ctx.mjs_array_caps or {}
- consumed_by_setto = ctx.consumed_by_setto
- attr_to_mjs_field = ctx.attr_to_mjs_field
-
- exports = ""
- target_collations: Dict[str, Any] = elem_rules.get("target_collations", {})
- unit_conversions: Dict[str, Any] = elem_rules.get("unit_conversion", {})
- vec3_convert_map: Dict[str, str] = elem_rules.get("vec3_convert", {})
-
- # 5) Canon exports first (set canonical mjs fields before per-attr
- # tweaks). canon_export_skip opts an element out per-canon (e.g.
- # body's pos/quat are written by MjSpecWrapper from the transform).
- canon_export_skip = set(elem_rules.get("canon_export_skip", []))
- for c in elem_canons:
- if c in canon_export_skip:
- continue
- cd = canonicalizations.get(c)
- if cd:
- exports += _canon_export_block(c, cd)
-
- # 5b) XML enum exports — same layer policy as imports (3a).
- xml_enum_attrs: Dict[str, Any] = elem_rules.get("xml_enum_attrs", {})
- for attr, enum_def in xml_enum_attrs.items():
- if _should_emit_xml_enum_at_this_layer(
- attr, attrs, global_excl, apply_canonicalizations=apply_canon,
- ):
- exports += _emit_xml_enum_export(attr, enum_def)
-
- # 6) Per-attr exports.
- data_packed_attrs: Dict[str, Any] = elem_rules.get("mjs_data_packed_attrs", {})
- double_vec_attrs: List[str] = elem_rules.get("mjs_double_vec_attrs", [])
- double_vec_set: set = set(double_vec_attrs)
- sentinel_skip: Dict[str, str] = elem_rules.get("sentinel_skip_export", {})
- export_skip_attrs: set = set(elem_rules.get("export_skip_attrs", []))
- unit_convert_export_attrs: set = {
- a for a, convs in unit_conversions.items()
- if any(cv.get("export_op") for cv in convs)
- }
- target_collation_absorbed: set = set()
- if apply_canon:
- for prop_name, coll_def in target_collations.items():
- target_collation_absorbed.update(coll_def.get("absorbs_attrs", []))
- export_extra_excl: set = set(xml_enum_attr_names)
- export_extra_excl |= double_vec_set
- export_extra_excl |= unit_convert_export_attrs
- export_extra_excl |= export_skip_attrs
- export_extra_excl |= target_collation_absorbed
- if apply_canon:
- export_extra_excl |= set(data_packed_attrs.keys())
- for attr in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed,
- extra_excl=export_extra_excl):
- ue_type = type_map.get(attr, default_type)
- prop_name = renames.get(attr, attr)
- # Cap export loops against the destination C array size so a
- # narrower mjs field can't overrun.
- resolved_field = _resolve_mjs_field(
- attr, mjs_fields, attr_to_mjs_field,
- ) if mjs_fields else (attr_to_mjs_field or {}).get(attr, attr)
- array_cap = mjs_array_caps.get(resolved_field)
- exports += _emit_export_line(
- attr, prop_name, ue_type,
- mjs_fields=mjs_fields,
- slot_sentinel=sentinel_skip.get(attr),
- attr_to_mjs_field=attr_to_mjs_field,
- consumed_by_setto=consumed_by_setto,
- vec3_convert=vec3_convert_map.get(attr),
- array_cap=array_cap,
- )
-
- # 6b) Data-packed exports.
- if apply_canon:
- for attr, packed_def in data_packed_attrs.items():
- ue_type = type_map.get(attr, default_type)
- prop_name = renames.get(attr, attr)
- exports += _emit_data_packed_export(
- attr, packed_def, ue_type, prop_name,
- )
-
- # 6d) Target-collation exports.
- if apply_canon:
- for prop_name, coll_def in target_collations.items():
- exports += _emit_target_collation_export(
- prop_name, coll_def["mjs_field"],
- )
-
- # 6e) Unit-conversion exports.
- for attr, conv_list in unit_conversions.items():
- if attr not in attrs and not apply_canon:
- continue
- prop_name = renames.get(attr, attr)
- ue_type = type_map.get(attr, default_type)
- is_array = ue_type.startswith("TArray")
- if mjs_fields:
- mjs_field = _resolve_mjs_field(attr, mjs_fields, attr_to_mjs_field)
- else:
- mjs_field = (attr_to_mjs_field or {}).get(attr, attr)
- exports += _emit_unit_conversion_export(
- prop_name, mjs_field, conv_list, is_array=is_array,
- )
-
- # 6c) Double-vec exports.
- for attr in double_vec_attrs:
- prop_name = renames.get(attr, attr)
- if mjs_fields:
- mjs_field = _resolve_mjs_field(attr, mjs_fields, attr_to_mjs_field)
- else:
- mjs_field = (attr_to_mjs_field or {}).get(attr, attr)
- exports += _emit_double_vec_export(attr, prop_name, mjs_field)
-
- return exports
-
-
-def emit_schema_for_attrs(
- attrs: Sequence[str],
- rules: Dict[str, Any],
- element_name: str,
- category_label: str,
- *,
- apply_canonicalizations: bool = True,
- mjs_fields: set | None = None,
- consumed_by_setto: set | None = None,
- mjs_array_caps: Dict[str, int] | None = None,
-) -> EmittedSchema:
- """Emit UPROPERTY + import/export blocks for a list of schema attrs.
-
- Applies global exclusions, element exclusions, canonicalisation
- absorption, and type mappings from `codegen_rules.json`.
-
- Pass ``apply_canonicalizations=False`` when emitting for a subclass
- in a category whose base class already owns the canonicalised
- properties (e.g. site/tendon/equality subtypes in multi_uclass
- layout, or geom subtypes that share base canonicalisations).
- Raw canonicalised attrs (pos/quat/euler/etc.) are still excluded
- so they don't re-appear as per-attr UPROPERTYs.
-
- ``consumed_by_setto`` is the set of schema attrs that will be packed
- into the mjs spec by an ``mjs_setTo*`` call prepended to the export
- block (see ``_emit_setto_call``). For those attrs, we suppress the
- fallback "(skipped: mjs has no field)" comment to keep the emitted
- file uncluttered.
- """
- ctx = EmissionContext.from_call(
- attrs, rules, element_name,
- apply_canonicalizations=apply_canonicalizations,
- mjs_fields=mjs_fields,
- consumed_by_setto=consumed_by_setto,
- mjs_array_caps=mjs_array_caps,
- )
- elem_rules = ctx.elem_rules
- hidden_canons: set = set(elem_rules.get("hidden_canon_properties", []))
- hidden_attrs: set = set(elem_rules.get("hidden_attrs", []))
-
- props = (
- _emit_canon_property_block(
- ctx.elem_canons, ctx.canonicalizations,
- category_label, hidden_canons,
- )
- + _emit_per_attr_property_block(
- attrs, elem_rules, ctx.type_map, ctx.default_type, ctx.renames,
- category_label,
- global_excl=ctx.global_excl, elem_excl=ctx.elem_excl,
- canon_absorbed=ctx.canon_absorbed,
- xml_enum_attr_names=ctx.xml_enum_attr_names,
- hidden_attrs=hidden_attrs,
- )
- + _emit_xml_enum_property_decls(
- elem_rules, category_label,
- apply_canonicalizations=apply_canonicalizations,
- )
- )
-
- imports = _emit_imports_block(ctx)
- exports = _emit_exports_block(ctx)
-
- return EmittedSchema(properties_h=props, imports_cpp=imports, exports_cpp=exports)
-
-
-def _emit_passthrough_canon_lines(
- elem_canons: List[str],
- canonicalizations: Dict[str, Any],
-) -> List[str]:
- """Emit ``pos="x y z"`` / ``quat="w x y z"`` formatters for the
- canonicalisation-owned UPROPERTYs. Round-trips through the same
- UEToMjPosition / UEToMjRotation helpers the canon export blocks
- use, so the XML matches the spec write exactly."""
- lines: List[str] = []
- for c in elem_canons:
- cd = canonicalizations.get(c)
- if not cd:
- continue
- emits = cd.get("emits_property")
- if not emits:
- continue
- prop = emits["name"]
- ue_t = emits["type"]
- toggle = override_toggle_name(prop)
- if ue_t == "FVector" and c == "spatial_pose":
- lines.append(f" if ({toggle})")
- lines.append(" {")
- lines.append(" double Tmp[3];")
- lines.append(f" MjUtils::UEToMjPosition({prop}, Tmp);")
- lines.append(' Out += FString::Printf(TEXT(" pos=\\"%f %f %f\\""), Tmp[0], Tmp[1], Tmp[2]);')
- lines.append(" }")
- elif ue_t == "FQuat" and c == "orientation":
- lines.append(f" if ({toggle})")
- lines.append(" {")
- lines.append(" double Tmp[4];")
- lines.append(f" MjUtils::UEToMjRotation({prop}, Tmp);")
- lines.append(' Out += FString::Printf(TEXT(" quat=\\"%f %f %f %f\\""), Tmp[0], Tmp[1], Tmp[2], Tmp[3]);')
- lines.append(" }")
- return lines
-
-
-def _emit_passthrough_xml_enum_lines(
- xml_enum_attrs: Dict[str, Any],
-) -> List[str]:
- """Emit the per-attr if/else-if chain that picks the XML string for
- the chosen enum value."""
- lines: List[str] = []
- for attr, enum_def in xml_enum_attrs.items():
- ue_prop = enum_def["ue_property"]
- ue_enum = enum_def["ue_enum_type"]
- value_map = _resolve_value_map(attr, enum_def)
- toggle = override_toggle_name(ue_prop)
- lines.append(f" if ({toggle})")
- lines.append(" {")
- first = True
- for xml_val, mapping in value_map.items():
- ue_member = mapping[0]
- prefix = "if " if first else "else if "
- first = False
- lines.append(f' {prefix}({ue_prop} == {ue_enum}::{ue_member}) '
- f'Out += TEXT(" {attr}=\\"{xml_val}\\"");')
- lines.append(" }")
- return lines
-
-
-def _emit_passthrough_attr_line(
- attr: str, prop_name: str, ue_type: str, toggle: str,
-) -> List[str]:
- """Emit the per-type XML-attr formatter line(s) for a single attr.
- Returns a list of indented C++ lines (one for scalars, multiple
- for TArray loops). Unknown types fall through with a TODO comment
- so the build still compiles."""
- if ue_type == "FString":
- return [f' if ({toggle} && !{prop_name}.IsEmpty()) '
- f'Out += FString::Printf(TEXT(" {attr}=\\"%s\\""), *{prop_name});']
- if ue_type == "bool":
- return [f' if ({toggle}) '
- f'Out += FString::Printf(TEXT(" {attr}=\\"%s\\""), '
- f'{prop_name} ? TEXT("true") : TEXT("false"));']
- if ue_type == "int32":
- return [f' if ({toggle}) '
- f'Out += FString::Printf(TEXT(" {attr}=\\"%d\\""), {prop_name});']
- if ue_type == "float":
- return [f' if ({toggle}) '
- f'Out += FString::Printf(TEXT(" {attr}=\\"%f\\""), {prop_name});']
- if ue_type == "FLinearColor":
- return [f" if ({toggle}) "
- f'Out += FString::Printf(TEXT(" {attr}=\\"%f %f %f %f\\""), '
- f'{prop_name}.R, {prop_name}.G, {prop_name}.B, {prop_name}.A);']
- if ue_type.startswith("TArray 0)",
- " {",
- f' Out += TEXT(" {attr}=\\"");',
- f" for (int32 i = 0; i < {prop_name}.Num(); ++i)",
- " {",
- ' if (i > 0) Out += TEXT(" ");',
- f' Out += FString::Printf(TEXT("%f"), {prop_name}[i]);',
- " }",
- ' Out += TEXT("\\"");',
- " }",
- ]
- if ue_type.startswith("TArray 0)",
- " {",
- f' Out += TEXT(" {attr}=\\"");',
- f" for (int32 i = 0; i < {prop_name}.Num(); ++i)",
- " {",
- ' if (i > 0) Out += TEXT(" ");',
- f' Out += FString::Printf(TEXT("%d"), {prop_name}[i]);',
- " }",
- ' Out += TEXT("\\"");',
- " }",
- ]
- return [f' // TODO(xml_passthrough): unsupported UE type "{ue_type}" for attr "{attr}"']
-
-
-def emit_xml_passthrough_body(
- attrs: Sequence[str],
- rules: Dict[str, Any],
- element_name: str,
-) -> str:
- """Emit the body of a `BuildSchemaAttrsXml() const -> FString` method.
-
- For categories with ``xml_passthrough_emission: true`` in their codegen
- rule, the spec-registration path goes through an MJCF re-parse
- (mj_parseXMLString + mjs_attach) instead of the mjs_addX API — flexcomp
- is the canonical example because MuJoCo expands the flexcomp macro in
- the XML parser, not the spec compiler. To keep new schema attrs
- flowing end-to-end without hand-edits, the codegen emits a single
- method that walks every override-tracked UPROPERTY and writes its
- value as an ``name="value"`` XML attribute string. The hand-rolled
- BuildFlexcompXml just calls this helper for the main attrs and
- handles sub-elements (which the codegen doesn't model yet) itself.
-
- Output is the indented C++ statements (no signature, no braces) —
- the caller wraps them in a method body. Per-type emission lives in
- ``_emit_passthrough_attr_line``; canon + xml_enum live in their own
- helpers.
- """
- global_excl = set(rules.get("global_exclusions", []))
- elem_rules = rules.get("element_rules", {}).get(element_name, {})
- elem_excl = set(elem_rules.get("exclude_attrs", []))
- elem_canons: List[str] = elem_rules.get("applies_canonicalizations", [])
- canonicalizations = rules.get("canonicalizations", {})
- canon_absorbed: set = compute_canon_absorbed(elem_canons, canonicalizations)
- xml_enum_attrs: Dict[str, Any] = elem_rules.get("xml_enum_attrs", {})
- type_map: Dict[str, str] = rules.get("type_mappings", {})
- default_type: str = rules.get("default_type", "float")
- renames: Dict[str, str] = rules.get("property_renames", {})
-
- lines: List[str] = [" FString Out;"]
- lines.extend(_emit_passthrough_canon_lines(elem_canons, canonicalizations))
- lines.extend(_emit_passthrough_xml_enum_lines(xml_enum_attrs))
-
- # ``name`` is written by the caller (it knows the prefix / MjName
- # logic).
- passthrough_extra_excl = set(xml_enum_attrs) | {"name"}
- for attr in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed,
- extra_excl=passthrough_extra_excl):
- prop_name = renames.get(attr, attr)
- ue_type = type_map.get(attr, default_type)
- toggle = override_toggle_name(prop_name)
- lines.extend(_emit_passthrough_attr_line(attr, prop_name, ue_type, toggle))
-
- lines.append(" return Out;")
- return "\n".join(lines) + "\n"
-
-
-# ---------------------------------------------------------------------------
-# File templates
-# ---------------------------------------------------------------------------
-
-SUBCLASS_HEADER_TEMPLATE = """{Copyright}
-#pragma once
-
-#include "CoreMinimal.h"
-#include "{BaseInclude}"
-#include "{ClassFileStem}.generated.h"
-
-/**
- * @class {ClassName}
- * @brief Autogenerated component representing the MuJoCo '{ElementName}' element.
- *
- * Subclass of {BaseClassName}. Sets Type = {TypeEnumValue} in the constructor.
- */
-UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
-class URLAB_API {ClassName} : public {BaseClassName}
-{{
- GENERATED_BODY()
-
-public:
- {ClassName}();
-
- // --- CODEGEN_PROPERTIES_START ---
-{Properties} // --- CODEGEN_PROPERTIES_END ---
-
- virtual void ImportFromXml(const class FXmlNode* Node, const FMjCompilerSettings& CompilerSettings = FMjCompilerSettings{{}}) override;
- virtual void ExportTo({MjsStruct}* Element, mjsDefault* Default = nullptr) override;
-}};
-"""
-
-
-SUBCLASS_SOURCE_TEMPLATE = """{Copyright}
-#include "{IncludePath}"
-#include "MuJoCo/Utils/MjXmlUtils.h"
-#include "MuJoCo/Utils/MjOrientationUtils.h"
-#include "MuJoCo/Utils/MjUtils.h"
-#include "XmlNode.h"
-#include "mujoco/mjspec.h"
-
-{ClassName}::{ClassName}()
-{{
- {ConstructorBody}
-}}
-
-void {ClassName}::ImportFromXml(const FXmlNode* Node, const FMjCompilerSettings& CompilerSettings)
-{{
- Super::ImportFromXml(Node, CompilerSettings);
- if (!Node) return;
-
- // --- CODEGEN_IMPORT_START ---
-{Imports} // --- CODEGEN_IMPORT_END ---
-}}
-
-void {ClassName}::ExportTo({MjsStruct}* Element, mjsDefault* Default)
-{{
- if (!Element) return;
-
- Super::ExportTo(Element, Default);
-
- // --- CODEGEN_EXPORT_START ---
-{Exports} // --- CODEGEN_EXPORT_END ---
-}}
-"""
-
-
-# ---------------------------------------------------------------------------
-# Boundary-tag injection
-# ---------------------------------------------------------------------------
-
-# Text-injection machinery lives in `_codegen_inject`. The symbols
-# (`_make_tag_pair`, `_strip_cpp_braces_in_strings`,
-# `_find_matching_brace`, `_check_brace_balance`,
-# `inject_between_tags`, `_inject_tags_into_cpp`) are re-exported
-# through the import block at the top of this file.
-
-
-# ---------------------------------------------------------------------------
-# Owned-name computation (used for the schema-for-tests header).
-# The generator no longer migrates / strips existing files. Hand-prep
-# each component to the codegen-canonical shape (see docs/plan_codegen.md):
-# explicit CODEGEN tag pairs, ExportTo param named ``Element``, type-enum
-# field named ``Type``, ExtractSpecifics/ApplyRawOverrides/ParseSpecifics
-# deleted, schema-owned UPROPERTYs removed. The generator's only job is
-# to fill the tag slots.
-# ---------------------------------------------------------------------------
-
-
-def codegen_owned_property_names(category: str, attrs: List[str], rules: Dict[str, Any]) -> set:
- """Return the set of property names this category's codegen will
- emit for the given attribute list. Includes canonicalisation
- outputs."""
- global_excl = set(rules.get("global_exclusions", []))
- renames: Dict[str, str] = rules.get("property_renames", {})
- elem_rules = rules.get("element_rules", {}).get(category, {})
- elem_excl = set(elem_rules.get("exclude_attrs", []))
- elem_canons: List[str] = elem_rules.get("applies_canonicalizations", [])
- canonicalizations: Dict[str, Any] = rules.get("canonicalizations", {})
- canon_absorbed: set = compute_canon_absorbed(elem_canons, canonicalizations)
- owned: set = set()
- for c in elem_canons:
- cdef = canonicalizations.get(c)
- if cdef:
- prop = cdef.get("emits_property")
- if prop:
- owned.add(prop["name"])
- for a in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed):
- owned.add(renames.get(a, a))
- return owned
-
-
-
-
-# ---------------------------------------------------------------------------
-# Pipeline: emit subclass files
-# ---------------------------------------------------------------------------
-
-# `FileWrite` lives in `_codegen_core`.
-
-
-def _resolve_include_path(public_root: str, file_relpath: str) -> str:
- """Convert ``Public/MuJoCo/Components/Actuators/MjMotorActuator.h`` to
- the include path ``MuJoCo/Components/Actuators/MjMotorActuator.h``."""
- # All emitted headers are under /MuJoCo/Components/... so the
- # include strips the leading public_root.
- rel = os.path.relpath(file_relpath, public_root)
- return rel.replace(os.sep, "/")
-
-
-_BANNER_TEMPLATE_INCLUDES = {
- "MuJoCo/Utils/MjXmlUtils.h",
- "MuJoCo/Utils/MjOrientationUtils.h",
- "MuJoCo/Utils/MjUtils.h",
- "XmlNode.h",
- "mujoco/mjspec.h",
-}
-
-
-def _audit_banner_safety(source_path: str, subtype: Dict[str, Any]) -> None:
- """Scan an existing source file the codegen is ABOUT to overwrite via
- ``fully_emitted: true`` and emit a diagnostic if it carries content
- the template wouldn't reproduce (extra includes beyond the template
- set, extra method definitions, ctor extras not in ``extra_constructor``).
-
- Non-fatal — the rewrite still proceeds. The diagnostic exists so a
- rule author who flips ``fully_emitted: true`` without running the
- audit helper sees a loud warning the next time the codegen runs.
- """
- try:
- with open(source_path, "r", encoding="utf-8") as f:
- text = f.read()
- except FileNotFoundError:
- return
- except OSError as e:
- _diag_add(
- f"[diagnostic] banner_overwrite: could not read '{source_path}' "
- f"({e}) — skipping the pre-overwrite audit. The rewrite still "
- f"proceeds, but any hand-edits in the existing file may be lost "
- f"unnoticed.",
- source="banner_overwrite",
- )
- return
-
- rel = os.path.basename(source_path)
- own_h = os.path.splitext(rel)[0] + ".h"
-
- # Extra includes beyond the template set.
- extras = []
- for inc in re.findall(r'#include\s+"([^"]+)"', text):
- if inc.endswith(own_h) or inc in _BANNER_TEMPLATE_INCLUDES:
- continue
- extras.append(inc)
- if extras:
- _diag_add(
- f"[diagnostic] fully_emitted: true on '{subtype.get('class_name', rel)}' "
- f"is about to OVERWRITE {rel} which has non-template includes "
- f"{extras}. Run Scripts/codegen/_audit_banner_candidates.py "
- f"before flipping, or revert fully_emitted on this subtype.",
- source="banner_overwrite",
- )
-
- # Extra ctor lines beyond what the rule provides via extra_constructor.
- # The ctor body can contain its own brace-bearing statements (range-for
- # loops, init lists, nested ifs); use the brace-aware extractor so the
- # diagnostic doesn't truncate at the first inner ``}`` and report a
- # spurious "non-template ctor content".
- expected = {subtype.get("extra_constructor", "").strip()}
- expected.discard("")
- class_name = subtype.get("class_name", "")
- if class_name:
- sig = re.search(
- rf'{re.escape(class_name)}::{re.escape(class_name)}\(\)\s*\{{',
- text,
- )
- if sig:
- open_idx = sig.end() - 1
- close_idx = _find_matching_brace(text, open_idx)
- if close_idx is not None:
- body = text[open_idx + 1:close_idx]
- stripped = re.sub(r"(Type\s*=\s*EMj\w+::\w+;|//[^\n]*|\s+)", "", body)
- for e in expected:
- # The expected extras may themselves contain whitespace —
- # strip to compare.
- stripped = stripped.replace(re.sub(r"\s+", "", e), "")
- if stripped:
- _diag_add(
- f"[diagnostic] fully_emitted: true on "
- f"'{class_name}' is about to OVERWRITE the ctor in "
- f"{rel} — non-template ctor content remains after "
- f"stripping Type+extra_constructor: {stripped!r}.",
- source="banner_overwrite",
- )
-
-
-def _subclass_constructor_body(
- category: str,
- subtype: Dict[str, Any],
- type_enum_name: Optional[str],
-) -> str:
- pieces: List[str] = []
- if type_enum_name and subtype.get("enum_value"):
- pieces.append(f"Type = {type_enum_name}::{subtype['enum_value']};")
- extra = subtype.get("extra_constructor")
- if extra:
- pieces.extend(extra.strip().splitlines())
- if not pieces:
- return "// (no per-subclass constructor body)"
- return ("\n ").join(pieces)
-
-
-def _setto_consumed_attrs(
- setto_rules: Dict[str, Any] | None,
- mjspec: Dict[str, Any] | None,
-) -> set:
- """Return the set of schema attr names that an ``mjs_setTo*`` call
- consumes for the given subtype. These attrs are packed into the mjs
- spec via the setTo function (e.g. position actuator's kp/kv/dampratio
- go into gainprm/biasprm via mjs_setToPosition); the codegen should
- NOT also emit a "skipped" fallback comment for them in the export
- block (the setTo call already handles them)."""
- if not setto_rules or not mjspec:
- return set()
- fn_name = setto_rules.get("call")
- if not fn_name or fn_name not in mjspec.get("setto_functions", {}):
- return set()
- sig = mjspec["setto_functions"][fn_name]
- param_renames: Dict[str, str] = setto_rules.get("param_renames", {})
- return {param_renames.get(p["name"], p["name"]) for p in sig.get("params", [])}
-
-
-def _emit_setto_call(
- subtype_key: str,
- setto_rules: Dict[str, Any],
- rules: Dict[str, Any],
- mjspec: Dict[str, Any] | None,
- subtype_schema_attrs: List[str],
- base_schema_attrs: Sequence[str],
-) -> str:
- """Generate the ``mjs_setToX(Element, ...)`` call inside CODEGEN_EXPORT
- from the function's signature in the mjspec snapshot. Replaces the hand-
- written multi-line C++ literals that used to live in ``codegen_rules.json``.
-
- Marshaling rules per function parameter ``p`` (``c_type``, ``array_dim``):
- - ``double`` scalar + UE ``float`` -> ``bOverride_p ? (double)p : ``
- - ``double`` scalar + UE ``FVector`` + projection ``X``
- -> ``bOverride_p ? (double)p.X : ``
- - ``double[N]`` array + UE ``TArray``
- -> ``double pBuf[N] = { ... }; pass pBuf``
- - ``double[1]`` array + UE ``float`` (scalar-in-buffer)
- -> ``double pBuf[1] = { ... }; pass pBuf``
- - ``int`` scalar -> ``bOverride_p ? (int)p : ``
- - Params NOT present in subtype/base schema -> force sentinel.
-
- Sentinels: defaults come from ``setto_param_defaults`` in the rules JSON,
- keyed by ``(function_name, param_name)``; otherwise ``-1.0`` for doubles,
- ``0`` for ints. The dcmotor pattern (``nullable_arrays``) emits
- ``bOverride_X ? Buf : nullptr`` and uses the ``FillDouble`` helper that
- lives file-local in ``MjDcMotorActuator.cpp``.
- """
- if setto_rules is None:
- return ""
- fn_name = setto_rules.get("call")
- if not fn_name:
- return ""
- if not mjspec or fn_name not in mjspec.get("setto_functions", {}):
- raise RuntimeError(
- f"mjs_setTo* function '{fn_name}' not found in the projected "
- f"mjspec. Rebuild the introspect snapshot via "
- f"`python Scripts/codegen/build_introspect_snapshot.py`."
- )
- sig = mjspec["setto_functions"][fn_name]
- if not sig["params"]:
- return (
- f" {{\n"
- f" const char* SetToErr = {fn_name}(Element);\n"
- f" if (SetToErr && *SetToErr)\n"
- f" {{\n"
- f" UE_LOG(LogURLabBind, Warning, TEXT(\"{fn_name} on '%s': %s\"), "
- f"*GetName(), UTF8_TO_TCHAR(SetToErr));\n"
- f" }}\n"
- f" }}\n"
- )
-
- type_mappings: Dict[str, str] = rules.get("type_mappings", {})
- default_type: str = rules.get("default_type", "float")
- fn_defaults: Dict[str, str] = rules.get("setto_param_defaults", {}).get(fn_name, {})
- param_renames: Dict[str, str] = setto_rules.get("param_renames", {})
- projections: Dict[str, str] = setto_rules.get("projections", {})
- nullable_arrays: bool = setto_rules.get("nullable_arrays", False)
- use_filldouble: bool = setto_rules.get("use_filldouble", False)
- # Params that MuJoCo writes UNCONDITIONALLY by value (e.g. position kp ->
- # gainprm[0] = kp): there is no sentinel that means "unset", so when the
- # UPROPERTY isn't overridden we must re-pass the value already inherited
- # onto the element (via mjs_addActuator's default class), not a sentinel
- # that would clobber it. Value is the verbatim C++ expression to re-assert.
- inherit_fields: Dict[str, str] = setto_rules.get("inherit_fields", {})
- # Pointer params (double x[1]) that MuJoCo skips when passed nullptr
- # (if (kv) { ... }): pass nullptr when not overridden so the inherited /
- # type-derived default survives, instead of a non-null pointer to a
- # sentinel (which trips MuJoCo's validation and gets written literally).
- nullable_params: set = set(setto_rules.get("nullable_params", []))
-
- schema_attr_set = set(subtype_schema_attrs) | set(base_schema_attrs)
-
- setup_lines: List[str] = []
- call_args: List[str] = []
- for p in sig["params"]:
- pname = p["name"]
- ue_prop = param_renames.get(pname, pname)
- param_in_schema = ue_prop in schema_attr_set
- ue_type = type_mappings.get(ue_prop, default_type)
- c_is_int = p["c_type"] == "int"
- default_sentinel = "0" if c_is_int else "-1.0"
- sentinel = fn_defaults.get(pname, default_sentinel)
- proj = projections.get(pname)
- # What to pass when the UPROPERTY is not overridden: re-assert the
- # inherited element field for unconditional-write params, else the
- # sentinel (correct only for params MuJoCo guards with `>= 0` / null).
- notset = inherit_fields.get(pname, sentinel)
- is_nullable = pname in nullable_params
-
- if p["array_dim"] is None:
- # Scalar parameter.
- if not param_in_schema:
- call_args.append(notset)
- continue
- if ue_type == "FVector" and proj:
- expr = f"bOverride_{ue_prop} ? (double){ue_prop}.{proj} : {notset}"
- elif ue_type.startswith("TArray"):
- # UE side is a TArray (e.g. cylinder.timeconst, where some
- # actuator subtypes share the TArray mapping but
- # mjs_setToCylinder takes a scalar). Take element [0].
- expr = (
- f"(bOverride_{ue_prop} && {ue_prop}.Num() > 0) ? "
- f"(double){ue_prop}[0] : {notset}"
- )
- elif c_is_int:
- expr = f"bOverride_{ue_prop} ? (int){ue_prop} : {notset}"
- else:
- expr = f"bOverride_{ue_prop} ? (double){ue_prop} : {notset}"
- call_args.append(expr)
- continue
-
- # Fixed-array parameter.
- dim = p["array_dim"]
- buf_name = f"{pname}Buf"
-
- if nullable_arrays:
- # DC-motor pattern: pass nullptr when the UPROPERTY is not overridden.
- if use_filldouble and param_in_schema:
- setup_lines.append(
- f" double {buf_name}[{dim}]; FillDouble({buf_name}, {ue_prop});"
- )
- call_args.append(f"bOverride_{ue_prop} ? {buf_name} : nullptr")
- elif param_in_schema:
- # No FillDouble helper — inline element-wise init.
- inits = ",".join(
- f" (bOverride_{ue_prop} && {ue_prop}.Num() > {i}) ? (double){ue_prop}[{i}] : {sentinel}"
- for i in range(dim)
- )
- setup_lines.append(f" double {buf_name}[{dim}] = {{{inits} }};")
- call_args.append(f"bOverride_{ue_prop} ? {buf_name} : nullptr")
- else:
- # Not even declared on the URLab side — always nullptr.
- call_args.append("nullptr")
- continue
-
- if not param_in_schema:
- if is_nullable:
- # Not authored on the URLab side and MuJoCo skips it on null:
- # pass nullptr so the inherited / type-derived default survives.
- call_args.append("nullptr")
- continue
- # Force-sentinel array.
- inits = ", ".join(sentinel for _ in range(dim))
- setup_lines.append(f" double {buf_name}[{dim}] = {{ {inits} }};")
- call_args.append(buf_name)
- continue
-
- if ue_type.startswith("TArray"):
- if dim == 1:
- setup_lines.append(
- f" double {buf_name}[1] = {{ (bOverride_{ue_prop} && "
- f"{ue_prop}.Num() > 0) ? (double){ue_prop}[0] : {sentinel} }};"
- )
- else:
- inits = ", ".join(
- f"(bOverride_{ue_prop} && {ue_prop}.Num() > {i}) ? "
- f"(double){ue_prop}[{i}] : {sentinel}"
- for i in range(dim)
- )
- setup_lines.append(f" double {buf_name}[{dim}] = {{ {inits} }};")
- else:
- # Scalar UE type wrapped in a 1-element buffer (e.g. position.kv:float -> double[1]).
- if dim != 1:
- raise RuntimeError(
- f"non-1 array dim {dim} with scalar UE type for {fn_name}.{pname}"
- )
- setup_lines.append(
- f" double {buf_name}[1] = {{ bOverride_{ue_prop} ? "
- f"(double){ue_prop} : {sentinel} }};"
- )
- # Nullable pointer param: pass the buffer only when overridden, else
- # nullptr so MuJoCo leaves the inherited value untouched. For a TArray
- # source, an authored-but-empty array is also treated as unset — passing
- # a sentinel buffer would trip MuJoCo's range check and short-circuit the
- # setTo (e.g. skipping biastype) instead of just inheriting.
- if is_nullable:
- nn = f"bOverride_{ue_prop}"
- if ue_type.startswith("TArray"):
- nn = f"(bOverride_{ue_prop} && {ue_prop}.Num() > 0)"
- call_args.append(f"{nn} ? {buf_name} : nullptr")
- else:
- call_args.append(buf_name)
-
- args_str = ", ".join(call_args)
- body = "\n".join(setup_lines)
- if body:
- body += "\n"
- # MuJoCo's mjs_setTo* return a diagnostic string on misuse (e.g. a param
- # out of range). Surface it instead of silently discarding it.
- call = (
- f" const char* SetToErr = {fn_name}(Element, {args_str});\n"
- f" if (SetToErr && *SetToErr)\n"
- f" {{\n"
- f" UE_LOG(LogURLabBind, Warning, TEXT(\"{fn_name} on '%s': %s\"), "
- f"*GetName(), UTF8_TO_TCHAR(SetToErr));\n"
- f" }}\n"
- )
- return f" {{\n{body}{call} }}\n"
-
-
-def _mjs_fields_for(cat_rules: Dict[str, Any], mjspec: Dict[str, Any] | None) -> set:
- """Pull the field-name set for a category's mjs_struct out of the
- mjspec snapshot. Returns empty set if snapshot is missing — codegen
- then falls back to using the raw schema attr name."""
- if not mjspec:
- return set()
- struct_name = cat_rules.get("mjs_struct")
- if not struct_name:
- return set()
- return set(mjspec.get("structs", {}).get(struct_name, []))
-
-
-def _mjs_array_caps_for(
- cat_rules: Dict[str, Any],
- mjspec: Dict[str, Any] | None,
-) -> Dict[str, int]:
- """Pull {field_name: c_array_dim} for a category's mjs_struct from the
- introspect snapshot, scoped to fixed-size C arrays only (skips scalars,
- dynamic vectors, pointers). The TArray export loop uses these caps to
- emit ``FMath::Min(prop.Num(), cap)`` so a future MuJoCo array-shrink
- (e.g. ``gainprm[10]`` → ``gainprm[6]``) doesn't overrun memory.
- """
- if not mjspec:
- return {}
- struct_name = cat_rules.get("mjs_struct")
- if not struct_name:
- return {}
- introspect = mjspec.get("introspect") or {}
- struct_table = introspect.get("structs", {})
- fields = struct_table.get(struct_name, {}).get("fields", [])
- caps: Dict[str, int] = {}
- for f in fields:
- dim = f.get("array_dim")
- if isinstance(dim, int) and dim > 1:
- caps[f["name"]] = dim
- return caps
-
-
-def emit_subclass_files(
- category: str,
- cat_rules: Dict[str, Any],
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- public_root: str,
- private_root: str,
- mjspec: Dict[str, Any] | None = None,
-) -> List[FileWrite]:
- """Emit one .h and one .cpp per subtype for layout=single_uclass_per_file.
-
- For files that do not exist yet (new subclasses): emit from template.
- For files that already exist: migrate (strip owned + insert tags +
- strip dead methods) then inject between tags. Custom non-schema
- methods and members in the existing files are preserved.
- """
- writes: List[FileWrite] = []
- base_class = cat_rules["base_class_name"]
- base_header_relpath = cat_rules["base_class_header"]
- mjs_struct = cat_rules["mjs_struct"]
- mjs_fields = _mjs_fields_for(cat_rules, mjspec)
- mjs_array_caps = _mjs_array_caps_for(cat_rules, mjspec)
- type_enum = cat_rules.get("type_enum_name")
- pub_dir = os.path.join(public_root, cat_rules.get("subclass_directory_pub", ""))
- priv_dir = os.path.join(private_root, cat_rules.get("subclass_directory_priv", ""))
-
- common_attrs = schema_attrs(schema, cat_rules["schema_common_block"])
- common_extras = cat_rules.get("schema_common_extra_attrs", [])
- common_set = set(common_attrs) | set(common_extras)
-
- for subtype in cat_rules.get("subtypes", []):
- sub_key = subtype["key"]
- per_type_attrs = schema_subtype_attrs(schema, category, sub_key)
- attrs = [a for a in per_type_attrs if a not in common_set]
-
- # Setto-consumed attrs feed the silent-skip path in emit_schema_for_attrs.
- # We compute them up front because the setTo block is prepended AFTER
- # the per-attr export emission but conceptually fires first.
- setto_rules = (cat_rules.get("subtype_setto") or {}).get(sub_key)
- setto_consumed = _setto_consumed_attrs(setto_rules, mjspec)
-
- emitted = emit_schema_for_attrs(
- attrs, rules, element_name=category,
- category_label=base_class.removeprefix("UMj"),
- apply_canonicalizations=False, # base owns the canon block
- mjs_fields=mjs_fields,
- consumed_by_setto=setto_consumed,
- mjs_array_caps=mjs_array_caps,
- )
-
- # Per-subtype ``mjs_setTo*`` preset call. Codegen owns this snippet — it
- # lands at the TOP of the CODEGEN_EXPORT block so every regeneration
- # keeps the call in sync with the C API. The call body is derived from
- # the function signature in the mjspec snapshot, NOT a hand-written
- # literal in codegen_rules.json. See ``_emit_setto_call``.
- if setto_rules:
- setto_block = _emit_setto_call(
- sub_key,
- setto_rules,
- rules,
- mjspec,
- subtype_schema_attrs=per_type_attrs,
- base_schema_attrs=common_attrs,
- )
- if setto_block:
- emitted = EmittedSchema(
- properties_h=emitted.properties_h,
- imports_cpp=emitted.imports_cpp,
- exports_cpp=setto_block + emitted.exports_cpp,
- )
-
- class_name = subtype["class_name"]
- header_filename = subtype["header"]
- class_file_stem = os.path.splitext(header_filename)[0]
- header_path = os.path.join(pub_dir, header_filename)
- source_path = os.path.join(priv_dir, class_file_stem + ".cpp")
-
- # ``fully_emitted: true`` on a subtype rule means codegen owns the
- # entire file (header + source). Existing files get overwritten
- # from the template every regen — equivalent to "delete and let
- # the codegen recreate", but stable across runs. Use this for
- # pure-stub subclasses (no extra includes, no extra methods, ctor
- # only sets Type). The ``Scripts/codegen/_audit_banner_candidates.py``
- # helper identifies the safe subset.
- fully_emitted = bool(subtype.get("fully_emitted"))
-
- if os.path.exists(header_path) and not fully_emitted:
- # Existing subclass file — inject between pre-prepped tags.
- # Diagnose missing markers loudly so a typo in the marker pair
- # (or a forgotten pre-prep step on a hand-rolled subclass)
- # surfaces here rather than as wrong runtime behaviour.
- with open(header_path, "r", encoding="utf-8") as f:
- h_text = f.read()
- h_text, _ = _inject_or_diag(
- h_text, "PROPERTIES", emitted.properties_h,
- host_path=header_path, host_kind="subclass header",
- block_label="per-subtype UPROPERTY block",
- diag_source="subclass_inject",
- )
- writes.append(FileWrite(path=header_path, content=h_text))
-
- if os.path.exists(source_path):
- with open(source_path, "r", encoding="utf-8") as f:
- c_text = f.read()
- c_text, _ = _inject_or_diag(
- c_text, "IMPORT", emitted.imports_cpp,
- host_path=source_path, host_kind="subclass source",
- block_label="per-subtype import block",
- diag_source="subclass_inject",
- )
- c_text, _ = _inject_or_diag(
- c_text, "EXPORT", emitted.exports_cpp,
- host_path=source_path, host_kind="subclass source",
- block_label="per-subtype export block",
- diag_source="subclass_inject",
- )
- writes.append(FileWrite(path=source_path, content=c_text))
- else:
- _diag_add(
- f"[diagnostic] subclass source '{source_path}' does not "
- f"exist alongside its header; import + export blocks "
- f"could not be injected.",
- source="subclass_inject",
- )
- else:
- # Brand-new file OR ``fully_emitted: true`` → write the whole
- # file from the template.
- #
- # Safety check on the ``fully_emitted`` overwrite path: if the
- # existing file carries non-template content (extra includes
- # beyond the template, hand-written methods, ctor extras not
- # covered by ``extra_constructor``), the rewrite would silently
- # destroy it. The audit-helper script
- # (Scripts/codegen/_audit_banner_candidates.py) is the
- # expected pre-flip gate; this is a defence-in-depth diagnostic
- # for cases where someone flips ``fully_emitted: true`` without
- # running the helper first.
- if fully_emitted and os.path.exists(source_path):
- _audit_banner_safety(source_path, subtype)
-
- include_path = _resolve_include_path(public_root, header_path)
- ctor_body = _subclass_constructor_body(category, subtype, type_enum)
-
- header_text = SUBCLASS_HEADER_TEMPLATE.format(
- Copyright=COPYRIGHT_BLOCK,
- BaseInclude=base_header_relpath,
- ClassName=class_name,
- ClassFileStem=class_file_stem,
- ElementName=sub_key,
- BaseClassName=base_class,
- TypeEnumValue=subtype.get("enum_value", "Unknown"),
- Properties=emitted.properties_h or " // (no type-specific schema attrs)\n",
- MjsStruct=mjs_struct,
- )
-
- source_text = SUBCLASS_SOURCE_TEMPLATE.format(
- Copyright=COPYRIGHT_BLOCK,
- IncludePath=include_path,
- ClassName=class_name,
- ConstructorBody=ctor_body,
- Imports=emitted.imports_cpp or " // (no type-specific schema imports)\n",
- Exports=emitted.exports_cpp or " // (no type-specific schema exports)\n",
- MjsStruct=mjs_struct,
- )
-
- writes.append(FileWrite(path=header_path, content=header_text))
- writes.append(FileWrite(path=source_path, content=source_text))
-
- return writes
-
-
-# ---------------------------------------------------------------------------
-# Pipeline: base-class injection (no_subclasses + multi_uclass base)
-# ---------------------------------------------------------------------------
-
-def emit_base_class_injection(
- category: str,
- cat_rules: Dict[str, Any],
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- public_root: str,
- private_root: str,
- mjspec: Dict[str, Any] | None = None,
-) -> List[FileWrite]:
- """Migrate (if needed) + inject codegen output between boundary
- tags in existing base class .h / .cpp files."""
- writes: List[FileWrite] = []
- base_class = cat_rules["base_class_name"]
- base_header_relpath = cat_rules["base_class_header"]
- mjs_fields = _mjs_fields_for(cat_rules, mjspec)
- mjs_array_caps = _mjs_array_caps_for(cat_rules, mjspec)
- common_attrs = schema_attrs(schema, cat_rules["schema_common_block"])
- # Extras: attrs that URLab puts on the base class even though MJCF
- # schema lists them per-subtype (e.g. gainprm/biasprm/dynprm).
- common_attrs = list(common_attrs) + cat_rules.get("schema_common_extra_attrs", [])
-
- emitted = emit_schema_for_attrs(
- common_attrs, rules, element_name=category, category_label=base_class.removeprefix("UMj"),
- mjs_fields=mjs_fields,
- mjs_array_caps=mjs_array_caps,
- )
-
- header_path = os.path.join(public_root, base_header_relpath)
- rel = os.path.relpath(header_path, public_root)
- source_path = os.path.join(private_root, rel.replace(".h", ".cpp"))
-
- if os.path.exists(header_path):
- with open(header_path, "r", encoding="utf-8") as f:
- h_text = f.read()
- new_h, ok = _inject_or_diag(
- h_text, "PROPERTIES", emitted.properties_h,
- host_path=header_path, host_kind="base header",
- block_label=f"category '{category}' UPROPERTY block",
- diag_source="base_inject",
- )
- if ok:
- writes.append(FileWrite(path=header_path, content=new_h))
- else:
- _diag_add(
- f"[diagnostic] category '{category}' has a rule but base header "
- f"'{header_path}' does not exist; codegen emitted no writes for "
- f"this category.",
- source="base_inject",
- )
-
- if os.path.exists(source_path):
- with open(source_path, "r", encoding="utf-8") as f:
- c_text = f.read()
- c_text, ok_i = _inject_or_diag(
- c_text, "IMPORT", emitted.imports_cpp,
- host_path=source_path, host_kind="base source",
- block_label=f"category '{category}' import block",
- diag_source="base_inject",
- )
- # ``xml_passthrough_emission`` routes per-attr export through the
- # XML_PASSTHROUGH block, NOT the EXPORT block — the mjs-side
- # ``Element->field = ...`` writes don't apply (flexcomp).
- # ``disable_mjs_export_emission`` covers categories that have no
- # corresponding mjs struct so the export block can't compile even
- # if injected (inertial — writes through ParentBody->ipos/iquat
- # in a hand-rolled RegisterToSpec). Both flags suppress EXPORT
- # injection AND its missing-marker diagnostic.
- skip_export = (
- cat_rules.get("xml_passthrough_emission")
- or cat_rules.get("disable_mjs_export_emission")
- )
- ok_e = False
- if not skip_export:
- c_text, ok_e = _inject_or_diag(
- c_text, "EXPORT", emitted.exports_cpp,
- host_path=source_path, host_kind="base source",
- block_label=f"category '{category}' export block",
- diag_source="base_inject",
- )
- ok_x = False
- if cat_rules.get("xml_passthrough_emission"):
- xml_body = emit_xml_passthrough_body(common_attrs, rules, element_name=category)
- c_text, ok_x = _inject_or_diag(
- c_text, "XML_PASSTHROUGH", xml_body,
- host_path=source_path, host_kind="base source",
- block_label=f"category '{category}' xml_passthrough block",
- diag_source="base_inject",
- )
- if ok_i or ok_e or ok_x:
- writes.append(FileWrite(path=source_path, content=c_text))
- else:
- _diag_add(
- f"[diagnostic] category '{category}' base source '{source_path}' "
- f"does not exist; import + export blocks could not be injected.",
- source="base_inject",
- )
-
- return writes
-
-
-# ---------------------------------------------------------------------------
-# Pipeline: multi-UCLASS base (site / tendon / equality)
-# ---------------------------------------------------------------------------
-
-def emit_multi_uclass(
- category: str,
- cat_rules: Dict[str, Any],
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- public_root: str,
- private_root: str,
- mjspec: Dict[str, Any] | None = None,
-) -> List[FileWrite]:
- """For categories whose layout is multi_uclass, emit:
- - the base class block (between PROPERTIES / IMPORT / EXPORT tags)
- - per-subtype UCLASS skeletons appended to the base file (first-run only)
- - per-subtype blocks (between SUBCLASS__PROPERTIES /
- IMPORT / EXPORT tags)"""
- # Run the base injection first (handles migration + properties).
- writes = emit_base_class_injection(category, cat_rules, schema, rules, public_root, private_root, mjspec=mjspec)
-
- base_header_relpath = cat_rules["base_class_header"]
- header_path = os.path.join(public_root, base_header_relpath)
- rel = os.path.relpath(header_path, public_root)
- source_path = os.path.join(private_root, rel.replace(".h", ".cpp"))
-
- if not os.path.exists(header_path):
- return writes
-
- # Re-load to capture the post-base-injection state.
- by_path = {w.path: w.content for w in writes}
- h_text = by_path.get(header_path)
- if h_text is None:
- with open(header_path, "r", encoding="utf-8") as f:
- h_text = f.read()
- c_text = by_path.get(source_path)
- if c_text is None and os.path.exists(source_path):
- with open(source_path, "r", encoding="utf-8") as f:
- c_text = f.read()
- elif c_text is None:
- c_text = ""
-
- base_class = cat_rules["base_class_name"]
- mjs_fields = _mjs_fields_for(cat_rules, mjspec)
- mjs_array_caps = _mjs_array_caps_for(cat_rules, mjspec)
- common_attrs = set(schema_attrs(schema, cat_rules["schema_common_block"]))
- common_attrs |= set(cat_rules.get("schema_common_extra_attrs", []))
-
- for subtype in cat_rules.get("subtypes", []):
- sub_key = subtype["key"]
- per_type_attrs = schema_subtype_attrs(schema, category, sub_key)
- attrs = [a for a in per_type_attrs if a not in common_attrs]
- emitted = emit_schema_for_attrs(
- attrs, rules, element_name=category,
- category_label=base_class.removeprefix("UMj"),
- apply_canonicalizations=False, # base owns the canon block
- mjs_fields=mjs_fields,
- mjs_array_caps=mjs_array_caps,
- )
- type_tag = subtype["enum_value"]
- # Diagnose missing per-subtype marker pairs ONLY when there's a
- # non-empty body to inject. Subtypes whose schema attrs are entirely
- # in the common set (or whose mjs export is handled elsewhere) emit
- # nothing per-subtype; not pre-prepping a marker pair for those is
- # legitimate, so suppress the diagnostic.
- h_text, _ = _inject_or_diag(
- h_text, f"SUBCLASS_{type_tag}_PROPERTIES", emitted.properties_h,
- host_path=header_path, host_kind="multi_uclass base header",
- block_label=f"subtype '{sub_key}' UPROPERTY block",
- diag_source="multi_uclass_inject",
- )
- if c_text:
- c_text, _ = _inject_or_diag(
- c_text, f"SUBCLASS_{type_tag}_IMPORT", emitted.imports_cpp,
- host_path=source_path, host_kind="multi_uclass base source",
- block_label=f"subtype '{sub_key}' import block",
- diag_source="multi_uclass_inject",
- )
- c_text, _ = _inject_or_diag(
- c_text, f"SUBCLASS_{type_tag}_EXPORT", emitted.exports_cpp,
- host_path=source_path, host_kind="multi_uclass base source",
- block_label=f"subtype '{sub_key}' export block",
- diag_source="multi_uclass_inject",
- )
-
- # Rewrite the merged writes (drop stale base writes; replace with merged).
- writes = [w for w in writes if w.path != header_path and w.path != source_path]
- writes.append(FileWrite(path=header_path, content=h_text))
- if os.path.exists(source_path) or c_text:
- writes.append(FileWrite(path=source_path, content=c_text))
- return writes
-
-
-# ---------------------------------------------------------------------------
-# Pipeline: view structs
-# ---------------------------------------------------------------------------
-
-_VIEW_FIELD_TYPE_MAP = {
- "int": "int*", "mjtByte": "mjtByte*", "mjtBool": "mjtBool*",
- "mjtNum": "mjtNum*", "float": "float*", "char": "char*",
-}
-
-
-def _view_field_type_cpp(c_type: str, field_name: str = "") -> str:
- mapped = _VIEW_FIELD_TYPE_MAP.get(c_type)
- if mapped is None:
- # Don't silently default a new MuJoCo scalar type to mjtNum* — that
- # ships a wrong (often 8-byte-over-1-byte) pointer with no warning.
- # A bump that introduces a new type should surface here loudly.
- _diag_add(
- f"[diagnostic] view field '{field_name or '?'}' has unmapped C "
- f"type '{c_type}'; defaulting to 'mjtNum*'. A MuJoCo bump likely "
- f"introduced a new scalar type; add it to _VIEW_FIELD_TYPE_MAP.",
- source="view_field_type",
- )
- return "mjtNum*"
- return mapped
-
-
-_MJ_M_MACRO_RE = re.compile(r"MJ_M\(\s*(\w+)\s*\)")
-# Any MJ_*( ... ) macro that survives _expand_stride is an unhandled
-# stride shape — emit invalid C++ in MjBind.h. The guard fires a
-# diagnostic so a MuJoCo bump that introduces new stride macros (e.g.
-# MJ_D(...) for mjData, MJ_V(...) for variable-size views) surfaces
-# loudly rather than landing as a compile error far downstream.
-_RESIDUAL_MJ_MACRO_RE = re.compile(r"\bMJ_[A-Z]\(\s*\w+\s*\)")
-
-
-def _expand_stride(stride: str) -> str:
- """Convert mjxmacro stride expressions to plain C++ expressions usable
- in MjBind.h. ``MJ_M(nuser_jnt)`` -> ``m->nuser_jnt``.
-
- Fires a diagnostic if any ``MJ_*(...)`` macro survives the
- substitution — that's an unhandled stride shape we'd otherwise
- silently emit into MjBind.h verbatim."""
- expanded = _MJ_M_MACRO_RE.sub(r"m->\1", stride)
- residual = _RESIDUAL_MJ_MACRO_RE.findall(expanded)
- if residual:
- _diag_add(
- f"[diagnostic] _expand_stride saw stride '{stride}' with "
- f"unhandled MuJoCo macro(s) {residual}. Result '{expanded}' "
- f"will land in MjBind.h verbatim and likely fail to compile. "
- f"Teach _expand_stride about the new macro shape.",
- source="expand_stride",
- )
- return expanded
-
-
-def emit_view_structs(rules: Dict[str, Any], mjxmacro: Dict[str, Any]) -> Dict[str, Tuple[str, str]]:
- """For each view in `rules['views']`, return (fields_block, bind_block)."""
- out: Dict[str, Tuple[str, str]] = {}
- views: Dict[str, Any] = rules.get("views", {})
-
- for view_name, view_def in views.items():
- renames: Dict[str, str] = view_def.get("field_renames", {})
- block_index_var: Dict[str, str] = view_def.get("block_index_var", {})
- derived_index_vars: Dict[str, str] = view_def.get("derived_index_vars", {})
- include_blocks: List[str] = view_def.get("include_blocks", [])
- data_fields: Dict[str, Dict[str, str]] = view_def.get("data_fields", {})
-
- # Collect the set of pointer-field names this view defines, so we
- # don't accidentally emit a derived local variable that shadows
- # one of them.
- pointer_field_names: set = set()
- for block in include_blocks:
- for entry in mjxmacro["mjmodel_pointers"].get(block, []):
- pointer_field_names.add(renames.get(entry["name"], entry["name"]))
- for data_name in data_fields:
- pointer_field_names.add(renames.get(data_name, data_name))
-
- fields_lines: List[str] = []
- bind_lines: List[str] = []
-
- # Derived index vars: emit at top of the bind block, but suppress
- # ones whose name collides with a pointer field. (Caller should
- # pick non-colliding names in the rules.)
- for var, expr in derived_index_vars.items():
- if var in pointer_field_names:
- continue
- bind_lines.append(f" const int {var} = {expr};")
-
- # mjModel pointer fields.
- #
- # Stride-1 ``int`` entries (e.g. ``geom_type``, ``body_mocapid``,
- # ``actuator_trntype``) are emitted as DEREFERENCED scalars rather
- # than pointers — there's exactly one int per element, and the
- # consumer always wants the value, not the pointer. Matches the
- # ergonomic shape the hand-written MjBind.h had before activation.
- # Mat-vec entries (``geom_size`` stride 3, ``jnt_solref`` stride
- # mjNREF, etc.) stay as pointers since consumers index into them.
- for block in include_blocks:
- entries = mjxmacro["mjmodel_pointers"].get(block, [])
- index_var = block_index_var.get(block, "id")
- for entry in entries:
- name = entry["name"]
- view_field = renames.get(name, name)
- stride = _expand_stride(entry["stride"])
- is_scalar_int = (entry["type"] == "int" and entry["stride"] == "1")
- if is_scalar_int:
- fields_lines.append(f" int {view_field};")
- bind_lines.append(
- f" {view_field} = m->{name}[{index_var}];"
- )
- else:
- cpp_type = _view_field_type_cpp(entry["type"], name)
- fields_lines.append(f" {cpp_type} {view_field};")
- bind_lines.append(
- f" {view_field} = m->{name} + {index_var} * {stride};"
- )
-
- # mjData fields (explicitly listed per view).
- #
- # Each spec dict has ``index_var`` + ``stride``. Some fields don't
- # fit the simple ``d->src + index_var * stride`` formula — e.g.
- # SensorView::sensordata, where the right slice depends on a
- # bounds-checked sensor_adr lookup. For those, set ``bind_override``
- # in the rule to a C++ statement that assigns the field; the field
- # decl is still emitted at the standard cpp_type. This kills the
- # fragile "codegen emits wrong code, hand-written override after
- # the marker" pattern.
- for data_name, spec in data_fields.items():
- # ``_note_*`` keys document the data_fields entries; skip them.
- if data_name.startswith("_note_"):
- continue
- cpp_type = "mjtNum*"
- view_field = renames.get(data_name, data_name)
- fields_lines.append(f" {cpp_type} {view_field};")
- bind_override = spec.get("bind_override")
- if bind_override:
- bind_lines.append(f" {bind_override}")
- else:
- index_var = spec.get("index_var", "id")
- stride = _expand_stride(spec.get("stride", "1"))
- bind_lines.append(f" {view_field} = d->{data_name} + {index_var} * {stride};")
-
- fields_block = "\n".join(fields_lines) + ("\n" if fields_lines else "")
- bind_block = "\n".join(bind_lines) + ("\n" if bind_lines else "")
- out[view_name] = (fields_block, bind_block)
- return out
-
-
-def emit_bind_h_injection(
- rules: Dict[str, Any], mjxmacro: Dict[str, Any], bind_h_path: str
-) -> Optional[FileWrite]:
- """Read MjBind.h, fill each view struct's
- ``// --- CODEGEN_VIEW__FIELDS_START/END ---`` and
- ``// --- CODEGEN_VIEW__BIND_START/END ---`` tag pairs with
- the codegen-emitted content. MjBind.h must already have the tag
- pairs pre-prepped (hand-edited)."""
- if not os.path.exists(bind_h_path):
- return None
- with open(bind_h_path, "r", encoding="utf-8") as f:
- text = f.read()
-
- views = emit_view_structs(rules, mjxmacro)
- new_text = text
- for view_name, (fields_block, bind_block) in views.items():
- new_text, _ = _inject_or_diag(
- new_text, f"VIEW_{view_name}_FIELDS", fields_block,
- host_path=bind_h_path, host_kind="MjBind.h",
- block_label=f"view struct '{view_name}' fields block (struct will ship empty)",
- diag_source="bind_inject",
- )
- new_text, _ = _inject_or_diag(
- new_text, f"VIEW_{view_name}_BIND", bind_block,
- host_path=bind_h_path, host_kind="MjBind.h",
- block_label=f"view '{view_name}' Bind() body",
- diag_source="bind_inject",
- )
-
- with open(bind_h_path, "r", encoding="utf-8") as f:
- original = f.read()
- if new_text == original:
- return None
- return FileWrite(path=bind_h_path, content=new_text)
-
-
-# ---------------------------------------------------------------------------
-# Pipeline: schema-for-tests header
-# ---------------------------------------------------------------------------
-
-def kept_props_for_category(
- cat: str, cat_rules: Dict[str, Any],
- schema: Dict[str, Any], rules: Dict[str, Any],
-) -> List[str]:
- """Return the ordered prop names the codegen will emit for one
- category. Order matches the canonical emission order: canon-
- owned properties first, then per-attr in schema order. xml_enum
- attrs lower to their ``ue_property`` because that's the hand-
- declared UPROPERTY the completeness test resolves against."""
- elem_rules = rules.get("element_rules", {}).get(cat, {})
- elem_excl = set(elem_rules.get("exclude_attrs", []))
- elem_canons: List[str] = elem_rules.get("applies_canonicalizations", [])
- canonicalizations = rules.get("canonicalizations", {})
- canon_absorbed: set = compute_canon_absorbed(elem_canons, canonicalizations)
- global_excl = set(rules.get("global_exclusions", []))
- renames: Dict[str, str] = rules.get("property_renames", {})
- xml_enum_attrs = elem_rules.get("xml_enum_attrs", {})
-
- attrs = list(schema_attrs(schema, cat_rules["schema_common_block"]))
- # ``schema_common_extra_attrs`` covers UPROPERTYs schema attrs miss
- # (frame's pos/quat/childclass come via this path because frame.attrs
- # is empty in the snapshot).
- for a in cat_rules.get("schema_common_extra_attrs", []):
- if a not in attrs:
- attrs.append(a)
-
- kept: List[str] = []
- for c in elem_canons:
- cd = canonicalizations.get(c)
- if cd and cd.get("emits_property"):
- kept.append(cd["emits_property"]["name"])
- for a in iter_category_attrs(attrs, global_excl=global_excl,
- elem_excl=elem_excl,
- canon_absorbed=canon_absorbed):
- if a in xml_enum_attrs:
- kept.append(xml_enum_attrs[a]["ue_property"])
- continue
- kept.append(renames.get(a, a))
- return kept
-
-
-def emit_schema_for_tests(schema: Dict[str, Any], rules: Dict[str, Any]) -> FileWrite:
- """Generate a C++ header that exposes schema attribute lists per
- category to URLab automation tests. Every category emits a
- ``CatProps()`` accessor returning a static ``TArray`` of
- the codegen-owned UPROPERTY names."""
- lines: List[str] = [
- COPYRIGHT_BLOCK,
- "#pragma once",
- "",
- "#include \"CoreMinimal.h\"",
- "",
- "// Autogenerated schema mirror for URLab.Codegen.* tests.",
- "// Lists the canonical UPROPERTY name produced by codegen for every",
- "// schema attribute on every category.",
- "",
- "namespace URLabCodegenSchemaForTests",
- "{",
- ]
-
- for cat, cat_rules in rules.get("categories", {}).items():
- kept_props = kept_props_for_category(cat, cat_rules, schema, rules)
- ident = cat.replace(".", "_")
- joined = ", ".join(f'TEXT("{p}")' for p in kept_props)
- lines.append(f" inline const TArray& {ident.title()}Props()")
- lines.append(" {")
- lines.append(f" static const TArray P{{{joined}}};")
- lines.append(" return P;")
- lines.append(" }")
- lines.append("")
-
- lines.append("}")
- lines.append("")
- text = "\n".join(lines)
-
- out_path = os.path.join(DEFAULT_TESTS_DIR, "MjSchemaForTests.h")
- return FileWrite(path=out_path, content=text)
-
-
-# ---------------------------------------------------------------------------
-# Top-level orchestration
-# ---------------------------------------------------------------------------
-
-@dataclass
-class PhaseContext:
- """All state a codegen emission phase needs. Phases mutate
- ``writes`` and surface diagnostics through ``_diag_add``."""
- schema: Dict[str, Any]
- rules: Dict[str, Any]
- mjxmacro: Dict[str, Any]
- mjspec: Optional[Dict[str, Any]]
- public_root: str
- private_root: str
- bind_h_path: str
- writes: List["FileWrite"]
-
-
-@dataclass
-class EmissionPhase:
- """One step in the codegen pipeline. Phases are run in order; each
- either appends to ``ctx.writes`` (emit phases) or has side effects
- only (the diagnostics phase). The registry below makes adding a
- phase a one-line insert rather than another `writes.extend(...)`
- block in ``collect_all_writes``.
- """
- name: str
- fn: Callable[["PhaseContext"], None]
-
-
-# ---------------------------------------------------------------------------
-# Synthetic categories: whole-file banner-mode emission
-# ---------------------------------------------------------------------------
-#
-# "Synthetic" because the USTRUCT doesn't correspond to one entry in the
-# MJCF schema (which describes XML element shapes). Instead it mirrors a
-# C struct laid out in mjxmacro.h (MJOPTION_FIELDS, MJSTATISTIC_FIELDS,
-# MJVISUAL_*_FIELDS) — the runtime-only state URLab exposes as USTRUCT
-# blueprint properties.
-#
-# Files are emitted in BANNER mode (no // --- CODEGEN_*_START/END ---
-# tags). The whole .h / .cpp pair is codegen-owned; hand-edits get
-# clobbered on next regen.
-#
-# Rule shape (under top-level ``synthetic_categories`` in codegen_rules.json):
-# "MjStatistic": {
-# "ue_struct_name": "FMjStatistic",
-# "mjxmacro_block": "MJSTATISTIC_FIELDS",
-# "public_header": "MuJoCo/Generated/MjStatistic.h",
-# "private_source": "MuJoCo/Generated/MjStatistic.cpp",
-# "category_label": "MuJoCo|Statistic",
-# "exclude_fields": [],
-# "per_field_meta": { "extent": "ClampMin=0.0" },
-# "urlab_extra_fields": [], // empty for pure mirrors
-# }
-
-
-_CPP_TO_UE_TYPE = {
- "int": "int32",
- "float": "float",
- "mjtNum": "double",
- "mjtByte": "uint8",
- "mjtBool": "bool",
-}
-
-
-def _ue_field_name(c_name: str) -> str:
- """snake_case mjxmacro name -> PascalCase UE field. Preserves URLab's
- naming convention from the hand-written MjSimOptions.h (ls_iterations
- -> LsIterations, ccd_iterations -> CCD_Iterations is a deliberate
- one-off — synthetic_categories rules can override via field_renames)."""
- parts = c_name.split("_")
- return "".join(p[:1].upper() + p[1:] for p in parts if p)
-
-
-# `_VEC3_CONVERT_FMT` lives in `_codegen_core`.
-
-
-def _emit_synth_mirror_properties(
- fields: List[Dict[str, Any]],
- def_: Dict[str, Any],
- category_label: str,
-) -> Tuple[List[str], List[Dict[str, Any]]]:
- """Emit the UPROPERTY block for the mjxmacro mirror fields and
- return the parallel ``fields_meta`` list. ``fields_meta`` carries
- the per-field shape (c_name, ue_name, ue_type, is_vec, count) the
- out-of-line ApplyTo emitters need."""
- exclude = set(def_.get("exclude_fields", []))
- field_renames: Dict[str, str] = def_.get("field_renames", {})
- field_types: Dict[str, str] = def_.get("field_types", {})
- all_fields_type: Optional[str] = def_.get("all_fields_type")
- field_defaults: Dict[str, str] = def_.get("field_defaults", {})
-
- prop_lines: List[str] = []
- fields_meta: List[Dict[str, Any]] = []
- for f in fields:
- c_name = f["name"]
- if c_name in exclude:
- continue
- ue_name = field_renames.get(c_name, _ue_field_name(c_name))
- c_type = f["type"]
- is_vec = f.get("is_vec", False)
- # Accept both str ("3") and int (3) — the mjxmacro snapshot
- # currently emits strings, but a future shape bump that yields
- # ints must NOT silently collapse vec3 fields to ``TArray``.
- raw_count = f.get("count", 1)
- if isinstance(raw_count, int):
- count = raw_count
- elif isinstance(raw_count, str) and raw_count.isdigit():
- count = int(raw_count)
- else:
- count = 1
-
- if c_name in field_types:
- ue_type = field_types[c_name]
- elif all_fields_type:
- ue_type = all_fields_type
- elif is_vec and count == 3:
- ue_type = "FVector"
- elif is_vec and count == 4:
- ue_type = "FLinearColor"
- elif is_vec:
- ue_type = "TArray"
- else:
- ue_type = _CPP_TO_UE_TYPE.get(c_type, "float")
-
- default_override = field_defaults.get(ue_name) or field_defaults.get(c_name)
-
- cat = f"MuJoCo|{category_label}"
- toggle = override_toggle_name(ue_name)
- default = default_override if default_override else _attr_default_value(ue_type)
- prop_lines.append(
- f' UPROPERTY(EditAnywhere, Category = "{cat}", meta=(InlineEditConditionToggle))\n'
- f' bool {toggle} = false;\n\n'
- f' UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "{cat}", meta=(EditCondition="{toggle}"))\n'
- f' {ue_type} {ue_name} = {default};\n\n'
- )
- fields_meta.append({
- "c_name": c_name,
- "ue_name": ue_name,
- "ue_type": ue_type,
- "is_vec": is_vec,
- "count": count,
- })
- return prop_lines, fields_meta
-
-
-def _emit_synth_extras_properties(
- urlab_extras: List[Dict[str, Any]],
- category_label: str,
-) -> Tuple[List[str], List[Dict[str, Any]]]:
- """Emit UPROPERTY blocks for the URLab-extra fields (non-mjxmacro
- additions like ``MemoryMB`` on MjOption). Returns prop_lines +
- extras_meta. Each extra carries optional ``has_override``,
- ``edit_condition``, ``meta`` knobs that the mirror loop above
- doesn't surface."""
- prop_lines: List[str] = []
- extras_meta: List[Dict[str, Any]] = []
- for extra in urlab_extras:
- ue_name = extra["name"]
- ue_type = extra["type"]
- default = extra.get("default", _attr_default_value(ue_type))
- sub_category = extra.get("sub_category")
- has_override = extra.get("has_override", True)
- edit_condition = extra.get("edit_condition")
- meta_extra = extra.get("meta")
- cat = f"MuJoCo|{category_label}"
- if sub_category:
- cat = f"{cat}|{sub_category}"
- if has_override:
- toggle = override_toggle_name(ue_name)
- meta_inner = f'EditCondition="{toggle}"'
- if meta_extra:
- meta_inner = f'{meta_inner}, {meta_extra}'
- prop_lines.append(
- f' UPROPERTY(EditAnywhere, Category = "{cat}", meta=(InlineEditConditionToggle))\n'
- f' bool {toggle} = false;\n\n'
- f' UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "{cat}", meta=({meta_inner}))\n'
- f' {ue_type} {ue_name} = {default};\n\n'
- )
- else:
- meta_parts = []
- if edit_condition:
- meta_parts.append(f'EditCondition="{edit_condition}"')
- if meta_extra:
- meta_parts.append(meta_extra)
- meta_str = ", ".join(meta_parts)
- meta_clause = f', meta=({meta_str})' if meta_str else ""
- prop_lines.append(
- f' UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "{cat}"{meta_clause})\n'
- f' {ue_type} {ue_name} = {default};\n\n'
- )
- extras_meta.append({"ue_name": ue_name, "type": ue_type,
- "has_override": has_override})
- return prop_lines, extras_meta
-
-
-def _emit_synth_inline_apply_template(
- fields_meta: List[Dict[str, Any]],
- field_skip_apply: Set[str],
-) -> str:
- """Emit the templated inline ``ApplyTo`` body for pure-mirror
- synthetic structs (mjStatistic etc.). The shape mirrors the
- out-of-line ApplyToSpec but lives in the header so it's reusable
- against any compatible C struct (mjStatistic, mjVisualRgba)."""
- apply_lines: List[str] = []
- for fm in fields_meta:
- c_name = fm["c_name"]
- ue_name = fm["ue_name"]
- if c_name in field_skip_apply:
- continue
- if fm["ue_type"] == "FLinearColor":
- apply_lines.append(
- f" Dst.{c_name}[0] = static_cast({ue_name}.R);\n"
- f" Dst.{c_name}[1] = static_cast({ue_name}.G);\n"
- f" Dst.{c_name}[2] = static_cast({ue_name}.B);\n"
- f" Dst.{c_name}[3] = static_cast({ue_name}.A);"
- )
- elif fm["ue_type"] == "FVector":
- apply_lines.append(
- f" Dst.{c_name}[0] = static_cast({ue_name}.X);\n"
- f" Dst.{c_name}[1] = static_cast({ue_name}.Y);\n"
- f" Dst.{c_name}[2] = static_cast({ue_name}.Z);"
- )
- elif fm["is_vec"]:
- apply_lines.append(
- f" for (int32 I = 0; I < {ue_name}.Num() && I < {fm['count']}; ++I)\n"
- f" Dst.{c_name}[I] = static_cast({ue_name}[I]);"
- )
- else:
- apply_lines.append(f" Dst.{c_name} = static_cast({ue_name});")
- return (
- f" /** @brief Mirror every field into a runtime C struct. */\n"
- f" template \n"
- f" void ApplyTo(TDst& Dst) const\n"
- f" {{\n"
- f"{chr(10).join(apply_lines)}\n"
- f" }}\n"
- )
-
-
-def _emit_synthetic_struct_files(
- cat_name: str, def_: Dict[str, Any], mjxmacro: Dict[str, Any],
- public_root: str, private_root: str,
-) -> List["FileWrite"]:
- """Emit the .h + .cpp pair for one synthetic_categories entry.
-
- Currently supports the mjxmacro_block source (X-macro field list).
- """
- block_name = def_.get("mjxmacro_block")
- if not block_name:
- return []
- fields = mjxmacro.get("struct_fields", {}).get(block_name, [])
- if not fields:
- _diag_add(
- f"[diagnostic] synthetic_categories['{cat_name}'] references "
- f"mjxmacro_block='{block_name}' which is empty or missing in "
- f"the snapshot. Skipping emission.",
- source="synthetic_categories",
- )
- return []
-
- ue_struct = def_["ue_struct_name"]
- category_label = def_.get("category_label", "MuJoCo")
- field_apply_mode: Dict[str, str] = def_.get("field_apply_to_spec_mode", {})
- field_skip_apply: set = set(def_.get("field_skip_apply", []))
- public_relpath = def_["public_header"]
- private_relpath = def_.get("private_source")
- extra_includes: List[str] = def_.get("include_directives", [])
- urlab_extras: List[Dict[str, Any]] = def_.get("urlab_extra_fields", [])
- apply_extras_function: Optional[str] = def_.get("apply_extras_function")
- emit_apply_methods: bool = bool(def_.get("emit_apply_methods", False))
-
- mirror_lines, fields_meta = _emit_synth_mirror_properties(
- fields, def_, category_label,
- )
- extras_lines, _extras_meta = _emit_synth_extras_properties(
- urlab_extras, category_label,
- )
- properties_block = "".join(mirror_lines + extras_lines)
- c_struct = def_.get("c_struct_type", block_name.lower().replace("_fields", ""))
-
- # ---------- header content ----------
- extra_includes_block = "".join(f'#include "{inc}"\n' for inc in extra_includes)
- header_basename = os.path.basename(public_relpath).replace('.h', '')
- public_path = os.path.join(public_root, public_relpath.replace("/", os.sep))
-
- # Method decls in the header. If emit_apply_methods=True, declare
- # ApplyToSpec / ApplyOverridesToModel as forward decls (definitions
- # land in the .cpp). Otherwise emit an inline-templated ApplyTo for
- # pure-mirror structs (mjStatistic etc.).
- if emit_apply_methods:
- method_decls = (
- f" /** @brief Writes every mirror field plus URLab extras into the "
- f"runtime spec. Used by articulations to set child spec options. */\n"
- f" void ApplyToSpec(mjSpec* Spec) const;\n\n"
- f" /** @brief Applies only override-toggled mirror fields to a "
- f"compiled model (post-compile override path). */\n"
- f" void ApplyOverridesToModel(mjModel* Model) const;\n"
- )
- else:
- method_decls = _emit_synth_inline_apply_template(
- fields_meta, field_skip_apply,
- )
-
- # Forward-decl the extras function so the codegen-emitted .cpp can
- # call it without #including a hand-written header. Operator writes
- # the body in *Extras.cpp.
- extras_forward_decl = ""
- if apply_extras_function and urlab_extras:
- extras_forward_decl = (
- f"// Forward-decl: hand-written body lives in "
- f"{os.path.basename(public_relpath).replace('.h', '')}Extras.cpp.\n"
- f"struct {ue_struct};\n"
- f"void {apply_extras_function}("
- f"mjOption* Opt, const {ue_struct}& Self, "
- f"mjSpec* Spec, mjModel* Model = nullptr);\n\n"
- )
-
- header_content = (
- f"{COPYRIGHT_BLOCK}\n"
- f"#pragma once\n\n"
- f"#include \"CoreMinimal.h\"\n"
- f"{extra_includes_block}"
- f"#include \"{header_basename}.generated.h\"\n\n"
- f"{extras_forward_decl}"
- f"// Mirror of MuJoCo's ``{c_struct}`` ({block_name}). Codegen-owned —\n"
- f"// hand-edits get clobbered on next regen. Add fields by editing\n"
- f"// codegen_rules.json[synthetic_categories.{cat_name}].\n"
- f"USTRUCT(BlueprintType)\n"
- f"struct URLAB_API {ue_struct}\n"
- f"{{\n"
- f" GENERATED_BODY()\n\n"
- f"{properties_block}"
- f"{method_decls}"
- f"}};\n"
- )
-
- writes: List[FileWrite] = [FileWrite(path=public_path, content=header_content)]
-
- if emit_apply_methods and private_relpath:
- cpp_content = _emit_synth_apply_methods_cpp(
- ue_struct=ue_struct,
- fields_meta=fields_meta,
- field_apply_mode=field_apply_mode,
- field_skip_apply=field_skip_apply,
- apply_extras_function=apply_extras_function,
- urlab_extras=urlab_extras,
- public_relpath=public_relpath,
- header_basename=header_basename,
- )
- private_path = os.path.join(private_root, private_relpath.replace("/", os.sep))
- writes.append(FileWrite(path=private_path, content=cpp_content))
-
- return writes
-
-
-def _emit_synth_apply_methods_cpp(
- *,
- ue_struct: str,
- fields_meta: List[Dict[str, Any]],
- field_apply_mode: Dict[str, str],
- field_skip_apply: Set[str],
- apply_extras_function: Optional[str],
- urlab_extras: List[Dict[str, Any]],
- public_relpath: str,
- header_basename: str,
-) -> str:
- """Emit the out-of-line ``ApplyToSpec`` and ``ApplyOverridesToModel``
- bodies for a synthetic struct whose mirror writes go through mjSpec
- + mjModel (mjOption is the canonical case).
-
- Both methods gate every field write with ``bOverride_X``. The earlier
- ``unconditional`` SPEC default silently clobbered MJCF-XML defaults
- with whatever the UE struct happened to carry, even for fields the
- user never authored. ``field_apply_mode`` now selects only the
- per-FVector conversion flavour (``vec3_cm`` / ``vec3_y_flip`` /
- ``pos``); the toggle guard is applied uniformly.
- """
- apply_to_spec_lines: List[str] = [" if (!Spec) return;"]
- apply_to_model_lines: List[str] = [" if (!Model) return;"]
- for fm in fields_meta:
- c_name = fm["c_name"]
- ue_name = fm["ue_name"]
- ue_type = fm["ue_type"]
- if c_name in field_skip_apply:
- continue
- toggle = override_toggle_name(ue_name)
- spec_mode = field_apply_mode.get(c_name, "")
- if ue_type == "FVector":
- # Strip a legacy "guarded_" prefix; the guard is now uniform.
- conv = spec_mode.replace("guarded_", "") if spec_mode.startswith("guarded_") else spec_mode
- if conv not in _VEC3_CONVERT_FMT:
- conv = "vec3_y_flip"
- stmt_spec_inner = _VEC3_CONVERT_FMT[conv].format(
- c=f"Spec->option.{c_name}", ue=ue_name,
- )
- stmt_model_inner = _VEC3_CONVERT_FMT[conv].format(
- c=f"Model->opt.{c_name}", ue=ue_name,
- )
- elif ue_type.startswith("EMj"):
- stmt_spec_inner = f"Spec->option.{c_name} = static_cast({ue_name});"
- stmt_model_inner = f"Model->opt.{c_name} = static_cast({ue_name});"
- else:
- stmt_spec_inner = f"Spec->option.{c_name} = {ue_name};"
- stmt_model_inner = f"Model->opt.{c_name} = {ue_name};"
-
- apply_to_spec_lines.append(f" if ({toggle}) {{ {stmt_spec_inner} }}")
- apply_to_model_lines.append(f" if ({toggle}) {{ {stmt_model_inner} }}")
-
- if apply_extras_function and urlab_extras:
- # Spec / Model already null-checked by the early return at the
- # top of each body, so the ternary is dead — pass the address
- # directly.
- apply_to_spec_lines.append(
- f" {apply_extras_function}(&Spec->option, *this, Spec);"
- )
- apply_to_model_lines.append(
- f" {apply_extras_function}(&Model->opt, *this, nullptr, Model);"
- )
-
- return (
- f"{COPYRIGHT_BLOCK}\n"
- f"#include \"{os.path.dirname(public_relpath).replace(os.sep, '/')}/{header_basename}.h\"\n"
- f"#include \n\n"
- f"void {ue_struct}::ApplyToSpec(mjSpec* Spec) const\n"
- f"{{\n"
- + "\n".join(apply_to_spec_lines) + "\n"
- f"}}\n\n"
- f"void {ue_struct}::ApplyOverridesToModel(mjModel* Model) const\n"
- f"{{\n"
- + "\n".join(apply_to_model_lines) + "\n"
- f"}}\n"
- )
-
-
-def _phase_synthetic_categories(ctx: PhaseContext) -> None:
- """Run after the main category walk; emits whole-file synthetic structs."""
- synth = ctx.rules.get("synthetic_categories", {})
- for cat_name, def_ in synth.items():
- # Skip _note_* sibling keys used for inline documentation.
- if cat_name.startswith("_") or not isinstance(def_, dict):
- continue
- ctx.writes.extend(_emit_synthetic_struct_files(
- cat_name, def_, ctx.mjxmacro, ctx.public_root, ctx.private_root,
- ))
-
-
-# ---------------------------------------------------------------------------
-# Sensor switch + TagToType codegen
-# ---------------------------------------------------------------------------
-#
-# Replaces the hand-written switch + map in MjSensor.cpp with codegen
-# output driven by:
-# - codegen_rules.json[categories.sensor.subtypes] for XML key + enum
-# value + (optional) case_body_override
-# - sensor_per_type (from build_mjcf_schema_snapshot.py's Sensor()
-# scrape) for mj_type + static objtype/reftype literals
-#
-# Variable-objtype/reftype branches (frame*, geomdist, contact, plugin,
-# user) stay hand-written in the post-switch block — that block reads
-# UE-side ObjType / RefType properties and applies them after the
-# codegen case fires.
-
-def _emit_sensor_switch_block(cat_rules: Dict[str, Any],
- sensor_per_type: Dict[str, Any]) -> str:
- """One ``case EMjSensorType::X: ...`` per subtype + the default fallback.
- Lives between ``CODEGEN_SENSOR_TYPE_SWITCH_*`` markers in MjSensor.cpp.
- """
- lines: List[str] = []
- type_enum = cat_rules.get("type_enum_name", "EMjSensorType")
- for subtype in cat_rules.get("subtypes", []):
- key = subtype["key"]
- enum_value = subtype["enum_value"]
- override = subtype.get("case_body_override")
- if override:
- lines.append(f" case {type_enum}::{enum_value}:")
- lines.append(f" {override} break;")
- continue
- per = sensor_per_type.get(key, {})
- mj_type = per.get("mj_type")
- if not mj_type:
- # The sensor switch will fall through to ``default:`` for this
- # subtype at runtime — i.e. all framejerk/whatever sensors get
- # the default mjSENS_ACCELEROMETER + mjOBJ_SITE substitution.
- # Loud diagnostic so a regression in build_mjcf_schema_snapshot's
- # _extract_sensor_per_type regex doesn't silently miscompile.
- _diag_add(
- f"[diagnostic] sensor subtype '{key}' has no entry in "
- f"sensor_per_type snapshot — runtime will fall through to "
- f"the default mjSENS_ACCELEROMETER + mjOBJ_SITE branch. "
- f"Check the _extract_sensor_per_type regex against "
- f"mujoco/src/user/user_objects.cc.",
- source="sensor_scrape_miss",
- )
- lines.append(f" // (skipped: no mj_type for '{key}' in sensor_per_type)")
- continue
- stmts = [f"Element->type = {mj_type};"]
- # Only emit static objtype/reftype when sensor_per_type carries a
- # literal mjOBJ_X. "from_xml" and "computed" entries are handled
- # by the post-switch block reading UE-side ObjType/RefType.
- objtype = per.get("objtype")
- if isinstance(objtype, str) and objtype.startswith("mjOBJ_"):
- stmts.append(f"Element->objtype = {objtype};")
- reftype = per.get("reftype")
- if isinstance(reftype, str) and reftype.startswith("mjOBJ_"):
- stmts.append(f"Element->reftype = {reftype};")
- lines.append(f" case {type_enum}::{enum_value}: "
- f"{' '.join(stmts)} break;")
- default_per = sensor_per_type.get("accelerometer", {})
- default_type = default_per.get("mj_type", "mjSENS_ACCELEROMETER")
- default_objtype = default_per.get("objtype") or "mjOBJ_SITE"
- if not (isinstance(default_objtype, str) and default_objtype.startswith("mjOBJ_")):
- default_objtype = "mjOBJ_SITE"
- lines.append(f" default: Element->type = {default_type}; "
- f"Element->objtype = {default_objtype}; break;")
- return "\n".join(lines) + "\n"
-
-
-def _emit_sensor_tag_to_type_block(cat_rules: Dict[str, Any]) -> str:
- """One ``{TEXT(""), EMjSensorType::X}`` per subtype. Lives between
- ``CODEGEN_SENSOR_TAG_TO_TYPE_*`` markers in MjSensor.cpp.
- """
- lines: List[str] = []
- type_enum = cat_rules.get("type_enum_name", "EMjSensorType")
- for subtype in cat_rules.get("subtypes", []):
- # Some subtype XML keys collide with C++ enum members that diverge
- # (e.g. `key=tendonactuatorfrc`, `enum_value=TendonActFrc`,
- # mjSENS_TENDONACTFRC). The tag-to-type map uses the XML key
- # verbatim so MJCF lookups match.
- key = subtype["key"]
- enum_value = subtype["enum_value"]
- lines.append(f' {{TEXT("{key}"), {type_enum}::{enum_value}}},')
- return "\n".join(lines) + "\n"
-
-
-# ---------------------------------------------------------------------------
-# Generated enum headers
-# ---------------------------------------------------------------------------
-#
-# Some MuJoCo C enums (mjtIntegrator/mjtCone/mjtSolver/...) map to URLab
-# UENUMs that are blueprint-exposed. Hand-written copies diverge from the
-# C source over time, so this emitter generates them from the projected
-# mjspec dict's ``enums`` table (sourced from the introspect snapshot).
-#
-# Rule shape (under top-level ``generated_enums`` in codegen_rules.json):
-# "MjOptionEnums": {
-# "public_header": "MuJoCo/Generated/MjOptionEnums.h",
-# "enums": [
-# {
-# "ue_name": "EMjIntegrator",
-# "from_mj_enum": "mjtIntegrator",
-# "underlying_type": "uint8", // optional, defaults uint8
-# "ue_member_from_mj": {
-# "mjINT_EULER": "Euler",
-# "mjINT_RK4": "RK4",
-# ...
-# },
-# // Optional: members from C enum to skip in UE (e.g. internal
-# // sentinels that aren't blueprint-meaningful).
-# "exclude_mj_members": []
-# }
-# ]
-# }
-
-
-def _emit_generated_enum_file(cat_name: str, def_: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]],
- public_root: str) -> List["FileWrite"]:
- """Emit a single banner-mode .h carrying one or more UENUMs.
-
- Rule shape (per enum entry):
- ``ue_name`` — UE enum class name (e.g. ``EMjGainType``)
- ``from_mj_enum`` — MuJoCo source enum (e.g. ``mjtGain``)
- ``ue_member_from_mj`` — opt-in mapping mj_const → UE member name
- ``exclude_mj_members``— optional skip list within the source enum
- ``extra_members`` — list of {"name": ...} URLab-extra
- members appended AFTER the mj-derived
- ones. Used by Camp B enums that carry
- URLab-specific values without a mjt
- counterpart (e.g. ``DcMotor`` for
- ``EMjGainType``).
-
- Rule entries with ``"disabled": true`` are skipped entirely — used
- while a hand-rolled enum is being staged for migration so the rule
- can land in JSON without breaking the build.
- """
- if def_.get("disabled"):
- return []
- if not mjspec or "enums" not in mjspec:
- _diag_add(
- f"[diagnostic] generated_enums['{cat_name}'] needs an mjspec "
- f"snapshot with an 'enums' key — run build_introspect_snapshot.py.",
- source="generated_enums",
- )
- return []
- enums = def_.get("enums", [])
- if not enums:
- return []
-
- public_relpath = def_["public_header"]
- header_basename = os.path.basename(public_relpath).replace(".h", "")
-
- enum_blocks: List[str] = []
- for entry in enums:
- if entry.get("disabled"):
- continue
- ue_name = entry["ue_name"]
- # ``from_mj_enum`` is optional when the URLab enum has no mjt
- # counterpart at all (EMjFluidShape, EMjGeomInertia, etc) — the
- # rule populates extra_members and skips the mjspec lookup.
- mj_enum_name: Optional[str] = entry.get("from_mj_enum")
- underlying = entry.get("underlying_type", "uint8")
- ue_member_from_mj: Dict[str, str] = entry.get("ue_member_from_mj", {})
- exclude: set = set(entry.get("exclude_mj_members", []))
- extra_members: List[Dict[str, Any]] = entry.get("extra_members", [])
- c_enum: Dict[str, int] = {}
- if mj_enum_name:
- c_enum = mjspec["enums"].get(mj_enum_name, {})
- if not c_enum:
- _diag_add(
- f"[diagnostic] generated_enums['{cat_name}']: C enum "
- f"'{mj_enum_name}' missing from the introspect snapshot. "
- f"Skipping '{ue_name}'.",
- source="generated_enums",
- )
- continue
- elif not extra_members:
- _diag_add(
- f"[diagnostic] generated_enums['{cat_name}']: '{ue_name}' "
- f"has neither from_mj_enum nor extra_members; nothing to "
- f"emit.",
- source="generated_enums",
- )
- continue
- member_lines: List[str] = []
- used_values: set = set()
- # Iterate by (value, mj_const) so the emitted UENUM order is stable
- # across libclang scrapes — the snapshot's dict insertion order is
- # whatever the AST walk produced, which can drift on header edits.
- for mj_const, value in sorted(c_enum.items(), key=lambda kv: (kv[1], kv[0])):
- if mj_const in exclude:
- continue
- ue_member = ue_member_from_mj.get(mj_const)
- if not ue_member:
- continue # silently skip; rule author opts in per-const
- member_lines.append(f" {ue_member} = {value},")
- used_values.add(value)
- # URLab-extra members run AFTER the mj-derived block. Values
- # auto-increment past the highest used mj value so the resulting
- # uint8 sequence stays contiguous + reproducible.
- next_value = (max(used_values) + 1) if used_values else 0
- for extra in extra_members:
- name = extra.get("name")
- if not name:
- _diag_add(
- f"[diagnostic] generated_enums['{cat_name}'] '{ue_name}'"
- f" extra_members entry {extra!r} missing 'name'.",
- source="generated_enums",
- )
- continue
- value = extra.get("value", next_value)
- member_lines.append(f" {name} = {value},")
- next_value = value + 1
- if not member_lines:
- continue
- # Strip the trailing comma on the last member for cleaner C++.
- member_lines[-1] = member_lines[-1].rstrip(",")
- # Doc line: only mention the mj source when the rule pinned
- # one. Pure-extras enums (no mjt counterpart) get a one-liner
- # naming them as URLab-side.
- doc = (
- f"/** {ue_name} — mirror of MuJoCo's {mj_enum_name}. */\n"
- if mj_enum_name
- else f"/** {ue_name} — URLab editorial enum (no mjt counterpart). */\n"
- )
- enum_blocks.append(
- doc
- + f"UENUM(BlueprintType)\n"
- f"enum class {ue_name} : {underlying}\n"
- f"{{\n"
- + "\n".join(member_lines) + "\n"
- f"}};\n"
- )
-
- if not enum_blocks:
- return []
-
- content = (
- f"{COPYRIGHT_BLOCK}\n"
- f"#pragma once\n\n"
- f"#include \"CoreMinimal.h\"\n"
- f"#include \"{header_basename}.generated.h\"\n\n"
- + "\n".join(enum_blocks)
- )
- public_path = os.path.join(public_root, public_relpath.replace("/", os.sep))
- return [FileWrite(path=public_path, content=content)]
-
-
-def _phase_generated_enums(ctx: PhaseContext) -> None:
- gen = ctx.rules.get("generated_enums", {})
- for cat_name, def_ in gen.items():
- # _note_* sibling keys document the surrounding entries; they
- # appear as strings, not dicts, and must skip the emit path.
- if cat_name.startswith("_") or not isinstance(def_, dict):
- continue
- ctx.writes.extend(_emit_generated_enum_file(
- cat_name, def_, ctx.mjspec, ctx.public_root,
- ))
-
-
-# ---------------------------------------------------------------------------
-# Articulation category registry
-# ---------------------------------------------------------------------------
-#
-# Emits a header with a compile-time table of every URLab-managed MuJoCo
-# category, listing the schema element name, UE base class, mjs struct,
-# and the layout shape. Consumers (diagnostic dumps, BP iteration,
-# test-time category enumeration) can iterate constexpr instead of
-# duplicating the category list in C++ source.
-
-# ---------------------------------------------------------------------------
-# Editor option helpers
-# ---------------------------------------------------------------------------
-#
-# Codegens the trivial ``TArray UMjX::GetYOptions() const`` editor
-# helpers that just forward to ``UMjComponent::GetSiblingComponentOptions``.
-# Wrappers with real per-class logic (UMjActuator::GetTargetNameOptions,
-# UMjSensor::Get(Target|Reference)NameOptions, UMjEquality::GetObjOptions)
-# stay hand-written in their owning .cpp files.
-#
-# Emission shape: each host .cpp file has a CODEGEN_EDITOR_OPTIONS_START/END
-# marker pair inside its ``#if WITH_EDITOR`` block. The phase injects the
-# class's wrappers between those markers — output stays INSIDE the host
-# .cpp, not a separate file. (Avoids the ``.gen.cpp`` UHT-collision name.)
-#
-# Rule shape (top-level ``editor_option_helpers.wrappers``):
-# [
-# {
-# "class": "UMjActuator",
-# "host_cpp": "MuJoCo/Components/Actuators/MjActuator.cpp",
-# "method": "GetSliderSiteOptions",
-# "filter_class": "UMjSite",
-# "include_defaults": false
-# },
-# ...
-# ]
-
-def _phase_editor_option_helpers(ctx: PhaseContext) -> None:
- def_ = ctx.rules.get("editor_option_helpers")
- if not def_:
- return
- wrappers = def_.get("wrappers", [])
- if not wrappers:
- return
- # Group by host_cpp.
- by_host: Dict[str, List[Dict[str, Any]]] = {}
- for w in wrappers:
- host = w.get("host_cpp")
- if not host:
- _diag_add(
- f"[diagnostic] editor_option_helpers: missing host_cpp on "
- f"wrapper {w!r}. Skipping.",
- source="editor_option_helpers",
- )
- continue
- by_host.setdefault(host, []).append(w)
- # Inject per-file.
- for host_relpath, group in by_host.items():
- host_path = os.path.join(ctx.private_root, host_relpath.replace("/", os.sep))
- if not os.path.exists(host_path):
- _diag_add(
- f"[diagnostic] editor_option_helpers: host_cpp '{host_relpath}' "
- f"not found on disk. Skipping injection.",
- source="editor_option_helpers",
- )
- continue
- with open(host_path, "r", encoding="utf-8") as f:
- text = f.read()
- lines: List[str] = []
- for w in group:
- cls = w["class"]
- method = w["method"]
- filt = w["filter_class"]
- inc_def = bool(w.get("include_defaults", False))
- defaults_arg = ", true" if inc_def else ""
- lines.append(
- f"TArray {cls}::{method}() const {{ return "
- f"UMjComponent::GetSiblingComponentOptions(this, "
- f"{filt}::StaticClass(){defaults_arg}); }}"
- )
- body = "\n".join(lines) + "\n"
- new_text, ok = inject_between_tags(text, "EDITOR_OPTIONS", body)
- if not ok:
- _diag_add(
- f"[diagnostic] editor_option_helpers: host_cpp '{host_relpath}' "
- f"missing the CODEGEN_EDITOR_OPTIONS_START/END marker pair. "
- f"Add the markers inside the host's #if WITH_EDITOR block "
- f"or remove the wrapper entries.",
- source="editor_option_helpers",
- )
- continue
- if new_text != text:
- ctx.writes.append(FileWrite(path=host_path, content=new_text))
-
-
-def _phase_articulation_registry(ctx: PhaseContext) -> None:
- cats = ctx.rules.get("categories", {})
- if not cats:
- return
- out_relpath = "MuJoCo/Generated/MjArticulationRegistry.h"
- entries: List[str] = []
- for name in sorted(cats):
- cat = cats[name]
- base = cat.get("base_class_name", "")
- mjs = cat.get("mjs_struct", "")
- layout = cat.get("layout", "no_subclasses")
- n_subtypes = len(cat.get("subtypes", []))
- entries.append(
- f' {{ TEXT("{name}"), TEXT("{base}"), TEXT("{mjs}"), '
- f'TEXT("{layout}"), {n_subtypes} }},'
- )
- content = (
- f"{COPYRIGHT_BLOCK}\n"
- f"#pragma once\n\n"
- f"#include \"CoreMinimal.h\"\n\n"
- f"// Compile-time registry of every URLab-managed MuJoCo category.\n"
- f"// Codegen-owned — driven by codegen_rules.json[categories].\n"
- f"namespace MjArticulationRegistry\n"
- f"{{\n"
- f" struct CategoryEntry\n"
- f" {{\n"
- f" const TCHAR* Name; // schema element name, e.g. \"body\"\n"
- f" const TCHAR* BaseClassName; // UE base UClass, e.g. \"UMjBody\"\n"
- f" const TCHAR* MjsStruct; // MuJoCo spec struct, e.g. \"mjsBody\"\n"
- f" const TCHAR* Layout; // \"single_uclass_per_file\" / \"multi_uclass\" / \"no_subclasses\"\n"
- f" int NumSubtypes;\n"
- f" }};\n\n"
- f" inline constexpr CategoryEntry kCategories[] = {{\n"
- + "\n".join(entries) + "\n"
- f" }};\n"
- f" inline constexpr int kNumCategories = sizeof(kCategories) / sizeof(kCategories[0]);\n"
- f"}}\n"
- )
- out_path = os.path.join(ctx.public_root, out_relpath.replace("/", os.sep))
- ctx.writes.append(FileWrite(path=out_path, content=content))
-
-
-def _emit_objtype_dispatch_block(cat_rules: Dict[str, Any]) -> Optional[str]:
- """Emit a switch on ``cat_rules['objtype_dispatch']`` that assigns
- each case's ``expr`` to ``target``. Used by categories where mjs's
- objtype field varies by enum value (today: MjEquality)."""
- dispatch = cat_rules.get("objtype_dispatch")
- if not dispatch:
- return None
- enum_name = cat_rules.get("type_enum_name")
- if not enum_name:
- _diag_add(
- "[diagnostic] objtype_dispatch on category missing "
- "'type_enum_name'; cannot emit case labels.",
- source="objtype_dispatch",
- )
- return None
- discriminator = dispatch["discriminator"]
- target = dispatch["target"]
- default_expr = dispatch.get("default", "mjOBJ_UNKNOWN")
- cases = dispatch.get("cases", [])
- if not cases:
- _diag_add(
- f"[diagnostic] objtype_dispatch '{discriminator}' has no cases; "
- f"only the default branch would emit.",
- source="objtype_dispatch",
- )
- return None
-
- switch_cases: List[Tuple[Any, str]] = []
- for i, case in enumerate(cases):
- keys = case.get("keys", [])
- if not keys:
- _diag_add(
- f"[diagnostic] objtype_dispatch case #{i} has empty "
- f"'keys' list; would emit a body with no case label.",
- source="objtype_dispatch",
- )
- return None
- if "expr" not in case:
- _diag_add(
- f"[diagnostic] objtype_dispatch case #{i} (keys={keys}) "
- f"missing 'expr'.",
- source="objtype_dispatch",
- )
- return None
- switch_cases.append((list(keys), f"{target} = {case['expr']}"))
- return emit_enum_switch(
- discriminator, enum_name, switch_cases,
- indent=" ",
- default_body=f"{target} = {default_expr}",
- )
-
-
-def _inject_into_category_cpp(
- rules: Dict[str, Any],
- private_root: str,
- writes: List["FileWrite"],
- tag: str,
- emit_fn,
- *,
- diag_source: str,
-) -> None:
- """Shared scaffolding: walk every category, call ``emit_fn(cat_rules)``,
- inject the result between ``CODEGEN__START/END`` markers in the
- category's base-class .cpp. ``emit_fn`` returns ``None`` to skip
- (already diagnosed inside the emit_fn). Missing-file / missing-marker
- diagnostics + the brace-balance check come from
- ``_inject_tags_into_cpp`` so every injection path shares the same
- safety net."""
- for cat_name, cat_rules in rules.get("categories", {}).items():
- body = emit_fn(cat_rules)
- if body is None:
- continue
- base_header = cat_rules.get("base_class_header")
- if not base_header:
- _diag_add(
- f"[diagnostic] category '{cat_name}' has codegen rule for "
- f"{diag_source} but no 'base_class_header'; block not emitted.",
- source=diag_source,
- )
- continue
- cpp_path = os.path.join(
- private_root, base_header.replace(".h", ".cpp"),
- )
- _inject_tags_into_cpp(
- cpp_path, [(tag, body)], writes, diag_source=diag_source,
- )
-
-
-def _phase_objtype_dispatch(ctx: PhaseContext) -> None:
- """Inject objtype dispatch block; host .cpp must carry
- ``CODEGEN_OBJTYPE_DISPATCH_START/END`` markers."""
- _inject_into_category_cpp(
- ctx.rules, ctx.private_root, ctx.writes,
- tag="OBJTYPE_DISPATCH",
- emit_fn=_emit_objtype_dispatch_block,
- diag_source="objtype_dispatch",
- )
-
-
-def _emit_geom_final_type_block(cat_rules: Dict[str, Any],
- element_rules: Dict[str, Any],
- mjspec: Optional[Dict[str, Any]] = None) -> Optional[str]:
- """Emit MjGeom's FinalType resolution + mesh-name export. Specific
- to geom because the mesh-name write depends on the COMPILE-TIME geom
- type (UPROPERTY Type if overridden, else Default's type).
-
- The value_map is pulled from ``element_rules[xml_enum_ref]`` via
- ``_resolve_value_map``. Returns None (with a diagnostic) when the
- xml_enum_ref entry is missing — silent failure here would drop the
- block from MjGeom.cpp and only surface as a runtime mesh-bind error.
- """
- final = cat_rules.get("geom_final_type")
- if not final:
- return None
- xml_enum_attrs = element_rules.get("xml_enum_attrs", {})
- attr_key = final["xml_enum_ref"]
- enum_def = xml_enum_attrs.get(attr_key)
- if not enum_def:
- _diag_add(
- f"[diagnostic] geom_final_type references xml_enum '{attr_key}' "
- f"that doesn't exist in element_rules; FinalType block will be "
- f"empty and mesh-name export will not fire.",
- source="geom_final_type",
- )
- return None
- value_map = _resolve_value_map(attr_key, enum_def)
- if not value_map:
- _diag_add(
- f"[diagnostic] geom_final_type xml_enum '{attr_key}' resolved "
- f"to an empty value_map; FinalType switch would have no cases.",
- source="geom_final_type",
- )
- return None
- ue_prop = enum_def["ue_property"]
- ue_enum = enum_def["ue_enum_type"]
-
- override = final["override_field"]
- default_lookup = final["default_lookup"]
- fallback = final["default_fallback"]
- name_field = final["name_field"]
- name_for = final["name_export_for"]
- name_target = final["name_target"]
- name_setter = final["name_setter"]
-
- # Placeholder for the FinalType init when override=true: any mj_const
- # works because the switch below remaps. Pick the value_map's first
- # entry for stability.
- first_mj = next(iter(value_map.values()))[1]
-
- switch_cases: List[Tuple[Any, str]] = [
- (mapping[0], f"FinalType = {mapping[1]}")
- for mapping in value_map.values()
- ]
- switch_body = emit_enum_switch(
- ue_prop, ue_enum, switch_cases, indent=" ",
- ).rstrip("\n")
- lines: List[str] = []
- lines.append(f" int FinalType = {override}")
- lines.append(f" ? {first_mj} /* placeholder; remapped below */")
- lines.append(f" : (Default ? {default_lookup} : {fallback});")
- lines.append(f" if ({override})")
- lines.append(" {")
- lines.append(switch_body)
- lines.append(" }")
- lines.append(f" if (FinalType == {name_for} && !{name_field}.IsEmpty())")
- lines.append(" {")
- lines.append(f" {name_setter}({name_target}, {name_field});")
- lines.append(" }")
- return "\n".join(lines) + "\n"
-
-
-def _phase_geom_final_type(ctx: PhaseContext) -> None:
- """Inject geom_final_type block into MjGeom.cpp between the
- CODEGEN_GEOM_FINAL_TYPE markers."""
- element_rules_all = ctx.rules.get("element_rules", {})
-
- def emit_fn(cat_rules):
- # Look up element_rules entry via the category key already used by
- # rules.categories. The shared helper passes cat_rules through;
- # we recover the category name from the dict identity.
- cat_name = next(
- (k for k, v in ctx.rules.get("categories", {}).items()
- if v is cat_rules),
- None,
- )
- if cat_name is None:
- return None
- return _emit_geom_final_type_block(
- cat_rules, element_rules_all.get(cat_name, {}), ctx.mjspec,
- )
-
- _inject_into_category_cpp(
- ctx.rules, ctx.private_root, ctx.writes,
- tag="GEOM_FINAL_TYPE",
- emit_fn=emit_fn,
- diag_source="geom_final_type",
- )
-
-
-def _phase_sensor_codegen(ctx: PhaseContext) -> None:
- """Inject codegen-emitted sensor switch + TagToType into MjSensor.cpp."""
- sensor_rules = ctx.rules.get("categories", {}).get("sensor")
- if not sensor_rules:
- return
- sensor_per_type = ctx.schema.get("sensor_per_type", {})
- if not sensor_per_type:
- _diag_add(
- "[diagnostic] sensor_per_type missing from schema snapshot; "
- "skipping sensor switch codegen (run "
- "build_mjcf_schema_snapshot.py).",
- source="sensor_codegen",
- )
- return
- cpp_path = os.path.join(
- ctx.private_root, "MuJoCo", "Components", "Sensors", "MjSensor.cpp",
- )
- _inject_tags_into_cpp(
- cpp_path,
- [
- ("SENSOR_TYPE_SWITCH", _emit_sensor_switch_block(sensor_rules, sensor_per_type)),
- ("SENSOR_TAG_TO_TYPE", _emit_sensor_tag_to_type_block(sensor_rules)),
- ],
- ctx.writes,
- diag_source="sensor_codegen",
- )
-
-
-_KNOWN_LAYOUTS = {"single_uclass_per_file", "multi_uclass", "no_subclasses"}
-
-
-def _phase_categories(ctx: PhaseContext) -> None:
- rules, schema = ctx.rules, ctx.schema
- public_root, private_root = ctx.public_root, ctx.private_root
- mjspec = ctx.mjspec
- categories: Dict[str, Any] = rules.get("categories", {})
- for cat, cat_rules in categories.items():
- layout = cat_rules.get("layout", "no_subclasses")
- if layout == "single_uclass_per_file":
- ctx.writes.extend(emit_base_class_injection(cat, cat_rules, schema, rules, public_root, private_root, mjspec=mjspec))
- ctx.writes.extend(emit_subclass_files(cat, cat_rules, schema, rules, public_root, private_root, mjspec=mjspec))
- elif layout == "multi_uclass":
- ctx.writes.extend(emit_multi_uclass(cat, cat_rules, schema, rules, public_root, private_root, mjspec=mjspec))
- elif layout == "no_subclasses":
- ctx.writes.extend(emit_base_class_injection(cat, cat_rules, schema, rules, public_root, private_root, mjspec=mjspec))
- else:
- _diag_add(
- f"[diagnostic] category '{cat}' has unknown layout "
- f"'{layout}'; expected one of {sorted(_KNOWN_LAYOUTS)}. "
- f"Category emitted no writes.",
- source="category_layout",
- )
-
-
-def _phase_bind_h(ctx: PhaseContext) -> None:
- bind_write = emit_bind_h_injection(ctx.rules, ctx.mjxmacro, ctx.bind_h_path)
- if bind_write:
- ctx.writes.append(bind_write)
-
-
-def _phase_schema_tests(ctx: PhaseContext) -> None:
- ctx.writes.append(emit_schema_for_tests(ctx.schema, ctx.rules))
-
-
-# The 17 drift checks, _emit_drift_diagnostics, the hand-enum regexes,
-# _scan_hand_enums, _hand_enums_from_snapshot, _all_schema_attrs,
-# _collect_every_schema_attr, and _VALID_APPLY_MODES live in
-# _codegen_checks. The orchestrator re-exports them through the import
-# block at the top of this file.
-
-
-def _phase_diagnostics(ctx: PhaseContext) -> None:
- rules, schema, mjspec, mjxmacro = ctx.rules, ctx.schema, ctx.mjspec, ctx.mjxmacro
- _emit_drift_diagnostics(schema, rules, mjspec)
- _check_hand_enum_drift(schema, rules, mjspec, ctx.public_root)
- _check_type_shape_drift(schema, rules, mjspec)
- _check_new_attr_typing(schema, rules)
- _check_value_map_stale_mj_consts(rules, mjspec)
- _check_orphan_rule_entries(schema, rules)
- _check_compiler_attrs_coverage(schema, rules)
- _check_mjxmacro_block_coverage(rules, mjxmacro)
- _check_property_units_validity(rules)
- _check_apply_mode_validity(rules)
- _check_embedded_cpp_references(rules, mjspec)
- _check_allowlist_staleness(schema, rules, mjspec)
-
-
-# Order matters: emit phases collect writes; diagnostics runs last and
-# scans the final rule set.
-EMISSION_PHASES: List[EmissionPhase] = [
- EmissionPhase(name="categories", fn=_phase_categories),
- EmissionPhase(name="synthetic_categories", fn=_phase_synthetic_categories),
- EmissionPhase(name="generated_enums", fn=_phase_generated_enums),
- EmissionPhase(name="editor_option_helpers", fn=_phase_editor_option_helpers),
- EmissionPhase(name="articulation_registry", fn=_phase_articulation_registry),
- EmissionPhase(name="sensor_codegen", fn=_phase_sensor_codegen),
- EmissionPhase(name="objtype_dispatch", fn=_phase_objtype_dispatch),
- EmissionPhase(name="geom_final_type", fn=_phase_geom_final_type),
- EmissionPhase(name="bind_h", fn=_phase_bind_h),
- EmissionPhase(name="schema_tests", fn=_phase_schema_tests),
- EmissionPhase(name="diagnostics", fn=_phase_diagnostics),
-]
-
-
-def collect_all_writes(
- schema: Dict[str, Any],
- rules: Dict[str, Any],
- mjxmacro: Dict[str, Any],
- public_root: str,
- private_root: str,
- bind_h_path: str,
- mjspec: Dict[str, Any] | None = None,
-) -> List[FileWrite]:
- """Drive every phase in ``EMISSION_PHASES`` and return the full set
- of file writes the codegen would perform. No I/O side effects on
- disk — diagnostics print to stderr at the end."""
- _reset_diags()
- writes: List[FileWrite] = []
- ctx = PhaseContext(
- schema=schema, rules=rules, mjxmacro=mjxmacro, mjspec=mjspec,
- public_root=public_root, private_root=private_root,
- bind_h_path=bind_h_path, writes=writes,
- )
- for phase in EMISSION_PHASES:
- phase.fn(ctx)
- _diag_flush()
- return writes
-
-
-def _mjspec_from_introspect(
- introspect: Dict[str, Any],
-) -> Dict[str, Any]:
- """Project the libclang-scraped introspect snapshot into the
- shape downstream code expects:
-
- ``structs``: ``{struct_name: [field_name, ...]}``
- ``enums``: ``{enum_name: {member_name: int_value}}``
- ``setto_functions``: ``{fn_name: {"params": [...], "return_type": ...}}``
- ``introspect``: passthrough of the richer per-field tables for
- the drift checks that need them.
-
- Every ``mjs_setTo*`` C signature takes the spec element as its
- first arg; the codegen emit path always passes ``Element`` there,
- so the projection drops that arg from the param list and the
- downstream emitter enumerates only the schema-attr-bound trailing
- args."""
- structs_in = introspect.get("structs", {}) or {}
- structs_out: Dict[str, List[str]] = {}
- for name, entry in structs_in.items():
- if isinstance(entry, dict):
- fields = entry.get("fields", [])
- structs_out[name] = [
- f["name"] for f in fields
- if isinstance(f, dict) and isinstance(f.get("name"), str)
- ]
-
- enums_in = introspect.get("enums", {}) or {}
- enums_out: Dict[str, Dict[str, int]] = {}
- for name, entry in enums_in.items():
- if isinstance(entry, dict):
- members = entry.get("members", {})
- if isinstance(members, dict):
- enums_out[name] = dict(members)
-
- fns_in = introspect.get("functions", {}) or {}
- setto_out: Dict[str, Dict[str, Any]] = {}
- for name, sig in fns_in.items():
- if not name.startswith("mjs_setTo"):
- continue
- if isinstance(sig, dict):
- params = sig.get("params", [])
- setto_out[name] = {
- "params": params[1:] if params else [],
- "return_type": sig.get("return_type", ""),
- }
-
- return {
- "structs": structs_out,
- "enums": enums_out,
- "setto_functions": setto_out,
- "introspect": {
- "functions": fns_in,
- "structs": structs_in,
- "defines": introspect.get("defines", {}),
- "hand_enums": introspect.get("hand_enums", {}),
- },
- }
-
-
-_CLANG_FORMAT_EXE: Optional[str] = None
-_CLANG_FORMAT_RESOLVED = False
-
-
-def _resolve_clang_format() -> Optional[str]:
- """Locate clang-format: $CLANG_FORMAT, then PATH, then VS2022's LLVM."""
- global _CLANG_FORMAT_EXE, _CLANG_FORMAT_RESOLVED
- if _CLANG_FORMAT_RESOLVED:
- return _CLANG_FORMAT_EXE
- _CLANG_FORMAT_RESOLVED = True
- cand = (os.environ.get("CLANG_FORMAT")
- or shutil.which("clang-format-19") # common on Linux
- or shutil.which("clang-format"))
- if not cand:
- # Windows: VS2022's bundled LLVM.
- vs = ("C:/Program Files/Microsoft Visual Studio/2022/Community/"
- "VC/Tools/Llvm/bin/clang-format.exe")
- if os.path.isfile(vs):
- cand = vs
- _CLANG_FORMAT_EXE = cand
- return cand
-
-
-def _clang_format_content(content: str, path: str) -> str:
- """Format emitted C++ with the project .clang-format so generated files
- match a clang-format pass over the whole tree. clang-format is a hard
- regen dependency (like libclang): the committed generated tree is
- formatted, so emitting unformatted would trip the --check drift gate.
- Use clang-format 19.x (VS2022 LLVM) to match what the tree was committed
- with. Non-C++ artifacts (e.g. the test-only schema header) pass through."""
- if not (path.endswith(".h") or path.endswith(".cpp")):
- return content
- exe = _resolve_clang_format()
- if not exe:
- raise RuntimeError(
- "clang-format not found — set $CLANG_FORMAT or put it on PATH "
- "(clang-format 19.x, e.g. VS2022's bundled LLVM). Required so the "
- "codegen emits formatted files; without it the --check drift gate "
- "will report spurious changes.")
- # --assume-filename lets clang-format pick up the repo-root .clang-format
- # by walking up from the (real) generated-file path.
- proc = subprocess.run(
- [exe, f"--assume-filename={path}", "--style=file"],
- input=content.encode("utf-8"),
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- )
- if proc.returncode != 0:
- raise RuntimeError(
- f"clang-format failed on {path}: "
- f"{proc.stderr.decode('utf-8', 'replace')}")
- return proc.stdout.decode("utf-8")
-
-
-def apply_writes(writes: List[FileWrite], dry_run: bool, check_only: bool) -> int:
- """Either apply, print diff, or check. Returns process exit code.
-
- Writes use ``newline="\\n"`` and a binary compare so a codegen run on
- Windows produces the same bytes as one on Linux — otherwise Python's
- default newline translation would silently bake ``\\r\\n`` into the
- on-disk artifacts and ``--check`` would still pass because the
- matching read would normalize it back."""
- changed = 0
- for w in writes:
- content = _clang_format_content(w.content, w.path)
- new_bytes = content.encode("utf-8")
- old_bytes: Optional[bytes] = None
- if os.path.exists(w.path):
- with open(w.path, "rb") as f:
- old_bytes = f.read()
- if old_bytes == new_bytes:
- continue
- changed += 1
- rel = os.path.relpath(w.path, PLUGIN_ROOT)
- if dry_run or check_only:
- print(f"==> WOULD WRITE: {rel} ({len(new_bytes)} bytes)")
- if old_bytes is not None and dry_run:
- old_text = old_bytes.decode("utf-8", errors="replace")
- diff = difflib.unified_diff(
- old_text.splitlines(keepends=True),
- content.splitlines(keepends=True),
- fromfile=rel + " (current)",
- tofile=rel + " (codegen)",
- n=2,
- )
- sys.stdout.writelines(diff)
- else:
- # Atomic write: stage to a sibling tmp file, then os.replace.
- # Without this, a Ctrl-C between truncate and write leaves a
- # zero-/partial-byte file that UBT picks up, producing a UHT
- # error far from "I interrupted codegen".
- os.makedirs(os.path.dirname(w.path), exist_ok=True)
- tmp_path = w.path + ".codegen.tmp"
- try:
- with open(tmp_path, "wb") as f:
- f.write(new_bytes)
- os.replace(tmp_path, w.path)
- except BaseException:
- if os.path.exists(tmp_path):
- try:
- os.remove(tmp_path)
- except OSError:
- pass
- raise
- print(f"WROTE {rel}")
- if check_only and changed:
- return 1
- print(f"{'(dry-run) ' if dry_run else ''}files changed: {changed}")
- return 0
-
-
-# Hand-written companion files that legitimately live in MuJoCo/Generated/
-# (their banner explicitly says "NOT codegen-managed"). Listed here so the
-# orphan walk doesn't flag them — anything else in Generated/ that the
-# codegen doesn't plan to write IS a real orphan.
-_HAND_WRITTEN_IN_GENERATED = {
- "MjOptionGeneratedExtras.cpp",
-}
-
-
-def find_orphan_generated_files(
- writes: List[FileWrite], public_root: str, private_root: str,
-) -> List[str]:
- """Walk ``MuJoCo/Generated/`` under public + private roots and return
- any file the codegen no longer plans to emit. A category removed from
- rules leaves a stale ``Generated/MjFoo.h`` that UBT will pick up — the
- user sees a confusing UHT error far from the JSON edit."""
- expected = {os.path.normcase(os.path.abspath(w.path)) for w in writes}
- orphans: List[str] = []
- for root in (public_root, private_root):
- gen_dir = os.path.join(root, "MuJoCo", "Generated")
- if not os.path.isdir(gen_dir):
- continue
- for dirpath, _dirs, files in os.walk(gen_dir):
- for fname in files:
- if not (fname.endswith(".h") or fname.endswith(".cpp")):
- continue
- if fname in _HAND_WRITTEN_IN_GENERATED:
- continue
- p = os.path.normcase(os.path.abspath(os.path.join(dirpath, fname)))
- if p not in expected:
- orphans.append(os.path.join(dirpath, fname))
- return sorted(orphans)
-
-
-def main() -> int:
- parser = argparse.ArgumentParser(description="URLab UE component codegen.")
- parser.add_argument("--schema", default=DEFAULT_SCHEMA)
- parser.add_argument("--mjxmacro", default=DEFAULT_MJXMACRO)
- parser.add_argument("--introspect", default=DEFAULT_INTROSPECT,
- help="Clang-AST scrape carrying mjsX struct fields, "
- "mjt* enums, mjs_setTo* signatures, and EMj* "
- "hand-enum members. Built by "
- "build_introspect_snapshot.py (requires libclang).")
- parser.add_argument("--rules", default=DEFAULT_RULES)
- parser.add_argument("--public-root", default=DEFAULT_PUBLIC_ROOT)
- parser.add_argument("--private-root", default=DEFAULT_PRIVATE_ROOT)
- parser.add_argument("--bind-h", default=DEFAULT_BIND_H)
- parser.add_argument("--dry-run", action="store_true",
- help="print diffs, write nothing")
- parser.add_argument("--check", action="store_true",
- help="non-zero exit if writes would change anything")
- parser.add_argument("--strict", dest="strict",
- action=argparse.BooleanOptionalAction, default=True,
- help="treat drift diagnostics as fatal (exit 2). "
- "Default on; --no-strict makes diagnostics "
- "print but not fail the run.")
- parser.add_argument("--require-introspect", dest="require_introspect",
- action=argparse.BooleanOptionalAction, default=True,
- help="hard-fail when the clang-AST introspect "
- "snapshot is missing. Default on; "
- "--no-require-introspect lets the codegen run "
- "against an existing (possibly stale) snapshot.")
- args = parser.parse_args()
-
- with open(args.schema, "r", encoding="utf-8") as f:
- schema = json.load(f)
- with open(args.mjxmacro, "r", encoding="utf-8") as f:
- mjxmacro = json.load(f)
- with open(args.rules, "r", encoding="utf-8") as f:
- rules = json.load(f)
-
- mjspec: Dict[str, Any] | None = None
- if not os.path.exists(args.introspect):
- msg = (
- f"[codegen] introspect snapshot missing at {args.introspect}. "
- f"Run `python Scripts/codegen/build_introspect_snapshot.py` "
- f"(requires libclang). Pass --no-require-introspect to bypass."
- )
- if args.require_introspect:
- print(msg, file=sys.stderr)
- return 3
- print(f"[codegen] warning: {msg}", file=sys.stderr)
- else:
- with open(args.introspect, "r", encoding="utf-8") as f:
- introspect = json.load(f)
- mjspec = _mjspec_from_introspect(introspect)
- # Post-projection invariants: a libclang scrape shape change can
- # silently empty the projection, which would neuter the type-shape
- # drift check and drop TArray array-cap clamps from emitted code.
- # Fail loud rather than ship a degraded but green-on---check run.
- if args.require_introspect:
- for key in ("enums", "structs", "setto_functions"):
- if not mjspec.get(key):
- print(
- f"[codegen] introspect projection produced empty "
- f"'{key}'. The libclang scrape shape may have "
- f"drifted — rebuild the snapshot or fix "
- f"_mjspec_from_introspect.",
- file=sys.stderr,
- )
- return 3
-
- writes = collect_all_writes(
- schema, rules, mjxmacro,
- args.public_root, args.private_root, args.bind_h, mjspec=mjspec,
- )
-
- orphans = find_orphan_generated_files(
- writes, args.public_root, args.private_root,
- )
- for orphan in orphans:
- rel = os.path.relpath(orphan, PLUGIN_ROOT)
- _diag_add(
- f"[diagnostic] orphan generated file: {rel}. The codegen no "
- f"longer plans to emit this path — a category or subtype was "
- f"likely removed from codegen_rules.json. Delete the file "
- f"(UBT will otherwise pick it up).",
- source="orphan_generated_file",
- )
- # Snapshot the diag SOURCE tags before flushing, so we can detect
- # destructive-overwrite warnings (banner_overwrite) and refuse to
- # write under --strict — otherwise apply_writes would destroy the
- # hand edits before the strict check fires.
- banner_overwrite_pending = any(
- d.source == "banner_overwrite" for d in _DIAGS_BUFFER.pending
- )
- _diag_flush()
-
- fired = _DIAGS_BUFFER.fired_count
- is_destructive_run = not args.dry_run and not args.check
- if is_destructive_run and args.strict and banner_overwrite_pending:
- print(
- f"[codegen] --strict: banner_overwrite diagnostic fired — "
- f"refusing to write (would destroy hand-edited content). "
- f"Re-run with --no-strict to proceed, or run the audit "
- f"helper at Scripts/codegen/_audit_banner_candidates.py.",
- file=sys.stderr,
- )
- return 2
-
- rc = apply_writes(writes, args.dry_run, args.check)
- if args.check and orphans:
- print(
- f"[codegen] --check: {len(orphans)} orphan generated file(s); "
- f"exiting non-zero.", file=sys.stderr,
- )
- return 1
- if args.strict and fired:
- print(
- f"[codegen] --strict: {fired} diagnostic(s) flushed; "
- f"exiting non-zero.", file=sys.stderr,
- )
- return 2
- return rc
-
-
-if __name__ == "__main__":
- raise SystemExit(main())
diff --git a/Scripts/codegen/regen_all.py b/Scripts/codegen/regen_all.py
deleted file mode 100644
index ab3c6227..00000000
--- a/Scripts/codegen/regen_all.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""One-shot regen pipeline for a MuJoCo version bump.
-
-Runs every codegen step in order:
-
- 1. Rebuild snapshots from the installed MuJoCo headers + submodule source:
- - Scripts/codegen/snapshots/mjxmacro_snapshot.json (model/data array layouts)
- - Scripts/codegen/snapshots/mjcf_schema_snapshot.json (MJCF schema + per-sensor objtype scrape)
- - Scripts/codegen/snapshots/introspect_snapshot.json (clang-AST scrape — mjsX struct fields, mjt* enums, mjs_setTo* sigs, EMj* hand enums)
- 2. Run the C++ generator (generate_ue_components.py) against the fresh
- snapshots. Emits / updates the per-component .h/.cpp files in Source/.
-
-The clang-AST introspect snapshot now supersedes the old
-``mjspec_snapshot.json`` — the runtime projects introspect into the
-legacy mjspec shape, so build_mjspec_snapshot.py is retired.
-
-Day-to-day this is the script developers run after either:
- - bumping the third_party/MuJoCo submodule pointer + rebuilding the
- install (build_all.ps1 / build_all.sh), OR
- - editing Scripts/codegen/codegen_rules.json.
-
-Usage:
- python Scripts/codegen/regen_all.py
- python Scripts/codegen/regen_all.py --skip-codegen # snapshots only
-
-Exit code:
- 0 on success, non-zero if any sub-step fails.
-"""
-from __future__ import annotations
-
-import argparse
-import os
-import subprocess
-import sys
-import time
-
-
-HERE = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_ROOT = os.path.normpath(os.path.join(HERE, "..", ".."))
-
-
-def _run(label: str, cmd: list[str]) -> int:
- print(f"\n>>> {label}", flush=True)
- t0 = time.monotonic()
- proc = subprocess.run(cmd, cwd=PLUGIN_ROOT)
- dt = time.monotonic() - t0
- if proc.returncode != 0:
- print(f"!!! {label} FAILED (exit {proc.returncode}, {dt:.1f}s)", flush=True)
- else:
- print(f"... {label} ok ({dt:.1f}s)", flush=True)
- return proc.returncode
-
-
-def main(argv: list[str] | None = None) -> int:
- ap = argparse.ArgumentParser()
- ap.add_argument(
- "--skip-codegen", action="store_true",
- help="Only rebuild the three snapshot JSONs; skip generate_ue_components.py.",
- )
- args = ap.parse_args(argv)
-
- py = sys.executable
-
- steps: list[tuple[str, list[str]]] = [
- ("mjxmacro snapshot",
- [py, os.path.join(HERE, "build_mjxmacro_snapshot.py")]),
- ("MJCF schema snapshot",
- [py, os.path.join(HERE, "build_mjcf_schema_snapshot.py")]),
- ]
- # Introspect snapshot needs libclang and now also supplies the data
- # build_mjspec_snapshot.py used to scrape via regex (mjsX struct
- # fields, mjt* enums, mjs_setTo* sigs). Optional only in the sense
- # that a stale on-disk snapshot still drives the codegen — the
- # --require-introspect default in generate_ue_components.py makes
- # the gate fatal at next run if the snapshot really is missing.
- introspect_step = (
- "introspect snapshot (clang AST — supersedes mjspec snapshot)",
- [py, os.path.join(HERE, "build_introspect_snapshot.py")],
- )
- steps.append(introspect_step)
- if not args.skip_codegen:
- steps.append(("UE component codegen",
- [py, os.path.join(HERE, "generate_ue_components.py")]))
-
- for label, cmd in steps:
- rc = _run(label, cmd)
- if rc != 0:
- # Introspect is optional — warn but continue when it's the
- # one that failed (most commonly: libclang not on PATH).
- if label.startswith("introspect snapshot"):
- print(
- " (introspect is optional; codegen will use the "
- "existing snapshot — type-shape drift may be stale "
- "until you install libclang.)",
- flush=True,
- )
- continue
- return rc
-
- print("\nAll regen steps completed.", flush=True)
- print("Next: close the editor, run the URLab build + test cycle to verify.", flush=True)
- return 0
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/Scripts/codegen/snapshots/introspect_snapshot.json b/Scripts/codegen/snapshots/introspect_snapshot.json
deleted file mode 100644
index cd8538a8..00000000
--- a/Scripts/codegen/snapshots/introspect_snapshot.json
+++ /dev/null
@@ -1,27250 +0,0 @@
-{
- "_meta": {
- "snapshot_version": 1,
- "header_hash": "fdebcce03a83af579b82cd49d8c908c70242a54f852ce9e13a98f4bf69e15d6d"
- },
- "functions": {
- "mj_defaultVFS": {
- "name": "mj_defaultVFS",
- "return_type": "void",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 82
- },
- "mj_mountVFS": {
- "name": "mj_mountVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "filepath",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "provider",
- "c_type": "const mjpResourceProvider *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 86
- },
- "mj_unmountVFS": {
- "name": "mj_unmountVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 89
- },
- "mj_addFileVFS": {
- "name": "mj_addFileVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "directory",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 92
- },
- "mj_addBufferVFS": {
- "name": "mj_addBufferVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "buffer",
- "c_type": "const void *",
- "array_dim": null
- },
- {
- "name": "nbuffer",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 95
- },
- "mj_deleteFileVFS": {
- "name": "mj_deleteFileVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 98
- },
- "mj_containsBufferVFS": {
- "name": "mj_containsBufferVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 101
- },
- "mj_containsFileVFS": {
- "name": "mj_containsFileVFS",
- "return_type": "int",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- },
- {
- "name": "directory",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 104
- },
- "mj_deleteVFS": {
- "name": "mj_deleteVFS",
- "return_type": "void",
- "params": [
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 107
- },
- "mj_getCacheSize": {
- "name": "mj_getCacheSize",
- "return_type": "size_t",
- "params": [
- {
- "name": "cache",
- "c_type": "const mjCache *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 112
- },
- "mj_getCacheCapacity": {
- "name": "mj_getCacheCapacity",
- "return_type": "size_t",
- "params": [
- {
- "name": "cache",
- "c_type": "const mjCache *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 115
- },
- "mj_setCacheCapacity": {
- "name": "mj_setCacheCapacity",
- "return_type": "size_t",
- "params": [
- {
- "name": "cache",
- "c_type": "mjCache *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 118
- },
- "mj_getCache": {
- "name": "mj_getCache",
- "return_type": "mjCache *",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 121
- },
- "mj_clearCache": {
- "name": "mj_clearCache",
- "return_type": "void",
- "params": [
- {
- "name": "cache",
- "c_type": "mjCache *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 124
- },
- "mj_loadXML": {
- "name": "mj_loadXML",
- "return_type": "mjModel *",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 132
- },
- "mj_parseXML": {
- "name": "mj_parseXML",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 136
- },
- "mj_parseXMLString": {
- "name": "mj_parseXMLString",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "xml",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 140
- },
- "mj_parse": {
- "name": "mj_parse",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 144
- },
- "mj_encode": {
- "name": "mj_encode",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 150
- },
- "mj_compile": {
- "name": "mj_compile",
- "return_type": "mjModel *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 156
- },
- "mj_copyBack": {
- "name": "mj_copyBack",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 159
- },
- "mj_recompile": {
- "name": "mj_recompile",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 163
- },
- "mj_saveLastXML": {
- "name": "mj_saveLastXML",
- "return_type": "int",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 168
- },
- "mj_freeLastXML": {
- "name": "mj_freeLastXML",
- "return_type": "void",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 171
- },
- "mj_saveXMLString": {
- "name": "mj_saveXMLString",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "xml",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "xml_sz",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 176
- },
- "mj_saveXML": {
- "name": "mj_saveXML",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 180
- },
- "mju_getXMLDependencies": {
- "name": "mju_getXMLDependencies",
- "return_type": "void",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "dependencies",
- "c_type": "mjStringVec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 184
- },
- "mj_step": {
- "name": "mj_step",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 189
- },
- "mj_step1": {
- "name": "mj_step1",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 192
- },
- "mj_step2": {
- "name": "mj_step2",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 195
- },
- "mj_forward": {
- "name": "mj_forward",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 198
- },
- "mj_inverse": {
- "name": "mj_inverse",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 201
- },
- "mj_forwardSkip": {
- "name": "mj_forwardSkip",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "skipstage",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "skipsensor",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 204
- },
- "mj_inverseSkip": {
- "name": "mj_inverseSkip",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "skipstage",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "skipsensor",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 207
- },
- "mj_defaultLROpt": {
- "name": "mj_defaultLROpt",
- "return_type": "void",
- "params": [
- {
- "name": "opt",
- "c_type": "mjLROpt *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 213
- },
- "mj_defaultSolRefImp": {
- "name": "mj_defaultSolRefImp",
- "return_type": "void",
- "params": [
- {
- "name": "solref",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "solimp",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 217
- },
- "mj_defaultOption": {
- "name": "mj_defaultOption",
- "return_type": "void",
- "params": [
- {
- "name": "opt",
- "c_type": "mjOption *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 220
- },
- "mj_defaultVisual": {
- "name": "mj_defaultVisual",
- "return_type": "void",
- "params": [
- {
- "name": "vis",
- "c_type": "mjVisual *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 223
- },
- "mj_copyModel": {
- "name": "mj_copyModel",
- "return_type": "mjModel *",
- "params": [
- {
- "name": "dest",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 227
- },
- "mj_saveModel": {
- "name": "mj_saveModel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "buffer",
- "c_type": "void *",
- "array_dim": null
- },
- {
- "name": "buffer_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 231
- },
- "mj_loadModel": {
- "name": "mj_loadModel",
- "return_type": "mjModel *",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 236
- },
- "mj_loadModelBuffer": {
- "name": "mj_loadModelBuffer",
- "return_type": "mjModel *",
- "params": [
- {
- "name": "buffer",
- "c_type": "const void *",
- "array_dim": null
- },
- {
- "name": "buffer_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 239
- },
- "mj_deleteModel": {
- "name": "mj_deleteModel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 242
- },
- "mj_sizeModel": {
- "name": "mj_sizeModel",
- "return_type": "mjtSize",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 245
- },
- "mj_makeData": {
- "name": "mj_makeData",
- "return_type": "mjData *",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 249
- },
- "mj_copyData": {
- "name": "mj_copyData",
- "return_type": "mjData *",
- "params": [
- {
- "name": "dest",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 253
- },
- "mjv_copyData": {
- "name": "mjv_copyData",
- "return_type": "mjData *",
- "params": [
- {
- "name": "dest",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 256
- },
- "mj_resetData": {
- "name": "mj_resetData",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 259
- },
- "mj_resetDataDebug": {
- "name": "mj_resetDataDebug",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "debug_value",
- "c_type": "unsigned char",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 262
- },
- "mj_resetDataKeyframe": {
- "name": "mj_resetDataKeyframe",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "key",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 265
- },
- "mj_markStack": {
- "name": "mj_markStack",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 270
- },
- "mj_freeStack": {
- "name": "mj_freeStack",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 274
- },
- "mj_stackAllocByte": {
- "name": "mj_stackAllocByte",
- "return_type": "void *",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "bytes",
- "c_type": "size_t",
- "array_dim": null
- },
- {
- "name": "alignment",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 280
- },
- "mj_stackAllocNum": {
- "name": "mj_stackAllocNum",
- "return_type": "mjtNum *",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 283
- },
- "mj_stackAllocInt": {
- "name": "mj_stackAllocInt",
- "return_type": "int *",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 286
- },
- "mj_deleteData": {
- "name": "mj_deleteData",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 289
- },
- "mj_resetCallbacks": {
- "name": "mj_resetCallbacks",
- "return_type": "void",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 292
- },
- "mj_setConst": {
- "name": "mj_setConst",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 295
- },
- "mj_setLengthRange": {
- "name": "mj_setLengthRange",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "index",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "opt",
- "c_type": "const mjLROpt *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "error_sz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 299
- },
- "mj_makeSpec": {
- "name": "mj_makeSpec",
- "return_type": "mjSpec *",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 303
- },
- "mj_copySpec": {
- "name": "mj_copySpec",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 306
- },
- "mj_deleteSpec": {
- "name": "mj_deleteSpec",
- "return_type": "void",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 309
- },
- "mjs_activatePlugin": {
- "name": "mjs_activatePlugin",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 312
- },
- "mjs_setDeepCopy": {
- "name": "mjs_setDeepCopy",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "deepcopy",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 315
- },
- "mj_printFormattedModel": {
- "name": "mj_printFormattedModel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "float_format",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 322
- },
- "mj_printModel": {
- "name": "mj_printModel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 325
- },
- "mj_printFormattedData": {
- "name": "mj_printFormattedData",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "float_format",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 329
- },
- "mj_printData": {
- "name": "mj_printData",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 333
- },
- "mju_printMat": {
- "name": "mju_printMat",
- "return_type": "void",
- "params": [
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 336
- },
- "mju_printMatSparse": {
- "name": "mju_printMatSparse",
- "return_type": "void",
- "params": [
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rownnz",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "rowadr",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "colind",
- "c_type": "const int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 339
- },
- "mj_printSchema": {
- "name": "mj_printSchema",
- "return_type": "int",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "buffer",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "buffer_sz",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_html",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_pad",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 343
- },
- "mj_printScene": {
- "name": "mj_printScene",
- "return_type": "void",
- "params": [
- {
- "name": "s",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 347
- },
- "mj_printFormattedScene": {
- "name": "mj_printFormattedScene",
- "return_type": "void",
- "params": [
- {
- "name": "s",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "float_format",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 351
- },
- "mj_fwdKinematics": {
- "name": "mj_fwdKinematics",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 358
- },
- "mj_fwdPosition": {
- "name": "mj_fwdPosition",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 361
- },
- "mj_fwdVelocity": {
- "name": "mj_fwdVelocity",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 364
- },
- "mj_fwdActuation": {
- "name": "mj_fwdActuation",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 367
- },
- "mj_fwdAcceleration": {
- "name": "mj_fwdAcceleration",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 370
- },
- "mj_fwdConstraint": {
- "name": "mj_fwdConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 373
- },
- "mj_Euler": {
- "name": "mj_Euler",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 376
- },
- "mj_RungeKutta": {
- "name": "mj_RungeKutta",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "N",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 379
- },
- "mj_implicit": {
- "name": "mj_implicit",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 382
- },
- "mj_invPosition": {
- "name": "mj_invPosition",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 385
- },
- "mj_invVelocity": {
- "name": "mj_invVelocity",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 388
- },
- "mj_invConstraint": {
- "name": "mj_invConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 391
- },
- "mj_compareFwdInv": {
- "name": "mj_compareFwdInv",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 394
- },
- "mj_sensorPos": {
- "name": "mj_sensorPos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 400
- },
- "mj_sensorVel": {
- "name": "mj_sensorVel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 403
- },
- "mj_sensorAcc": {
- "name": "mj_sensorAcc",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 406
- },
- "mj_energyPos": {
- "name": "mj_energyPos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 409
- },
- "mj_energyVel": {
- "name": "mj_energyVel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 412
- },
- "mj_checkPos": {
- "name": "mj_checkPos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 415
- },
- "mj_checkVel": {
- "name": "mj_checkVel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 418
- },
- "mj_checkAcc": {
- "name": "mj_checkAcc",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 421
- },
- "mj_kinematics": {
- "name": "mj_kinematics",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 424
- },
- "mj_comPos": {
- "name": "mj_comPos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 427
- },
- "mj_camlight": {
- "name": "mj_camlight",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 430
- },
- "mj_flex": {
- "name": "mj_flex",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 433
- },
- "mj_tendon": {
- "name": "mj_tendon",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 436
- },
- "mj_transmission": {
- "name": "mj_transmission",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 439
- },
- "mj_crb": {
- "name": "mj_crb",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 442
- },
- "mj_makeM": {
- "name": "mj_makeM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 445
- },
- "mj_factorM": {
- "name": "mj_factorM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 448
- },
- "mj_solveM": {
- "name": "mj_solveM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "x",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "y",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 451
- },
- "mj_solveM2": {
- "name": "mj_solveM2",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "x",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "y",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "sqrtInvD",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 454
- },
- "mj_comVel": {
- "name": "mj_comVel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 458
- },
- "mj_passive": {
- "name": "mj_passive",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 461
- },
- "mj_subtreeVel": {
- "name": "mj_subtreeVel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 464
- },
- "mj_rne": {
- "name": "mj_rne",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "flg_acc",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "result",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 467
- },
- "mj_rnePostConstraint": {
- "name": "mj_rnePostConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 470
- },
- "mj_maxContact": {
- "name": "mj_maxContact",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "g1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "g2",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "has_margin",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 475
- },
- "mj_collision": {
- "name": "mj_collision",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 478
- },
- "mj_makeConstraint": {
- "name": "mj_makeConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 481
- },
- "mj_island": {
- "name": "mj_island",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 484
- },
- "mj_projectConstraint": {
- "name": "mj_projectConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 487
- },
- "mj_referenceConstraint": {
- "name": "mj_referenceConstraint",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 490
- },
- "mj_constraintUpdate": {
- "name": "mj_constraintUpdate",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "jar",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "cost",
- "c_type": "mjtNum [1]",
- "array_dim": 1
- },
- {
- "name": "flg_coneHessian",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 495
- },
- "mj_stateSize": {
- "name": "mj_stateSize",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "sig",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 502
- },
- "mj_getState": {
- "name": "mj_getState",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "state",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "sig",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 505
- },
- "mj_extractState": {
- "name": "mj_extractState",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "srcsig",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "dst",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "dstsig",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 508
- },
- "mj_setState": {
- "name": "mj_setState",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "state",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "sig",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 512
- },
- "mj_copyState": {
- "name": "mj_copyState",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "dst",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "sig",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 515
- },
- "mj_readCtrl": {
- "name": "mj_readCtrl",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "time",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "interp",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 520
- },
- "mj_readSensor": {
- "name": "mj_readSensor",
- "return_type": "const mjtNum *",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "time",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "result",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "interp",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 526
- },
- "mj_initCtrlHistory": {
- "name": "mj_initCtrlHistory",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "times",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "values",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 531
- },
- "mj_initSensorHistory": {
- "name": "mj_initSensorHistory",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "times",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "values",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "phase",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 537
- },
- "mj_setKeyframe": {
- "name": "mj_setKeyframe",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "k",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 541
- },
- "mj_addContact": {
- "name": "mj_addContact",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjContact *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 544
- },
- "mj_isPyramidal": {
- "name": "mj_isPyramidal",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 547
- },
- "mj_isSparse": {
- "name": "mj_isSparse",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 550
- },
- "mj_isDual": {
- "name": "mj_isDual",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 553
- },
- "mj_mulJacVec": {
- "name": "mj_mulJacVec",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 556
- },
- "mj_mulJacTVec": {
- "name": "mj_mulJacTVec",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 559
- },
- "mj_jac": {
- "name": "mj_jac",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "point",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 563
- },
- "mj_jacBody": {
- "name": "mj_jacBody",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 568
- },
- "mj_jacBodyCom": {
- "name": "mj_jacBodyCom",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 572
- },
- "mj_jacSubtreeCom": {
- "name": "mj_jacSubtreeCom",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 575
- },
- "mj_jacGeom": {
- "name": "mj_jacGeom",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "geom",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 579
- },
- "mj_jacSite": {
- "name": "mj_jacSite",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "site",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 583
- },
- "mj_jacPointAxis": {
- "name": "mj_jacPointAxis",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "jacPoint",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacAxis",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "point",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "axis",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 587
- },
- "mj_jacDot": {
- "name": "mj_jacDot",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "jacp",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "jacr",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "point",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 592
- },
- "mj_angmomMat": {
- "name": "mj_angmomMat",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 596
- },
- "mj_name2id": {
- "name": "mj_name2id",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 599
- },
- "mj_id2name": {
- "name": "mj_id2name",
- "return_type": "const char *",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 602
- },
- "mj_fullM": {
- "name": "mj_fullM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "dst",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 605
- },
- "mj_mulM": {
- "name": "mj_mulM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 608
- },
- "mj_mulM2": {
- "name": "mj_mulM2",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 611
- },
- "mj_addM": {
- "name": "mj_addM",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "dst",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "rownnz",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "rowadr",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "colind",
- "c_type": "int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 616
- },
- "mj_applyFT": {
- "name": "mj_applyFT",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "force",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "torque",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "point",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "qfrc_target",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 620
- },
- "mj_objectVelocity": {
- "name": "mj_objectVelocity",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "objtype",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "objid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum [6]",
- "array_dim": 6
- },
- {
- "name": "flg_local",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 624
- },
- "mj_objectAcceleration": {
- "name": "mj_objectAcceleration",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "objtype",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "objid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "res",
- "c_type": "mjtNum [6]",
- "array_dim": 6
- },
- {
- "name": "flg_local",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 628
- },
- "mj_geomDistance": {
- "name": "mj_geomDistance",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "geom1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "geom2",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "distmax",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "fromto",
- "c_type": "mjtNum [6]",
- "array_dim": 6
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 633
- },
- "mj_contactForce": {
- "name": "mj_contactForce",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "result",
- "c_type": "mjtNum [6]",
- "array_dim": 6
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 637
- },
- "mj_differentiatePos": {
- "name": "mj_differentiatePos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "qvel",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "dt",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "qpos1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "qpos2",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 640
- },
- "mj_integratePos": {
- "name": "mj_integratePos",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "qpos",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "qvel",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "dt",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 644
- },
- "mj_normalizeQuat": {
- "name": "mj_normalizeQuat",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "qpos",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 647
- },
- "mj_local2Global": {
- "name": "mj_local2Global",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "xpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "xmat",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "pos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "body",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "sameframe",
- "c_type": "mjtByte",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 650
- },
- "mj_getTotalmass": {
- "name": "mj_getTotalmass",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 654
- },
- "mj_setTotalmass": {
- "name": "mj_setTotalmass",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "newmass",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 657
- },
- "mj_getPluginConfig": {
- "name": "mj_getPluginConfig",
- "return_type": "const char *",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "plugin_id",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "attrib",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 661
- },
- "mj_loadPluginLibrary": {
- "name": "mj_loadPluginLibrary",
- "return_type": "void",
- "params": [
- {
- "name": "path",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 664
- },
- "mj_loadAllPluginLibraries": {
- "name": "mj_loadAllPluginLibraries",
- "return_type": "void",
- "params": [
- {
- "name": "directory",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "callback",
- "c_type": "mjfPluginLibraryLoadCallback",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 669
- },
- "mj_version": {
- "name": "mj_version",
- "return_type": "int",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 672
- },
- "mj_versionString": {
- "name": "mj_versionString",
- "return_type": "const char *",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 675
- },
- "mj_ray": {
- "name": "mj_ray",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "geomgroup",
- "c_type": "const mjtByte *",
- "array_dim": null
- },
- {
- "name": "flg_static",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "bodyexclude",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "geomid",
- "c_type": "int [1]",
- "array_dim": 1
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 684
- },
- "mj_multiRay": {
- "name": "mj_multiRay",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "geomgroup",
- "c_type": "const mjtByte *",
- "array_dim": null
- },
- {
- "name": "flg_static",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "bodyexclude",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "geomid",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "dist",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "normal",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "nray",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "cutoff",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 692
- },
- "mj_rayHfield": {
- "name": "mj_rayHfield",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "geomid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 698
- },
- "mj_rayMesh": {
- "name": "mj_rayMesh",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "geomid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 703
- },
- "mju_rayGeom": {
- "name": "mju_rayGeom",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "pos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "size",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "geomtype",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 708
- },
- "mj_rayFlex": {
- "name": "mj_rayFlex",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "flex_layer",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_vert",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "flg_edge",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "flg_face",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "flg_skin",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "flexid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vertid",
- "c_type": "int [1]",
- "array_dim": 1
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 715
- },
- "mju_raySkin": {
- "name": "mju_raySkin",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "nface",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nvert",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "face",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "vert",
- "c_type": "const float *",
- "array_dim": null
- },
- {
- "name": "pnt",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vertid",
- "c_type": "int [1]",
- "array_dim": 1
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 723
- },
- "mjv_defaultCamera": {
- "name": "mjv_defaultCamera",
- "return_type": "void",
- "params": [
- {
- "name": "cam",
- "c_type": "mjvCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 729
- },
- "mjv_defaultFreeCamera": {
- "name": "mjv_defaultFreeCamera",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "mjvCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 732
- },
- "mjv_defaultPerturb": {
- "name": "mjv_defaultPerturb",
- "return_type": "void",
- "params": [
- {
- "name": "pert",
- "c_type": "mjvPerturb *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 735
- },
- "mjv_room2model": {
- "name": "mjv_room2model",
- "return_type": "void",
- "params": [
- {
- "name": "modelpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "modelquat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "roompos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "roomquat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 738
- },
- "mjv_model2room": {
- "name": "mjv_model2room",
- "return_type": "void",
- "params": [
- {
- "name": "roompos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "roomquat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "modelpos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "modelquat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 742
- },
- "mjv_cameraInModel": {
- "name": "mjv_cameraInModel",
- "return_type": "void",
- "params": [
- {
- "name": "headpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "forward",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "up",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 746
- },
- "mjv_cameraInRoom": {
- "name": "mjv_cameraInRoom",
- "return_type": "void",
- "params": [
- {
- "name": "headpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "forward",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "up",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 750
- },
- "mjv_frustumHeight": {
- "name": "mjv_frustumHeight",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 754
- },
- "mjv_alignToCamera": {
- "name": "mjv_alignToCamera",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "forward",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 757
- },
- "mjv_moveCamera": {
- "name": "mjv_moveCamera",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "action",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "reldx",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "reldy",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "mjvCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 760
- },
- "mjv_movePerturb": {
- "name": "mjv_movePerturb",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "action",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "reldx",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "reldy",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "mjvPerturb *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 764
- },
- "mjv_moveModel": {
- "name": "mjv_moveModel",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "action",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "reldx",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "reldy",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "roomup",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 768
- },
- "mjv_initPerturb": {
- "name": "mjv_initPerturb",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "mjvPerturb *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 772
- },
- "mjv_applyPerturbPose": {
- "name": "mjv_applyPerturbPose",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "const mjvPerturb *",
- "array_dim": null
- },
- {
- "name": "flg_paused",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 776
- },
- "mjv_applyPerturbForce": {
- "name": "mjv_applyPerturbForce",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "const mjvPerturb *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 780
- },
- "mjv_averageCamera": {
- "name": "mjv_averageCamera",
- "return_type": "mjvGLCamera",
- "params": [
- {
- "name": "cam1",
- "c_type": "const mjvGLCamera *",
- "array_dim": null
- },
- {
- "name": "cam2",
- "c_type": "const mjvGLCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 783
- },
- "mjv_select": {
- "name": "mjv_select",
- "return_type": "int",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "vopt",
- "c_type": "const mjvOption *",
- "array_dim": null
- },
- {
- "name": "aspectratio",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "relx",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "rely",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "const mjvScene *",
- "array_dim": null
- },
- {
- "name": "selpnt",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "geomid",
- "c_type": "int [1]",
- "array_dim": 1
- },
- {
- "name": "flexid",
- "c_type": "int [1]",
- "array_dim": 1
- },
- {
- "name": "skinid",
- "c_type": "int [1]",
- "array_dim": 1
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 787
- },
- "mjv_defaultOption": {
- "name": "mjv_defaultOption",
- "return_type": "void",
- "params": [
- {
- "name": "opt",
- "c_type": "mjvOption *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 796
- },
- "mjv_defaultFigure": {
- "name": "mjv_defaultFigure",
- "return_type": "void",
- "params": [
- {
- "name": "fig",
- "c_type": "mjvFigure *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 799
- },
- "mjv_initGeom": {
- "name": "mjv_initGeom",
- "return_type": "void",
- "params": [
- {
- "name": "geom",
- "c_type": "mjvGeom *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "pos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "rgba",
- "c_type": "const float [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 803
- },
- "mjv_connector": {
- "name": "mjv_connector",
- "return_type": "void",
- "params": [
- {
- "name": "geom",
- "c_type": "mjvGeom *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "width",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "from",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "to",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 809
- },
- "mjv_defaultScene": {
- "name": "mjv_defaultScene",
- "return_type": "void",
- "params": [
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 813
- },
- "mjv_makeScene": {
- "name": "mjv_makeScene",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- },
- {
- "name": "maxgeom",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 816
- },
- "mjv_freeScene": {
- "name": "mjv_freeScene",
- "return_type": "void",
- "params": [
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 819
- },
- "mjv_updateScene": {
- "name": "mjv_updateScene",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "opt",
- "c_type": "const mjvOption *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "const mjvPerturb *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "mjvCamera *",
- "array_dim": null
- },
- {
- "name": "catmask",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 822
- },
- "mjv_copyModel": {
- "name": "mjv_copyModel",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjModel *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const mjModel *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 827
- },
- "mjv_addGeoms": {
- "name": "mjv_addGeoms",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "opt",
- "c_type": "const mjvOption *",
- "array_dim": null
- },
- {
- "name": "pert",
- "c_type": "const mjvPerturb *",
- "array_dim": null
- },
- {
- "name": "catmask",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 830
- },
- "mjv_makeLights": {
- "name": "mjv_makeLights",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 834
- },
- "mjv_updateCamera": {
- "name": "mjv_updateCamera",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "mjvCamera *",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 837
- },
- "mjv_updateSkin": {
- "name": "mjv_updateSkin",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 840
- },
- "mjv_cameraFrame": {
- "name": "mjv_cameraFrame",
- "return_type": "void",
- "params": [
- {
- "name": "headpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "forward",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "up",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "right",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "const mjvCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 844
- },
- "mjv_cameraFrustum": {
- "name": "mjv_cameraFrustum",
- "return_type": "void",
- "params": [
- {
- "name": "zver",
- "c_type": "float [2]",
- "array_dim": 2
- },
- {
- "name": "zhor",
- "c_type": "float [2]",
- "array_dim": 2
- },
- {
- "name": "zclip",
- "c_type": "float [2]",
- "array_dim": 2
- },
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "cam",
- "c_type": "const mjvCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 849
- },
- "mjr_defaultContext": {
- "name": "mjr_defaultContext",
- "return_type": "void",
- "params": [
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 856
- },
- "mjr_makeContext": {
- "name": "mjr_makeContext",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- },
- {
- "name": "fontscale",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 859
- },
- "mjr_changeFont": {
- "name": "mjr_changeFont",
- "return_type": "void",
- "params": [
- {
- "name": "fontscale",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 862
- },
- "mjr_addAux": {
- "name": "mjr_addAux",
- "return_type": "void",
- "params": [
- {
- "name": "index",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "width",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "height",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "samples",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 865
- },
- "mjr_freeContext": {
- "name": "mjr_freeContext",
- "return_type": "void",
- "params": [
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 868
- },
- "mjr_resizeOffscreen": {
- "name": "mjr_resizeOffscreen",
- "return_type": "void",
- "params": [
- {
- "name": "width",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "height",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 871
- },
- "mjr_uploadTexture": {
- "name": "mjr_uploadTexture",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- },
- {
- "name": "texid",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 874
- },
- "mjr_uploadMesh": {
- "name": "mjr_uploadMesh",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- },
- {
- "name": "meshid",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 877
- },
- "mjr_uploadHField": {
- "name": "mjr_uploadHField",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- },
- {
- "name": "hfieldid",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 880
- },
- "mjr_restoreBuffer": {
- "name": "mjr_restoreBuffer",
- "return_type": "void",
- "params": [
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 883
- },
- "mjr_setBuffer": {
- "name": "mjr_setBuffer",
- "return_type": "void",
- "params": [
- {
- "name": "framebuffer",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 887
- },
- "mjr_readPixels": {
- "name": "mjr_readPixels",
- "return_type": "void",
- "params": [
- {
- "name": "rgb",
- "c_type": "unsigned char *",
- "array_dim": null
- },
- {
- "name": "depth",
- "c_type": "float *",
- "array_dim": null
- },
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 891
- },
- "mjr_drawPixels": {
- "name": "mjr_drawPixels",
- "return_type": "void",
- "params": [
- {
- "name": "rgb",
- "c_type": "const unsigned char *",
- "array_dim": null
- },
- {
- "name": "depth",
- "c_type": "const float *",
- "array_dim": null
- },
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 896
- },
- "mjr_blitBuffer": {
- "name": "mjr_blitBuffer",
- "return_type": "void",
- "params": [
- {
- "name": "src",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "dst",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "flg_color",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_depth",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 901
- },
- "mjr_setAux": {
- "name": "mjr_setAux",
- "return_type": "void",
- "params": [
- {
- "name": "index",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 905
- },
- "mjr_blitAux": {
- "name": "mjr_blitAux",
- "return_type": "void",
- "params": [
- {
- "name": "index",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "left",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "bottom",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 908
- },
- "mjr_text": {
- "name": "mjr_text",
- "return_type": "void",
- "params": [
- {
- "name": "font",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "txt",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- },
- {
- "name": "x",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "y",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "r",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "g",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "b",
- "c_type": "float",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 911
- },
- "mjr_overlay": {
- "name": "mjr_overlay",
- "return_type": "void",
- "params": [
- {
- "name": "font",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "gridpos",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "overlay",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "overlay2",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 915
- },
- "mjr_maxViewport": {
- "name": "mjr_maxViewport",
- "return_type": "mjrRect",
- "params": [
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 919
- },
- "mjr_rectangle": {
- "name": "mjr_rectangle",
- "return_type": "void",
- "params": [
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "r",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "g",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "b",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "a",
- "c_type": "float",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 922
- },
- "mjr_label": {
- "name": "mjr_label",
- "return_type": "void",
- "params": [
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "font",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "txt",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "r",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "g",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "b",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "a",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "rt",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "gt",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "bt",
- "c_type": "float",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 925
- },
- "mjr_figure": {
- "name": "mjr_figure",
- "return_type": "void",
- "params": [
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "fig",
- "c_type": "mjvFigure *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 930
- },
- "mjr_render": {
- "name": "mjr_render",
- "return_type": "void",
- "params": [
- {
- "name": "viewport",
- "c_type": "mjrRect",
- "array_dim": null
- },
- {
- "name": "scn",
- "c_type": "mjvScene *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 933
- },
- "mjr_finish": {
- "name": "mjr_finish",
- "return_type": "void",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 936
- },
- "mjr_getError": {
- "name": "mjr_getError",
- "return_type": "int",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 939
- },
- "mjr_findRect": {
- "name": "mjr_findRect",
- "return_type": "int",
- "params": [
- {
- "name": "x",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "y",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nrect",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rect",
- "c_type": "const mjrRect *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 942
- },
- "mjui_themeSpacing": {
- "name": "mjui_themeSpacing",
- "return_type": "mjuiThemeSpacing",
- "params": [
- {
- "name": "ind",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 948
- },
- "mjui_themeColor": {
- "name": "mjui_themeColor",
- "return_type": "mjuiThemeColor",
- "params": [
- {
- "name": "ind",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 951
- },
- "mjui_add": {
- "name": "mjui_add",
- "return_type": "void",
- "params": [
- {
- "name": "ui",
- "c_type": "mjUI *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjuiDef *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 954
- },
- "mjui_addToSection": {
- "name": "mjui_addToSection",
- "return_type": "void",
- "params": [
- {
- "name": "ui",
- "c_type": "mjUI *",
- "array_dim": null
- },
- {
- "name": "sect",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjuiDef *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 957
- },
- "mjui_resize": {
- "name": "mjui_resize",
- "return_type": "void",
- "params": [
- {
- "name": "ui",
- "c_type": "mjUI *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 960
- },
- "mjui_update": {
- "name": "mjui_update",
- "return_type": "void",
- "params": [
- {
- "name": "section",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "item",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ui",
- "c_type": "const mjUI *",
- "array_dim": null
- },
- {
- "name": "state",
- "c_type": "const mjuiState *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 963
- },
- "mjui_event": {
- "name": "mjui_event",
- "return_type": "mjuiItem *",
- "params": [
- {
- "name": "ui",
- "c_type": "mjUI *",
- "array_dim": null
- },
- {
- "name": "state",
- "c_type": "mjuiState *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 967
- },
- "mjui_render": {
- "name": "mjui_render",
- "return_type": "void",
- "params": [
- {
- "name": "ui",
- "c_type": "mjUI *",
- "array_dim": null
- },
- {
- "name": "state",
- "c_type": "const mjuiState *",
- "array_dim": null
- },
- {
- "name": "con",
- "c_type": "const mjrContext *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 970
- },
- "mju_error": {
- "name": "mju_error",
- "return_type": "void",
- "params": [
- {
- "name": "msg",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 976
- },
- "mju_warning": {
- "name": "mju_warning",
- "return_type": "void",
- "params": [
- {
- "name": "msg",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 979
- },
- "mju_clearHandlers": {
- "name": "mju_clearHandlers",
- "return_type": "void",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 982
- },
- "mju_setLogHandler": {
- "name": "mju_setLogHandler",
- "return_type": "mjfLogHandler",
- "params": [
- {
- "name": "handler",
- "c_type": "mjfLogHandler",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 986
- },
- "mju_getLogConfig": {
- "name": "mju_getLogConfig",
- "return_type": "mjLogConfig",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 989
- },
- "mju_setLogConfig": {
- "name": "mju_setLogConfig",
- "return_type": "void",
- "params": [
- {
- "name": "config",
- "c_type": "mjLogConfig",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 992
- },
- "mju_info": {
- "name": "mju_info",
- "return_type": "void",
- "params": [
- {
- "name": "topic",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "msg",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 995
- },
- "mju_message": {
- "name": "mju_message",
- "return_type": "void",
- "params": [
- {
- "name": "msg",
- "c_type": "const mjLogMessage *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 998
- },
- "mju_malloc": {
- "name": "mju_malloc",
- "return_type": "void *",
- "params": [
- {
- "name": "size",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1001
- },
- "mju_free": {
- "name": "mju_free",
- "return_type": "void",
- "params": [
- {
- "name": "ptr",
- "c_type": "void *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1004
- },
- "mj_warning": {
- "name": "mj_warning",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "warning",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "info",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1007
- },
- "mju_writeLog": {
- "name": "mju_writeLog",
- "return_type": "void",
- "params": [
- {
- "name": "type",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "msg",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1010
- },
- "mjs_getError": {
- "name": "mjs_getError",
- "return_type": "const char *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1013
- },
- "mjs_getTimer": {
- "name": "mjs_getTimer",
- "return_type": "const double *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1016
- },
- "mjs_isWarning": {
- "name": "mjs_isWarning",
- "return_type": "int",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1019
- },
- "mju_zero3": {
- "name": "mju_zero3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1063
- },
- "mju_copy3": {
- "name": "mju_copy3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "data",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1066
- },
- "mju_scl3": {
- "name": "mju_scl3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1069
- },
- "mju_add3": {
- "name": "mju_add3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1072
- },
- "mju_sub3": {
- "name": "mju_sub3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1075
- },
- "mju_addTo3": {
- "name": "mju_addTo3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1078
- },
- "mju_subFrom3": {
- "name": "mju_subFrom3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1081
- },
- "mju_addToScl3": {
- "name": "mju_addToScl3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1084
- },
- "mju_addScl3": {
- "name": "mju_addScl3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1087
- },
- "mju_normalize3": {
- "name": "mju_normalize3",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1090
- },
- "mju_norm3": {
- "name": "mju_norm3",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1093
- },
- "mju_dot3": {
- "name": "mju_dot3",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1096
- },
- "mju_dist3": {
- "name": "mju_dist3",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "pos1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "pos2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1099
- },
- "mju_mulMatVec3": {
- "name": "mju_mulMatVec3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1102
- },
- "mju_mulMatTVec3": {
- "name": "mju_mulMatTVec3",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1105
- },
- "mju_cross": {
- "name": "mju_cross",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "a",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "b",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1108
- },
- "mju_zero4": {
- "name": "mju_zero4",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1111
- },
- "mju_unit4": {
- "name": "mju_unit4",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1114
- },
- "mju_copy4": {
- "name": "mju_copy4",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "data",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1117
- },
- "mju_normalize4": {
- "name": "mju_normalize4",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1120
- },
- "mju_zero": {
- "name": "mju_zero",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1123
- },
- "mju_fill": {
- "name": "mju_fill",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "val",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1126
- },
- "mju_copy": {
- "name": "mju_copy",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1129
- },
- "mju_sum": {
- "name": "mju_sum",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1132
- },
- "mju_L1": {
- "name": "mju_L1",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1135
- },
- "mju_scl": {
- "name": "mju_scl",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1138
- },
- "mju_add": {
- "name": "mju_add",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1141
- },
- "mju_sub": {
- "name": "mju_sub",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1144
- },
- "mju_addTo": {
- "name": "mju_addTo",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1147
- },
- "mju_subFrom": {
- "name": "mju_subFrom",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1150
- },
- "mju_addToScl": {
- "name": "mju_addToScl",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1153
- },
- "mju_addScl": {
- "name": "mju_addScl",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "scl",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1156
- },
- "mju_normalize": {
- "name": "mju_normalize",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1159
- },
- "mju_norm": {
- "name": "mju_norm",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "res",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1162
- },
- "mju_dot": {
- "name": "mju_dot",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1165
- },
- "mju_mulMatVec": {
- "name": "mju_mulMatVec",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1168
- },
- "mju_mulMatTVec": {
- "name": "mju_mulMatTVec",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1171
- },
- "mju_mulVecMatVec": {
- "name": "mju_mulVecMatVec",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "vec1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1174
- },
- "mju_transpose": {
- "name": "mju_transpose",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1177
- },
- "mju_symmetrize": {
- "name": "mju_symmetrize",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1180
- },
- "mju_eye": {
- "name": "mju_eye",
- "return_type": "void",
- "params": [
- {
- "name": "mat",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1183
- },
- "mju_mulMatMat": {
- "name": "mju_mulMatMat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "r1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "c1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "c2",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1186
- },
- "mju_mulMatMatT": {
- "name": "mju_mulMatMatT",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "r1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "c1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "r2",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1190
- },
- "mju_mulMatTMat": {
- "name": "mju_mulMatTMat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat1",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat2",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "r1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "c1",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "c2",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1194
- },
- "mju_sqrMatTD": {
- "name": "mju_sqrMatTD",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "diag",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1198
- },
- "mju_transformSpatial": {
- "name": "mju_transformSpatial",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [6]",
- "array_dim": 6
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [6]",
- "array_dim": 6
- },
- {
- "name": "flg_force",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "newpos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "oldpos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "rotnew2old",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1203
- },
- "mju_dense2sparse": {
- "name": "mju_dense2sparse",
- "return_type": "int",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rownnz",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "rowadr",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "colind",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "nnz",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1212
- },
- "mju_sparse2dense": {
- "name": "mju_sparse2dense",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "nr",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nc",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rownnz",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "rowadr",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "colind",
- "c_type": "const int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1216
- },
- "mju_sym2dense": {
- "name": "mju_sym2dense",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rownnz",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "rowadr",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "colind",
- "c_type": "const int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1220
- },
- "mju_rotVecQuat": {
- "name": "mju_rotVecQuat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1227
- },
- "mju_negQuat": {
- "name": "mju_negQuat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1230
- },
- "mju_mulQuat": {
- "name": "mju_mulQuat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "quat1",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "quat2",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1233
- },
- "mju_mulQuatAxis": {
- "name": "mju_mulQuatAxis",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "axis",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1236
- },
- "mju_axisAngle2Quat": {
- "name": "mju_axisAngle2Quat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "axis",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "angle",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1239
- },
- "mju_quat2Vel": {
- "name": "mju_quat2Vel",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "dt",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1242
- },
- "mju_subQuat": {
- "name": "mju_subQuat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "qa",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "qb",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1245
- },
- "mju_quat2Mat": {
- "name": "mju_quat2Mat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1248
- },
- "mju_mat2Quat": {
- "name": "mju_mat2Quat",
- "return_type": "void",
- "params": [
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1251
- },
- "mju_derivQuat": {
- "name": "mju_derivQuat",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "vel",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1254
- },
- "mju_quatIntegrate": {
- "name": "mju_quatIntegrate",
- "return_type": "void",
- "params": [
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "vel",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scale",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1257
- },
- "mju_quatZ2Vec": {
- "name": "mju_quatZ2Vec",
- "return_type": "void",
- "params": [
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1260
- },
- "mju_mat2Rot": {
- "name": "mju_mat2Rot",
- "return_type": "int",
- "params": [
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1264
- },
- "mju_euler2Quat": {
- "name": "mju_euler2Quat",
- "return_type": "void",
- "params": [
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "euler",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "seq",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1268
- },
- "mju_mulPose": {
- "name": "mju_mulPose",
- "return_type": "void",
- "params": [
- {
- "name": "posres",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quatres",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "pos1",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat1",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "pos2",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat2",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1274
- },
- "mju_negPose": {
- "name": "mju_negPose",
- "return_type": "void",
- "params": [
- {
- "name": "posres",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quatres",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "pos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1279
- },
- "mju_trnVecPose": {
- "name": "mju_trnVecPose",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "pos",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "vec",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1283
- },
- "mju_cholFactor": {
- "name": "mju_cholFactor",
- "return_type": "int",
- "params": [
- {
- "name": "mat",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "mindiag",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1290
- },
- "mju_cholSolve": {
- "name": "mju_cholSolve",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1293
- },
- "mju_cholUpdate": {
- "name": "mju_cholUpdate",
- "return_type": "int",
- "params": [
- {
- "name": "mat",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "x",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_plus",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1296
- },
- "mju_cholFactorBand": {
- "name": "mju_cholFactorBand",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "mat",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "diagadd",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "diagmul",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1304
- },
- "mju_cholSolveBand": {
- "name": "mju_cholSolveBand",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1308
- },
- "mju_band2Dense": {
- "name": "mju_band2Dense",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_sym",
- "c_type": "mjtBool",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1312
- },
- "mju_dense2Band": {
- "name": "mju_dense2Band",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1316
- },
- "mju_bandMulMatVec": {
- "name": "mju_bandMulMatVec",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "mat",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nvec",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flg_sym",
- "c_type": "mjtBool",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1319
- },
- "mju_bandDiag": {
- "name": "mju_bandDiag",
- "return_type": "int",
- "params": [
- {
- "name": "i",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ntotal",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "nband",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "ndense",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1323
- },
- "mju_eig3": {
- "name": "mju_eig3",
- "return_type": "int",
- "params": [
- {
- "name": "eigval",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "eigvec",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "quat",
- "c_type": "mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "mat",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1326
- },
- "mju_boxQP": {
- "name": "mju_boxQP",
- "return_type": "int",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "R",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "index",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "H",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "g",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "lower",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "upper",
- "c_type": "const mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1350
- },
- "mju_boxQPmalloc": {
- "name": "mju_boxQPmalloc",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum **",
- "array_dim": null
- },
- {
- "name": "R",
- "c_type": "mjtNum **",
- "array_dim": null
- },
- {
- "name": "index",
- "c_type": "int **",
- "array_dim": null
- },
- {
- "name": "H",
- "c_type": "mjtNum **",
- "array_dim": null
- },
- {
- "name": "g",
- "c_type": "mjtNum **",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "lower",
- "c_type": "mjtNum **",
- "array_dim": null
- },
- {
- "name": "upper",
- "c_type": "mjtNum **",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1356
- },
- "mju_muscleGain": {
- "name": "mju_muscleGain",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "len",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "vel",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "lengthrange",
- "c_type": "const mjtNum [2]",
- "array_dim": 2
- },
- {
- "name": "acc0",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "prm",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1363
- },
- "mju_muscleBias": {
- "name": "mju_muscleBias",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "len",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "lengthrange",
- "c_type": "const mjtNum [2]",
- "array_dim": 2
- },
- {
- "name": "acc0",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "prm",
- "c_type": "const mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1367
- },
- "mju_muscleDynamics": {
- "name": "mju_muscleDynamics",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "ctrl",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "act",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "prm",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1371
- },
- "mju_encodePyramid": {
- "name": "mju_encodePyramid",
- "return_type": "void",
- "params": [
- {
- "name": "pyramid",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "force",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mu",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1374
- },
- "mju_decodePyramid": {
- "name": "mju_decodePyramid",
- "return_type": "void",
- "params": [
- {
- "name": "force",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "pyramid",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "mu",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1377
- },
- "mju_springDamper": {
- "name": "mju_springDamper",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "pos0",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "vel0",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "Kp",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "Kv",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "dt",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1380
- },
- "mju_min": {
- "name": "mju_min",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "a",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "b",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1383
- },
- "mju_max": {
- "name": "mju_max",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "a",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "b",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1386
- },
- "mju_clip": {
- "name": "mju_clip",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "x",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "min",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "max",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1389
- },
- "mju_sign": {
- "name": "mju_sign",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "x",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1392
- },
- "mju_round": {
- "name": "mju_round",
- "return_type": "int",
- "params": [
- {
- "name": "x",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1395
- },
- "mju_type2Str": {
- "name": "mju_type2Str",
- "return_type": "const char *",
- "params": [
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1398
- },
- "mju_str2Type": {
- "name": "mju_str2Type",
- "return_type": "int",
- "params": [
- {
- "name": "str",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1401
- },
- "mju_writeNumBytes": {
- "name": "mju_writeNumBytes",
- "return_type": "const char *",
- "params": [
- {
- "name": "nbytes",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1404
- },
- "mju_warningText": {
- "name": "mju_warningText",
- "return_type": "const char *",
- "params": [
- {
- "name": "warning",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "info",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1407
- },
- "mju_isBad": {
- "name": "mju_isBad",
- "return_type": "int",
- "params": [
- {
- "name": "x",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1410
- },
- "mju_isZero": {
- "name": "mju_isZero",
- "return_type": "int",
- "params": [
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1413
- },
- "mju_standardNormal": {
- "name": "mju_standardNormal",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "num2",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1416
- },
- "mju_f2n": {
- "name": "mju_f2n",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const float *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1419
- },
- "mju_n2f": {
- "name": "mju_n2f",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "float *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1422
- },
- "mju_d2n": {
- "name": "mju_d2n",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const double *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1425
- },
- "mju_n2d": {
- "name": "mju_n2d",
- "return_type": "void",
- "params": [
- {
- "name": "res",
- "c_type": "double *",
- "array_dim": null
- },
- {
- "name": "vec",
- "c_type": "const mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1428
- },
- "mju_insertionSort": {
- "name": "mju_insertionSort",
- "return_type": "void",
- "params": [
- {
- "name": "list",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1431
- },
- "mju_insertionSortInt": {
- "name": "mju_insertionSortInt",
- "return_type": "void",
- "params": [
- {
- "name": "list",
- "c_type": "int *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1434
- },
- "mju_Halton": {
- "name": "mju_Halton",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "index",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "base",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1437
- },
- "mju_strncpy": {
- "name": "mju_strncpy",
- "return_type": "char *",
- "params": [
- {
- "name": "dst",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "src",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "n",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1440
- },
- "mju_sigmoid": {
- "name": "mju_sigmoid",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "x",
- "c_type": "mjtNum",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1443
- },
- "mjc_getSDF": {
- "name": "mjc_getSDF",
- "return_type": "const mjpPlugin *",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1449
- },
- "mjc_distance": {
- "name": "mjc_distance",
- "return_type": "mjtNum",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "s",
- "c_type": "const mjSDF *",
- "array_dim": null
- },
- {
- "name": "x",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1452
- },
- "mjc_gradient": {
- "name": "mjc_gradient",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "const mjData *",
- "array_dim": null
- },
- {
- "name": "s",
- "c_type": "const mjSDF *",
- "array_dim": null
- },
- {
- "name": "gradient",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "x",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1455
- },
- "mjd_transitionFD": {
- "name": "mjd_transitionFD",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "eps",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "flg_centered",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "A",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "B",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "C",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "D",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1470
- },
- "mjd_inverseFD": {
- "name": "mjd_inverseFD",
- "return_type": "void",
- "params": [
- {
- "name": "m",
- "c_type": "const mjModel *",
- "array_dim": null
- },
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "eps",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "flg_actuation",
- "c_type": "mjtBool",
- "array_dim": null
- },
- {
- "name": "DfDq",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DfDv",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DfDa",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DsDq",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DsDv",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DsDa",
- "c_type": "mjtNum *",
- "array_dim": null
- },
- {
- "name": "DmDq",
- "c_type": "mjtNum *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1489
- },
- "mjd_subQuat": {
- "name": "mjd_subQuat",
- "return_type": "void",
- "params": [
- {
- "name": "qa",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "qb",
- "c_type": "const mjtNum [4]",
- "array_dim": 4
- },
- {
- "name": "Da",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "Db",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1496
- },
- "mjd_quatIntegrate": {
- "name": "mjd_quatIntegrate",
- "return_type": "void",
- "params": [
- {
- "name": "vel",
- "c_type": "const mjtNum [3]",
- "array_dim": 3
- },
- {
- "name": "scale",
- "c_type": "mjtNum",
- "array_dim": null
- },
- {
- "name": "Dquat",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "Dvel",
- "c_type": "mjtNum [9]",
- "array_dim": 9
- },
- {
- "name": "Dscale",
- "c_type": "mjtNum [3]",
- "array_dim": 3
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1500
- },
- "mjp_defaultPlugin": {
- "name": "mjp_defaultPlugin",
- "return_type": "void",
- "params": [
- {
- "name": "plugin",
- "c_type": "mjpPlugin *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1507
- },
- "mjp_registerPlugin": {
- "name": "mjp_registerPlugin",
- "return_type": "int",
- "params": [
- {
- "name": "plugin",
- "c_type": "const mjpPlugin *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1515
- },
- "mjp_pluginCount": {
- "name": "mjp_pluginCount",
- "return_type": "int",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1518
- },
- "mjp_getPlugin": {
- "name": "mjp_getPlugin",
- "return_type": "const mjpPlugin *",
- "params": [
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "slot",
- "c_type": "int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1521
- },
- "mjp_getPluginAtSlot": {
- "name": "mjp_getPluginAtSlot",
- "return_type": "const mjpPlugin *",
- "params": [
- {
- "name": "slot",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1524
- },
- "mjp_defaultResourceProvider": {
- "name": "mjp_defaultResourceProvider",
- "return_type": "void",
- "params": [
- {
- "name": "provider",
- "c_type": "mjpResourceProvider *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1527
- },
- "mjp_registerResourceProvider": {
- "name": "mjp_registerResourceProvider",
- "return_type": "int",
- "params": [
- {
- "name": "provider",
- "c_type": "const mjpResourceProvider *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1532
- },
- "mjp_resourceProviderCount": {
- "name": "mjp_resourceProviderCount",
- "return_type": "int",
- "params": [],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1535
- },
- "mjp_getResourceProvider": {
- "name": "mjp_getResourceProvider",
- "return_type": "const mjpResourceProvider *",
- "params": [
- {
- "name": "resource_name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1539
- },
- "mjp_getResourceProviderAtSlot": {
- "name": "mjp_getResourceProviderAtSlot",
- "return_type": "const mjpResourceProvider *",
- "params": [
- {
- "name": "slot",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1543
- },
- "mjp_registerDecoder": {
- "name": "mjp_registerDecoder",
- "return_type": "void",
- "params": [
- {
- "name": "decoder",
- "c_type": "const mjpDecoder *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1548
- },
- "mjp_defaultDecoder": {
- "name": "mjp_defaultDecoder",
- "return_type": "void",
- "params": [
- {
- "name": "decoder",
- "c_type": "mjpDecoder *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1551
- },
- "mjp_findDecoder": {
- "name": "mjp_findDecoder",
- "return_type": "const mjpDecoder *",
- "params": [
- {
- "name": "resource",
- "c_type": "const mjResource *",
- "array_dim": null
- },
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1555
- },
- "mjp_registerEncoder": {
- "name": "mjp_registerEncoder",
- "return_type": "void",
- "params": [
- {
- "name": "encoder",
- "c_type": "const mjpEncoder *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1560
- },
- "mjp_defaultEncoder": {
- "name": "mjp_defaultEncoder",
- "return_type": "void",
- "params": [
- {
- "name": "encoder",
- "c_type": "mjpEncoder *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1563
- },
- "mjp_findEncoder": {
- "name": "mjp_findEncoder",
- "return_type": "const mjpEncoder *",
- "params": [
- {
- "name": "filename",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1567
- },
- "mju_openResource": {
- "name": "mju_openResource",
- "return_type": "mjResource *",
- "params": [
- {
- "name": "dir",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- },
- {
- "name": "error",
- "c_type": "char *",
- "array_dim": null
- },
- {
- "name": "nerror",
- "c_type": "size_t",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1576
- },
- "mju_closeResource": {
- "name": "mju_closeResource",
- "return_type": "void",
- "params": [
- {
- "name": "resource",
- "c_type": "mjResource *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1580
- },
- "mju_readResource": {
- "name": "mju_readResource",
- "return_type": "int",
- "params": [
- {
- "name": "resource",
- "c_type": "mjResource *",
- "array_dim": null
- },
- {
- "name": "buffer",
- "c_type": "const void **",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1584
- },
- "mju_getResourceDir": {
- "name": "mju_getResourceDir",
- "return_type": "void",
- "params": [
- {
- "name": "resource",
- "c_type": "mjResource *",
- "array_dim": null
- },
- {
- "name": "dir",
- "c_type": "const char **",
- "array_dim": null
- },
- {
- "name": "ndir",
- "c_type": "int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1587
- },
- "mju_isModifiedResource": {
- "name": "mju_isModifiedResource",
- "return_type": "int",
- "params": [
- {
- "name": "resource",
- "c_type": "const mjResource *",
- "array_dim": null
- },
- {
- "name": "timestamp",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1591
- },
- "mju_decodeResource": {
- "name": "mju_decodeResource",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "resource",
- "c_type": "mjResource *",
- "array_dim": null
- },
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1596
- },
- "mju_threadpool": {
- "name": "mju_threadpool",
- "return_type": "void",
- "params": [
- {
- "name": "d",
- "c_type": "mjData *",
- "array_dim": null
- },
- {
- "name": "nthread",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1603
- },
- "mjs_attach": {
- "name": "mjs_attach",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "parent",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "child",
- "c_type": "const mjsElement *",
- "array_dim": null
- },
- {
- "name": "prefix",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "suffix",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1609
- },
- "mjs_addBody": {
- "name": "mjs_addBody",
- "return_type": "mjsBody *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1617
- },
- "mjs_addSite": {
- "name": "mjs_addSite",
- "return_type": "mjsSite *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1621
- },
- "mjs_addJoint": {
- "name": "mjs_addJoint",
- "return_type": "mjsJoint *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1625
- },
- "mjs_addFreeJoint": {
- "name": "mjs_addFreeJoint",
- "return_type": "mjsJoint *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1628
- },
- "mjs_addGeom": {
- "name": "mjs_addGeom",
- "return_type": "mjsGeom *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1632
- },
- "mjs_addCamera": {
- "name": "mjs_addCamera",
- "return_type": "mjsCamera *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1636
- },
- "mjs_addLight": {
- "name": "mjs_addLight",
- "return_type": "mjsLight *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1640
- },
- "mjs_addFrame": {
- "name": "mjs_addFrame",
- "return_type": "mjsFrame *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "parentframe",
- "c_type": "mjsFrame *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1643
- },
- "mjs_delete": {
- "name": "mjs_delete",
- "return_type": "int",
- "params": [
- {
- "name": "spec",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1646
- },
- "mjs_addActuator": {
- "name": "mjs_addActuator",
- "return_type": "mjsActuator *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1653
- },
- "mjs_addSensor": {
- "name": "mjs_addSensor",
- "return_type": "mjsSensor *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1656
- },
- "mjs_addFlex": {
- "name": "mjs_addFlex",
- "return_type": "mjsFlex *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1659
- },
- "mjs_makeFlex": {
- "name": "mjs_makeFlex",
- "return_type": "mjsFlex *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "dof",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "count",
- "c_type": "const int [3]",
- "array_dim": 3
- },
- {
- "name": "cellcount",
- "c_type": "const int [3]",
- "array_dim": 3
- },
- {
- "name": "spacing",
- "c_type": "const double [3]",
- "array_dim": 3
- },
- {
- "name": "scale",
- "c_type": "const double [3]",
- "array_dim": 3
- },
- {
- "name": "radius",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "mass",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "inertiabox",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "equality",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "rigid",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "flatskin",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "elastic2d",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "pos",
- "c_type": "const double [3]",
- "array_dim": 3
- },
- {
- "name": "quat",
- "c_type": "const double [4]",
- "array_dim": 4
- },
- {
- "name": "origin",
- "c_type": "const double [3]",
- "array_dim": 3
- },
- {
- "name": "file",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "vfs",
- "c_type": "const mjVFS *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1663
- },
- "mjs_addPair": {
- "name": "mjs_addPair",
- "return_type": "mjsPair *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1672
- },
- "mjs_addExclude": {
- "name": "mjs_addExclude",
- "return_type": "mjsExclude *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1675
- },
- "mjs_addEquality": {
- "name": "mjs_addEquality",
- "return_type": "mjsEquality *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1679
- },
- "mjs_addTendon": {
- "name": "mjs_addTendon",
- "return_type": "mjsTendon *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1683
- },
- "mjs_wrapSite": {
- "name": "mjs_wrapSite",
- "return_type": "mjsWrap *",
- "params": [
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1686
- },
- "mjs_wrapGeom": {
- "name": "mjs_wrapGeom",
- "return_type": "mjsWrap *",
- "params": [
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "sidesite",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1689
- },
- "mjs_wrapJoint": {
- "name": "mjs_wrapJoint",
- "return_type": "mjsWrap *",
- "params": [
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "coef",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1692
- },
- "mjs_wrapPulley": {
- "name": "mjs_wrapPulley",
- "return_type": "mjsWrap *",
- "params": [
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null
- },
- {
- "name": "divisor",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1695
- },
- "mjs_addNumeric": {
- "name": "mjs_addNumeric",
- "return_type": "mjsNumeric *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1698
- },
- "mjs_addText": {
- "name": "mjs_addText",
- "return_type": "mjsText *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1701
- },
- "mjs_addTuple": {
- "name": "mjs_addTuple",
- "return_type": "mjsTuple *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1704
- },
- "mjs_addKey": {
- "name": "mjs_addKey",
- "return_type": "mjsKey *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1707
- },
- "mjs_addPlugin": {
- "name": "mjs_addPlugin",
- "return_type": "mjsPlugin *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1710
- },
- "mjs_addDefault": {
- "name": "mjs_addDefault",
- "return_type": "mjsDefault *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "classname",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "parent",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1714
- },
- "mjs_setToMotor": {
- "name": "mjs_setToMotor",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1720
- },
- "mjs_setToPosition": {
- "name": "mjs_setToPosition",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "kp",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "kv",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "dampratio",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "timeconst",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "inheritrange",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1723
- },
- "mjs_setToIntVelocity": {
- "name": "mjs_setToIntVelocity",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "kp",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "kv",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "dampratio",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "timeconst",
- "c_type": "double [1]",
- "array_dim": 1
- },
- {
- "name": "inheritrange",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1727
- },
- "mjs_setToVelocity": {
- "name": "mjs_setToVelocity",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "kv",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1731
- },
- "mjs_setToDamper": {
- "name": "mjs_setToDamper",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "kv",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1734
- },
- "mjs_setToCylinder": {
- "name": "mjs_setToCylinder",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "timeconst",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "bias",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "area",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "diameter",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1737
- },
- "mjs_setToMuscle": {
- "name": "mjs_setToMuscle",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "timeconst",
- "c_type": "double [2]",
- "array_dim": 2
- },
- {
- "name": "tausmooth",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "range",
- "c_type": "double [2]",
- "array_dim": 2
- },
- {
- "name": "force",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "scale",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "lmin",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "lmax",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "vmax",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "fpmax",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "fvmax",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1741
- },
- "mjs_setToAdhesion": {
- "name": "mjs_setToAdhesion",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "gain",
- "c_type": "double",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1746
- },
- "mjs_setToDCMotor": {
- "name": "mjs_setToDCMotor",
- "return_type": "const char *",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- },
- {
- "name": "motorconst",
- "c_type": "double [2]",
- "array_dim": 2
- },
- {
- "name": "resistance",
- "c_type": "double",
- "array_dim": null
- },
- {
- "name": "nominal",
- "c_type": "double [3]",
- "array_dim": 3
- },
- {
- "name": "saturation",
- "c_type": "double [3]",
- "array_dim": 3
- },
- {
- "name": "inductance",
- "c_type": "double [2]",
- "array_dim": 2
- },
- {
- "name": "cogging",
- "c_type": "double [3]",
- "array_dim": 3
- },
- {
- "name": "controller",
- "c_type": "double [6]",
- "array_dim": 6
- },
- {
- "name": "thermal",
- "c_type": "double [6]",
- "array_dim": 6
- },
- {
- "name": "lugre",
- "c_type": "double [5]",
- "array_dim": 5
- },
- {
- "name": "input_mode",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1750
- },
- "mjs_addMesh": {
- "name": "mjs_addMesh",
- "return_type": "mjsMesh *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1760
- },
- "mjs_addHField": {
- "name": "mjs_addHField",
- "return_type": "mjsHField *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1763
- },
- "mjs_addSkin": {
- "name": "mjs_addSkin",
- "return_type": "mjsSkin *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1766
- },
- "mjs_addTexture": {
- "name": "mjs_addTexture",
- "return_type": "mjsTexture *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1769
- },
- "mjs_addMaterial": {
- "name": "mjs_addMaterial",
- "return_type": "mjsMaterial *",
- "params": [
- {
- "name": "s",
- "c_type": "mjSpec *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1773
- },
- "mjs_makeMesh": {
- "name": "mjs_makeMesh",
- "return_type": "int",
- "params": [
- {
- "name": "mesh",
- "c_type": "mjsMesh *",
- "array_dim": null
- },
- {
- "name": "builtin",
- "c_type": "mjtMeshBuiltin",
- "array_dim": null
- },
- {
- "name": "params",
- "c_type": "double *",
- "array_dim": null
- },
- {
- "name": "nparams",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1776
- },
- "mjs_getSpec": {
- "name": "mjs_getSpec",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1781
- },
- "mjs_getOriginSpec": {
- "name": "mjs_getOriginSpec",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1785
- },
- "mjs_getCompiler": {
- "name": "mjs_getCompiler",
- "return_type": "mjsCompiler *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1788
- },
- "mjs_findSpec": {
- "name": "mjs_findSpec",
- "return_type": "mjSpec *",
- "params": [
- {
- "name": "spec",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1791
- },
- "mjs_findBody": {
- "name": "mjs_findBody",
- "return_type": "mjsBody *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1794
- },
- "mjs_findElement": {
- "name": "mjs_findElement",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "mjtObj",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1797
- },
- "mjs_findChild": {
- "name": "mjs_findChild",
- "return_type": "mjsBody *",
- "params": [
- {
- "name": "body",
- "c_type": "const mjsBody *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1800
- },
- "mjs_getParent": {
- "name": "mjs_getParent",
- "return_type": "mjsBody *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1803
- },
- "mjs_getFrame": {
- "name": "mjs_getFrame",
- "return_type": "mjsFrame *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1806
- },
- "mjs_findFrame": {
- "name": "mjs_findFrame",
- "return_type": "mjsFrame *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1809
- },
- "mjs_getDefault": {
- "name": "mjs_getDefault",
- "return_type": "mjsDefault *",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1812
- },
- "mjs_findDefault": {
- "name": "mjs_findDefault",
- "return_type": "mjsDefault *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "classname",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1815
- },
- "mjs_getSpecDefault": {
- "name": "mjs_getSpecDefault",
- "return_type": "mjsDefault *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1818
- },
- "mjs_getId": {
- "name": "mjs_getId",
- "return_type": "int",
- "params": [
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1821
- },
- "mjs_firstChild": {
- "name": "mjs_firstChild",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "body",
- "c_type": "const mjsBody *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "mjtObj",
- "array_dim": null
- },
- {
- "name": "recurse",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1824
- },
- "mjs_nextChild": {
- "name": "mjs_nextChild",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "body",
- "c_type": "const mjsBody *",
- "array_dim": null
- },
- {
- "name": "child",
- "c_type": "const mjsElement *",
- "array_dim": null
- },
- {
- "name": "recurse",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1828
- },
- "mjs_firstElement": {
- "name": "mjs_firstElement",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "type",
- "c_type": "mjtObj",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1831
- },
- "mjs_nextElement": {
- "name": "mjs_nextElement",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "s",
- "c_type": "const mjSpec *",
- "array_dim": null
- },
- {
- "name": "element",
- "c_type": "const mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1834
- },
- "mjs_getWrapTarget": {
- "name": "mjs_getWrapTarget",
- "return_type": "mjsElement *",
- "params": [
- {
- "name": "wrap",
- "c_type": "const mjsWrap *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1837
- },
- "mjs_getWrapSideSite": {
- "name": "mjs_getWrapSideSite",
- "return_type": "mjsSite *",
- "params": [
- {
- "name": "wrap",
- "c_type": "const mjsWrap *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1840
- },
- "mjs_getWrapDivisor": {
- "name": "mjs_getWrapDivisor",
- "return_type": "double",
- "params": [
- {
- "name": "wrap",
- "c_type": "const mjsWrap *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1843
- },
- "mjs_getWrapCoef": {
- "name": "mjs_getWrapCoef",
- "return_type": "double",
- "params": [
- {
- "name": "wrap",
- "c_type": "const mjsWrap *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1846
- },
- "mjs_setName": {
- "name": "mjs_setName",
- "return_type": "int",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1851
- },
- "mjs_setBuffer": {
- "name": "mjs_setBuffer",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjByteVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const void *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1854
- },
- "mjs_setString": {
- "name": "mjs_setString",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjString *",
- "array_dim": null
- },
- {
- "name": "text",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1857
- },
- "mjs_setStringVec": {
- "name": "mjs_setStringVec",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjStringVec *",
- "array_dim": null
- },
- {
- "name": "text",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1860
- },
- "mjs_setInStringVec": {
- "name": "mjs_setInStringVec",
- "return_type": "mjtBool",
- "params": [
- {
- "name": "dest",
- "c_type": "mjStringVec *",
- "array_dim": null
- },
- {
- "name": "i",
- "c_type": "int",
- "array_dim": null
- },
- {
- "name": "text",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1863
- },
- "mjs_appendString": {
- "name": "mjs_appendString",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjStringVec *",
- "array_dim": null
- },
- {
- "name": "text",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1866
- },
- "mjs_setInt": {
- "name": "mjs_setInt",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjIntVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1869
- },
- "mjs_appendIntVec": {
- "name": "mjs_appendIntVec",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjIntVecVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const int *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1872
- },
- "mjs_setFloat": {
- "name": "mjs_setFloat",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjFloatVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const float *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1875
- },
- "mjs_appendFloatVec": {
- "name": "mjs_appendFloatVec",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjFloatVecVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const float *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1878
- },
- "mjs_setDouble": {
- "name": "mjs_setDouble",
- "return_type": "void",
- "params": [
- {
- "name": "dest",
- "c_type": "mjDoubleVec *",
- "array_dim": null
- },
- {
- "name": "array",
- "c_type": "const double *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1881
- },
- "mjs_setPluginAttributes": {
- "name": "mjs_setPluginAttributes",
- "return_type": "void",
- "params": [
- {
- "name": "plugin",
- "c_type": "mjsPlugin *",
- "array_dim": null
- },
- {
- "name": "attributes",
- "c_type": "void *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1884
- },
- "mjs_getName": {
- "name": "mjs_getName",
- "return_type": "mjString *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1890
- },
- "mjs_getString": {
- "name": "mjs_getString",
- "return_type": "const char *",
- "params": [
- {
- "name": "source",
- "c_type": "const mjString *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1893
- },
- "mjs_getDouble": {
- "name": "mjs_getDouble",
- "return_type": "const double *",
- "params": [
- {
- "name": "source",
- "c_type": "const mjDoubleVec *",
- "array_dim": null
- },
- {
- "name": "size",
- "c_type": "int *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1897
- },
- "mjs_getWrapNum": {
- "name": "mjs_getWrapNum",
- "return_type": "int",
- "params": [
- {
- "name": "tendonspec",
- "c_type": "const mjsTendon *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1900
- },
- "mjs_getWrap": {
- "name": "mjs_getWrap",
- "return_type": "mjsWrap *",
- "params": [
- {
- "name": "tendonspec",
- "c_type": "const mjsTendon *",
- "array_dim": null
- },
- {
- "name": "i",
- "c_type": "int",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1903
- },
- "mjs_getPluginAttributes": {
- "name": "mjs_getPluginAttributes",
- "return_type": "const void *",
- "params": [
- {
- "name": "plugin",
- "c_type": "const mjsPlugin *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1906
- },
- "mjs_setDefault": {
- "name": "mjs_setDefault",
- "return_type": "void",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "def",
- "c_type": "const mjsDefault *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1912
- },
- "mjs_setFrame": {
- "name": "mjs_setFrame",
- "return_type": "int",
- "params": [
- {
- "name": "dest",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "frame",
- "c_type": "mjsFrame *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1915
- },
- "mjs_resolveOrientation": {
- "name": "mjs_resolveOrientation",
- "return_type": "const char *",
- "params": [
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4
- },
- {
- "name": "degree",
- "c_type": "mjtByte",
- "array_dim": null
- },
- {
- "name": "sequence",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "orientation",
- "c_type": "const mjsOrientation *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1918
- },
- "mjs_bodyToFrame": {
- "name": "mjs_bodyToFrame",
- "return_type": "mjsFrame *",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody **",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1922
- },
- "mjs_setUserValue": {
- "name": "mjs_setUserValue",
- "return_type": "void",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "key",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "data",
- "c_type": "const void *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1925
- },
- "mjs_setUserValueWithCleanup": {
- "name": "mjs_setUserValueWithCleanup",
- "return_type": "void",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "key",
- "c_type": "const char *",
- "array_dim": null
- },
- {
- "name": "data",
- "c_type": "const void *",
- "array_dim": null
- },
- {
- "name": "cleanup",
- "c_type": "void (*)(const void *)",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1930
- },
- "mjs_getUserValue": {
- "name": "mjs_getUserValue",
- "return_type": "const void *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "key",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1935
- },
- "mjs_deleteUserValue": {
- "name": "mjs_deleteUserValue",
- "return_type": "void",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- },
- {
- "name": "key",
- "c_type": "const char *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1938
- },
- "mjs_sensorDim": {
- "name": "mjs_sensorDim",
- "return_type": "int",
- "params": [
- {
- "name": "sensor",
- "c_type": "const mjsSensor *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1941
- },
- "mjs_defaultSpec": {
- "name": "mjs_defaultSpec",
- "return_type": "void",
- "params": [
- {
- "name": "spec",
- "c_type": "mjSpec *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1946
- },
- "mjs_defaultOrientation": {
- "name": "mjs_defaultOrientation",
- "return_type": "void",
- "params": [
- {
- "name": "orient",
- "c_type": "mjsOrientation *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1949
- },
- "mjs_defaultBody": {
- "name": "mjs_defaultBody",
- "return_type": "void",
- "params": [
- {
- "name": "body",
- "c_type": "mjsBody *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1952
- },
- "mjs_defaultFrame": {
- "name": "mjs_defaultFrame",
- "return_type": "void",
- "params": [
- {
- "name": "frame",
- "c_type": "mjsFrame *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1955
- },
- "mjs_defaultJoint": {
- "name": "mjs_defaultJoint",
- "return_type": "void",
- "params": [
- {
- "name": "joint",
- "c_type": "mjsJoint *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1958
- },
- "mjs_defaultGeom": {
- "name": "mjs_defaultGeom",
- "return_type": "void",
- "params": [
- {
- "name": "geom",
- "c_type": "mjsGeom *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1961
- },
- "mjs_defaultSite": {
- "name": "mjs_defaultSite",
- "return_type": "void",
- "params": [
- {
- "name": "site",
- "c_type": "mjsSite *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1964
- },
- "mjs_defaultCamera": {
- "name": "mjs_defaultCamera",
- "return_type": "void",
- "params": [
- {
- "name": "camera",
- "c_type": "mjsCamera *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1967
- },
- "mjs_defaultLight": {
- "name": "mjs_defaultLight",
- "return_type": "void",
- "params": [
- {
- "name": "light",
- "c_type": "mjsLight *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1970
- },
- "mjs_defaultFlex": {
- "name": "mjs_defaultFlex",
- "return_type": "void",
- "params": [
- {
- "name": "flex",
- "c_type": "mjsFlex *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1973
- },
- "mjs_defaultMesh": {
- "name": "mjs_defaultMesh",
- "return_type": "void",
- "params": [
- {
- "name": "mesh",
- "c_type": "mjsMesh *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1976
- },
- "mjs_defaultHField": {
- "name": "mjs_defaultHField",
- "return_type": "void",
- "params": [
- {
- "name": "hfield",
- "c_type": "mjsHField *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1979
- },
- "mjs_defaultSkin": {
- "name": "mjs_defaultSkin",
- "return_type": "void",
- "params": [
- {
- "name": "skin",
- "c_type": "mjsSkin *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1982
- },
- "mjs_defaultTexture": {
- "name": "mjs_defaultTexture",
- "return_type": "void",
- "params": [
- {
- "name": "texture",
- "c_type": "mjsTexture *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1985
- },
- "mjs_defaultMaterial": {
- "name": "mjs_defaultMaterial",
- "return_type": "void",
- "params": [
- {
- "name": "material",
- "c_type": "mjsMaterial *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1988
- },
- "mjs_defaultPair": {
- "name": "mjs_defaultPair",
- "return_type": "void",
- "params": [
- {
- "name": "pair",
- "c_type": "mjsPair *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1991
- },
- "mjs_defaultEquality": {
- "name": "mjs_defaultEquality",
- "return_type": "void",
- "params": [
- {
- "name": "equality",
- "c_type": "mjsEquality *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1994
- },
- "mjs_defaultTendon": {
- "name": "mjs_defaultTendon",
- "return_type": "void",
- "params": [
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1997
- },
- "mjs_defaultActuator": {
- "name": "mjs_defaultActuator",
- "return_type": "void",
- "params": [
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2000
- },
- "mjs_defaultSensor": {
- "name": "mjs_defaultSensor",
- "return_type": "void",
- "params": [
- {
- "name": "sensor",
- "c_type": "mjsSensor *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2003
- },
- "mjs_defaultNumeric": {
- "name": "mjs_defaultNumeric",
- "return_type": "void",
- "params": [
- {
- "name": "numeric",
- "c_type": "mjsNumeric *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2006
- },
- "mjs_defaultText": {
- "name": "mjs_defaultText",
- "return_type": "void",
- "params": [
- {
- "name": "text",
- "c_type": "mjsText *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2009
- },
- "mjs_defaultTuple": {
- "name": "mjs_defaultTuple",
- "return_type": "void",
- "params": [
- {
- "name": "tuple",
- "c_type": "mjsTuple *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2012
- },
- "mjs_defaultKey": {
- "name": "mjs_defaultKey",
- "return_type": "void",
- "params": [
- {
- "name": "key",
- "c_type": "mjsKey *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2015
- },
- "mjs_defaultPlugin": {
- "name": "mjs_defaultPlugin",
- "return_type": "void",
- "params": [
- {
- "name": "plugin",
- "c_type": "mjsPlugin *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2018
- },
- "mjs_asBody": {
- "name": "mjs_asBody",
- "return_type": "mjsBody *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2024
- },
- "mjs_asGeom": {
- "name": "mjs_asGeom",
- "return_type": "mjsGeom *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2027
- },
- "mjs_asJoint": {
- "name": "mjs_asJoint",
- "return_type": "mjsJoint *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2030
- },
- "mjs_asSite": {
- "name": "mjs_asSite",
- "return_type": "mjsSite *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2033
- },
- "mjs_asCamera": {
- "name": "mjs_asCamera",
- "return_type": "mjsCamera *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2036
- },
- "mjs_asLight": {
- "name": "mjs_asLight",
- "return_type": "mjsLight *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2039
- },
- "mjs_asFrame": {
- "name": "mjs_asFrame",
- "return_type": "mjsFrame *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2042
- },
- "mjs_asActuator": {
- "name": "mjs_asActuator",
- "return_type": "mjsActuator *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2045
- },
- "mjs_asSensor": {
- "name": "mjs_asSensor",
- "return_type": "mjsSensor *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2048
- },
- "mjs_asFlex": {
- "name": "mjs_asFlex",
- "return_type": "mjsFlex *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2051
- },
- "mjs_asPair": {
- "name": "mjs_asPair",
- "return_type": "mjsPair *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2054
- },
- "mjs_asEquality": {
- "name": "mjs_asEquality",
- "return_type": "mjsEquality *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2057
- },
- "mjs_asExclude": {
- "name": "mjs_asExclude",
- "return_type": "mjsExclude *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2060
- },
- "mjs_asTendon": {
- "name": "mjs_asTendon",
- "return_type": "mjsTendon *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2063
- },
- "mjs_asNumeric": {
- "name": "mjs_asNumeric",
- "return_type": "mjsNumeric *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2066
- },
- "mjs_asText": {
- "name": "mjs_asText",
- "return_type": "mjsText *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2069
- },
- "mjs_asTuple": {
- "name": "mjs_asTuple",
- "return_type": "mjsTuple *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2072
- },
- "mjs_asKey": {
- "name": "mjs_asKey",
- "return_type": "mjsKey *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2075
- },
- "mjs_asMesh": {
- "name": "mjs_asMesh",
- "return_type": "mjsMesh *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2078
- },
- "mjs_asHField": {
- "name": "mjs_asHField",
- "return_type": "mjsHField *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2081
- },
- "mjs_asSkin": {
- "name": "mjs_asSkin",
- "return_type": "mjsSkin *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2084
- },
- "mjs_asTexture": {
- "name": "mjs_asTexture",
- "return_type": "mjsTexture *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2087
- },
- "mjs_asMaterial": {
- "name": "mjs_asMaterial",
- "return_type": "mjsMaterial *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2090
- },
- "mjs_asPlugin": {
- "name": "mjs_asPlugin",
- "return_type": "mjsPlugin *",
- "params": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 2093
- }
- },
- "enums": {
- "mjtDisableBit": {
- "name": "mjtDisableBit",
- "members": {
- "mjDSBL_CONSTRAINT": 1,
- "mjDSBL_EQUALITY": 2,
- "mjDSBL_FRICTIONLOSS": 4,
- "mjDSBL_LIMIT": 8,
- "mjDSBL_CONTACT": 16,
- "mjDSBL_SPRING": 32,
- "mjDSBL_DAMPER": 64,
- "mjDSBL_GRAVITY": 128,
- "mjDSBL_CLAMPCTRL": 256,
- "mjDSBL_WARMSTART": 512,
- "mjDSBL_FILTERPARENT": 1024,
- "mjDSBL_ACTUATION": 2048,
- "mjDSBL_REFSAFE": 4096,
- "mjDSBL_SENSOR": 8192,
- "mjDSBL_MIDPHASE": 16384,
- "mjDSBL_EULERDAMP": 32768,
- "mjDSBL_AUTORESET": 65536,
- "mjDSBL_NATIVECCD": 131072,
- "mjDSBL_ISLAND": 262144,
- "mjDSBL_MULTICCD": 524288,
- "mjNDISABLE": 20
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 53
- },
- "mjtEnableBit": {
- "name": "mjtEnableBit",
- "members": {
- "mjENBL_OVERRIDE": 1,
- "mjENBL_ENERGY": 2,
- "mjENBL_FWDINV": 4,
- "mjENBL_INVDISCRETE": 8,
- "mjENBL_SLEEP": 16,
- "mjENBL_DIAGEXACT": 32,
- "mjNENABLE": 6
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 79
- },
- "mjtJoint": {
- "name": "mjtJoint",
- "members": {
- "mjJNT_FREE": 0,
- "mjJNT_BALL": 1,
- "mjJNT_SLIDE": 2,
- "mjJNT_HINGE": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 91
- },
- "mjtGeom": {
- "name": "mjtGeom",
- "members": {
- "mjGEOM_PLANE": 0,
- "mjGEOM_HFIELD": 1,
- "mjGEOM_SPHERE": 2,
- "mjGEOM_CAPSULE": 3,
- "mjGEOM_ELLIPSOID": 4,
- "mjGEOM_CYLINDER": 5,
- "mjGEOM_BOX": 6,
- "mjGEOM_MESH": 7,
- "mjGEOM_SDF": 8,
- "mjNGEOMTYPES": 9,
- "mjGEOM_ARROW": 100,
- "mjGEOM_ARROW1": 101,
- "mjGEOM_ARROW2": 102,
- "mjGEOM_LINE": 103,
- "mjGEOM_LINEBOX": 104,
- "mjGEOM_FLEX": 105,
- "mjGEOM_SKIN": 106,
- "mjGEOM_LABEL": 107,
- "mjGEOM_TRIANGLE": 108,
- "mjGEOM_NONE": 1001
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 99
- },
- "mjtProjection": {
- "name": "mjtProjection",
- "members": {
- "mjPROJ_PERSPECTIVE": 0,
- "mjPROJ_ORTHOGRAPHIC": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 128
- },
- "mjtCamLight": {
- "name": "mjtCamLight",
- "members": {
- "mjCAMLIGHT_FIXED": 0,
- "mjCAMLIGHT_TRACK": 1,
- "mjCAMLIGHT_TRACKCOM": 2,
- "mjCAMLIGHT_TARGETBODY": 3,
- "mjCAMLIGHT_TARGETBODYCOM": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 134
- },
- "mjtLightType": {
- "name": "mjtLightType",
- "members": {
- "mjLIGHT_SPOT": 0,
- "mjLIGHT_DIRECTIONAL": 1,
- "mjLIGHT_POINT": 2,
- "mjLIGHT_IMAGE": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 143
- },
- "mjtTexture": {
- "name": "mjtTexture",
- "members": {
- "mjTEXTURE_2D": 0,
- "mjTEXTURE_CUBE": 1,
- "mjTEXTURE_SKYBOX": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 151
- },
- "mjtTextureRole": {
- "name": "mjtTextureRole",
- "members": {
- "mjTEXROLE_USER": 0,
- "mjTEXROLE_RGB": 1,
- "mjTEXROLE_OCCLUSION": 2,
- "mjTEXROLE_ROUGHNESS": 3,
- "mjTEXROLE_METALLIC": 4,
- "mjTEXROLE_NORMAL": 5,
- "mjTEXROLE_OPACITY": 6,
- "mjTEXROLE_EMISSIVE": 7,
- "mjTEXROLE_RGBA": 8,
- "mjTEXROLE_ORM": 9,
- "mjNTEXROLE": 10
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 158
- },
- "mjtColorSpace": {
- "name": "mjtColorSpace",
- "members": {
- "mjCOLORSPACE_AUTO": 0,
- "mjCOLORSPACE_LINEAR": 1,
- "mjCOLORSPACE_SRGB": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 173
- },
- "mjtIntegrator": {
- "name": "mjtIntegrator",
- "members": {
- "mjINT_EULER": 0,
- "mjINT_RK4": 1,
- "mjINT_IMPLICIT": 2,
- "mjINT_IMPLICITFAST": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 180
- },
- "mjtCone": {
- "name": "mjtCone",
- "members": {
- "mjCONE_PYRAMIDAL": 0,
- "mjCONE_ELLIPTIC": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 188
- },
- "mjtJacobian": {
- "name": "mjtJacobian",
- "members": {
- "mjJAC_DENSE": 0,
- "mjJAC_SPARSE": 1,
- "mjJAC_AUTO": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 194
- },
- "mjtSolver": {
- "name": "mjtSolver",
- "members": {
- "mjSOL_PGS": 0,
- "mjSOL_CG": 1,
- "mjSOL_NEWTON": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 201
- },
- "mjtEq": {
- "name": "mjtEq",
- "members": {
- "mjEQ_CONNECT": 0,
- "mjEQ_WELD": 1,
- "mjEQ_JOINT": 2,
- "mjEQ_TENDON": 3,
- "mjEQ_FLEX": 4,
- "mjEQ_FLEXVERT": 5,
- "mjEQ_FLEXSTRAIN": 6,
- "mjEQ_DISTANCE": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 208
- },
- "mjtWrap": {
- "name": "mjtWrap",
- "members": {
- "mjWRAP_NONE": 0,
- "mjWRAP_JOINT": 1,
- "mjWRAP_PULLEY": 2,
- "mjWRAP_SITE": 3,
- "mjWRAP_SPHERE": 4,
- "mjWRAP_CYLINDER": 5
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 220
- },
- "mjtTrn": {
- "name": "mjtTrn",
- "members": {
- "mjTRN_JOINT": 0,
- "mjTRN_JOINTINPARENT": 1,
- "mjTRN_SLIDERCRANK": 2,
- "mjTRN_TENDON": 3,
- "mjTRN_SITE": 4,
- "mjTRN_BODY": 5,
- "mjTRN_UNDEFINED": 1000
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 230
- },
- "mjtDyn": {
- "name": "mjtDyn",
- "members": {
- "mjDYN_NONE": 0,
- "mjDYN_INTEGRATOR": 1,
- "mjDYN_FILTER": 2,
- "mjDYN_FILTEREXACT": 3,
- "mjDYN_MUSCLE": 4,
- "mjDYN_DCMOTOR": 5,
- "mjDYN_USER": 6
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 242
- },
- "mjtGain": {
- "name": "mjtGain",
- "members": {
- "mjGAIN_FIXED": 0,
- "mjGAIN_AFFINE": 1,
- "mjGAIN_MUSCLE": 2,
- "mjGAIN_DCMOTOR": 3,
- "mjGAIN_USER": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 253
- },
- "mjtBias": {
- "name": "mjtBias",
- "members": {
- "mjBIAS_NONE": 0,
- "mjBIAS_AFFINE": 1,
- "mjBIAS_MUSCLE": 2,
- "mjBIAS_DCMOTOR": 3,
- "mjBIAS_USER": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 262
- },
- "mjtObj": {
- "name": "mjtObj",
- "members": {
- "mjOBJ_UNKNOWN": 0,
- "mjOBJ_BODY": 1,
- "mjOBJ_XBODY": 2,
- "mjOBJ_JOINT": 3,
- "mjOBJ_DOF": 4,
- "mjOBJ_GEOM": 5,
- "mjOBJ_SITE": 6,
- "mjOBJ_CAMERA": 7,
- "mjOBJ_LIGHT": 8,
- "mjOBJ_FLEX": 9,
- "mjOBJ_MESH": 10,
- "mjOBJ_SKIN": 11,
- "mjOBJ_HFIELD": 12,
- "mjOBJ_TEXTURE": 13,
- "mjOBJ_MATERIAL": 14,
- "mjOBJ_PAIR": 15,
- "mjOBJ_EXCLUDE": 16,
- "mjOBJ_EQUALITY": 17,
- "mjOBJ_TENDON": 18,
- "mjOBJ_ACTUATOR": 19,
- "mjOBJ_SENSOR": 20,
- "mjOBJ_NUMERIC": 21,
- "mjOBJ_TEXT": 22,
- "mjOBJ_TUPLE": 23,
- "mjOBJ_KEY": 24,
- "mjOBJ_PLUGIN": 25,
- "mjNOBJECT": 26,
- "mjOBJ_FRAME": 100,
- "mjOBJ_DEFAULT": 101,
- "mjOBJ_MODEL": 102
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 271
- },
- "mjtSensor": {
- "name": "mjtSensor",
- "members": {
- "mjSENS_TOUCH": 0,
- "mjSENS_ACCELEROMETER": 1,
- "mjSENS_VELOCIMETER": 2,
- "mjSENS_GYRO": 3,
- "mjSENS_FORCE": 4,
- "mjSENS_TORQUE": 5,
- "mjSENS_MAGNETOMETER": 6,
- "mjSENS_RANGEFINDER": 7,
- "mjSENS_CAMPROJECTION": 8,
- "mjSENS_JOINTPOS": 9,
- "mjSENS_JOINTVEL": 10,
- "mjSENS_TENDONPOS": 11,
- "mjSENS_TENDONVEL": 12,
- "mjSENS_ACTUATORPOS": 13,
- "mjSENS_ACTUATORVEL": 14,
- "mjSENS_ACTUATORFRC": 15,
- "mjSENS_JOINTACTFRC": 16,
- "mjSENS_TENDONACTFRC": 17,
- "mjSENS_BALLQUAT": 18,
- "mjSENS_BALLANGVEL": 19,
- "mjSENS_JOINTLIMITPOS": 20,
- "mjSENS_JOINTLIMITVEL": 21,
- "mjSENS_JOINTLIMITFRC": 22,
- "mjSENS_TENDONLIMITPOS": 23,
- "mjSENS_TENDONLIMITVEL": 24,
- "mjSENS_TENDONLIMITFRC": 25,
- "mjSENS_FRAMEPOS": 26,
- "mjSENS_FRAMEQUAT": 27,
- "mjSENS_FRAMEXAXIS": 28,
- "mjSENS_FRAMEYAXIS": 29,
- "mjSENS_FRAMEZAXIS": 30,
- "mjSENS_FRAMELINVEL": 31,
- "mjSENS_FRAMEANGVEL": 32,
- "mjSENS_FRAMELINACC": 33,
- "mjSENS_FRAMEANGACC": 34,
- "mjSENS_SUBTREECOM": 35,
- "mjSENS_SUBTREELINVEL": 36,
- "mjSENS_SUBTREEANGMOM": 37,
- "mjSENS_INSIDESITE": 38,
- "mjSENS_GEOMDIST": 39,
- "mjSENS_GEOMNORMAL": 40,
- "mjSENS_GEOMFROMTO": 41,
- "mjSENS_CONTACT": 42,
- "mjSENS_E_POTENTIAL": 43,
- "mjSENS_E_KINETIC": 44,
- "mjSENS_CLOCK": 45,
- "mjSENS_TACTILE": 46,
- "mjSENS_PLUGIN": 47,
- "mjSENS_USER": 48
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 308
- },
- "mjtStage": {
- "name": "mjtStage",
- "members": {
- "mjSTAGE_NONE": 0,
- "mjSTAGE_POS": 1,
- "mjSTAGE_VEL": 2,
- "mjSTAGE_ACC": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 384
- },
- "mjtDataType": {
- "name": "mjtDataType",
- "members": {
- "mjDATATYPE_REAL": 0,
- "mjDATATYPE_POSITIVE": 1,
- "mjDATATYPE_AXIS": 2,
- "mjDATATYPE_QUATERNION": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 392
- },
- "mjtConDataField": {
- "name": "mjtConDataField",
- "members": {
- "mjCONDATA_FOUND": 0,
- "mjCONDATA_FORCE": 1,
- "mjCONDATA_TORQUE": 2,
- "mjCONDATA_DIST": 3,
- "mjCONDATA_POS": 4,
- "mjCONDATA_NORMAL": 5,
- "mjCONDATA_TANGENT": 6,
- "mjNCONDATA": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 400
- },
- "mjtRayDataField": {
- "name": "mjtRayDataField",
- "members": {
- "mjRAYDATA_DIST": 0,
- "mjRAYDATA_DIR": 1,
- "mjRAYDATA_ORIGIN": 2,
- "mjRAYDATA_POINT": 3,
- "mjRAYDATA_NORMAL": 4,
- "mjRAYDATA_DEPTH": 5,
- "mjNRAYDATA": 6
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 413
- },
- "mjtCamOutBit": {
- "name": "mjtCamOutBit",
- "members": {
- "mjCAMOUT_RGB": 1,
- "mjCAMOUT_DEPTH": 2,
- "mjCAMOUT_DIST": 4,
- "mjCAMOUT_NORMAL": 8,
- "mjCAMOUT_SEG": 16,
- "mjNCAMOUT": 5
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 425
- },
- "mjtSameFrame": {
- "name": "mjtSameFrame",
- "members": {
- "mjSAMEFRAME_NONE": 0,
- "mjSAMEFRAME_BODY": 1,
- "mjSAMEFRAME_INERTIA": 2,
- "mjSAMEFRAME_BODYROT": 3,
- "mjSAMEFRAME_INERTIAROT": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 436
- },
- "mjtSleepPolicy": {
- "name": "mjtSleepPolicy",
- "members": {
- "mjSLEEP_AUTO": 0,
- "mjSLEEP_AUTO_NEVER": 1,
- "mjSLEEP_AUTO_ALLOWED": 2,
- "mjSLEEP_NEVER": 3,
- "mjSLEEP_ALLOWED": 4,
- "mjSLEEP_INIT": 5
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 445
- },
- "mjtLRMode": {
- "name": "mjtLRMode",
- "members": {
- "mjLRMODE_NONE": 0,
- "mjLRMODE_MUSCLE": 1,
- "mjLRMODE_MUSCLEUSER": 2,
- "mjLRMODE_ALL": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 455
- },
- "mjtFlexSelf": {
- "name": "mjtFlexSelf",
- "members": {
- "mjFLEXSELF_NONE": 0,
- "mjFLEXSELF_NARROW": 1,
- "mjFLEXSELF_BVH": 2,
- "mjFLEXSELF_SAP": 3,
- "mjFLEXSELF_AUTO": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 463
- },
- "mjtSDFType": {
- "name": "mjtSDFType",
- "members": {
- "mjSDFTYPE_SINGLE": 0,
- "mjSDFTYPE_INTERSECTION": 1,
- "mjSDFTYPE_MIDSURFACE": 2,
- "mjSDFTYPE_COLLISION": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 472
- },
- "mjtState": {
- "name": "mjtState",
- "members": {
- "mjSTATE_TIME": 1,
- "mjSTATE_QPOS": 2,
- "mjSTATE_QVEL": 4,
- "mjSTATE_ACT": 8,
- "mjSTATE_HISTORY": 16,
- "mjSTATE_WARMSTART": 32,
- "mjSTATE_CTRL": 64,
- "mjSTATE_QFRC_APPLIED": 128,
- "mjSTATE_XFRC_APPLIED": 256,
- "mjSTATE_EQ_ACTIVE": 512,
- "mjSTATE_MOCAP_POS": 1024,
- "mjSTATE_MOCAP_QUAT": 2048,
- "mjSTATE_USERDATA": 4096,
- "mjSTATE_PLUGIN": 8192,
- "mjNSTATE": 14,
- "mjSTATE_PHYSICS": 30,
- "mjSTATE_FULLPHYSICS": 8223,
- "mjSTATE_USER": 8128,
- "mjSTATE_INTEGRATION": 16383
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 483
- },
- "mjtConstraint": {
- "name": "mjtConstraint",
- "members": {
- "mjCNSTR_EQUALITY": 0,
- "mjCNSTR_FRICTION_DOF": 1,
- "mjCNSTR_FRICTION_TENDON": 2,
- "mjCNSTR_LIMIT_JOINT": 3,
- "mjCNSTR_LIMIT_TENDON": 4,
- "mjCNSTR_CONTACT_FRICTIONLESS": 5,
- "mjCNSTR_CONTACT_PYRAMIDAL": 6,
- "mjCNSTR_CONTACT_ELLIPTIC": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 511
- },
- "mjtConstraintState": {
- "name": "mjtConstraintState",
- "members": {
- "mjCNSTRSTATE_SATISFIED": 0,
- "mjCNSTRSTATE_QUADRATIC": 1,
- "mjCNSTRSTATE_LINEARNEG": 2,
- "mjCNSTRSTATE_LINEARPOS": 3,
- "mjCNSTRSTATE_CONE": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 523
- },
- "mjtWarning": {
- "name": "mjtWarning",
- "members": {
- "mjWARN_INERTIA": 0,
- "mjWARN_CONTACTFULL": 1,
- "mjWARN_CNSTRFULL": 2,
- "mjWARN_BADQPOS": 3,
- "mjWARN_BADQVEL": 4,
- "mjWARN_BADQACC": 5,
- "mjWARN_BADCTRL": 6,
- "mjNWARNING": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 532
- },
- "mjtTimer": {
- "name": "mjtTimer",
- "members": {
- "mjTIMER_STEP": 0,
- "mjTIMER_FORWARD": 1,
- "mjTIMER_INVERSE": 2,
- "mjTIMER_POSITION": 3,
- "mjTIMER_VELOCITY": 4,
- "mjTIMER_ACTUATION": 5,
- "mjTIMER_CONSTRAINT": 6,
- "mjTIMER_ADVANCE": 7,
- "mjTIMER_POS_KINEMATICS": 8,
- "mjTIMER_POS_INERTIA": 9,
- "mjTIMER_POS_COLLISION": 10,
- "mjTIMER_POS_MAKE": 11,
- "mjTIMER_POS_PROJECT": 12,
- "mjTIMER_COL_BROAD": 13,
- "mjTIMER_COL_NARROW": 14,
- "mjNTIMER": 15
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 545
- },
- "mjtSleepState": {
- "name": "mjtSleepState",
- "members": {
- "mjS_STATIC": -1,
- "mjS_ASLEEP": 0,
- "mjS_AWAKE": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 573
- },
- "mjtLogLevel": {
- "name": "mjtLogLevel",
- "members": {
- "mjLOG_DEBUG": 0,
- "mjLOG_INFO": 1,
- "mjLOG_WARNING": 2,
- "mjLOG_ERROR": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 583
- },
- "mjtLogTopic": {
- "name": "mjtLogTopic",
- "members": {
- "mjTOPIC_NONE": 0,
- "mjTOPIC_TIME_STP": 1,
- "mjTOPIC_TIME_CMP": 2,
- "mjTOPIC_SLEEP": 3,
- "mjNTOPIC": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 590
- },
- "mjtGeomInertia": {
- "name": "mjtGeomInertia",
- "members": {
- "mjINERTIA_VOLUME": 0,
- "mjINERTIA_SHELL": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 60
- },
- "mjtMeshInertia": {
- "name": "mjtMeshInertia",
- "members": {
- "mjMESH_INERTIA_CONVEX": 0,
- "mjMESH_INERTIA_EXACT": 1,
- "mjMESH_INERTIA_LEGACY": 2,
- "mjMESH_INERTIA_SHELL": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 66
- },
- "mjtMeshBuiltin": {
- "name": "mjtMeshBuiltin",
- "members": {
- "mjMESH_BUILTIN_NONE": 0,
- "mjMESH_BUILTIN_SPHERE": 1,
- "mjMESH_BUILTIN_HEMISPHERE": 2,
- "mjMESH_BUILTIN_CONE": 3,
- "mjMESH_BUILTIN_SUPERSPHERE": 4,
- "mjMESH_BUILTIN_SUPERTORUS": 5,
- "mjMESH_BUILTIN_WEDGE": 6,
- "mjMESH_BUILTIN_PLATE": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 74
- },
- "mjtBuiltin": {
- "name": "mjtBuiltin",
- "members": {
- "mjBUILTIN_NONE": 0,
- "mjBUILTIN_GRADIENT": 1,
- "mjBUILTIN_CHECKER": 2,
- "mjBUILTIN_FLAT": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 86
- },
- "mjtMark": {
- "name": "mjtMark",
- "members": {
- "mjMARK_NONE": 0,
- "mjMARK_EDGE": 1,
- "mjMARK_CROSS": 2,
- "mjMARK_RANDOM": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 94
- },
- "mjtLimited": {
- "name": "mjtLimited",
- "members": {
- "mjLIMITED_FALSE": 0,
- "mjLIMITED_TRUE": 1,
- "mjLIMITED_AUTO": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 102
- },
- "mjtAlignFree": {
- "name": "mjtAlignFree",
- "members": {
- "mjALIGNFREE_FALSE": 0,
- "mjALIGNFREE_TRUE": 1,
- "mjALIGNFREE_AUTO": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 109
- },
- "mjtInertiaFromGeom": {
- "name": "mjtInertiaFromGeom",
- "members": {
- "mjINERTIAFROMGEOM_FALSE": 0,
- "mjINERTIAFROMGEOM_TRUE": 1,
- "mjINERTIAFROMGEOM_AUTO": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 116
- },
- "mjtOrientation": {
- "name": "mjtOrientation",
- "members": {
- "mjORIENTATION_QUAT": 0,
- "mjORIENTATION_AXISANGLE": 1,
- "mjORIENTATION_XYAXES": 2,
- "mjORIENTATION_ZAXIS": 3,
- "mjORIENTATION_EULER": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 123
- },
- "mjtCTimer": {
- "name": "mjtCTimer",
- "members": {
- "mjCTIMER_TOTAL": 0,
- "mjCTIMER_ASSETS": 1,
- "mjCTIMER_TEXTURE": 2,
- "mjCTIMER_MESH_LOAD": 3,
- "mjCTIMER_MESH_HULL": 4,
- "mjCTIMER_MESH_POLYGON": 5,
- "mjCTIMER_MESH_INERTIA": 6,
- "mjCTIMER_MESH_BVH": 7,
- "mjCTIMER_MESH_OCTREE": 8,
- "mjNCTIMER": 9
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 132
- },
- "mjtCatBit": {
- "name": "mjtCatBit",
- "members": {
- "mjCAT_STATIC": 1,
- "mjCAT_DYNAMIC": 2,
- "mjCAT_DECOR": 4,
- "mjCAT_ALL": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 33
- },
- "mjtMouse": {
- "name": "mjtMouse",
- "members": {
- "mjMOUSE_NONE": 0,
- "mjMOUSE_ROTATE_V": 1,
- "mjMOUSE_ROTATE_H": 2,
- "mjMOUSE_MOVE_V": 3,
- "mjMOUSE_MOVE_H": 4,
- "mjMOUSE_ZOOM": 5,
- "mjMOUSE_MOVE_V_REL": 6,
- "mjMOUSE_MOVE_H_REL": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 41
- },
- "mjtPertBit": {
- "name": "mjtPertBit",
- "members": {
- "mjPERT_TRANSLATE": 1,
- "mjPERT_ROTATE": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 53
- },
- "mjtCamera": {
- "name": "mjtCamera",
- "members": {
- "mjCAMERA_FREE": 0,
- "mjCAMERA_TRACKING": 1,
- "mjCAMERA_FIXED": 2,
- "mjCAMERA_USER": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 59
- },
- "mjtLabel": {
- "name": "mjtLabel",
- "members": {
- "mjLABEL_NONE": 0,
- "mjLABEL_BODY": 1,
- "mjLABEL_JOINT": 2,
- "mjLABEL_GEOM": 3,
- "mjLABEL_SITE": 4,
- "mjLABEL_CAMERA": 5,
- "mjLABEL_LIGHT": 6,
- "mjLABEL_TENDON": 7,
- "mjLABEL_ACTUATOR": 8,
- "mjLABEL_CONSTRAINT": 9,
- "mjLABEL_FLEX": 10,
- "mjLABEL_SKIN": 11,
- "mjLABEL_SELECTION": 12,
- "mjLABEL_SELPNT": 13,
- "mjLABEL_CONTACTPOINT": 14,
- "mjLABEL_CONTACTFORCE": 15,
- "mjLABEL_ISLAND": 16,
- "mjNLABEL": 17
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 67
- },
- "mjtFrame": {
- "name": "mjtFrame",
- "members": {
- "mjFRAME_NONE": 0,
- "mjFRAME_BODY": 1,
- "mjFRAME_GEOM": 2,
- "mjFRAME_SITE": 3,
- "mjFRAME_CAMERA": 4,
- "mjFRAME_LIGHT": 5,
- "mjFRAME_CONTACT": 6,
- "mjFRAME_WORLD": 7,
- "mjNFRAME": 8
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 90
- },
- "mjtVisFlag": {
- "name": "mjtVisFlag",
- "members": {
- "mjVIS_CONVEXHULL": 0,
- "mjVIS_TEXTURE": 1,
- "mjVIS_JOINT": 2,
- "mjVIS_CAMERA": 3,
- "mjVIS_ACTUATOR": 4,
- "mjVIS_ACTIVATION": 5,
- "mjVIS_LIGHT": 6,
- "mjVIS_TENDON": 7,
- "mjVIS_RANGEFINDER": 8,
- "mjVIS_CONSTRAINT": 9,
- "mjVIS_INERTIA": 10,
- "mjVIS_SCLINERTIA": 11,
- "mjVIS_PERTFORCE": 12,
- "mjVIS_PERTOBJ": 13,
- "mjVIS_CONTACTPOINT": 14,
- "mjVIS_ISLAND": 15,
- "mjVIS_CONTACTFORCE": 16,
- "mjVIS_CONTACTSPLIT": 17,
- "mjVIS_TRANSPARENT": 18,
- "mjVIS_AUTOCONNECT": 19,
- "mjVIS_COM": 20,
- "mjVIS_SELECT": 21,
- "mjVIS_STATIC": 22,
- "mjVIS_SKIN": 23,
- "mjVIS_FLEXVERT": 24,
- "mjVIS_FLEXEDGE": 25,
- "mjVIS_FLEXFACE": 26,
- "mjVIS_FLEXSKIN": 27,
- "mjVIS_BODYBVH": 28,
- "mjVIS_MESHBVH": 29,
- "mjVIS_SDFITER": 30,
- "mjNVISFLAG": 31
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 104
- },
- "mjtRndFlag": {
- "name": "mjtRndFlag",
- "members": {
- "mjRND_SHADOW": 0,
- "mjRND_WIREFRAME": 1,
- "mjRND_REFLECTION": 2,
- "mjRND_ADDITIVE": 3,
- "mjRND_SKYBOX": 4,
- "mjRND_FOG": 5,
- "mjRND_HAZE": 6,
- "mjRND_DEPTH": 7,
- "mjRND_SEGMENT": 8,
- "mjRND_IDCOLOR": 9,
- "mjRND_CULL_FACE": 10,
- "mjNRNDFLAG": 11
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 141
- },
- "mjtStereo": {
- "name": "mjtStereo",
- "members": {
- "mjSTEREO_NONE": 0,
- "mjSTEREO_QUADBUFFERED": 1,
- "mjSTEREO_SIDEBYSIDE": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 158
- },
- "mjtPluginCapabilityBit": {
- "name": "mjtPluginCapabilityBit",
- "members": {
- "mjPLUGIN_ACTUATOR": 1,
- "mjPLUGIN_SENSOR": 2,
- "mjPLUGIN_PASSIVE": 4,
- "mjPLUGIN_SDF": 8
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 110
- },
- "mjtGridPos": {
- "name": "mjtGridPos",
- "members": {
- "mjGRID_TOPLEFT": 0,
- "mjGRID_TOPRIGHT": 1,
- "mjGRID_BOTTOMLEFT": 2,
- "mjGRID_BOTTOMRIGHT": 3,
- "mjGRID_TOP": 4,
- "mjGRID_BOTTOM": 5,
- "mjGRID_LEFT": 6,
- "mjGRID_RIGHT": 7
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 31
- },
- "mjtFramebuffer": {
- "name": "mjtFramebuffer",
- "members": {
- "mjFB_WINDOW": 0,
- "mjFB_OFFSCREEN": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 43
- },
- "mjtDepthMap": {
- "name": "mjtDepthMap",
- "members": {
- "mjDEPTH_ZERONEAR": 0,
- "mjDEPTH_ZEROFAR": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 49
- },
- "mjtFontScale": {
- "name": "mjtFontScale",
- "members": {
- "mjFONTSCALE_50": 50,
- "mjFONTSCALE_100": 100,
- "mjFONTSCALE_150": 150,
- "mjFONTSCALE_200": 200,
- "mjFONTSCALE_250": 250,
- "mjFONTSCALE_300": 300
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 55
- },
- "mjtFont": {
- "name": "mjtFont",
- "members": {
- "mjFONT_NORMAL": 0,
- "mjFONT_SHADOW": 1,
- "mjFONT_BIG": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 65
- },
- "mjrPixelFormat": {
- "name": "mjrPixelFormat",
- "members": {
- "mjPIXEL_FORMAT_UNKNOWN": 0,
- "mjPIXEL_FORMAT_R8": 1,
- "mjPIXEL_FORMAT_RGB8": 2,
- "mjPIXEL_FORMAT_RGBA8": 3,
- "mjPIXEL_FORMAT_R32F": 4,
- "mjPIXEL_FORMAT_DEPTH32F": 5,
- "mjPIXEL_FORMAT_KTX": 6
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 72
- },
- "mjrVertexAttributeUsage": {
- "name": "mjrVertexAttributeUsage",
- "members": {
- "mjVERTEX_ATTRIBUTE_USAGE_POSITION": 0,
- "mjVERTEX_ATTRIBUTE_USAGE_NORMAL": 1,
- "mjVERTEX_ATTRIBUTE_USAGE_TANGENTS": 2,
- "mjVERTEX_ATTRIBUTE_USAGE_UV": 3,
- "mjVERTEX_ATTRIBUTE_USAGE_COLOR": 4
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 83
- },
- "mjrVertexAttributeType": {
- "name": "mjrVertexAttributeType",
- "members": {
- "mjVERTEX_ATTRIBUTE_TYPE_FLOAT2": 0,
- "mjVERTEX_ATTRIBUTE_TYPE_FLOAT3": 1,
- "mjVERTEX_ATTRIBUTE_TYPE_FLOAT4": 2,
- "mjVERTEX_ATTRIBUTE_TYPE_UBYTE4": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 92
- },
- "mjrIndexType": {
- "name": "mjrIndexType",
- "members": {
- "mjINDEX_TYPE_U16": 0,
- "mjINDEX_TYPE_U32": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 100
- },
- "mjrMeshPrimitiveType": {
- "name": "mjrMeshPrimitiveType",
- "members": {
- "mjMESH_PRIMITIVE_TYPE_TRIANGLES": 0,
- "mjMESH_PRIMITIVE_TYPE_LINES": 1
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 106
- },
- "mjtButton": {
- "name": "mjtButton",
- "members": {
- "mjBUTTON_NONE": 0,
- "mjBUTTON_LEFT": 1,
- "mjBUTTON_RIGHT": 2,
- "mjBUTTON_MIDDLE": 3
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 65
- },
- "mjtEvent": {
- "name": "mjtEvent",
- "members": {
- "mjEVENT_NONE": 0,
- "mjEVENT_MOVE": 1,
- "mjEVENT_PRESS": 2,
- "mjEVENT_RELEASE": 3,
- "mjEVENT_SCROLL": 4,
- "mjEVENT_KEY": 5,
- "mjEVENT_RESIZE": 6,
- "mjEVENT_REDRAW": 7,
- "mjEVENT_FILESDROP": 8
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 73
- },
- "mjtItem": {
- "name": "mjtItem",
- "members": {
- "mjITEM_END": -2,
- "mjITEM_SECTION": -1,
- "mjITEM_SEPARATOR": 0,
- "mjITEM_STATIC": 1,
- "mjITEM_BUTTON": 2,
- "mjITEM_CHECKINT": 3,
- "mjITEM_CHECKBYTE": 4,
- "mjITEM_RADIO": 5,
- "mjITEM_RADIOLINE": 6,
- "mjITEM_SELECT": 7,
- "mjITEM_SLIDERINT": 8,
- "mjITEM_SLIDERNUM": 9,
- "mjITEM_EDITINT": 10,
- "mjITEM_EDITNUM": 11,
- "mjITEM_EDITFLOAT": 12,
- "mjITEM_EDITTXT": 13,
- "mjNITEM": 14
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 86
- },
- "mjtSection": {
- "name": "mjtSection",
- "members": {
- "mjSECT_CLOSED": 0,
- "mjSECT_OPEN": 1,
- "mjSECT_FIXED": 2
- },
- "member_docs": {},
- "underlying_type": "int",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 110
- }
- },
- "structs": {
- "mjLogMessage": {
- "name": "mjLogMessage",
- "fields": [
- {
- "name": "level",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "topic",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "subject",
- "c_type": "char [1024]",
- "array_dim": 1024,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "body",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "func",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "file",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "line",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "timestamp",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 601
- },
- "mjLogConfig": {
- "name": "mjLogConfig",
- "fields": [
- {
- "name": "logto_console",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "logto_file",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "logfile",
- "c_type": "char [1024]",
- "array_dim": 1024,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "topics",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 612
- },
- "mjLROpt": {
- "name": "mjLROpt",
- "fields": [
- {
- "name": "mode",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "useexisting",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "uselimit",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "accel",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxforce",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "timeconst",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "timestep",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inttotal",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "interval",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "tolrange",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 53
- },
- "mjCache": {
- "name": "mjCache",
- "fields": [
- {
- "name": "impl_",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 72
- },
- "mjVFS": {
- "name": "mjVFS",
- "fields": [
- {
- "name": "impl_",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 79
- },
- "mjOption": {
- "name": "mjOption",
- "fields": [
- {
- "name": "timestep",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "impratio",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "tolerance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ls_tolerance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "noslip_tolerance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ccd_tolerance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sleep_tolerance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gravity",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "wind",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "magnetic",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "density",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "viscosity",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "o_margin",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "o_solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "o_solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "o_friction",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "integrator",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cone",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "jacobian",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solver",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "iterations",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ls_iterations",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "noslip_iterations",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ccd_iterations",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "disableflags",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "enableflags",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "disableactuator",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sdf_initpoints",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sdf_iterations",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 86
- },
- "mjVisual": {
- "name": "mjVisual",
- "fields": [
- {
- "name": "global",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:136:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quality",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:152:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "headlight",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:160:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "map",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:167:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scale",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:183:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "struct (anonymous struct at C:\\Users\\jonat\\Documents\\Unreal Projects\\url_proj\\Plugins\\UnrealRoboticsLab\\third_party\\install\\MuJoCo\\include\\mujoco/mjmodel.h:203:3)",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 135
- },
- "mjStatistic": {
- "name": "mjStatistic",
- "fields": [
- {
- "name": "meaninertia",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "meanmass",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "meansize",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "extent",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "center",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 236
- },
- "mjModel": {
- "name": "mjModel",
- "fields": [
- {
- "name": "nq",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nv",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nu",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "na",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbody",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbvh",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbvhstatic",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbvhdynamic",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "noct",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "njnt",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntree",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nM",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nB",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nC",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nD",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ngeom",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nsite",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ncam",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nlight",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflex",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexnode",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexvert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexedge",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexelem",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexelemdata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexstiffness",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexbending",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexelemedge",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexshelldata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflexevpair",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nflextexcoord",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nJfe",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nJfv",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmesh",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshvert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshnormal",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshtexcoord",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshface",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshgraph",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshpoly",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshpolyvert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmeshpolymap",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskin",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskinvert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskintexvert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskinface",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskinbone",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskinbonevert",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nhfield",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nhfielddata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntex",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntexdata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmat",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "npair",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nexclude",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "neq",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntendon",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nJten",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nwrap",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nsensor",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nnumeric",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nnumericdata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntext",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntextdata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntuple",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntupledata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nkey",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nmocap",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nplugin",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "npluginattr",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_body",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_jnt",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_geom",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_site",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_cam",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_tendon",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_actuator",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_sensor",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nnames",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "npaths",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nnames_map",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nJmom",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ngravcomp",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nemax",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "njmax",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nconmax",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuserdata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nsensordata",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "npluginstate",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nhistory",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "narena",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbuffer",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "opt",
- "c_type": "mjOption",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "vis",
- "c_type": "mjVisual",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "stat",
- "c_type": "mjStatistic",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "buffer",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qpos0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qpos_spring",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_parentid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_rootid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_weldid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_mocapid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_jntnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_jntadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_dofnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_dofadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_treeid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_geomnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_geomadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_simple",
- "c_type": "mjtByte *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_sameframe",
- "c_type": "mjtByte *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_ipos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_iquat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_mass",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_subtreemass",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_inertia",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_invweight0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_gravcomp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_contype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_conaffinity",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_bvhadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_bvhnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_depth",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_child",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_nodeid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_aabb",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "oct_depth",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "oct_child",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "oct_aabb",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "oct_coeff",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_qposadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_dofadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_actuatorid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_limited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_actfrclimited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_actgravcomp",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_axis",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_stiffness",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_stiffnesspoly",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_range",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_actfrcrange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "jnt_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_jntid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_parentid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_treeid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_Madr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_simplenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_frictionloss",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_armature",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_damping",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_dampingpoly",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_invweight0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_M0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_length",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_bodyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_bodynum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_dofadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_dofnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_sleep_policy",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_contype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_conaffinity",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_condim",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_dataid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_matid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_priority",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_sameframe",
- "c_type": "mjtByte *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_solmix",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_size",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_aabb",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_rbound",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_friction",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_gap",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_fluid",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_matid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_sameframe",
- "c_type": "mjtByte *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_size",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_mode",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_targetbodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_poscom0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_pos0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_mat0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_projection",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_fovy",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_ipd",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_resolution",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_output",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_sensorsize",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_intrinsic",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_mode",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_bodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_targetbodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_texid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_castshadow",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_bulbradius",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_intensity",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_range",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_active",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_dir",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_poscom0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_pos0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_dir0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_attenuation",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_cutoff",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_exponent",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_ambient",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_diffuse",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_specular",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_contype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_conaffinity",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_condim",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_priority",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_solmix",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_friction",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_gap",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_internal",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_selfcollide",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_activelayers",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_passive",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_dim",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_matid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_interp",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_cellnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_nodeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_nodenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemdataadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_stiffnessadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemedgeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_bendingadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_shellnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_shelldataadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_evpairadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_evpairnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_texcoordadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_nodebodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertbodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertedgeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertedgenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertedge",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edge",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgeflap",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elem",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemtexcoord",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemedge",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_elemlayer",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_shell",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_evpair",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vert",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vert0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_vertmetric",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_node",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_node0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_length0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_invweight0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_radius",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_size",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_stiffness",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_bending",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_damping",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgestiffness",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgedamping",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_edgeequality",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_rigid",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_rigid",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_centered",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_flatskin",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_bvhadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_bvhnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_J_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_J_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_J_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_J_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_J_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_J_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex_texcoord",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_vertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_vertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_faceadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_facenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_bvhadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_bvhnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_octadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_octnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_normaladr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_normalnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_texcoordadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_texcoordnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_graphadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_vert",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_normal",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_texcoord",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_face",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_facenormal",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_facetexcoord",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_graph",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_scale",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_pathadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polynum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polynormal",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polyvertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polyvertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polyvert",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polymapadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polymapnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh_polymap",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_matid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_inflate",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_vertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_vertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_texcoordadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_faceadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_facenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_boneadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_vert",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_texcoord",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_face",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonevertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonevertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonebindpos",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonebindquat",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonebodyid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonevertid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_bonevertweight",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skin_pathadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_size",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_nrow",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_ncol",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_data",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hfield_pathadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_colorspace",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_height",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_width",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_nchannel",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_adr",
- "c_type": "mjtSize *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_data",
- "c_type": "mjtByte *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tex_pathadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_texid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_texuniform",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_texrepeat",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_emission",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_specular",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_shininess",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_reflectance",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_metallic",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_roughness",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mat_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_dim",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_geom1",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_geom2",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_signature",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_solreffriction",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_gap",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair_friction",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "exclude_signature",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_obj1id",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_obj2id",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_objtype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_active0",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_solref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_solimp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_data",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_num",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_matid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_actuatorid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_treenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_treeid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_J_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_J_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_J_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_limited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_actfrclimited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_width",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_solref_lim",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_solimp_lim",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_solref_fri",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_solimp_fri",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_range",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_actfrcrange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_stiffness",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_stiffnesspoly",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_damping",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_dampingpoly",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_armature",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_frictionloss",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_lengthspring",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_length0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_invweight0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_rgba",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "wrap_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "wrap_objid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "wrap_prm",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_trntype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_dyntype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_gaintype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_biastype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_trnid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_damping",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_dampingpoly",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_armature",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_actadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_actnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_group",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_history",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_historyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_delay",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_ctrllimited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_forcelimited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_actlimited",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_dynprm",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_gainprm",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_biasprm",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_actearly",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_ctrlrange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_forcerange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_actrange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_gear",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_cranklength",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_acc0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_length0",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_lengthrange",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_datatype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_needstage",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_objtype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_objid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_reftype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_refid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_intprm",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_dim",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_cutoff",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_noise",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_history",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_historyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_delay",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_interval",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_user",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensor_plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_stateadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_statenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_attr",
- "c_type": "char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_attradr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "numeric_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "numeric_size",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "numeric_data",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "text_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "text_size",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "text_data",
- "c_type": "char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tuple_adr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tuple_size",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tuple_objtype",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tuple_objid",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tuple_objprm",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_time",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_qpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_qvel",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_act",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_mpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_mquat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "key_ctrl",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_bodyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_jntadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_geomadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_siteadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_camadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_lightadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_flexadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_meshadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_skinadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_hfieldadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_texadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_matadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_pairadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_excludeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_eqadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_tendonadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_actuatoradr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_sensoradr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_numericadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_textadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_tupleadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_keyadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name_pluginadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "names",
- "c_type": "char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "names_map",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "paths",
- "c_type": "char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "B_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "B_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "B_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "M_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "M_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "M_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mapM2M",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "D_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "D_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "D_diag",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "D_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mapM2D",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mapD2M",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "signature",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 248
- },
- "mjsElement": {
- "name": "mjsElement",
- "fields": [
- {
- "name": "elemtype",
- "c_type": "mjtObj",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "signature",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 152
- },
- "mjsCompiler": {
- "name": "mjsCompiler",
- "fields": [
- {
- "name": "autolimits",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "boundmass",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "boundinertia",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "settotalmass",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "balanceinertia",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fitaabb",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "degree",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "eulerseq",
- "c_type": "char [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "discardvisual",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "usethread",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fusestatic",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inertiafromgeom",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inertiagrouprange",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "saveinertial",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alignfree",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "LRopt",
- "c_type": "mjLROpt",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "meshdir",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "texturedir",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "authored",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 158
- },
- "mjsAuthored": {
- "name": "mjsAuthored",
- "fields": [
- {
- "name": "option",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "disableflags",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "enableflags",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "disableactuator",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_global",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_quality",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_headlight",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_map",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_scale",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual_rgba",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 181
- },
- "mjSpec": {
- "name": "mjSpec",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "modelname",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "compiler",
- "c_type": "mjsCompiler",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "strippath",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "option",
- "c_type": "mjOption",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "visual",
- "c_type": "mjVisual",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "stat",
- "c_type": "mjStatistic",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "memory",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nemax",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuserdata",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_body",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_jnt",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_geom",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_site",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_cam",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_tendon",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_actuator",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nuser_sensor",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nkey",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "njmax",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nconmax",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nstack",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "comment",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "modelfiledir",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hasImplicitPluginElem",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "authored",
- "c_type": "mjsAuthored",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 195
- },
- "mjsOrientation": {
- "name": "mjsOrientation",
- "fields": [
- {
- "name": "type",
- "c_type": "mjtOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "axisangle",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "xyaxes",
- "c_type": "double [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "zaxis",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "euler",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 237
- },
- "mjsPlugin": {
- "name": "mjsPlugin",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_name",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "active",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 246
- },
- "mjsBody": {
- "name": "mjsBody",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "childclass",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mass",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ipos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "iquat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inertia",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ialt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fullinertia",
- "c_type": "double [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mocap",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gravcomp",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sleep",
- "c_type": "mjtSleepPolicy",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "explicitinertial",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "mjsPlugin",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 255
- },
- "mjsFrame": {
- "name": "mjsFrame",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "childclass",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 283
- },
- "mjsJoint": {
- "name": "mjsJoint",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtJoint",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "axis",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ref",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "align",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "stiffness",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "springref",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "springdamper",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "limited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "margin",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref_limit",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp_limit",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actfrclimited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actfrcrange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "armature",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "damping",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frictionloss",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref_friction",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp_friction",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actgravcomp",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 293
- },
- "mjsGeom": {
- "name": "mjsGeom",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtGeom",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fromto",
- "c_type": "double [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "contype",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "conaffinity",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "condim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "priority",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "friction",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solmix",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "margin",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gap",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mass",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "density",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "typeinertia",
- "c_type": "mjtGeomInertia",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fluid_ellipsoid",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fluid_coefs",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "hfieldname",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "meshname",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "fitscale",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "mjsPlugin",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 332
- },
- "mjsSite": {
- "name": "mjsSite",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fromto",
- "c_type": "double [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtGeom",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 379
- },
- "mjsCamera": {
- "name": "mjsCamera",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "quat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "mjsOrientation",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mode",
- "c_type": "mjtCamLight",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "targetbody",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "proj",
- "c_type": "mjtProjection",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "resolution",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "output",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fovy",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ipd",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "intrinsic",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sensor_size",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "focal_length",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "focal_pixel",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "principal_length",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "principal_pixel",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 401
- },
- "mjsLight": {
- "name": "mjsLight",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dir",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mode",
- "c_type": "mjtCamLight",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "targetbody",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "active",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtLightType",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texture",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "castshadow",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "bulbradius",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "intensity",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "attenuation",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cutoff",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "exponent",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ambient",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "diffuse",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "specular",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 430
- },
- "mjsFlex": {
- "name": "mjsFlex",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "contype",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "conaffinity",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "condim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "priority",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "friction",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solmix",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "margin",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gap",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "radius",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "internal",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flatskin",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "selfcollide",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "passive",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "activelayers",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edgestiffness",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edgedamping",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "young",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "poisson",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "damping",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "thickness",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "elastic2d",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cellcount",
- "c_type": "int [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "order",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nodebody",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "vertbody",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "node",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "vert",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "elem",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "texcoord",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "elemtexcoord",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 459
- },
- "mjsMesh": {
- "name": "mjsMesh",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "content_type",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "file",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "refpos",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "refquat",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scale",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inertia",
- "c_type": "mjtMeshInertia",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "smoothnormal",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "needsdf",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxhullvert",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "uservert",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "usernormal",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "usertexcoord",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "userface",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "userfacenormal",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "userfacetexcoord",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "mjsPlugin",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "octree_maxdepth",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 510
- },
- "mjsHField": {
- "name": "mjsHField",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "content_type",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "file",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "double [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nrow",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ncol",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 534
- },
- "mjsSkin": {
- "name": "mjsSkin",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "file",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inflate",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "vert",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "texcoord",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "face",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bodyname",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bindpos",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bindquat",
- "c_type": "mjFloatVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "vertid",
- "c_type": "mjIntVecVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "vertweight",
- "c_type": "mjFloatVecVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 547
- },
- "mjsTexture": {
- "name": "mjsTexture",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtTexture",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "colorspace",
- "c_type": "mjtColorSpace",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "builtin",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mark",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgb1",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgb2",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "markrgb",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "random",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "height",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "width",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nchannel",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "content_type",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "file",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "gridsize",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gridlayout",
- "c_type": "char [12]",
- "array_dim": 12,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cubefiles",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "mjByteVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "hflip",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "vflip",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 572
- },
- "mjsMaterial": {
- "name": "mjsMaterial",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "textures",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "texuniform",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texrepeat",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "emission",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "specular",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shininess",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "reflectance",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "metallic",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "roughness",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 609
- },
- "mjsPair": {
- "name": "mjsPair",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geomname1",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geomname2",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "condim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solreffriction",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "margin",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gap",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "friction",
- "c_type": "double [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 625
- },
- "mjsExclude": {
- "name": "mjsExclude",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bodyname1",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bodyname2",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 642
- },
- "mjsEquality": {
- "name": "mjsEquality",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtEq",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "double [11]",
- "array_dim": 11,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "active",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "name1",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "name2",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "objtype",
- "c_type": "mjtObj",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 650
- },
- "mjsTendon": {
- "name": "mjsTendon",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "stiffness",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "springlength",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "damping",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frictionloss",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref_friction",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp_friction",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "armature",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "limited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actfrclimited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actfrcrange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "margin",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref_limit",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp_limit",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "width",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 664
- },
- "mjsWrap": {
- "name": "mjsWrap",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtWrap",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 697
- },
- "mjsActuator": {
- "name": "mjsActuator",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "gaintype",
- "c_type": "mjtGain",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gainprm",
- "c_type": "double [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "biastype",
- "c_type": "mjtBias",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "biasprm",
- "c_type": "double [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dyntype",
- "c_type": "mjtDyn",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dynprm",
- "c_type": "double [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actdim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actearly",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "trntype",
- "c_type": "mjtTrn",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gear",
- "c_type": "double [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "target",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "refsite",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "slidersite",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cranklength",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "lengthrange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "inheritrange",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "damping",
- "c_type": "double [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "armature",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ctrllimited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ctrlrange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "forcelimited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "forcerange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actlimited",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actrange",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "group",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nsample",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "interp",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "delay",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "mjsPlugin",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 704
- },
- "mjsSensor": {
- "name": "mjsSensor",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtSensor",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "objtype",
- "c_type": "mjtObj",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "objname",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "reftype",
- "c_type": "mjtObj",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "refname",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "intprm",
- "c_type": "int [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "datatype",
- "c_type": "mjtDataType",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "needstage",
- "c_type": "mjtStage",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cutoff",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "noise",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nsample",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "interp",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "delay",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "interval",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "mjsPlugin",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 750
- },
- "mjsNumeric": {
- "name": "mjsNumeric",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 783
- },
- "mjsText": {
- "name": "mjsText",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 791
- },
- "mjsTuple": {
- "name": "mjsTuple",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "objtype",
- "c_type": "mjIntVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "objname",
- "c_type": "mjStringVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "objprm",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 798
- },
- "mjsKey": {
- "name": "mjsKey",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "time",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "qpos",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qvel",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "act",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mpos",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mquat",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ctrl",
- "c_type": "mjDoubleVec *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "info",
- "c_type": "mjString *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 807
- },
- "mjsDefault": {
- "name": "mjsDefault",
- "fields": [
- {
- "name": "element",
- "c_type": "mjsElement *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "joint",
- "c_type": "mjsJoint *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom",
- "c_type": "mjsGeom *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site",
- "c_type": "mjsSite *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "camera",
- "c_type": "mjsCamera *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light",
- "c_type": "mjsLight *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flex",
- "c_type": "mjsFlex *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mesh",
- "c_type": "mjsMesh *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "material",
- "c_type": "mjsMaterial *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "pair",
- "c_type": "mjsPair *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "equality",
- "c_type": "mjsEquality *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon",
- "c_type": "mjsTendon *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator",
- "c_type": "mjsActuator *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspec.h",
- "line": 820
- },
- "mjPreContact": {
- "name": "mjPreContact",
- "fields": [
- {
- "name": "dist",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "normal",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "tangent",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 29
- },
- "mjContact": {
- "name": "mjContact",
- "fields": [
- {
- "name": "dist",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frame",
- "c_type": "mjtNum [9]",
- "array_dim": 9,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "includemargin",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "friction",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solref",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solreffriction",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solimp",
- "c_type": "mjtNum [5]",
- "array_dim": 5,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mu",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "H",
- "c_type": "mjtNum [36]",
- "array_dim": 36,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dim",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "geom1",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "geom2",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "geom",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flex",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "elem",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "vert",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "exclude",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "efc_address",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 37
- },
- "mjWarningStat": {
- "name": "mjWarningStat",
- "fields": [
- {
- "name": "lastinfo",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "number",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 74
- },
- "mjTimerStat": {
- "name": "mjTimerStat",
- "fields": [
- {
- "name": "duration",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "number",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 81
- },
- "mjSolverStat": {
- "name": "mjSolverStat",
- "fields": [
- {
- "name": "improvement",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gradient",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "lineslope",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nactive",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nchange",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "neval",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nupdate",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 88
- },
- "mjData": {
- "name": "mjData",
- "fields": [
- {
- "name": "narena",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbuffer",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nplugin",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pstack",
- "c_type": "size_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pbase",
- "c_type": "size_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "parena",
- "c_type": "size_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "threadpool",
- "c_type": "uintptr_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "threadlock",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxuse_stack",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxuse_arena",
- "c_type": "mjtSize",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxuse_con",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxuse_efc",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solver",
- "c_type": "mjSolverStat [4000]",
- "array_dim": 4000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solver_niter",
- "c_type": "int [20]",
- "array_dim": 20,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solver_nnz",
- "c_type": "int [20]",
- "array_dim": 20,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "solver_fwdinv",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "warning",
- "c_type": "mjWarningStat [7]",
- "array_dim": 7,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "timer",
- "c_type": "mjTimerStat [15]",
- "array_dim": 15,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ncon",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ne",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nf",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nl",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nefc",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nJ",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nY",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nA",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nisland",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nidof",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntree_awake",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nbody_awake",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nparent_awake",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nv_awake",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_energypos",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_energyvel",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_subtreevel",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_rnepost",
- "c_type": "mjtBool",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "time",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "energy",
- "c_type": "mjtNum [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "buffer",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "arena",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qvel",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "act",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "history",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qacc_warmstart",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_state",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ctrl",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_applied",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xfrc_applied",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "eq_active",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mocap_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "mocap_quat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qacc",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "act_dot",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sensordata",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_asleep",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "plugin_data",
- "c_type": "uintptr_t *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xquat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xmat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xipos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ximat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xanchor",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "xaxis",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geom_xmat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "site_xmat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cam_xmat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "light_xdir",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "subtree_com",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cdof",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cinert",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexelem_aabb",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_J",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_length",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_J",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert_length",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_aabb_dyn",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_wrapadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_wrapnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_J",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_length",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "wrap_obj",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "wrap_xpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_length",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "moment_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "moment_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "moment_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_moment",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "crb",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qM",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "M",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qLD",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qLDiagInv",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "bvh_active",
- "c_type": "mjtBool *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_awake",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_awake",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "body_awake_ind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "parent_awake_ind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_awake_ind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge_velocity",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ten_velocity",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_velocity",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cvel",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cdof_dot",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_bias",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_spring",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_damper",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_gravcomp",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_fluid",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_passive",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "subtree_linvel",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "subtree_angmom",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qH",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qHDiagInv",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qDeriv",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qLU",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_force",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_actuator",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_smooth",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qacc_smooth",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_constraint",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "qfrc_inverse",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cacc",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cfrc_int",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "cfrc_ext",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "contact",
- "c_type": "mjContact *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_id",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_J_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_J_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_J_rowsuper",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_J_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_J",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_pos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_margin",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_frictionloss",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_diagA",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_KBIP",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_D",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_R",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tendon_efcadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "tree_island",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_ntree",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_itreeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "map_itree2tree",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "dof_island",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_nv",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_idofadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_dofadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "map_dof2idof",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "map_idof2dof",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ifrc_smooth",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iacc_smooth",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iacc",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_island",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_ne",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_nf",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_nefc",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "island_iefcadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "map_efc2iefc",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "map_iefc2efc",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_type",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_id",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_frictionloss",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_D",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_R",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_Y_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_Y_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_Y_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_Y",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_AR_rownnz",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_AR_rowadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_AR_colind",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_AR",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_vel",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_aref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_b",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_aref",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_state",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "iefc_force",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_state",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "efc_force",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "ifrc_constraint",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "signature",
- "c_type": "uint64_t",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjdata.h",
- "line": 102
- },
- "mjvPerturb": {
- "name": "mjvPerturb",
- "fields": [
- {
- "name": "select",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexselect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "skinselect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "active",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "active2",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "refpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "refquat",
- "c_type": "mjtNum [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "refselpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "localpos",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "localmass",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scale",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 167
- },
- "mjvCamera": {
- "name": "mjvCamera",
- "fields": [
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fixedcamid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "trackbodyid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "lookat",
- "c_type": "mjtNum [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "distance",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "azimuth",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "elevation",
- "c_type": "mjtNum",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "orthographic",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 185
- },
- "mjvGLCamera": {
- "name": "mjvGLCamera",
- "fields": [
- {
- "name": "pos",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "forward",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "up",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_center",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_width",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_bottom",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_top",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_near",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frustum_far",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "orthographic",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 205
- },
- "mjvGeom": {
- "name": "mjvGeom",
- "fields": [
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dataid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "objtype",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "objid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "category",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "matid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texcoord",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "segid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "size",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mat",
- "c_type": "float [9]",
- "array_dim": 9,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "emission",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "specular",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shininess",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "reflectance",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "label",
- "c_type": "char [100]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "camdist",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "modelrbound",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "transparent",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 227
- },
- "mjvLight": {
- "name": "mjvLight",
- "fields": [
- {
- "name": "id",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pos",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dir",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "attenuation",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cutoff",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "exponent",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ambient",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "diffuse",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "specular",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "headlight",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "castshadow",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "bulbradius",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "intensity",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 262
- },
- "mjvOption": {
- "name": "mjvOption",
- "fields": [
- {
- "name": "label",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "frame",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "geomgroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sitegroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "jointgroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "tendongroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "actuatorgroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexgroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "skingroup",
- "c_type": "mjtByte [6]",
- "array_dim": 6,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flags",
- "c_type": "mjtByte [31]",
- "array_dim": 31,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "bvh_depth",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flex_layer",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 285
- },
- "mjvScene": {
- "name": "mjvScene",
- "fields": [
- {
- "name": "maxgeom",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ngeom",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "geoms",
- "c_type": "mjvGeom *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geomorder",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "nflex",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexedgeadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedgenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexfaceadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexfacenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexfaceused",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexedge",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvert",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexface",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexnormal",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flextexcoord",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "flexvertopt",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexedgeopt",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexfaceopt",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flexskinopt",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskin",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "skinfacenum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinvertadr",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinvertnum",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinvert",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinnormal",
- "c_type": "float *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "nlight",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "lights",
- "c_type": "mjvLight [100]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "camera",
- "c_type": "mjvGLCamera [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "enabletransform",
- "c_type": "mjtByte",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "translate",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rotate",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scale",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "stereo",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flags",
- "c_type": "mjtByte [11]",
- "array_dim": 11,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "framewidth",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "framergb",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "status",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 304
- },
- "mjvFigure": {
- "name": "mjvFigure",
- "fields": [
- {
- "name": "flg_legend",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_ticklabel",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_extend",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_barplot",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_selection",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "flg_symmetric",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linewidth",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gridwidth",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gridsize",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "gridrgb",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "figurergba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "panergba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "legendrgba",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "textrgb",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linergb",
- "c_type": "float [100][3]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "float [2][2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "xformat",
- "c_type": "char [20]",
- "array_dim": 20,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "yformat",
- "c_type": "char [20]",
- "array_dim": 20,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "minwidth",
- "c_type": "char [20]",
- "array_dim": 20,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "title",
- "c_type": "char [1000]",
- "array_dim": 1000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "xlabel",
- "c_type": "char [100]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linename",
- "c_type": "char [100][100]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "legendoffset",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "subplot",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "highlight",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "highlightid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "selection",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linepnt",
- "c_type": "int [100]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linedata",
- "c_type": "float [100][2002]",
- "array_dim": 100,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "xaxispixel",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "yaxispixel",
- "c_type": "int [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "xaxisdata",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "yaxisdata",
- "c_type": "float [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 367
- },
- "mjResource": {
- "name": "mjResource",
- "fields": [
- {
- "name": "name",
- "c_type": "char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "vfs",
- "c_type": "mjVFS *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "timestamp",
- "c_type": "char [512]",
- "array_dim": 512,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "provider",
- "c_type": "const struct mjpResourceProvider *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 27
- },
- "mjpResourceProvider": {
- "name": "mjpResourceProvider",
- "fields": [
- {
- "name": "prefix",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "open",
- "c_type": "mjfOpenResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "read",
- "c_type": "mjfReadResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "close",
- "c_type": "mjfCloseResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mount",
- "c_type": "mjfMountResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "unmount",
- "c_type": "mjfUnmountResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "modified",
- "c_type": "mjfResourceModified",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "data",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 63
- },
- "mjpDecoder": {
- "name": "mjpDecoder",
- "fields": [
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "extension",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "can_decode",
- "c_type": "mjfCanDecode",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "decode",
- "c_type": "mjfDecode",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 84
- },
- "mjpEncoder": {
- "name": "mjpEncoder",
- "fields": [
- {
- "name": "content_type",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "extension",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "encode",
- "c_type": "mjfEncode",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "close_resource",
- "c_type": "mjfCloseResource",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 100
- },
- "mjpPlugin": {
- "name": "mjpPlugin",
- "fields": [
- {
- "name": "name",
- "c_type": "const char *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "nattribute",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "attributes",
- "c_type": "const char *const *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "capabilityflags",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "needstage",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nstate",
- "c_type": "int (*)(const mjModel *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "nsensordata",
- "c_type": "int (*)(const mjModel *, int, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "init",
- "c_type": "int (*)(const mjModel *, mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "destroy",
- "c_type": "void (*)(mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "copy",
- "c_type": "void (*)(mjData *, const mjModel *, const mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "reset",
- "c_type": "void (*)(const mjModel *, mjtNum *, void *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "compute",
- "c_type": "void (*)(const mjModel *, mjData *, int, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "advance",
- "c_type": "void (*)(const mjModel *, mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "visualize",
- "c_type": "void (*)(const mjModel *, mjData *, const mjvOption *, mjvScene *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "actuator_act_dot",
- "c_type": "void (*)(const mjModel *, mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sdf_distance",
- "c_type": "mjtNum (*)(const mjtNum *, const mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sdf_gradient",
- "c_type": "void (*)(mjtNum *, const mjtNum *, const mjData *, int)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sdf_staticdistance",
- "c_type": "mjtNum (*)(const mjtNum *, const mjtNum *)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sdf_attribute",
- "c_type": "void (*)(mjtNum *, const char **, const char **)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sdf_aabb",
- "c_type": "void (*)(mjtNum *, const mjtNum *)",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 117
- },
- "mjSDF": {
- "name": "mjSDF",
- "fields": [
- {
- "name": "plugin",
- "c_type": "const mjpPlugin **",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "id",
- "c_type": "int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "mjtSDFType",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "relpos",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "relmat",
- "c_type": "mjtNum *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "geomtype",
- "c_type": "mjtGeom *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 178
- },
- "mjrRect": {
- "name": "mjrRect",
- "fields": [
- {
- "name": "left",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "bottom",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "width",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "height",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 112
- },
- "mjrVertexAttribute": {
- "name": "mjrVertexAttribute",
- "fields": [
- {
- "name": "bytes",
- "c_type": "const void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "usage",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 121
- },
- "mjrContext": {
- "name": "mjrContext",
- "fields": [
- {
- "name": "lineWidth",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shadowClip",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shadowScale",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fogStart",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fogEnd",
- "c_type": "float",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fogRGBA",
- "c_type": "float [4]",
- "array_dim": 4,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shadowSize",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offWidth",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offHeight",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offSamples",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fontScale",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxWidth",
- "c_type": "int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxHeight",
- "c_type": "int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxSamples",
- "c_type": "int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offFBO",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offFBO_r",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offColor",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offColor_r",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offDepthStencil",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "offDepthStencil_r",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shadowFBO",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shadowTex",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxFBO",
- "c_type": "unsigned int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxFBO_r",
- "c_type": "unsigned int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxColor",
- "c_type": "unsigned int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxColor_r",
- "c_type": "unsigned int [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mat_texid",
- "c_type": "int [10000]",
- "array_dim": 10000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mat_texuniform",
- "c_type": "int [1000]",
- "array_dim": 1000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mat_texrepeat",
- "c_type": "float [2000]",
- "array_dim": 2000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "ntexture",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "textureType",
- "c_type": "int [1000]",
- "array_dim": 1000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texture",
- "c_type": "unsigned int [1000]",
- "array_dim": 1000,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "basePlane",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseMesh",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseHField",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseBuiltin",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseFontNormal",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseFontShadow",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "baseFontBig",
- "c_type": "unsigned int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rangePlane",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rangeMesh",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rangeHField",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rangeBuiltin",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rangeFont",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nskin",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "skinvertVBO",
- "c_type": "unsigned int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinnormalVBO",
- "c_type": "unsigned int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skintexcoordVBO",
- "c_type": "unsigned int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "skinfaceVBO",
- "c_type": "unsigned int *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "charWidth",
- "c_type": "int [127]",
- "array_dim": 127,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "charWidthBig",
- "c_type": "int [127]",
- "array_dim": 127,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "charHeight",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "charHeightBig",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "glInitialized",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "windowAvailable",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "windowSamples",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "windowStereo",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "windowDoublebuffer",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "currentBuffer",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "readPixelFormat",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "readDepthMap",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 138
- },
- "mjuiState": {
- "name": "mjuiState",
- "fields": [
- {
- "name": "nrect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rect",
- "c_type": "mjrRect [25]",
- "array_dim": 25,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "left",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "right",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "middle",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "doubleclick",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "button",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "buttontime",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "x",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "y",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dx",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dy",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sx",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sy",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "control",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shift",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "alt",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "key",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "keytime",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mouserect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dragrect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dragbutton",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "dropcount",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "droppaths",
- "c_type": "const char **",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 123
- },
- "mjuiThemeSpacing": {
- "name": "mjuiThemeSpacing",
- "fields": [
- {
- "name": "total",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scroll",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "label",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "section",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cornersect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cornersep",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "itemside",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "itemmid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "itemver",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "texthor",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "textver",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "linescroll",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "samples",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 169
- },
- "mjuiThemeColor": {
- "name": "mjuiThemeColor",
- "fields": [
- {
- "name": "master",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "thumb",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitle",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitle2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitleuncheck",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitleuncheck2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitlecheck",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "secttitlecheck2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sectfont",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sectsymbol",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sectpane",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "separator",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "separator2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shortcut",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fontactive",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "fontinactive",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "decorinactive",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "decorinactive2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "button",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "check",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "radio",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "select",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "select2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "slider",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "slider2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edit",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edit2",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "cursor",
- "c_type": "float [3]",
- "array_dim": 3,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 189
- },
- "mjuiItemSingle": {
- "name": "mjuiItemSingle",
- "fields": [
- {
- "name": "modifier",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shortcut",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 224
- },
- "mjuiItemMulti": {
- "name": "mjuiItemMulti",
- "fields": [
- {
- "name": "nelem",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "name",
- "c_type": "char [35][40]",
- "array_dim": 35,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 230
- },
- "mjuiItemSlider": {
- "name": "mjuiItemSlider",
- "fields": [
- {
- "name": "range",
- "c_type": "double [2]",
- "array_dim": 2,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "divisions",
- "c_type": "double",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 236
- },
- "mjuiItemEdit": {
- "name": "mjuiItemEdit",
- "fields": [
- {
- "name": "nelem",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "range",
- "c_type": "double [7][2]",
- "array_dim": 7,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 242
- },
- "mjuiItem": {
- "name": "mjuiItem",
- "fields": [
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "name",
- "c_type": "char [40]",
- "array_dim": 40,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "state",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pdata",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "sectionid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "itemid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rect",
- "c_type": "mjrRect",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "skip",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 248
- },
- "mjuiSection": {
- "name": "mjuiSection",
- "fields": [
- {
- "name": "name",
- "c_type": "char [40]",
- "array_dim": 40,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "state",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "modifier",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "shortcut",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "checkbox",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "nitem",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "item",
- "c_type": "mjuiItem [200]",
- "array_dim": 200,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rtitle",
- "c_type": "mjrRect",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "rcontent",
- "c_type": "mjrRect",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "lastclick",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 275
- },
- "mjUI": {
- "name": "mjUI",
- "fields": [
- {
- "name": "spacing",
- "c_type": "mjuiThemeSpacing",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "color",
- "c_type": "mjuiThemeColor",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "predicate",
- "c_type": "mjfItemEnable",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "userdata",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "rectid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "auxid",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "radiocol",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "width",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "height",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "maxheight",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "scroll",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mousesect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mouseitem",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mousehelp",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mouseclicks",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "mousesectcheck",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "editsect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edititem",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "editcursor",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "editscroll",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "edittext",
- "c_type": "char [300]",
- "array_dim": 300,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "editchanged",
- "c_type": "mjuiItem *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "nsect",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "sect",
- "c_type": "mjuiSection [10]",
- "array_dim": 10,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 295
- },
- "mjuiDef": {
- "name": "mjuiDef",
- "fields": [
- {
- "name": "type",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "name",
- "c_type": "char [40]",
- "array_dim": 40,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "state",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "pdata",
- "c_type": "void *",
- "array_dim": null,
- "is_pointer": true,
- "doc": ""
- },
- {
- "name": "other",
- "c_type": "char [300]",
- "array_dim": 300,
- "is_pointer": false,
- "doc": ""
- },
- {
- "name": "otherint",
- "c_type": "int",
- "array_dim": null,
- "is_pointer": false,
- "doc": ""
- }
- ],
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 335
- }
- },
- "defines": {
- "mjMINVAL": {
- "value": "1E-15",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjtype.h",
- "line": 27
- },
- "mjPI": {
- "value": "3.14159265358979323846",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 24
- },
- "mjMAXVAL": {
- "value": "1E+10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 25
- },
- "mjMINMU": {
- "value": "1E-5",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 26
- },
- "mjMINIMP": {
- "value": "0.0001",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 27
- },
- "mjMAXIMP": {
- "value": "0.9999",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 28
- },
- "mjMAXCONPAIR": {
- "value": "50",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 29
- },
- "mjMAXTREEDEPTH": {
- "value": "50",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 30
- },
- "mjMAXFLEXNODES": {
- "value": "27",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 31
- },
- "mjMINAWAKE": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 32
- },
- "mjNEQDATA": {
- "value": "11",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 37
- },
- "mjNDYN": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 38
- },
- "mjNGAIN": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 39
- },
- "mjNBIAS": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 40
- },
- "mjNFLUID": {
- "value": "12",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 41
- },
- "mjNREF": {
- "value": "2",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 42
- },
- "mjNIMP": {
- "value": "5",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 43
- },
- "mjNPOLY": {
- "value": "2",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 44
- },
- "mjNSENS": {
- "value": "3",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 45
- },
- "mjNSOLVER": {
- "value": "200",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 46
- },
- "mjNISLAND": {
- "value": "20",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmodel.h",
- "line": 47
- },
- "MJOPTION_FIELDS": {
- "value": "X ( mjtNum , timestep , 1 ) X ( mjtNum , impratio , 1 ) X ( mjtNum , tolerance , 1 ) X ( mjtNum , ls_tolerance , 1 ) X ( mjtNum , noslip_tolerance , 1 ) X ( mjtNum , ccd_tolerance , 1 ) X ( mjtNum , sleep_tolerance , 1 ) XVEC ( mjtNum , gravity , 3 ) XVEC ( mjtNum , wind , 3 ) XVEC ( mjtNum , magnetic , 3 ) X ( mjtNum , density , 1 ) X ( mjtNum , viscosity , 1 ) X ( mjtNum , o_margin , 1 ) XVEC ( mjtNum , o_solref , mjNREF ) XVEC ( mjtNum , o_solimp , mjNIMP ) XVEC ( mjtNum , o_friction , 5 ) X ( int , integrator , 1 ) X ( int , cone , 1 ) X ( int , jacobian , 1 ) X ( int , solver , 1 ) X ( int , iterations , 1 ) X ( int , ls_iterations , 1 ) X ( int , noslip_iterations , 1 ) X ( int , ccd_iterations , 1 ) X ( int , disableflags , 1 ) X ( int , enableflags , 1 ) X ( int , disableactuator , 1 ) X ( int , sdf_initpoints , 1 ) X ( int , sdf_iterations , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 23
- },
- "MJSTATISTIC_FIELDS": {
- "value": "X ( meaninertia , 1 ) X ( meanmass , 1 ) X ( meansize , 1 ) X ( extent , 1 ) XVEC ( center , 3 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 58
- },
- "MJVISUAL_GLOBAL_FIELDS": {
- "value": "X ( int , cameraid , 1 ) X ( int , orthographic , 1 ) X ( float , fovy , 1 ) X ( float , ipd , 1 ) X ( float , azimuth , 1 ) X ( float , elevation , 1 ) X ( float , linewidth , 1 ) X ( float , glow , 1 ) X ( float , realtime , 1 ) X ( int , offwidth , 1 ) X ( int , offheight , 1 ) X ( int , ellipsoidinertia , 1 ) X ( int , bvactive , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 69
- },
- "MJVISUAL_QUALITY_FIELDS": {
- "value": "X ( int , shadowsize , 1 ) X ( int , offsamples , 1 ) X ( int , numslices , 1 ) X ( int , numstacks , 1 ) X ( int , numquads , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 84
- },
- "MJVISUAL_HEADLIGHT_FIELDS": {
- "value": "XVEC ( float , ambient , 3 ) XVEC ( float , diffuse , 3 ) XVEC ( float , specular , 3 ) X ( int , active , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 91
- },
- "MJVISUAL_MAP_FIELDS": {
- "value": "X ( float , stiffness , 1 ) X ( float , stiffnessrot , 1 ) X ( float , force , 1 ) X ( float , torque , 1 ) X ( float , alpha , 1 ) X ( float , fogstart , 1 ) X ( float , fogend , 1 ) X ( float , znear , 1 ) X ( float , zfar , 1 ) X ( float , haze , 1 ) X ( float , shadowclip , 1 ) X ( float , shadowscale , 1 ) X ( float , actuatortendon , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 97
- },
- "MJVISUAL_SCALE_FIELDS": {
- "value": "X ( float , forcewidth , 1 ) X ( float , contactwidth , 1 ) X ( float , contactheight , 1 ) X ( float , connect , 1 ) X ( float , com , 1 ) X ( float , camera , 1 ) X ( float , light , 1 ) X ( float , selectpoint , 1 ) X ( float , jointlength , 1 ) X ( float , jointwidth , 1 ) X ( float , actuatorlength , 1 ) X ( float , actuatorwidth , 1 ) X ( float , framelength , 1 ) X ( float , framewidth , 1 ) X ( float , constraint , 1 ) X ( float , slidercrank , 1 ) X ( float , frustum , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 112
- },
- "MJVISUAL_RGBA_FIELDS": {
- "value": "XVEC ( float , fog , 4 ) XVEC ( float , haze , 4 ) XVEC ( float , force , 4 ) XVEC ( float , inertia , 4 ) XVEC ( float , joint , 4 ) XVEC ( float , actuator , 4 ) XVEC ( float , actuatornegative , 4 ) XVEC ( float , actuatorpositive , 4 ) XVEC ( float , com , 4 ) XVEC ( float , camera , 4 ) XVEC ( float , light , 4 ) XVEC ( float , selectpoint , 4 ) XVEC ( float , connect , 4 ) XVEC ( float , contactpoint , 4 ) XVEC ( float , contactforce , 4 ) XVEC ( float , contactfriction , 4 ) XVEC ( float , contacttorque , 4 ) XVEC ( float , contactgap , 4 ) XVEC ( float , rangefinder , 4 ) XVEC ( float , constraint , 4 ) XVEC ( float , slidercrank , 4 ) XVEC ( float , crankbroken , 4 ) XVEC ( float , frustum , 4 ) XVEC ( float , bv , 4 ) XVEC ( float , bvactive , 4 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 131
- },
- "MJMODEL_SIZES": {
- "value": "X ( nq ) X ( nv ) X ( nu ) X ( na ) X ( nbody ) X ( nbvh ) X ( nbvhstatic ) X ( nbvhdynamic ) X ( noct ) X ( njnt ) X ( ntree ) X ( nM ) X ( nB ) X ( nC ) X ( nD ) X ( ngeom ) X ( nsite ) X ( ncam ) X ( nlight ) X ( nflex ) X ( nflexnode ) X ( nflexvert ) X ( nflexedge ) X ( nflexelem ) X ( nflexelemdata ) X ( nflexstiffness ) X ( nflexbending ) X ( nflexelemedge ) X ( nflexshelldata ) X ( nflexevpair ) X ( nflextexcoord ) X ( nJfe ) X ( nJfv ) X ( nmesh ) X ( nmeshvert ) X ( nmeshnormal ) X ( nmeshtexcoord ) X ( nmeshface ) X ( nmeshgraph ) X ( nmeshpoly ) X ( nmeshpolyvert ) X ( nmeshpolymap ) X ( nskin ) X ( nskinvert ) X ( nskintexvert ) X ( nskinface ) X ( nskinbone ) X ( nskinbonevert ) X ( nhfield ) X ( nhfielddata ) X ( ntex ) X ( ntexdata ) X ( nmat ) X ( npair ) X ( nexclude ) X ( neq ) X ( ntendon ) X ( nJten ) X ( nwrap ) X ( nsensor ) X ( nnumeric ) X ( nnumericdata ) X ( ntext ) X ( ntextdata ) X ( ntuple ) X ( ntupledata ) X ( nkey ) X ( nmocap ) X ( nplugin ) X ( npluginattr ) X ( nuser_body ) X ( nuser_jnt ) X ( nuser_geom ) X ( nuser_site ) X ( nuser_cam ) X ( nuser_tendon ) X ( nuser_actuator ) X ( nuser_sensor ) X ( nnames ) X ( npaths ) X ( nnames_map ) X ( nJmom ) X ( ngravcomp ) X ( nemax ) X ( njmax ) X ( nconmax ) X ( nuserdata ) X ( nsensordata ) X ( npluginstate ) X ( nhistory ) X ( narena ) X ( nbuffer )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 162
- },
- "MJMODEL_POINTERS_PREAMBLE": {
- "value": "( m ) int nuser_body = m -> nuser_body ; int nuser_jnt = m -> nuser_jnt ; int nuser_geom = m -> nuser_geom ; int nuser_site = m -> nuser_site ; int nuser_cam = m -> nuser_cam ; int nuser_tendon = m -> nuser_tendon ; int nuser_actuator = m -> nuser_actuator ; int nuser_sensor = m -> nuser_sensor ; int nq = m -> nq ; int nv = m -> nv ; int na = m -> na ; int nu = m -> nu ; int nmocap = m -> nmocap ;",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 260
- },
- "MJ_M": {
- "value": "( n ) n",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 277
- },
- "MJMODEL_POINTERS_BODY": {
- "value": "X ( int , body_parentid , nbody , 1 ) X ( int , body_rootid , nbody , 1 ) X ( int , body_weldid , nbody , 1 ) X ( int , body_mocapid , nbody , 1 ) X ( int , body_jntnum , nbody , 1 ) X ( int , body_jntadr , nbody , 1 ) X ( int , body_dofnum , nbody , 1 ) X ( int , body_dofadr , nbody , 1 ) X ( int , body_treeid , nbody , 1 ) X ( int , body_geomnum , nbody , 1 ) X ( int , body_geomadr , nbody , 1 ) X ( mjtByte , body_simple , nbody , 1 ) X ( mjtByte , body_sameframe , nbody , 1 ) X ( mjtNum , body_pos , nbody , 3 ) X ( mjtNum , body_quat , nbody , 4 ) X ( mjtNum , body_ipos , nbody , 3 ) X ( mjtNum , body_iquat , nbody , 4 ) X ( mjtNum , body_mass , nbody , 1 ) X ( mjtNum , body_subtreemass , nbody , 1 ) X ( mjtNum , body_inertia , nbody , 3 ) X ( mjtNum , body_invweight0 , nbody , 2 ) X ( mjtNum , body_gravcomp , nbody , 1 ) X ( mjtNum , body_margin , nbody , 1 ) X ( mjtNum , body_user , nbody , MJ_M ( nuser_body ) ) X ( int , body_plugin , nbody , 1 ) X ( int , body_contype , nbody , 1 ) X ( int , body_conaffinity , nbody , 1 ) X ( int , body_bvhadr , nbody , 1 ) X ( int , body_bvhnum , nbody , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 283
- },
- "MJMODEL_POINTERS_JOINT": {
- "value": "X ( int , jnt_type , njnt , 1 ) X ( int , jnt_qposadr , njnt , 1 ) X ( int , jnt_dofadr , njnt , 1 ) X ( int , jnt_bodyid , njnt , 1 ) X ( int , jnt_actuatorid , njnt , 1 ) X ( int , jnt_group , njnt , 1 ) X ( mjtBool , jnt_limited , njnt , 1 ) X ( mjtBool , jnt_actfrclimited , njnt , 1 ) X ( mjtBool , jnt_actgravcomp , njnt , 1 ) X ( mjtNum , jnt_solref , njnt , mjNREF ) X ( mjtNum , jnt_solimp , njnt , mjNIMP ) X ( mjtNum , jnt_pos , njnt , 3 ) X ( mjtNum , jnt_axis , njnt , 3 ) X ( mjtNum , jnt_stiffness , njnt , 1 ) X ( mjtNum , jnt_stiffnesspoly , njnt , mjNPOLY ) X ( mjtNum , jnt_range , njnt , 2 ) X ( mjtNum , jnt_actfrcrange , njnt , 2 ) X ( mjtNum , jnt_margin , njnt , 1 ) X ( mjtNum , jnt_user , njnt , MJ_M ( nuser_jnt ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 314
- },
- "MJMODEL_POINTERS_DOF": {
- "value": "X ( int , dof_bodyid , nv , 1 ) X ( int , dof_jntid , nv , 1 ) X ( int , dof_parentid , nv , 1 ) X ( int , dof_treeid , nv , 1 ) X ( int , dof_Madr , nv , 1 ) X ( int , dof_simplenum , nv , 1 ) X ( mjtNum , dof_solref , nv , mjNREF ) X ( mjtNum , dof_solimp , nv , mjNIMP ) X ( mjtNum , dof_frictionloss , nv , 1 ) X ( mjtNum , dof_armature , nv , 1 ) X ( mjtNum , dof_damping , nv , 1 ) X ( mjtNum , dof_dampingpoly , nv , mjNPOLY ) X ( mjtNum , dof_invweight0 , nv , 1 ) X ( mjtNum , dof_M0 , nv , 1 ) X ( mjtNum , dof_length , nv , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 335
- },
- "MJMODEL_POINTERS_TREE": {
- "value": "X ( int , tree_bodyadr , ntree , 1 ) X ( int , tree_bodynum , ntree , 1 ) X ( int , tree_dofadr , ntree , 1 ) X ( int , tree_dofnum , ntree , 1 ) X ( int , tree_sleep_policy , ntree , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 352
- },
- "MJMODEL_POINTERS_GEOM": {
- "value": "X ( int , geom_type , ngeom , 1 ) X ( int , geom_contype , ngeom , 1 ) X ( int , geom_conaffinity , ngeom , 1 ) X ( int , geom_condim , ngeom , 1 ) X ( int , geom_bodyid , ngeom , 1 ) X ( int , geom_dataid , ngeom , 1 ) X ( int , geom_matid , ngeom , 1 ) X ( int , geom_group , ngeom , 1 ) X ( int , geom_priority , ngeom , 1 ) X ( int , geom_plugin , ngeom , 1 ) X ( mjtByte , geom_sameframe , ngeom , 1 ) X ( mjtNum , geom_solmix , ngeom , 1 ) X ( mjtNum , geom_solref , ngeom , mjNREF ) X ( mjtNum , geom_solimp , ngeom , mjNIMP ) X ( mjtNum , geom_size , ngeom , 3 ) X ( mjtNum , geom_aabb , ngeom , 6 ) X ( mjtNum , geom_rbound , ngeom , 1 ) X ( mjtNum , geom_pos , ngeom , 3 ) X ( mjtNum , geom_quat , ngeom , 4 ) X ( mjtNum , geom_friction , ngeom , 3 ) X ( mjtNum , geom_margin , ngeom , 1 ) X ( mjtNum , geom_gap , ngeom , 1 ) XNV ( mjtNum , geom_fluid , ngeom , mjNFLUID ) X ( mjtNum , geom_user , ngeom , MJ_M ( nuser_geom ) ) X ( float , geom_rgba , ngeom , 4 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 359
- },
- "MJMODEL_POINTERS_SITE": {
- "value": "X ( int , site_type , nsite , 1 ) X ( int , site_bodyid , nsite , 1 ) X ( int , site_matid , nsite , 1 ) X ( int , site_group , nsite , 1 ) X ( mjtByte , site_sameframe , nsite , 1 ) X ( mjtNum , site_size , nsite , 3 ) X ( mjtNum , site_pos , nsite , 3 ) X ( mjtNum , site_quat , nsite , 4 ) X ( mjtNum , site_user , nsite , MJ_M ( nuser_site ) ) X ( float , site_rgba , nsite , 4 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 386
- },
- "MJMODEL_POINTERS_CAMERA": {
- "value": "X ( int , cam_mode , ncam , 1 ) X ( int , cam_bodyid , ncam , 1 ) X ( int , cam_targetbodyid , ncam , 1 ) X ( mjtNum , cam_pos , ncam , 3 ) X ( mjtNum , cam_quat , ncam , 4 ) X ( mjtNum , cam_poscom0 , ncam , 3 ) X ( mjtNum , cam_pos0 , ncam , 3 ) X ( mjtNum , cam_mat0 , ncam , 9 ) X ( int , cam_projection , ncam , 1 ) X ( mjtNum , cam_fovy , ncam , 1 ) X ( mjtNum , cam_ipd , ncam , 1 ) X ( int , cam_resolution , ncam , 2 ) X ( int , cam_output , ncam , 1 ) X ( float , cam_sensorsize , ncam , 2 ) X ( float , cam_intrinsic , ncam , 4 ) X ( mjtNum , cam_user , ncam , MJ_M ( nuser_cam ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 398
- },
- "MJMODEL_POINTERS_LIGHT": {
- "value": "X ( int , light_mode , nlight , 1 ) X ( int , light_bodyid , nlight , 1 ) X ( int , light_targetbodyid , nlight , 1 ) X ( int , light_type , nlight , 1 ) X ( int , light_texid , nlight , 1 ) X ( mjtBool , light_castshadow , nlight , 1 ) X ( float , light_bulbradius , nlight , 1 ) X ( float , light_intensity , nlight , 1 ) X ( float , light_range , nlight , 1 ) X ( mjtBool , light_active , nlight , 1 ) X ( mjtNum , light_pos , nlight , 3 ) X ( mjtNum , light_dir , nlight , 3 ) X ( mjtNum , light_poscom0 , nlight , 3 ) X ( mjtNum , light_pos0 , nlight , 3 ) X ( mjtNum , light_dir0 , nlight , 3 ) X ( float , light_attenuation , nlight , 3 ) X ( float , light_cutoff , nlight , 1 ) X ( float , light_exponent , nlight , 1 ) X ( float , light_ambient , nlight , 3 ) X ( float , light_diffuse , nlight , 3 ) X ( float , light_specular , nlight , 3 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 416
- },
- "MJMODEL_POINTERS_FLEX": {
- "value": "X ( int , flex_contype , nflex , 1 ) X ( int , flex_conaffinity , nflex , 1 ) X ( int , flex_condim , nflex , 1 ) X ( int , flex_priority , nflex , 1 ) X ( mjtNum , flex_solmix , nflex , 1 ) X ( mjtNum , flex_solref , nflex , mjNREF ) X ( mjtNum , flex_solimp , nflex , mjNIMP ) X ( mjtNum , flex_friction , nflex , 3 ) X ( mjtNum , flex_margin , nflex , 1 ) X ( mjtNum , flex_gap , nflex , 1 ) X ( mjtBool , flex_internal , nflex , 1 ) X ( int , flex_selfcollide , nflex , 1 ) X ( int , flex_activelayers , nflex , 1 ) X ( int , flex_passive , nflex , 1 ) X ( int , flex_dim , nflex , 1 ) X ( int , flex_matid , nflex , 1 ) X ( int , flex_group , nflex , 1 ) X ( int , flex_interp , nflex , 1 ) X ( int , flex_cellnum , nflex , 3 ) X ( int , flex_nodeadr , nflex , 1 ) X ( int , flex_nodenum , nflex , 1 ) X ( int , flex_vertadr , nflex , 1 ) X ( int , flex_vertnum , nflex , 1 ) X ( int , flex_edgeadr , nflex , 1 ) X ( int , flex_edgenum , nflex , 1 ) X ( int , flex_elemadr , nflex , 1 ) X ( int , flex_elemnum , nflex , 1 ) X ( int , flex_elemdataadr , nflex , 1 ) X ( int , flex_stiffnessadr , nflex , 1 ) X ( int , flex_elemedgeadr , nflex , 1 ) X ( int , flex_bendingadr , nflex , 1 ) X ( int , flex_shellnum , nflex , 1 ) X ( int , flex_shelldataadr , nflex , 1 ) X ( int , flex_evpairadr , nflex , 1 ) X ( int , flex_evpairnum , nflex , 1 ) X ( int , flex_texcoordadr , nflex , 1 ) X ( int , flex_nodebodyid , nflexnode , 1 ) X ( int , flex_vertbodyid , nflexvert , 1 ) X ( int , flex_vertedgeadr , nflexvert , 1 ) X ( int , flex_vertedgenum , nflexvert , 1 ) X ( int , flex_vertedge , nflexedge , 2 ) X ( int , flex_edge , nflexedge , 2 ) X ( int , flex_edgeflap , nflexedge , 2 ) X ( int , flex_elem , nflexelemdata , 1 ) X ( int , flex_elemtexcoord , nflexelemdata , 1 ) X ( int , flex_elemedge , nflexelemedge , 1 ) X ( int , flex_elemlayer , nflexelem , 1 ) X ( int , flex_shell , nflexshelldata , 1 ) X ( int , flex_evpair , nflexevpair , 2 ) X ( mjtNum , flex_vert , nflexvert , 3 ) X ( mjtNum , flex_vert0 , nflexvert , 3 ) X ( mjtNum , flex_vertmetric , nflexvert , 4 ) X ( mjtNum , flex_node , nflexnode , 3 ) X ( mjtNum , flex_node0 , nflexnode , 3 ) X ( mjtNum , flexedge_length0 , nflexedge , 1 ) X ( mjtNum , flexedge_invweight0 , nflexedge , 1 ) X ( mjtNum , flex_radius , nflex , 1 ) X ( mjtNum , flex_size , nflex , 3 ) X ( mjtNum , flex_stiffness , nflexstiffness , 1 ) X ( mjtNum , flex_bending , nflexbending , 1 ) X ( mjtNum , flex_damping , nflex , 1 ) X ( mjtNum , flex_edgestiffness , nflex , 1 ) X ( mjtNum , flex_edgedamping , nflex , 1 ) X ( int , flex_edgeequality , nflex , 1 ) X ( mjtBool , flex_rigid , nflex , 1 ) X ( mjtBool , flexedge_rigid , nflexedge , 1 ) X ( mjtBool , flex_centered , nflex , 1 ) X ( mjtBool , flex_flatskin , nflex , 1 ) X ( int , flex_bvhadr , nflex , 1 ) X ( int , flex_bvhnum , nflex , 1 ) X ( int , flexedge_J_rownnz , nflexedge , 1 ) X ( int , flexedge_J_rowadr , nflexedge , 1 ) X ( int , flexedge_J_colind , nJfe , 1 ) X ( int , flexvert_J_rownnz , nflexvert , 2 ) X ( int , flexvert_J_rowadr , nflexvert , 2 ) X ( int , flexvert_J_colind , nJfv , 2 ) X ( float , flex_rgba , nflex , 4 ) X ( float , flex_texcoord , nflextexcoord , 2 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 439
- },
- "MJMODEL_POINTERS_MESH": {
- "value": "X ( int , mesh_vertadr , nmesh , 1 ) X ( int , mesh_vertnum , nmesh , 1 ) X ( int , mesh_faceadr , nmesh , 1 ) X ( int , mesh_facenum , nmesh , 1 ) X ( int , mesh_bvhadr , nmesh , 1 ) X ( int , mesh_bvhnum , nmesh , 1 ) X ( int , mesh_octadr , nmesh , 1 ) X ( int , mesh_octnum , nmesh , 1 ) X ( int , mesh_normaladr , nmesh , 1 ) X ( int , mesh_normalnum , nmesh , 1 ) X ( int , mesh_texcoordadr , nmesh , 1 ) X ( int , mesh_texcoordnum , nmesh , 1 ) X ( int , mesh_graphadr , nmesh , 1 ) XNV ( float , mesh_vert , nmeshvert , 3 ) XNV ( float , mesh_normal , nmeshnormal , 3 ) XNV ( float , mesh_texcoord , nmeshtexcoord , 2 ) XNV ( int , mesh_face , nmeshface , 3 ) XNV ( int , mesh_facenormal , nmeshface , 3 ) XNV ( int , mesh_facetexcoord , nmeshface , 3 ) XNV ( int , mesh_graph , nmeshgraph , 1 ) X ( mjtNum , mesh_scale , nmesh , 3 ) X ( mjtNum , mesh_pos , nmesh , 3 ) X ( mjtNum , mesh_quat , nmesh , 4 ) X ( int , mesh_pathadr , nmesh , 1 ) XNV ( int , mesh_polynum , nmesh , 1 ) XNV ( int , mesh_polyadr , nmesh , 1 ) XNV ( mjtNum , mesh_polynormal , nmeshpoly , 3 ) XNV ( int , mesh_polyvertadr , nmeshpoly , 1 ) XNV ( int , mesh_polyvertnum , nmeshpoly , 1 ) XNV ( int , mesh_polyvert , nmeshpolyvert , 1 ) XNV ( int , mesh_polymapadr , nmeshvert , 1 ) XNV ( int , mesh_polymapnum , nmeshvert , 1 ) XNV ( int , mesh_polymap , nmeshpolymap , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 519
- },
- "MJMODEL_POINTERS_SKIN": {
- "value": "X ( int , skin_matid , nskin , 1 ) X ( int , skin_group , nskin , 1 ) X ( float , skin_rgba , nskin , 4 ) X ( float , skin_inflate , nskin , 1 ) X ( int , skin_vertadr , nskin , 1 ) X ( int , skin_vertnum , nskin , 1 ) X ( int , skin_texcoordadr , nskin , 1 ) X ( int , skin_faceadr , nskin , 1 ) X ( int , skin_facenum , nskin , 1 ) X ( int , skin_boneadr , nskin , 1 ) X ( int , skin_bonenum , nskin , 1 ) X ( float , skin_vert , nskinvert , 3 ) X ( float , skin_texcoord , nskintexvert , 2 ) X ( int , skin_face , nskinface , 3 ) X ( int , skin_bonevertadr , nskinbone , 1 ) X ( int , skin_bonevertnum , nskinbone , 1 ) X ( float , skin_bonebindpos , nskinbone , 3 ) X ( float , skin_bonebindquat , nskinbone , 4 ) X ( int , skin_bonebodyid , nskinbone , 1 ) X ( int , skin_bonevertid , nskinbonevert , 1 ) X ( float , skin_bonevertweight , nskinbonevert , 1 ) X ( int , skin_pathadr , nskin , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 554
- },
- "MJMODEL_POINTERS_HFIELD": {
- "value": "X ( mjtNum , hfield_size , nhfield , 4 ) X ( int , hfield_nrow , nhfield , 1 ) X ( int , hfield_ncol , nhfield , 1 ) X ( int , hfield_adr , nhfield , 1 ) XNV ( float , hfield_data , nhfielddata , 1 ) X ( int , hfield_pathadr , nhfield , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 578
- },
- "MJMODEL_POINTERS_TEXTURE": {
- "value": "X ( int , tex_type , ntex , 1 ) X ( int , tex_colorspace , ntex , 1 ) X ( int , tex_height , ntex , 1 ) X ( int , tex_width , ntex , 1 ) X ( int , tex_nchannel , ntex , 1 ) X ( mjtSize , tex_adr , ntex , 1 ) XNV ( mjtByte , tex_data , ntexdata , 1 ) X ( int , tex_pathadr , ntex , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 586
- },
- "MJMODEL_POINTERS_MATERIAL": {
- "value": "X ( int , mat_texid , nmat , mjNTEXROLE ) X ( mjtBool , mat_texuniform , nmat , 1 ) X ( float , mat_texrepeat , nmat , 2 ) X ( float , mat_emission , nmat , 1 ) X ( float , mat_specular , nmat , 1 ) X ( float , mat_shininess , nmat , 1 ) X ( float , mat_reflectance , nmat , 1 ) X ( float , mat_metallic , nmat , 1 ) X ( float , mat_roughness , nmat , 1 ) X ( float , mat_rgba , nmat , 4 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 596
- },
- "MJMODEL_POINTERS_PAIR": {
- "value": "X ( int , pair_dim , npair , 1 ) X ( int , pair_geom1 , npair , 1 ) X ( int , pair_geom2 , npair , 1 ) X ( int , pair_signature , npair , 1 ) X ( mjtNum , pair_solref , npair , mjNREF ) X ( mjtNum , pair_solreffriction , npair , mjNREF ) X ( mjtNum , pair_solimp , npair , mjNIMP ) X ( mjtNum , pair_margin , npair , 1 ) X ( mjtNum , pair_gap , npair , 1 ) X ( mjtNum , pair_friction , npair , 5 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 608
- },
- "MJMODEL_POINTERS_EXCLUDE": {
- "value": "X ( int , exclude_signature , nexclude , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 620
- },
- "MJMODEL_POINTERS_EQUALITY": {
- "value": "X ( int , eq_type , neq , 1 ) X ( int , eq_obj1id , neq , 1 ) X ( int , eq_obj2id , neq , 1 ) X ( int , eq_objtype , neq , 1 ) X ( mjtBool , eq_active0 , neq , 1 ) X ( mjtNum , eq_solref , neq , mjNREF ) X ( mjtNum , eq_solimp , neq , mjNIMP ) X ( mjtNum , eq_data , neq , mjNEQDATA )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 623
- },
- "MJMODEL_POINTERS_TENDON": {
- "value": "X ( int , tendon_adr , ntendon , 1 ) X ( int , tendon_num , ntendon , 1 ) X ( int , tendon_matid , ntendon , 1 ) X ( int , tendon_actuatorid , ntendon , 1 ) X ( int , tendon_group , ntendon , 1 ) X ( int , tendon_treenum , ntendon , 1 ) X ( int , tendon_treeid , ntendon , 2 ) X ( int , ten_J_rownnz , ntendon , 1 ) X ( int , ten_J_rowadr , ntendon , 1 ) X ( int , ten_J_colind , nJten , 1 ) X ( mjtBool , tendon_limited , ntendon , 1 ) X ( mjtBool , tendon_actfrclimited , ntendon , 1 ) X ( mjtNum , tendon_width , ntendon , 1 ) X ( mjtNum , tendon_solref_lim , ntendon , mjNREF ) X ( mjtNum , tendon_solimp_lim , ntendon , mjNIMP ) X ( mjtNum , tendon_solref_fri , ntendon , mjNREF ) X ( mjtNum , tendon_solimp_fri , ntendon , mjNIMP ) X ( mjtNum , tendon_range , ntendon , 2 ) X ( mjtNum , tendon_actfrcrange , ntendon , 2 ) X ( mjtNum , tendon_margin , ntendon , 1 ) X ( mjtNum , tendon_stiffness , ntendon , 1 ) X ( mjtNum , tendon_stiffnesspoly , ntendon , mjNPOLY ) X ( mjtNum , tendon_damping , ntendon , 1 ) X ( mjtNum , tendon_dampingpoly , ntendon , mjNPOLY ) X ( mjtNum , tendon_armature , ntendon , 1 ) X ( mjtNum , tendon_frictionloss , ntendon , 1 ) X ( mjtNum , tendon_lengthspring , ntendon , 2 ) X ( mjtNum , tendon_length0 , ntendon , 1 ) X ( mjtNum , tendon_invweight0 , ntendon , 1 ) X ( mjtNum , tendon_user , ntendon , MJ_M ( nuser_tendon ) ) X ( float , tendon_rgba , ntendon , 4 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 633
- },
- "MJMODEL_POINTERS_ACTUATOR": {
- "value": "X ( int , actuator_trntype , nu , 1 ) X ( int , actuator_dyntype , nu , 1 ) X ( int , actuator_gaintype , nu , 1 ) X ( int , actuator_biastype , nu , 1 ) X ( int , actuator_trnid , nu , 2 ) X ( mjtNum , actuator_damping , nu , 1 ) X ( mjtNum , actuator_dampingpoly , nu , mjNPOLY ) X ( mjtNum , actuator_armature , nu , 1 ) X ( int , actuator_actadr , nu , 1 ) X ( int , actuator_actnum , nu , 1 ) X ( int , actuator_group , nu , 1 ) X ( int , actuator_history , nu , 2 ) X ( int , actuator_historyadr , nu , 1 ) X ( mjtNum , actuator_delay , nu , 1 ) X ( mjtBool , actuator_ctrllimited , nu , 1 ) X ( mjtBool , actuator_forcelimited , nu , 1 ) X ( mjtBool , actuator_actlimited , nu , 1 ) X ( mjtNum , actuator_dynprm , nu , mjNDYN ) X ( mjtNum , actuator_gainprm , nu , mjNGAIN ) X ( mjtNum , actuator_biasprm , nu , mjNBIAS ) X ( mjtBool , actuator_actearly , nu , 1 ) X ( mjtNum , actuator_ctrlrange , nu , 2 ) X ( mjtNum , actuator_forcerange , nu , 2 ) X ( mjtNum , actuator_actrange , nu , 2 ) X ( mjtNum , actuator_gear , nu , 6 ) X ( mjtNum , actuator_cranklength , nu , 1 ) X ( mjtNum , actuator_acc0 , nu , 1 ) X ( mjtNum , actuator_length0 , nu , 1 ) X ( mjtNum , actuator_lengthrange , nu , 2 ) X ( mjtNum , actuator_user , nu , MJ_M ( nuser_actuator ) ) X ( int , actuator_plugin , nu , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 666
- },
- "MJMODEL_POINTERS_SENSOR": {
- "value": "X ( int , sensor_type , nsensor , 1 ) X ( int , sensor_datatype , nsensor , 1 ) X ( int , sensor_needstage , nsensor , 1 ) X ( int , sensor_objtype , nsensor , 1 ) X ( int , sensor_objid , nsensor , 1 ) X ( int , sensor_reftype , nsensor , 1 ) X ( int , sensor_refid , nsensor , 1 ) X ( int , sensor_intprm , nsensor , mjNSENS ) X ( int , sensor_dim , nsensor , 1 ) X ( int , sensor_adr , nsensor , 1 ) X ( mjtNum , sensor_cutoff , nsensor , 1 ) X ( mjtNum , sensor_noise , nsensor , 1 ) X ( int , sensor_history , nsensor , 2 ) X ( int , sensor_historyadr , nsensor , 1 ) X ( mjtNum , sensor_delay , nsensor , 1 ) X ( mjtNum , sensor_interval , nsensor , 2 ) X ( mjtNum , sensor_user , nsensor , MJ_M ( nuser_sensor ) ) X ( int , sensor_plugin , nsensor , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 699
- },
- "MJMODEL_POINTERS": {
- "value": "X ( mjtNum , qpos0 , nq , 1 ) X ( mjtNum , qpos_spring , nq , 1 ) MJMODEL_POINTERS_BODY X ( int , bvh_depth , nbvh , 1 ) X ( int , bvh_child , nbvh , 2 ) X ( int , bvh_nodeid , nbvh , 1 ) X ( mjtNum , bvh_aabb , nbvhstatic , 6 ) X ( int , oct_depth , noct , 1 ) X ( int , oct_child , noct , 8 ) X ( mjtNum , oct_aabb , noct , 6 ) X ( mjtNum , oct_coeff , noct , 8 ) MJMODEL_POINTERS_JOINT MJMODEL_POINTERS_DOF MJMODEL_POINTERS_TREE MJMODEL_POINTERS_GEOM MJMODEL_POINTERS_SITE MJMODEL_POINTERS_CAMERA MJMODEL_POINTERS_LIGHT MJMODEL_POINTERS_FLEX MJMODEL_POINTERS_MESH MJMODEL_POINTERS_SKIN MJMODEL_POINTERS_HFIELD MJMODEL_POINTERS_TEXTURE MJMODEL_POINTERS_MATERIAL MJMODEL_POINTERS_PAIR MJMODEL_POINTERS_EXCLUDE MJMODEL_POINTERS_EQUALITY MJMODEL_POINTERS_TENDON X ( int , wrap_type , nwrap , 1 ) X ( int , wrap_objid , nwrap , 1 ) X ( mjtNum , wrap_prm , nwrap , 1 ) MJMODEL_POINTERS_ACTUATOR MJMODEL_POINTERS_SENSOR X ( int , plugin , nplugin , 1 ) X ( int , plugin_stateadr , nplugin , 1 ) X ( int , plugin_statenum , nplugin , 1 ) X ( char , plugin_attr , npluginattr , 1 ) X ( int , plugin_attradr , nplugin , 1 ) X ( int , numeric_adr , nnumeric , 1 ) X ( int , numeric_size , nnumeric , 1 ) X ( mjtNum , numeric_data , nnumericdata , 1 ) X ( int , text_adr , ntext , 1 ) X ( int , text_size , ntext , 1 ) X ( char , text_data , ntextdata , 1 ) X ( int , tuple_adr , ntuple , 1 ) X ( int , tuple_size , ntuple , 1 ) X ( int , tuple_objtype , ntupledata , 1 ) X ( int , tuple_objid , ntupledata , 1 ) X ( mjtNum , tuple_objprm , ntupledata , 1 ) X ( mjtNum , key_time , nkey , 1 ) X ( mjtNum , key_qpos , nkey , MJ_M ( nq ) ) X ( mjtNum , key_qvel , nkey , MJ_M ( nv ) ) X ( mjtNum , key_act , nkey , MJ_M ( na ) ) X ( mjtNum , key_mpos , nkey , MJ_M ( nmocap ) * 3 ) X ( mjtNum , key_mquat , nkey , MJ_M ( nmocap ) * 4 ) X ( mjtNum , key_ctrl , nkey , MJ_M ( nu ) ) X ( int , name_bodyadr , nbody , 1 ) X ( int , name_jntadr , njnt , 1 ) X ( int , name_geomadr , ngeom , 1 ) X ( int , name_siteadr , nsite , 1 ) X ( int , name_camadr , ncam , 1 ) X ( int , name_lightadr , nlight , 1 ) X ( int , name_flexadr , nflex , 1 ) X ( int , name_meshadr , nmesh , 1 ) X ( int , name_skinadr , nskin , 1 ) X ( int , name_hfieldadr , nhfield , 1 ) X ( int , name_texadr , ntex , 1 ) X ( int , name_matadr , nmat , 1 ) X ( int , name_pairadr , npair , 1 ) X ( int , name_excludeadr , nexclude , 1 ) X ( int , name_eqadr , neq , 1 ) X ( int , name_tendonadr , ntendon , 1 ) X ( int , name_actuatoradr , nu , 1 ) X ( int , name_sensoradr , nsensor , 1 ) X ( int , name_numericadr , nnumeric , 1 ) X ( int , name_textadr , ntext , 1 ) X ( int , name_tupleadr , ntuple , 1 ) X ( int , name_keyadr , nkey , 1 ) X ( int , name_pluginadr , nplugin , 1 ) X ( char , names , nnames , 1 ) X ( int , names_map , nnames_map , 1 ) X ( char , paths , npaths , 1 ) X ( int , B_rownnz , nbody , 1 ) X ( int , B_rowadr , nbody , 1 ) X ( int , B_colind , nB , 1 ) X ( int , M_rownnz , nv , 1 ) X ( int , M_rowadr , nv , 1 ) X ( int , M_colind , nC , 1 ) X ( int , mapM2M , nC , 1 ) X ( int , D_rownnz , nv , 1 ) X ( int , D_rowadr , nv , 1 ) X ( int , D_diag , nv , 1 ) X ( int , D_colind , nD , 1 ) X ( int , mapM2D , nD , 1 ) X ( int , mapD2M , nC , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 719
- },
- "MJDATA_POINTERS": {
- "value": "X ( mjtNum , qpos , nq , 1 ) X ( mjtNum , qvel , nv , 1 ) X ( mjtNum , act , na , 1 ) X ( mjtNum , history , nhistory , 1 ) X ( mjtNum , qacc_warmstart , nv , 1 ) X ( mjtNum , plugin_state , npluginstate , 1 ) X ( mjtNum , ctrl , nu , 1 ) X ( mjtNum , qfrc_applied , nv , 1 ) X ( mjtNum , xfrc_applied , nbody , 6 ) X ( mjtBool , eq_active , neq , 1 ) X ( mjtNum , mocap_pos , nmocap , 3 ) X ( mjtNum , mocap_quat , nmocap , 4 ) X ( mjtNum , qacc , nv , 1 ) X ( mjtNum , act_dot , na , 1 ) X ( mjtNum , userdata , nuserdata , 1 ) X ( mjtNum , sensordata , nsensordata , 1 ) X ( int , tree_asleep , ntree , 1 ) X ( int , plugin , nplugin , 1 ) X ( uintptr_t , plugin_data , nplugin , 1 ) X ( mjtNum , xpos , nbody , 3 ) X ( mjtNum , xquat , nbody , 4 ) X ( mjtNum , xmat , nbody , 9 ) X ( mjtNum , xipos , nbody , 3 ) X ( mjtNum , ximat , nbody , 9 ) X ( mjtNum , xanchor , njnt , 3 ) X ( mjtNum , xaxis , njnt , 3 ) X ( mjtNum , geom_xpos , ngeom , 3 ) X ( mjtNum , geom_xmat , ngeom , 9 ) X ( mjtNum , site_xpos , nsite , 3 ) X ( mjtNum , site_xmat , nsite , 9 ) X ( mjtNum , cam_xpos , ncam , 3 ) X ( mjtNum , cam_xmat , ncam , 9 ) X ( mjtNum , light_xpos , nlight , 3 ) X ( mjtNum , light_xdir , nlight , 3 ) X ( mjtNum , subtree_com , nbody , 3 ) X ( mjtNum , cdof , nv , 6 ) X ( mjtNum , cinert , nbody , 10 ) X ( mjtNum , flexvert_xpos , nflexvert , 3 ) X ( mjtNum , flexelem_aabb , nflexelem , 6 ) X ( mjtNum , flexedge_J , nJfe , 1 ) X ( mjtNum , flexedge_length , nflexedge , 1 ) X ( mjtNum , flexvert_J , nJfv , 2 ) X ( mjtNum , flexvert_length , nflexvert , 2 ) X ( mjtNum , bvh_aabb_dyn , nbvhdynamic , 6 ) X ( int , ten_wrapadr , ntendon , 1 ) X ( int , ten_wrapnum , ntendon , 1 ) X ( mjtNum , ten_J , nJten , 1 ) X ( mjtNum , ten_length , ntendon , 1 ) X ( int , wrap_obj , nwrap , 2 ) X ( mjtNum , wrap_xpos , nwrap , 6 ) X ( mjtNum , actuator_length , nu , 1 ) X ( int , moment_rownnz , nu , 1 ) X ( int , moment_rowadr , nu , 1 ) X ( int , moment_colind , nJmom , 1 ) X ( mjtNum , actuator_moment , nJmom , 1 ) XNV ( mjtNum , crb , nbody , 10 ) XNV ( mjtNum , qM , nM , 1 ) XNV ( mjtNum , M , nC , 1 ) XNV ( mjtNum , qLD , nC , 1 ) X ( mjtNum , qLDiagInv , nv , 1 ) X ( mjtBool , bvh_active , nbvh , 1 ) X ( int , tree_awake , ntree , 1 ) X ( int , body_awake , nbody , 1 ) X ( int , body_awake_ind , nbody , 1 ) X ( int , parent_awake_ind , nbody , 1 ) X ( int , dof_awake_ind , nv , 1 ) X ( mjtNum , flexedge_velocity , nflexedge , 1 ) X ( mjtNum , ten_velocity , ntendon , 1 ) X ( mjtNum , actuator_velocity , nu , 1 ) X ( mjtNum , cvel , nbody , 6 ) X ( mjtNum , cdof_dot , nv , 6 ) X ( mjtNum , qfrc_bias , nv , 1 ) X ( mjtNum , qfrc_spring , nv , 1 ) X ( mjtNum , qfrc_damper , nv , 1 ) X ( mjtNum , qfrc_gravcomp , nv , 1 ) X ( mjtNum , qfrc_fluid , nv , 1 ) X ( mjtNum , qfrc_passive , nv , 1 ) X ( mjtNum , subtree_linvel , nbody , 3 ) X ( mjtNum , subtree_angmom , nbody , 3 ) XNV ( mjtNum , qH , nC , 1 ) X ( mjtNum , qHDiagInv , nv , 1 ) XNV ( mjtNum , qDeriv , nD , 1 ) XNV ( mjtNum , qLU , nD , 1 ) X ( mjtNum , actuator_force , nu , 1 ) X ( mjtNum , qfrc_actuator , nv , 1 ) X ( mjtNum , qfrc_smooth , nv , 1 ) X ( mjtNum , qacc_smooth , nv , 1 ) X ( mjtNum , qfrc_constraint , nv , 1 ) X ( mjtNum , qfrc_inverse , nv , 1 ) X ( mjtNum , cacc , nbody , 6 ) X ( mjtNum , cfrc_int , nbody , 6 ) X ( mjtNum , cfrc_ext , nbody , 6 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 821
- },
- "MJ_D": {
- "value": "( n ) n",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 918
- },
- "MJDATA_ARENA_POINTERS_CONTACT": {
- "value": "X ( mjContact , contact , MJ_D ( ncon ) , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 921
- },
- "MJDATA_ARENA_POINTERS_SOLVER": {
- "value": "X ( int , efc_type , MJ_D ( nefc ) , 1 ) X ( int , efc_id , MJ_D ( nefc ) , 1 ) XNV ( int , efc_J_rownnz , MJ_D ( nefc ) , 1 ) XNV ( int , efc_J_rowadr , MJ_D ( nefc ) , 1 ) XNV ( int , efc_J_rowsuper , MJ_D ( nefc ) , 1 ) XNV ( int , efc_J_colind , MJ_D ( nJ ) , 1 ) XNV ( mjtNum , efc_J , MJ_D ( nJ ) , 1 ) X ( mjtNum , efc_pos , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_margin , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_frictionloss , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_diagA , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_KBIP , MJ_D ( nefc ) , 4 ) X ( mjtNum , efc_D , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_R , MJ_D ( nefc ) , 1 ) X ( int , tendon_efcadr , MJ_M ( ntendon ) , 1 ) X ( mjtNum , efc_vel , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_aref , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_b , MJ_D ( nefc ) , 1 ) X ( int , efc_state , MJ_D ( nefc ) , 1 ) X ( mjtNum , efc_force , MJ_D ( nefc ) , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 925
- },
- "MJDATA_ARENA_POINTERS_DUAL": {
- "value": "XNV ( int , efc_Y_rownnz , MJ_D ( nefc ) , 1 ) XNV ( int , efc_Y_rowadr , MJ_D ( nefc ) , 1 ) XNV ( int , efc_Y_colind , MJ_D ( nY ) , 1 ) XNV ( mjtNum , efc_Y , MJ_D ( nY ) , 1 ) XNV ( int , efc_AR_rownnz , MJ_D ( nefc ) , 1 ) XNV ( int , efc_AR_rowadr , MJ_D ( nefc ) , 1 ) XNV ( int , efc_AR_colind , MJ_D ( nA ) , 1 ) XNV ( mjtNum , efc_AR , MJ_D ( nA ) , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 948
- },
- "MJDATA_ARENA_POINTERS_ISLAND": {
- "value": "X ( int , tree_island , MJ_M ( ntree ) , 1 ) X ( int , island_ntree , MJ_D ( nisland ) , 1 ) X ( int , island_itreeadr , MJ_D ( nisland ) , 1 ) X ( int , map_itree2tree , MJ_M ( ntree ) , 1 ) X ( int , dof_island , MJ_M ( nv ) , 1 ) X ( int , island_nv , MJ_D ( nisland ) , 1 ) X ( int , island_idofadr , MJ_D ( nisland ) , 1 ) X ( int , island_dofadr , MJ_D ( nisland ) , 1 ) X ( int , map_dof2idof , MJ_M ( nv ) , 1 ) X ( int , map_idof2dof , MJ_M ( nv ) , 1 ) X ( mjtNum , ifrc_smooth , MJ_D ( nidof ) , 1 ) X ( mjtNum , iacc_smooth , MJ_D ( nidof ) , 1 ) X ( mjtNum , iacc , MJ_D ( nidof ) , 1 ) X ( int , efc_island , MJ_D ( nefc ) , 1 ) X ( int , island_ne , MJ_D ( nisland ) , 1 ) X ( int , island_nf , MJ_D ( nisland ) , 1 ) X ( int , island_nefc , MJ_D ( nisland ) , 1 ) X ( int , island_iefcadr , MJ_D ( nisland ) , 1 ) X ( int , map_efc2iefc , MJ_D ( nefc ) , 1 ) X ( int , map_iefc2efc , MJ_D ( nefc ) , 1 ) X ( int , iefc_type , MJ_D ( nefc ) , 1 ) X ( int , iefc_id , MJ_D ( nefc ) , 1 ) X ( mjtNum , iefc_frictionloss , MJ_D ( nefc ) , 1 ) X ( mjtNum , iefc_D , MJ_D ( nefc ) , 1 ) X ( mjtNum , iefc_R , MJ_D ( nefc ) , 1 ) X ( mjtNum , iefc_aref , MJ_D ( nefc ) , 1 ) X ( int , iefc_state , MJ_D ( nefc ) , 1 ) X ( mjtNum , iefc_force , MJ_D ( nefc ) , 1 ) X ( mjtNum , ifrc_constraint , MJ_D ( nidof ) , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 959
- },
- "MJDATA_ARENA_POINTERS": {
- "value": "MJDATA_ARENA_POINTERS_CONTACT MJDATA_ARENA_POINTERS_SOLVER MJDATA_ARENA_POINTERS_DUAL MJDATA_ARENA_POINTERS_ISLAND",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 991
- },
- "MJDATA_SCALAR": {
- "value": "X ( size_t , narena ) X ( size_t , nbuffer ) X ( int , nplugin ) X ( size_t , pstack ) X ( size_t , pbase ) X ( size_t , parena ) X ( uintptr_t , threadpool ) X ( size_t , maxuse_stack ) X ( size_t , maxuse_arena ) X ( int , maxuse_con ) X ( int , maxuse_efc ) X ( int , ncon ) X ( int , ne ) X ( int , nf ) X ( int , nl ) X ( int , nefc ) X ( int , nJ ) X ( int , nY ) X ( int , nA ) X ( int , nisland ) X ( int , nidof ) X ( int , ntree_awake ) X ( int , nbody_awake ) X ( int , nparent_awake ) X ( int , nv_awake ) X ( mjtBool , flg_energypos ) X ( mjtBool , flg_energyvel ) X ( mjtBool , flg_subtreevel ) X ( mjtBool , flg_rnepost ) X ( mjtNum , time )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 999
- },
- "MJDATA_VECTOR": {
- "value": "X ( mjSolverStat , solver , mjNISLAND , mjNSOLVER ) X ( int , solver_niter , mjNISLAND , 1 ) X ( int , solver_nnz , mjNISLAND , 1 ) X ( mjtNum , solver_fwdinv , 2 , 1 ) X ( mjWarningStat , warning , mjNWARNING , 1 ) X ( mjTimerStat , timer , mjNTIMER , 1 ) X ( mjtNum , energy , 2 , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 1033
- },
- "XNV": {
- "value": "X",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjxmacro.h",
- "line": 1045
- },
- "mjVERSION_HEADER": {
- "value": "3010000",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 19
- },
- "MUJOCO_HELPER_DLL_IMPORT": {
- "value": "__declspec ( dllimport )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjexport.h",
- "line": 19
- },
- "MUJOCO_HELPER_DLL_EXPORT": {
- "value": "__declspec ( dllexport )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjexport.h",
- "line": 20
- },
- "mjMAX": {
- "value": "( a , b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 19
- },
- "mjMIN": {
- "value": "( a , b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 20
- },
- "mjDISABLED": {
- "value": "( x ) ( m -> opt . disableflags & ( x ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 23
- },
- "mjENABLED": {
- "value": "( x ) ( m -> opt . enableflags & ( x ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 24
- },
- "mjACTUATORDISABLED": {
- "value": "( i ) ( m -> opt . disableactuator & ( 1 << m -> actuator_group [ i ] ) )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 27
- },
- "mjPRINTFLIKE": {
- "value": "( n , m )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjmacro.h",
- "line": 34
- },
- "mjNGROUP": {
- "value": "6",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 23
- },
- "mjMAXLIGHT": {
- "value": "100",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 24
- },
- "mjMAXOVERLAY": {
- "value": "500",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 25
- },
- "mjMAXLINE": {
- "value": "100",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 26
- },
- "mjMAXLINEPNT": {
- "value": "1001",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 27
- },
- "mjMAXPLANEGRID": {
- "value": "200",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjvisualize.h",
- "line": 28
- },
- "mjPLUGIN_LIB_INIT": {
- "value": "( n ) static void _mj_init_ ## n ( void ) __attribute__ ( ( constructor ) ) ; static void _mj_init_ ## n ( void )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjplugin.h",
- "line": 192
- },
- "mjNAUX": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 25
- },
- "mjMAXTEXTURE": {
- "value": "1000",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 26
- },
- "mjMAXMATERIAL": {
- "value": "1000",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjrender.h",
- "line": 27
- },
- "ASAN_POISON_MEMORY_REGION": {
- "value": "( addr , size )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjsan.h",
- "line": 33
- },
- "ASAN_UNPOISON_MEMORY_REGION": {
- "value": "( addr , size )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjsan.h",
- "line": 34
- },
- "mjMAXUISECT": {
- "value": "10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 20
- },
- "mjMAXUIITEM": {
- "value": "200",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 21
- },
- "mjMAXUITEXT": {
- "value": "300",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 22
- },
- "mjMAXUINAME": {
- "value": "40",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 23
- },
- "mjMAXUIMULTI": {
- "value": "35",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 24
- },
- "mjMAXUIEDIT": {
- "value": "7",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 25
- },
- "mjMAXUIRECT": {
- "value": "25",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 26
- },
- "mjSEPCLOSED": {
- "value": "1000",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 28
- },
- "mjPRESERVE": {
- "value": "2000",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 29
- },
- "mjKEY_ESCAPE": {
- "value": "256",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 33
- },
- "mjKEY_ENTER": {
- "value": "257",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 34
- },
- "mjKEY_TAB": {
- "value": "258",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 35
- },
- "mjKEY_BACKSPACE": {
- "value": "259",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 36
- },
- "mjKEY_INSERT": {
- "value": "260",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 37
- },
- "mjKEY_DELETE": {
- "value": "261",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 38
- },
- "mjKEY_RIGHT": {
- "value": "262",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 39
- },
- "mjKEY_LEFT": {
- "value": "263",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 40
- },
- "mjKEY_DOWN": {
- "value": "264",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 41
- },
- "mjKEY_UP": {
- "value": "265",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 42
- },
- "mjKEY_PAGE_UP": {
- "value": "266",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 43
- },
- "mjKEY_PAGE_DOWN": {
- "value": "267",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 44
- },
- "mjKEY_HOME": {
- "value": "268",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 45
- },
- "mjKEY_END": {
- "value": "269",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 46
- },
- "mjKEY_F1": {
- "value": "290",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 47
- },
- "mjKEY_F2": {
- "value": "291",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 48
- },
- "mjKEY_F3": {
- "value": "292",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 49
- },
- "mjKEY_F4": {
- "value": "293",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 50
- },
- "mjKEY_F5": {
- "value": "294",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 51
- },
- "mjKEY_F6": {
- "value": "295",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 52
- },
- "mjKEY_F7": {
- "value": "296",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 53
- },
- "mjKEY_F8": {
- "value": "297",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 54
- },
- "mjKEY_F9": {
- "value": "298",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 55
- },
- "mjKEY_F10": {
- "value": "299",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 56
- },
- "mjKEY_F11": {
- "value": "300",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 57
- },
- "mjKEY_F12": {
- "value": "301",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 58
- },
- "mjKEY_NUMPAD_0": {
- "value": "320",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 59
- },
- "mjKEY_NUMPAD_9": {
- "value": "329",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjui.h",
- "line": 60
- },
- "MJSELEMENT_FIELDS": {
- "value": "X ( mjtObj , elemtype , 1 ) X ( uint64_t , signature , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 21
- },
- "MJSCOMPILER_FIELDS": {
- "value": "X ( mjtByte , autolimits , 1 ) X ( double , boundmass , 1 ) X ( double , boundinertia , 1 ) X ( double , settotalmass , 1 ) X ( mjtByte , balanceinertia , 1 ) X ( mjtByte , fitaabb , 1 ) X ( mjtByte , degree , 1 ) XVEC ( char , eulerseq , 3 ) X ( mjtByte , discardvisual , 1 ) X ( mjtByte , usethread , 1 ) X ( mjtByte , fusestatic , 1 ) X ( int , inertiafromgeom , 1 ) XVEC ( int , inertiagrouprange , 2 ) X ( mjtByte , saveinertial , 1 ) X ( int , alignfree , 1 ) X ( mjLROpt , LRopt , 1 ) X ( mjString * , meshdir , 1 ) X ( mjString * , texturedir , 1 ) X ( uint64_t , authored , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 28
- },
- "MJSPEC_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , modelname , 1 ) X ( mjsCompiler , compiler , 1 ) X ( mjtByte , strippath , 1 ) X ( mjOption , option , 1 ) X ( mjVisual , visual , 1 ) X ( mjStatistic , stat , 1 ) X ( mjtSize , memory , 1 ) X ( int , nemax , 1 ) X ( int , nuserdata , 1 ) X ( int , nuser_body , 1 ) X ( int , nuser_jnt , 1 ) X ( int , nuser_geom , 1 ) X ( int , nuser_site , 1 ) X ( int , nuser_cam , 1 ) X ( int , nuser_tendon , 1 ) X ( int , nuser_actuator , 1 ) X ( int , nuser_sensor , 1 ) X ( int , nkey , 1 ) X ( int , njmax , 1 ) X ( int , nconmax , 1 ) X ( mjtSize , nstack , 1 ) X ( mjString * , comment , 1 ) X ( mjString * , modelfiledir , 1 ) X ( mjtByte , hasImplicitPluginElem , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 52
- },
- "MJSORIENTATION_FIELDS": {
- "value": "X ( mjtOrientation , type , 1 ) XVEC ( double , axisangle , 4 ) XVEC ( double , xyaxes , 6 ) XVEC ( double , zaxis , 3 ) XVEC ( double , euler , 3 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 82
- },
- "MJSPLUGIN_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , name , 1 ) X ( mjString * , plugin_name , 1 ) X ( mjtByte , active , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 92
- },
- "MJSBODY_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , childclass , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , quat , 4 ) X ( mjsOrientation , alt , 1 ) X ( double , mass , 1 ) XVEC ( double , ipos , 3 ) XVEC ( double , iquat , 4 ) XVEC ( double , inertia , 3 ) X ( mjsOrientation , ialt , 1 ) XVEC ( double , fullinertia , 6 ) X ( mjtByte , mocap , 1 ) X ( double , gravcomp , 1 ) X ( mjtSleepPolicy , sleep , 1 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjtByte , explicitinertial , 1 ) X ( mjsPlugin , plugin , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 102
- },
- "MJSFRAME_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , childclass , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , quat , 4 ) X ( mjsOrientation , alt , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 125
- },
- "MJSJOINT_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtJoint , type , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , axis , 3 ) X ( double , ref , 1 ) X ( int , align , 1 ) XVEC ( double , stiffness , mjNPOLY + 1 ) X ( double , springref , 1 ) XVEC ( double , springdamper , 2 ) X ( int , limited , 1 ) XVEC ( double , range , 2 ) X ( double , margin , 1 ) XVEC ( mjtNum , solref_limit , mjNREF ) XVEC ( mjtNum , solimp_limit , mjNIMP ) X ( int , actfrclimited , 1 ) XVEC ( double , actfrcrange , 2 ) X ( double , armature , 1 ) XVEC ( double , damping , mjNPOLY + 1 ) X ( double , frictionloss , 1 ) XVEC ( mjtNum , solref_friction , mjNREF ) XVEC ( mjtNum , solimp_friction , mjNIMP ) X ( int , group , 1 ) X ( mjtByte , actgravcomp , 1 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 136
- },
- "MJSGEOM_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtGeom , type , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , quat , 4 ) X ( mjsOrientation , alt , 1 ) XVEC ( double , fromto , 6 ) XVEC ( double , size , 3 ) X ( int , contype , 1 ) X ( int , conaffinity , 1 ) X ( int , condim , 1 ) X ( int , priority , 1 ) XVEC ( double , friction , 3 ) X ( double , solmix , 1 ) XVEC ( mjtNum , solref , mjNREF ) XVEC ( mjtNum , solimp , mjNIMP ) X ( double , margin , 1 ) X ( double , gap , 1 ) X ( double , mass , 1 ) X ( double , density , 1 ) X ( mjtGeomInertia , typeinertia , 1 ) X ( mjtNum , fluid_ellipsoid , 1 ) XVEC ( mjtNum , fluid_coefs , 5 ) X ( mjString * , material , 1 ) XVEC ( float , rgba , 4 ) X ( int , group , 1 ) X ( mjString * , hfieldname , 1 ) X ( mjString * , meshname , 1 ) X ( double , fitscale , 1 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjsPlugin , plugin , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 166
- },
- "MJSSITE_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , quat , 4 ) X ( mjsOrientation , alt , 1 ) XVEC ( double , fromto , 6 ) XVEC ( double , size , 3 ) X ( mjtGeom , type , 1 ) X ( mjString * , material , 1 ) X ( int , group , 1 ) XVEC ( float , rgba , 4 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 202
- },
- "MJSCAMERA_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , quat , 4 ) X ( mjsOrientation , alt , 1 ) X ( mjtCamLight , mode , 1 ) X ( mjString * , targetbody , 1 ) X ( mjtProjection , proj , 1 ) XVEC ( int , resolution , 2 ) X ( int , output , 1 ) X ( double , fovy , 1 ) X ( double , ipd , 1 ) XVEC ( float , intrinsic , 4 ) XVEC ( float , sensor_size , 2 ) XVEC ( float , focal_length , 2 ) XVEC ( float , focal_pixel , 2 ) XVEC ( float , principal_length , 2 ) XVEC ( float , principal_pixel , 2 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 219
- },
- "MJSLIGHT_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) XVEC ( double , pos , 3 ) XVEC ( double , dir , 3 ) X ( mjtCamLight , mode , 1 ) X ( mjString * , targetbody , 1 ) X ( mjtByte , active , 1 ) X ( mjtLightType , type , 1 ) X ( mjString * , texture , 1 ) X ( mjtByte , castshadow , 1 ) X ( float , bulbradius , 1 ) X ( float , intensity , 1 ) X ( float , range , 1 ) XVEC ( float , attenuation , 3 ) X ( float , cutoff , 1 ) X ( float , exponent , 1 ) XVEC ( float , ambient , 3 ) XVEC ( float , diffuse , 3 ) XVEC ( float , specular , 3 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 243
- },
- "MJSFLEX_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( int , contype , 1 ) X ( int , conaffinity , 1 ) X ( int , condim , 1 ) X ( int , priority , 1 ) XVEC ( double , friction , 3 ) X ( double , solmix , 1 ) XVEC ( mjtNum , solref , mjNREF ) XVEC ( mjtNum , solimp , mjNIMP ) X ( double , margin , 1 ) X ( double , gap , 1 ) X ( int , dim , 1 ) X ( double , radius , 1 ) XVEC ( double , size , 3 ) X ( mjtByte , internal , 1 ) X ( mjtByte , flatskin , 1 ) X ( int , selfcollide , 1 ) X ( int , passive , 1 ) X ( int , activelayers , 1 ) X ( int , group , 1 ) X ( double , edgestiffness , 1 ) X ( double , edgedamping , 1 ) XVEC ( float , rgba , 4 ) X ( mjString * , material , 1 ) X ( double , young , 1 ) X ( double , poisson , 1 ) X ( double , damping , 1 ) X ( double , thickness , 1 ) X ( int , elastic2d , 1 ) XVEC ( int , cellcount , 3 ) X ( int , order , 1 ) X ( mjStringVec * , nodebody , 1 ) X ( mjStringVec * , vertbody , 1 ) X ( mjDoubleVec * , node , 1 ) X ( mjDoubleVec * , vert , 1 ) X ( mjIntVec * , elem , 1 ) X ( mjFloatVec * , texcoord , 1 ) X ( mjIntVec * , elemtexcoord , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 267
- },
- "MJSMESH_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , content_type , 1 ) X ( mjString * , file , 1 ) XVEC ( double , refpos , 3 ) XVEC ( double , refquat , 4 ) XVEC ( double , scale , 3 ) X ( mjtMeshInertia , inertia , 1 ) X ( mjtByte , smoothnormal , 1 ) X ( mjtByte , needsdf , 1 ) X ( int , maxhullvert , 1 ) X ( mjFloatVec * , uservert , 1 ) X ( mjFloatVec * , usernormal , 1 ) X ( mjFloatVec * , usertexcoord , 1 ) X ( mjIntVec * , userface , 1 ) X ( mjIntVec * , userfacenormal , 1 ) X ( mjIntVec * , userfacetexcoord , 1 ) X ( mjsPlugin , plugin , 1 ) X ( mjString * , material , 1 ) X ( int , octree_maxdepth , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 311
- },
- "MJSHFIELD_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , content_type , 1 ) X ( mjString * , file , 1 ) XVEC ( double , size , 4 ) X ( int , nrow , 1 ) X ( int , ncol , 1 ) X ( mjFloatVec * , userdata , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 336
- },
- "MJSSKIN_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , file , 1 ) X ( mjString * , material , 1 ) XVEC ( float , rgba , 4 ) X ( float , inflate , 1 ) X ( int , group , 1 ) X ( mjFloatVec * , vert , 1 ) X ( mjFloatVec * , texcoord , 1 ) X ( mjIntVec * , face , 1 ) X ( mjStringVec * , bodyname , 1 ) X ( mjFloatVec * , bindpos , 1 ) X ( mjFloatVec * , bindquat , 1 ) X ( mjIntVecVec * , vertid , 1 ) X ( mjFloatVecVec * , vertweight , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 349
- },
- "MJSTEXTURE_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtTexture , type , 1 ) X ( mjtColorSpace , colorspace , 1 ) X ( int , builtin , 1 ) X ( int , mark , 1 ) XVEC ( double , rgb1 , 3 ) XVEC ( double , rgb2 , 3 ) XVEC ( double , markrgb , 3 ) X ( double , random , 1 ) X ( int , height , 1 ) X ( int , width , 1 ) X ( int , nchannel , 1 ) X ( mjString * , content_type , 1 ) X ( mjString * , file , 1 ) XVEC ( int , gridsize , 2 ) XVEC ( char , gridlayout , 12 ) X ( mjStringVec * , cubefiles , 1 ) X ( mjByteVec * , data , 1 ) X ( mjtByte , hflip , 1 ) X ( mjtByte , vflip , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 369
- },
- "MJSMATERIAL_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjStringVec * , textures , 1 ) X ( mjtByte , texuniform , 1 ) XVEC ( float , texrepeat , 2 ) X ( float , emission , 1 ) X ( float , specular , 1 ) X ( float , shininess , 1 ) X ( float , reflectance , 1 ) X ( float , metallic , 1 ) X ( float , roughness , 1 ) XVEC ( float , rgba , 4 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 395
- },
- "MJSPAIR_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , geomname1 , 1 ) X ( mjString * , geomname2 , 1 ) X ( int , condim , 1 ) XVEC ( mjtNum , solref , mjNREF ) XVEC ( mjtNum , solreffriction , mjNREF ) XVEC ( mjtNum , solimp , mjNIMP ) X ( double , margin , 1 ) X ( double , gap , 1 ) XVEC ( double , friction , 5 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 412
- },
- "MJSEXCLUDE_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , bodyname1 , 1 ) X ( mjString * , bodyname2 , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 428
- },
- "MJSEQUALITY_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtEq , type , 1 ) XVEC ( double , data , mjNEQDATA ) X ( mjtByte , active , 1 ) X ( mjString * , name1 , 1 ) X ( mjString * , name2 , 1 ) X ( mjtObj , objtype , 1 ) XVEC ( mjtNum , solref , mjNREF ) XVEC ( mjtNum , solimp , mjNIMP ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 437
- },
- "MJSTENDON_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) XVEC ( double , stiffness , mjNPOLY + 1 ) XVEC ( double , springlength , 2 ) XVEC ( double , damping , mjNPOLY + 1 ) X ( double , frictionloss , 1 ) XVEC ( mjtNum , solref_friction , mjNREF ) XVEC ( mjtNum , solimp_friction , mjNIMP ) X ( double , armature , 1 ) X ( int , limited , 1 ) X ( int , actfrclimited , 1 ) XVEC ( double , range , 2 ) XVEC ( double , actfrcrange , 2 ) X ( double , margin , 1 ) XVEC ( mjtNum , solref_limit , mjNREF ) XVEC ( mjtNum , solimp_limit , mjNIMP ) X ( mjString * , material , 1 ) X ( double , width , 1 ) XVEC ( float , rgba , 4 ) X ( int , group , 1 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 452
- },
- "MJSWRAP_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtWrap , type , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 478
- },
- "MJSACTUATOR_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtGain , gaintype , 1 ) XVEC ( double , gainprm , mjNGAIN ) X ( mjtBias , biastype , 1 ) XVEC ( double , biasprm , mjNGAIN ) X ( mjtDyn , dyntype , 1 ) XVEC ( double , dynprm , mjNDYN ) X ( int , actdim , 1 ) X ( mjtByte , actearly , 1 ) X ( mjtTrn , trntype , 1 ) XVEC ( double , gear , 6 ) X ( mjString * , target , 1 ) X ( mjString * , refsite , 1 ) X ( mjString * , slidersite , 1 ) X ( double , cranklength , 1 ) XVEC ( double , lengthrange , 2 ) X ( double , inheritrange , 1 ) XVEC ( double , damping , mjNPOLY + 1 ) X ( double , armature , 1 ) X ( int , ctrllimited , 1 ) XVEC ( double , ctrlrange , 2 ) X ( int , forcelimited , 1 ) XVEC ( double , forcerange , 2 ) X ( int , actlimited , 1 ) XVEC ( double , actrange , 2 ) X ( int , group , 1 ) X ( int , nsample , 1 ) X ( int , interp , 1 ) X ( double , delay , 1 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjsPlugin , plugin , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 486
- },
- "MJSSENSOR_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjtSensor , type , 1 ) X ( mjtObj , objtype , 1 ) X ( mjString * , objname , 1 ) X ( mjtObj , reftype , 1 ) X ( mjString * , refname , 1 ) XVEC ( int , intprm , mjNSENS ) X ( mjtDataType , datatype , 1 ) X ( mjtStage , needstage , 1 ) X ( int , dim , 1 ) X ( double , cutoff , 1 ) X ( double , noise , 1 ) X ( int , nsample , 1 ) X ( int , interp , 1 ) X ( double , delay , 1 ) XVEC ( double , interval , 2 ) X ( mjDoubleVec * , userdata , 1 ) X ( mjsPlugin , plugin , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 523
- },
- "MJSNUMERIC_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjDoubleVec * , data , 1 ) X ( int , size , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 547
- },
- "MJSTEXT_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjString * , data , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 556
- },
- "MJSTUPLE_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjIntVec * , objtype , 1 ) X ( mjStringVec * , objname , 1 ) X ( mjDoubleVec * , objprm , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 564
- },
- "MJSKEY_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( double , time , 1 ) X ( mjDoubleVec * , qpos , 1 ) X ( mjDoubleVec * , qvel , 1 ) X ( mjDoubleVec * , act , 1 ) X ( mjDoubleVec * , mpos , 1 ) X ( mjDoubleVec * , mquat , 1 ) X ( mjDoubleVec * , ctrl , 1 ) X ( mjString * , info , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 574
- },
- "MJSDEFAULT_FIELDS": {
- "value": "X ( mjsElement * , element , 1 ) X ( mjsJoint * , joint , 1 ) X ( mjsGeom * , geom , 1 ) X ( mjsSite * , site , 1 ) X ( mjsCamera * , camera , 1 ) X ( mjsLight * , light , 1 ) X ( mjsFlex * , flex , 1 ) X ( mjsMesh * , mesh , 1 ) X ( mjsMaterial * , material , 1 ) X ( mjsPair * , pair , 1 ) X ( mjsEquality * , equality , 1 ) X ( mjsTendon * , tendon , 1 ) X ( mjsActuator * , actuator , 1 )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjspecmacro.h",
- "line": 588
- },
- "MJ_ASSERT_SIZE": {
- "value": "( type , size ) _Static_assert ( sizeof ( type ) == ( size ) , # type \" must be \" # size \" bytes for MuJoCo ABI stability\" )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjassert.h",
- "line": 34
- },
- "MJ_STATIC_ASSERT": {
- "value": "( expr ) _Static_assert ( expr , # expr )",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjassert.h",
- "line": 36
- },
- "X": {
- "value": "( type , name , dim ) + 1",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjassert.h",
- "line": 135
- },
- "XVEC": {
- "value": "( type , name , dim ) + 1",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mjassert.h",
- "line": 136
- },
- "mju_sqrt": {
- "value": "sqrt",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1025
- },
- "mju_exp": {
- "value": "exp",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1026
- },
- "mju_sin": {
- "value": "sin",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1027
- },
- "mju_cos": {
- "value": "cos",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1028
- },
- "mju_tan": {
- "value": "tan",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1029
- },
- "mju_asin": {
- "value": "asin",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1030
- },
- "mju_acos": {
- "value": "acos",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1031
- },
- "mju_atan2": {
- "value": "atan2",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1032
- },
- "mju_tanh": {
- "value": "tanh",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1033
- },
- "mju_pow": {
- "value": "pow",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1034
- },
- "mju_abs": {
- "value": "fabs",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1035
- },
- "mju_log": {
- "value": "log",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1036
- },
- "mju_log10": {
- "value": "log10",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1037
- },
- "mju_floor": {
- "value": "floor",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1038
- },
- "mju_ceil": {
- "value": "ceil",
- "doc": "",
- "file": "third_party/install/mujoco/include/mujoco/mujoco.h",
- "line": 1039
- }
- },
- "hand_enums": {
- "EMjActuatorType": {
- "name": "EMjActuatorType",
- "members": {
- "Motor": 0,
- "Position": 1,
- "Velocity": 2,
- "IntVelocity": 3,
- "Damper": 4,
- "Cylinder": 5,
- "Muscle": 6,
- "Adhesion": 7,
- "DcMotor": 8
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/actuators/mjactuator.h",
- "line": 42
- },
- "EMjDcMotorInput": {
- "name": "EMjDcMotorInput",
- "members": {
- "Voltage": 0,
- "Position": 1,
- "Velocity": 2
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/actuators/mjdcmotoractuator.h",
- "line": 35
- },
- "EMjBodySleepPolicy": {
- "name": "EMjBodySleepPolicy",
- "members": {
- "Auto": 0,
- "Never": 3,
- "Allowed": 4,
- "InitAsleep": 5
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/bodies/mjbody.h",
- "line": 47
- },
- "EMjEqualityType": {
- "name": "EMjEqualityType",
- "members": {
- "Connect": 0,
- "Weld": 1,
- "Joint": 2,
- "Tendon": 3,
- "Flex": 4,
- "FlexVert": 5,
- "FlexStrain": 6
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/constraints/mjequality.h",
- "line": 36
- },
- "EMjFlexcompType": {
- "name": "EMjFlexcompType",
- "members": {
- "Grid": 0,
- "Box": 1,
- "Cylinder": 2,
- "Ellipsoid": 3,
- "Square": 4,
- "Disc": 5,
- "Circle": 6,
- "Mesh": 7,
- "Gmsh": 8,
- "Direct": 9
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/deformable/mjflexcomp.h",
- "line": 36
- },
- "EMjGeomType": {
- "name": "EMjGeomType",
- "members": {
- "Plane": 0,
- "Hfield": 1,
- "Sphere": 2,
- "Capsule": 3,
- "Ellipsoid": 4,
- "Cylinder": 5,
- "Box": 6,
- "Mesh": 7,
- "SDF": 8
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/geometry/mjgeom.h",
- "line": 39
- },
- "EMjSiteType": {
- "name": "EMjSiteType",
- "members": {
- "Sphere": 0,
- "Capsule": 1,
- "Ellipsoid": 2,
- "Cylinder": 3,
- "Box": 4,
- "Mesh": 5,
- "Hfield": 6
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/geometry/mjsite.h",
- "line": 41
- },
- "EMjJointType": {
- "name": "EMjJointType",
- "members": {
- "Free": 0,
- "Ball": 1,
- "Slide": 2,
- "Hinge": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/joints/mjjoint.h",
- "line": 39
- },
- "EMjCameraMode": {
- "name": "EMjCameraMode",
- "members": {
- "Real": 0,
- "Depth": 1,
- "SemanticSegmentation": 2,
- "InstanceSegmentation": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/sensors/mjcameratypes.h",
- "line": 35
- },
- "EMjSensorType": {
- "name": "EMjSensorType",
- "members": {
- "Touch": 0,
- "Accelerometer": 1,
- "Velocimeter": 2,
- "Gyro": 3,
- "Force": 4,
- "Torque": 5,
- "Magnetometer": 6,
- "RangeFinder": 7,
- "CamProjection": 8,
- "JointPos": 9,
- "JointVel": 10,
- "TendonPos": 11,
- "TendonVel": 12,
- "ActuatorPos": 13,
- "ActuatorVel": 14,
- "ActuatorFrc": 15,
- "JointActFrc": 16,
- "TendonActFrc": 17,
- "BallQuat": 18,
- "BallAngVel": 19,
- "JointLimitPos": 20,
- "JointLimitVel": 21,
- "JointLimitFrc": 22,
- "TendonLimitPos": 23,
- "TendonLimitVel": 24,
- "TendonLimitFrc": 25,
- "FramePos": 26,
- "FrameQuat": 27,
- "FrameXAxis": 28,
- "FrameYAxis": 29,
- "FrameZAxis": 30,
- "FrameLinVel": 31,
- "FrameAngVel": 32,
- "FrameLinAcc": 33,
- "FrameAngAcc": 34,
- "SubtreeCom": 35,
- "SubtreeLinVel": 36,
- "SubtreeAngMom": 37,
- "InsideSite": 38,
- "GeomDist": 39,
- "GeomNormal": 40,
- "GeomFromTo": 41,
- "Contact": 42,
- "EPotential": 43,
- "EKinetic": 44,
- "Clock": 45,
- "Tactile": 46,
- "Plugin": 47,
- "User": 48
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/sensors/mjsensor.h",
- "line": 42
- },
- "EMjTendonWrapType": {
- "name": "EMjTendonWrapType",
- "members": {
- "Joint": 0,
- "Site": 1,
- "Geom": 2,
- "Pulley": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/components/tendons/mjtendon.h",
- "line": 40
- },
- "EMjDebugShaderMode": {
- "name": "EMjDebugShaderMode",
- "members": {
- "Off": 0,
- "Island": 1,
- "InstanceSegmentation": 2,
- "SemanticSegmentation": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/core/mjdebugvisualizer.h",
- "line": 39
- },
- "EMjGainType": {
- "name": "EMjGainType",
- "members": {
- "Fixed": 0,
- "Affine": 1,
- "Muscle": 2,
- "DcMotor": 3,
- "User": 4
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 33
- },
- "EMjBiasType": {
- "name": "EMjBiasType",
- "members": {
- "None": 0,
- "Affine": 1,
- "Muscle": 2,
- "DcMotor": 3,
- "User": 4
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 44
- },
- "EMjDynType": {
- "name": "EMjDynType",
- "members": {
- "None": 0,
- "Integrator": 1,
- "Filter": 2,
- "FilterExact": 3,
- "Muscle": 4,
- "DcMotor": 5,
- "User": 6
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 55
- },
- "EMjGeomInertia": {
- "name": "EMjGeomInertia",
- "members": {
- "Volume": 0,
- "Shell": 1
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 68
- },
- "EMjFluidShape": {
- "name": "EMjFluidShape",
- "members": {
- "None": 0,
- "Ellipsoid": 1
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 76
- },
- "EMjCameraTrackingMode": {
- "name": "EMjCameraTrackingMode",
- "members": {
- "Fixed": 0,
- "Track": 1,
- "TrackCom": 2,
- "TargetBody": 3,
- "TargetBodyCom": 4
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 84
- },
- "EMjCameraProjection": {
- "name": "EMjCameraProjection",
- "members": {
- "Perspective": 0,
- "Orthographic": 1
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 95
- },
- "EMjObjType": {
- "name": "EMjObjType",
- "members": {
- "Unknown": 0,
- "Body": 1,
- "XBody": 2,
- "Joint": 3,
- "DoF": 4,
- "Geom": 5,
- "Site": 6,
- "Camera": 7,
- "Light": 8,
- "Flex": 9,
- "Mesh": 10,
- "Skin": 11,
- "HField": 12,
- "Texture": 13,
- "Material": 14,
- "Pair": 15,
- "Exclude": 16,
- "Equality": 17,
- "Tendon": 18,
- "Actuator": 19,
- "Sensor": 20,
- "Numeric": 21,
- "Text": 22,
- "Tuple": 23,
- "Key": 24,
- "Plugin": 25,
- "Frame": 100
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 103
- },
- "EMjActuatorTrnType": {
- "name": "EMjActuatorTrnType",
- "members": {
- "Joint": 0,
- "JointInParent": 1,
- "SliderCrank": 2,
- "Tendon": 3,
- "Site": 4,
- "Body": 5,
- "Undefined": 6
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 136
- },
- "EMjFlexcompDof": {
- "name": "EMjFlexcompDof",
- "members": {
- "Full": 0,
- "Radial": 1,
- "Trilinear": 2,
- "Quadratic": 3,
- "TwoD": 4
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjarticulationenums.h",
- "line": 149
- },
- "EMjIntegrator": {
- "name": "EMjIntegrator",
- "members": {
- "Euler": 0,
- "RK4": 1,
- "Implicit": 2,
- "ImplicitFast": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjoptionenums.h",
- "line": 33
- },
- "EMjCone": {
- "name": "EMjCone",
- "members": {
- "Pyramidal": 0,
- "Elliptic": 1
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjoptionenums.h",
- "line": 43
- },
- "EMjSolver": {
- "name": "EMjSolver",
- "members": {
- "PGS": 0,
- "CG": 1,
- "Newton": 2
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/mujoco/generated/mjoptionenums.h",
- "line": 51
- },
- "EMjPropertyType": {
- "name": "EMjPropertyType",
- "members": {
- "Slider": 0,
- "Toggle": 1,
- "LabelOnly": 2,
- "Header": 3
- },
- "member_docs": {},
- "underlying_type": "uint8",
- "doc": "",
- "file": "source/urlab/public/ui/mjpropertyrow.h",
- "line": 38
- }
- }
-}
\ No newline at end of file
diff --git a/Scripts/codegen/snapshots/mjcf_schema_snapshot.json b/Scripts/codegen/snapshots/mjcf_schema_snapshot.json
deleted file mode 100644
index 863c7b68..00000000
--- a/Scripts/codegen/snapshots/mjcf_schema_snapshot.json
+++ /dev/null
@@ -1,1181 +0,0 @@
-{
- "_meta": {
- "mujoco_version": "3.10.0",
- "snapshot_date": "2026-06-14",
- "source": "https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc",
- "description": "MJCF schema snapshot, auto-extracted by Scripts/codegen/build_mjcf_schema_snapshot.py from the MuJoCo submodule's xml_native_reader.cc."
- },
- "body": {
- "attrs": [
- "name",
- "childclass",
- "pos",
- "quat",
- "mocap",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "gravcomp",
- "sleep",
- "user"
- ],
- "children": [
- "inertial",
- "joint",
- "freejoint",
- "geom",
- "attach",
- "site",
- "camera",
- "light",
- "plugin",
- "composite",
- "flexcomp"
- ]
- },
- "inertial": {
- "attrs": [
- "pos",
- "quat",
- "mass",
- "diaginertia",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "fullinertia"
- ]
- },
- "joint": {
- "attrs": [
- "name",
- "class",
- "type",
- "group",
- "pos",
- "axis",
- "springdamper",
- "limited",
- "actuatorfrclimited",
- "solreflimit",
- "solimplimit",
- "solreffriction",
- "solimpfriction",
- "stiffness",
- "range",
- "actuatorfrcrange",
- "actuatorgravcomp",
- "margin",
- "ref",
- "springref",
- "armature",
- "damping",
- "frictionloss",
- "user"
- ]
- },
- "freejoint": {
- "attrs": [
- "name",
- "group",
- "align"
- ]
- },
- "geom": {
- "attrs": [
- "name",
- "class",
- "type",
- "contype",
- "conaffinity",
- "condim",
- "group",
- "priority",
- "size",
- "material",
- "friction",
- "mass",
- "density",
- "shellinertia",
- "solmix",
- "solref",
- "solimp",
- "margin",
- "gap",
- "fromto",
- "pos",
- "quat",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "hfield",
- "mesh",
- "fitscale",
- "rgba",
- "fluidshape",
- "fluidcoef",
- "user"
- ],
- "children": [
- "plugin"
- ]
- },
- "site": {
- "attrs": [
- "name",
- "class",
- "type",
- "group",
- "pos",
- "quat",
- "material",
- "size",
- "fromto",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "rgba",
- "user"
- ]
- },
- "camera": {
- "attrs": [
- "name",
- "class",
- "projection",
- "fovy",
- "ipd",
- "resolution",
- "output",
- "pos",
- "quat",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "mode",
- "target",
- "focal",
- "focalpixel",
- "principal",
- "principalpixel",
- "sensorsize",
- "user"
- ]
- },
- "light": {
- "attrs": [
- "name",
- "class",
- "directional",
- "type",
- "castshadow",
- "active",
- "pos",
- "dir",
- "bulbradius",
- "intensity",
- "range",
- "attenuation",
- "cutoff",
- "exponent",
- "ambient",
- "diffuse",
- "specular",
- "mode",
- "target",
- "texture"
- ]
- },
- "actuator_common": {
- "attrs": [
- "name",
- "class",
- "group",
- "nsample",
- "interp",
- "delay",
- "ctrllimited",
- "forcelimited",
- "actlimited",
- "ctrlrange",
- "forcerange",
- "actrange",
- "lengthrange",
- "gear",
- "damping",
- "armature",
- "cranklength",
- "user"
- ],
- "targets": [
- "joint",
- "jointinparent",
- "tendon",
- "slidersite",
- "cranksite",
- "site",
- "refsite"
- ]
- },
- "actuator_types": {
- "general": [
- "body",
- "actdim",
- "dyntype",
- "gaintype",
- "biastype",
- "dynprm",
- "gainprm",
- "biasprm",
- "actearly"
- ],
- "motor": [],
- "position": [
- "inheritrange",
- "kp",
- "kv",
- "dampratio",
- "timeconst"
- ],
- "velocity": [
- "kv"
- ],
- "intvelocity": [
- "inheritrange",
- "kp",
- "kv",
- "dampratio"
- ],
- "damper": [
- "kv"
- ],
- "cylinder": [
- "timeconst",
- "area",
- "diameter",
- "bias"
- ],
- "muscle": [
- "timeconst",
- "tausmooth",
- "range",
- "force",
- "scale",
- "lmin",
- "lmax",
- "vmax",
- "fpmax",
- "fvmax"
- ],
- "adhesion": [
- "body",
- "gain"
- ],
- "dcmotor": [
- "motorconst",
- "resistance",
- "nominal",
- "saturation",
- "inductance",
- "cogging",
- "controller",
- "thermal",
- "lugre",
- "input"
- ]
- },
- "sensor_types": [
- "touch",
- "accelerometer",
- "velocimeter",
- "gyro",
- "force",
- "torque",
- "magnetometer",
- "camprojection",
- "rangefinder",
- "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",
- "subtreecom",
- "subtreelinvel",
- "subtreeangmom",
- "insidesite",
- "distance",
- "normal",
- "fromto",
- "contact",
- "e_potential",
- "e_kinetic",
- "clock",
- "tactile",
- "user",
- "plugin"
- ],
- "sensor_common": {
- "attrs": [
- "name",
- "nsample",
- "interp",
- "delay",
- "interval",
- "cutoff",
- "noise",
- "user"
- ]
- },
- "sensor_per_type": {
- "touch": {
- "mj_type": "mjSENS_TOUCH",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "accelerometer": {
- "mj_type": "mjSENS_ACCELEROMETER",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "velocimeter": {
- "mj_type": "mjSENS_VELOCIMETER",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "gyro": {
- "mj_type": "mjSENS_GYRO",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "force": {
- "mj_type": "mjSENS_FORCE",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "torque": {
- "mj_type": "mjSENS_TORQUE",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "magnetometer": {
- "mj_type": "mjSENS_MAGNETOMETER",
- "objtype": "mjOBJ_SITE",
- "reftype": null,
- "obj_attr": "site",
- "ref_attr": null,
- "computed": false
- },
- "camprojection": {
- "mj_type": "mjSENS_CAMPROJECTION",
- "objtype": "mjOBJ_SITE",
- "reftype": "mjOBJ_CAMERA",
- "obj_attr": "site",
- "ref_attr": "camera",
- "computed": false
- },
- "rangefinder": {
- "mj_type": "mjSENS_RANGEFINDER",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "site",
- "ref_attr": null,
- "computed": true
- },
- "jointpos": {
- "mj_type": "mjSENS_JOINTPOS",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "jointvel": {
- "mj_type": "mjSENS_JOINTVEL",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "tendonpos": {
- "mj_type": "mjSENS_TENDONPOS",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "tendonvel": {
- "mj_type": "mjSENS_TENDONVEL",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "actuatorpos": {
- "mj_type": "mjSENS_ACTUATORPOS",
- "objtype": "mjOBJ_ACTUATOR",
- "reftype": null,
- "obj_attr": "actuator",
- "ref_attr": null,
- "computed": false
- },
- "actuatorvel": {
- "mj_type": "mjSENS_ACTUATORVEL",
- "objtype": "mjOBJ_ACTUATOR",
- "reftype": null,
- "obj_attr": "actuator",
- "ref_attr": null,
- "computed": false
- },
- "actuatorfrc": {
- "mj_type": "mjSENS_ACTUATORFRC",
- "objtype": "mjOBJ_ACTUATOR",
- "reftype": null,
- "obj_attr": "actuator",
- "ref_attr": null,
- "computed": false
- },
- "jointactuatorfrc": {
- "mj_type": "mjSENS_JOINTACTFRC",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "tendonactuatorfrc": {
- "mj_type": "mjSENS_TENDONACTFRC",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "ballquat": {
- "mj_type": "mjSENS_BALLQUAT",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "ballangvel": {
- "mj_type": "mjSENS_BALLANGVEL",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "jointlimitpos": {
- "mj_type": "mjSENS_JOINTLIMITPOS",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "jointlimitvel": {
- "mj_type": "mjSENS_JOINTLIMITVEL",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "jointlimitfrc": {
- "mj_type": "mjSENS_JOINTLIMITFRC",
- "objtype": "mjOBJ_JOINT",
- "reftype": null,
- "obj_attr": "joint",
- "ref_attr": null,
- "computed": false
- },
- "tendonlimitpos": {
- "mj_type": "mjSENS_TENDONLIMITPOS",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "tendonlimitvel": {
- "mj_type": "mjSENS_TENDONLIMITVEL",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "tendonlimitfrc": {
- "mj_type": "mjSENS_TENDONLIMITFRC",
- "objtype": "mjOBJ_TENDON",
- "reftype": null,
- "obj_attr": "tendon",
- "ref_attr": null,
- "computed": false
- },
- "framepos": {
- "mj_type": "mjSENS_FRAMEPOS",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "framequat": {
- "mj_type": "mjSENS_FRAMEQUAT",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "framexaxis": {
- "mj_type": "mjSENS_FRAMEXAXIS",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "frameyaxis": {
- "mj_type": "mjSENS_FRAMEYAXIS",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "framezaxis": {
- "mj_type": "mjSENS_FRAMEZAXIS",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "framelinvel": {
- "mj_type": "mjSENS_FRAMELINVEL",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "frameangvel": {
- "mj_type": "mjSENS_FRAMEANGVEL",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": false
- },
- "framelinacc": {
- "mj_type": "mjSENS_FRAMELINACC",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": null,
- "computed": false
- },
- "frameangacc": {
- "mj_type": "mjSENS_FRAMEANGACC",
- "objtype": "from_xml",
- "reftype": null,
- "obj_attr": "objname",
- "ref_attr": null,
- "computed": false
- },
- "subtreecom": {
- "mj_type": "mjSENS_SUBTREECOM",
- "objtype": "mjOBJ_BODY",
- "reftype": null,
- "obj_attr": "body",
- "ref_attr": null,
- "computed": false
- },
- "subtreelinvel": {
- "mj_type": "mjSENS_SUBTREELINVEL",
- "objtype": "mjOBJ_BODY",
- "reftype": null,
- "obj_attr": "body",
- "ref_attr": null,
- "computed": false
- },
- "subtreeangmom": {
- "mj_type": "mjSENS_SUBTREEANGMOM",
- "objtype": "mjOBJ_BODY",
- "reftype": null,
- "obj_attr": "body",
- "ref_attr": null,
- "computed": false
- },
- "insidesite": {
- "mj_type": "mjSENS_INSIDESITE",
- "objtype": "from_xml",
- "reftype": "mjOBJ_SITE",
- "obj_attr": "objname",
- "ref_attr": "site",
- "computed": false
- },
- "distance": {
- "mj_type": "mjSENS_GEOMDIST",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "body1",
- "ref_attr": "body2",
- "computed": true
- },
- "normal": {
- "mj_type": "mjSENS_GEOMNORMAL",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "body1",
- "ref_attr": "body2",
- "computed": true
- },
- "fromto": {
- "mj_type": "mjSENS_GEOMFROMTO",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "body1",
- "ref_attr": "body2",
- "computed": true
- },
- "contact": {
- "mj_type": "mjSENS_CONTACT",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "site",
- "ref_attr": "body2",
- "computed": true
- },
- "e_potential": {
- "mj_type": "mjSENS_E_POTENTIAL",
- "objtype": "mjOBJ_UNKNOWN",
- "reftype": null,
- "obj_attr": null,
- "ref_attr": null,
- "computed": false
- },
- "e_kinetic": {
- "mj_type": "mjSENS_E_KINETIC",
- "objtype": "mjOBJ_UNKNOWN",
- "reftype": null,
- "obj_attr": null,
- "ref_attr": null,
- "computed": false
- },
- "clock": {
- "mj_type": "mjSENS_CLOCK",
- "objtype": "mjOBJ_UNKNOWN",
- "reftype": null,
- "obj_attr": null,
- "ref_attr": null,
- "computed": false
- },
- "tactile": {
- "mj_type": "mjSENS_TACTILE",
- "objtype": "mjOBJ_MESH",
- "reftype": "mjOBJ_GEOM",
- "obj_attr": "mesh",
- "ref_attr": "geom",
- "computed": false
- },
- "user": {
- "mj_type": "mjSENS_USER",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "objname",
- "ref_attr": null,
- "computed": true
- },
- "plugin": {
- "mj_type": "mjSENS_PLUGIN",
- "objtype": "computed",
- "reftype": "computed",
- "obj_attr": "objname",
- "ref_attr": "refname",
- "computed": true
- }
- },
- "tendon": {
- "spatial": {
- "attrs": [
- "name",
- "class",
- "group",
- "limited",
- "actuatorfrclimited",
- "range",
- "actuatorfrcrange",
- "solreflimit",
- "solimplimit",
- "solreffriction",
- "solimpfriction",
- "frictionloss",
- "springlength",
- "width",
- "material",
- "margin",
- "stiffness",
- "damping",
- "armature",
- "rgba",
- "user"
- ],
- "wrap_types": [
- "site",
- "geom",
- "pulley"
- ]
- },
- "fixed": {
- "attrs": [
- "name",
- "class",
- "group",
- "limited",
- "actuatorfrclimited",
- "range",
- "actuatorfrcrange",
- "solreflimit",
- "solimplimit",
- "solreffriction",
- "solimpfriction",
- "frictionloss",
- "springlength",
- "margin",
- "stiffness",
- "damping",
- "armature",
- "user"
- ],
- "wrap_types": [
- "joint"
- ]
- }
- },
- "equality": {
- "connect": [
- "name",
- "class",
- "body1",
- "body2",
- "anchor",
- "site1",
- "site2",
- "active",
- "solref",
- "solimp"
- ],
- "weld": [
- "name",
- "class",
- "body1",
- "body2",
- "relpose",
- "anchor",
- "site1",
- "site2",
- "active",
- "solref",
- "solimp",
- "torquescale"
- ],
- "joint": [
- "name",
- "class",
- "joint1",
- "joint2",
- "polycoef",
- "active",
- "solref",
- "solimp"
- ],
- "tendon": [
- "name",
- "class",
- "tendon1",
- "tendon2",
- "polycoef",
- "active",
- "solref",
- "solimp"
- ],
- "flex": [
- "name",
- "class",
- "flex",
- "active",
- "solref",
- "solimp"
- ],
- "flexvert": [
- "name",
- "class",
- "flex",
- "active",
- "solref",
- "solimp"
- ],
- "flexstrain": [
- "name",
- "class",
- "flex",
- "cell",
- "active",
- "solref",
- "solimp"
- ]
- },
- "contact": {
- "pair": [
- "name",
- "class",
- "geom1",
- "geom2",
- "condim",
- "friction",
- "solref",
- "solreffriction",
- "solimp",
- "gap",
- "margin"
- ],
- "exclude": [
- "name",
- "body1",
- "body2"
- ]
- },
- "asset": {
- "mesh": [
- "name",
- "class",
- "content_type",
- "file",
- "vertex",
- "normal",
- "texcoord",
- "face",
- "refpos",
- "refquat",
- "scale",
- "smoothnormal",
- "maxhullvert",
- "inertia",
- "builtin",
- "params",
- "material"
- ],
- "hfield": [
- "name",
- "content_type",
- "file",
- "nrow",
- "ncol",
- "size",
- "elevation"
- ],
- "skin": [
- "name",
- "file",
- "material",
- "rgba",
- "inflate",
- "vertex",
- "texcoord",
- "face",
- "group"
- ],
- "texture": [
- "name",
- "type",
- "colorspace",
- "content_type",
- "file",
- "gridsize",
- "gridlayout",
- "fileright",
- "fileleft",
- "fileup",
- "filedown",
- "filefront",
- "fileback",
- "builtin",
- "rgb1",
- "rgb2",
- "mark",
- "markrgb",
- "random",
- "width",
- "height",
- "hflip",
- "vflip",
- "nchannel"
- ],
- "material": [
- "name",
- "class",
- "texture",
- "texrepeat",
- "texuniform",
- "emission",
- "specular",
- "shininess",
- "reflectance",
- "metallic",
- "roughness",
- "rgba"
- ],
- "model": [
- "name",
- "file",
- "content_type"
- ]
- },
- "compiler": {
- "attrs": [
- "autolimits",
- "boundmass",
- "boundinertia",
- "settotalmass",
- "balanceinertia",
- "strippath",
- "coordinate",
- "angle",
- "fitaabb",
- "eulerseq",
- "meshdir",
- "texturedir",
- "discardvisual",
- "usethread",
- "fusestatic",
- "inertiafromgeom",
- "inertiagrouprange",
- "saveinertial",
- "assetdir",
- "alignfree"
- ]
- },
- "option": {
- "attrs": [
- "timestep",
- "impratio",
- "tolerance",
- "ls_tolerance",
- "noslip_tolerance",
- "ccd_tolerance",
- "sleep_tolerance",
- "gravity",
- "wind",
- "magnetic",
- "density",
- "viscosity",
- "o_margin",
- "o_solref",
- "o_solimp",
- "o_friction",
- "integrator",
- "cone",
- "jacobian",
- "solver",
- "iterations",
- "ls_iterations",
- "noslip_iterations",
- "ccd_iterations",
- "sdf_iterations",
- "sdf_initpoints",
- "actuatorgroupdisable"
- ],
- "flag": [
- "constraint",
- "equality",
- "frictionloss",
- "limit",
- "contact",
- "spring",
- "damper",
- "gravity",
- "clampctrl",
- "warmstart",
- "filterparent",
- "actuation",
- "refsafe",
- "sensor",
- "midphase",
- "eulerdamp",
- "autoreset",
- "nativeccd",
- "island",
- "override",
- "energy",
- "fwdinv",
- "invdiscrete",
- "multiccd",
- "sleep",
- "diagexact"
- ]
- },
- "keyframe": {
- "key": [
- "name",
- "time",
- "qpos",
- "qvel",
- "act",
- "mpos",
- "mquat",
- "ctrl"
- ]
- },
- "default": {
- "child_elements": [
- "mesh",
- "material",
- "joint",
- "geom",
- "site",
- "camera",
- "light",
- "pair",
- "equality",
- "tendon",
- "general",
- "motor",
- "position",
- "velocity",
- "intvelocity",
- "damper",
- "cylinder",
- "muscle",
- "adhesion",
- "dcmotor"
- ]
- },
- "flex": {
- "attrs": [
- "name",
- "group",
- "dim",
- "radius",
- "material",
- "rgba",
- "flatskin",
- "body",
- "vertex",
- "element",
- "texcoord",
- "elemtexcoord",
- "node",
- "cellcount",
- "dof"
- ],
- "children": [
- "contact",
- "edge",
- "elasticity"
- ]
- },
- "skin": {
- "attrs": [
- "name",
- "file",
- "material",
- "rgba",
- "inflate",
- "vertex",
- "texcoord",
- "face",
- "group"
- ],
- "children": [
- "bone"
- ]
- },
- "flexcomp": {
- "attrs": [
- "name",
- "type",
- "group",
- "dim",
- "dof",
- "count",
- "cellcount",
- "spacing",
- "radius",
- "rigid",
- "mass",
- "inertiabox",
- "scale",
- "file",
- "point",
- "element",
- "texcoord",
- "material",
- "rgba",
- "flatskin",
- "pos",
- "quat",
- "axisangle",
- "xyaxes",
- "zaxis",
- "euler",
- "origin"
- ],
- "children": [
- "edge",
- "elasticity",
- "contact",
- "pin",
- "plugin"
- ]
- }
-}
diff --git a/Scripts/codegen/snapshots/mjxmacro_snapshot.json b/Scripts/codegen/snapshots/mjxmacro_snapshot.json
deleted file mode 100644
index 65c7660a..00000000
--- a/Scripts/codegen/snapshots/mjxmacro_snapshot.json
+++ /dev/null
@@ -1,4301 +0,0 @@
-{
- "_meta": {
- "source": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "schema_kind": "mjxmacro",
- "struct_field_sources": {
- "MJOPTION_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJSTATISTIC_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_GLOBAL_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_QUALITY_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_HEADLIGHT_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_MAP_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_SCALE_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJVISUAL_RGBA_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjxmacro.h",
- "MJSCOMPILER_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjspecmacro.h",
- "MJSPEC_FIELDS": "third_party\\install\\MuJoCo\\include\\mujoco\\mjspecmacro.h"
- }
- },
- "mjmodel_pointers": {
- "MJMODEL_POINTERS_BODY": [
- {
- "type": "int",
- "name": "body_parentid",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_rootid",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_weldid",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_mocapid",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_jntnum",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_jntadr",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_dofnum",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_dofadr",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_treeid",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_geomnum",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_geomadr",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtByte",
- "name": "body_simple",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtByte",
- "name": "body_sameframe",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "body_pos",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "body_quat",
- "outer_dim": "nbody",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "body_ipos",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "body_iquat",
- "outer_dim": "nbody",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "body_mass",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "body_subtreemass",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "body_inertia",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "body_invweight0",
- "outer_dim": "nbody",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "body_gravcomp",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "body_margin",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "body_user",
- "outer_dim": "nbody",
- "stride": "MJ_M(nuser_body)"
- },
- {
- "type": "int",
- "name": "body_plugin",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_contype",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_conaffinity",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_bvhadr",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_bvhnum",
- "outer_dim": "nbody",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_JOINT": [
- {
- "type": "int",
- "name": "jnt_type",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "jnt_qposadr",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "jnt_dofadr",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "jnt_bodyid",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "jnt_actuatorid",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "jnt_group",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "jnt_limited",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "jnt_actfrclimited",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "jnt_actgravcomp",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "jnt_solref",
- "outer_dim": "njnt",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "jnt_solimp",
- "outer_dim": "njnt",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "jnt_pos",
- "outer_dim": "njnt",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "jnt_axis",
- "outer_dim": "njnt",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "jnt_stiffness",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "jnt_stiffnesspoly",
- "outer_dim": "njnt",
- "stride": "mjNPOLY"
- },
- {
- "type": "mjtNum",
- "name": "jnt_range",
- "outer_dim": "njnt",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "jnt_actfrcrange",
- "outer_dim": "njnt",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "jnt_margin",
- "outer_dim": "njnt",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "jnt_user",
- "outer_dim": "njnt",
- "stride": "MJ_M(nuser_jnt)"
- }
- ],
- "MJMODEL_POINTERS_DOF": [
- {
- "type": "int",
- "name": "dof_bodyid",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_jntid",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_parentid",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_treeid",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_Madr",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_simplenum",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_solref",
- "outer_dim": "nv",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "dof_solimp",
- "outer_dim": "nv",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "dof_frictionloss",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_armature",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_damping",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_dampingpoly",
- "outer_dim": "nv",
- "stride": "mjNPOLY"
- },
- {
- "type": "mjtNum",
- "name": "dof_invweight0",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_M0",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "dof_length",
- "outer_dim": "nv",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_TREE": [
- {
- "type": "int",
- "name": "tree_bodyadr",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_bodynum",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_dofadr",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_dofnum",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_sleep_policy",
- "outer_dim": "ntree",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_GEOM": [
- {
- "type": "int",
- "name": "geom_type",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_contype",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_conaffinity",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_condim",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_bodyid",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_dataid",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_matid",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_group",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_priority",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "geom_plugin",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtByte",
- "name": "geom_sameframe",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "geom_solmix",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "geom_solref",
- "outer_dim": "ngeom",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "geom_solimp",
- "outer_dim": "ngeom",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "geom_size",
- "outer_dim": "ngeom",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "geom_aabb",
- "outer_dim": "ngeom",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "geom_rbound",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "geom_pos",
- "outer_dim": "ngeom",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "geom_quat",
- "outer_dim": "ngeom",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "geom_friction",
- "outer_dim": "ngeom",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "geom_margin",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "geom_gap",
- "outer_dim": "ngeom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "geom_fluid",
- "outer_dim": "ngeom",
- "stride": "mjNFLUID"
- },
- {
- "type": "mjtNum",
- "name": "geom_user",
- "outer_dim": "ngeom",
- "stride": "MJ_M(nuser_geom)"
- },
- {
- "type": "float",
- "name": "geom_rgba",
- "outer_dim": "ngeom",
- "stride": "4"
- }
- ],
- "MJMODEL_POINTERS_SITE": [
- {
- "type": "int",
- "name": "site_type",
- "outer_dim": "nsite",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "site_bodyid",
- "outer_dim": "nsite",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "site_matid",
- "outer_dim": "nsite",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "site_group",
- "outer_dim": "nsite",
- "stride": "1"
- },
- {
- "type": "mjtByte",
- "name": "site_sameframe",
- "outer_dim": "nsite",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "site_size",
- "outer_dim": "nsite",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "site_pos",
- "outer_dim": "nsite",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "site_quat",
- "outer_dim": "nsite",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "site_user",
- "outer_dim": "nsite",
- "stride": "MJ_M(nuser_site)"
- },
- {
- "type": "float",
- "name": "site_rgba",
- "outer_dim": "nsite",
- "stride": "4"
- }
- ],
- "MJMODEL_POINTERS_CAMERA": [
- {
- "type": "int",
- "name": "cam_mode",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "cam_bodyid",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "cam_targetbodyid",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "cam_pos",
- "outer_dim": "ncam",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "cam_quat",
- "outer_dim": "ncam",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "cam_poscom0",
- "outer_dim": "ncam",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "cam_pos0",
- "outer_dim": "ncam",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "cam_mat0",
- "outer_dim": "ncam",
- "stride": "9"
- },
- {
- "type": "int",
- "name": "cam_projection",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "cam_fovy",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "cam_ipd",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "cam_resolution",
- "outer_dim": "ncam",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "cam_output",
- "outer_dim": "ncam",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "cam_sensorsize",
- "outer_dim": "ncam",
- "stride": "2"
- },
- {
- "type": "float",
- "name": "cam_intrinsic",
- "outer_dim": "ncam",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "cam_user",
- "outer_dim": "ncam",
- "stride": "MJ_M(nuser_cam)"
- }
- ],
- "MJMODEL_POINTERS_LIGHT": [
- {
- "type": "int",
- "name": "light_mode",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "light_bodyid",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "light_targetbodyid",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "light_type",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "light_texid",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "light_castshadow",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "light_bulbradius",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "light_intensity",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "light_range",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "light_active",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "light_pos",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "light_dir",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "light_poscom0",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "light_pos0",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "light_dir0",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "light_attenuation",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "light_cutoff",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "light_exponent",
- "outer_dim": "nlight",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "light_ambient",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "light_diffuse",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "light_specular",
- "outer_dim": "nlight",
- "stride": "3"
- }
- ],
- "MJMODEL_POINTERS_FLEX": [
- {
- "type": "int",
- "name": "flex_contype",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_conaffinity",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_condim",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_priority",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_solmix",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_solref",
- "outer_dim": "nflex",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "flex_solimp",
- "outer_dim": "nflex",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "flex_friction",
- "outer_dim": "nflex",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flex_margin",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_gap",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "flex_internal",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_selfcollide",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_activelayers",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_passive",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_dim",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_matid",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_group",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_interp",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_cellnum",
- "outer_dim": "nflex",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "flex_nodeadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_nodenum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertnum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_edgeadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_edgenum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemnum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemdataadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_stiffnessadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemedgeadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_bendingadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_shellnum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_shelldataadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_evpairadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_evpairnum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_texcoordadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_nodebodyid",
- "outer_dim": "nflexnode",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertbodyid",
- "outer_dim": "nflexvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertedgeadr",
- "outer_dim": "nflexvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertedgenum",
- "outer_dim": "nflexvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_vertedge",
- "outer_dim": "nflexedge",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "flex_edge",
- "outer_dim": "nflexedge",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "flex_edgeflap",
- "outer_dim": "nflexedge",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "flex_elem",
- "outer_dim": "nflexelemdata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemtexcoord",
- "outer_dim": "nflexelemdata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemedge",
- "outer_dim": "nflexelemedge",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_elemlayer",
- "outer_dim": "nflexelem",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_shell",
- "outer_dim": "nflexshelldata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_evpair",
- "outer_dim": "nflexevpair",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "flex_vert",
- "outer_dim": "nflexvert",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flex_vert0",
- "outer_dim": "nflexvert",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flex_vertmetric",
- "outer_dim": "nflexvert",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "flex_node",
- "outer_dim": "nflexnode",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flex_node0",
- "outer_dim": "nflexnode",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flexedge_length0",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flexedge_invweight0",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_radius",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_size",
- "outer_dim": "nflex",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flex_stiffness",
- "outer_dim": "nflexstiffness",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_bending",
- "outer_dim": "nflexbending",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_damping",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_edgestiffness",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flex_edgedamping",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_edgeequality",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "flex_rigid",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "flexedge_rigid",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "flex_centered",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "flex_flatskin",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_bvhadr",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flex_bvhnum",
- "outer_dim": "nflex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flexedge_J_rownnz",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flexedge_J_rowadr",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flexedge_J_colind",
- "outer_dim": "nJfe",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "flexvert_J_rownnz",
- "outer_dim": "nflexvert",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "flexvert_J_rowadr",
- "outer_dim": "nflexvert",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "flexvert_J_colind",
- "outer_dim": "nJfv",
- "stride": "2"
- },
- {
- "type": "float",
- "name": "flex_rgba",
- "outer_dim": "nflex",
- "stride": "4"
- },
- {
- "type": "float",
- "name": "flex_texcoord",
- "outer_dim": "nflextexcoord",
- "stride": "2"
- }
- ],
- "MJMODEL_POINTERS_MESH": [
- {
- "type": "int",
- "name": "mesh_vertadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_vertnum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_faceadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_facenum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_bvhadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_bvhnum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_octadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_octnum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_normaladr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_normalnum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_texcoordadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_texcoordnum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_graphadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mesh_vert",
- "outer_dim": "nmeshvert",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "mesh_normal",
- "outer_dim": "nmeshnormal",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "mesh_texcoord",
- "outer_dim": "nmeshtexcoord",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "mesh_face",
- "outer_dim": "nmeshface",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "mesh_facenormal",
- "outer_dim": "nmeshface",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "mesh_facetexcoord",
- "outer_dim": "nmeshface",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "mesh_graph",
- "outer_dim": "nmeshgraph",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "mesh_scale",
- "outer_dim": "nmesh",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "mesh_pos",
- "outer_dim": "nmesh",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "mesh_quat",
- "outer_dim": "nmesh",
- "stride": "4"
- },
- {
- "type": "int",
- "name": "mesh_pathadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polynum",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polyadr",
- "outer_dim": "nmesh",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "mesh_polynormal",
- "outer_dim": "nmeshpoly",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "mesh_polyvertadr",
- "outer_dim": "nmeshpoly",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polyvertnum",
- "outer_dim": "nmeshpoly",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polyvert",
- "outer_dim": "nmeshpolyvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polymapadr",
- "outer_dim": "nmeshvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polymapnum",
- "outer_dim": "nmeshvert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "mesh_polymap",
- "outer_dim": "nmeshpolymap",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_SKIN": [
- {
- "type": "int",
- "name": "skin_matid",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_group",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "skin_rgba",
- "outer_dim": "nskin",
- "stride": "4"
- },
- {
- "type": "float",
- "name": "skin_inflate",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_vertadr",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_vertnum",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_texcoordadr",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_faceadr",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_facenum",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_boneadr",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_bonenum",
- "outer_dim": "nskin",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "skin_vert",
- "outer_dim": "nskinvert",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "skin_texcoord",
- "outer_dim": "nskintexvert",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "skin_face",
- "outer_dim": "nskinface",
- "stride": "3"
- },
- {
- "type": "int",
- "name": "skin_bonevertadr",
- "outer_dim": "nskinbone",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_bonevertnum",
- "outer_dim": "nskinbone",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "skin_bonebindpos",
- "outer_dim": "nskinbone",
- "stride": "3"
- },
- {
- "type": "float",
- "name": "skin_bonebindquat",
- "outer_dim": "nskinbone",
- "stride": "4"
- },
- {
- "type": "int",
- "name": "skin_bonebodyid",
- "outer_dim": "nskinbone",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_bonevertid",
- "outer_dim": "nskinbonevert",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "skin_bonevertweight",
- "outer_dim": "nskinbonevert",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "skin_pathadr",
- "outer_dim": "nskin",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_HFIELD": [
- {
- "type": "mjtNum",
- "name": "hfield_size",
- "outer_dim": "nhfield",
- "stride": "4"
- },
- {
- "type": "int",
- "name": "hfield_nrow",
- "outer_dim": "nhfield",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "hfield_ncol",
- "outer_dim": "nhfield",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "hfield_adr",
- "outer_dim": "nhfield",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "hfield_data",
- "outer_dim": "nhfielddata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "hfield_pathadr",
- "outer_dim": "nhfield",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_TEXTURE": [
- {
- "type": "int",
- "name": "tex_type",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tex_colorspace",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tex_height",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tex_width",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tex_nchannel",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "mjtSize",
- "name": "tex_adr",
- "outer_dim": "ntex",
- "stride": "1"
- },
- {
- "type": "mjtByte",
- "name": "tex_data",
- "outer_dim": "ntexdata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tex_pathadr",
- "outer_dim": "ntex",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_MATERIAL": [
- {
- "type": "int",
- "name": "mat_texid",
- "outer_dim": "nmat",
- "stride": "mjNTEXROLE"
- },
- {
- "type": "mjtBool",
- "name": "mat_texuniform",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_texrepeat",
- "outer_dim": "nmat",
- "stride": "2"
- },
- {
- "type": "float",
- "name": "mat_emission",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_specular",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_shininess",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_reflectance",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_metallic",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_roughness",
- "outer_dim": "nmat",
- "stride": "1"
- },
- {
- "type": "float",
- "name": "mat_rgba",
- "outer_dim": "nmat",
- "stride": "4"
- }
- ],
- "MJMODEL_POINTERS_PAIR": [
- {
- "type": "int",
- "name": "pair_dim",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "pair_geom1",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "pair_geom2",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "pair_signature",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "pair_solref",
- "outer_dim": "npair",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "pair_solreffriction",
- "outer_dim": "npair",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "pair_solimp",
- "outer_dim": "npair",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "pair_margin",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "pair_gap",
- "outer_dim": "npair",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "pair_friction",
- "outer_dim": "npair",
- "stride": "5"
- }
- ],
- "MJMODEL_POINTERS_EXCLUDE": [
- {
- "type": "int",
- "name": "exclude_signature",
- "outer_dim": "nexclude",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_EQUALITY": [
- {
- "type": "int",
- "name": "eq_type",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "eq_obj1id",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "eq_obj2id",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "eq_objtype",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "eq_active0",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "eq_solref",
- "outer_dim": "neq",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "eq_solimp",
- "outer_dim": "neq",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "eq_data",
- "outer_dim": "neq",
- "stride": "mjNEQDATA"
- }
- ],
- "MJMODEL_POINTERS_TENDON": [
- {
- "type": "int",
- "name": "tendon_adr",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_num",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_matid",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_actuatorid",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_group",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_treenum",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_treeid",
- "outer_dim": "ntendon",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "ten_J_rownnz",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "ten_J_rowadr",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "ten_J_colind",
- "outer_dim": "nJten",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "tendon_limited",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "tendon_actfrclimited",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_width",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_solref_lim",
- "outer_dim": "ntendon",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "tendon_solimp_lim",
- "outer_dim": "ntendon",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "tendon_solref_fri",
- "outer_dim": "ntendon",
- "stride": "mjNREF"
- },
- {
- "type": "mjtNum",
- "name": "tendon_solimp_fri",
- "outer_dim": "ntendon",
- "stride": "mjNIMP"
- },
- {
- "type": "mjtNum",
- "name": "tendon_range",
- "outer_dim": "ntendon",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "tendon_actfrcrange",
- "outer_dim": "ntendon",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "tendon_margin",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_stiffness",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_stiffnesspoly",
- "outer_dim": "ntendon",
- "stride": "mjNPOLY"
- },
- {
- "type": "mjtNum",
- "name": "tendon_damping",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_dampingpoly",
- "outer_dim": "ntendon",
- "stride": "mjNPOLY"
- },
- {
- "type": "mjtNum",
- "name": "tendon_armature",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_frictionloss",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_lengthspring",
- "outer_dim": "ntendon",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "tendon_length0",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_invweight0",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "tendon_user",
- "outer_dim": "ntendon",
- "stride": "MJ_M(nuser_tendon)"
- },
- {
- "type": "float",
- "name": "tendon_rgba",
- "outer_dim": "ntendon",
- "stride": "4"
- }
- ],
- "MJMODEL_POINTERS_ACTUATOR": [
- {
- "type": "int",
- "name": "actuator_trntype",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_dyntype",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_gaintype",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_biastype",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_trnid",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "actuator_damping",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_dampingpoly",
- "outer_dim": "nu",
- "stride": "mjNPOLY"
- },
- {
- "type": "mjtNum",
- "name": "actuator_armature",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_actadr",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_actnum",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_group",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "actuator_history",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "actuator_historyadr",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_delay",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "actuator_ctrllimited",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "actuator_forcelimited",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "actuator_actlimited",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_dynprm",
- "outer_dim": "nu",
- "stride": "mjNDYN"
- },
- {
- "type": "mjtNum",
- "name": "actuator_gainprm",
- "outer_dim": "nu",
- "stride": "mjNGAIN"
- },
- {
- "type": "mjtNum",
- "name": "actuator_biasprm",
- "outer_dim": "nu",
- "stride": "mjNBIAS"
- },
- {
- "type": "mjtBool",
- "name": "actuator_actearly",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_ctrlrange",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "actuator_forcerange",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "actuator_actrange",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "actuator_gear",
- "outer_dim": "nu",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "actuator_cranklength",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_acc0",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_length0",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_lengthrange",
- "outer_dim": "nu",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "actuator_user",
- "outer_dim": "nu",
- "stride": "MJ_M(nuser_actuator)"
- },
- {
- "type": "int",
- "name": "actuator_plugin",
- "outer_dim": "nu",
- "stride": "1"
- }
- ],
- "MJMODEL_POINTERS_SENSOR": [
- {
- "type": "int",
- "name": "sensor_type",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_datatype",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_needstage",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_objtype",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_objid",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_reftype",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_refid",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_intprm",
- "outer_dim": "nsensor",
- "stride": "mjNSENS"
- },
- {
- "type": "int",
- "name": "sensor_dim",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_adr",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "sensor_cutoff",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "sensor_noise",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "sensor_history",
- "outer_dim": "nsensor",
- "stride": "2"
- },
- {
- "type": "int",
- "name": "sensor_historyadr",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "sensor_delay",
- "outer_dim": "nsensor",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "sensor_interval",
- "outer_dim": "nsensor",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "sensor_user",
- "outer_dim": "nsensor",
- "stride": "MJ_M(nuser_sensor)"
- },
- {
- "type": "int",
- "name": "sensor_plugin",
- "outer_dim": "nsensor",
- "stride": "1"
- }
- ]
- },
- "mjdata_pointers": {
- "MJDATA_POINTERS": [
- {
- "type": "mjtNum",
- "name": "qpos",
- "outer_dim": "nq",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qvel",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "act",
- "outer_dim": "na",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "history",
- "outer_dim": "nhistory",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qacc_warmstart",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "plugin_state",
- "outer_dim": "npluginstate",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ctrl",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_applied",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "xfrc_applied",
- "outer_dim": "nbody",
- "stride": "6"
- },
- {
- "type": "mjtBool",
- "name": "eq_active",
- "outer_dim": "neq",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "mocap_pos",
- "outer_dim": "nmocap",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "mocap_quat",
- "outer_dim": "nmocap",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "qacc",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "act_dot",
- "outer_dim": "na",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "userdata",
- "outer_dim": "nuserdata",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "sensordata",
- "outer_dim": "nsensordata",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_asleep",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "plugin",
- "outer_dim": "nplugin",
- "stride": "1"
- },
- {
- "type": "uintptr_t",
- "name": "plugin_data",
- "outer_dim": "nplugin",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "xpos",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "xquat",
- "outer_dim": "nbody",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "xmat",
- "outer_dim": "nbody",
- "stride": "9"
- },
- {
- "type": "mjtNum",
- "name": "xipos",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "ximat",
- "outer_dim": "nbody",
- "stride": "9"
- },
- {
- "type": "mjtNum",
- "name": "xanchor",
- "outer_dim": "njnt",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "xaxis",
- "outer_dim": "njnt",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "geom_xpos",
- "outer_dim": "ngeom",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "geom_xmat",
- "outer_dim": "ngeom",
- "stride": "9"
- },
- {
- "type": "mjtNum",
- "name": "site_xpos",
- "outer_dim": "nsite",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "site_xmat",
- "outer_dim": "nsite",
- "stride": "9"
- },
- {
- "type": "mjtNum",
- "name": "cam_xpos",
- "outer_dim": "ncam",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "cam_xmat",
- "outer_dim": "ncam",
- "stride": "9"
- },
- {
- "type": "mjtNum",
- "name": "light_xpos",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "light_xdir",
- "outer_dim": "nlight",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "subtree_com",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "cdof",
- "outer_dim": "nv",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "cinert",
- "outer_dim": "nbody",
- "stride": "10"
- },
- {
- "type": "mjtNum",
- "name": "flexvert_xpos",
- "outer_dim": "nflexvert",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "flexelem_aabb",
- "outer_dim": "nflexelem",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "flexedge_J",
- "outer_dim": "nJfe",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flexedge_length",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flexvert_J",
- "outer_dim": "nJfv",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "flexvert_length",
- "outer_dim": "nflexvert",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "bvh_aabb_dyn",
- "outer_dim": "nbvhdynamic",
- "stride": "6"
- },
- {
- "type": "int",
- "name": "ten_wrapadr",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "ten_wrapnum",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ten_J",
- "outer_dim": "nJten",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ten_length",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "wrap_obj",
- "outer_dim": "nwrap",
- "stride": "2"
- },
- {
- "type": "mjtNum",
- "name": "wrap_xpos",
- "outer_dim": "nwrap",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "actuator_length",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "moment_rownnz",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "moment_rowadr",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "moment_colind",
- "outer_dim": "nJmom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_moment",
- "outer_dim": "nJmom",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "crb",
- "outer_dim": "nbody",
- "stride": "10"
- },
- {
- "type": "mjtNum",
- "name": "qM",
- "outer_dim": "nM",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "M",
- "outer_dim": "nC",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qLD",
- "outer_dim": "nC",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qLDiagInv",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtBool",
- "name": "bvh_active",
- "outer_dim": "nbvh",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tree_awake",
- "outer_dim": "ntree",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_awake",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "body_awake_ind",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "parent_awake_ind",
- "outer_dim": "nbody",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_awake_ind",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "flexedge_velocity",
- "outer_dim": "nflexedge",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ten_velocity",
- "outer_dim": "ntendon",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_velocity",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "cvel",
- "outer_dim": "nbody",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "cdof_dot",
- "outer_dim": "nv",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_bias",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_spring",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_damper",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_gravcomp",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_fluid",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_passive",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "subtree_linvel",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "subtree_angmom",
- "outer_dim": "nbody",
- "stride": "3"
- },
- {
- "type": "mjtNum",
- "name": "qH",
- "outer_dim": "nC",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qHDiagInv",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qDeriv",
- "outer_dim": "nD",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qLU",
- "outer_dim": "nD",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "actuator_force",
- "outer_dim": "nu",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_actuator",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_smooth",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qacc_smooth",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_constraint",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "qfrc_inverse",
- "outer_dim": "nv",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "cacc",
- "outer_dim": "nbody",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "cfrc_int",
- "outer_dim": "nbody",
- "stride": "6"
- },
- {
- "type": "mjtNum",
- "name": "cfrc_ext",
- "outer_dim": "nbody",
- "stride": "6"
- }
- ],
- "MJDATA_ARENA_POINTERS_CONTACT": [
- {
- "type": "mjContact",
- "name": "contact",
- "outer_dim": "MJ_D(ncon)",
- "stride": "1"
- }
- ],
- "MJDATA_ARENA_POINTERS_SOLVER": [
- {
- "type": "int",
- "name": "efc_type",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_id",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_J_rownnz",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_J_rowadr",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_J_rowsuper",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_J_colind",
- "outer_dim": "MJ_D(nJ)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_J",
- "outer_dim": "MJ_D(nJ)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_pos",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_margin",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_frictionloss",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_diagA",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_KBIP",
- "outer_dim": "MJ_D(nefc)",
- "stride": "4"
- },
- {
- "type": "mjtNum",
- "name": "efc_D",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_R",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "tendon_efcadr",
- "outer_dim": "MJ_M(ntendon)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_vel",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_aref",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_b",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_state",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_force",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- }
- ],
- "MJDATA_ARENA_POINTERS_DUAL": [
- {
- "type": "int",
- "name": "efc_Y_rownnz",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_Y_rowadr",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_Y_colind",
- "outer_dim": "MJ_D(nY)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_Y",
- "outer_dim": "MJ_D(nY)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_AR_rownnz",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_AR_rowadr",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_AR_colind",
- "outer_dim": "MJ_D(nA)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "efc_AR",
- "outer_dim": "MJ_D(nA)",
- "stride": "1"
- }
- ],
- "MJDATA_ARENA_POINTERS_ISLAND": [
- {
- "type": "int",
- "name": "tree_island",
- "outer_dim": "MJ_M(ntree)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_ntree",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_itreeadr",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "map_itree2tree",
- "outer_dim": "MJ_M(ntree)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "dof_island",
- "outer_dim": "MJ_M(nv)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_nv",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_idofadr",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_dofadr",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "map_dof2idof",
- "outer_dim": "MJ_M(nv)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "map_idof2dof",
- "outer_dim": "MJ_M(nv)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ifrc_smooth",
- "outer_dim": "MJ_D(nidof)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iacc_smooth",
- "outer_dim": "MJ_D(nidof)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iacc",
- "outer_dim": "MJ_D(nidof)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "efc_island",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_ne",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_nf",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_nefc",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "island_iefcadr",
- "outer_dim": "MJ_D(nisland)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "map_efc2iefc",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "map_iefc2efc",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "iefc_type",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "iefc_id",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iefc_frictionloss",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iefc_D",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iefc_R",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iefc_aref",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "int",
- "name": "iefc_state",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "iefc_force",
- "outer_dim": "MJ_D(nefc)",
- "stride": "1"
- },
- {
- "type": "mjtNum",
- "name": "ifrc_constraint",
- "outer_dim": "MJ_D(nidof)",
- "stride": "1"
- }
- ],
- "MJDATA_ARENA_POINTERS": []
- },
- "struct_fields": {
- "MJOPTION_FIELDS": [
- {
- "type": "mjtNum",
- "name": "timestep",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "impratio",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "tolerance",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "ls_tolerance",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "noslip_tolerance",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "ccd_tolerance",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "sleep_tolerance",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "gravity",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "mjtNum",
- "name": "wind",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "mjtNum",
- "name": "magnetic",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "mjtNum",
- "name": "density",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "viscosity",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "o_margin",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "o_solref",
- "count": "mjNREF",
- "is_vec": true
- },
- {
- "type": "mjtNum",
- "name": "o_solimp",
- "count": "mjNIMP",
- "is_vec": true
- },
- {
- "type": "mjtNum",
- "name": "o_friction",
- "count": "5",
- "is_vec": true
- },
- {
- "type": "int",
- "name": "integrator",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "cone",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "jacobian",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "solver",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "iterations",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "ls_iterations",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "noslip_iterations",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "ccd_iterations",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "disableflags",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "enableflags",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "disableactuator",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "sdf_initpoints",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "sdf_iterations",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJSTATISTIC_FIELDS": [
- {
- "type": "mjtNum",
- "name": "meaninertia",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "meanmass",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "meansize",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "extent",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtNum",
- "name": "center",
- "count": "3",
- "is_vec": true
- }
- ],
- "MJVISUAL_GLOBAL_FIELDS": [
- {
- "type": "int",
- "name": "cameraid",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "orthographic",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "fovy",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "ipd",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "azimuth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "elevation",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "linewidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "glow",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "realtime",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "offwidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "offheight",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "ellipsoidinertia",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "bvactive",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJVISUAL_QUALITY_FIELDS": [
- {
- "type": "int",
- "name": "shadowsize",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "offsamples",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "numslices",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "numstacks",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "numquads",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJVISUAL_HEADLIGHT_FIELDS": [
- {
- "type": "float",
- "name": "ambient",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "diffuse",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "specular",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "int",
- "name": "active",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJVISUAL_MAP_FIELDS": [
- {
- "type": "float",
- "name": "stiffness",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "stiffnessrot",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "force",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "torque",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "alpha",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "fogstart",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "fogend",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "znear",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "zfar",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "haze",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "shadowclip",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "shadowscale",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "actuatortendon",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJVISUAL_SCALE_FIELDS": [
- {
- "type": "float",
- "name": "forcewidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "contactwidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "contactheight",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "connect",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "com",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "camera",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "light",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "selectpoint",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "jointlength",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "jointwidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "actuatorlength",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "actuatorwidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "framelength",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "framewidth",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "constraint",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "slidercrank",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "float",
- "name": "frustum",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJVISUAL_RGBA_FIELDS": [
- {
- "type": "float",
- "name": "fog",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "haze",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "force",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "inertia",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "joint",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "actuator",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "actuatornegative",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "actuatorpositive",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "com",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "camera",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "light",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "selectpoint",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "connect",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "contactpoint",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "contactforce",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "contactfriction",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "contacttorque",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "contactgap",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "rangefinder",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "constraint",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "slidercrank",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "crankbroken",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "frustum",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "bv",
- "count": "4",
- "is_vec": true
- },
- {
- "type": "float",
- "name": "bvactive",
- "count": "4",
- "is_vec": true
- }
- ],
- "MJSCOMPILER_FIELDS": [
- {
- "type": "mjtByte",
- "name": "autolimits",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "double",
- "name": "boundmass",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "double",
- "name": "boundinertia",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "double",
- "name": "settotalmass",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "balanceinertia",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "fitaabb",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "degree",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "char",
- "name": "eulerseq",
- "count": "3",
- "is_vec": true
- },
- {
- "type": "mjtByte",
- "name": "discardvisual",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "usethread",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "fusestatic",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "inertiafromgeom",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "inertiagrouprange",
- "count": "2",
- "is_vec": true
- },
- {
- "type": "mjtByte",
- "name": "saveinertial",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "alignfree",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjLROpt",
- "name": "LRopt",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjString*",
- "name": "meshdir",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjString*",
- "name": "texturedir",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "uint64_t",
- "name": "authored",
- "count": "1",
- "is_vec": false
- }
- ],
- "MJSPEC_FIELDS": [
- {
- "type": "mjsElement*",
- "name": "element",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjString*",
- "name": "modelname",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjsCompiler",
- "name": "compiler",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "strippath",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjOption",
- "name": "option",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjVisual",
- "name": "visual",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjStatistic",
- "name": "stat",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtSize",
- "name": "memory",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nemax",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuserdata",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_body",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_jnt",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_geom",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_site",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_cam",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_tendon",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_actuator",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nuser_sensor",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nkey",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "njmax",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "int",
- "name": "nconmax",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtSize",
- "name": "nstack",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjString*",
- "name": "comment",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjString*",
- "name": "modelfiledir",
- "count": "1",
- "is_vec": false
- },
- {
- "type": "mjtByte",
- "name": "hasImplicitPluginElem",
- "count": "1",
- "is_vec": false
- }
- ]
- }
-}
\ No newline at end of file
diff --git a/Scripts/codegen/tests/__init__.py b/Scripts/codegen/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/Scripts/codegen/tests/conftest.py b/Scripts/codegen/tests/conftest.py
deleted file mode 100644
index 97eda15e..00000000
--- a/Scripts/codegen/tests/conftest.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Shared fixtures + helpers for codegen pytest tests.
-"""
-
-from __future__ import annotations
-
-import json
-import os
-import sys
-from typing import Any, Dict
-
-# Make the parent codegen package importable when running pytest from the
-# plugin root or from this directory.
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-_PLUGIN_ROOT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
-
-import pytest
-
-
-@pytest.fixture(scope="session")
-def real_schema() -> Dict[str, Any]:
- """The actual MJCF schema snapshot shipped with the plugin."""
- path = os.path.join(_PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "mjcf_schema_snapshot.json")
- with open(path, "r", encoding="utf-8") as f:
- return json.load(f)
-
-
-@pytest.fixture(scope="session")
-def real_rules() -> Dict[str, Any]:
- path = os.path.join(_CODEGEN_DIR, "codegen_rules.json")
- with open(path, "r", encoding="utf-8") as f:
- return json.load(f)
-
-
-@pytest.fixture(scope="session")
-def real_mjxmacro() -> Dict[str, Any]:
- path = os.path.join(_PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "mjxmacro_snapshot.json")
- with open(path, "r", encoding="utf-8") as f:
- return json.load(f)
-
-
-@pytest.fixture(scope="session")
-def real_mjspec() -> Dict[str, Any]:
- """The mjspec snapshot file was retired; the runtime
- now projects the introspect snapshot into the legacy mjspec shape.
- The fixture mirrors that projection so tests stay isomorphic."""
- import generate_ue_components as gen
- introspect_path = os.path.join(
- _PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "introspect_snapshot.json",
- )
- with open(introspect_path, "r", encoding="utf-8") as f:
- introspect = json.load(f)
- return gen._mjspec_from_introspect(introspect)
-
-
-@pytest.fixture(autouse=True)
-def _clear_diags():
- """Each test starts with a clean diagnostics buffer + strict counter.
- Module-level state survives across tests otherwise — autouse keeps
- drift-check tests from leaking state into one another."""
- import generate_ue_components as gen # noqa: E402, local import
- gen._reset_diags()
- yield
- gen._reset_diags()
-
-
-@pytest.fixture
-def minimal_rules() -> Dict[str, Any]:
- """A small synthetic rules block, useful for unit-testing emission
- shapes without coupling to the real schema."""
- return {
- "global_exclusions": ["user"],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {
- "range": "TArray",
- "limited": "bool",
- "rgba": "FLinearColor",
- "axis": "FVector",
- },
- "canonicalizations": {
- "spatial_pose": {
- "absorbs_attrs": ["pos"],
- "emits_property": {"name": "Pos", "type": "FVector"},
- "import_helper": "MjUtils::ReadVec3InMeters",
- "export_helper": "MjUtils::UEToMjPosition",
- },
- "orientation": {
- "absorbs_attrs": ["quat", "euler", "axisangle", "xyaxes", "zaxis"],
- "emits_property": {"name": "Quat", "type": "FQuat"},
- "import_helper": "MjOrientationUtils::OrientationToMjQuat",
- "export_helper": "MjUtils::UEToMjRotation",
- },
- },
- "element_rules": {
- "joint": {
- "exclude_attrs": ["pos", "axis"],
- },
- "geom": {
- "exclude_attrs": ["material", "pos", "quat", "size", "fromto",
- "axisangle", "euler", "xyaxes", "zaxis"],
- "applies_canonicalizations": ["spatial_pose", "orientation"],
- },
- },
- }
diff --git a/Scripts/codegen/tests/test_behavioral_emit_guarantees.py b/Scripts/codegen/tests/test_behavioral_emit_guarantees.py
deleted file mode 100644
index fc13977a..00000000
--- a/Scripts/codegen/tests/test_behavioral_emit_guarantees.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Behavioural lock-ins for the codegen's emit surface.
-
-Substring-only assertions catch typos but not semantics — these tests
-pin three load-bearing properties of the generated C++:
-
-1. XML enum roundtrip — every ``value_map`` entry produces matching
- import + export arms whose XML strings and UE members agree.
-2. ``mjs_setTo*`` argument order — the codegen feeds params to the
- call in the exact order declared by the C signature in the
- snapshot, not by rule-side iteration order. Misordered args here
- would call ``mjs_setToPosition(kp_value, kv_value, ...)`` swapped
- and silently miscalibrate every Position actuator.
-3. Override-toggle gate — every codegen-emitted UPROPERTY pair is
- ``bOverride_X`` (toggle) + ``X`` (value). Both names must agree
- so the editor InlineEditConditionToggle wiring binds correctly.
-"""
-
-from __future__ import annotations
-
-import os
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-
-import re
-
-import generate_ue_components as gen
-
-
-# ---------- xml_enum roundtrip ---------------------------------------------
-
-def test_xml_enum_roundtrip_arms_match(real_rules):
- """Every value_map entry must be reachable from both directions:
- ``XML string -> UE member`` (import) and ``UE member -> XML
- string`` (export). A typo in either arm would silently misimport
- or misexport the attr without a compile error."""
- for elem, elem_rule in real_rules.get("element_rules", {}).items():
- for attr, enum_def in elem_rule.get("xml_enum_attrs", {}).items():
- value_map = enum_def.get("value_map") or {}
- if not value_map:
- continue
- ue_enum_type = enum_def["ue_enum_type"]
- import_cpp = gen._emit_xml_enum_import(attr, enum_def)
- # Enums with no ``mjs_field`` (e.g. dcmotor.input, routed
- # through mjs_setToDCMotor) emit nothing on the export side
- # by design — skip the export arm in that case.
- export_cpp = (
- gen._emit_xml_enum_export(attr, enum_def)
- if enum_def.get("mjs_field") else ""
- )
- for xml_val, mapping in value_map.items():
- ue_member = mapping[0] if isinstance(mapping, list) else mapping
- # Import side mentions both XML literal and UE member.
- assert f'"{xml_val}"' in import_cpp, (
- f"{elem}.{attr}: import arm missing XML literal "
- f"'{xml_val}'\n{import_cpp}"
- )
- assert f"{ue_enum_type}::{ue_member}" in import_cpp, (
- f"{elem}.{attr}: import arm missing "
- f"{ue_enum_type}::{ue_member}\n{import_cpp}"
- )
- if export_cpp:
- assert f"{ue_enum_type}::{ue_member}" in export_cpp, (
- f"{elem}.{attr}: export arm missing "
- f"{ue_enum_type}::{ue_member}\n{export_cpp}"
- )
-
-
-# ---------- mjs_setTo* arg order -------------------------------------------
-
-def test_setto_call_args_follow_c_signature_order():
- """The generated ``mjs_setToX(Element, a, b, c)`` call must list
- args in the order declared by the C signature. Reordering by
- rule-side iteration would silently swap kp/kv on actuator
- subtypes."""
- rules = {
- "default_type": "float",
- "type_mappings": {"kp": "float", "kv": "float", "dampratio": "float"},
- "setto_param_defaults": {},
- }
- mjspec = {
- "setto_functions": {
- "mjs_setToPosition": {
- "params": [
- {"name": "kp", "c_type": "double", "array_dim": None},
- {"name": "kv", "c_type": "double", "array_dim": None},
- {"name": "dampratio", "c_type": "double", "array_dim": None},
- ],
- },
- },
- }
- setto_rules = {"call": "mjs_setToPosition"}
- out = gen._emit_setto_call(
- subtype_key="position",
- setto_rules=setto_rules,
- rules=rules,
- mjspec=mjspec,
- subtype_schema_attrs=["kp", "kv", "dampratio"],
- base_schema_attrs=[],
- )
- assert "mjs_setToPosition(Element" in out
- # Capture the argument list and confirm kp appears before kv before
- # dampratio — exact textual order in the call.
- match = re.search(r"mjs_setToPosition\(Element,(.*?)\);", out, re.DOTALL)
- assert match is not None, out
- args_blob = match.group(1)
- kp_pos = args_blob.find("(double)kp")
- kv_pos = args_blob.find("(double)kv")
- dampratio_pos = args_blob.find("(double)dampratio")
- assert 0 < kp_pos < kv_pos < dampratio_pos, (
- f"setto args out of order: kp@{kp_pos} kv@{kv_pos} "
- f"dampratio@{dampratio_pos}\n{out}"
- )
-
-
-def test_setto_call_respects_signature_order_when_rule_lists_differently():
- """Rule-side ``param_renames`` lookup order MUST NOT influence the
- emitted arg order — the C signature is the source of truth."""
- rules = {
- "default_type": "float",
- "type_mappings": {"PropB": "float", "PropA": "float"},
- "setto_param_defaults": {},
- }
- mjspec = {
- "setto_functions": {
- "mjs_setToFake": {
- "params": [
- {"name": "a", "c_type": "double", "array_dim": None},
- {"name": "b", "c_type": "double", "array_dim": None},
- ],
- },
- },
- }
- # param_renames iteration order intentionally NOT matching signature order.
- setto_rules = {"call": "mjs_setToFake",
- "param_renames": {"b": "PropB", "a": "PropA"}}
- out = gen._emit_setto_call(
- subtype_key="fake",
- setto_rules=setto_rules,
- rules=rules,
- mjspec=mjspec,
- subtype_schema_attrs=["PropA", "PropB"],
- base_schema_attrs=[],
- )
- match = re.search(r"mjs_setToFake\(Element,(.*?)\);", out, re.DOTALL)
- assert match is not None, out
- args_blob = match.group(1)
- a_pos = args_blob.find("PropA")
- b_pos = args_blob.find("PropB")
- assert 0 < a_pos < b_pos, (
- f"renamed setto args out of signature order: A@{a_pos} B@{b_pos}\n{out}"
- )
-
-
-# ---------- override-toggle gate -------------------------------------------
-
-_UPROPERTY_PAIR_RE = re.compile(
- r"bool\s+(bOverride_(\w+))\s*=\s*false;\s*\n+"
- r"\s*UPROPERTY\(.*?\)\)\s*\n"
- r"\s*\S+\s+(\w+)\s*="
-)
-
-
-def test_override_toggle_name_matches_uproperty_for_all_categories(real_rules):
- """For every category whose schema produces a UPROPERTY pair, the
- ``bOverride_X`` toggle and the value property ``X`` must share the
- same final identifier. A drift between them would still compile
- but the InlineEditConditionToggle wiring in the editor would
- silently dead-end."""
- schema_path = os.path.join(_CODEGEN_DIR, "snapshots", "mjcf_schema_snapshot.json")
- if not os.path.exists(schema_path):
- import pytest
- pytest.skip("mjcf_schema.json snapshot not present")
- import json
- with open(schema_path, "r", encoding="utf-8") as f:
- schema = json.load(f)
- saw_pair = False
- for cat_name, cat_rules in real_rules.get("categories", {}).items():
- attrs = gen.schema_attrs(schema, cat_rules.get("schema_common_block", ""))
- if not attrs:
- continue
- out = gen.emit_schema_for_attrs(
- attrs, real_rules,
- element_name=cat_name,
- category_label=cat_name,
- )
- for match in _UPROPERTY_PAIR_RE.finditer(out.properties_h):
- full_toggle, toggle_suffix, value_name = match.groups()
- assert toggle_suffix == value_name, (
- f"category '{cat_name}': UPROPERTY pair drift — toggle "
- f"'{full_toggle}' but value name is '{value_name}'"
- )
- saw_pair = True
- assert saw_pair, "no UPROPERTY pairs found in any category — check broken"
diff --git a/Scripts/codegen/tests/test_camp_b_enum_migration.py b/Scripts/codegen/tests/test_camp_b_enum_migration.py
deleted file mode 100644
index f2d73a16..00000000
--- a/Scripts/codegen/tests/test_camp_b_enum_migration.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks the generated_enums extensions:
-``extra_members`` (URLab-extra members appended after mj-derived ones)
-and the ``disabled`` opt-out (skips emission so a rule can land before
-the corresponding hand-rolled enums are swapped out).
-
-Also asserts that the Camp B rule entries shipped under
-``MjArticulationEnums`` in codegen_rules.json resolve cleanly against
-the current mjspec snapshot — every ``from_mj_enum`` exists and the
-``ue_member_from_mj`` keys all map to real ``mjt*`` constants."""
-
-from __future__ import annotations
-
-import os
-
-import generate_ue_components as gen
-
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-_PLUGIN_ROOT = os.path.dirname(os.path.dirname(_CODEGEN_DIR))
-
-
-# ---------- extra_members --------------------------------------------------
-
-def test_extra_members_append_after_mj_derived_members():
- """URLab-extra members (DcMotor on EMjGainType etc) must follow
- the mj-derived block so existing member ordering doesn't change."""
- rules_def = {
- "public_header": "Generated/MjT.h",
- "enums": [{
- "ue_name": "EMjT",
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {
- "mjT_A": "A",
- "mjT_B": "B",
- },
- "extra_members": [{"name": "DcMotor"}],
- }],
- }
- mjspec = {"enums": {"mjtT": {"mjT_A": 0, "mjT_B": 1}}}
- writes = gen._emit_generated_enum_file(
- "MjArticulationEnums", rules_def, mjspec, "/tmp/public",
- )
- assert len(writes) == 1
- content = writes[0].content
- a_idx = content.index("A = 0")
- b_idx = content.index("B = 1")
- dc_idx = content.index("DcMotor = 2")
- assert a_idx < b_idx < dc_idx
-
-
-def test_extra_member_explicit_value_overrides_auto_increment():
- """``{"name": ..., "value": N}`` pins a specific underlying value
- — needed for enums that mirror mjt* numbering exactly."""
- rules_def = {
- "public_header": "Generated/MjT.h",
- "enums": [{
- "ue_name": "EMjT",
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {},
- "extra_members": [
- {"name": "None", "value": 0},
- {"name": "Plane", "value": 7},
- ],
- }],
- }
- mjspec = {"enums": {"mjtT": {"mjT_DUMMY": 0}}}
- writes = gen._emit_generated_enum_file(
- "MjArticulationEnums", rules_def, mjspec, "/tmp/public",
- )
- assert writes
- content = writes[0].content
- assert "None = 0" in content
- assert "Plane = 7" in content
-
-
-def test_extra_member_without_name_fires_diagnostic():
- rules_def = {
- "public_header": "Generated/MjT.h",
- "enums": [{
- "ue_name": "EMjT",
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {"mjT_A": "A"},
- "extra_members": [{"value": 5}], # missing name
- }],
- }
- mjspec = {"enums": {"mjtT": {"mjT_A": 0}}}
- gen._emit_generated_enum_file(
- "MjArticulationEnums", rules_def, mjspec, "/tmp/public",
- )
- assert any("missing 'name'" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-# ---------- disabled opt-out -----------------------------------------------
-
-def test_disabled_top_level_skips_emission():
- """``disabled: true`` at the rule entry level emits no FileWrite —
- used while staging a migration so a hand-rolled enum isn't
- duplicated by the codegen output."""
- rules_def = {
- "disabled": True,
- "public_header": "Generated/MjT.h",
- "enums": [{
- "ue_name": "EMjT",
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {"mjT_A": "A"},
- }],
- }
- mjspec = {"enums": {"mjtT": {"mjT_A": 0}}}
- writes = gen._emit_generated_enum_file(
- "MjArticulationEnums", rules_def, mjspec, "/tmp/public",
- )
- assert writes == []
-
-
-def test_disabled_per_entry_skips_one_enum_in_a_rule():
- """Per-entry ``disabled: true`` skips just that enum but lets the
- rule's other entries still emit. Granular staging."""
- rules_def = {
- "public_header": "Generated/MjT.h",
- "enums": [
- {
- "ue_name": "EMjEnabled",
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {"mjT_A": "Alpha"},
- },
- {
- "ue_name": "EMjDisabled",
- "disabled": True,
- "from_mj_enum": "mjtT",
- "ue_member_from_mj": {"mjT_A": "Beta"},
- },
- ],
- }
- mjspec = {"enums": {"mjtT": {"mjT_A": 0}}}
- writes = gen._emit_generated_enum_file(
- "MjArticulationEnums", rules_def, mjspec, "/tmp/public",
- )
- assert len(writes) == 1
- content = writes[0].content
- assert "EMjEnabled" in content
- assert "EMjDisabled" not in content
-
-
-# ---------- Camp B rule audit ---------------------------------------------
-
-def test_camp_b_rule_resolves_against_real_mjspec(real_rules, real_mjspec):
- """Every Camp B entry's from_mj_enum must exist in the mjspec
- snapshot, and every ue_member_from_mj key must be a real mjt*
- constant. Catches typos in the migration rule before the actual
- flip lands."""
- camp_b = real_rules.get("generated_enums", {}).get("MjArticulationEnums")
- if not camp_b or not isinstance(camp_b, dict):
- return # rule not present yet
- mj_enums = real_mjspec.get("enums", {})
- for entry in camp_b.get("enums", []):
- # Pure URLab enums (no mjt counterpart) omit from_mj_enum and
- # rely entirely on extra_members. Skip the cross-check for those.
- mj_enum_name = entry.get("from_mj_enum")
- if not mj_enum_name:
- continue
- assert mj_enum_name in mj_enums, (
- f"Camp B '{entry['ue_name']}' -> from_mj_enum "
- f"'{mj_enum_name}' not in mjspec.enums"
- )
- members = mj_enums[mj_enum_name]
- for mj_const in entry.get("ue_member_from_mj", {}):
- assert mj_const in members, (
- f"Camp B '{entry['ue_name']}' ue_member_from_mj key "
- f"'{mj_const}' is not in mjtEnum '{mj_enum_name}'"
- )
-
-
-def test_camp_b_rule_post_flip_state(real_rules):
- """After the flip, the rule no longer carries ``disabled: true``
- and the hand-rolled UENUM decls under
- ``Source/URLab/Public/MuJoCo/Components/`` have been replaced
- with includes of the generated header."""
- camp_b = real_rules.get("generated_enums", {}).get("MjArticulationEnums")
- if not camp_b or not isinstance(camp_b, dict):
- return
- assert not camp_b.get("disabled"), (
- "MjArticulationEnums should be enabled after the Camp B flip."
- )
-
-
-# On-disk presence is covered by test_regen_no_diff.py::test_codegen_check_clean.
diff --git a/Scripts/codegen/tests/test_canon_emitter_bodies.py b/Scripts/codegen/tests/test_canon_emitter_bodies.py
deleted file mode 100644
index 13b81706..00000000
--- a/Scripts/codegen/tests/test_canon_emitter_bodies.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Behavioural lock-ins for the canon emitter bodies that previously
-only had registry-presence coverage. ``actuator_transmission`` and
-``fromto_decompose`` are inline (no rule-side helper string); their
-emitted C++ is hand-crafted, so any rename or signature change there
-should surface in pytest rather than at UE compile."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-# ---------- actuator_transmission ---------------------------------------
-
-def test_actuator_transmission_import_reads_every_target_attr():
- """The import block reads joint/jointinparent/tendon/site/body and
- the slidersite/refsite siblings. A missing branch means a rule
- author can't author that transmission type via XML."""
- out = gen._canon_import_actuator_transmission(canon_def={}, element_name="actuator")
- for attr in ("joint", "jointinparent", "tendon", "site", "body",
- "slidersite", "refsite"):
- assert f'TEXT("{attr}")' in out, f"import missing TEXT(\"{attr}\")"
- # Each path resolves to an EMjActuatorTrnType.
- for trn in ("Joint", "JointInParent", "Tendon", "Site", "Body",
- "SliderCrank"):
- assert f"EMjActuatorTrnType::{trn}" in out, trn
-
-
-def test_actuator_transmission_export_emits_switch_with_undefined_default():
- out = gen._canon_export_actuator_transmission(canon_def={})
- # Every case writes Element->trntype.
- for trn, mj_const in [
- ("Joint", "mjTRN_JOINT"),
- ("JointInParent", "mjTRN_JOINTINPARENT"),
- ("Tendon", "mjTRN_TENDON"),
- ("Site", "mjTRN_SITE"),
- ("Body", "mjTRN_BODY"),
- ("SliderCrank", "mjTRN_SLIDERCRANK"),
- ]:
- assert f"EMjActuatorTrnType::{trn}" in out, trn
- assert mj_const in out, mj_const
- assert "default:" in out and "mjTRN_UNDEFINED" in out
- # slidersite / refsite only written when their type is set.
- assert "SliderCrank && !SliderSite.IsEmpty()" in out
- assert "Site && !RefSite.IsEmpty()" in out
-
-
-# ---------- fromto_decompose --------------------------------------------
-
-def test_fromto_decompose_import_uses_helper_and_writes_pos_quat_size():
- canon_def = {
- "import_helper": "MjUtils::DecomposeFromTo",
- "category_specifics": {"geom": {
- "z_slot_check": "(Type == EMjGeomType::Box || Type == EMjGeomType::Ellipsoid)"
- }},
- }
- out = gen._canon_import_fromto_decompose(canon_def, element_name="geom")
- assert "MjUtils::DecomposeFromTo(Node, FTPos, FTQuat, FTHalf)" in out
- # Writes Pos / Quat with their override toggles.
- assert "Pos = FTPos;" in out and "bOverride_Pos = true;" in out
- assert "Quat = FTQuat;" in out and "bOverride_Quat = true;" in out
- # Uses the category-specific z_slot_check inline.
- assert "EMjGeomType::Box" in out and "EMjGeomType::Ellipsoid" in out
- # Grows the size array to accommodate the slot.
- assert "while (size.Num() <= FTSlot)" in out
-
-
-def test_fromto_decompose_import_falls_back_to_y_slot_for_capsule():
- canon_def = {
- "import_helper": "MjUtils::DecomposeFromTo",
- "category_specifics": {"site": {
- "z_slot_check": "(Type == EMjSiteType::Box || Type == EMjSiteType::Ellipsoid)"
- }},
- }
- out = gen._canon_import_fromto_decompose(canon_def, element_name="site")
- # The z_slot_check is element-specific; site uses EMjSiteType, not Geom.
- assert "EMjSiteType::Box" in out
- assert "EMjGeomType" not in out
- # Without a matching category_specifics entry, the slot would be `false` (Y slot).
- out_other = gen._canon_import_fromto_decompose(
- {"import_helper": "MjUtils::DecomposeFromTo"},
- element_name="unknown",
- )
- assert "bFTZSlot = false" in out_other
-
-
-def test_fromto_decompose_export_is_empty():
- """The export path is a no-op: ``fromto`` decomposes to Pos/Quat/Size
- on import; those properties carry the values through to export via
- their own canonicalisations."""
- assert gen._canon_export_fromto_decompose(canon_def={}) == ""
diff --git a/Scripts/codegen/tests/test_canon_registry.py b/Scripts/codegen/tests/test_canon_registry.py
deleted file mode 100644
index f0081887..00000000
--- a/Scripts/codegen/tests/test_canon_registry.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the canonicalisation registry.
-
-The registry collapses the previous duplicated if-chains in
-``_canon_import_block`` / ``_canon_export_block`` into one dict.
-Adding a new canon means adding one ``Canonicalisation`` entry; an
-unknown canon name in the JSON rules still fires the same loud
-diagnostic instead of silently dropping its emission."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_registry_covers_every_canonicalisation_in_rules_json(real_rules):
- """Every canonicalisation declared in codegen_rules.json must have
- a registry entry. Mismatch fires the silent-drop diagnostic at
- runtime — catch it here at test time instead."""
- declared = set(real_rules.get("canonicalizations", {}).keys())
- registered = set(gen._CANONICALISATIONS.keys())
- missing = declared - registered
- assert not missing, (
- f"canonicalizations declared in rules JSON but not in the "
- f"registry: {sorted(missing)}"
- )
-
-
-def test_unknown_canon_fires_import_diagnostic():
- out = gen._canon_import_block("nonexistent_canon", {}, element_name="geom")
- assert out == ""
- assert any("nonexistent_canon" in d.message and "import" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_unknown_canon_fires_export_diagnostic():
- out = gen._canon_export_block("nonexistent_canon", {})
- assert out == ""
- assert any("nonexistent_canon" in d.message and "export" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_spatial_pose_import_is_one_liner_helper_call():
- """Locks the trivial-shape canonicalisation so a regression in the
- registry dispatch shows up directly."""
- canon_def = {
- "import_helper": "MjUtils::ReadVec3InMeters",
- "emits_property": {"name": "Pos", "type": "FVector"},
- }
- out = gen._canon_import_block("spatial_pose", canon_def, "")
- assert out.strip() == (
- 'MjUtils::ReadVec3InMeters(Node, TEXT("pos"), Pos, bOverride_Pos);'
- )
-
-
-def test_canonicalisation_class_is_frozen():
- """Registry entries must be frozen so a phase can't accidentally
- swap an emitter at runtime."""
- entry = next(iter(gen._CANONICALISATIONS.values()))
- import dataclasses
- assert dataclasses.is_dataclass(entry)
- # FrozenInstanceError on attempted assignment.
- import pytest
- with pytest.raises(dataclasses.FrozenInstanceError):
- entry.name = "mutated" # type: ignore[misc]
diff --git a/Scripts/codegen/tests/test_canonicalization.py b/Scripts/codegen/tests/test_canonicalization.py
deleted file mode 100644
index 2fe93e21..00000000
--- a/Scripts/codegen/tests/test_canonicalization.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Canonicalisation (orientation + position) emission tests."""
-
-from __future__ import annotations
-
-from generate_ue_components import emit_schema_for_attrs
-
-
-def test_orientation_absorbs_all_attrs(minimal_rules):
- """Every orientation sibling (euler / axisangle / xyaxes / zaxis)
- is absorbed into the canonical Quat UPROPERTY — none should leak
- out as a standalone property."""
- attrs = ["quat", "euler", "axisangle", "xyaxes", "zaxis", "size"]
- out = emit_schema_for_attrs(attrs, minimal_rules, "geom", "Geom")
- assert "FQuat Quat" in out.properties_h
- assert "bOverride_Quat" in out.properties_h
- assert "FQuat Euler" not in out.properties_h
- assert "AxisAngle " not in out.properties_h
- assert "Xyaxes " not in out.properties_h
-
-
-def test_orientation_roundtrips_through_canon_helpers(minimal_rules):
- """A single ``quat`` schema attr drives both arms of the canon — the
- import pulls through ``MjOrientationUtils::OrientationToMjQuat`` +
- ``MjToUERotation``, and the export pushes through
- ``UEToMjRotation``."""
- out = emit_schema_for_attrs(["quat"], minimal_rules, "geom", "Geom")
- # Import arm.
- assert "MjOrientationUtils::OrientationToMjQuat(Node, CompilerSettings, TmpQuat)" in out.imports_cpp
- assert "Quat = MjUtils::MjToUERotation(TmpQuat)" in out.imports_cpp
- assert "bOverride_Quat = true" in out.imports_cpp
- # Export arm.
- assert "MjUtils::UEToMjRotation(Quat, TmpQuat)" in out.exports_cpp
- assert "Element->quat[0] = TmpQuat[0]" in out.exports_cpp
- assert "Element->quat[3] = TmpQuat[3]" in out.exports_cpp
-
-
-def test_position_absorbs_pos(minimal_rules):
- out = emit_schema_for_attrs(["pos", "stiffness"], minimal_rules, "geom", "Geom")
- # Canonical Pos is emitted; raw pos attr is not.
- assert "FVector Pos" in out.properties_h
- # The non-canonical attr survives.
- assert "stiffness" in out.properties_h
- # Import + export route through the helpers.
- assert "MjUtils::ReadVec3InMeters(Node, TEXT(\"pos\"), Pos, bOverride_Pos)" in out.imports_cpp
- assert "MjUtils::UEToMjPosition(Pos, TmpPos)" in out.exports_cpp
- assert "Element->pos[0] = TmpPos[0]" in out.exports_cpp
-
-
-def test_no_canonicalization_when_element_opts_out(minimal_rules):
- # 'joint' has no applies_canonicalizations in minimal_rules — make sure
- # nothing canonical leaks in.
- out = emit_schema_for_attrs(["pos", "axis", "stiffness"], minimal_rules, "joint", "Joint")
- assert "FQuat Quat" not in out.properties_h
- assert "FVector Pos" not in out.properties_h
diff --git a/Scripts/codegen/tests/test_coverage_checks.py b/Scripts/codegen/tests/test_coverage_checks.py
deleted file mode 100644
index 099f7e04..00000000
--- a/Scripts/codegen/tests/test_coverage_checks.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Behavioural coverage tests for the six drift checks that previously
-had no direct test — every check now has a "should fire" path and a
-"should be quiet" path. Each check fires through ``_diag_add`` with a
-specific ``source=`` tag so assertions can target the message bucket
-without depending on prose."""
-
-from __future__ import annotations
-
-import _codegen_checks as checks
-import generate_ue_components as gen
-
-
-def _pending_sources() -> list:
- return [d.source for d in gen._DIAGS_BUFFER.pending]
-
-
-def _reset() -> None:
- gen._reset_diags()
-
-
-# ---------- _check_top_level_elements_coverage --------------------------
-
-def test_top_level_elements_coverage_fires_for_unmodeled_element():
- _reset()
- schema = {"new_widget": {}, "joint": {}}
- rules = {
- "categories": {"joint": {"schema_common_block": "joint"}},
- "intentionally_unmodeled_elements": {},
- }
- checks._check_top_level_elements_coverage(schema, rules)
- assert any("new_widget" in d.message and d.source == "top_level_coverage"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_top_level_elements_coverage_quiet_for_documented_element():
- _reset()
- schema = {"asset": {}, "joint": {}}
- rules = {
- "categories": {"joint": {"schema_common_block": "joint"}},
- "intentionally_unmodeled_elements": {},
- }
- # 'asset' is in the container_keys allowlist.
- checks._check_top_level_elements_coverage(schema, rules)
- assert "top_level_coverage" not in _pending_sources()
-
-
-# ---------- _check_actuator_subtypes_coverage --------------------------
-
-def test_actuator_subtypes_coverage_fires_for_unmodeled_subtype():
- _reset()
- schema = {"actuator_types": {"newkind": []}}
- rules = {"categories": {"actuator": {
- "subtypes": [{"key": "motor"}, {"key": "position"}],
- }}}
- checks._check_actuator_subtypes_coverage(schema, rules)
- assert any("newkind" in d.message and d.source == "actuator_subtypes_coverage"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_actuator_subtypes_coverage_quiet_when_all_modeled():
- _reset()
- schema = {"actuator_types": {"motor": []}}
- rules = {"categories": {"actuator": {
- "subtypes": [{"key": "motor"}],
- }}}
- checks._check_actuator_subtypes_coverage(schema, rules)
- assert "actuator_subtypes_coverage" not in _pending_sources()
-
-
-# ---------- _check_sensor_subtypes_coverage ----------------------------
-
-def test_sensor_subtypes_coverage_fires_for_unmodeled_subtype():
- _reset()
- schema = {"sensor_types": ["touch", "newsensor"]}
- rules = {"categories": {"sensor": {
- "subtypes": [{"key": "touch"}],
- }}}
- checks._check_sensor_subtypes_coverage(schema, rules)
- assert any("newsensor" in d.message and d.source == "sensor_subtypes_coverage"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_sensor_subtypes_coverage_quiet_when_all_modeled():
- _reset()
- schema = {"sensor_types": ["touch"]}
- rules = {"categories": {"sensor": {
- "subtypes": [{"key": "touch"}],
- }}}
- checks._check_sensor_subtypes_coverage(schema, rules)
- assert "sensor_subtypes_coverage" not in _pending_sources()
-
-
-# ---------- _check_setto_param_coverage --------------------------------
-
-def test_setto_param_coverage_fires_for_unmapped_param():
- _reset()
- schema = {"actuator_common": {"attrs": ["kp"]}, "actuator_types": {"position": ["kv"]}}
- rules = {
- "categories": {"actuator": {
- "schema_common_block": "actuator_common",
- "subtype_setto": {"position": {"call": "mjs_setToPosition"}},
- }},
- "setto_param_defaults": {},
- }
- mjspec = {"setto_functions": {"mjs_setToPosition": {
- "params": [
- {"name": "kp", "c_type": "double", "array_dim": None},
- {"name": "kv", "c_type": "double", "array_dim": None},
- {"name": "noveltie", "c_type": "double", "array_dim": None},
- ],
- }}}
- checks._check_setto_param_coverage(schema, rules, mjspec)
- assert any("noveltie" in d.message and d.source == "setto_param_coverage"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_setto_param_coverage_quiet_when_all_mapped():
- _reset()
- schema = {"actuator_common": {"attrs": ["kp"]}, "actuator_types": {"position": ["kv"]}}
- rules = {
- "categories": {"actuator": {
- "schema_common_block": "actuator_common",
- "subtype_setto": {"position": {"call": "mjs_setToPosition"}},
- }},
- "setto_param_defaults": {"mjs_setToPosition": {"inheritrange": "0.0"}},
- }
- mjspec = {"setto_functions": {"mjs_setToPosition": {
- "params": [
- {"name": "kp", "c_type": "double", "array_dim": None},
- {"name": "kv", "c_type": "double", "array_dim": None},
- {"name": "inheritrange", "c_type": "double", "array_dim": None},
- ],
- }}}
- checks._check_setto_param_coverage(schema, rules, mjspec)
- assert "setto_param_coverage" not in _pending_sources()
-
-
-# ---------- _check_mjs_struct_field_drift ------------------------------
-
-def test_mjs_struct_field_drift_fires_for_uncovered_field():
- _reset()
- schema = {"joint_common": ["stiffness"]}
- rules = {
- "categories": {"joint": {
- "schema_common_block": "joint_common",
- "mjs_struct": "mjsJoint",
- }},
- "intentionally_unmodeled_mjs_fields": {},
- }
- mjspec = {"structs": {"mjsJoint": ["stiffness", "mystery_field"]}}
- checks._check_mjs_struct_field_drift(schema, rules, mjspec)
- assert any("mystery_field" in d.message and d.source == "mjs_field_drift"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_mjs_struct_field_drift_quiet_when_all_modeled():
- _reset()
- schema = {"joint_common": ["stiffness"]}
- rules = {
- "categories": {"joint": {
- "schema_common_block": "joint_common",
- "mjs_struct": "mjsJoint",
- }},
- "intentionally_unmodeled_mjs_fields": {},
- }
- mjspec = {"structs": {"mjsJoint": ["stiffness", "name"]}} # 'name' is structural
- checks._check_mjs_struct_field_drift(schema, rules, mjspec)
- assert "mjs_field_drift" not in _pending_sources()
-
-
-# ---------- _check_generated_enum_coverage -----------------------------
-
-def test_generated_enum_coverage_fires_for_unmapped_member():
- _reset()
- rules = {"generated_enums": {"MjOptionEnums": {
- "enums": [{
- "ue_name": "EMjIntegrator",
- "from_mj_enum": "mjtIntegrator",
- "ue_member_from_mj": {"mjINT_EULER": "Euler"},
- # mjINT_RK4 missing from the rule -> should diag.
- }],
- }}}
- mjspec = {"enums": {"mjtIntegrator": {"mjINT_EULER": 0, "mjINT_RK4": 1}}}
- checks._check_generated_enum_coverage(rules, mjspec)
- assert any("mjINT_RK4" in d.message and d.source == "enum_drift"
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_generated_enum_coverage_quiet_when_all_mapped():
- _reset()
- rules = {"generated_enums": {"MjOptionEnums": {
- "enums": [{
- "ue_name": "EMjIntegrator",
- "from_mj_enum": "mjtIntegrator",
- "ue_member_from_mj": {"mjINT_EULER": "Euler", "mjINT_RK4": "RK4"},
- }],
- }}}
- mjspec = {"enums": {"mjtIntegrator": {"mjINT_EULER": 0, "mjINT_RK4": 1}}}
- checks._check_generated_enum_coverage(rules, mjspec)
- assert "enum_drift" not in _pending_sources()
-
-
-def test_generated_enum_coverage_fires_when_from_mj_enum_unknown():
- """Snapshot drift: a from_mj_enum that's not in the projected
- mjspec must produce a diagnostic instead of a silent skip."""
- _reset()
- rules = {"generated_enums": {"MjOptionEnums": {
- "enums": [{
- "ue_name": "EMjGone",
- "from_mj_enum": "mjtGoneRenamed",
- "ue_member_from_mj": {"mjGONE_X": "X"},
- }],
- }}}
- mjspec = {"enums": {"mjtIntegrator": {"mjINT_EULER": 0}}}
- checks._check_generated_enum_coverage(rules, mjspec)
- assert any("mjtGoneRenamed" in d.message and d.source == "enum_drift"
- for d in gen._DIAGS_BUFFER.pending)
diff --git a/Scripts/codegen/tests/test_data_packed_export.py b/Scripts/codegen/tests/test_data_packed_export.py
deleted file mode 100644
index b9a06a01..00000000
--- a/Scripts/codegen/tests/test_data_packed_export.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for mjs_data_packed_attrs emission, including the per-element
-``export_op`` unit-conversion path used by mjsEquality.anchor (cm -> m
-before packing into data[0..2])."""
-
-from __future__ import annotations
-
-import pytest
-
-from generate_ue_components import _emit_data_packed_export
-
-
-def test_slot_scalar_no_conversion():
- """Single-slot pack without export_op writes raw scalar."""
- cpp = _emit_data_packed_export(
- attr="torquescale",
- packed_def={
- "slot": 10,
- "condition": "EqualityType == EMjEqualityType::Weld",
- },
- ue_type="float",
- prop_name="torquescale",
- )
- assert "Element->data[10] = (mjtNum)torquescale" in cpp
- assert "bOverride_torquescale" in cpp
- assert "EqualityType == EMjEqualityType::Weld" in cpp
- # No temp var needed when no conversion
- assert "float V" not in cpp
-
-
-def test_slot_range_no_conversion():
- """Slot-range pack without export_op writes raw array elements."""
- cpp = _emit_data_packed_export(
- attr="polycoef",
- packed_def={
- "slot_range": [0, 5],
- "condition": "(EqualityType == EMjEqualityType::Joint) || (EqualityType == EMjEqualityType::Tendon)",
- },
- ue_type="TArray",
- prop_name="polycoef",
- )
- assert "Element->data[0 + i] = (mjtNum)polycoef[i]" in cpp
- assert "i < polycoef.Num() && i < 5" in cpp
- # No temp var needed when no conversion
- assert "float V" not in cpp
-
-
-def test_slot_range_with_cm_to_m():
- """anchor pattern: cm -> m per-element conversion before packing."""
- cpp = _emit_data_packed_export(
- attr="anchor",
- packed_def={
- "slot_range": [0, 3],
- "condition": "(EqualityType == EMjEqualityType::Connect) || (EqualityType == EMjEqualityType::Weld)",
- "export_op": "cm_to_m",
- },
- ue_type="TArray",
- prop_name="anchor",
- )
- # Temp var used to apply conversion before write
- assert "float V = anchor[i]" in cpp
- assert "V *= 0.01f" in cpp
- assert "Element->data[0 + i] = (mjtNum)V" in cpp
- assert "i < anchor.Num() && i < 3" in cpp
-
-
-def test_slot_scalar_with_m_to_cm():
- """Scalar slot with export_op — symmetric to the range case."""
- cpp = _emit_data_packed_export(
- attr="z_offset_cm",
- packed_def={
- "slot": 4,
- "export_op": "m_to_cm",
- },
- ue_type="float",
- prop_name="z_offset_cm",
- )
- assert "float V = (float)z_offset_cm" in cpp
- assert "V *= 100.0f" in cpp
- assert "Element->data[4] = (mjtNum)V" in cpp
-
-
-def test_unknown_export_op_raises():
- with pytest.raises(RuntimeError, match="unknown export_op"):
- _emit_data_packed_export(
- attr="x",
- packed_def={"slot": 0, "export_op": "lightyears_to_furlongs"},
- ue_type="float",
- prop_name="x",
- )
-
-
-def test_missing_slot_and_slot_range_raises():
- with pytest.raises(RuntimeError, match="must specify either"):
- _emit_data_packed_export(
- attr="x",
- packed_def={"condition": "true"},
- ue_type="float",
- prop_name="x",
- )
-
-
-def test_slot_range_requires_tarray():
- """slot_range path needs a TArray UPROPERTY — fail loudly on scalar."""
- with pytest.raises(RuntimeError, match="slot_range requires UE TArray"):
- _emit_data_packed_export(
- attr="x",
- packed_def={"slot_range": [0, 3]},
- ue_type="float",
- prop_name="x",
- )
diff --git a/Scripts/codegen/tests/test_dry_run.py b/Scripts/codegen/tests/test_dry_run.py
deleted file mode 100644
index 8a05fcba..00000000
--- a/Scripts/codegen/tests/test_dry_run.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""End-to-end dry-run test: generator runs against the real schema +
-mjxmacro snapshots and produces a deterministic set of writes."""
-
-from __future__ import annotations
-
-import json
-import os
-import sys
-
-import pytest
-
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_PLUGIN_ROOT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
-
-
-def test_collect_all_writes_includes_expected_categories(real_schema, real_rules, real_mjxmacro, real_mjspec):
- from generate_ue_components import collect_all_writes
- # The plugin's actual Public/Private roots (read-only — we don't write).
- plugin_root = _PLUGIN_ROOT
- public_root = os.path.join(plugin_root, "Source", "URLab", "Public")
- private_root = os.path.join(plugin_root, "Source", "URLab", "Private")
- bind_h = os.path.join(public_root, "MuJoCo", "Utils", "MjBind.h")
- writes = collect_all_writes(real_schema, real_rules, real_mjxmacro,
- public_root, private_root, bind_h,
- mjspec=real_mjspec)
- # We always emit the test-schema header.
- paths = [w.path for w in writes]
- assert any(p.endswith("MjSchemaForTests.h") for p in paths)
- # 49 sensor subtypes × (.h + .cpp) = 98 subclass writes; plus the
- # base files (MjSensor.h/.cpp + MjCamera.h/.cpp, post-migration).
- sensor_subclass_writes = [
- p for p in paths
- if "Components" in p and "Sensors" in p
- and (p.endswith(".h") or p.endswith(".cpp"))
- and "MjSensor" not in os.path.basename(p)
- and "MjCamera" not in os.path.basename(p)
- ]
- assert len(sensor_subclass_writes) == 98, (
- f"expected 98 sensor subclass file writes, got {len(sensor_subclass_writes)}"
- )
-
-
-def test_generator_is_deterministic(real_schema, real_rules, real_mjxmacro, real_mjspec):
- """Same inputs -> same outputs."""
- from generate_ue_components import collect_all_writes
- plugin_root = _PLUGIN_ROOT
- public_root = os.path.join(plugin_root, "Source", "URLab", "Public")
- private_root = os.path.join(plugin_root, "Source", "URLab", "Private")
- bind_h = os.path.join(public_root, "MuJoCo", "Utils", "MjBind.h")
- a = collect_all_writes(real_schema, real_rules, real_mjxmacro,
- public_root, private_root, bind_h, mjspec=real_mjspec)
- b = collect_all_writes(real_schema, real_rules, real_mjxmacro,
- public_root, private_root, bind_h, mjspec=real_mjspec)
- a_map = {w.path: w.content for w in a}
- b_map = {w.path: w.content for w in b}
- assert a_map == b_map
diff --git a/Scripts/codegen/tests/test_emit_enum_switch.py b/Scripts/codegen/tests/test_emit_enum_switch.py
deleted file mode 100644
index 34da5276..00000000
--- a/Scripts/codegen/tests/test_emit_enum_switch.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the ``emit_enum_switch`` codegen helper.
-
-The helper backs three sites: xml_enum exports (single-line cases +
-``default: break;``), objtype dispatch (multi-key groups + multi-line
-default), and geom FinalType resolution (single-line cases, no
-default). Each shape is locked here so a future tweak to the helper
-can't silently break byte-identity on the emitted .cpp."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_single_line_case_shape_matches_xml_enum_export():
- """Single ``str`` member → one-line ``case Enum::M: ; break;``
- — the shape every xml_enum_export emits."""
- out = gen.emit_enum_switch(
- "JointType", "EMjJointType",
- [
- ("Hinge", "Element->type = (mjtJoint)mjJNT_HINGE"),
- ("Slide", "Element->type = (mjtJoint)mjJNT_SLIDE"),
- ],
- indent=" ",
- default_break=True,
- )
- expected = (
- " switch (JointType)\n"
- " {\n"
- " case EMjJointType::Hinge: Element->type = (mjtJoint)mjJNT_HINGE; break;\n"
- " case EMjJointType::Slide: Element->type = (mjtJoint)mjJNT_SLIDE; break;\n"
- " default: break;\n"
- " }\n"
- )
- assert out == expected
-
-
-def test_multi_key_group_stacks_labels_with_multiline_body():
- """A list-of-strings member stacks case labels and emits body +
- break on indented separate lines — the shape objtype_dispatch
- needs for ``case Body:`` / ``case XBody:`` collapsing to one expr."""
- out = gen.emit_enum_switch(
- "ObjType", "EMjObjType",
- [
- (["Body", "XBody"], "Target = mjOBJ_BODY"),
- ("Geom", "Target = mjOBJ_GEOM"),
- ],
- indent=" ",
- default_body="Target = mjOBJ_UNKNOWN",
- )
- expected = (
- " switch (ObjType)\n"
- " {\n"
- " case EMjObjType::Body:\n"
- " case EMjObjType::XBody:\n"
- " Target = mjOBJ_BODY;\n"
- " break;\n"
- " case EMjObjType::Geom: Target = mjOBJ_GEOM; break;\n"
- " default:\n"
- " Target = mjOBJ_UNKNOWN;\n"
- " break;\n"
- " }\n"
- )
- assert out == expected
-
-
-def test_no_default_when_neither_flag_set():
- """geom_final_type emits no default branch — the helper must
- omit it cleanly."""
- out = gen.emit_enum_switch(
- "Type", "EMjGeomType",
- [("Sphere", "FinalType = mjGEOM_SPHERE")],
- indent=" ",
- )
- expected = (
- " switch (Type)\n"
- " {\n"
- " case EMjGeomType::Sphere: FinalType = mjGEOM_SPHERE; break;\n"
- " }\n"
- )
- assert out == expected
-
-
-def test_default_body_takes_priority_over_default_break():
- """When both are set, the multi-line default wins. Keeps caller
- intent obvious — ``default_break`` is the simple short-form."""
- out = gen.emit_enum_switch(
- "X", "EMjX",
- [("A", "y = 1")],
- default_break=True,
- default_body="y = 0",
- )
- assert "default:\n" in out
- assert "default: break;" not in out
-
-
-def test_indent_propagates_to_case_labels_and_body():
- """Case labels sit at ``indent + 4 spaces``; multi-line case bodies
- at ``indent + 8 spaces``. The lock prevents indentation drift."""
- out = gen.emit_enum_switch(
- "X", "EMjX",
- [(["A", "B"], "z = 1")],
- indent=" ", # 12 spaces
- )
- # switch line at 12 spaces.
- assert out.startswith(" switch (X)\n")
- # case labels at 12 + 4 = 16 spaces.
- assert " case EMjX::A:\n" in out
- # body at 12 + 8 = 20 spaces.
- assert " z = 1;\n" in out
diff --git a/Scripts/codegen/tests/test_emit_property.py b/Scripts/codegen/tests/test_emit_property.py
deleted file mode 100644
index 3b66f3dd..00000000
--- a/Scripts/codegen/tests/test_emit_property.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Per-property emission shape tests."""
-
-from __future__ import annotations
-
-import pytest
-
-from generate_ue_components import (
- EmittedSchema,
- emit_schema_for_attrs,
-)
-
-
-# override_toggle_name is exercised everywhere emit_schema_for_attrs runs;
-# the cross-category guarantee is pinned in
-# test_behavioral_emit_guarantees::test_override_toggle_name_matches_uproperty_for_all_categories.
-
-
-def test_emit_basic_property(minimal_rules):
- out = emit_schema_for_attrs(["stiffness"], minimal_rules, "joint", "Joint")
- assert "float stiffness" in out.properties_h
- assert "bOverride_stiffness" in out.properties_h
- assert "= 0.0f;" in out.properties_h
- assert "MjXmlUtils::ReadAttrFloat" in out.imports_cpp
- assert 'TEXT("stiffness")' in out.imports_cpp
- assert "Element->stiffness" in out.exports_cpp
-
-
-def test_emit_typed_property_range(minimal_rules):
- out = emit_schema_for_attrs(["range"], minimal_rules, "joint", "Joint")
- assert "TArray range" in out.properties_h
- assert "MjXmlUtils::ReadAttrFloatArray" in out.imports_cpp
- assert "Element->range[i]" in out.exports_cpp
-
-
-def test_emit_bool_property(minimal_rules):
- out = emit_schema_for_attrs(["limited"], minimal_rules, "joint", "Joint")
- assert "bool limited" in out.properties_h
- assert "MjXmlUtils::ReadAttrBool" in out.imports_cpp
- assert "Element->limited = limited ? 1 : 0;" in out.exports_cpp
-
-
-def test_emit_vector_property(minimal_rules):
- out = emit_schema_for_attrs(["axis"], minimal_rules, "joint", "Joint")
- # 'axis' is in joint excludes; should not appear.
- assert "FVector axis" not in out.properties_h
- rules2 = {**minimal_rules,
- "element_rules": {"joint": {"exclude_attrs": []}}}
- out2 = emit_schema_for_attrs(["axis"], rules2, "joint", "Joint")
- assert "FVector axis" in out2.properties_h
- assert "MjXmlUtils::ReadAttrVec3" in out2.imports_cpp
-
-
-def test_global_exclude_skipped(minimal_rules):
- out = emit_schema_for_attrs(["user", "stiffness"], minimal_rules, "joint", "Joint")
- assert "stiffness" in out.properties_h
- assert " user " not in out.properties_h
-
-
-def test_element_exclude_skipped(minimal_rules):
- out = emit_schema_for_attrs(["pos", "axis", "stiffness"], minimal_rules, "joint", "Joint")
- assert "stiffness" in out.properties_h
- assert "FVector pos" not in out.properties_h
- assert "FVector axis" not in out.properties_h
-
-
-def test_no_b_prefix_on_bool(minimal_rules):
- """`limited` emits as `bool limited`, not `bool bLimited`."""
- out = emit_schema_for_attrs(["limited"], minimal_rules, "joint", "Joint")
- assert "bool limited" in out.properties_h
- assert "bOverride_limited" in out.properties_h
- assert "bLimited" not in out.properties_h
diff --git a/Scripts/codegen/tests/test_emitter_capabilities.py b/Scripts/codegen/tests/test_emitter_capabilities.py
deleted file mode 100644
index 24d85153..00000000
--- a/Scripts/codegen/tests/test_emitter_capabilities.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Tests for opt-in emitter capabilities in generate_ue_components.py:
-
-1. ``_resolve_value_map``: returns the rule's literal ``value_map``;
- missing ``value_map`` raises.
-2. ``xml_enum_attrs.emit_property_decl: true``: codegen emits the UE
- enum UPROPERTY decl into the schema PROPERTIES block.
-
-Each test uses synthetic rules to exercise its capability in isolation.
-"""
-
-from __future__ import annotations
-
-import os
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-
-import pytest # noqa: E402
-
-from generate_ue_components import ( # noqa: E402
- _resolve_value_map,
- _emit_xml_enum_import,
- emit_schema_for_attrs,
-)
-
-
-# ----- value_map resolver ----------------------------------------------
-
-def test_value_map_returned_verbatim():
- """The resolver returns the rule's literal ``value_map`` unchanged."""
- enum_def = {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "value_map": {"hinge": ["Hinge", "mjJNT_HINGE"]},
- }
- resolved = _resolve_value_map("type", enum_def)
- assert resolved == {"hinge": ["Hinge", "mjJNT_HINGE"]}
-
-
-def test_value_map_resolver_errors_when_missing():
- enum_def = {"ue_property": "X", "ue_enum_type": "E"}
- with pytest.raises(RuntimeError, match="missing value_map"):
- _resolve_value_map("attr", enum_def)
-
-
-def test_xml_enum_import_emits_expected_blocks():
- enum_def = {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "value_map": {"hinge": ["Hinge", "mjJNT_HINGE"], "slide": ["Slide", "mjJNT_SLIDE"]},
- }
- out = _emit_xml_enum_import("type", enum_def)
- assert "Type = EMjJointType::Hinge" in out
- assert "Type = EMjJointType::Slide" in out
- assert "bOverride_Type = true" in out
-
-
-# ----- emit_property_decl opt-in ---------------------------------------
-
-def test_emit_property_decl_off_skips_uproperty():
- """Default behaviour: xml_enum_attrs entries do NOT emit the UE
- UPROPERTY decl (the .h hand-declares it)."""
- rules = {
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "value_map": {"hinge": ["Hinge", "mjJNT_HINGE"]},
- }
- }
- }
- }
- }
- out = emit_schema_for_attrs([], rules, element_name="joint", category_label="Joint")
- assert "EMjJointType" not in out.properties_h
-
-
-def test_emit_property_decl_on_emits_uproperty_pair():
- """With opt-in, codegen emits both the override toggle and the
- EMjX UPROPERTY using the standard _emit_uproperty shape."""
- rules = {
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum_type": "EMjJointType",
- "emit_property_decl": True,
- "value_map": {"hinge": ["Hinge", "mjJNT_HINGE"]},
- }
- }
- }
- }
- }
- out = emit_schema_for_attrs([], rules, element_name="joint", category_label="Joint")
- assert "EMjJointType Type" in out.properties_h
- assert "bOverride_Type" in out.properties_h
-
-
diff --git a/Scripts/codegen/tests/test_enum_scrape.py b/Scripts/codegen/tests/test_enum_scrape.py
deleted file mode 100644
index c4055014..00000000
--- a/Scripts/codegen/tests/test_enum_scrape.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the mjt* enum surface the codegen consumes.
-
-mjt* enums come from the clang-AST introspect snapshot — libclang
-gives us the real member values and handles every ``typedef enum
-mjtX_ { ... } mjtX;`` shape uniformly. The shipped snapshot has to
-carry every enum the codegen rules reference; the cross-check below
-is the guard."""
-
-from __future__ import annotations
-
-import json
-import os
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-
-
-def _load_projected_mjspec():
- """Load introspect + project into the legacy mjspec shape via the
- same helper the runtime uses. Mirrors the conftest fixture."""
- import generate_ue_components as gen
- plugin_root = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
- snap_path = os.path.join(
- plugin_root, "Scripts", "codegen", "snapshots",
- "introspect_snapshot.json",
- )
- with open(snap_path, "r", encoding="utf-8") as f:
- introspect = json.load(f)
- return gen._mjspec_from_introspect(introspect)
-
-
-def test_real_snapshot_has_expected_enums():
- """Introspect must carry every mjt* enum the codegen rules drift
- checks rely on (the cross-walk between value_map entries and the
- enum members the snapshot reports for that mjt* type)."""
- mjspec = _load_projected_mjspec()
- enums = mjspec.get("enums", {})
- for expected in (
- "mjtJoint", # joint.type
- "mjtGeom", # geom.type
- "mjtSensor", # sensor types
- "mjtObj", # objtype / reftype
- "mjtTrn", # actuator transmission
- "mjtIntegrator", # mjOption.integrator
- "mjtCone", # mjOption.cone
- "mjtSolver", # mjOption.solver
- ):
- assert expected in enums, f"missing enum {expected} from snapshot"
- assert len(enums[expected]) > 0, f"enum {expected} has no members"
diff --git a/Scripts/codegen/tests/test_expand_stride_guard.py b/Scripts/codegen/tests/test_expand_stride_guard.py
deleted file mode 100644
index 58d156dc..00000000
--- a/Scripts/codegen/tests/test_expand_stride_guard.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks the ``_expand_stride`` guard. ``MJ_M(...)`` lowers to
-``m->...``; numeric and ``mjN*`` strides pass through unchanged. Any
-``MJ_*( ... )`` macro that survives is an unhandled shape and must
-surface a diagnostic before the generated MjBind.h fails to compile."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_mj_m_macro_lowers_to_pointer_field():
- assert gen._expand_stride("MJ_M(nuser_jnt)") == "m->nuser_jnt"
-
-
-def test_numeric_stride_passes_through_unchanged():
- for s in ("1", "3", "9"):
- assert gen._expand_stride(s) == s
-
-
-def test_mj_n_constant_passes_through_unchanged():
- assert gen._expand_stride("mjNREF") == "mjNREF"
- assert gen._expand_stride("mjNBIAS") == "mjNBIAS"
-
-
-def test_compound_expression_expands_and_keeps_other_tokens():
- """Real MuJoCo strides occasionally combine ``MJ_M(...)*N`` for
- derived per-element block sizes. The guard must NOT fire because
- the substitution removes the only MJ_ macro."""
- assert gen._expand_stride("MJ_M(nuser_geom)*3") == "m->nuser_geom*3"
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_unknown_macro_fires_guard_diagnostic():
- """A future MuJoCo bump that introduces e.g. ``MJ_D(foo)`` must
- not silently land verbatim in MjBind.h."""
- out = gen._expand_stride("MJ_D(foo)")
- assert "MJ_D(foo)" in out
- assert any("unhandled MuJoCo macro" in d.message and "MJ_D(foo)" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_multiple_unknown_macros_listed_together():
- gen._expand_stride("MJ_D(a) + MJ_V(b)")
- diags = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("MJ_D(a)" in m and "MJ_V(b)" in m for m in diags), diags
-
-
-def test_known_and_unknown_mixed_still_fires_for_unknown():
- """Known macro expanded, unknown surfaces a diag."""
- out = gen._expand_stride("MJ_M(nuser_jnt) * MJ_D(foo)")
- assert "m->nuser_jnt" in out
- assert "MJ_D(foo)" in out
- assert any("MJ_D(foo)" in d.message for d in gen._DIAGS_BUFFER.pending)
diff --git a/Scripts/codegen/tests/test_find_matching_brace.py b/Scripts/codegen/tests/test_find_matching_brace.py
deleted file mode 100644
index 61c2e702..00000000
--- a/Scripts/codegen/tests/test_find_matching_brace.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks ``_find_matching_brace`` — the brace-aware extractor that
-backs the banner-overwrite audit. The previous ``\\{([^}]*)\\}`` regex
-truncated at the first inner ``}``, silently underreporting extra ctor
-content when a real ctor body contained a range-for loop or nested
-if. The extractor must track string literals and comments so a ``{``
-inside ``TEXT("...")`` does not shift the depth count."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_finds_simple_matching_brace():
- text = "x { hello } y"
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- assert close_idx is not None
- assert text[close_idx] == "}"
- assert text[open_idx + 1:close_idx] == " hello "
-
-
-def test_handles_nested_braces():
- text = "ctor() { if (x) { do(); } else { other(); } }"
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- # close_idx must be the FINAL '}', not the first inner one.
- assert close_idx == len(text) - 1
-
-
-def test_ignores_braces_in_string_literal():
- text = 'fn() { Print(TEXT("{nested}")); }'
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- # The string contains '{' and '}' but they must NOT change depth;
- # the matcher should land on the final outer '}'.
- assert close_idx == len(text) - 1
-
-
-def test_ignores_braces_in_char_literal():
- text = "fn() { char c = '{'; print(c); }"
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- assert close_idx == len(text) - 1
-
-
-def test_ignores_braces_in_line_comment():
- text = "fn() { // tail {\n real(); }"
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- assert close_idx == len(text) - 1
-
-
-def test_ignores_braces_in_block_comment():
- text = "fn() { /* tail { in comment */ real(); }"
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- assert close_idx == len(text) - 1
-
-
-def test_returns_none_for_unmatched_open():
- """If the input is malformed (open without a matching close), the
- helper returns None — caller decides whether that's a diag or a
- silent skip."""
- assert gen._find_matching_brace("fn() { unclosed", 5) is None
-
-
-def test_returns_none_when_index_is_not_open_brace():
- assert gen._find_matching_brace("x }", 1) is None
- assert gen._find_matching_brace("x", 5) is None # off-end
-
-
-def test_escape_sequences_in_string_dont_terminate_early():
- """A ``\\"`` inside a string literal must not close the string
- early — the matcher would otherwise re-enter brace-counting mode
- inside the literal and mis-count."""
- text = r'fn() { print("a\"b{c"); real(); }'
- open_idx = text.index("{")
- close_idx = gen._find_matching_brace(text, open_idx)
- assert close_idx == len(text) - 1
diff --git a/Scripts/codegen/tests/test_geom_final_type.py b/Scripts/codegen/tests/test_geom_final_type.py
deleted file mode 100644
index b0f40af9..00000000
--- a/Scripts/codegen/tests/test_geom_final_type.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the ``geom_final_type`` rule shape — resolves an mjsGeom
-type at compile time + emits the mesh-name export under the right
-EMjGeomType condition."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-from generate_ue_components import _emit_geom_final_type_block
-
-
-def _geom_value_map_rules():
- """Minimal cat/element rules that exercise the FinalType switch."""
- cat_rules = {
- "geom_final_type": {
- "xml_enum_ref": "type",
- "override_field": "bOverride_Type",
- "default_lookup": "Default->Type",
- "default_fallback": "mjGEOM_SPHERE",
- "name_export_for": "mjGEOM_MESH",
- "name_field": "MeshName",
- "name_setter": "Element->meshname.assign",
- "name_target": "*Element",
- },
- }
- element_rules = {
- "xml_enum_attrs": {
- "type": {
- "ue_property": "Type",
- "ue_enum": "EMjGeomType",
- "ue_enum_type": "EMjGeomType",
- "override_toggle": "bOverride_Type",
- "default_lookup": "Default->Type",
- "value_map": {
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "box": ["Box", "mjGEOM_BOX"],
- "mesh": ["Mesh", "mjGEOM_MESH"],
- },
- },
- },
- }
- return cat_rules, element_rules
-
-
-def test_geom_final_type_emits_full_block():
- cat_rules, element_rules = _geom_value_map_rules()
- out = _emit_geom_final_type_block(cat_rules, element_rules)
- assert out is not None
- assert "FinalType" in out
- assert "case EMjGeomType::Sphere: FinalType = mjGEOM_SPHERE;" in out
- assert "case EMjGeomType::Box: FinalType = mjGEOM_BOX;" in out
- assert "case EMjGeomType::Mesh: FinalType = mjGEOM_MESH;" in out
- assert "MeshName" in out
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_geom_final_type_returns_none_when_no_rule():
- assert _emit_geom_final_type_block({}, {}) is None
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_geom_final_type_diagnoses_missing_enum_def():
- cat_rules = {
- "geom_final_type": {
- "xml_enum_ref": "nonexistent",
- "default_fallback": "mjGEOM_SPHERE",
- "first_mj_const_token": "mjGEOM_PLANE",
- "name_for": "mjGEOM_MESH",
- "name_field": "MeshName",
- "name_setter": "Element->meshname.assign",
- "name_target": "*Element",
- },
- }
- out = _emit_geom_final_type_block(cat_rules, {"xml_enum_attrs": {}})
- assert out is None
- assert any("nonexistent" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_geom_final_type_diagnoses_empty_value_map():
- cat_rules, element_rules = _geom_value_map_rules()
- # Wipe out the value_map and provide no mjspec to fall back to.
- element_rules["xml_enum_attrs"]["type"]["value_map"] = {}
- out = _emit_geom_final_type_block(cat_rules, element_rules)
- assert out is None
- assert any("empty value_map" in d.message for d in gen._DIAGS_BUFFER.pending)
diff --git a/Scripts/codegen/tests/test_hand_enum_drift.py b/Scripts/codegen/tests/test_hand_enum_drift.py
deleted file mode 100644
index 9c8d1688..00000000
--- a/Scripts/codegen/tests/test_hand_enum_drift.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the hand-enum drift checks: ``_scan_hand_enums`` scrapes
-URLab ``EMj*`` enum members from Source/, and ``_check_hand_enum_drift``
-cross-references them against MuJoCo's ``mjt*`` enums and the rules'
-``value_map`` UE-member references."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-import _codegen_checks as _checks
-gen._scan_hand_enums = _checks._scan_hand_enums
-
-
-def _write_enum_header(tmp_path, filename: str, enum_text: str):
- p = tmp_path / filename
- p.write_text(enum_text, encoding="utf-8")
- return p
-
-
-# ---------- _scan_hand_enums -----------------------------------------------
-
-def test_scan_hand_enums_parses_umeta_members(tmp_path):
- """UMETA(DisplayName=...) on each member must NOT hide the member
- from the scanner (was the original parser bug — EMjCameraTrackingMode
- lost TrackCom and TargetBodyCom because the per-line regex required
- the line to end at the member)."""
- _write_enum_header(tmp_path, "Sample.h", """
- UENUM(BlueprintType)
- enum class EMjSample : uint8
- {
- Fixed UMETA(DisplayName = "Fixed"),
- Track UMETA(DisplayName = "Track"),
- TrackCom UMETA(DisplayName = "Track (Centre of Mass)"),
- TargetBody UMETA(DisplayName = "Target Body"),
- TargetBodyCom UMETA(DisplayName = "Target Body (Centre of Mass)"),
- };
- """)
- enums = gen._scan_hand_enums(str(tmp_path))
- assert "EMjSample" in enums
- assert enums["EMjSample"] == [
- "Fixed", "Track", "TrackCom", "TargetBody", "TargetBodyCom",
- ]
-
-
-def test_scan_hand_enums_handles_explicit_values(tmp_path):
- """Explicit ``= N`` initialisers must not break member capture."""
- _write_enum_header(tmp_path, "WithVals.h", """
- enum class EMjWithVals : uint8
- {
- Connect = 0,
- Weld = 1,
- Joint = 2,
- };
- """)
- enums = gen._scan_hand_enums(str(tmp_path))
- assert enums["EMjWithVals"] == ["Connect", "Weld", "Joint"]
-
-
-# ---------- _check_hand_enum_drift -----------------------------------------
-
-def test_hand_enum_drift_diagnoses_subtype_enum_value_typo(tmp_path):
- _write_enum_header(tmp_path, "MjJoint.h", """
- enum class EMjJointType : uint8 { Hinge, Slide, Ball };
- """)
- rules = {
- "categories": {
- "joint": {
- "type_enum_name": "EMjJointType",
- "subtypes": [
- {"key": "hinge", "enum_value": "Hinge"},
- {"key": "screw", "enum_value": "Screwd"}, # typo
- ],
- },
- },
- }
- gen._check_hand_enum_drift({}, rules, None, str(tmp_path))
- assert any("Screwd" in d.message and "EMjJointType" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_hand_enum_drift_diagnoses_value_map_ue_member_typo(tmp_path):
- _write_enum_header(tmp_path, "MjGeom.h", """
- enum class EMjGeomType : uint8 { Sphere, Box, Mesh };
- """)
- rules = {
- "categories": {},
- "element_rules": {
- "geom": {
- "xml_enum_attrs": {
- "type": {
- "ue_enum_type": "EMjGeomType",
- "value_map": {
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "box": ["Bxox", "mjGEOM_BOX"], # typo
- },
- },
- },
- },
- },
- }
- gen._check_hand_enum_drift({}, rules, None, str(tmp_path))
- assert any("Bxox" in d.message and "EMjGeomType" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_hand_enum_drift_surfaces_new_mj_enum_value(tmp_path):
- """A new mjJNT_SCREW upstream with no value_map entry fires a
- diagnostic — closes the silent-runtime-fallthrough class."""
- _write_enum_header(tmp_path, "MjJoint.h", """
- enum class EMjJointType : uint8 { Hinge, Slide, Ball };
- """)
- rules = {
- "categories": {},
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "ue_enum_type": "EMjJointType",
- "mjs_cast": "mjtJoint",
- "value_map": {
- "hinge": ["Hinge", "mjJNT_HINGE"],
- "slide": ["Slide", "mjJNT_SLIDE"],
- "ball": ["Ball", "mjJNT_BALL"],
- },
- },
- },
- },
- },
- }
- mjspec = {
- "enums": {
- "mjtJoint": ["mjJNT_FREE", "mjJNT_BALL", "mjJNT_SLIDE",
- "mjJNT_HINGE", "mjJNT_SCREW"],
- },
- }
- gen._check_hand_enum_drift({}, rules, mjspec, str(tmp_path))
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("mjJNT_SCREW" in m for m in msgs), msgs
- assert any("mjJNT_FREE" in m for m in msgs), msgs
-
-
-def test_hand_enum_drift_respects_intentional_skips(tmp_path):
- _write_enum_header(tmp_path, "MjActuator.h", """
- enum class EMjGainType : uint8 { Fixed, Affine, Muscle };
- """)
- rules = {
- "categories": {},
- "intentionally_unmapped_mj_enum_values": {
- "mjtGain": ["mjGAIN_DCMOTOR"],
- },
- "element_rules": {
- "actuator": {
- "xml_enum_attrs": {
- "gaintype": {
- "ue_enum_type": "EMjGainType",
- "mjs_cast": "mjtGain",
- "value_map": {
- "fixed": ["Fixed", "mjGAIN_FIXED"],
- "affine": ["Affine", "mjGAIN_AFFINE"],
- "muscle": ["Muscle", "mjGAIN_MUSCLE"],
- },
- },
- },
- },
- },
- }
- mjspec = {
- "enums": {
- "mjtGain": ["mjGAIN_FIXED", "mjGAIN_AFFINE", "mjGAIN_MUSCLE",
- "mjGAIN_USER", "mjGAIN_DCMOTOR"],
- },
- }
- gen._check_hand_enum_drift({}, rules, mjspec, str(tmp_path))
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- # DCMOTOR is in the skip list -> no diag.
- assert not any("mjGAIN_DCMOTOR" in m for m in msgs)
- # USER is not -> diag fires.
- assert any("mjGAIN_USER" in m for m in msgs), msgs
-
-
-def test_hand_enum_drift_per_element_overrides(tmp_path):
- """Same mjt* enum (mjtGeom) admits different subsets for geom vs
- site. The __per_element__ override must scope correctly."""
- _write_enum_header(tmp_path, "MjGeom.h", """
- enum class EMjGeomType : uint8 { Sphere, Box, Plane, Mesh };
- """)
- _write_enum_header(tmp_path, "MjSite.h", """
- enum class EMjSiteType : uint8 { Sphere, Box };
- """)
- rules = {
- "categories": {},
- "intentionally_unmapped_mj_enum_values": {
- "__per_element__": {
- "site.type": ["mjGEOM_PLANE", "mjGEOM_MESH"],
- },
- },
- "element_rules": {
- "geom": {
- "xml_enum_attrs": {
- "type": {
- "ue_enum_type": "EMjGeomType",
- "mjs_cast": "mjtGeom",
- "value_map": {
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "box": ["Box", "mjGEOM_BOX"],
- "plane": ["Plane", "mjGEOM_PLANE"],
- "mesh": ["Mesh", "mjGEOM_MESH"],
- },
- },
- },
- },
- "site": {
- "xml_enum_attrs": {
- "type": {
- "ue_enum_type": "EMjSiteType",
- "mjs_cast": "mjtGeom",
- "value_map": {
- "sphere": ["Sphere", "mjGEOM_SPHERE"],
- "box": ["Box", "mjGEOM_BOX"],
- },
- },
- },
- },
- },
- }
- mjspec = {"enums": {"mjtGeom": ["mjGEOM_SPHERE", "mjGEOM_BOX",
- "mjGEOM_PLANE", "mjGEOM_MESH"]}}
- gen._check_hand_enum_drift({}, rules, mjspec, str(tmp_path))
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- # Geom has all 4 mapped -> no diag.
- assert not any("element 'geom'" in m for m in msgs)
- # Site skips Plane + Mesh -> no diag for those either.
- assert not any("mjGEOM_PLANE" in m and "site" in m for m in msgs)
- assert not any("mjGEOM_MESH" in m and "site" in m for m in msgs)
diff --git a/Scripts/codegen/tests/test_inject_helpers.py b/Scripts/codegen/tests/test_inject_helpers.py
deleted file mode 100644
index adfc4513..00000000
--- a/Scripts/codegen/tests/test_inject_helpers.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the codegen's inject-guard layer: ``_audit_banner_safety``
-on ``fully_emitted`` overwrites, layout dispatcher fall-through,
-and canonicalisation dispatch on unknown canon names."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-from generate_ue_components import _audit_banner_safety
-
-
-# ---------- banner-safety audit ---------------------------------------------
-
-def test_audit_banner_safety_silent_on_template_only(tmp_path):
- """A subclass file containing only its own header include and a
- bare ``Type = ...`` constructor should not trigger a diagnostic."""
- p = tmp_path / "MjBoxGeom.cpp"
- p.write_text(
- '#include "MuJoCo/Components/Geometry/MjBoxGeom.h"\n'
- "UMjBoxGeom::UMjBoxGeom()\n"
- "{\n"
- " Type = EMjGeomType::Box;\n"
- "}\n",
- encoding="utf-8",
- )
- subtype = {"class_name": "UMjBoxGeom"}
- _audit_banner_safety(str(p), subtype)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_audit_banner_safety_flags_extra_include(tmp_path):
- """An extra non-template #include in a soon-to-be-overwritten file
- triggers a diagnostic so the rule author knows hand-rolled content
- will be discarded."""
- p = tmp_path / "MjBoxGeom.cpp"
- p.write_text(
- '#include "MuJoCo/Components/Geometry/MjBoxGeom.h"\n'
- '#include "SomeOther/Header.h"\n'
- "UMjBoxGeom::UMjBoxGeom()\n"
- "{\n"
- " Type = EMjGeomType::Box;\n"
- "}\n",
- encoding="utf-8",
- )
- subtype = {"class_name": "UMjBoxGeom"}
- _audit_banner_safety(str(p), subtype)
- assert any("SomeOther/Header.h" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_audit_banner_safety_flags_extra_ctor_body(tmp_path):
- """Constructor body content beyond ``Type = EMj...::X`` and the
- rule-provided ``extra_constructor`` is flagged — that's where the
- joint-subtype bOverride_Type bug came from."""
- p = tmp_path / "MjHingeJoint.cpp"
- p.write_text(
- '#include "MuJoCo/Components/Joints/MjHingeJoint.h"\n'
- "UMjHingeJoint::UMjHingeJoint()\n"
- "{\n"
- " Type = EMjJointType::Hinge;\n"
- " HandRolledHelperCall();\n"
- "}\n",
- encoding="utf-8",
- )
- subtype = {
- "class_name": "UMjHingeJoint",
- "extra_constructor": "",
- }
- _audit_banner_safety(str(p), subtype)
- assert any("non-template ctor content" in d.message
- and "HandRolledHelperCall" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-# ---------- inject-guard diagnostics ----------------------------------------
-
-def test_layout_dispatch_diagnoses_unknown_layout():
- """`_phase_categories` else-branch fires a diag for typo'd layouts.
- Catches the silent fall-through where mistyped 'single_uclass'
- instead of 'single_uclass_per_file' produces zero output."""
- writes = []
- rules = {
- "categories": {
- "bogus": {"layout": "single_uclass"},
- },
- }
- ctx = gen.PhaseContext(
- schema={}, rules=rules, mjxmacro={}, mjspec={},
- public_root="", private_root="", bind_h_path="", writes=writes,
- )
- gen._phase_categories(ctx)
- assert any("unknown layout" in d.message and "bogus" in d.message
- and "single_uclass" in d.message
- for d in gen._DIAGS_BUFFER.pending)
- assert writes == []
-
-
-# Unknown-canon diagnostic is pinned in test_canon_registry.py.
diff --git a/Scripts/codegen/tests/test_inject_helpers_brace.py b/Scripts/codegen/tests/test_inject_helpers_brace.py
deleted file mode 100644
index e82fdf45..00000000
--- a/Scripts/codegen/tests/test_inject_helpers_brace.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the codegen injection helpers: brace-balance gate +
-multi-tag inject + string/comment-aware brace stripping.
-
-The brace-balance check exists because a stray ``}`` lost inside a
-long composed block silently relocates the compile error to a place
-unrelated to the codegen site. We want the diagnostic to point at the
-exact tag instead."""
-
-from __future__ import annotations
-
-import os
-
-import generate_ue_components as gen
-import _codegen_inject as _inject
-gen._check_brace_balance = _inject._check_brace_balance
-
-
-def _write(tmp_path, name: str, body: str) -> str:
- p = tmp_path / name
- p.write_text(body, encoding="utf-8")
- return str(p)
-
-
-# ---------- brace-balance --------------------------------------------------
-
-def test_brace_balance_flags_unbalanced_block():
- body = "if (x) { do_thing(); " # missing close
- gen._check_brace_balance(body, "FOO", "unit_test")
- assert any("unbalanced braces" in d.message and "CODEGEN_FOO" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_brace_balance_quiet_on_balanced_block():
- body = "if (x) { do_thing(); }"
- gen._check_brace_balance(body, "FOO", "unit_test")
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_brace_balance_ignores_braces_in_strings_and_comments():
- """``"{"`` inside a TEXT() literal must not count toward the open
- tally; same for braces in // and /* */ comments."""
- body = (
- 'if (x)\n'
- '{\n'
- ' Log(TEXT("brace { in string")); // and { in line comment\n'
- ' /* and { in block comment */\n'
- '}\n'
- )
- gen._check_brace_balance(body, "FOO", "unit_test")
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_inject_between_tags_with_balance_flag_fires_diag():
- """``balance_source`` kwarg routes through the brace-balance check."""
- file_text = "before\n// --- CODEGEN_FOO_START ---\nold\n// --- CODEGEN_FOO_END ---\nafter\n"
- new_inner = "if (x) {" # unbalanced
- _, ok = gen.inject_between_tags(file_text, "FOO", new_inner,
- balance_source="unit_test")
- assert ok is True
- assert any("unbalanced braces" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_inject_between_tags_default_skips_balance_check():
- """Without ``balance_source``, the helper does not run the gate —
- callers writing non-C++ blocks (markdown, JSON) aren't forced to
- opt out."""
- file_text = "// --- CODEGEN_FOO_START ---\nold\n// --- CODEGEN_FOO_END ---\n"
- gen.inject_between_tags(file_text, "FOO", "{ stray")
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-# ---------- _inject_tags_into_cpp -----------------------------------------
-
-def test_inject_tags_into_cpp_handles_multiple_tags(tmp_path):
- body = (
- "// --- CODEGEN_FOO_START ---\n"
- "old foo\n"
- "// --- CODEGEN_FOO_END ---\n"
- "between\n"
- "// --- CODEGEN_BAR_START ---\n"
- "old bar\n"
- "// --- CODEGEN_BAR_END ---\n"
- )
- cpp_path = _write(tmp_path, "host.cpp", body)
- writes: list = []
- gen._inject_tags_into_cpp(
- cpp_path,
- [("FOO", "new foo body"), ("BAR", "new bar body")],
- writes,
- diag_source="unit_test",
- )
- assert len(writes) == 1
- out = writes[0].content
- assert "new foo body" in out
- assert "new bar body" in out
- assert "old foo" not in out
- assert "old bar" not in out
-
-
-def test_inject_tags_into_cpp_diagnoses_missing_file(tmp_path):
- missing = str(tmp_path / "nope.cpp")
- writes: list = []
- gen._inject_tags_into_cpp(
- missing, [("FOO", "x")], writes, diag_source="unit_test",
- )
- assert writes == []
- assert any("does not exist" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_inject_tags_into_cpp_diagnoses_missing_marker(tmp_path):
- cpp_path = _write(tmp_path, "host.cpp",
- "// --- CODEGEN_FOO_START ---\nx\n// --- CODEGEN_FOO_END ---\n")
- writes: list = []
- gen._inject_tags_into_cpp(
- cpp_path,
- [("FOO", "new foo"), ("MISSING_TAG", "new missing")],
- writes,
- diag_source="unit_test",
- )
- # The FOO write still landed; MISSING_TAG fires a diagnostic.
- assert len(writes) == 1
- assert any("CODEGEN_MISSING_TAG" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_inject_tags_into_cpp_skips_write_when_unchanged(tmp_path):
- """Idempotency: re-injecting the same body must not append a
- FileWrite. The ``--check`` gate relies on this. The END marker's
- indent mirrors the START marker's, so a START at column 0 lands
- END at column 0 too."""
- body = (
- "// --- CODEGEN_FOO_START ---\n"
- "same body\n"
- "// --- CODEGEN_FOO_END ---\n"
- )
- cpp_path = _write(tmp_path, "host.cpp", body)
- writes: list = []
- gen._inject_tags_into_cpp(
- cpp_path, [("FOO", "same body")], writes, diag_source="unit_test",
- )
- assert writes == []
-
-
-def test_inject_between_tags_normalises_end_indent_to_match_start(tmp_path):
- """A hand-prepped source where START is at 8 spaces but END is
- at 4 spaces (or any mismatch) gets its END normalised to match
- START."""
- text = (
- " // --- CODEGEN_FOO_START ---\n"
- " body content\n"
- " // --- CODEGEN_FOO_END ---\n"
- )
- new_text, ok = gen.inject_between_tags(text, "FOO", "new body")
- assert ok is True
- # Both marker lines now sit at the START's 8-space indent — assert
- # the END's leading whitespace exactly so we don't accidentally
- # match a substring of a deeper indent.
- import re
- match = re.search(r"^(\s*)// --- CODEGEN_FOO_END ---$", new_text,
- re.MULTILINE)
- assert match is not None
- assert match.group(1) == " ", repr(match.group(1))
diff --git a/Scripts/codegen/tests/test_injection.py b/Scripts/codegen/tests/test_injection.py
deleted file mode 100644
index 00bd278f..00000000
--- a/Scripts/codegen/tests/test_injection.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Boundary-tag injection tests."""
-
-from __future__ import annotations
-
-from generate_ue_components import inject_between_tags
-
-
-def test_replace_between_existing_tags():
- src = """class UFoo {
-public:
- // --- CODEGEN_PROPERTIES_START ---
- int OldStuff;
- // --- CODEGEN_PROPERTIES_END ---
-};
-"""
- out, found = inject_between_tags(src, "PROPERTIES", " int NewStuff;\n")
- assert found is True
- assert "OldStuff" not in out
- assert "NewStuff" in out
- # Tag lines preserved.
- assert "// --- CODEGEN_PROPERTIES_START ---" in out
- assert "// --- CODEGEN_PROPERTIES_END ---" in out
-
-
-def test_missing_tags_returns_unchanged():
- src = "class UFoo { int X; };"
- out, found = inject_between_tags(src, "PROPERTIES", "int Y;")
- assert found is False
- assert out == src
-
-
-def test_idempotent_replace():
- src = """// --- CODEGEN_FOO_START ---
-old body
-// --- CODEGEN_FOO_END ---"""
- out1, _ = inject_between_tags(src, "FOO", "new body\n")
- out2, _ = inject_between_tags(out1, "FOO", "new body\n")
- # second injection of the same body produces byte-identical output.
- assert out1 == out2
-
-
-def test_preserves_text_outside_tags():
- prefix = "// custom comment that must survive\n"
- suffix = "\n// trailing custom code\nvoid Helper() {}\n"
- src = prefix + "// --- CODEGEN_X_START ---\nold\n// --- CODEGEN_X_END ---" + suffix
- out, _ = inject_between_tags(src, "X", "new\n")
- assert out.startswith(prefix)
- assert out.endswith(suffix)
-
-
-def test_dotall_does_not_swallow_subsequent_tags():
- # Two separate codegen blocks must be replaced independently.
- src = """// --- CODEGEN_A_START ---
-A old
-// --- CODEGEN_A_END ---
-some middle code
-// --- CODEGEN_B_START ---
-B old
-// --- CODEGEN_B_END ---"""
- out, _ = inject_between_tags(src, "A", "A new\n")
- out, _ = inject_between_tags(out, "B", "B new\n")
- assert "A new" in out and "B new" in out
- assert "A old" not in out and "B old" not in out
- # Middle code is still there.
- assert "some middle code" in out
diff --git a/Scripts/codegen/tests/test_introspect_snapshot.py b/Scripts/codegen/tests/test_introspect_snapshot.py
deleted file mode 100644
index 54d7f0e3..00000000
--- a/Scripts/codegen/tests/test_introspect_snapshot.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Smoke tests for the clang-AST introspect snapshot.
-
-Skipped automatically when libclang isn't available (e.g. CI runners
-without the package). The real validation happens on the committed
-``Scripts/introspect_snapshot.json`` itself — these tests just spot-check
-that schema-evolution surprises don't slip through.
-"""
-
-from __future__ import annotations
-
-import json
-import os
-
-import pytest
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_PLUGIN_ROOT = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
-_SNAPSHOT = os.path.join(_PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "introspect_snapshot.json")
-
-
-def _load() -> dict:
- if not os.path.exists(_SNAPSHOT):
- pytest.skip("introspect_snapshot.json not built yet; run "
- "build_introspect_snapshot.py")
- with open(_SNAPSHOT, "r", encoding="utf-8") as f:
- return json.load(f)
-
-
-def test_snapshot_meta_and_top_level_keys_present():
- """One combined smoke test: top-level sections are present, each is
- non-empty, and the ``_meta`` block carries a stable header hash.
- Substring presence of specific MuJoCo names (mjs_addBody, mjtJoint,
- etc.) is covered by ``test_enum_scrape::test_real_snapshot_has_
- expected_enums`` plus the regen --check gate."""
- snap = _load()
- for section in ("functions", "enums", "structs", "defines"):
- assert section in snap, section
- assert len(snap[section]) > 0, section
- assert "_meta" in snap
- assert snap["_meta"]["snapshot_version"] >= 1
- assert len(snap["_meta"]["header_hash"]) == 64
diff --git a/Scripts/codegen/tests/test_kept_props_for_category.py b/Scripts/codegen/tests/test_kept_props_for_category.py
deleted file mode 100644
index 87232c05..00000000
--- a/Scripts/codegen/tests/test_kept_props_for_category.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks ``kept_props_for_category`` — the ordered prop-list helper
-extracted from emit_schema_for_tests. Used by the
-schema-completeness header that drives URLab.Codegen.* automation
-tests, so the order + composition must stay deterministic."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_emits_canon_property_first_then_per_attr_in_schema_order():
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "canonicalizations": {
- "spatial_pose": {
- "absorbs_attrs": ["pos"],
- "emits_property": {"name": "Pos", "type": "FVector"},
- "import_helper": "X",
- "export_helper": "Y",
- },
- },
- "element_rules": {
- "joint": {
- "applies_canonicalizations": ["spatial_pose"],
- },
- },
- }
- schema = {"joint": {"attrs": ["pos", "type", "axis", "limited"]}}
- cat_rules = {"schema_common_block": "joint.attrs"}
- out = gen.kept_props_for_category("joint", cat_rules, schema, rules)
- # Pos comes first (canon-owned), then per-attr in schema order
- # minus the canon-absorbed ``pos``.
- assert out == ["Pos", "type", "axis", "limited"]
-
-
-def test_disable_schema_emission_returns_empty():
- rules = {"global_exclusions": [], "canonicalizations": {},
- "element_rules": {}}
- cat_rules = {"disable_schema_emission": True,
- "schema_common_block": "joint.attrs"}
- out = gen.kept_props_for_category("joint", cat_rules, {}, rules)
- assert out == []
-
-
-def test_xml_enum_attr_lowers_to_ue_property():
- rules = {
- "global_exclusions": [],
- "property_renames": {},
- "canonicalizations": {},
- "element_rules": {
- "camera": {
- "xml_enum_attrs": {
- "mode": {
- "ue_property": "TrackingMode",
- "ue_enum_type": "EMjCameraTrackingMode",
- "value_map": {"fixed": ["Fixed", "mjCAMLIGHT_FIXED"]},
- },
- },
- },
- },
- }
- schema = {"camera": {"attrs": ["mode", "fovy"]}}
- cat_rules = {"schema_common_block": "camera.attrs"}
- out = gen.kept_props_for_category("camera", cat_rules, schema, rules)
- # ``mode`` -> ``TrackingMode``; ``fovy`` passes through.
- assert out == ["TrackingMode", "fovy"]
-
-
-def test_schema_common_extra_attrs_append_after_block():
- rules = {"global_exclusions": [], "property_renames": {},
- "canonicalizations": {}, "element_rules": {}}
- schema = {"frame": {"attrs": []}}
- cat_rules = {
- "schema_common_block": "frame.attrs",
- "schema_common_extra_attrs": ["pos", "quat", "childclass"],
- }
- out = gen.kept_props_for_category("frame", cat_rules, schema, rules)
- assert out == ["pos", "quat", "childclass"]
-
-
-def test_global_and_element_exclusions_drop_attrs():
- rules = {
- "global_exclusions": ["type"],
- "property_renames": {},
- "canonicalizations": {},
- "element_rules": {
- "joint": {"exclude_attrs": ["limited"]},
- },
- }
- schema = {"joint": {"attrs": ["type", "axis", "limited", "stiffness"]}}
- cat_rules = {"schema_common_block": "joint.attrs"}
- out = gen.kept_props_for_category("joint", cat_rules, schema, rules)
- assert "type" not in out
- assert "limited" not in out
- assert out == ["axis", "stiffness"]
-
-
-def test_property_rename_lowers_to_renamed_prop():
- rules = {
- "global_exclusions": [],
- "property_renames": {"qpos": "Qpos"},
- "canonicalizations": {},
- "element_rules": {},
- }
- schema = {"keyframe": {"attrs": ["qpos", "time"]}}
- cat_rules = {"schema_common_block": "keyframe.attrs"}
- out = gen.kept_props_for_category("keyframe", cat_rules, schema, rules)
- assert out == ["Qpos", "time"]
diff --git a/Scripts/codegen/tests/test_libclang_hand_enum_scrape.py b/Scripts/codegen/tests/test_libclang_hand_enum_scrape.py
deleted file mode 100644
index 15f929ae..00000000
--- a/Scripts/codegen/tests/test_libclang_hand_enum_scrape.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the libclang-backed EMj* hand-enum scrape in
-``build_introspect_snapshot.py`` and the snapshot consumer
-``_hand_enums_from_snapshot``.
-
-The scrape:
- - extracts every ``enum class EMj* : uint8 { ... }`` block under
- ``Source/URLab/Public``;
- - strips UE-only macros (UMETA / UENUM) so a minimal libclang TU
- can parse the block — including nested parens like
- ``UMETA(DisplayName="Track (Centre of Mass)")``;
- - lands the result under ``snapshot.hand_enums`` in
- ``introspect_snapshot.json``.
-
-The hand-enum drift check prefers this over the fallback regex
-scrape — the snapshot is byte-stable across machines because the
-macro stripping is deterministic."""
-
-from __future__ import annotations
-
-import json
-import os
-
-import pytest
-import generate_ue_components as gen
-import _codegen_checks as _checks
-gen._hand_enums_from_snapshot = _checks._hand_enums_from_snapshot
-
-# build_introspect_snapshot lives alongside generate_ue_components but is
-# not always import-clean (it would try to load clang.cindex at import
-# time). Test the strip helper via a tolerant import path.
-import importlib.util
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-_BUILD_SNAP = os.path.join(_CODEGEN_DIR, "build_introspect_snapshot.py")
-
-
-def _load_build_snapshot_module():
- spec = importlib.util.spec_from_file_location(
- "_build_introspect_snapshot_for_test", _BUILD_SNAP,
- )
- mod = importlib.util.module_from_spec(spec)
- sys.modules[spec.name] = mod
- spec.loader.exec_module(mod)
- return mod
-
-
-@pytest.fixture(scope="module")
-def build_snap():
- return _load_build_snapshot_module()
-
-
-# ---------- macro stripper -------------------------------------------------
-
-def test_strip_handles_nested_parens_in_umeta(build_snap):
- """``UMETA(DisplayName="Track (Centre of Mass)")`` — the inner
- ``(Centre`` opens a paren the regex must not bail on. The previous
- naive ``UMETA\\([^)]*\\)`` regex stopped at the first ``)``, leaving
- a stray ``)`` that broke libclang's enum-member walk for any member
- after the first nested-paren UMETA."""
- src = (
- "enum class EMjSample : uint8 {\n"
- " Fixed UMETA(DisplayName = \"Fixed\"),\n"
- " TrackCom UMETA(DisplayName = \"Track (Centre of Mass)\"),\n"
- " TargetBody UMETA(DisplayName = \"Target Body\"),\n"
- " TargetBodyCom UMETA(DisplayName = \"Target Body (Centre of Mass)\"),\n"
- "};\n"
- )
- out = build_snap._strip_ue_macros_from_enum_block(src)
- assert "UMETA" not in out
- # No stray close-parens left behind after the strip.
- assert ")" not in out
- # All four members survive.
- for m in ("Fixed", "TrackCom", "TargetBody", "TargetBodyCom"):
- assert m in out, f"member {m} lost during strip; out={out!r}"
-
-
-def test_strip_handles_uenum_header(build_snap):
- src = (
- "UENUM(BlueprintType)\n"
- "enum class EMjFoo : uint8 { A, B };\n"
- )
- out = build_snap._strip_ue_macros_from_enum_block(src)
- assert "UENUM" not in out
- assert "enum class EMjFoo : uint8 { A, B };" in out
-
-
-def test_strip_handles_line_and_block_comments(build_snap):
- src = (
- "enum class EMjFoo : uint8 {\n"
- " A, // first\n"
- " B, /* second */\n"
- " /* a multi\n"
- " line */ C,\n"
- "};\n"
- )
- out = build_snap._strip_ue_macros_from_enum_block(src)
- assert "first" not in out
- assert "second" not in out
- assert "multi" not in out
- for m in ("A", "B", "C"):
- assert m in out
-
-
-def test_strip_balanced_call_terminates_on_unbalanced_input(build_snap):
- """An open-paren without a matching close should consume to EOF
- rather than infinite-loop the macro stripper."""
- src = "UMETA(unbalanced"
- out = build_snap._strip_ue_macros_from_enum_block(src)
- # Strip drove the cursor to EOF -> empty residue.
- assert out == ""
-
-
-# ---------- snapshot output ------------------------------------------------
-
-def test_snapshot_contains_at_least_one_hand_enum():
- """If the shipped snapshot has hand_enums, we trust the build step
- ran libclang against URLab's Public/ tree."""
- snap_path = os.path.join(
- os.path.dirname(_CODEGEN_DIR),
- "codegen", "snapshots", "introspect_snapshot.json",
- )
- if not os.path.exists(snap_path):
- pytest.skip("introspect_snapshot.json not present")
- with open(snap_path, "r", encoding="utf-8") as f:
- snap = json.load(f)
- hand_enums = snap.get("hand_enums", {})
- if not hand_enums:
- pytest.skip("hand_enums empty (libclang scrape disabled?)")
- # At least one EMj* enum and every entry has members.
- emj = [k for k in hand_enums if k.startswith("EMj")]
- assert emj, f"hand_enums missing EMj* entries; keys={list(hand_enums)[:5]}"
- for name, entry in hand_enums.items():
- assert "members" in entry, name
- assert entry["members"], f"{name} has no members"
-
-
-# ---------- runtime consumer ----------------------------------------------
-
-def test_hand_enums_from_snapshot_returns_flat_member_list():
- """The runtime drift check expects ``{enum_name: [member,...]}`` —
- the same shape the regex scrape produced. Confirm the converter
- flattens the introspect dict shape correctly."""
- mjspec = {
- "introspect": {
- "hand_enums": {
- "EMjSample": {
- "members": {"A": 0, "B": 1, "C": 2},
- },
- },
- },
- }
- out = gen._hand_enums_from_snapshot(mjspec)
- assert out == {"EMjSample": ["A", "B", "C"]}
-
-
-def test_hand_enums_from_snapshot_empty_when_missing():
- """No introspect / no hand_enums section -> empty dict (the drift
- check then falls back to the regex scrape)."""
- assert gen._hand_enums_from_snapshot({}) == {}
- assert gen._hand_enums_from_snapshot({"introspect": {}}) == {}
- assert gen._hand_enums_from_snapshot(None) == {}
diff --git a/Scripts/codegen/tests/test_mjxmacro_snapshot.py b/Scripts/codegen/tests/test_mjxmacro_snapshot.py
deleted file mode 100644
index 1ef35291..00000000
--- a/Scripts/codegen/tests/test_mjxmacro_snapshot.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the mjxmacro snapshot parser.
-
-The XNV-accepting regex was added after a silent-drop bug — every entry
-listed AFTER an XNV line in the same block (e.g. ``geom_user``, ``geom_rgba``
-after ``XNV(mjtNum, geom_fluid, ...)`` in MJMODEL_POINTERS_GEOM) was
-discarded because the body-collector treated XNV as a non-entry sentinel
-and stopped the loop. These tests pin the regex behaviour so adding a
-new tag is a deliberate change with a test failure to acknowledge.
-"""
-
-from __future__ import annotations
-
-import textwrap
-
-from build_mjxmacro_snapshot import (
- _BODY_ENTRY_RE,
- _X_ENTRY_RE,
- _X_TAG_RE,
- _parse_block_body,
- _parse_pointer_entry,
-)
-
-
-# ---------------------------------------------------------------------------
-# Regex behaviour
-# ---------------------------------------------------------------------------
-
-def test_x_tag_re_accepts_known_tags():
- """X, XVEC, XNV are the three macro tags MuJoCo uses today."""
- import re
- rx = re.compile(rf"^{_X_TAG_RE}$")
- assert rx.match("X")
- assert rx.match("XVEC")
- assert rx.match("XNV")
- # Future tags should fail until added (the failure is the canary).
- assert not rx.match("XSEG")
- assert not rx.match("XMODEL")
-
-
-def test_body_entry_re_matches_all_three_tags():
- assert _BODY_ENTRY_RE.match(" X ( int, foo, nfoo, 1 )")
- assert _BODY_ENTRY_RE.match(" XVEC( mjtNum, bar, nbar, 3 )")
- assert _BODY_ENTRY_RE.match(" XNV ( mjtNum, baz, nbaz, mjNFLUID )")
- # Tags that look similar but aren't in the set.
- assert not _BODY_ENTRY_RE.match(" X3 ( ... )")
-
-
-def test_x_entry_re_captures_payload_for_all_tags():
- m = _X_ENTRY_RE.match(" XNV ( mjtNum, geom_fluid, ngeom, mjNFLUID ) \\")
- assert m
- assert "geom_fluid" in m.group(1)
- m2 = _X_ENTRY_RE.match(" X ( int, geom_type, ngeom, 1 ) \\")
- assert m2
- assert "geom_type" in m2.group(1)
-
-
-# ---------------------------------------------------------------------------
-# End-to-end block parsing — the bug that motivated this file
-# ---------------------------------------------------------------------------
-
-def _block_lines(block_body: str) -> list:
- """Strip the leading newline + dedent so test bodies read naturally."""
- return textwrap.dedent(block_body).strip("\n").split("\n")
-
-
-def test_block_body_does_not_stop_at_xnv():
- """The original regex matched (X|XVEC) only; XNV broke the body collector
- so every subsequent entry in the block was silently dropped. This pins
- the behaviour so MJMODEL_POINTERS_GEOM can never lose geom_user /
- geom_rgba again."""
- lines = _block_lines("""
- X ( int, geom_type, ngeom, 1 )
- XNV ( mjtNum, geom_fluid, ngeom, mjNFLUID )
- X ( mjtNum, geom_user, ngeom, MJ_M(nuser_geom) )
- X ( float, geom_rgba, ngeom, 4 )
- """)
- entries = _parse_block_body(lines, 0)
- assert len(entries) == 4, "XNV must not abort the body collector"
- parsed = [_parse_pointer_entry(e) for e in entries]
- names = [p["name"] for p in parsed if p]
- assert names == ["geom_type", "geom_fluid", "geom_user", "geom_rgba"]
-
-
-def test_parse_pointer_entry_for_xnv():
- """XNV entries parse as 4-tuples identical to X entries."""
- entry = _parse_pointer_entry("XNV ( mjtNum, geom_fluid, ngeom, mjNFLUID )")
- assert entry == {
- "type": "mjtNum",
- "name": "geom_fluid",
- "outer_dim": "ngeom",
- "stride": "mjNFLUID",
- }
-
-
-# ---------------------------------------------------------------------------
-# Two-source fold-in: mjxmacro.h + mjspecmacro.h => one snapshot
-# ---------------------------------------------------------------------------
-
-def test_shipped_snapshot_has_struct_field_sources(real_mjxmacro):
- """The snapshot writer should record which header each struct-field
- block came from so consumers can tell mjmodel-side from mjspec-side."""
- meta = real_mjxmacro.get("_meta", {})
- sources = meta.get("struct_field_sources")
- assert isinstance(sources, dict) and sources, (
- "expected _meta.struct_field_sources to be populated"
- )
-
-
-def test_shipped_snapshot_attributes_mjspec_blocks_to_mjspecmacro(real_mjxmacro):
- """MJSCOMPILER_FIELDS + MJSPEC_FIELDS must come from mjspecmacro.h,
- not mjxmacro.h — they only exist in the spec header."""
- sources = real_mjxmacro["_meta"]["struct_field_sources"]
- for block in ("MJSCOMPILER_FIELDS", "MJSPEC_FIELDS"):
- assert block in sources, f"snapshot missing {block} source attribution"
- assert "mjspecmacro.h" in sources[block], (
- f"{block} should be sourced from mjspecmacro.h, got {sources[block]!r}"
- )
-
-
-def test_shipped_snapshot_attributes_mjoption_blocks_to_mjxmacro(real_mjxmacro):
- """MJOPTION_FIELDS / MJSTATISTIC_FIELDS live in mjxmacro.h."""
- sources = real_mjxmacro["_meta"]["struct_field_sources"]
- for block in ("MJOPTION_FIELDS", "MJSTATISTIC_FIELDS"):
- assert block in sources, f"snapshot missing {block} source attribution"
- assert "mjxmacro.h" in sources[block], (
- f"{block} should be sourced from mjxmacro.h, got {sources[block]!r}"
- )
-
-
-# ---------------------------------------------------------------------------
-# Defensive block-coverage tripwire
-# ---------------------------------------------------------------------------
-
-def test_shipped_snapshot_includes_arena_pointers_contact(real_mjxmacro):
- """MJDATA_ARENA_POINTERS_CONTACT must round-trip. It was previously
- dropped silently because POINTER_BLOCKS_MJDATA omitted it; the
- unrecognised-block warning in build_mjxmacro_snapshot.py catches
- similar gaps at parse time, and this test pins the result."""
- blocks = real_mjxmacro["mjdata_pointers"]
- assert "MJDATA_ARENA_POINTERS_CONTACT" in blocks, (
- "MJDATA_ARENA_POINTERS_CONTACT was previously silently dropped — "
- "if this fails again, check POINTER_BLOCKS_MJDATA in "
- "build_mjxmacro_snapshot.py."
- )
- assert blocks["MJDATA_ARENA_POINTERS_CONTACT"], (
- "block recognised but body collection produced 0 entries"
- )
-
-
-def test_parse_mjxmacro_warns_on_unrecognised_block(tmp_path, capsys):
- """An MJ-prefixed block not in any allow-list AND not in
- KNOWN_UNCONSUMED_BLOCKS must print a stderr warning, NOT silently
- appear in the snapshot output."""
- from build_mjxmacro_snapshot import parse_mjxmacro
- fake = tmp_path / "fake_mjxmacro.h"
- fake.write_text(
- "#define MJMODEL_POINTERS_FROBNOZ \\\n"
- " X ( int, frob_a, nfrob, 1 ) \\\n"
- " X ( int, frob_b, nfrob, 1 )\n",
- encoding="utf-8",
- )
- parse_mjxmacro(str(fake))
- captured = capsys.readouterr()
- assert "MJMODEL_POINTERS_FROBNOZ" in captured.err
- assert "unrecognised" in captured.err.lower()
diff --git a/Scripts/codegen/tests/test_new_rule_shapes.py b/Scripts/codegen/tests/test_new_rule_shapes.py
deleted file mode 100644
index f46cb228..00000000
--- a/Scripts/codegen/tests/test_new_rule_shapes.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Residual unit tests for rule shapes that don't have a dedicated
-file: ``property_default`` (with value_map cross-check),
-``_guarded_export(multiline=...)`` emission shapes, and the full-coverage
-drift checks (value_map stale, orphan type_mappings, compiler attrs,
-mjxmacro block coverage, mjs_array_caps_for).
-
-Larger concerns moved to dedicated files: see ``test_objtype_dispatch``,
-``test_geom_final_type``, ``test_inject_helpers``, ``test_hand_enum_drift``,
-``test_type_shape_drift``, ``test_property_units``.
-"""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-from generate_ue_components import _guarded_export
-
-
-# ---------- property_default + cross-check ---------------------------------
-
-def test_property_default_emitted_on_base():
- """`property_default` ends up as the UPROPERTY initializer when
- ``emit_property_decl: true`` is set on an xml_enum_attr."""
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {},
- "canonicalizations": {},
- "element_rules": {
- "actuator": {
- "xml_enum_attrs": {
- "gaintype": {
- "ue_property": "GainType",
- "ue_enum": "EMjGainType",
- "ue_enum_type": "EMjGainType",
- "override_toggle": "bOverride_GainType",
- "default_lookup": "Default->GainType",
- "emit_property_decl": True,
- "property_default": "Fixed",
- "value_map": {
- "fixed": ["Fixed", "mjGAIN_FIXED"],
- "affine": ["Affine", "mjGAIN_AFFINE"],
- },
- },
- },
- },
- },
- }
- out = gen.emit_schema_for_attrs(
- ["gaintype"], rules, "actuator", "Actuator",
- apply_canonicalizations=True,
- )
- assert "EMjGainType GainType = EMjGainType::Fixed;" in out.properties_h
-
-
-def test_property_default_cross_check_diagnoses_bad_member():
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {},
- "canonicalizations": {},
- "element_rules": {
- "actuator": {
- "xml_enum_attrs": {
- "gaintype": {
- "ue_property": "GainType",
- "ue_enum": "EMjGainType",
- "ue_enum_type": "EMjGainType",
- "override_toggle": "bOverride_GainType",
- "default_lookup": "Default->GainType",
- "emit_property_decl": True,
- # NotAMember does not appear in value_map below.
- "property_default": "NotAMember",
- "value_map": {
- "fixed": ["Fixed", "mjGAIN_FIXED"],
- "affine": ["Affine", "mjGAIN_AFFINE"],
- },
- },
- },
- },
- },
- }
- gen.emit_schema_for_attrs(
- ["gaintype"], rules, "actuator", "Actuator",
- apply_canonicalizations=True,
- )
- assert any("NotAMember" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-# ---------- _guarded_export(multiline=True) --------------------------------
-
-def test_guarded_export_singleline_form():
- """Single-line form: ``if (toggle) `` on one line."""
- out = _guarded_export("bOverride_x", "Element->x = X;")
- assert out == " if (bOverride_x) Element->x = X;\n"
-
-
-def test_guarded_export_multiline_brace_layout():
- """Multiline form: brace on its own line; body is emitted verbatim
- between braces (caller owns inner indentation)."""
- body = " line_a;\n line_b;\n"
- out = _guarded_export("bOverride_x", body, multiline=True)
- expected = (
- " if (bOverride_x)\n"
- " {\n"
- " line_a;\n"
- " line_b;\n"
- " }\n"
- )
- assert out == expected
-
-
-def test_guarded_export_multiline_with_extra_cond():
- """``extra_cond`` (default order) appears after the toggle."""
- body = " do_thing();\n"
- out = _guarded_export(
- "bOverride_x", body,
- extra_cond="ready",
- multiline=True,
- )
- assert out.startswith(" if (bOverride_x && ready)\n {\n")
- assert " do_thing();\n" in out
- assert out.endswith(" }\n")
-
-
-def test_guarded_export_extra_cond_first_order():
- """``extra_cond_first=True`` flips the order and parenthesises
- the extra cond."""
- out = _guarded_export(
- "bOverride_x", "Element->x = X;",
- extra_cond="ready",
- extra_cond_first=True,
- )
- assert out == " if ((ready) && bOverride_x) Element->x = X;\n"
-
-
-# ---------- full-coverage drift checks -------------------------------------
-
-def test_value_map_stale_mj_const_flagged():
- """A value_map entry referencing a constant NOT in any mjspec enum
- is stale — surface it before the C++ compile fails."""
- rules = {
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "value_map": {
- "hinge": ["Hinge", "mjJNT_HINGE"],
- "screwd": ["Screwd", "mjJNT_NONEXISTENT"],
- },
- },
- },
- },
- },
- }
- mjspec = {"enums": {"mjtJoint": {"mjJNT_HINGE": 0, "mjJNT_SLIDE": 1}}}
- gen._check_value_map_stale_mj_consts(rules, mjspec)
- assert any("mjJNT_NONEXISTENT" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_orphan_type_mappings_flagged():
- schema = {"joint": {"attrs": ["stiffness"]}}
- rules = {
- "type_mappings": {
- "stiffness": "TArray",
- "vanishedattr": "TArray",
- },
- "categories": {"joint": {"schema_common_block": "joint.attrs"}},
- "element_rules": {},
- }
- gen._check_orphan_rule_entries(schema, rules)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("'vanishedattr'" in m for m in msgs)
- assert not any("'stiffness'" in m for m in msgs)
-
-
-def test_compiler_attrs_coverage_flags_unhandled():
- schema = {"compiler": {"attrs": ["angle", "newflag2030", "eulerseq"]}}
- rules = {
- "compiler_attr_field_map": {"angle": "bAngleInDegrees", "eulerseq": "EulerSeq"},
- "intentionally_unmodeled_compiler_attrs": [],
- }
- gen._check_compiler_attrs_coverage(schema, rules)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("newflag2030" in m for m in msgs), msgs
- assert not any("'angle'" in m for m in msgs)
-
-
-def test_compiler_attrs_coverage_respects_intentional_skip():
- schema = {"compiler": {"attrs": ["angle", "balanceinertia"]}}
- rules = {
- "compiler_attr_field_map": {"angle": "bAngleInDegrees"},
- "intentionally_unmodeled_compiler_attrs": ["balanceinertia"],
- }
- gen._check_compiler_attrs_coverage(schema, rules)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_mjxmacro_block_coverage_forward():
- rules = {
- "synthetic_categories": {
- "MjOption": {"mjxmacro_block": "MJOPTION_FIELDS"},
- },
- }
- mjxmacro = {
- "struct_fields": {
- "MJOPTION_FIELDS": [{"name": "timestep"}],
- "MJNEW_FIELDS": [{"name": "wat"}], # no rule entry
- },
- }
- gen._check_mjxmacro_block_coverage(rules, mjxmacro)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("MJNEW_FIELDS" in m for m in msgs)
- assert not any("MJOPTION_FIELDS" in m for m in msgs)
-
-
-def test_mjxmacro_block_coverage_reverse():
- rules = {
- "synthetic_categories": {
- "MjGhost": {"mjxmacro_block": "MJGHOST_FIELDS"},
- },
- }
- mjxmacro = {"struct_fields": {}}
- gen._check_mjxmacro_block_coverage(rules, mjxmacro)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("MJGHOST_FIELDS" in m and "MjGhost" in m for m in msgs)
-
-
-def test_mjs_array_caps_for_extracts_fixed_size_arrays():
- cat_rules = {"mjs_struct": "mjsActuator"}
- mjspec = {
- "introspect": {
- "structs": {
- "mjsActuator": {
- "fields": [
- {"name": "gainprm", "c_type": "double [10]", "array_dim": 10},
- {"name": "scalar", "c_type": "double", "array_dim": None},
- {"name": "noslot", "c_type": "double [1]", "array_dim": 1},
- ],
- },
- },
- },
- }
- caps = gen._mjs_array_caps_for(cat_rules, mjspec)
- assert caps == {"gainprm": 10}
diff --git a/Scripts/codegen/tests/test_objtype_dispatch.py b/Scripts/codegen/tests/test_objtype_dispatch.py
deleted file mode 100644
index b633c8f2..00000000
--- a/Scripts/codegen/tests/test_objtype_dispatch.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the ``objtype_dispatch`` rule shape — emits a switch on a
-UE enum that assigns each case's ``expr`` to ``target``."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-from generate_ue_components import _emit_objtype_dispatch_block
-
-
-def test_objtype_dispatch_emits_switch_with_default():
- cat_rules = {
- "type_enum_name": "EMjEqualityType",
- "objtype_dispatch": {
- "discriminator": "Type",
- "target": "Element->objtype",
- "default": "mjOBJ_UNKNOWN",
- "cases": [
- {"keys": ["Connect", "Weld"], "expr": "mjOBJ_BODY"},
- {"keys": ["Joint"], "expr": "mjOBJ_JOINT"},
- ],
- },
- }
- out = _emit_objtype_dispatch_block(cat_rules)
- assert "switch (Type)" in out
- assert "case EMjEqualityType::Connect:" in out
- assert "case EMjEqualityType::Weld:" in out
- assert "Element->objtype = mjOBJ_BODY;" in out
- assert "case EMjEqualityType::Joint:" in out
- assert "Element->objtype = mjOBJ_JOINT;" in out
- assert "default:" in out
- assert "Element->objtype = mjOBJ_UNKNOWN;" in out
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_objtype_dispatch_returns_none_when_no_rule():
- assert _emit_objtype_dispatch_block({}) is None
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_objtype_dispatch_diagnoses_missing_type_enum_name():
- out = _emit_objtype_dispatch_block({
- "objtype_dispatch": {
- "discriminator": "Type",
- "target": "Element->objtype",
- "cases": [{"keys": ["A"], "expr": "X"}],
- },
- })
- assert out is None
- assert any("type_enum_name" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_objtype_dispatch_diagnoses_empty_cases():
- out = _emit_objtype_dispatch_block({
- "type_enum_name": "EMjEqualityType",
- "objtype_dispatch": {
- "discriminator": "Type",
- "target": "Element->objtype",
- "cases": [],
- },
- })
- assert out is None
- assert any("no cases" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_objtype_dispatch_diagnoses_empty_keys():
- out = _emit_objtype_dispatch_block({
- "type_enum_name": "EMjEqualityType",
- "objtype_dispatch": {
- "discriminator": "Type",
- "target": "Element->objtype",
- "cases": [{"keys": [], "expr": "mjOBJ_BODY"}],
- },
- })
- assert out is None
- assert any("empty" in d.message and "keys" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_objtype_dispatch_diagnoses_missing_expr():
- out = _emit_objtype_dispatch_block({
- "type_enum_name": "EMjEqualityType",
- "objtype_dispatch": {
- "discriminator": "Type",
- "target": "Element->objtype",
- "cases": [{"keys": ["Connect"]}],
- },
- })
- assert out is None
- assert any("missing 'expr'" in d.message for d in gen._DIAGS_BUFFER.pending)
diff --git a/Scripts/codegen/tests/test_phase_2_6_checks.py b/Scripts/codegen/tests/test_phase_2_6_checks.py
deleted file mode 100644
index a9df2f8d..00000000
--- a/Scripts/codegen/tests/test_phase_2_6_checks.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the three new drift checks:
-``_check_apply_mode_validity``, ``_check_embedded_cpp_references``,
-and ``_check_allowlist_staleness`` (narrowed to 4 of 6 allowlists per
-the rule design)."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-import _codegen_checks as _checks
-gen._collect_every_schema_attr = _checks._collect_every_schema_attr
-
-
-# ---------- _check_apply_mode_validity -------------------------------------
-
-def test_apply_mode_unknown_value_fires_diag():
- """A typo'd mode (``"guarderd"`` instead of ``"guarded"``) would
- silently fall through to the unconditional branch — the check
- surfaces it before the codegen emits a bad write path."""
- rules = {
- "synthetic_categories": {
- "MjOption": {
- "field_apply_to_spec_mode": {"timestep": "guarderd"},
- },
- },
- }
- gen._check_apply_mode_validity(rules)
- assert any("guarderd" in d.message and "timestep" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_apply_mode_known_values_silent():
- rules = {
- "synthetic_categories": {
- "MjOption": {
- "field_apply_to_spec_mode": {
- "timestep": "unconditional",
- "gravity": "guarded_pos",
- "wind": "vec3_y_flip",
- },
- },
- },
- }
- gen._check_apply_mode_validity(rules)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_apply_mode_skips_note_keys():
- """The phase iterator must ignore ``_note_*`` sibling keys; they
- appear as strings, not dicts."""
- rules = {
- "synthetic_categories": {
- "_note_intent": "doc string for the section",
- "MjOption": {
- "field_apply_to_spec_mode": {"timestep": "unconditional"},
- },
- },
- }
- gen._check_apply_mode_validity(rules)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-# ---------- _check_embedded_cpp_references ---------------------------------
-
-def test_embedded_cpp_refs_flags_stale_mj_const():
- """``value_map[...][1]`` referencing a constant not in any mjspec
- enum is a UHT-bound failure — the check moves it forward into
- codegen-time."""
- rules = {
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "value_map": {
- "hinge": ["Hinge", "mjJNT_HINGE"],
- "screw": ["Screw", "mjJNT_FXED"], # typo
- },
- },
- },
- },
- },
- }
- mjspec = {"enums": {"mjtJoint": {"mjJNT_HINGE": 0, "mjJNT_SLIDE": 1}}}
- gen._check_embedded_cpp_references(rules, mjspec)
- assert any("mjJNT_FXED" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_embedded_cpp_refs_silent_on_real_const():
- rules = {
- "element_rules": {
- "joint": {
- "xml_enum_attrs": {
- "type": {
- "value_map": {
- "hinge": ["Hinge", "mjJNT_HINGE"],
- },
- },
- },
- },
- },
- }
- mjspec = {"enums": {"mjtJoint": {"mjJNT_HINGE": 0}}}
- gen._check_embedded_cpp_references(rules, mjspec)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_embedded_cpp_refs_flags_bad_geom_final_type_fallback():
- rules = {
- "categories": {
- "geom": {
- "geom_final_type": {
- "xml_enum_ref": "type",
- "override_field": "bOverride_Type",
- "default_lookup": "Default->Type",
- "default_fallback": "mjGEOM_FXED", # typo
- "name_field": "MeshName",
- "name_export_for": "mjGEOM_MESH",
- "name_target": "Element->mesh",
- "name_setter": "MjSetString",
- },
- },
- },
- }
- mjspec = {"enums": {"mjtGeom": {"mjGEOM_SPHERE": 0, "mjGEOM_MESH": 7}}}
- gen._check_embedded_cpp_references(rules, mjspec)
- assert any("mjGEOM_FXED" in d.message for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_embedded_cpp_refs_quiet_without_snapshot():
- """No mjspec / no enums -> can't check; the helper no-ops without
- crashing."""
- gen._check_embedded_cpp_references({}, None)
- assert len(gen._DIAGS_BUFFER.pending) == 0
- gen._check_embedded_cpp_references({}, {"enums": {}})
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-# ---------- _check_allowlist_staleness -------------------------------------
-
-def test_unmodeled_element_must_exist_in_schema():
- rules = {
- "intentionally_unmodeled_elements": {
- "skin": "URLab uses UE skeletal meshes instead",
- "phantom_element": "no longer exists", # stale
- },
- }
- schema = {"body": {"attrs": ["pos"]}, "skin": {"attrs": []}}
- gen._check_allowlist_staleness(schema, rules, None)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("phantom_element" in m and "no longer carries" in m for m in msgs)
- assert not any("'skin'" in m for m in msgs)
-
-
-def test_unmodeled_mjs_field_must_exist_on_struct():
- rules = {
- "intentionally_unmodeled_mjs_fields": {
- "mjsBody": ["explicitinertial", "phantom_field"],
- "mjsGhost": ["any"], # stale struct
- },
- }
- mjspec = {
- "structs": {"mjsBody": ["explicitinertial", "name", "parent"]},
- }
- gen._check_allowlist_staleness({}, rules, mjspec)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("phantom_field" in m and "mjsBody" in m for m in msgs)
- assert any("mjsGhost" in m for m in msgs)
- assert not any("'explicitinertial'" in m and "mjsBody" in m for m in msgs)
-
-
-def test_default_typed_attr_must_exist_somewhere_in_schema():
- rules = {
- "intentionally_default_typed_attrs": [
- "kp", # in actuator_types.position list
- "torquescale", # nested under equality.weld
- "phantom_attr", # stale
- ],
- }
- schema = {
- "actuator_types": {"position": ["kp", "kv"]},
- "equality": {"weld": ["torquescale", "anchor"]},
- }
- gen._check_allowlist_staleness(schema, rules, None)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("phantom_attr" in m for m in msgs)
- assert not any("'kp'" in m for m in msgs)
- assert not any("'torquescale'" in m for m in msgs)
-
-
-def test_unmapped_mj_enum_must_exist_in_mjspec():
- rules = {
- "intentionally_unmapped_mj_enum_values": {
- "mjtJoint": ["mjJNT_SLIDE"],
- "mjtGhost": ["mjGHOST_X"],
- "__per_element__": {"site.type": ["mjGEOM_PLANE"]}, # skipped
- },
- }
- mjspec = {"enums": {"mjtJoint": {"mjJNT_HINGE": 0, "mjJNT_SLIDE": 1}}}
- gen._check_allowlist_staleness({}, rules, mjspec)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("mjtGhost" in m for m in msgs)
- assert not any("mjtJoint" in m for m in msgs)
- # __per_element__ never fires its own staleness diag.
- assert not any("__per_element__" in m for m in msgs)
-
-
-# ---------- _collect_every_schema_attr ------------------------------------
-
-def test_collect_every_schema_attr_picks_up_three_shapes():
- """Cover the three list shapes the walker handles:
- nested-attrs key, flat list at any depth (actuator_types,
- equality.weld), nested-attrs inside sensor_types entries."""
- schema = {
- "body": {"attrs": ["pos", "quat"]},
- "actuator_types": {"position": ["kp", "kv"]},
- "equality": {"weld": ["torquescale"]},
- "sensor_types": [{"name": "accel", "attrs": ["cutoff"]}],
- }
- out = gen._collect_every_schema_attr(schema)
- for needed in ("pos", "quat", "kp", "kv", "torquescale", "cutoff"):
- assert needed in out, f"missing {needed} from {out}"
diff --git a/Scripts/codegen/tests/test_phase_context.py b/Scripts/codegen/tests/test_phase_context.py
deleted file mode 100644
index ea87bce8..00000000
--- a/Scripts/codegen/tests/test_phase_context.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the ``PhaseContext``. Every
-emission phase used to take 7 (or 8) positional args; they now take
-one ``PhaseContext`` so adding a new field to the pipeline doesn't
-touch a dozen signatures."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_every_emission_phase_accepts_phase_context():
- """Every entry in EMISSION_PHASES.fn must be callable with one
- PhaseContext arg. Catches refactor drift where one phase keeps the
- old 7-positional-arg signature."""
- ctx = gen.PhaseContext(
- schema={}, rules={}, mjxmacro={}, mjspec={},
- public_root="", private_root="", bind_h_path="",
- writes=[],
- )
- for phase in gen.EMISSION_PHASES:
- # No assertion on side effects — just that the call doesn't
- # TypeError on signature mismatch.
- phase.fn(ctx)
-
-
-def test_phase_context_is_dataclass_with_writes_list():
- """Quick sanity: ``writes`` must be a mutable list, not a frozen
- sequence — phases append to it."""
- ctx = gen.PhaseContext(
- schema={}, rules={}, mjxmacro={}, mjspec={},
- public_root="", private_root="", bind_h_path="",
- writes=[],
- )
- ctx.writes.append("sentinel")
- assert ctx.writes == ["sentinel"]
-
-
-# Unknown-layout diagnostic is pinned in test_inject_helpers::test_layout_dispatch_diagnoses_unknown_layout.
diff --git a/Scripts/codegen/tests/test_property_units.py b/Scripts/codegen/tests/test_property_units.py
deleted file mode 100644
index a7a904be..00000000
--- a/Scripts/codegen/tests/test_property_units.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the editor display-unit rule shapes: ``property_units``
-(UE-native ``Units="m"`` meta on scalars, custom ``MjUnit="m"`` on
-TArrays), ``hidden_attrs`` / ``hidden_canon_properties``
-(EditConditionHides), and the validity drift check."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_property_units_emits_units_meta_on_scalar():
- """Scalar/struct UE types get UE-native meta=(Units="...")."""
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {"margin": "float"},
- "canonicalizations": {},
- "element_rules": {
- "geom": {"property_units": {"margin": "m"}},
- },
- }
- out = gen.emit_schema_for_attrs(["margin"], rules, "geom", "Geom")
- assert 'Units="m"' in out.properties_h, out.properties_h
- assert out.properties_h.count('Units="m"') == 1
-
-
-def test_property_units_emits_mjunit_meta_on_tarray():
- """TArray UE types get MjUnit="..." — UHT rejects Units on arrays;
- URLab's detail customization reads MjUnit at runtime."""
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {"size": "TArray"},
- "canonicalizations": {},
- "element_rules": {
- "geom": {"property_units": {"size": "m"}},
- },
- }
- out = gen.emit_schema_for_attrs(["size"], rules, "geom", "Geom")
- assert 'MjUnit="m"' in out.properties_h, out.properties_h
- assert 'Units="m"' not in out.properties_h
-
-
-def test_property_units_coexists_with_property_meta():
- """Units composes with existing property_meta (e.g. DisplayName)
- without one clobbering the other."""
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {},
- "canonicalizations": {},
- "element_rules": {
- "geom": {
- "property_meta": {"foo": 'DisplayName="Foo Bar"'},
- "property_units": {"foo": "m"},
- },
- },
- }
- out = gen.emit_schema_for_attrs(["foo"], rules, "geom", "Geom")
- assert 'DisplayName="Foo Bar"' in out.properties_h
- assert 'Units="m"' in out.properties_h
-
-
-def test_property_units_validity_diagnoses_bad_unit():
- rules = {
- "element_rules": {
- "geom": {"property_units": {"size": "meters"}},
- },
- }
- gen._check_property_units_validity(rules)
- assert any("'meters'" in d.message and "geom" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_property_units_validity_silent_on_known_units():
- rules = {
- "element_rules": {
- "geom": {"property_units": {"size": "m", "fovy": "deg"}},
- },
- }
- gen._check_property_units_validity(rules)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-def test_hidden_attrs_emits_edit_condition_hides():
- """hidden_attrs entries emit EditCondition=false + EditConditionHides
- so the field stays in C++ but the Details panel widget vanishes."""
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {"size": "TArray"},
- "canonicalizations": {},
- "element_rules": {
- "geom": {"hidden_attrs": ["size"]},
- },
- }
- out = gen.emit_schema_for_attrs(["size"], rules, "geom", "Geom")
- assert 'EditCondition="false"' in out.properties_h
- assert 'EditConditionHides' in out.properties_h
-
-
-def test_hidden_canon_properties_emits_edit_condition_hides():
- rules = {
- "global_exclusions": [],
- "default_type": "float",
- "property_renames": {},
- "type_mappings": {},
- "canonicalizations": {
- "spatial_pose": {
- "absorbs_attrs": ["pos"],
- "emits_property": {"name": "Pos", "type": "FVector"},
- "import_helper": "X",
- "export_helper": "Y",
- },
- },
- "element_rules": {
- "geom": {
- "applies_canonicalizations": ["spatial_pose"],
- "hidden_canon_properties": ["spatial_pose"],
- },
- },
- }
- out = gen.emit_schema_for_attrs([], rules, "geom", "Geom")
- assert 'FVector Pos' in out.properties_h
- assert 'EditConditionHides' in out.properties_h
diff --git a/Scripts/codegen/tests/test_regen_no_diff.py b/Scripts/codegen/tests/test_regen_no_diff.py
deleted file mode 100644
index fdea920d..00000000
--- a/Scripts/codegen/tests/test_regen_no_diff.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Golden-file gate.
-
-Runs ``generate_ue_components.py --check`` against the real schema /
-mjxmacro / rules / mjspec snapshots and asserts:
- 1. Every emitted file is byte-identical to what's on disk (exit 0).
- 2. The run produced zero diagnostics in stderr — catches new warn-mode
- drift introduced by a rule change that the byte-identity check
- can't see (drift fires on stderr without changing the emit output).
-"""
-
-from __future__ import annotations
-
-import os
-import subprocess
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_GENERATOR = os.path.normpath(os.path.join(_HERE, "..", "generate_ue_components.py"))
-
-
-def test_codegen_check_clean() -> None:
- """`generate_ue_components.py --check` exits 0 with no diagnostics."""
- proc = subprocess.run(
- [sys.executable, _GENERATOR, "--check"],
- capture_output=True,
- text=True,
- )
- stdout = proc.stdout or ""
- stderr = proc.stderr or ""
- assert proc.returncode == 0, (
- "codegen drift detected: re-running the generator would rewrite one or "
- "more on-disk files. Re-run `python Scripts/codegen/generate_ue_components.py` "
- "to regenerate, or update the emit functions if hand-edits to "
- "CODEGEN_*_START/END regions slipped past the generator.\n"
- f"--- stdout ---\n{stdout}\n--- stderr ---\n{stderr}"
- )
- # Diagnostics fire on stderr without changing emit output — catches the
- # warn-mode drift class that the byte-identity check is blind to.
- assert "[diagnostic]" not in stderr, (
- "codegen ran clean (no file rewrites) but emitted one or more "
- "diagnostics. A rule entry or snapshot likely drifted; rules JSON or "
- "an intentionally_* allowlist needs updating.\n"
- f"--- stderr ---\n{stderr}"
- )
diff --git a/Scripts/codegen/tests/test_require_introspect.py b/Scripts/codegen/tests/test_require_introspect.py
deleted file mode 100644
index 92c975d9..00000000
--- a/Scripts/codegen/tests/test_require_introspect.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Verifies the ``--require-introspect`` flag's exit-code contract.
-
-The clang-AST introspect snapshot drives the embedded-C++ drift checks
-(value_map / hand-enum / mjs_array shape). Letting codegen silently fall
-back to a stale or missing snapshot turned subtle rule typos into runtime
-fall-through; this flag is the hard-fail gate.
-
-These tests shell out to ``generate_ue_components.py`` so the real
-``main()`` arg-parsing + early-exit branches are exercised.
-"""
-
-from __future__ import annotations
-
-import os
-import subprocess
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-_PLUGIN_ROOT = os.path.dirname(os.path.dirname(_CODEGEN_DIR))
-_GENERATOR = os.path.join(_CODEGEN_DIR, "generate_ue_components.py")
-
-
-def _run(extra_args: list[str], introspect_path: str) -> subprocess.CompletedProcess:
- return subprocess.run(
- [sys.executable, _GENERATOR,
- "--check", "--introspect", introspect_path,
- *extra_args],
- capture_output=True, text=True, cwd=_PLUGIN_ROOT,
- )
-
-
-def test_require_introspect_default_hard_fails_when_missing(tmp_path):
- """Default behaviour (no flag = require_introspect=True) MUST exit
- non-zero with the documented exit code (3) when the snapshot is
- absent. Closes the silent-fallback path."""
- missing = str(tmp_path / "introspect_snapshot.json")
- assert not os.path.exists(missing)
- proc = _run([], missing)
- assert proc.returncode == 3, (
- f"expected exit 3, got {proc.returncode}\n"
- f"stdout={proc.stdout!r}\nstderr={proc.stderr!r}"
- )
- assert "introspect snapshot missing" in proc.stderr
-
-
-def test_no_require_introspect_skips_the_exit_3_gate(tmp_path):
- """``--no-require-introspect`` skips the up-front exit-3 hard-fail
- so the run reaches the codegen loop. The loop itself raises
- downstream once it needs the setto signatures the introspect
- carries — the flag isn't a way to make the codegen succeed
- without introspect, it's a way to defer the failure for triage."""
- missing = str(tmp_path / "introspect_snapshot.json")
- proc = _run(["--no-require-introspect"], missing)
- # The up-front gate didn't fire (exit 3), and the run reached the
- # loop. Exit 1 (the downstream RuntimeError) is the documented
- # failure mode.
- assert proc.returncode != 3
- assert "warning" in proc.stderr.lower()
- assert "introspect snapshot missing" in proc.stderr
diff --git a/Scripts/codegen/tests/test_resolve_mjs_field.py b/Scripts/codegen/tests/test_resolve_mjs_field.py
deleted file mode 100644
index 8aa80421..00000000
--- a/Scripts/codegen/tests/test_resolve_mjs_field.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks ``_resolve_mjs_field``'s 5-step resolution chain and the
-per-strategy helpers. Each strategy lives in
-its own function and is composed via ``_MJS_FIELD_RESOLVERS``."""
-
-from __future__ import annotations
-
-import _codegen_core as gen # private resolver surface lives in _codegen_core
-
-
-# ---------- per-strategy resolvers ----------------------------------------
-
-def test_resolve_direct_match():
- assert gen._resolve_direct("condim", {"condim", "type"}) == "condim"
- assert gen._resolve_direct("absent", {"other"}) is None
-
-
-def test_resolve_name_suffix():
- """MuJoCo name-ref fields uniformly append 'name'."""
- assert gen._resolve_name_suffix("mesh", {"meshname"}) == "meshname"
- assert gen._resolve_name_suffix("scalar", {"scalarvalue"}) is None
-
-
-def test_resolve_root_name_digits_variants():
- """``body1`` -> ``bodyname1`` and the underscore variant
- ``body_name1`` both resolve."""
- assert gen._resolve_root_name_digits("body1", {"bodyname1"}) == "bodyname1"
- assert gen._resolve_root_name_digits("body1", {"body_name1"}) == "body_name1"
- # No-digit suffix -> no match.
- assert gen._resolve_root_name_digits("body", {"bodyname"}) is None
-
-
-def test_resolve_underscore_norm_matches_drop_underscores():
- assert gen._resolve_underscore_norm("solreflimit", {"solref_limit"}) == "solref_limit"
- assert gen._resolve_underscore_norm("solreflimit", {"solref_friction"}) is None
-
-
-def test_resolve_actuator_prefix_with_underscore_norm():
- """schema ``actuatorfrclimited`` -> mjs ``actfrclimited`` (direct)
- or ``act_frc_limited`` (via underscore norm)."""
- assert gen._resolve_actuator_prefix("actuatorfrclimited", {"actfrclimited"}) == "actfrclimited"
- assert gen._resolve_actuator_prefix("actuatorfrclimited", {"act_frc_limited"}) == "act_frc_limited"
- assert gen._resolve_actuator_prefix("notanactuator", {"anything"}) is None
-
-
-# ---------- composition through _resolve_mjs_field ------------------------
-
-def test_resolve_mjs_field_prefers_override_table():
- """Per-element ``attr_to_mjs_field`` rules ALWAYS win — no
- convention can override a rule author's explicit mapping."""
- out = gen._resolve_mjs_field(
- "target", {"target", "targetbody"},
- attr_to_mjs_field={"target": "targetbody"},
- )
- assert out == "targetbody"
-
-
-def test_resolve_mjs_field_falls_through_strategy_order():
- """Each strategy fires in declared order; only the first match
- wins. Strategies that don't apply return None and fall through."""
- # No direct match; falls through to root+name+digits.
- out = gen._resolve_mjs_field("body1", {"bodyname1", "geomname1"})
- assert out == "bodyname1"
-
-
-def test_resolve_mjs_field_falls_back_to_attr_when_nothing_matches():
- """If every strategy returns None, return the attr verbatim — the
- downstream C++ build will fail loudly on the bad field name."""
- out = gen._resolve_mjs_field(
- "novel_attr", {"unrelated_field"},
- )
- assert out == "novel_attr"
-
-
-def test_resolve_mjs_field_empty_fields_returns_attr():
- """When ``mjs_fields`` is empty, no resolution is possible — the
- attr passes through unchanged."""
- assert gen._resolve_mjs_field("any", set()) == "any"
-
-
-def test_resolvers_tuple_is_module_constant():
- """The resolver chain order must be a module-level constant so a
- test can assert it explicitly. Catches accidental reordering that
- would change which strategy wins on ambiguous inputs."""
- assert gen._MJS_FIELD_RESOLVERS == (
- gen._resolve_direct,
- gen._resolve_name_suffix,
- gen._resolve_root_name_digits,
- gen._resolve_underscore_norm,
- gen._resolve_actuator_prefix,
- )
diff --git a/Scripts/codegen/tests/test_rule_iter_helpers.py b/Scripts/codegen/tests/test_rule_iter_helpers.py
deleted file mode 100644
index d2e92c40..00000000
--- a/Scripts/codegen/tests/test_rule_iter_helpers.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the rule-iteration helpers ``compute_canon_absorbed`` /
-``iter_canon_absorbed`` / ``iter_category_attrs``. They are the single
-source of truth for the standard three-skip exclusion gate that every
-per-attr emission site used to inline."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-import _codegen_core as _core
-gen.iter_canon_absorbed = _core.iter_canon_absorbed
-
-
-# ---------- iter_canon_absorbed / compute_canon_absorbed -------------------
-
-def test_compute_canon_absorbed_unions_applied_canons():
- canons = {
- "spatial_pose": {"absorbs_attrs": ["pos", "quat", "euler", "axisangle"]},
- "fromto_decompose": {"absorbs_attrs": ["fromto"]},
- "unused": {"absorbs_attrs": ["other"]},
- }
- got = gen.compute_canon_absorbed(["spatial_pose", "fromto_decompose"], canons)
- assert got == {"pos", "quat", "euler", "axisangle", "fromto"}
- # An unapplied canon stays out — gating is by applies_canonicalizations.
- assert "other" not in got
-
-
-def test_compute_canon_absorbed_silent_on_missing_canon():
- canons = {"spatial_pose": {"absorbs_attrs": ["pos"]}}
- got = gen.compute_canon_absorbed(["spatial_pose", "ghost_canon"], canons)
- assert got == {"pos"}
-
-
-def test_compute_canon_absorbed_handles_empty_inputs():
- assert gen.compute_canon_absorbed([], {}) == set()
- assert gen.compute_canon_absorbed(["any"], {}) == set()
- assert gen.compute_canon_absorbed([], {"spatial_pose": {"absorbs_attrs": ["pos"]}}) == set()
-
-
-def test_iter_canon_absorbed_is_lazy_view():
- canons = {"c": {"absorbs_attrs": ["a", "b"]}}
- it = gen.iter_canon_absorbed(["c"], canons)
- # Confirm it's an iterator, not a materialised list — call sites that
- # only want a single membership check shouldn't pay for a list build.
- assert iter(it) is it
- assert list(it) == ["a", "b"]
-
-
-# ---------- iter_category_attrs --------------------------------------------
-
-def test_iter_category_attrs_filters_three_gates():
- attrs = ["a", "b", "c", "d", "e"]
- got = list(gen.iter_category_attrs(
- attrs,
- global_excl={"a"},
- elem_excl={"b"},
- canon_absorbed={"c"},
- ))
- assert got == ["d", "e"]
-
-
-def test_iter_category_attrs_preserves_order():
- """Codegen output depends on attr order — schema order must survive
- the filter so emitted .h/.cpp stay byte-identical to the schema."""
- attrs = ["zeta", "alpha", "mu"]
- got = list(gen.iter_category_attrs(
- attrs, global_excl=set(), elem_excl=set(), canon_absorbed=set(),
- ))
- assert got == ["zeta", "alpha", "mu"]
-
-
-def test_iter_category_attrs_handles_empty_attrs():
- got = list(gen.iter_category_attrs(
- [], global_excl={"a"}, elem_excl=set(), canon_absorbed=set(),
- ))
- assert got == []
diff --git a/Scripts/codegen/tests/test_rule_shape_contract.py b/Scripts/codegen/tests/test_rule_shape_contract.py
deleted file mode 100644
index fc1cd6f9..00000000
--- a/Scripts/codegen/tests/test_rule_shape_contract.py
+++ /dev/null
@@ -1,326 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Contract tests for codegen_rules.json. The rules file is the
-single source of truth for the codegen — these tests pin the
-structural invariants every emitter depends on, so a hand-edit
-that breaks them surfaces in pytest instead of as a UE compile
-failure far downstream."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen # noqa: F401 (kept for module discovery)
-from _codegen_core import _UE_TYPE_INFO
-
-
-_KNOWN_TOP_LEVEL_KEYS = {
- # data driving the emit path
- "global_exclusions",
- "default_type",
- "property_renames",
- "setto_param_defaults",
- "type_mappings",
- "categories",
- "element_rules",
- "canonicalizations",
- "synthetic_categories",
- "generated_enums",
- "editor_option_helpers",
- "views",
- # drift-suppression allowlists
- "intentionally_unmodeled_elements",
- "intentionally_unmodeled_mjs_fields",
- "intentionally_unmodeled_compiler_attrs",
- "intentionally_default_typed_attrs",
- "intentionally_unmapped_mj_enum_values",
- # shared per-rule namespaces
- "compiler_attr_field_map",
-}
-
-
-def test_top_level_keys_are_recognised(real_rules):
- """Every top-level key in the rules JSON is either a known shape
- or a ``_note_*`` sibling string. Catches typo'd renames at edit
- time."""
- unknown = []
- for key in real_rules:
- if key.startswith("_") or key in _KNOWN_TOP_LEVEL_KEYS:
- continue
- unknown.append(key)
- assert not unknown, (
- f"unknown top-level keys in codegen_rules.json: {unknown}. "
- f"Either add them to _KNOWN_TOP_LEVEL_KEYS in this test or "
- f"_note_-prefix them to mark as documentation."
- )
-
-
-def test_every_category_carries_required_keys(real_rules):
- """Every entry under ``categories`` needs a schema_common_block.
- Missing the block silently produces an empty emit; the test
- surfaces the missing key at JSON-edit time."""
- for cat, cat_rules in real_rules.get("categories", {}).items():
- if cat.startswith("_"):
- continue
- assert "schema_common_block" in cat_rules, (
- f"category '{cat}' missing schema_common_block")
-
-
-def test_canonicalisations_referenced_by_element_rules_exist(real_rules):
- """element_rules[X].applies_canonicalizations must list canon
- names that exist in the top-level ``canonicalizations`` block.
- Otherwise per-element XML import silently drops absorbed attrs."""
- canon_keys = set(real_rules.get("canonicalizations", {}).keys())
- for elem, elem_rule in real_rules.get("element_rules", {}).items():
- for canon in elem_rule.get("applies_canonicalizations", []):
- assert canon in canon_keys, (
- f"element_rules['{elem}'].applies_canonicalizations "
- f"references '{canon}' which is not declared in the "
- f"top-level canonicalizations block.")
-
-
-def test_xml_enum_attr_value_maps_have_correct_shape(real_rules):
- """Each ``value_map`` entry must be a 2-element ``[ue_member,
- mj_const]`` list, non-empty xml key, and the map itself non-empty.
- An empty map silently emits a dead block that toggles the override
- flag without ever assigning the enum; empty xml keys match every
- missing attr at runtime via ``GetAttribute()`` returning ``""``."""
- for elem, elem_rule in real_rules.get("element_rules", {}).items():
- for attr, enum_def in elem_rule.get("xml_enum_attrs", {}).items():
- value_map = enum_def.get("value_map", {})
- assert value_map, (
- f"element_rules['{elem}'].xml_enum_attrs['{attr}']"
- f".value_map is empty — emit would set the override "
- f"toggle without ever assigning the enum.")
- for xml_val, mapping in value_map.items():
- assert xml_val != "", (
- f"element_rules['{elem}'].xml_enum_attrs['{attr}']"
- f".value_map has an empty-string xml key — at "
- f"runtime this matches every missing attr.")
- assert isinstance(mapping, (list, tuple)), (
- f"element_rules['{elem}'].xml_enum_attrs['{attr}']"
- f".value_map['{xml_val}'] must be a list, got "
- f"{type(mapping).__name__}")
- assert len(mapping) == 2, (
- f"element_rules['{elem}'].xml_enum_attrs['{attr}']"
- f".value_map['{xml_val}'] must be "
- f"[ue_member, mj_const]; got {mapping!r}")
-
-
-def test_synthetic_categories_carry_block_or_skip_flag(real_rules):
- """Every synthetic_categories entry must either name an
- mjxmacro_block or carry a disabled flag. A bare entry would
- silently emit nothing."""
- synth = real_rules.get("synthetic_categories", {})
- for cat_name, def_ in synth.items():
- if cat_name.startswith("_") or not isinstance(def_, dict):
- continue
- assert def_.get("mjxmacro_block") or def_.get("disabled"), (
- f"synthetic_categories['{cat_name}'] needs either an "
- f"mjxmacro_block or a disabled flag")
-
-
-# ---------- inner-key shape contracts ----------------------------------
-#
-# The top-level allowlist catches typo'd renames at the rules root, but
-# inner-key typos (e.g. ``attr_to_mjs_fields`` instead of
-# ``attr_to_mjs_field``) silently fall through every reader's
-# ``.get(..., {})``. The contracts below close that loop: every reader
-# fetches by bracketed access against the keys listed here, so a typo
-# surfaces in pytest instead of as a KeyError mid-emit (or worse — a
-# silent no-op that ships wrong-runtime C++).
-
-
-_CATEGORY_REQUIRED = {"schema_common_block", "base_class_name", "base_class_header", "mjs_struct"}
-_CATEGORY_OPTIONAL = {
- "subtypes", "layout", "subtype_setto", "type_enum_name",
- "schema_subtypes_block", "schema_common_extra_attrs",
- "objtype_dispatch", "geom_final_type", "applies_canonicalizations",
- "subclass_directory_pub", "subclass_directory_priv",
- "xml_passthrough_emission", "disable_mjs_export_emission",
-}
-_SUBTYPE_REQUIRED = {"key", "enum_value", "class_name"}
-_SUBTYPE_OPTIONAL = {
- "header", "fully_emitted", "case_body_override", "extra_constructor",
-}
-_ELEMENT_RULE_OPTIONAL = {
- "exclude_attrs", "applies_canonicalizations", "xml_enum_attrs",
- "attr_to_mjs_field", "property_renames", "property_meta",
- "property_units", "property_defaults", "target_collations",
- "common_imports", "mjs_data_packed_attrs", "mjs_double_vec_attrs",
- "sentinel_skip_export", "export_skip_attrs", "unit_conversion",
- "vec3_convert", "hidden_canon_properties", "hidden_attrs",
- "canon_export_skip", "xml_passthrough_emission", "common_attrs",
- "field_apply_to_spec_mode", "field_defaults",
-}
-_XML_ENUM_ATTR_REQUIRED = {"ue_property", "ue_enum_type", "value_map"}
-_XML_ENUM_ATTR_OPTIONAL = {
- "mjs_field", "mjs_cast", "has_override_toggle",
- "emit_property_decl", "property_default", "property_meta",
- "from_mj_enum",
-}
-_CANON_REQUIRED = {"absorbs_attrs"}
-_CANON_OPTIONAL = {
- "emits_property", "category_specifics",
- "import_helper", "export_helper",
-}
-
-
-def _assert_inner_keys(path: str, obj: dict, required: set, optional: set):
- for k in required:
- assert k in obj, f"{path}: missing required key '{k}'"
- allowed = required | optional
- bad = [k for k in obj if not k.startswith("_") and k not in allowed]
- assert not bad, (
- f"{path}: unknown key(s) {bad}. Either add to the contract "
- f"allowlist in test_rule_shape_contract.py or _note_-prefix "
- f"as documentation."
- )
-
-
-def test_category_inner_keys_match_contract(real_rules):
- for cat, cat_rules in real_rules.get("categories", {}).items():
- if cat.startswith("_"):
- continue
- _assert_inner_keys(
- f"categories['{cat}']", cat_rules,
- _CATEGORY_REQUIRED, _CATEGORY_OPTIONAL,
- )
-
-
-def test_category_subtype_inner_keys_match_contract(real_rules):
- for cat, cat_rules in real_rules.get("categories", {}).items():
- if cat.startswith("_"):
- continue
- for i, sub in enumerate(cat_rules.get("subtypes", [])):
- if not isinstance(sub, dict):
- continue
- _assert_inner_keys(
- f"categories['{cat}'].subtypes[{i}] ({sub.get('key', '?')})",
- sub, _SUBTYPE_REQUIRED, _SUBTYPE_OPTIONAL,
- )
-
-
-def test_element_rule_inner_keys_match_contract(real_rules):
- for elem, elem_rule in real_rules.get("element_rules", {}).items():
- if elem.startswith("_"):
- continue
- _assert_inner_keys(
- f"element_rules['{elem}']", elem_rule,
- set(), _ELEMENT_RULE_OPTIONAL,
- )
-
-
-def test_xml_enum_attr_inner_keys_match_contract(real_rules):
- for elem, elem_rule in real_rules.get("element_rules", {}).items():
- for attr, enum_def in elem_rule.get("xml_enum_attrs", {}).items():
- if not isinstance(enum_def, dict):
- continue
- _assert_inner_keys(
- f"element_rules['{elem}'].xml_enum_attrs['{attr}']",
- enum_def,
- _XML_ENUM_ATTR_REQUIRED, _XML_ENUM_ATTR_OPTIONAL,
- )
-
-
-def test_canonicalisation_inner_keys_match_contract(real_rules):
- for canon, canon_def in real_rules.get("canonicalizations", {}).items():
- if canon.startswith("_"):
- continue
- _assert_inner_keys(
- f"canonicalizations['{canon}']", canon_def,
- _CANON_REQUIRED, _CANON_OPTIONAL,
- )
-
-
-def test_synthetic_category_required_public_header(real_rules):
- """Every active synthetic_categories entry needs ``public_header``
- pointing under ``MuJoCo/Generated/``. Missing key would KeyError at
- emit; a stray absolute path would write outside the plugin tree."""
- for cat_name, def_ in real_rules.get("synthetic_categories", {}).items():
- if cat_name.startswith("_") or not isinstance(def_, dict):
- continue
- if def_.get("disabled"):
- continue
- assert "public_header" in def_, (
- f"synthetic_categories['{cat_name}']: missing public_header"
- )
- ph = def_["public_header"]
- assert ph.startswith("MuJoCo/Generated/") and ph.endswith(".h"), (
- f"synthetic_categories['{cat_name}'].public_header = "
- f"'{ph}' must be 'MuJoCo/Generated/*.h'"
- )
-
-
-def test_generated_enums_carry_ue_name_and_mapping(real_rules):
- """generated_enums entries must declare ue_name (starts with EMj)
- and at least one mapping source (ue_member_from_mj or
- extra_members)."""
- for group, group_def in real_rules.get("generated_enums", {}).items():
- if group.startswith("_") or not isinstance(group_def, dict):
- continue
- for i, entry in enumerate(group_def.get("enums", [])):
- if entry.get("disabled"):
- continue
- ue_name = entry.get("ue_name", "")
- assert ue_name.startswith("EMj"), (
- f"generated_enums['{group}'].enums[{i}].ue_name = "
- f"'{ue_name}' must start with 'EMj'"
- )
- has_mj = entry.get("from_mj_enum")
- has_members = entry.get("ue_member_from_mj") or entry.get("extra_members")
- assert has_mj or has_members, (
- f"generated_enums['{group}'].enums[{i}] ({ue_name}): "
- f"needs from_mj_enum or extra_members; otherwise emits "
- f"nothing."
- )
-
-
-def test_setto_param_defaults_are_finite_numeric_literals(real_rules):
- """Values land VERBATIM in the generated C++ as a ternary's else
- branch (see ``_emit_setto_call``). Allowed shapes: int / signed-or-
- -unsigned float with optional decimal + exponent. Reject ``"inf"``,
- ``"nan"``, hex, or empty strings — they compile to non-finite or
- invalid C++."""
- import re
- finite_re = re.compile(r"^-?\d+(\.\d*)?([eE][+-]?\d+)?$")
- defaults = real_rules.get("setto_param_defaults", {})
- for fn_name, params in defaults.items():
- if fn_name.startswith("_") or not isinstance(params, dict):
- continue
- for pname, value in params.items():
- assert isinstance(value, str), (
- f"setto_param_defaults['{fn_name}']['{pname}'] = "
- f"{value!r}: must be a string (drops verbatim into C++)"
- )
- assert finite_re.match(value), (
- f"setto_param_defaults['{fn_name}']['{pname}'] = "
- f"'{value}': must be a finite decimal literal "
- f"('inf' / 'nan' / hex / empty rejected)"
- )
-
-
-def test_type_mappings_use_known_ue_types(real_rules):
- """Every type in type_mappings must be a UE type the codegen
- can emit (i.e. resolves through _UE_TYPE_INFO or is a known
- TArray<...>). Surfacing typo'd types here catches "TArray"
- long before UHT fails."""
- known = set(_UE_TYPE_INFO.keys())
- for attr, ue_type in real_rules.get("type_mappings", {}).items():
- if attr.startswith("_"):
- continue
- if ue_type in known:
- continue
- if ue_type.startswith("TArray<") and ue_type.endswith(">"):
- inner = ue_type[len("TArray<"):-1]
- assert (inner in known or inner.startswith("U")
- or inner.startswith("EMj")), (
- f"type_mappings['{attr}'] = '{ue_type}' has unknown "
- f"inner type '{inner}'")
- continue
- # URLab-side hand-rolled enums (EMj*) are legitimate UPROPERTY
- # types but live outside the registry's UE type universe.
- if ue_type.startswith("EMj"):
- continue
- # Unrecognised types fall through to default_type with a diag;
- # the test surfaces the JSON-edit-time intent.
- assert False, (
- f"type_mappings['{attr}'] = '{ue_type}' is not a "
- f"recognised UE type")
diff --git a/Scripts/codegen/tests/test_sensor_per_type_extractor.py b/Scripts/codegen/tests/test_sensor_per_type_extractor.py
deleted file mode 100644
index 3197e0cf..00000000
--- a/Scripts/codegen/tests/test_sensor_per_type_extractor.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Unit tests for the per-sensor objtype/reftype extractor in
-build_mjcf_schema_snapshot.py.
-
-The extractor scrapes xml_native_reader.cc's ``Sensor()`` if/else cascade
-so codegen rules don't have to hand-list each sensor's mjsSensor object
-defaults. Tests cover the four shape classes the extractor produces:
-literal default, from_xml, computed (multi-attr derivation), and the
-nested-branch suppression case (distance/normal/fromto share an outer
-branch whose inner ``if`` would otherwise overwrite the entry).
-"""
-
-from __future__ import annotations
-
-import os
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-
-from build_mjcf_schema_snapshot import _extract_sensor_per_type # noqa: E402
-
-
-_FAKE_SOURCE = r"""
-void mjXReader::Sensor(XMLElement* section) {
- while (elem) {
- mjsSensor* sensor = mjs_addSensor(spec);
- string type = elem->Value();
- string text, name, objname, refname;
-
- if (type == "touch") {
- sensor->type = mjSENS_TOUCH;
- sensor->objtype = mjOBJ_SITE;
- ReadAttrTxt(elem, "site", objname, true);
- } else if (type == "framepos") {
- sensor->type = mjSENS_FRAMEPOS;
- ReadAttrTxt(elem, "objtype", text, true);
- sensor->objtype = (mjtObj)mju_str2Type(text.c_str());
- ReadAttrTxt(elem, "objname", objname, true);
- if (ReadAttrTxt(elem, "reftype", text)) {
- sensor->reftype = (mjtObj)mju_str2Type(text.c_str());
- ReadAttrTxt(elem, "refname", refname, true);
- }
- } else if (type == "distance" || type == "normal" || type == "fromto") {
- bool has_body1 = ReadAttrTxt(elem, "body1", objname);
- sensor->objtype = has_body1 ? mjOBJ_BODY : mjOBJ_GEOM;
- ReadAttrTxt(elem, "body2", refname);
- sensor->reftype = mjOBJ_BODY;
- if (type == "distance") {
- sensor->type = mjSENS_GEOMDIST;
- } else if (type == "normal") {
- sensor->type = mjSENS_GEOMNORMAL;
- } else {
- sensor->type = mjSENS_GEOMFROMTO;
- }
- } else if (type == "clock") {
- sensor->type = mjSENS_CLOCK;
- sensor->objtype = mjOBJ_UNKNOWN;
- }
- elem = NextSiblingElement(elem);
- }
-}
-"""
-
-
-def test_literal_objtype_with_site_name_read():
- result = _extract_sensor_per_type(_FAKE_SOURCE)
- assert result["touch"] == {
- "mj_type": "mjSENS_TOUCH",
- "objtype": "mjOBJ_SITE",
- "reftype": None,
- "obj_attr": "site",
- "ref_attr": None,
- "computed": False,
- }
-
-
-def test_from_xml_objtype_picks_up_objname_attr():
- result = _extract_sensor_per_type(_FAKE_SOURCE)
- framepos = result["framepos"]
- assert framepos["objtype"] == "from_xml"
- assert framepos["obj_attr"] == "objname"
- assert framepos["ref_attr"] == "refname"
- assert framepos["computed"] is False
-
-
-def test_multi_name_branch_emits_one_entry_per_name():
- result = _extract_sensor_per_type(_FAKE_SOURCE)
- for name in ("distance", "normal", "fromto"):
- assert name in result, f"missing {name}"
- assert result[name]["computed"] is True
- assert result[name]["objtype"] == "computed"
- # All three share the same body1/body2 attr-read.
- assert result[name]["obj_attr"] == "body1"
- assert result[name]["ref_attr"] == "body2"
-
-
-def test_inner_if_inside_multi_name_branch_does_not_overwrite():
- """Regression: the body of the distance/normal/fromto branch contains
- ``if (type == "distance")`` and ``else if (type == "normal")`` which set
- only ->type. Those inner matches would override the outer entry's
- obj_attr/ref_attr with None if the extractor walked them naively."""
- result = _extract_sensor_per_type(_FAKE_SOURCE)
- assert result["distance"]["obj_attr"] == "body1"
- assert result["normal"]["obj_attr"] == "body1"
-
-
-def test_clock_has_unknown_objtype_no_name_read():
- result = _extract_sensor_per_type(_FAKE_SOURCE)
- assert result["clock"] == {
- "mj_type": "mjSENS_CLOCK",
- "objtype": "mjOBJ_UNKNOWN",
- "reftype": None,
- "obj_attr": None,
- "ref_attr": None,
- "computed": False,
- }
-
-
-def test_missing_sensor_method_returns_empty():
- assert _extract_sensor_per_type("// no Sensor method here") == {}
-
-
-# ---------- sensor switch + TagToType codegen ----------------------------
-
-def test_sensor_switch_body_emits_static_objtype_when_present():
- from generate_ue_components import _emit_sensor_switch_block # noqa
- cat_rules = {
- "type_enum_name": "EMjSensorType",
- "subtypes": [
- {"key": "touch", "enum_value": "Touch"},
- {"key": "framepos", "enum_value": "FramePos"},
- ],
- }
- sensor_per_type = {
- "touch": {"mj_type": "mjSENS_TOUCH", "objtype": "mjOBJ_SITE", "reftype": None},
- "framepos": {"mj_type": "mjSENS_FRAMEPOS", "objtype": "from_xml", "reftype": None},
- "accelerometer": {"mj_type": "mjSENS_ACCELEROMETER", "objtype": "mjOBJ_SITE", "reftype": None},
- }
- out = _emit_sensor_switch_block(cat_rules, sensor_per_type)
- # Touch gets static objtype literal.
- assert "case EMjSensorType::Touch: Element->type = mjSENS_TOUCH; Element->objtype = mjOBJ_SITE; break;" in out
- # framepos has objtype=from_xml -> NO static objtype emitted (handled in post-switch block).
- assert "case EMjSensorType::FramePos: Element->type = mjSENS_FRAMEPOS; break;" in out
- # Default fallback is hard-wired to accelerometer.
- assert "default: Element->type = mjSENS_ACCELEROMETER; Element->objtype = mjOBJ_SITE; break;" in out
-
-
-def test_sensor_switch_body_honours_case_override():
- from generate_ue_components import _emit_sensor_switch_block
- cat_rules = {
- "type_enum_name": "EMjSensorType",
- "subtypes": [
- {"key": "rangefinder", "enum_value": "RangeFinder",
- "case_body_override": "Element->type = mjSENS_RANGEFINDER; Element->objtype = X;"},
- ],
- }
- out = _emit_sensor_switch_block(cat_rules, {"rangefinder": {"mj_type": "mjSENS_RANGEFINDER"}})
- # Override appears verbatim; the emitter's automatic mj_type / objtype
- # lines are SKIPPED for this case.
- assert "Element->objtype = X;" in out
- assert out.count("RangeFinder") >= 1
-
-
-def test_sensor_tag_to_type_map_uses_xml_key_verbatim():
- from generate_ue_components import _emit_sensor_tag_to_type_block
- cat_rules = {
- "type_enum_name": "EMjSensorType",
- "subtypes": [
- {"key": "touch", "enum_value": "Touch"},
- {"key": "e_potential", "enum_value": "EPotential"},
- {"key": "jointactuatorfrc", "enum_value": "JointActFrc"},
- ],
- }
- out = _emit_sensor_tag_to_type_block(cat_rules)
- assert '{TEXT("touch"), EMjSensorType::Touch},' in out
- # Underscore-containing XML keys preserved literally.
- assert '{TEXT("e_potential"), EMjSensorType::EPotential},' in out
- # XML key and UE enum_value can diverge; map uses XML key.
- assert '{TEXT("jointactuatorfrc"), EMjSensorType::JointActFrc},' in out
-
-
-def test_real_snapshot_covers_every_schema_sensor():
- """End-to-end: the snapshot shipped in Scripts/ should have one
- per_type entry for every sensor_types entry — and vice versa. Catches
- drift between the static MJCF[] schema and the parser cascade."""
- import json
- plugin_root = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
- snap = json.load(open(os.path.join(plugin_root, "Scripts", "codegen", "snapshots", "mjcf_schema_snapshot.json")))
- schema_names = set(snap["sensor_types"])
- per_type_names = set(snap.get("sensor_per_type", {}).keys())
- assert schema_names == per_type_names, (
- f"schema/per_type drift: only-in-schema={sorted(schema_names - per_type_names)}; "
- f"only-in-per_type={sorted(per_type_names - schema_names)}"
- )
diff --git a/Scripts/codegen/tests/test_setto_introspection.py b/Scripts/codegen/tests/test_setto_introspection.py
deleted file mode 100644
index 9e20e496..00000000
--- a/Scripts/codegen/tests/test_setto_introspection.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Regression guard for introspected mjs_setTo* emission.
-
-The 9 hand-written C++ literal blocks that used to live in
-``codegen_rules.json`` were replaced by ``_emit_setto_call``, which derives
-the call body from the parsed mjs_setTo* signature. The signature now
-comes from the clang-AST introspect snapshot, projected into the
-legacy mjspec shape via ``_mjspec_from_introspect``."""
-
-from __future__ import annotations
-
-import json
-import os
-
-from generate_ue_components import _emit_setto_call, _mjspec_from_introspect
-
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_PLUGIN_ROOT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
-
-
-def _load_mjspec():
- with open(os.path.join(_PLUGIN_ROOT, "Scripts", "codegen", "snapshots", "introspect_snapshot.json"), "r") as f:
- return _mjspec_from_introspect(json.load(f))
-
-
-def _setto_for(subtype_key, real_rules, real_schema, mjspec):
- """Helper: invoke _emit_setto_call with the rules-real args for one actuator subtype."""
- actuator = real_rules["categories"]["actuator"]
- setto_rules = actuator["subtype_setto"].get(subtype_key)
- if setto_rules is None:
- return ""
- per_type_attrs = real_schema["actuator_types"].get(subtype_key, [])
- base_attrs = real_schema.get("actuator_common", {}).get("attrs", [])
- return _emit_setto_call(
- subtype_key, setto_rules, real_rules, mjspec,
- subtype_schema_attrs=per_type_attrs, base_schema_attrs=base_attrs,
- )
-
-
-def test_motor_call_minimal(real_rules, real_schema):
- """Motor's setTo has no params besides Element — output is a one-liner."""
- mjspec = _load_mjspec()
- out = _setto_for("motor", real_rules, real_schema, mjspec)
- assert "mjs_setToMotor(Element);" in out
-
-
-def test_position_inherits_kp_and_nulls_unset_pointers(real_rules, real_schema):
- """Position's kv/dampratio/timeconst are double[1] in C and nullable: the
- buffer is built but passed only when overridden, else nullptr. kp is written
- unconditionally by MuJoCo, so an unset kp re-asserts the inherited element
- gain. inheritrange keeps its 0.0 sentinel (MuJoCo guards it with `> 0`)."""
- mjspec = _load_mjspec()
- out = _setto_for("position", real_rules, real_schema, mjspec)
- assert "double kvBuf[1] = { bOverride_kv ? (double)kv : -1.0 };" in out
- assert "double dampratioBuf[1] = { bOverride_dampratio ? (double)dampratio : -1.0 };" in out
- # kp is unconditional-by-value -> re-assert the inherited gain, not -1.0.
- assert "bOverride_kp ? (double)kp : Element->gainprm[0]" in out
- # Pointer params passed only when authored, else nullptr (MuJoCo's unset
- # convention) so the class default survives.
- assert "bOverride_kv ? kvBuf : nullptr" in out
- assert "bOverride_dampratio ? dampratioBuf : nullptr" in out
- # timeconst is TArray-backed: an authored-but-empty array is unset too.
- assert "(bOverride_timeconst && timeconst.Num() > 0) ? timeconstBuf : nullptr" in out
- # inheritrange override sentinel from setto_param_defaults.
- assert "bOverride_inheritrange ? (double)inheritrange : 0.0" in out
- assert "mjs_setToPosition(Element," in out
-
-
-def test_unconditional_gain_params_reassert_inherited_field(real_rules, real_schema):
- """velocity/adhesion/damper each write a single gain slot unconditionally.
- An unset param must re-assert the inherited element field so a class default
- (e.g. under a ) is preserved, not clobbered
- to a sentinel. damper's kv maps to -gainprm[2] (setToDamper does gainprm[2]
- = -kv), so the re-assert carries the sign."""
- mjspec = _load_mjspec()
- assert "bOverride_kv ? (double)kv : Element->gainprm[0]" in \
- _setto_for("velocity", real_rules, real_schema, mjspec)
- assert "bOverride_gain ? (double)gain : Element->gainprm[0]" in \
- _setto_for("adhesion", real_rules, real_schema, mjspec)
- assert "bOverride_kv ? (double)kv : -Element->gainprm[2]" in \
- _setto_for("damper", real_rules, real_schema, mjspec)
-
-
-def test_setto_call_surfaces_error_return(real_rules, real_schema):
- """Every mjs_setTo* return string is checked and logged, not discarded —
- that discarded return is what hid the gain-clobber bug for so long."""
- mjspec = _load_mjspec()
- for sub in ("position", "velocity", "cylinder", "motor"):
- out = _setto_for(sub, real_rules, real_schema, mjspec)
- assert "const char* SetToErr =" in out
- assert "if (SetToErr && *SetToErr)" in out
-
-
-def test_muscle_scale_projection_and_tausmooth_zero(real_rules, real_schema):
- """Muscle's scale (TArray) is collapsed to a scalar for the
- setTo call — we take element [0]. tausmooth has the 0.0 sentinel
- (so MuJoCo treats unset as 'no smoothing', not 'broken default')."""
- mjspec = _load_mjspec()
- out = _setto_for("muscle", real_rules, real_schema, mjspec)
- assert "(bOverride_scale && scale.Num() > 0) ? (double)scale[0] : -1.0" in out
- assert "bOverride_tausmooth ? (double)tausmooth : 0.0" in out
- assert "double timeconstBuf[2]" in out
- assert "double rangeBuf[2]" in out
-
-
-def test_dcmotor_nullable_arrays_use_filldouble_and_input_rename(real_rules, real_schema):
- """DCMotor passes nullptr when arrays not overridden; uses FillDouble
- helper. input_mode (C param) -> input (UE prop) rename."""
- mjspec = _load_mjspec()
- out = _setto_for("dcmotor", real_rules, real_schema, mjspec)
- assert "FillDouble(motorconstBuf, motorconst)" in out
- assert "bOverride_motorconst ? motorconstBuf : nullptr" in out
- # input_mode -> input rename: the C arg name in the signature is input_mode,
- # but the UE-side property is `input`. The expression must reference `input`,
- # not `input_mode`.
- assert "bOverride_input ? (int)input : 0" in out
- # resistance has 0.0 sentinel per setto_param_defaults.
- assert "bOverride_resistance ? (double)resistance : 0.0" in out
-
-
-def test_intvelocity_inherits_kp_and_nulls_unset_pointers(real_rules, real_schema):
- """IntVelocity writes gainprm[0] = kp unconditionally, so an unset kp must
- re-assert the inherited element value, not a sentinel that clobbers it.
- timeconst (not in the intvelocity schema) is a nullable pointer param, so it
- passes nullptr — MuJoCo then leaves the type-derived default alone."""
- mjspec = _load_mjspec()
- out = _setto_for("intvelocity", real_rules, real_schema, mjspec)
- assert "double kvBuf[1]" in out
- # kp is unconditional-by-value -> re-assert the inherited gain, not -1.0.
- assert "bOverride_kp ? (double)kp : Element->gainprm[0]" in out
- # timeconst nullable + not authored -> bare nullptr, no sentinel buffer.
- assert "double timeconstBuf" not in out
- assert "nullptr" in out
- # kv/dampratio are nullable too: buffer built, but passed only when set.
- assert "bOverride_kv ? kvBuf : nullptr" in out
-
-
-def test_cylinder_reasserts_inherited_gain_fields(real_rules, real_schema):
- """Cylinder writes dynprm[0]/biasprm[0]/gainprm[0] unconditionally, so unset
- timeconst/bias/area re-assert the inherited element field rather than a -1
- sentinel that would clobber the class default. diameter keeps its sentinel
- because MuJoCo guards it with `>= 0`."""
- mjspec = _load_mjspec()
- out = _setto_for("cylinder", real_rules, real_schema, mjspec)
- assert "(bOverride_timeconst && timeconst.Num() > 0) ? (double)timeconst[0] : Element->dynprm[0]" in out
- assert "bOverride_bias ? (double)bias : Element->biasprm[0]" in out
- assert "bOverride_area ? (double)area : Element->gainprm[0]" in out
- assert "bOverride_diameter ? (double)diameter : -1.0" in out
diff --git a/Scripts/codegen/tests/test_should_emit_xml_enum_at_layer.py b/Scripts/codegen/tests/test_should_emit_xml_enum_at_layer.py
deleted file mode 100644
index 8bff7f11..00000000
--- a/Scripts/codegen/tests/test_should_emit_xml_enum_at_layer.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks the two-case ``_should_emit_xml_enum_at_this_layer`` decision
-the previous closure inside ``emit_schema_for_attrs`` encoded
-implicitly:
- - subtype-specific xml_enum attrs fire on the subtype's own emission
- - "type"-like globally-excluded xml_enum attrs fire on the base
- (apply_canonicalizations=True) layer."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_attr_in_attrs_list_fires_at_any_layer():
- """Subtype case — dcmotor.input is a subtype attr the base doesn't
- carry; the subtype layer (apply_canonicalizations=False) owns it."""
- assert gen._should_emit_xml_enum_at_this_layer(
- "input", attrs=["input"], global_excl=set(),
- apply_canonicalizations=False,
- )
- assert gen._should_emit_xml_enum_at_this_layer(
- "input", attrs=["input"], global_excl=set(),
- apply_canonicalizations=True,
- )
-
-
-def test_globally_excluded_attr_fires_only_on_base_layer():
- """Always-at-base case — joint.type is globally excluded from
- per-attr UPROPERTY emission but xml_enum still owns its import/
- export at the base. Subtype layer must NOT re-emit it (would cause
- duplicate switch case + UHT shadowing)."""
- assert gen._should_emit_xml_enum_at_this_layer(
- "type", attrs=[], global_excl={"type"},
- apply_canonicalizations=True,
- )
- assert not gen._should_emit_xml_enum_at_this_layer(
- "type", attrs=[], global_excl={"type"},
- apply_canonicalizations=False,
- )
-
-
-def test_unrelated_attr_never_fires():
- assert not gen._should_emit_xml_enum_at_this_layer(
- "stranger", attrs=["unrelated"], global_excl={"other"},
- apply_canonicalizations=True,
- )
diff --git a/Scripts/codegen/tests/test_strict_exit_code.py b/Scripts/codegen/tests/test_strict_exit_code.py
deleted file mode 100644
index 08c9d0b3..00000000
--- a/Scripts/codegen/tests/test_strict_exit_code.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Verifies that ``--strict`` (the default) maps fired diagnostics to
-exit code 2. ``--no-strict`` lets the same rules surface diagnostics
-without failing the run — local-triage workflow.
-
-These tests drive the public DiagBuffer surface directly rather than
-shelling out so they stay deterministic across CI without a libclang
-install (the introspect snapshot is read from disk regardless of CI
-state)."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def test_strict_exit_2_when_diagnostics_fire():
- """A single diagnostic + ``--strict`` semantics yields exit 2 in
- main()'s gate path. We simulate by adding to the buffer, flushing,
- and reading the gate's input — ``_DIAGS_BUFFER.fired_count``."""
- gen._reset_diags()
- gen._diag_add("[diagnostic] test", source="unit_test")
- gen._diag_flush()
- fired = gen._DIAGS_BUFFER.fired_count
- assert fired == 1
- # The gate in main() is: `if args.strict and fired: return 2`.
- # That predicate is true here -> exit code would be 2.
- assert fired > 0
-
-
-def test_strict_exit_0_when_no_diagnostics():
- gen._reset_diags()
- gen._diag_flush()
- assert gen._DIAGS_BUFFER.fired_count == 0
-
-
-def test_reset_diags_clears_both_pending_and_fired_count():
- gen._diag_add("[diagnostic] alpha", source="unit_test")
- gen._diag_flush()
- assert gen._DIAGS_BUFFER.fired_count >= 1
- gen._reset_diags()
- assert gen._DIAGS_BUFFER.fired_count == 0
- assert gen._DIAGS_BUFFER.pending == []
diff --git a/Scripts/codegen/tests/test_subclass_emission.py b/Scripts/codegen/tests/test_subclass_emission.py
deleted file mode 100644
index 959bbed1..00000000
--- a/Scripts/codegen/tests/test_subclass_emission.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Subclass file emission tests (single_uclass_per_file layout)."""
-
-from __future__ import annotations
-
-import json
-import os
-import tempfile
-
-import pytest
-
-from generate_ue_components import emit_subclass_files
-
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_PLUGIN_ROOT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
-
-
-def _find_writes(writes, suffix):
- return [w for w in writes if w.path.endswith(suffix)]
-
-
-def test_actuator_subclass_count(real_schema, real_rules, real_mjspec):
- cat_rules = real_rules["categories"]["actuator"]
- writes = emit_subclass_files(
- "actuator", cat_rules, real_schema, real_rules,
- "/tmp/pub", "/tmp/priv", mjspec=real_mjspec,
- )
- # 10 subtypes * 2 (h + cpp) = 20 writes.
- assert len(writes) == 20
- # Every advertised class_name has an .h.
- for st in cat_rules["subtypes"]:
- assert _find_writes(writes, st["header"]), f"missing {st['header']}"
-
-
-def test_sensor_subclass_count(real_schema, real_rules):
- cat_rules = real_rules["categories"]["sensor"]
- writes = emit_subclass_files(
- "sensor", cat_rules, real_schema, real_rules,
- "/tmp/pub", "/tmp/priv",
- )
- # 49 subtypes * 2 = 98 writes.
- assert len(writes) == 98
-
-
-def test_subclass_header_has_codegen_tags(real_schema, real_rules):
- cat_rules = real_rules["categories"]["joint"]
- writes = emit_subclass_files(
- "joint", cat_rules, real_schema, real_rules, "/tmp/pub", "/tmp/priv",
- )
- hinge_h = _find_writes(writes, "MjHingeJoint.h")[0]
- assert "// --- CODEGEN_PROPERTIES_START ---" in hinge_h.content
- assert "// --- CODEGEN_PROPERTIES_END ---" in hinge_h.content
- assert "GENERATED_BODY()" in hinge_h.content
- # Inherits base class.
- assert ": public UMjJoint" in hinge_h.content
-
-
-def test_subclass_source_has_super_export(real_schema, real_rules):
- cat_rules = real_rules["categories"]["joint"]
- writes = emit_subclass_files(
- "joint", cat_rules, real_schema, real_rules, "/tmp/pub", "/tmp/priv",
- )
- hinge_cpp = _find_writes(writes, "MjHingeJoint.cpp")[0]
- # ImportFromXml chains to Super.
- assert "Super::ImportFromXml(Node, CompilerSettings);" in hinge_cpp.content
- # ExportTo chains to Super.
- assert "Super::ExportTo(Element, Default);" in hinge_cpp.content
- # Constructor sets the right enum.
- assert "Type = EMjJointType::Hinge;" in hinge_cpp.content
-
-
-def test_actuator_subclass_calls_mjs_set_to(real_schema, real_rules, real_mjspec):
- cat_rules = real_rules["categories"]["actuator"]
- writes = emit_subclass_files(
- "actuator", cat_rules, real_schema, real_rules,
- "/tmp/pub", "/tmp/priv", mjspec=real_mjspec,
- )
- motor_cpp = _find_writes(writes, "MjMotorActuator.cpp")[0]
- # The introspected setto emitter places ``mjs_setToMotor(Element);`` at
- # the TOP of the CODEGEN_EXPORT block. Super::ExportTo is called BEFORE
- # the codegen block (so that base attrs are written before subtype
- # presets). Both orderings used to be claimed in different places of the
- # generator — assert the current actual behaviour.
- src = motor_cpp.content
- set_idx = src.index("mjs_setToMotor(Element);")
- super_idx = src.index("Super::ExportTo(Element, Default);")
- # Super first, then setto preset.
- assert super_idx < set_idx
- # No ApplyRawOverrides call anywhere.
- assert "ApplyRawOverrides" not in src
-
-
-def test_new_geom_subtypes_emitted(real_schema, real_rules):
- cat_rules = real_rules["categories"]["geom"]
- writes = emit_subclass_files(
- "geom", cat_rules, real_schema, real_rules, "/tmp/pub", "/tmp/priv",
- )
- for new_subtype in ("MjEllipsoid.h", "MjPlane.h", "MjSdf.h"):
- assert _find_writes(writes, new_subtype), f"missing geom subtype {new_subtype}"
-
-
-def test_new_sensor_subtypes_emitted(real_schema, real_rules):
- cat_rules = real_rules["categories"]["sensor"]
- writes = emit_subclass_files(
- "sensor", cat_rules, real_schema, real_rules, "/tmp/pub", "/tmp/priv",
- )
- for new_subtype in ("MjUserSensor.h", "MjPluginSensor.h"):
- assert _find_writes(writes, new_subtype), f"missing sensor subtype {new_subtype}"
diff --git a/Scripts/codegen/tests/test_synthetic_categories.py b/Scripts/codegen/tests/test_synthetic_categories.py
deleted file mode 100644
index 6ed0d6ee..00000000
--- a/Scripts/codegen/tests/test_synthetic_categories.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""
-Tests for the synthetic_categories emitter.
-
-Emits one banner-mode .h file per entry from an mjxmacro X-macro field
-list. Covers MjStatistic, MjOption, the 6 MjVisual_* structs, plus
-MjsCompilerOptions and MjsSpec.
-"""
-
-from __future__ import annotations
-
-import os
-import sys
-
-_HERE = os.path.dirname(os.path.abspath(__file__))
-_CODEGEN_DIR = os.path.dirname(_HERE)
-if _CODEGEN_DIR not in sys.path:
- sys.path.insert(0, _CODEGEN_DIR)
-
-from generate_ue_components import ( # noqa: E402
- _emit_synthetic_struct_files,
- _ue_field_name,
-)
-
-
-def test_ue_field_name_pascal_cases_snake_input():
- assert _ue_field_name("timestep") == "Timestep"
- assert _ue_field_name("ls_iterations") == "LsIterations"
- assert _ue_field_name("sleep_tolerance") == "SleepTolerance"
- # Single component stays capitalised.
- assert _ue_field_name("extent") == "Extent"
-
-
-def test_synthetic_struct_emits_uproperty_per_field():
- mjxmacro = {
- "struct_fields": {
- "TEST_FIELDS": [
- {"type": "mjtNum", "name": "timestep", "count": "1", "is_vec": False},
- {"type": "int", "name": "iterations", "count": "1", "is_vec": False},
- {"type": "float", "name": "gravity", "count": "3", "is_vec": True},
- ],
- },
- }
- def_ = {
- "ue_struct_name": "FTestStruct",
- "mjxmacro_block": "TEST_FIELDS",
- "c_struct_type": "mjTest",
- "public_header": "MuJoCo/Generated/MjTest.h",
- "private_source": "MuJoCo/Generated/MjTest.cpp",
- "category_label": "Test",
- "exclude_fields": [],
- "per_field_meta": {},
- "urlab_extra_fields": [],
- }
- writes = _emit_synthetic_struct_files(
- "MjTest", def_, mjxmacro, public_root="/tmp/pub", private_root="/tmp/priv",
- )
- assert len(writes) == 1
- h = writes[0].content
- # USTRUCT outline.
- assert "USTRUCT(BlueprintType)" in h
- assert "struct URLAB_API FTestStruct" in h
- # Each field gets its toggle + value pair.
- assert "bOverride_Timestep" in h
- assert "double Timestep" in h
- assert "bOverride_Iterations" in h
- assert "int32 Iterations" in h
- # is_vec + count==3 -> FVector.
- assert "FVector Gravity" in h
- # Category labels use the rule's category_label.
- assert 'Category = "MuJoCo|Test"' in h
- # ApplyTo body assigns each field with a static_cast.
- assert "Dst.timestep = static_cast(Timestep);" in h
- assert "Dst.gravity[0] = static_cast(Gravity.X);" in h
-
-
-def test_synthetic_struct_skips_excluded_fields():
- mjxmacro = {
- "struct_fields": {
- "TEST_FIELDS": [
- {"type": "int", "name": "keep_me", "count": "1", "is_vec": False},
- {"type": "int", "name": "drop_me", "count": "1", "is_vec": False},
- ],
- },
- }
- def_ = {
- "ue_struct_name": "F",
- "mjxmacro_block": "TEST_FIELDS",
- "public_header": "P/F.h",
- "private_source": "P/F.cpp",
- "category_label": "C",
- "exclude_fields": ["drop_me"],
- "per_field_meta": {},
- }
- writes = _emit_synthetic_struct_files("X", def_, mjxmacro, "/tmp/pub", "/tmp/priv")
- h = writes[0].content
- assert "KeepMe" in h
- assert "DropMe" not in h
-
-
-def test_synthetic_struct_field_rename_overrides_default():
- """``field_renames`` lets rules pin a non-default UE name (e.g. URLab's
- historical CCD_Iterations vs default CcdIterations)."""
- mjxmacro = {
- "struct_fields": {
- "T_FIELDS": [
- {"type": "int", "name": "ccd_iterations", "count": "1", "is_vec": False},
- ],
- },
- }
- def_ = {
- "ue_struct_name": "FT",
- "mjxmacro_block": "T_FIELDS",
- "public_header": "P/T.h",
- "private_source": "P/T.cpp",
- "category_label": "T",
- "field_renames": {"ccd_iterations": "CCD_Iterations"},
- }
- writes = _emit_synthetic_struct_files("MjT", def_, mjxmacro, "/tmp/pub", "/tmp/priv")
- h = writes[0].content
- assert "CCD_Iterations" in h
- assert "CcdIterations" not in h
-
-
-def test_synthetic_struct_skips_when_mjxmacro_block_missing():
- """Defensive: a typo in mjxmacro_block produces a diagnostic, not a
- crash, and emits no file."""
- from generate_ue_components import _DIAGS_BUFFER, _reset_diags
- _reset_diags()
- mjxmacro = {"struct_fields": {}}
- def_ = {
- "ue_struct_name": "F", "mjxmacro_block": "NONEXISTENT",
- "public_header": "P/F.h", "private_source": "P/F.cpp",
- "category_label": "C",
- }
- writes = _emit_synthetic_struct_files("M", def_, mjxmacro, "/tmp/pub", "/tmp/priv")
- assert writes == []
- assert any("NONEXISTENT" in d.message for d in _DIAGS_BUFFER.pending)
- _reset_diags()
-
-
-def test_generated_enum_emits_uenum_per_entry():
- from generate_ue_components import _emit_generated_enum_file
- mjspec = {"enums": {
- "mjtIntegrator": {"mjINT_EULER": 0, "mjINT_RK4": 1, "mjINT_IMPLICIT": 2},
- }}
- def_ = {
- "public_header": "Generated/MjOptionEnums.h",
- "enums": [{
- "ue_name": "EMjIntegrator",
- "from_mj_enum": "mjtIntegrator",
- "ue_member_from_mj": {
- "mjINT_EULER": "Euler",
- "mjINT_RK4": "RK4",
- "mjINT_IMPLICIT": "Implicit",
- },
- }],
- }
- writes = _emit_generated_enum_file("MjOptionEnums", def_, mjspec, "/tmp/pub")
- assert len(writes) == 1
- h = writes[0].content
- assert "UENUM(BlueprintType)" in h
- assert "enum class EMjIntegrator : uint8" in h
- assert "Euler = 0" in h
- assert "RK4 = 1" in h
- assert "Implicit = 2" in h
-
-
-def test_generated_enum_skips_when_mj_enum_missing():
- from generate_ue_components import _emit_generated_enum_file, _DIAGS_BUFFER, _reset_diags
- _reset_diags()
- mjspec = {"enums": {}}
- def_ = {
- "public_header": "P/H.h",
- "enums": [{"ue_name": "E", "from_mj_enum": "mjtMissing", "ue_member_from_mj": {}}],
- }
- writes = _emit_generated_enum_file("X", def_, mjspec, "/tmp/pub")
- assert writes == []
- assert any("mjtMissing" in d.message for d in _DIAGS_BUFFER.pending)
- _reset_diags()
-
-
-def test_generated_enum_member_without_mapping_silently_skipped():
- """C enums often have sentinel constants (mjNGEOMTYPES) that don't
- map to UE. Rule author omits them from ue_member_from_mj; emitter
- skips them without diagnostics."""
- from generate_ue_components import _emit_generated_enum_file
- mjspec = {"enums": {"mjtX": {"mjX_A": 0, "mjX_SENTINEL": 1, "mjX_B": 2}}}
- def_ = {
- "public_header": "P/H.h",
- "enums": [{
- "ue_name": "EMjX", "from_mj_enum": "mjtX",
- "ue_member_from_mj": {"mjX_A": "A", "mjX_B": "B"},
- }],
- }
- h = _emit_generated_enum_file("X", def_, mjspec, "/tmp/pub")[0].content
- assert "A = 0" in h
- # B retains its original value 2 (skipped sentinel doesn't renumber).
- assert "B = 2" in h
- assert "Sentinel" not in h
-
-
-def test_real_snapshot_mjstatistic_pilot():
- """End-to-end: the shipped rule produces a syntactically plausible
- .h file. UE compile separately verifies it actually builds."""
- import json
- plugin_root = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
- h_path = os.path.join(plugin_root, "Source", "URLab", "Public",
- "MuJoCo", "Generated", "MjStatistic.h")
- assert os.path.exists(h_path), "MjStatistic.h was not generated"
- with open(h_path, "r", encoding="utf-8") as f:
- h = f.read()
- # Pilot fields from MJSTATISTIC_FIELDS.
- for ue_name in ("Meaninertia", "Meanmass", "Meansize", "Extent", "Center"):
- assert ue_name in h, f"missing field {ue_name}"
- # ApplyTo is templated so it works against both mjStatistic and any
- # alias type. Compile correctness is verified by UE's build step.
- assert "template " in h
- assert "void ApplyTo(TDst& Dst) const" in h
diff --git a/Scripts/codegen/tests/test_type_shape_drift.py b/Scripts/codegen/tests/test_type_shape_drift.py
deleted file mode 100644
index 99c4fd59..00000000
--- a/Scripts/codegen/tests/test_type_shape_drift.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for the type-shape reconcile + new-attr fail-loud checks.
-
-Covers ``_classify_c_type`` (C-type kind classifier), ``_shapes_compatible``
-(UE-vs-C shape gate), ``_check_type_shape_drift`` (rule-vs-introspect
-cross-check), and ``_check_new_attr_typing`` (every schema attr must
-be typed or explicitly default-acknowledged)."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-import _codegen_core as _core
-import _codegen_checks as _checks
-
-# Stitch test-only re-exports onto `gen` so the assertions below keep
-# their compact ``gen._classify_c_type`` form. The orchestrator's import
-# block intentionally no longer carries these — they're private to
-# _codegen_core / _codegen_checks.
-gen._classify_c_type = _core._classify_c_type
-gen._shapes_compatible = _core._shapes_compatible
-gen._check_type_shape_drift = _checks._check_type_shape_drift
-gen._check_new_attr_typing = _checks._check_new_attr_typing
-
-
-# ---------- _classify_c_type ------------------------------------------------
-
-def test_classify_c_type_scalar_num():
- assert gen._classify_c_type("double", None) == ("scalar", "num")
- assert gen._classify_c_type("mjtNum", None) == ("scalar", "num")
- assert gen._classify_c_type("float", 1) == ("scalar", "num")
-
-
-def test_classify_c_type_vec_dim():
- assert gen._classify_c_type("double [3]", 3) == ("vec", 3)
- assert gen._classify_c_type("mjtNum [4]", 4) == ("vec", 4)
-
-
-def test_classify_c_type_dynamic_vec_pointer():
- """mjFloatVec* / mjDoubleVec* are dynamic-length vectors, NOT
- opaque pointers — must classify as ('array', None) so TArray
- rules match cleanly."""
- assert gen._classify_c_type("mjDoubleVec *", None) == ("array", None)
- assert gen._classify_c_type("mjFloatVec *", None) == ("array", None)
-
-
-def test_classify_c_type_opaque_element_pointer():
- """mjsElement* is the parent-spec back-pointer URLab never models;
- classify as opaque so the shape check skips it."""
- assert gen._classify_c_type("mjsElement *", None) == ("opaque", None)
-
-
-def test_classify_c_type_string_pointer():
- assert gen._classify_c_type("mjString", None) == ("scalar", "string")
- assert gen._classify_c_type("char *", None) == ("scalar", "string")
-
-
-# ---------- _shapes_compatible ----------------------------------------------
-
-def test_shapes_compatible_array_matches_vec():
- """TArray at the UE layer is the universal carrier for
- fixed-size C arrays — codegen writes prop.Num() elements and the
- common case is len(prop) <= C cap."""
- assert gen._shapes_compatible(("array", None), ("vec", 3))
- assert gen._shapes_compatible(("array", None), ("array", None))
-
-
-def test_shapes_compatible_scalar_vs_array_is_mismatch():
- assert not gen._shapes_compatible(("scalar", "num"), ("vec", 3))
- assert not gen._shapes_compatible(("array", None), ("scalar", "num"))
- assert not gen._shapes_compatible(("vec", 3), ("vec", 4))
-
-
-# ---------- _check_type_shape_drift ----------------------------------------
-
-def test_type_shape_drift_flags_scalar_vs_array_mismatch():
- """Rule says TArray but the introspect struct field is a
- scalar mjtNum — diagnostic fires; emitted code would not compile
- correctly."""
- rules = {
- "type_mappings": {"stiffness": "TArray"},
- "categories": {
- "joint": {"mjs_struct": "mjsJoint"},
- },
- }
- mjspec = {
- "introspect": {
- "structs": {
- "mjsJoint": {
- "fields": [
- {"name": "stiffness", "c_type": "double",
- "array_dim": None, "is_pointer": False},
- ],
- },
- },
- },
- }
- gen._check_type_shape_drift({}, rules, mjspec)
- assert any("stiffness" in d.message and "mismatch" in d.message
- for d in gen._DIAGS_BUFFER.pending)
-
-
-def test_type_shape_drift_quiet_on_unmodeled_field():
- """A field listed in intentionally_unmodeled_mjs_fields is not
- emitted by codegen — drift check must NOT fire on it."""
- rules = {
- "type_mappings": {"damping": "TArray"},
- "categories": {
- "flexcomp": {"mjs_struct": "mjsFlex"},
- },
- "intentionally_unmodeled_mjs_fields": {
- "mjsFlex": ["damping"],
- },
- }
- mjspec = {
- "introspect": {
- "structs": {
- "mjsFlex": {
- "fields": [
- {"name": "damping", "c_type": "double",
- "array_dim": None, "is_pointer": False},
- ],
- },
- },
- },
- }
- gen._check_type_shape_drift({}, rules, mjspec)
- assert len(gen._DIAGS_BUFFER.pending) == 0
-
-
-# ---------- _check_new_attr_typing -----------------------------------------
-
-def test_new_attr_typing_flags_unmapped_attr():
- schema = {
- "joint": {"attrs": ["stiffness", "novel_attr"]},
- }
- rules = {
- "type_mappings": {"stiffness": "TArray"},
- "default_type": "float",
- "global_exclusions": [],
- "intentionally_default_typed_attrs": [],
- "element_rules": {"joint": {}},
- "canonicalizations": {},
- "categories": {
- "joint": {"schema_common_block": "joint.attrs"},
- },
- }
- gen._check_new_attr_typing(schema, rules)
- msgs = [d.message for d in gen._DIAGS_BUFFER.pending]
- assert any("novel_attr" in m and "joint" in m for m in msgs), msgs
- # stiffness is typed -> no diag.
- assert not any("'stiffness'" in m for m in msgs)
-
-
-def test_new_attr_typing_respects_intentional_default():
- schema = {"sensor": {"attrs": ["cutoff"]}}
- rules = {
- "type_mappings": {},
- "default_type": "float",
- "global_exclusions": [],
- "intentionally_default_typed_attrs": ["cutoff"],
- "element_rules": {"sensor": {}},
- "canonicalizations": {},
- "categories": {
- "sensor": {"schema_common_block": "sensor.attrs"},
- },
- }
- gen._check_new_attr_typing(schema, rules)
- assert len(gen._DIAGS_BUFFER.pending) == 0
diff --git a/Scripts/codegen/tests/test_ue_type_registry.py b/Scripts/codegen/tests/test_ue_type_registry.py
deleted file mode 100644
index 2b938e51..00000000
--- a/Scripts/codegen/tests/test_ue_type_registry.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Locks the ``_UE_TYPE_INFO`` registry as the single source of truth
-for every UE type codegen emits. Prevents the previous failure mode
-where ``_attr_default_value`` / ``_UE_TYPE_FAMILY`` / ``Units``-meta
-gates each declared their own type list and drifted apart."""
-
-from __future__ import annotations
-
-from _codegen_core import (
- _UE_TYPE_INFO, _UE_TYPE_FAMILY, _UE_TYPES_ACCEPTING_UNITS_META,
- _attr_default_value, _ue_type_accepts_units_meta,
-)
-
-
-def test_ue_type_family_is_view_over_registry():
- """``_UE_TYPE_FAMILY`` (drift-check input) must be a faithful view
- over ``_UE_TYPE_INFO`` — same keys, same shape values."""
- assert set(_UE_TYPE_FAMILY.keys()) == set(_UE_TYPE_INFO.keys())
- for k, info in _UE_TYPE_INFO.items():
- assert _UE_TYPE_FAMILY[k] == info.shape, k
-
-
-def test_units_meta_set_is_view_over_registry():
- expected = {k for k, v in _UE_TYPE_INFO.items() if v.accepts_units_meta}
- assert _UE_TYPES_ACCEPTING_UNITS_META == expected
-
-
-def test_attr_default_value_uses_registry():
- for ue_type, info in _UE_TYPE_INFO.items():
- assert _attr_default_value(ue_type) == info.default_init, ue_type
-
-
-def test_attr_default_value_falls_back_for_novel_tarray():
- """Novel TArray<...> shapes (e.g. TArray) the registry
- doesn't enumerate still default-construct empty — the catch-all
- stays load-bearing for forward compatibility."""
- assert _attr_default_value("TArray") == "{}"
-
-
-def test_ue_type_accepts_units_meta_matches_registry():
- for ue_type, info in _UE_TYPE_INFO.items():
- assert _ue_type_accepts_units_meta(ue_type) == info.accepts_units_meta, ue_type
- # Unknown types must default to "no Units meta" — UHT would reject.
- assert _ue_type_accepts_units_meta("UMjFoo*") is False
diff --git a/Scripts/codegen/tests/test_view_struct.py b/Scripts/codegen/tests/test_view_struct.py
deleted file mode 100644
index 4d542bc9..00000000
--- a/Scripts/codegen/tests/test_view_struct.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""View-struct emitter tests."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-from generate_ue_components import emit_view_structs
-
-
-def test_joint_view_includes_dof_fields(real_rules, real_mjxmacro):
- views = emit_view_structs(real_rules, real_mjxmacro)
- assert "JointView" in views
- fields, bind = views["JointView"]
- # Natural mjModel/JOINT field names (no renames — codegen pure).
- assert "jnt_pos;" in fields
- assert "jnt_axis;" in fields
- assert "jnt_solref;" in fields
- # mjModel/DOF block fields (mapped onto dof_adr).
- assert "dof_damping;" in fields
- assert "dof_solref;" in fields
- # mjData fields.
- assert "qpos;" in fields
- assert "qvel;" in fields
- assert "xanchor;" in fields
-
-
-def test_joint_view_bind_uses_correct_indices(real_rules, real_mjxmacro):
- views = emit_view_structs(real_rules, real_mjxmacro)
- fields, bind = views["JointView"]
- # Per-joint fields use id stride.
- assert "jnt_pos = m->jnt_pos + id * 3;" in bind
- assert "jnt_axis = m->jnt_axis + id * 3;" in bind
- # solref uses mjNREF stride.
- assert "jnt_solref = m->jnt_solref + id * mjNREF;" in bind
- # DOF fields use dof_adr.
- assert "dof_damping = m->dof_damping + dof_adr * 1;" in bind
- # mjData qpos uses qpos_adr.
- assert "qpos = d->qpos + qpos_adr * 1;" in bind
- # Derived index vars declared at top of bind.
- assert "const int qpos_adr = m->jnt_qposadr[id];" in bind
- assert "const int dof_adr = m->jnt_dofadr[id];" in bind
-
-
-def test_body_view_basic(real_rules, real_mjxmacro):
- views = emit_view_structs(real_rules, real_mjxmacro)
- assert "BodyView" in views
- fields, bind = views["BodyView"]
- # mjModel/BODY block emits pointer fields.
- # `body_pos`, `body_quat`, `body_mass` should be present (verbatim names).
- assert "body_pos" in fields or "BodyPos" in fields
- # mjData fields present.
- assert "xpos;" in fields
- assert "xquat;" in fields
-
-
-def test_view_has_one_field_per_mjxmacro_entry(real_rules, real_mjxmacro):
- """Schema-completeness: every entry in the included mjmodel blocks
- should appear as a pointer field on the view."""
- views = emit_view_structs(real_rules, real_mjxmacro)
- fields, _ = views["JointView"]
- joint_block = real_mjxmacro["mjmodel_pointers"]["MJMODEL_POINTERS_JOINT"]
- field_renames = real_rules["views"]["JointView"].get("field_renames", {})
- for entry in joint_block:
- name = entry["name"]
- view_name = field_renames.get(name, name)
- assert f" {view_name};" in fields, f"missing view field for {name} (-> {view_name})"
-
-
-def test_stride_one_int_entries_emit_as_dereferenced_scalars():
- """Single-int entries (stride=="1", type=="int") emit as ``int X``
- with ``X = m->src[id]`` in the bind body — value semantics, not pointer."""
- rules = {"views": {"FooView": {
- "obj_type": "mjOBJ_BODY",
- "include_blocks": ["FOO_BLOCK"],
- }}}
- mjxmacro = {"mjmodel_pointers": {"FOO_BLOCK": [
- {"type": "int", "name": "foo_kind", "outer_dim": "nfoo", "stride": "1"},
- {"type": "int", "name": "foo_size_arr", "outer_dim": "nfoo", "stride": "3"},
- {"type": "mjtNum", "name": "foo_pos", "outer_dim": "nfoo", "stride": "3"},
- ]}}
- views = emit_view_structs(rules, mjxmacro)
- fields, bind = views["FooView"]
- # Scalar int — dereferenced, not pointer.
- assert " int foo_kind;" in fields
- assert " foo_kind = m->foo_kind[id];" in bind
- # Int but stride>1 — stays a pointer.
- assert " int* foo_size_arr;" in fields
- assert " foo_size_arr = m->foo_size_arr + id * 3;" in bind
- # mjtNum stride>1 — pointer.
- assert " mjtNum* foo_pos;" in fields
- assert " foo_pos = m->foo_pos + id * 3;" in bind
-
-
-def test_data_fields_bind_override():
- """``data_fields[name].bind_override`` short-circuits the standard
- ``base + index_var * stride`` emit and drops the override verbatim
- inside the BIND marker. Used by SensorView::sensordata (bounds-checked
- slice) and ActuatorView::act (nullable lookup)."""
- rules = {"views": {"BarView": {
- "obj_type": "mjOBJ_GEOM",
- "include_blocks": [],
- "data_fields": {
- "_note_skip_me": "comment-only; codegen must skip _note_* keys",
- "plain": {"index_var": "id", "stride": "1"},
- "bounds_check": {"bind_override":
- "bounds_check = (id < m->nfoo) ? d->bounds_check + id : nullptr;"},
- },
- }}}
- mjxmacro = {"mjmodel_pointers": {}}
- views = emit_view_structs(rules, mjxmacro)
- fields, bind = views["BarView"]
- # Standard data_field bind emitted.
- assert " mjtNum* plain;" in fields
- assert " plain = d->plain + id * 1;" in bind
- # bind_override field still declared at the standard cpp_type.
- assert " mjtNum* bounds_check;" in fields
- # bind_override body dropped verbatim — no base+id*stride.
- assert " bounds_check = (id < m->nfoo) ? d->bounds_check + id : nullptr;" in bind
- # _note_* keys are documentation, not data fields.
- assert "_note_skip_me" not in fields
- assert "_note_skip_me" not in bind
-
-
-def test_mjtbool_field_emits_mjtbool_pointer():
- """A field typed ``mjtBool`` (MuJoCo 3.9.0's selective mjtByte->mjtBool
- migration of boolean fields like jnt_limited) must emit ``mjtBool*``,
- not the silent ``mjtNum*`` fallback (an 8-byte stride over 1-byte data)."""
- rules = {"views": {"BoolView": {
- "obj_type": "mjOBJ_JOINT",
- "include_blocks": ["BOOL_BLOCK"],
- }}}
- mjxmacro = {"mjmodel_pointers": {"BOOL_BLOCK": [
- {"type": "mjtBool", "name": "jnt_limited", "outer_dim": "njnt", "stride": "1"},
- ]}}
- views = emit_view_structs(rules, mjxmacro)
- fields, _ = views["BoolView"]
- assert " mjtBool* jnt_limited;" in fields
- assert " mjtNum* jnt_limited;" not in fields
-
-
-def test_unmapped_view_field_type_fires_diagnostic():
- """An unknown C type must fire a diagnostic (while still falling back to
- ``mjtNum*``), never default silently — a silent fallback is exactly how the
- 3.9.0 ``mjtBool`` gap shipped a wrong pointer type with no warning."""
- gen._reset_diags()
- rules = {"views": {"OddView": {
- "obj_type": "mjOBJ_GEOM",
- "include_blocks": ["ODD_BLOCK"],
- }}}
- mjxmacro = {"mjmodel_pointers": {"ODD_BLOCK": [
- {"type": "mjFutureType", "name": "geom_whatever",
- "outer_dim": "ngeom", "stride": "3"},
- ]}}
- views = gen.emit_view_structs(rules, mjxmacro)
- fields, _ = views["OddView"]
- assert " mjtNum* geom_whatever;" in fields # fallback still applies
- assert any(d.source == "view_field_type" for d in gen._DIAGS_BUFFER.pending), \
- "unmapped view field type should fire a diagnostic, not default silently"
- gen._reset_diags()
diff --git a/Scripts/codegen/tests/test_xml_passthrough_emit.py b/Scripts/codegen/tests/test_xml_passthrough_emit.py
deleted file mode 100644
index d01d5b34..00000000
--- a/Scripts/codegen/tests/test_xml_passthrough_emit.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
-"""Tests for ``emit_xml_passthrough_body``. Categories with
-``xml_passthrough_emission: true`` (flexcomp) build an MJCF XML string
-instead of writing through the mjs spec API — the codegen owns the
-per-attr formatter so a new schema attr flows end-to-end. The body
-emits ``name="value"`` substrings for every override-tracked
-UPROPERTY."""
-
-from __future__ import annotations
-
-import generate_ue_components as gen
-
-
-def _rules(attr: str, ue_type: str) -> dict:
- return {
- "default_type": "float",
- "type_mappings": {attr: ue_type},
- "element_rules": {"thing": {}},
- }
-
-
-def test_float_attr_emits_printf_with_toggle_guard():
- body = gen.emit_xml_passthrough_body(["stiffness"], _rules("stiffness", "float"), element_name="thing")
- assert "FString Out;" in body
- assert "if (bOverride_stiffness)" in body
- assert '" stiffness=\\"%f\\""' in body
- assert "return Out;" in body
-
-
-def test_int32_attr_emits_printf_with_d_format():
- body = gen.emit_xml_passthrough_body(["group"], _rules("group", "int32"), element_name="thing")
- assert "if (bOverride_group)" in body
- assert '" group=\\"%d\\""' in body
-
-
-def test_bool_attr_emits_ternary_string():
- body = gen.emit_xml_passthrough_body(["limited"], _rules("limited", "bool"), element_name="thing")
- assert 'TEXT("true") : TEXT("false")' in body
- assert '" limited=\\"%s\\""' in body
-
-
-def test_tarray_float_emits_space_separated_loop():
- body = gen.emit_xml_passthrough_body(["range"], _rules("range", "TArray"), element_name="thing")
- assert "if (bOverride_range && range.Num() > 0)" in body
- assert "for (int32 i = 0; i < range.Num(); ++i)" in body
- assert 'if (i > 0) Out += TEXT(" ");' in body
-
-
-def test_flinearcolor_emits_four_component_format():
- body = gen.emit_xml_passthrough_body(["rgba"], _rules("rgba", "FLinearColor"), element_name="thing")
- assert "rgba.R" in body and "rgba.G" in body and "rgba.B" in body and "rgba.A" in body
- assert '" rgba=\\"%f %f %f %f\\""' in body
-
-
-def test_name_attr_is_skipped_by_caller_owned_logic():
- """The caller handles ``name`` (prefix / MjName logic); the body must
- not duplicate it."""
- body = gen.emit_xml_passthrough_body(["name", "stiffness"], _rules("stiffness", "float"), element_name="thing")
- assert '" name=' not in body
- assert "stiffness" in body
-
-
-def test_global_exclusion_skips_attr():
- rules = {**_rules("stiffness", "float"), "global_exclusions": ["stiffness"]}
- body = gen.emit_xml_passthrough_body(["stiffness", "group"], rules, element_name="thing")
- assert "stiffness" not in body
- # 'group' still passes if it's typed (it isn't here -> falls back to default_type 'float').
-
-
-def test_unsupported_type_emits_todo_marker():
- """Novel UE types produce a TODO comment so a reviewer sees the gap
- instead of a silent missing attr."""
- body = gen.emit_xml_passthrough_body(["mystery"], _rules("mystery", "FQuat"), element_name="thing")
- assert "TODO(xml_passthrough)" in body
- assert '"mystery"' in body and "FQuat" in body
diff --git a/Scripts/format.ps1 b/Scripts/format.ps1
index 1cafe713..a25100ed 100644
--- a/Scripts/format.ps1
+++ b/Scripts/format.ps1
@@ -4,9 +4,10 @@
# Scripts/format.ps1 # format Source/ in place
# Scripts/format.ps1 -Check # exit 1 if anything is unformatted (CI)
#
-# Codegen-managed files are also formatted here, but the codegen emits the
-# same formatting (see _clang_format_content in generate_ue_components.py), so
-# running this after a regen is a no-op on generated files.
+# `*.gen.h` / `*.gen.cpp` are skipped. The emitter owns their bytes and the
+# codegen drift gate compares them exactly, so formatting them here would be
+# reverted by the next regen and the two gates would each undo the other. The
+# emitter's own output is the standard those files are held to.
#
# Requires clang-format 19.x (VS2022's bundled LLVM, or set $env:CLANG_FORMAT).
param([switch]$Check)
@@ -25,7 +26,8 @@ function Resolve-ClangFormat {
$cf = Resolve-ClangFormat
$files = Get-ChildItem -Path (Join-Path $root 'Source') -Recurse -Include *.h, *.cpp -File |
- Where-Object { $_.FullName -notmatch '[\\/](Intermediate|Binaries)[\\/]' }
+ Where-Object { $_.FullName -notmatch '[\\/](Intermediate|Binaries)[\\/]' } |
+ Where-Object { $_.Name -notmatch '\.gen\.(h|cpp)$' }
Write-Host "clang-format: $cf"
Write-Host "files: $($files.Count)"
diff --git a/Scripts/format.sh b/Scripts/format.sh
index 65fe5175..737f1740 100755
--- a/Scripts/format.sh
+++ b/Scripts/format.sh
@@ -5,9 +5,10 @@
# Scripts/format.sh # format Source/ in place
# Scripts/format.sh --check # exit 1 if anything is unformatted (CI)
#
-# Codegen-managed files are also formatted here, but the codegen emits the
-# same formatting (see _clang_format_content in generate_ue_components.py), so
-# running this after a regen is a no-op on generated files.
+# `*.gen.h` / `*.gen.cpp` are skipped. The emitter owns their bytes and the
+# codegen drift gate compares them exactly, so formatting them here would be
+# reverted by the next regen and the two gates would each undo the other. The
+# emitter's own output is the standard those files are held to.
#
# Requires clang-format 19.x. Set $CLANG_FORMAT, or have clang-format(-19) on PATH.
set -euo pipefail
@@ -23,7 +24,8 @@ resolve_cf() {
CF="$(resolve_cf)"
mapfile -t FILES < <(find "${ROOT}/Source" -type f \( -name '*.h' -o -name '*.cpp' \) \
- -not -path '*/Intermediate/*' -not -path '*/Binaries/*' | sort)
+ -not -path '*/Intermediate/*' -not -path '*/Binaries/*' \
+ -not -name '*.gen.h' -not -name '*.gen.cpp' | sort)
echo "clang-format: ${CF}"
echo "files: ${#FILES[@]}"
diff --git a/Scripts/regen_ue_profile.ps1 b/Scripts/regen_ue_profile.ps1
new file mode 100644
index 00000000..cec87b8f
--- /dev/null
+++ b/Scripts/regen_ue_profile.ps1
@@ -0,0 +1,36 @@
+# Generated by protospec_gen.emit_ue -- do not edit.
+#
+# Regenerate URLab's MuJoCo spec profile from the MJCF schema.
+#
+# The generator lives in the plugin (protospec/), and reads the schema from the
+# MuJoCo submodule: a MuJoCo bump moves the grammar and this regenerates against
+# it, without a ProtoSpec change dragging MuJoCo's own build along with it.
+#
+# .\Scripts\regen_ue_profile.ps1 # rewrite Source/URLab/*/MuJoCo/Gen
+# .\Scripts\regen_ue_profile.ps1 -Check # fail if it is out of date
+[CmdletBinding()]
+param(
+ [switch]$Check,
+ [string]$ProtospecRoot
+)
+$ErrorActionPreference = "Stop"
+
+$UrlabRoot = Split-Path -Parent $PSScriptRoot
+if (-not $ProtospecRoot) {
+ $ProtospecRoot = Join-Path $UrlabRoot "protospec"
+}
+if (-not (Test-Path (Join-Path $ProtospecRoot "protospec_gen"))) {
+ throw "No ProtoSpec generator at $ProtospecRoot. Pass -ProtospecRoot."
+}
+
+$Args = @("run", "python", "-m", "protospec_gen.emit_ue", "--out", $UrlabRoot)
+if ($Check) { $Args += "--check" }
+
+Push-Location $ProtospecRoot
+try {
+ & uv @Args
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+}
+finally {
+ Pop-Location
+}
diff --git a/Scripts/regen_ue_profile.sh b/Scripts/regen_ue_profile.sh
new file mode 100644
index 00000000..72d003dc
--- /dev/null
+++ b/Scripts/regen_ue_profile.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# Generated by protospec_gen.emit_ue -- do not edit.
+#
+# Regenerate URLab's MuJoCo spec profile from the MJCF schema.
+#
+# The generator lives in the plugin (protospec/), and reads the schema from the
+# MuJoCo submodule: a MuJoCo bump moves the grammar and this regenerates against
+# it, without a ProtoSpec change dragging MuJoCo's own build along with it.
+#
+# ./Scripts/regen_ue_profile.sh # rewrite Source/URLab/*/MuJoCo/Gen
+# ./Scripts/regen_ue_profile.sh --check # fail if it is out of date
+set -euo pipefail
+
+check=""
+protospec_root=""
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --check) check="--check"; shift ;;
+ --protospec-root) protospec_root="$2"; shift 2 ;;
+ *) echo "unknown argument: $1" >&2; exit 2 ;;
+ esac
+done
+
+script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+urlab_root="$(dirname "$script_dir")"
+if [ -z "$protospec_root" ]; then
+ protospec_root="$urlab_root/protospec"
+fi
+if [ ! -d "$protospec_root/protospec_gen" ]; then
+ echo "No ProtoSpec generator at $protospec_root." >&2
+ echo "Pass --protospec-root." >&2
+ exit 1
+fi
+
+cd "$protospec_root"
+exec uv run python -m protospec_gen.emit_ue --out "$urlab_root" ${check:+$check}
diff --git a/Source/URLab/Private/Bridge/AssetCache.cpp b/Source/URLab/Private/Bridge/AssetCache.cpp
new file mode 100644
index 00000000..f846f2b3
--- /dev/null
+++ b/Source/URLab/Private/Bridge/AssetCache.cpp
@@ -0,0 +1,314 @@
+// Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
+//
+// 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.
+//
+// --- LEGAL DISCLAIMER ---
+// UnrealRoboticsLab is an independent software plugin. It is NOT affiliated with,
+// endorsed by, or sponsored by Epic Games, Inc. "Unreal" and "Unreal Engine" are
+// trademarks or registered trademarks of Epic Games, Inc. in the US and elsewhere.
+//
+// This plugin incorporates third-party software: MuJoCo (Apache 2.0),
+// CoACD (MIT), and libzmq (MPL 2.0). See ThirdPartyNotices.txt for details.
+
+#include "Bridge/AssetCache.h"
+
+#include "HAL/FileManager.h"
+#include "HAL/PlatformMisc.h"
+#include "HAL/PlatformProcess.h"
+#include "Misc/DateTime.h"
+#include "Misc/FileHelper.h"
+#include "Misc/Guid.h"
+#include "Misc/Paths.h"
+
+namespace
+{
+// --- SHA-256 (FIPS 180-4), self-contained -----------------------------------
+// UE's Core exposes SHA-1 (FSHA1) but no public SHA-256; the upload protocol is
+// content-addressed on SHA-256, so a small standard implementation lives here.
+// It hashes raw bytes only (no secrets), so this is a plain digest, not a MAC.
+struct FSha256
+{
+ uint32 State[8];
+ uint64 BitLen = 0;
+ uint8 Block[64];
+ int32 BlockLen = 0;
+
+ FSha256() { Reset(); }
+
+ void Reset()
+ {
+ State[0] = 0x6a09e667u;
+ State[1] = 0xbb67ae85u;
+ State[2] = 0x3c6ef372u;
+ State[3] = 0xa54ff53au;
+ State[4] = 0x510e527fu;
+ State[5] = 0x9b05688cu;
+ State[6] = 0x1f83d9abu;
+ State[7] = 0x5be0cd19u;
+ BitLen = 0;
+ BlockLen = 0;
+ }
+
+ static uint32 Rotr(uint32 X, uint32 N) { return (X >> N) | (X << (32 - N)); }
+
+ void Transform()
+ {
+ static const uint32 K[64] = {
+ 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u,
+ 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u,
+ 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u, 0xe49b69c1u, 0xefbe4786u,
+ 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
+ 0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u,
+ 0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u,
+ 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u, 0xa2bfe8a1u, 0xa81a664bu,
+ 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
+ 0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au,
+ 0x5b9cca4fu, 0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u,
+ 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u};
+
+ uint32 W[64];
+ for (int32 i = 0; i < 16; ++i)
+ {
+ W[i] = (uint32(Block[i * 4]) << 24) | (uint32(Block[i * 4 + 1]) << 16)
+ | (uint32(Block[i * 4 + 2]) << 8) | uint32(Block[i * 4 + 3]);
+ }
+ for (int32 i = 16; i < 64; ++i)
+ {
+ const uint32 S0 = Rotr(W[i - 15], 7) ^ Rotr(W[i - 15], 18) ^ (W[i - 15] >> 3);
+ const uint32 S1 = Rotr(W[i - 2], 17) ^ Rotr(W[i - 2], 19) ^ (W[i - 2] >> 10);
+ W[i] = W[i - 16] + S0 + W[i - 7] + S1;
+ }
+
+ uint32 A = State[0], B = State[1], C = State[2], D = State[3];
+ uint32 E = State[4], F = State[5], G = State[6], H = State[7];
+ for (int32 i = 0; i < 64; ++i)
+ {
+ const uint32 S1 = Rotr(E, 6) ^ Rotr(E, 11) ^ Rotr(E, 25);
+ const uint32 Ch = (E & F) ^ (~E & G);
+ const uint32 T1 = H + S1 + Ch + K[i] + W[i];
+ const uint32 S0 = Rotr(A, 2) ^ Rotr(A, 13) ^ Rotr(A, 22);
+ const uint32 Maj = (A & B) ^ (A & C) ^ (B & C);
+ const uint32 T2 = S0 + Maj;
+ H = G;
+ G = F;
+ F = E;
+ E = D + T1;
+ D = C;
+ C = B;
+ B = A;
+ A = T1 + T2;
+ }
+ State[0] += A;
+ State[1] += B;
+ State[2] += C;
+ State[3] += D;
+ State[4] += E;
+ State[5] += F;
+ State[6] += G;
+ State[7] += H;
+ }
+
+ void Update(const uint8* Data, int32 Size)
+ {
+ for (int32 i = 0; i < Size; ++i)
+ {
+ Block[BlockLen++] = Data[i];
+ if (BlockLen == 64)
+ {
+ Transform();
+ BitLen += 512;
+ BlockLen = 0;
+ }
+ }
+ }
+
+ FString Finalize()
+ {
+ const uint64 TotalBits = BitLen + uint64(BlockLen) * 8;
+ Block[BlockLen++] = 0x80;
+ if (BlockLen > 56)
+ {
+ while (BlockLen < 64)
+ Block[BlockLen++] = 0;
+ Transform();
+ BlockLen = 0;
+ }
+ while (BlockLen < 56)
+ Block[BlockLen++] = 0;
+ for (int32 i = 7; i >= 0; --i)
+ Block[BlockLen++] = uint8((TotalBits >> (i * 8)) & 0xff);
+ Transform();
+
+ FString Hex;
+ Hex.Reserve(64);
+ const TCHAR* Digits = TEXT("0123456789abcdef");
+ for (int32 i = 0; i < 8; ++i)
+ {
+ for (int32 Shift = 28; Shift >= 0; Shift -= 4)
+ Hex.AppendChar(Digits[(State[i] >> Shift) & 0xf]);
+ }
+ return Hex;
+ }
+};
+} // namespace
+
+FURLabAssetCache::FURLabAssetCache(const FString& InRoot)
+ : Root(InRoot)
+{
+}
+
+FURLabAssetCache& FURLabAssetCache::Get()
+{
+ static FURLabAssetCache Instance(ResolveCacheRoot());
+ return Instance;
+}
+
+FString FURLabAssetCache::ResolveCacheRoot()
+{
+ const FString Override = FPlatformMisc::GetEnvironmentVariable(TEXT("URLAB_ASSET_CACHE"));
+ if (!Override.IsEmpty())
+ return Override;
+
+#if PLATFORM_WINDOWS
+ FString Base = FPlatformMisc::GetEnvironmentVariable(TEXT("LOCALAPPDATA"));
+ if (Base.IsEmpty())
+ Base = FPlatformProcess::UserSettingsDir();
+#else
+ FString Base = FPlatformMisc::GetEnvironmentVariable(TEXT("XDG_CACHE_HOME"));
+ if (Base.IsEmpty())
+ Base = FPaths::Combine(FPlatformMisc::GetEnvironmentVariable(TEXT("HOME")), TEXT(".cache"));
+#endif
+ return FPaths::Combine(Base, TEXT("URLab"), TEXT("cache"));
+}
+
+FString FURLabAssetCache::Sha256Hex(const uint8* Data, int32 Size)
+{
+ FSha256 Ctx;
+ if (Data && Size > 0)
+ Ctx.Update(Data, Size);
+ return Ctx.Finalize();
+}
+
+bool FURLabAssetCache::IsValidSha256Hex(const FString& Candidate)
+{
+ if (Candidate.Len() != 64)
+ return false;
+ for (const TCHAR C : Candidate)
+ {
+ const bool bHex = (C >= '0' && C <= '9') || (C >= 'a' && C <= 'f');
+ if (!bHex)
+ return false;
+ }
+ return true;
+}
+
+FString FURLabAssetCache::BlobPath(const FString& Sha256Hex) const
+{
+ return FPaths::Combine(Root, TEXT("blobs"), Sha256Hex.Left(2), Sha256Hex);
+}
+
+bool FURLabAssetCache::Has(const FString& Sha256Hex) const
+{
+ if (!IsValidSha256Hex(Sha256Hex))
+ return false;
+ return IFileManager::Get().FileExists(*BlobPath(Sha256Hex));
+}
+
+bool FURLabAssetCache::GetPath(const FString& Sha256Hex, FString& OutPath) const
+{
+ if (!Has(Sha256Hex))
+ return false;
+ OutPath = BlobPath(Sha256Hex);
+ return true;
+}
+
+bool FURLabAssetCache::Put(const FString& Sha256Hex, const uint8* Data, int32 Size)
+{
+ if (!IsValidSha256Hex(Sha256Hex))
+ return false;
+
+ const FString Final = BlobPath(Sha256Hex);
+ if (IFileManager::Get().FileExists(*Final))
+ return true; // immutable content already present
+
+ const FString Dir = FPaths::GetPath(Final);
+ IFileManager::Get().MakeDirectory(*Dir, /*Tree=*/true);
+
+ // Temp file in the SAME directory so the rename is an atomic same-volume
+ // move. A distinct GUID per writer keeps concurrent writers of the same
+ // hash from clobbering each other's temp file.
+ const FString Temp = Final + TEXT(".") + FGuid::NewGuid().ToString(EGuidFormats::Digits) + TEXT(".tmp");
+
+ TArray Payload;
+ if (Data && Size > 0)
+ Payload.Append(Data, Size);
+ if (!FFileHelper::SaveArrayToFile(Payload, *Temp))
+ return false;
+
+ // bReplace=true: content is identical across writers, so replacing a blob a
+ // racing process just created is harmless and keeps this call idempotent.
+ if (!IFileManager::Get().Move(*Final, *Temp, /*bReplace=*/true))
+ {
+ // A concurrent writer may have won the rename; treat an existing final
+ // blob as success and drop our temp copy.
+ IFileManager::Get().Delete(*Temp, /*RequireExists=*/false, /*EvenReadOnly=*/true);
+ return IFileManager::Get().FileExists(*Final);
+ }
+ return true;
+}
+
+int64 FURLabAssetCache::EvictToBudget(int64 MaxBytes)
+{
+ if (MaxBytes <= 0)
+ {
+ const FString Env = FPlatformMisc::GetEnvironmentVariable(TEXT("URLAB_ASSET_CACHE_MAX_BYTES"));
+ MaxBytes = Env.IsEmpty() ? 0 : FCString::Atoi64(*Env);
+ }
+ if (MaxBytes <= 0)
+ return 0; // eviction disabled
+
+ const FString BlobsDir = FPaths::Combine(Root, TEXT("blobs"));
+
+ struct FBlob
+ {
+ FString Path;
+ int64 Size = 0;
+ FDateTime Modified;
+ };
+ TArray Blobs;
+ int64 Total = 0;
+ IFileManager::Get().IterateDirectoryStatRecursively(*BlobsDir,
+ [&Blobs, &Total](const TCHAR* Path, const FFileStatData& Stat) {
+ if (!Stat.bIsDirectory && Stat.FileSize > 0)
+ {
+ Blobs.Add({Path, Stat.FileSize, Stat.ModificationTime});
+ Total += Stat.FileSize;
+ }
+ return true;
+ });
+
+ if (Total <= MaxBytes)
+ return 0;
+
+ Blobs.Sort([](const FBlob& A, const FBlob& B) { return A.Modified < B.Modified; });
+
+ int64 Freed = 0;
+ for (const FBlob& B : Blobs)
+ {
+ if (Total - Freed <= MaxBytes)
+ break;
+ if (IFileManager::Get().Delete(*B.Path, /*RequireExists=*/false, /*EvenReadOnly=*/true))
+ Freed += B.Size;
+ }
+ return Freed;
+}
diff --git a/Source/URLab/Private/Bridge/BridgeServer.cpp b/Source/URLab/Private/Bridge/BridgeServer.cpp
index 0ce9ab5c..54335eca 100644
--- a/Source/URLab/Private/Bridge/BridgeServer.cpp
+++ b/Source/URLab/Private/Bridge/BridgeServer.cpp
@@ -7,11 +7,127 @@
#include "Bridge/RpcDispatcher.h"
#include "Transport/ZmqRpcTransport.h"
#include "Transport/ShmRpcTransport.h"
+#include "Transport/RpcTransport.h"
+#include "Transport/PublishTransport.h"
+#include "Transport/MjExternalTransportProvider.h"
#include "MuJoCo/Core/AMjManager.h"
#include "Utils/URLabLogging.h"
+#include "HAL/IConsoleManager.h"
+#include "HAL/PlatformMisc.h"
+#include "Engine/Engine.h"
+#include "Misc/CommandLine.h"
+#include "Misc/Parse.h"
+#include "Misc/Guid.h"
+#include "HAL/PlatformTime.h"
+
+namespace
+{
+/** Parse the trailing port from a "tcp://host:port" endpoint. Returns 0 when
+ * no numeric port is present. */
+int32 ParseEndpointPort(const FString& Endpoint)
+{
+ int32 ColonIdx = INDEX_NONE;
+ if (Endpoint.FindLastChar(TEXT(':'), ColonIdx))
+ {
+ const FString PortStr = Endpoint.Mid(ColonIdx + 1);
+ if (!PortStr.IsEmpty() && PortStr.IsNumeric())
+ return FCString::Atoi(*PortStr);
+ }
+ return 0;
+}
+
+/** Resolve the step-RPC endpoint, letting an operator override the port per
+ * editor instance without editing the project INI. Precedence: command-line
+ * `-URLabStepPort=N`, then the `URLAB_STEP_PORT` environment variable, then
+ * the requested endpoint unchanged. This is what lets many render-server
+ * editors run side by side on one host, each on its own port. */
+FString ResolveStepEndpoint(const FString& Requested)
+{
+ int32 OverridePort = 0;
+ if (!FParse::Value(FCommandLine::Get(), TEXT("URLabStepPort="), OverridePort))
+ {
+ const FString Env = FPlatformMisc::GetEnvironmentVariable(TEXT("URLAB_STEP_PORT"));
+ if (!Env.IsEmpty() && Env.IsNumeric())
+ OverridePort = FCString::Atoi(*Env);
+ }
+ if (OverridePort <= 0)
+ return Requested;
+
+ int32 ColonIdx = INDEX_NONE;
+ if (Requested.FindLastChar(TEXT(':'), ColonIdx))
+ return FString::Printf(TEXT("%s:%d"), *Requested.Left(ColonIdx), OverridePort);
+ return FString::Printf(TEXT("tcp://0.0.0.0:%d"), OverridePort);
+}
+} // namespace
UURLabBridgeServer::UURLabBridgeServer() = default;
+void UURLabBridgeServer::EnsureDispatcher()
+{
+ if (!Dispatcher.IsValid())
+ {
+ Dispatcher = MakeUnique();
+ Dispatcher->SetOwningBridge(this);
+ }
+}
+
+void UURLabBridgeServer::ApplyPerformanceOverrides()
+{
+ if (bPacingOverridden || !GEngine)
+ return;
+
+ auto Override = [](const TCHAR* Name, const TCHAR* Command, float& OutSaved, bool& OutHad) {
+ if (IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(Name))
+ {
+ OutHad = true;
+ OutSaved = CVar->GetFloat();
+ }
+ GEngine->Exec(nullptr, Command);
+ };
+
+ Override(TEXT("r.VSync"), TEXT("r.VSync 0"), SavedVSync, bHadVSync);
+#if WITH_EDITOR
+ Override(TEXT("r.VSyncEditor"), TEXT("r.VSyncEditor 0"), SavedVSyncEditor, bHadVSyncEditor);
+#endif
+ Override(TEXT("t.MaxFPS"), TEXT("t.MaxFPS 240"), SavedMaxFPS, bHadMaxFPS);
+
+ // Keep rendering when the editor is not the foreground window. Without this
+ // Slate throttles the whole app to a few FPS in the background, which starves
+ // camera capture/readback -- a headless RPC client then sees near-zero frame
+ // throughput even though the bridge is serving.
+ Override(TEXT("Slate.bAllowThrottling"), TEXT("Slate.bAllowThrottling 0"),
+ SavedSlateThrottle, bHadSlateThrottle);
+ Override(TEXT("t.IdleWhenNotForeground"), TEXT("t.IdleWhenNotForeground 0"),
+ SavedIdleWhenNotForeground, bHadIdleWhenNotForeground);
+
+ bPacingOverridden = true;
+ UE_LOG(LogURLabNet, Log,
+ TEXT("UURLabBridgeServer: disabled editor frame pacing + background throttling "
+ "while serving (VSync off, MaxFPS 240, Slate throttling off)"));
+}
+
+void UURLabBridgeServer::RestorePerformanceOverrides()
+{
+ if (!bPacingOverridden || !GEngine)
+ return;
+
+ auto Restore = [](const TCHAR* Name, float Value, bool bHad) {
+ if (bHad)
+ GEngine->Exec(nullptr, *FString::Printf(TEXT("%s %g"), Name, Value));
+ };
+
+ Restore(TEXT("r.VSync"), SavedVSync, bHadVSync);
+#if WITH_EDITOR
+ Restore(TEXT("r.VSyncEditor"), SavedVSyncEditor, bHadVSyncEditor);
+#endif
+ Restore(TEXT("t.MaxFPS"), SavedMaxFPS, bHadMaxFPS);
+ Restore(TEXT("Slate.bAllowThrottling"), SavedSlateThrottle, bHadSlateThrottle);
+ Restore(TEXT("t.IdleWhenNotForeground"), SavedIdleWhenNotForeground, bHadIdleWhenNotForeground);
+
+ bPacingOverridden = false;
+ UE_LOG(LogURLabNet, Log, TEXT("UURLabBridgeServer: restored editor frame pacing"));
+}
+
void UURLabBridgeServer::BeginDestroy()
{
Stop();
@@ -20,16 +136,13 @@ void UURLabBridgeServer::BeginDestroy()
void UURLabBridgeServer::Start(const FString& StepEndpoint)
{
- if (!Dispatcher.IsValid())
- {
- Dispatcher = MakeUnique();
- }
+ EnsureDispatcher();
// Empty endpoint: dispatcher only, no transports (test path).
if (StepEndpoint.IsEmpty())
return;
- EnsureZmqBound(StepEndpoint);
+ EnsureZmqBound(ResolveStepEndpoint(StepEndpoint));
}
bool UURLabBridgeServer::EnsureZmqBound(const FString& Endpoint)
@@ -37,10 +150,7 @@ bool UURLabBridgeServer::EnsureZmqBound(const FString& Endpoint)
if (Endpoint.IsEmpty())
return false;
- if (!Dispatcher.IsValid())
- {
- Dispatcher = MakeUnique();
- }
+ EnsureDispatcher();
for (const TObjectPtr& T : RpcTransports)
{
@@ -49,7 +159,9 @@ bool UURLabBridgeServer::EnsureZmqBound(const FString& Endpoint)
return true;
}
- UURLabZmqRpcTransport* Zmq = NewObject(this, TEXT("BridgeZmqTransport"));
+ // NAME_None: let UE pick a fresh unique name. A fixed name collides on
+ // rebind while the previous worker is still tearing down.
+ UURLabZmqRpcTransport* Zmq = NewObject(this, NAME_None);
Zmq->StepEndpoint = Endpoint;
Zmq->SetOwningBridge(this);
if (!Zmq->TransportInit())
@@ -59,6 +171,7 @@ bool UURLabBridgeServer::EnsureZmqBound(const FString& Endpoint)
return false;
}
RpcTransports.Add(Zmq);
+ ApplyPerformanceOverrides();
UE_LOG(LogURLabNet, Log,
TEXT("UURLabBridgeServer: ZMQ REP bound at %s"), *Endpoint);
return true;
@@ -66,10 +179,7 @@ bool UURLabBridgeServer::EnsureZmqBound(const FString& Endpoint)
bool UURLabBridgeServer::EnsureShmBound(const FString& SessionId)
{
- if (!Dispatcher.IsValid())
- {
- Dispatcher = MakeUnique();
- }
+ EnsureDispatcher();
const FString Sid = SessionId.IsEmpty() ? FString(TEXT("live")) : SessionId;
@@ -86,8 +196,24 @@ bool UURLabBridgeServer::EnsureShmBound(const FString& SessionId)
}
}
- UURLabShmRpcTransport* Shm = NewObject(this, TEXT("BridgeShmTransport"));
+ // SHM session naming includes the instance's step port for traceability.
+ // SHM currently depends on ZMQ being bound first: the step port is read from
+ // the ZMQ transport's bound endpoint. If ZMQ is not running (e.g. a
+ // same-host-only deployment that skips TCP), InstancePort stays 0 and the
+ // session name falls back to the bare session id.
+ int32 StepPort = 0;
+ for (const TObjectPtr& T : RpcTransports)
+ {
+ if (UURLabZmqRpcTransport* Zmq = Cast(T))
+ {
+ StepPort = ParseEndpointPort(Zmq->StepEndpoint);
+ break;
+ }
+ }
+
+ UURLabShmRpcTransport* Shm = NewObject(this, NAME_None);
Shm->SessionId = SessionId; // empty -> defaults to "live" inside Init
+ Shm->InstancePort = StepPort;
Shm->SetOwningBridge(this);
if (!Shm->TransportInit())
{
@@ -96,11 +222,91 @@ bool UURLabBridgeServer::EnsureShmBound(const FString& SessionId)
return false;
}
RpcTransports.Add(Shm);
+ ApplyPerformanceOverrides();
UE_LOG(LogURLabNet, Log,
TEXT("UURLabBridgeServer: SHM RPC bound (session=%s)"), *Sid);
return true;
}
+bool UURLabBridgeServer::EnsureExternalTransportsBound()
+{
+ // The concrete transports live in a separate, optional module that installs
+ // factory hooks at startup. Absent that module the hooks are unbound, so there
+ // is nothing to bind and the core names no external transport type.
+ if (!FMjExternalTransportProvider::HasControlRpcTransport())
+ {
+ UE_LOG(LogURLabNet, Log,
+ TEXT("UURLabBridgeServer: external control transport unavailable; "
+ "EnsureExternalTransportsBound is a no-op."));
+ return false;
+ }
+
+ EnsureDispatcher();
+
+ // RPC / control leg: one external executor transport, persisting across PIE
+ // like the other RPC transports. Its TransportInit brings up the process-wide
+ // context; a false return means the runtime is unavailable, so there is
+ // nothing to bind. Identified by its transport name so the core needs no cast.
+ bool bHaveRpc = false;
+ for (const TObjectPtr& T : RpcTransports)
+ {
+ if (T && T->GetTransportName() == TEXT("ros2-rpc"))
+ {
+ bHaveRpc = true;
+ break;
+ }
+ }
+ if (!bHaveRpc)
+ {
+ UURLabRpcTransport* External = FMjExternalTransportProvider::MakeControlRpcTransport.Execute(this);
+ if (!External || !External->TransportInit())
+ {
+ UE_LOG(LogURLabNet, Log,
+ TEXT("UURLabBridgeServer: external control runtime unavailable; "
+ "EnsureExternalTransportsBound is a no-op."));
+ return false;
+ }
+ RpcTransports.Add(External);
+ ApplyPerformanceOverrides();
+ UE_LOG(LogURLabNet, Log, TEXT("UURLabBridgeServer: control RPC transport bound"));
+ }
+
+ // Publish / fan-out leg: registered with the live manager, which owns per-PIE
+ // publish transports and tears them down in EndPlay. When no manager is live
+ // yet the publish leg is deferred to the next call with one present.
+ if (AAMjManager* Manager = GetActiveManager())
+ {
+ bool bHavePub = false;
+ for (const TObjectPtr& T : Manager->ManagerOwnedPublishTransports)
+ {
+ if (T && T->GetTransportName() == TEXT("ros2-pub"))
+ {
+ bHavePub = true;
+ break;
+ }
+ }
+ if (!bHavePub && FMjExternalTransportProvider::MakeStatePublishTransport.IsBound())
+ {
+ UURLabPublishTransport* Pub =
+ FMjExternalTransportProvider::MakeStatePublishTransport.Execute(Manager);
+ if (Pub && Pub->TransportInit())
+ {
+ Manager->ManagerOwnedPublishTransports.Add(Pub);
+ UE_LOG(LogURLabNet, Log,
+ TEXT("UURLabBridgeServer: state publish transport registered with manager"));
+ }
+ }
+ }
+ else
+ {
+ UE_LOG(LogURLabNet, Warning,
+ TEXT("UURLabBridgeServer: EnsureExternalTransportsBound with no active manager; "
+ "publish leg deferred until a manager is live."));
+ }
+
+ return true;
+}
+
void UURLabBridgeServer::Stop()
{
// Drain before tearing transports down so blocking handlers see the
@@ -117,6 +323,7 @@ void UURLabBridgeServer::Stop()
T->TransportShutdown();
}
RpcTransports.Reset();
+ RestorePerformanceOverrides();
if (!Dispatcher.IsValid())
return;
@@ -148,3 +355,77 @@ void UURLabBridgeServer::UnregisterManager(AAMjManager* InManager)
}
ActiveManager.Reset();
}
+
+double UURLabBridgeServer::LeaseNow() const
+{
+ return LeaseClockOverrideForTest >= 0.0 ? LeaseClockOverrideForTest : FPlatformTime::Seconds();
+}
+
+bool UURLabBridgeServer::IsLeaseHeldInternal(double NowSeconds)
+{
+ if (bLeaseHeld && (NowSeconds - LeaseLastActivitySeconds) > LeaseTtlSeconds)
+ {
+ // Idle past its TTL: auto-release so the next acquire succeeds.
+ bLeaseHeld = false;
+ LeaseId.Empty();
+ LeaseOwner.Empty();
+ }
+ return bLeaseHeld;
+}
+
+bool UURLabBridgeServer::TryAcquireLease(const FString& Owner, double TtlSeconds,
+ FString& OutLeaseId, FString& OutExistingLeaseId)
+{
+ FScopeLock Lock(&LeaseMutex);
+ const double Now = LeaseNow();
+ if (IsLeaseHeldInternal(Now))
+ {
+ OutExistingLeaseId = LeaseId;
+ return false;
+ }
+
+ bLeaseHeld = true;
+ LeaseId = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphens);
+ LeaseOwner = Owner;
+ LeaseTtlSeconds = TtlSeconds;
+ LeaseLastActivitySeconds = Now;
+ OutLeaseId = LeaseId;
+ return true;
+}
+
+bool UURLabBridgeServer::ReleaseLease(const FString& InLeaseId)
+{
+ FScopeLock Lock(&LeaseMutex);
+ if (!bLeaseHeld || !LeaseId.Equals(InLeaseId))
+ return false;
+
+ bLeaseHeld = false;
+ LeaseId.Empty();
+ LeaseOwner.Empty();
+ return true;
+}
+
+void UURLabBridgeServer::TouchLease()
+{
+ FScopeLock Lock(&LeaseMutex);
+ if (bLeaseHeld)
+ LeaseLastActivitySeconds = LeaseNow();
+}
+
+bool UURLabBridgeServer::IsLeaseHeld()
+{
+ FScopeLock Lock(&LeaseMutex);
+ return IsLeaseHeldInternal(LeaseNow());
+}
+
+FString UURLabBridgeServer::GetLeaseId() const
+{
+ FScopeLock Lock(&LeaseMutex);
+ return LeaseId;
+}
+
+void UURLabBridgeServer::SetLeaseClockForTest(double NowSeconds)
+{
+ FScopeLock Lock(&LeaseMutex);
+ LeaseClockOverrideForTest = NowSeconds;
+}
diff --git a/Source/URLab/Private/Bridge/BridgeServerConfigUtils.cpp b/Source/URLab/Private/Bridge/BridgeServerConfigUtils.cpp
index dacea2dd..15f78012 100644
--- a/Source/URLab/Private/Bridge/BridgeServerConfigUtils.cpp
+++ b/Source/URLab/Private/Bridge/BridgeServerConfigUtils.cpp
@@ -8,7 +8,10 @@
#include "Interfaces/IPluginManager.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/Paths.h"
+#include "Misc/CommandLine.h"
+#include "Misc/Parse.h"
#include "HAL/FileManager.h"
+#include "HAL/PlatformMisc.h"
namespace URLabBridgeServerConfigUtils
{
@@ -47,6 +50,21 @@ void LoadFromIni(FURLabBridgeServerConfig& Out)
Out.StepPort = TmpInt;
if (File.GetInt(SectionName, TEXT("StatePort"), TmpInt))
Out.StatePort = TmpInt;
+
+ FString TmpStr;
+ if (File.GetString(SectionName, TEXT("InstanceId"), TmpStr))
+ Out.InstanceId = TmpStr;
+ if (File.GetInt(SectionName, TEXT("InstanceIndex"), TmpInt))
+ Out.InstanceIndex = TmpInt;
+ if (File.GetInt(SectionName, TEXT("PortBase"), TmpInt))
+ Out.PortBase = TmpInt;
+ if (File.GetInt(SectionName, TEXT("PortStride"), TmpInt))
+ Out.PortStride = TmpInt;
+ if (File.GetInt(SectionName, TEXT("CamBasePort"), TmpInt))
+ Out.CamBasePort = TmpInt;
+ if (File.GetString(SectionName, TEXT("BindAddress"), TmpStr))
+ Out.BindAddress = TmpStr;
+
if (File.GetBool(SectionName, TEXT("StopOnPIEEnd"), TmpBool))
Out.bStopOnPIEEnd = TmpBool;
}
@@ -62,9 +80,94 @@ void SaveToIni(const FURLabBridgeServerConfig& In)
File.SetString(SectionName, TEXT("AutoStart"), In.bAutoStart ? TEXT("True") : TEXT("False"));
File.SetInt64(SectionName, TEXT("StepPort"), In.StepPort);
File.SetInt64(SectionName, TEXT("StatePort"), In.StatePort);
+ File.SetString(SectionName, TEXT("InstanceId"), *In.InstanceId);
+ File.SetInt64(SectionName, TEXT("InstanceIndex"), In.InstanceIndex);
+ File.SetInt64(SectionName, TEXT("PortBase"), In.PortBase);
+ File.SetInt64(SectionName, TEXT("PortStride"), In.PortStride);
+ File.SetInt64(SectionName, TEXT("CamBasePort"), In.CamBasePort);
+ File.SetString(SectionName, TEXT("BindAddress"), *In.BindAddress);
File.SetString(SectionName, TEXT("StopOnPIEEnd"), In.bStopOnPIEEnd ? TEXT("True") : TEXT("False"));
File.Dirty = true;
File.Write(Path);
}
+
+void DerivePorts(FURLabBridgeServerConfig& Cfg,
+ bool bStepExplicit, bool bStateExplicit, bool bCamExplicit)
+{
+ if (Cfg.InstanceIndex >= 0)
+ {
+ const int32 Slot = Cfg.PortBase + Cfg.InstanceIndex * Cfg.PortStride;
+ if (!bStepExplicit)
+ Cfg.StepPort = Slot + 0;
+ if (!bStateExplicit)
+ Cfg.StatePort = Slot + 1;
+ if (!bCamExplicit)
+ Cfg.CamBasePort = Slot + 2;
+ }
+
+ if (Cfg.CamBasePort == 0)
+ Cfg.CamBasePort = Cfg.StepPort + 2;
+
+ if (Cfg.InstanceId.IsEmpty() && Cfg.InstanceIndex >= 0)
+ Cfg.InstanceId = FString::Printf(TEXT("instance_%d"), Cfg.InstanceIndex);
+}
+
+FString BuildCameraEndpoint(const FURLabBridgeServerConfig& Cfg, int32 CameraIndex)
+{
+ const int32 Index = FMath::Max(0, CameraIndex);
+ return FString::Printf(TEXT("tcp://%s:%d"), *Cfg.BindAddress, Cfg.CamBasePort + Index);
+}
+
+void ApplyEnvAndCommandLineOverrides(FURLabBridgeServerConfig& Cfg)
+{
+ // Command line beats environment; a value from either replaces the INI
+ // one. Returns true when a value was found so callers can flag explicit
+ // port overrides (which then survive derivation).
+ auto ResolveString = [](const TCHAR* CmdKey, const TCHAR* EnvKey, FString& Out) -> bool {
+ if (FParse::Value(FCommandLine::Get(), CmdKey, Out))
+ return true;
+ const FString Env = FPlatformMisc::GetEnvironmentVariable(EnvKey);
+ if (!Env.IsEmpty())
+ {
+ Out = Env;
+ return true;
+ }
+ return false;
+ };
+ auto ResolveInt = [&ResolveString](const TCHAR* CmdKey, const TCHAR* EnvKey, int32& Out) -> bool {
+ FString Str;
+ if (!ResolveString(CmdKey, EnvKey, Str) || !Str.IsNumeric())
+ return false;
+ Out = FCString::Atoi(*Str);
+ return true;
+ };
+
+ FString StrVal;
+ int32 IntVal = 0;
+
+ if (ResolveString(TEXT("URLabInstanceId="), TEXT("URLAB_INSTANCE_ID"), StrVal))
+ Cfg.InstanceId = StrVal;
+ if (ResolveInt(TEXT("URLabInstanceIndex="), TEXT("URLAB_INSTANCE_INDEX"), IntVal))
+ Cfg.InstanceIndex = IntVal;
+ if (ResolveInt(TEXT("URLabPortBase="), TEXT("URLAB_PORT_BASE"), IntVal))
+ Cfg.PortBase = IntVal;
+ if (ResolveInt(TEXT("URLabPortStride="), TEXT("URLAB_PORT_STRIDE"), IntVal))
+ Cfg.PortStride = IntVal;
+
+ const bool bStepExplicit = ResolveInt(TEXT("URLabStepPort="), TEXT("URLAB_STEP_PORT"), IntVal);
+ if (bStepExplicit)
+ Cfg.StepPort = IntVal;
+ const bool bStateExplicit = ResolveInt(TEXT("URLabStatePort="), TEXT("URLAB_STATE_PORT"), IntVal);
+ if (bStateExplicit)
+ Cfg.StatePort = IntVal;
+ const bool bCamExplicit = ResolveInt(TEXT("URLabCamBasePort="), TEXT("URLAB_CAM_BASE_PORT"), IntVal);
+ if (bCamExplicit)
+ Cfg.CamBasePort = IntVal;
+
+ if (ResolveString(TEXT("URLabBindAddress="), TEXT("URLAB_BIND_ADDRESS"), StrVal))
+ Cfg.BindAddress = StrVal;
+
+ DerivePorts(Cfg, bStepExplicit, bStateExplicit, bCamExplicit);
+}
} // namespace URLabBridgeServerConfigUtils
diff --git a/Source/URLab/Private/Bridge/ControlOwnership.cpp b/Source/URLab/Private/Bridge/ControlOwnership.cpp
new file mode 100644
index 00000000..42ae50df
--- /dev/null
+++ b/Source/URLab/Private/Bridge/ControlOwnership.cpp
@@ -0,0 +1,138 @@
+// Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
+//
+// 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.
+//
+// --- LEGAL DISCLAIMER ---
+// UnrealRoboticsLab is an independent software plugin. It is NOT affiliated with,
+// endorsed by, or sponsored by Epic Games, Inc. "Unreal" and "Unreal Engine" are
+// trademarks or registered trademarks of Epic Games, Inc. in the US and elsewhere.
+//
+// This plugin incorporates third-party software: MuJoCo (Apache 2.0),
+// CoACD (MIT), and libzmq (MPL 2.0). See ThirdPartyNotices.txt for details.
+
+#include "Bridge/ControlOwnership.h"
+#include "HAL/PlatformTime.h"
+
+double FMjControlOwnership::Now() const
+{
+ return ClockOverrideForTest >= 0.0 ? ClockOverrideForTest : FPlatformTime::Seconds();
+}
+
+bool FMjControlOwnership::IsExpired(const FMjControlClaim& Claim, double NowSeconds)
+{
+ return Claim.TtlSeconds > 0.0 && (NowSeconds - Claim.LastActivitySeconds) > Claim.TtlSeconds;
+}
+
+FMjControlOwnership::EClaimResult FMjControlOwnership::Claim(FName Art, const FString& Source,
+ double TtlSeconds, bool bForce, FString& OutCurrentOwner)
+{
+ FScopeLock Lock(&Mutex);
+ const double N = Now();
+
+ if (FMjControlClaim* Existing = Claims.Find(Art))
+ {
+ // An expired claim is free for the taking; a live one held by someone
+ // else blocks unless the caller forces the steal.
+ if (!IsExpired(*Existing, N) && !bForce && !Existing->Owner.Equals(Source))
+ {
+ OutCurrentOwner = Existing->Owner;
+ return EClaimResult::AlreadyOwned;
+ }
+ }
+
+ FMjControlClaim& Held = Claims.FindOrAdd(Art);
+ Held.Owner = Source;
+ Held.TtlSeconds = TtlSeconds;
+ Held.LastActivitySeconds = N;
+ OutCurrentOwner = Source;
+ return EClaimResult::Ok;
+}
+
+bool FMjControlOwnership::Release(FName Art, const FString& Source)
+{
+ FScopeLock Lock(&Mutex);
+ const double N = Now();
+
+ FMjControlClaim* Existing = Claims.Find(Art);
+ if (!Existing)
+ return false;
+ if (IsExpired(*Existing, N))
+ {
+ Claims.Remove(Art);
+ return false;
+ }
+ if (!Existing->Owner.Equals(Source))
+ return false;
+
+ Claims.Remove(Art);
+ return true;
+}
+
+FMjControlOwnership::EWriteCheck FMjControlOwnership::CheckWrite(FName Art, const FString& Source,
+ FString& OutCurrentOwner)
+{
+ FScopeLock Lock(&Mutex);
+ const double N = Now();
+
+ FMjControlClaim* Existing = Claims.Find(Art);
+ if (Existing && IsExpired(*Existing, N))
+ {
+ Claims.Remove(Art);
+ Existing = nullptr;
+ }
+
+ if (!Existing)
+ {
+ OutCurrentOwner = TEXT("(unclaimed)");
+ return EWriteCheck::NotOwner;
+ }
+ if (!Existing->Owner.Equals(Source))
+ {
+ OutCurrentOwner = Existing->Owner;
+ return EWriteCheck::NotOwner;
+ }
+
+ Existing->LastActivitySeconds = N;
+ OutCurrentOwner = Existing->Owner;
+ return EWriteCheck::Ok;
+}
+
+TMap FMjControlOwnership::GetActiveOwners()
+{
+ FScopeLock Lock(&Mutex);
+ const double N = Now();
+
+ TMap Owners;
+ for (auto It = Claims.CreateIterator(); It; ++It)
+ {
+ if (IsExpired(It->Value, N))
+ {
+ It.RemoveCurrent();
+ continue;
+ }
+ Owners.Add(It->Key, It->Value.Owner);
+ }
+ return Owners;
+}
+
+void FMjControlOwnership::Reset()
+{
+ FScopeLock Lock(&Mutex);
+ Claims.Empty();
+}
+
+void FMjControlOwnership::SetClockOverrideForTest(double NowSeconds)
+{
+ FScopeLock Lock(&Mutex);
+ ClockOverrideForTest = NowSeconds;
+}
diff --git a/Source/URLab/Private/Bridge/InstanceRegistry.cpp b/Source/URLab/Private/Bridge/InstanceRegistry.cpp
new file mode 100644
index 00000000..1fab5c3a
--- /dev/null
+++ b/Source/URLab/Private/Bridge/InstanceRegistry.cpp
@@ -0,0 +1,107 @@
+// Copyright (c) 2026 Jonathan Embley-Riches. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+
+#include "Bridge/InstanceRegistry.h"
+#include "Bridge/BridgeServerConfig.h"
+
+#include "Dom/JsonObject.h"
+#include "Dom/JsonValue.h"
+#include "Serialization/JsonSerializer.h"
+#include "Serialization/JsonWriter.h"
+#include "Misc/FileHelper.h"
+#include "Misc/Paths.h"
+#include "Misc/DateTime.h"
+#include "HAL/FileManager.h"
+#include "HAL/PlatformProcess.h"
+#include "HAL/PlatformMisc.h"
+
+namespace
+{
+/** Instance id used for the file name and the JSON, falling back to the SHM
+ * default so a single-editor entry stays readable. */
+FString EffectiveInstanceId(const FURLabBridgeServerConfig& Cfg)
+{
+ return Cfg.InstanceId.IsEmpty() ? FString(TEXT("live")) : Cfg.InstanceId;
+}
+} // namespace
+
+const TArray& FURLabInstanceRegistry::Capabilities()
+{
+ static const TArray Caps = {
+ TEXT("render_sync"),
+ TEXT("render_async"),
+ TEXT("shm_rpc"),
+ TEXT("model_upload"),
+ TEXT("content_cache"),
+ };
+ return Caps;
+}
+
+FString FURLabInstanceRegistry::ResolveRegistryDir()
+{
+ const FString Override = FPlatformMisc::GetEnvironmentVariable(TEXT("URLAB_REGISTRY_DIR"));
+ if (!Override.IsEmpty())
+ return Override;
+
+#if PLATFORM_WINDOWS
+ FString Base = FPlatformMisc::GetEnvironmentVariable(TEXT("LOCALAPPDATA"));
+ if (Base.IsEmpty())
+ Base = FPlatformProcess::UserSettingsDir();
+#else
+ FString Base = FPlatformMisc::GetEnvironmentVariable(TEXT("XDG_CACHE_HOME"));
+ if (Base.IsEmpty())
+ Base = FPaths::Combine(FPlatformMisc::GetEnvironmentVariable(TEXT("HOME")), TEXT(".cache"));
+#endif
+ return FPaths::Combine(Base, TEXT("URLab"), TEXT("registry"));
+}
+
+FString FURLabInstanceRegistry::ResolveEntryPath(const FURLabBridgeServerConfig& Cfg)
+{
+ const FString FileName = FString::Printf(TEXT("%s_%u.json"),
+ *EffectiveInstanceId(Cfg), FPlatformProcess::GetCurrentProcessId());
+ return FPaths::Combine(ResolveRegistryDir(), FileName);
+}
+
+void FURLabInstanceRegistry::WriteEntry(const FURLabBridgeServerConfig& Cfg,
+ const FString& UrlabVersion, bool bManagerPresent, bool bBusy)
+{
+ TSharedPtr Entry = MakeShared();
+ Entry->SetStringField(TEXT("instance_id"), EffectiveInstanceId(Cfg));
+ Entry->SetNumberField(TEXT("index"), Cfg.InstanceIndex);
+ Entry->SetNumberField(TEXT("pid"), static_cast(FPlatformProcess::GetCurrentProcessId()));
+ Entry->SetStringField(TEXT("host"), FPlatformProcess::ComputerName());
+ Entry->SetNumberField(TEXT("step_port"), Cfg.StepPort);
+ Entry->SetNumberField(TEXT("state_port"), Cfg.StatePort);
+ Entry->SetNumberField(TEXT("cam_base_port"), Cfg.CamBasePort);
+ Entry->SetBoolField(TEXT("manager_present"), bManagerPresent);
+ Entry->SetBoolField(TEXT("busy"), bBusy);
+ Entry->SetStringField(TEXT("urlab_version"), UrlabVersion);
+
+ TArray> Caps;
+ for (const FString& Cap : Capabilities())
+ Caps.Add(MakeShared(Cap));
+ Entry->SetArrayField(TEXT("capabilities"), Caps);
+
+ Entry->SetStringField(TEXT("registry_written_at"), FDateTime::UtcNow().ToIso8601());
+
+ FString Serialized;
+ TSharedRef> Writer = TJsonWriterFactory<>::Create(&Serialized);
+ FJsonSerializer::Serialize(Entry.ToSharedRef(), Writer);
+
+ const FString Path = ResolveEntryPath(Cfg);
+ IFileManager::Get().MakeDirectory(*FPaths::GetPath(Path), /*Tree=*/true);
+ FFileHelper::SaveStringToFile(Serialized, *Path);
+}
+
+void FURLabInstanceRegistry::RefreshEntry(const FURLabBridgeServerConfig& Cfg,
+ const FString& UrlabVersion, bool bManagerPresent, bool bBusy)
+{
+ WriteEntry(Cfg, UrlabVersion, bManagerPresent, bBusy);
+}
+
+void FURLabInstanceRegistry::RemoveEntry(const FURLabBridgeServerConfig& Cfg)
+{
+ IFileManager::Get().Delete(*ResolveEntryPath(Cfg), /*RequireExists=*/false, /*EvenReadOnly=*/true);
+}
diff --git a/Source/URLab/Private/Bridge/MsgpackHelpers.cpp b/Source/URLab/Private/Bridge/MsgpackHelpers.cpp
index 117dbd55..ac7fda35 100644
--- a/Source/URLab/Private/Bridge/MsgpackHelpers.cpp
+++ b/Source/URLab/Private/Bridge/MsgpackHelpers.cpp
@@ -25,6 +25,7 @@
#include "Dom/JsonObject.h"
#include "Dom/JsonValue.h"
#include "Misc/Base64.h"
+#include "Utils/URLabLogging.h"
// rpclib's msgpack-cxx headers use member functions and templates named
// `check`, which collides with UE's `check(cond)` assertion macro. Save
@@ -50,6 +51,37 @@ namespace
constexpr const TCHAR* kBinSuffix = TEXT("__b64__");
constexpr int32 kBinSuffixLen = 7;
+// FJsonValue carrying raw bytes to pack straight through as msgpack `bin`, with
+// no base64 encode/decode round trip and no intermediate FString. It holds a
+// Keeper that owns the underlying buffer so the bytes stay valid until the reply
+// is packed. It is always stored under a kBinSuffix key, and its Type is set to
+// EJson::Null so PackJsonObjectInner can tell it apart from the legacy base64
+// string form (a msgpack->JSON round trip yields EJson::String there, and no
+// code ever stores a plain null under a __b64__ key). EJson::Null also serialises
+// safely if the reply ever goes out as JSON: the __b64__ field is the
+// msgpack-canonical form and JSON clients read the parallel *_base64 field.
+class FURLabJsonValueBinary : public FJsonValue
+{
+public:
+ FURLabJsonValueBinary(const uint8* InData, int32 InSize,
+ TSharedPtr InKeeper)
+ : Data(InData), Size(InSize), Keeper(MoveTemp(InKeeper))
+ {
+ Type = EJson::Null;
+ }
+
+ const uint8* GetBinaryData() const { return Data; }
+ int32 GetBinarySize() const { return Size; }
+
+protected:
+ virtual FString GetType() const override { return TEXT("URLabBinary"); }
+
+private:
+ const uint8* Data = nullptr;
+ int32 Size = 0;
+ TSharedPtr Keeper;
+};
+
template