@rydr/game-sdk 8.10.0 → 8.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +26 -2
  2. package/dist/client/PlatformClient.d.ts.map +1 -1
  3. package/dist/client/PlatformClient.js +14 -2
  4. package/dist/client/PlatformClient.js.map +1 -1
  5. package/dist/client/Room.d.ts +9 -4
  6. package/dist/client/Room.d.ts.map +1 -1
  7. package/dist/client/Room.js +8 -5
  8. package/dist/client/Room.js.map +1 -1
  9. package/dist/host/PlatformHost.d.ts +4 -2
  10. package/dist/host/PlatformHost.d.ts.map +1 -1
  11. package/dist/host/PlatformHost.js +5 -3
  12. package/dist/host/PlatformHost.js.map +1 -1
  13. package/dist/protocol/identity.d.ts +63 -0
  14. package/dist/protocol/identity.d.ts.map +1 -1
  15. package/dist/protocol/identity.js +40 -1
  16. package/dist/protocol/identity.js.map +1 -1
  17. package/dist/protocol/messages.d.ts +11 -4
  18. package/dist/protocol/messages.d.ts.map +1 -1
  19. package/dist/protocol/room.d.ts +26 -0
  20. package/dist/protocol/room.d.ts.map +1 -1
  21. package/dist/protocol/version.d.ts +2 -2
  22. package/dist/protocol/version.d.ts.map +1 -1
  23. package/dist/protocol/version.js +23 -2
  24. package/dist/protocol/version.js.map +1 -1
  25. package/dist/three/README.md +111 -0
  26. package/dist/three/character/index.d.ts +14 -0
  27. package/dist/three/character/index.d.ts.map +1 -0
  28. package/dist/three/character/index.js +14 -0
  29. package/dist/three/character/index.js.map +1 -0
  30. package/dist/three/character/kit.d.ts +74 -0
  31. package/dist/three/character/kit.d.ts.map +1 -0
  32. package/dist/three/character/kit.js +254 -0
  33. package/dist/three/character/kit.js.map +1 -0
  34. package/dist/three/character/riders.d.ts +20 -0
  35. package/dist/three/character/riders.d.ts.map +1 -0
  36. package/dist/three/character/riders.js +383 -0
  37. package/dist/three/character/riders.js.map +1 -0
  38. package/dist/three/character/skeleton.d.ts +105 -0
  39. package/dist/three/character/skeleton.d.ts.map +1 -0
  40. package/dist/three/character/skeleton.js +57 -0
  41. package/dist/three/character/skeleton.js.map +1 -0
  42. package/dist/three/controller/glyph-texture.d.ts +29 -0
  43. package/dist/three/controller/glyph-texture.d.ts.map +1 -0
  44. package/dist/three/controller/glyph-texture.js +68 -0
  45. package/dist/three/controller/glyph-texture.js.map +1 -0
  46. package/dist/three/controller/index.d.ts +12 -0
  47. package/dist/three/controller/index.d.ts.map +1 -0
  48. package/dist/three/controller/index.js +12 -0
  49. package/dist/three/controller/index.js.map +1 -0
  50. package/dist/three/controller/joycon-designs.d.ts +49 -0
  51. package/dist/three/controller/joycon-designs.d.ts.map +1 -0
  52. package/dist/three/controller/joycon-designs.js +742 -0
  53. package/dist/three/controller/joycon-designs.js.map +1 -0
  54. package/dist/three/controller/joycon-shoulder-mesh.d.ts +41 -0
  55. package/dist/three/controller/joycon-shoulder-mesh.d.ts.map +1 -0
  56. package/dist/three/controller/joycon-shoulder-mesh.js +527 -0
  57. package/dist/three/controller/joycon-shoulder-mesh.js.map +1 -0
  58. package/dist/three/controller/joycon-spec.d.ts +233 -0
  59. package/dist/three/controller/joycon-spec.d.ts.map +1 -0
  60. package/dist/three/controller/joycon-spec.js +285 -0
  61. package/dist/three/controller/joycon-spec.js.map +1 -0
  62. package/dist/three/controller/three-pad-renderer.d.ts +81 -0
  63. package/dist/three/controller/three-pad-renderer.d.ts.map +1 -0
  64. package/dist/three/controller/three-pad-renderer.js +433 -0
  65. package/dist/three/controller/three-pad-renderer.js.map +1 -0
  66. package/dist/three/index.d.ts +2 -0
  67. package/dist/three/index.d.ts.map +1 -1
  68. package/dist/three/index.js +2 -0
  69. package/dist/three/index.js.map +1 -1
  70. package/dist/three/rider/cyclist-pose.d.ts +62 -0
  71. package/dist/three/rider/cyclist-pose.d.ts.map +1 -0
  72. package/dist/three/rider/cyclist-pose.js +173 -0
  73. package/dist/three/rider/cyclist-pose.js.map +1 -0
  74. package/dist/three/rider/index.d.ts +8 -0
  75. package/dist/three/rider/index.d.ts.map +1 -0
  76. package/dist/three/rider/index.js +8 -0
  77. package/dist/three/rider/index.js.map +1 -0
  78. package/dist/three/rider/three-rider-rig.d.ts +80 -0
  79. package/dist/three/rider/three-rider-rig.d.ts.map +1 -0
  80. package/dist/three/rider/three-rider-rig.js +418 -0
  81. package/dist/three/rider/three-rider-rig.js.map +1 -0
  82. package/dist/ui/README.md +153 -1
  83. package/dist/ui/controller/combo-demo.d.ts +9 -0
  84. package/dist/ui/controller/combo-demo.d.ts.map +1 -1
  85. package/dist/ui/controller/combo-demo.js +1 -0
  86. package/dist/ui/controller/combo-demo.js.map +1 -1
  87. package/dist/ui/controller/control-spotlight.d.ts +10 -1
  88. package/dist/ui/controller/control-spotlight.d.ts.map +1 -1
  89. package/dist/ui/controller/control-spotlight.js +42 -42
  90. package/dist/ui/controller/control-spotlight.js.map +1 -1
  91. package/dist/ui/controller/control-trainer.d.ts +14 -0
  92. package/dist/ui/controller/control-trainer.d.ts.map +1 -1
  93. package/dist/ui/controller/control-trainer.js +6 -0
  94. package/dist/ui/controller/control-trainer.js.map +1 -1
  95. package/dist/ui/controller/controller-map.d.ts +9 -0
  96. package/dist/ui/controller/controller-map.d.ts.map +1 -1
  97. package/dist/ui/controller/controller-map.js +8 -6
  98. package/dist/ui/controller/controller-map.js.map +1 -1
  99. package/dist/ui/controller/controller-pad.d.ts +35 -2
  100. package/dist/ui/controller/controller-pad.d.ts.map +1 -1
  101. package/dist/ui/controller/controller-pad.js +47 -7
  102. package/dist/ui/controller/controller-pad.js.map +1 -1
  103. package/dist/ui/controller/index.d.ts +1 -0
  104. package/dist/ui/controller/index.d.ts.map +1 -1
  105. package/dist/ui/controller/index.js +1 -0
  106. package/dist/ui/controller/index.js.map +1 -1
  107. package/dist/ui/controller/renderer.d.ts +118 -0
  108. package/dist/ui/controller/renderer.d.ts.map +1 -0
  109. package/dist/ui/controller/renderer.js +93 -0
  110. package/dist/ui/controller/renderer.js.map +1 -0
  111. package/dist/ui/controller/styles.js +30 -0
  112. package/dist/ui/controller/styles.js.map +1 -1
  113. package/dist/ui/index.d.ts +6 -0
  114. package/dist/ui/index.d.ts.map +1 -1
  115. package/dist/ui/index.js +6 -0
  116. package/dist/ui/index.js.map +1 -1
  117. package/dist/ui/rider-rig.d.ts +315 -0
  118. package/dist/ui/rider-rig.d.ts.map +1 -0
  119. package/dist/ui/rider-rig.js +1000 -0
  120. package/dist/ui/rider-rig.js.map +1 -0
  121. package/dist/ui/showcase/index.d.ts +11 -0
  122. package/dist/ui/showcase/index.d.ts.map +1 -1
  123. package/dist/ui/showcase/index.js +109 -1
  124. package/dist/ui/showcase/index.js.map +1 -1
  125. package/package.json +8 -4
