Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
1362 lines (1090 loc) · 65.9 KB
/
Copy pathMakefile
File metadata and controls
1362 lines (1090 loc) · 65.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
PY := .venv/bin/python
PYTEST := .venv/bin/pytest
RUFF := .venv/bin/ruff
# Keep native tools consistent with the Python development environment, including sub-makes.
export PATH := $(abspath .venv/bin):$(PATH)
.DEFAULT_GOAL := help
.PHONY: debug-draw
debug-draw:
MOJIVE_RENDERER=$(BACKEND) $(PY) examples/debug_draw.py $(ARGS)
.PHONY: recording-layers
.PHONY: camera-tracking
.PHONY: keyframe-timeline
.PHONY: take-video
take-video:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.take_video $(ARGS)
keyframe-timeline:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.keyframe_timeline $(ARGS)
.PHONY: timeline-profile
## Profile 100 to 100,000 keys; add ARGS='--capture' for Linux EGL panel captures.
timeline-profile:
$(PY) -m mojive.tools.timeline_profile $(ARGS)
camera-tracking:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.camera_tracking $(ARGS)
.PHONY: camera-navigation
.PHONY: contact-style
## Capture contact shapes/colors and exercise their settings and scene capture.
contact-style: $(if $(filter bgfx,$(BACKEND)),native-python-build)
$(if $(filter bgfx,$(BACKEND)),MOJIVE_NATIVE_BUILD="$(abspath $(NATIVE_BUILD))") MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_contact_style.py
## Exercise saved focus/zoom settings and extreme native wheel input.
camera-navigation: camera-focus
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_camera_navigation.py
.PHONY: camera-focus
## Capture object focus from offset/away/below views and verify joint/camera/light focus.
camera-focus:
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_camera_tracking.py -k double_click
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_ui_interaction.py -k double_clicking_joint_and_hierarchy
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_joint_focus_readability.py
.PHONY: camera-helpers
## Capture double-click focus on moving and world-attached cameras and lights.
camera-helpers:
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m "gpu and physics" tests/gpu/test_camera_tracking.py -k double_click
recording-layers:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.recording_layers $(ARGS)
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_recording_layers.py -k narrow_status
.PHONY: rollout-video
.PHONY: passive-viewer
.PHONY: physics-render-benchmark
.PHONY: physics-concurrency
physics-render-benchmark:
$(PY) -m mojive.tools.physics_render_benchmark $(ARGS)
HUMANOIDS_MODEL ?= $(firstword $(MUJOCO_MODEL_ROOTS))/humanoid/100_humanoids.xml
physics-concurrency:
$(PY) -m mojive.tools.physics_render_benchmark --production \
--workloads joint_types,cloth_stress,humanoids100 --humanoids-model "$(HUMANOIDS_MODEL)" \
--seconds 6 --warmup 36 --output output/physics-concurrency $(ARGS)
passive-viewer:
$(PY) examples/passive_viewer.py $(ARGS)
.PHONY: help setup check lint fmt docs docs-check docs-serve examples-check test test-fast test-integration test-physics test-all gpu gpu-bgfx egl p0 p1 renderer-api renderer-benchmark renderer-benchmark-full golden golden-accept parity calibrate gallery ui-feasibility ui-runtime readme-media ui-frame-profile ui-gallery tool-icons mouse-icons gizmo-gallery hidpi-gallery model-loading model-composition mjcf-roundtrip editor-performance stability rpc-soak format-validation scene-io editor-files entity-edit undo-redo remote-authoring additive bench showcase probe reverse viewer egl-viewer hidpi empty editor settings workspace-edit canvas canvas-2d lighting image-light many-lights material-parity material-parity-accept texture-minification local-shadow-precision shadow-quality shadow-scheduling scene-icons scene-entities text-overlay capture record serve attach live-view snapshot-record snapshot-replay camera-state scene-snapshot cli rpc toy-physics adapter-conformance inspector gizmo joint-gizmo primitive-authoring material-authoring contact-authoring body-authoring resource-authoring asset-browser joint-site-authoring model-component-authoring keyframe-authoring batch-editing perturb reflect outline robot mujoco-physics mujoco-audit mujoco-model-suite mujoco-visuals mujoco-debug mujoco-actuators mujoco-slider-crank mujoco-solver-diagnostics mujoco-islands mujoco-bvh mujoco-convex-hull mujoco-rangefinder mujoco-constraints mujoco-editing mujoco-overlays cameras camera-intrinsics geom-groups deformables assets backends doctor clean
help:
@printf '%s\n' \
'Interactive:' \
' make viewer default MuJoCo scene' \
' make native-viewer build and launch the C++/bgfx Viewer' \
' make native-wayland-viewer interactive viewer in a nested Wayland desktop' \
' make native-editor C++/bgfx scene editor' \
' make native-parity compare native/OpenGL render products' \
' make native-model-parity verify live rigid, skin, and flex scenes' \
' make native-wheel-test build, install, and verify the native wheel' \
' make passive-viewer independent physics and display rates with captures' \
' make viewer-managed MuJoCo-style managed viewer; Mojive steps physics' \
' make viewer-passive MuJoCo-style passive viewer; caller steps physics' \
' make egl-viewer Linux viewer with a GLFW EGL context' \
' make hidpi viewer with an explicit 200% UI scale' \
' make empty empty viewer; load MJCF or URDF from File menu' \
' make editor empty Mojive workspace; combine MJCF/URDF and entities' \
' make settings editor with the dockable Settings panel open' \
' make workspace-edit workspace, MjSpec topology, camera and light acceptance' \
' make model-loading empty, MJCF, and URDF loading reference images' \
' make model-composition add and remove MJCF/URDF models at runtime' \
' make mjcf-roundtrip export edited workspaces as re-loadable MJCF' \
' make editor-performance composition editing performance baseline' \
' make editor-soak sustained hidden editing and recovery measurements' \
' make editor-tail-profile attribute slow editing frames and GC pauses' \
' make stability long-frame, large-model, and multi-camera gates' \
' make rpc-soak persistent RPC, concurrency, timeout, and recovery' \
' make rpc-benchmark real socket load, frame budgets, and input latency' \
' make format-validation current scene snapshot and recording formats' \
' make robot Unitree Go2; downloads on first run' \
' make outline selection and antialiased outline' \
' make inspector compact Inspector transform reference image' \
' make ui-feasibility interactive M1-M18 UI feasibility probe' \
' make ui-components compare production widgets and local corner experiments' \
' make ui-optical compare optical offsets across icon sizes and contexts' \
' make ui-icon-concepts production icon family review captures' \
' make svg-icons export production icons to standalone SVG assets' \
' make ui-svg-icons compare production code and SVG files in ImGui' \
' make ui-icon-references compare icon outline and filled references' \
' make ui-redesign new layout feasibility capture (--interactive via ARGS)' \
' make ui-native-design live native UI parameter editor and production preview' \
' make ui-native-workspace interactive production UI (--float-panel Timeline via ARGS)' \
' make ui-native-capture capture production panels and menus' \
' make ui-notice-review capture operation notices and file receipts' \
' make ui-design-guide browse the native design specification and panel prototypes' \
' make ui-design serve the browser design reference locally' \
' make ui-gallery deterministic UI feasibility acceptance pages' \
' make readme-media refresh unmodified production screenshots for README' \
' make tool-icons transparent 1024px Tool Column icon sources' \
' make mouse-icons black/transparent 1024px mouse hint sources' \
' make gizmo 2D/3D position/rotation gizmo' \
' make joint-gizmo numbered joint-gizmo acceptance scene' \
' make primitive-authoring fixed transforms and primitive dimensions' \
' make material-authoring material creation, binding, and 2D texture import' \
' make contact-authoring geometry contact, mass, group, and fluid properties' \
' make body-authoring body mass, inertia, gravcomp, mocap, and sleep policy' \
' make resource-authoring geometry shape, mesh/hfield, cube, and skybox import' \
' make asset-browser model-local files, materials, and height-field dimensions' \
' make joint-site-authoring advanced joint and site shape/endpoint properties' \
' make model-component-authoring contacts, actuators, sensors, tendons, and equality' \
' make keyframe-authoring record/replay take and snapshot Dope Sheet' \
' make batch-editing Ctrl/Cmd multi-select and one-rebuild topology deletion' \
' make gizmo-gallery enlarged 2D/3D gizmo reference images' \
' make hidpi-gallery gizmo references at explicit 200% UI scale' \
' make perturb MuJoCo translation/rotation perturbation' \
' make physics-options-check validate and capture environment physics controls' \
' make text-overlay GPU world-space text' \
' make mujoco-visuals hfield/site/tendon/contact' \
' make mujoco-debug joint/COM/inertia debug visuals' \
' make mujoco-actuators joint/site/body actuator visuals' \
' make mujoco-slider-crank slider-crank linkage reference image' \
' make mujoco-solver-diagnostics contact split and autoconnect images' \
' make mujoco-islands constraint-island color reference images' \
' make mujoco-bvh body, mesh, and flex BVH reference images' \
' make mujoco-convex-hull original and collision-hull reference images' \
' make geometry-views visual, collision, and combined geometry images' \
' make mujoco-rangefinder site/camera rays, hits, and normals' \
' make mujoco-constraints equality constraint endpoint markers' \
' make mujoco-editing mocap pose and equality controls' \
' make mujoco-overlays flex edges/vertices, labels, and frames' \
' make deformables flex/skin dynamic meshes' \
'' \
'Rendering and output:' \
' make lighting editable lights and environment' \
' make image-light MuJoCo cube-map environment light' \
' make many-lights 16-light and 24-light reference images' \
' make material-parity texture, transparency, tendon, deformable, and dense scenes' \
' make texture-minification near/far textured-plane filtering acceptance' \
' make local-shadow-precision anymal-c spotlight receiver precision acceptance' \
' make shadow-quality performance/balanced/high shadow comparison' \
' make shadow-scheduling deterministic light and shadow-slot report' \
' make scene-icons camera and light scene icons' \
' make reflect multiple planar reflections' \
' make additive standard and additive transparency images' \
' make cameras free, named, and orthographic cameras' \
' make capture write PNG' \
' make record stream MP4' \
' make recording-layers live layers, countdown, and compact joint acceptance' \
' make take-video one-shot take recording, end hold, and copyable save path' \
' make rollout-video offscreen MP4 with simulation-time subtitles' \
' make showcase render feature overview' \
'' \
'Backends and remote viewing:' \
' make canvas standalone scene and material editor' \
' make canvas-2d retained 2D physics/geometry debug canvas' \
' make scene-io save, load, and capture a Mojive scene' \
' make editor-files scene document workflow acceptance' \
' make entity-edit Entity lifecycle acceptance' \
' make undo-redo editor history and continuous edit acceptance' \
' make toy-physics minimal independent physics backend' \
' make live-view one publisher and two remote viewers' \
' make remote-authoring runtime entity creation over Live View' \
' make snapshot-record record remote scene snapshots' \
' make snapshot-replay replay recorded snapshots' \
'' \
'Verification:' \
' make p0 complete Renderer compatibility gate' \
' make p1 complete P0 and P1 acceptance gate' \
' make test-fast pure CPU behavior used during iteration' \
' make test-integration file, protocol, and multi-module CPU tests' \
' make test-physics tests that compile or step physics worlds' \
' make check lint plus fast and integration CPU tests' \
' make test-all CPU, physics, and both real GPU backends' \
' make gpu real OpenGL tests' \
' make gpu-bgfx native bgfx GPU tests' \
' make egl Linux EGL Renderer and wireframe contract' \
' make scene-renderer authored RGB, depth, and object-ID images' \
' make renderer-api public Renderer CPU and GPU contract' \
' make renderer-benchmark MuJoCo/OpenGL/bgfx public API timing comparison' \
' make renderer-benchmark-full complete resolution and output-mode matrix' \
' make physics-render-benchmark same-process physics/render concurrency experiment' \
' make physics-concurrency default editor runtime, including 100 humanoids' \
' make camera-state camera bookmark serialization and restore' \
' make scene-snapshot complete scene-state serialization and restore' \
' make cli typed local control commands' \
' make rpc local RPC protocol and capture artifacts' \
' make agent-control discover, edit, and verify an authored scene through RPC' \
' make agent-viewer verify RPC edits and presented viewport/window capture' \
' make material-parity material and dense-scene image baselines' \
' make shadow-scheduling deterministic light and shadow selection' \
' make doctor window-path smoke test' \
' make mujoco-audit MuJoCo visualization and core schema coverage' \
' make mujoco-model-suite compile, adapt, and render MuJoCo model collections' \
' make adapter-conformance adapter contract report' \
' make docs build the API and user guide under output/site' \
' make clean clear test/lint caches; keep builds and captures' \
' make clean-output delete generated captures, recordings and reports' \
' make clean-build delete build dependencies/products; rebuild before use' \
' make docs-check validate public docs, examples, and the strict site build' \
' make examples-check validate the runnable examples without opening a window' \
' make docs-serve serve the documentation locally' \
'' \
'Display and backend options:' \
' make editor BACKEND=opengl' \
' make editor LANGUAGE=zh_CN simplified Chinese UI' \
' MOJIVE_UI_SCALE=2 make editor' \
' MOJIVE_CJK_FONT=/path/font.otf make editor' \
' make hidpi BACKEND=opengl UI_SCALE=2' \
' MOJIVE_UI_SCALE=1.5 make viewer BACKEND=opengl SCENE=gizmo ARGS="--paused"' \
' make egl-viewer Linux GLFW EGL context' \
'' \
'BACKEND accepts opengl or bgfx (requires native build). Leave UI scale unset for automatic scaling.'
setup:
uv sync --python 3.11 --extra dev --extra mujoco --extra native
$(MAKE) setup-imgui
$(MAKE) native-editable
.PHONY: setup-imgui setup-g3 g3-ui g3-benchmark interaction-benchmark ui-corners ui-corners-gallery
setup-imgui:
$(PY) -m mojive.tools.build_imgui --install
# Keep the previous setup command working for existing checkouts.
setup-g3: setup-imgui
g3-ui:
$(PY) -m mojive.tools.tool_icons -o output/g3-ui/tool-icons
$(PY) -m mojive.tools.mouse_hint_icons -o output/g3-ui/mouse-icons
$(PY) -m mojive.tools.ui_runtime -o output/g3-ui/runtime
g3-benchmark:
$(PY) -m mojive.tools.benchmark_g3 $(ARGS)
interaction-benchmark:
$(PY) -m mojive.tools.benchmark_interaction $(ARGS)
ui-corners:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --interactive --page geometry --geometry-tab corners $(ARGS)
ui-corners-gallery:
$(PYTEST) -q -m gpu tests/gpu/test_ui_corner_controls.py -k tab_focus
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --smoothing 0 -o output/g3-controls/corners-000.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --smoothing 0.6 -o output/g3-controls/corners-060.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --smoothing 1 -o output/g3-controls/corners-100.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --imgui-radius 0 -o output/g3-controls/radius-00.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --imgui-radius 8 -o output/g3-controls/radius-08.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --imgui-radius 12 -o output/g3-controls/radius-12.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab corners --imgui-radius 16 -o output/g3-controls/radius-16.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab playback -o output/g3-controls/playback-aligned.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab workspaces -o output/g3-controls/workspaces.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page panels -o output/g3-controls/panels.png
MOJIVE_BACKEND=opengl $(PYTEST) -q -m gpu tests/gpu/test_debugdraw.py -k screen_arrows
## Lint, formatting, and CPU tests.
check: lint test
lint:
$(RUFF) check python tests examples
$(RUFF) format --check python tests examples
fmt:
$(RUFF) check --fix python tests examples
$(RUFF) format python tests examples
.PHONY: icon-presets fmt-cpp
icon-presets:
$(PY) -m mojive.tools.generate_icon_presets $(ARGS)
fmt-cpp:
rg --files cpp -g '*.cpp' -g '*.hpp' | xargs clang-format -i
docs:
uv run --no-sync mkdocs build --strict --site-dir output/site
docs-check: examples-check
$(PY) -m mojive.tools.check_docs
$(MAKE) docs
examples-check:
$(PY) -m compileall -q examples
docs-serve:
uv run --no-sync mkdocs serve --strict --open
## Fast tests contain pure CPU behavior and module contracts.
test-fast:
$(PYTEST) -q -m "not integration and not gpu and not physics and not slow and not golden"
## Integration tests cover files, protocols, processes, and composed modules.
test-integration:
$(PYTEST) -q -m "integration and not gpu and not physics and not slow and not golden"
## The default CPU suite excludes real GPU and physics worlds.
test: test-fast test-integration
test-physics:
$(PYTEST) -q -m physics
test-all: test test-physics gpu gpu-bgfx
mjcf-roundtrip:
$(PYTEST) -q -m physics tests/test_workspace.py -k 'mjcf_export or exports_formatted or export_current_pose'
## Isolate files because OpenGL and physics libraries own process-global registries.
gpu:
@for f in $$(ls tests/gpu/test_*.py); do echo "--- $$f"; $(PYTEST) -q -m "gpu or physics" $$f || exit 1; done
.PHONY: gpu-bgfx
gpu-bgfx: native-python-build setup-imgui
@export MOJIVE_RENDERER=bgfx MOJIVE_NATIVE_BUILD="$(abspath $(NATIVE_BUILD))"; \
for f in $(wildcard tests/gpu/test_*.py); do $(PYTEST) -q -m "gpu or physics" $$f || exit 1; done
egl:
@test "$$(uname -s)" = Linux || { echo 'make egl requires Linux'; exit 2; }
MOJIVE_GL=egl $(PYTEST) -q -m gpu tests/gpu/test_renderer_api.py
.PHONY: scene-renderer
scene-renderer:
$(PY) examples/offscreen_scene.py
renderer-api:
$(PYTEST) -q tests/test_renderer_api.py
$(PYTEST) -q -m gpu tests/gpu/test_renderer_api.py
$(PY) -m mojive.tools.renderer_api
renderer-benchmark:
$(PY) -m mojive.tools.renderer_benchmark $(ARGS)
renderer-benchmark-full:
$(PY) -m mojive.tools.renderer_benchmark --preset full \
-o output/renderer-benchmark/full-report.json $(ARGS)
p0: renderer-api
p1: check p0 mujoco-physics camera-state scene-snapshot rpc material-parity shadow-scheduling mujoco-audit golden parity reverse gpu gpu-bgfx
$(MAKE) adapter-conformance ADAPTER=mujoco CONFORMANCE_ASSET=deformables
## Compare golden images. ARGS selects cases; the agent reviews differences before accepting.
golden:
$(PY) -m mojive.tools.golden $(ARGS)
golden-accept:
$(PY) -m mojive.tools.golden --accept $(ARGS)
## Render OpenGL and the MuJoCo reference from one camera. The reference uses a subprocess.
parity:
$(PY) -m mojive.tools.parity $(ARGS)
## Calibrate diffuse, headlight, ambient, and texture lighting against MuJoCo.
calibrate:
$(PY) -m mojive.tools.calibrate
## Render the scene gallery for visual review.
gallery:
$(PY) -m mojive.tools.gallery
.PHONY: ui-diagnostics
ui-diagnostics:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab diagnostics -o output/ui-diagnostics.png $(ARGS)
.PHONY: ui-keyframe-follow
ui-keyframe-follow:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab icons --icon-group keyframe-follow -o output/ui-keyframe-follow/family.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --ui-scale 2 --page geometry --geometry-tab icons --icon-group keyframe-follow -o output/ui-keyframe-follow/family-hidpi.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab workspaces -o output/ui-keyframe-follow/keyframes.png
.PHONY: ui-icon-concepts
ui-icon-concepts:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab icons --icon-group overview -o output/ui-icon-concepts/overview.png
$(MAKE) ui-keyframe-follow
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1100 --page geometry --geometry-tab icons --icon-group ui-context -o output/ui-icon-concepts/ui-context.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1100 --page geometry --geometry-tab icons --icon-group ui-context --icon-alignment box -o output/ui-icon-concepts/ui-context-box.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1100 --ui-scale 2 --page geometry --geometry-tab icons --icon-group ui-context -o output/ui-icon-concepts/ui-context-hidpi.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1400 --page geometry --geometry-tab icons --icon-group capsules -o output/ui-icon-concepts/capsules.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group viewport-tools -o output/ui-icon-concepts/viewport-tools.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group viewport-playback -o output/ui-icon-concepts/viewport-playback.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1800 --page geometry --geometry-tab icons --icon-group keyframe-transport -o output/ui-icon-concepts/keyframe-transport.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 2050 --page geometry --geometry-tab icons --icon-group keyframes -o output/ui-icon-concepts/keyframes.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 2050 --page geometry --geometry-tab icons --icon-group keyframes --icon-alignment box -o output/ui-icon-concepts/keyframes-box.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group panels -o output/ui-icon-concepts/panels.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group scene-helpers -o output/ui-icon-concepts/scene-helpers.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group scene-helpers --icon-alignment box -o output/ui-icon-concepts/scene-helpers-box.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1650 --page geometry --geometry-tab icons --icon-group status-and-input -o output/ui-icon-concepts/status-input.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab tools --tool-stroke 1.46 --rotate-gap-ratio 1.0 -o output/ui-icon-concepts/tools-max-gap.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1850 --page geometry --geometry-tab playback --preview-icon-library --playback-zoom 4 -o output/ui-icon-concepts/playback-layout-4x.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --preview-icon-library --page workspace -o output/ui-icon-concepts/context-workspace.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --preview-icon-library --page panels -o output/ui-icon-concepts/context-panels.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1200 --preview-icon-library --page geometry --geometry-tab hints -o output/ui-icon-concepts/context-hints.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --height 1200 --ui-scale 2 --preview-icon-library --page geometry --geometry-tab hints -o output/ui-icon-concepts/context-hints-hidpi.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --preview-icon-library --page geometry --geometry-tab workspaces -o output/ui-icon-concepts/context-keyframes.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --preview-icon-library --page redesign -o output/ui-icon-concepts/context-redesign.png
.PHONY: ui-icon-scales ui-icon-references
ui-icon-references:
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_ui_icon_alignment.py -k reference_styles
ICON_SCALES ?= 0.65 1 1.25 1.5
ICON_SCALE_GROUPS ?= viewport-tools viewport-playback keyframe-transport keyframes
ui-icon-scales:
@set -e; for scale in $(ICON_SCALES); do \
for group in $(ICON_SCALE_GROUPS); do \
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility \
--ui-scale $$scale --height 2050 --page geometry --geometry-tab icons \
--icon-group $$group -o output/ui-icon-scales/$$group-$$scale.png $(ARGS); \
done; \
done
.PHONY: ui-reset-heads
ui-reset-heads:
@set -e; for scale in 0.65 1 1.25 1.5; do \
for head in 1 1.5 2; do \
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility \
--ui-scale $$scale --height 1850 --page geometry --geometry-tab icons \
--icon-group viewport-playback --reset-head-scale $$head \
-o output/ui-reset-heads/scale-$$scale-head-$$head.png; \
done; \
done
ui-feasibility:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --interactive $(ARGS)
.PHONY: svg-icons ui-svg-icons ui-svg-icons-gallery
svg-icons:
$(PY) -m mojive.tools.svg_icons $(ARGS)
ui-svg-icons:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --interactive --page geometry --geometry-tab svg --width 1100 --height 800 $(ARGS)
ui-svg-icons-gallery:
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_svg_icons.py
.PHONY: ui-components ui-components-gallery ui-optical ui-optical-gallery
ui-components:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --interactive --page components --width 1100 --height 760 $(ARGS)
ui-components-gallery:
@set -e; for scale in 1 2.25; do \
for surface in panel card; do \
for scene in basic inspector filters actions transform material scene joints capture; do \
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility \
--page components --corner-scene $$scene --corner-surface $$surface --width 1100 --height 800 \
--ui-scale $$scale -o output/ui-components/$(BACKEND)-$$scene-$$surface-$$scale.png $(ARGS); \
done; \
done; \
done
ui-optical:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --interactive --page components --component-tab optical --width 1100 --height 800 $(ARGS)
ui-optical-gallery:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page components --component-tab optical --width 1100 --height 800 --ui-scale 1 -o output/ui-optical/$(BACKEND)-1.png $(ARGS)
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page components --component-tab optical --width 1100 --height 800 --ui-scale 2.25 -o output/ui-optical/$(BACKEND)-2.25.png $(ARGS)
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page components --component-tab optical --width 1100 --height 800 --auto-align-centroid -o output/ui-optical/$(BACKEND)-auto.png $(ARGS)
ui-runtime:
$(PY) -m mojive.tools.ui_runtime $(ARGS)
.PHONY: viewport-resize
## Verify current-frame viewport sizing during native and dock-splitter resizing.
viewport-resize:
$(PY) -m mojive.tools.viewport_resize --backend $(BACKEND) $(ARGS)
.PHONY: ui-default-layout
ui-default-layout:
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m "gpu or physics" tests/gpu/test_default_layout.py $(ARGS)
.PHONY: ui-layout-audit
ui-layout-audit:
$(PY) -m mojive.tools.ui_layout_audit $(ARGS)
.PHONY: ui-redesign
ui-redesign:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page redesign -o output/ui-redesign/overview.png $(ARGS)
## Refresh README images with unmodified production UI and renderer captures.
readme-media:
$(PY) -m mojive.tools.build_readme_media \
--output output/readme-media --publish docs/images/readme $(ARGS)
## Export production Tool Column geometry on transparent 1024px canvases.
tool-icons:
$(PY) -m mojive.tools.tool_icons $(ARGS)
## Export production mouse hint geometry with black and transparent shells.
mouse-icons:
$(PY) -m mojive.tools.mouse_hint_icons $(ARGS)
## Measure fresh-process startup and first presentation across render backends.
.PHONY: startup-profile
startup-profile:
$(PY) -m mojive.tools.startup_profile $(ARGS)
## Profile production viewport chrome and enforce its incremental frame budget.
ui-frame-profile:
$(PY) -m mojive.tools.ui_frame_profile $(ARGS)
.PHONY: editor-profile
editor-profile:
$(PY) -m mojive.tools.editor_profile --renderer $(BACKEND) $(ARGS)
.PHONY: inspector-profile
inspector-profile:
$(PY) -m mojive.tools.inspector_profile --renderer $(BACKEND) $(ARGS)
.PHONY: editor-soak
editor-soak:
$(PY) -m mojive.tools.editor_soak --renderer $(BACKEND) $(ARGS)
.PHONY: editor-tail-profile
editor-tail-profile:
$(PY) -m mojive.tools.editor_tail_profile --renderer $(BACKEND) $(ARGS)
.PHONY: hierarchy-benchmark
hierarchy-benchmark:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.hierarchy_benchmark $(ARGS)
.PHONY: timeline-benchmark
timeline-benchmark:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.timeline_benchmark $(ARGS)
.PHONY: recording-benchmark
recording-benchmark:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.recording_benchmark $(ARGS)
.PHONY: joint-gizmo-profile
joint-gizmo-profile:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.joint_gizmo_profile $(ARGS)
ui-gallery:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page workspace -o output/ui-workspace.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab playback -o output/ui-geometry-playback.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab tools -o output/ui-geometry-tools.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab icons --icon-group overview -o output/ui-icon-concepts/overview.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab hints -o output/ui-geometry-hints.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab gizmos -o output/ui-geometry-transform-gizmos.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab helpers -o output/ui-geometry-joint-helpers.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab status -o output/ui-geometry-status.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab diagnostics -o output/ui-diagnostics.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab shell -o output/ui-geometry-shell.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab panels -o output/ui-geometry-panels.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab workspaces -o output/ui-geometry-workspaces.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --page geometry --geometry-tab workspaces --preview-icon-library -o output/ui-geometry-workspaces-preview.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --ui-scale 4 --page workspace -o output/ui-workspace-hidpi.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --ui-scale 4 --page panels -o output/ui-panels-hidpi.png
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.ui_feasibility --ui-scale 4 --page geometry --geometry-tab helpers -o output/ui-geometry-joint-helpers-hidpi.png
$(PY) -m mojive.tools.ui_runtime -o output/ui-runtime
gizmo-gallery:
$(PY) -m mojive.tools.gizmo_gallery $(ARGS)
hidpi-gallery:
MOJIVE_UI_SCALE=$(UI_SCALE) $(PY) -m mojive.tools.gizmo_gallery \
-o output/gizmo-gallery-hidpi $(ARGS)
model-loading:
$(PY) -m mojive.tools.model_loading $(ARGS)
model-composition:
$(PYTEST) -q -m physics tests/test_adapter.py -k 'mjspec_model_composition'
$(PY) -m mojive.tools.model_composition $(ARGS)
editor-performance:
$(PYTEST) -q -m physics tests/test_editor_performance.py
$(PY) -m mojive.tools.editor_performance $(ARGS)
stability: rpc-soak format-validation
$(PYTEST) -q -m physics tests/test_stability.py
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_renderer_api.py -k 'multi_camera_concurrency'
$(PY) -m mojive.tools.stability $(ARGS)
rpc-soak:
$(PYTEST) -q -m physics tests/test_control_rpc.py -k 'reuses_one_connection or recovers_after_invalid or idle_connection or reconnects_on_the_call'
.PHONY: rpc-benchmark
rpc-benchmark:
$(PY) -m mojive.tools.benchmark_rpc --backend $(BACKEND) $(ARGS)
format-validation:
$(PYTEST) -q tests/test_recording.py
$(PYTEST) -q -m physics tests/test_scene_state.py -k 'version or current or future'
scene-io:
$(PY) -m mojive.tools.scene_io $(ARGS)
editor-files:
$(PYTEST) -q tests/test_static_scene.py -k 'document_commands'
$(PY) -m mojive.tools.scene_io $(ARGS)
entity-edit:
$(PYTEST) -q tests/test_static_scene.py -k 'entity_lifecycle'
$(PYTEST) -q -m gpu tests/gpu/test_static_viewer.py -k 'editor_actions'
undo-redo:
$(PYTEST) -q tests/test_static_scene.py -k 'undo_redo or history or edit_transaction'
$(PYTEST) -q -m gpu tests/gpu/test_static_viewer.py -k 'undo_redo'
remote-authoring:
$(PY) -m mojive.tools.remote_authoring $(ARGS)
additive:
$(PY) -m mojive.tools.additive $(ARGS)
bench:
$(PY) -m mojive.tools.bench
showcase:
$(PY) -m mojive.tools.showcase
## Probe current OpenGL platform capabilities.
probe:
$(PY) -m mojive.tools.probe_gl
## Apply registered mutations and confirm their regression checks fail.
reverse:
$(PY) -m mojive.tools.reverse_verify
## Open an asset. Pass viewer flags through ARGS.
SCENE ?= test_scene
ARGS ?=
BACKEND ?= opengl
LANGUAGE ?= $(MOJIVE_LANGUAGE)
viewer:
MOJIVE_RENDERER=$(BACKEND) MOJIVE_LANGUAGE=$(LANGUAGE) $(PY) -m mojive.cli view $(SCENE) $(ARGS)
egl-viewer:
@test "$$(uname -s)" = Linux || { echo 'make egl-viewer requires Linux'; exit 2; }
MOJIVE_GL=egl PYOPENGL_PLATFORM=egl $(PY) -m mojive.cli view $(SCENE) $(ARGS)
UI_SCALE ?= 2
hidpi:
MOJIVE_RENDERER=$(BACKEND) MOJIVE_LANGUAGE=$(LANGUAGE) MOJIVE_UI_SCALE=$(UI_SCALE) $(PY) -m mojive.cli view gizmo --paused $(ARGS)
## Open an empty MuJoCo scene and load MJCF or URDF from File > Open Model.
empty:
MOJIVE_RENDERER=$(BACKEND) MOJIVE_LANGUAGE=$(LANGUAGE) $(PY) -m mojive.cli view empty --paused $(ARGS)
## Empty authored scene with New/Open/Save and Entity creation workflows.
editor:
MOJIVE_RENDERER=$(BACKEND) MOJIVE_LANGUAGE=$(LANGUAGE) $(PY) -m mojive.cli editor $(ARGS)
workspace-edit:
$(PYTEST) -q tests/test_workspace.py tests/test_scene_entities.py
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor $(ARGS)
## Programmatic scene, OpenGL rendering, and the standard UI.
canvas:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli canvas $(ARGS)
canvas-2d:
MOJIVE_RENDERER=$(BACKEND) $(PY) examples/canvas2d.py $(ARGS)
## Independent physics adapter with gravity, collision, controls, and pose editing.
toy-physics:
$(PY) -m mojive.cli toy $(ARGS)
ADAPTER ?= toy
CONFORMANCE_ASSET ?=
## Headless contract report for third-party adapters. MuJoCo example:
## make adapter-conformance ADAPTER=mujoco CONFORMANCE_ASSET=test_scene
adapter-conformance:
$(PY) -m mojive.cli conformance $(ADAPTER) $(if $(CONFORMANCE_ASSET),--asset $(CONFORMANCE_ASSET),) $(ARGS)
## Editable lights and Environment controls for ambient light, fog, haze, and headlight.
lighting:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli canvas --demo lighting $(ARGS)
image-light:
$(PY) -m mojive.cli view assets/image_light.xml --paused $(ARGS)
many-lights:
$(PY) -m mojive.tools.mujoco_many_lights $(ARGS)
material-parity:
$(PYTEST) -q tests/test_builder.py tests/test_scene.py
$(PY) -m mojive.tools.material_parity $(ARGS)
material-parity-accept:
$(PY) -m mojive.tools.material_parity --accept $(ARGS)
shadow-scheduling:
$(PYTEST) -q tests/test_light_schedule.py
$(PYTEST) -q -m gpu tests/gpu/test_shadows.py -k 'eight_local or local_light_indices'
$(PY) -m mojive.tools.shadow_scheduling $(ARGS)
scene-icons:
$(PY) -m mojive.cli canvas --demo lighting \
--enable-render camera --enable-render light $(ARGS)
scene-entities:
$(PYTEST) -q tests/test_scene_entities.py
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.scene_entities $(ARGS)
## World anchors, screen offsets, alignment, and depth modes with the UI font.
text-overlay:
$(PY) -m mojive.cli canvas --demo text $(ARGS)
OUTPUT ?= output/recording.mp4
SCREENSHOT ?= output/capture.png
## Capture at any resolution. Example: make capture SCENE=test_scene ARGS="--width 1920 --height 1080".
capture:
$(PY) -m mojive.cli capture $(SCENE) -o $(SCREENSHOT) $(ARGS)
## Stream video encoding. Example: make record SCENE=test_scene ARGS="--frames 120".
record:
$(PY) -m mojive.cli record $(SCENE) -o $(OUTPUT) $(ARGS)
## End-to-end Renderer + VideoRecorder + Pillow acceptance, without editor UI.
rollout-video:
$(PY) examples/mujoco_video.py assets/test_scene.xml --label "Mojive rollout" \
--output output/examples/rollout.mp4 $(ARGS)
LIVE_HOST ?= 127.0.0.1
LIVE_PORT ?= 47650
LIVE_SCENE ?= gizmo
## Run physics headlessly and publish the latest snapshot.
serve:
$(PY) -m mojive.cli serve $(LIVE_SCENE) --host $(LIVE_HOST) --port $(LIVE_PORT) $(ARGS)
## Open an independent remote viewer.
attach:
$(PY) -m mojive.cli attach --host $(LIVE_HOST) --port $(LIVE_PORT) $(ARGS)
## Start one physics publisher, one effect viewer, and one normal-debug viewer.
live-view:
@$(PY) -m mojive.cli serve $(LIVE_SCENE) --host $(LIVE_HOST) --port $(LIVE_PORT) $(ARGS) & server=$$!; \
$(PY) -m mojive.cli attach --host $(LIVE_HOST) --port $(LIVE_PORT) --title "Mojive effect" & effect=$$!; \
$(PY) -m mojive.cli attach --host $(LIVE_HOST) --port $(LIVE_PORT) --title "Mojive debug" --debug-view normal & debug=$$!; \
trap 'kill $$effect $$debug $$server 2>/dev/null || true' EXIT INT TERM; \
wait $$effect; wait $$debug
SNAPSHOT ?= output/session.fvs
## Record structure revisions, physics frames, and debug commands.
snapshot-record:
$(PY) -m mojive.cli serve $(LIVE_SCENE) --host $(LIVE_HOST) --port $(LIVE_PORT) --record-snapshot $(SNAPSHOT) $(ARGS)
## Replay a snapshot loop through the remote protocol.
snapshot-replay:
@$(PY) -m mojive.cli replay $(SNAPSHOT) --host $(LIVE_HOST) --port $(LIVE_PORT) --loop & server=$$!; \
trap 'kill $$server 2>/dev/null || true' EXIT INT TERM; \
$(PY) -m mojive.cli attach --host $(LIVE_HOST) --port $(LIVE_PORT) --title "Mojive replay" $(ARGS)
camera-state:
$(PY) -m pytest -q -m physics tests/test_scene_state.py -k camera
$(PY) -m mojive.tools.scene_state $(ARGS)
scene-snapshot:
$(PY) -m pytest -q -m physics tests/test_scene_state.py
$(PY) -m mojive.tools.scene_state $(ARGS)
cli:
$(PYTEST) -q -m physics tests/test_control_rpc.py
rpc: cli
$(PYTEST) -q -m "gpu or physics" tests/gpu/test_control_rpc_capture.py
$(PY) -m mojive.tools.control_rpc
.PHONY: agent-control agent-viewer
agent-control:
$(PY) examples/agent_inspection.py $(ARGS)
agent-viewer:
$(PY) examples/agent_inspection.py --viewer $(ARGS)
## Compact Inspector transform acceptance image.
inspector:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.inspector $(ARGS)
MOJIVE_RENDERER=$(BACKEND) $(PYTEST) -q -m gpu tests/gpu/test_inspector_solver.py
## Native gizmo acceptance: G position, R rotation, T frame, F9 settings.
gizmo:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli view gizmo --paused $(ARGS)
## Numbered revolute, prismatic, ball, free, multi-joint, and compact-range acceptance.
joint-gizmo:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor joint_gizmo $(ARGS)
## Fixed-body transform and sphere/box/cylinder/capsule dimension authoring acceptance.
primitive-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
.PHONY: scene-editing-audit
scene-editing-audit:
$(PY) -m mojive.tools.scene_editing_audit $(ARGS)
.PHONY: material-workflow
## Offscreen public API acceptance for box/floor materials, skybox, and editable grid.
material-workflow:
$(PY) -m mojive.tools.material_workflow $(ARGS)
.PHONY: viewer-compat
viewer-compat:
$(PY) examples/mujoco_viewer.py $(ARGS)
.PHONY: viewer-managed viewer-passive
viewer-managed:
$(PY) examples/viewer_managed.py $(ARGS)
viewer-passive:
$(PY) examples/viewer_passive.py $(ARGS)
## Material creation/copy/binding and 2D image import acceptance.
material-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Geometry contact, solver, surface, mass, group, inertia, and fluid acceptance.
contact-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Body auto/explicit inertia, gravcomp, mocap, and sleep-policy acceptance.
body-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Geometry shape switching plus mesh, height-field, cube, and skybox import acceptance.
resource-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Model-local files, materials, and height-field physical-dimension acceptance.
asset-browser:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Joint dynamics/solver/force limits and site shape/group/endpoints acceptance.
joint-site-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor joint_gizmo $(ARGS)
## Contact, actuator, sensor, tendon, and equality component acceptance.
model-component-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Simulation-take transport plus model-local snapshot Dope Sheet acceptance.
keyframe-authoring:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Ctrl/Cmd multi-selection and one-rebuild model topology deletion acceptance.
batch-editing:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor test_scene $(ARGS)
## Dockable non-modal Settings acceptance.
settings:
MOJIVE_OPEN_SETTINGS=1 MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli editor $(ARGS)
## Perturbation acceptance: Ctrl+left translates and Ctrl+right rotates a selected free body.
perturb:
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.cli view gizmo $(ARGS)
.PHONY: physics-options-check
## Exercise live physics options and capture localized Inspector controls.
physics-options-check:
$(PYTEST) -q -m physics tests/test_physics_options.py
MOJIVE_PHYSICS_OPTIONS_CAPTURE=output/physics-options $(PYTEST) -q -m gpu tests/gpu/test_physics_options.py
.PHONY: perturb-check
## Force parity, passive write-back, strength settings, and held Control drags.
perturb-check:
$(PYTEST) -q -m physics tests/test_mujoco_perturb.py tests/test_passive.py tests/test_mujoco_viewer.py
MOJIVE_PERTURB_CAPTURE=output/perturb-check $(PYTEST) -q -m gpu tests/gpu/test_perturb_drag.py
## Selection outline acceptance across multiple geoms and occlusion.
outline:
$(PY) -m mojive.cli view outline --paused
## Multiple planar reflection acceptance for height, clipping, and winding.
reflect:
$(PY) -m mojive.cli view reflection_multiple --paused
## Sparse checkout of one Google DeepMind MuJoCo Menagerie model.
ROBOT ?= unitree_go2
MENAGERIE_DIR ?= build/mujoco_menagerie
robot:
@if [ ! -d "$(MENAGERIE_DIR)/.git" ]; then \
git clone --depth 1 --filter=blob:none --sparse \
https://github.com/google-deepmind/mujoco_menagerie.git "$(MENAGERIE_DIR)"; \
fi
@git -C "$(MENAGERIE_DIR)" sparse-checkout add assets "$(ROBOT)"
$(PY) -m mojive.cli view "$(MENAGERIE_DIR)/$(ROBOT)/scene.xml" $(ARGS)
TEXTURE_MINIFICATION_SCENE ?= $(MENAGERIE_DIR)/anybotics_anymal_c/scene.xml
texture-minification:
@test -f "$(TEXTURE_MINIFICATION_SCENE)" || { \
echo "missing scene: $(TEXTURE_MINIFICATION_SCENE)"; \
echo "set TEXTURE_MINIFICATION_SCENE=/path/to/anybotics_anymal_c/scene.xml"; \
exit 2; \
}
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.texture_minification \
"$(TEXTURE_MINIFICATION_SCENE)"
LOCAL_SHADOW_SCENE ?= $(MENAGERIE_DIR)/anybotics_anymal_c/scene.xml
local-shadow-precision:
@test -f "$(LOCAL_SHADOW_SCENE)" || { \
echo "missing scene: $(LOCAL_SHADOW_SCENE)"; \
echo "set LOCAL_SHADOW_SCENE=/path/to/anybotics_anymal_c/scene.xml"; \
exit 2; \
}
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.local_shadow_precision \
"$(LOCAL_SHADOW_SCENE)"
shadow-quality:
$(PYTEST) -q tests/test_cascades.py tests/test_panels.py -k shadow_quality
MOJIVE_RENDERER=$(BACKEND) $(PY) -m mojive.tools.shadow_quality $(ARGS)
AUDIT_SCENE ?= mujoco_visuals
## Full MuJoCo adapter and simulation regression suite.
mujoco-physics:
$(PYTEST) -q -m physics
## Headless MuJoCo visualization and exact linked-schema coverage report.
mujoco-audit:
$(PY) -m mojive.cli audit $(AUDIT_SCENE) --strict
MUJOCO_MODEL_ROOTS ?= $(HOME)/Downloads/mujoco/model $(HOME)/Projects/PhysicsEngines/mujoco/model
MUJOCO_MODEL_REPORT ?= output/mujoco-model-suite.json
MUJOCO_MODEL_JOBS ?= 4
## Compile, adapt, and render every XML below the configured MuJoCo model roots.
mujoco-model-suite:
$(PY) -m mojive.tools.mujoco_model_suite $(MUJOCO_MODEL_ROOTS) \
--jobs $(MUJOCO_MODEL_JOBS) --report $(MUJOCO_MODEL_REPORT) $(ARGS)
## Interactive heightfield, site, tendon, and contact scene.
mujoco-visuals:
$(PY) -m mojive.cli view mujoco_visuals \
--enable-render tendon --enable-render contactpoint --enable-render contactforce $(ARGS)
## MuJoCo joint markers, root subtree COM and body inertia boxes.
mujoco-debug:
$(PY) -m mojive.cli view joint_types --paused \
--enable-render joint --enable-render com --enable-render inertia $(ARGS)
mujoco-actuators:
$(PY) -m mojive.cli view actuator_visuals --paused \
--camera overview --enable-render actuator --enable-render activation $(ARGS)
mujoco-slider-crank:
$(PY) -m mojive.tools.mujoco_slider_crank
mujoco-solver-diagnostics:
$(PY) -m mojive.tools.mujoco_solver_diagnostics
mujoco-islands:
$(PY) -m mojive.tools.mujoco_islands
mujoco-bvh:
$(PY) -m mojive.tools.mujoco_bvh $(ARGS)
mujoco-convex-hull:
$(PY) -m mojive.tools.mujoco_convex_hull $(ARGS)
.PHONY: geometry-views geometry-ui
geometry-views:
$(PY) -m mojive.tools.geometry_views $(ARGS)
geometry-ui:
$(PY) -m mojive.tools.geometry_views_ui $(ARGS)
mujoco-rangefinder:
$(PY) -m mojive.cli view rangefinder --paused \
--enable-render rangefinder $(ARGS)
mujoco-constraints:
$(PY) -m mojive.cli view constraints --paused \
--camera overview --enable-render constraint $(ARGS)
mujoco-editing:
$(PY) -m mojive.cli view mocap_equality --paused $(ARGS)
## Open Camera with F6; calibrated_shift demonstrates an off-center principal point.
cameras:
$(PY) -m mojive.cli view mujoco_visuals $(ARGS)
camera-intrinsics:
$(PY) -m mojive.cli capture mujoco_visuals --camera calibrated_shift \
--width 1600 --height 1000 -o output/cameras/calibrated-shift.png $(ARGS)
## Inspect MuJoCo visual groups and synchronized picking filters in Settings.
geom-groups:
$(PY) -m mojive.cli view mujoco_visuals --paused $(ARGS)