@rydr/game-sdk 8.11.0 → 8.13.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 (135) 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/messages.d.ts +11 -4
  14. package/dist/protocol/messages.d.ts.map +1 -1
  15. package/dist/protocol/room.d.ts +26 -0
  16. package/dist/protocol/room.d.ts.map +1 -1
  17. package/dist/protocol/version.d.ts +2 -2
  18. package/dist/protocol/version.d.ts.map +1 -1
  19. package/dist/protocol/version.js +23 -2
  20. package/dist/protocol/version.js.map +1 -1
  21. package/dist/three/README.md +111 -0
  22. package/dist/three/character/index.d.ts +14 -0
  23. package/dist/three/character/index.d.ts.map +1 -0
  24. package/dist/three/character/index.js +14 -0
  25. package/dist/three/character/index.js.map +1 -0
  26. package/dist/three/character/kit.d.ts +74 -0
  27. package/dist/three/character/kit.d.ts.map +1 -0
  28. package/dist/three/character/kit.js +254 -0
  29. package/dist/three/character/kit.js.map +1 -0
  30. package/dist/three/character/riders.d.ts +20 -0
  31. package/dist/three/character/riders.d.ts.map +1 -0
  32. package/dist/three/character/riders.js +383 -0
  33. package/dist/three/character/riders.js.map +1 -0
  34. package/dist/three/character/skeleton.d.ts +105 -0
  35. package/dist/three/character/skeleton.d.ts.map +1 -0
  36. package/dist/three/character/skeleton.js +57 -0
  37. package/dist/three/character/skeleton.js.map +1 -0
  38. package/dist/three/controller/glyph-texture.d.ts +29 -0
  39. package/dist/three/controller/glyph-texture.d.ts.map +1 -0
  40. package/dist/three/controller/glyph-texture.js +68 -0
  41. package/dist/three/controller/glyph-texture.js.map +1 -0
  42. package/dist/three/controller/index.d.ts +12 -0
  43. package/dist/three/controller/index.d.ts.map +1 -0
  44. package/dist/three/controller/index.js +12 -0
  45. package/dist/three/controller/index.js.map +1 -0
  46. package/dist/three/controller/joycon-designs.d.ts +49 -0
  47. package/dist/three/controller/joycon-designs.d.ts.map +1 -0
  48. package/dist/three/controller/joycon-designs.js +742 -0
  49. package/dist/three/controller/joycon-designs.js.map +1 -0
  50. package/dist/three/controller/joycon-shoulder-mesh.d.ts +41 -0
  51. package/dist/three/controller/joycon-shoulder-mesh.d.ts.map +1 -0
  52. package/dist/three/controller/joycon-shoulder-mesh.js +527 -0
  53. package/dist/three/controller/joycon-shoulder-mesh.js.map +1 -0
  54. package/dist/three/controller/joycon-spec.d.ts +233 -0
  55. package/dist/three/controller/joycon-spec.d.ts.map +1 -0
  56. package/dist/three/controller/joycon-spec.js +285 -0
  57. package/dist/three/controller/joycon-spec.js.map +1 -0
  58. package/dist/three/controller/three-pad-renderer.d.ts +81 -0
  59. package/dist/three/controller/three-pad-renderer.d.ts.map +1 -0
  60. package/dist/three/controller/three-pad-renderer.js +433 -0
  61. package/dist/three/controller/three-pad-renderer.js.map +1 -0
  62. package/dist/three/index.d.ts +2 -0
  63. package/dist/three/index.d.ts.map +1 -1
  64. package/dist/three/index.js +2 -0
  65. package/dist/three/index.js.map +1 -1
  66. package/dist/three/rider/cyclist-pose.d.ts +62 -0
  67. package/dist/three/rider/cyclist-pose.d.ts.map +1 -0
  68. package/dist/three/rider/cyclist-pose.js +173 -0
  69. package/dist/three/rider/cyclist-pose.js.map +1 -0
  70. package/dist/three/rider/index.d.ts +8 -0
  71. package/dist/three/rider/index.d.ts.map +1 -0
  72. package/dist/three/rider/index.js +8 -0
  73. package/dist/three/rider/index.js.map +1 -0
  74. package/dist/three/rider/three-rider-rig.d.ts +80 -0
  75. package/dist/three/rider/three-rider-rig.d.ts.map +1 -0
  76. package/dist/three/rider/three-rider-rig.js +418 -0
  77. package/dist/three/rider/three-rider-rig.js.map +1 -0
  78. package/dist/ui/README.md +153 -1
  79. package/dist/ui/controller/combo-demo.d.ts +9 -0
  80. package/dist/ui/controller/combo-demo.d.ts.map +1 -1
  81. package/dist/ui/controller/combo-demo.js +1 -0
  82. package/dist/ui/controller/combo-demo.js.map +1 -1
  83. package/dist/ui/controller/control-spotlight.d.ts +10 -1
  84. package/dist/ui/controller/control-spotlight.d.ts.map +1 -1
  85. package/dist/ui/controller/control-spotlight.js +42 -42
  86. package/dist/ui/controller/control-spotlight.js.map +1 -1
  87. package/dist/ui/controller/control-trainer.d.ts +14 -0
  88. package/dist/ui/controller/control-trainer.d.ts.map +1 -1
  89. package/dist/ui/controller/control-trainer.js +6 -0
  90. package/dist/ui/controller/control-trainer.js.map +1 -1
  91. package/dist/ui/controller/controller-map.d.ts +9 -0
  92. package/dist/ui/controller/controller-map.d.ts.map +1 -1
  93. package/dist/ui/controller/controller-map.js +8 -6
  94. package/dist/ui/controller/controller-map.js.map +1 -1
  95. package/dist/ui/controller/controller-pad.d.ts +35 -2
  96. package/dist/ui/controller/controller-pad.d.ts.map +1 -1
  97. package/dist/ui/controller/controller-pad.js +47 -7
  98. package/dist/ui/controller/controller-pad.js.map +1 -1
  99. package/dist/ui/controller/index.d.ts +1 -0
  100. package/dist/ui/controller/index.d.ts.map +1 -1
  101. package/dist/ui/controller/index.js +1 -0
  102. package/dist/ui/controller/index.js.map +1 -1
  103. package/dist/ui/controller/renderer.d.ts +118 -0
  104. package/dist/ui/controller/renderer.d.ts.map +1 -0
  105. package/dist/ui/controller/renderer.js +93 -0
  106. package/dist/ui/controller/renderer.js.map +1 -0
  107. package/dist/ui/controller/styles.js +30 -0
  108. package/dist/ui/controller/styles.js.map +1 -1
  109. package/dist/ui/index.d.ts +7 -0
  110. package/dist/ui/index.d.ts.map +1 -1
  111. package/dist/ui/index.js +7 -0
  112. package/dist/ui/index.js.map +1 -1
  113. package/dist/ui/keycap.d.ts +11 -0
  114. package/dist/ui/keycap.d.ts.map +1 -1
  115. package/dist/ui/keycap.js +3 -0
  116. package/dist/ui/keycap.js.map +1 -1
  117. package/dist/ui/pad-hints.d.ts +78 -0
  118. package/dist/ui/pad-hints.d.ts.map +1 -0
  119. package/dist/ui/pad-hints.js +103 -0
  120. package/dist/ui/pad-hints.js.map +1 -0
  121. package/dist/ui/rider-rig.d.ts +315 -0
  122. package/dist/ui/rider-rig.d.ts.map +1 -0
  123. package/dist/ui/rider-rig.js +1000 -0
  124. package/dist/ui/rider-rig.js.map +1 -0
  125. package/dist/ui/showcase/index.d.ts +11 -0
  126. package/dist/ui/showcase/index.d.ts.map +1 -1
  127. package/dist/ui/showcase/index.js +109 -1
  128. package/dist/ui/showcase/index.js.map +1 -1
  129. package/dist/ui/solo-labeled-diamond.d.ts +7 -0
  130. package/dist/ui/solo-labeled-diamond.d.ts.map +1 -1
  131. package/dist/ui/solo-labeled-diamond.js +1 -1
  132. package/dist/ui/solo-labeled-diamond.js.map +1 -1
  133. package/dist/ui/styles.js +9 -0
  134. package/dist/ui/styles.js.map +1 -1
  135. package/package.json +8 -4
