@haiyue/extensions 0.1.0 → 0.2.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 (269) hide show
  1. package/README.md +25 -0
  2. package/dist/animation/Animation2DComponent.d.ts +18 -0
  3. package/dist/animation/Animation2DExtensionRegistry.d.ts +7 -0
  4. package/dist/animation/Animation2DRenderSystem.d.ts +6 -0
  5. package/dist/animation/Animation2DRuntime.d.ts +6 -2
  6. package/dist/animation/AnimationTextRasterizer.d.ts +4 -0
  7. package/dist/animation/AnimationVisual2D.d.ts +58 -2
  8. package/dist/animation/interaction/InteractionRuntime.d.ts +83 -0
  9. package/dist/animation/interaction/runtime-types.d.ts +257 -0
  10. package/dist/animation.d.ts +3 -1
  11. package/dist/animation.js +551 -59
  12. package/dist/animation3d.js +1 -1
  13. package/dist/canvas-text.js +1 -1
  14. package/dist/chunks/2d-ui-animation-2d.generated-FpziAeGJ.js +4 -0
  15. package/dist/chunks/2d-ui-indexed-sprite.generated-DmKR0CC3.js +4 -0
  16. package/dist/chunks/Animation2DStateMachine-BHcA6Cu3.js +18212 -0
  17. package/dist/chunks/{AnimationStateMachineController-BIcAh-sT.js → AnimationStateMachineController-4sKaqh9E.js} +2 -2
  18. package/dist/chunks/AnimationVisual2D-8y3qp0_U.js +230 -0
  19. package/dist/chunks/{RenderSystem2DBase-DDT61dAu.js → RenderSystem2DBase-CF2s00vg.js} +2 -2
  20. package/dist/controls/VirtualJoystickControls.d.ts +46 -0
  21. package/dist/controls/contracts.d.ts +91 -0
  22. package/dist/controls.d.ts +2 -0
  23. package/dist/controls.js +358 -0
  24. package/dist/deformable-animation/runtime/DeformableMesh2DRuntimeExtension.d.ts +11 -0
  25. package/dist/deformable-animation/runtime/DeformableMesh2DSampler.d.ts +11 -0
  26. package/dist/deformable-animation.d.ts +5 -0
  27. package/dist/deformable-animation.js +316 -0
  28. package/dist/experimental-indexed-sprite.d.ts +5 -0
  29. package/dist/experimental-indexed-sprite.js +482 -0
  30. package/dist/gltf-worker-runtime.js +9 -9
  31. package/dist/hya-state-machine.js +3 -2
  32. package/dist/index.js +1 -1
  33. package/dist/indexed-sprite/AtlasLayout.d.ts +2 -0
  34. package/dist/indexed-sprite/IndexedSpriteRenderer.d.ts +23 -0
  35. package/dist/indexed-sprite/contracts.d.ts +89 -0
  36. package/dist/internal/2d-ui-shader-artifact.js +232 -23
  37. package/dist/ray-tracing/acceleration/bvh.d.ts +37 -0
  38. package/dist/ray-tracing/acceleration/index.d.ts +6 -0
  39. package/dist/ray-tracing/acceleration/pack.d.ts +152 -0
  40. package/dist/ray-tracing/acceleration/query.d.ts +4 -0
  41. package/dist/ray-tracing/acceleration/runtime.d.ts +30 -0
  42. package/dist/ray-tracing/acceleration/tlas.d.ts +4 -0
  43. package/dist/ray-tracing/acceleration/types.d.ts +165 -0
  44. package/dist/ray-tracing/denoise/index.d.ts +3 -0
  45. package/dist/ray-tracing/denoise/layout.d.ts +9 -0
  46. package/dist/ray-tracing/denoise/runtime.d.ts +23 -0
  47. package/dist/ray-tracing/denoise/types.d.ts +28 -0
  48. package/dist/ray-tracing/hybrid/contract.d.ts +2 -0
  49. package/dist/ray-tracing/hybrid/index.d.ts +5 -0
  50. package/dist/ray-tracing/hybrid/layout.d.ts +17 -0
  51. package/dist/ray-tracing/hybrid/plan.d.ts +2 -0
  52. package/dist/ray-tracing/hybrid/runtime.d.ts +31 -0
  53. package/dist/ray-tracing/hybrid/shaders/hybrid-artifact.generated.d.ts +625 -0
  54. package/dist/ray-tracing/hybrid/types.d.ts +144 -0
  55. package/dist/ray-tracing/lifecycle/device-recovery.d.ts +31 -0
  56. package/dist/ray-tracing/lifecycle/index.d.ts +2 -0
  57. package/dist/ray-tracing/lifecycle/types.d.ts +37 -0
  58. package/dist/ray-tracing/material/index.d.ts +2 -0
  59. package/dist/ray-tracing/material/pack.d.ts +5 -0
  60. package/dist/ray-tracing/material/types.d.ts +63 -0
  61. package/dist/ray-tracing/reference/index.d.ts +122 -0
  62. package/dist/ray-tracing/renderer/index.d.ts +7 -0
  63. package/dist/ray-tracing/renderer/layout.d.ts +20 -0
  64. package/dist/ray-tracing/renderer/plan.d.ts +2 -0
  65. package/dist/ray-tracing/renderer/reference.d.ts +17 -0
  66. package/dist/ray-tracing/renderer/runtime.d.ts +39 -0
  67. package/dist/ray-tracing/renderer/scene.d.ts +4 -0
  68. package/dist/ray-tracing/renderer/types.d.ts +115 -0
  69. package/dist/ray-tracing/sampling/index.d.ts +8 -0
  70. package/dist/ray-tracing/sampling/layout.d.ts +12 -0
  71. package/dist/ray-tracing/sampling/plan.d.ts +5 -0
  72. package/dist/ray-tracing/sampling/revision.d.ts +15 -0
  73. package/dist/ray-tracing/sampling/runtime.d.ts +44 -0
  74. package/dist/ray-tracing/sampling/sequence.d.ts +2 -0
  75. package/dist/ray-tracing/sampling/types.d.ts +96 -0
  76. package/dist/ray-tracing/scene/index.d.ts +41 -0
  77. package/dist/ray-tracing/traversal/index.d.ts +4 -0
  78. package/dist/ray-tracing/traversal/layout.d.ts +16 -0
  79. package/dist/ray-tracing/traversal/plan.d.ts +2 -0
  80. package/dist/ray-tracing/traversal/runtime.d.ts +25 -0
  81. package/dist/ray-tracing/traversal/types.d.ts +79 -0
  82. package/dist/ray-tracing/worker/client.d.ts +25 -0
  83. package/dist/ray-tracing/worker/index.d.ts +5 -0
  84. package/dist/ray-tracing/worker/runtime.d.ts +11 -0
  85. package/dist/ray-tracing/worker/serialization.d.ts +16 -0
  86. package/dist/ray-tracing/worker/source.d.ts +1 -0
  87. package/dist/ray-tracing/worker/types.d.ts +91 -0
  88. package/dist/ray-tracing.d.ts +17 -0
  89. package/dist/ray-tracing.js +7666 -0
  90. package/dist/spine.js +1 -1
  91. package/dist/tilemap.js +1 -1
  92. package/package.json +26 -23
  93. package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +0 -27
  94. package/dist/animation/Particle2DDescriptorAdapter.d.ts +0 -5
  95. package/dist/animation3d/Animation3DResource.d.ts +0 -28
  96. package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +0 -65
  97. package/dist/animation3d/hya/index.d.ts +0 -4
  98. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +0 -81
  99. package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +0 -39
  100. package/dist/animation3d/runtime/integration/index.d.ts +0 -2
  101. package/dist/animation3d/runtime/mixer/Action.d.ts +0 -150
  102. package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +0 -6
  103. package/dist/animation3d/runtime/mixer/Mixer.d.ts +0 -59
  104. package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +0 -1
  105. package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +0 -24
  106. package/dist/animation3d/runtime/mixer/index.d.ts +0 -4
  107. package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +0 -1
  108. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +0 -1
  109. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +0 -1
  110. package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +0 -1
  111. package/dist/animation3d/runtime/state-machine/index.d.ts +0 -6
  112. package/dist/benchmark.d.ts +0 -30
  113. package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +0 -4
  114. package/dist/chunks/Animation2DStateMachine-9IonguNa.js +0 -3245
  115. package/dist/gltf/GltfAccessorReader.d.ts +0 -7
  116. package/dist/gltf/GltfDracoDecoder.d.ts +0 -4
  117. package/dist/gltf/GltfLoaderErrors.d.ts +0 -4
  118. package/dist/gltf/GltfMaterialDescriptor.d.ts +0 -23
  119. package/dist/gltf/GltfMaterialLoader.d.ts +0 -6
  120. package/dist/gltf-worker-runtime.d.ts +0 -7
  121. package/dist/plugins/pluginUtils.d.ts +0 -20
  122. package/dist/plugins.d.ts +0 -6
  123. package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +0 -658
  124. package/dist/spine/Spine2DGpuRenderer.d.ts +0 -65
  125. package/dist/spine/Spine2DRuntime.d.ts +0 -103
  126. package/dist/spine/SpineAnimationBoneTimelines.d.ts +0 -8
  127. package/dist/spine/SpineFloatBuilder.d.ts +0 -15
  128. package/dist/spine/SpinePathConstraintSolver.d.ts +0 -32
  129. package/dist/spine/SpineSkeletonRuntime.d.ts +0 -185
  130. package/dist/spine/SpineSlotAnimation.d.ts +0 -17
  131. package/dist/spine/SpineTimelineRuntime.d.ts +0 -25
  132. package/dist/spine/SpineVertexBuilder.d.ts +0 -61
  133. package/dist/tilemap/Tilemap2DRenderer.d.ts +0 -24
  134. package/dist/utils/arrayAccess.d.ts +0 -4
  135. package/dist/utils/camera2d.d.ts +0 -12
  136. package/src/animation/Animation2DComponent.ts +0 -135
  137. package/src/animation/Animation2DExtensionRegistry.ts +0 -52
  138. package/src/animation/Animation2DRenderSystem.ts +0 -1026
  139. package/src/animation/Animation2DRuntime.ts +0 -1326
  140. package/src/animation/Animation2DStateMachine.ts +0 -39
  141. package/src/animation/Animation2DStateMachineComponent.ts +0 -228
  142. package/src/animation/Animation2DStateMachineRuntime.ts +0 -141
  143. package/src/animation/Animation2DStateMachineSystem.ts +0 -60
  144. package/src/animation/Animation2DStateMachineVisualRuntime.ts +0 -282
  145. package/src/animation/Animation2DSystem.ts +0 -72
  146. package/src/animation/AnimationAssetLoader.ts +0 -84
  147. package/src/animation/AnimationAudioClip.ts +0 -140
  148. package/src/animation/AnimationPathTessellator.ts +0 -691
  149. package/src/animation/AnimationTextRasterizer.ts +0 -340
  150. package/src/animation/AnimationVisual2D.ts +0 -153
  151. package/src/animation/HyaAnimation2DClipAdapter.ts +0 -845
  152. package/src/animation/Particle2DDescriptorAdapter.ts +0 -35
  153. package/src/animation/runtime/mixer/Action.ts +0 -876
  154. package/src/animation/runtime/mixer/Mixer.ts +0 -505
  155. package/src/animation/runtime/mixer/PoseBuffer.ts +0 -105
  156. package/src/animation/runtime/mixer/Sampler.ts +0 -252
  157. package/src/animation/runtime/mixer/Types.ts +0 -138
  158. package/src/animation/runtime/mixer/index.ts +0 -31
  159. package/src/animation-state-machine/AnimationStateMachine.ts +0 -146
  160. package/src/animation-state-machine/AnimationStateMachineChannels.ts +0 -116
  161. package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +0 -197
  162. package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +0 -503
  163. package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +0 -763
  164. package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +0 -987
  165. package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +0 -54
  166. package/src/animation-state-machine/runtime/index.ts +0 -47
  167. package/src/animation.ts +0 -33
  168. package/src/animation3d/Animation3DAction.ts +0 -73
  169. package/src/animation3d/Animation3DBinding.ts +0 -116
  170. package/src/animation3d/Animation3DClip.ts +0 -22
  171. package/src/animation3d/Animation3DError.ts +0 -34
  172. package/src/animation3d/Animation3DMixer.ts +0 -82
  173. package/src/animation3d/Animation3DPose.ts +0 -100
  174. package/src/animation3d/Animation3DPoseBuffer.ts +0 -85
  175. package/src/animation3d/Animation3DResource.ts +0 -49
  176. package/src/animation3d/Animation3DStateMachine.ts +0 -126
  177. package/src/animation3d/Animation3DStateMachineRuntime.ts +0 -191
  178. package/src/animation3d/Animation3DTrack.ts +0 -29
  179. package/src/animation3d/hya/HyaAnimation3DRuntime.ts +0 -756
  180. package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +0 -618
  181. package/src/animation3d/hya/HyaAnimation3DTypes.ts +0 -168
  182. package/src/animation3d/hya/index.ts +0 -10
  183. package/src/animation3d/index.ts +0 -76
  184. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +0 -325
  185. package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +0 -158
  186. package/src/animation3d/runtime/integration/index.ts +0 -9
  187. package/src/animation3d/runtime/mixer/Action.ts +0 -833
  188. package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +0 -26
  189. package/src/animation3d/runtime/mixer/Mixer.ts +0 -562
  190. package/src/animation3d/runtime/mixer/PoseBuffer.ts +0 -1
  191. package/src/animation3d/runtime/mixer/TrackSampler.ts +0 -399
  192. package/src/animation3d/runtime/mixer/index.ts +0 -8
  193. package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +0 -4
  194. package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +0 -1
  195. package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +0 -1
  196. package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +0 -1
  197. package/src/animation3d/runtime/state-machine/index.ts +0 -45
  198. package/src/animation3d.ts +0 -5
  199. package/src/benchmark.ts +0 -168
  200. package/src/canvas-text/CanvasText2DRenderSystem.ts +0 -292
  201. package/src/canvas-text/CanvasTextComponent.ts +0 -47
  202. package/src/canvas-text.ts +0 -4
  203. package/src/experimental-gltf-worker.ts +0 -18
  204. package/src/experimental-spine-worker.ts +0 -9
  205. package/src/gltf/GltfAccessorReader.ts +0 -271
  206. package/src/gltf/GltfAnimation3DAdapter.ts +0 -680
  207. package/src/gltf/GltfAnimationRuntime.ts +0 -392
  208. package/src/gltf/GltfAssetWorkerClient.ts +0 -136
  209. package/src/gltf/GltfCompatibilityReport.ts +0 -214
  210. package/src/gltf/GltfConservativeBounds.ts +0 -219
  211. package/src/gltf/GltfDracoDecoder.ts +0 -251
  212. package/src/gltf/GltfExtensionAdapter.ts +0 -340
  213. package/src/gltf/GltfLoaderContract.ts +0 -333
  214. package/src/gltf/GltfLoaderErrors.ts +0 -59
  215. package/src/gltf/GltfMaterialDescriptor.ts +0 -134
  216. package/src/gltf/GltfMaterialEncoder.ts +0 -173
  217. package/src/gltf/GltfMaterialLoader.ts +0 -293
  218. package/src/gltf/GltfModelComponent.ts +0 -115
  219. package/src/gltf/GltfModelSystem.ts +0 -208
  220. package/src/gltf/GltfPlugin.ts +0 -84
  221. package/src/gltf/GltfSchema.ts +0 -229
  222. package/src/gltf/GltfUvSemanticPlanner.ts +0 -166
  223. package/src/gltf/gltfLoader.ts +0 -910
  224. package/src/gltf-animation3d.ts +0 -10
  225. package/src/gltf-worker-runtime.ts +0 -10
  226. package/src/gltf.ts +0 -56
  227. package/src/grid/Grid2DComponent.ts +0 -69
  228. package/src/grid.ts +0 -2
  229. package/src/hya-state-machine.ts +0 -19
  230. package/src/index.ts +0 -2
  231. package/src/plugins/pluginUtils.ts +0 -50
  232. package/src/plugins.ts +0 -6
  233. package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +0 -242
  234. package/src/shaders/generated/2d-ui-artifact.generated.ts +0 -867
  235. package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +0 -38
  236. package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +0 -41
  237. package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +0 -36
  238. package/src/spine/Spine2DComponent.ts +0 -168
  239. package/src/spine/Spine2DGpuRenderer.ts +0 -449
  240. package/src/spine/Spine2DRenderSystem.ts +0 -199
  241. package/src/spine/Spine2DRuntime.ts +0 -1529
  242. package/src/spine/SpineAnimationBoneTimelines.ts +0 -30
  243. package/src/spine/SpineAssetParser.ts +0 -20
  244. package/src/spine/SpineAssetWorkerClient.ts +0 -112
  245. package/src/spine/SpineAssetWorkerContract.ts +0 -4
  246. package/src/spine/SpineAtlasParser.ts +0 -127
  247. package/src/spine/SpineFloatBuilder.ts +0 -66
  248. package/src/spine/SpinePathConstraintSolver.ts +0 -582
  249. package/src/spine/SpinePlugin.ts +0 -76
  250. package/src/spine/SpineSkeletonRuntime.ts +0 -521
  251. package/src/spine/SpineSlotAnimation.ts +0 -195
  252. package/src/spine/SpineTimelineRuntime.ts +0 -453
  253. package/src/spine/SpineVertexBuilder.ts +0 -686
  254. package/src/spine.ts +0 -7
  255. package/src/tilemap/Tilemap2DComponent.ts +0 -232
  256. package/src/tilemap/Tilemap2DRenderSystem.ts +0 -58
  257. package/src/tilemap/Tilemap2DRenderer.ts +0 -289
  258. package/src/tilemap/TilemapPlugin.ts +0 -75
  259. package/src/tilemap.ts +0 -6
  260. package/src/tween/Tween2DComponent.ts +0 -83
  261. package/src/tween/Tween2DSystem.ts +0 -78
  262. package/src/tween.ts +0 -4
  263. package/src/types/earcut.d.ts +0 -7
  264. package/src/types/wgsl.d.ts +0 -4
  265. package/src/utils/RenderSystem2DBase.ts +0 -164
  266. package/src/utils/arrayAccess.ts +0 -17
  267. package/src/utils/camera2d.ts +0 -68
  268. package/src/utils/render2dGpu.ts +0 -132
  269. package/test/fixtures/gltf/animation-characterization.gltf +0 -344
