reze-engine 0.21.1 → 0.22.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 CHANGED
@@ -12,14 +12,13 @@ npm install reze-engine
12
12
 
13
13
  ## Features
14
14
 
15
- - Anime/MMD **hybrid renderer** — toon-ramp NPR over a Principled GGX BSDF, mixed per material
16
- - **Shader-graph materials + style groups** — every look is a Blender-style **shader graph** (JSON) compiled to WGSL at runtime; **style groups** bind any set of materials to any graph (unlimited, user-defined). 9 NPR graphs ship built-in (`face` / `hair` / `body` / `eye` / `stockings` / `metal` / `cloth_smooth` / `cloth_rough` / `default`); fully customizable — see [reze-design](https://reze.design) for the visual shader-graph editor
15
+ - **Anime-style rendering** — toon-ramp NPR over a Principled GGX BSDF, mixed per material
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, 4× MSAA, Apple-TBDR-friendly targets
18
- - **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs, no external dependency
19
- - **VMD animation** with MMD IK, morphs (GPU compute path), and VMD export
20
- - **PMX textures** — browser-native formats plus a built-in TGA decoder (common in MMD sphere/eye maps); unsupported files log and fall back, never crash
18
+ - **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs, zero dependencies
19
+ - **VMD animation** MMD IK, morphs on a GPU compute path, and VMD export
21
20
  - **Interactive editing** — GPU picking, transform gizmo, bone/material selection
22
- - Orbit camera with bone-follow, ground + PCF shadows, multi-model
21
+ - **Camera** orbit, bone-follow, or a driven MMD camera VMD; ground + PCF shadows, multi-model scenes
23
22
 
24
23
  See [Physics](#physics) and [Rendering](#rendering) for the internals.
25
24
 
@@ -32,6 +31,25 @@ See [Physics](#physics) and [Rendering](#rendering) for the internals.
32
31
  - [MPL](https://mmd-mpl.vercel.app) (motion language)
33
32
  - [Mixamo-MMD](https://mixamo-mmd.vercel.app) (FBX→VMD retarget)
34
33
 
34
+ ## Quick start
35
+
36
+ ```javascript
37
+ import { Engine } from "reze-engine"
38
+
39
+ const engine = new Engine(canvas)
40
+ await engine.init()
41
+
42
+ const model = await engine.loadModel("reze", "/models/reze/reze.pmx")
43
+ await engine.autoStyleGroups("reze")
44
+
45
+ await model.loadVmd("idle", "/animations/idle.vmd")
46
+ model.show("idle")
47
+ model.play()
48
+
49
+ engine.addGround()
50
+ engine.runRenderLoop()
51
+ ```
52
+
35
53
  ## Codebase map
36
54
 
37
55
  ```
@@ -72,46 +90,6 @@ engine/src/
72
90
  outline, selection, gizmo, pick, ground, mipmap
73
91
  ```
74
92
 
75
- ## Quick start
76
-
77
- ```javascript
78
- import { Engine, Vec3 } from "reze-engine"
79
-
80
- const engine = new Engine(canvas, {
81
- world: { color: new Vec3(0.4, 0.49, 0.65), strength: 1.0 }, // environment light
82
- sun: { color: new Vec3(1, 1, 1), strength: 2.0, direction: new Vec3(0, -0.5, 1) },
83
- bloom: { color: new Vec3(0.9, 0.1, 0.8), intensity: 0.05, threshold: 0.5 },
84
- camera: { distance: 31.5, target: new Vec3(0, 11.5, 0) }, // MMD units (1 unit = 8 cm)
85
- })
86
- await engine.init()
87
-
88
- const model = await engine.loadModel("reze", "/models/reze/reze.pmx")
89
-
90
- // One-tap styling: bucket materials into the engine's built-in default shader graphs
91
- // (face / hair / eye / cloth / stockings / metal). These categories are just the shipped
92
- // starter graphs — NOT fixed slots. `overrides` maps names the built-in JP/CN/EN hints
93
- // miss; standard-named models need no map. Unmatched materials stay ungrouped (neutral).
94
- // For arbitrary groups with any graph, use applyStyleGroups (see "Shader graphs & style groups").
95
- await engine.autoStyleGroups("reze", {
96
- face: ["face01"],
97
- body: ["skin"],
98
- hair: ["hair_f"],
99
- eye: ["eye"],
100
- cloth_smooth: ["shirt", "dress", "shoes"],
101
- cloth_rough: ["jacket"],
102
- stockings: ["stockings"],
103
- metal: ["earring"],
104
- })
105
-
106
- await model.loadVmd("idle", "/animations/idle.vmd")
107
- model.show("idle")
108
- model.play()
109
-
110
- engine.setCameraFollow(model, "センター", new Vec3(0, 3.5, 0))
111
- engine.addGround({ width: 160, height: 160 })
112
- engine.runRenderLoop()
113
- ```
114
-
115
93
  ## API
116
94
 
117
95
  One WebGPU **Engine** per page (singleton after `init()`). Models load by URL **or** from a user-selected folder ([below](#local-folder-uploads-browser)).
@@ -122,6 +100,7 @@ One WebGPU **Engine** per page (singleton after `init()`). Models load by URL **
122
100
  engine.init()
123
101
  engine.loadModel(name, path) // or ({ files, pmxFile? }) for folder upload
124
102
  engine.getModel(name) / getModelNames() / removeModel(name)
103
+ engine.setModelTransform(name, { position?, rotation?, scale?, visible? }) / getModelTransform(name) // place a stage, scale or hide a model (scale is uniform)
125
104
 
126
105
  engine.autoStyleGroups(name, overrides?) // default style groups by material name
127
106
  engine.applyStyleGroups(name, groups) / upsertStyleGroup / removeStyleGroup / getStyleGroups
@@ -134,6 +113,9 @@ engine.resetPhysics() // re-pose bodies from animation +
134
113
  engine.setCameraFollow(model, bone?, offset?) / setCameraFollow(null)
135
114
  engine.setCameraTarget(vec3) / setCameraDistance(d) / setCameraAlpha(a) / setCameraBeta(b)
136
115
 
116
+ engine.loadCameraVmd(url) / loadCameraVmdFromBuffer(buffer) // MMD camera track (dedicated file or a VMD's camera block) drives target/rotation/distance/fov — default-on once loaded
117
+ engine.setCameraVmdEnabled(on) / isCameraVmdEnabled() / hasCameraVmd() / clearCameraVmd() // toggle the shot; off falls back to orbit / follow-bone
118
+
137
119
  engine.setWorld({ color?, strength? }) / setSun({ color?, strength?, direction? }) // runtime lighting
138
120
  engine.addGround(options?)
139
121
  engine.runRenderLoop(callback?) / stopRenderLoop()
@@ -226,11 +208,10 @@ Two ways to make groups:
226
208
  ```javascript
227
209
  import { HAIR_GRAPH, compileGraph } from "reze-engine"
228
210
 
229
- // 1. autoStyleGroups — one default group per built-in category (each backed by its shipped
230
- // graph), bucketed by material-name hints (+ optional overrides). The "just works" path.
211
+ // 1. autoStyleGroups — one default group per matched category (its shipped graph). Easy path.
231
212
  await engine.autoStyleGroups("reze")
232
213
 
233
- // 2. applyStyleGroups — define ARBITRARY groups: any id, any materials, any graph.
214
+ // 2. applyStyleGroups — arbitrary groups: any id, any materials, any graph.
234
215
  await engine.applyStyleGroups("reze", [
235
216
  { id: "hair", materials: ["髪", "前髪"], graph: HAIR_GRAPH, renderClass: "hair" },
236
217
  { id: "visor", materials: ["visor", "hud"], graph: myCustomGraph }, // your own graph
@@ -248,7 +229,19 @@ const { ok, wgsl, diagnostics } = compileGraph(HAIR_GRAPH, { renderClass: "hair"
248
229
  2. **Then built-in name hints** — a case-insensitive **substring** match of the material name against per-category JP/CN/EN keyword lists, ordered **most-specific-first** so families don't collide (`靴下`/`stocking` resolves to `stockings` before `靴`/`shoes` would hit `cloth_smooth`). This covers standard-named models with no overrides at all.
249
230
  3. **No match → ungrouped** — the material renders the neutral default. "Unmatched" is a real, intended outcome, not a catch-all bucket.
250
231
 
251
- Each category carries its shipped graph **and** pass-integration: `eye` `EYE_GRAPH` + `renderClass: "eye"`, `hair` → `HAIR_GRAPH` + `"hair"`, `stockings` → `STOCKINGS_GRAPH` + `alphaMode: "hashed"`, the rest → their graph + `auto`/`opaque`. The group `id` is the category name (`hair`, `eye`, ), so re-running is idempotent. The returned promise resolves after grouping **and** every graph compiles, so `getStyleGroups(model)` is populated the moment it resolves — seed your own store from it and edit with `applyStyleGroups` afterward.
232
+ The **built-in name hints**, checked top-to-bottom (first match wins), with the graph and pass-integration each category carries:
233
+
234
+ | Category | Graph · render-class / alpha | Matches a name containing (case-insensitive substring) |
235
+ | --- | --- | --- |
236
+ | `stockings` | `STOCKINGS_GRAPH` · `hashed` alpha | 靴下 · ソックス · タイツ · ニーソ · 袜 · stocking · socks · tights |
237
+ | `eye` | `EYE_GRAPH` · `eye` | 白目 · 目影 · 二重 · 睫 · まつげ · まゆ · 眉 · 目 · 瞳 · 眼 · eye · iris · pupil · lash · brow |
238
+ | `face` | `FACE_GRAPH` | 顔 · 颜 · 脸 · かお · face · 舌 · tongue · 牙 · 牙齿 · 歯 · teeth · tooth · 口腔 · 口内 · mouth · 嘴 · 歯茎 · gums |
239
+ | `hair` | `HAIR_GRAPH` · `hair` | 前髪 · 後髪 · 髪 · 髮 · 头发 · 頭髪 · もみあげ · アホ毛 · ヘア · hair · ahoge · bang |
240
+ | `body` | `BODY_GRAPH` | 肌 · 皮肤 · skin |
241
+ | `metal` | `METAL_GRAPH` | 金属 · メタル · metal |
242
+ | `cloth_smooth` | `CLOTH_SMOOTH_GRAPH` | 服 · 衣 · 裙 · 裤 · スカート · ワンピ · リボン · 袖 · 靴 · 鞋 · 帽 · 体 · 飾 · 饰 · 尾 · skirt · dress · ribbon · sleeve · shoes · boot · hat · cloth · accessor |
243
+
244
+ `cloth_rough` and `default` have **no** name hints — a material reaches them only via an explicit `overrides` entry. The group `id` is the category name, so re-running `autoStyleGroups` is idempotent; its promise resolves after every graph compiles, so `getStyleGroups(model)` is ready the moment it resolves — seed your own store from it, then edit with `applyStyleGroups`.
252
245
 
253
246
  Validation catches material conflicts, type mismatches, cycles, and bad links with node-level diagnostics; a failed compile keeps the previous pipeline rendering (fallback-on-error).
254
247
 
@@ -0,0 +1,20 @@
1
+ import { Vec3 } from "./math";
2
+ import type { CameraKeyframe } from "./vmd-loader";
3
+ /** A sampled camera pose. `rotation` is euler radians; `fov` is radians. */
4
+ export interface CameraPose {
5
+ target: Vec3;
6
+ rotation: Vec3;
7
+ distance: number;
8
+ fov: number;
9
+ }
10
+ export declare class CameraAnimation {
11
+ private readonly frames;
12
+ /** Track length in seconds (last keyframe). */
13
+ readonly duration: number;
14
+ constructor(frames: CameraKeyframe[]);
15
+ get frameCount(): number;
16
+ /** Sample the camera pose at time `t` (seconds). Clamps to the track ends; null if empty. */
17
+ sample(t: number): CameraPose | null;
18
+ private pose;
19
+ }
20
+ //# sourceMappingURL=camera-animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-animation.d.ts","sourceRoot":"","sources":["../src/camera-animation.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAKlD,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,IAAI,CAAA;IACZ,QAAQ,EAAE,IAAI,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ;AAaD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,MAAM,EAAE,cAAc,EAAE;IAKpC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,6FAA6F;IAC7F,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IA4CpC,OAAO,CAAC,IAAI;CAGb"}
@@ -0,0 +1,66 @@
1
+ // Samples an MMD camera track (from a VMD) at a playback time. Four bezier-interpolated
2
+ // channels — target (Vec3), rotation (Vec3 euler), distance, fov — driven off the same
3
+ // clock as the model motion so the shot stays synced to the dance.
4
+ import { Vec3 } from "./math";
5
+ import { bezierInterpolate } from "./animation";
6
+ const FPS = 30;
7
+ const DEG2RAD = Math.PI / 180;
8
+ // MMD camera interpolation is 24 bytes, stored CONTIGUOUS per channel — each channel's 4
9
+ // bezier bytes are [x1, x2, y1, y2] in order. Channels: 0=posX 1=posY 2=posZ 3=rotation
10
+ // 4=distance 5=fov. So channel c lives at bytes [4c .. 4c+3]. (Matches babylon-mmd, which
11
+ // slices these into position/rotation/distance/fov interpolation buffers.)
12
+ function bez(ip, c, t) {
13
+ const b = c * 4;
14
+ return bezierInterpolate(ip[b] / 127, ip[b + 1] / 127, ip[b + 2] / 127, ip[b + 3] / 127, t);
15
+ }
16
+ const lerp = (a, b, w) => a + (b - a) * w;
17
+ export class CameraAnimation {
18
+ constructor(frames) {
19
+ this.frames = frames;
20
+ this.duration = frames.length ? frames[frames.length - 1].frame / FPS : 0;
21
+ }
22
+ get frameCount() {
23
+ return this.frames.length;
24
+ }
25
+ /** Sample the camera pose at time `t` (seconds). Clamps to the track ends; null if empty. */
26
+ sample(t) {
27
+ const frames = this.frames;
28
+ const n = frames.length;
29
+ if (n === 0)
30
+ return null;
31
+ const frame = t * FPS;
32
+ if (frame <= frames[0].frame)
33
+ return this.pose(frames[0]);
34
+ if (frame >= frames[n - 1].frame)
35
+ return this.pose(frames[n - 1]);
36
+ // Binary search for the segment [a, b] with a.frame <= frame < b.frame.
37
+ let lo = 0;
38
+ let hi = n - 1;
39
+ while (hi - lo > 1) {
40
+ const mid = (lo + hi) >> 1;
41
+ if (frames[mid].frame <= frame)
42
+ lo = mid;
43
+ else
44
+ hi = mid;
45
+ }
46
+ const a = frames[lo];
47
+ const b = frames[hi];
48
+ const span = b.frame - a.frame;
49
+ const localT = span > 0 ? (frame - a.frame) / span : 0;
50
+ // The incoming interpolation curve is stored on the segment's end keyframe (b).
51
+ const ip = b.interpolation;
52
+ return {
53
+ target: new Vec3(lerp(a.target.x, b.target.x, bez(ip, 0, localT)), lerp(a.target.y, b.target.y, bez(ip, 1, localT)), lerp(a.target.z, b.target.z, bez(ip, 2, localT))),
54
+ // MMD rotation animates as one channel (single bezier for all three euler components).
55
+ rotation: (() => {
56
+ const w = bez(ip, 3, localT);
57
+ return new Vec3(lerp(a.rotation.x, b.rotation.x, w), lerp(a.rotation.y, b.rotation.y, w), lerp(a.rotation.z, b.rotation.z, w));
58
+ })(),
59
+ distance: lerp(a.distance, b.distance, bez(ip, 4, localT)),
60
+ fov: lerp(a.fov * DEG2RAD, b.fov * DEG2RAD, bez(ip, 5, localT)),
61
+ };
62
+ }
63
+ pose(f) {
64
+ return { target: f.target, rotation: f.rotation, distance: f.distance, fov: f.fov * DEG2RAD };
65
+ }
66
+ }
package/dist/camera.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Mat4, Vec3 } from "./math";
2
+ import type { CameraPose } from "./camera-animation";
2
3
  export declare class Camera {
3
4
  alpha: number;
4
5
  beta: number;
@@ -29,8 +30,19 @@ export declare class Camera {
29
30
  upperBetaLimit: number;
30
31
  private _viewMat;
31
32
  private _projMat;
33
+ vmdDriven: boolean;
34
+ private _vmdTarget;
35
+ private _vmdRotation;
36
+ private _vmdDistance;
37
+ private _savedFov;
38
+ private _quatScratch;
32
39
  constructor(alpha: number, beta: number, radius: number, target: Vec3, fov?: number);
33
40
  getPosition(): Vec3;
41
+ /** Enter/leave VMD-camera drive. Backs up the orbit fov on enter, restores it on leave
42
+ * (the VMD camera animates fov, so orbit's value would otherwise be clobbered). */
43
+ setVmdDriven(enabled: boolean): void;
44
+ /** Feed the next sampled MMD camera pose (engine calls this each frame while driving). */
45
+ setVmdPose(pose: CameraPose): void;
34
46
  getViewMatrix(): Mat4;
35
47
  private getCameraVectors;
36
48
  private panCamera;
@@ -1 +1 @@
1
- {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAMnC,qBAAa,MAAM;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAI;IAClB,IAAI,EAAE,MAAM,CAAO;IACnB,GAAG,EAAE,MAAM,CAAU;IAGrB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAY;IAGxC,kBAAkB,EAAE,MAAM,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAS;IAC/B,cAAc,EAAE,MAAM,CAAO;IAC7B,cAAc,EAAE,MAAM,CAAO;IAC7B,IAAI,EAAE,MAAM,CAAO;IACnB,IAAI,EAAE,MAAM,CAAU;IACtB,cAAc,EAAE,MAAM,CAAQ;IAC9B,cAAc,EAAE,MAAM,CAAkB;IAGxC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAiC;gBAErC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAE,MAAoB;IAmBhG,WAAW,IAAI,IAAI;IAQnB,aAAa,IAAI,IAAI;IASrB,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,SAAS;IAiBjB,kFAAkF;IAClF,OAAO,CAAC,mBAAmB;IAK3B,mBAAmB,IAAI,IAAI;IAM3B,aAAa,CAAC,MAAM,EAAE,iBAAiB;IAiBvC,aAAa;IAkBb,cAAc,CAAC,MAAM,EAAE,OAAO;IAS9B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,WAAW;IAiFnB,OAAO,CAAC,UAAU;CA+BnB"}
1
+ {"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAQ,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAMpD,qBAAa,MAAM;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAI;IAClB,IAAI,EAAE,MAAM,CAAO;IACnB,GAAG,EAAE,MAAM,CAAU;IAGrB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,oBAAoB,CAAY;IAGxC,kBAAkB,EAAE,MAAM,CAAQ;IAClC,cAAc,EAAE,MAAM,CAAS;IAC/B,cAAc,EAAE,MAAM,CAAO;IAC7B,cAAc,EAAE,MAAM,CAAO;IAC7B,IAAI,EAAE,MAAM,CAAO;IACnB,IAAI,EAAE,MAAM,CAAU;IACtB,cAAc,EAAE,MAAM,CAAQ;IAC9B,cAAc,EAAE,MAAM,CAAkB;IAGxC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAiC;IAKjD,SAAS,EAAE,OAAO,CAAQ;IAC1B,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAE,MAAoB;IAmBhG,WAAW,IAAI,IAAI;IAQnB;wFACoF;IACpF,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOpC,0FAA0F;IAC1F,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAOlC,aAAa,IAAI,IAAI;IAyBrB,OAAO,CAAC,gBAAgB;IA0CxB,OAAO,CAAC,SAAS;IAiBjB,kFAAkF;IAClF,OAAO,CAAC,mBAAmB;IAK3B,mBAAmB,IAAI,IAAI;IAM3B,aAAa,CAAC,MAAM,EAAE,iBAAiB;IAiBvC,aAAa;IAkBb,cAAc,CAAC,MAAM,EAAE,OAAO;IAS9B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,WAAW;IAiFnB,OAAO,CAAC,UAAU;CA+BnB"}
package/dist/camera.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Mat4, Vec3 } from "./math";
1
+ import { Mat4, Quat, Vec3 } from "./math";
2
2
  /** Far cap / zoom limit; large enough for wide shots without clipping distant ground */
3
3
  const FAR_CAP = 8000;
4
4
  const FAR_MIN = 200;
@@ -31,6 +31,15 @@ export class Camera {
31
31
  // Reused each frame so getViewMatrix/getProjectionMatrix don't allocate a Mat4 per call.
32
32
  this._viewMat = new Mat4(new Float32Array(16));
33
33
  this._projMat = new Mat4(new Float32Array(16));
34
+ // ── VMD camera drive ──
35
+ // When vmdDriven, getViewMatrix builds the shot from a sampled MMD camera pose (target /
36
+ // rotation-euler / distance / fov) instead of the orbit params. Toggled by the engine.
37
+ this.vmdDriven = false;
38
+ this._vmdTarget = new Vec3(0, 0, 0);
39
+ this._vmdRotation = new Vec3(0, 0, 0); // euler radians
40
+ this._vmdDistance = -45;
41
+ this._savedFov = Math.PI / 4;
42
+ this._quatScratch = new Float32Array(16);
34
43
  this.alpha = alpha;
35
44
  this.beta = beta;
36
45
  this.radius = radius;
@@ -54,7 +63,41 @@ export class Camera {
54
63
  const z = this.target.z + this.radius * Math.sin(this.beta) * Math.cos(this.alpha);
55
64
  return new Vec3(x, y, z);
56
65
  }
66
+ /** Enter/leave VMD-camera drive. Backs up the orbit fov on enter, restores it on leave
67
+ * (the VMD camera animates fov, so orbit's value would otherwise be clobbered). */
68
+ setVmdDriven(enabled) {
69
+ if (enabled === this.vmdDriven)
70
+ return;
71
+ if (enabled)
72
+ this._savedFov = this.fov;
73
+ else
74
+ this.fov = this._savedFov;
75
+ this.vmdDriven = enabled;
76
+ }
77
+ /** Feed the next sampled MMD camera pose (engine calls this each frame while driving). */
78
+ setVmdPose(pose) {
79
+ this._vmdTarget.set(pose.target);
80
+ this._vmdRotation.set(pose.rotation);
81
+ this._vmdDistance = pose.distance;
82
+ this.fov = pose.fov; // drives the projection
83
+ }
57
84
  getViewMatrix() {
85
+ if (this.vmdDriven) {
86
+ // MMD camera: look at `target` from `distance` back, oriented by the euler rotation.
87
+ // forward = q·(0,0,1) (LH), up = q·(0,1,0) — read as columns 2 and 1 of the rot matrix.
88
+ // eye = target + forward·distance (distance is negative in VMD, so eye sits behind).
89
+ // NOTE: euler sign/order follows the engine's fromEuler; if a loaded shot looks
90
+ // mirrored or rolled, this is the one line to flip (negate axes / reorder).
91
+ const r = this._vmdRotation;
92
+ const q = Quat.fromEuler(r.x, r.y, r.z);
93
+ Mat4.fromQuatInto(q.x, q.y, q.z, q.w, this._quatScratch, 0);
94
+ const s = this._quatScratch;
95
+ const t = this._vmdTarget;
96
+ const d = this._vmdDistance;
97
+ const ex = t.x + s[8] * d, ey = t.y + s[9] * d, ez = t.z + s[10] * d;
98
+ Mat4.lookAtInto(this._viewMat.values, ex, ey, ez, t.x, t.y, t.z, s[4], s[5], s[6]);
99
+ return this._viewMat;
100
+ }
58
101
  const eye = this.getPosition();
59
102
  const t = this.target;
60
103
  Mat4.lookAtInto(this._viewMat.values, eye.x, eye.y, eye.z, t.x, t.y, t.z, 0, 1, 0);
package/dist/engine.d.ts CHANGED
@@ -17,6 +17,15 @@ export type WorldOptions = {
17
17
  /** Multiplier on world color (Blender: World > Surface > Strength). */
18
18
  strength?: number;
19
19
  };
20
+ /** A model's scene placement — root offset baked into skinning + visibility. Serializable
21
+ * into a scene descriptor via getModelTransform. */
22
+ export type ModelTransform = {
23
+ position: Vec3;
24
+ rotation: Quat;
25
+ /** Uniform scale (default 1). */
26
+ scale: number;
27
+ visible: boolean;
28
+ };
20
29
  export type SunOptions = {
21
30
  /** Linear color of the sun lamp (Blender: Light > Color). */
22
31
  color?: Vec3;
@@ -266,6 +275,7 @@ export declare class Engine {
266
275
  private ikEnabled;
267
276
  private physicsEnabled;
268
277
  private useGpuMorphs;
278
+ private cameraAnimation;
269
279
  private cameraTargetModel;
270
280
  private cameraTargetBoneName;
271
281
  private cameraTargetOffset;
@@ -308,6 +318,20 @@ export declare class Engine {
308
318
  setCameraTarget(model: Model | null, boneName: string, offset?: Vec3): void;
309
319
  /** Souls-style follow cam: orbit center tracks a model bone each frame. Shorthand for setCameraTarget(model, boneName, offset). */
310
320
  setCameraFollow(model: Model | null, boneName?: string, offset?: Vec3): void;
321
+ /** Load a camera VMD (dedicated camera file, or any VMD's camera block) and drive the shot
322
+ * from it. Default-on once a non-empty track loads; toggle with setCameraVmdEnabled. */
323
+ loadCameraVmd(url: string): Promise<void>;
324
+ /** Load a camera VMD from an already-fetched buffer (e.g. a File the user dropped). */
325
+ loadCameraVmdFromBuffer(buffer: ArrayBuffer): void;
326
+ /** Turn the loaded camera VMD on/off (falls back to orbit when off). No-op if none loaded. */
327
+ setCameraVmdEnabled(enabled: boolean): void;
328
+ /** True while the loaded camera VMD is actively driving the shot. */
329
+ isCameraVmdEnabled(): boolean;
330
+ /** True if a (non-empty) camera VMD is loaded, regardless of enabled state. */
331
+ hasCameraVmd(): boolean;
332
+ /** Drop the loaded camera VMD and return to orbit control. */
333
+ clearCameraVmd(): void;
334
+ private cameraClockTime;
311
335
  getCameraDistance(): number;
312
336
  setCameraDistance(d: number): void;
313
337
  getCameraAlpha(): number;
@@ -361,6 +385,16 @@ export declare class Engine {
361
385
  removeModel(name: string): void;
362
386
  getModelNames(): string[];
363
387
  getModel(name: string): Model | null;
388
+ /**
389
+ * Place a model in the scene — position, rotation, uniform scale, visibility. The
390
+ * transform is a root offset baked into skinning (moves the whole rig), so it composes
391
+ * with animation. Use it to sit a `stage.pmx` with a character, or to fit/hide either.
392
+ * Scale is **uniform** (normals renormalize in-shader). Don't scale a physics-driven
393
+ * character — its colliders won't scale; scale stages (which are typically physics-free).
394
+ */
395
+ setModelTransform(name: string, transform: Partial<ModelTransform>): void;
396
+ /** Read a model's scene transform (for serialization into a scene descriptor). */
397
+ getModelTransform(name: string): ModelTransform | null;
364
398
  markVertexBufferDirty(modelNameOrModel?: string | Model): void;
365
399
  setSelectedMaterial(modelName: string | null, materialName: string | null): void;
366
400
  setSelectedBone(modelName: string | null, boneName: string | null): void;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/engine.js CHANGED
@@ -2,6 +2,8 @@ import { Camera } from "./camera";
2
2
  import { Mat4, Quat, Vec3 } from "./math";
3
3
  import { MORPH_COMPUTE_WGSL } from "./shaders/passes/morph";
4
4
  import { decodeTga } from "./tga-loader";
5
+ import { VMDLoader } from "./vmd-loader";
6
+ import { CameraAnimation } from "./camera-animation";
5
7
  import { PmxLoader } from "./pmx-loader";
6
8
  import { RezePhysics } from "./physics";
7
9
  import { createFetchAssetReader, createFileMapAssetReader, deriveBasePathFromPmxPath, fileListToMap, findFirstPmxFileInList, joinAssetPath, normalizeAssetPath, } from "./asset-reader";
@@ -36,7 +38,12 @@ const PRESET_NAME_HINTS = [
36
38
  "eye",
37
39
  ["白目", "目影", "二重", "睫", "まつげ", "まゆ", "眉", "目", "瞳", "眼", "eye", "iris", "pupil", "lash", "brow"],
38
40
  ],
39
- ["face", ["顔", "颜", "脸", "かお", "face"]],
41
+ // face also catches mouth-interior parts (tongue / teeth / gums / oral cavity), which
42
+ // share the face material family. Bare 口 is omitted — it collides with 袖口 (cuff).
43
+ [
44
+ "face",
45
+ ["顔", "颜", "脸", "かお", "face", "舌", "tongue", "牙", "牙齿", "歯", "teeth", "tooth", "口腔", "口内", "mouth", "嘴", "歯茎", "gums"],
46
+ ],
40
47
  ["hair", ["前髪", "後髪", "髪", "髮", "头发", "頭髪", "もみあげ", "アホ毛", "ヘア", "hair", "ahoge", "bang"]],
41
48
  ["body", ["肌", "皮肤", "skin"]],
42
49
  ["metal", ["金属", "メタル", "metal"]],
@@ -200,6 +207,9 @@ export class Engine {
200
207
  this.physicsEnabled = true;
201
208
  // GPU vertex-morph path. Set false BEFORE loadModel to fall back to the CPU path (A/B).
202
209
  this.useGpuMorphs = true;
210
+ // VMD camera track (a dedicated camera VMD). When loaded + enabled it drives the shot,
211
+ // sampled off the animated model's clock so it stays synced to the dance.
212
+ this.cameraAnimation = null;
203
213
  // Camera target binding (Babylon/Three style: camera follows model)
204
214
  this.cameraTargetModel = null;
205
215
  this.cameraTargetBoneName = "全ての親";
@@ -1819,6 +1829,53 @@ export class Engine {
1819
1829
  this.cameraTargetOffset.y = offset?.y ?? 0;
1820
1830
  this.cameraTargetOffset.z = offset?.z ?? 0;
1821
1831
  }
1832
+ // ── VMD camera track ──
1833
+ // A dedicated camera VMD (target / rotation / distance / fov animated). Motion VMDs loaded
1834
+ // via model.loadVmd never touch the camera — the camera shot is opt-in through here.
1835
+ /** Load a camera VMD (dedicated camera file, or any VMD's camera block) and drive the shot
1836
+ * from it. Default-on once a non-empty track loads; toggle with setCameraVmdEnabled. */
1837
+ async loadCameraVmd(url) {
1838
+ const frames = await VMDLoader.loadCamera(url);
1839
+ this.cameraAnimation = frames.length ? new CameraAnimation(frames) : null;
1840
+ this.camera.setVmdDriven(this.cameraAnimation !== null);
1841
+ }
1842
+ /** Load a camera VMD from an already-fetched buffer (e.g. a File the user dropped). */
1843
+ loadCameraVmdFromBuffer(buffer) {
1844
+ const frames = VMDLoader.loadCameraFromBuffer(buffer);
1845
+ this.cameraAnimation = frames.length ? new CameraAnimation(frames) : null;
1846
+ this.camera.setVmdDriven(this.cameraAnimation !== null);
1847
+ }
1848
+ /** Turn the loaded camera VMD on/off (falls back to orbit when off). No-op if none loaded. */
1849
+ setCameraVmdEnabled(enabled) {
1850
+ this.camera.setVmdDriven(enabled && this.cameraAnimation !== null);
1851
+ }
1852
+ /** True while the loaded camera VMD is actively driving the shot. */
1853
+ isCameraVmdEnabled() {
1854
+ return this.camera.vmdDriven;
1855
+ }
1856
+ /** True if a (non-empty) camera VMD is loaded, regardless of enabled state. */
1857
+ hasCameraVmd() {
1858
+ return this.cameraAnimation !== null;
1859
+ }
1860
+ /** Drop the loaded camera VMD and return to orbit control. */
1861
+ clearCameraVmd() {
1862
+ this.cameraAnimation = null;
1863
+ this.camera.setVmdDriven(false);
1864
+ }
1865
+ // Clock the camera VMD runs on: the first model with an active clip (playing or scrubbed),
1866
+ // so a static stage in the scene never freezes the shot at frame 0. Falls back to the first
1867
+ // model, then to 0 (empty scene).
1868
+ cameraClockTime() {
1869
+ let first = null;
1870
+ for (const inst of this.modelInstances.values()) {
1871
+ const p = inst.model.getAnimationProgress();
1872
+ if (first === null)
1873
+ first = p.current;
1874
+ if (p.playing || p.paused)
1875
+ return p.current;
1876
+ }
1877
+ return first ?? 0;
1878
+ }
1822
1879
  getCameraDistance() {
1823
1880
  return this.camera.radius;
1824
1881
  }
@@ -2047,6 +2104,39 @@ export class Engine {
2047
2104
  getModel(name) {
2048
2105
  return this.modelInstances.get(name)?.model ?? null;
2049
2106
  }
2107
+ /**
2108
+ * Place a model in the scene — position, rotation, uniform scale, visibility. The
2109
+ * transform is a root offset baked into skinning (moves the whole rig), so it composes
2110
+ * with animation. Use it to sit a `stage.pmx` with a character, or to fit/hide either.
2111
+ * Scale is **uniform** (normals renormalize in-shader). Don't scale a physics-driven
2112
+ * character — its colliders won't scale; scale stages (which are typically physics-free).
2113
+ */
2114
+ setModelTransform(name, transform) {
2115
+ const model = this.modelInstances.get(name)?.model;
2116
+ if (!model)
2117
+ return;
2118
+ if (transform.position)
2119
+ model.setPosition(transform.position);
2120
+ if (transform.rotation)
2121
+ model.setRotation(transform.rotation);
2122
+ if (transform.scale !== undefined)
2123
+ model.setScale(transform.scale);
2124
+ if (transform.visible !== undefined)
2125
+ model.setVisible(transform.visible);
2126
+ }
2127
+ /** Read a model's scene transform (for serialization into a scene descriptor). */
2128
+ getModelTransform(name) {
2129
+ const model = this.modelInstances.get(name)?.model;
2130
+ if (!model)
2131
+ return null;
2132
+ const p = model.position;
2133
+ return {
2134
+ position: new Vec3(p.x, p.y, p.z),
2135
+ rotation: model.rotation.clone(),
2136
+ scale: model.scale,
2137
+ visible: model.visible,
2138
+ };
2139
+ }
2050
2140
  markVertexBufferDirty(modelNameOrModel) {
2051
2141
  if (modelNameOrModel === undefined)
2052
2142
  return;
@@ -3009,6 +3099,8 @@ export class Engine {
3009
3099
  pass.setPipeline(this.pickPipeline);
3010
3100
  pass.setBindGroup(0, this.pickPerFrameBindGroup);
3011
3101
  this.forEachInstance((inst) => {
3102
+ if (!inst.model.visible)
3103
+ return; // hidden models aren't pickable
3012
3104
  pass.setVertexBuffer(0, inst.vertexBuffer);
3013
3105
  pass.setVertexBuffer(1, inst.jointsBuffer);
3014
3106
  pass.setVertexBuffer(2, inst.weightsBuffer);
@@ -3098,6 +3190,12 @@ export class Engine {
3098
3190
  this.camera.target.z = pz + this.cameraTargetOffset.z;
3099
3191
  }
3100
3192
  }
3193
+ // Drive the shot from the camera VMD (synced to the animated model's clock).
3194
+ if (this.camera.vmdDriven && this.cameraAnimation) {
3195
+ const pose = this.cameraAnimation.sample(this.cameraClockTime());
3196
+ if (pose)
3197
+ this.camera.setVmdPose(pose);
3198
+ }
3101
3199
  this.updateCameraUniforms();
3102
3200
  this.updateShadowLightVP();
3103
3201
  const encoder = this.device.createCommandEncoder();
@@ -3116,12 +3214,18 @@ export class Engine {
3116
3214
  },
3117
3215
  });
3118
3216
  sp.setPipeline(this.shadowDepthPipeline);
3119
- this.forEachInstance((inst) => this.drawInstanceShadow(sp, inst));
3217
+ this.forEachInstance((inst) => {
3218
+ if (inst.model.visible)
3219
+ this.drawInstanceShadow(sp, inst);
3220
+ });
3120
3221
  sp.end();
3121
3222
  }
3122
3223
  const pass = encoder.beginRenderPass(this.renderPassDescriptor);
3123
3224
  if (hasModels)
3124
- this.forEachInstance((inst) => this.renderOneModel(pass, inst));
3225
+ this.forEachInstance((inst) => {
3226
+ if (inst.model.visible)
3227
+ this.renderOneModel(pass, inst);
3228
+ });
3125
3229
  if (this.hasGround)
3126
3230
  this.renderGround(pass);
3127
3231
  pass.end();
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { Engine, DEFAULT_BLOOM_OPTIONS, DEFAULT_VIEW_TRANSFORM, type EngineStats, type EngineOptions, type BloomOptions, type ViewTransformOptions, type LoadModelFromFilesOptions, type MaterialPreset, type MaterialPresetMap, type GizmoDragEvent, type GizmoDragCallback, type GizmoDragKind, } from "./engine";
1
+ export { Engine, DEFAULT_BLOOM_OPTIONS, DEFAULT_VIEW_TRANSFORM, type EngineStats, type EngineOptions, type BloomOptions, type ViewTransformOptions, type LoadModelFromFilesOptions, type MaterialPreset, type MaterialPresetMap, type ModelTransform, type GizmoDragEvent, type GizmoDragCallback, type GizmoDragKind, } from "./engine";
2
2
  export { parsePmxFolderInput, pmxFileAtRelativePath, type PmxFolderInputResult } from "./folder-upload";
3
3
  export { compileGraph, validateGraph, assignStyleSlots, type CompileOptions, type CompileResult, type StyleSlot, } from "./graph/compile";
4
4
  export type { ShaderGraph, GraphNode, GraphLink, ExposedParam, SocketValue, Diagnostic, } from "./graph/schema";
@@ -18,5 +18,7 @@ export { Model } from "./model";
18
18
  export { Vec3, Quat, Mat4 } from "./math";
19
19
  export type { AnimationClip, AnimationPlayOptions, AnimationProgress, BoneKeyframe, MorphKeyframe, BoneInterpolation, ControlPoint, } from "./animation";
20
20
  export { FPS } from "./animation";
21
+ export { VMDLoader, type CameraKeyframe } from "./vmd-loader";
22
+ export { CameraAnimation, type CameraPose } from "./camera-animation";
21
23
  export { RezePhysics } from "./physics";
22
24
  //# sourceMappingURL=index.d.ts.map