@edv4h/usketch-plugin-character 0.3.0 → 0.4.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 +72 -11
- package/dist/character-input.d.ts +15 -4
- package/dist/character-input.d.ts.map +1 -1
- package/dist/character-input.js +174 -26
- package/dist/character-input.js.map +1 -1
- package/dist/character-key-choices.d.ts +14 -0
- package/dist/character-key-choices.d.ts.map +1 -0
- package/dist/character-key-choices.js +23 -0
- package/dist/character-key-choices.js.map +1 -0
- package/dist/character-layer.d.ts +1 -1
- package/dist/character-layer.d.ts.map +1 -1
- package/dist/character-layer.js +45 -14
- package/dist/character-layer.js.map +1 -1
- package/dist/character-physics.d.ts +156 -2
- package/dist/character-physics.d.ts.map +1 -1
- package/dist/character-physics.js +270 -22
- package/dist/character-physics.js.map +1 -1
- package/dist/character-runtime.d.ts +8 -1
- package/dist/character-runtime.d.ts.map +1 -1
- package/dist/character-runtime.js +74 -8
- package/dist/character-runtime.js.map +1 -1
- package/dist/character-service.d.ts +23 -3
- package/dist/character-service.d.ts.map +1 -1
- package/dist/character-service.js +7 -0
- package/dist/character-service.js.map +1 -1
- package/dist/character-store.d.ts +34 -1
- package/dist/character-store.d.ts.map +1 -1
- package/dist/character-store.js +86 -4
- package/dist/character-store.js.map +1 -1
- package/dist/character-sync.d.ts +11 -1
- package/dist/character-sync.d.ts.map +1 -1
- package/dist/character-sync.js +23 -1
- package/dist/character-sync.js.map +1 -1
- package/dist/character-types.d.ts +31 -2
- package/dist/character-types.d.ts.map +1 -1
- package/dist/character-types.js +2 -1
- package/dist/character-types.js.map +1 -1
- package/dist/character-virtual-input.d.ts +20 -0
- package/dist/character-virtual-input.d.ts.map +1 -0
- package/dist/character-virtual-input.js +34 -0
- package/dist/character-virtual-input.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +13 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +2 -0
- package/dist/plugin.js.map +1 -1
- package/dist/register-character-hud.d.ts.map +1 -1
- package/dist/register-character-hud.js +88 -1
- package/dist/register-character-hud.js.map +1 -1
- package/package.json +2 -2
|
@@ -8,6 +8,8 @@ export const NO_INPUT = {
|
|
|
8
8
|
left: false,
|
|
9
9
|
right: false,
|
|
10
10
|
drift: false,
|
|
11
|
+
jump: false,
|
|
12
|
+
jumpPressed: false,
|
|
11
13
|
};
|
|
12
14
|
/** A pose at rest at the origin, facing up. */
|
|
13
15
|
export const ORIGIN_POSE = {
|
|
@@ -19,6 +21,11 @@ export const ORIGIN_POSE = {
|
|
|
19
21
|
steering: 0,
|
|
20
22
|
slip: 0,
|
|
21
23
|
drift: 0,
|
|
24
|
+
z: 0,
|
|
25
|
+
vz: 0,
|
|
26
|
+
airborne: false,
|
|
27
|
+
hovering: false,
|
|
28
|
+
hoverGauge: 1,
|
|
22
29
|
};
|
|
23
30
|
export const DEFAULT_MOTION = {
|
|
24
31
|
moveSpeed: 400,
|
|
@@ -36,6 +43,8 @@ export const DEFAULT_DRIFT = {
|
|
|
36
43
|
slipAngle: 28,
|
|
37
44
|
steerSlipAngle: 8,
|
|
38
45
|
recoveryRate: 8,
|
|
46
|
+
hop: false,
|
|
47
|
+
hopHeight: 10,
|
|
39
48
|
};
|
|
40
49
|
/** Unit vector of a heading in world space (0° → (0, -1), 90° → (1, 0)). */
|
|
41
50
|
export function headingVector(deg) {
|
|
@@ -53,6 +62,20 @@ export function turnToward(from, to, maxStep) {
|
|
|
53
62
|
return wrapDeg(to);
|
|
54
63
|
return wrapDeg(from + Math.sign(d) * maxStep);
|
|
55
64
|
}
|
|
65
|
+
/** Clamp to -1 … 1; a missing or non-finite value counts as 0 (released). */
|
|
66
|
+
export const clampUnit = (v) => v !== undefined && Number.isFinite(v) ? Math.max(-1, Math.min(1, v)) : 0;
|
|
67
|
+
/** Forward / back of an input, -1 … 1: the analog `throttle` when set, else up − down. */
|
|
68
|
+
export function inputThrottle(input) {
|
|
69
|
+
if (input.throttle !== undefined)
|
|
70
|
+
return clampUnit(input.throttle);
|
|
71
|
+
return (input.up ? 1 : 0) - (input.down ? 1 : 0);
|
|
72
|
+
}
|
|
73
|
+
/** Left / right of an input, -1 … 1: the analog `steer` when set, else right − left. */
|
|
74
|
+
export function inputSteer(input) {
|
|
75
|
+
if (input.steer !== undefined)
|
|
76
|
+
return clampUnit(input.steer);
|
|
77
|
+
return (input.right ? 1 : 0) - (input.left ? 1 : 0);
|
|
78
|
+
}
|
|
56
79
|
function approach(v, target, step) {
|
|
57
80
|
if (v < target)
|
|
58
81
|
return Math.min(target, v + step);
|
|
@@ -64,51 +87,51 @@ function approach(v, target, step) {
|
|
|
64
87
|
* - `directional`: the held keys give a SCREEN-space direction (up = screen up),
|
|
65
88
|
* turned into world space through the camera rotation; the character moves that
|
|
66
89
|
* way at `moveSpeed` and its heading turns toward it at `turnRate`. (Turning
|
|
67
|
-
* rather than snapping keeps a heading-following camera from spinning.)
|
|
90
|
+
* rather than snapping keeps a heading-following camera from spinning.) An analog
|
|
91
|
+
* input (`steer` / `throttle`) moves at `moveSpeed` × its length (capped at 1).
|
|
68
92
|
* - `vehicle`: up/down are throttle/reverse along the heading, left/right steer.
|
|
69
93
|
* Steering authority scales with speed (a stopped car can't turn) and inverts
|
|
70
94
|
* when reversing, like a car. With `driftParams`, holding the drift key while
|
|
71
|
-
* steering at speed drifts (see `DriftParams`).
|
|
95
|
+
* steering at speed drifts (see `DriftParams`). An analog `throttle` aims for that
|
|
96
|
+
* fraction of the top speed, and an analog `steer` turns by that fraction.
|
|
72
97
|
*/
|
|
73
98
|
export function stepCharacter(pose, input, dt, scheme, params, cameraRotation = 0, driftParams = null) {
|
|
74
99
|
if (dt <= 0)
|
|
75
100
|
return pose;
|
|
76
101
|
if (scheme === "directional") {
|
|
77
|
-
const sx = (input
|
|
78
|
-
const sy =
|
|
102
|
+
const sx = inputSteer(input);
|
|
103
|
+
const sy = -inputThrottle(input);
|
|
79
104
|
if (sx === 0 && sy === 0) {
|
|
80
105
|
return pose.moving || pose.speed !== 0 ? { ...pose, speed: 0, moving: false } : pose;
|
|
81
106
|
}
|
|
82
107
|
// Screen direction → world direction: undo the camera rotation.
|
|
83
108
|
const target = wrapDeg(vectorHeading(sx, sy) - cameraRotation);
|
|
84
109
|
const dir = headingVector(target);
|
|
85
|
-
|
|
110
|
+
// Keys are always full speed (diagonals normalized); an analog stick scales it.
|
|
111
|
+
const moveSpeed = params.moveSpeed * Math.min(1, Math.hypot(sx, sy));
|
|
112
|
+
const dist = moveSpeed * dt;
|
|
86
113
|
return {
|
|
87
114
|
x: pose.x + dir.x * dist,
|
|
88
115
|
y: pose.y + dir.y * dist,
|
|
89
116
|
heading: turnToward(pose.heading, target, params.turnRate * dt),
|
|
90
|
-
speed:
|
|
117
|
+
speed: moveSpeed,
|
|
91
118
|
moving: true,
|
|
92
119
|
steering: 0,
|
|
93
120
|
slip: 0,
|
|
94
121
|
drift: 0,
|
|
122
|
+
z: pose.z,
|
|
123
|
+
vz: pose.vz,
|
|
124
|
+
airborne: pose.airborne,
|
|
125
|
+
hovering: pose.hovering,
|
|
126
|
+
hoverGauge: pose.hoverGauge,
|
|
95
127
|
};
|
|
96
128
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
else if (throttle < 0) {
|
|
105
|
-
const accel = speed > 0 ? params.acceleration + params.friction : params.acceleration;
|
|
106
|
-
speed = approach(speed, -params.moveSpeed * params.reverseRatio, accel * dt);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
speed = approach(speed, 0, params.friction * dt);
|
|
110
|
-
}
|
|
111
|
-
const steering = (input.right ? 1 : 0) - (input.left ? 1 : 0);
|
|
129
|
+
// In the air a car keeps its momentum: no throttle, brakes or steering until it lands.
|
|
130
|
+
const grounded = !pose.airborne;
|
|
131
|
+
const speed = grounded
|
|
132
|
+
? throttledSpeed(pose.speed, inputThrottle(input), dt, params)
|
|
133
|
+
: pose.speed;
|
|
134
|
+
const steering = grounded ? inputSteer(input) : 0;
|
|
112
135
|
const drift = nextDrift(pose.drift, input.drift === true, steering, speed, params, driftParams);
|
|
113
136
|
let turn;
|
|
114
137
|
if (drift !== 0 && driftParams) {
|
|
@@ -138,6 +161,11 @@ export function stepCharacter(pose, input, dt, scheme, params, cameraRotation =
|
|
|
138
161
|
steering,
|
|
139
162
|
slip,
|
|
140
163
|
drift,
|
|
164
|
+
z: pose.z,
|
|
165
|
+
vz: pose.vz,
|
|
166
|
+
airborne: pose.airborne,
|
|
167
|
+
hovering: pose.hovering,
|
|
168
|
+
hoverGauge: pose.hoverGauge,
|
|
141
169
|
};
|
|
142
170
|
}
|
|
143
171
|
/**
|
|
@@ -150,7 +178,10 @@ export function stepCharacter(pose, input, dt, scheme, params, cameraRotation =
|
|
|
150
178
|
export function constrainToGround(prev, next, heightAt, maxStep) {
|
|
151
179
|
if (next.x === prev.x && next.y === prev.y)
|
|
152
180
|
return next;
|
|
153
|
-
|
|
181
|
+
// Measured from the feet: on the ground that is the ground itself, in the air it is
|
|
182
|
+
// higher, so a jump clears cliffs the step alone can't.
|
|
183
|
+
const feet = Math.max(heightAt(prev.x, prev.y), prev.z ?? 0);
|
|
184
|
+
const limit = feet + Math.max(0, maxStep);
|
|
154
185
|
const ok = (x, y) => heightAt(x, y) <= limit;
|
|
155
186
|
if (ok(next.x, next.y))
|
|
156
187
|
return next;
|
|
@@ -160,6 +191,223 @@ export function constrainToGround(prev, next, heightAt, maxStep) {
|
|
|
160
191
|
return { ...next, x: prev.x };
|
|
161
192
|
return { ...next, x: prev.x, y: prev.y, speed: 0, moving: false };
|
|
162
193
|
}
|
|
194
|
+
export const DEFAULT_HOVER = {
|
|
195
|
+
duration: 1.5,
|
|
196
|
+
fallSpeed: 15,
|
|
197
|
+
rechargeTime: 0.8,
|
|
198
|
+
thrust: 0,
|
|
199
|
+
riseSpeed: 60,
|
|
200
|
+
};
|
|
201
|
+
export const DEFAULT_JUMP = {
|
|
202
|
+
height: 40,
|
|
203
|
+
timeToApex: 0.32,
|
|
204
|
+
fallGravity: 1.5,
|
|
205
|
+
releaseCut: 0.5,
|
|
206
|
+
coyoteTime: 0.1,
|
|
207
|
+
bufferTime: 0.1,
|
|
208
|
+
airJumps: 0,
|
|
209
|
+
airJumpRatio: 0.8,
|
|
210
|
+
hover: null,
|
|
211
|
+
};
|
|
212
|
+
/** Gravity (world units / s²) and take-off speed (world units / s) of a jump. */
|
|
213
|
+
export function jumpArc(params) {
|
|
214
|
+
const t = Math.max(0.01, params.timeToApex);
|
|
215
|
+
return { gravity: (2 * params.height) / (t * t), speed: (2 * params.height) / t };
|
|
216
|
+
}
|
|
217
|
+
export const IDLE_JUMP = {
|
|
218
|
+
sinceGround: 0,
|
|
219
|
+
sincePress: Number.POSITIVE_INFINITY,
|
|
220
|
+
jumped: false,
|
|
221
|
+
cut: false,
|
|
222
|
+
airJumpsUsed: 0,
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Advance the vertical motion by `dt` seconds, after the horizontal step put the
|
|
226
|
+
* character over ground of height `ground`.
|
|
227
|
+
*
|
|
228
|
+
* - On the ground, a step up (already limited to `maxStep` by `constrainToGround`) or a
|
|
229
|
+
* step down of at most `maxStep` keeps the feet on the ground; a bigger drop starts a
|
|
230
|
+
* fall instead of snapping down.
|
|
231
|
+
* - With `jump` tuning, a press (or one buffered for `bufferTime`) jumps from the ground
|
|
232
|
+
* or within `coyoteTime` of leaving it; releasing the key while rising cuts the jump.
|
|
233
|
+
* - A fresh press in the air uses one of the `airJumps` while any remain (`airJumpRatio`
|
|
234
|
+
* of the height); they come back on landing.
|
|
235
|
+
* - With `hover` tuning, once the air jumps are used up, holding the key while falling
|
|
236
|
+
* hovers: the thrust pushes against gravity (see `hoverSpeed`) while the gauge drains,
|
|
237
|
+
* and it keeps firing while the key stays held, also once it climbs; an empty gauge
|
|
238
|
+
* falls normally. On the ground the gauge refills over `rechargeTime`.
|
|
239
|
+
* - A `hopHeight` above 0 (a vehicle's drift hop) makes a drift-key press on the ground
|
|
240
|
+
* hop that high, under the same gravity.
|
|
241
|
+
* - In the air, gravity pulls the feet down (`fallGravity` × while falling) until they
|
|
242
|
+
* meet the ground. Without `jump` the default arc's gravity still drives falls.
|
|
243
|
+
*/
|
|
244
|
+
export function stepVertical(pose, timers, input, dt, ground, maxStep, jump, hopHeight = 0) {
|
|
245
|
+
if (dt <= 0)
|
|
246
|
+
return { pose, timers };
|
|
247
|
+
let { z, vz, airborne, hoverGauge } = pose;
|
|
248
|
+
let hovering = false;
|
|
249
|
+
let { sinceGround, sincePress, jumped, cut, airJumpsUsed } = timers;
|
|
250
|
+
if (!airborne) {
|
|
251
|
+
if (z - ground > Math.max(0, maxStep)) {
|
|
252
|
+
airborne = true; // walked off a cliff: fall
|
|
253
|
+
vz = 0;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
z = ground;
|
|
257
|
+
jumped = false; // e.g. teleported mid-jump
|
|
258
|
+
cut = false;
|
|
259
|
+
airJumpsUsed = 0;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (z < ground) {
|
|
263
|
+
z = ground; // reached a ledge within the step mid-air: stand on its edge
|
|
264
|
+
}
|
|
265
|
+
sinceGround = airborne ? sinceGround + dt : 0;
|
|
266
|
+
const arc = jumpArc(jump ?? DEFAULT_JUMP);
|
|
267
|
+
if (hopHeight > 0 && input.driftPressed && !airborne) {
|
|
268
|
+
// A drift hop: spends the ground jump (no coyote jump after it), never cut short.
|
|
269
|
+
airborne = true;
|
|
270
|
+
vz = Math.sqrt(2 * arc.gravity * hopHeight);
|
|
271
|
+
jumped = true;
|
|
272
|
+
cut = true;
|
|
273
|
+
}
|
|
274
|
+
const hover = jump?.hover ?? null;
|
|
275
|
+
if (jump) {
|
|
276
|
+
sincePress = input.jumpPressed ? 0 : sincePress + dt;
|
|
277
|
+
const fromGround = !airborne || (!jumped && sinceGround <= jump.coyoteTime);
|
|
278
|
+
if (sincePress <= jump.bufferTime && fromGround) {
|
|
279
|
+
airborne = true;
|
|
280
|
+
vz = arc.speed;
|
|
281
|
+
jumped = true;
|
|
282
|
+
cut = false;
|
|
283
|
+
sincePress = Number.POSITIVE_INFINITY;
|
|
284
|
+
}
|
|
285
|
+
else if (input.jumpPressed && airborne && airJumpsUsed < Math.max(0, jump.airJumps)) {
|
|
286
|
+
vz = airJumpSpeed(arc.speed, jump.airJumpRatio);
|
|
287
|
+
airJumpsUsed++;
|
|
288
|
+
jumped = true;
|
|
289
|
+
cut = false;
|
|
290
|
+
sincePress = Number.POSITIVE_INFINITY;
|
|
291
|
+
}
|
|
292
|
+
else if (jumped && !cut && vz > 0 && !input.jump) {
|
|
293
|
+
vz *= Math.min(1, Math.max(0, jump.releaseCut));
|
|
294
|
+
cut = true;
|
|
295
|
+
}
|
|
296
|
+
// Hover: the air jumps used up, the key held, falling (or already hovering: a thrust
|
|
297
|
+
// above gravity climbs), and gauge left.
|
|
298
|
+
hovering =
|
|
299
|
+
hover !== null &&
|
|
300
|
+
airborne &&
|
|
301
|
+
airJumpsUsed >= Math.max(0, jump.airJumps) &&
|
|
302
|
+
input.jump === true &&
|
|
303
|
+
(vz <= 0 || pose.hovering) &&
|
|
304
|
+
hoverGauge > 0;
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
sincePress = Number.POSITIVE_INFINITY;
|
|
308
|
+
}
|
|
309
|
+
if (hovering && hover) {
|
|
310
|
+
vz = hoverSpeed(vz, dt, arc.gravity, hover);
|
|
311
|
+
z += vz * dt;
|
|
312
|
+
hoverGauge = drainHoverGauge(hoverGauge, dt, hover);
|
|
313
|
+
}
|
|
314
|
+
else if (airborne) {
|
|
315
|
+
const gravity = vz > 0 ? arc.gravity : arc.gravity * (jump ?? DEFAULT_JUMP).fallGravity;
|
|
316
|
+
vz -= gravity * dt;
|
|
317
|
+
z += vz * dt;
|
|
318
|
+
}
|
|
319
|
+
if (airborne && z <= ground) {
|
|
320
|
+
z = ground;
|
|
321
|
+
vz = 0;
|
|
322
|
+
airborne = false;
|
|
323
|
+
hovering = false;
|
|
324
|
+
jumped = false;
|
|
325
|
+
cut = false;
|
|
326
|
+
airJumpsUsed = 0;
|
|
327
|
+
sinceGround = 0;
|
|
328
|
+
}
|
|
329
|
+
// The gauge refills only on the ground; with hover off it stays full.
|
|
330
|
+
if (!hover)
|
|
331
|
+
hoverGauge = 1;
|
|
332
|
+
else if (!airborne)
|
|
333
|
+
hoverGauge = rechargeHoverGauge(hoverGauge, dt, hover);
|
|
334
|
+
const nextTimers = sinceGround === timers.sinceGround &&
|
|
335
|
+
sincePress === timers.sincePress &&
|
|
336
|
+
jumped === timers.jumped &&
|
|
337
|
+
cut === timers.cut &&
|
|
338
|
+
airJumpsUsed === timers.airJumpsUsed
|
|
339
|
+
? timers
|
|
340
|
+
: { sinceGround, sincePress, jumped, cut, airJumpsUsed };
|
|
341
|
+
const nextPose = z === pose.z &&
|
|
342
|
+
vz === pose.vz &&
|
|
343
|
+
airborne === pose.airborne &&
|
|
344
|
+
hovering === pose.hovering &&
|
|
345
|
+
hoverGauge === pose.hoverGauge
|
|
346
|
+
? pose
|
|
347
|
+
: { ...pose, z, vz, airborne, hovering, hoverGauge };
|
|
348
|
+
return { pose: nextPose, timers: nextTimers };
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* The input for the horizontal step on a frame that may start a drift hop: the press
|
|
352
|
+
* that hops doesn't also start the drift (it would carry through the air), so the drift
|
|
353
|
+
* begins on landing if the key is still held and steering.
|
|
354
|
+
*/
|
|
355
|
+
export function holdDriftForHop(input, pose, hopHeight) {
|
|
356
|
+
return hopHeight > 0 && input.driftPressed && !pose.airborne && input.drift
|
|
357
|
+
? { ...input, drift: false }
|
|
358
|
+
: input;
|
|
359
|
+
}
|
|
360
|
+
/** An air jump's take-off speed: the same gravity reaches `ratio` × the height. */
|
|
361
|
+
export function airJumpSpeed(takeoffSpeed, ratio) {
|
|
362
|
+
return takeoffSpeed * Math.sqrt(Math.max(0, Number.isFinite(ratio) ? ratio : 0));
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* The vertical speed after `dt` seconds of hovering from `vz`: the thrust (× `gravity`)
|
|
366
|
+
* against gravity, so the speed changes by (thrust − 1) × gravity per second, kept
|
|
367
|
+
* between −`fallSpeed` (a faster fall is caught at once) and `riseSpeed`.
|
|
368
|
+
*/
|
|
369
|
+
export function hoverSpeed(vz, dt, gravity, hover) {
|
|
370
|
+
const thrust = Number.isFinite(hover.thrust) ? Math.max(0, hover.thrust) : 0;
|
|
371
|
+
const next = vz + (thrust - 1) * gravity * dt;
|
|
372
|
+
return Math.min(Math.max(0, hover.riseSpeed), Math.max(-Math.max(0, hover.fallSpeed), next));
|
|
373
|
+
}
|
|
374
|
+
/** The hover gauge after `dt` seconds of hovering (a full gauge lasts `duration`). */
|
|
375
|
+
export function drainHoverGauge(gauge, dt, hover) {
|
|
376
|
+
if (!(hover.duration > 0))
|
|
377
|
+
return 0;
|
|
378
|
+
return Math.max(0, gauge - dt / hover.duration);
|
|
379
|
+
}
|
|
380
|
+
/** The hover gauge after `dt` seconds on the ground (empty → full in `rechargeTime`). */
|
|
381
|
+
export function rechargeHoverGauge(gauge, dt, hover) {
|
|
382
|
+
if (!(hover.rechargeTime > 0))
|
|
383
|
+
return 1;
|
|
384
|
+
return Math.min(1, gauge + dt / hover.rechargeTime);
|
|
385
|
+
}
|
|
386
|
+
/** Vehicle speed after a step of throttle (1), reverse (-1) or coasting (0). */
|
|
387
|
+
function throttledSpeed(speed, throttle, dt, params) {
|
|
388
|
+
if (throttle > 0) {
|
|
389
|
+
// Partial (analog) throttle aims for that fraction of the top speed; easing off
|
|
390
|
+
// above it slows down like coasting. Braking from reverse uses friction + throttle
|
|
391
|
+
// for a snappier stop.
|
|
392
|
+
const target = params.moveSpeed * throttle;
|
|
393
|
+
let accel = params.acceleration;
|
|
394
|
+
if (speed < 0)
|
|
395
|
+
accel = params.acceleration + params.friction;
|
|
396
|
+
else if (speed > target && throttle < 1)
|
|
397
|
+
accel = params.friction;
|
|
398
|
+
return approach(speed, target, accel * dt);
|
|
399
|
+
}
|
|
400
|
+
if (throttle < 0) {
|
|
401
|
+
const target = params.moveSpeed * params.reverseRatio * throttle;
|
|
402
|
+
let accel = params.acceleration;
|
|
403
|
+
if (speed > 0)
|
|
404
|
+
accel = params.acceleration + params.friction;
|
|
405
|
+
else if (speed < target && throttle > -1)
|
|
406
|
+
accel = params.friction;
|
|
407
|
+
return approach(speed, target, accel * dt);
|
|
408
|
+
}
|
|
409
|
+
return approach(speed, 0, params.friction * dt);
|
|
410
|
+
}
|
|
163
411
|
function nextDrift(current, held, steering, speed, params, driftParams) {
|
|
164
412
|
// Drifts only run forward: a stopped car never spins in place, whatever the tuning.
|
|
165
413
|
if (!driftParams || !held || speed <= 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"character-physics.js","sourceRoot":"","sources":["../src/character-physics.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"character-physics.js","sourceRoot":"","sources":["../src/character-physics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type PluginContext, type Point } from "@edv4h/usketch-shared";
|
|
2
|
-
import type
|
|
2
|
+
import { type CharacterStore } from "./character-store.js";
|
|
3
3
|
import { type CharacterAwareness } from "./character-sync.js";
|
|
4
4
|
import type { CharacterKeys } from "./character-types.js";
|
|
5
|
+
import { type VirtualInput } from "./character-virtual-input.js";
|
|
5
6
|
export declare const CHARACTER_LAYER_ID = "character";
|
|
6
7
|
/** `viewport:claimed` priority: above start-position (10), below deep links (100). */
|
|
7
8
|
export declare const CHARACTER_VIEWPORT_PRIORITY = 20;
|
|
@@ -23,7 +24,13 @@ export interface CharacterRuntime {
|
|
|
23
24
|
placeAtAnchor(): void;
|
|
24
25
|
/** The screen-px anchor (for rotating the camera about the character's spot). */
|
|
25
26
|
anchorPoint(): Point;
|
|
27
|
+
/** Jump on the next frame, as a full (held) jump. No-op while jumping is off. */
|
|
28
|
+
jump(): void;
|
|
26
29
|
setKeys(keys: CharacterKeys): void;
|
|
30
|
+
getKeys(): CharacterKeys;
|
|
31
|
+
/** Feed analog input from a host control (touch stick …); `null` releases it. */
|
|
32
|
+
setVirtualInput(input: Partial<VirtualInput> | null): void;
|
|
33
|
+
getVirtualInput(): VirtualInput | null;
|
|
27
34
|
dispose(): void;
|
|
28
35
|
}
|
|
29
36
|
export declare function setupCharacterRuntime(ctx: PluginContext, store: CharacterStore, options: CharacterRuntimeOptions): CharacterRuntime;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"character-runtime.d.ts","sourceRoot":"","sources":["../src/character-runtime.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,KAAK,EAIV,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"character-runtime.d.ts","sourceRoot":"","sources":["../src/character-runtime.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,KAAK,EAIV,MAAM,uBAAuB,CAAC;AAqB/B,OAAO,EAAE,KAAK,cAAc,EAAiC,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACN,KAAK,kBAAkB,EAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,8BAA8B,CAAC;AAEtC,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAG9C,sFAAsF;AACtF,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAiB9C;;;;GAIG;AACH,wBAAgB,UAAU,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAkB9D;AAED,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAChC,qEAAqE;IACrE,aAAa,IAAI,IAAI,CAAC;IACtB,iFAAiF;IACjF,WAAW,IAAI,KAAK,CAAC;IACrB,iFAAiF;IACjF,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,OAAO,IAAI,aAAa,CAAC;IACzB,iFAAiF;IACjF,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3D,eAAe,IAAI,YAAY,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,uBAAuB,GAC9B,gBAAgB,CA+OlB"}
|
|
@@ -6,8 +6,10 @@ import { groundHeightService, screenToWorld, viewportRotation, } from "@edv4h/us
|
|
|
6
6
|
import { anchorPx, easeFocus, followViewport, sameViewport, smoothingAlpha, targetRotation, } from "./character-camera.js";
|
|
7
7
|
import { createKeyInput } from "./character-input.js";
|
|
8
8
|
import { CharacterLayer } from "./character-layer.js";
|
|
9
|
-
import { constrainToGround, stepCharacter } from "./character-physics.js";
|
|
9
|
+
import { constrainToGround, holdDriftForHop, IDLE_JUMP, stepCharacter, stepVertical, } from "./character-physics.js";
|
|
10
|
+
import { driftHopHeight, effectiveJump } from "./character-store.js";
|
|
10
11
|
import { createCharacterSync, easeRemotes, } from "./character-sync.js";
|
|
12
|
+
import { combineInput, isVirtualInputActive, normalizeVirtualInput, } from "./character-virtual-input.js";
|
|
11
13
|
export const CHARACTER_LAYER_ID = "character";
|
|
12
14
|
/** Above shapes and most overlays, below the HUD (9999). */
|
|
13
15
|
const CHARACTER_LAYER_ORDER = 700;
|
|
@@ -17,6 +19,8 @@ export const CHARACTER_VIEWPORT_PRIORITY = 20;
|
|
|
17
19
|
const REMOTE_SMOOTHING = 0.75;
|
|
18
20
|
/** Largest simulated step, so a background-tab pause doesn't teleport the character. */
|
|
19
21
|
const MAX_DT = 0.05;
|
|
22
|
+
/** How long a measured canvas size is reused (a window resize re-measures at once). */
|
|
23
|
+
const CANVAS_SIZE_TTL_MS = 500;
|
|
20
24
|
function scheduleFrame(fn) {
|
|
21
25
|
if (typeof requestAnimationFrame === "function")
|
|
22
26
|
return requestAnimationFrame(fn);
|
|
@@ -55,14 +59,37 @@ export function canvasSize() {
|
|
|
55
59
|
return { width: 0, height: 0 };
|
|
56
60
|
}
|
|
57
61
|
export function setupCharacterRuntime(ctx, store, options) {
|
|
58
|
-
const keys = createKeyInput(options.keys, () => store.getState().enabled, () => store.getState().controlScheme === "vehicle" && store.getState().drift !== null);
|
|
62
|
+
const keys = createKeyInput(options.keys, () => store.getState().enabled, () => store.getState().controlScheme === "vehicle" && store.getState().drift !== null, () => store.getState().jump !== null);
|
|
63
|
+
let jumpTimers = IDLE_JUMP;
|
|
64
|
+
// `jump()` from code: a press on the next frame, held until the apex (a full jump).
|
|
65
|
+
let pendingJump = false;
|
|
66
|
+
let holdJump = false;
|
|
67
|
+
// Cleared when the character turns off, so a control that never sent its release
|
|
68
|
+
// (unmounted mid-touch) can't leave the next ride driving on its own.
|
|
69
|
+
let virtual = null;
|
|
59
70
|
let cam = null;
|
|
60
71
|
let display = new Map();
|
|
61
72
|
let rafId = null;
|
|
62
73
|
let lastFrame = null;
|
|
63
74
|
// Set while WE write the viewport, so our own writes don't read as a user pan.
|
|
64
75
|
let writing = false;
|
|
65
|
-
|
|
76
|
+
// The anchor is read every frame while following; measuring the canvas walks the layer
|
|
77
|
+
// wrappers and forces a layout, so the size is cached and refreshed on resize or after
|
|
78
|
+
// a short TTL (covers layout changes that aren't a window resize, e.g. a side panel).
|
|
79
|
+
let sizeCache = null;
|
|
80
|
+
const cachedCanvasSize = () => {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
if (!sizeCache || now - sizeCache.at > CANVAS_SIZE_TTL_MS) {
|
|
83
|
+
sizeCache = { ...canvasSize(), at: now };
|
|
84
|
+
}
|
|
85
|
+
return sizeCache;
|
|
86
|
+
};
|
|
87
|
+
const onResize = () => {
|
|
88
|
+
sizeCache = null;
|
|
89
|
+
};
|
|
90
|
+
if (typeof window !== "undefined")
|
|
91
|
+
window.addEventListener("resize", onResize);
|
|
92
|
+
const anchorPoint = () => anchorPx(store.getState().anchor, cachedCanvasSize());
|
|
66
93
|
// Ground height from whichever plugin provides it (e.g. the map's raised terrain), looked up
|
|
67
94
|
// per call so a provider registered later still counts. Absent = flat board.
|
|
68
95
|
const heightAt = (x, y) => groundHeightService.get(ctx.services)?.heightAt(x, y) ?? 0;
|
|
@@ -73,6 +100,7 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
73
100
|
const vp = ctx.store.getViewport();
|
|
74
101
|
const a = anchorPoint();
|
|
75
102
|
store.setPosition(screenToWorld(a.x, a.y, vp));
|
|
103
|
+
jumpTimers = IDLE_JUMP;
|
|
76
104
|
cam = null;
|
|
77
105
|
};
|
|
78
106
|
const writeViewport = (vp) => {
|
|
@@ -98,13 +126,29 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
98
126
|
store.setHeading(-viewportRotation(ctx.store.getViewport()));
|
|
99
127
|
s = store.getState();
|
|
100
128
|
}
|
|
101
|
-
const
|
|
102
|
-
|
|
129
|
+
const keyInput = combineInput(keys.read(), virtual);
|
|
130
|
+
const input = {
|
|
131
|
+
...keyInput,
|
|
132
|
+
jump: keyInput.jump || holdJump,
|
|
133
|
+
jumpPressed: keyInput.jumpPressed || pendingJump,
|
|
134
|
+
};
|
|
135
|
+
if (pendingJump)
|
|
136
|
+
holdJump = true;
|
|
137
|
+
pendingJump = false;
|
|
138
|
+
if (s.followSuspended && (keys.anyHeld() || isVirtualInputActive(virtual))) {
|
|
103
139
|
store.setFollowSuspended(false);
|
|
140
|
+
}
|
|
104
141
|
const vp = ctx.store.getViewport();
|
|
105
|
-
const
|
|
142
|
+
const hopHeight = driftHopHeight(s);
|
|
143
|
+
const stepped = stepCharacter(s.pose, holdDriftForHop(input, s.pose, hopHeight), dt, s.controlScheme, s.motion, viewportRotation(vp), s.drift);
|
|
106
144
|
// Cliffs taller than the climbable step block the move (slide along them).
|
|
107
|
-
const
|
|
145
|
+
const moved = constrainToGround(s.pose, stepped, heightAt, s.motion.maxStep);
|
|
146
|
+
// Then up and down: jumps, falls off cliffs, landings.
|
|
147
|
+
const vertical = stepVertical(moved, jumpTimers, input, dt, heightAt(moved.x, moved.y), s.motion.maxStep, effectiveJump(s), hopHeight);
|
|
148
|
+
jumpTimers = vertical.timers;
|
|
149
|
+
const pose = vertical.pose;
|
|
150
|
+
if (holdJump && (!pose.airborne || pose.vz <= 0))
|
|
151
|
+
holdJump = false;
|
|
108
152
|
store.setPose(pose);
|
|
109
153
|
s = store.getState();
|
|
110
154
|
if (s.cameraMode !== "free" && !s.followSuspended) {
|
|
@@ -158,6 +202,7 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
158
202
|
}
|
|
159
203
|
else {
|
|
160
204
|
cam = null;
|
|
205
|
+
virtual = null;
|
|
161
206
|
// Hand the camera back upright.
|
|
162
207
|
if (viewportRotation(ctx.store.getViewport()) !== 0) {
|
|
163
208
|
ctx.store.rotateTo(0, anchorPoint(), { animate: true });
|
|
@@ -175,7 +220,8 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
175
220
|
});
|
|
176
221
|
// A viewport change we didn't make: zoom (wheel / keys) is welcome — the follow
|
|
177
222
|
// keeps the character on its anchor at the new zoom. A pure pan means the user
|
|
178
|
-
// wants to look around, so pause following until a movement key
|
|
223
|
+
// wants to look around, so pause following until a movement key (or the virtual
|
|
224
|
+
// control) is pressed.
|
|
179
225
|
let lastZoom = ctx.store.getViewport().zoom;
|
|
180
226
|
const offViewport = ctx.store.onMutation((e) => {
|
|
181
227
|
if (e.type !== "viewport:changed")
|
|
@@ -200,7 +246,21 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
200
246
|
return {
|
|
201
247
|
placeAtAnchor,
|
|
202
248
|
anchorPoint,
|
|
249
|
+
jump() {
|
|
250
|
+
const s = store.getState();
|
|
251
|
+
if (!s.enabled || !s.jump)
|
|
252
|
+
return;
|
|
253
|
+
pendingJump = true;
|
|
254
|
+
ensureLoop();
|
|
255
|
+
},
|
|
203
256
|
setKeys: (k) => keys.setKeys(k),
|
|
257
|
+
getKeys: () => keys.getKeys(),
|
|
258
|
+
setVirtualInput(input) {
|
|
259
|
+
// Ignored while off (like the keys), so input sent before the character is
|
|
260
|
+
// turned on can't make it drive away on its own the moment it spawns.
|
|
261
|
+
virtual = store.getState().enabled ? normalizeVirtualInput(input) : null;
|
|
262
|
+
},
|
|
263
|
+
getVirtualInput: () => (virtual ? { ...virtual } : null),
|
|
204
264
|
dispose() {
|
|
205
265
|
if (rafId !== null)
|
|
206
266
|
cancelFrame(rafId);
|
|
@@ -209,6 +269,8 @@ export function setupCharacterRuntime(ctx, store, options) {
|
|
|
209
269
|
offViewport();
|
|
210
270
|
keys.dispose();
|
|
211
271
|
sync?.dispose();
|
|
272
|
+
if (typeof window !== "undefined")
|
|
273
|
+
window.removeEventListener("resize", onResize);
|
|
212
274
|
ctx.layers.unregister(CHARACTER_LAYER_ID);
|
|
213
275
|
},
|
|
214
276
|
};
|
|
@@ -227,6 +289,10 @@ function sameRemotes(a, b) {
|
|
|
227
289
|
o.steering !== r.steering ||
|
|
228
290
|
o.slip !== r.slip ||
|
|
229
291
|
o.drifting !== r.drifting ||
|
|
292
|
+
o.z !== r.z ||
|
|
293
|
+
o.airborne !== r.airborne ||
|
|
294
|
+
o.hovering !== r.hovering ||
|
|
295
|
+
o.hoverGauge !== r.hoverGauge ||
|
|
230
296
|
o.name !== r.name ||
|
|
231
297
|
o.appearance !== r.appearance) {
|
|
232
298
|
return false;
|