@aura3d/assets 1.0.6
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 +17 -0
- package/dist/AdvancedAssetCorpus.d.ts +124 -0
- package/dist/AdvancedAssetCorpus.d.ts.map +1 -0
- package/dist/AdvancedAssetCorpus.js +266 -0
- package/dist/AdvancedAssetCorpus.js.map +1 -0
- package/dist/AssetBundleCacheFixtures.d.ts +62 -0
- package/dist/AssetBundleCacheFixtures.d.ts.map +1 -0
- package/dist/AssetBundleCacheFixtures.js +222 -0
- package/dist/AssetBundleCacheFixtures.js.map +1 -0
- package/dist/AssetCache.d.ts +21 -0
- package/dist/AssetCache.d.ts.map +1 -0
- package/dist/AssetCache.js +54 -0
- package/dist/AssetCache.js.map +1 -0
- package/dist/AssetCompatibility.d.ts +54 -0
- package/dist/AssetCompatibility.d.ts.map +1 -0
- package/dist/AssetCompatibility.js +122 -0
- package/dist/AssetCompatibility.js.map +1 -0
- package/dist/AssetCorpus.d.ts +88 -0
- package/dist/AssetCorpus.d.ts.map +1 -0
- package/dist/AssetCorpus.js +215 -0
- package/dist/AssetCorpus.js.map +1 -0
- package/dist/AssetDependencyGraph.d.ts +12 -0
- package/dist/AssetDependencyGraph.d.ts.map +1 -0
- package/dist/AssetDependencyGraph.js +66 -0
- package/dist/AssetDependencyGraph.js.map +1 -0
- package/dist/AssetHandle.d.ts +26 -0
- package/dist/AssetHandle.d.ts.map +1 -0
- package/dist/AssetHandle.js +53 -0
- package/dist/AssetHandle.js.map +1 -0
- package/dist/AssetImportPreflight.d.ts +43 -0
- package/dist/AssetImportPreflight.d.ts.map +1 -0
- package/dist/AssetImportPreflight.js +117 -0
- package/dist/AssetImportPreflight.js.map +1 -0
- package/dist/AssetInspection.d.ts +183 -0
- package/dist/AssetInspection.d.ts.map +1 -0
- package/dist/AssetInspection.js +397 -0
- package/dist/AssetInspection.js.map +1 -0
- package/dist/AssetLoader.d.ts +26 -0
- package/dist/AssetLoader.d.ts.map +1 -0
- package/dist/AssetLoader.js +12 -0
- package/dist/AssetLoader.js.map +1 -0
- package/dist/AssetManager.d.ts +37 -0
- package/dist/AssetManager.d.ts.map +1 -0
- package/dist/AssetManager.js +161 -0
- package/dist/AssetManager.js.map +1 -0
- package/dist/AssetRegistry.d.ts +10 -0
- package/dist/AssetRegistry.d.ts.map +1 -0
- package/dist/AssetRegistry.js +34 -0
- package/dist/AssetRegistry.js.map +1 -0
- package/dist/AssetRenderDefaults.d.ts +13 -0
- package/dist/AssetRenderDefaults.d.ts.map +1 -0
- package/dist/AssetRenderDefaults.js +23 -0
- package/dist/AssetRenderDefaults.js.map +1 -0
- package/dist/AudioLoader.d.ts +17 -0
- package/dist/AudioLoader.d.ts.map +1 -0
- package/dist/AudioLoader.js +23 -0
- package/dist/AudioLoader.js.map +1 -0
- package/dist/BlenderExportValidation.d.ts +64 -0
- package/dist/BlenderExportValidation.d.ts.map +1 -0
- package/dist/BlenderExportValidation.js +143 -0
- package/dist/BlenderExportValidation.js.map +1 -0
- package/dist/CarConceptMaterialStability.d.ts +28 -0
- package/dist/CarConceptMaterialStability.d.ts.map +1 -0
- package/dist/CarConceptMaterialStability.js +1308 -0
- package/dist/CarConceptMaterialStability.js.map +1 -0
- package/dist/EXRLoader.d.ts +2 -0
- package/dist/EXRLoader.d.ts.map +1 -0
- package/dist/EXRLoader.js +2 -0
- package/dist/EXRLoader.js.map +1 -0
- package/dist/ExternalParityGLTFCorpus.d.ts +39 -0
- package/dist/ExternalParityGLTFCorpus.d.ts.map +1 -0
- package/dist/ExternalParityGLTFCorpus.js +32 -0
- package/dist/ExternalParityGLTFCorpus.js.map +1 -0
- package/dist/GLTFAnimationRuntime.d.ts +243 -0
- package/dist/GLTFAnimationRuntime.d.ts.map +1 -0
- package/dist/GLTFAnimationRuntime.js +954 -0
- package/dist/GLTFAnimationRuntime.js.map +1 -0
- package/dist/GLTFCompressionDecoders.d.ts +42 -0
- package/dist/GLTFCompressionDecoders.d.ts.map +1 -0
- package/dist/GLTFCompressionDecoders.js +99 -0
- package/dist/GLTFCompressionDecoders.js.map +1 -0
- package/dist/GLTFExtensionSupport.d.ts +33 -0
- package/dist/GLTFExtensionSupport.d.ts.map +1 -0
- package/dist/GLTFExtensionSupport.js +85 -0
- package/dist/GLTFExtensionSupport.js.map +1 -0
- package/dist/GLTFLoader.d.ts +361 -0
- package/dist/GLTFLoader.d.ts.map +1 -0
- package/dist/GLTFLoader.js +2735 -0
- package/dist/GLTFLoader.js.map +1 -0
- package/dist/GLTFRenderResources.d.ts +162 -0
- package/dist/GLTFRenderResources.d.ts.map +1 -0
- package/dist/GLTFRenderResources.js +1684 -0
- package/dist/GLTFRenderResources.js.map +1 -0
- package/dist/HDRLoader.d.ts +2 -0
- package/dist/HDRLoader.d.ts.map +1 -0
- package/dist/HDRLoader.js +2 -0
- package/dist/HDRLoader.js.map +1 -0
- package/dist/ImageLoader.d.ts +15 -0
- package/dist/ImageLoader.d.ts.map +1 -0
- package/dist/ImageLoader.js +36 -0
- package/dist/ImageLoader.js.map +1 -0
- package/dist/ImportPipeline.d.ts +39 -0
- package/dist/ImportPipeline.d.ts.map +1 -0
- package/dist/ImportPipeline.js +105 -0
- package/dist/ImportPipeline.js.map +1 -0
- package/dist/KTX2BasisTextureTranscoder.d.ts +9 -0
- package/dist/KTX2BasisTextureTranscoder.d.ts.map +1 -0
- package/dist/KTX2BasisTextureTranscoder.js +178 -0
- package/dist/KTX2BasisTextureTranscoder.js.map +1 -0
- package/dist/LoadContext.d.ts +20 -0
- package/dist/LoadContext.d.ts.map +1 -0
- package/dist/LoadContext.js +42 -0
- package/dist/LoadContext.js.map +1 -0
- package/dist/MaterialLoader.d.ts +17 -0
- package/dist/MaterialLoader.d.ts.map +1 -0
- package/dist/MaterialLoader.js +138 -0
- package/dist/MaterialLoader.js.map +1 -0
- package/dist/MeshOptimization.d.ts +20 -0
- package/dist/MeshOptimization.d.ts.map +1 -0
- package/dist/MeshOptimization.js +65 -0
- package/dist/MeshOptimization.js.map +1 -0
- package/dist/OBJLoader.d.ts +13 -0
- package/dist/OBJLoader.d.ts.map +1 -0
- package/dist/OBJLoader.js +492 -0
- package/dist/OBJLoader.js.map +1 -0
- package/dist/SceneAnalysisFixtures.d.ts +100 -0
- package/dist/SceneAnalysisFixtures.d.ts.map +1 -0
- package/dist/SceneAnalysisFixtures.js +331 -0
- package/dist/SceneAnalysisFixtures.js.map +1 -0
- package/dist/SceneLoader.d.ts +27 -0
- package/dist/SceneLoader.d.ts.map +1 -0
- package/dist/SceneLoader.js +40 -0
- package/dist/SceneLoader.js.map +1 -0
- package/dist/ShaderLoader.d.ts +12 -0
- package/dist/ShaderLoader.d.ts.map +1 -0
- package/dist/ShaderLoader.js +18 -0
- package/dist/ShaderLoader.js.map +1 -0
- package/dist/TextureLoader.d.ts +16 -0
- package/dist/TextureLoader.d.ts.map +1 -0
- package/dist/TextureLoader.js +17 -0
- package/dist/TextureLoader.js.map +1 -0
- package/dist/TexturePipeline.d.ts +24 -0
- package/dist/TexturePipeline.d.ts.map +1 -0
- package/dist/TexturePipeline.js +64 -0
- package/dist/TexturePipeline.js.map +1 -0
- package/dist/TextureStreaming.d.ts +10 -0
- package/dist/TextureStreaming.d.ts.map +1 -0
- package/dist/TextureStreaming.js +11 -0
- package/dist/TextureStreaming.js.map +1 -0
- package/dist/WorkerAssetJobs.d.ts +18 -0
- package/dist/WorkerAssetJobs.d.ts.map +1 -0
- package/dist/WorkerAssetJobs.js +37 -0
- package/dist/WorkerAssetJobs.js.map +1 -0
- package/dist/advanced-gallery/index.d.ts +3 -0
- package/dist/advanced-gallery/index.d.ts.map +1 -0
- package/dist/advanced-gallery/index.js +2 -0
- package/dist/advanced-gallery/index.js.map +1 -0
- package/dist/asset-corpus/GLTFSceneLoader.d.ts +3 -0
- package/dist/asset-corpus/GLTFSceneLoader.d.ts.map +1 -0
- package/dist/asset-corpus/GLTFSceneLoader.js +2 -0
- package/dist/asset-corpus/GLTFSceneLoader.js.map +1 -0
- package/dist/asset-corpus/ProductionAssetCorpus.d.ts +89 -0
- package/dist/asset-corpus/ProductionAssetCorpus.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionAssetCorpus.js +116 -0
- package/dist/asset-corpus/ProductionAssetCorpus.js.map +1 -0
- package/dist/asset-corpus/ProductionAssetPipeline.d.ts +3 -0
- package/dist/asset-corpus/ProductionAssetPipeline.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionAssetPipeline.js +3 -0
- package/dist/asset-corpus/ProductionAssetPipeline.js.map +1 -0
- package/dist/asset-corpus/ProductionGLTFRenderPipeline.d.ts +65 -0
- package/dist/asset-corpus/ProductionGLTFRenderPipeline.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionGLTFRenderPipeline.js +110 -0
- package/dist/asset-corpus/ProductionGLTFRenderPipeline.js.map +1 -0
- package/dist/asset-corpus/ProductionHDRTextureLoader.d.ts +8 -0
- package/dist/asset-corpus/ProductionHDRTextureLoader.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionHDRTextureLoader.js +2 -0
- package/dist/asset-corpus/ProductionHDRTextureLoader.js.map +1 -0
- package/dist/asset-corpus/ProductionKTX2TextureLoader.d.ts +7 -0
- package/dist/asset-corpus/ProductionKTX2TextureLoader.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionKTX2TextureLoader.js +2 -0
- package/dist/asset-corpus/ProductionKTX2TextureLoader.js.map +1 -0
- package/dist/asset-corpus/ProductionTextureLoader.d.ts +7 -0
- package/dist/asset-corpus/ProductionTextureLoader.d.ts.map +1 -0
- package/dist/asset-corpus/ProductionTextureLoader.js +2 -0
- package/dist/asset-corpus/ProductionTextureLoader.js.map +1 -0
- package/dist/asset-corpus/index.d.ts +10 -0
- package/dist/asset-corpus/index.d.ts.map +1 -0
- package/dist/asset-corpus/index.js +8 -0
- package/dist/asset-corpus/index.js.map +1 -0
- package/dist/browser-index.d.ts +48 -0
- package/dist/browser-index.d.ts.map +1 -0
- package/dist/browser-index.js +26 -0
- package/dist/browser-index.js.map +1 -0
- package/dist/createRenderableScene.d.ts +23 -0
- package/dist/createRenderableScene.d.ts.map +1 -0
- package/dist/createRenderableScene.js +94 -0
- package/dist/createRenderableScene.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/loadRenderableAsset.d.ts +16 -0
- package/dist/loadRenderableAsset.d.ts.map +1 -0
- package/dist/loadRenderableAsset.js +50 -0
- package/dist/loadRenderableAsset.js.map +1 -0
- package/dist/loaders/CubeTextureLoader.d.ts +4 -0
- package/dist/loaders/CubeTextureLoader.d.ts.map +1 -0
- package/dist/loaders/CubeTextureLoader.js +9 -0
- package/dist/loaders/CubeTextureLoader.js.map +1 -0
- package/dist/loaders/EXRLoader.d.ts +4 -0
- package/dist/loaders/EXRLoader.d.ts.map +1 -0
- package/dist/loaders/EXRLoader.js +10 -0
- package/dist/loaders/EXRLoader.js.map +1 -0
- package/dist/loaders/HDRLoader.d.ts +4 -0
- package/dist/loaders/HDRLoader.d.ts.map +1 -0
- package/dist/loaders/HDRLoader.js +7 -0
- package/dist/loaders/HDRLoader.js.map +1 -0
- package/dist/loaders/KTX2Loader.d.ts +4 -0
- package/dist/loaders/KTX2Loader.d.ts.map +1 -0
- package/dist/loaders/KTX2Loader.js +7 -0
- package/dist/loaders/KTX2Loader.js.map +1 -0
- package/dist/loaders/LoaderDiagnostics.d.ts +18 -0
- package/dist/loaders/LoaderDiagnostics.d.ts.map +1 -0
- package/dist/loaders/LoaderDiagnostics.js +18 -0
- package/dist/loaders/LoaderDiagnostics.js.map +1 -0
- package/dist/loaders/MTLLoader.d.ts +10 -0
- package/dist/loaders/MTLLoader.d.ts.map +1 -0
- package/dist/loaders/MTLLoader.js +14 -0
- package/dist/loaders/MTLLoader.js.map +1 -0
- package/dist/loaders/OBJLoader.d.ts +12 -0
- package/dist/loaders/OBJLoader.d.ts.map +1 -0
- package/dist/loaders/OBJLoader.js +16 -0
- package/dist/loaders/OBJLoader.js.map +1 -0
- package/dist/loaders/TextureLoader.d.ts +6 -0
- package/dist/loaders/TextureLoader.d.ts.map +1 -0
- package/dist/loaders/TextureLoader.js +11 -0
- package/dist/loaders/TextureLoader.js.map +1 -0
- package/dist/loaders/ThreeCompatGLTFLoader.d.ts +10 -0
- package/dist/loaders/ThreeCompatGLTFLoader.d.ts.map +1 -0
- package/dist/loaders/ThreeCompatGLTFLoader.js +13 -0
- package/dist/loaders/ThreeCompatGLTFLoader.js.map +1 -0
- package/dist/loaders/index.d.ts +15 -0
- package/dist/loaders/index.d.ts.map +1 -0
- package/dist/loaders/index.js +10 -0
- package/dist/loaders/index.js.map +1 -0
- package/dist/threejs-compatibility/ThreeCompatAssetProvenance.d.ts +34 -0
- package/dist/threejs-compatibility/ThreeCompatAssetProvenance.d.ts.map +1 -0
- package/dist/threejs-compatibility/ThreeCompatAssetProvenance.js +16 -0
- package/dist/threejs-compatibility/ThreeCompatAssetProvenance.js.map +1 -0
- package/dist/threejs-compatibility/ThreeCompatAssetRegistry.d.ts +29 -0
- package/dist/threejs-compatibility/ThreeCompatAssetRegistry.d.ts.map +1 -0
- package/dist/threejs-compatibility/ThreeCompatAssetRegistry.js +33 -0
- package/dist/threejs-compatibility/ThreeCompatAssetRegistry.js.map +1 -0
- package/dist/threejs-example-parity/index.d.ts +20 -0
- package/dist/threejs-example-parity/index.d.ts.map +1 -0
- package/dist/threejs-example-parity/index.js +218 -0
- package/dist/threejs-example-parity/index.js.map +1 -0
- package/package.json +23 -0
- package/src/AdvancedAssetCorpus.ts +454 -0
- package/src/AssetBundleCacheFixtures.ts +290 -0
- package/src/AssetCache.ts +76 -0
- package/src/AssetCompatibility.ts +224 -0
- package/src/AssetCorpus.ts +329 -0
- package/src/AssetDependencyGraph.ts +83 -0
- package/src/AssetHandle.ts +74 -0
- package/src/AssetImportPreflight.ts +179 -0
- package/src/AssetInspection.ts +706 -0
- package/src/AssetLoader.ts +36 -0
- package/src/AssetManager.ts +211 -0
- package/src/AssetRegistry.ts +44 -0
- package/src/AssetRenderDefaults.ts +36 -0
- package/src/AudioLoader.ts +41 -0
- package/src/BlenderExportValidation.ts +227 -0
- package/src/CarConceptMaterialStability.ts +1405 -0
- package/src/EXRLoader.ts +1 -0
- package/src/ExternalParityGLTFCorpus.ts +65 -0
- package/src/GLTFAnimationRuntime.ts +1221 -0
- package/src/GLTFCompressionDecoders.ts +190 -0
- package/src/GLTFExtensionSupport.ts +138 -0
- package/src/GLTFLoader.ts +4001 -0
- package/src/GLTFRenderResources.ts +2105 -0
- package/src/HDRLoader.ts +1 -0
- package/src/ImageLoader.ts +52 -0
- package/src/ImportPipeline.ts +148 -0
- package/src/KTX2BasisTextureTranscoder.ts +224 -0
- package/src/LoadContext.ts +60 -0
- package/src/MaterialLoader.ts +166 -0
- package/src/MeshOptimization.ts +93 -0
- package/src/OBJLoader.ts +551 -0
- package/src/SceneAnalysisFixtures.ts +438 -0
- package/src/SceneLoader.ts +62 -0
- package/src/ShaderLoader.ts +30 -0
- package/src/TextureLoader.ts +30 -0
- package/src/TexturePipeline.ts +96 -0
- package/src/TextureStreaming.ts +20 -0
- package/src/WorkerAssetJobs.ts +56 -0
- package/src/advanced-gallery/index.ts +18 -0
- package/src/asset-corpus/GLTFSceneLoader.ts +9 -0
- package/src/asset-corpus/ProductionAssetCorpus.ts +230 -0
- package/src/asset-corpus/ProductionAssetPipeline.ts +5 -0
- package/src/asset-corpus/ProductionGLTFRenderPipeline.ts +182 -0
- package/src/asset-corpus/ProductionHDRTextureLoader.ts +2 -0
- package/src/asset-corpus/ProductionKTX2TextureLoader.ts +2 -0
- package/src/asset-corpus/ProductionTextureLoader.ts +2 -0
- package/src/asset-corpus/index.ts +29 -0
- package/src/browser-index.ts +224 -0
- package/src/createRenderableScene.ts +128 -0
- package/src/index.ts +317 -0
- package/src/loadRenderableAsset.ts +67 -0
- package/src/loaders/CubeTextureLoader.ts +8 -0
- package/src/loaders/EXRLoader.ts +10 -0
- package/src/loaders/HDRLoader.ts +7 -0
- package/src/loaders/KTX2Loader.ts +7 -0
- package/src/loaders/LoaderDiagnostics.ts +36 -0
- package/src/loaders/MTLLoader.ts +20 -0
- package/src/loaders/OBJLoader.ts +24 -0
- package/src/loaders/TextureLoader.ts +14 -0
- package/src/loaders/ThreeCompatGLTFLoader.ts +19 -0
- package/src/loaders/index.ts +14 -0
- package/src/threejs-compatibility/ThreeCompatAssetProvenance.ts +51 -0
- package/src/threejs-compatibility/ThreeCompatAssetRegistry.ts +61 -0
- package/src/threejs-example-parity/index.ts +262 -0
- package/tests/assets.test.ts +311 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const GLB_MAGIC = 0x46546c67;
|
|
6
|
+
const JSON_CHUNK_TYPE = 0x4e4f534a;
|
|
7
|
+
|
|
8
|
+
export type CurrentRoutesAssetClass =
|
|
9
|
+
| "product"
|
|
10
|
+
| "automotive"
|
|
11
|
+
| "character"
|
|
12
|
+
| "animation"
|
|
13
|
+
| "materials"
|
|
14
|
+
| "architecture"
|
|
15
|
+
| "physics";
|
|
16
|
+
|
|
17
|
+
export interface CurrentRoutesAssetRequirement {
|
|
18
|
+
readonly minimumAssetCount: number;
|
|
19
|
+
readonly minimumTotalBytes: number;
|
|
20
|
+
readonly minimumTotalTriangles: number;
|
|
21
|
+
readonly minimumTexturedPbrAssets: number;
|
|
22
|
+
readonly minimumAnimationAssets: number;
|
|
23
|
+
readonly minimumSkinAssets: number;
|
|
24
|
+
readonly minimumMorphAssets: number;
|
|
25
|
+
readonly minimumMaterialExtensionAssets: number;
|
|
26
|
+
readonly requiredClasses: readonly CurrentRoutesAssetClass[];
|
|
27
|
+
readonly requiredFeatures: readonly string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CurrentRoutesAssetManifestEntry {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly class: CurrentRoutesAssetClass;
|
|
34
|
+
readonly role: string;
|
|
35
|
+
readonly localPath: string;
|
|
36
|
+
readonly source: string;
|
|
37
|
+
readonly sourceUri: string;
|
|
38
|
+
readonly license: string;
|
|
39
|
+
readonly sha256: string;
|
|
40
|
+
readonly bytes: number;
|
|
41
|
+
readonly triangleCount: number;
|
|
42
|
+
readonly textureCount: number;
|
|
43
|
+
readonly animationCount: number;
|
|
44
|
+
readonly skinCount: number;
|
|
45
|
+
readonly morphTargetCount: number;
|
|
46
|
+
readonly materialExtensionCount: number;
|
|
47
|
+
readonly tags: readonly string[];
|
|
48
|
+
readonly requiredFeatures: readonly string[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface CurrentRoutesEnvironmentManifestEntry {
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly localPath: string;
|
|
55
|
+
readonly source: string;
|
|
56
|
+
readonly sourceUri: string;
|
|
57
|
+
readonly license: string;
|
|
58
|
+
readonly sha256: string;
|
|
59
|
+
readonly bytes: number;
|
|
60
|
+
readonly tags: readonly string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface CurrentRoutesAssetManifest {
|
|
64
|
+
readonly schema: "a3d-current-routes-local-asset-corpus";
|
|
65
|
+
readonly claimBoundary: string;
|
|
66
|
+
readonly requirements: CurrentRoutesAssetRequirement;
|
|
67
|
+
readonly assets: readonly CurrentRoutesAssetManifestEntry[];
|
|
68
|
+
readonly environments: readonly CurrentRoutesEnvironmentManifestEntry[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CurrentRoutesGlbInspection {
|
|
72
|
+
readonly validGlb: boolean;
|
|
73
|
+
readonly version: number;
|
|
74
|
+
readonly jsonChunkBytes: number;
|
|
75
|
+
readonly sceneCount: number;
|
|
76
|
+
readonly nodeCount: number;
|
|
77
|
+
readonly meshCount: number;
|
|
78
|
+
readonly primitiveCount: number;
|
|
79
|
+
readonly vertexCount: number;
|
|
80
|
+
readonly triangleCount: number;
|
|
81
|
+
readonly materialCount: number;
|
|
82
|
+
readonly texturedPbrMaterialCount: number;
|
|
83
|
+
readonly textureCount: number;
|
|
84
|
+
readonly imageCount: number;
|
|
85
|
+
readonly animationCount: number;
|
|
86
|
+
readonly animationChannelCount: number;
|
|
87
|
+
readonly animationSamplerCount: number;
|
|
88
|
+
readonly skinCount: number;
|
|
89
|
+
readonly jointCount: number;
|
|
90
|
+
readonly morphTargetPrimitiveCount: number;
|
|
91
|
+
readonly morphTargetCount: number;
|
|
92
|
+
readonly materialExtensionCount: number;
|
|
93
|
+
readonly materialTextureSlotCount: number;
|
|
94
|
+
readonly textureTransformCount: number;
|
|
95
|
+
readonly materialVariantCount: number;
|
|
96
|
+
readonly extensionsUsed: readonly string[];
|
|
97
|
+
readonly extensionsRequired: readonly string[];
|
|
98
|
+
readonly features: readonly string[];
|
|
99
|
+
readonly unsupportedRequiredExtensions: readonly string[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface CurrentRoutesAssetReadinessEntry {
|
|
103
|
+
readonly id: string;
|
|
104
|
+
readonly localPath: string;
|
|
105
|
+
readonly exists: boolean;
|
|
106
|
+
readonly bytesMatch: boolean;
|
|
107
|
+
readonly sha256Matches: boolean;
|
|
108
|
+
readonly missingDeclaredFields: readonly string[];
|
|
109
|
+
readonly missingRequiredFeatures: readonly string[];
|
|
110
|
+
readonly inspection: CurrentRoutesGlbInspection | null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface CurrentRoutesEnvironmentReadinessEntry {
|
|
114
|
+
readonly id: string;
|
|
115
|
+
readonly localPath: string;
|
|
116
|
+
readonly exists: boolean;
|
|
117
|
+
readonly bytesMatch: boolean;
|
|
118
|
+
readonly sha256Matches: boolean;
|
|
119
|
+
readonly bytes: number;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface AdvancedAssetCorpusSummary {
|
|
123
|
+
readonly schema: "a3d-current-routes-asset-readiness";
|
|
124
|
+
readonly pass: boolean;
|
|
125
|
+
readonly assetCount: number;
|
|
126
|
+
readonly environmentCount: number;
|
|
127
|
+
readonly existingAssetCount: number;
|
|
128
|
+
readonly shaVerifiedAssetCount: number;
|
|
129
|
+
readonly totalBytes: number;
|
|
130
|
+
readonly totalTriangles: number;
|
|
131
|
+
readonly texturedPbrAssetCount: number;
|
|
132
|
+
readonly animationAssetCount: number;
|
|
133
|
+
readonly skinAssetCount: number;
|
|
134
|
+
readonly morphAssetCount: number;
|
|
135
|
+
readonly materialExtensionAssetCount: number;
|
|
136
|
+
readonly classCoverage: readonly CurrentRoutesAssetClass[];
|
|
137
|
+
readonly featureCoverage: readonly string[];
|
|
138
|
+
readonly failures: readonly string[];
|
|
139
|
+
readonly entries: readonly CurrentRoutesAssetReadinessEntry[];
|
|
140
|
+
readonly environments: readonly CurrentRoutesEnvironmentReadinessEntry[];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type GLTFJson = {
|
|
144
|
+
readonly scenes?: readonly unknown[];
|
|
145
|
+
readonly nodes?: readonly { readonly mesh?: number; readonly skin?: number }[];
|
|
146
|
+
readonly meshes?: readonly {
|
|
147
|
+
readonly primitives?: readonly {
|
|
148
|
+
readonly attributes?: Readonly<Record<string, number>>;
|
|
149
|
+
readonly indices?: number;
|
|
150
|
+
readonly material?: number;
|
|
151
|
+
readonly mode?: number;
|
|
152
|
+
readonly targets?: readonly Readonly<Record<string, number>>[];
|
|
153
|
+
readonly extensions?: Record<string, unknown>;
|
|
154
|
+
}[];
|
|
155
|
+
}[];
|
|
156
|
+
readonly accessors?: readonly { readonly count?: number }[];
|
|
157
|
+
readonly materials?: readonly {
|
|
158
|
+
readonly pbrMetallicRoughness?: {
|
|
159
|
+
readonly baseColorTexture?: TextureInfo;
|
|
160
|
+
readonly metallicRoughnessTexture?: TextureInfo;
|
|
161
|
+
};
|
|
162
|
+
readonly normalTexture?: TextureInfo;
|
|
163
|
+
readonly occlusionTexture?: TextureInfo;
|
|
164
|
+
readonly emissiveTexture?: TextureInfo;
|
|
165
|
+
readonly extensions?: Record<string, unknown>;
|
|
166
|
+
}[];
|
|
167
|
+
readonly textures?: readonly unknown[];
|
|
168
|
+
readonly images?: readonly unknown[];
|
|
169
|
+
readonly animations?: readonly {
|
|
170
|
+
readonly channels?: readonly { readonly target?: { readonly path?: string } }[];
|
|
171
|
+
readonly samplers?: readonly { readonly interpolation?: string }[];
|
|
172
|
+
}[];
|
|
173
|
+
readonly skins?: readonly { readonly joints?: readonly number[] }[];
|
|
174
|
+
readonly extensionsUsed?: readonly string[];
|
|
175
|
+
readonly extensionsRequired?: readonly string[];
|
|
176
|
+
readonly extensions?: Record<string, unknown>;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
type TextureInfo = {
|
|
180
|
+
readonly index?: number;
|
|
181
|
+
readonly extensions?: {
|
|
182
|
+
readonly KHR_texture_transform?: unknown;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const SUPPORTED_REQUIRED_EXTENSIONS = new Set([
|
|
187
|
+
"KHR_lights_punctual",
|
|
188
|
+
"KHR_materials_anisotropy",
|
|
189
|
+
"KHR_materials_clearcoat",
|
|
190
|
+
"KHR_materials_diffuse_transmission",
|
|
191
|
+
"KHR_materials_dispersion",
|
|
192
|
+
"KHR_materials_emissive_strength",
|
|
193
|
+
"KHR_materials_ior",
|
|
194
|
+
"KHR_materials_iridescence",
|
|
195
|
+
"KHR_materials_pbrSpecularGlossiness",
|
|
196
|
+
"KHR_materials_sheen",
|
|
197
|
+
"KHR_materials_specular",
|
|
198
|
+
"KHR_materials_transmission",
|
|
199
|
+
"KHR_materials_unlit",
|
|
200
|
+
"KHR_materials_variants",
|
|
201
|
+
"KHR_materials_volume",
|
|
202
|
+
"KHR_mesh_quantization",
|
|
203
|
+
"KHR_texture_transform"
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
export function loadCurrentRoutesAssetManifest(path = "fixtures/threejs-parity/assets/manifest.json"): CurrentRoutesAssetManifest {
|
|
207
|
+
return JSON.parse(readFileSync(resolve(path), "utf8")) as CurrentRoutesAssetManifest;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function inspectCurrentRoutesGlb(path: string): CurrentRoutesGlbInspection {
|
|
211
|
+
const data = readFileSync(resolve(path));
|
|
212
|
+
if (data.byteLength < 20 || data.readUInt32LE(0) !== GLB_MAGIC) {
|
|
213
|
+
throw new Error(`Not a GLB file: ${path}`);
|
|
214
|
+
}
|
|
215
|
+
const version = data.readUInt32LE(4);
|
|
216
|
+
const jsonChunkBytes = data.readUInt32LE(12);
|
|
217
|
+
const jsonChunkType = data.readUInt32LE(16);
|
|
218
|
+
if (jsonChunkType !== JSON_CHUNK_TYPE) {
|
|
219
|
+
throw new Error(`GLB missing JSON chunk: ${path}`);
|
|
220
|
+
}
|
|
221
|
+
const gltf = JSON.parse(data.toString("utf8", 20, 20 + jsonChunkBytes).trim()) as GLTFJson;
|
|
222
|
+
const meshes = gltf.meshes ?? [];
|
|
223
|
+
const materials = gltf.materials ?? [];
|
|
224
|
+
const primitives = meshes.flatMap((mesh) => mesh.primitives ?? []);
|
|
225
|
+
const textureInfos = materials.flatMap((material) => collectMaterialTextureInfos(material));
|
|
226
|
+
const extensionsUsed = [
|
|
227
|
+
...new Set([
|
|
228
|
+
...(gltf.extensionsUsed ?? []),
|
|
229
|
+
...materials.flatMap((material) => Object.keys(material.extensions ?? {})),
|
|
230
|
+
...primitives.flatMap((primitive) => Object.keys(primitive.extensions ?? {}))
|
|
231
|
+
])
|
|
232
|
+
].sort();
|
|
233
|
+
const materialVariantCount = countMaterialVariants(gltf);
|
|
234
|
+
const materialExtensionCount = materials.reduce((total, material) => total + Object.keys(material.extensions ?? {}).length, 0);
|
|
235
|
+
const textureTransformCount = textureInfos.filter((textureInfo) => Boolean(textureInfo.extensions?.KHR_texture_transform)).length;
|
|
236
|
+
const animationChannelCount = (gltf.animations ?? []).reduce((total, animation) => total + (animation.channels?.length ?? 0), 0);
|
|
237
|
+
const animationSamplerCount = (gltf.animations ?? []).reduce((total, animation) => total + (animation.samplers?.length ?? 0), 0);
|
|
238
|
+
const morphTargetCounts = primitives.map((primitive) => primitive.targets?.length ?? 0);
|
|
239
|
+
const skinJointCounts = (gltf.skins ?? []).map((skin) => skin.joints?.length ?? 0);
|
|
240
|
+
const vertexCount = primitives.reduce((total, primitive) => total + accessorCount(gltf, primitive.attributes?.POSITION), 0);
|
|
241
|
+
const triangleCount = primitives.reduce((total, primitive) => total + primitiveTriangleCount(gltf, primitive), 0);
|
|
242
|
+
const unsupportedRequiredExtensions = (gltf.extensionsRequired ?? []).filter((extension) => !SUPPORTED_REQUIRED_EXTENSIONS.has(extension));
|
|
243
|
+
const features = [
|
|
244
|
+
...(triangleCount > 1000 ? ["real-geometry"] : []),
|
|
245
|
+
...(materials.length > 0 ? ["materials"] : []),
|
|
246
|
+
...(textureInfos.length > 0 ? ["textures"] : []),
|
|
247
|
+
...(materials.some((material) => material.pbrMetallicRoughness) ? ["pbr-metallic-roughness"] : []),
|
|
248
|
+
...(materials.some((material) => material.normalTexture) ? ["normal-texture"] : []),
|
|
249
|
+
...(materials.some((material) => material.occlusionTexture || material.pbrMetallicRoughness?.metallicRoughnessTexture) ? ["orm-texture"] : []),
|
|
250
|
+
...(materials.some((material) => material.emissiveTexture) ? ["emissive-texture"] : []),
|
|
251
|
+
...(materialExtensionCount > 0 ? ["material-extensions"] : []),
|
|
252
|
+
...(textureTransformCount > 0 ? ["texture-transform"] : []),
|
|
253
|
+
...(materialVariantCount > 0 ? ["material-variants"] : []),
|
|
254
|
+
...((gltf.animations?.length ?? 0) > 0 ? ["animation"] : []),
|
|
255
|
+
...((gltf.skins?.length ?? 0) > 0 ? ["skinning"] : []),
|
|
256
|
+
...(morphTargetCounts.some((count) => count > 0) ? ["morph-targets"] : [])
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
validGlb: true,
|
|
261
|
+
version,
|
|
262
|
+
jsonChunkBytes,
|
|
263
|
+
sceneCount: gltf.scenes?.length ?? 0,
|
|
264
|
+
nodeCount: gltf.nodes?.length ?? 0,
|
|
265
|
+
meshCount: meshes.length,
|
|
266
|
+
primitiveCount: primitives.length,
|
|
267
|
+
vertexCount,
|
|
268
|
+
triangleCount,
|
|
269
|
+
materialCount: materials.length,
|
|
270
|
+
texturedPbrMaterialCount: materials.filter((material) => {
|
|
271
|
+
const pbr = material.pbrMetallicRoughness;
|
|
272
|
+
return Boolean(pbr?.baseColorTexture || pbr?.metallicRoughnessTexture || material.normalTexture || material.occlusionTexture || material.emissiveTexture);
|
|
273
|
+
}).length,
|
|
274
|
+
textureCount: gltf.textures?.length ?? 0,
|
|
275
|
+
imageCount: gltf.images?.length ?? 0,
|
|
276
|
+
animationCount: gltf.animations?.length ?? 0,
|
|
277
|
+
animationChannelCount,
|
|
278
|
+
animationSamplerCount,
|
|
279
|
+
skinCount: gltf.skins?.length ?? 0,
|
|
280
|
+
jointCount: skinJointCounts.reduce((total, count) => total + count, 0),
|
|
281
|
+
morphTargetPrimitiveCount: morphTargetCounts.filter((count) => count > 0).length,
|
|
282
|
+
morphTargetCount: morphTargetCounts.reduce((total, count) => total + count, 0),
|
|
283
|
+
materialExtensionCount,
|
|
284
|
+
materialTextureSlotCount: textureInfos.length,
|
|
285
|
+
textureTransformCount,
|
|
286
|
+
materialVariantCount,
|
|
287
|
+
extensionsUsed,
|
|
288
|
+
extensionsRequired: gltf.extensionsRequired ?? [],
|
|
289
|
+
features,
|
|
290
|
+
unsupportedRequiredExtensions
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export function createAdvancedAssetCorpusSummary(manifest = loadCurrentRoutesAssetManifest()): AdvancedAssetCorpusSummary {
|
|
295
|
+
const entries = manifest.assets.map((asset): CurrentRoutesAssetReadinessEntry => {
|
|
296
|
+
const path = resolve(asset.localPath);
|
|
297
|
+
const exists = existsSync(path);
|
|
298
|
+
const bytesMatch = exists && statSync(path).size === asset.bytes;
|
|
299
|
+
const sha256Matches = exists && sha256(path) === asset.sha256;
|
|
300
|
+
const inspection = exists ? inspectCurrentRoutesGlb(path) : null;
|
|
301
|
+
const missingDeclaredFields = [
|
|
302
|
+
...requiredText(asset.id, "source", asset.source),
|
|
303
|
+
...requiredText(asset.id, "sourceUri", asset.sourceUri),
|
|
304
|
+
...requiredText(asset.id, "license", asset.license),
|
|
305
|
+
...requiredText(asset.id, "sha256", asset.sha256),
|
|
306
|
+
...(asset.bytes > 0 ? [] : [`${asset.id}.bytes`]),
|
|
307
|
+
...(asset.triangleCount > 0 ? [] : [`${asset.id}.triangleCount`]),
|
|
308
|
+
...(asset.tags.length > 0 ? [] : [`${asset.id}.tags`])
|
|
309
|
+
];
|
|
310
|
+
const featureSet = new Set(inspection?.features ?? []);
|
|
311
|
+
const missingRequiredFeatures = asset.requiredFeatures.filter((feature) => !featureSet.has(feature));
|
|
312
|
+
const metadataMismatches = inspection ? [
|
|
313
|
+
...(asset.triangleCount === inspection.triangleCount ? [] : [`${asset.id}.triangleCount expected ${asset.triangleCount} actual ${inspection.triangleCount}`]),
|
|
314
|
+
...(asset.textureCount === inspection.textureCount ? [] : [`${asset.id}.textureCount expected ${asset.textureCount} actual ${inspection.textureCount}`]),
|
|
315
|
+
...(asset.animationCount === inspection.animationCount ? [] : [`${asset.id}.animationCount expected ${asset.animationCount} actual ${inspection.animationCount}`]),
|
|
316
|
+
...(asset.skinCount === inspection.skinCount ? [] : [`${asset.id}.skinCount expected ${asset.skinCount} actual ${inspection.skinCount}`]),
|
|
317
|
+
...(asset.morphTargetCount === inspection.morphTargetCount ? [] : [`${asset.id}.morphTargetCount expected ${asset.morphTargetCount} actual ${inspection.morphTargetCount}`]),
|
|
318
|
+
...(asset.materialExtensionCount === inspection.materialExtensionCount ? [] : [`${asset.id}.materialExtensionCount expected ${asset.materialExtensionCount} actual ${inspection.materialExtensionCount}`])
|
|
319
|
+
] : [];
|
|
320
|
+
return {
|
|
321
|
+
id: asset.id,
|
|
322
|
+
localPath: asset.localPath,
|
|
323
|
+
exists,
|
|
324
|
+
bytesMatch,
|
|
325
|
+
sha256Matches,
|
|
326
|
+
missingDeclaredFields: [...missingDeclaredFields, ...metadataMismatches],
|
|
327
|
+
missingRequiredFeatures,
|
|
328
|
+
inspection
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
const environments = manifest.environments.map((environment): CurrentRoutesEnvironmentReadinessEntry => {
|
|
332
|
+
const path = resolve(environment.localPath);
|
|
333
|
+
const exists = existsSync(path);
|
|
334
|
+
return {
|
|
335
|
+
id: environment.id,
|
|
336
|
+
localPath: environment.localPath,
|
|
337
|
+
exists,
|
|
338
|
+
bytesMatch: exists && statSync(path).size === environment.bytes,
|
|
339
|
+
sha256Matches: exists && sha256(path) === environment.sha256,
|
|
340
|
+
bytes: exists ? statSync(path).size : 0
|
|
341
|
+
};
|
|
342
|
+
});
|
|
343
|
+
const inspections = entries.flatMap((entry) => entry.inspection ? [entry.inspection] : []);
|
|
344
|
+
const totalBytes = manifest.assets.reduce((total, asset) => total + asset.bytes, 0) + manifest.environments.reduce((total, environment) => total + environment.bytes, 0);
|
|
345
|
+
const totalTriangles = inspections.reduce((total, inspection) => total + inspection.triangleCount, 0);
|
|
346
|
+
const classCoverage = [...new Set(manifest.assets.map((asset) => asset.class))].sort() as CurrentRoutesAssetClass[];
|
|
347
|
+
const featureCoverage = [...new Set(inspections.flatMap((inspection) => inspection.features))].sort();
|
|
348
|
+
const texturedPbrAssetCount = entries.filter((entry) => (entry.inspection?.texturedPbrMaterialCount ?? 0) > 0).length;
|
|
349
|
+
const animationAssetCount = entries.filter((entry) => (entry.inspection?.animationCount ?? 0) > 0).length;
|
|
350
|
+
const skinAssetCount = entries.filter((entry) => (entry.inspection?.skinCount ?? 0) > 0).length;
|
|
351
|
+
const morphAssetCount = entries.filter((entry) => (entry.inspection?.morphTargetCount ?? 0) > 0).length;
|
|
352
|
+
const materialExtensionAssetCount = entries.filter((entry) => (entry.inspection?.materialExtensionCount ?? 0) > 0).length;
|
|
353
|
+
const failures = [
|
|
354
|
+
...(manifest.assets.length < manifest.requirements.minimumAssetCount ? [`asset count ${manifest.assets.length} is below ${manifest.requirements.minimumAssetCount}`] : []),
|
|
355
|
+
...(entries.some((entry) => !entry.exists) ? ["one or more assets are missing from fixtures/threejs-parity"] : []),
|
|
356
|
+
...(entries.some((entry) => !entry.bytesMatch) ? ["one or more asset byte sizes do not match manifest"] : []),
|
|
357
|
+
...(entries.some((entry) => !entry.sha256Matches) ? ["one or more asset sha256 checks do not match manifest"] : []),
|
|
358
|
+
...(entries.some((entry) => entry.missingDeclaredFields.length > 0) ? ["one or more assets are missing source/license/checksum/tags"] : []),
|
|
359
|
+
...(entries.some((entry) => entry.missingRequiredFeatures.length > 0) ? ["one or more assets are missing required declared GLB features"] : []),
|
|
360
|
+
...(inspections.some((inspection) => inspection.unsupportedRequiredExtensions.length > 0) ? ["one or more GLBs require unsupported extensions"] : []),
|
|
361
|
+
...(environments.some((entry) => !entry.exists || !entry.bytesMatch || !entry.sha256Matches) ? ["one or more HDR environments failed checksum validation"] : []),
|
|
362
|
+
...(totalBytes < manifest.requirements.minimumTotalBytes ? [`total corpus bytes ${totalBytes} is below ${manifest.requirements.minimumTotalBytes}`] : []),
|
|
363
|
+
...(totalTriangles < manifest.requirements.minimumTotalTriangles ? [`total triangle count ${totalTriangles} is below ${manifest.requirements.minimumTotalTriangles}`] : []),
|
|
364
|
+
...(texturedPbrAssetCount < manifest.requirements.minimumTexturedPbrAssets ? ["too few textured PBR assets"] : []),
|
|
365
|
+
...(animationAssetCount < manifest.requirements.minimumAnimationAssets ? ["too few animated assets"] : []),
|
|
366
|
+
...(skinAssetCount < manifest.requirements.minimumSkinAssets ? ["too few skinned assets"] : []),
|
|
367
|
+
...(morphAssetCount < manifest.requirements.minimumMorphAssets ? ["too few morph assets"] : []),
|
|
368
|
+
...(materialExtensionAssetCount < manifest.requirements.minimumMaterialExtensionAssets ? ["too few material-extension assets"] : []),
|
|
369
|
+
...manifest.requirements.requiredClasses.filter((assetClass) => !classCoverage.includes(assetClass)).map((assetClass) => `missing asset class ${assetClass}`),
|
|
370
|
+
...manifest.requirements.requiredFeatures.filter((feature) => !featureCoverage.includes(feature)).map((feature) => `missing corpus feature ${feature}`)
|
|
371
|
+
];
|
|
372
|
+
return {
|
|
373
|
+
schema: "a3d-current-routes-asset-readiness",
|
|
374
|
+
pass: failures.length === 0,
|
|
375
|
+
assetCount: manifest.assets.length,
|
|
376
|
+
environmentCount: manifest.environments.length,
|
|
377
|
+
existingAssetCount: entries.filter((entry) => entry.exists).length,
|
|
378
|
+
shaVerifiedAssetCount: entries.filter((entry) => entry.sha256Matches).length,
|
|
379
|
+
totalBytes,
|
|
380
|
+
totalTriangles,
|
|
381
|
+
texturedPbrAssetCount,
|
|
382
|
+
animationAssetCount,
|
|
383
|
+
skinAssetCount,
|
|
384
|
+
morphAssetCount,
|
|
385
|
+
materialExtensionAssetCount,
|
|
386
|
+
classCoverage,
|
|
387
|
+
featureCoverage,
|
|
388
|
+
failures,
|
|
389
|
+
entries,
|
|
390
|
+
environments
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function writeAdvancedAssetCorpusReport(path = "tests/reports/current-routes-assets.json"): AdvancedAssetCorpusSummary {
|
|
395
|
+
const summary = createAdvancedAssetCorpusSummary();
|
|
396
|
+
const outputPath = resolve(path);
|
|
397
|
+
writeFileSync(outputPath, `${JSON.stringify(summary, null, 2)}\n`);
|
|
398
|
+
return summary;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function collectMaterialTextureInfos(material: NonNullable<GLTFJson["materials"]>[number]): TextureInfo[] {
|
|
402
|
+
const extensionTextureInfos = Object.values(material.extensions ?? {}).flatMap((extension) => {
|
|
403
|
+
if (!extension || typeof extension !== "object") return [];
|
|
404
|
+
return Object.entries(extension as Record<string, unknown>)
|
|
405
|
+
.filter(([key, value]) => /Texture$/.test(key) && value && typeof value === "object")
|
|
406
|
+
.map(([, value]) => value as TextureInfo);
|
|
407
|
+
});
|
|
408
|
+
return [
|
|
409
|
+
...[material.pbrMetallicRoughness?.baseColorTexture, material.pbrMetallicRoughness?.metallicRoughnessTexture],
|
|
410
|
+
material.normalTexture,
|
|
411
|
+
material.occlusionTexture,
|
|
412
|
+
material.emissiveTexture,
|
|
413
|
+
...extensionTextureInfos
|
|
414
|
+
].filter((textureInfo): textureInfo is TextureInfo => Boolean(textureInfo));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function countMaterialVariants(gltf: GLTFJson): number {
|
|
418
|
+
const rootVariants = gltf.extensions?.KHR_materials_variants as { readonly variants?: readonly unknown[] } | undefined;
|
|
419
|
+
const primitiveVariantMappings = (gltf.meshes ?? [])
|
|
420
|
+
.flatMap((mesh) => mesh.primitives ?? [])
|
|
421
|
+
.flatMap((primitive) => {
|
|
422
|
+
const variants = primitive.extensions?.KHR_materials_variants as { readonly mappings?: readonly unknown[] } | undefined;
|
|
423
|
+
return variants?.mappings ?? [];
|
|
424
|
+
});
|
|
425
|
+
return (rootVariants?.variants?.length ?? 0) + primitiveVariantMappings.length;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function primitiveTriangleCount(gltf: GLTFJson, primitive: NonNullable<NonNullable<GLTFJson["meshes"]>[number]["primitives"]>[number]): number {
|
|
429
|
+
const primitiveCount = primitive.indices === undefined
|
|
430
|
+
? accessorCount(gltf, primitive.attributes?.POSITION)
|
|
431
|
+
: accessorCount(gltf, primitive.indices);
|
|
432
|
+
switch (primitive.mode ?? 4) {
|
|
433
|
+
case 4:
|
|
434
|
+
return Math.floor(primitiveCount / 3);
|
|
435
|
+
case 5:
|
|
436
|
+
case 6:
|
|
437
|
+
return Math.max(0, primitiveCount - 2);
|
|
438
|
+
default:
|
|
439
|
+
return 0;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function accessorCount(gltf: GLTFJson, accessorIndex: number | undefined): number {
|
|
444
|
+
if (accessorIndex === undefined) return 0;
|
|
445
|
+
return gltf.accessors?.[accessorIndex]?.count ?? 0;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function requiredText(id: string, field: string, value: string): string[] {
|
|
449
|
+
return value.trim().length > 0 ? [] : [`${id}.${field}`];
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function sha256(path: string): string {
|
|
453
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
454
|
+
}
|