@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
|
@@ -69,6 +69,8 @@ export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
|
69
69
|
const REAL = Symbol('vgai.realRender');
|
|
70
70
|
let captured = null;
|
|
71
71
|
let drawCount = 0;
|
|
72
|
+
/** Set post-capture by the host; see {@link SceneCaptureHandle.setRenderPassHooks}. */
|
|
73
|
+
let renderPassHooks = null;
|
|
72
74
|
const waiters = [];
|
|
73
75
|
// Preserve any descriptor already on the prototype so uninstall can restore it.
|
|
74
76
|
const priorDescriptor = Object.getOwnPropertyDescriptor(proto, 'render');
|
|
@@ -101,6 +103,26 @@ export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
|
101
103
|
};
|
|
102
104
|
},
|
|
103
105
|
});
|
|
106
|
+
/**
|
|
107
|
+
* Call the renderer's own real `render`, bracketed by the render-pass hooks
|
|
108
|
+
* when this IS the captured game's renderer (see `setRenderPassHooks`).
|
|
109
|
+
* `after` runs in a `finally`, so a throwing game frame still restores
|
|
110
|
+
* whatever the hook armed.
|
|
111
|
+
*/
|
|
112
|
+
function forwardRender(self, args) {
|
|
113
|
+
const real = self[REAL];
|
|
114
|
+
const hooks = renderPassHooks;
|
|
115
|
+
if (hooks === null || !captured || self !== captured.renderer) {
|
|
116
|
+
return real.apply(self, args);
|
|
117
|
+
}
|
|
118
|
+
hooks.before();
|
|
119
|
+
try {
|
|
120
|
+
return real.apply(self, args);
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
hooks.after();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
104
126
|
Object.defineProperty(proto, 'render', {
|
|
105
127
|
configurable: true,
|
|
106
128
|
set(fn) {
|
|
@@ -123,13 +145,11 @@ export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
|
123
145
|
drawCount++;
|
|
124
146
|
// Never capture a scene the HOST owns. The trap sits on the shared
|
|
125
147
|
// `WebGLRenderer.prototype`, so the editor's own viewport renders
|
|
126
|
-
// arrive here too — and when a game bundles its own MISMATCHED three
|
|
127
|
-
//
|
|
128
|
-
// editor's scene is then the only thing that ever reaches the trap.
|
|
148
|
+
// arrive here too — and when a game bundles its own MISMATCHED three,
|
|
149
|
+
// the editor's scene is then the only thing that ever reaches the trap.
|
|
129
150
|
// It was duly "captured" as the game: the editor got a hierarchy of
|
|
130
151
|
// its own GridHelper, BatchedRenderer and viewport lights presented as
|
|
131
|
-
// the ingested game's content, and
|
|
132
|
-
// whole graceful-degradation contract is built on — never fired.
|
|
152
|
+
// the ingested game's content, and the mount reported success.
|
|
133
153
|
// Whether that happened at all came down to whether the editor
|
|
134
154
|
// rendered a frame inside the game's capture window, so the same
|
|
135
155
|
// session could pass or fail on timing alone.
|
|
@@ -143,8 +163,7 @@ export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
|
143
163
|
for (const resolve of waiters.splice(0))
|
|
144
164
|
resolve(captured);
|
|
145
165
|
}
|
|
146
|
-
|
|
147
|
-
return self[REAL].apply(self, args);
|
|
166
|
+
return forwardRender(self, args);
|
|
148
167
|
};
|
|
149
168
|
},
|
|
150
169
|
});
|
|
@@ -189,6 +208,9 @@ export function installSceneCapture(threeNamespace, effectComposerCtor, opts) {
|
|
|
189
208
|
getDrawCount() {
|
|
190
209
|
return drawCount;
|
|
191
210
|
},
|
|
211
|
+
setRenderPassHooks(hooks) {
|
|
212
|
+
renderPassHooks = hooks;
|
|
213
|
+
},
|
|
192
214
|
getAnimationLoop(renderer) {
|
|
193
215
|
return loopCallbacks.get(renderer) ?? null;
|
|
194
216
|
},
|
|
@@ -45,7 +45,7 @@ export interface StructuralIdWalk {
|
|
|
45
45
|
* tree re-binds the same ids to the same objects.
|
|
46
46
|
*
|
|
47
47
|
* EDITOR FURNITURE IS EXCLUDED, and that exclusion is load-bearing rather than
|
|
48
|
-
* cosmetic.
|
|
48
|
+
* cosmetic. On an ingest root the editor adds its grid, lights, particle
|
|
49
49
|
* BatchedRenderer and TransformControls gizmo to the GAME'S OWN scene, and
|
|
50
50
|
* they arrive asynchronously — some before the walk, some after. Indexing them
|
|
51
51
|
* made a game object's path depend on how much editor furniture happened to be
|
|
@@ -25,7 +25,7 @@ export const CAMERA_ID = 'ingest:camera';
|
|
|
25
25
|
* The editor parks its OWN objects — grid, its two lights, the particle
|
|
26
26
|
* BatchedRenderer, every TransformControls/gizmo helper — on layer 31
|
|
27
27
|
* (`packages/editor/src/editor-layers.ts`'s `EDITOR_LAYER`) so the game camera
|
|
28
|
-
* never sees them.
|
|
28
|
+
* never sees them. On an ingest root those objects are added to the GAME'S OWN
|
|
29
29
|
* scene, which is the same tree this walk indexes.
|
|
30
30
|
*/
|
|
31
31
|
const EDITOR_ONLY_LAYER_MASK = 1 << 31;
|
|
@@ -60,7 +60,7 @@ export function colorMaterialOf(o) {
|
|
|
60
60
|
* tree re-binds the same ids to the same objects.
|
|
61
61
|
*
|
|
62
62
|
* EDITOR FURNITURE IS EXCLUDED, and that exclusion is load-bearing rather than
|
|
63
|
-
* cosmetic.
|
|
63
|
+
* cosmetic. On an ingest root the editor adds its grid, lights, particle
|
|
64
64
|
* BatchedRenderer and TransformControls gizmo to the GAME'S OWN scene, and
|
|
65
65
|
* they arrive asynchronously — some before the walk, some after. Indexing them
|
|
66
66
|
* made a game object's path depend on how much editor furniture happened to be
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format-neutral live reflection-probe mark.
|
|
3
|
+
*
|
|
4
|
+
* A project-owned scene component writes this mark onto the Object3D it
|
|
5
|
+
* returns. The renderer capability owns capture and material integration; the
|
|
6
|
+
* editor only reads the mark to draw ordinary probe gizmos and expose the
|
|
7
|
+
* capture command/status. Authored truth remains the component's JSX props —
|
|
8
|
+
* this is a live adapter seam, not another document format.
|
|
9
|
+
*/
|
|
10
|
+
import type * as THREE from 'three';
|
|
11
|
+
export type ReflectionProbeShape = 'box' | 'sphere';
|
|
12
|
+
export type ReflectionProbeCaptureMode = 'on-change' | 'manual' | 'realtime';
|
|
13
|
+
export type ReflectionProbeCaptureStatus = 'idle' | 'queued' | 'capturing' | 'ready' | 'error';
|
|
14
|
+
export interface ReflectionProbeConfig {
|
|
15
|
+
readonly shape: ReflectionProbeShape;
|
|
16
|
+
/** Full local-space box dimensions. */
|
|
17
|
+
readonly size: readonly [number, number, number];
|
|
18
|
+
/** Local-space sphere radius when `shape === 'sphere'`. */
|
|
19
|
+
readonly radius: number;
|
|
20
|
+
/** Local-space distance over which this probe fades at its boundary. */
|
|
21
|
+
readonly blendDistance: number;
|
|
22
|
+
/** Larger values win before equal-priority probes blend. */
|
|
23
|
+
readonly priority: number;
|
|
24
|
+
readonly intensity: number;
|
|
25
|
+
readonly parallaxProjection: boolean;
|
|
26
|
+
/** Full local-space projection-box dimensions. */
|
|
27
|
+
readonly parallaxSize: readonly [number, number, number];
|
|
28
|
+
readonly parallaxOffset: readonly [number, number, number];
|
|
29
|
+
readonly captureOffset: readonly [number, number, number];
|
|
30
|
+
readonly captureMode: ReflectionProbeCaptureMode;
|
|
31
|
+
readonly resolution: number;
|
|
32
|
+
readonly near: number;
|
|
33
|
+
readonly far: number;
|
|
34
|
+
readonly cullMask: number;
|
|
35
|
+
readonly captureShadows: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ReflectionProbeSnapshot {
|
|
38
|
+
readonly status: ReflectionProbeCaptureStatus;
|
|
39
|
+
/** Monotonic browser time from `performance.now()`, or null before capture. */
|
|
40
|
+
readonly lastCapturedAt: number | null;
|
|
41
|
+
readonly message?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ReflectionProbeMark {
|
|
44
|
+
readonly config: ReflectionProbeConfig;
|
|
45
|
+
readonly revision: number;
|
|
46
|
+
recapture(): void;
|
|
47
|
+
getSnapshot(): ReflectionProbeSnapshot;
|
|
48
|
+
subscribe(listener: () => void): () => void;
|
|
49
|
+
}
|
|
50
|
+
export declare function reflectionProbeOf(object: THREE.Object3D | null | undefined): ReflectionProbeMark | null;
|
|
51
|
+
export declare function setReflectionProbeMark(object: THREE.Object3D, mark: ReflectionProbeMark): void;
|
|
52
|
+
export declare function clearReflectionProbeMark(object: THREE.Object3D): void;
|
|
53
|
+
//# sourceMappingURL=reflection-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection-probe.d.ts","sourceRoot":"","sources":["../../src/adapter/reflection-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAGpC,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,QAAQ,CAAC;AACpD,MAAM,MAAM,0BAA0B,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC7E,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;IACrC,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,kDAAkD;IAClD,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3D,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,4BAA4B,CAAC;IAC9C,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,SAAS,IAAI,IAAI,CAAC;IAClB,WAAW,IAAI,uBAAuB,CAAC;IACvC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7C;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,GAAG,SAAS,GACxC,mBAAmB,GAAG,IAAI,CAS5B;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAE9F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAErE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { deleteUserData, getUserData, setUserData } from '../ecs/user-data';
|
|
2
|
+
export function reflectionProbeOf(object) {
|
|
3
|
+
const candidate = getUserData(object, 'reflectionProbe');
|
|
4
|
+
if (!candidate || typeof candidate !== 'object')
|
|
5
|
+
return null;
|
|
6
|
+
const mark = candidate;
|
|
7
|
+
return mark.config &&
|
|
8
|
+
typeof mark.recapture === 'function' &&
|
|
9
|
+
typeof mark.getSnapshot === 'function'
|
|
10
|
+
? candidate
|
|
11
|
+
: null;
|
|
12
|
+
}
|
|
13
|
+
export function setReflectionProbeMark(object, mark) {
|
|
14
|
+
setUserData(object, 'reflectionProbe', mark);
|
|
15
|
+
}
|
|
16
|
+
export function clearReflectionProbeMark(object) {
|
|
17
|
+
deleteUserData(object, 'reflectionProbe');
|
|
18
|
+
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The engine's
|
|
2
|
+
* The engine's runtime descriptor schemas.
|
|
3
3
|
*
|
|
4
4
|
* WO-8 deleted the `.vscn.json` scene format and everything under
|
|
5
5
|
* `engine/src/scene/`. What survived is here, and each module is here because a
|
|
6
6
|
* real runtime reader still consumes it:
|
|
7
7
|
*
|
|
8
|
-
* - `material.ts` — the
|
|
9
|
-
* plus the inline material descriptor `render/material-factory.ts` reads
|
|
10
|
-
* - `instances.ts` — the `.instances.json` transform format (`parseInstancesFile`),
|
|
11
|
-
* read by `render/instance-mesh.ts`
|
|
8
|
+
* - `material.ts` — the inline material descriptor `render/material-factory.ts` reads
|
|
12
9
|
* - `mesh.ts` — the geometry descriptor `render/material-factory.ts`'s `createGeometry` reads
|
|
13
10
|
* - `light.ts` / `camera.ts` — the descriptors `render/light-camera-factory.ts` reads
|
|
14
11
|
* - `collider.ts` — the descriptor `physics/collider-dimensions.ts` and the editor's
|
|
@@ -28,15 +25,12 @@ export type { CameraDescriptor } from './camera';
|
|
|
28
25
|
export { CameraDescriptorSchema } from './camera';
|
|
29
26
|
export type { ColliderDescriptor } from './collider';
|
|
30
27
|
export { ColliderDescriptorSchema } from './collider';
|
|
31
|
-
export type { InstancesFile } from './instances';
|
|
32
|
-
export { InstancesFileSchema } from './instances';
|
|
33
28
|
export type { LightDescriptor } from './light';
|
|
34
29
|
export { LightDescriptorSchema } from './light';
|
|
35
|
-
export type { MaterialDescriptor
|
|
36
|
-
export { MaterialDescriptorSchema
|
|
30
|
+
export type { MaterialDescriptor } from './material';
|
|
31
|
+
export { MaterialDescriptorSchema } from './material';
|
|
37
32
|
export type { MeshDescriptor } from './mesh';
|
|
38
33
|
export { MeshDescriptorSchema } from './mesh';
|
|
39
|
-
export { parseInstancesFile, parseMaterialFile } from './parse';
|
|
40
34
|
export type { ParticlesDescriptor } from './particles';
|
|
41
35
|
export { ParticlesDescriptorSchema } from './particles';
|
|
42
36
|
export type { PostProcessingDescriptor, RenderEnvironment, ToneMappingDescriptor, } from './render-env';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/asset-formats/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/asset-formats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EACV,wBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The engine's
|
|
2
|
+
* The engine's runtime descriptor schemas.
|
|
3
3
|
*
|
|
4
4
|
* WO-8 deleted the `.vscn.json` scene format and everything under
|
|
5
5
|
* `engine/src/scene/`. What survived is here, and each module is here because a
|
|
6
6
|
* real runtime reader still consumes it:
|
|
7
7
|
*
|
|
8
|
-
* - `material.ts` — the
|
|
9
|
-
* plus the inline material descriptor `render/material-factory.ts` reads
|
|
10
|
-
* - `instances.ts` — the `.instances.json` transform format (`parseInstancesFile`),
|
|
11
|
-
* read by `render/instance-mesh.ts`
|
|
8
|
+
* - `material.ts` — the inline material descriptor `render/material-factory.ts` reads
|
|
12
9
|
* - `mesh.ts` — the geometry descriptor `render/material-factory.ts`'s `createGeometry` reads
|
|
13
10
|
* - `light.ts` / `camera.ts` — the descriptors `render/light-camera-factory.ts` reads
|
|
14
11
|
* - `collider.ts` — the descriptor `physics/collider-dimensions.ts` and the editor's
|
|
@@ -26,11 +23,9 @@
|
|
|
26
23
|
*/
|
|
27
24
|
export { CameraDescriptorSchema } from './camera';
|
|
28
25
|
export { ColliderDescriptorSchema } from './collider';
|
|
29
|
-
export { InstancesFileSchema } from './instances';
|
|
30
26
|
export { LightDescriptorSchema } from './light';
|
|
31
|
-
export { MaterialDescriptorSchema
|
|
27
|
+
export { MaterialDescriptorSchema } from './material';
|
|
32
28
|
export { MeshDescriptorSchema } from './mesh';
|
|
33
|
-
export { parseInstancesFile, parseMaterialFile } from './parse';
|
|
34
29
|
export { ParticlesDescriptorSchema } from './particles';
|
|
35
30
|
export { PostProcessingDescriptorSchema, RenderEnvironmentSchema, ToneMappingDescriptorSchema, } from './render-env';
|
|
36
31
|
export { QuatSchema, TransformSchema, Vec3Schema } from './tuples';
|
|
@@ -60,70 +60,4 @@ export declare const MaterialDescriptorSchema: z.ZodObject<{
|
|
|
60
60
|
displacementBias: z.ZodOptional<z.ZodNumber>;
|
|
61
61
|
}, z.core.$strict>;
|
|
62
62
|
export type MaterialDescriptor = z.infer<typeof MaterialDescriptorSchema>;
|
|
63
|
-
/** .mat.json file format for shared/reusable material assets. */
|
|
64
|
-
export declare const MaterialFileSchema: z.ZodObject<{
|
|
65
|
-
version: z.ZodNumber;
|
|
66
|
-
name: z.ZodString;
|
|
67
|
-
material: z.ZodObject<{
|
|
68
|
-
type: z.ZodEnum<{
|
|
69
|
-
standard: "standard";
|
|
70
|
-
physical: "physical";
|
|
71
|
-
basic: "basic";
|
|
72
|
-
toon: "toon";
|
|
73
|
-
}>;
|
|
74
|
-
color: z.ZodOptional<z.ZodString>;
|
|
75
|
-
metalness: z.ZodOptional<z.ZodNumber>;
|
|
76
|
-
roughness: z.ZodOptional<z.ZodNumber>;
|
|
77
|
-
map: z.ZodOptional<z.ZodString>;
|
|
78
|
-
normalMap: z.ZodOptional<z.ZodString>;
|
|
79
|
-
emissive: z.ZodOptional<z.ZodString>;
|
|
80
|
-
emissiveIntensity: z.ZodOptional<z.ZodNumber>;
|
|
81
|
-
emissiveMap: z.ZodOptional<z.ZodString>;
|
|
82
|
-
aoMap: z.ZodOptional<z.ZodString>;
|
|
83
|
-
lightMap: z.ZodOptional<z.ZodString>;
|
|
84
|
-
lightMapIntensity: z.ZodOptional<z.ZodNumber>;
|
|
85
|
-
roughnessMap: z.ZodOptional<z.ZodString>;
|
|
86
|
-
metalnessMap: z.ZodOptional<z.ZodString>;
|
|
87
|
-
opacity: z.ZodOptional<z.ZodNumber>;
|
|
88
|
-
transparent: z.ZodOptional<z.ZodBoolean>;
|
|
89
|
-
side: z.ZodOptional<z.ZodEnum<{
|
|
90
|
-
front: "front";
|
|
91
|
-
back: "back";
|
|
92
|
-
double: "double";
|
|
93
|
-
}>>;
|
|
94
|
-
flatShading: z.ZodOptional<z.ZodBoolean>;
|
|
95
|
-
clearcoat: z.ZodOptional<z.ZodObject<{
|
|
96
|
-
clearcoat: z.ZodNumber;
|
|
97
|
-
clearcoatRoughness: z.ZodOptional<z.ZodNumber>;
|
|
98
|
-
clearcoatMap: z.ZodOptional<z.ZodString>;
|
|
99
|
-
clearcoatRoughnessMap: z.ZodOptional<z.ZodString>;
|
|
100
|
-
}, z.core.$strip>>;
|
|
101
|
-
transmission: z.ZodOptional<z.ZodObject<{
|
|
102
|
-
transmission: z.ZodNumber;
|
|
103
|
-
ior: z.ZodOptional<z.ZodNumber>;
|
|
104
|
-
thickness: z.ZodOptional<z.ZodNumber>;
|
|
105
|
-
attenuationColor: z.ZodOptional<z.ZodString>;
|
|
106
|
-
attenuationDistance: z.ZodOptional<z.ZodNumber>;
|
|
107
|
-
transmissionMap: z.ZodOptional<z.ZodString>;
|
|
108
|
-
}, z.core.$strip>>;
|
|
109
|
-
sheen: z.ZodOptional<z.ZodObject<{
|
|
110
|
-
sheen: z.ZodNumber;
|
|
111
|
-
sheenColor: z.ZodOptional<z.ZodString>;
|
|
112
|
-
sheenRoughness: z.ZodOptional<z.ZodNumber>;
|
|
113
|
-
sheenColorMap: z.ZodOptional<z.ZodString>;
|
|
114
|
-
sheenRoughnessMap: z.ZodOptional<z.ZodString>;
|
|
115
|
-
}, z.core.$strip>>;
|
|
116
|
-
iridescence: z.ZodOptional<z.ZodObject<{
|
|
117
|
-
iridescence: z.ZodNumber;
|
|
118
|
-
iridescenceIOR: z.ZodOptional<z.ZodNumber>;
|
|
119
|
-
iridescenceThicknessRange: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
120
|
-
iridescenceMap: z.ZodOptional<z.ZodString>;
|
|
121
|
-
iridescenceThicknessMap: z.ZodOptional<z.ZodString>;
|
|
122
|
-
}, z.core.$strip>>;
|
|
123
|
-
displacementMap: z.ZodOptional<z.ZodString>;
|
|
124
|
-
displacementScale: z.ZodOptional<z.ZodNumber>;
|
|
125
|
-
displacementBias: z.ZodOptional<z.ZodNumber>;
|
|
126
|
-
}, z.core.$strict>;
|
|
127
|
-
}, z.core.$strip>;
|
|
128
|
-
export type MaterialFile = z.infer<typeof MaterialFileSchema>;
|
|
129
63
|
//# sourceMappingURL=material.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/asset-formats/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwFxB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAEpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/asset-formats/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwFxB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAEpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -78,11 +78,3 @@ const MaterialDescriptorObjectSchema = z
|
|
|
78
78
|
})
|
|
79
79
|
.strict();
|
|
80
80
|
export const MaterialDescriptorSchema = MaterialDescriptorObjectSchema.describe('Material appearance properties');
|
|
81
|
-
/** .mat.json file format for shared/reusable material assets. */
|
|
82
|
-
export const MaterialFileSchema = z
|
|
83
|
-
.object({
|
|
84
|
-
version: z.number().describe('File format version'),
|
|
85
|
-
name: z.string().describe('Human-readable material name'),
|
|
86
|
-
material: MaterialDescriptorSchema.describe('Material definition'),
|
|
87
|
-
})
|
|
88
|
-
.describe('Shared material asset file (.mat.json)');
|
|
@@ -2,8 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
export declare const MeshDescriptorSchema: z.ZodObject<{
|
|
3
3
|
type: z.ZodEnum<{
|
|
4
4
|
box: "box";
|
|
5
|
-
capsule: "capsule";
|
|
6
5
|
sphere: "sphere";
|
|
6
|
+
capsule: "capsule";
|
|
7
7
|
plane: "plane";
|
|
8
8
|
cylinder: "cylinder";
|
|
9
9
|
gltf: "gltf";
|
|
@@ -12,7 +12,6 @@ export declare const MeshDescriptorSchema: z.ZodObject<{
|
|
|
12
12
|
args: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
13
13
|
src: z.ZodOptional<z.ZodString>;
|
|
14
14
|
node: z.ZodOptional<z.ZodString>;
|
|
15
|
-
instances: z.ZodOptional<z.ZodString>;
|
|
16
15
|
lod: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
17
16
|
distance: z.ZodNumber;
|
|
18
17
|
node: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/asset-formats/mesh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/asset-formats/mesh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2DxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;kBAgBM,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -21,13 +21,6 @@ const MeshDescriptorBase = z
|
|
|
21
21
|
'Only meaningful with type: "gltf". CONSTRAINT: a skinned/animated node cannot be ' +
|
|
22
22
|
'lifted out of its armature — if the named node is a SkinnedMesh (or contains one), ' +
|
|
23
23
|
'resolving it throws (degrade loudly, not silently).'),
|
|
24
|
-
instances: z
|
|
25
|
-
.string()
|
|
26
|
-
.optional()
|
|
27
|
-
.describe('Path to an instance-transform asset (.instances.json: an array of ' +
|
|
28
|
-
'[posX,posY,posZ, quatX,quatY,quatZ,quatW, scaleX,scaleY,scaleZ] tuples). Renders one ' +
|
|
29
|
-
'THREE.InstancedMesh (one draw call). Bulk transform data is referenced as an asset, ' +
|
|
30
|
-
'never inlined — keeps the document thin.'),
|
|
31
24
|
lod: z
|
|
32
25
|
.array(z.object({
|
|
33
26
|
distance: z
|
|
@@ -43,7 +36,7 @@ const MeshDescriptorBase = z
|
|
|
43
36
|
.optional()
|
|
44
37
|
.describe('Per-entity Level-of-Detail: distance-keyed glTF sub-nodes swapped by camera distance ' +
|
|
45
38
|
'(THREE.LOD). gltf-only. Gated by the environment.rendering.lod master toggle — when ' +
|
|
46
|
-
'off, only the closest level renders. Cannot combine with node
|
|
39
|
+
'off, only the closest level renders. Cannot combine with node.'),
|
|
47
40
|
})
|
|
48
41
|
.strict();
|
|
49
42
|
export const MeshDescriptorSchema = MeshDescriptorBase.refine((m) => (m.type !== 'gltf' && m.type !== 'splat') || m.src != null, {
|
|
@@ -55,10 +48,7 @@ export const MeshDescriptorSchema = MeshDescriptorBase.refine((m) => (m.type !==
|
|
|
55
48
|
.refine((m) => m.lod == null || m.type === 'gltf', {
|
|
56
49
|
message: "Mesh 'lod' is only meaningful with type: 'gltf'",
|
|
57
50
|
})
|
|
58
|
-
.refine((m) => m.
|
|
59
|
-
message: "Mesh '
|
|
60
|
-
})
|
|
61
|
-
.refine((m) => !(m.lod && (m.node || m.instances)), {
|
|
62
|
-
message: "Mesh 'lod' cannot combine with 'node'/'instances' — LOD is the multi-level form of a node ref",
|
|
51
|
+
.refine((m) => !(m.lod && m.node), {
|
|
52
|
+
message: "Mesh 'lod' cannot combine with 'node' — LOD is the multi-level form of a node ref",
|
|
63
53
|
})
|
|
64
54
|
.describe('Mesh geometry definition');
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
export declare const ToneMappingDescriptorSchema: z.ZodObject<{
|
|
14
14
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
15
|
-
aces: "aces";
|
|
16
15
|
none: "none";
|
|
17
16
|
linear: "linear";
|
|
17
|
+
aces: "aces";
|
|
18
18
|
reinhard: "reinhard";
|
|
19
19
|
cineon: "cineon";
|
|
20
20
|
agx: "agx";
|
|
@@ -199,9 +199,9 @@ export type PostProcessingDescriptor = z.infer<typeof PostProcessingDescriptorSc
|
|
|
199
199
|
export declare const RenderEnvironmentSchema: z.ZodObject<{
|
|
200
200
|
toneMapping: z.ZodOptional<z.ZodObject<{
|
|
201
201
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
202
|
-
aces: "aces";
|
|
203
202
|
none: "none";
|
|
204
203
|
linear: "linear";
|
|
204
|
+
aces: "aces";
|
|
205
205
|
reinhard: "reinhard";
|
|
206
206
|
cineon: "cineon";
|
|
207
207
|
agx: "agx";
|
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* Every authored asset format the engine validates at fetch time throws this
|
|
5
5
|
* when Zod rejects the payload, naming the offending file (T4.6). It lives
|
|
6
6
|
* here — beside `loader.ts`/`assets.ts` — rather than inside a format module so
|
|
7
|
-
* every caller (
|
|
8
|
-
*
|
|
9
|
-
* it.
|
|
7
|
+
* every caller (currently the input-map loader in `input/input-manager.ts`)
|
|
8
|
+
* does not have to reach into an unrelated subsystem for it.
|
|
10
9
|
*
|
|
11
10
|
* It was called `SceneParseError` until WO-9 task #6. The extraction that gave
|
|
12
11
|
* this file its name deliberately deferred the class rename ("extraction, not
|
|
13
|
-
* redesign"); with `.vscn` gone the old name described nothing —
|
|
14
|
-
*
|
|
12
|
+
* redesign"); with `.vscn` gone the old name described nothing — an
|
|
13
|
+
* `.inputmap.json` failure is not a scene failure — so the class and its
|
|
15
14
|
* message header now say `asset`.
|
|
16
15
|
*/
|
|
17
16
|
import type { ZodIssue } from 'zod';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-parse-error.d.ts","sourceRoot":"","sources":["../src/asset-parse-error.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"asset-parse-error.d.ts","sourceRoot":"","sources":["../src/asset-parse-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE3B,MAAM,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM;CAQlD"}
|
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* Every authored asset format the engine validates at fetch time throws this
|
|
5
5
|
* when Zod rejects the payload, naming the offending file (T4.6). It lives
|
|
6
6
|
* here — beside `loader.ts`/`assets.ts` — rather than inside a format module so
|
|
7
|
-
* every caller (
|
|
8
|
-
*
|
|
9
|
-
* it.
|
|
7
|
+
* every caller (currently the input-map loader in `input/input-manager.ts`)
|
|
8
|
+
* does not have to reach into an unrelated subsystem for it.
|
|
10
9
|
*
|
|
11
10
|
* It was called `SceneParseError` until WO-9 task #6. The extraction that gave
|
|
12
11
|
* this file its name deliberately deferred the class rename ("extraction, not
|
|
13
|
-
* redesign"); with `.vscn` gone the old name described nothing —
|
|
14
|
-
*
|
|
12
|
+
* redesign"); with `.vscn` gone the old name described nothing — an
|
|
13
|
+
* `.inputmap.json` failure is not a scene failure — so the class and its
|
|
15
14
|
* message header now say `asset`.
|
|
16
15
|
*/
|
|
17
16
|
export class AssetParseError extends Error {
|
package/dist/config.d.ts
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
* evaluated. The package build emits this entry as ordinary JavaScript, so
|
|
4
4
|
* project config remains package-native without asking Node to execute raw
|
|
5
5
|
* TypeScript or reach into an adjacent checkout.
|
|
6
|
+
*
|
|
7
|
+
* A project's `*.schema.ts` is reached from `vite.config.ts` itself (through
|
|
8
|
+
* `./src/data/assets`, so the dangling-ref gate can run the real Zod), which
|
|
9
|
+
* is why every schema-time field factory belongs here: `dataRef` and `curve`
|
|
10
|
+
* are both authored in a schema, and a schema module must stay loadable by
|
|
11
|
+
* plain Node.
|
|
6
12
|
*/
|
|
13
|
+
export { type CurveAxes, type CurvePoint, type CurveValue, curve, sampleCurve, } from './data/curve';
|
|
7
14
|
export { type DataRef, dataRef, getRef } from './data/data-ref';
|
|
8
15
|
export { type VgaiDataCheckOptions, vgaiDataCheck } from './data/vite-plugin-data';
|
|
9
16
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,EACL,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* evaluated. The package build emits this entry as ordinary JavaScript, so
|
|
4
4
|
* project config remains package-native without asking Node to execute raw
|
|
5
5
|
* TypeScript or reach into an adjacent checkout.
|
|
6
|
+
*
|
|
7
|
+
* A project's `*.schema.ts` is reached from `vite.config.ts` itself (through
|
|
8
|
+
* `./src/data/assets`, so the dangling-ref gate can run the real Zod), which
|
|
9
|
+
* is why every schema-time field factory belongs here: `dataRef` and `curve`
|
|
10
|
+
* are both authored in a schema, and a schema module must stay loadable by
|
|
11
|
+
* plain Node.
|
|
6
12
|
*/
|
|
13
|
+
export { curve, sampleCurve, } from './data/curve';
|
|
7
14
|
export { dataRef, getRef } from './data/data-ref';
|
|
8
15
|
export { vgaiDataCheck } from './data/vite-plugin-data';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curve FIELDS in data assets — a response curve a designer shapes, living
|
|
3
|
+
* inside an ordinary `.data.json` like any other tunable value.
|
|
4
|
+
*
|
|
5
|
+
* A curve is a FIELD TYPE, never a file type: there is no `.curve.json`, no
|
|
6
|
+
* curve asset class, no baked LUT, and no document. `curve(axes)` is a real
|
|
7
|
+
* Zod schema you drop into a `*.schema.ts` beside `z.number()`, so the value
|
|
8
|
+
* lives in the same data file, hot-swaps through the same `defineData` handle,
|
|
9
|
+
* and is edited by the same Data panel that edits everything else.
|
|
10
|
+
*
|
|
11
|
+
* The JSON a designer (or an agent) reads and writes:
|
|
12
|
+
*
|
|
13
|
+
* ```json
|
|
14
|
+
* { "interpolation": "smooth",
|
|
15
|
+
* "points": [{ "x": 0, "y": 1 }, { "x": 12, "y": 0.85 }, { "x": 30, "y": 0.2 }] }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* TWO MODES, NO TANGENTS. `linear` and `smooth`, and nothing else. Per-key
|
|
19
|
+
* tangent handles would double the JSON, make it unreadable to an agent, and
|
|
20
|
+
* hand every author a way to make a curve overshoot its own points. Smoothness
|
|
21
|
+
* is DERIVED instead — Fritsch–Carlson monotone cubic tangents, computed from
|
|
22
|
+
* the points themselves — so the interpolant is guaranteed to stay inside each
|
|
23
|
+
* segment's `[yLeft, yRight]` band. "Shape it by moving points" is the whole
|
|
24
|
+
* authoring model.
|
|
25
|
+
*
|
|
26
|
+
* RUNG AUDIT (recorded decision, 2026-08-14): no npm dependency. The candidate
|
|
27
|
+
* packages (`monotone-cubic-spline` and its siblings) are unmaintained
|
|
28
|
+
* micro-packages, and d3's `curveMonotoneX` is an SVG PATH GENERATOR — it
|
|
29
|
+
* draws, it does not sample `y` at an `x`. What we need is ~40 lines of
|
|
30
|
+
* well-known numerics with no API surface, so it is written here.
|
|
31
|
+
*
|
|
32
|
+
* `sampleCurve` is the entire runtime: a pure function, no class, no cache
|
|
33
|
+
* object, no "curve system". Game code calls it every frame from its own
|
|
34
|
+
* update, the same way it reads any other tuning value.
|
|
35
|
+
*/
|
|
36
|
+
import { z } from 'zod';
|
|
37
|
+
/** One authored key: a `y` value at an `x` position. No tangents — see above. */
|
|
38
|
+
export interface CurvePoint {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
}
|
|
42
|
+
/** A curve field's value, exactly as it sits in the `.data.json`. */
|
|
43
|
+
export interface CurveValue {
|
|
44
|
+
interpolation: 'linear' | 'smooth';
|
|
45
|
+
points: CurvePoint[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The curve's DOMAIN, declared by the engineer in the schema (never by the
|
|
49
|
+
* data): what the axes mean and how far they run. The editor draws its rails
|
|
50
|
+
* from this and clamps every drag to it; the schema rejects a point outside
|
|
51
|
+
* it.
|
|
52
|
+
*/
|
|
53
|
+
export interface CurveAxes {
|
|
54
|
+
x: {
|
|
55
|
+
min: number;
|
|
56
|
+
max: number;
|
|
57
|
+
label?: string;
|
|
58
|
+
};
|
|
59
|
+
y: {
|
|
60
|
+
min: number;
|
|
61
|
+
max: number;
|
|
62
|
+
label?: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A Zod schema for a data-asset FIELD holding a response curve. Use it in a
|
|
67
|
+
* `.schema.ts` exactly like any other field:
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* export const TuningSchema = z.object({
|
|
71
|
+
* spawnRate: z.number().min(0).max(10).default(1),
|
|
72
|
+
* difficultyRamp: curve({
|
|
73
|
+
* x: { min: 0, max: 300, label: 'Sim time (s)' },
|
|
74
|
+
* y: { min: 0, max: 2, label: 'Spawn multiplier' },
|
|
75
|
+
* }).describe('How hard the game leans on the player as the round runs.'),
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* The schema is STRICT (an unrecognized key is an error, never a silent
|
|
80
|
+
* strip), demands at least two points, and enforces strictly-increasing `x`
|
|
81
|
+
* with every point inside the declared axes — each with a message that names
|
|
82
|
+
* the fix rather than the rule.
|
|
83
|
+
*
|
|
84
|
+
* The emitted JSON Schema (`toDataJsonSchema`) carries
|
|
85
|
+
* `"x-vgai-curve": axes` — a Zod `.meta()`, which survives `z.toJSONSchema`
|
|
86
|
+
* including inside a table's `additionalProperties` row schema, exactly the
|
|
87
|
+
* way `dataRef`'s `"x-vgai-ref"` does. That marker is what makes the editor's
|
|
88
|
+
* Data panel render a curve EDITOR instead of a raw-JSON cell, with no emitter
|
|
89
|
+
* changes anywhere.
|
|
90
|
+
*/
|
|
91
|
+
export declare function curve(axes: CurveAxes): z.ZodType<CurveValue>;
|
|
92
|
+
/**
|
|
93
|
+
* Read a curve field's declared axes back off a LIVE Zod schema (as opposed to
|
|
94
|
+
* the emitted JSON Schema, which the editor's Data panel reads instead).
|
|
95
|
+
*
|
|
96
|
+
* This is the dev-menu capability's detection door: it derives its rows by
|
|
97
|
+
* walking the game's own `TuningSchema` object, so it needs the axes from the
|
|
98
|
+
* schema in hand. Wrappers (`.optional()`, `.default(…)`, `.describe(…)` chains
|
|
99
|
+
* that re-wrap) hide the metadata behind an inner type, so a bounded unwrap
|
|
100
|
+
* walks down to it.
|
|
101
|
+
*/
|
|
102
|
+
export declare function curveAxesOf(schema: z.ZodType): CurveAxes | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* The curve's value at `x` — the whole runtime API.
|
|
105
|
+
*
|
|
106
|
+
* Read it every frame from the game's own update, the way every other data
|
|
107
|
+
* value is read (`tuning.get()` then sample); never precompute a table, and
|
|
108
|
+
* never hold the result across frames — an edit to the `.data.json` hot-swaps
|
|
109
|
+
* underneath you and that is the point.
|
|
110
|
+
*
|
|
111
|
+
* Outside `[first.x, last.x]` the value CLAMPS to the nearest endpoint: a
|
|
112
|
+
* curve declares what it knows about, and extrapolating past it would invent
|
|
113
|
+
* numbers nobody authored.
|
|
114
|
+
*/
|
|
115
|
+
export declare function sampleCurve(value: CurveValue, x: number): number;
|
|
116
|
+
//# sourceMappingURL=curve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curve.d.ts","sourceRoot":"","sources":["../../src/data/curve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACnC,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD;AA0CD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAwB5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,SAAS,CASpE;AAoDD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BhE"}
|