@@ -0,0 +1,433 @@
1
+ /**
2
+ * THE 3D PAD RENDERER — a Joy-Con pair in three.js, drop-in wherever the flat drawing goes.
3
+ *
4
+ * ```ts
5
+ * import { createThreePadRenderer } from "@rydr/game-sdk/three";
6
+ * import { mountControllerMap } from "@rydr/game-sdk/ui";
7
+ *
8
+ * mountControllerMap(host, { press: session, actions, renderer: createThreePadRenderer });
9
+ * ```
10
+ *
11
+ * It satisfies `PadRenderer` (see `ui/controller/renderer.ts`), which is the entire contract the five
12
+ * controller views speak. So the map's leader lines, the combo demo's timeline, the spotlight's
13
+ * captions and the guided lesson's gating all work against it **unchanged** — none of them knows or
14
+ * cares that there is a WebGL canvas where an `<svg>` used to be.
15
+ *
16
+ * ## What the third dimension actually buys
17
+ *
18
+ * Two things the flat pad could not say:
19
+ *
20
+ * 1. **The triggers are visible.** `ZL`/`ZR` live on the back of each half. The flat drawing had to
21
+ * float them above the shell (that's what the `y −20` band in `PAD_VIEWBOX` is for). Here they sit
22
+ * where they really are, and the pad tilts forward just enough to show them.
23
+ * 2. **A press is a press.** The flat pad simulates depth by dropping a shape onto its own drop
24
+ * shadow. Here the button actually moves along the viewing axis, and a stick actually leans.
25
+ *
26
+ * ## Only the Joy-Con
27
+ *
28
+ * `brand: "joycon"` is the one silhouette modelled — it's what PLAT-1556 asked for, and it happens to
29
+ * be the most tractable shape in the kit (two rounded slabs rather than one organic shell). Ask this
30
+ * renderer for any other brand and it says so and draws the Joy-Con anyway, rather than failing: a
31
+ * caller who pinned `brand` has a bug, and a blank canvas hides it.
32
+ *
33
+ * ## Cost
34
+ *
35
+ * One WebGL context per mounted pad, and browsers cap those (~8–16). A page showing several 3D views at
36
+ * once is close to that ceiling — which is why the render loop is shared, idle-skipping and paused on a
37
+ * hidden tab: a pad nobody is touching costs nothing per frame, exactly like the flat one's dirty-guard.
38
+ */
39
+ import * as THREE from "three";
40
+ import { FAINT_PARTS, SHELL_OWNED_PARTS, STICK_LIT_DEADZONE } from "../../ui/controller/pad-svg.js";
41
+ import { partRectOf, } from "../../ui/controller/renderer.js";
42
+ import { JOYCON_DESIGNS } from "./joycon-designs.js";
43
+ import { VIEW, W } from "./joycon-spec.js";
44
+ import { glyphTexture } from "./glyph-texture.js";
45
+ /** The four things a part can say, as colours. Same grammar and same hues as the flat pad's CSS. */
46
+ const STATE_COLOR = {
47
+ off: 0x8ea3bd,
48
+ hint: 0xf2f6ff,
49
+ on: 0x38bdf8,
50
+ done: 0x22c55e,
51
+ };
52
+ /** Emissive strength per state — what makes a lit button read as lit rather than merely repainted. */
53
+ const STATE_EMISSIVE = { off: 0, hint: 0.5, on: 0.85, done: 0.7 };
54
+ /** Glyph ink. A lit face goes bright, so its letter has to go dark to stay readable. */
55
+ const GLYPH_INK = {
56
+ off: "#eaf2ff",
57
+ hint: "#0b0f17",
58
+ on: "#06121a",
59
+ done: "#05210f",
60
+ };
61
+ /** How far a pressed key sinks, world units. A press is real travel here, not a simulated shadow. */
62
+ const PRESS_TRAVEL = W * 0.06;
63
+ /** Cap tilt at full stick deflection, radians. A stick leans; it doesn't slide. */
64
+ const STICK_TILT = 0.42;
65
+ /** Opacity for a part the rider's device doesn't have. Matches `.unavailable` on the flat pad. */
66
+ const UNAVAILABLE_OPACITY = 0.22;
67
+ /**
68
+ * Frames the pad fills of the canvas height. Below 1 leaves the margin the tilt needs — a tilted pad is
69
+ * taller than its flat footprint, and a camera framed on the flat one clips the triggers off the top.
70
+ */
71
+ const FRAME_FILL = 0.82;
72
+ /**
73
+ * Build a three.js pad renderer. Matches {@link PadRendererFactory}, so it can be handed straight to
74
+ * any controller view's `renderer` option.
75
+ */
76
+ export function createThreePadRenderer(layout, opts = {}) {
77
+ if (layout.brand !== "joycon") {
78
+ console.warn(`[rydr] createThreePadRenderer only models the Joy-Con pair; got brand "${layout.brand}". ` +
79
+ `Drawing the Joy-Con. Pass brand: "joycon" to the view to make this explicit.`);
80
+ }
81
+ const canvas = document.createElement("canvas");
82
+ // Give the canvas the layout's own aspect ratio, so it behaves exactly like the `<svg>` it replaces:
83
+ // `.rydr-pad > svg` is `width:100%; height:auto`, and an SVG supplies its own ratio through its
84
+ // viewBox. A canvas has NO intrinsic ratio, so without this it collapses to zero height inside every
85
+ // host that doesn't happen to set one — the pad would simply not appear.
86
+ const [, , vbW, vbH] = layout.viewBox;
87
+ canvas.style.cssText = `display:block; width:100%; height:auto; aspect-ratio:${vbW} / ${vbH};`;
88
+ const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
89
+ renderer.setClearAlpha(0);
90
+ renderer.outputColorSpace = THREE.SRGBColorSpace;
91
+ const scene = new THREE.Scene();
92
+ const camera = new THREE.PerspectiveCamera(30, 1, 0.1, 100);
93
+ camera.position.set(0, 0, 9);
94
+ const design = JOYCON_DESIGNS.find((d) => d.id === (opts.design ?? "toy")) ?? JOYCON_DESIGNS[1];
95
+ const model = design.build();
96
+ // Lighting belongs to the art direction, so the design supplies it. A separate rig here would make
97
+ // the same pad look different in a game than in the showcase that chose it.
98
+ design.light(scene);
99
+ // Two groups: `yawGroup` turns, `pivot` tilts. Separate so a yaw never introduces roll.
100
+ const pivot = new THREE.Group();
101
+ pivot.rotation.x = opts.tilt ?? VIEW.pitch;
102
+ pivot.add(model.group);
103
+ const yawGroup = new THREE.Group();
104
+ yawGroup.rotation.y = opts.yaw ?? 0;
105
+ yawGroup.add(pivot);
106
+ scene.add(yawGroup);
107
+ // Accent is themable on the flat pad through a CSS variable; here it has to reach the materials.
108
+ const accent = opts.accent ? new THREE.Color(opts.accent).getHex() : STATE_COLOR.on;
109
+ /** Every part this model actually draws. */
110
+ const ALL_PARTS = [...model.controls.keys()];
111
+ /**
112
+ * The mesh and material behind a part.
113
+ *
114
+ * `JoyconBuild` keys its controls by name and hands back plain `Object3D`s, so this resolves one to
115
+ * something paintable. A stick's entry is its cap mesh, which is what should light and sink.
116
+ */
117
+ function visualOf(part) {
118
+ const node = model.controls.get(part);
119
+ if (!node)
120
+ return undefined;
121
+ const mesh = node;
122
+ const mat = mesh.material;
123
+ if (!mat || !("color" in mat))
124
+ return undefined;
125
+ let rest = restZ.get(part);
126
+ if (rest === undefined) {
127
+ rest = node.position.z;
128
+ restZ.set(part, rest);
129
+ }
130
+ return { node, material: mat, restZ: rest };
131
+ }
132
+ /** Resting z per part, captured on first paint so a press is absolute, not cumulative. */
133
+ const restZ = new Map();
134
+ // ── state ───────────────────────────────────────────────────────────────────────────────────────
135
+ /** Dirty-guard, same intent as the flat driver's: an idle pad must do no work per frame. */
136
+ const lastVal = new Map();
137
+ const STATE_CODE = { off: 0, on: 1, hint: 2, done: 3 };
138
+ let unavailable = new Set();
139
+ let referenced = new Set();
140
+ /** Set whenever something changed; the loop renders only then. */
141
+ let dirty = true;
142
+ function applyOpacity(part) {
143
+ const v = visualOf(part);
144
+ if (!v)
145
+ return;
146
+ const dim = unavailable.has(part);
147
+ // `referenced` only ever RAISES a faint part back to full, exactly as the flat pad's rule does.
148
+ const faint = FAINT_PARTS.has(part) && !referenced.has(part);
149
+ const o = dim ? UNAVAILABLE_OPACITY : faint ? 0.4 : 1;
150
+ v.material.transparent = o < 1;
151
+ v.material.opacity = o;
152
+ }
153
+ function paint(part, state) {
154
+ const v = visualOf(part);
155
+ if (!v)
156
+ return;
157
+ const color = state === "on" ? accent : STATE_COLOR[state];
158
+ v.material.color.setHex(color);
159
+ v.material.emissive.setHex(state === "off" ? 0x000000 : color);
160
+ v.material.emissiveIntensity = STATE_EMISSIVE[state];
161
+ // A press is real travel here — the flat pad had to fake it with a drop shadow.
162
+ v.node.position.z = v.restZ - (state === "on" || state === "done" ? PRESS_TRAVEL : 0);
163
+ applyOpacity(part);
164
+ dirty = true;
165
+ }
166
+ /** What's printed on a part — read back off the built glyph so it can be re-inked per state. */
167
+ const glyphTexts = new Map();
168
+ function glyphTextOf(part) {
169
+ return glyphTexts.get(part) ?? "";
170
+ }
171
+ for (const [name, spec] of [
172
+ ["faceTop", layout.face.top],
173
+ ["faceRight", layout.face.right],
174
+ ["faceBottom", layout.face.bottom],
175
+ ["faceLeft", layout.face.left],
176
+ ["select", layout.system?.select],
177
+ ["start", layout.system?.start],
178
+ ["lb", layout.bumpers?.l],
179
+ ["rb", layout.bumpers?.r],
180
+ ["lt", layout.triggers?.l],
181
+ ["rt", layout.triggers?.r],
182
+ ]) {
183
+ if (spec?.glyph)
184
+ glyphTexts.set(name, spec.glyph);
185
+ }
186
+ // ── the driver ──────────────────────────────────────────────────────────────────────────────────
187
+ const setPartState = (part, state) => {
188
+ if (SHELL_OWNED_PARTS.has(part) && !opts.allowShellOwned)
189
+ return;
190
+ if (lastVal.get(part) === STATE_CODE[state])
191
+ return;
192
+ lastVal.set(part, STATE_CODE[state]);
193
+ paint(part, state);
194
+ // A lit trigger rolls the pad forward so it can actually be seen — see `triggerTilt`.
195
+ if (part === "lt" || part === "rt") {
196
+ if (state === "off")
197
+ litTriggers.delete(part);
198
+ else
199
+ litTriggers.add(part);
200
+ aimRoll();
201
+ }
202
+ };
203
+ const setStick = (side, x, y, lit = "auto") => {
204
+ const pivot = model.sticks[side];
205
+ if (!pivot)
206
+ return;
207
+ const litKey = `${side}lit`;
208
+ const resolved = lit === "auto" ? (Math.hypot(x, y) > STICK_LIT_DEADZONE ? "on" : "off") : lit;
209
+ const code = resolved === "on" ? 1 : resolved === "hint" ? 2 : resolved === "done" ? 3 : 0;
210
+ if (lastVal.get(litKey) !== code) {
211
+ lastVal.set(litKey, code);
212
+ // Colour lives on the CAP, which is registered as the stick-click part.
213
+ const cap = visualOf(side === "l" ? "lstickPress" : "rstickPress");
214
+ if (cap) {
215
+ const state = resolved;
216
+ const color = state === "on" ? accent : STATE_COLOR[state];
217
+ cap.material.color.setHex(color);
218
+ cap.material.emissive.setHex(state === "off" ? 0x000000 : color);
219
+ cap.material.emissiveIntensity = STATE_EMISSIVE[state];
220
+ }
221
+ dirty = true;
222
+ }
223
+ // A real stick LEANS. `y` is up-positive in the SDK's convention, and a push "up" tips the cap away
224
+ // from the viewer — a negative rotation about x — so the sign works out without the flat
225
+ // renderer's y-negation.
226
+ const rx = -y * STICK_TILT;
227
+ const ry = x * STICK_TILT;
228
+ if (Math.abs(rx - (lastVal.get(`${side}rx`) ?? 0)) < 0.002 &&
229
+ Math.abs(ry - (lastVal.get(`${side}ry`) ?? 0)) < 0.002) {
230
+ return;
231
+ }
232
+ lastVal.set(`${side}rx`, rx);
233
+ lastVal.set(`${side}ry`, ry);
234
+ pivot.rotation.x = rx;
235
+ pivot.rotation.y = ry;
236
+ dirty = true;
237
+ };
238
+ const driver = {
239
+ setPartState,
240
+ setPart: (part, on) => setPartState(part, on ? "on" : "off"),
241
+ setStick,
242
+ setMeter(side, v01) {
243
+ // The generated model draws no travel meter: in this protocol LT/RT are plain clicks (see
244
+ // `protocol/buttons.ts`), so the trigger simply lights, which `setPart` already does.
245
+ void side;
246
+ void v01;
247
+ },
248
+ setAvailable(available) {
249
+ unavailable = available == null
250
+ ? new Set()
251
+ : new Set(ALL_PARTS.filter((p) => !available.includes(p) && !SHELL_OWNED_PARTS.has(p)));
252
+ for (const part of ALL_PARTS)
253
+ applyOpacity(part);
254
+ dirty = true;
255
+ },
256
+ clearAll() {
257
+ for (const part of ALL_PARTS) {
258
+ lastVal.set(part, 0);
259
+ paint(part, "off");
260
+ }
261
+ litTriggers.clear();
262
+ aimRoll();
263
+ for (const side of ["l", "r"]) {
264
+ lastVal.delete(`${side}lit`);
265
+ setStick(side, 0, 0, "off");
266
+ this.setMeter(side, 0);
267
+ }
268
+ },
269
+ };
270
+ // Paint every part once so a part's material starts in a known state rather than its build colour.
271
+ for (const part of ALL_PARTS)
272
+ paint(part, "off");
273
+ // ── sizing ──────────────────────────────────────────────────────────────────────────────────────
274
+ function resize() {
275
+ const w = canvas.clientWidth || 1;
276
+ const h = canvas.clientHeight || 1;
277
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, opts.maxPixelRatio ?? 2));
278
+ renderer.setSize(w, h, false);
279
+ camera.aspect = w / h;
280
+ // Frame from the model's bounding SPHERE, which is invariant under rotation: one number frames
281
+ // every tilt and yaw without the framing pumping as the pad turns.
282
+ yawGroup.updateMatrixWorld(true);
283
+ const box = new THREE.Box3().setFromObject(yawGroup);
284
+ const sphere = box.getBoundingSphere(new THREE.Sphere());
285
+ const fovV = (camera.fov * Math.PI) / 180;
286
+ const fovH = 2 * Math.atan(Math.tan(fovV / 2) * camera.aspect);
287
+ const fill = opts.fill ?? 0.82;
288
+ const dist = Math.max(sphere.radius / Math.sin(fovV / 2), sphere.radius / Math.sin(fovH / 2)) / fill;
289
+ // Offsets are expressed as fractions of the visible frame at the pad's distance, so they mean the
290
+ // same thing whatever the fill or the aspect.
291
+ const halfH = Math.tan(fovV / 2) * dist;
292
+ const halfW = halfH * camera.aspect;
293
+ camera.position.set(sphere.center.x - (opts.offsetX ?? 0) * halfW * 2, sphere.center.y - (opts.offsetY ?? 0) * halfH * 2, sphere.center.z + dist);
294
+ camera.lookAt(camera.position.x, camera.position.y, sphere.center.z);
295
+ camera.updateProjectionMatrix();
296
+ dirty = true;
297
+ }
298
+ const ro = new ResizeObserver(() => resize());
299
+ ro.observe(canvas);
300
+ // ── the trigger roll ────────────────────────────────────────────────────────────────────────────
301
+ /** Which triggers are currently lit. The pad rolls while this is non-empty. */
302
+ const litTriggers = new Set();
303
+ const restTilt = opts.tilt ?? VIEW.pitch;
304
+ const extraTilt = opts.triggerTilt ?? 0.38;
305
+ const rollMs = opts.triggerTiltMs ?? 420;
306
+ /** 0 = at rest, 1 = fully rolled forward. */
307
+ let roll = 0;
308
+ let rollFrom = 0;
309
+ let rollTarget = 0;
310
+ let rollStart = 0;
311
+ const projectionCbs = new Set();
312
+ function aimRoll() {
313
+ const want = litTriggers.size > 0 ? 1 : 0;
314
+ if (want === rollTarget)
315
+ return;
316
+ rollFrom = roll;
317
+ rollTarget = want;
318
+ rollStart = performance.now();
319
+ start();
320
+ }
321
+ /** Advance the roll. Returns true while it is still moving. */
322
+ function stepRoll(now) {
323
+ if (roll === rollTarget)
324
+ return false;
325
+ const t = Math.min(1, (now - rollStart) / rollMs);
326
+ // Ease in-out: the pad should settle rather than snap, or the labels riding on it jitter.
327
+ const e = t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
328
+ roll = rollFrom + (rollTarget - rollFrom) * e;
329
+ if (t >= 1)
330
+ roll = rollTarget;
331
+ pivot.rotation.x = restTilt + extraTilt * roll;
332
+ dirty = true;
333
+ // Anything positioned from partRect has to follow, so tell it every frame of the roll.
334
+ for (const cb of projectionCbs)
335
+ cb();
336
+ return roll !== rollTarget;
337
+ }
338
+ // ── the loop ────────────────────────────────────────────────────────────────────────────────────
339
+ // Renders only on a change. An untouched pad therefore costs one `requestAnimationFrame` callback and
340
+ // no GPU work at all — the 3D equivalent of the flat driver's dirty-guard.
341
+ let raf = 0;
342
+ function frame() {
343
+ raf = requestAnimationFrame(frame);
344
+ stepRoll(performance.now());
345
+ if (!dirty)
346
+ return;
347
+ dirty = false;
348
+ renderer.render(scene, camera);
349
+ }
350
+ function start() {
351
+ if (!raf)
352
+ raf = requestAnimationFrame(frame);
353
+ }
354
+ function stop() {
355
+ if (raf)
356
+ cancelAnimationFrame(raf);
357
+ raf = 0;
358
+ }
359
+ const onVisibility = () => {
360
+ if (document.visibilityState === "hidden")
361
+ stop();
362
+ else {
363
+ dirty = true;
364
+ start();
365
+ }
366
+ };
367
+ document.addEventListener("visibilitychange", onVisibility);
368
+ start();
369
+ // ── projection ──────────────────────────────────────────────────────────────────────────────────
370
+ return {
371
+ node: canvas,
372
+ driver,
373
+ layout,
374
+ // A shaded object, not a flat diagram — so a caption sitting ON the pad drops its opaque chip.
375
+ perspective: true,
376
+ partRect(part) {
377
+ const v = visualOf(part);
378
+ if (!v)
379
+ return null;
380
+ const box = canvas.getBoundingClientRect();
381
+ if (box.width < 1 || box.height < 1)
382
+ return null;
383
+ // Corners come from the part's own bounding box, in WORLD space.
384
+ //
385
+ // `setFromObject` already walks the object's `matrixWorld`, so the box it returns is world-space
386
+ // and includes the pad's tilt. Running the corners through `pivot.localToWorld` afterwards — as
387
+ // this did — applied that rotation a SECOND time, which is why leader lines and captions landed
388
+ // beside their control instead of on it.
389
+ pivot.updateMatrixWorld(true);
390
+ const world = new THREE.Box3().setFromObject(v.node);
391
+ const p3 = new THREE.Vector3();
392
+ let minX = Infinity;
393
+ let minY = Infinity;
394
+ let maxX = -Infinity;
395
+ let maxY = -Infinity;
396
+ for (let i = 0; i < 8; i++) {
397
+ p3.set(i & 1 ? world.max.x : world.min.x, i & 2 ? world.max.y : world.min.y, i & 4 ? world.max.z : world.min.z);
398
+ p3.project(camera);
399
+ const sx = box.left + ((p3.x + 1) / 2) * box.width;
400
+ const sy = box.top + ((1 - p3.y) / 2) * box.height;
401
+ minX = Math.min(minX, sx);
402
+ maxX = Math.max(maxX, sx);
403
+ minY = Math.min(minY, sy);
404
+ maxY = Math.max(maxY, sy);
405
+ }
406
+ return partRectOf(minX, minY, maxX - minX, maxY - minY);
407
+ },
408
+ setReferenced(parts) {
409
+ referenced = parts;
410
+ for (const part of ALL_PARTS)
411
+ applyOpacity(part);
412
+ dirty = true;
413
+ },
414
+ resize,
415
+ onProjectionChange(cb) {
416
+ projectionCbs.add(cb);
417
+ return () => projectionCbs.delete(cb);
418
+ },
419
+ dispose() {
420
+ stop();
421
+ document.removeEventListener("visibilitychange", onVisibility);
422
+ ro.disconnect();
423
+ for (const d of model.disposables)
424
+ d.dispose();
425
+ renderer.dispose();
426
+ // Hand the context back rather than waiting for GC: browsers cap live WebGL contexts, and a page
427
+ // that mounts and unmounts several 3D pads would otherwise run out and start killing old ones.
428
+ renderer.forceContextLoss();
429
+ canvas.remove();
430
+ },
431
+ };
432
+ }
433
+ //# sourceMappingURL=three-pad-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three-pad-renderer.js","sourceRoot":"","sources":["../../../src/three/controller/three-pad-renderer.ts"],"names":[],"mappings":"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"}
@@ -11,4 +11,6 @@ export * from "./perf-marks.js";
11
11
  export * from "./perf-overlay.js";