@@ -0,0 +1,173 @@
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 { RIG_GEOMETRY as G } from "../../ui/rider-rig.js";
31
+ /**
32
+ * The swing angle that points a HANGING limb from `a` to `b`, in the character's sagittal plane.
33
+ *
34
+ * Two conventions have to be honoured at once, and getting either wrong lays the rider flat on the
35
+ * floor — which is exactly what the first attempt did.
36
+ *
37
+ * 1. **The rig faces +Z and swings about X.** The platform's own note is the authority: "`rotation.x`
38
+ * = t puts its far end at `z = −L·sin(t)`: NEGATIVE swings the limb FORWARD (+Z)". So rest is
39
+ * `(0, −1, 0)` and rotating by φ gives `(0, −cos φ, −sin φ)`. Rotating about Z instead — the
40
+ * obvious guess for a side-on drawing — swings the limbs sideways out of the bike's plane.
41
+ * 2. **The flat drawing has y pointing DOWN**, the scene has it UP.
42
+ *
43
+ * Put the character under a group turned +90° about Y (see {@link mountCyclist}) and its local +Z
44
+ * becomes world +X, the way the bike faces. Working the two frames through leaves φ = −θ, where θ is
45
+ * the angle in the flat drawing.
46
+ */
47
+ function swingDown(a, b) {
48
+ const dx = b.x - a.x;
49
+ const dyUp = -(b.y - a.y);
50
+ return -Math.atan2(dx, dyUp === 0 ? 1e-6 : -dyUp);
51
+ }
52
+ /**
53
+ * The same, for a segment that RISES from its joint rather than hangs from it.
54
+ *
55
+ * The torso and the neck are the two: `chest` sits on the hips and its geometry runs up to `neck`,
56
+ * which runs up to the head. Their rest direction is `(0, +1, 0)`, not `(0, −1, 0)`, so rotating by φ
57
+ * gives `(0, cos φ, sin φ)` and the angle is `atan2(dx, dyUp)` with no negation.
58
+ *
59
+ * Using the hanging formula on the torso was a real bug and a quiet one: the rider sat up straight,
60
+ * pedalled correctly, held the bars — and faced backwards down the bike, because a sign error of this
61
+ * shape reflects the segment rather than breaking it.
62
+ */
63
+ function swingUp(a, b) {
64
+ const dx = b.x - a.x;
65
+ const dyUp = -(b.y - a.y);
66
+ return Math.atan2(dx, dyUp === 0 ? 1e-6 : dyUp);
67
+ }
68
+ /**
69
+ * The dimensions the character must be built to, in metres — everything else is the variant's own.
70
+ *
71
+ * `scale` is the flat-units-to-metres factor the renderer already uses, so every length here is the
72
+ * same length the IK solved with. Only the lengths the pose depends on are forced; `spine` and `neck`
73
+ * stay the variant's, because those are its silhouette rather than its reach.
74
+ *
75
+ * Worth knowing: this rider's legs are long for the wheel — the flat drawing is a stylised stick
76
+ * figure whose limbs were tuned to read at a glance, not to anatomy, and that only becomes visible
77
+ * once a correctly-proportioned character stands next to it. Forcing the drawing's lengths keeps the
78
+ * two renderers showing the same rider; deriving them from anatomy instead would put the feet through
79
+ * the cranks.
80
+ */
81
+ export function cyclistOverrides(scale) {
82
+ const dist = (a, b) => Math.hypot(b.x - a.x, b.y - a.y) * scale;
83
+ return {
84
+ /**
85
+ * The spine is REACH, not silhouette — which is what I got wrong first.
86
+ *
87
+ * It is what places the shoulder, and the shoulder is where the arm starts. Left at the variant's
88
+ * own ~0.5 m against the drawing's 0.74 m, the shoulder sat too low and the hands could not get to
89
+ * the bars however correct the arm angles were: the rider pedalled properly with both arms hanging
90
+ * at their sides.
91
+ */
92
+ spine: dist(G.HIP0, G.SHOULDER0),
93
+ // Floor → hip, straight off the saddle's own height in the drawing.
94
+ hipHeight: (G.GROUND - G.SADDLE.y) * scale,
95
+ thigh: 42 * scale,
96
+ shin: 44 * scale,
97
+ upperArm: 25 * scale,
98
+ forearm: 25 * scale,
99
+ hipWidth: 0.085,
100
+ shoulderWidth: 0.16,
101
+ };
102
+ }
103
+ /**
104
+ * The group to add to the scene: it carries the quarter-turn that makes the character face the way the
105
+ * bike does, and it parks the rig at the saddle so every joint below it works in local space.
106
+ */
107
+ export function mountCyclist(riderRoot, scale) {
108
+ const mount = new THREE.Group();
109
+ // Face +X. `root.rotation.y = facing` is the rig's own convention, with 0 facing +Z.
110
+ mount.rotation.y = Math.PI / 2;
111
+ mount.position.x = (G.SADDLE.x - G.VB_W / 2) * scale;
112
+ mount.add(riderRoot);
113
+ return mount;
114
+ }
115
+ /**
116
+ * Drive one frame. Every joint the flat pose solved gets its rotation; nothing is re-derived.
117
+ *
118
+ * The rise out of the saddle goes on `body`, which is the joint the rig documents as owning bob and
119
+ * lean — so it lifts the whole rider without disturbing the skeleton's own hip height. `chest` carries
120
+ * the fold onto the bars, and the arms and head inherit it, which is why a folded rider's head tucks
121
+ * without a second calculation.
122
+ */
123
+ export function poseCyclist(joints, pose, scale) {
124
+ const j = joints;
125
+ // Fore-aft and rise, both relative to the saddle the mount is parked on. Local +Z is world +X.
126
+ j.body.position.z = (pose.hip.x - G.SADDLE.x) * scale;
127
+ j.body.position.y = (G.SADDLE.y - pose.hip.y) * scale;
128
+ /**
129
+ * The fold goes on `hips`, NOT on `chest` — and this is the whole reason the hands could not reach
130
+ * the bars.
131
+ *
132
+ * `chest` is chained at `hips + (0, spine, 0)` and the shoulders sit AT the chest's origin, so
133
+ * rotating the chest pivots the upper body about a point directly above the hips: the shoulders
134
+ * never move forward, however far the rider is leaning. They stayed 45 drawing-units behind where
135
+ * the flat IK had solved them, so the arms were reaching for bars that were out of range.
136
+ *
137
+ * Rotating `hips` moves the chest — and with it the shoulders — around the hip joint, which is where
138
+ * a cyclist actually folds. The cost is that the legs are chained off `hips` too and would swing
139
+ * with the torso, so each leg subtracts the lean back out below. That is the same additive-rotation
140
+ * bookkeeping as everywhere else here.
141
+ */
142
+ const torso = swingUp(pose.hip, pose.shoulder);
143
+ j.hips.rotation.x = torso;
144
+ j.chest.rotation.x = 0;
145
+ // The neck brings the head back toward level, so a folded rider still looks where they are going
146
+ // rather than at the front hub.
147
+ j.neck.rotation.x = swingUp(pose.shoulder, pose.head) - torso;
148
+ // Arms: both hands on the bars. They hang off the chest, which now inherits the fold.
149
+ const upper = swingDown(pose.shoulder, pose.elbow);
150
+ const fore = swingDown(pose.elbow, G.BAR);
151
+ for (const [shoulder, elbow] of [
152
+ [j.shoulderL, j.elbowL],
153
+ [j.shoulderR, j.elbowR],
154
+ ]) {
155
+ shoulder.rotation.x = upper - torso;
156
+ elbow.rotation.x = fore - upper;
157
+ }
158
+ // Legs: one per side, each on its own crank throw — which is what the flat view could only suggest
159
+ // by drawing the far one darker. Minus the fold, which they inherit from `hips` and must not follow.
160
+ for (const leg of [
161
+ { hip: j.hipL, knee: j.kneeL, kneePt: pose.kneeNear, pedal: pose.pedalNear },
162
+ { hip: j.hipR, knee: j.kneeR, kneePt: pose.kneeFar, pedal: pose.pedalFar },
163
+ ]) {
164
+ const thigh = swingDown(pose.hip, leg.kneePt);
165
+ leg.hip.rotation.x = thigh - torso;
166
+ leg.knee.rotation.x = swingDown(leg.kneePt, leg.pedal) - thigh;
167
+ }
168
+ }
169
+ /** What a variant's own flourishes read. The crank angle is the gait phase for a cyclist. */
170
+ export function tickPose(pose, time) {
171
+ return { effort: pose.effort, time, phase: pose.crankAngle * (Math.PI / 180) };
172
+ }
173
+ //# sourceMappingURL=cyclist-pose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cyclist-pose.js","sourceRoot":"","sources":["../../../src/three/rider/cyclist-pose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The 3D rider rig — a second renderer for `mountRiderRig` from `@rydr/game-sdk/ui`.
3
+ *
4
+ * See `three-rider-rig.ts` for what is shared with the flat renderer (everything but the drawing) and
5
+ * for when a 3D rig is worth a WebGL context.
6
+ */
7
+ export * from "./three-rider-rig.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/three/rider/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The 3D rider rig — a second renderer for `mountRiderRig` from `@rydr/game-sdk/ui`.
3
+ *
4
+ * See `three-rider-rig.ts` for what is shared with the flat renderer (everything but the drawing) and
5
+ * for when a 3D rig is worth a WebGL context.
6
+ */
7
+ export * from "./three-rider-rig.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/three/rider/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * THREE RIDER RIG — the rider-on-a-trainer drawing, in 3D.
3
+ *
4
+ * A second {@link RigRenderer} for `mountRiderRig`, exactly as `createThreePadRenderer` is a second
5
+ * renderer for the controller views. The component is unchanged: it still owns the two EMAs, the
6
+ * crank, the effort, the %FTP zone and the glass tooltip, and it still hands over one
7
+ * {@link RigPose} per frame. All this file does is draw that pose with meshes instead of paths.
8
+ *
9
+ * ```ts
10
+ * import { createThreeRiderRig } from "@rydr/game-sdk/three";
11
+ * import { mountRiderRig } from "@rydr/game-sdk/ui";
12
+ *
13
+ * mountRiderRig(panel, { design: "solid", ftp: 240, renderer: createThreeRiderRig });
14
+ * ```
15
+ *
16
+ * ## What is shared, and what that buys
17
+ *
18
+ * **The joints arrive already solved.** `RigPose` carries the hip, shoulder, head, elbow, both knees
19
+ * and both pedals as points in the flat 200×200 drawing space — so the two-bone IK, the crank
20
+ * kinematics, the out-of-the-saddle rise and the posture fold all stay in `rider-rig.ts` and run
21
+ * once. This file re-derives nothing, which is the whole point of the seam: two renderers cannot
22
+ * drift into two different gaits, and a fix to the pedalling fixes both.
23
+ *
24
+ * So the mapping is the only geometry here: {@link toWorld} takes a flat point to metres. The drawing
25
+ * space is scaled off the ONE wheel that is left — a 700c wheel is 0.68 m and 52 units across, giving
26
+ * ~1.05 m of wheelbase and a rider whose head sits at ~1.7 m. Those are a real bike's numbers, which
27
+ * matters because in 3D a wrong scale reads as a toy the moment perspective is applied.
28
+ *
29
+ * **The tooltip needs nothing from us.** It is an HTML box the component positions over the drawing,
30
+ * so it sits over this canvas exactly as it sits over the flat `<svg>` — no 3D projection, no
31
+ * re-layout, no second implementation. That is a payoff from building it in CSS.
32
+ *
33
+ * ## What only 3D can add, and what it costs
34
+ *
35
+ * The flat drawing is a strict side view, so the bike is a silhouette. Here the camera sits off-axis,
36
+ * which is what makes the trainer read as a machine with a body rather than an outline: you see the
37
+ * housing's depth, the flywheel as a disc rather than a circle, and the rider's far leg genuinely
38
+ * behind the near one instead of merely darker.
39
+ *
40
+ * The cost is a WebGL context. **This renderer draws on demand — one frame per `setPose`, no
41
+ * animation loop of its own** — because a game calling `rig.tick(dt)` already has a loop, and a
42
+ * decorative rig must not open a second one. It is still a second context beside the game's own
43
+ * scene, so prefer the flat renderer in-game and reach for this one on the screens where the picture
44
+ * IS the content: onboarding, a store page, a "how this works" panel.
45
+ *
46
+ * Requires the optional `three` peer dependency, like everything else in `@rydr/game-sdk/three`.
47
+ */
48
+ import type { RigRendererFactory } from "../../ui/rider-rig.js";
49
+ /**
50
+ * Where the camera stands.
51
+ *
52
+ * `profile` is the default, and deliberately: it is the SAME view the flat renderer draws, so the two
53
+ * are directly comparable and swapping the renderer changes the medium rather than the shot. It also
54
+ * hides the far leg behind the near one, exactly as the flat drawing does.
55
+ *
56
+ * `three-quarter` is the one that shows off the third dimension — the housing gets depth, the flywheel
57
+ * becomes a disc rather than a circle, and both legs are visible on their own sides of the frame.
58
+ */
59
+ export type RiderRigView = "profile" | "three-quarter";
60
+ export interface ThreeRiderRigOptions {
61
+ /** Where the camera stands. Default `"profile"`, matching the flat renderer's own view. */
62
+ view?: RiderRigView;
63
+ /**
64
+ * Which rider variant to wear, overriding the design's default (`cel` / `facet` / `neon`).
65
+ *
66
+ * Any id from `CHARACTERS` — `clay` and `knight` are there too and nothing stops a game using them.
67
+ */
68
+ character?: string;
69
+ }
70
+ /**
71
+ * Build a renderer factory with options.
72
+ *
73
+ * `RigRendererFactory` takes only the design, so anything else has to be closed over — hence a factory
74
+ * of a factory rather than one more argument. {@link createThreeRiderRig} is this with the defaults,
75
+ * and is what you pass when you have nothing to configure.
76
+ */
77
+ export declare function threeRiderRig(opts?: ThreeRiderRigOptions): RigRendererFactory;
78
+ /** The 3D renderer with its defaults — pass it straight to `mountRiderRig`'s `renderer` option. */
79
+ export declare const createThreeRiderRig: RigRendererFactory;
80
+ //# sourceMappingURL=three-rider-rig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three-rider-rig.d.ts","sourceRoot":"","sources":["../../../src/three/rider/three-rider-rig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAIH,OAAO,KAAK,EAIV,kBAAkB,EAEnB,MAAM,uBAAuB,CAAC;AAkJ/B;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,eAAe,CAAC;AAQvD,MAAM,WAAW,oBAAoB;IACnC,2FAA2F;IAC3F,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,kBAAkB,CAEjF;AAED,mGAAmG;AACnG,eAAO,MAAM,mBAAmB,EAAE,kBAA8D,CAAC"}