@forgeax/engine-assets-runtime 0.1.6 → 0.1.19
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 +11 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/asset-registry.d.ts +2 -0
- package/dist/asset-registry.d.ts.map +1 -1
- package/dist/handles.d.ts +2 -0
- package/dist/handles.d.ts.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +62 -9
- package/dist/index.mjs.map +1 -1
- package/dist/mipmap-generator.d.ts +3 -1
- package/dist/mipmap-generator.d.ts.map +1 -1
- package/dist/registry/instantiate.d.ts +2 -0
- package/dist/registry/instantiate.d.ts.map +1 -1
- package/dist/registry/validate-material.d.ts +1 -0
- package/dist/registry/validate-material.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/__tests__/catalog-replica.unit.test.ts +36 -0
- package/src/__tests__/inline-pack-loaders.unit.test.ts +37 -0
- package/src/__tests__/instantiate-publication-fence.unit.test.ts +59 -1
- package/src/__tests__/material-ready.integration.test.ts +87 -6
- package/src/__tests__/material-stale-generation.unit.test.ts +1 -6
- package/src/__tests__/resolve-asset-handle.unit.test.ts +1 -1
- package/src/__tests__/scriptable-pack-public-surface.test-d.ts +11 -0
- package/src/__tests__/validate-material.unit.test.ts +46 -1
- package/src/asset-registry.ts +5 -0
- package/src/handles.ts +7 -1
- package/src/index.ts +17 -3
- package/src/material/inspection.ts +1 -1
- package/src/material/loader.ts +9 -9
- package/src/material/runtime-shader.ts +1 -1
- package/src/mipmap-generator.ts +43 -1
- package/src/registry/instantiate.ts +14 -4
- package/src/registry/load-by-guid.ts +1 -1
- package/src/registry/validate-material.ts +96 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Result, RhiError } from '@forgeax/engine-rhi';
|
|
1
|
+
import { type Result, RhiError, type RhiRenderPassEncoder } from '@forgeax/engine-rhi';
|
|
2
2
|
/**
|
|
3
3
|
* Subset of `RhiDevice` consumed by the mipmap utility (charter F2: only
|
|
4
4
|
* the methods the algorithm actually invokes; the dawn integration tests
|
|
@@ -129,4 +129,6 @@ export declare function blitMipmapsSync(device: MipmapBlitDevice, texture: any,
|
|
|
129
129
|
readonly height: number;
|
|
130
130
|
readonly levels?: number;
|
|
131
131
|
}): Result<void, RhiError>;
|
|
132
|
+
/** Encode one prewarmed mip level into a caller-owned graph render pass. */
|
|
133
|
+
export declare function encodeMipmapLevel(device: MipmapBlitDevice, pass: RhiRenderPassEncoder, sourceView: unknown, format: GPUTextureFormat): Result<void, RhiError>;
|
|
132
134
|
//# sourceMappingURL=mipmap-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mipmap-generator.d.ts","sourceRoot":"","sources":["../src/mipmap-generator.ts"],"names":[],"mappings":"AA+CA,OAAO,EAAW,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"mipmap-generator.d.ts","sourceRoot":"","sources":["../src/mipmap-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,8 @@ import { type ScenePublicationFence, type ScenePublicationFenceError } from './s
|
|
|
12
12
|
export interface SkinJointResolver {
|
|
13
13
|
resolveSkinAsset(skeletonHandleRaw: number): SkinAsset | undefined;
|
|
14
14
|
}
|
|
15
|
+
/** Derive a publication fence from the registry's unified live projections. */
|
|
16
|
+
export declare function scenePublicationFenceFromRegistry(registry: AssetRegistry, outputGuid: string): Result<ScenePublicationFence, ScenePublicationFenceError>;
|
|
15
17
|
/**
|
|
16
18
|
* Post-spawn hook contract (D-1). A hook runs after instantiate spawns the
|
|
17
19
|
* scene subtree; the shipped implementation is runtime's `postSpawnResolveJoints`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instantiate.d.ts","sourceRoot":"","sources":["../../src/registry/instantiate.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAO3D,OAAO,EACL,KAAK,KAAK,EAEV,UAAU,EAEV,KAAK,MAAM,EAGX,KAAK,UAAU,EACf,KAAK,kBAAkB,EAEvB,KAAK,SAAS,EACd,KAAK,KAAK,EAEX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAEhC,MAAM,2BAA2B,CAAC;AAEnC;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;CACpE;
|
|
1
|
+
{"version":3,"file":"instantiate.d.ts","sourceRoot":"","sources":["../../src/registry/instantiate.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import type { AssetRegistry } from '../asset-registry';
|
|
|
15
15
|
* @returns AssetError on failure, null on success
|
|
16
16
|
*/
|
|
17
17
|
export declare function validateMaterialPasses(registry: AssetRegistry, asset: MaterialAsset): AssetError | null;
|
|
18
|
+
export declare function validateMaterialTransmissionContract(asset: MaterialAsset): MaterialError | null;
|
|
18
19
|
export interface MaterialEffectiveRootIdentity {
|
|
19
20
|
readonly guid: string;
|
|
20
21
|
readonly layoutIdentity: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-material.d.ts","sourceRoot":"","sources":["../../src/registry/validate-material.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,UAAU,EAEV,KAAK,aAAa,EAClB,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,aAAa,GACnB,UAAU,GAAG,IAAI,CAoFnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC,EACtD,IAAI,EAAE,6BAA6B,GAClC,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"validate-material.d.ts","sourceRoot":"","sources":["../../src/registry/validate-material.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,UAAU,EAEV,KAAK,aAAa,EAClB,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,aAAa,GACnB,UAAU,GAAG,IAAI,CAoFnB;AA4CD,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAkD/F;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC,EACtD,IAAI,EAAE,6BAA6B,GAClC,aAAa,GAAG,IAAI,CAiBtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,GACnB,UAAU,GAAG,IAAI,CA8GnB;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,OAAO,CAgCT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CA8BhG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,MAAM,GACf,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAIjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-assets-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -26,22 +26,22 @@
|
|
|
26
26
|
"LICENSE"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@forgeax/engine-codec": "0.1.
|
|
30
|
-
"@forgeax/engine-ecs": "0.1.
|
|
31
|
-
"@forgeax/engine-geometry": "0.1.
|
|
32
|
-
"@forgeax/engine-graphics-extras": "0.1.
|
|
33
|
-
"@forgeax/engine-image": "0.1.
|
|
34
|
-
"@forgeax/engine-pack": "0.1.
|
|
35
|
-
"@forgeax/engine-plugin": "0.1.
|
|
36
|
-
"@forgeax/engine-rhi": "0.1.
|
|
37
|
-
"@forgeax/engine-scene": "0.1.
|
|
38
|
-
"@forgeax/engine-shader": "0.1.
|
|
39
|
-
"@forgeax/engine-types": "0.1.
|
|
40
|
-
"@forgeax/engine-ui": "0.1.
|
|
29
|
+
"@forgeax/engine-codec": "0.1.19",
|
|
30
|
+
"@forgeax/engine-ecs": "0.1.19",
|
|
31
|
+
"@forgeax/engine-geometry": "0.1.19",
|
|
32
|
+
"@forgeax/engine-graphics-extras": "0.1.19",
|
|
33
|
+
"@forgeax/engine-image": "0.1.19",
|
|
34
|
+
"@forgeax/engine-pack": "0.1.19",
|
|
35
|
+
"@forgeax/engine-plugin": "0.1.19",
|
|
36
|
+
"@forgeax/engine-rhi": "0.1.19",
|
|
37
|
+
"@forgeax/engine-scene": "0.1.19",
|
|
38
|
+
"@forgeax/engine-shader": "0.1.19",
|
|
39
|
+
"@forgeax/engine-types": "0.1.19",
|
|
40
|
+
"@forgeax/engine-ui": "0.1.19",
|
|
41
41
|
"@webgpu/types": "^0.1.71"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@forgeax/engine-skinning": "0.1.
|
|
44
|
+
"@forgeax/engine-skinning": "0.1.19",
|
|
45
45
|
"@webgpu/types": "^0.1.71"
|
|
46
46
|
},
|
|
47
47
|
"forgeax": {
|
|
@@ -193,4 +193,40 @@ describe('CatalogReplica', () => {
|
|
|
193
193
|
diagnostics: [{ code: 'catalog-revision-conflict', severity: 'blocking' }],
|
|
194
194
|
});
|
|
195
195
|
});
|
|
196
|
+
|
|
197
|
+
it('applies a failed lifecycle projection when the producer advances its observation revision', async () => {
|
|
198
|
+
const fixture = source();
|
|
199
|
+
const replica = new CatalogReplica(fixture.source as never);
|
|
200
|
+
await replica.start();
|
|
201
|
+
|
|
202
|
+
fixture.emit({
|
|
203
|
+
added: [],
|
|
204
|
+
changed: [
|
|
205
|
+
{
|
|
206
|
+
...base,
|
|
207
|
+
lifecycle: 'failed',
|
|
208
|
+
revision: {
|
|
209
|
+
digest: 'failure:source-package-ddc-failed:sha256:old',
|
|
210
|
+
observedAt: 2,
|
|
211
|
+
rootId: base.revision.rootId,
|
|
212
|
+
},
|
|
213
|
+
diagnostics: [
|
|
214
|
+
{
|
|
215
|
+
code: 'source-package-ddc-failed',
|
|
216
|
+
severity: 'blocking',
|
|
217
|
+
hint: 'repair and retry',
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
removed: [],
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
expect(replica.snapshot().entries[0]).toMatchObject({
|
|
226
|
+
guid: base.guid,
|
|
227
|
+
lifecycle: 'failed',
|
|
228
|
+
revision: { observedAt: 2 },
|
|
229
|
+
});
|
|
230
|
+
expect(replica.snapshot().stale).toBe(false);
|
|
231
|
+
});
|
|
196
232
|
});
|
|
@@ -279,6 +279,43 @@ describe('materialLoader', () => {
|
|
|
279
279
|
});
|
|
280
280
|
});
|
|
281
281
|
|
|
282
|
+
it('resolves transmission and thickness texture refs through authored contract', () => {
|
|
283
|
+
const out = materialLoader.load(
|
|
284
|
+
{
|
|
285
|
+
passes: [{ name: 'Forward', program: { module: 'forgeax::default-standard-pbr' } }],
|
|
286
|
+
parameters: [
|
|
287
|
+
{ name: 'transmissionTexture', type: 'texture' },
|
|
288
|
+
{ name: 'thicknessTexture', type: 'texture' },
|
|
289
|
+
],
|
|
290
|
+
values: {
|
|
291
|
+
transmission: 0.8,
|
|
292
|
+
ior: 1.45,
|
|
293
|
+
thickness: 0.25,
|
|
294
|
+
transmissionTexture: { texture: 0, sampler: 1, coordinates: { set: 2 } },
|
|
295
|
+
thicknessTexture: { texture: 2, sampler: 3, coordinates: { set: 3 } },
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
['texture-transmission', 'sampler-linear', 'texture-thickness', 'sampler-nearest'],
|
|
299
|
+
emptyCtx,
|
|
300
|
+
) as MaterialAsset;
|
|
301
|
+
|
|
302
|
+
expect(out.values).toMatchObject({
|
|
303
|
+
transmission: 0.8,
|
|
304
|
+
ior: 1.45,
|
|
305
|
+
thickness: 0.25,
|
|
306
|
+
transmissionTexture: {
|
|
307
|
+
texture: 'texture-transmission',
|
|
308
|
+
sampler: 'sampler-linear',
|
|
309
|
+
coordinates: { set: 2 },
|
|
310
|
+
},
|
|
311
|
+
thicknessTexture: {
|
|
312
|
+
texture: 'texture-thickness',
|
|
313
|
+
sampler: 'sampler-nearest',
|
|
314
|
+
coordinates: { set: 3 },
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
282
319
|
it('resolves nested texture values when the shader schema is present but empty', () => {
|
|
283
320
|
const out = materialLoader.load(
|
|
284
321
|
{
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@forgeax/engine-types';
|
|
7
7
|
import { describe, expect, it } from 'vitest';
|
|
8
8
|
import type { AssetRegistry } from '../asset-registry';
|
|
9
|
-
import { resolveMountsRec } from '../registry/instantiate';
|
|
9
|
+
import { resolveMountsRec, scenePublicationFenceFromRegistry } from '../registry/instantiate';
|
|
10
10
|
import { createScenePublicationFence } from '../registry/scene-publication-fence';
|
|
11
11
|
|
|
12
12
|
const SCENE_GUID = '019ffdb4-1000-7000-8000-000000000008';
|
|
@@ -155,4 +155,62 @@ describe('resolveMountsRec publication fence identity', () => {
|
|
|
155
155
|
);
|
|
156
156
|
expect(result).toMatchObject({ ok: true, value: [{ source: 6 }] });
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
it('prefers the complete pack-index tuple during a CatalogReplica handoff', () => {
|
|
160
|
+
const world = new World();
|
|
161
|
+
const currentSourcePath = 'assets/current.glb';
|
|
162
|
+
const currentPublication = {
|
|
163
|
+
...publication(),
|
|
164
|
+
sourcePath: currentSourcePath,
|
|
165
|
+
receipt: { ...publication().receipt, sourcePath: currentSourcePath },
|
|
166
|
+
};
|
|
167
|
+
const fence = createScenePublicationFence(currentPublication);
|
|
168
|
+
expect(fence.ok).toBe(true);
|
|
169
|
+
if (!fence.ok) return;
|
|
170
|
+
const registry = {
|
|
171
|
+
assetCatalog: new Map(),
|
|
172
|
+
// The replica may still expose the prior complete tuple while the
|
|
173
|
+
// latest pack-index has already been hydrated after a source write.
|
|
174
|
+
catalogSnapshot: () => ({
|
|
175
|
+
entries: [
|
|
176
|
+
{
|
|
177
|
+
guid: SCENE_GUID,
|
|
178
|
+
kind: 'scene',
|
|
179
|
+
sourcePath: publication().sourcePath,
|
|
180
|
+
packageUrl: '/assets/scene.pack.json',
|
|
181
|
+
publication: publication(),
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
}),
|
|
185
|
+
packIndexCache: new Map([
|
|
186
|
+
[
|
|
187
|
+
SCENE_GUID,
|
|
188
|
+
{
|
|
189
|
+
guid: SCENE_GUID,
|
|
190
|
+
kind: 'scene',
|
|
191
|
+
sourcePath: currentSourcePath,
|
|
192
|
+
packageUrl: '/assets/current.pack.json',
|
|
193
|
+
publication: currentPublication,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
]),
|
|
197
|
+
_guidForAsset: () => undefined,
|
|
198
|
+
} as unknown as AssetRegistry;
|
|
199
|
+
const result = resolveMountsRec(
|
|
200
|
+
registry,
|
|
201
|
+
[
|
|
202
|
+
{
|
|
203
|
+
localId: 0 as never,
|
|
204
|
+
source: 6,
|
|
205
|
+
memberFirst: 0 as never,
|
|
206
|
+
memberCount: 0,
|
|
207
|
+
publicationFence: fence.value,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
world,
|
|
211
|
+
new Set(),
|
|
212
|
+
);
|
|
213
|
+
expect(result).toMatchObject({ ok: true, value: [{ source: 6 }] });
|
|
214
|
+
expect(scenePublicationFenceFromRegistry(registry, SCENE_GUID)).toEqual(fence);
|
|
215
|
+
});
|
|
158
216
|
});
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from '@forgeax/engine-pack';
|
|
6
6
|
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
7
7
|
import { ShaderRegistry } from '@forgeax/engine-shader';
|
|
8
|
+
import type { MaterialParameter } from '@forgeax/engine-types';
|
|
8
9
|
import { describe, expect, it, vi } from 'vitest';
|
|
9
10
|
import { AssetRegistry } from '../asset-registry';
|
|
10
11
|
import { MaterialGenerationCache } from '../material/generation-cache';
|
|
@@ -19,7 +20,7 @@ const PRODUCTION_GUID = '019f0000-0000-7000-8000-000000000701';
|
|
|
19
20
|
function cookedRecord(guid = MATERIAL_GUID): CookedMaterialRecord {
|
|
20
21
|
const artifactDigest = createMaterialArtifactDigest(ARTIFACT_BYTES);
|
|
21
22
|
return {
|
|
22
|
-
schemaVersion: 'material-cook/
|
|
23
|
+
schemaVersion: 'material-cook/3',
|
|
23
24
|
guid,
|
|
24
25
|
materialGuid: guid,
|
|
25
26
|
publicationGeneration: 7,
|
|
@@ -36,15 +37,31 @@ function cookedRecord(guid = MATERIAL_GUID): CookedMaterialRecord {
|
|
|
36
37
|
bytes: ARTIFACT_BYTES,
|
|
37
38
|
},
|
|
38
39
|
receipt: {
|
|
39
|
-
schemaVersion: 'material-cook/
|
|
40
|
+
schemaVersion: 'material-cook/3',
|
|
40
41
|
sourceClosure: ['materials/ready.material.json', 'shaders/ready.wgsl'],
|
|
41
42
|
profile: 'webgpu/v1',
|
|
42
43
|
compilerVersion: 'compiler/1',
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
identity: {
|
|
45
|
+
materialContractDigest: 'sha256:ready-contract',
|
|
46
|
+
sourceRevision: 'sha256:ready-source',
|
|
47
|
+
sourceClosureDigest: 'sha256:ready-closure',
|
|
48
|
+
layoutIdentity: 'sha256:ready-layout',
|
|
49
|
+
programIdentity: 'sha256:ready-program',
|
|
50
|
+
pipelineIdentity: 'sha256:ready-pipeline',
|
|
51
|
+
materialPublicationIdentity: 'sha256:ready-publication',
|
|
52
|
+
cookIdentity: 'sha256:ready-cook',
|
|
53
|
+
compilerFingerprint: 'sha256:ready-compiler',
|
|
54
|
+
wasm: {
|
|
55
|
+
sourceContentKey: 'unavailable',
|
|
56
|
+
artifactSha256: 'unavailable',
|
|
57
|
+
glueSha256: 'unavailable',
|
|
58
|
+
},
|
|
59
|
+
artifactDigest,
|
|
60
|
+
valueGeneration: 7,
|
|
61
|
+
dependencyGeneration: 7,
|
|
62
|
+
cookGeneration: 7,
|
|
63
|
+
},
|
|
46
64
|
derivedInterface: { layoutIdentity: 'sha256:ready-layout' },
|
|
47
|
-
publicationGeneration: 7,
|
|
48
65
|
},
|
|
49
66
|
};
|
|
50
67
|
}
|
|
@@ -87,6 +104,70 @@ describe('material runtime readiness', () => {
|
|
|
87
104
|
]);
|
|
88
105
|
});
|
|
89
106
|
|
|
107
|
+
it('keeps the Standard transmission contract in the published snapshot', async () => {
|
|
108
|
+
const parameters: readonly MaterialParameter[] = [
|
|
109
|
+
{ name: 'transmission', type: 'f32', default: 0 },
|
|
110
|
+
{ name: 'ior', type: 'f32', default: 1.5 },
|
|
111
|
+
{ name: 'thickness', type: 'f32', default: 0 },
|
|
112
|
+
{ name: 'attenuationColor', type: 'vec3', default: [1, 1, 1] },
|
|
113
|
+
{ name: 'attenuationDistance', type: 'f32' },
|
|
114
|
+
{ name: 'transmissionTexture', type: 'texture' },
|
|
115
|
+
{ name: 'thicknessTexture', type: 'texture' },
|
|
116
|
+
];
|
|
117
|
+
expect(materialParametersToParamSchema(parameters, 'published::standard')).toEqual([
|
|
118
|
+
{ name: 'transmission', type: 'f32', default: 0 },
|
|
119
|
+
{ name: 'ior', type: 'f32', default: 1.5 },
|
|
120
|
+
{ name: 'thickness', type: 'f32', default: 0 },
|
|
121
|
+
{ name: 'attenuationColor', type: 'vec3', default: [1, 1, 1] },
|
|
122
|
+
{ name: 'attenuationDistance', type: 'f32' },
|
|
123
|
+
{ name: 'transmissionTexture', type: 'texture2d' },
|
|
124
|
+
{ name: 'thicknessTexture', type: 'texture2d' },
|
|
125
|
+
]);
|
|
126
|
+
const baseRecord = cookedRecord(PRODUCTION_GUID);
|
|
127
|
+
const record: CookedMaterialRecord = {
|
|
128
|
+
...baseRecord,
|
|
129
|
+
parameterContract: {
|
|
130
|
+
parameters,
|
|
131
|
+
values: {
|
|
132
|
+
transmission: 0.8,
|
|
133
|
+
ior: 1.45,
|
|
134
|
+
thickness: 0.25,
|
|
135
|
+
attenuationColor: [0.9, 0.95, 1],
|
|
136
|
+
attenuationDistance: 4,
|
|
137
|
+
transmissionTexture: { texture: 'texture/transmission' },
|
|
138
|
+
thicknessTexture: { texture: 'texture/thickness' },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
resolved: {
|
|
142
|
+
...baseRecord.resolved,
|
|
143
|
+
parameters,
|
|
144
|
+
values: {
|
|
145
|
+
transmission: 0.8,
|
|
146
|
+
ior: 1.45,
|
|
147
|
+
thickness: 0.25,
|
|
148
|
+
attenuationColor: [0.9, 0.95, 1],
|
|
149
|
+
attenuationDistance: 4,
|
|
150
|
+
transmissionTexture: { texture: 'texture/transmission' },
|
|
151
|
+
thicknessTexture: { texture: 'texture/thickness' },
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
const loader = createMaterialLoader({
|
|
156
|
+
loadPublication: async () => ({ ...publication(), guid: PRODUCTION_GUID, record }),
|
|
157
|
+
loadReference: async () => true,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const result = await loader.load({
|
|
161
|
+
guid: PRODUCTION_GUID,
|
|
162
|
+
specializationKey: 'material-specialization/7/ready',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
expect(result.status).toBe('Ready');
|
|
166
|
+
if (result.status !== 'Ready') return;
|
|
167
|
+
expect(result.parameterContract).toEqual(record.parameterContract);
|
|
168
|
+
expect(inspectMaterialRuntime(result).parameterContract).toEqual(record.parameterContract);
|
|
169
|
+
});
|
|
170
|
+
|
|
90
171
|
it('loads only a cooked record with its artifact and complete references', async () => {
|
|
91
172
|
const loader = createLoader(async () => publication());
|
|
92
173
|
|
|
@@ -30,7 +30,6 @@ function createCookedMaterialLoader() {
|
|
|
30
30
|
guid,
|
|
31
31
|
record: {
|
|
32
32
|
...raw,
|
|
33
|
-
schemaVersion: 'material-cook/2',
|
|
34
33
|
materialGuid: raw.guid,
|
|
35
34
|
publicationGeneration: 1,
|
|
36
35
|
specializationKey: SPECIALIZATION_KEY,
|
|
@@ -40,11 +39,7 @@ function createCookedMaterialLoader() {
|
|
|
40
39
|
artifact: { ...raw.artifact, digest, bytes },
|
|
41
40
|
receipt: {
|
|
42
41
|
...raw.receipt,
|
|
43
|
-
|
|
44
|
-
layoutIdentity: 'sha256:pulse-layout',
|
|
45
|
-
derivedInterface: { layoutIdentity: 'sha256:pulse-layout' },
|
|
46
|
-
publicationGeneration: 1,
|
|
47
|
-
outputDigest: digest,
|
|
42
|
+
identity: { ...raw.receipt.identity, artifactDigest: digest, cookGeneration: 1 },
|
|
48
43
|
},
|
|
49
44
|
},
|
|
50
45
|
artifact: { bytes },
|
|
@@ -167,7 +167,7 @@ describe('walkMaterialPassesOverSharedRefs', () => {
|
|
|
167
167
|
const child = mat({
|
|
168
168
|
parent: 'p-guid' as never,
|
|
169
169
|
parameters: [
|
|
170
|
-
{ name: 'roughness', type: 'f32'
|
|
170
|
+
{ name: 'roughness', type: 'f32' },
|
|
171
171
|
{ name: 'normalTexture', type: 'texture' },
|
|
172
172
|
],
|
|
173
173
|
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AnimationGraph,
|
|
3
3
|
AssetRegistry,
|
|
4
|
+
AssetRegistryResolver,
|
|
4
5
|
AudioClipAsset,
|
|
5
6
|
ParticleEffectAsset,
|
|
7
|
+
RuntimeAssetRegistry,
|
|
6
8
|
TilesetAsset,
|
|
7
9
|
} from '@forgeax/engine-assets-runtime';
|
|
8
10
|
import { expectTypeOf, it } from 'vitest';
|
|
@@ -14,3 +16,12 @@ it('exports concrete loadByGuid payload types from the runtime entry point', ()
|
|
|
14
16
|
expectTypeOf<AudioClipAsset['mediaType']>().toMatchTypeOf<`audio/${string}`>();
|
|
15
17
|
expectTypeOf<ParticleEffectAsset['program']>().toMatchTypeOf<ParticleEffectAsset['program']>();
|
|
16
18
|
});
|
|
19
|
+
|
|
20
|
+
it('exports the five-action runtime registry and its resolver from the root entry point', () => {
|
|
21
|
+
expectTypeOf<RuntimeAssetRegistry>().toHaveProperty('installDecoder');
|
|
22
|
+
expectTypeOf<RuntimeAssetRegistry>().toHaveProperty('load');
|
|
23
|
+
expectTypeOf<RuntimeAssetRegistry>().toHaveProperty('snapshot');
|
|
24
|
+
expectTypeOf<RuntimeAssetRegistry>().toHaveProperty('subscribe');
|
|
25
|
+
expectTypeOf<AssetRegistryResolver>().toHaveProperty('lookup');
|
|
26
|
+
expectTypeOf<AssetRegistryResolver>().toHaveProperty('guidOf');
|
|
27
|
+
});
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
materialShaderTextureFieldNames,
|
|
19
19
|
validateMaterialCookIdentity,
|
|
20
20
|
validateMaterialPasses,
|
|
21
|
+
validateMaterialTransmissionContract,
|
|
21
22
|
validateParamType,
|
|
22
23
|
validateSpriteSlices,
|
|
23
24
|
} from '../registry/validate-material';
|
|
@@ -64,7 +65,7 @@ describe('validateMaterialCookIdentity', () => {
|
|
|
64
65
|
const record = {
|
|
65
66
|
guid: 'mat-child',
|
|
66
67
|
receipt: {
|
|
67
|
-
layoutIdentity: 'sha256:root-layout',
|
|
68
|
+
identity: { layoutIdentity: 'sha256:root-layout' },
|
|
68
69
|
derivedInterface: { layoutIdentity: 'sha256:root-layout' },
|
|
69
70
|
},
|
|
70
71
|
} as never;
|
|
@@ -180,6 +181,50 @@ describe('validateMaterialPasses', () => {
|
|
|
180
181
|
});
|
|
181
182
|
});
|
|
182
183
|
|
|
184
|
+
describe('validateMaterialTransmissionContract', () => {
|
|
185
|
+
it.each([
|
|
186
|
+
['transmission range', { transmission: 1.1 }],
|
|
187
|
+
['ior range', { ior: 0 }],
|
|
188
|
+
['thickness range', { thickness: -0.1 }],
|
|
189
|
+
['attenuation distance', { attenuationDistance: Number.POSITIVE_INFINITY }],
|
|
190
|
+
])('returns a structured error for %s', (_name, value) => {
|
|
191
|
+
const error = validateMaterialTransmissionContract(mat({ values: value }));
|
|
192
|
+
expect(error?.code).toBe('material-transmission-contract-invalid');
|
|
193
|
+
expect(error?.detail).toMatchObject({ reason: expect.any(String) });
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('rejects BLEND and depth writes when transmission is active', () => {
|
|
197
|
+
expect(
|
|
198
|
+
validateMaterialTransmissionContract(
|
|
199
|
+
mat({
|
|
200
|
+
values: { transmission: 0.5 },
|
|
201
|
+
passes: [
|
|
202
|
+
{
|
|
203
|
+
name: 'forward',
|
|
204
|
+
program: { module: 'forgeax_material::standard' },
|
|
205
|
+
renderState: { blend: {} },
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
}),
|
|
209
|
+
)?.detail,
|
|
210
|
+
).toMatchObject({ reason: 'blend' });
|
|
211
|
+
expect(
|
|
212
|
+
validateMaterialTransmissionContract(
|
|
213
|
+
mat({
|
|
214
|
+
values: { transmission: 0.5 },
|
|
215
|
+
passes: [
|
|
216
|
+
{
|
|
217
|
+
name: 'forward',
|
|
218
|
+
program: { module: 'forgeax_material::standard' },
|
|
219
|
+
renderState: { depthWriteEnabled: true },
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
}),
|
|
223
|
+
)?.detail,
|
|
224
|
+
).toMatchObject({ reason: 'depth-write' });
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
183
228
|
describe('validateParamType', () => {
|
|
184
229
|
const reg = makeRegistry({});
|
|
185
230
|
it('numeric scalars', () => {
|
package/src/asset-registry.ts
CHANGED
|
@@ -611,6 +611,11 @@ export class AssetRegistry {
|
|
|
611
611
|
return this._originIndex.get(asset as object);
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
+
/** Public identity projection consumed by scene collection boundaries. */
|
|
615
|
+
guidOf(asset: Asset): string | undefined {
|
|
616
|
+
return this._guidForAsset(asset);
|
|
617
|
+
}
|
|
618
|
+
|
|
614
619
|
/** Return the production MaterialReady/Error result for one material GUID. */
|
|
615
620
|
getMaterialReadiness(guid: string): MaterialReady | MaterialLoadError | undefined {
|
|
616
621
|
return this.materialReadiness.get(guid.toLowerCase());
|
package/src/handles.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// straight-cut). Pure move from asset-registry.ts; zero identifier changes.
|
|
4
4
|
|
|
5
5
|
import type { Handle } from '@forgeax/engine-types';
|
|
6
|
-
import { toShared } from '@forgeax/engine-types';
|
|
6
|
+
import { handleSlot, toShared } from '@forgeax/engine-types';
|
|
7
7
|
|
|
8
8
|
// ─── Builtin handles (D-S9 / backward compat with hello-triangle + hello-cube) ─
|
|
9
9
|
|
|
@@ -146,6 +146,12 @@ export const BUILTIN_MESH_GUIDS: ReadonlyArray<readonly [Handle<'MeshAsset', 'sh
|
|
|
146
146
|
[HANDLE_CYLINDER, 'ab20af21-0764-55be-a7f2-b80ab3d46a0a'],
|
|
147
147
|
];
|
|
148
148
|
|
|
149
|
+
/** Resolve the stable producer GUID for one process-static builtin mesh handle. */
|
|
150
|
+
export function builtinMeshGuid(handle: Handle<string, 'shared'>): string | undefined {
|
|
151
|
+
const slot = handleSlot(handle);
|
|
152
|
+
return BUILTIN_MESH_GUIDS.find(([candidate]) => handleSlot(candidate) === slot)?.[1];
|
|
153
|
+
}
|
|
154
|
+
|
|
149
155
|
/**
|
|
150
156
|
* Field names known to carry handle<> schema-vocab references (plan-strategy
|
|
151
157
|
* D-4). parseScenePayload uses this allowlist to replace integer values
|
package/src/index.ts
CHANGED
|
@@ -76,6 +76,7 @@ export {
|
|
|
76
76
|
} from './errors/asset';
|
|
77
77
|
// ─── Builtin mesh handles (re-exported by asset-registry from ./handles) ─────
|
|
78
78
|
export {
|
|
79
|
+
builtinMeshGuid,
|
|
79
80
|
HANDLE_CUBE,
|
|
80
81
|
HANDLE_CYLINDER,
|
|
81
82
|
HANDLE_NINESLICE_QUAD,
|
|
@@ -83,7 +84,15 @@ export {
|
|
|
83
84
|
HANDLE_SPHERE,
|
|
84
85
|
HANDLE_TRIANGLE,
|
|
85
86
|
} from './handles';
|
|
86
|
-
|
|
87
|
+
// The five-action runtime registry is distinct from the legacy authoring
|
|
88
|
+
// AssetRegistry class above. Keep its resolver on the public package boundary
|
|
89
|
+
// so render/VFX hosts never reach through `/internal` to inspect loaded assets.
|
|
90
|
+
export {
|
|
91
|
+
type AssetRegistry as RuntimeAssetRegistry,
|
|
92
|
+
type AssetRegistryResolver,
|
|
93
|
+
createAssetRegistry,
|
|
94
|
+
getAssetRegistryResolver,
|
|
95
|
+
} from './internal/load-asset.js';
|
|
87
96
|
// ─── Loader-injection surface ───────────────────────────────────────────────
|
|
88
97
|
export { LoaderRegistry } from './loader-registry';
|
|
89
98
|
// ─── Default loader tables + individual loaders (pre-w14 consumer face) ──────
|
|
@@ -134,6 +143,7 @@ export {
|
|
|
134
143
|
// ─── Mipmap generation helpers ──────────────────────────────────────────────
|
|
135
144
|
export {
|
|
136
145
|
blitMipmapsSync,
|
|
146
|
+
encodeMipmapLevel,
|
|
137
147
|
getOrCreateMipmapPipeline,
|
|
138
148
|
type MipmapBlitDevice,
|
|
139
149
|
type MipmapShaderModuleFactory,
|
|
@@ -148,9 +158,13 @@ export {
|
|
|
148
158
|
type RuntimeEvidenceSource,
|
|
149
159
|
} from './registry/asset-evidence';
|
|
150
160
|
export { CatalogReplica, type CatalogReplicaSnapshot } from './registry/catalog-state';
|
|
151
|
-
export type { PostSpawnHook, SkinJointResolver } from './registry/instantiate';
|
|
152
161
|
// ─── Scene instantiate collaboration contract types (D-1 injected hook) ─────
|
|
153
|
-
export {
|
|
162
|
+
export {
|
|
163
|
+
buildSceneChildContext,
|
|
164
|
+
type PostSpawnHook,
|
|
165
|
+
type SkinJointResolver,
|
|
166
|
+
scenePublicationFenceFromRegistry,
|
|
167
|
+
} from './registry/instantiate';
|
|
154
168
|
export { loadMaterialReadyByGuid } from './registry/load-by-guid';
|
|
155
169
|
export {
|
|
156
170
|
compareScenePublicationFences,
|
|
@@ -29,7 +29,7 @@ export function inspectMaterialRuntime(ready: MaterialReady): MaterialRuntimeInf
|
|
|
29
29
|
publicationGeneration: ready.publicationGeneration,
|
|
30
30
|
specializationKey: ready.specializationKey,
|
|
31
31
|
artifactDigest: ready.artifactDigest,
|
|
32
|
-
layoutIdentity: ready.record.receipt.layoutIdentity,
|
|
32
|
+
layoutIdentity: ready.record.receipt.identity.layoutIdentity,
|
|
33
33
|
dependencies: [
|
|
34
34
|
...ready.record.refs.parent,
|
|
35
35
|
...ready.record.refs.textures,
|
package/src/material/loader.ts
CHANGED
|
@@ -108,7 +108,7 @@ function missingCook(request: MaterialLoadRequest): MaterialLoadError {
|
|
|
108
108
|
function recordError(
|
|
109
109
|
request: MaterialLoadRequest,
|
|
110
110
|
field: string,
|
|
111
|
-
expected = 'a complete material-cook/
|
|
111
|
+
expected = 'a complete material-cook/3 publication record',
|
|
112
112
|
): MaterialLoadError {
|
|
113
113
|
return materialError(
|
|
114
114
|
request,
|
|
@@ -174,18 +174,18 @@ function completeTupleField(record: CookedMaterialRecord): string | undefined {
|
|
|
174
174
|
receipt.profile.length === 0 ||
|
|
175
175
|
typeof receipt.compilerVersion !== 'string' ||
|
|
176
176
|
receipt.compilerVersion.length === 0 ||
|
|
177
|
-
typeof receipt.
|
|
178
|
-
receipt.
|
|
179
|
-
receipt.
|
|
180
|
-
receipt.
|
|
177
|
+
typeof receipt.identity.cookIdentity !== 'string' ||
|
|
178
|
+
receipt.identity.cookIdentity.length === 0 ||
|
|
179
|
+
receipt.identity.artifactDigest !== record.artifactDigest ||
|
|
180
|
+
receipt.identity.cookGeneration !== record.publicationGeneration
|
|
181
181
|
)
|
|
182
182
|
return 'receipt';
|
|
183
183
|
if (
|
|
184
|
-
typeof receipt.layoutIdentity !== 'string' ||
|
|
185
|
-
receipt.layoutIdentity.length === 0 ||
|
|
186
|
-
receipt.derivedInterface?.layoutIdentity !== receipt.layoutIdentity
|
|
184
|
+
typeof receipt.identity.layoutIdentity !== 'string' ||
|
|
185
|
+
receipt.identity.layoutIdentity.length === 0 ||
|
|
186
|
+
receipt.derivedInterface?.layoutIdentity !== receipt.identity.layoutIdentity
|
|
187
187
|
)
|
|
188
|
-
return 'receipt.layoutIdentity';
|
|
188
|
+
return 'receipt.identity.layoutIdentity';
|
|
189
189
|
if (
|
|
190
190
|
typeof record.artifact.mediaType !== 'string' ||
|
|
191
191
|
record.artifact.mediaType.length === 0 ||
|