@haiyue/extensions 0.1.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.
Files changed (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/animation/Animation2DComponent.d.ts +46 -0
  4. package/dist/animation/Animation2DExtensionRegistry.d.ts +27 -0
  5. package/dist/animation/Animation2DRenderSystem.d.ts +89 -0
  6. package/dist/animation/Animation2DRuntime.d.ts +99 -0
  7. package/dist/animation/Animation2DStateMachine.d.ts +13 -0
  8. package/dist/animation/Animation2DStateMachineComponent.d.ts +54 -0
  9. package/dist/animation/Animation2DStateMachineRuntime.d.ts +30 -0
  10. package/dist/animation/Animation2DStateMachineSystem.d.ts +14 -0
  11. package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +27 -0
  12. package/dist/animation/Animation2DSystem.d.ts +14 -0
  13. package/dist/animation/AnimationAssetLoader.d.ts +9 -0
  14. package/dist/animation/AnimationAudioClip.d.ts +26 -0
  15. package/dist/animation/AnimationPathTessellator.d.ts +52 -0
  16. package/dist/animation/AnimationTextRasterizer.d.ts +21 -0
  17. package/dist/animation/AnimationVisual2D.d.ts +68 -0
  18. package/dist/animation/HyaAnimation2DClipAdapter.d.ts +16 -0
  19. package/dist/animation/Particle2DDescriptorAdapter.d.ts +5 -0
  20. package/dist/animation/runtime/mixer/Action.d.ts +150 -0
  21. package/dist/animation/runtime/mixer/Mixer.d.ts +54 -0
  22. package/dist/animation/runtime/mixer/PoseBuffer.d.ts +23 -0
  23. package/dist/animation/runtime/mixer/Sampler.d.ts +17 -0
  24. package/dist/animation/runtime/mixer/Types.d.ts +101 -0
  25. package/dist/animation/runtime/mixer/index.d.ts +6 -0
  26. package/dist/animation-state-machine/AnimationStateMachine.d.ts +111 -0
  27. package/dist/animation-state-machine/AnimationStateMachineChannels.d.ts +23 -0
  28. package/dist/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.d.ts +51 -0
  29. package/dist/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.d.ts +14 -0
  30. package/dist/animation-state-machine/runtime/AnimationStateMachineCompiler.d.ts +109 -0
  31. package/dist/animation-state-machine/runtime/AnimationStateMachineController.d.ts +103 -0
  32. package/dist/animation-state-machine/runtime/AnimationStateMachineMixerPort.d.ts +35 -0
  33. package/dist/animation-state-machine/runtime/index.d.ts +7 -0
  34. package/dist/animation.d.ts +15 -0
  35. package/dist/animation.js +1171 -0
  36. package/dist/animation3d/Animation3DAction.d.ts +46 -0
  37. package/dist/animation3d/Animation3DBinding.d.ts +85 -0
  38. package/dist/animation3d/Animation3DClip.d.ts +20 -0
  39. package/dist/animation3d/Animation3DError.d.ts +13 -0
  40. package/dist/animation3d/Animation3DMixer.d.ts +27 -0
  41. package/dist/animation3d/Animation3DPose.d.ts +40 -0
  42. package/dist/animation3d/Animation3DPoseBuffer.d.ts +24 -0
  43. package/dist/animation3d/Animation3DResource.d.ts +28 -0
  44. package/dist/animation3d/Animation3DStateMachine.d.ts +95 -0
  45. package/dist/animation3d/Animation3DStateMachineRuntime.d.ts +70 -0
  46. package/dist/animation3d/Animation3DTrack.d.ts +19 -0
  47. package/dist/animation3d/hya/HyaAnimation3DRuntime.d.ts +73 -0
  48. package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +65 -0
  49. package/dist/animation3d/hya/HyaAnimation3DTypes.d.ts +170 -0
  50. package/dist/animation3d/hya/index.d.ts +4 -0
  51. package/dist/animation3d/index.d.ts +14 -0
  52. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +81 -0
  53. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +39 -0
  54. package/dist/animation3d/runtime/integration/index.d.ts +2 -0
  55. package/dist/animation3d/runtime/mixer/Action.d.ts +150 -0
  56. package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +6 -0
  57. package/dist/animation3d/runtime/mixer/Mixer.d.ts +59 -0
  58. package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +1 -0
  59. package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +24 -0
  60. package/dist/animation3d/runtime/mixer/index.d.ts +4 -0
  61. package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +1 -0
  62. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +1 -0
  63. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +1 -0
  64. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +1 -0
  65. package/dist/animation3d/runtime/state-machine/index.d.ts +6 -0
  66. package/dist/animation3d.d.ts +5 -0
  67. package/dist/animation3d.js +1708 -0
  68. package/dist/benchmark.d.ts +30 -0
  69. package/dist/benchmark.js +119 -0
  70. package/dist/canvas-text/CanvasText2DRenderSystem.d.ts +24 -0
  71. package/dist/canvas-text/CanvasTextComponent.d.ts +18 -0
  72. package/dist/canvas-text.d.ts +4 -0
  73. package/dist/canvas-text.js +276 -0
  74. package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +4 -0
  75. package/dist/chunks/2d-ui-canvas-text-2d.generated-C0Eaej2m.js +4 -0
  76. package/dist/chunks/2d-ui-spine2d.generated-CUUi8xjl.js +4 -0
  77. package/dist/chunks/2d-ui-tilemap2d.generated-gebw4mX7.js +4 -0
  78. package/dist/chunks/Animation2DStateMachine-9IonguNa.js +3245 -0
  79. package/dist/chunks/AnimationStateMachineController-BIcAh-sT.js +1438 -0
  80. package/dist/chunks/GltfAnimation3DAdapter-Cu3rQQsW.js +2240 -0
  81. package/dist/chunks/GltfAnimationRuntime-CRHsLycN.js +631 -0
  82. package/dist/chunks/RenderSystem2DBase-DDT61dAu.js +227 -0
  83. package/dist/chunks/Spine2DRuntime-D9M9LAQR.js +3056 -0
  84. package/dist/chunks/SpineAssetParser-BSDmPge1.js +378 -0
  85. package/dist/chunks/gltfLoader-Dm22jLYB.js +2085 -0
  86. package/dist/chunks/pluginUtils-CvwroRMd.js +33 -0
  87. package/dist/experimental-gltf-worker.d.ts +4 -0
  88. package/dist/experimental-gltf-worker.js +138 -0
  89. package/dist/experimental-spine-worker.d.ts +4 -0
  90. package/dist/experimental-spine-worker.js +110 -0
  91. package/dist/gltf/GltfAccessorReader.d.ts +7 -0
  92. package/dist/gltf/GltfAnimation3DAdapter.d.ts +47 -0
  93. package/dist/gltf/GltfAnimationRuntime.d.ts +10 -0
  94. package/dist/gltf/GltfAssetWorkerClient.d.ts +20 -0
  95. package/dist/gltf/GltfCompatibilityReport.d.ts +70 -0
  96. package/dist/gltf/GltfConservativeBounds.d.ts +18 -0
  97. package/dist/gltf/GltfDracoDecoder.d.ts +4 -0
  98. package/dist/gltf/GltfExtensionAdapter.d.ts +54 -0
  99. package/dist/gltf/GltfLoaderContract.d.ts +249 -0
  100. package/dist/gltf/GltfLoaderErrors.d.ts +4 -0
  101. package/dist/gltf/GltfMaterialDescriptor.d.ts +23 -0
  102. package/dist/gltf/GltfMaterialEncoder.d.ts +20 -0
  103. package/dist/gltf/GltfMaterialLoader.d.ts +6 -0
  104. package/dist/gltf/GltfModelComponent.d.ts +72 -0
  105. package/dist/gltf/GltfModelSystem.d.ts +37 -0
  106. package/dist/gltf/GltfPlugin.d.ts +6 -0
  107. package/dist/gltf/GltfSchema.d.ts +225 -0
  108. package/dist/gltf/GltfUvSemanticPlanner.d.ts +33 -0
  109. package/dist/gltf/gltfLoader.d.ts +9 -0
  110. package/dist/gltf-animation3d.d.ts +3 -0
  111. package/dist/gltf-animation3d.js +8 -0
  112. package/dist/gltf-worker-runtime.d.ts +7 -0
  113. package/dist/gltf-worker-runtime.js +6981 -0
  114. package/dist/gltf.d.ts +12 -0
  115. package/dist/gltf.js +517 -0
  116. package/dist/grid/Grid2DComponent.d.ts +25 -0
  117. package/dist/grid.d.ts +2 -0
  118. package/dist/grid.js +56 -0
  119. package/dist/hya-state-machine.d.ts +7 -0
  120. package/dist/hya-state-machine.js +2934 -0
  121. package/dist/index.d.ts +2 -0
  122. package/dist/index.js +7 -0
  123. package/dist/internal/2d-ui-shader-artifact.js +870 -0
  124. package/dist/plugins/pluginUtils.d.ts +20 -0
  125. package/dist/plugins.d.ts +6 -0
  126. package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +658 -0
  127. package/dist/spine/Spine2DComponent.d.ts +116 -0
  128. package/dist/spine/Spine2DGpuRenderer.d.ts +65 -0
  129. package/dist/spine/Spine2DRenderSystem.d.ts +27 -0
  130. package/dist/spine/Spine2DRuntime.d.ts +103 -0
  131. package/dist/spine/SpineAnimationBoneTimelines.d.ts +8 -0
  132. package/dist/spine/SpineAssetParser.d.ts +18 -0
  133. package/dist/spine/SpineAssetWorkerClient.d.ts +19 -0
  134. package/dist/spine/SpineAssetWorkerContract.d.ts +6 -0
  135. package/dist/spine/SpineAtlasParser.d.ts +21 -0
  136. package/dist/spine/SpineFloatBuilder.d.ts +15 -0
  137. package/dist/spine/SpinePathConstraintSolver.d.ts +32 -0
  138. package/dist/spine/SpinePlugin.d.ts +8 -0
  139. package/dist/spine/SpineSkeletonRuntime.d.ts +185 -0
  140. package/dist/spine/SpineSlotAnimation.d.ts +17 -0
  141. package/dist/spine/SpineTimelineRuntime.d.ts +25 -0
  142. package/dist/spine/SpineVertexBuilder.d.ts +61 -0
  143. package/dist/spine.d.ts +7 -0
  144. package/dist/spine.js +578 -0
  145. package/dist/tilemap/Tilemap2DComponent.d.ts +110 -0
  146. package/dist/tilemap/Tilemap2DRenderSystem.d.ts +11 -0
  147. package/dist/tilemap/Tilemap2DRenderer.d.ts +24 -0
  148. package/dist/tilemap/TilemapPlugin.d.ts +8 -0
  149. package/dist/tilemap.d.ts +6 -0
  150. package/dist/tilemap.js +535 -0
  151. package/dist/tween/Tween2DComponent.d.ts +70 -0
  152. package/dist/tween/Tween2DSystem.d.ts +12 -0
  153. package/dist/tween.d.ts +4 -0
  154. package/dist/tween.js +138 -0
  155. package/dist/utils/RenderSystem2DBase.d.ts +42 -0
  156. package/dist/utils/arrayAccess.d.ts +4 -0
  157. package/dist/utils/camera2d.d.ts +12 -0
  158. package/dist/utils/render2dGpu.d.ts +32 -0
  159. package/package.json +124 -0
  160. package/src/animation/Animation2DComponent.ts +135 -0
  161. package/src/animation/Animation2DExtensionRegistry.ts +52 -0
  162. package/src/animation/Animation2DRenderSystem.ts +1026 -0
  163. package/src/animation/Animation2DRuntime.ts +1326 -0
  164. package/src/animation/Animation2DStateMachine.ts +39 -0
  165. package/src/animation/Animation2DStateMachineComponent.ts +228 -0
  166. package/src/animation/Animation2DStateMachineRuntime.ts +141 -0
  167. package/src/animation/Animation2DStateMachineSystem.ts +60 -0
  168. package/src/animation/Animation2DStateMachineVisualRuntime.ts +282 -0
  169. package/src/animation/Animation2DSystem.ts +72 -0
  170. package/src/animation/AnimationAssetLoader.ts +84 -0
  171. package/src/animation/AnimationAudioClip.ts +140 -0
  172. package/src/animation/AnimationPathTessellator.ts +691 -0
  173. package/src/animation/AnimationTextRasterizer.ts +340 -0
  174. package/src/animation/AnimationVisual2D.ts +153 -0
  175. package/src/animation/HyaAnimation2DClipAdapter.ts +845 -0
  176. package/src/animation/Particle2DDescriptorAdapter.ts +35 -0
  177. package/src/animation/runtime/mixer/Action.ts +876 -0
  178. package/src/animation/runtime/mixer/Mixer.ts +505 -0
  179. package/src/animation/runtime/mixer/PoseBuffer.ts +105 -0
  180. package/src/animation/runtime/mixer/Sampler.ts +252 -0
  181. package/src/animation/runtime/mixer/Types.ts +138 -0
  182. package/src/animation/runtime/mixer/index.ts +31 -0
  183. package/src/animation-state-machine/AnimationStateMachine.ts +146 -0
  184. package/src/animation-state-machine/AnimationStateMachineChannels.ts +116 -0
  185. package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +197 -0
  186. package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +503 -0
  187. package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +763 -0
  188. package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +987 -0
  189. package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +54 -0
  190. package/src/animation-state-machine/runtime/index.ts +47 -0
  191. package/src/animation.ts +33 -0
  192. package/src/animation3d/Animation3DAction.ts +73 -0
  193. package/src/animation3d/Animation3DBinding.ts +116 -0
  194. package/src/animation3d/Animation3DClip.ts +22 -0
  195. package/src/animation3d/Animation3DError.ts +34 -0
  196. package/src/animation3d/Animation3DMixer.ts +82 -0
  197. package/src/animation3d/Animation3DPose.ts +100 -0
  198. package/src/animation3d/Animation3DPoseBuffer.ts +85 -0
  199. package/src/animation3d/Animation3DResource.ts +49 -0
  200. package/src/animation3d/Animation3DStateMachine.ts +126 -0
  201. package/src/animation3d/Animation3DStateMachineRuntime.ts +191 -0
  202. package/src/animation3d/Animation3DTrack.ts +29 -0
  203. package/src/animation3d/hya/HyaAnimation3DRuntime.ts +756 -0
  204. package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +618 -0
  205. package/src/animation3d/hya/HyaAnimation3DTypes.ts +168 -0
  206. package/src/animation3d/hya/index.ts +10 -0
  207. package/src/animation3d/index.ts +76 -0
  208. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +325 -0
  209. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +158 -0
  210. package/src/animation3d/runtime/integration/index.ts +9 -0
  211. package/src/animation3d/runtime/mixer/Action.ts +833 -0
  212. package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +26 -0
  213. package/src/animation3d/runtime/mixer/Mixer.ts +562 -0
  214. package/src/animation3d/runtime/mixer/PoseBuffer.ts +1 -0
  215. package/src/animation3d/runtime/mixer/TrackSampler.ts +399 -0
  216. package/src/animation3d/runtime/mixer/index.ts +8 -0
  217. package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +4 -0
  218. package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +1 -0
  219. package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +1 -0
  220. package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +1 -0
  221. package/src/animation3d/runtime/state-machine/index.ts +45 -0
  222. package/src/animation3d.ts +5 -0
  223. package/src/benchmark.ts +168 -0
  224. package/src/canvas-text/CanvasText2DRenderSystem.ts +292 -0
  225. package/src/canvas-text/CanvasTextComponent.ts +47 -0
  226. package/src/canvas-text.ts +4 -0
  227. package/src/experimental-gltf-worker.ts +18 -0
  228. package/src/experimental-spine-worker.ts +9 -0
  229. package/src/gltf/GltfAccessorReader.ts +271 -0
  230. package/src/gltf/GltfAnimation3DAdapter.ts +680 -0
  231. package/src/gltf/GltfAnimationRuntime.ts +392 -0
  232. package/src/gltf/GltfAssetWorkerClient.ts +136 -0
  233. package/src/gltf/GltfCompatibilityReport.ts +214 -0
  234. package/src/gltf/GltfConservativeBounds.ts +219 -0
  235. package/src/gltf/GltfDracoDecoder.ts +251 -0
  236. package/src/gltf/GltfExtensionAdapter.ts +340 -0
  237. package/src/gltf/GltfLoaderContract.ts +333 -0
  238. package/src/gltf/GltfLoaderErrors.ts +59 -0
  239. package/src/gltf/GltfMaterialDescriptor.ts +134 -0
  240. package/src/gltf/GltfMaterialEncoder.ts +173 -0
  241. package/src/gltf/GltfMaterialLoader.ts +293 -0
  242. package/src/gltf/GltfModelComponent.ts +115 -0
  243. package/src/gltf/GltfModelSystem.ts +208 -0
  244. package/src/gltf/GltfPlugin.ts +84 -0
  245. package/src/gltf/GltfSchema.ts +229 -0
  246. package/src/gltf/GltfUvSemanticPlanner.ts +166 -0
  247. package/src/gltf/gltfLoader.ts +910 -0
  248. package/src/gltf-animation3d.ts +10 -0
  249. package/src/gltf-worker-runtime.ts +10 -0
  250. package/src/gltf.ts +56 -0
  251. package/src/grid/Grid2DComponent.ts +69 -0
  252. package/src/grid.ts +2 -0
  253. package/src/hya-state-machine.ts +19 -0
  254. package/src/index.ts +2 -0
  255. package/src/plugins/pluginUtils.ts +50 -0
  256. package/src/plugins.ts +6 -0
  257. package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +242 -0
  258. package/src/shaders/generated/2d-ui-artifact.generated.ts +867 -0
  259. package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +38 -0
  260. package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +41 -0
  261. package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +36 -0
  262. package/src/spine/Spine2DComponent.ts +168 -0
  263. package/src/spine/Spine2DGpuRenderer.ts +449 -0
  264. package/src/spine/Spine2DRenderSystem.ts +199 -0
  265. package/src/spine/Spine2DRuntime.ts +1529 -0
  266. package/src/spine/SpineAnimationBoneTimelines.ts +30 -0
  267. package/src/spine/SpineAssetParser.ts +20 -0
  268. package/src/spine/SpineAssetWorkerClient.ts +112 -0
  269. package/src/spine/SpineAssetWorkerContract.ts +4 -0
  270. package/src/spine/SpineAtlasParser.ts +127 -0
  271. package/src/spine/SpineFloatBuilder.ts +66 -0
  272. package/src/spine/SpinePathConstraintSolver.ts +582 -0
  273. package/src/spine/SpinePlugin.ts +76 -0
  274. package/src/spine/SpineSkeletonRuntime.ts +521 -0
  275. package/src/spine/SpineSlotAnimation.ts +195 -0
  276. package/src/spine/SpineTimelineRuntime.ts +453 -0
  277. package/src/spine/SpineVertexBuilder.ts +686 -0
  278. package/src/spine.ts +7 -0
  279. package/src/tilemap/Tilemap2DComponent.ts +232 -0
  280. package/src/tilemap/Tilemap2DRenderSystem.ts +58 -0
  281. package/src/tilemap/Tilemap2DRenderer.ts +289 -0
  282. package/src/tilemap/TilemapPlugin.ts +75 -0
  283. package/src/tilemap.ts +6 -0
  284. package/src/tween/Tween2DComponent.ts +83 -0
  285. package/src/tween/Tween2DSystem.ts +78 -0
  286. package/src/tween.ts +4 -0
  287. package/src/types/earcut.d.ts +7 -0
  288. package/src/types/wgsl.d.ts +4 -0
  289. package/src/utils/RenderSystem2DBase.ts +164 -0
  290. package/src/utils/arrayAccess.ts +17 -0
  291. package/src/utils/camera2d.ts +68 -0
  292. package/src/utils/render2dGpu.ts +132 -0
  293. package/test/fixtures/gltf/animation-characterization.gltf +344 -0
@@ -0,0 +1,340 @@
1
+ import type { PbrMaterialState, PbrTextureSlot } from '@haiyue/engine/material';
2
+ import type { GltfAsset, GltfMaterial, GltfPrimitive, GltfTextureInfo } from './GltfSchema';
3
+
4
+ export type GltfExtensionSupport = 'supported' | 'partial' | 'unsupported';
5
+
6
+ export interface GltfExtensionCapability {
7
+ readonly support: GltfExtensionSupport;
8
+ readonly note: string;
9
+ }
10
+
11
+ export interface GltfMaterialTextureBinding {
12
+ readonly slot: PbrTextureSlot;
13
+ readonly textureInfo: GltfTextureInfo;
14
+ readonly path: string;
15
+ }
16
+
17
+ export interface GltfMaterialExtensionContext {
18
+ readonly gltf: GltfAsset;
19
+ readonly material: GltfMaterial;
20
+ readonly primitive: GltfPrimitive;
21
+ readonly materialPath: string;
22
+ readonly extensionData: unknown;
23
+ }
24
+
25
+ export type GltfMaterialStatePatch = Readonly<Partial<Omit<PbrMaterialState,
26
+ | 'baseColorTexture'
27
+ | 'metallicRoughnessTexture'
28
+ | 'normalTexture'
29
+ | 'occlusionTexture'
30
+ | 'emissiveTexture'
31
+ | 'clearcoatTexture'
32
+ | 'clearcoatRoughnessTexture'
33
+ | 'clearcoatNormalTexture'
34
+ | 'specularTexture'
35
+ | 'specularColorTexture'
36
+ | 'sheenColorTexture'
37
+ | 'sheenRoughnessTexture'
38
+ | 'transmissionTexture'
39
+ | 'thicknessTexture'
40
+ | 'textureMappings'
41
+ | 'samplers'
42
+ | 'sampler'
43
+ >>>;
44
+
45
+ export interface GltfMaterialExtensionPatch {
46
+ /** Pure material parameters. Texture ownership must use `textures`. */
47
+ readonly state?: GltfMaterialStatePatch;
48
+ readonly textures?: readonly GltfMaterialTextureBinding[];
49
+ }
50
+
51
+ export interface GltfMaterialVariantReference {
52
+ readonly name: string;
53
+ readonly materialIndex: number;
54
+ }
55
+
56
+ export interface GltfPrimitiveExtensionContext {
57
+ readonly gltf: GltfAsset;
58
+ readonly primitive: GltfPrimitive;
59
+ readonly rootExtensionData: unknown;
60
+ readonly primitiveExtensionData: unknown;
61
+ }
62
+
63
+ /**
64
+ * A stateless glTF extension adapter. Hooks return declarative patches and
65
+ * references; resource ownership and concrete material creation stay in the
66
+ * loader and engine respectively.
67
+ */
68
+ export interface GltfExtensionAdapter {
69
+ readonly extension: string;
70
+ readonly capability: GltfExtensionCapability;
71
+ readonly extendMaterial?: (context: GltfMaterialExtensionContext) => GltfMaterialExtensionPatch | null;
72
+ readonly collectMaterialVariantNames?: (gltf: GltfAsset, rootExtensionData: unknown) => readonly string[];
73
+ readonly collectMaterialVariants?: (context: GltfPrimitiveExtensionContext) => readonly GltfMaterialVariantReference[];
74
+ }
75
+
76
+ const clearcoatAdapter: GltfExtensionAdapter = Object.freeze({
77
+ extension: 'KHR_materials_clearcoat',
78
+ capability: Object.freeze({ support: 'supported', note: 'Imported as a native layered PBR clearcoat lobe.' }),
79
+ extendMaterial(context: GltfMaterialExtensionContext) {
80
+ const clearcoat = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_clearcoat'];
81
+ if (!clearcoat) return null;
82
+ const basePath = `${context.materialPath}.extensions.KHR_materials_clearcoat`;
83
+ const textures: GltfMaterialTextureBinding[] = [];
84
+ if (clearcoat.clearcoatTexture) textures.push({
85
+ slot: 'clearcoat',
86
+ textureInfo: clearcoat.clearcoatTexture,
87
+ path: `${basePath}.clearcoatTexture`,
88
+ });
89
+ if (clearcoat.clearcoatRoughnessTexture) textures.push({
90
+ slot: 'clearcoatRoughness',
91
+ textureInfo: clearcoat.clearcoatRoughnessTexture,
92
+ path: `${basePath}.clearcoatRoughnessTexture`,
93
+ });
94
+ if (clearcoat.clearcoatNormalTexture) textures.push({
95
+ slot: 'clearcoatNormal',
96
+ textureInfo: clearcoat.clearcoatNormalTexture,
97
+ path: `${basePath}.clearcoatNormalTexture`,
98
+ });
99
+ return {
100
+ state: {
101
+ clearcoatFactor: clearcoat.clearcoatFactor ?? 0,
102
+ clearcoatRoughnessFactor: clearcoat.clearcoatRoughnessFactor ?? 0,
103
+ clearcoatNormalScale: clearcoat.clearcoatNormalTexture?.scale ?? 1,
104
+ },
105
+ textures: Object.freeze(textures),
106
+ };
107
+ },
108
+ });
109
+
110
+ const iorAdapter: GltfExtensionAdapter = Object.freeze({
111
+ extension: 'KHR_materials_ior',
112
+ capability: Object.freeze({ support: 'supported', note: 'Imported into the native dielectric Fresnel IOR parameter.' }),
113
+ extendMaterial(context: GltfMaterialExtensionContext) {
114
+ const ior = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_ior'];
115
+ if (!ior) return null;
116
+ return { state: { ior: ior.ior ?? 1.5 } };
117
+ },
118
+ });
119
+
120
+ const specularAdapter: GltfExtensionAdapter = Object.freeze({
121
+ extension: 'KHR_materials_specular',
122
+ capability: Object.freeze({ support: 'supported', note: 'Imported into the native dielectric specular BRDF.' }),
123
+ extendMaterial(context: GltfMaterialExtensionContext) {
124
+ const specular = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_specular'];
125
+ if (!specular) return null;
126
+ const basePath = `${context.materialPath}.extensions.KHR_materials_specular`;
127
+ const textures: GltfMaterialTextureBinding[] = [];
128
+ if (specular.specularTexture) textures.push({
129
+ slot: 'specular',
130
+ textureInfo: specular.specularTexture,
131
+ path: `${basePath}.specularTexture`,
132
+ });
133
+ if (specular.specularColorTexture) textures.push({
134
+ slot: 'specularColor',
135
+ textureInfo: specular.specularColorTexture,
136
+ path: `${basePath}.specularColorTexture`,
137
+ });
138
+ return {
139
+ state: {
140
+ specularFactor: specular.specularFactor ?? 1,
141
+ specularColorFactor: specular.specularColorFactor ?? [1, 1, 1],
142
+ },
143
+ textures: Object.freeze(textures),
144
+ };
145
+ },
146
+ });
147
+
148
+ const sheenAdapter: GltfExtensionAdapter = Object.freeze({
149
+ extension: 'KHR_materials_sheen',
150
+ capability: Object.freeze({ support: 'supported', note: 'Imported as a native Charlie sheen layer with direct-light and IBL energy compensation.' }),
151
+ extendMaterial(context: GltfMaterialExtensionContext) {
152
+ const sheen = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_sheen'];
153
+ if (!sheen) return null;
154
+ const basePath = `${context.materialPath}.extensions.KHR_materials_sheen`;
155
+ const textures: GltfMaterialTextureBinding[] = [];
156
+ if (sheen.sheenColorTexture) textures.push({
157
+ slot: 'sheenColor',
158
+ textureInfo: sheen.sheenColorTexture,
159
+ path: `${basePath}.sheenColorTexture`,
160
+ });
161
+ if (sheen.sheenRoughnessTexture) textures.push({
162
+ slot: 'sheenRoughness',
163
+ textureInfo: sheen.sheenRoughnessTexture,
164
+ path: `${basePath}.sheenRoughnessTexture`,
165
+ });
166
+ return {
167
+ state: {
168
+ sheenColorFactor: sheen.sheenColorFactor ?? [0, 0, 0],
169
+ sheenRoughnessFactor: sheen.sheenRoughnessFactor ?? 0,
170
+ },
171
+ textures: Object.freeze(textures),
172
+ };
173
+ },
174
+ });
175
+
176
+ const transmissionAdapter: GltfExtensionAdapter = Object.freeze({
177
+ extension: 'KHR_materials_transmission',
178
+ capability: Object.freeze({
179
+ support: 'supported',
180
+ note: 'Imported into the native screen-space scene-color path; combined Sheen keeps factor BRDF but omits Sheen texture sampling to stay within the WebGPU minimum binding budget.',
181
+ }),
182
+ extendMaterial(context: GltfMaterialExtensionContext) {
183
+ const transmission = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_transmission'];
184
+ if (!transmission) return null;
185
+ const basePath = `${context.materialPath}.extensions.KHR_materials_transmission`;
186
+ return {
187
+ state: { transmissionFactor: transmission.transmissionFactor ?? 0 },
188
+ textures: transmission.transmissionTexture ? Object.freeze([{
189
+ slot: 'transmission' as const,
190
+ textureInfo: transmission.transmissionTexture,
191
+ path: `${basePath}.transmissionTexture`,
192
+ }]) : Object.freeze([]),
193
+ };
194
+ },
195
+ });
196
+
197
+ const volumeAdapter: GltfExtensionAdapter = Object.freeze({
198
+ extension: 'KHR_materials_volume',
199
+ capability: Object.freeze({ support: 'supported', note: 'Imported with thickness and Beer-Lambert attenuation in the native transmission path.' }),
200
+ extendMaterial(context: GltfMaterialExtensionContext) {
201
+ const volume = context.extensionData as NonNullable<GltfMaterial['extensions']>['KHR_materials_volume'];
202
+ if (!volume) return null;
203
+ const basePath = `${context.materialPath}.extensions.KHR_materials_volume`;
204
+ return {
205
+ state: {
206
+ thicknessFactor: volume.thicknessFactor ?? 0,
207
+ attenuationDistance: volume.attenuationDistance ?? Infinity,
208
+ attenuationColor: volume.attenuationColor ?? [1, 1, 1],
209
+ },
210
+ textures: volume.thicknessTexture ? Object.freeze([{
211
+ slot: 'thickness' as const,
212
+ textureInfo: volume.thicknessTexture,
213
+ path: `${basePath}.thicknessTexture`,
214
+ }]) : Object.freeze([]),
215
+ };
216
+ },
217
+ });
218
+
219
+ const variantsAdapter: GltfExtensionAdapter = Object.freeze({
220
+ extension: 'KHR_materials_variants',
221
+ capability: Object.freeze({ support: 'supported', note: 'Imported as native PBR material variants.' }),
222
+ collectMaterialVariantNames(gltf: GltfAsset, rootExtensionData: unknown) {
223
+ void gltf;
224
+ const definitions = (rootExtensionData as NonNullable<GltfAsset['extensions']>['KHR_materials_variants'])?.variants ?? [];
225
+ return Object.freeze(definitions.map(variant => variant.name));
226
+ },
227
+ collectMaterialVariants(context: GltfPrimitiveExtensionContext) {
228
+ const definitions = (context.rootExtensionData as NonNullable<GltfAsset['extensions']>['KHR_materials_variants'])?.variants ?? [];
229
+ const mappings = (context.primitiveExtensionData as NonNullable<GltfPrimitive['extensions']>['KHR_materials_variants'])?.mappings ?? [];
230
+ const result: GltfMaterialVariantReference[] = [];
231
+ for (const mapping of mappings) {
232
+ for (const variantIndex of mapping.variants) {
233
+ const name = definitions[variantIndex]?.name;
234
+ if (name) result.push(Object.freeze({ name, materialIndex: mapping.material }));
235
+ }
236
+ }
237
+ return Object.freeze(result);
238
+ },
239
+ });
240
+
241
+ function capabilityAdapter(
242
+ extension: string,
243
+ support: GltfExtensionSupport,
244
+ note: string,
245
+ ): GltfExtensionAdapter {
246
+ return Object.freeze({ extension, capability: Object.freeze({ support, note }) });
247
+ }
248
+
249
+ export const DEFAULT_GLTF_EXTENSION_ADAPTERS: readonly GltfExtensionAdapter[] = Object.freeze([
250
+ capabilityAdapter('KHR_draco_mesh_compression', 'supported', 'Decoded through the configured Draco decoder.'),
251
+ variantsAdapter,
252
+ clearcoatAdapter,
253
+ iorAdapter,
254
+ specularAdapter,
255
+ sheenAdapter,
256
+ transmissionAdapter,
257
+ volumeAdapter,
258
+ capabilityAdapter('KHR_materials_anisotropy', 'partial', 'The base PBR material is imported, but anisotropy shading is not rendered.'),
259
+ capabilityAdapter('KHR_texture_basisu', 'supported', 'Imported through the KTX2/Basis texture path.'),
260
+ capabilityAdapter('KHR_texture_transform', 'supported', 'Applied per PBR texture slot in the shader.'),
261
+ ]);
262
+
263
+ /** Resolves an immutable per-load adapter set; user adapters replace defaults by extension id. */
264
+ export function resolveGltfExtensionAdapters(
265
+ customAdapters: readonly GltfExtensionAdapter[] = [],
266
+ ): readonly GltfExtensionAdapter[] {
267
+ const adapters = new Map(DEFAULT_GLTF_EXTENSION_ADAPTERS.map(adapter => [adapter.extension, adapter]));
268
+ for (const adapter of customAdapters) {
269
+ const extension = adapter.extension.trim();
270
+ if (!extension) throw new TypeError('GltfExtensionAdapter.extension must not be empty.');
271
+ adapters.set(extension, Object.freeze({
272
+ ...adapter,
273
+ extension,
274
+ capability: Object.freeze({ ...adapter.capability }),
275
+ }));
276
+ }
277
+ return Object.freeze([...adapters.values()]);
278
+ }
279
+
280
+ export function createGltfExtensionCapabilities(
281
+ adapters: readonly GltfExtensionAdapter[],
282
+ ): Readonly<Record<string, GltfExtensionCapability>> {
283
+ return Object.freeze(Object.fromEntries(adapters.map(adapter => [adapter.extension, adapter.capability])));
284
+ }
285
+
286
+ export function collectGltfMaterialExtensionPatches(
287
+ gltf: GltfAsset,
288
+ material: GltfMaterial | null,
289
+ primitive: GltfPrimitive,
290
+ materialPath: string,
291
+ adapters: readonly GltfExtensionAdapter[],
292
+ ): readonly GltfMaterialExtensionPatch[] {
293
+ if (!material) return Object.freeze([]);
294
+ const patches: GltfMaterialExtensionPatch[] = [];
295
+ for (const adapter of adapters) {
296
+ if (!adapter.extendMaterial) continue;
297
+ const extensionData = material.extensions?.[adapter.extension];
298
+ if (extensionData === undefined) continue;
299
+ const patch = adapter.extendMaterial({ gltf, material, primitive, materialPath, extensionData });
300
+ if (patch) patches.push(patch);
301
+ }
302
+ return Object.freeze(patches);
303
+ }
304
+
305
+ export function collectGltfMaterialVariantReferences(
306
+ gltf: GltfAsset,
307
+ primitive: GltfPrimitive,
308
+ adapters: readonly GltfExtensionAdapter[],
309
+ ): readonly GltfMaterialVariantReference[] {
310
+ const result: GltfMaterialVariantReference[] = [];
311
+ for (const adapter of adapters) {
312
+ if (!adapter.collectMaterialVariants) continue;
313
+ const rootExtensionData = gltf.extensions?.[adapter.extension];
314
+ const primitiveExtensionData = primitive.extensions?.[adapter.extension];
315
+ if (rootExtensionData === undefined && primitiveExtensionData === undefined) continue;
316
+ result.push(...adapter.collectMaterialVariants({ gltf, primitive, rootExtensionData, primitiveExtensionData }));
317
+ }
318
+ return Object.freeze(result);
319
+ }
320
+
321
+ export function collectGltfMaterialVariantNames(
322
+ gltf: GltfAsset,
323
+ adapters: readonly GltfExtensionAdapter[],
324
+ ): readonly string[] {
325
+ const names = new Set<string>();
326
+ for (const adapter of adapters) {
327
+ if (!adapter.collectMaterialVariantNames) continue;
328
+ const rootExtensionData = gltf.extensions?.[adapter.extension];
329
+ if (rootExtensionData === undefined) continue;
330
+ for (const name of adapter.collectMaterialVariantNames(gltf, rootExtensionData)) {
331
+ if (name) names.add(name);
332
+ }
333
+ }
334
+ for (const mesh of gltf.meshes ?? []) {
335
+ for (const primitive of mesh.primitives) {
336
+ for (const variant of collectGltfMaterialVariantReferences(gltf, primitive, adapters)) names.add(variant.name);
337
+ }
338
+ }
339
+ return Object.freeze([...names]);
340
+ }
@@ -0,0 +1,333 @@
1
+ import type { AssetHandle, AssetManager } from '@haiyue/engine/assets';
2
+ import type { Entity, Geometry3D } from '@haiyue/engine';
3
+ import type { Transform3D } from '@haiyue/engine/components';
4
+ import {
5
+ isGltfAsset,
6
+ isRecord,
7
+ type GltfAnimationInterpolation,
8
+ type GltfAsset,
9
+ } from './GltfSchema';
10
+ import {
11
+ DEFAULT_GLTF_EXTENSION_ADAPTERS,
12
+ createGltfExtensionCapabilities,
13
+ type GltfExtensionAdapter,
14
+ type GltfExtensionCapability,
15
+ } from './GltfExtensionAdapter';
16
+ import type {
17
+ GltfCompatibilityExtensionEntry,
18
+ GltfCompatibilityReport,
19
+ GltfPrimitiveCompatibilityInput,
20
+ } from './GltfCompatibilityReport';
21
+
22
+ export type {
23
+ GltfCompatibilityExtensionEntry,
24
+ GltfCompatibilityIssue,
25
+ GltfCompatibilityPerformanceSummary,
26
+ GltfCompatibilityReport,
27
+ GltfCompatibilityStatus,
28
+ GltfPrimitiveBoundsCompatibilityEntry,
29
+ GltfPrimitiveBoundsSupport,
30
+ GltfPrimitiveUvSemanticCompatibilityEntry,
31
+ GltfTextureCompatibilityEntry,
32
+ GltfTextureMipmapSource,
33
+ } from './GltfCompatibilityReport';
34
+ export type { GltfAnimationInterpolation } from './GltfSchema';
35
+ export type {
36
+ GltfExtensionAdapter,
37
+ GltfExtensionCapability,
38
+ GltfExtensionSupport,
39
+ } from './GltfExtensionAdapter';
40
+
41
+ export interface LoadedGltfModel {
42
+ root: Entity;
43
+ animations: GltfAnimationInfo[];
44
+ animationClips: GltfAnimationClip[];
45
+ assetStats: GltfAssetStats;
46
+ loadMetrics: GltfLoadMetrics;
47
+ objectUrls: string[];
48
+ assetHandles: AssetHandle<unknown>[];
49
+ materialVariants: readonly string[];
50
+ warnings: readonly GltfLoadWarning[];
51
+ extensionReport: GltfExtensionReport;
52
+ compatibilityReport: GltfCompatibilityReport;
53
+ }
54
+
55
+ export type GltfExtensionReportEntry = GltfCompatibilityExtensionEntry;
56
+
57
+ export interface GltfExtensionReport {
58
+ readonly fullySupported: boolean;
59
+ readonly entries: readonly GltfExtensionReportEntry[];
60
+ }
61
+
62
+ export const GLTF_EXTENSION_CAPABILITIES: Readonly<Record<string, GltfExtensionCapability>> =
63
+ createGltfExtensionCapabilities(DEFAULT_GLTF_EXTENSION_ADAPTERS);
64
+
65
+ export interface GltfLoadWarning {
66
+ readonly code: 'W_GLTF_PARTIAL_OPTIONAL_EXTENSION' | 'W_GLTF_UNSUPPORTED_OPTIONAL_EXTENSION';
67
+ readonly message: string;
68
+ readonly extension: string;
69
+ readonly path: string;
70
+ }
71
+
72
+ export interface GltfAnimationInfo {
73
+ name: string;
74
+ duration: number;
75
+ channelCount: number;
76
+ }
77
+
78
+ export type GltfAnimationPath = 'translation' | 'rotation' | 'scale' | 'weights';
79
+
80
+ export interface GltfAnimationTarget {
81
+ entity: Entity;
82
+ transform: Transform3D;
83
+ translation: [number, number, number];
84
+ rotation: [number, number, number, number];
85
+ scale: [number, number, number];
86
+ weights: number[];
87
+ morphPrimitives: GltfMorphPrimitiveRuntime[];
88
+ }
89
+
90
+ export interface GltfMorphPrimitiveRuntime {
91
+ geometry: Geometry3D;
92
+ basePositions: Float32Array;
93
+ baseNormals: Float32Array | null;
94
+ positionTargets: Float32Array[];
95
+ normalTargets: Float32Array[];
96
+ }
97
+
98
+ export interface GltfAnimationChannelRuntime {
99
+ target: GltfAnimationTarget;
100
+ path: GltfAnimationPath;
101
+ interpolation: GltfAnimationInterpolation;
102
+ valueSize: number;
103
+ input: Float32Array;
104
+ output: Float32Array;
105
+ sampleA: Float32Array;
106
+ sampleB: Float32Array;
107
+ sampleOut: Float32Array;
108
+ quatScratch: Float32Array;
109
+ }
110
+
111
+ export interface GltfAnimationClip {
112
+ name: string;
113
+ duration: number;
114
+ channels: GltfAnimationChannelRuntime[];
115
+ skinnedPrimitives: GltfSkinnedPrimitiveRuntime[];
116
+ stateCache: Map<GltfAnimationTarget, GltfAnimationTargetState>;
117
+ activeStates: GltfAnimationTargetState[];
118
+ }
119
+
120
+ export interface GltfAnimationTargetState {
121
+ target: GltfAnimationTarget;
122
+ translation: Float32Array;
123
+ rotation: Float32Array;
124
+ scale: Float32Array;
125
+ matrix: Float32Array<ArrayBuffer>;
126
+ active: boolean;
127
+ }
128
+
129
+ export interface GltfAssetStats {
130
+ meshCount: number;
131
+ primitiveCount: number;
132
+ materialCount: number;
133
+ textureCount: number;
134
+ imageCount: number;
135
+ animationCount: number;
136
+ }
137
+
138
+ export interface GltfLoadPhaseTimings {
139
+ readonly fetchMs: number;
140
+ readonly workerParseMs: number;
141
+ readonly dracoDecodeMs: number;
142
+ readonly geometryPreparationMs: number;
143
+ readonly instantiateMs: number;
144
+ readonly textureDecodeTranscodeUploadMs: number;
145
+ readonly totalMs: number;
146
+ }
147
+
148
+ export interface GltfLoadMetrics {
149
+ readonly timings: GltfLoadPhaseTimings;
150
+ readonly sourceBytes: number;
151
+ readonly decodedGeometryBytes: number;
152
+ readonly workerTransferBytes: number;
153
+ readonly workerTransferBufferCount: number;
154
+ }
155
+
156
+ export interface GltfLoadDiagnostics {
157
+ onDracoDecode?(durationMs: number, decodedBytes: number): void;
158
+ }
159
+
160
+ export interface LoadGltfOptions {
161
+ scene?: number | null;
162
+ baseColorFactor?: [number, number, number, number];
163
+ dracoDecoder?: DracoDecoderModule | Promise<DracoDecoderModule> | DracoDecoderFactory | null;
164
+ dracoDecoderConfig?: DracoDecoderConfig;
165
+ assetManager?: AssetManager | null;
166
+ assetWorker?: GltfAssetWorker | null;
167
+ signal?: AbortSignal;
168
+ onWarning?: (warning: GltfLoadWarning) => void;
169
+ diagnostics?: GltfLoadDiagnostics;
170
+ extensionAdapters?: readonly GltfExtensionAdapter[];
171
+ }
172
+
173
+ export interface GltfAssetWorker {
174
+ loadParsedAsset(src: string, options?: { signal?: AbortSignal; dracoDecoderConfig?: DracoDecoderConfig }): Promise<GltfParsedAsset>;
175
+ }
176
+
177
+ export interface GltfParsedAsset {
178
+ gltf: GltfAsset;
179
+ binaryChunk: ArrayBuffer | null;
180
+ buffers: ArrayBuffer[];
181
+ baseUrl: string;
182
+ geometryPayloads?: GltfGeometryPayloadMatrix;
183
+ metrics?: GltfParsedAssetMetrics;
184
+ }
185
+
186
+ export interface GltfParsedAssetMetrics {
187
+ readonly fetchMs: number;
188
+ readonly parseMs: number;
189
+ readonly workerParseMs: number;
190
+ readonly dracoDecodeMs: number;
191
+ readonly geometryPreparationMs: number;
192
+ readonly sourceBytes: number;
193
+ readonly workerTransferBytes: number;
194
+ readonly workerTransferBufferCount: number;
195
+ }
196
+
197
+ export function isGltfParsedAsset(value: unknown): value is GltfParsedAsset {
198
+ if (!isRecord(value)) return false;
199
+ if (!isGltfAsset(value.gltf)) return false;
200
+ if (!(value.binaryChunk === null || value.binaryChunk instanceof ArrayBuffer)) return false;
201
+ if (!Array.isArray(value.buffers) || !value.buffers.every(buffer => buffer instanceof ArrayBuffer)) return false;
202
+ if (typeof value.baseUrl !== 'string') return false;
203
+ if (value.geometryPayloads !== undefined && !isGeometryPayloadMatrix(value.geometryPayloads)) return false;
204
+ return value.metrics === undefined || isParsedAssetMetrics(value.metrics);
205
+ }
206
+
207
+ export type GltfGeometryPayloadMatrix = Array<Array<GltfPrimitiveGeometryPayload | null>>;
208
+
209
+ export interface GltfPrimitiveGeometryPayload {
210
+ positions: Float32Array;
211
+ indices?: Uint16Array | Uint32Array;
212
+ normals?: Float32Array;
213
+ textureCoordinates: Array<{ set: number; data: Float32Array }>;
214
+ joints?: Uint16Array | Uint32Array;
215
+ weights?: Float32Array;
216
+ positionTargets: Float32Array[];
217
+ normalTargets: Float32Array[];
218
+ }
219
+
220
+ export interface DracoDecoderConfig {
221
+ scriptUrl?: string;
222
+ locateFile?: (path: string, prefix: string) => string;
223
+ wasmBinary?: ArrayBuffer | Uint8Array;
224
+ }
225
+
226
+ export interface DracoDecoderArray {
227
+ GetValue(index: number): number;
228
+ size(): number;
229
+ }
230
+
231
+ export interface DracoPointAttribute { size(): number; }
232
+ export interface DracoStatus { ok(): boolean; error_msg(): string; }
233
+ export interface DracoMesh { num_faces(): number; num_points(): number; }
234
+
235
+ export interface DracoDecoder {
236
+ DecodeBufferToMesh(buffer: unknown, mesh: DracoMesh): DracoStatus;
237
+ GetAttributeByUniqueId(mesh: DracoMesh, uniqueId: number): DracoPointAttribute;
238
+ GetAttributeFloatForAllPoints(mesh: DracoMesh, attribute: DracoPointAttribute, out: DracoDecoderArray): boolean;
239
+ GetAttributeUInt16ForAllPoints?(mesh: DracoMesh, attribute: DracoPointAttribute, out: DracoDecoderArray): boolean;
240
+ GetAttributeUInt32ForAllPoints?(mesh: DracoMesh, attribute: DracoPointAttribute, out: DracoDecoderArray): boolean;
241
+ GetFaceFromMesh(mesh: DracoMesh, faceIndex: number, out: DracoDecoderArray): boolean;
242
+ }
243
+
244
+ export interface DracoDecoderModule {
245
+ Decoder: new () => DracoDecoder;
246
+ DecoderBuffer: new () => { Init(data: Uint8Array, byteLength: number): void };
247
+ Mesh: new () => DracoMesh;
248
+ DracoFloat32Array: new () => DracoDecoderArray;
249
+ DracoUInt16Array?: new () => DracoDecoderArray;
250
+ DracoUInt32Array?: new () => DracoDecoderArray;
251
+ DracoInt32Array: new () => DracoDecoderArray;
252
+ destroy(object: unknown): void;
253
+ }
254
+
255
+ export type DracoDecoderFactory = (config?: DracoDecoderConfig) => Promise<DracoDecoderModule> | DracoDecoderModule;
256
+
257
+ export interface DracoPrimitiveGeometry {
258
+ positions: Float32Array;
259
+ normals?: Float32Array;
260
+ textureCoordinates: Array<{ set: number; data: Float32Array }>;
261
+ joints?: Uint16Array | Uint32Array;
262
+ weights?: Float32Array;
263
+ indices: Uint16Array | Uint32Array;
264
+ }
265
+
266
+ export interface GltfLoadContext {
267
+ baseUrl: string;
268
+ assetIdentity: string;
269
+ objectUrls: string[];
270
+ imageSources: Map<number, string>;
271
+ sharedImageSources: boolean;
272
+ preloadedTextures: Map<string, GPUTexture>;
273
+ animationTargets: Map<number, GltfAnimationTarget>;
274
+ skinnedPrimitives: GltfSkinnedPrimitiveRuntime[];
275
+ pendingSkinnedPrimitives: GltfPendingSkinnedPrimitive[];
276
+ assetHandles: AssetHandle<unknown>[];
277
+ geometryPayloads?: GltfGeometryPayloadMatrix;
278
+ compatibilityPrimitives: GltfPrimitiveCompatibilityInput[];
279
+ extensionAdapters: readonly GltfExtensionAdapter[];
280
+ }
281
+
282
+ export interface GltfPendingSkinnedPrimitive {
283
+ skinIndex: number;
284
+ geometry: Geometry3D;
285
+ meshEntity: Entity;
286
+ joints: Uint16Array | Uint32Array;
287
+ weights: Float32Array;
288
+ }
289
+
290
+ export interface GltfSkinnedPrimitiveRuntime {
291
+ geometry: Geometry3D;
292
+ meshEntity: Entity;
293
+ jointTargets: Array<GltfAnimationTarget | null>;
294
+ inverseBindMatrices: Float32Array[];
295
+ jointMatrices: Float32Array;
296
+ inverseMeshWorldScratch: Float32Array;
297
+ jointMatrixScratch: Float32Array;
298
+ skinMatrixScratch: Float32Array;
299
+ lastMeshWorldVersion: number;
300
+ lastGeometryVersion: number;
301
+ lastJointWorldVersions: Int32Array;
302
+ }
303
+
304
+ function isGeometryPayloadMatrix(value: unknown): value is GltfGeometryPayloadMatrix {
305
+ return Array.isArray(value) && value.every(mesh => Array.isArray(mesh) && mesh.every(payload => {
306
+ if (payload === null) return true;
307
+ if (!isRecord(payload) || !(payload.positions instanceof Float32Array)) return false;
308
+ if (payload.indices !== undefined && !(payload.indices instanceof Uint16Array) && !(payload.indices instanceof Uint32Array)) return false;
309
+ if (payload.normals !== undefined && !(payload.normals instanceof Float32Array)) return false;
310
+ if (!Array.isArray(payload.textureCoordinates)
311
+ || !payload.textureCoordinates.every(entry => isRecord(entry)
312
+ && typeof entry.set === 'number'
313
+ && Number.isInteger(entry.set)
314
+ && entry.set >= 0
315
+ && entry.data instanceof Float32Array)) return false;
316
+ if (!Array.isArray(payload.positionTargets) || !payload.positionTargets.every(target => target instanceof Float32Array)) return false;
317
+ return Array.isArray(payload.normalTargets) && payload.normalTargets.every(target => target instanceof Float32Array);
318
+ }));
319
+ }
320
+
321
+ function isParsedAssetMetrics(value: unknown): value is GltfParsedAssetMetrics {
322
+ if (!isRecord(value)) return false;
323
+ return [
324
+ 'fetchMs',
325
+ 'parseMs',
326
+ 'workerParseMs',
327
+ 'dracoDecodeMs',
328
+ 'geometryPreparationMs',
329
+ 'sourceBytes',
330
+ 'workerTransferBytes',
331
+ 'workerTransferBufferCount',
332
+ ].every(key => typeof value[key] === 'number' && Number.isFinite(value[key]) && value[key] >= 0);
333
+ }