reze-engine 0.32.0 → 0.32.1
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 +3 -1
- package/dist/locomotion.d.ts.map +1 -1
- package/dist/locomotion.js +23 -18
- package/package.json +1 -1
- package/src/locomotion.ts +24 -17
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install reze-engine
|
|
|
15
15
|
- **Anime-style rendering** — toon-ramp NPR over a Principled GGX BSDF, mixed per material
|
|
16
16
|
- **Shader-graph materials** — every look is a Blender-style node graph compiled to WGSL; style groups bind any materials to any graph, fully customizable
|
|
17
17
|
- **HDR pipeline** — bloom, Filmic tone mapping, ASC CDL colour grading, 4× MSAA, Apple-TBDR-friendly targets
|
|
18
|
-
- **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs with rest-stable implicit spring-dampers, zero dependencies
|
|
18
|
+
- **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs with rest-stable implicit spring-dampers, zero dependencies; each model simulates on its own Web Worker (plain transferables — no SharedArrayBuffer, no special headers), so physics costs the main thread ~0.1 ms and a multi-model scene pays for its slowest world, not the sum
|
|
19
19
|
- **Math library** — the shared Vec3/Quat/Mat4 layer of the Reze family: euler orders, swing-twist, shortest-arc, look-rotation, zero-alloc `*Into` variants
|
|
20
20
|
- **VMD animation** — MMD IK with per-chain enable read from the motion, morphs on a GPU compute path, and VMD export
|
|
21
21
|
- **Clip blending & locomotion** — weighted multi-clip pose blending, crossfades, and a game-style character controller (idle/run/sprint speed blend, authored stop skids, code-driven root motion) — the [demo](https://reze.one) is WASD-playable
|
|
@@ -88,6 +88,8 @@ engine/src/
|
|
|
88
88
|
|
|
89
89
|
physics/ in-house rigid-body solver (~2.5k lines)
|
|
90
90
|
physics.ts RezePhysics: bone↔body sync, fixed-step accumulator + interpolation
|
|
91
|
+
physics.worker.ts worker entry — one model's world per worker, pipelined one
|
|
92
|
+
worker-physics.ts frame deep over transferable buffers (main-thread facade)
|
|
91
93
|
solver.ts sequential-impulse PGS (joint + contact rows)
|
|
92
94
|
contact.ts narrowphase (analytical sphere/box/capsule pairs) + contact pool
|
|
93
95
|
constraint.ts 6DOF spring joints · world.ts broadphase + step
|
package/dist/locomotion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locomotion.d.ts","sourceRoot":"","sources":["../src/locomotion.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAO,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAEnC,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAA;IACb,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAA;IAChB;qFACiF;IACjF,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAA;IACtB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAA;IAChB;8EAC0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAA;IACtB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;kEAC8D;IAC9D,SAAS,CAAC,EAAE,eAAe,EAAE,CAAA;IAC7B,YAAY,CAAC,EAAE,eAAe,EAAE,CAAA;IAChC;;mFAE+E;IAC/E,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;IAC7B;;;qCAGiC;IACjC,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B;;wEAEoE;IACpE,IAAI,CAAC,EAAE,aAAa,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC;;oEAEgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;qDAEiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;iFAC6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;+EAC2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;2CACuC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;qEACiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;iEAEiE;AACjE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,IAAI,CAAA;IACd,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAA;IACX,uEAAuE;IACvE,QAAQ,EAAE,IAAI,CAAA;IACd,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAA;CACnB;
|
|
1
|
+
{"version":3,"file":"locomotion.d.ts","sourceRoot":"","sources":["../src/locomotion.ts"],"names":[],"mappings":"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"}
|
package/dist/locomotion.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import { FPS } from "./animation";
|
|
7
7
|
import { Quat, Vec3 } from "./math";
|
|
8
8
|
const TWO_PI = Math.PI * 2;
|
|
9
|
+
/** Seconds an interrupted stop's ghost pose takes to dissolve over resumed locomotion. */
|
|
10
|
+
const GHOST_FADE = 0.25;
|
|
9
11
|
function wrapAngle(a) {
|
|
10
12
|
while (a > Math.PI)
|
|
11
13
|
a -= TWO_PI;
|
|
@@ -281,12 +283,24 @@ export class LocomotionController {
|
|
|
281
283
|
const maxStep = this.speedResponse * dt;
|
|
282
284
|
const d = target - this.speedLevel;
|
|
283
285
|
this.speedLevel += Math.abs(d) <= maxStep ? d : Math.sign(d) * maxStep;
|
|
286
|
+
// Breakout throttle: while an interrupted skid's ghost still owns part of
|
|
287
|
+
// the pose (planted feet), root motion and the gait clock scale by what's
|
|
288
|
+
// LEFT of it — she accelerates exactly as the skid dissolves, so the feet
|
|
289
|
+
// never slide (滑步) through the handoff.
|
|
290
|
+
let ghostW = 0;
|
|
291
|
+
if (this.exitGhost) {
|
|
292
|
+
this.exitGhost.elapsed += dt;
|
|
293
|
+
ghostW = Math.max(0, 1 - this.exitGhost.elapsed / GHOST_FADE);
|
|
294
|
+
if (ghostW <= 0)
|
|
295
|
+
this.exitGhost = null;
|
|
296
|
+
}
|
|
284
297
|
// Root motion along the travel direction. In-place clips carry no horizontal root.
|
|
285
298
|
const speed = (this.speedLevel <= 1
|
|
286
299
|
? this.runSpeed * this.speedLevel
|
|
287
300
|
: this.runSpeed + (this.sprintSpeed - this.runSpeed) * (this.speedLevel - 1)) *
|
|
288
301
|
align *
|
|
289
|
-
speedScale
|
|
302
|
+
speedScale *
|
|
303
|
+
(1 - ghostW);
|
|
290
304
|
this.position.x += this.dirX * speed * dt;
|
|
291
305
|
this.position.z += this.dirZ * speed * dt;
|
|
292
306
|
// Clocks: idle free-runs; run/sprint share one normalized gait phase so a
|
|
@@ -296,7 +310,7 @@ export class LocomotionController {
|
|
|
296
310
|
const sprintDur = hasSprint ? this.clipDuration(this.clips.sprint) : runDur;
|
|
297
311
|
this.idleTime = (this.idleTime + dt) % idleDur;
|
|
298
312
|
const gaitDur = this.speedLevel <= 1 ? runDur : runDur + (sprintDur - runDur) * (this.speedLevel - 1);
|
|
299
|
-
this.gaitPhase = (this.gaitPhase + dt / gaitDur) % 1;
|
|
313
|
+
this.gaitPhase = (this.gaitPhase + (dt * (1 - ghostW)) / gaitDur) % 1;
|
|
300
314
|
// Weights along the 1D speed axis.
|
|
301
315
|
let wIdle, wRun, wSprint;
|
|
302
316
|
if (this.speedLevel <= 1) {
|
|
@@ -315,23 +329,14 @@ export class LocomotionController {
|
|
|
315
329
|
this.entries[1].weight = wRun;
|
|
316
330
|
this.entries[2].time = this.gaitPhase * sprintDur;
|
|
317
331
|
this.entries[2].weight = wSprint;
|
|
318
|
-
|
|
319
|
-
if (this.exitGhost) {
|
|
332
|
+
if (this.exitGhost !== null && ghostW > 0) {
|
|
320
333
|
const g = this.exitGhost;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
else {
|
|
328
|
-
this.entries[0].weight *= 1 - wGhost;
|
|
329
|
-
this.entries[1].weight *= 1 - wGhost;
|
|
330
|
-
this.entries[2].weight *= 1 - wGhost;
|
|
331
|
-
this.entries[3].name = g.clip;
|
|
332
|
-
this.entries[3].time = g.clipTime + g.elapsed; // the clip's real tail keeps playing
|
|
333
|
-
this.entries[3].weight = wGhost;
|
|
334
|
-
}
|
|
334
|
+
this.entries[0].weight *= 1 - ghostW;
|
|
335
|
+
this.entries[1].weight *= 1 - ghostW;
|
|
336
|
+
this.entries[2].weight *= 1 - ghostW;
|
|
337
|
+
this.entries[3].name = g.clip;
|
|
338
|
+
this.entries[3].time = g.clipTime + g.elapsed; // the clip's real tail keeps playing
|
|
339
|
+
this.entries[3].weight = ghostW;
|
|
335
340
|
}
|
|
336
341
|
else {
|
|
337
342
|
this.entries[3].weight = 0;
|
package/package.json
CHANGED
package/src/locomotion.ts
CHANGED
|
@@ -126,6 +126,9 @@ export interface LocomotionPose {
|
|
|
126
126
|
|
|
127
127
|
const TWO_PI = Math.PI * 2
|
|
128
128
|
|
|
129
|
+
/** Seconds an interrupted stop's ghost pose takes to dissolve over resumed locomotion. */
|
|
130
|
+
const GHOST_FADE = 0.25
|
|
131
|
+
|
|
129
132
|
function wrapAngle(a: number): number {
|
|
130
133
|
while (a > Math.PI) a -= TWO_PI
|
|
131
134
|
while (a < -Math.PI) a += TWO_PI
|
|
@@ -457,13 +460,25 @@ export class LocomotionController {
|
|
|
457
460
|
const d = target - this.speedLevel
|
|
458
461
|
this.speedLevel += Math.abs(d) <= maxStep ? d : Math.sign(d) * maxStep
|
|
459
462
|
|
|
463
|
+
// Breakout throttle: while an interrupted skid's ghost still owns part of
|
|
464
|
+
// the pose (planted feet), root motion and the gait clock scale by what's
|
|
465
|
+
// LEFT of it — she accelerates exactly as the skid dissolves, so the feet
|
|
466
|
+
// never slide (滑步) through the handoff.
|
|
467
|
+
let ghostW = 0
|
|
468
|
+
if (this.exitGhost) {
|
|
469
|
+
this.exitGhost.elapsed += dt
|
|
470
|
+
ghostW = Math.max(0, 1 - this.exitGhost.elapsed / GHOST_FADE)
|
|
471
|
+
if (ghostW <= 0) this.exitGhost = null
|
|
472
|
+
}
|
|
473
|
+
|
|
460
474
|
// Root motion along the travel direction. In-place clips carry no horizontal root.
|
|
461
475
|
const speed =
|
|
462
476
|
(this.speedLevel <= 1
|
|
463
477
|
? this.runSpeed * this.speedLevel
|
|
464
478
|
: this.runSpeed + (this.sprintSpeed - this.runSpeed) * (this.speedLevel - 1)) *
|
|
465
479
|
align *
|
|
466
|
-
speedScale
|
|
480
|
+
speedScale *
|
|
481
|
+
(1 - ghostW)
|
|
467
482
|
this.position.x += this.dirX * speed * dt
|
|
468
483
|
this.position.z += this.dirZ * speed * dt
|
|
469
484
|
|
|
@@ -474,7 +489,7 @@ export class LocomotionController {
|
|
|
474
489
|
const sprintDur = hasSprint ? this.clipDuration(this.clips.sprint!) : runDur
|
|
475
490
|
this.idleTime = (this.idleTime + dt) % idleDur
|
|
476
491
|
const gaitDur = this.speedLevel <= 1 ? runDur : runDur + (sprintDur - runDur) * (this.speedLevel - 1)
|
|
477
|
-
this.gaitPhase = (this.gaitPhase + dt / gaitDur) % 1
|
|
492
|
+
this.gaitPhase = (this.gaitPhase + (dt * (1 - ghostW)) / gaitDur) % 1
|
|
478
493
|
|
|
479
494
|
// Weights along the 1D speed axis.
|
|
480
495
|
let wIdle: number, wRun: number, wSprint: number
|
|
@@ -494,22 +509,14 @@ export class LocomotionController {
|
|
|
494
509
|
this.entries[1].weight = wRun
|
|
495
510
|
this.entries[2].time = this.gaitPhase * sprintDur
|
|
496
511
|
this.entries[2].weight = wSprint
|
|
497
|
-
|
|
498
|
-
if (this.exitGhost) {
|
|
512
|
+
if (this.exitGhost !== null && ghostW > 0) {
|
|
499
513
|
const g = this.exitGhost
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
this.entries[0].weight *= 1 - wGhost
|
|
507
|
-
this.entries[1].weight *= 1 - wGhost
|
|
508
|
-
this.entries[2].weight *= 1 - wGhost
|
|
509
|
-
this.entries[3].name = g.clip
|
|
510
|
-
this.entries[3].time = g.clipTime + g.elapsed // the clip's real tail keeps playing
|
|
511
|
-
this.entries[3].weight = wGhost
|
|
512
|
-
}
|
|
514
|
+
this.entries[0].weight *= 1 - ghostW
|
|
515
|
+
this.entries[1].weight *= 1 - ghostW
|
|
516
|
+
this.entries[2].weight *= 1 - ghostW
|
|
517
|
+
this.entries[3].name = g.clip
|
|
518
|
+
this.entries[3].time = g.clipTime + g.elapsed // the clip's real tail keeps playing
|
|
519
|
+
this.entries[3].weight = ghostW
|
|
513
520
|
} else {
|
|
514
521
|
this.entries[3].weight = 0
|
|
515
522
|
}
|