Robot arms pass goods from belt to belt; native beam primitive
Deploy web Studio / deploy (push) Successful in 1m3s

- Robot arm (category Industry): picks goods off the end of the nearest conveyor within its reach
  and puts them on the start of another conveyor within reach, or on a pallet a quarter turn on
  (pick / put: auto or a side). One move per item coming in (cycle 0) or a set cycle; waits while
  the line before it stands. The belt it feeds carries its goods at its pace and starts its loop
  when they land (feeds carry a time offset `ph`), so arm and belts stay in step.
- Drawn as a 16-pose flipbook: two-link inverse kinematics per pose, each pose shown for a
  sixteenth of the cycle by a stepped CSS animation (iso-flip; pose 0 alone when unanimated).
  Poses pointing away from the viewer are drawn before the base, the others after it.
- New sprite method beam(a, b, n, w, mat): a square bar between two 3D points, six faces culled
  and shaded like face(). Native, so the factory demo renders in 4.7 ms instead of 18.8 ms.
- Factory demo: a palletiser at the end of the carton line, a loading robot passing drums from the
  incline onto the loading belt into the truck. MCP instructions on robot arms.

Checks: 70 Rust tests (arms and belts in step, waiting arm, beam faces from every side),
Studio 109/109, web 90/90.
This commit is contained in:
grabowski committed 2026-10-24 22:05:46 +07:00
1 parent 18dd324543
commit f49798583e
14 files changed
+460 -31

No files matched your search

+5
View File
@@ -122,6 +122,10 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
.iso-svg .iso-rideout { animation: iso-fadeout 2s linear infinite; }
.iso-svg .iso-rideio { animation: iso-fadeio 2s linear infinite; }
.iso-svg .iso-ram { animation: iso-ram 2s ease-in-out infinite; }
/* robot arms: a flipbook of 16 poses, each shown for a sixteenth of the cycle (delays set the turn);
unanimated (reduced motion, ghosted) only the first */
.iso-svg .iso-flip { visibility: hidden; animation: iso-flip16 4s step-end infinite; }
.iso-svg .iso-flip.iso-pose0 { visibility: visible; }
.iso-svg .iso-park { display: none; }
/* paused off-screen (iso-off), when stopped (iso-still), with animation off and during pan/zoom gestures */
.iso-off .iso-a, .iso-still .iso-a, .iso-off .iso-drive, .iso-still .iso-drive, .iso-off .iso-ledr, .iso-off .iso-ledo, .iso-still .iso-ledr, .iso-still .iso-ledo,
@@ -142,6 +146,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
@keyframes iso-fadein { 0% { opacity: 0; } 35%, 100% { opacity: 1; } }
@keyframes iso-fadeout { 0%, 65% { opacity: 1; } 100% { opacity: 0; } }
@keyframes iso-fadeio { 0%, 100% { opacity: 0; } 30%, 70% { opacity: 1; } }
@keyframes iso-flip16 { 0% { visibility: visible; } 6.25%, 100% { visibility: hidden; } }
@keyframes iso-ram { 0%, 20%, 100% { transform: translate(0, 0); } 45%, 55% { transform: translate(var(--dx), var(--dy)); } }
@keyframes iso-move { from { transform: translate(0, 0); } to { transform: translate(var(--dx), var(--dy)); } }
@keyframes iso-shuttle {