@flighthq/scene3d-resources 0.3.0-next.906.07cea63 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anisotropyPbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/anisotropyPbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/anisotropyPbrScene3DMaterialTextures.js +10 -0
- package/dist/anisotropyPbrScene3DMaterialTextures.js.map +1 -0
- package/dist/awd2Load.d.ts.map +1 -1
- package/dist/awd2Load.js +3 -2
- package/dist/awd2Load.js.map +1 -1
- package/dist/clearcoatPbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/clearcoatPbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/clearcoatPbrScene3DMaterialTextures.js +14 -0
- package/dist/clearcoatPbrScene3DMaterialTextures.js.map +1 -0
- package/dist/contract.d.ts +10 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +10 -1
- package/dist/contract.js.map +1 -1
- package/dist/enableScene3DResourceFailureGuards.d.ts.map +1 -1
- package/dist/enableScene3DResourceFailureGuards.js +2 -2
- package/dist/enableScene3DResourceFailureGuards.js.map +1 -1
- package/dist/explainScene3DResourceCoverage.d.ts +4 -0
- package/dist/explainScene3DResourceCoverage.d.ts.map +1 -0
- package/dist/explainScene3DResourceCoverage.js +42 -0
- package/dist/explainScene3DResourceCoverage.js.map +1 -0
- package/dist/getScene3DResourceTextures.d.ts +3 -2
- package/dist/getScene3DResourceTextures.d.ts.map +1 -1
- package/dist/getScene3DResourceTextures.js +23 -27
- package/dist/getScene3DResourceTextures.js.map +1 -1
- package/dist/imageResourceFetch.d.ts +2 -2
- package/dist/imageResourceFetch.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/iridescencePbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/iridescencePbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/iridescencePbrScene3DMaterialTextures.js +12 -0
- package/dist/iridescencePbrScene3DMaterialTextures.js.map +1 -0
- package/dist/loadScene3DResources.d.ts +4 -0
- package/dist/loadScene3DResources.d.ts.map +1 -0
- package/dist/{resolveScene3DResourcesAndWait.js → loadScene3DResources.js} +11 -21
- package/dist/loadScene3DResources.js.map +1 -0
- package/dist/resolveScene3DResources.d.ts +4 -3
- package/dist/resolveScene3DResources.d.ts.map +1 -1
- package/dist/resolveScene3DResources.js +49 -26
- package/dist/resolveScene3DResources.js.map +1 -1
- package/dist/revealScene3DResourcesOnResolve.d.ts +2 -2
- package/dist/revealScene3DResourcesOnResolve.d.ts.map +1 -1
- package/dist/revealScene3DResourcesOnResolve.js +9 -6
- package/dist/revealScene3DResourcesOnResolve.js.map +1 -1
- package/dist/sceneMaterialTextureRegistry.d.ts +6 -2
- package/dist/sceneMaterialTextureRegistry.d.ts.map +1 -1
- package/dist/sceneMaterialTextureRegistry.js +31 -8
- package/dist/sceneMaterialTextureRegistry.js.map +1 -1
- package/dist/sceneResourceRecovery.d.ts +2 -4
- package/dist/sceneResourceRecovery.d.ts.map +1 -1
- package/dist/sceneResourceRecovery.js +9 -28
- package/dist/sceneResourceRecovery.js.map +1 -1
- package/dist/sceneResourceResolver.d.ts.map +1 -1
- package/dist/sceneResourceResolver.js +6 -2
- package/dist/sceneResourceResolver.js.map +1 -1
- package/dist/shadedScene3DMaterialTextures.d.ts +3 -0
- package/dist/shadedScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/shadedScene3DMaterialTextures.js +30 -0
- package/dist/shadedScene3DMaterialTextures.js.map +1 -0
- package/dist/sheenPbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/sheenPbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/sheenPbrScene3DMaterialTextures.js +12 -0
- package/dist/sheenPbrScene3DMaterialTextures.js.map +1 -0
- package/dist/specularPbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/specularPbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/specularPbrScene3DMaterialTextures.js +12 -0
- package/dist/specularPbrScene3DMaterialTextures.js.map +1 -0
- package/dist/transmissionVolumePbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/transmissionVolumePbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/transmissionVolumePbrScene3DMaterialTextures.js +12 -0
- package/dist/transmissionVolumePbrScene3DMaterialTextures.js.map +1 -0
- package/dist/wrappedDiffusePbrScene3DMaterialTextures.d.ts +3 -0
- package/dist/wrappedDiffusePbrScene3DMaterialTextures.d.ts.map +1 -0
- package/dist/wrappedDiffusePbrScene3DMaterialTextures.js +12 -0
- package/dist/wrappedDiffusePbrScene3DMaterialTextures.js.map +1 -0
- package/package.json +16 -13
- package/src/anisotropyPbrScene3DMaterialTextures.test.ts +26 -0
- package/src/awd2Load.test.ts +2 -2
- package/src/clearcoatPbrScene3DMaterialTextures.test.ts +36 -0
- package/src/enableScene3DResourceFailureGuards.test.ts +9 -8
- package/src/explainScene3DResourceCoverage.test.ts +115 -0
- package/src/getScene3DResourceTextures.test.ts +65 -38
- package/src/gltfLoad.test.ts +2 -2
- package/src/imageResourceFetch.test.ts +3 -3
- package/src/iridescencePbrScene3DMaterialTextures.test.ts +34 -0
- package/src/{resolveScene3DResourcesAndWait.test.ts → loadScene3DResources.test.ts} +40 -18
- package/src/md2Load.test.ts +2 -2
- package/src/md5Load.test.ts +2 -2
- package/src/objLoad.test.ts +2 -2
- package/src/resolveScene3DResources.test.ts +136 -53
- package/src/revealScene3DResourcesOnResolve.test.ts +39 -21
- package/src/sceneMaterialTextureRegistry.test.ts +118 -26
- package/src/sceneResourceRecovery.test.ts +13 -47
- package/src/sceneResourceResolver.test.ts +14 -11
- package/src/sceneResourceResolverTreeShaking.test.ts +1 -1
- package/src/shadedScene3DMaterialTextures.test.ts +52 -0
- package/src/sheenPbrScene3DMaterialTextures.test.ts +29 -0
- package/src/specularPbrScene3DMaterialTextures.test.ts +29 -0
- package/src/threeDsLoad.test.ts +2 -2
- package/src/transmissionVolumePbrScene3DMaterialTextures.test.ts +34 -0
- package/src/wrappedDiffusePbrScene3DMaterialTextures.test.ts +34 -0
- package/dist/resolveScene3DResourcesAndWait.d.ts +0 -4
- package/dist/resolveScene3DResourcesAndWait.d.ts.map +0 -1
- package/dist/resolveScene3DResourcesAndWait.js.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { WrappedDiffusePbrExtensionKind } from '@flighthq/types/contract';
|
|
2
|
+
import { registerScene3DPbrExtensionTextures } from './sceneMaterialTextureRegistry';
|
|
3
|
+
export function registerWrappedDiffusePbrScene3DMaterialTextures(registry) {
|
|
4
|
+
registerScene3DPbrExtensionTextures(registry, WrappedDiffusePbrExtensionKind, (extension, out) => {
|
|
5
|
+
const wrappedDiffuse = extension;
|
|
6
|
+
if (wrappedDiffuse.wrappedDiffuseMap !== null)
|
|
7
|
+
out.push(wrappedDiffuse.wrappedDiffuseMap);
|
|
8
|
+
if (wrappedDiffuse.thicknessMap !== null)
|
|
9
|
+
out.push(wrappedDiffuse.thicknessMap);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=wrappedDiffusePbrScene3DMaterialTextures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappedDiffusePbrScene3DMaterialTextures.js","sourceRoot":"","sources":["../src/wrappedDiffusePbrScene3DMaterialTextures.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAErF,MAAM,UAAU,gDAAgD,CAAC,QAAwC;IACvG,mCAAmC,CAAC,QAAQ,EAAE,8BAA8B,EAAE,CAAC,SAAS,EAAE,GAAG,EAAQ,EAAE;QACrG,MAAM,cAAc,GAAG,SAAiD,CAAC;QACzE,IAAI,cAAc,CAAC,iBAAiB,KAAK,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC1F,IAAI,cAAc,CAAC,YAAY,KAAK,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/scene3d-resources",
|
|
3
|
-
"version": "0.3.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"author": "Joshua Granick and other contributors",
|
|
5
|
+
"license": "MIT",
|
|
4
6
|
"repository": {
|
|
5
7
|
"type": "git",
|
|
6
8
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,22 +38,23 @@
|
|
|
36
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@flighthq/entity": "0.3.0
|
|
40
|
-
"@flighthq/image": "0.3.0
|
|
41
|
-
"@flighthq/loader": "0.3.0
|
|
42
|
-
"@flighthq/log": "0.3.0
|
|
43
|
-
"@flighthq/net": "0.3.0
|
|
44
|
-
"@flighthq/node": "0.3.0
|
|
45
|
-
"@flighthq/scene3d": "0.3.0
|
|
46
|
-
"@flighthq/scene3d-formats": "0.3.0
|
|
47
|
-
"@flighthq/signals": "0.3.0
|
|
48
|
-
"@flighthq/
|
|
49
|
-
"@flighthq/
|
|
41
|
+
"@flighthq/entity": "0.3.0",
|
|
42
|
+
"@flighthq/image": "0.3.0",
|
|
43
|
+
"@flighthq/loader": "0.3.0",
|
|
44
|
+
"@flighthq/log": "0.3.0",
|
|
45
|
+
"@flighthq/net": "0.3.0",
|
|
46
|
+
"@flighthq/node": "0.3.0",
|
|
47
|
+
"@flighthq/scene3d": "0.3.0",
|
|
48
|
+
"@flighthq/scene3d-formats": "0.3.0",
|
|
49
|
+
"@flighthq/signals": "0.3.0",
|
|
50
|
+
"@flighthq/texture": "0.3.0",
|
|
51
|
+
"@flighthq/tween": "0.3.0",
|
|
52
|
+
"@flighthq/types": "0.3.0"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
52
55
|
"@flighthq/materials": "*",
|
|
53
56
|
"@flighthq/mesh": "*",
|
|
54
|
-
"@flighthq/
|
|
57
|
+
"@flighthq/shading": "*",
|
|
55
58
|
"typescript": "^5.3.0"
|
|
56
59
|
},
|
|
57
60
|
"description": "Renderer-neutral scene-document URL acquisition and caller-driven resolution of scene texture references into live ImageResources",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createAnisotropyPbrExtension, createExtendedPbrMaterial } from '@flighthq/materials/contract';
|
|
2
|
+
import { createTexture } from '@flighthq/texture/contract';
|
|
3
|
+
import type { Texture } from '@flighthq/types/contract';
|
|
4
|
+
|
|
5
|
+
import { registerAnisotropyPbrScene3DMaterialTextures } from './anisotropyPbrScene3DMaterialTextures';
|
|
6
|
+
import {
|
|
7
|
+
createScene3DMaterialTextureRegistry,
|
|
8
|
+
getScene3DMaterialTextures,
|
|
9
|
+
registerExtendedPbrScene3DMaterialTextures,
|
|
10
|
+
} from './sceneMaterialTextureRegistry';
|
|
11
|
+
|
|
12
|
+
describe('registerAnisotropyPbrScene3DMaterialTextures', () => {
|
|
13
|
+
it('lists the anisotropy map through the generic Extended PBR material lister', () => {
|
|
14
|
+
const registry = createScene3DMaterialTextureRegistry();
|
|
15
|
+
registerExtendedPbrScene3DMaterialTextures(registry);
|
|
16
|
+
registerAnisotropyPbrScene3DMaterialTextures(registry);
|
|
17
|
+
const map = createTexture();
|
|
18
|
+
const out: Texture[] = [];
|
|
19
|
+
getScene3DMaterialTextures(
|
|
20
|
+
registry,
|
|
21
|
+
createExtendedPbrMaterial({ extensions: [createAnisotropyPbrExtension({ anisotropyMap: map })] }),
|
|
22
|
+
out,
|
|
23
|
+
);
|
|
24
|
+
expect(out).toEqual([map]);
|
|
25
|
+
});
|
|
26
|
+
});
|
package/src/awd2Load.test.ts
CHANGED
|
@@ -39,8 +39,8 @@ beforeAll(async () => {
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
afterAll(() => {
|
|
42
|
-
vi.doUnmock('@flighthq/net');
|
|
43
|
-
vi.doUnmock('@flighthq/scene3d-formats');
|
|
42
|
+
vi.doUnmock('@flighthq/net/contract');
|
|
43
|
+
vi.doUnmock('@flighthq/scene3d-formats/contract');
|
|
44
44
|
vi.resetModules();
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createClearcoatPbrExtension, createExtendedPbrMaterial } from '@flighthq/materials/contract';
|
|
2
|
+
import { createTexture } from '@flighthq/texture/contract';
|
|
3
|
+
import type { Texture } from '@flighthq/types/contract';
|
|
4
|
+
|
|
5
|
+
import { registerClearcoatPbrScene3DMaterialTextures } from './clearcoatPbrScene3DMaterialTextures';
|
|
6
|
+
import {
|
|
7
|
+
createScene3DMaterialTextureRegistry,
|
|
8
|
+
getScene3DMaterialTextures,
|
|
9
|
+
registerExtendedPbrScene3DMaterialTextures,
|
|
10
|
+
} from './sceneMaterialTextureRegistry';
|
|
11
|
+
|
|
12
|
+
describe('registerClearcoatPbrScene3DMaterialTextures', () => {
|
|
13
|
+
it('lists all clearcoat maps in descriptor order', () => {
|
|
14
|
+
const registry = createScene3DMaterialTextureRegistry();
|
|
15
|
+
registerExtendedPbrScene3DMaterialTextures(registry);
|
|
16
|
+
registerClearcoatPbrScene3DMaterialTextures(registry);
|
|
17
|
+
const factor = createTexture();
|
|
18
|
+
const normal = createTexture();
|
|
19
|
+
const roughness = createTexture();
|
|
20
|
+
const out: Texture[] = [];
|
|
21
|
+
getScene3DMaterialTextures(
|
|
22
|
+
registry,
|
|
23
|
+
createExtendedPbrMaterial({
|
|
24
|
+
extensions: [
|
|
25
|
+
createClearcoatPbrExtension({
|
|
26
|
+
clearcoatMap: factor,
|
|
27
|
+
clearcoatNormalMap: normal,
|
|
28
|
+
clearcoatRoughnessMap: roughness,
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
}),
|
|
32
|
+
out,
|
|
33
|
+
);
|
|
34
|
+
expect(out).toEqual([factor, normal, roughness]);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -63,9 +63,10 @@ describe('enableScene3DResourceFailureGuards', () => {
|
|
|
63
63
|
addLogSink(sink.sink);
|
|
64
64
|
const resolver = createScene3DResourceResolver();
|
|
65
65
|
const signals = enableScene3DResourceSignals(resolver);
|
|
66
|
-
const
|
|
66
|
+
const ref = failedRef();
|
|
67
|
+
const texture = createTexture({ resource: ref });
|
|
67
68
|
const dispose = enableScene3DResourceFailureGuards(resolver);
|
|
68
|
-
const event = { ref
|
|
69
|
+
const event = { ref, texture };
|
|
69
70
|
|
|
70
71
|
expect(() => emitSignal(signals.onResourceFailed, event)).not.toThrow();
|
|
71
72
|
emitSignal(signals.onResourceFailed, event);
|
|
@@ -76,13 +77,12 @@ describe('enableScene3DResourceFailureGuards', () => {
|
|
|
76
77
|
failureKind: ImageResourceFailureKind.Error,
|
|
77
78
|
failureMessage: 'bad image',
|
|
78
79
|
failureName: 'CodecError',
|
|
79
|
-
message:
|
|
80
|
-
'resolveScene3DResources: image resource resolution failed — call retryFailedScene3DResources to request it again',
|
|
80
|
+
message: 'Scene3D resource acquisition failed — call retryFailedScene3DResources to request it again',
|
|
81
81
|
});
|
|
82
|
-
expect(
|
|
82
|
+
expect(ref.state).toBe(ResourceResolutionState.Failed);
|
|
83
83
|
|
|
84
84
|
emitSignal(signals.onResourceResolved, event);
|
|
85
|
-
|
|
85
|
+
ref.failure = {
|
|
86
86
|
kind: ImageResourceFailureKind.Unavailable,
|
|
87
87
|
message: 'still unavailable',
|
|
88
88
|
name: null,
|
|
@@ -102,11 +102,12 @@ describe('enableScene3DResourceFailureGuards', () => {
|
|
|
102
102
|
addLogSink(sink.sink);
|
|
103
103
|
const resolver = createScene3DResourceResolver();
|
|
104
104
|
const signals = enableScene3DResourceSignals(resolver);
|
|
105
|
-
const
|
|
105
|
+
const ref = failedRef();
|
|
106
|
+
const texture = createTexture({ resource: ref });
|
|
106
107
|
const firstDispose = enableScene3DResourceFailureGuards(resolver);
|
|
107
108
|
const secondDispose = enableScene3DResourceFailureGuards(resolver);
|
|
108
109
|
|
|
109
|
-
emitSignal(signals.onResourceFailed, { ref
|
|
110
|
+
emitSignal(signals.onResourceFailed, { ref, texture });
|
|
110
111
|
expect(getMemoryLogSinkEntries(sink)).toHaveLength(1);
|
|
111
112
|
secondDispose();
|
|
112
113
|
expect(areScene3DResourceFailureGuardsEnabled(resolver)).toBe(false);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createBlinnPhongMaterial, createUnlitMaterial } from '@flighthq/materials/contract';
|
|
2
|
+
import { createBoxMeshGeometry } from '@flighthq/mesh/contract';
|
|
3
|
+
import { addNodeChild } from '@flighthq/node/contract';
|
|
4
|
+
import { createMesh, createScene3D, createScene3DKindUsage, getScene3DKindUsage } from '@flighthq/scene3d/contract';
|
|
5
|
+
import { createShadedMaterial } from '@flighthq/shading/contract';
|
|
6
|
+
import type { Material, SceneCoverageEntry, Scene3DKindUsage } from '@flighthq/types/contract';
|
|
7
|
+
import { RenderRegistry, SceneCoverage } from '@flighthq/types/contract';
|
|
8
|
+
import { describe, expect, it } from 'vitest';
|
|
9
|
+
|
|
10
|
+
import { explainScene3DResourceCoverage, hasScene3DResourceCoverage } from './explainScene3DResourceCoverage';
|
|
11
|
+
import { createBuiltInScene3DResourceResolver, createScene3DResourceResolver } from './sceneResourceResolver';
|
|
12
|
+
import { registerShadedScene3DMaterialTextures } from './shadedScene3DMaterialTextures';
|
|
13
|
+
|
|
14
|
+
function usageOf(...materials: Material[]): Scene3DKindUsage {
|
|
15
|
+
const scene = createScene3D();
|
|
16
|
+
for (const material of materials) {
|
|
17
|
+
addNodeChild(scene.root, createMesh(createBoxMeshGeometry(), [material]));
|
|
18
|
+
}
|
|
19
|
+
const usage = createScene3DKindUsage();
|
|
20
|
+
getScene3DKindUsage(usage, scene);
|
|
21
|
+
return usage;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function gaps(resolver: Parameters<typeof explainScene3DResourceCoverage>[1], usage: Scene3DKindUsage) {
|
|
25
|
+
const out: SceneCoverageEntry[] = [];
|
|
26
|
+
explainScene3DResourceCoverage(out, resolver, usage);
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('explainScene3DResourceCoverage', () => {
|
|
31
|
+
it('reports a bare resolver as missing every material kind, since its registry starts empty', () => {
|
|
32
|
+
const found = gaps(createScene3DResourceResolver(), usageOf(createUnlitMaterial()));
|
|
33
|
+
expect(found).toEqual([
|
|
34
|
+
{ coverage: SceneCoverage.Missing, kind: 'UnlitMaterial', registry: RenderRegistry.MaterialTextureLister },
|
|
35
|
+
]);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('reports a covered kind as Satisfied rather than omitting it', () => {
|
|
39
|
+
// The manifest lists every requirement, so a caller can render a checklist and tell "covered" from
|
|
40
|
+
// "never asked about". Omitting covered kinds would make those two indistinguishable.
|
|
41
|
+
expect(gaps(createBuiltInScene3DResourceResolver(), usageOf(createUnlitMaterial()))).toEqual([
|
|
42
|
+
{ coverage: SceneCoverage.Satisfied, kind: 'UnlitMaterial', registry: RenderRegistry.MaterialTextureLister },
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('reports ShadedMaterial against the built-in assembly, which does not wire its lister', () => {
|
|
47
|
+
// The gap this query exists to surface: shading ships registerShadedScene3DMaterialTextures, but
|
|
48
|
+
// createBuiltInScene3DResourceResolver covers only the surface-PBR families, so an AWD2 document
|
|
49
|
+
// loaded through the built-in assembly has no lister for its materials.
|
|
50
|
+
expect(gaps(createBuiltInScene3DResourceResolver(), usageOf(createShadedMaterial()))).toContainEqual({
|
|
51
|
+
coverage: SceneCoverage.Missing,
|
|
52
|
+
kind: 'ShadedMaterial',
|
|
53
|
+
registry: RenderRegistry.MaterialTextureLister,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('stops reporting once the named door for that family is called', () => {
|
|
58
|
+
const resolver = createBuiltInScene3DResourceResolver();
|
|
59
|
+
registerShadedScene3DMaterialTextures(resolver.registry);
|
|
60
|
+
expect(gaps(resolver, usageOf(createShadedMaterial()))).toEqual([
|
|
61
|
+
{ coverage: SceneCoverage.Satisfied, kind: 'ShadedMaterial', registry: RenderRegistry.MaterialTextureLister },
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('reports a family that ships no lister at all, so the omission is visible rather than inferred', () => {
|
|
66
|
+
// BlinnPhongMaterial carries four texture slots and has no lister anywhere in the SDK.
|
|
67
|
+
expect(gaps(createBuiltInScene3DResourceResolver(), usageOf(createBlinnPhongMaterial()))).toContainEqual({
|
|
68
|
+
coverage: SceneCoverage.Missing,
|
|
69
|
+
kind: 'BlinnPhongMaterial',
|
|
70
|
+
registry: RenderRegistry.MaterialTextureLister,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('clears out, so a repeated call does not accumulate', () => {
|
|
75
|
+
const resolver = createScene3DResourceResolver();
|
|
76
|
+
const usage = usageOf(createUnlitMaterial());
|
|
77
|
+
const out: SceneCoverageEntry[] = [];
|
|
78
|
+
explainScene3DResourceCoverage(out, resolver, usage);
|
|
79
|
+
const first = out.length;
|
|
80
|
+
explainScene3DResourceCoverage(out, resolver, usage);
|
|
81
|
+
expect(out).toHaveLength(first);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('hasScene3DResourceCoverage', () => {
|
|
86
|
+
it('is false while any material kind is undescribed', () => {
|
|
87
|
+
expect(hasScene3DResourceCoverage(createScene3DResourceResolver(), usageOf(createUnlitMaterial()))).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('agrees with the explain tier on the same resolver, so the two can never disagree', () => {
|
|
91
|
+
const resolver = createBuiltInScene3DResourceResolver();
|
|
92
|
+
const usage = usageOf(createUnlitMaterial(), createShadedMaterial());
|
|
93
|
+
const out: SceneCoverageEntry[] = [];
|
|
94
|
+
explainScene3DResourceCoverage(out, resolver, usage);
|
|
95
|
+
expect(hasScene3DResourceCoverage(resolver, usage)).toBe(out.length === 0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('stays true when the manifest is all Satisfied entries, which are not shortfalls', () => {
|
|
99
|
+
// The invariant the manifest widening could have broken: explain now appends entries for covered
|
|
100
|
+
// kinds too, and the predicate must keep counting only real gaps.
|
|
101
|
+
const resolver = createBuiltInScene3DResourceResolver();
|
|
102
|
+
const usage = usageOf(createUnlitMaterial());
|
|
103
|
+
const out: SceneCoverageEntry[] = [];
|
|
104
|
+
explainScene3DResourceCoverage(out, resolver, usage);
|
|
105
|
+
expect(out.length).toBeGreaterThan(0);
|
|
106
|
+
expect(out.every((e) => e.coverage === SceneCoverage.Satisfied)).toBe(true);
|
|
107
|
+
expect(hasScene3DResourceCoverage(resolver, usage)).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('is true for an empty scene, which names no material kinds', () => {
|
|
111
|
+
const usage = createScene3DKindUsage();
|
|
112
|
+
getScene3DKindUsage(usage, createScene3D());
|
|
113
|
+
expect(hasScene3DResourceCoverage(createScene3DResourceResolver(), usage)).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { createStandardPbrMaterial, createUnlitMaterial } from '@flighthq/materials/contract';
|
|
1
|
+
import { createBlinnPhongMaterial, createStandardPbrMaterial, createUnlitMaterial } from '@flighthq/materials/contract';
|
|
2
2
|
import { createBoxMeshGeometry } from '@flighthq/mesh/contract';
|
|
3
3
|
import { addNodeChild } from '@flighthq/node/contract';
|
|
4
4
|
import { createMesh, createScene3D } from '@flighthq/scene3d/contract';
|
|
5
5
|
import { createTexture } from '@flighthq/texture/contract';
|
|
6
6
|
import type { ImageResourceReference, Texture } from '@flighthq/types/contract';
|
|
7
|
-
import {
|
|
7
|
+
import { ImageResourceReferenceKind, ResourceResolutionState } from '@flighthq/types/contract';
|
|
8
8
|
import { describe, expect, it } from 'vitest';
|
|
9
9
|
|
|
10
|
-
import { getScene3DResourceTextures } from './getScene3DResourceTextures';
|
|
11
|
-
import {
|
|
12
|
-
createScene3DMaterialTextureRegistry,
|
|
13
|
-
registerBuiltInScene3DMaterialTextures,
|
|
14
|
-
} from './sceneMaterialTextureRegistry';
|
|
10
|
+
import { getScene3DResourceTextures, getScene3DTextureResourceReference } from './getScene3DResourceTextures';
|
|
15
11
|
|
|
16
12
|
function embeddedRef(state: ResourceResolutionState = ResourceResolutionState.Unresolved): ImageResourceReference {
|
|
17
13
|
return {
|
|
@@ -23,41 +19,32 @@ function embeddedRef(state: ResourceResolutionState = ResourceResolutionState.Un
|
|
|
23
19
|
};
|
|
24
20
|
}
|
|
25
21
|
|
|
26
|
-
function registry() {
|
|
27
|
-
const r = createScene3DMaterialTextureRegistry();
|
|
28
|
-
registerBuiltInScene3DMaterialTextures(r);
|
|
29
|
-
return r;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
22
|
describe('getScene3DResourceTextures', () => {
|
|
33
23
|
it('finds pending textures on the root mesh and descendants', () => {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
24
|
+
const rootRef = embeddedRef();
|
|
25
|
+
const childRef = embeddedRef();
|
|
26
|
+
const rootMap = createTexture({ resource: rootRef });
|
|
27
|
+
const childMap = createTexture({ resource: childRef });
|
|
36
28
|
const root = createMesh(createBoxMeshGeometry(), [createUnlitMaterial({ baseColorMap: rootMap })]);
|
|
37
29
|
const child = createMesh(createBoxMeshGeometry(), [createUnlitMaterial({ baseColorMap: childMap })]);
|
|
38
30
|
addNodeChild(root, child);
|
|
31
|
+
const scene = createScene3D();
|
|
32
|
+
scene.resources.push(rootRef, childRef);
|
|
33
|
+
addNodeChild(scene.root, root);
|
|
39
34
|
|
|
40
35
|
const out: Texture[] = [];
|
|
41
|
-
getScene3DResourceTextures(
|
|
36
|
+
getScene3DResourceTextures(out, scene);
|
|
42
37
|
expect(out).toContain(rootMap);
|
|
43
38
|
expect(out).toContain(childMap);
|
|
44
39
|
expect(out).toHaveLength(2);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
it('walks a group scene root that is not itself a mesh', () => {
|
|
48
|
-
const map = createTexture({ resource: embeddedRef() });
|
|
49
|
-
const scene = createScene3D();
|
|
50
|
-
const mesh = createMesh(createBoxMeshGeometry(), [createUnlitMaterial({ baseColorMap: map })]);
|
|
51
|
-
addNodeChild(scene.root, mesh);
|
|
52
|
-
|
|
53
|
-
const out: Texture[] = [];
|
|
54
|
-
getScene3DResourceTextures(scene.root, registry(), out);
|
|
55
|
-
expect(out).toEqual([map]);
|
|
40
|
+
expect(getScene3DTextureResourceReference(scene, rootMap)).toBe(rootRef);
|
|
56
41
|
});
|
|
57
42
|
|
|
58
43
|
it('dedupes a texture shared across meshes and materials', () => {
|
|
59
|
-
const
|
|
44
|
+
const ref = embeddedRef();
|
|
45
|
+
const shared = createTexture({ resource: ref });
|
|
60
46
|
const scene = createScene3D();
|
|
47
|
+
scene.resources.push(ref);
|
|
61
48
|
const a = createMesh(createBoxMeshGeometry(), [
|
|
62
49
|
createUnlitMaterial({ baseColorMap: shared }),
|
|
63
50
|
createStandardPbrMaterial({ baseColorMap: shared }),
|
|
@@ -67,35 +54,75 @@ describe('getScene3DResourceTextures', () => {
|
|
|
67
54
|
addNodeChild(scene.root, b);
|
|
68
55
|
|
|
69
56
|
const out: Texture[] = [];
|
|
70
|
-
getScene3DResourceTextures(
|
|
57
|
+
getScene3DResourceTextures(out, scene);
|
|
71
58
|
expect(out).toEqual([shared]);
|
|
72
59
|
});
|
|
73
60
|
|
|
74
|
-
it('ignores a texture that carries no resource ref', () => {
|
|
61
|
+
it('ignores a texture that carries no resource ref, since nothing needs fetching for it', () => {
|
|
75
62
|
const bound = createTexture();
|
|
76
|
-
const
|
|
63
|
+
const ref = embeddedRef();
|
|
64
|
+
const pending = createTexture({ resource: ref });
|
|
77
65
|
const mesh = createMesh(createBoxMeshGeometry(), [
|
|
78
66
|
createStandardPbrMaterial({ baseColorMap: bound, normalMap: pending }),
|
|
79
67
|
]);
|
|
80
68
|
|
|
69
|
+
const scene = createScene3D();
|
|
70
|
+
scene.resources.push(ref);
|
|
71
|
+
addNodeChild(scene.root, mesh);
|
|
81
72
|
const out: Texture[] = [];
|
|
82
|
-
getScene3DResourceTextures(
|
|
73
|
+
getScene3DResourceTextures(out, scene);
|
|
83
74
|
expect(out).toEqual([pending]);
|
|
84
75
|
});
|
|
85
76
|
|
|
86
|
-
it('
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
it('finds a texture on any material kind, with nothing registered', () => {
|
|
78
|
+
// The defect this closes: discovery used to run through a per-kind lister registry, so a kind with
|
|
79
|
+
// no lister — BlinnPhongMaterial here, and every custom kind — was undiscoverable. The map was
|
|
80
|
+
// never requested and the model rendered untextured in silence. Now the resource's own back-edge
|
|
81
|
+
// answers, so no registration exists to forget.
|
|
82
|
+
const ref = embeddedRef();
|
|
83
|
+
const map = createTexture({ resource: ref });
|
|
84
|
+
const scene = createScene3D();
|
|
85
|
+
scene.resources.push(ref);
|
|
86
|
+
addNodeChild(scene.root, createMesh(createBoxMeshGeometry(), [createBlinnPhongMaterial({ specularMap: map })]));
|
|
87
|
+
|
|
89
88
|
const out: Texture[] = [];
|
|
90
|
-
getScene3DResourceTextures(
|
|
89
|
+
getScene3DResourceTextures(out, scene);
|
|
91
90
|
expect(out).toEqual([map]);
|
|
92
91
|
});
|
|
93
92
|
|
|
93
|
+
it('returns a texture whose material hangs off no mesh, which is the cost of dropping the registry', () => {
|
|
94
|
+
// Honest about the trade: the lister walk used to narrow the set by mesh attachment, so an orphan
|
|
95
|
+
// material's map was not fetched. That narrowing only ever held while every kind in the scene was
|
|
96
|
+
// describable, and it cost a registry the caller had to know to populate. The residue is one
|
|
97
|
+
// over-fetch for a document carrying materials it never attaches.
|
|
98
|
+
const attachedRef = embeddedRef();
|
|
99
|
+
const orphanRef = embeddedRef();
|
|
100
|
+
const attached = createTexture({ resource: attachedRef });
|
|
101
|
+
const orphan = createTexture({ resource: orphanRef });
|
|
102
|
+
const scene = createScene3D();
|
|
103
|
+
scene.resources.push(attachedRef, orphanRef);
|
|
104
|
+
addNodeChild(scene.root, createMesh(createBoxMeshGeometry(), [createUnlitMaterial({ baseColorMap: attached })]));
|
|
105
|
+
|
|
106
|
+
const out: Texture[] = [];
|
|
107
|
+
getScene3DResourceTextures(out, scene);
|
|
108
|
+
expect(out).toEqual([attached, orphan]);
|
|
109
|
+
});
|
|
110
|
+
|
|
94
111
|
it('clears out before filling it', () => {
|
|
95
|
-
const
|
|
112
|
+
const ref = embeddedRef();
|
|
113
|
+
const map = createTexture({ resource: ref });
|
|
96
114
|
const mesh = createMesh(createBoxMeshGeometry(), [createUnlitMaterial({ baseColorMap: map })]);
|
|
115
|
+
const scene = createScene3D();
|
|
116
|
+
scene.resources.push(ref);
|
|
117
|
+
addNodeChild(scene.root, mesh);
|
|
97
118
|
const out: Texture[] = [createTexture(), createTexture()];
|
|
98
|
-
getScene3DResourceTextures(
|
|
119
|
+
getScene3DResourceTextures(out, scene);
|
|
99
120
|
expect(out).toEqual([map]);
|
|
100
121
|
});
|
|
101
122
|
});
|
|
123
|
+
|
|
124
|
+
describe('getScene3DTextureResourceReference', () => {
|
|
125
|
+
it('returns null for a texture outside the scene resource sidecar', () => {
|
|
126
|
+
expect(getScene3DTextureResourceReference(createScene3D(), createTexture())).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
});
|
package/src/gltfLoad.test.ts
CHANGED
|
@@ -42,8 +42,8 @@ beforeAll(async () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
afterAll(() => {
|
|
45
|
-
vi.doUnmock('@flighthq/net');
|
|
46
|
-
vi.doUnmock('@flighthq/scene3d-formats');
|
|
45
|
+
vi.doUnmock('@flighthq/net/contract');
|
|
46
|
+
vi.doUnmock('@flighthq/scene3d-formats/contract');
|
|
47
47
|
vi.resetModules();
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type * as ImageModule from '@flighthq/image/contract';
|
|
2
|
-
import type { ExternalImageResourceReference,
|
|
2
|
+
import type { ExternalImageResourceReference, Image } from '@flighthq/types/contract';
|
|
3
3
|
import { ResourceResolutionState, ImageResourceReferenceKind } from '@flighthq/types/contract';
|
|
4
4
|
import type { Mock } from 'vitest';
|
|
5
5
|
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import type * as ImageResourceFetchModule from './imageResourceFetch';
|
|
8
8
|
|
|
9
|
-
const fakeImage = { height: 1, width: 1 } as unknown as
|
|
9
|
+
const fakeImage = { height: 1, width: 1 } as unknown as Image;
|
|
10
10
|
type LoadImageResourceFromUrl = typeof ImageModule.loadImageResourceFromUrl;
|
|
11
11
|
|
|
12
12
|
let fetchWebImageResource: typeof ImageResourceFetchModule.fetchWebImageResource;
|
|
@@ -35,7 +35,7 @@ beforeAll(async () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
afterAll(() => {
|
|
38
|
-
vi.doUnmock('@flighthq/image');
|
|
38
|
+
vi.doUnmock('@flighthq/image/contract');
|
|
39
39
|
vi.resetModules();
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createExtendedPbrMaterial, createIridescencePbrExtension } from '@flighthq/materials/contract';
|
|
2
|
+
import { createTexture } from '@flighthq/texture/contract';
|
|
3
|
+
import type { Texture } from '@flighthq/types/contract';
|
|
4
|
+
|
|
5
|
+
import { registerIridescencePbrScene3DMaterialTextures } from './iridescencePbrScene3DMaterialTextures';
|
|
6
|
+
import {
|
|
7
|
+
createScene3DMaterialTextureRegistry,
|
|
8
|
+
getScene3DMaterialTextures,
|
|
9
|
+
registerExtendedPbrScene3DMaterialTextures,
|
|
10
|
+
} from './sceneMaterialTextureRegistry';
|
|
11
|
+
|
|
12
|
+
describe('registerIridescencePbrScene3DMaterialTextures', () => {
|
|
13
|
+
it('lists the iridescence factor and thickness maps', () => {
|
|
14
|
+
const registry = createScene3DMaterialTextureRegistry();
|
|
15
|
+
registerExtendedPbrScene3DMaterialTextures(registry);
|
|
16
|
+
registerIridescencePbrScene3DMaterialTextures(registry);
|
|
17
|
+
const factor = createTexture();
|
|
18
|
+
const thickness = createTexture();
|
|
19
|
+
const out: Texture[] = [];
|
|
20
|
+
getScene3DMaterialTextures(
|
|
21
|
+
registry,
|
|
22
|
+
createExtendedPbrMaterial({
|
|
23
|
+
extensions: [
|
|
24
|
+
createIridescencePbrExtension({
|
|
25
|
+
iridescenceMap: factor,
|
|
26
|
+
iridescenceThicknessMap: thickness,
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
29
|
+
}),
|
|
30
|
+
out,
|
|
31
|
+
);
|
|
32
|
+
expect(out).toEqual([factor, thickness]);
|
|
33
|
+
});
|
|
34
|
+
});
|