@vgai/engine 0.5.11 → 0.5.13
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 +6 -5
- package/dist/adapter/authoring.d.ts +51 -28
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/body-marks.d.ts +59 -0
- package/dist/adapter/body-marks.d.ts.map +1 -0
- package/dist/adapter/body-marks.js +62 -0
- package/dist/adapter/constraint.d.ts +41 -0
- package/dist/adapter/constraint.d.ts.map +1 -0
- package/dist/adapter/constraint.js +27 -0
- package/dist/adapter/hierarchy-marks.d.ts +138 -0
- package/dist/adapter/hierarchy-marks.d.ts.map +1 -0
- package/dist/adapter/hierarchy-marks.js +148 -0
- package/dist/adapter/index.d.ts +1 -1
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/ingest/contract-system-adapters.d.ts +64 -0
- package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -0
- package/dist/adapter/ingest/contract-system-adapters.js +134 -0
- package/dist/adapter/ingest/game-contract.d.ts +87 -9
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +7 -6
- package/dist/adapter/ingest/scene-capture.d.ts +31 -4
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +29 -7
- package/dist/adapter/ingest/structural-ids.d.ts +1 -1
- package/dist/adapter/ingest/structural-ids.js +2 -2
- package/dist/adapter/reflection-probe.d.ts +53 -0
- package/dist/adapter/reflection-probe.d.ts.map +1 -0
- package/dist/adapter/reflection-probe.js +18 -0
- package/dist/asset-formats/index.d.ts +4 -10
- package/dist/asset-formats/index.d.ts.map +1 -1
- package/dist/asset-formats/index.js +3 -8
- package/dist/asset-formats/material.d.ts +0 -66
- package/dist/asset-formats/material.d.ts.map +1 -1
- package/dist/asset-formats/material.js +0 -8
- package/dist/asset-formats/mesh.d.ts +1 -2
- package/dist/asset-formats/mesh.d.ts.map +1 -1
- package/dist/asset-formats/mesh.js +3 -13
- package/dist/asset-formats/render-env.d.ts +2 -2
- package/dist/asset-parse-error.d.ts +4 -5
- package/dist/asset-parse-error.d.ts.map +1 -1
- package/dist/asset-parse-error.js +4 -5
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/data/curve.d.ts +116 -0
- package/dist/data/curve.d.ts.map +1 -0
- package/dist/data/curve.js +230 -0
- package/dist/data/vite-plugin-data.d.ts +2 -2
- package/dist/data/vite-plugin-data.d.ts.map +1 -1
- package/dist/data/vite-plugin-data.js +24 -15
- package/dist/dev/performance-profiler.d.ts +1 -0
- package/dist/dev/performance-profiler.d.ts.map +1 -1
- package/dist/dev/performance-profiler.js +25 -2
- package/dist/ecs/user-data.d.ts +49 -1
- package/dist/ecs/user-data.d.ts.map +1 -1
- package/dist/ecs/user-data.js +34 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/manifest/index.d.ts +3 -3
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +2 -2
- package/dist/manifest/load.d.ts +15 -67
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +11 -103
- package/dist/manifest/schema.d.ts +18 -103
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +59 -179
- package/dist/pixi/index.d.ts +2 -3
- package/dist/pixi/index.d.ts.map +1 -1
- package/dist/pixi/index.js +2 -3
- package/dist/pixi/ingest.d.ts +7 -75
- package/dist/pixi/ingest.d.ts.map +1 -1
- package/dist/pixi/ingest.js +6 -14
- package/dist/pixi/scene-capture.d.ts +2 -2
- package/dist/pixi/scene-capture.js +2 -2
- package/dist/react/use-data.d.ts +10 -5
- package/dist/react/use-data.d.ts.map +1 -1
- package/dist/react/use-data.js +15 -15
- package/dist/render/viewport-shading.d.ts +1 -1
- package/dist/render/viewport-shading.d.ts.map +1 -1
- package/dist/render/viewport-shading.js +14 -0
- package/dist/runtime/create-runtime.d.ts +12 -0
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +7 -2
- package/dist/runtime/mount-game.d.ts +1 -1
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +5 -1
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
- package/dist/world3d-react/r3f-adapter.js +69 -39
- package/dist/world3d-react/renderer-config.d.ts +15 -0
- package/dist/world3d-react/renderer-config.d.ts.map +1 -1
- package/dist/world3d-react/renderer-config.js +15 -0
- package/dist/world3d-react/world-context.d.ts +2 -1
- package/dist/world3d-react/world-context.d.ts.map +1 -1
- package/dist-config/config.js +140 -20
- package/dist-config/config.js.map +4 -4
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +10 -10
- package/schemas/vgai-project.schema.json +21 -76
- package/src/adapter/authoring.ts +54 -31
- package/src/adapter/body-marks.ts +69 -0
- package/src/adapter/constraint.ts +71 -0
- package/src/adapter/hierarchy-marks.ts +155 -0
- package/src/adapter/index.ts +2 -3
- package/src/adapter/ingest/contract-system-adapters.ts +174 -0
- package/src/adapter/ingest/game-contract.ts +98 -9
- package/src/adapter/ingest/scene-capture.ts +61 -11
- package/src/adapter/ingest/structural-ids.ts +2 -2
- package/src/adapter/reflection-probe.ts +75 -0
- package/src/asset-formats/index.ts +4 -10
- package/src/asset-formats/material.ts +0 -11
- package/src/asset-formats/mesh.ts +3 -16
- package/src/asset-parse-error.ts +4 -5
- package/src/config.ts +13 -0
- package/src/data/curve.ts +263 -0
- package/src/data/vite-plugin-data.ts +48 -14
- package/src/dev/performance-profiler.ts +21 -2
- package/src/ecs/user-data.ts +50 -0
- package/src/index.ts +2 -3
- package/src/manifest/index.ts +3 -15
- package/src/manifest/load.ts +27 -143
- package/src/manifest/schema.ts +65 -223
- package/src/pixi/index.ts +2 -15
- package/src/pixi/ingest.ts +13 -87
- package/src/pixi/scene-capture.ts +2 -2
- package/src/react/use-data.ts +15 -20
- package/src/render/viewport-shading.ts +16 -1
- package/src/runtime/create-runtime.ts +30 -5
- package/src/runtime/mount-game.ts +1 -1
- package/src/runtime/mount-manifest.ts +5 -1
- package/src/world3d-react/r3f-adapter.tsx +73 -39
- package/src/world3d-react/renderer-config.ts +31 -0
- package/src/world3d-react/world-context.ts +2 -1
- package/dist/asset-formats/instances.d.ts +0 -17
- package/dist/asset-formats/instances.d.ts.map +0 -1
- package/dist/asset-formats/instances.js +0 -31
- package/dist/asset-formats/parse.d.ts +0 -20
- package/dist/asset-formats/parse.d.ts.map +0 -1
- package/dist/asset-formats/parse.js +0 -34
- package/dist/pixi/ingest-iframe.d.ts +0 -82
- package/dist/pixi/ingest-iframe.d.ts.map +0 -1
- package/dist/pixi/ingest-iframe.js +0 -166
- package/dist/render/instance-mesh.d.ts +0 -5
- package/dist/render/instance-mesh.d.ts.map +0 -1
- package/dist/render/instance-mesh.js +0 -19
- package/schemas/mat.schema.json +0 -255
- package/src/asset-formats/instances.ts +0 -38
- package/src/asset-formats/parse.ts +0 -39
- package/src/pixi/ingest-iframe.ts +0 -255
- package/src/render/instance-mesh.ts +0 -25
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pixi iframe ingest tiers — the PixiJS analogs of the 3D ingest-iframe adapters.
|
|
3
|
-
*
|
|
4
|
-
* - OPAQUE EMBED (tier 0-1): a prebuilt/self-contained bundle runs in a sandboxed
|
|
5
|
-
* iframe; hosted + sized + disposed, NOT introspectable.
|
|
6
|
-
* - IFRAME-REACHABLE (tier 2-3): a bundle runs in its own iframe realm, but its
|
|
7
|
-
* `import 'pixi.js'` is wired (via an importmap) to a blob module re-exporting the
|
|
8
|
-
* HOST's pixi instance, so every Application/Sprite it creates is a HOST-realm
|
|
9
|
-
* object → the host `Application.prototype.render` trap fires and capture works.
|
|
10
|
-
*/
|
|
11
|
-
import {
|
|
12
|
-
type CapturedRuntime2D,
|
|
13
|
-
installSceneCapture2D,
|
|
14
|
-
type SceneCapture2DHandle,
|
|
15
|
-
} from './scene-capture';
|
|
16
|
-
|
|
17
|
-
export interface EmbedMount2D {
|
|
18
|
-
iframe: HTMLIFrameElement;
|
|
19
|
-
dispose: () => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** OPAQUE EMBED: sandboxed iframe, no scene introspection (tier 0-1). */
|
|
23
|
-
export function mountIngestGame2DEmbed(html: string, container: HTMLElement): EmbedMount2D {
|
|
24
|
-
const iframe = document.createElement('iframe');
|
|
25
|
-
iframe.setAttribute('sandbox', 'allow-scripts');
|
|
26
|
-
iframe.style.border = '0';
|
|
27
|
-
iframe.style.width = '100%';
|
|
28
|
-
iframe.style.height = '100%';
|
|
29
|
-
iframe.srcdoc = html;
|
|
30
|
-
container.appendChild(iframe);
|
|
31
|
-
return { iframe, dispose: () => iframe.remove() };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const HOST_PIXI_KEY = '__vgaiHostPixi';
|
|
35
|
-
|
|
36
|
-
/** Build a blob module that re-exports the host's pixi namespace (for the importmap). */
|
|
37
|
-
function makeHostPixiReexportUrl(pixiNamespace: Record<string, unknown>): string {
|
|
38
|
-
(window as unknown as Record<string, unknown>)[HOST_PIXI_KEY] = pixiNamespace;
|
|
39
|
-
const ident = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
40
|
-
const keys = Object.keys(pixiNamespace).filter((k) => k !== 'default' && ident.test(k));
|
|
41
|
-
const body =
|
|
42
|
-
`const T = window.parent[${JSON.stringify(HOST_PIXI_KEY)}];\n` +
|
|
43
|
-
`export default T;\n` +
|
|
44
|
-
keys.map((k) => `export const ${k} = T[${JSON.stringify(k)}];`).join('\n');
|
|
45
|
-
return URL.createObjectURL(new Blob([body], { type: 'text/javascript' }));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
let _reexportKeySeq = 0;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Generalized host-namespace re-export (the multi-dep analog of {@link makeHostPixiReexportUrl}).
|
|
52
|
-
* Stashes `ns` (an ES module namespace object, e.g. `import * as ns from 'gsap'`) on a unique
|
|
53
|
-
* window key and builds a blob module re-exporting it, so the iframe's importmap can map a bare
|
|
54
|
-
* specifier (pixi.js, @pixi/sound, @pixi/ui, gsap, …) to the HOST's single instance. Default-export
|
|
55
|
-
* handling: `export default T.default ?? T` so `import gsap from 'gsap'` gets gsap, while a
|
|
56
|
-
* default-less namespace (pixi.js) re-exports the namespace itself for `import * as`.
|
|
57
|
-
*/
|
|
58
|
-
function makeHostNamespaceReexportUrl(ns: Record<string, unknown>): string {
|
|
59
|
-
const key = `__vgaiHostNs_${_reexportKeySeq++}`;
|
|
60
|
-
(window as unknown as Record<string, unknown>)[key] = ns;
|
|
61
|
-
const ident = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
62
|
-
const keys = Object.keys(ns).filter((k) => k !== 'default' && ident.test(k));
|
|
63
|
-
const body =
|
|
64
|
-
`const T = window.parent[${JSON.stringify(key)}];\n` +
|
|
65
|
-
`export default (T && T.default !== undefined ? T.default : T);\n` +
|
|
66
|
-
keys.map((k) => `export const ${k} = T[${JSON.stringify(k)}];`).join('\n');
|
|
67
|
-
return URL.createObjectURL(new Blob([body], { type: 'text/javascript' }));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface IframeReachableMultiOpts {
|
|
71
|
-
captureTimeoutMs?: number;
|
|
72
|
-
/**
|
|
73
|
-
* Bare-specifier → host module-namespace map. MUST include the pixi.js instance the trap is
|
|
74
|
-
* installed on (passed separately as `pixiNamespace`); list the game's OTHER shared bare deps
|
|
75
|
-
* here (@pixi/sound, @pixi/ui, gsap, pixi-filters) so they resolve to host instances and their
|
|
76
|
-
* extension side-effects register on the host pixi (the trapped instance).
|
|
77
|
-
*/
|
|
78
|
-
extraDeps?: Record<string, Record<string, unknown>>;
|
|
79
|
-
/**
|
|
80
|
-
* Bare-specifier -> VERBATIM URL importmap entries (the
|
|
81
|
-
* project-node_modules fallback for a specifier that isn't in the
|
|
82
|
-
* host-namespace registry but IS installed in the open project's own
|
|
83
|
-
* `node_modules`). Written into the importmap DIRECTLY alongside the
|
|
84
|
-
* `extraDeps` blob-namespace entries — no host-side import, no blob
|
|
85
|
-
* wrapping, no decision logic here: this function just merges whatever
|
|
86
|
-
* `Record<specifier, url>` the caller (editor-side
|
|
87
|
-
* `host-namespace-registry.ts`) already decided. The URL's own transitive
|
|
88
|
-
* `import 'pixi.js'` resolves through this SAME importmap back to the host
|
|
89
|
-
* pixi trap (§0.3), keeping module identity converged without a second pixi
|
|
90
|
-
* instance.
|
|
91
|
-
*/
|
|
92
|
-
extraDepUrls?: Record<string, string>;
|
|
93
|
-
/** <base href> for the iframe so the game's relative asset URLs (Assets basePath) resolve. */
|
|
94
|
-
baseHref?: string;
|
|
95
|
-
/**
|
|
96
|
-
* HOST-SIDE asset URL remap (the Pixi analog of the three.js DefaultLoadingManager.setURLModifier
|
|
97
|
-
* asset adapter). A document.write iframe keeps the PARENT's window.location, so PixiJS's Assets
|
|
98
|
-
* resolver (which builds absolute URLs from window.location, not document.baseURI) would resolve
|
|
99
|
-
* the game's relative `basePath:'assets'` against the parent page. Wrapping the host pixi's
|
|
100
|
-
* Assets.init to force this ABSOLUTE basePath fixes resolution without touching the game source —
|
|
101
|
-
* pure host library configuration, restored on dispose.
|
|
102
|
-
*/
|
|
103
|
-
assetBaseUrl?: string;
|
|
104
|
-
/** Load the game bundle from this absolute URL (a built multi-file game). */
|
|
105
|
-
bundleUrl?: string;
|
|
106
|
-
/** …or run this inline module source (a single-file game). One of bundleUrl/inlineSrc required. */
|
|
107
|
-
inlineSrc?: string;
|
|
108
|
-
/** DOM the game expects to find before it boots (e.g. a `<div id="game-root">` it appends to). */
|
|
109
|
-
bodyHtml?: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* IFRAME-REACHABLE for REAL MULTI-FILE GAMES (cov2d-bundled-dedupe): run a built game bundle
|
|
114
|
-
* (its OWN unaltered source, externalized against pixi at build time) in its own iframe realm
|
|
115
|
-
* whose importmap maps EVERY shared bare dep — pixi.js + @pixi/sound/@pixi/ui/gsap/… — to the
|
|
116
|
-
* HOST instances, and (optionally) a <base href> so its AssetPack/manifest URLs resolve. The
|
|
117
|
-
* host `Application.prototype.render` trap then captures the live stage IN-REALM. The game's
|
|
118
|
-
* source is never touched; all of this is host-side wiring.
|
|
119
|
-
*/
|
|
120
|
-
export async function mountIngestGame2DIframeReachableMulti(
|
|
121
|
-
pixiNamespace: unknown,
|
|
122
|
-
container: HTMLElement,
|
|
123
|
-
opts: IframeReachableMultiOpts,
|
|
124
|
-
): Promise<IframeReachableMount2D> {
|
|
125
|
-
const capture = installSceneCapture2D(pixiNamespace);
|
|
126
|
-
const created: string[] = [];
|
|
127
|
-
const mkUrl = (ns: Record<string, unknown>): string => {
|
|
128
|
-
const u = makeHostNamespaceReexportUrl(ns);
|
|
129
|
-
created.push(u);
|
|
130
|
-
return u;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const imports: Record<string, string> = {
|
|
134
|
-
'pixi.js': mkUrl(pixiNamespace as Record<string, unknown>),
|
|
135
|
-
};
|
|
136
|
-
for (const [spec, ns] of Object.entries(opts.extraDeps ?? {})) imports[spec] = mkUrl(ns);
|
|
137
|
-
// D-Z3 fallback: verbatim URL entries, no blob wrapping, merged in beside
|
|
138
|
-
// the host-namespace ones — decision-free (see `extraDepUrls`'s doc comment).
|
|
139
|
-
for (const [spec, url] of Object.entries(opts.extraDepUrls ?? {})) imports[spec] = url;
|
|
140
|
-
|
|
141
|
-
// Host-side asset URL remap (asset adapter): force the game's Assets.init basePath to an
|
|
142
|
-
// absolute URL so its assets resolve to the served bundle dir, not the parent page path.
|
|
143
|
-
let restoreInit: (() => void) | undefined;
|
|
144
|
-
if (opts.assetBaseUrl) {
|
|
145
|
-
const assetsApi = (
|
|
146
|
-
pixiNamespace as { Assets?: { init?: (o?: Record<string, unknown>) => unknown } }
|
|
147
|
-
).Assets;
|
|
148
|
-
if (assetsApi?.init) {
|
|
149
|
-
const orig = assetsApi.init.bind(assetsApi);
|
|
150
|
-
assetsApi.init = (o: Record<string, unknown> = {}) =>
|
|
151
|
-
orig({ ...o, basePath: opts.assetBaseUrl });
|
|
152
|
-
restoreInit = () => {
|
|
153
|
-
assetsApi.init = orig;
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const iframe = document.createElement('iframe');
|
|
159
|
-
iframe.style.border = '0';
|
|
160
|
-
iframe.style.width = '100%';
|
|
161
|
-
iframe.style.height = '100%';
|
|
162
|
-
container.appendChild(iframe);
|
|
163
|
-
|
|
164
|
-
// Split the closing script token so this module's own bundling never sees a literal
|
|
165
|
-
// </script> (defensive; matches the single-dep mount's convention).
|
|
166
|
-
const close = `</${'scr'}ipt>`;
|
|
167
|
-
const baseTag = opts.baseHref ? `<base href="${opts.baseHref}">` : '';
|
|
168
|
-
const scriptTag = opts.bundleUrl
|
|
169
|
-
? `<script type="module" src="${opts.bundleUrl}">${close}`
|
|
170
|
-
: `<script type="module">${opts.inlineSrc ?? ''}${close}`;
|
|
171
|
-
const importmapTag = `<script type="importmap">${JSON.stringify({ imports })}${close}`;
|
|
172
|
-
const bodyHtml = opts.bodyHtml ?? '';
|
|
173
|
-
|
|
174
|
-
const doc = iframe.contentDocument!;
|
|
175
|
-
doc.open();
|
|
176
|
-
doc.write(
|
|
177
|
-
`<!doctype html><html><head><meta charset="utf-8">${baseTag}${importmapTag}</head><body>${bodyHtml}${scriptTag}</body></html>`,
|
|
178
|
-
);
|
|
179
|
-
doc.close();
|
|
180
|
-
|
|
181
|
-
let captured: CapturedRuntime2D | null = null;
|
|
182
|
-
try {
|
|
183
|
-
captured = await capture.waitForCapture(opts.captureTimeoutMs ?? 12_000);
|
|
184
|
-
} catch {
|
|
185
|
-
captured = null;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
iframe,
|
|
190
|
-
capture,
|
|
191
|
-
captured,
|
|
192
|
-
dispose: () => {
|
|
193
|
-
capture.uninstall();
|
|
194
|
-
restoreInit?.();
|
|
195
|
-
for (const u of created) URL.revokeObjectURL(u);
|
|
196
|
-
iframe.remove();
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export interface IframeReachableMount2D {
|
|
202
|
-
iframe: HTMLIFrameElement;
|
|
203
|
-
capture: SceneCapture2DHandle;
|
|
204
|
-
captured: CapturedRuntime2D | null;
|
|
205
|
-
dispose: () => void;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* IFRAME-REACHABLE (tier 2-3): run `gameModuleSrc` in an iframe whose importmap maps
|
|
210
|
-
* `pixi.js` to a host-pixi re-export blob, and trap the host `Application.prototype`
|
|
211
|
-
* so the bundle's render is captured in-realm.
|
|
212
|
-
*/
|
|
213
|
-
export async function mountIngestGame2DIframeReachable(
|
|
214
|
-
pixiNamespace: unknown,
|
|
215
|
-
gameModuleSrc: string,
|
|
216
|
-
container: HTMLElement,
|
|
217
|
-
opts: { captureTimeoutMs?: number } = {},
|
|
218
|
-
): Promise<IframeReachableMount2D> {
|
|
219
|
-
const capture = installSceneCapture2D(pixiNamespace);
|
|
220
|
-
const reexportUrl = makeHostPixiReexportUrl(pixiNamespace as Record<string, unknown>);
|
|
221
|
-
|
|
222
|
-
const iframe = document.createElement('iframe');
|
|
223
|
-
iframe.style.border = '0';
|
|
224
|
-
iframe.style.width = '100%';
|
|
225
|
-
iframe.style.height = '100%';
|
|
226
|
-
container.appendChild(iframe);
|
|
227
|
-
|
|
228
|
-
const doc = iframe.contentDocument!;
|
|
229
|
-
doc.open();
|
|
230
|
-
doc.write(
|
|
231
|
-
`<!doctype html><html><head><meta charset="utf-8">` +
|
|
232
|
-
`<script type="importmap">${JSON.stringify({ imports: { 'pixi.js': reexportUrl } })}</scr` +
|
|
233
|
-
`ipt></head><body><script type="module">${gameModuleSrc}</scr` +
|
|
234
|
-
`ipt></body></html>`,
|
|
235
|
-
);
|
|
236
|
-
doc.close();
|
|
237
|
-
|
|
238
|
-
let captured: CapturedRuntime2D | null = null;
|
|
239
|
-
try {
|
|
240
|
-
captured = await capture.waitForCapture(opts.captureTimeoutMs ?? 8000);
|
|
241
|
-
} catch {
|
|
242
|
-
captured = null;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
iframe,
|
|
247
|
-
capture,
|
|
248
|
-
captured,
|
|
249
|
-
dispose: () => {
|
|
250
|
-
capture.uninstall();
|
|
251
|
-
URL.revokeObjectURL(reexportUrl);
|
|
252
|
-
iframe.remove();
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import type { InstancesFile } from '../asset-formats/instances';
|
|
3
|
-
|
|
4
|
-
/** Build one native InstancedMesh from a parsed `.instances.json` tuple array. */
|
|
5
|
-
export function buildInstancedMeshFromTuples(
|
|
6
|
-
geometry: THREE.BufferGeometry,
|
|
7
|
-
material: THREE.Material,
|
|
8
|
-
tuples: InstancesFile,
|
|
9
|
-
): THREE.InstancedMesh {
|
|
10
|
-
const mesh = new THREE.InstancedMesh(geometry, material, tuples.length);
|
|
11
|
-
const position = new THREE.Vector3();
|
|
12
|
-
const quaternion = new THREE.Quaternion();
|
|
13
|
-
const scale = new THREE.Vector3();
|
|
14
|
-
const matrix = new THREE.Matrix4();
|
|
15
|
-
for (let index = 0; index < tuples.length; index += 1) {
|
|
16
|
-
const tuple = tuples[index]!;
|
|
17
|
-
position.set(tuple[0], tuple[1], tuple[2]);
|
|
18
|
-
quaternion.set(tuple[3], tuple[4], tuple[5], tuple[6]);
|
|
19
|
-
scale.set(tuple[7], tuple[8], tuple[9]);
|
|
20
|
-
matrix.compose(position, quaternion, scale);
|
|
21
|
-
mesh.setMatrixAt(index, matrix);
|
|
22
|
-
}
|
|
23
|
-
mesh.instanceMatrix.needsUpdate = true;
|
|
24
|
-
return mesh;
|
|
25
|
-
}
|