12
12
  export * from "./screen-anchor.js";
13
13
  export * from "./waypoint-beacon.js";
14
+ export * from "./controller/index.js";
15
+ export * from "./rider/index.js";
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -11,4 +11,6 @@ export * from "./perf-marks.js";
11
11
  export * from "./perf-overlay.js";
12
12
  export * from "./screen-anchor.js";
13
13
  export * from "./waypoint-beacon.js";
14
+ export * from "./controller/index.js";
15
+ export * from "./rider/index.js";
14
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/three/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * POSE A HUMANOID AS A CYCLIST — the bridge from the flat rig's solved joints to a skeleton's
3
+ * rotations.
4
+ *
5
+ * `mountRiderRig` already solves every joint the pose needs: hip, shoulder, head, elbow, both knees
6
+ * and both pedals, as points in the flat 200×200 drawing space. So there is no cycling *animation*
7
+ * to author here and no clip to bake — the gait already exists, and this file only re-expresses it.
8
+ * That is why the rider can be a real character without anyone producing a `Cycling` clip.
9
+ *
10
+ * ## Why this is rotations and not positions
11
+ *
12
+ * The skeleton is a parented chain (`hips → chest → shoulder → elbow → hand`, `hips → hipL → kneeL`)
13
+ * whose limbs hang along **−Y** at rest. You cannot place a knee: you rotate the hip until the knee
14
+ * lands there. And because each joint inherits its parent's rotation, a joint's own angle is the
15
+ * WORLD angle it needs MINUS the world angle its parent already has — which is the whole of
16
+ * {@link segmentAngle} and the subtractions below.
17
+ *
18
+ * The bike is drawn side-on, in a plane, so every rotation is about Z alone. Rotating the rest
19
+ * direction `(0, −1)` by θ gives `(sin θ, −cos θ)`, so the angle that points a segment along `d` is
20
+ * `atan2(dx, −dy)`. All of the trigonometry in this file is that one identity.
21
+ *
22
+ * ## The lengths have to agree
23
+ *
24
+ * A rotation can aim a limb but cannot stretch it, so if the skeleton's thigh is not the thigh the IK
25
+ * solved with, the knee lands in the right *direction* at the wrong *distance* and the foot leaves the
26
+ * pedal. {@link cyclistProportions} builds the character to the drawing's own dimensions instead of
27
+ * re-solving the IK against the character's — one conversion, and the feet stay on the pedals.
28
+ */
29
+ import * as THREE from "three";
30
+ import type { RigPose } from "../../ui/rider-rig.js";
31
+ import type { Joints, Proportions, RiderTickPose } from "../character/index.js";
32
+ /**
33
+ * The dimensions the character must be built to, in metres — everything else is the variant's own.
34
+ *
35
+ * `scale` is the flat-units-to-metres factor the renderer already uses, so every length here is the
36
+ * same length the IK solved with. Only the lengths the pose depends on are forced; `spine` and `neck`
37
+ * stay the variant's, because those are its silhouette rather than its reach.
38
+ *
39
+ * Worth knowing: this rider's legs are long for the wheel — the flat drawing is a stylised stick
40
+ * figure whose limbs were tuned to read at a glance, not to anatomy, and that only becomes visible
41
+ * once a correctly-proportioned character stands next to it. Forcing the drawing's lengths keeps the
42
+ * two renderers showing the same rider; deriving them from anatomy instead would put the feet through
43
+ * the cranks.
44
+ */
45
+ export declare function cyclistOverrides(scale: number): Partial<Proportions>;
46
+ /**
47
+ * The group to add to the scene: it carries the quarter-turn that makes the character face the way the
48
+ * bike does, and it parks the rig at the saddle so every joint below it works in local space.
49
+ */
50
+ export declare function mountCyclist(riderRoot: THREE.Object3D, scale: number): THREE.Group;
51
+ /**
52
+ * Drive one frame. Every joint the flat pose solved gets its rotation; nothing is re-derived.
53
+ *
54
+ * The rise out of the saddle goes on `body`, which is the joint the rig documents as owning bob and
55
+ * lean — so it lifts the whole rider without disturbing the skeleton's own hip height. `chest` carries
56
+ * the fold onto the bars, and the arms and head inherit it, which is why a folded rider's head tucks
57
+ * without a second calculation.
58
+ */
59
+ export declare function poseCyclist(joints: Joints, pose: RigPose, scale: number): void;
60
+ /** What a variant's own flourishes read. The crank angle is the gait phase for a cyclist. */
61
+ export declare function tickPose(pose: RigPose, time: number): RiderTickPose;
62
+ //# sourceMappingURL=cyclist-pose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cyclist-pose.d.ts","sourceRoot":"","sources":["../../../src/three/rider/cyclist-pose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAY,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAyChF;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBpE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAOlF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAiD9E;AAED,6FAA6F;AAC7F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAEnE"}