@@ -1,115 +0,0 @@
1
- import { Component, Entity } from '@haiyue/engine';
2
- import { UniqueCheckType } from '@haiyue/engine/ecs';
3
- import type { GltfAnimationClip, GltfAnimationInfo, GltfAssetStats } from './GltfLoaderContract';
4
- import type { GltfCompatibilityReport } from './GltfCompatibilityReport';
5
-
6
- export interface GltfModelComponentOptions {
7
- src?: string;
8
- scene?: number;
9
- autoLoad?: boolean;
10
- clearPrevious?: boolean;
11
- baseColorFactor?: [number, number, number, number];
12
- }
13
-
14
- export type GltfModelStatus = 'idle' | 'loading' | 'loaded' | 'error';
15
-
16
- export class GltfModelComponent extends Component {
17
- static override UniqueCheckType = UniqueCheckType.SYMBOL | UniqueCheckType.REPLACE;
18
- static override UniqueSymbol = Symbol.for('GltfModelComponent');
19
- static editor = {
20
- fields: {
21
- src: {
22
- type: 'asset-ref',
23
- label: 'Source',
24
- assetType: 'gltf',
25
- placeholder: 'glTF / GLB URL or asset key',
26
- validate: (value: unknown) => String(value ?? '').trim() ? null : 'Source is required.',
27
- },
28
- scene: {
29
- type: 'number',
30
- label: 'Scene Index',
31
- min: 0,
32
- step: 1,
33
- visibleWhen: (component: GltfModelComponent) => String(component.src).trim().length > 0,
34
- },
35
- autoLoad: { type: 'boolean', label: 'Auto Load' },
36
- clearPrevious: { type: 'boolean', label: 'Clear Previous' },
37
- baseColorFactor: {
38
- type: 'array',
39
- label: 'Fallback Color',
40
- rows: 2,
41
- validate: (value: unknown) => Array.isArray(value) && value.length === 4 ? null : 'Fallback Color must be [r, g, b, a].',
42
- },
43
- },
44
- };
45
-
46
- private _src = '';
47
- private _scene: number | null = null;
48
- private _sourceKey = '|';
49
- private _sourceKeyDirty = false;
50
-
51
- autoLoad: boolean;
52
- clearPrevious: boolean;
53
- baseColorFactor: [number, number, number, number];
54
- status: GltfModelStatus = 'idle';
55
- error: string | null = null;
56
-
57
- /** Runtime root inserted by GltfModelSystem. Do not serialize. */
58
- runtimeRoot: Entity | null = null;
59
- runtimeAnimations: GltfAnimationInfo[] = [];
60
- runtimeAnimationClips: GltfAnimationClip[] = [];
61
- runtimeAssetStats: GltfAssetStats | null = null;
62
- runtimeCompatibilityReport: GltfCompatibilityReport | null = null;
63
- runtimeMaterialVariants: readonly string[] = [];
64
- runtimeSourceKey = '';
65
- loadingSourceKey = '';
66
-
67
- constructor(options: GltfModelComponentOptions = {}) {
68
- super('GltfModelComponent');
69
- this.src = options.src ?? '';
70
- this.scene = options.scene ?? null;
71
- this.autoLoad = options.autoLoad ?? true;
72
- this.clearPrevious = options.clearPrevious ?? true;
73
- this.baseColorFactor = options.baseColorFactor
74
- ? [...options.baseColorFactor] as [number, number, number, number]
75
- : [1, 1, 1, 1];
76
- }
77
-
78
- get src(): string {
79
- return this._src;
80
- }
81
-
82
- set src(value: string) {
83
- if (this._src === value) return;
84
- this._src = value;
85
- this._sourceKeyDirty = true;
86
- }
87
-
88
- get scene(): number | null {
89
- return this._scene;
90
- }
91
-
92
- set scene(value: number | null) {
93
- if (this._scene === value) return;
94
- this._scene = value;
95
- this._sourceKeyDirty = true;
96
- }
97
-
98
- get sourceKey(): string {
99
- if (this._sourceKeyDirty) {
100
- this._sourceKey = `${this._src}|${this._scene ?? ''}`;
101
- this._sourceKeyDirty = false;
102
- }
103
- return this._sourceKey;
104
- }
105
-
106
- override clone(): GltfModelComponent {
107
- return new GltfModelComponent({
108
- src: this.src,
109
- ...(this.scene === null ? {} : { scene: this.scene }),
110
- autoLoad: this.autoLoad,
111
- clearPrevious: this.clearPrevious,
112
- baseColorFactor: this.baseColorFactor,
113
- });
114
- }
115
- }
@@ -1,208 +0,0 @@
1
- import { AssetJob, type AssetJobPriority, type AssetManager } from '@haiyue/engine/assets';
2
- import { Entity, System, type World } from '@haiyue/engine';
3
- import { GltfModelComponent } from './GltfModelComponent';
4
- import { disposeGltfModel, loadGltfModel } from './gltfLoader';
5
- import type { DracoDecoderConfig, DracoDecoderFactory, DracoDecoderModule, GltfAssetWorker, LoadedGltfModel } from './GltfLoaderContract';
6
-
7
- export interface GltfModelSystemOptions {
8
- priority?: number;
9
- dracoDecoder?: DracoDecoderModule | Promise<DracoDecoderModule> | DracoDecoderFactory | null;
10
- dracoDecoderConfig?: DracoDecoderConfig;
11
- loadTimeoutMs?: number;
12
- assetManager?: AssetManager | null;
13
- assetWorker?: GltfAssetWorker | null;
14
- assetPriority?: AssetJobPriority | number;
15
- }
16
-
17
- interface PendingGltfLoad {
18
- key: string;
19
- job: AssetJob<LoadedGltfModel>;
20
- }
21
-
22
- export class GltfModelSystem extends System {
23
- private dracoDecoder: DracoDecoderModule | Promise<DracoDecoderModule> | DracoDecoderFactory | null;
24
- private dracoDecoderConfig: DracoDecoderConfig | undefined;
25
- private loadTimeoutMs: number;
26
- private assetManager: AssetManager | null;
27
- private assetWorker: GltfAssetWorker | null;
28
- private assetPriority: AssetJobPriority | number;
29
- private readonly componentModels = new Map<GltfModelComponent, Set<LoadedGltfModel>>();
30
- private readonly pendingLoads = new Map<GltfModelComponent, PendingGltfLoad>();
31
- private readonly failedLoads = new Map<GltfModelComponent, string>();
32
- private readonly liveComponents = new Set<GltfModelComponent>();
33
-
34
- constructor(options: GltfModelSystemOptions = {}) {
35
- super({ all: [GltfModelComponent] });
36
- this.name = 'GltfModelSystem';
37
- if (options.priority !== undefined) this.priority = options.priority;
38
- this.dracoDecoder = options.dracoDecoder ?? null;
39
- this.dracoDecoderConfig = options.dracoDecoderConfig;
40
- this.loadTimeoutMs = Math.max(0, options.loadTimeoutMs ?? 30000);
41
- this.assetManager = options.assetManager ?? null;
42
- this.assetWorker = options.assetWorker ?? null;
43
- this.assetPriority = options.assetPriority ?? 'normal';
44
- }
45
-
46
- override update(world: World, _time: number, _delta: number): this {
47
- this.liveComponents.clear();
48
- const entities = this.entitySet.get(world);
49
- if (entities) for (const entity of entities) {
50
- const component = entity.getComponent(GltfModelComponent);
51
- if (!component) continue;
52
- this.liveComponents.add(component);
53
- if (!component.autoLoad || !component.src) continue;
54
- const key = component.sourceKey;
55
- if (component.runtimeSourceKey === key
56
- || component.loadingSourceKey === key
57
- || this.failedLoads.get(component) === key) continue;
58
- this.loadIntoEntity(entity, component, key);
59
- }
60
- this.releaseModelsNotIn(this.liveComponents);
61
- this.abortLoadsNotIn(this.liveComponents);
62
- this.releaseFailuresNotIn(this.liveComponents);
63
- return this;
64
- }
65
-
66
- override destroy(): this {
67
- for (const component of [...this.pendingLoads.keys()]) this.abortPendingLoad(component);
68
- this.disposeAllModels();
69
- this.failedLoads.clear();
70
- return super.destroy();
71
- }
72
-
73
- private async loadIntoEntity(entity: Entity, component: GltfModelComponent, key: string): Promise<void> {
74
- this.abortPendingLoad(component);
75
- component.status = 'loading';
76
- component.error = null;
77
- component.loadingSourceKey = key;
78
- this.failedLoads.delete(component);
79
- component.runtimeAnimations = [];
80
- component.runtimeAnimationClips = [];
81
- component.runtimeAssetStats = null;
82
- component.runtimeCompatibilityReport = null;
83
- component.runtimeMaterialVariants = [];
84
- const pending = this.createPendingLoad(component, key);
85
- try {
86
- const model = await pending.job.start(async context => {
87
- context.setPhase('parsing');
88
- return await loadGltfModel(component.src, {
89
- scene: component.scene,
90
- baseColorFactor: component.baseColorFactor,
91
- dracoDecoder: this.dracoDecoder,
92
- ...(this.dracoDecoderConfig === undefined ? {} : { dracoDecoderConfig: this.dracoDecoderConfig }),
93
- assetManager: this.assetManager,
94
- assetWorker: this.assetWorker,
95
- signal: context.signal,
96
- });
97
- });
98
- if (component.loadingSourceKey !== key) {
99
- disposeGltfModel(model);
100
- return;
101
- }
102
- if (component.clearPrevious) {
103
- if (component.runtimeRoot) entity.removeChild(component.runtimeRoot);
104
- this.disposeModelsForComponent(component);
105
- }
106
- model.root.name = `${entity.name || 'glTF'} Model`;
107
- entity.addChild(model.root);
108
- this.trackModel(component, model);
109
- component.runtimeRoot = model.root;
110
- component.runtimeAnimations = model.animations;
111
- component.runtimeAnimationClips = model.animationClips;
112
- component.runtimeAssetStats = model.assetStats;
113
- component.runtimeCompatibilityReport = model.compatibilityReport;
114
- component.runtimeMaterialVariants = model.materialVariants;
115
- component.runtimeSourceKey = key;
116
- this.failedLoads.delete(component);
117
- component.status = 'loaded';
118
- } catch (error) {
119
- const timedOut = String(pending.job.controller.signal.reason ?? '').startsWith('timeout:');
120
- if (component.loadingSourceKey !== key || (pending.job.controller.signal.aborted && !timedOut)) {
121
- if (component.loadingSourceKey === key) component.loadingSourceKey = '';
122
- return;
123
- }
124
- component.status = 'error';
125
- this.failedLoads.set(component, key);
126
- component.error = timedOut
127
- ? `glTF load timed out after ${this.loadTimeoutMs}ms.`
128
- : error instanceof Error ? error.message : String(error);
129
- console.warn(`[GltfModelSystem] ${component.error}`, error);
130
- } finally {
131
- this.clearPendingLoad(component, pending);
132
- if (component.loadingSourceKey === key) component.loadingSourceKey = '';
133
- }
134
- }
135
-
136
- private createPendingLoad(component: GltfModelComponent, key: string): PendingGltfLoad {
137
- const pending: PendingGltfLoad = {
138
- key,
139
- job: new AssetJob<LoadedGltfModel>(`gltf:${key}`, {
140
- timeoutMs: this.loadTimeoutMs,
141
- priority: this.assetPriority,
142
- disposeLateResult: disposeGltfModel,
143
- }),
144
- };
145
- this.pendingLoads.set(component, pending);
146
- return pending;
147
- }
148
-
149
- private clearPendingLoad(component: GltfModelComponent, pending: PendingGltfLoad): void {
150
- if (this.pendingLoads.get(component) === pending) this.pendingLoads.delete(component);
151
- }
152
-
153
- private abortPendingLoad(component: GltfModelComponent): void {
154
- const pending = this.pendingLoads.get(component);
155
- if (!pending) return;
156
- pending.job.abort('component-removed');
157
- this.pendingLoads.delete(component);
158
- if (component.loadingSourceKey === pending.key) component.loadingSourceKey = '';
159
- }
160
-
161
- private trackModel(component: GltfModelComponent, model: LoadedGltfModel): void {
162
- let models = this.componentModels.get(component);
163
- if (!models) {
164
- models = new Set();
165
- this.componentModels.set(component, models);
166
- }
167
- models.add(model);
168
- }
169
-
170
- private disposeModelsForComponent(component: GltfModelComponent): void {
171
- const models = this.componentModels.get(component);
172
- if (!models) return;
173
- for (const model of models) disposeGltfModel(model);
174
- models.clear();
175
- this.componentModels.delete(component);
176
- }
177
-
178
- private releaseModelsNotIn(liveComponents: ReadonlySet<GltfModelComponent>): void {
179
- for (const component of [...this.componentModels.keys()]) {
180
- if (!liveComponents.has(component)) {
181
- this.disposeModelsForComponent(component);
182
- component.runtimeRoot = null;
183
- component.runtimeAnimations = [];
184
- component.runtimeAnimationClips = [];
185
- component.runtimeAssetStats = null;
186
- component.runtimeCompatibilityReport = null;
187
- component.runtimeMaterialVariants = [];
188
- component.runtimeSourceKey = '';
189
- }
190
- }
191
- }
192
-
193
- private abortLoadsNotIn(liveComponents: ReadonlySet<GltfModelComponent>): void {
194
- for (const component of [...this.pendingLoads.keys()]) {
195
- if (!liveComponents.has(component)) this.abortPendingLoad(component);
196
- }
197
- }
198
-
199
- private releaseFailuresNotIn(liveComponents: ReadonlySet<GltfModelComponent>): void {
200
- for (const component of this.failedLoads.keys()) {
201
- if (!liveComponents.has(component)) this.failedLoads.delete(component);
202
- }
203
- }
204
-
205
- private disposeAllModels(): void {
206
- for (const component of [...this.componentModels.keys()]) this.disposeModelsForComponent(component);
207
- }
208
- }
@@ -1,84 +0,0 @@
1
- import type { EnginePlugin } from '@haiyue/engine/core';
2
- import { GltfModelComponent, type GltfModelComponentOptions } from './GltfModelComponent';
3
- import { GltfModelSystem, type GltfModelSystemOptions } from './GltfModelSystem';
4
- import {
5
- EXTENSIONS_PLUGIN_VERSION,
6
- ownedEditorViewportSystem,
7
- removeSystem,
8
- type EditorViewportContributionContext,
9
- } from '../plugins/pluginUtils';
10
-
11
- export interface GltfPluginOptions {
12
- system?: GltfModelSystemOptions;
13
- }
14
-
15
- export function createGltfPlugin(options: GltfPluginOptions = {}): EnginePlugin {
16
- let system: GltfModelSystem | null = null;
17
- return {
18
- name: '@haiyue/extensions/gltf',
19
- version: EXTENSIONS_PLUGIN_VERSION,
20
- installEngine(context) {
21
- context.registerComponent({ type: 'GltfModelComponent', component: GltfModelComponent });
22
- },
23
- installScene(context) {
24
- context.registerComponent({ type: 'GltfModelComponent', component: GltfModelComponent });
25
- system = new GltfModelSystem({
26
- ...options.system,
27
- assetManager: options.system?.assetManager ?? context.assetManager ?? null,
28
- });
29
- context.addSystem(system, false);
30
- },
31
- uninstallScene(context) {
32
- removeSystem(context, system);
33
- system = null;
34
- },
35
- installEditor(context) {
36
- context.registerContribution({ components: [{
37
- type: 'GltfModelComponent',
38
- create: () => new GltfModelComponent({ src: '', autoLoad: true }),
39
- inspector: GltfModelComponent.editor,
40
- serialize(component: GltfModelComponent) {
41
- return {
42
- type: 'GltfModelComponent',
43
- src: component.src,
44
- scene: component.scene,
45
- autoLoad: component.autoLoad,
46
- clearPrevious: component.clearPrevious,
47
- baseColorFactor: [...component.baseColorFactor],
48
- };
49
- },
50
- deserialize(data: unknown) {
51
- const value = data as GltfModelComponentOptions & { type?: unknown; scene?: number | null };
52
- if (value.type !== 'GltfModelComponent') return null;
53
- return new GltfModelComponent({ ...value, ...(typeof value.scene === 'number' ? { scene: value.scene } : {}) });
54
- },
55
- clone: (component: GltfModelComponent) => component.clone(),
56
- getIgnoredChildren: (component: GltfModelComponent) => component.runtimeRoot ? [component.runtimeRoot] : [],
57
- collectDependencies(component: GltfModelComponent, dependencyContext: { resolveModelBySrc(src: string): string | null }) {
58
- const dependency = dependencyContext.resolveModelBySrc(component.src);
59
- return dependency ? [dependency] : [];
60
- },
61
- collectSerializedDependencies(data: unknown, dependencyContext: { resolveModelBySrc(src: string): string | null }) {
62
- const value = data as { type?: unknown; src?: unknown };
63
- const dependency = value.type === 'GltfModelComponent' && typeof value.src === 'string'
64
- ? dependencyContext.resolveModelBySrc(value.src)
65
- : null;
66
- return dependency ? [dependency] : [];
67
- },
68
- installViewport(viewport: EditorViewportContributionContext) {
69
- const existing = viewport.world.getSystem(GltfModelSystem);
70
- const viewportSystem = existing ?? new GltfModelSystem({ priority: 0 });
71
- if (!existing) viewport.world.addSystem(viewportSystem);
72
- return ownedEditorViewportSystem(viewport.world, viewportSystem, existing === null);
73
- },
74
- runtimeExport: {
75
- imports: [{ from: '@haiyue/extensions/gltf', names: ['GltfModelComponent', 'GltfModelSystem'] }],
76
- systems: ['GltfModelSystem'],
77
- deserializeExpression: 'new GltfModelComponent(data)',
78
- installSystems: ' if (hasComponentType(world, GltfModelComponent)) world.addSystem(new GltfModelSystem({ priority: 0 }));',
79
- has3D: true,
80
- },
81
- }] });
82
- },
83
- };
84
- }
@@ -1,229 +0,0 @@
1
- export type GltfComponentType = 5120 | 5121 | 5122 | 5123 | 5125 | 5126;
2
- export type GltfAccessorType = 'SCALAR' | 'VEC2' | 'VEC3' | 'VEC4' | 'MAT2' | 'MAT3' | 'MAT4';
3
- export type GltfAnimationInterpolation = 'LINEAR' | 'STEP' | 'CUBICSPLINE';
4
-
5
- export interface GltfBuffer { uri?: string; byteLength?: number }
6
- export interface GltfBufferView { buffer: number; byteOffset?: number; byteLength: number; byteStride?: number }
7
- export interface GltfAccessor {
8
- bufferView?: number;
9
- byteOffset?: number;
10
- componentType: GltfComponentType;
11
- count: number;
12
- type: GltfAccessorType;
13
- normalized?: boolean;
14
- min?: number[];
15
- max?: number[];
16
- sparse?: GltfAccessorSparse;
17
- }
18
- export interface GltfAccessorSparse {
19
- count: number;
20
- indices: {
21
- bufferView: number;
22
- byteOffset?: number;
23
- componentType: 5121 | 5123 | 5125;
24
- };
25
- values: {
26
- bufferView: number;
27
- byteOffset?: number;
28
- };
29
- }
30
-
31
- export interface GltfDracoMeshCompression {
32
- bufferView: number;
33
- attributes: Record<string, number>;
34
- }
35
-
36
- export interface GltfPrimitive {
37
- attributes: Record<string, number>;
38
- indices?: number;
39
- material?: number;
40
- mode?: number;
41
- targets?: Array<Record<string, number>>;
42
- extensions?: {
43
- [extension: string]: unknown;
44
- KHR_draco_mesh_compression?: GltfDracoMeshCompression;
45
- KHR_materials_variants?: {
46
- mappings: Array<{ material: number; variants: number[] }>;
47
- };
48
- };
49
- }
50
- export interface GltfMesh { name?: string; primitives: GltfPrimitive[]; weights?: number[] }
51
- export interface GltfNode {
52
- name?: string;
53
- mesh?: number;
54
- skin?: number;
55
- children?: number[];
56
- matrix?: number[];
57
- translation?: [number, number, number];
58
- rotation?: [number, number, number, number];
59
- scale?: [number, number, number];
60
- }
61
- export interface GltfScene { nodes?: number[] }
62
- export interface GltfSkin {
63
- inverseBindMatrices?: number;
64
- joints: number[];
65
- skeleton?: number;
66
- name?: string;
67
- }
68
- export interface GltfMaterial {
69
- name?: string;
70
- doubleSided?: boolean;
71
- pbrMetallicRoughness?: {
72
- baseColorFactor?: [number, number, number, number];
73
- baseColorTexture?: GltfTextureInfo;
74
- metallicRoughnessTexture?: GltfTextureInfo;
75
- metallicFactor?: number;
76
- roughnessFactor?: number;
77
- };
78
- emissiveFactor?: [number, number, number];
79
- emissiveTexture?: GltfTextureInfo;
80
- normalTexture?: GltfTextureInfo & { scale?: number };
81
- occlusionTexture?: GltfTextureInfo & { strength?: number };
82
- alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';
83
- alphaCutoff?: number;
84
- extensions?: {
85
- [extension: string]: unknown;
86
- KHR_materials_clearcoat?: {
87
- clearcoatFactor?: number;
88
- clearcoatTexture?: GltfTextureInfo;
89
- clearcoatRoughnessFactor?: number;
90
- clearcoatRoughnessTexture?: GltfTextureInfo;
91
- clearcoatNormalTexture?: GltfTextureInfo & { scale?: number };
92
- };
93
- KHR_materials_anisotropy?: {
94
- anisotropyStrength?: number;
95
- anisotropyRotation?: number;
96
- anisotropyTexture?: GltfTextureInfo;
97
- };
98
- KHR_materials_ior?: {
99
- ior?: number;
100
- };
101
- KHR_materials_specular?: {
102
- specularFactor?: number;
103
- specularTexture?: GltfTextureInfo;
104
- specularColorFactor?: [number, number, number];
105
- specularColorTexture?: GltfTextureInfo;
106
- };
107
- KHR_materials_sheen?: {
108
- sheenColorFactor?: [number, number, number];
109
- sheenColorTexture?: GltfTextureInfo;
110
- sheenRoughnessFactor?: number;
111
- sheenRoughnessTexture?: GltfTextureInfo;
112
- };
113
- KHR_materials_transmission?: {
114
- transmissionFactor?: number;
115
- transmissionTexture?: GltfTextureInfo;
116
- };
117
- KHR_materials_volume?: {
118
- thicknessFactor?: number;
119
- thicknessTexture?: GltfTextureInfo;
120
- attenuationDistance?: number;
121
- attenuationColor?: [number, number, number];
122
- };
123
- };
124
- }
125
- export interface GltfTextureInfo {
126
- index: number;
127
- texCoord?: number;
128
- extensions?: { [extension: string]: unknown; KHR_texture_transform?: GltfTextureTransform };
129
- }
130
- export interface GltfTextureTransform {
131
- offset?: [number, number];
132
- rotation?: number;
133
- scale?: [number, number];
134
- texCoord?: number;
135
- }
136
- export interface GltfImage { uri?: string; bufferView?: number; mimeType?: string }
137
- export interface GltfTexture {
138
- sampler?: number;
139
- source?: number;
140
- extensions?: { [extension: string]: unknown; KHR_texture_basisu?: { source: number } };
141
- }
142
- export interface GltfSampler {
143
- magFilter?: number;
144
- minFilter?: number;
145
- wrapS?: number;
146
- wrapT?: number;
147
- }
148
- export interface GltfAnimation {
149
- name?: string;
150
- channels?: Array<{
151
- sampler: number;
152
- target: { node?: number; path?: string };
153
- }>;
154
- samplers?: Array<{ input: number; output: number; interpolation?: GltfAnimationInterpolation }>;
155
- }
156
-
157
- export interface GltfAsset {
158
- asset: { version: string };
159
- extensionsUsed?: string[];
160
- extensionsRequired?: string[];
161
- buffers?: GltfBuffer[];
162
- bufferViews?: GltfBufferView[];
163
- accessors?: GltfAccessor[];
164
- meshes?: GltfMesh[];
165
- nodes?: GltfNode[];
166
- scenes?: GltfScene[];
167
- scene?: number;
168
- skins?: GltfSkin[];
169
- materials?: GltfMaterial[];
170
- images?: GltfImage[];
171
- textures?: GltfTexture[];
172
- samplers?: GltfSampler[];
173
- animations?: GltfAnimation[];
174
- extensions?: {
175
- [extension: string]: unknown;
176
- KHR_materials_variants?: { variants: Array<{ name: string }> };
177
- };
178
- }
179
-
180
- /** Validates the untrusted JSON envelope before the loader follows references. */
181
- export function isGltfAsset(value: unknown): value is GltfAsset {
182
- if (!isRecord(value)) return false;
183
- if (!isRecord(value.asset) || typeof value.asset.version !== 'string' || !value.asset.version.startsWith('2')) return false;
184
- const arrayFields = [
185
- 'buffers', 'bufferViews', 'accessors', 'meshes', 'nodes', 'scenes', 'skins',
186
- 'materials', 'images', 'textures', 'samplers', 'animations',
187
- ] as const;
188
- if (arrayFields.some(field => value[field] !== undefined && !Array.isArray(value[field]))) return false;
189
- if (value.scene !== undefined && !isNonNegativeInteger(value.scene)) return false;
190
- if (value.extensionsUsed !== undefined && (!Array.isArray(value.extensionsUsed) || !value.extensionsUsed.every(item => typeof item === 'string'))) return false;
191
- if (value.extensionsRequired !== undefined && (!Array.isArray(value.extensionsRequired) || !value.extensionsRequired.every(item => typeof item === 'string'))) return false;
192
- if (!((value.buffers as unknown[] | undefined) ?? []).every(buffer => isRecord(buffer)
193
- && (buffer.uri === undefined || typeof buffer.uri === 'string')
194
- && (buffer.byteLength === undefined || isNonNegativeInteger(buffer.byteLength)))) return false;
195
- if (!((value.bufferViews as unknown[] | undefined) ?? []).every(view => isRecord(view)
196
- && isNonNegativeInteger(view.buffer)
197
- && isNonNegativeInteger(view.byteLength)
198
- && (view.byteOffset === undefined || isNonNegativeInteger(view.byteOffset)))) return false;
199
- if (!((value.accessors as unknown[] | undefined) ?? []).every(accessor => isRecord(accessor)
200
- && isNonNegativeInteger(accessor.count)
201
- && typeof accessor.type === 'string'
202
- && isNonNegativeInteger(accessor.componentType)
203
- && isOptionalFiniteNumberArray(accessor.min)
204
- && isOptionalFiniteNumberArray(accessor.max)
205
- && (accessor.bufferView === undefined || isNonNegativeInteger(accessor.bufferView)))) return false;
206
- if (!((value.meshes as unknown[] | undefined) ?? []).every(mesh => isRecord(mesh)
207
- && Array.isArray(mesh.primitives)
208
- && mesh.primitives.every(primitive => isRecord(primitive) && isNumericRecord(primitive.attributes)))) return false;
209
- if (!((value.nodes as unknown[] | undefined) ?? []).every(isRecord)) return false;
210
- if (!((value.scenes as unknown[] | undefined) ?? []).every(scene => isRecord(scene)
211
- && (scene.nodes === undefined || (Array.isArray(scene.nodes) && scene.nodes.every(isNonNegativeInteger))))) return false;
212
- return true;
213
- }
214
-
215
- export function isRecord(value: unknown): value is Record<string, unknown> {
216
- return typeof value === 'object' && value !== null && !Array.isArray(value);
217
- }
218
-
219
- function isNonNegativeInteger(value: unknown): value is number {
220
- return typeof value === 'number' && Number.isInteger(value) && value >= 0;
221
- }
222
-
223
- function isNumericRecord(value: unknown): value is Record<string, number> {
224
- return isRecord(value) && Object.values(value).every(isNonNegativeInteger);
225
- }
226
-
227
- function isOptionalFiniteNumberArray(value: unknown): boolean {
228
- return value === undefined || (Array.isArray(value) && value.every(item => typeof item === 'number' && Number.isFinite(item)));
229
- }