@forgeax/engine-gltf 0.1.21 → 0.1.24
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 +115 -3
- package/dist/__tests__/lod-import.integration.test.d.ts +2 -0
- package/dist/__tests__/lod-import.integration.test.d.ts.map +1 -0
- package/dist/__tests__/lod-meta-publication.integration.test.d.ts +2 -0
- package/dist/__tests__/lod-meta-publication.integration.test.d.ts.map +1 -0
- package/dist/__tests__/physical-clearcoat.unit.test.d.ts +2 -0
- package/dist/__tests__/physical-clearcoat.unit.test.d.ts.map +1 -0
- package/dist/__tests__/physical-material-import.integration.test.d.ts +2 -0
- package/dist/__tests__/physical-material-import.integration.test.d.ts.map +1 -0
- package/dist/bridge.d.ts +1 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/check-extensions.d.ts +1 -1
- package/dist/check-extensions.d.ts.map +1 -1
- package/dist/cli-gltf.mjs +362 -14
- package/dist/cli-gltf.mjs.map +1 -1
- package/dist/errors.d.ts +13 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/gltf-importer.d.ts.map +1 -1
- package/dist/image-color-space.d.ts +12 -0
- package/dist/image-color-space.d.ts.map +1 -1
- package/dist/importer-entry.mjs +516 -25
- package/dist/importer-entry.mjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +609 -28
- package/dist/index.mjs.map +1 -1
- package/dist/lod/parse-lod.d.ts +15 -0
- package/dist/lod/parse-lod.d.ts.map +1 -0
- package/dist/lod/project-meta.d.ts +23 -0
- package/dist/lod/project-meta.d.ts.map +1 -0
- package/dist/material/parse-material.d.ts +66 -0
- package/dist/material/parse-material.d.ts.map +1 -1
- package/dist/node-file-entry.mjs +265 -8
- package/dist/node-file-entry.mjs.map +1 -1
- package/dist/parse-gltf.d.ts +3 -1
- package/dist/parse-gltf.d.ts.map +1 -1
- package/dist/reimport-reuse-meta.d.ts +1 -1
- package/dist/reimport-reuse-meta.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/__tests__/bridge-material-values.unit.test.ts +84 -1
- package/src/__tests__/bridge-skin-stride.unit.test.ts +22 -0
- package/src/__tests__/fixtures/lod/core-only.gltf +1 -0
- package/src/__tests__/fixtures/lod/msft-lod-malformed.gltf +1 -0
- package/src/__tests__/fixtures/lod/msft-lod-multi-root.gltf +1 -0
- package/src/__tests__/fixtures/lod/msft-lod-node-extras.gltf +1 -0
- package/src/__tests__/fixtures/lod/msft-lod.gltf +1 -0
- package/src/__tests__/gltf-error-derived-views.test-d.ts +8 -0
- package/src/__tests__/gltf-error-migration.test.ts +3 -3
- package/src/__tests__/gltf.unit.test.ts +60 -5
- package/src/__tests__/lod-import.integration.test.ts +106 -0
- package/src/__tests__/lod-meta-publication.integration.test.ts +24 -0
- package/src/__tests__/material-pack-refs.integration.test.ts +53 -0
- package/src/__tests__/parse-gltf.unit.test.ts +50 -0
- package/src/__tests__/physical-clearcoat.unit.test.ts +110 -0
- package/src/__tests__/physical-material-import.integration.test.ts +239 -0
- package/src/__tests__/source-key-producer.integration.test.ts +6 -2
- package/src/bridge.ts +259 -14
- package/src/check-extensions.ts +16 -8
- package/src/errors.ts +32 -2
- package/src/gltf-importer.ts +122 -1
- package/src/image-color-space.ts +29 -4
- package/src/index.ts +10 -1
- package/src/lod/parse-lod.ts +129 -0
- package/src/lod/project-meta.ts +48 -0
- package/src/material/parse-material.ts +307 -0
- package/src/parse-gltf.ts +97 -1
- package/src/reimport-reuse-meta.ts +3 -1
- package/dist/.tsbuildinfo +0 -1
package/dist/parse-gltf.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ImportError } from '@forgeax/engine-types';
|
|
2
2
|
import { COMPONENT_TYPE } from './accessor/decode-accessor.js';
|
|
3
3
|
import { type GltfError, type Result } from './errors.js';
|
|
4
|
+
import { type GltfLodRelation } from './lod/parse-lod.js';
|
|
4
5
|
import { type GltfImageIr, type GltfMaterialIr, type GltfSamplerIr, type GltfTextureIr } from './material/parse-material.js';
|
|
5
6
|
import { type GltfBufferViewDecodeCapability } from './meshopt-decode.js';
|
|
6
7
|
import { type GltfAnimationClipRecord } from './parse-animation.js';
|
|
@@ -129,6 +130,7 @@ export interface GltfDoc {
|
|
|
129
130
|
* fixtures; producers from parseGltf / parseGlb always populate it.
|
|
130
131
|
*/
|
|
131
132
|
readonly meshPrimitiveCount?: ReadonlyMap<number, number>;
|
|
133
|
+
readonly lod?: GltfLodRelation;
|
|
132
134
|
}
|
|
133
135
|
export type ExternalLoader = (uri: string) => Promise<ArrayBuffer>;
|
|
134
136
|
type GltfParseError = GltfError | ImportError;
|
|
@@ -156,7 +158,7 @@ export interface GltfAssetPack {
|
|
|
156
158
|
readonly meta: GltfMetaJson;
|
|
157
159
|
readonly subAssets: readonly GltfSubAssetEntry[];
|
|
158
160
|
}
|
|
159
|
-
export type GltfAssetPackResult = Result<GltfAssetPack, GltfSourceKeyError>;
|
|
161
|
+
export type GltfAssetPackResult = Result<GltfAssetPack, GltfSourceKeyError | GltfError>;
|
|
160
162
|
/**
|
|
161
163
|
* Project a parsed `GltfDoc` into the disk-shape `<source>.meta.json` plus
|
|
162
164
|
* the freshly minted `subAssets[]` list (UUIDv7 + reimport-reuse-meta
|
package/dist/parse-gltf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-gltf.d.ts","sourceRoot":"","sources":["../src/parse-gltf.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"parse-gltf.d.ts","sourceRoot":"","sources":["../src/parse-gltf.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ export interface GltfMetaJson {
|
|
|
19
19
|
readonly importer: 'gltf';
|
|
20
20
|
readonly source: string;
|
|
21
21
|
readonly subAssets: readonly GltfSubAssetEntry[];
|
|
22
|
-
readonly sourceOverrides?: Readonly<Record<string, Readonly<Record<string, unknown
|
|
22
|
+
readonly sourceOverrides?: Readonly<Record<string, Readonly<Record<string, unknown>>>> | undefined;
|
|
23
23
|
readonly sourceOverrideDescriptors?: readonly import('@forgeax/engine-types').SourceOverrideDescriptor[];
|
|
24
24
|
readonly importSettings: {
|
|
25
25
|
readonly defaultSceneIndex: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reimport-reuse-meta.d.ts","sourceRoot":"","sources":["../src/reimport-reuse-meta.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEvE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C,gGAAgG;AAChG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACjD,QAAQ,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"reimport-reuse-meta.d.ts","sourceRoot":"","sources":["../src/reimport-reuse-meta.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEvE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C,gGAAgG;AAChG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACjD,QAAQ,CAAC,eAAe,CAAC,EACrB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAC3D,SAAS,CAAC;IACd,QAAQ,CAAC,yBAAyB,CAAC,EAAE,SAAS,OAAO,uBAAuB,EAAE,wBAAwB,EAAE,CAAC;IACzG,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QACvC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,WAAW,EAAE;YACpB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;YACtC,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;YAClD,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;SACnD,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAClD;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;AAEjF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC,mBAAmB,CAmDrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-gltf",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,21 +38,21 @@
|
|
|
38
38
|
"LICENSE"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@forgeax/engine-animation": "0.1.
|
|
42
|
-
"@forgeax/engine-geometry": "0.1.
|
|
43
|
-
"@forgeax/engine-import": "0.1.
|
|
44
|
-
"@forgeax/engine-math": "0.1.
|
|
45
|
-
"@forgeax/engine-pack": "0.1.
|
|
46
|
-
"@forgeax/engine-scene": "0.1.
|
|
47
|
-
"@forgeax/engine-types": "0.1.
|
|
41
|
+
"@forgeax/engine-animation": "0.1.24",
|
|
42
|
+
"@forgeax/engine-geometry": "0.1.24",
|
|
43
|
+
"@forgeax/engine-import": "0.1.24",
|
|
44
|
+
"@forgeax/engine-math": "0.1.24",
|
|
45
|
+
"@forgeax/engine-pack": "0.1.24",
|
|
46
|
+
"@forgeax/engine-scene": "0.1.24",
|
|
47
|
+
"@forgeax/engine-types": "0.1.24",
|
|
48
48
|
"@webgpu/types": "^0.1.71",
|
|
49
49
|
"meshoptimizer": "^0.20.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@forgeax/engine-assets-runtime": "0.1.
|
|
53
|
-
"@forgeax/engine-picking": "0.1.
|
|
54
|
-
"@forgeax/engine-render": "0.1.
|
|
55
|
-
"@forgeax/engine-runtime": "0.1.
|
|
52
|
+
"@forgeax/engine-assets-runtime": "0.1.24",
|
|
53
|
+
"@forgeax/engine-picking": "0.1.24",
|
|
54
|
+
"@forgeax/engine-render": "0.1.24",
|
|
55
|
+
"@forgeax/engine-runtime": "0.1.24",
|
|
56
56
|
"@types/node": "^20.14.0"
|
|
57
57
|
},
|
|
58
58
|
"forgeax": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Handle } from '@forgeax/engine-types';
|
|
1
|
+
import type { AssetGuid, Handle } from '@forgeax/engine-types';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
3
|
import { toMaterialAsset } from '../bridge.js';
|
|
4
4
|
import type { GltfMaterialIr } from '../parse-gltf.js';
|
|
@@ -149,4 +149,87 @@ describe('glTF material bridge values', () => {
|
|
|
149
149
|
},
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
it('owns a complete five-extension Standard root and admits only authored physical textures', () => {
|
|
154
|
+
const material = toMaterialAsset(
|
|
155
|
+
{
|
|
156
|
+
name: 'physical-root',
|
|
157
|
+
baseColorFactor: [0.8, 0.7, 0.6, 1],
|
|
158
|
+
metallicFactor: 0.1,
|
|
159
|
+
roughnessFactor: 0.35,
|
|
160
|
+
clearcoatFactor: 0.75,
|
|
161
|
+
clearcoatRoughnessFactor: 0.2,
|
|
162
|
+
clearcoatNormalTexture: { texture: 0 },
|
|
163
|
+
anisotropyStrength: 0.5,
|
|
164
|
+
anisotropyRotation: 0.25,
|
|
165
|
+
anisotropyTexture: { texture: 1 },
|
|
166
|
+
sheenColorFactor: [0.2, 0.1, 0.05],
|
|
167
|
+
sheenRoughnessFactor: 0.3,
|
|
168
|
+
sheenColorTexture: { texture: 2 },
|
|
169
|
+
iridescenceFactor: 0.6,
|
|
170
|
+
iridescenceIor: 1.4,
|
|
171
|
+
iridescenceThicknessMinimum: 120,
|
|
172
|
+
iridescenceThicknessMaximum: 380,
|
|
173
|
+
iridescenceTexture: { texture: 3 },
|
|
174
|
+
specularFactor: 0.8,
|
|
175
|
+
specularColorFactor: [0.9, 0.85, 0.75],
|
|
176
|
+
specularColorTexture: { texture: 4 },
|
|
177
|
+
} as unknown as GltfMaterialIr,
|
|
178
|
+
{
|
|
179
|
+
standardRootGuid: 'standard-root' as unknown as AssetGuid,
|
|
180
|
+
textureHandles: new Map([
|
|
181
|
+
[0, 100],
|
|
182
|
+
[1, 101],
|
|
183
|
+
[2, 102],
|
|
184
|
+
[3, 103],
|
|
185
|
+
[4, 104],
|
|
186
|
+
]) as unknown as ReadonlyMap<number, Handle<'TextureAsset', 'shared'>>,
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
expect(material.parent).toBeUndefined();
|
|
191
|
+
const names = new Set((material.parameters ?? []).map((parameter) => parameter.name));
|
|
192
|
+
for (const name of [
|
|
193
|
+
'clearcoat',
|
|
194
|
+
'clearcoatRoughness',
|
|
195
|
+
'clearcoatNormalTexture',
|
|
196
|
+
'anisotropyStrength',
|
|
197
|
+
'anisotropyRotation',
|
|
198
|
+
'anisotropyTexture',
|
|
199
|
+
'sheenColor',
|
|
200
|
+
'sheenRoughness',
|
|
201
|
+
'sheenColorTexture',
|
|
202
|
+
'iridescence',
|
|
203
|
+
'iridescenceIor',
|
|
204
|
+
'iridescenceThicknessMinimum',
|
|
205
|
+
'iridescenceThicknessMaximum',
|
|
206
|
+
'iridescenceTexture',
|
|
207
|
+
'specular',
|
|
208
|
+
'specularColor',
|
|
209
|
+
'specularColorTexture',
|
|
210
|
+
]) {
|
|
211
|
+
expect(names.has(name)).toBe(true);
|
|
212
|
+
}
|
|
213
|
+
for (const name of [
|
|
214
|
+
'clearcoatTexture',
|
|
215
|
+
'clearcoatRoughnessTexture',
|
|
216
|
+
'sheenRoughnessTexture',
|
|
217
|
+
'iridescenceThicknessTexture',
|
|
218
|
+
'specularTexture',
|
|
219
|
+
]) {
|
|
220
|
+
expect(names.has(name)).toBe(false);
|
|
221
|
+
}
|
|
222
|
+
expect(material.values).toMatchObject({
|
|
223
|
+
clearcoat: 0.75,
|
|
224
|
+
anisotropyStrength: 0.5,
|
|
225
|
+
sheenColor: [0.2, 0.1, 0.05],
|
|
226
|
+
iridescenceIor: 1.4,
|
|
227
|
+
specularColor: [0.9, 0.85, 0.75],
|
|
228
|
+
clearcoatNormalTexture: { texture: 100 },
|
|
229
|
+
anisotropyTexture: { texture: 101 },
|
|
230
|
+
sheenColorTexture: { texture: 102 },
|
|
231
|
+
iridescenceTexture: { texture: 103 },
|
|
232
|
+
specularColorTexture: { texture: 104 },
|
|
233
|
+
});
|
|
234
|
+
});
|
|
152
235
|
});
|
|
@@ -102,6 +102,28 @@ describe('meshIrToMeshAsset pure-unskinned path (AC-04 / AC-08 / OOS-9)', () =>
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
describe('glTF bridge uses geometry-owned packing', () => {
|
|
105
|
+
it('persists a generated tangent frame when source TANGENT is absent', () => {
|
|
106
|
+
const asset = meshIrToMeshAsset([
|
|
107
|
+
{
|
|
108
|
+
meshIndex: 0,
|
|
109
|
+
materialIndex: null,
|
|
110
|
+
positions: new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]),
|
|
111
|
+
normals: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1]),
|
|
112
|
+
texcoord0: new Float32Array([0, 0, 1, 0, 0, 1]),
|
|
113
|
+
indices: new Uint16Array([0, 1, 2]),
|
|
114
|
+
},
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
const tangent = asset.attributes.tangent;
|
|
118
|
+
expect(tangent).toBeInstanceOf(Float32Array);
|
|
119
|
+
if (!(tangent instanceof Float32Array)) throw new Error('generated tangent stream missing');
|
|
120
|
+
expect(tangent?.length).toBe(12);
|
|
121
|
+
expect(tangent?.[0]).toBeCloseTo(1, 5);
|
|
122
|
+
expect(tangent?.[1]).toBeCloseTo(0, 5);
|
|
123
|
+
expect(tangent?.[2]).toBeCloseTo(0, 5);
|
|
124
|
+
expect(Math.abs(tangent?.[3] ?? 0)).toBeCloseTo(1, 5);
|
|
125
|
+
});
|
|
126
|
+
|
|
105
127
|
it('does not own a parallel 12F/18F stride or uv count calculation', () => {
|
|
106
128
|
const asset = meshIrToMeshAsset([makeUnskinnedPrim(0, 4)]);
|
|
107
129
|
expect(asset.vertices.length / 12).toBe(4);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"asset":{"version":"2.0"},"nodes":[{"mesh":0}],"meshes":[{"primitives":[]}],"scenes":[{"nodes":[0]}]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"asset":{"version":"2.0"},"extensionsRequired":["MSFT_lod"],"extensionsUsed":["MSFT_lod"],"nodes":[{"mesh":0,"extensions":{"MSFT_lod":{"ids":[99]}}}],"scenes":[{"nodes":[0]}]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"asset":{"version":"2.0"},"extensionsUsed":["MSFT_lod"],"meshes":[{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]}],"nodes":[{"mesh":0,"extensions":{"MSFT_lod":{"ids":[1,2]}}},{"mesh":1},{"mesh":2},{"mesh":3,"extensions":{"MSFT_lod":{"ids":[4,5]}}},{"mesh":4},{"mesh":5}],"extensions":{"MSFT_screencoverage":{"scales":[0.5,0.2]}},"scenes":[{"nodes":[0,3]}]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"asset":{"version":"2.0"},"extensionsUsed":["MSFT_lod"],"meshes":[{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]}],"nodes":[{"mesh":0,"extensions":{"MSFT_lod":{"ids":[1,2]}},"extras":{"MSFT_screencoverage":[0.5,0.2,0.01]}},{"mesh":1},{"mesh":2}],"scenes":[{"nodes":[0]}]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"asset":{"version":"2.0"},"extensionsUsed":["MSFT_lod"],"meshes":[{"primitives":[{}]},{"primitives":[{}]},{"primitives":[{}]}],"nodes":[{"mesh":0,"extensions":{"MSFT_lod":{"ids":[1,2]}}},{"mesh":1},{"mesh":2}],"extensions":{"MSFT_screencoverage":{"scales":[0.5,0.2]}},"scenes":[{"nodes":[0]}]}
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
type GltfImageExtractFailedDetail,
|
|
14
14
|
type GltfImageMimeUnsupportedDetail,
|
|
15
15
|
type GltfInstancingCountMismatchDetail,
|
|
16
|
+
type GltfLodInvalidDetail,
|
|
16
17
|
type GltfMalformedHeaderDetail,
|
|
18
|
+
type GltfMaterialPhysicalInvalidDetail,
|
|
17
19
|
type GltfMaterialTransmissionInvalidDetail,
|
|
18
20
|
type GltfMeshBridgeInvalidDetail,
|
|
19
21
|
type GltfMeshoptDecodeFailedDetail,
|
|
@@ -52,7 +54,9 @@ type ExpectedDetails = {
|
|
|
52
54
|
readonly 'gltf-color-accessor-unsupported': GltfColorAccessorUnsupportedDetail;
|
|
53
55
|
readonly 'gltf-color-accessor-malformed': GltfColorAccessorMalformedDetail;
|
|
54
56
|
readonly 'gltf-mesh-bridge-invalid': GltfMeshBridgeInvalidDetail;
|
|
57
|
+
readonly 'gltf-lod-invalid': GltfLodInvalidDetail;
|
|
55
58
|
readonly 'gltf-material-transmission-invalid': GltfMaterialTransmissionInvalidDetail;
|
|
59
|
+
readonly 'gltf-material-physical-invalid': GltfMaterialPhysicalInvalidDetail;
|
|
56
60
|
};
|
|
57
61
|
|
|
58
62
|
type ExpectedCodes = keyof ExpectedDetails;
|
|
@@ -75,6 +79,8 @@ function exhaustive(error: GltfError): string {
|
|
|
75
79
|
return `${error.detail.accessor}:${error.detail.bufferIndex}`;
|
|
76
80
|
case 'gltf-extension-unsupported':
|
|
77
81
|
return error.detail.extension;
|
|
82
|
+
case 'gltf-lod-invalid':
|
|
83
|
+
return String(error.detail.rootNode);
|
|
78
84
|
case 'gltf-accessor-type-mismatch':
|
|
79
85
|
return error.detail.reason;
|
|
80
86
|
case 'gltf-texture-load-failed':
|
|
@@ -113,6 +119,8 @@ function exhaustive(error: GltfError): string {
|
|
|
113
119
|
return error.detail.reason;
|
|
114
120
|
case 'gltf-material-transmission-invalid':
|
|
115
121
|
return `${error.detail.extension}:${error.detail.field}:${error.detail.reason}`;
|
|
122
|
+
case 'gltf-material-physical-invalid':
|
|
123
|
+
return `${error.detail.extension}:${error.detail.field}:${error.detail.reason}`;
|
|
116
124
|
}
|
|
117
125
|
return error;
|
|
118
126
|
}
|
|
@@ -17,7 +17,7 @@ import { resolve } from 'node:path';
|
|
|
17
17
|
import { describe, expect, it } from 'vitest';
|
|
18
18
|
|
|
19
19
|
const REPO_ROOT = resolve(import.meta.dirname ?? '.', '..', '..', '..', '..');
|
|
20
|
-
const TYPES_INDEX = resolve(REPO_ROOT, 'packages', 'types', 'src', '
|
|
20
|
+
const TYPES_INDEX = resolve(REPO_ROOT, 'packages', 'types', 'src', 'core-contracts.ts');
|
|
21
21
|
const GLTF_ERRORS = resolve(REPO_ROOT, 'packages', 'gltf', 'src', 'errors.ts');
|
|
22
22
|
|
|
23
23
|
function grepCount(pattern: string, file: string): number {
|
|
@@ -125,12 +125,12 @@ function grepCountImportGltfErrorFromTypes(): number {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
describe('M1 GltfErrorCode migration grep gate (AC-28)', () => {
|
|
128
|
-
it("(a) types/src/
|
|
128
|
+
it("(a) types/src/core-contracts.ts contains zero 'gltf-' string literals", () => {
|
|
129
129
|
const count = grepCount("'gltf-", TYPES_INDEX);
|
|
130
130
|
expect(count).toBe(0);
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
-
it('(b) types/src/
|
|
133
|
+
it('(b) types/src/core-contracts.ts contains zero export type GltfError* exports', () => {
|
|
134
134
|
const count = grepCount('export type GltfError', TYPES_INDEX);
|
|
135
135
|
expect(count).toBe(0);
|
|
136
136
|
});
|
|
@@ -278,7 +278,9 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
278
278
|
'gltf-version-unsupported',
|
|
279
279
|
'gltf-buffer-out-of-bounds',
|
|
280
280
|
'gltf-extension-unsupported',
|
|
281
|
+
'gltf-lod-invalid',
|
|
281
282
|
'gltf-material-transmission-invalid',
|
|
283
|
+
'gltf-material-physical-invalid',
|
|
282
284
|
'gltf-accessor-type-mismatch',
|
|
283
285
|
'gltf-texture-load-failed',
|
|
284
286
|
'gltf-meta-missing',
|
|
@@ -300,7 +302,8 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
300
302
|
];
|
|
301
303
|
|
|
302
304
|
function classifyByExhaustiveSwitch(err: GltfError): string {
|
|
303
|
-
|
|
305
|
+
const code = err.code;
|
|
306
|
+
switch (code) {
|
|
304
307
|
case 'gltf-malformed-header':
|
|
305
308
|
return 'malformed';
|
|
306
309
|
case 'gltf-version-unsupported':
|
|
@@ -309,8 +312,12 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
309
312
|
return 'oob';
|
|
310
313
|
case 'gltf-extension-unsupported':
|
|
311
314
|
return 'ext';
|
|
315
|
+
case 'gltf-lod-invalid':
|
|
316
|
+
return 'lod';
|
|
312
317
|
case 'gltf-material-transmission-invalid':
|
|
313
318
|
return 'material-transmission-invalid';
|
|
319
|
+
case 'gltf-material-physical-invalid':
|
|
320
|
+
return 'material-physical-invalid';
|
|
314
321
|
case 'gltf-accessor-type-mismatch':
|
|
315
322
|
return 'accessor';
|
|
316
323
|
case 'gltf-texture-load-failed':
|
|
@@ -348,6 +355,7 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
348
355
|
case 'gltf-mesh-bridge-invalid':
|
|
349
356
|
return 'mesh-bridge-invalid';
|
|
350
357
|
}
|
|
358
|
+
throw new Error(`unhandled glTF error code: ${code}`);
|
|
351
359
|
}
|
|
352
360
|
|
|
353
361
|
function buildErrSample(code: GltfErrorCode): GltfError {
|
|
@@ -360,6 +368,8 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
360
368
|
return gltfErr(code, { accessor: 0, byteOffset: 0, byteLength: 0, bufferIndex: 0 });
|
|
361
369
|
case 'gltf-extension-unsupported':
|
|
362
370
|
return gltfErr(code, { extension: 'KHR_x', source: 'extensionsRequired' });
|
|
371
|
+
case 'gltf-lod-invalid':
|
|
372
|
+
return gltfErr(code, { rootNode: 0, ids: [1], reason: 'missing-node' });
|
|
363
373
|
case 'gltf-material-transmission-invalid':
|
|
364
374
|
return gltfErr(code, {
|
|
365
375
|
extension: 'KHR_materials_transmission',
|
|
@@ -367,6 +377,13 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
367
377
|
reason: 'range',
|
|
368
378
|
actual: 2,
|
|
369
379
|
});
|
|
380
|
+
case 'gltf-material-physical-invalid':
|
|
381
|
+
return gltfErr(code, {
|
|
382
|
+
extension: 'KHR_materials_clearcoat',
|
|
383
|
+
field: 'clearcoatFactor',
|
|
384
|
+
reason: 'range',
|
|
385
|
+
actual: 2,
|
|
386
|
+
});
|
|
370
387
|
case 'gltf-accessor-type-mismatch':
|
|
371
388
|
return gltfErr(code, { accessorIndex: 0, reason: 'sparse' });
|
|
372
389
|
case 'gltf-texture-load-failed':
|
|
@@ -448,6 +465,7 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
448
465
|
case 'gltf-mesh-bridge-invalid':
|
|
449
466
|
return gltfErr(code, { reason: 'empty-input', primitiveCount: 0 });
|
|
450
467
|
}
|
|
468
|
+
throw new Error(`unhandled glTF error code: ${code}`);
|
|
451
469
|
}
|
|
452
470
|
|
|
453
471
|
describe('errors.test.ts', () => {
|
|
@@ -456,8 +474,8 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
456
474
|
});
|
|
457
475
|
|
|
458
476
|
describe('GltfErrorCode roster', () => {
|
|
459
|
-
it('GLTF_ERROR_HINTS exposes exactly
|
|
460
|
-
expect(Object.keys(GLTF_ERROR_HINTS).length).toBe(
|
|
477
|
+
it('GLTF_ERROR_HINTS exposes exactly 25 keys', () => {
|
|
478
|
+
expect(Object.keys(GLTF_ERROR_HINTS).length).toBe(25);
|
|
461
479
|
});
|
|
462
480
|
|
|
463
481
|
it.each(ALL_CODES)('hint for %s is a non-empty string', (code) => {
|
|
@@ -1930,6 +1948,25 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
1930
1948
|
expect(map.get(0)).toBe('srgb');
|
|
1931
1949
|
});
|
|
1932
1950
|
|
|
1951
|
+
it('physical extension texture slots keep their glTF color domains', () => {
|
|
1952
|
+
const map = deriveTextureColorSpace({
|
|
1953
|
+
imageCount: 4,
|
|
1954
|
+
textures: [{ source: 0 }, { source: 1 }, { source: 2 }, { source: 3 }],
|
|
1955
|
+
materials: [
|
|
1956
|
+
{
|
|
1957
|
+
sheenColorTexture: 0,
|
|
1958
|
+
specularColorTexture: 1,
|
|
1959
|
+
anisotropyTexture: 2,
|
|
1960
|
+
thicknessTexture: 3,
|
|
1961
|
+
},
|
|
1962
|
+
],
|
|
1963
|
+
});
|
|
1964
|
+
expect(map.get(0)).toBe('srgb');
|
|
1965
|
+
expect(map.get(1)).toBe('srgb');
|
|
1966
|
+
expect(map.get(2)).toBe('linear');
|
|
1967
|
+
expect(map.get(3)).toBe('linear');
|
|
1968
|
+
});
|
|
1969
|
+
|
|
1933
1970
|
it('occlusionTexture image classifies as linear', () => {
|
|
1934
1971
|
const map = deriveTextureColorSpace({
|
|
1935
1972
|
imageCount: 1,
|
|
@@ -2019,8 +2056,21 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
2019
2056
|
stderrSpy.mockRestore();
|
|
2020
2057
|
});
|
|
2021
2058
|
|
|
2022
|
-
it('
|
|
2023
|
-
expect(EXTENSION_ALLOWLIST).toEqual([
|
|
2059
|
+
it('public allowlist contains every currently supported extension (literal)', () => {
|
|
2060
|
+
expect(EXTENSION_ALLOWLIST).toEqual([
|
|
2061
|
+
'EXT_mesh_gpu_instancing',
|
|
2062
|
+
'EXT_meshopt_compression',
|
|
2063
|
+
'KHR_lights_punctual',
|
|
2064
|
+
'KHR_texture_transform',
|
|
2065
|
+
'KHR_materials_transmission',
|
|
2066
|
+
'KHR_materials_ior',
|
|
2067
|
+
'KHR_materials_volume',
|
|
2068
|
+
'KHR_materials_clearcoat',
|
|
2069
|
+
'KHR_materials_anisotropy',
|
|
2070
|
+
'KHR_materials_sheen',
|
|
2071
|
+
'KHR_materials_iridescence',
|
|
2072
|
+
'KHR_materials_specular',
|
|
2073
|
+
]);
|
|
2024
2074
|
});
|
|
2025
2075
|
|
|
2026
2076
|
it('(a) rejects unsupported extensionsRequired entries', () => {
|
|
@@ -2086,6 +2136,11 @@ function unwrapReimport(result: ReturnType<typeof reimportReuseMeta>) {
|
|
|
2086
2136
|
'KHR_materials_transmission',
|
|
2087
2137
|
'KHR_materials_ior',
|
|
2088
2138
|
'KHR_materials_volume',
|
|
2139
|
+
'KHR_materials_clearcoat',
|
|
2140
|
+
'KHR_materials_anisotropy',
|
|
2141
|
+
'KHR_materials_sheen',
|
|
2142
|
+
'KHR_materials_iridescence',
|
|
2143
|
+
'KHR_materials_specular',
|
|
2089
2144
|
])('%s in extensionsRequired routes ok (supported)', (extension) => {
|
|
2090
2145
|
const result = checkExtensions({ extensionsRequired: [extension] });
|
|
2091
2146
|
expect(result.ok).toBe(true);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { parseGltfLodExtension } from '../lod/parse-lod.js';
|
|
4
|
+
|
|
5
|
+
async function fixture(name: string): Promise<Record<string, unknown>> {
|
|
6
|
+
return JSON.parse(
|
|
7
|
+
await readFile(new URL(`./fixtures/lod/${name}`, import.meta.url), 'utf8'),
|
|
8
|
+
) as Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('glTF MSFT_lod producer contract', () => {
|
|
12
|
+
it('adopts node-level ids in author order and suppresses lower nodes', async () => {
|
|
13
|
+
const json = await fixture('msft-lod.gltf');
|
|
14
|
+
const result = parseGltfLodExtension(json);
|
|
15
|
+
expect(result).toMatchObject({
|
|
16
|
+
ok: true,
|
|
17
|
+
value: { rootNode: 0, lodNodeIds: [1, 2], screenCoverages: [0.5, 0.2] },
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('adopts the official node extras coverage array and drops its terminal discard hint', async () => {
|
|
22
|
+
const json = await fixture('msft-lod-node-extras.gltf');
|
|
23
|
+
const result = parseGltfLodExtension(json);
|
|
24
|
+
expect(result).toMatchObject({
|
|
25
|
+
ok: true,
|
|
26
|
+
value: {
|
|
27
|
+
rootNode: 0,
|
|
28
|
+
lodNodeIds: [1, 2],
|
|
29
|
+
screenCoverages: [0.5, 0.2],
|
|
30
|
+
groups: [{ rootNode: 0, lodNodeIds: [1, 2], screenCoverages: [0.5, 0.2] }],
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('rejects an official node extras array whose root/level count is incomplete', () => {
|
|
36
|
+
expect(
|
|
37
|
+
parseGltfLodExtension({
|
|
38
|
+
meshes: [{ primitives: [{}] }, { primitives: [{}] }, { primitives: [{}] }],
|
|
39
|
+
nodes: [
|
|
40
|
+
{
|
|
41
|
+
extensions: { MSFT_lod: { ids: [1, 2] } },
|
|
42
|
+
extras: { MSFT_screencoverage: [0.5, 0.2] },
|
|
43
|
+
},
|
|
44
|
+
{},
|
|
45
|
+
{},
|
|
46
|
+
],
|
|
47
|
+
}),
|
|
48
|
+
).toMatchObject({ ok: false, error: { code: 'gltf-lod-invalid' } });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('fails closed when a required MSFT_lod extension has no normalizable group', () => {
|
|
52
|
+
expect(
|
|
53
|
+
parseGltfLodExtension({ extensionsRequired: ['MSFT_lod'], nodes: [{ mesh: 0 }] }),
|
|
54
|
+
).toMatchObject({ ok: false, error: { code: 'gltf-lod-invalid' } });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('requires every referenced node to resolve a mesh sub-asset', () => {
|
|
58
|
+
expect(
|
|
59
|
+
parseGltfLodExtension({
|
|
60
|
+
nodes: [{ mesh: 0, extensions: { MSFT_lod: { ids: [1] } } }, {}],
|
|
61
|
+
}),
|
|
62
|
+
).toMatchObject({ ok: false, error: { code: 'gltf-lod-invalid' } });
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('rejects a referenced mesh index outside the source mesh table', () => {
|
|
66
|
+
expect(
|
|
67
|
+
parseGltfLodExtension({
|
|
68
|
+
meshes: [{}],
|
|
69
|
+
nodes: [{ mesh: 0, extensions: { MSFT_lod: { ids: [1] } } }, { mesh: 2 }],
|
|
70
|
+
}),
|
|
71
|
+
).toMatchObject({ ok: false, error: { code: 'gltf-lod-invalid' } });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('rejects a referenced mesh with no primitives before publication', () => {
|
|
75
|
+
expect(
|
|
76
|
+
parseGltfLodExtension({
|
|
77
|
+
meshes: [{ primitives: [] }, { primitives: [{}] }],
|
|
78
|
+
nodes: [{ mesh: 0, extensions: { MSFT_lod: { ids: [1] } } }, { mesh: 1 }],
|
|
79
|
+
}),
|
|
80
|
+
).toMatchObject({ ok: false, error: { code: 'gltf-lod-invalid' } });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('rejects malformed required extension instead of loading only LOD0', async () => {
|
|
84
|
+
const json = await fixture('msft-lod-malformed.gltf');
|
|
85
|
+
expect(parseGltfLodExtension(json)).toMatchObject({
|
|
86
|
+
ok: false,
|
|
87
|
+
error: { code: 'gltf-lod-invalid' },
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('retains every node-level relation for multi-root scenes', async () => {
|
|
92
|
+
const json = await fixture('msft-lod-multi-root.gltf');
|
|
93
|
+
const result = parseGltfLodExtension(json);
|
|
94
|
+
expect(result).toMatchObject({
|
|
95
|
+
ok: true,
|
|
96
|
+
value: {
|
|
97
|
+
rootNode: 0,
|
|
98
|
+
lodNodeIds: [1, 2],
|
|
99
|
+
groups: [
|
|
100
|
+
{ rootNode: 0, lodNodeIds: [1, 2] },
|
|
101
|
+
{ rootNode: 3, lodNodeIds: [4, 5] },
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { projectGltfLodMeta } from '../lod/project-meta.js';
|
|
3
|
+
|
|
4
|
+
describe('glTF LOD Meta publication candidate', () => {
|
|
5
|
+
it('uses declared GUIDs and leaves publication to the shared host', () => {
|
|
6
|
+
const result = projectGltfLodMeta({
|
|
7
|
+
rootSourceKey: 'mesh/root',
|
|
8
|
+
levels: [
|
|
9
|
+
{ sourceKey: 'mesh/lod1', guid: 'guid-1' },
|
|
10
|
+
{ sourceKey: 'mesh/lod2', guid: 'guid-2' },
|
|
11
|
+
],
|
|
12
|
+
previous: undefined,
|
|
13
|
+
});
|
|
14
|
+
expect(result).toMatchObject({
|
|
15
|
+
ok: true,
|
|
16
|
+
value: {
|
|
17
|
+
lods: [
|
|
18
|
+
{ meshGuid: 'guid-1', screenCoverage: 0.5 },
|
|
19
|
+
{ meshGuid: 'guid-2', screenCoverage: 0.2 },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -67,4 +67,57 @@ describe('glTF material Pack refs', () => {
|
|
|
67
67
|
'sampler-6',
|
|
68
68
|
]);
|
|
69
69
|
});
|
|
70
|
+
|
|
71
|
+
it('keeps the five physical extension texture edges in producer slot order', () => {
|
|
72
|
+
const material = {
|
|
73
|
+
name: 'PhysicalPackMaterial',
|
|
74
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
75
|
+
metallicFactor: 0,
|
|
76
|
+
roughnessFactor: 0.5,
|
|
77
|
+
clearcoatNormalTexture: { texture: 0, sampler: 0 },
|
|
78
|
+
anisotropyTexture: { texture: 1, sampler: 1 },
|
|
79
|
+
sheenColorTexture: { texture: 2, sampler: 2 },
|
|
80
|
+
iridescenceTexture: { texture: 3, sampler: 3 },
|
|
81
|
+
specularColorTexture: { texture: 4, sampler: 4 },
|
|
82
|
+
} as unknown as GltfMaterialIr;
|
|
83
|
+
const doc = {
|
|
84
|
+
textures: [
|
|
85
|
+
{ source: 0, sampler: 0 },
|
|
86
|
+
{ source: 1, sampler: 1 },
|
|
87
|
+
{ source: 2, sampler: 2 },
|
|
88
|
+
{ source: 3, sampler: 3 },
|
|
89
|
+
{ source: 4, sampler: 4 },
|
|
90
|
+
],
|
|
91
|
+
} as unknown as GltfDoc;
|
|
92
|
+
const refs = materialRefsForPack(
|
|
93
|
+
material,
|
|
94
|
+
doc,
|
|
95
|
+
new Map([
|
|
96
|
+
[0, 'clearcoat-normal-texture'],
|
|
97
|
+
[1, 'anisotropy-texture'],
|
|
98
|
+
[2, 'sheen-color-texture'],
|
|
99
|
+
[3, 'iridescence-texture'],
|
|
100
|
+
[4, 'specular-color-texture'],
|
|
101
|
+
]),
|
|
102
|
+
new Map([
|
|
103
|
+
[0, 'clearcoat-normal-sampler'],
|
|
104
|
+
[1, 'anisotropy-sampler'],
|
|
105
|
+
[2, 'sheen-color-sampler'],
|
|
106
|
+
[3, 'iridescence-sampler'],
|
|
107
|
+
[4, 'specular-color-sampler'],
|
|
108
|
+
]),
|
|
109
|
+
);
|
|
110
|
+
expect(refs.map((ref) => ref.guid)).toEqual([
|
|
111
|
+
'clearcoat-normal-texture',
|
|
112
|
+
'clearcoat-normal-sampler',
|
|
113
|
+
'anisotropy-texture',
|
|
114
|
+
'anisotropy-sampler',
|
|
115
|
+
'sheen-color-texture',
|
|
116
|
+
'sheen-color-sampler',
|
|
117
|
+
'iridescence-texture',
|
|
118
|
+
'iridescence-sampler',
|
|
119
|
+
'specular-color-texture',
|
|
120
|
+
'specular-color-sampler',
|
|
121
|
+
]);
|
|
122
|
+
});
|
|
70
123
|
});
|