@codexo/exojs 0.9.0 → 0.11.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 (242) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +14 -14
  3. package/dist/esm/core/Application.d.ts +25 -6
  4. package/dist/esm/core/Application.js +42 -8
  5. package/dist/esm/core/Application.js.map +1 -1
  6. package/dist/esm/core/Perf.d.ts +23 -0
  7. package/dist/esm/core/Perf.js +49 -0
  8. package/dist/esm/core/Perf.js.map +1 -0
  9. package/dist/esm/core/Scene.d.ts +8 -8
  10. package/dist/esm/core/Scene.js +7 -7
  11. package/dist/esm/core/Scene.js.map +1 -1
  12. package/dist/esm/core/SceneManager.js +2 -2
  13. package/dist/esm/core/SceneManager.js.map +1 -1
  14. package/dist/esm/core/SceneNode.d.ts +0 -3
  15. package/dist/esm/core/SceneNode.js +0 -9
  16. package/dist/esm/core/SceneNode.js.map +1 -1
  17. package/dist/esm/core/capabilities.d.ts +2 -0
  18. package/dist/esm/core/capabilities.js +15 -0
  19. package/dist/esm/core/capabilities.js.map +1 -1
  20. package/dist/esm/core/dev.d.ts +21 -0
  21. package/dist/esm/core/dev.js +18 -0
  22. package/dist/esm/core/dev.js.map +1 -0
  23. package/dist/esm/core/index.d.ts +1 -0
  24. package/dist/esm/core/types.d.ts +1 -1
  25. package/dist/esm/core/utils.d.ts +12 -0
  26. package/dist/esm/core/utils.js +18 -1
  27. package/dist/esm/core/utils.js.map +1 -1
  28. package/dist/esm/index.js +14 -3
  29. package/dist/esm/index.js.map +1 -1
  30. package/dist/esm/particles/ParticleSystem.d.ts +8 -5
  31. package/dist/esm/particles/ParticleSystem.js +9 -5
  32. package/dist/esm/particles/ParticleSystem.js.map +1 -1
  33. package/dist/esm/particles/distributions/{Gradient.d.ts → ColorGradient.d.ts} +5 -5
  34. package/dist/esm/particles/distributions/{Gradient.js → ColorGradient.js} +5 -5
  35. package/dist/esm/particles/distributions/ColorGradient.js.map +1 -0
  36. package/dist/esm/particles/distributions/Distribution.d.ts +2 -2
  37. package/dist/esm/particles/distributions/index.d.ts +2 -2
  38. package/dist/esm/particles/gpu/ParticleGpuState.js +1 -1
  39. package/dist/esm/particles/modules/AlphaFadeOverLifetime.d.ts +2 -2
  40. package/dist/esm/particles/modules/AlphaFadeOverLifetime.js +5 -1
  41. package/dist/esm/particles/modules/AlphaFadeOverLifetime.js.map +1 -1
  42. package/dist/esm/particles/modules/ColorOverLifetime.d.ts +3 -3
  43. package/dist/esm/particles/modules/ColorOverLifetime.js.map +1 -1
  44. package/dist/esm/particles/modules/ColorOverSpeed.d.ts +3 -3
  45. package/dist/esm/particles/modules/ColorOverSpeed.js.map +1 -1
  46. package/dist/esm/particles/modules/UpdateModule.d.ts +2 -2
  47. package/dist/esm/particles/modules/UpdateModule.js +1 -1
  48. package/dist/esm/particles/modules/WgslContribution.d.ts +2 -2
  49. package/dist/esm/rendering/Camera.d.ts +33 -0
  50. package/dist/esm/rendering/Camera.js +38 -0
  51. package/dist/esm/rendering/Camera.js.map +1 -0
  52. package/dist/esm/rendering/Container.d.ts +5 -24
  53. package/dist/esm/rendering/Container.js +8 -71
  54. package/dist/esm/rendering/Container.js.map +1 -1
  55. package/dist/esm/rendering/Drawable.d.ts +8 -10
  56. package/dist/esm/rendering/Drawable.js +12 -20
  57. package/dist/esm/rendering/Drawable.js.map +1 -1
  58. package/dist/esm/rendering/RenderBackend.d.ts +18 -0
  59. package/dist/esm/rendering/RenderNode.d.ts +81 -8
  60. package/dist/esm/rendering/RenderNode.js +121 -144
  61. package/dist/esm/rendering/RenderNode.js.map +1 -1
  62. package/dist/esm/rendering/RenderTarget.d.ts +13 -0
  63. package/dist/esm/rendering/RenderTarget.js +13 -0
  64. package/dist/esm/rendering/RenderTarget.js.map +1 -1
  65. package/dist/esm/rendering/RenderTargetPass.js +17 -0
  66. package/dist/esm/rendering/RenderTargetPass.js.map +1 -1
  67. package/dist/esm/rendering/RenderingContext.d.ts +87 -0
  68. package/dist/esm/rendering/RenderingContext.js +157 -0
  69. package/dist/esm/rendering/RenderingContext.js.map +1 -0
  70. package/dist/esm/rendering/TransformBuffer.d.ts +82 -0
  71. package/dist/esm/rendering/TransformBuffer.js +180 -0
  72. package/dist/esm/rendering/TransformBuffer.js.map +1 -0
  73. package/dist/esm/rendering/filters/WebGpuShaderFilter.js +5 -12
  74. package/dist/esm/rendering/filters/WebGpuShaderFilter.js.map +1 -1
  75. package/dist/esm/rendering/geometry/Geometry.d.ts +40 -0
  76. package/dist/esm/rendering/geometry/Geometry.js +228 -0
  77. package/dist/esm/rendering/geometry/Geometry.js.map +1 -0
  78. package/dist/esm/rendering/geometry/GeometryAttribute.d.ts +32 -0
  79. package/dist/esm/rendering/geometry/QuadGeometry.d.ts +5 -0
  80. package/dist/esm/rendering/gradient/Gradient.d.ts +67 -0
  81. package/dist/esm/rendering/gradient/Gradient.js +160 -0
  82. package/dist/esm/rendering/gradient/Gradient.js.map +1 -0
  83. package/dist/esm/rendering/gradient/LinearGradient.d.ts +18 -0
  84. package/dist/esm/rendering/gradient/LinearGradient.js +49 -0
  85. package/dist/esm/rendering/gradient/LinearGradient.js.map +1 -0
  86. package/dist/esm/rendering/gradient/RadialGradient.d.ts +18 -0
  87. package/dist/esm/rendering/gradient/RadialGradient.js +44 -0
  88. package/dist/esm/rendering/gradient/RadialGradient.js.map +1 -0
  89. package/dist/esm/rendering/index.d.ts +16 -2
  90. package/dist/esm/rendering/material/Material.d.ts +114 -0
  91. package/dist/esm/rendering/material/Material.js +111 -0
  92. package/dist/esm/rendering/material/Material.js.map +1 -0
  93. package/dist/esm/rendering/material/MaterialKey.d.ts +18 -0
  94. package/dist/esm/rendering/material/MaterialKey.js +82 -0
  95. package/dist/esm/rendering/material/MaterialKey.js.map +1 -0
  96. package/dist/esm/rendering/material/MeshMaterial.d.ts +16 -0
  97. package/dist/esm/rendering/material/MeshMaterial.js +21 -0
  98. package/dist/esm/rendering/material/MeshMaterial.js.map +1 -0
  99. package/dist/esm/rendering/{mesh/MeshShader.d.ts → material/ShaderSource.d.ts} +29 -62
  100. package/dist/esm/rendering/{mesh/MeshShader.js → material/ShaderSource.js} +35 -62
  101. package/dist/esm/rendering/material/ShaderSource.js.map +1 -0
  102. package/dist/esm/rendering/material/SpriteMaterial.d.ts +15 -0
  103. package/dist/esm/rendering/material/SpriteMaterial.js +20 -0
  104. package/dist/esm/rendering/material/SpriteMaterial.js.map +1 -0
  105. package/dist/esm/rendering/mesh/Mesh.d.ts +29 -12
  106. package/dist/esm/rendering/mesh/Mesh.js +122 -3
  107. package/dist/esm/rendering/mesh/Mesh.js.map +1 -1
  108. package/dist/esm/rendering/pass/RenderPassCoordinator.d.ts +63 -0
  109. package/dist/esm/rendering/pass/RenderPassDescriptor.d.ts +48 -0
  110. package/dist/esm/rendering/pass/RenderPassDescriptor.js +16 -0
  111. package/dist/esm/rendering/pass/RenderPassDescriptor.js.map +1 -0
  112. package/dist/esm/rendering/plan/RenderCommand.d.ts +86 -0
  113. package/dist/esm/rendering/plan/RenderCommand.js +127 -0
  114. package/dist/esm/rendering/plan/RenderCommand.js.map +1 -0
  115. package/dist/esm/rendering/plan/RenderEffectExecutor.d.ts +10 -0
  116. package/dist/esm/rendering/plan/RenderEffectExecutor.js +159 -0
  117. package/dist/esm/rendering/plan/RenderEffectExecutor.js.map +1 -0
  118. package/dist/esm/rendering/plan/RenderInstruction.d.ts +51 -0
  119. package/dist/esm/rendering/plan/RenderInstruction.js +45 -0
  120. package/dist/esm/rendering/plan/RenderInstruction.js.map +1 -0
  121. package/dist/esm/rendering/plan/RenderPlan.d.ts +23 -0
  122. package/dist/esm/rendering/plan/RenderPlan.js +12 -0
  123. package/dist/esm/rendering/plan/RenderPlan.js.map +1 -0
  124. package/dist/esm/rendering/plan/RenderPlanBuilder.d.ts +31 -0
  125. package/dist/esm/rendering/plan/RenderPlanBuilder.js +242 -0
  126. package/dist/esm/rendering/plan/RenderPlanBuilder.js.map +1 -0
  127. package/dist/esm/rendering/plan/RenderPlanOptimizer.d.ts +10 -0
  128. package/dist/esm/rendering/plan/RenderPlanOptimizer.js +180 -0
  129. package/dist/esm/rendering/plan/RenderPlanOptimizer.js.map +1 -0
  130. package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts +13 -0
  131. package/dist/esm/rendering/plan/RenderPlanPlayer.js +107 -0
  132. package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -0
  133. package/dist/esm/rendering/plan/RenderScope.d.ts +70 -0
  134. package/dist/esm/rendering/plan/RenderScope.js +16 -0
  135. package/dist/esm/rendering/plan/RenderScope.js.map +1 -0
  136. package/dist/esm/rendering/plan/playRenderTree.d.ts +4 -0
  137. package/dist/esm/rendering/plan/playRenderTree.js +19 -0
  138. package/dist/esm/rendering/plan/playRenderTree.js.map +1 -0
  139. package/dist/esm/rendering/primitives/Graphics.d.ts +70 -5
  140. package/dist/esm/rendering/primitives/Graphics.js +172 -14
  141. package/dist/esm/rendering/primitives/Graphics.js.map +1 -1
  142. package/dist/esm/rendering/sprite/Sprite.d.ts +22 -1
  143. package/dist/esm/rendering/sprite/Sprite.js +33 -2
  144. package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
  145. package/dist/esm/rendering/sprite/spriteMaterialSources.d.ts +41 -0
  146. package/dist/esm/rendering/sprite/spriteMaterialSources.js +149 -0
  147. package/dist/esm/rendering/sprite/spriteMaterialSources.js.map +1 -0
  148. package/dist/esm/rendering/text/BitmapText.d.ts +2 -0
  149. package/dist/esm/rendering/text/BitmapText.js +8 -1
  150. package/dist/esm/rendering/text/BitmapText.js.map +1 -1
  151. package/dist/esm/rendering/text/BmFont.js +3 -0
  152. package/dist/esm/rendering/text/BmFont.js.map +1 -1
  153. package/dist/esm/rendering/text/GlyphSdf.d.ts +14 -0
  154. package/dist/esm/rendering/text/GlyphSdf.js +41 -11
  155. package/dist/esm/rendering/text/GlyphSdf.js.map +1 -1
  156. package/dist/esm/rendering/text/TextStyle.d.ts +6 -1
  157. package/dist/esm/rendering/text/TextStyle.js +1 -1
  158. package/dist/esm/rendering/text/TextStyle.js.map +1 -1
  159. package/dist/esm/rendering/texture/DataTexture.d.ts +5 -0
  160. package/dist/esm/rendering/texture/DataTexture.js +7 -0
  161. package/dist/esm/rendering/texture/DataTexture.js.map +1 -1
  162. package/dist/esm/rendering/texture/RenderTexture.js.map +1 -1
  163. package/dist/esm/rendering/video/Video.d.ts +3 -7
  164. package/dist/esm/rendering/video/Video.js +3 -8
  165. package/dist/esm/rendering/video/Video.js.map +1 -1
  166. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +62 -0
  167. package/dist/esm/rendering/webgl2/WebGl2Backend.js +352 -21
  168. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  169. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.d.ts +22 -2
  170. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +404 -112
  171. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
  172. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.d.ts +8 -0
  173. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js +8 -0
  174. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js.map +1 -1
  175. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.d.ts +57 -0
  176. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js +79 -0
  177. package/dist/esm/rendering/webgl2/WebGl2PassCoordinator.js.map +1 -0
  178. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +14 -0
  179. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +257 -78
  180. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  181. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.d.ts +34 -0
  182. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js +169 -0
  183. package/dist/esm/rendering/webgl2/WebGl2StencilClipper.js.map +1 -0
  184. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.d.ts +7 -0
  185. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +11 -0
  186. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -1
  187. package/dist/esm/rendering/webgl2/glsl/mesh.frag.js +1 -1
  188. package/dist/esm/rendering/webgl2/glsl/mesh.vert.js +1 -1
  189. package/dist/esm/rendering/webgl2/glsl/sprite.vert.js +1 -1
  190. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js +4 -0
  191. package/dist/esm/rendering/webgl2/glsl/stencil-clip.frag.js.map +1 -0
  192. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js +4 -0
  193. package/dist/esm/rendering/webgl2/glsl/stencil-clip.vert.js.map +1 -0
  194. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js +1 -1
  195. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +63 -0
  196. package/dist/esm/rendering/webgpu/WebGpuBackend.js +180 -19
  197. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  198. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js +22 -17
  199. package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js.map +1 -1
  200. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.d.ts +24 -0
  201. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +524 -98
  202. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
  203. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.d.ts +7 -0
  204. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +24 -22
  205. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
  206. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.d.ts +141 -0
  207. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js +270 -0
  208. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js.map +1 -0
  209. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +25 -1
  210. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +430 -76
  211. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  212. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.d.ts +57 -0
  213. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js +257 -0
  214. package/dist/esm/rendering/webgpu/WebGpuStencilClipper.js.map +1 -0
  215. package/dist/esm/rendering/webgpu/WebGpuStencilState.d.ts +14 -0
  216. package/dist/esm/rendering/webgpu/WebGpuStencilState.js +36 -0
  217. package/dist/esm/rendering/webgpu/WebGpuStencilState.js.map +1 -0
  218. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.d.ts +7 -0
  219. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +30 -19
  220. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -1
  221. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +48 -0
  222. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +103 -0
  223. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -0
  224. package/dist/esm/resources/JsonStore.d.ts +18 -0
  225. package/dist/esm/resources/JsonStore.js +62 -0
  226. package/dist/esm/resources/JsonStore.js.map +1 -0
  227. package/dist/esm/resources/Loader.js +1 -1
  228. package/dist/esm/resources/Loader.js.map +1 -1
  229. package/dist/esm/resources/factories/ImageFactory.d.ts +14 -8
  230. package/dist/esm/resources/factories/ImageFactory.js +13 -6
  231. package/dist/esm/resources/factories/ImageFactory.js.map +1 -1
  232. package/dist/esm/resources/factories/TextureFactory.d.ts +4 -4
  233. package/dist/esm/resources/factories/TextureFactory.js +8 -4
  234. package/dist/esm/resources/factories/TextureFactory.js.map +1 -1
  235. package/dist/esm/resources/index.d.ts +1 -0
  236. package/dist/exo.esm.js +6326 -2350
  237. package/dist/exo.esm.js.map +1 -1
  238. package/package.json +34 -24
  239. package/dist/esm/particles/distributions/Gradient.js.map +0 -1
  240. package/dist/esm/rendering/mesh/MeshShader.js.map +0 -1
  241. package/dist/esm/vendor/webgl-debug.js +0 -1160
  242. package/dist/esm/vendor/webgl-debug.js.map +0 -1
