@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,34 +0,0 @@
|
|
|
1
|
-
import { AssetParseError } from '../asset-parse-error';
|
|
2
|
-
import { InstancesFileSchema } from './instances';
|
|
3
|
-
import { MaterialFileSchema } from './material';
|
|
4
|
-
// The error class itself is format-neutral and lives in
|
|
5
|
-
// `engine/src/asset-parse-error.ts` (the input-map loader raises it too).
|
|
6
|
-
// Re-exported here so callers have one import for parse + error.
|
|
7
|
-
export { AssetParseError };
|
|
8
|
-
/**
|
|
9
|
-
* Parse a `.mat.json` shared material asset (T4.6). There is no version-range
|
|
10
|
-
* gate for this format — `MaterialFileSchema`'s `version` field is RESERVED
|
|
11
|
-
* (see `schema-consumption-map.ts`).
|
|
12
|
-
*
|
|
13
|
-
* Formerly `@engine/scene/parse`'s `parseMaterialFile`; moved here when WO-8
|
|
14
|
-
* deleted the `.vscn` scene format that module was named for.
|
|
15
|
-
*/
|
|
16
|
-
export function parseMaterialFile(json, filePath) {
|
|
17
|
-
const result = MaterialFileSchema.safeParse(json);
|
|
18
|
-
if (!result.success) {
|
|
19
|
-
throw new AssetParseError(result.error.issues, filePath);
|
|
20
|
-
}
|
|
21
|
-
return result.data;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Parse a `.instances.json` instance-transform asset (F3). Mirrors
|
|
25
|
-
* `parseMaterialFile` exactly — no version-range gate (the format is a bare
|
|
26
|
-
* tuple array, no `version` field).
|
|
27
|
-
*/
|
|
28
|
-
export function parseInstancesFile(json, filePath) {
|
|
29
|
-
const result = InstancesFileSchema.safeParse(json);
|
|
30
|
-
if (!result.success) {
|
|
31
|
-
throw new AssetParseError(result.error.issues, filePath);
|
|
32
|
-
}
|
|
33
|
-
return result.data;
|
|
34
|
-
}
|
|
@@ -1,82 +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 { type CapturedRuntime2D, type SceneCapture2DHandle } from './scene-capture';
|
|
12
|
-
export interface EmbedMount2D {
|
|
13
|
-
iframe: HTMLIFrameElement;
|
|
14
|
-
dispose: () => void;
|
|
15
|
-
}
|
|
16
|
-
/** OPAQUE EMBED: sandboxed iframe, no scene introspection (tier 0-1). */
|
|
17
|
-
export declare function mountIngestGame2DEmbed(html: string, container: HTMLElement): EmbedMount2D;
|
|
18
|
-
export interface IframeReachableMultiOpts {
|
|
19
|
-
captureTimeoutMs?: number;
|
|
20
|
-
/**
|
|
21
|
-
* Bare-specifier → host module-namespace map. MUST include the pixi.js instance the trap is
|
|
22
|
-
* installed on (passed separately as `pixiNamespace`); list the game's OTHER shared bare deps
|
|
23
|
-
* here (@pixi/sound, @pixi/ui, gsap, pixi-filters) so they resolve to host instances and their
|
|
24
|
-
* extension side-effects register on the host pixi (the trapped instance).
|
|
25
|
-
*/
|
|
26
|
-
extraDeps?: Record<string, Record<string, unknown>>;
|
|
27
|
-
/**
|
|
28
|
-
* Bare-specifier -> VERBATIM URL importmap entries (the
|
|
29
|
-
* project-node_modules fallback for a specifier that isn't in the
|
|
30
|
-
* host-namespace registry but IS installed in the open project's own
|
|
31
|
-
* `node_modules`). Written into the importmap DIRECTLY alongside the
|
|
32
|
-
* `extraDeps` blob-namespace entries — no host-side import, no blob
|
|
33
|
-
* wrapping, no decision logic here: this function just merges whatever
|
|
34
|
-
* `Record<specifier, url>` the caller (editor-side
|
|
35
|
-
* `host-namespace-registry.ts`) already decided. The URL's own transitive
|
|
36
|
-
* `import 'pixi.js'` resolves through this SAME importmap back to the host
|
|
37
|
-
* pixi trap (§0.3), keeping module identity converged without a second pixi
|
|
38
|
-
* instance.
|
|
39
|
-
*/
|
|
40
|
-
extraDepUrls?: Record<string, string>;
|
|
41
|
-
/** <base href> for the iframe so the game's relative asset URLs (Assets basePath) resolve. */
|
|
42
|
-
baseHref?: string;
|
|
43
|
-
/**
|
|
44
|
-
* HOST-SIDE asset URL remap (the Pixi analog of the three.js DefaultLoadingManager.setURLModifier
|
|
45
|
-
* asset adapter). A document.write iframe keeps the PARENT's window.location, so PixiJS's Assets
|
|
46
|
-
* resolver (which builds absolute URLs from window.location, not document.baseURI) would resolve
|
|
47
|
-
* the game's relative `basePath:'assets'` against the parent page. Wrapping the host pixi's
|
|
48
|
-
* Assets.init to force this ABSOLUTE basePath fixes resolution without touching the game source —
|
|
49
|
-
* pure host library configuration, restored on dispose.
|
|
50
|
-
*/
|
|
51
|
-
assetBaseUrl?: string;
|
|
52
|
-
/** Load the game bundle from this absolute URL (a built multi-file game). */
|
|
53
|
-
bundleUrl?: string;
|
|
54
|
-
/** …or run this inline module source (a single-file game). One of bundleUrl/inlineSrc required. */
|
|
55
|
-
inlineSrc?: string;
|
|
56
|
-
/** DOM the game expects to find before it boots (e.g. a `<div id="game-root">` it appends to). */
|
|
57
|
-
bodyHtml?: string;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* IFRAME-REACHABLE for REAL MULTI-FILE GAMES (cov2d-bundled-dedupe): run a built game bundle
|
|
61
|
-
* (its OWN unaltered source, externalized against pixi at build time) in its own iframe realm
|
|
62
|
-
* whose importmap maps EVERY shared bare dep — pixi.js + @pixi/sound/@pixi/ui/gsap/… — to the
|
|
63
|
-
* HOST instances, and (optionally) a <base href> so its AssetPack/manifest URLs resolve. The
|
|
64
|
-
* host `Application.prototype.render` trap then captures the live stage IN-REALM. The game's
|
|
65
|
-
* source is never touched; all of this is host-side wiring.
|
|
66
|
-
*/
|
|
67
|
-
export declare function mountIngestGame2DIframeReachableMulti(pixiNamespace: unknown, container: HTMLElement, opts: IframeReachableMultiOpts): Promise<IframeReachableMount2D>;
|
|
68
|
-
export interface IframeReachableMount2D {
|
|
69
|
-
iframe: HTMLIFrameElement;
|
|
70
|
-
capture: SceneCapture2DHandle;
|
|
71
|
-
captured: CapturedRuntime2D | null;
|
|
72
|
-
dispose: () => void;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* IFRAME-REACHABLE (tier 2-3): run `gameModuleSrc` in an iframe whose importmap maps
|
|
76
|
-
* `pixi.js` to a host-pixi re-export blob, and trap the host `Application.prototype`
|
|
77
|
-
* so the bundle's render is captured in-realm.
|
|
78
|
-
*/
|
|
79
|
-
export declare function mountIngestGame2DIframeReachable(pixiNamespace: unknown, gameModuleSrc: string, container: HTMLElement, opts?: {
|
|
80
|
-
captureTimeoutMs?: number;
|
|
81
|
-
}): Promise<IframeReachableMount2D>;
|
|
82
|
-
//# sourceMappingURL=ingest-iframe.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ingest-iframe.d.ts","sourceRoot":"","sources":["../../src/pixi/ingest-iframe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,YAAY,CASzF;AAsCD,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,qCAAqC,CACzD,aAAa,EAAE,OAAO,EACtB,SAAS,EAAE,WAAW,EACtB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CA2EjC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,gCAAgC,CACpD,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,WAAW,EACtB,IAAI,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC,sBAAsB,CAAC,CAqCjC"}
|
|
@@ -1,166 +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 { installSceneCapture2D, } from './scene-capture';
|
|
12
|
-
/** OPAQUE EMBED: sandboxed iframe, no scene introspection (tier 0-1). */
|
|
13
|
-
export function mountIngestGame2DEmbed(html, container) {
|
|
14
|
-
const iframe = document.createElement('iframe');
|
|
15
|
-
iframe.setAttribute('sandbox', 'allow-scripts');
|
|
16
|
-
iframe.style.border = '0';
|
|
17
|
-
iframe.style.width = '100%';
|
|
18
|
-
iframe.style.height = '100%';
|
|
19
|
-
iframe.srcdoc = html;
|
|
20
|
-
container.appendChild(iframe);
|
|
21
|
-
return { iframe, dispose: () => iframe.remove() };
|
|
22
|
-
}
|
|
23
|
-
const HOST_PIXI_KEY = '__vgaiHostPixi';
|
|
24
|
-
/** Build a blob module that re-exports the host's pixi namespace (for the importmap). */
|
|
25
|
-
function makeHostPixiReexportUrl(pixiNamespace) {
|
|
26
|
-
window[HOST_PIXI_KEY] = pixiNamespace;
|
|
27
|
-
const ident = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
28
|
-
const keys = Object.keys(pixiNamespace).filter((k) => k !== 'default' && ident.test(k));
|
|
29
|
-
const body = `const T = window.parent[${JSON.stringify(HOST_PIXI_KEY)}];\n` +
|
|
30
|
-
`export default T;\n` +
|
|
31
|
-
keys.map((k) => `export const ${k} = T[${JSON.stringify(k)}];`).join('\n');
|
|
32
|
-
return URL.createObjectURL(new Blob([body], { type: 'text/javascript' }));
|
|
33
|
-
}
|
|
34
|
-
let _reexportKeySeq = 0;
|
|
35
|
-
/**
|
|
36
|
-
* Generalized host-namespace re-export (the multi-dep analog of {@link makeHostPixiReexportUrl}).
|
|
37
|
-
* Stashes `ns` (an ES module namespace object, e.g. `import * as ns from 'gsap'`) on a unique
|
|
38
|
-
* window key and builds a blob module re-exporting it, so the iframe's importmap can map a bare
|
|
39
|
-
* specifier (pixi.js, @pixi/sound, @pixi/ui, gsap, …) to the HOST's single instance. Default-export
|
|
40
|
-
* handling: `export default T.default ?? T` so `import gsap from 'gsap'` gets gsap, while a
|
|
41
|
-
* default-less namespace (pixi.js) re-exports the namespace itself for `import * as`.
|
|
42
|
-
*/
|
|
43
|
-
function makeHostNamespaceReexportUrl(ns) {
|
|
44
|
-
const key = `__vgaiHostNs_${_reexportKeySeq++}`;
|
|
45
|
-
window[key] = ns;
|
|
46
|
-
const ident = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
47
|
-
const keys = Object.keys(ns).filter((k) => k !== 'default' && ident.test(k));
|
|
48
|
-
const body = `const T = window.parent[${JSON.stringify(key)}];\n` +
|
|
49
|
-
`export default (T && T.default !== undefined ? T.default : T);\n` +
|
|
50
|
-
keys.map((k) => `export const ${k} = T[${JSON.stringify(k)}];`).join('\n');
|
|
51
|
-
return URL.createObjectURL(new Blob([body], { type: 'text/javascript' }));
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* IFRAME-REACHABLE for REAL MULTI-FILE GAMES (cov2d-bundled-dedupe): run a built game bundle
|
|
55
|
-
* (its OWN unaltered source, externalized against pixi at build time) in its own iframe realm
|
|
56
|
-
* whose importmap maps EVERY shared bare dep — pixi.js + @pixi/sound/@pixi/ui/gsap/… — to the
|
|
57
|
-
* HOST instances, and (optionally) a <base href> so its AssetPack/manifest URLs resolve. The
|
|
58
|
-
* host `Application.prototype.render` trap then captures the live stage IN-REALM. The game's
|
|
59
|
-
* source is never touched; all of this is host-side wiring.
|
|
60
|
-
*/
|
|
61
|
-
export async function mountIngestGame2DIframeReachableMulti(pixiNamespace, container, opts) {
|
|
62
|
-
const capture = installSceneCapture2D(pixiNamespace);
|
|
63
|
-
const created = [];
|
|
64
|
-
const mkUrl = (ns) => {
|
|
65
|
-
const u = makeHostNamespaceReexportUrl(ns);
|
|
66
|
-
created.push(u);
|
|
67
|
-
return u;
|
|
68
|
-
};
|
|
69
|
-
const imports = {
|
|
70
|
-
'pixi.js': mkUrl(pixiNamespace),
|
|
71
|
-
};
|
|
72
|
-
for (const [spec, ns] of Object.entries(opts.extraDeps ?? {}))
|
|
73
|
-
imports[spec] = mkUrl(ns);
|
|
74
|
-
// D-Z3 fallback: verbatim URL entries, no blob wrapping, merged in beside
|
|
75
|
-
// the host-namespace ones — decision-free (see `extraDepUrls`'s doc comment).
|
|
76
|
-
for (const [spec, url] of Object.entries(opts.extraDepUrls ?? {}))
|
|
77
|
-
imports[spec] = url;
|
|
78
|
-
// Host-side asset URL remap (asset adapter): force the game's Assets.init basePath to an
|
|
79
|
-
// absolute URL so its assets resolve to the served bundle dir, not the parent page path.
|
|
80
|
-
let restoreInit;
|
|
81
|
-
if (opts.assetBaseUrl) {
|
|
82
|
-
const assetsApi = pixiNamespace.Assets;
|
|
83
|
-
if (assetsApi?.init) {
|
|
84
|
-
const orig = assetsApi.init.bind(assetsApi);
|
|
85
|
-
assetsApi.init = (o = {}) => orig({ ...o, basePath: opts.assetBaseUrl });
|
|
86
|
-
restoreInit = () => {
|
|
87
|
-
assetsApi.init = orig;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const iframe = document.createElement('iframe');
|
|
92
|
-
iframe.style.border = '0';
|
|
93
|
-
iframe.style.width = '100%';
|
|
94
|
-
iframe.style.height = '100%';
|
|
95
|
-
container.appendChild(iframe);
|
|
96
|
-
// Split the closing script token so this module's own bundling never sees a literal
|
|
97
|
-
// </script> (defensive; matches the single-dep mount's convention).
|
|
98
|
-
const close = `</${'scr'}ipt>`;
|
|
99
|
-
const baseTag = opts.baseHref ? `<base href="${opts.baseHref}">` : '';
|
|
100
|
-
const scriptTag = opts.bundleUrl
|
|
101
|
-
? `<script type="module" src="${opts.bundleUrl}">${close}`
|
|
102
|
-
: `<script type="module">${opts.inlineSrc ?? ''}${close}`;
|
|
103
|
-
const importmapTag = `<script type="importmap">${JSON.stringify({ imports })}${close}`;
|
|
104
|
-
const bodyHtml = opts.bodyHtml ?? '';
|
|
105
|
-
const doc = iframe.contentDocument;
|
|
106
|
-
doc.open();
|
|
107
|
-
doc.write(`<!doctype html><html><head><meta charset="utf-8">${baseTag}${importmapTag}</head><body>${bodyHtml}${scriptTag}</body></html>`);
|
|
108
|
-
doc.close();
|
|
109
|
-
let captured = null;
|
|
110
|
-
try {
|
|
111
|
-
captured = await capture.waitForCapture(opts.captureTimeoutMs ?? 12_000);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
captured = null;
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
iframe,
|
|
118
|
-
capture,
|
|
119
|
-
captured,
|
|
120
|
-
dispose: () => {
|
|
121
|
-
capture.uninstall();
|
|
122
|
-
restoreInit?.();
|
|
123
|
-
for (const u of created)
|
|
124
|
-
URL.revokeObjectURL(u);
|
|
125
|
-
iframe.remove();
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* IFRAME-REACHABLE (tier 2-3): run `gameModuleSrc` in an iframe whose importmap maps
|
|
131
|
-
* `pixi.js` to a host-pixi re-export blob, and trap the host `Application.prototype`
|
|
132
|
-
* so the bundle's render is captured in-realm.
|
|
133
|
-
*/
|
|
134
|
-
export async function mountIngestGame2DIframeReachable(pixiNamespace, gameModuleSrc, container, opts = {}) {
|
|
135
|
-
const capture = installSceneCapture2D(pixiNamespace);
|
|
136
|
-
const reexportUrl = makeHostPixiReexportUrl(pixiNamespace);
|
|
137
|
-
const iframe = document.createElement('iframe');
|
|
138
|
-
iframe.style.border = '0';
|
|
139
|
-
iframe.style.width = '100%';
|
|
140
|
-
iframe.style.height = '100%';
|
|
141
|
-
container.appendChild(iframe);
|
|
142
|
-
const doc = iframe.contentDocument;
|
|
143
|
-
doc.open();
|
|
144
|
-
doc.write(`<!doctype html><html><head><meta charset="utf-8">` +
|
|
145
|
-
`<script type="importmap">${JSON.stringify({ imports: { 'pixi.js': reexportUrl } })}</scr` +
|
|
146
|
-
`ipt></head><body><script type="module">${gameModuleSrc}</scr` +
|
|
147
|
-
`ipt></body></html>`);
|
|
148
|
-
doc.close();
|
|
149
|
-
let captured = null;
|
|
150
|
-
try {
|
|
151
|
-
captured = await capture.waitForCapture(opts.captureTimeoutMs ?? 8000);
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
captured = null;
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
iframe,
|
|
158
|
-
capture,
|
|
159
|
-
captured,
|
|
160
|
-
dispose: () => {
|
|
161
|
-
capture.uninstall();
|
|
162
|
-
URL.revokeObjectURL(reexportUrl);
|
|
163
|
-
iframe.remove();
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import type { InstancesFile } from '../asset-formats/instances';
|
|
3
|
-
/** Build one native InstancedMesh from a parsed `.instances.json` tuple array. */
|
|
4
|
-
export declare function buildInstancedMeshFromTuples(geometry: THREE.BufferGeometry, material: THREE.Material, tuples: InstancesFile): THREE.InstancedMesh;
|
|
5
|
-
//# sourceMappingURL=instance-mesh.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"instance-mesh.d.ts","sourceRoot":"","sources":["../../src/render/instance-mesh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,kFAAkF;AAClF,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,MAAM,EAAE,aAAa,GACpB,KAAK,CAAC,aAAa,CAgBrB"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
/** Build one native InstancedMesh from a parsed `.instances.json` tuple array. */
|
|
3
|
-
export function buildInstancedMeshFromTuples(geometry, material, tuples) {
|
|
4
|
-
const mesh = new THREE.InstancedMesh(geometry, material, tuples.length);
|
|
5
|
-
const position = new THREE.Vector3();
|
|
6
|
-
const quaternion = new THREE.Quaternion();
|
|
7
|
-
const scale = new THREE.Vector3();
|
|
8
|
-
const matrix = new THREE.Matrix4();
|
|
9
|
-
for (let index = 0; index < tuples.length; index += 1) {
|
|
10
|
-
const tuple = tuples[index];
|
|
11
|
-
position.set(tuple[0], tuple[1], tuple[2]);
|
|
12
|
-
quaternion.set(tuple[3], tuple[4], tuple[5], tuple[6]);
|
|
13
|
-
scale.set(tuple[7], tuple[8], tuple[9]);
|
|
14
|
-
matrix.compose(position, quaternion, scale);
|
|
15
|
-
mesh.setMatrixAt(index, matrix);
|
|
16
|
-
}
|
|
17
|
-
mesh.instanceMatrix.needsUpdate = true;
|
|
18
|
-
return mesh;
|
|
19
|
-
}
|
package/schemas/mat.schema.json
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$comment": "AUTO-GENERATED by scripts/generate-schema.ts — do not edit manually",
|
|
3
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
-
"type": "object",
|
|
5
|
-
"properties": {
|
|
6
|
-
"version": {
|
|
7
|
-
"type": "number",
|
|
8
|
-
"description": "File format version"
|
|
9
|
-
},
|
|
10
|
-
"name": {
|
|
11
|
-
"type": "string",
|
|
12
|
-
"description": "Human-readable material name"
|
|
13
|
-
},
|
|
14
|
-
"material": {
|
|
15
|
-
"type": "object",
|
|
16
|
-
"properties": {
|
|
17
|
-
"type": {
|
|
18
|
-
"type": "string",
|
|
19
|
-
"enum": [
|
|
20
|
-
"standard",
|
|
21
|
-
"physical",
|
|
22
|
-
"basic",
|
|
23
|
-
"toon"
|
|
24
|
-
],
|
|
25
|
-
"description": "Material shading model"
|
|
26
|
-
},
|
|
27
|
-
"color": {
|
|
28
|
-
"description": "Base color as CSS hex string (e.g. \"#ff0000\")",
|
|
29
|
-
"type": "string"
|
|
30
|
-
},
|
|
31
|
-
"metalness": {
|
|
32
|
-
"description": "Metalness factor 0–1 (standard/physical only)",
|
|
33
|
-
"type": "number"
|
|
34
|
-
},
|
|
35
|
-
"roughness": {
|
|
36
|
-
"description": "Roughness factor 0–1 (standard/physical only)",
|
|
37
|
-
"type": "number"
|
|
38
|
-
},
|
|
39
|
-
"map": {
|
|
40
|
-
"description": "Path to albedo/diffuse texture image",
|
|
41
|
-
"type": "string"
|
|
42
|
-
},
|
|
43
|
-
"normalMap": {
|
|
44
|
-
"description": "Path to normal map texture image",
|
|
45
|
-
"type": "string"
|
|
46
|
-
},
|
|
47
|
-
"emissive": {
|
|
48
|
-
"description": "Emissive color as CSS hex string",
|
|
49
|
-
"type": "string"
|
|
50
|
-
},
|
|
51
|
-
"emissiveIntensity": {
|
|
52
|
-
"description": "Emissive light intensity multiplier",
|
|
53
|
-
"type": "number"
|
|
54
|
-
},
|
|
55
|
-
"emissiveMap": {
|
|
56
|
-
"description": "Path to emissive map texture image",
|
|
57
|
-
"type": "string"
|
|
58
|
-
},
|
|
59
|
-
"aoMap": {
|
|
60
|
-
"description": "Path to ambient occlusion map texture image",
|
|
61
|
-
"type": "string"
|
|
62
|
-
},
|
|
63
|
-
"lightMap": {
|
|
64
|
-
"description": "Path to a baked lightmap texture (uses the mesh's second UV set). Applies the pre-baked GI/shadow result on top of the material.",
|
|
65
|
-
"type": "string"
|
|
66
|
-
},
|
|
67
|
-
"lightMapIntensity": {
|
|
68
|
-
"description": "Lightmap intensity multiplier (default 1).",
|
|
69
|
-
"type": "number"
|
|
70
|
-
},
|
|
71
|
-
"roughnessMap": {
|
|
72
|
-
"description": "Path to roughness map texture image",
|
|
73
|
-
"type": "string"
|
|
74
|
-
},
|
|
75
|
-
"metalnessMap": {
|
|
76
|
-
"description": "Path to metalness map texture image",
|
|
77
|
-
"type": "string"
|
|
78
|
-
},
|
|
79
|
-
"opacity": {
|
|
80
|
-
"description": "Opacity 0–1. Set transparent: true to enable",
|
|
81
|
-
"type": "number"
|
|
82
|
-
},
|
|
83
|
-
"transparent": {
|
|
84
|
-
"description": "Enable alpha blending for this material",
|
|
85
|
-
"type": "boolean"
|
|
86
|
-
},
|
|
87
|
-
"side": {
|
|
88
|
-
"description": "Which face sides to render",
|
|
89
|
-
"type": "string",
|
|
90
|
-
"enum": [
|
|
91
|
-
"front",
|
|
92
|
-
"back",
|
|
93
|
-
"double"
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
"flatShading": {
|
|
97
|
-
"description": "Use flat (faceted) shading instead of smooth",
|
|
98
|
-
"type": "boolean"
|
|
99
|
-
},
|
|
100
|
-
"clearcoat": {
|
|
101
|
-
"description": "Clearcoat layer (physical only)",
|
|
102
|
-
"type": "object",
|
|
103
|
-
"properties": {
|
|
104
|
-
"clearcoat": {
|
|
105
|
-
"type": "number",
|
|
106
|
-
"description": "Clearcoat layer intensity 0–1"
|
|
107
|
-
},
|
|
108
|
-
"clearcoatRoughness": {
|
|
109
|
-
"description": "Clearcoat roughness 0–1",
|
|
110
|
-
"type": "number"
|
|
111
|
-
},
|
|
112
|
-
"clearcoatMap": {
|
|
113
|
-
"description": "Path to clearcoat intensity map",
|
|
114
|
-
"type": "string"
|
|
115
|
-
},
|
|
116
|
-
"clearcoatRoughnessMap": {
|
|
117
|
-
"description": "Path to clearcoat roughness map",
|
|
118
|
-
"type": "string"
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
"required": [
|
|
122
|
-
"clearcoat"
|
|
123
|
-
],
|
|
124
|
-
"additionalProperties": false
|
|
125
|
-
},
|
|
126
|
-
"transmission": {
|
|
127
|
-
"description": "Light transmission (physical only)",
|
|
128
|
-
"type": "object",
|
|
129
|
-
"properties": {
|
|
130
|
-
"transmission": {
|
|
131
|
-
"type": "number",
|
|
132
|
-
"description": "Transmission intensity 0–1 (glass, liquid)"
|
|
133
|
-
},
|
|
134
|
-
"ior": {
|
|
135
|
-
"description": "Index of refraction (default 1.5)",
|
|
136
|
-
"type": "number"
|
|
137
|
-
},
|
|
138
|
-
"thickness": {
|
|
139
|
-
"description": "Volume thickness for refraction",
|
|
140
|
-
"type": "number"
|
|
141
|
-
},
|
|
142
|
-
"attenuationColor": {
|
|
143
|
-
"description": "Color absorbed over distance",
|
|
144
|
-
"type": "string"
|
|
145
|
-
},
|
|
146
|
-
"attenuationDistance": {
|
|
147
|
-
"description": "Distance at which attenuation color takes full effect",
|
|
148
|
-
"type": "number"
|
|
149
|
-
},
|
|
150
|
-
"transmissionMap": {
|
|
151
|
-
"description": "Path to transmission map",
|
|
152
|
-
"type": "string"
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
"required": [
|
|
156
|
-
"transmission"
|
|
157
|
-
],
|
|
158
|
-
"additionalProperties": false
|
|
159
|
-
},
|
|
160
|
-
"sheen": {
|
|
161
|
-
"description": "Sheen layer (physical only)",
|
|
162
|
-
"type": "object",
|
|
163
|
-
"properties": {
|
|
164
|
-
"sheen": {
|
|
165
|
-
"type": "number",
|
|
166
|
-
"description": "Sheen intensity 0–1 (fabric, velvet)"
|
|
167
|
-
},
|
|
168
|
-
"sheenColor": {
|
|
169
|
-
"description": "Sheen tint color",
|
|
170
|
-
"type": "string"
|
|
171
|
-
},
|
|
172
|
-
"sheenRoughness": {
|
|
173
|
-
"description": "Sheen roughness 0–1",
|
|
174
|
-
"type": "number"
|
|
175
|
-
},
|
|
176
|
-
"sheenColorMap": {
|
|
177
|
-
"description": "Path to sheen color map",
|
|
178
|
-
"type": "string"
|
|
179
|
-
},
|
|
180
|
-
"sheenRoughnessMap": {
|
|
181
|
-
"description": "Path to sheen roughness map",
|
|
182
|
-
"type": "string"
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
"required": [
|
|
186
|
-
"sheen"
|
|
187
|
-
],
|
|
188
|
-
"additionalProperties": false
|
|
189
|
-
},
|
|
190
|
-
"iridescence": {
|
|
191
|
-
"description": "Iridescence thin-film (physical only)",
|
|
192
|
-
"type": "object",
|
|
193
|
-
"properties": {
|
|
194
|
-
"iridescence": {
|
|
195
|
-
"type": "number",
|
|
196
|
-
"description": "Iridescence intensity 0–1 (soap bubbles, oil slick)"
|
|
197
|
-
},
|
|
198
|
-
"iridescenceIOR": {
|
|
199
|
-
"description": "Thin-film IOR (default 1.3)",
|
|
200
|
-
"type": "number"
|
|
201
|
-
},
|
|
202
|
-
"iridescenceThicknessRange": {
|
|
203
|
-
"description": "Min/max thin-film thickness in nm",
|
|
204
|
-
"type": "array",
|
|
205
|
-
"prefixItems": [
|
|
206
|
-
{
|
|
207
|
-
"type": "number"
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
"type": "number"
|
|
211
|
-
}
|
|
212
|
-
]
|
|
213
|
-
},
|
|
214
|
-
"iridescenceMap": {
|
|
215
|
-
"description": "Path to iridescence intensity map",
|
|
216
|
-
"type": "string"
|
|
217
|
-
},
|
|
218
|
-
"iridescenceThicknessMap": {
|
|
219
|
-
"description": "Path to iridescence thickness map",
|
|
220
|
-
"type": "string"
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
"required": [
|
|
224
|
-
"iridescence"
|
|
225
|
-
],
|
|
226
|
-
"additionalProperties": false
|
|
227
|
-
},
|
|
228
|
-
"displacementMap": {
|
|
229
|
-
"description": "Path to displacement/height map",
|
|
230
|
-
"type": "string"
|
|
231
|
-
},
|
|
232
|
-
"displacementScale": {
|
|
233
|
-
"description": "Displacement height multiplier",
|
|
234
|
-
"type": "number"
|
|
235
|
-
},
|
|
236
|
-
"displacementBias": {
|
|
237
|
-
"description": "Displacement offset",
|
|
238
|
-
"type": "number"
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
"required": [
|
|
242
|
-
"type"
|
|
243
|
-
],
|
|
244
|
-
"additionalProperties": false,
|
|
245
|
-
"description": "Material definition"
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
"required": [
|
|
249
|
-
"version",
|
|
250
|
-
"name",
|
|
251
|
-
"material"
|
|
252
|
-
],
|
|
253
|
-
"additionalProperties": false,
|
|
254
|
-
"description": "Shared material asset file (.mat.json)"
|
|
255
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* `.instances.json` — a declarative, authored-data instance-transform asset
|
|
5
|
-
* (F3). Referenced by `mesh.instances` as a bare array of 10-number tuples,
|
|
6
|
-
* one per instance, each `[posX,posY,posZ, quatX,quatY,quatZ,quatW,
|
|
7
|
-
* scaleX,scaleY,scaleZ]`. The scene loader fetches+parses this file and
|
|
8
|
-
* renders it as one `THREE.InstancedMesh` (one draw call) — bulk transform
|
|
9
|
-
* data is referenced as an asset, never inlined into the referencing
|
|
10
|
-
* document (gate G4).
|
|
11
|
-
*
|
|
12
|
-
* WO-8: the document that referenced it was `.vscn.json`, and that format is
|
|
13
|
-
* deleted. `.instances.json` survives as a FETCHED-ASSET format with its own
|
|
14
|
-
* `parseInstancesFile` — nothing in the shipped tree references one today.
|
|
15
|
-
*/
|
|
16
|
-
export const InstancesFileSchema = z
|
|
17
|
-
.array(
|
|
18
|
-
z.tuple([
|
|
19
|
-
z.number().describe('posX'),
|
|
20
|
-
z.number().describe('posY'),
|
|
21
|
-
z.number().describe('posZ'),
|
|
22
|
-
z.number().describe('quatX'),
|
|
23
|
-
z.number().describe('quatY'),
|
|
24
|
-
z.number().describe('quatZ'),
|
|
25
|
-
z.number().describe('quatW'),
|
|
26
|
-
z.number().describe('scaleX'),
|
|
27
|
-
z.number().describe('scaleY'),
|
|
28
|
-
z.number().describe('scaleZ'),
|
|
29
|
-
]),
|
|
30
|
-
)
|
|
31
|
-
.describe(
|
|
32
|
-
'Instance-transform asset (.instances.json): an array of 10-number tuples ' +
|
|
33
|
-
'[posX,posY,posZ, quatX,quatY,quatZ,quatW, scaleX,scaleY,scaleZ], one per instance. ' +
|
|
34
|
-
'Referenced by a mesh via `mesh.instances` and rendered as a single THREE.InstancedMesh ' +
|
|
35
|
-
'(one draw call).',
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
export type InstancesFile = z.infer<typeof InstancesFileSchema>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { AssetParseError } from '../asset-parse-error';
|
|
2
|
-
import type { InstancesFile } from './instances';
|
|
3
|
-
import { InstancesFileSchema } from './instances';
|
|
4
|
-
import type { MaterialFile } from './material';
|
|
5
|
-
import { MaterialFileSchema } from './material';
|
|
6
|
-
|
|
7
|
-
// The error class itself is format-neutral and lives in
|
|
8
|
-
// `engine/src/asset-parse-error.ts` (the input-map loader raises it too).
|
|
9
|
-
// Re-exported here so callers have one import for parse + error.
|
|
10
|
-
export { AssetParseError };
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Parse a `.mat.json` shared material asset (T4.6). There is no version-range
|
|
14
|
-
* gate for this format — `MaterialFileSchema`'s `version` field is RESERVED
|
|
15
|
-
* (see `schema-consumption-map.ts`).
|
|
16
|
-
*
|
|
17
|
-
* Formerly `@engine/scene/parse`'s `parseMaterialFile`; moved here when WO-8
|
|
18
|
-
* deleted the `.vscn` scene format that module was named for.
|
|
19
|
-
*/
|
|
20
|
-
export function parseMaterialFile(json: unknown, filePath?: string): MaterialFile {
|
|
21
|
-
const result = MaterialFileSchema.safeParse(json);
|
|
22
|
-
if (!result.success) {
|
|
23
|
-
throw new AssetParseError(result.error.issues, filePath);
|
|
24
|
-
}
|
|
25
|
-
return result.data;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parse a `.instances.json` instance-transform asset (F3). Mirrors
|
|
30
|
-
* `parseMaterialFile` exactly — no version-range gate (the format is a bare
|
|
31
|
-
* tuple array, no `version` field).
|
|
32
|
-
*/
|
|
33
|
-
export function parseInstancesFile(json: unknown, filePath?: string): InstancesFile {
|
|
34
|
-
const result = InstancesFileSchema.safeParse(json);
|
|
35
|
-
if (!result.success) {
|
|
36
|
-
throw new AssetParseError(result.error.issues, filePath);
|
|
37
|
-
}
|
|
38
|
-
return result.data;
|
|
39
|
-
}
|