@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.
- package/README.md +26 -2
- package/dist/client/PlatformClient.d.ts.map +1 -1
- package/dist/client/PlatformClient.js +14 -2
- package/dist/client/PlatformClient.js.map +1 -1
- package/dist/client/Room.d.ts +9 -4
- package/dist/client/Room.d.ts.map +1 -1
- package/dist/client/Room.js +8 -5
- package/dist/client/Room.js.map +1 -1
- package/dist/host/PlatformHost.d.ts +4 -2
- package/dist/host/PlatformHost.d.ts.map +1 -1
- package/dist/host/PlatformHost.js +5 -3
- package/dist/host/PlatformHost.js.map +1 -1
- package/dist/protocol/messages.d.ts +11 -4
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/room.d.ts +26 -0
- package/dist/protocol/room.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +2 -2
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +23 -2
- package/dist/protocol/version.js.map +1 -1
- package/dist/three/README.md +111 -0
- package/dist/three/character/index.d.ts +14 -0
- package/dist/three/character/index.d.ts.map +1 -0
- package/dist/three/character/index.js +14 -0
- package/dist/three/character/index.js.map +1 -0
- package/dist/three/character/kit.d.ts +74 -0
- package/dist/three/character/kit.d.ts.map +1 -0
- package/dist/three/character/kit.js +254 -0
- package/dist/three/character/kit.js.map +1 -0
- package/dist/three/character/riders.d.ts +20 -0
- package/dist/three/character/riders.d.ts.map +1 -0
- package/dist/three/character/riders.js +383 -0
- package/dist/three/character/riders.js.map +1 -0
- package/dist/three/character/skeleton.d.ts +105 -0
- package/dist/three/character/skeleton.d.ts.map +1 -0
- package/dist/three/character/skeleton.js +57 -0
- package/dist/three/character/skeleton.js.map +1 -0
- package/dist/three/controller/glyph-texture.d.ts +29 -0
- package/dist/three/controller/glyph-texture.d.ts.map +1 -0
- package/dist/three/controller/glyph-texture.js +68 -0
- package/dist/three/controller/glyph-texture.js.map +1 -0
- package/dist/three/controller/index.d.ts +12 -0
- package/dist/three/controller/index.d.ts.map +1 -0
- package/dist/three/controller/index.js +12 -0
- package/dist/three/controller/index.js.map +1 -0
- package/dist/three/controller/joycon-designs.d.ts +49 -0
- package/dist/three/controller/joycon-designs.d.ts.map +1 -0
- package/dist/three/controller/joycon-designs.js +742 -0
- package/dist/three/controller/joycon-designs.js.map +1 -0
- package/dist/three/controller/joycon-shoulder-mesh.d.ts +41 -0
- package/dist/three/controller/joycon-shoulder-mesh.d.ts.map +1 -0
- package/dist/three/controller/joycon-shoulder-mesh.js +527 -0
- package/dist/three/controller/joycon-shoulder-mesh.js.map +1 -0
- package/dist/three/controller/joycon-spec.d.ts +233 -0
- package/dist/three/controller/joycon-spec.d.ts.map +1 -0
- package/dist/three/controller/joycon-spec.js +285 -0
- package/dist/three/controller/joycon-spec.js.map +1 -0
- package/dist/three/controller/three-pad-renderer.d.ts +81 -0
- package/dist/three/controller/three-pad-renderer.d.ts.map +1 -0
- package/dist/three/controller/three-pad-renderer.js +433 -0
- package/dist/three/controller/three-pad-renderer.js.map +1 -0
- package/dist/three/index.d.ts +2 -0
- package/dist/three/index.d.ts.map +1 -1
- package/dist/three/index.js +2 -0
- package/dist/three/index.js.map +1 -1
- package/dist/three/rider/cyclist-pose.d.ts +62 -0
- package/dist/three/rider/cyclist-pose.d.ts.map +1 -0
- package/dist/three/rider/cyclist-pose.js +173 -0
- package/dist/three/rider/cyclist-pose.js.map +1 -0
- package/dist/three/rider/index.d.ts +8 -0
- package/dist/three/rider/index.d.ts.map +1 -0
- package/dist/three/rider/index.js +8 -0
- package/dist/three/rider/index.js.map +1 -0
- package/dist/three/rider/three-rider-rig.d.ts +80 -0
- package/dist/three/rider/three-rider-rig.d.ts.map +1 -0
- package/dist/three/rider/three-rider-rig.js +418 -0
- package/dist/three/rider/three-rider-rig.js.map +1 -0
- package/dist/ui/README.md +153 -1
- package/dist/ui/controller/combo-demo.d.ts +9 -0
- package/dist/ui/controller/combo-demo.d.ts.map +1 -1
- package/dist/ui/controller/combo-demo.js +1 -0
- package/dist/ui/controller/combo-demo.js.map +1 -1
- package/dist/ui/controller/control-spotlight.d.ts +10 -1
- package/dist/ui/controller/control-spotlight.d.ts.map +1 -1
- package/dist/ui/controller/control-spotlight.js +42 -42
- package/dist/ui/controller/control-spotlight.js.map +1 -1
- package/dist/ui/controller/control-trainer.d.ts +14 -0
- package/dist/ui/controller/control-trainer.d.ts.map +1 -1
- package/dist/ui/controller/control-trainer.js +6 -0
- package/dist/ui/controller/control-trainer.js.map +1 -1
- package/dist/ui/controller/controller-map.d.ts +9 -0
- package/dist/ui/controller/controller-map.d.ts.map +1 -1
- package/dist/ui/controller/controller-map.js +8 -6
- package/dist/ui/controller/controller-map.js.map +1 -1
- package/dist/ui/controller/controller-pad.d.ts +35 -2
- package/dist/ui/controller/controller-pad.d.ts.map +1 -1
- package/dist/ui/controller/controller-pad.js +47 -7
- package/dist/ui/controller/controller-pad.js.map +1 -1
- package/dist/ui/controller/index.d.ts +1 -0
- package/dist/ui/controller/index.d.ts.map +1 -1
- package/dist/ui/controller/index.js +1 -0
- package/dist/ui/controller/index.js.map +1 -1
- package/dist/ui/controller/renderer.d.ts +118 -0
- package/dist/ui/controller/renderer.d.ts.map +1 -0
- package/dist/ui/controller/renderer.js +93 -0
- package/dist/ui/controller/renderer.js.map +1 -0
- package/dist/ui/controller/styles.js +30 -0
- package/dist/ui/controller/styles.js.map +1 -1
- package/dist/ui/index.d.ts +7 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +7 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/keycap.d.ts +11 -0
- package/dist/ui/keycap.d.ts.map +1 -1
- package/dist/ui/keycap.js +3 -0
- package/dist/ui/keycap.js.map +1 -1
- package/dist/ui/pad-hints.d.ts +78 -0
- package/dist/ui/pad-hints.d.ts.map +1 -0
- package/dist/ui/pad-hints.js +103 -0
- package/dist/ui/pad-hints.js.map +1 -0
- package/dist/ui/rider-rig.d.ts +315 -0
- package/dist/ui/rider-rig.d.ts.map +1 -0
- package/dist/ui/rider-rig.js +1000 -0
- package/dist/ui/rider-rig.js.map +1 -0
- package/dist/ui/showcase/index.d.ts +11 -0
- package/dist/ui/showcase/index.d.ts.map +1 -1
- package/dist/ui/showcase/index.js +109 -1
- package/dist/ui/showcase/index.js.map +1 -1
- package/dist/ui/solo-labeled-diamond.d.ts +7 -0
- package/dist/ui/solo-labeled-diamond.d.ts.map +1 -1
- package/dist/ui/solo-labeled-diamond.js +1 -1
- package/dist/ui/solo-labeled-diamond.js.map +1 -1
- package/dist/ui/styles.js +9 -0
- package/dist/ui/styles.js.map +1 -1
- 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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,YAAY,IAAI,CAAC,EAAE,MAAM,uBAAuB,CAAC;AAG1D;;;;;;;;;;;;;;;GAeG;AACH,SAAS,SAAS,CAAC,CAAW,EAAE,CAAW;IACzC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,OAAO,CAAC,CAAW,EAAE,CAAW;IACvC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,IAAI,GAAG,CAAC,CAAW,EAAE,CAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACpF,OAAO;QACL;;;;;;;WAOG;QACH,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC;QAChC,oEAAoE;QACpE,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK;QAC1C,KAAK,EAAE,EAAE,GAAG,KAAK;QACjB,IAAI,EAAE,EAAE,GAAG,KAAK;QAChB,QAAQ,EAAE,EAAE,GAAG,KAAK;QACpB,OAAO,EAAE,EAAE,GAAG,KAAK;QACnB,QAAQ,EAAE,KAAK;QACf,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,SAAyB,EAAE,KAAa;IACnE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IAChC,qFAAqF;IACrF,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/B,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IACrD,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,IAAa,EAAE,KAAa;IACtE,MAAM,CAAC,GAAG,MAAM,CAAC;IAEjB,+FAA+F;IAC/F,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACtD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAEtD;;;;;;;;;;;;;OAaG;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,KAAK,CAAC;IAC1B,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;IACvB,iGAAiG;IACjG,gCAAgC;IAChC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAE9D,sFAAsF;IACtF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1C,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI;QAC9B,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QACvB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;KACf,EAAE,CAAC;QACX,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;QACpC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;IAClC,CAAC;IAED,mGAAmG;IACnG,qGAAqG;IACrG,KAAK,MAAM,GAAG,IAAI;QAChB,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;QAC5E,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE;KAC3E,EAAE,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9C,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IACjE,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,QAAQ,CAAC,IAAa,EAAE,IAAY;IAClD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;AACjF,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.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"}
|