@@ -0,0 +1,228 @@
1
+ import { Rectangle } from '../../math/Rectangle.js';
2
+
3
+ const attributeTypeByteSizes = {
4
+ f32: 4,
5
+ u8: 1,
6
+ u16: 2,
7
+ u32: 4,
8
+ i32: 4,
9
+ };
10
+ const validTopologies = new Set(['triangle-list', 'triangle-strip']);
11
+ const validUsages = new Set(['static', 'dynamic', 'stream']);
12
+ const positionAttributeNames = new Set(['a_position', 'position']);
13
+ const geometryIds = new WeakMap();
14
+ let nextGeometryId = 1;
15
+ const getOrCreateGeometryId = (geometry) => {
16
+ const cached = geometryIds.get(geometry);
17
+ if (cached !== undefined) {
18
+ return cached;
19
+ }
20
+ const id = nextGeometryId++;
21
+ geometryIds.set(geometry, id);
22
+ return id;
23
+ };
24
+ const getVertexCount = (vertexData, stride) => {
25
+ const { byteLength } = vertexData;
26
+ if (byteLength % stride !== 0) {
27
+ throw new Error(`Geometry vertexData byteLength ${byteLength} must be divisible by stride ${stride}.`);
28
+ }
29
+ return byteLength / stride;
30
+ };
31
+ const readComponent = (view, type, offset, normalized) => {
32
+ switch (type) {
33
+ case 'f32':
34
+ return view.getFloat32(offset, true);
35
+ case 'u8': {
36
+ const value = view.getUint8(offset);
37
+ return normalized ? value / 255 : value;
38
+ }
39
+ case 'u16': {
40
+ const value = view.getUint16(offset, true);
41
+ return normalized ? value / 65535 : value;
42
+ }
43
+ case 'u32': {
44
+ const value = view.getUint32(offset, true);
45
+ return normalized ? value / 4294967295 : value;
46
+ }
47
+ case 'i32': {
48
+ const value = view.getInt32(offset, true);
49
+ return normalized ? Math.max(value / 2147483647, -1) : value;
50
+ }
51
+ default:
52
+ return 0;
53
+ }
54
+ };
55
+ const cloneAttributes = (attributes) => {
56
+ return attributes.map(attribute => ({ ...attribute }));
57
+ };
58
+ const resolvePositionAttribute = (attributes) => {
59
+ const directMatch = attributes.find(attribute => positionAttributeNames.has(attribute.name));
60
+ if (directMatch) {
61
+ return directMatch;
62
+ }
63
+ const fuzzyMatch = attributes.find(attribute => attribute.name.toLowerCase().includes('position'));
64
+ if (fuzzyMatch) {
65
+ return fuzzyMatch;
66
+ }
67
+ throw new Error('Geometry requires a position attribute named `a_position` or `position`.');
68
+ };
69
+ /**
70
+ * Non-renderable geometry data object used by advanced rendering paths.
71
+ *
72
+ * Geometry owns only vertex/index data and its layout metadata; it is not a
73
+ * scene node, has no transform state, and cannot render itself.
74
+ * @advanced
75
+ */
76
+ class Geometry {
77
+ attributes;
78
+ stride;
79
+ topology;
80
+ usage;
81
+ indices;
82
+ vertexData;
83
+ _version = 0;
84
+ _localBounds = new Rectangle();
85
+ _localBoundsDirty = true;
86
+ _positionAttribute;
87
+ _disposeCallbacks = new Set();
88
+ constructor(options) {
89
+ const { attributes, vertexData, stride, indices = null, topology = 'triangle-list', usage = 'static' } = options;
90
+ if (attributes.length === 0) {
91
+ throw new Error('Geometry attributes must be a non-empty array.');
92
+ }
93
+ if (!Number.isInteger(stride) || stride <= 0) {
94
+ throw new Error(`Geometry stride must be a positive integer (got ${stride}).`);
95
+ }
96
+ if (!validTopologies.has(topology)) {
97
+ throw new Error(`Geometry topology must be one of: triangle-list, triangle-strip (got ${String(topology)}).`);
98
+ }
99
+ if (!validUsages.has(usage)) {
100
+ throw new Error(`Geometry usage must be one of: static, dynamic, stream (got ${String(usage)}).`);
101
+ }
102
+ const ranges = [];
103
+ const names = new Set();
104
+ for (const attribute of attributes) {
105
+ if (typeof attribute.name !== 'string' || attribute.name.length === 0) {
106
+ throw new Error('Geometry attribute name must be a non-empty string.');
107
+ }
108
+ if (names.has(attribute.name)) {
109
+ throw new Error(`Geometry attribute "${attribute.name}" is declared more than once.`);
110
+ }
111
+ names.add(attribute.name);
112
+ if (!Number.isInteger(attribute.size) || attribute.size < 1 || attribute.size > 4) {
113
+ throw new Error(`Geometry attribute "${attribute.name}" size must be an integer in [1..4] (got ${attribute.size}).`);
114
+ }
115
+ if (!Number.isInteger(attribute.offset) || attribute.offset < 0) {
116
+ throw new Error(`Geometry attribute "${attribute.name}" offset must be a non-negative integer (got ${attribute.offset}).`);
117
+ }
118
+ const byteSize = attributeTypeByteSizes[attribute.type];
119
+ const end = attribute.offset + byteSize * attribute.size;
120
+ if (end > stride) {
121
+ throw new Error(`Geometry attribute "${attribute.name}" range [${attribute.offset}, ${end}) exceeds stride ${stride}.`);
122
+ }
123
+ for (const range of ranges) {
124
+ if (attribute.offset < range.end && end > range.start) {
125
+ throw new Error(`Geometry attribute "${attribute.name}" overlaps attribute "${range.name}" in the interleaved layout.`);
126
+ }
127
+ }
128
+ ranges.push({ name: attribute.name, start: attribute.offset, end });
129
+ }
130
+ const positionAttribute = resolvePositionAttribute(attributes);
131
+ if (positionAttribute.size < 2) {
132
+ throw new Error(`Geometry position attribute "${positionAttribute.name}" must declare at least 2 components.`);
133
+ }
134
+ const vertexCount = getVertexCount(vertexData, stride);
135
+ if (indices !== null) {
136
+ for (let i = 0; i < indices.length; i++) {
137
+ if (indices[i] >= vertexCount) {
138
+ throw new Error(`Geometry index ${indices[i]} at position ${i} is out of range for vertex count ${vertexCount}.`);
139
+ }
140
+ }
141
+ }
142
+ this.attributes = cloneAttributes(attributes);
143
+ this.vertexData = vertexData;
144
+ this.stride = stride;
145
+ this.indices = indices;
146
+ this.topology = topology;
147
+ this.usage = usage;
148
+ this._positionAttribute = { ...positionAttribute };
149
+ }
150
+ get vertexCount() {
151
+ return getVertexCount(this.vertexData, this.stride);
152
+ }
153
+ get indexCount() {
154
+ return this.indices?.length ?? this.vertexCount;
155
+ }
156
+ get version() {
157
+ return this._version;
158
+ }
159
+ get id() {
160
+ return getOrCreateGeometryId(this);
161
+ }
162
+ /** Mark vertex data as mutated in place so backends can re-upload GPU buffers. */
163
+ invalidate() {
164
+ this._version++;
165
+ this._localBoundsDirty = true;
166
+ return this;
167
+ }
168
+ /** Return local-space bounds; when `out` is provided it is populated and returned. */
169
+ getLocalBounds(out = this._localBounds) {
170
+ if (this._localBoundsDirty) {
171
+ this.recomputeLocalBounds();
172
+ }
173
+ if (out === this._localBounds) {
174
+ return this._localBounds;
175
+ }
176
+ return out.copy(this._localBounds);
177
+ }
178
+ /** Force local-space AABB recomputation from the current position attribute data. */
179
+ recomputeLocalBounds() {
180
+ const vertexCount = this.vertexCount;
181
+ if (vertexCount === 0) {
182
+ this._localBounds.set(0, 0, 0, 0);
183
+ this._localBoundsDirty = false;
184
+ return this;
185
+ }
186
+ const view = this.vertexData instanceof Float32Array
187
+ ? new DataView(this.vertexData.buffer, this.vertexData.byteOffset, this.vertexData.byteLength)
188
+ : new DataView(this.vertexData);
189
+ const componentByteSize = attributeTypeByteSizes[this._positionAttribute.type];
190
+ let minX = Infinity;
191
+ let minY = Infinity;
192
+ let maxX = -Infinity;
193
+ let maxY = -Infinity;
194
+ for (let vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
195
+ const start = vertexIndex * this.stride + this._positionAttribute.offset;
196
+ const x = readComponent(view, this._positionAttribute.type, start, this._positionAttribute.normalized);
197
+ const y = readComponent(view, this._positionAttribute.type, start + componentByteSize, this._positionAttribute.normalized);
198
+ if (x < minX)
199
+ minX = x;
200
+ if (x > maxX)
201
+ maxX = x;
202
+ if (y < minY)
203
+ minY = y;
204
+ if (y > maxY)
205
+ maxY = y;
206
+ }
207
+ this._localBounds.set(minX, minY, maxX - minX, maxY - minY);
208
+ this._localBoundsDirty = false;
209
+ return this;
210
+ }
211
+ /** Release backend-owned resources associated with this geometry instance. */
212
+ destroy() {
213
+ for (const callback of this._disposeCallbacks) {
214
+ callback();
215
+ }
216
+ this._disposeCallbacks.clear();
217
+ }
218
+ /**
219
+ * Internal backend hook used to register per-geometry cleanup callbacks.
220
+ * @internal
221
+ */
222
+ _onDispose(callback) {
223
+ this._disposeCallbacks.add(callback);
224
+ }
225
+ }
226
+
227
+ export { Geometry };
228
+ //# sourceMappingURL=Geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Geometry.js","sources":["../../../../../src/rendering/geometry/Geometry.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * GPU buffer ownership strategy used by geometry-aware render paths.
3
+ *
4
+ * - `static` — immutable after creation; eligible for shared batched buffers.
5
+ * - `dynamic` — occasionally mutated; backend should keep a dedicated buffer.
6
+ * - `stream` — mutated every frame; backend should treat as immediate data.
7
+ */
8
+ export type GeometryUsage = 'static' | 'dynamic' | 'stream';
9
+ /** Scalar component type used by a geometry vertex attribute. */
10
+ export type AttributeType = 'f32' | 'u8' | 'u16' | 'u32' | 'i32';
11
+ /** Primitive topology used when drawing this geometry. */
12
+ export type Topology = 'triangle-list' | 'triangle-strip';
13
+ /**
14
+ * Descriptor for one attribute in an interleaved vertex layout.
15
+ * Offsets and stride are expressed in bytes.
16
+ */
17
+ export interface GeometryAttribute {
18
+ readonly name: string;
19
+ readonly size: number;
20
+ readonly type: AttributeType;
21
+ readonly normalized: boolean;
22
+ readonly offset: number;
23
+ }
24
+ /** Construction options for {@link Geometry}. */
25
+ export interface GeometryOptions {
26
+ readonly attributes: readonly GeometryAttribute[];
27
+ readonly vertexData: Float32Array | ArrayBuffer;
28
+ readonly stride: number;
29
+ readonly indices?: Uint16Array | Uint32Array | null;
30
+ readonly topology?: Topology;
31
+ readonly usage?: GeometryUsage;
32
+ }
@@ -0,0 +1,5 @@
1
+ import { Geometry } from './Geometry';
2
+ /** @internal */
3
+ export declare class QuadGeometry extends Geometry {
4
+ constructor();
5
+ }
@@ -0,0 +1,67 @@
1
+ import type { Color } from '@/core/Color';
2
+ import type { Cloneable, Destroyable } from '@/core/types';
3
+ import { DataTexture } from '@/rendering/texture/DataTexture';
4
+ import type { SamplerOptions } from '@/rendering/texture/Sampler';
5
+ /** Discriminant identifying the concrete gradient kind (`gradient.type`). */
6
+ export type GradientType = 'linear' | 'radial';
7
+ export interface GradientStop {
8
+ offset: number;
9
+ color: Color;
10
+ }
11
+ export interface GradientToTextureOptions {
12
+ readonly format?: 'rgba8' | 'rgba32f';
13
+ readonly samplerOptions?: Partial<SamplerOptions>;
14
+ }
15
+ /**
16
+ * CPU-rasterized gradient base. A {@link Color}-like paint value (not a
17
+ * {@link Drawable}): it owns a normalized list of color stops plus subclass
18
+ * geometry and supports the value-object contract — {@link Gradient.clone},
19
+ * {@link Gradient.copy}, and {@link Gradient.equals}. Stops are cloned on the
20
+ * way in, clamped to `0..1`, and kept sorted by offset.
21
+ *
22
+ * Convert a gradient into a sampleable {@link DataTexture} with
23
+ * {@link Gradient.toTexture}; wrap that texture in a `Sprite`/`Mesh` to draw it.
24
+ */
25
+ export declare abstract class Gradient implements Cloneable, Destroyable {
26
+ /** Concrete gradient kind, e.g. `'linear'` or `'radial'`. */
27
+ abstract readonly type: GradientType;
28
+ private _stops;
29
+ private readonly _sample;
30
+ protected constructor(stops: readonly GradientStop[]);
31
+ get stops(): readonly GradientStop[];
32
+ /** Deep-clone into a new instance of the same concrete gradient type. */
33
+ abstract clone(): this;
34
+ /**
35
+ * Copy every value (stops and geometry) from a same-type `source` into this
36
+ * instance, replacing its current state. Returns `this` for chaining.
37
+ */
38
+ copy(source: this): this;
39
+ /**
40
+ * Structural value equality: same {@link GradientType}, same ordered stops
41
+ * (offset and {@link Color}), and same subclass geometry.
42
+ */
43
+ equals(other: Gradient): boolean;
44
+ toTexture(width: number, height: number, options?: GradientToTextureOptions & {
45
+ format?: 'rgba8';
46
+ }): DataTexture<'rgba8'>;
47
+ toTexture(width: number, height: number, options: GradientToTextureOptions & {
48
+ format: 'rgba32f';
49
+ }): DataTexture<'rgba32f'>;
50
+ destroy(): void;
51
+ protected abstract resolveT(u: number, v: number): number;
52
+ /** Copy the concrete subclass geometry from a same-type `source`. */
53
+ protected abstract _copyGeometry(source: this): void;
54
+ /**
55
+ * Compare the concrete subclass geometry against `other`. Only invoked once
56
+ * {@link Gradient.equals} has confirmed both sides share the same
57
+ * {@link GradientType}, so implementations may narrow `other` accordingly.
58
+ */
59
+ protected abstract _geometryEquals(other: Gradient): boolean;
60
+ /**
61
+ * Shared stop sampling logic ported from the legacy GLSL implementation.
62
+ */
63
+ protected sampleAt(t: number, out: Float32Array): void;
64
+ private static _normalizeStops;
65
+ private _toRgba8Texture;
66
+ private _toRgba32fTexture;
67
+ }
@@ -0,0 +1,160 @@
1
+ import { clamp } from '../../math/utils.js';
2
+ import { DataTexture } from '../texture/DataTexture.js';
3
+
4
+ const sortedStopOffset = (left, right) => left.offset - right.offset;
5
+ /**
6
+ * CPU-rasterized gradient base. A {@link Color}-like paint value (not a
7
+ * {@link Drawable}): it owns a normalized list of color stops plus subclass
8
+ * geometry and supports the value-object contract — {@link Gradient.clone},
9
+ * {@link Gradient.copy}, and {@link Gradient.equals}. Stops are cloned on the
10
+ * way in, clamped to `0..1`, and kept sorted by offset.
11
+ *
12
+ * Convert a gradient into a sampleable {@link DataTexture} with
13
+ * {@link Gradient.toTexture}; wrap that texture in a `Sprite`/`Mesh` to draw it.
14
+ */
15
+ class Gradient {
16
+ _stops;
17
+ _sample = new Float32Array(4);
18
+ constructor(stops) {
19
+ this._stops = Gradient._normalizeStops(stops);
20
+ }
21
+ get stops() {
22
+ return this._stops;
23
+ }
24
+ /**
25
+ * Copy every value (stops and geometry) from a same-type `source` into this
26
+ * instance, replacing its current state. Returns `this` for chaining.
27
+ */
28
+ copy(source) {
29
+ this._stops = source._stops.map(stop => ({ offset: stop.offset, color: stop.color.clone() }));
30
+ this._copyGeometry(source);
31
+ return this;
32
+ }
33
+ /**
34
+ * Structural value equality: same {@link GradientType}, same ordered stops
35
+ * (offset and {@link Color}), and same subclass geometry.
36
+ */
37
+ equals(other) {
38
+ if (this === other) {
39
+ return true;
40
+ }
41
+ if (this.type !== other.type || this._stops.length !== other._stops.length) {
42
+ return false;
43
+ }
44
+ for (let i = 0; i < this._stops.length; i++) {
45
+ const own = this._stops[i];
46
+ const their = other._stops[i];
47
+ if (own.offset !== their.offset || !own.color.equals(their.color)) {
48
+ return false;
49
+ }
50
+ }
51
+ return this._geometryEquals(other);
52
+ }
53
+ toTexture(width, height, options = {}) {
54
+ if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {
55
+ throw new Error('Gradient.toTexture() width/height must be positive integers.');
56
+ }
57
+ if (options.format === 'rgba32f') {
58
+ return this._toRgba32fTexture(width, height, options);
59
+ }
60
+ return this._toRgba8Texture(width, height, options);
61
+ }
62
+ destroy() {
63
+ for (const stop of this._stops) {
64
+ stop.color.destroy();
65
+ }
66
+ this._stops = [];
67
+ }
68
+ /**
69
+ * Shared stop sampling logic ported from the legacy GLSL implementation.
70
+ */
71
+ sampleAt(t, out) {
72
+ const clamped = clamp(t, 0, 1);
73
+ const first = this._stops[0];
74
+ let previousOffset = first.offset;
75
+ let previousColor = first.color;
76
+ for (let i = 1; i < this._stops.length; i++) {
77
+ const current = this._stops[i];
78
+ if (clamped <= current.offset) {
79
+ const span = Math.max(current.offset - previousOffset, 0.000001);
80
+ const ratio = clamp((clamped - previousOffset) / span, 0, 1);
81
+ out[0] = previousColor.r / 255 + (current.color.r / 255 - previousColor.r / 255) * ratio;
82
+ out[1] = previousColor.g / 255 + (current.color.g / 255 - previousColor.g / 255) * ratio;
83
+ out[2] = previousColor.b / 255 + (current.color.b / 255 - previousColor.b / 255) * ratio;
84
+ out[3] = previousColor.a + (current.color.a - previousColor.a) * ratio;
85
+ return;
86
+ }
87
+ previousOffset = current.offset;
88
+ previousColor = current.color;
89
+ }
90
+ out[0] = previousColor.r / 255;
91
+ out[1] = previousColor.g / 255;
92
+ out[2] = previousColor.b / 255;
93
+ out[3] = previousColor.a;
94
+ }
95
+ static _normalizeStops(stops) {
96
+ if (stops.length < 2) {
97
+ throw new Error('Gradient requires at least 2 color stops.');
98
+ }
99
+ return stops
100
+ .map(stop => {
101
+ if (!Number.isFinite(stop.offset)) {
102
+ throw new Error('Gradient stop offset must be a finite number.');
103
+ }
104
+ return { offset: clamp(stop.offset, 0, 1), color: stop.color.clone() };
105
+ })
106
+ .sort(sortedStopOffset);
107
+ }
108
+ _toRgba8Texture(width, height, options) {
109
+ const texture = new DataTexture({
110
+ width,
111
+ height,
112
+ format: 'rgba8',
113
+ samplerOptions: options.samplerOptions,
114
+ });
115
+ const buffer = texture.buffer;
116
+ let offset = 0;
117
+ for (let y = 0; y < height; y++) {
118
+ const v = height === 1 ? 0 : y / (height - 1);
119
+ for (let x = 0; x < width; x++) {
120
+ const u = width === 1 ? 0 : x / (width - 1);
121
+ this.sampleAt(this.resolveT(u, v), this._sample);
122
+ buffer[offset] = toUnorm8(this._sample[0]);
123
+ buffer[offset + 1] = toUnorm8(this._sample[1]);
124
+ buffer[offset + 2] = toUnorm8(this._sample[2]);
125
+ buffer[offset + 3] = toUnorm8(this._sample[3]);
126
+ offset += 4;
127
+ }
128
+ }
129
+ texture.commit();
130
+ return texture;
131
+ }
132
+ _toRgba32fTexture(width, height, options) {
133
+ const texture = new DataTexture({
134
+ width,
135
+ height,
136
+ format: 'rgba32f',
137
+ samplerOptions: options.samplerOptions,
138
+ });
139
+ const buffer = texture.buffer;
140
+ let offset = 0;
141
+ for (let y = 0; y < height; y++) {
142
+ const v = height === 1 ? 0 : y / (height - 1);
143
+ for (let x = 0; x < width; x++) {
144
+ const u = width === 1 ? 0 : x / (width - 1);
145
+ this.sampleAt(this.resolveT(u, v), this._sample);
146
+ buffer[offset] = this._sample[0];
147
+ buffer[offset + 1] = this._sample[1];
148
+ buffer[offset + 2] = this._sample[2];
149
+ buffer[offset + 3] = this._sample[3];
150
+ offset += 4;
151
+ }
152
+ }
153
+ texture.commit();
154
+ return texture;
155
+ }
156
+ }
157
+ const toUnorm8 = (value) => (clamp(value, 0, 1) * 255 + 0.5) | 0;
158
+
159
+ export { Gradient };
160
+ //# sourceMappingURL=Gradient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Gradient.js","sources":["../../../../../src/rendering/gradient/Gradient.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Gradient, type GradientStop, type GradientType } from './Gradient';
2
+ /**
3
+ * Linear gradient in UV space projected from `start` to `end`.
4
+ */
5
+ export declare class LinearGradient extends Gradient {
6
+ readonly type: GradientType;
7
+ private _start;
8
+ private _end;
9
+ constructor(stops: readonly GradientStop[], start?: readonly [number, number], end?: readonly [number, number]);
10
+ /** Projection axis start point in UV space. */
11
+ get start(): readonly [number, number];
12
+ /** Projection axis end point in UV space. */
13
+ get end(): readonly [number, number];
14
+ clone(): this;
15
+ protected resolveT(u: number, v: number): number;
16
+ protected _copyGeometry(source: LinearGradient): void;
17
+ protected _geometryEquals(other: Gradient): boolean;
18
+ }
@@ -0,0 +1,49 @@
1
+ import { Gradient } from './Gradient.js';
2
+
3
+ /**
4
+ * Linear gradient in UV space projected from `start` to `end`.
5
+ */
6
+ class LinearGradient extends Gradient {
7
+ type = 'linear';
8
+ _start;
9
+ _end;
10
+ constructor(stops, start = [0, 0], end = [1, 0]) {
11
+ super(stops);
12
+ this._start = [start[0], start[1]];
13
+ this._end = [end[0], end[1]];
14
+ }
15
+ /** Projection axis start point in UV space. */
16
+ get start() {
17
+ return [this._start[0], this._start[1]];
18
+ }
19
+ /** Projection axis end point in UV space. */
20
+ get end() {
21
+ return [this._end[0], this._end[1]];
22
+ }
23
+ clone() {
24
+ return new LinearGradient(this.stops, this._start, this._end);
25
+ }
26
+ resolveT(u, v) {
27
+ const axisX = this._end[0] - this._start[0];
28
+ const axisY = this._end[1] - this._start[1];
29
+ const lengthSquared = axisX * axisX + axisY * axisY;
30
+ if (lengthSquared <= 0.000001) {
31
+ return 0;
32
+ }
33
+ return ((u - this._start[0]) * axisX + (v - this._start[1]) * axisY) / lengthSquared;
34
+ }
35
+ _copyGeometry(source) {
36
+ this._start = [source._start[0], source._start[1]];
37
+ this._end = [source._end[0], source._end[1]];
38
+ }
39
+ _geometryEquals(other) {
40
+ return (other instanceof LinearGradient &&
41
+ this._start[0] === other._start[0] &&
42
+ this._start[1] === other._start[1] &&
43
+ this._end[0] === other._end[0] &&
44
+ this._end[1] === other._end[1]);
45
+ }
46
+ }
47
+
48
+ export { LinearGradient };
49
+ //# sourceMappingURL=LinearGradient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinearGradient.js","sources":["../../../../../src/rendering/gradient/LinearGradient.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;AAEG;AACG,MAAO,cAAe,SAAQ,QAAQ,CAAA;IAC1B,IAAI,GAAiB,QAAQ;AAErC,IAAA,MAAM;AACN,IAAA,IAAI;AAEZ,IAAA,WAAA,CAAmB,KAA8B,EAAE,KAAA,GAAmC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAA,GAAiC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAA;QACnI,KAAK,CAAC,KAAK,CAAC;AAEZ,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B;;AAGA,IAAA,IAAW,KAAK,GAAA;AACd,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzC;;AAGA,IAAA,IAAW,GAAG,GAAA;AACZ,QAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC;IAEO,KAAK,GAAA;AACV,QAAA,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAS;IACvE;IAEmB,QAAQ,CAAC,CAAS,EAAE,CAAS,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AAEnD,QAAA,IAAI,aAAa,IAAI,QAAQ,EAAE;AAC7B,YAAA,OAAO,CAAC;QACV;AAEA,QAAA,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,aAAa;IACtF;AAEmB,IAAA,aAAa,CAAC,MAAsB,EAAA;AACrD,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClD,QAAA,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C;AAEmB,IAAA,eAAe,CAAC,KAAe,EAAA;QAChD,QACE,KAAK,YAAY,cAAc;YAC/B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9B,YAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAElC;AACD;;;;"}
@@ -0,0 +1,18 @@
1
+ import { Gradient, type GradientStop, type GradientType } from './Gradient';
2
+ /**
3
+ * Radial gradient in UV space around `center` with normalized radius.
4
+ */
5
+ export declare class RadialGradient extends Gradient {
6
+ readonly type: GradientType;
7
+ private _center;
8
+ private _radius;
9
+ constructor(stops: readonly GradientStop[], center?: readonly [number, number], radius?: number);
10
+ /** Gradient center in UV space. */
11
+ get center(): readonly [number, number];
12
+ /** Normalized radius (UV units, clamped to be non-negative). */
13
+ get radius(): number;
14
+ clone(): this;
15
+ protected resolveT(u: number, v: number): number;
16
+ protected _copyGeometry(source: RadialGradient): void;
17
+ protected _geometryEquals(other: Gradient): boolean;
18
+ }
@@ -0,0 +1,44 @@
1
+ import { Gradient } from './Gradient.js';
2
+
3
+ /**
4
+ * Radial gradient in UV space around `center` with normalized radius.
5
+ */
6
+ class RadialGradient extends Gradient {
7
+ type = 'radial';
8
+ _center;
9
+ _radius;
10
+ constructor(stops, center = [0.5, 0.5], radius = 0.5) {
11
+ super(stops);
12
+ this._center = [center[0], center[1]];
13
+ this._radius = Math.max(0, radius);
14
+ }
15
+ /** Gradient center in UV space. */
16
+ get center() {
17
+ return [this._center[0], this._center[1]];
18
+ }
19
+ /** Normalized radius (UV units, clamped to be non-negative). */
20
+ get radius() {
21
+ return this._radius;
22
+ }
23
+ clone() {
24
+ return new RadialGradient(this.stops, this._center, this._radius);
25
+ }
26
+ resolveT(u, v) {
27
+ if (this._radius <= 0.000001) {
28
+ return 1;
29
+ }
30
+ const dx = u - this._center[0];
31
+ const dy = v - this._center[1];
32
+ return Math.sqrt(dx * dx + dy * dy) / this._radius;
33
+ }
34
+ _copyGeometry(source) {
35
+ this._center = [source._center[0], source._center[1]];
36
+ this._radius = source._radius;
37
+ }
38
+ _geometryEquals(other) {
39
+ return other instanceof RadialGradient && this._center[0] === other._center[0] && this._center[1] === other._center[1] && this._radius === other._radius;
40
+ }
41
+ }
42
+
43
+ export { RadialGradient };
44
+ //# sourceMappingURL=RadialGradient.js.map