@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,232 @@
1
+ import { Component } from '@haiyue/engine';
2
+ import { UniqueCheckType } from '@haiyue/engine/ecs';
3
+
4
+ export type TilemapCellValue = number;
5
+ export type TilemapPaletteColor = [number, number, number, number];
6
+
7
+ export interface Tilemap2DComponentOptions {
8
+ columns?: number;
9
+ rows?: number;
10
+ cellWidth?: number;
11
+ cellHeight?: number;
12
+ originX?: number;
13
+ originY?: number;
14
+ gap?: number;
15
+ cells?: ArrayLike<TilemapCellValue>;
16
+ palette?: TilemapPaletteColor[];
17
+ }
18
+
19
+ export class Tilemap2DComponent extends Component {
20
+ static override UniqueCheckType = UniqueCheckType.SYMBOL | UniqueCheckType.REPLACE;
21
+ static override UniqueSymbol = Symbol.for('Tilemap2DComponent');
22
+ static editor = {
23
+ fields: {
24
+ columns: { type: 'number', label: 'Columns', min: 1, step: 1 },
25
+ rows: { type: 'number', label: 'Rows', min: 1, step: 1 },
26
+ cellWidth: { type: 'number', label: 'Cell Width', min: 0.001, step: 1 },
27
+ cellHeight: { type: 'number', label: 'Cell Height', min: 0.001, step: 1 },
28
+ gap: { type: 'number', label: 'Gap', min: 0, step: 1 },
29
+ originX: { type: 'number', label: 'Origin X', step: 1 },
30
+ originY: { type: 'number', label: 'Origin Y', step: 1 },
31
+ palette: { type: 'json', label: 'Palette JSON', rows: 7 },
32
+ cells: { type: 'int-array', label: 'Cells JSON', rows: 8 },
33
+ },
34
+ };
35
+
36
+ private _columns: number;
37
+ private _rows: number;
38
+ private _cellWidth: number;
39
+ private _cellHeight: number;
40
+ private _originX: number;
41
+ private _originY: number;
42
+ private _gap: number;
43
+ private _cells: Int16Array;
44
+ private _palette: TilemapPaletteColor[];
45
+ private _version = 0;
46
+
47
+ constructor(options: Tilemap2DComponentOptions = {}) {
48
+ super('Tilemap2DComponent');
49
+ this._columns = Math.max(1, Math.floor(options.columns ?? 10));
50
+ this._rows = Math.max(1, Math.floor(options.rows ?? 20));
51
+ this._cellWidth = options.cellWidth ?? 32;
52
+ this._cellHeight = options.cellHeight ?? 32;
53
+ this._originX = options.originX ?? 0;
54
+ this._originY = options.originY ?? 0;
55
+ this._gap = Math.max(0, options.gap ?? 1);
56
+ this._cells = new Int16Array(this.columns * this.rows);
57
+ if (options.cells) this._cells.set(Array.from(options.cells).slice(0, this._cells.length));
58
+ this._palette = options.palette?.length
59
+ ? options.palette.map(color => [...color] as TilemapPaletteColor)
60
+ : [
61
+ [0, 0, 0, 0],
62
+ [0.18, 0.62, 1, 1],
63
+ [0.96, 0.72, 0.18, 1],
64
+ [0.35, 0.86, 0.48, 1],
65
+ [0.92, 0.28, 0.36, 1],
66
+ ];
67
+ }
68
+
69
+ get columns(): number {
70
+ return this._columns;
71
+ }
72
+
73
+ set columns(value: number) {
74
+ const next = Math.max(1, Math.floor(value));
75
+ if (this._columns === next) return;
76
+ this._columns = next;
77
+ this.markDirty();
78
+ }
79
+
80
+ get rows(): number {
81
+ return this._rows;
82
+ }
83
+
84
+ set rows(value: number) {
85
+ const next = Math.max(1, Math.floor(value));
86
+ if (this._rows === next) return;
87
+ this._rows = next;
88
+ this.markDirty();
89
+ }
90
+
91
+ get cellWidth(): number {
92
+ return this._cellWidth;
93
+ }
94
+
95
+ set cellWidth(value: number) {
96
+ if (this._cellWidth === value) return;
97
+ this._cellWidth = value;
98
+ this.markDirty();
99
+ }
100
+
101
+ get cellHeight(): number {
102
+ return this._cellHeight;
103
+ }
104
+
105
+ set cellHeight(value: number) {
106
+ if (this._cellHeight === value) return;
107
+ this._cellHeight = value;
108
+ this.markDirty();
109
+ }
110
+
111
+ get originX(): number {
112
+ return this._originX;
113
+ }
114
+
115
+ set originX(value: number) {
116
+ if (this._originX === value) return;
117
+ this._originX = value;
118
+ this.markDirty();
119
+ }
120
+
121
+ get originY(): number {
122
+ return this._originY;
123
+ }
124
+
125
+ set originY(value: number) {
126
+ if (this._originY === value) return;
127
+ this._originY = value;
128
+ this.markDirty();
129
+ }
130
+
131
+ get gap(): number {
132
+ return this._gap;
133
+ }
134
+
135
+ set gap(value: number) {
136
+ const next = Math.max(0, value);
137
+ if (this._gap === next) return;
138
+ this._gap = next;
139
+ this.markDirty();
140
+ }
141
+
142
+ get cells(): Int16Array {
143
+ return this._cells;
144
+ }
145
+
146
+ set cells(value: Int16Array) {
147
+ this._cells = value;
148
+ this.markDirty();
149
+ }
150
+
151
+ get palette(): TilemapPaletteColor[] {
152
+ return this._palette;
153
+ }
154
+
155
+ set palette(value: TilemapPaletteColor[]) {
156
+ this._palette = value;
157
+ this.markDirty();
158
+ }
159
+
160
+ get version(): number {
161
+ return this._version;
162
+ }
163
+
164
+ markDirty(): this {
165
+ this._version++;
166
+ return this;
167
+ }
168
+
169
+ index(column: number, row: number): number {
170
+ return row * this.columns + column;
171
+ }
172
+
173
+ contains(column: number, row: number): boolean {
174
+ return column >= 0 && row >= 0 && column < this.columns && row < this.rows;
175
+ }
176
+
177
+ getCell(column: number, row: number): TilemapCellValue {
178
+ if (!this.contains(column, row)) return 0;
179
+ return this.cells[this.index(column, row)] ?? 0;
180
+ }
181
+
182
+ setCell(column: number, row: number, value: TilemapCellValue): this {
183
+ if (this.contains(column, row)) {
184
+ const index = this.index(column, row);
185
+ if (this._cells[index] !== value) {
186
+ this._cells[index] = value;
187
+ this.markDirty();
188
+ }
189
+ }
190
+ return this;
191
+ }
192
+
193
+ clear(value = 0): this {
194
+ this._cells.fill(value);
195
+ this.markDirty();
196
+ return this;
197
+ }
198
+
199
+ resize(columns: number, rows: number): this {
200
+ const nextColumns = Math.max(1, Math.floor(columns));
201
+ const nextRows = Math.max(1, Math.floor(rows));
202
+ if (nextColumns === this.columns && nextRows === this.rows) return this;
203
+
204
+ const next = new Int16Array(nextColumns * nextRows);
205
+ const copyColumns = Math.min(this.columns, nextColumns);
206
+ const copyRows = Math.min(this.rows, nextRows);
207
+ for (let row = 0; row < copyRows; row++) {
208
+ for (let column = 0; column < copyColumns; column++) {
209
+ next[row * nextColumns + column] = this.getCell(column, row);
210
+ }
211
+ }
212
+ this._columns = nextColumns;
213
+ this._rows = nextRows;
214
+ this._cells = next;
215
+ this.markDirty();
216
+ return this;
217
+ }
218
+
219
+ override clone(): Tilemap2DComponent {
220
+ return new Tilemap2DComponent({
221
+ columns: this.columns,
222
+ rows: this.rows,
223
+ cellWidth: this.cellWidth,
224
+ cellHeight: this.cellHeight,
225
+ originX: this.originX,
226
+ originY: this.originY,
227
+ gap: this.gap,
228
+ cells: this.cells,
229
+ palette: this.palette,
230
+ });
231
+ }
232
+ }
@@ -0,0 +1,58 @@
1
+ import {
2
+ beginRenderCommandPass,
3
+ type IEngine,
4
+ type RenderCommandContext,
5
+ } from '@haiyue/engine/extension-authoring';
6
+ import { Entity, World } from '@haiyue/engine/ecs';
7
+ import { Tilemap2DComponent } from './Tilemap2DComponent';
8
+ import { Tilemap2DRenderer } from './Tilemap2DRenderer';
9
+ import { RenderSystem2DBase, type RenderSystem2DBaseOptions } from '../utils/RenderSystem2DBase';
10
+
11
+ export type Tilemap2DRenderSystemOptions = RenderSystem2DBaseOptions;
12
+
13
+ export class Tilemap2DRenderSystem extends RenderSystem2DBase {
14
+ private renderer: Tilemap2DRenderer | null = null;
15
+
16
+ constructor(engine: IEngine, cameraEntity: Entity, options: Tilemap2DRenderSystemOptions = {}) {
17
+ super({ all: [Tilemap2DComponent] }, engine, cameraEntity, options, 'Tilemap2DRenderSystem');
18
+ }
19
+
20
+ record(world: World, context: RenderCommandContext): this {
21
+ if (this.disabled) return this;
22
+ if (!this.renderer) {
23
+ this.renderer = new Tilemap2DRenderer();
24
+ this.renderer.prepare(this.engine);
25
+ }
26
+ this.renderer.reverseZ = context.view?.reverseZ ?? this.engine.reverseZ;
27
+ this.renderer.msaaSamples = context.view?.sampleCount ?? this.engine.msaaSamples;
28
+ const liveEntities = this.beginLiveEntityTracking();
29
+
30
+ const camera = this.getCamera2D(context);
31
+ if (!camera) return this;
32
+ this.renderer.updateCamera(this.computeCameraViewProjection(camera, context));
33
+
34
+ const { passEncoder, ownsPass } = beginRenderCommandPass(context);
35
+ const entities = this.entitySet.get(world);
36
+ if (entities) for (const entity of entities) {
37
+ if (!this.isEntityRenderable(entity)) continue;
38
+ const tilemap = entity.getComponent(Tilemap2DComponent);
39
+ if (!tilemap) continue;
40
+ this.renderer!.render(passEncoder, entity.id, tilemap, this.getWorldMatrix2D(entity, context));
41
+ this.markEntityLive(entity);
42
+ }
43
+ if (ownsPass) passEncoder.end();
44
+ this.renderer.releaseEntitiesNotIn(liveEntities);
45
+ return this;
46
+ }
47
+
48
+ override destroy(): this {
49
+ this.releaseGpuResourcesForRecovery();
50
+ return super.destroy();
51
+ }
52
+
53
+ protected releaseGpuResourcesForRecovery(): void {
54
+ this.renderer?.destroy();
55
+ this.renderer = null;
56
+ }
57
+
58
+ }
@@ -0,0 +1,289 @@
1
+ import { getExtensionGPUResourceTracker, requireEngineDevice, type IEngine } from '@haiyue/engine/extension-authoring';
2
+ import type { Tilemap2DComponent } from './Tilemap2DComponent';
3
+ import {
4
+ createCamera2DGpu,
5
+ createCamera2DLayout,
6
+ createObject2DGpu,
7
+ createObject2DLayout,
8
+ destroyCamera2DGpu,
9
+ destroyObject2DGpu,
10
+ writeFloatBuffer,
11
+ writeObjectMatrixIfChanged,
12
+ type Camera2DGpu,
13
+ type Object2DGpu,
14
+ } from '../utils/render2dGpu';
15
+ import tilemap2dWgsl from '../shaders/generated/2d-ui-tilemap2d.generated.wgsl';
16
+
17
+ const TILEMAP_WGSL = tilemap2dWgsl;
18
+
19
+ const TILEMAP_INITIAL_VERTEX_FLOATS = 36;
20
+ const TILEMAP_INITIAL_VERTEX_BYTES = TILEMAP_INITIAL_VERTEX_FLOATS * 4;
21
+
22
+ interface EntityGpu {
23
+ objectGpu: Object2DGpu;
24
+ vertexBuffer: GPUBuffer;
25
+ vertexBufferSize: number;
26
+ vertexData: Float32Array;
27
+ vertexByteLength: number;
28
+ vertexCount: number;
29
+ tilemapSignature: string;
30
+ }
31
+
32
+ interface TilemapSignatureCache {
33
+ version: number;
34
+ signature: string;
35
+ }
36
+
37
+ interface TilemapSharedGpu {
38
+ cameraLayout: GPUBindGroupLayout;
39
+ objectLayout: GPUBindGroupLayout;
40
+ shaderModule: GPUShaderModule;
41
+ pipelineLayout: GPUPipelineLayout;
42
+ pipelineCache: Map<number, GPURenderPipeline>;
43
+ }
44
+
45
+ const tilemapSharedGpuCache = new WeakMap<GPUDevice, TilemapSharedGpu>();
46
+
47
+ function getTilemapSharedGpu(device: GPUDevice): TilemapSharedGpu {
48
+ let shared = tilemapSharedGpuCache.get(device);
49
+ if (shared) return shared;
50
+
51
+ const cameraLayout = createCamera2DLayout(device);
52
+ const objectLayout = createObject2DLayout(device);
53
+ const shaderModule = device.createShaderModule({ code: TILEMAP_WGSL });
54
+ const pipelineLayout = device.createPipelineLayout({
55
+ bindGroupLayouts: [cameraLayout, objectLayout],
56
+ });
57
+ shared = {
58
+ cameraLayout,
59
+ objectLayout,
60
+ shaderModule,
61
+ pipelineLayout,
62
+ pipelineCache: new Map(),
63
+ };
64
+ tilemapSharedGpuCache.set(device, shared);
65
+ return shared;
66
+ }
67
+
68
+ export class Tilemap2DRenderer {
69
+ reverseZ = false;
70
+ msaaSamples: 1 | 4 = 1;
71
+
72
+ private engine!: IEngine;
73
+ private cameraGpu!: Camera2DGpu;
74
+ private objectLayout!: GPUBindGroupLayout;
75
+ private shaderModule!: GPUShaderModule;
76
+ private pipelineLayout!: GPUPipelineLayout;
77
+ private sharedGpu!: TilemapSharedGpu;
78
+ private entityCache = new Map<number, EntityGpu>();
79
+ private signatureCache = new WeakMap<Tilemap2DComponent, TilemapSignatureCache>();
80
+ private initialized = false;
81
+
82
+ prepare(engine: IEngine): void {
83
+ if (this.initialized) return;
84
+ this.initialized = true;
85
+ this.engine = engine;
86
+ const device = requireEngineDevice(engine);
87
+ this.sharedGpu = getTilemapSharedGpu(device);
88
+ this.cameraGpu = createCamera2DGpu(device, getExtensionGPUResourceTracker(engine), this.sharedGpu.cameraLayout);
89
+ this.objectLayout = this.sharedGpu.objectLayout;
90
+ this.shaderModule = this.sharedGpu.shaderModule;
91
+ this.pipelineLayout = this.sharedGpu.pipelineLayout;
92
+ }
93
+
94
+ updateCamera(viewProj: Float32Array): void {
95
+ writeFloatBuffer(requireEngineDevice(this.engine).queue, this.cameraGpu.buffer, viewProj);
96
+ }
97
+
98
+ releaseEntitiesNotIn(liveEntities: ReadonlySet<number>): void {
99
+ for (const [entityId, entityGpu] of this.entityCache) {
100
+ if (!liveEntities.has(entityId)) {
101
+ this.destroyEntityGpu(entityGpu);
102
+ this.entityCache.delete(entityId);
103
+ }
104
+ }
105
+ }
106
+
107
+ render(
108
+ passEncoder: GPURenderPassEncoder,
109
+ entityId: number,
110
+ tilemap: Tilemap2DComponent,
111
+ worldMatrix: Float32Array,
112
+ ): void {
113
+ const device = requireEngineDevice(this.engine);
114
+ const signature = this.computeSignature(tilemap);
115
+
116
+ let entityGpu = this.entityCache.get(entityId);
117
+ if (!entityGpu) {
118
+ entityGpu = {
119
+ objectGpu: createObject2DGpu(device, this.objectLayout, getExtensionGPUResourceTracker(this.engine)),
120
+ vertexBuffer: device.createBuffer({
121
+ size: TILEMAP_INITIAL_VERTEX_BYTES,
122
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
123
+ }),
124
+ vertexBufferSize: TILEMAP_INITIAL_VERTEX_BYTES,
125
+ vertexData: new Float32Array(TILEMAP_INITIAL_VERTEX_FLOATS),
126
+ vertexByteLength: 0,
127
+ vertexCount: 0,
128
+ tilemapSignature: '',
129
+ };
130
+ getExtensionGPUResourceTracker(this.engine)?.trackBuffer(entityGpu.vertexBuffer, 'Tilemap2DRenderer.vertexBuffer', entityGpu.vertexBufferSize);
131
+ this.entityCache.set(entityId, entityGpu);
132
+ }
133
+
134
+ if (entityGpu.tilemapSignature !== signature) {
135
+ this.buildVertices(tilemap, entityGpu);
136
+ entityGpu.tilemapSignature = signature;
137
+ if (entityGpu.vertexByteLength > entityGpu.vertexBufferSize) {
138
+ getExtensionGPUResourceTracker(this.engine)?.untrackBuffer(entityGpu.vertexBuffer);
139
+ entityGpu.vertexBuffer.destroy();
140
+ entityGpu.vertexBufferSize = Math.max(entityGpu.vertexByteLength, entityGpu.vertexBufferSize * 2);
141
+ entityGpu.vertexBuffer = device.createBuffer({
142
+ size: entityGpu.vertexBufferSize,
143
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
144
+ });
145
+ getExtensionGPUResourceTracker(this.engine)?.trackBuffer(entityGpu.vertexBuffer, 'Tilemap2DRenderer.vertexBuffer', entityGpu.vertexBufferSize);
146
+ }
147
+ if (entityGpu.vertexByteLength > 0) {
148
+ device.queue.writeBuffer(
149
+ entityGpu.vertexBuffer,
150
+ 0,
151
+ entityGpu.vertexData.buffer as ArrayBuffer,
152
+ entityGpu.vertexData.byteOffset,
153
+ entityGpu.vertexByteLength,
154
+ );
155
+ }
156
+ }
157
+
158
+ if (entityGpu.vertexCount === 0) return;
159
+
160
+ writeObjectMatrixIfChanged(device.queue, entityGpu.objectGpu, worldMatrix);
161
+
162
+ passEncoder.setPipeline(this.getPipeline());
163
+ passEncoder.setBindGroup(0, this.cameraGpu.bindGroup);
164
+ passEncoder.setBindGroup(1, entityGpu.objectGpu.bindGroup);
165
+ passEncoder.setVertexBuffer(0, entityGpu.vertexBuffer);
166
+ passEncoder.draw(entityGpu.vertexCount);
167
+ }
168
+
169
+ private computeSignature(tilemap: Tilemap2DComponent): string {
170
+ const cached = this.signatureCache.get(tilemap);
171
+ if (cached && cached.version === tilemap.version) {
172
+ return cached.signature;
173
+ }
174
+
175
+ const signature = String(tilemap.version);
176
+ this.signatureCache.set(tilemap, {
177
+ version: tilemap.version,
178
+ signature,
179
+ });
180
+ return signature;
181
+ }
182
+
183
+ private buildVertices(tilemap: Tilemap2DComponent, entityGpu: EntityGpu): void {
184
+ let count = 0;
185
+ for (const cell of tilemap.cells) {
186
+ if (cell > 0) count++;
187
+ }
188
+ if (count === 0) {
189
+ entityGpu.vertexByteLength = 0;
190
+ entityGpu.vertexCount = 0;
191
+ return;
192
+ }
193
+
194
+ const requiredFloats = count * 6 * 6;
195
+ if (entityGpu.vertexData.length < requiredFloats) {
196
+ entityGpu.vertexData = new Float32Array(Math.max(requiredFloats, entityGpu.vertexData.length * 2, 36));
197
+ }
198
+ const vertices = entityGpu.vertexData;
199
+ let offset = 0;
200
+ const gap = tilemap.gap;
201
+ const w = Math.max(0, tilemap.cellWidth - gap);
202
+ const h = Math.max(0, tilemap.cellHeight - gap);
203
+
204
+ const push = (x: number, y: number, color: readonly number[]) => {
205
+ vertices[offset++] = x;
206
+ vertices[offset++] = y;
207
+ vertices[offset++] = color[0] ?? 1;
208
+ vertices[offset++] = color[1] ?? 1;
209
+ vertices[offset++] = color[2] ?? 1;
210
+ vertices[offset++] = color[3] ?? 1;
211
+ };
212
+
213
+ for (let row = 0; row < tilemap.rows; row++) {
214
+ for (let column = 0; column < tilemap.columns; column++) {
215
+ const value = tilemap.getCell(column, row);
216
+ if (value <= 0) continue;
217
+ const color = tilemap.palette[value] ?? tilemap.palette[1] ?? [1, 1, 1, 1];
218
+ const x0 = tilemap.originX + column * tilemap.cellWidth + gap * 0.5;
219
+ const y0 = tilemap.originY + row * tilemap.cellHeight + gap * 0.5;
220
+ const x1 = x0 + w;
221
+ const y1 = y0 + h;
222
+ push(x0, y0, color);
223
+ push(x1, y0, color);
224
+ push(x1, y1, color);
225
+ push(x0, y0, color);
226
+ push(x1, y1, color);
227
+ push(x0, y1, color);
228
+ }
229
+ }
230
+ entityGpu.vertexByteLength = requiredFloats * 4;
231
+ entityGpu.vertexCount = count * 6;
232
+ }
233
+
234
+ private getPipeline(): GPURenderPipeline {
235
+ const depthFormat = this.engine.getDepthFormat(this.reverseZ);
236
+ const key = (this.reverseZ ? 1 : 0) | ((this.msaaSamples > 1 ? 1 : 0) << 1);
237
+ let pipeline = this.sharedGpu.pipelineCache.get(key);
238
+ if (pipeline) return pipeline;
239
+
240
+ const device = requireEngineDevice(this.engine);
241
+ const { format } = this.engine;
242
+ const created = device.createRenderPipeline({
243
+ layout: this.pipelineLayout,
244
+ vertex: {
245
+ module: this.shaderModule,
246
+ entryPoint: 'vs_main',
247
+ buffers: [{
248
+ arrayStride: 24,
249
+ attributes: [
250
+ { shaderLocation: 0, offset: 0, format: 'float32x2' },
251
+ { shaderLocation: 1, offset: 8, format: 'float32x4' },
252
+ ],
253
+ }],
254
+ },
255
+ fragment: {
256
+ module: this.shaderModule,
257
+ entryPoint: 'fs_main',
258
+ targets: [{
259
+ format,
260
+ blend: {
261
+ color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },
262
+ alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
263
+ },
264
+ }],
265
+ },
266
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
267
+ depthStencil: {
268
+ format: depthFormat,
269
+ depthWriteEnabled: false,
270
+ depthCompare: 'always',
271
+ },
272
+ multisample: { count: this.msaaSamples },
273
+ });
274
+ this.sharedGpu.pipelineCache.set(key, created);
275
+ return created;
276
+ }
277
+
278
+ destroy(): void {
279
+ if (this.cameraGpu) destroyCamera2DGpu(this.cameraGpu);
280
+ for (const entity of this.entityCache.values()) this.destroyEntityGpu(entity);
281
+ this.entityCache.clear();
282
+ }
283
+
284
+ private destroyEntityGpu(entity: EntityGpu): void {
285
+ destroyObject2DGpu(entity.objectGpu);
286
+ getExtensionGPUResourceTracker(this.engine)?.untrackBuffer(entity.vertexBuffer);
287
+ entity.vertexBuffer.destroy();
288
+ }
289
+ }
@@ -0,0 +1,75 @@
1
+ import type { EnginePlugin } from '@haiyue/engine/core';
2
+ import type { RenderPipelineEntryOptions } from '@haiyue/engine/extension-authoring';
3
+ import { Tilemap2DComponent } from './Tilemap2DComponent';
4
+ import { Tilemap2DRenderSystem, type Tilemap2DRenderSystemOptions } from './Tilemap2DRenderSystem';
5
+ import {
6
+ EXTENSIONS_PLUGIN_VERSION,
7
+ installEditorRenderSystem,
8
+ removeSystem,
9
+ type EditorViewportContributionContext,
10
+ } from '../plugins/pluginUtils';
11
+
12
+ export interface TilemapPluginOptions {
13
+ system?: Tilemap2DRenderSystemOptions;
14
+ render?: RenderPipelineEntryOptions | false | null;
15
+ }
16
+
17
+ export function createTilemapPlugin(options: TilemapPluginOptions = {}): EnginePlugin {
18
+ let system: Tilemap2DRenderSystem | null = null;
19
+ return {
20
+ name: '@haiyue/extensions/tilemap',
21
+ version: EXTENSIONS_PLUGIN_VERSION,
22
+ installEngine(context) {
23
+ context.registerComponent({ type: 'Tilemap2DComponent', component: Tilemap2DComponent });
24
+ },
25
+ installScene(context) {
26
+ context.registerComponent({ type: 'Tilemap2DComponent', component: Tilemap2DComponent });
27
+ system = new Tilemap2DRenderSystem(context.engine, context.cameraEntity, options.system);
28
+ context.addSystem(system, options.render ?? { pass: 'shared', loadOp: system.loadOp });
29
+ },
30
+ uninstallScene(context) {
31
+ removeSystem(context, system);
32
+ system = null;
33
+ },
34
+ installEditor(context) {
35
+ context.registerContribution({ components: [{
36
+ type: 'Tilemap2DComponent',
37
+ create: () => new Tilemap2DComponent({ columns: 10, rows: 20, cellWidth: 32, cellHeight: 32, gap: 1 }),
38
+ inspector: Tilemap2DComponent.editor,
39
+ serialize(component: Tilemap2DComponent) {
40
+ return {
41
+ type: 'Tilemap2DComponent',
42
+ columns: component.columns,
43
+ rows: component.rows,
44
+ cellWidth: component.cellWidth,
45
+ cellHeight: component.cellHeight,
46
+ originX: component.originX,
47
+ originY: component.originY,
48
+ gap: component.gap,
49
+ cells: Array.from(component.cells),
50
+ palette: component.palette.map(color => [...color]),
51
+ };
52
+ },
53
+ deserialize(data: unknown) {
54
+ const value = data as ConstructorParameters<typeof Tilemap2DComponent>[0] & { type?: unknown };
55
+ return value.type === 'Tilemap2DComponent' ? new Tilemap2DComponent(value) : null;
56
+ },
57
+ clone: (component: Tilemap2DComponent) => component.clone(),
58
+ installViewport(viewport: EditorViewportContributionContext) {
59
+ return installEditorRenderSystem(viewport, Tilemap2DRenderSystem, () => new Tilemap2DRenderSystem(viewport.engine, viewport.camera2DEntity, options.system));
60
+ },
61
+ runtimeExport: {
62
+ imports: [{ from: '@haiyue/extensions/tilemap', names: ['Tilemap2DComponent', 'Tilemap2DRenderSystem'] }],
63
+ systems: ['Tilemap2DRenderSystem'],
64
+ deserializeExpression: 'new Tilemap2DComponent(data)',
65
+ installSystems: ` const tilemapCamera = findCamera2DEntity(world);
66
+ if (tilemapCamera && hasComponentType(world, Tilemap2DComponent)) {
67
+ applyViewportSettingsToCamera2D(tilemapCamera, scene.globals);
68
+ addRenderSystem(new Tilemap2DRenderSystem(engine, tilemapCamera, { loadOp: 'load', priority: 2 }), { pass: 'shared', loadOp: 'load' });
69
+ }`,
70
+ has2D: true,
71
+ },
72
+ }] });
73
+ },
74
+ };
75
+ }
package/src/tilemap.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { Tilemap2DComponent } from './tilemap/Tilemap2DComponent';
2
+ export type { Tilemap2DComponentOptions, TilemapCellValue, TilemapPaletteColor } from './tilemap/Tilemap2DComponent';
3
+ export { Tilemap2DRenderSystem } from './tilemap/Tilemap2DRenderSystem';
4
+ export type { Tilemap2DRenderSystemOptions } from './tilemap/Tilemap2DRenderSystem';
5
+ export { createTilemapPlugin } from './tilemap/TilemapPlugin';
6
+ export type { TilemapPluginOptions } from './tilemap/TilemapPlugin';