@lightningjs/renderer 3.0.0-beta2 → 3.0.0-beta20

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 (551) hide show
  1. package/README.md +16 -26
  2. package/dist/exports/canvas.d.ts +1 -1
  3. package/dist/exports/canvas.js +1 -1
  4. package/dist/exports/canvas.js.map +1 -1
  5. package/dist/exports/index.d.ts +2 -5
  6. package/dist/exports/index.js +1 -5
  7. package/dist/exports/index.js.map +1 -1
  8. package/dist/exports/utils.d.ts +2 -1
  9. package/dist/exports/utils.js +2 -1
  10. package/dist/exports/utils.js.map +1 -1
  11. package/dist/exports/webgl.d.ts +2 -1
  12. package/dist/exports/webgl.js +2 -1
  13. package/dist/exports/webgl.js.map +1 -1
  14. package/dist/src/common/CommonTypes.d.ts +13 -2
  15. package/dist/src/core/Autosizer.d.ts +35 -0
  16. package/dist/src/core/Autosizer.js +196 -0
  17. package/dist/src/core/Autosizer.js.map +1 -0
  18. package/dist/src/core/CoreNode.d.ts +73 -95
  19. package/dist/src/core/CoreNode.js +599 -461
  20. package/dist/src/core/CoreNode.js.map +1 -1
  21. package/dist/src/core/CoreShaderManager.d.ts +3 -5
  22. package/dist/src/core/CoreShaderManager.js.map +1 -1
  23. package/dist/src/core/CoreTextNode.d.ts +74 -87
  24. package/dist/src/core/CoreTextNode.js +357 -232
  25. package/dist/src/core/CoreTextNode.js.map +1 -1
  26. package/dist/src/core/CoreTextureManager.d.ts +25 -13
  27. package/dist/src/core/CoreTextureManager.js +80 -104
  28. package/dist/src/core/CoreTextureManager.js.map +1 -1
  29. package/dist/src/core/Stage.d.ts +92 -33
  30. package/dist/src/core/Stage.js +313 -151
  31. package/dist/src/core/Stage.js.map +1 -1
  32. package/dist/src/core/TextureError.d.ts +11 -0
  33. package/dist/src/core/TextureError.js +37 -0
  34. package/dist/src/core/TextureError.js.map +1 -0
  35. package/dist/src/core/TextureMemoryManager.d.ts +11 -4
  36. package/dist/src/core/TextureMemoryManager.js +128 -109
  37. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  38. package/dist/src/core/animations/CoreAnimation.d.ts +3 -3
  39. package/dist/src/core/animations/CoreAnimation.js +8 -3
  40. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  41. package/dist/src/core/animations/CoreAnimationController.d.ts +1 -0
  42. package/dist/src/core/animations/CoreAnimationController.js +11 -4
  43. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  44. package/dist/src/core/lib/ImageWorker.js +1 -1
  45. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  46. package/dist/src/core/lib/WebGlContextWrapper.d.ts +41 -3
  47. package/dist/src/core/lib/WebGlContextWrapper.js +104 -27
  48. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  49. package/dist/src/core/lib/collectionUtils.d.ts +5 -0
  50. package/dist/src/core/lib/collectionUtils.js +100 -0
  51. package/dist/src/core/lib/collectionUtils.js.map +1 -0
  52. package/dist/src/core/lib/colorCache.d.ts +1 -0
  53. package/dist/src/core/lib/colorCache.js +19 -0
  54. package/dist/src/core/lib/colorCache.js.map +1 -0
  55. package/dist/src/core/lib/colorParser.d.ts +21 -0
  56. package/dist/src/core/lib/colorParser.js +72 -0
  57. package/dist/src/core/lib/colorParser.js.map +1 -0
  58. package/dist/src/core/lib/textureCompression.d.ts +14 -2
  59. package/dist/src/core/lib/textureCompression.js +320 -67
  60. package/dist/src/core/lib/textureCompression.js.map +1 -1
  61. package/dist/src/core/lib/utils.d.ts +2 -0
  62. package/dist/src/core/lib/utils.js +22 -0
  63. package/dist/src/core/lib/utils.js.map +1 -1
  64. package/dist/src/core/lib/validateImageBitmap.d.ts +2 -1
  65. package/dist/src/core/lib/validateImageBitmap.js +4 -4
  66. package/dist/src/core/lib/validateImageBitmap.js.map +1 -1
  67. package/dist/src/core/platform.js +30 -5
  68. package/dist/src/core/platform.js.map +1 -1
  69. package/dist/src/core/platforms/Platform.d.ts +42 -0
  70. package/dist/src/{main-api/IRenderDriver.js → core/platforms/Platform.js} +4 -2
  71. package/dist/src/core/platforms/Platform.js.map +1 -0
  72. package/dist/src/core/platforms/web/WebPlatform.d.ts +10 -0
  73. package/dist/src/core/platforms/web/WebPlatform.js +87 -0
  74. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -0
  75. package/dist/src/core/renderers/CoreContextTexture.d.ts +2 -1
  76. package/dist/src/core/renderers/CoreContextTexture.js.map +1 -1
  77. package/dist/src/core/renderers/CoreRenderer.d.ts +7 -2
  78. package/dist/src/core/renderers/CoreRenderer.js +1 -0
  79. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  80. package/dist/src/core/renderers/CoreShaderNode.d.ts +8 -1
  81. package/dist/src/core/renderers/CoreShaderNode.js +11 -0
  82. package/dist/src/core/renderers/CoreShaderNode.js.map +1 -1
  83. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +2 -1
  84. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +11 -9
  85. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  86. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +1 -2
  87. package/dist/src/core/renderers/canvas/CanvasRenderer.js +32 -59
  88. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  89. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +3 -5
  90. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  91. package/dist/src/core/renderers/canvas/CanvasTexture.d.ts +3 -2
  92. package/dist/src/core/renderers/canvas/CanvasTexture.js +17 -13
  93. package/dist/src/core/renderers/canvas/CanvasTexture.js.map +1 -1
  94. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.d.ts +13 -0
  95. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js +113 -192
  96. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js.map +1 -1
  97. package/dist/src/core/renderers/canvas/internal/ColorUtils.d.ts +0 -2
  98. package/dist/src/core/renderers/canvas/internal/ColorUtils.js +0 -14
  99. package/dist/src/core/renderers/canvas/internal/ColorUtils.js.map +1 -1
  100. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js +3 -0
  101. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js.map +1 -1
  102. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +18 -6
  103. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +86 -41
  104. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  105. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +1 -1
  106. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +53 -17
  107. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  108. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -7
  109. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +21 -50
  110. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  111. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +2 -0
  112. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js +14 -6
  113. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -1
  114. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +13 -0
  115. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js +34 -5
  116. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +1 -1
  117. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +16 -6
  118. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +95 -49
  119. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  120. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +3 -2
  121. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +14 -5
  122. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -1
  123. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +5 -3
  124. package/dist/src/core/renderers/webgl/WebGlRenderer.js +141 -112
  125. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  126. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +1 -4
  127. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  128. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +6 -3
  129. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +47 -18
  130. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  131. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
  132. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  133. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +0 -11
  134. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  135. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +5 -10
  136. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  137. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +5 -10
  138. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  139. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +0 -12
  140. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  141. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js +1 -1
  142. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js +1 -1
  143. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js +1 -1
  144. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js +1 -1
  145. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js +5 -5
  146. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +1 -1
  147. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +24 -19
  148. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  149. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.d.ts +1 -0
  150. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +32 -5
  151. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  152. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js +1 -1
  153. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +5 -5
  154. package/dist/src/core/shaders/canvas/Border.js +5 -5
  155. package/dist/src/core/shaders/canvas/Border.js.map +1 -1
  156. package/dist/src/core/shaders/canvas/HolePunch.js +3 -3
  157. package/dist/src/core/shaders/canvas/HolePunch.js.map +1 -1
  158. package/dist/src/core/shaders/canvas/LinearGradient.js +7 -5
  159. package/dist/src/core/shaders/canvas/LinearGradient.js.map +1 -1
  160. package/dist/src/core/shaders/canvas/RadialGradient.js +14 -12
  161. package/dist/src/core/shaders/canvas/RadialGradient.js.map +1 -1
  162. package/dist/src/core/shaders/canvas/Rounded.js +1 -1
  163. package/dist/src/core/shaders/canvas/Rounded.js.map +1 -1
  164. package/dist/src/core/shaders/canvas/RoundedWithBorder.js +14 -6
  165. package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +1 -1
  166. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +10 -8
  167. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +1 -1
  168. package/dist/src/core/shaders/canvas/RoundedWithShadow.js +7 -5
  169. package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +1 -1
  170. package/dist/src/core/shaders/templates/BorderTemplate.d.ts +2 -2
  171. package/dist/src/core/shaders/templates/BorderTemplate.js +11 -11
  172. package/dist/src/core/shaders/templates/BorderTemplate.js.map +1 -1
  173. package/dist/src/core/shaders/templates/HolePunchTemplate.d.ts +2 -2
  174. package/dist/src/core/shaders/templates/HolePunchTemplate.js +3 -3
  175. package/dist/src/core/shaders/templates/HolePunchTemplate.js.map +1 -1
  176. package/dist/src/core/shaders/templates/RadialGradientTemplate.d.ts +8 -6
  177. package/dist/src/core/shaders/templates/RadialGradientTemplate.js +2 -2
  178. package/dist/src/core/shaders/templates/RadialGradientTemplate.js.map +1 -1
  179. package/dist/src/core/shaders/templates/RoundedTemplate.js +1 -1
  180. package/dist/src/core/shaders/templates/RoundedTemplate.js.map +1 -1
  181. package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.d.ts +1 -1
  182. package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.d.ts +1 -1
  183. package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.d.ts +1 -1
  184. package/dist/src/core/shaders/templates/ShadowTemplate.d.ts +1 -1
  185. package/dist/src/core/shaders/{templates/shaderUtils.d.ts → utils.d.ts} +1 -1
  186. package/dist/src/core/shaders/{templates/shaderUtils.js → utils.js} +2 -2
  187. package/dist/src/core/shaders/utils.js.map +1 -0
  188. package/dist/src/core/shaders/webgl/Border.js +57 -34
  189. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  190. package/dist/src/core/shaders/webgl/Default.js +6 -7
  191. package/dist/src/core/shaders/webgl/Default.js.map +1 -1
  192. package/dist/src/core/shaders/webgl/HolePunch.js +4 -3
  193. package/dist/src/core/shaders/webgl/HolePunch.js.map +1 -1
  194. package/dist/src/core/shaders/webgl/LinearGradient.js +33 -8
  195. package/dist/src/core/shaders/webgl/LinearGradient.js.map +1 -1
  196. package/dist/src/core/shaders/webgl/RadialGradient.js +56 -32
  197. package/dist/src/core/shaders/webgl/RadialGradient.js.map +1 -1
  198. package/dist/src/core/shaders/webgl/Rounded.js +4 -2
  199. package/dist/src/core/shaders/webgl/Rounded.js.map +1 -1
  200. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +81 -37
  201. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  202. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +93 -42
  203. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  204. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +3 -2
  205. package/dist/src/core/shaders/webgl/RoundedWithShadow.js.map +1 -1
  206. package/dist/src/core/shaders/webgl/SdfShader.d.ts +0 -2
  207. package/dist/src/core/shaders/webgl/SdfShader.js +7 -17
  208. package/dist/src/core/shaders/webgl/SdfShader.js.map +1 -1
  209. package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +59 -0
  210. package/dist/src/core/text-rendering/CanvasFontHandler.js +224 -0
  211. package/dist/src/core/text-rendering/CanvasFontHandler.js.map +1 -0
  212. package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +17 -0
  213. package/dist/src/core/text-rendering/CanvasTextRenderer.js +157 -0
  214. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -0
  215. package/dist/src/core/text-rendering/SdfFontHandler.d.ts +182 -0
  216. package/dist/src/core/text-rendering/SdfFontHandler.js +391 -0
  217. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -0
  218. package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +17 -0
  219. package/dist/src/core/text-rendering/SdfTextRenderer.js +311 -0
  220. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -0
  221. package/dist/src/core/text-rendering/TextLayoutEngine.d.ts +18 -0
  222. package/dist/src/core/text-rendering/TextLayoutEngine.js +380 -0
  223. package/dist/src/core/text-rendering/TextLayoutEngine.js.map +1 -0
  224. package/dist/src/core/text-rendering/TextRenderer.d.ts +383 -0
  225. package/dist/src/{main-api/ICoreDriver.js → core/text-rendering/TextRenderer.js} +1 -1
  226. package/dist/src/core/text-rendering/TextRenderer.js.map +1 -0
  227. package/dist/src/core/text-rendering/TextTextureRendererUtils.js.map +1 -1
  228. package/dist/src/core/text-rendering/Utils.d.ts +30 -0
  229. package/dist/src/core/text-rendering/Utils.js +84 -0
  230. package/dist/src/core/text-rendering/Utils.js.map +1 -0
  231. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +2 -2
  232. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  233. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +0 -6
  234. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  235. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
  236. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +35 -38
  237. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  238. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +4 -1
  239. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  240. package/dist/src/core/textures/ColorTexture.d.ts +1 -1
  241. package/dist/src/core/textures/ColorTexture.js +3 -4
  242. package/dist/src/core/textures/ColorTexture.js.map +1 -1
  243. package/dist/src/core/textures/ImageTexture.d.ts +11 -4
  244. package/dist/src/core/textures/ImageTexture.js +31 -40
  245. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  246. package/dist/src/core/textures/NoiseTexture.d.ts +3 -3
  247. package/dist/src/core/textures/NoiseTexture.js +8 -8
  248. package/dist/src/core/textures/NoiseTexture.js.map +1 -1
  249. package/dist/src/core/textures/RenderTexture.d.ts +7 -7
  250. package/dist/src/core/textures/RenderTexture.js +12 -12
  251. package/dist/src/core/textures/RenderTexture.js.map +1 -1
  252. package/dist/src/core/textures/SubTexture.d.ts +6 -8
  253. package/dist/src/core/textures/SubTexture.js +19 -37
  254. package/dist/src/core/textures/SubTexture.js.map +1 -1
  255. package/dist/src/core/textures/Texture.d.ts +87 -10
  256. package/dist/src/core/textures/Texture.js +160 -17
  257. package/dist/src/core/textures/Texture.js.map +1 -1
  258. package/dist/src/core/utils.d.ts +3 -2
  259. package/dist/src/core/utils.js +1 -1
  260. package/dist/src/core/utils.js.map +1 -1
  261. package/dist/src/main-api/INode.d.ts +2 -2
  262. package/dist/src/main-api/Inspector.d.ts +130 -1
  263. package/dist/src/main-api/Inspector.js +341 -27
  264. package/dist/src/main-api/Inspector.js.map +1 -1
  265. package/dist/src/main-api/Renderer.d.ts +285 -82
  266. package/dist/src/main-api/Renderer.js +221 -76
  267. package/dist/src/main-api/Renderer.js.map +1 -1
  268. package/dist/src/utils.d.ts +1 -6
  269. package/dist/src/utils.js +2 -9
  270. package/dist/src/utils.js.map +1 -1
  271. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  272. package/dist/tsconfig.tsbuildinfo +1 -0
  273. package/exports/canvas.ts +1 -1
  274. package/exports/index.ts +2 -8
  275. package/exports/utils.ts +7 -1
  276. package/exports/webgl.ts +3 -1
  277. package/package.json +15 -17
  278. package/src/common/CommonTypes.ts +18 -2
  279. package/src/core/CoreNode.test.ts +63 -15
  280. package/src/core/CoreNode.ts +709 -582
  281. package/src/core/CoreShaderManager.ts +5 -10
  282. package/src/core/CoreTextNode.ts +424 -286
  283. package/src/core/CoreTextureManager.ts +110 -130
  284. package/src/core/Stage.ts +394 -195
  285. package/src/core/TextureError.ts +46 -0
  286. package/src/core/TextureMemoryManager.ts +164 -141
  287. package/src/core/animations/CoreAnimation.ts +15 -9
  288. package/src/core/animations/CoreAnimationController.ts +13 -4
  289. package/src/core/lib/ImageWorker.ts +7 -1
  290. package/src/core/lib/WebGlContextWrapper.ts +126 -78
  291. package/src/core/lib/collectionUtils.ts +118 -0
  292. package/src/core/lib/colorCache.ts +20 -0
  293. package/src/core/{renderers/canvas/internal/ColorUtils.ts → lib/colorParser.ts} +2 -2
  294. package/src/core/lib/textureCompression.ts +433 -75
  295. package/src/core/lib/utils.ts +26 -0
  296. package/src/core/lib/validateImageBitmap.ts +17 -6
  297. package/src/core/platforms/Platform.ts +83 -0
  298. package/src/core/platforms/web/WebPlatform.ts +132 -0
  299. package/src/core/renderers/CoreContextTexture.ts +2 -1
  300. package/src/core/renderers/CoreRenderer.ts +7 -3
  301. package/src/core/renderers/CoreShaderNode.ts +18 -3
  302. package/src/core/renderers/canvas/CanvasRenderer.ts +48 -82
  303. package/src/core/renderers/canvas/CanvasShaderNode.ts +3 -6
  304. package/src/core/renderers/canvas/CanvasTexture.ts +22 -18
  305. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +18 -15
  306. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +50 -5
  307. package/src/core/renderers/webgl/WebGlCtxTexture.ts +124 -81
  308. package/src/core/renderers/webgl/WebGlRenderOp.ts +21 -12
  309. package/src/core/renderers/webgl/WebGlRenderer.ts +172 -137
  310. package/src/core/renderers/webgl/WebGlShaderNode.ts +2 -4
  311. package/src/core/renderers/webgl/WebGlShaderProgram.ts +58 -20
  312. package/src/core/shaders/canvas/Border.ts +5 -8
  313. package/src/core/shaders/canvas/HolePunch.ts +4 -11
  314. package/src/core/shaders/canvas/LinearGradient.ts +10 -8
  315. package/src/core/shaders/canvas/RadialGradient.ts +23 -37
  316. package/src/core/shaders/canvas/Rounded.ts +2 -2
  317. package/src/core/shaders/canvas/RoundedWithBorder.ts +20 -16
  318. package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +17 -17
  319. package/src/core/shaders/canvas/RoundedWithShadow.ts +10 -9
  320. package/src/core/shaders/templates/BorderTemplate.ts +12 -12
  321. package/src/core/shaders/templates/HolePunchTemplate.ts +5 -5
  322. package/src/core/shaders/templates/RadialGradientTemplate.ts +10 -8
  323. package/src/core/shaders/templates/RoundedTemplate.ts +1 -1
  324. package/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.ts +1 -1
  325. package/src/core/shaders/templates/RoundedWithBorderTemplate.ts +1 -1
  326. package/src/core/shaders/templates/RoundedWithShadowTemplate.ts +1 -1
  327. package/src/core/shaders/templates/ShadowTemplate.ts +1 -1
  328. package/src/core/shaders/{templates/shaderUtils.ts → utils.ts} +2 -3
  329. package/src/core/shaders/webgl/Border.ts +57 -37
  330. package/src/core/shaders/webgl/Default.ts +6 -7
  331. package/src/core/shaders/webgl/HolePunch.ts +4 -7
  332. package/src/core/shaders/webgl/LinearGradient.ts +33 -8
  333. package/src/core/shaders/webgl/RadialGradient.ts +58 -34
  334. package/src/core/shaders/webgl/Rounded.ts +4 -6
  335. package/src/core/shaders/webgl/RoundedWithBorder.ts +82 -44
  336. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +93 -50
  337. package/src/core/shaders/webgl/RoundedWithShadow.ts +3 -6
  338. package/src/core/shaders/webgl/SdfShader.ts +7 -19
  339. package/src/core/text-rendering/CanvasFontHandler.ts +304 -0
  340. package/src/core/text-rendering/CanvasTextRenderer.ts +255 -0
  341. package/src/core/text-rendering/SdfFontHandler.ts +591 -0
  342. package/src/core/text-rendering/SdfTextRenderer.ts +411 -0
  343. package/src/core/text-rendering/TextLayoutEngine.ts +672 -0
  344. package/src/core/text-rendering/TextRenderer.ts +444 -0
  345. package/src/core/text-rendering/Utils.ts +99 -0
  346. package/src/core/text-rendering/tests/TextLayoutEngine.test.ts +453 -0
  347. package/src/core/textures/ColorTexture.ts +7 -5
  348. package/src/core/textures/ImageTexture.ts +78 -66
  349. package/src/core/textures/NoiseTexture.ts +14 -12
  350. package/src/core/textures/RenderTexture.ts +18 -16
  351. package/src/core/textures/SubTexture.ts +25 -46
  352. package/src/core/textures/Texture.ts +207 -24
  353. package/src/core/utils.ts +9 -7
  354. package/src/main-api/INode.ts +4 -3
  355. package/src/main-api/Inspector.ts +571 -33
  356. package/src/main-api/Renderer.ts +505 -139
  357. package/src/utils.ts +10 -10
  358. package/dist/exports/core-api.d.ts +0 -74
  359. package/dist/exports/core-api.js +0 -96
  360. package/dist/exports/core-api.js.map +0 -1
  361. package/dist/exports/main-api.d.ts +0 -30
  362. package/dist/exports/main-api.js +0 -45
  363. package/dist/exports/main-api.js.map +0 -1
  364. package/dist/src/core/CoreExtension.d.ts +0 -12
  365. package/dist/src/core/CoreExtension.js +0 -29
  366. package/dist/src/core/CoreExtension.js.map +0 -1
  367. package/dist/src/core/CoreStuff.d.ts +0 -1
  368. package/dist/src/core/CoreStuff.js +0 -138
  369. package/dist/src/core/CoreStuff.js.map +0 -1
  370. package/dist/src/core/CoreTexturizer.d.ts +0 -14
  371. package/dist/src/core/CoreTexturizer.js +0 -47
  372. package/dist/src/core/CoreTexturizer.js.map +0 -1
  373. package/dist/src/core/LngNode.d.ts +0 -736
  374. package/dist/src/core/LngNode.js +0 -1174
  375. package/dist/src/core/LngNode.js.map +0 -1
  376. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  377. package/dist/src/core/Matrix2DContext.js +0 -45
  378. package/dist/src/core/Matrix2DContext.js.map +0 -1
  379. package/dist/src/core/ShaderNode.d.ts +0 -10
  380. package/dist/src/core/ShaderNode.js +0 -30
  381. package/dist/src/core/ShaderNode.js.map +0 -1
  382. package/dist/src/core/TextNode.d.ts +0 -103
  383. package/dist/src/core/TextNode.js +0 -331
  384. package/dist/src/core/TextNode.js.map +0 -1
  385. package/dist/src/core/lib/Coords.d.ts +0 -14
  386. package/dist/src/core/lib/Coords.js +0 -55
  387. package/dist/src/core/lib/Coords.js.map +0 -1
  388. package/dist/src/core/lib/glm/common.d.ts +0 -162
  389. package/dist/src/core/lib/glm/common.js +0 -81
  390. package/dist/src/core/lib/glm/common.js.map +0 -1
  391. package/dist/src/core/lib/glm/index.d.ts +0 -11
  392. package/dist/src/core/lib/glm/index.js +0 -30
  393. package/dist/src/core/lib/glm/index.js.map +0 -1
  394. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  395. package/dist/src/core/lib/glm/mat2.js +0 -396
  396. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  397. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  398. package/dist/src/core/lib/glm/mat2d.js +0 -442
  399. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  400. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  401. package/dist/src/core/lib/glm/mat3.js +0 -680
  402. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  403. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  404. package/dist/src/core/lib/glm/mat4.js +0 -1802
  405. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  406. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  407. package/dist/src/core/lib/glm/quat.js +0 -693
  408. package/dist/src/core/lib/glm/quat.js.map +0 -1
  409. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  410. package/dist/src/core/lib/glm/quat2.js +0 -754
  411. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  412. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  413. package/dist/src/core/lib/glm/vec2.js +0 -569
  414. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  415. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  416. package/dist/src/core/lib/glm/vec3.js +0 -720
  417. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  418. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  419. package/dist/src/core/lib/glm/vec4.js +0 -608
  420. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  421. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  422. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  423. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  424. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  425. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  426. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  427. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  428. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  429. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  430. package/dist/src/core/scene/Scene.d.ts +0 -59
  431. package/dist/src/core/scene/Scene.js +0 -106
  432. package/dist/src/core/scene/Scene.js.map +0 -1
  433. package/dist/src/core/shaders/templates/shaderUtils.js.map +0 -1
  434. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  435. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  436. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  437. package/dist/src/main-api/ICoreDriver.d.ts +0 -27
  438. package/dist/src/main-api/ICoreDriver.js.map +0 -1
  439. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  440. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  441. package/dist/src/main-api/IShaderController.d.ts +0 -14
  442. package/dist/src/main-api/IShaderController.js +0 -30
  443. package/dist/src/main-api/IShaderController.js.map +0 -1
  444. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  445. package/dist/src/main-api/IShaderNode.js +0 -19
  446. package/dist/src/main-api/IShaderNode.js.map +0 -1
  447. package/dist/src/main-api/RendererMain.d.ts +0 -375
  448. package/dist/src/main-api/RendererMain.js +0 -365
  449. package/dist/src/main-api/RendererMain.js.map +0 -1
  450. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.d.ts +0 -9
  451. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js +0 -38
  452. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js.map +0 -1
  453. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.d.ts +0 -56
  454. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js +0 -101
  455. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +0 -1
  456. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.d.ts +0 -32
  457. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js +0 -28
  458. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js.map +0 -1
  459. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +0 -24
  460. package/dist/src/render-drivers/main/MainCoreDriver.js +0 -118
  461. package/dist/src/render-drivers/main/MainCoreDriver.js.map +0 -1
  462. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +0 -99
  463. package/dist/src/render-drivers/main/MainOnlyNode.js +0 -396
  464. package/dist/src/render-drivers/main/MainOnlyNode.js.map +0 -1
  465. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  466. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  467. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  468. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  469. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  470. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  471. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +0 -47
  472. package/dist/src/render-drivers/main/MainOnlyTextNode.js +0 -205
  473. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +0 -1
  474. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  475. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  476. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  477. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +0 -90
  478. package/dist/src/render-drivers/threadx/NodeStruct.js +0 -281
  479. package/dist/src/render-drivers/threadx/NodeStruct.js.map +0 -1
  480. package/dist/src/render-drivers/threadx/SharedNode.d.ts +0 -39
  481. package/dist/src/render-drivers/threadx/SharedNode.js +0 -60
  482. package/dist/src/render-drivers/threadx/SharedNode.js.map +0 -1
  483. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +0 -44
  484. package/dist/src/render-drivers/threadx/TextNodeStruct.js +0 -201
  485. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +0 -1
  486. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +0 -28
  487. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +0 -234
  488. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +0 -1
  489. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +0 -20
  490. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +0 -84
  491. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +0 -1
  492. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +0 -44
  493. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +0 -154
  494. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +0 -1
  495. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  496. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  497. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  498. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  499. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  500. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  501. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +0 -28
  502. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +0 -55
  503. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +0 -1
  504. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  505. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  506. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
  507. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +0 -70
  508. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js +0 -32
  509. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +0 -1
  510. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.d.ts +0 -19
  511. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +0 -177
  512. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +0 -1
  513. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +0 -27
  514. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +0 -108
  515. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +0 -1
  516. package/dist/src/render-drivers/threadx/worker/renderer.d.ts +0 -1
  517. package/dist/src/render-drivers/threadx/worker/renderer.js +0 -145
  518. package/dist/src/render-drivers/threadx/worker/renderer.js.map +0 -1
  519. package/dist/src/render-drivers/utils.d.ts +0 -12
  520. package/dist/src/render-drivers/utils.js +0 -69
  521. package/dist/src/render-drivers/utils.js.map +0 -1
  522. package/scripts/please-use-pnpm.js +0 -13
  523. package/src/core/platform.ts +0 -64
  524. package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +0 -220
  525. package/src/core/text-rendering/TextRenderingUtils.ts +0 -36
  526. package/src/core/text-rendering/TextTextureRendererUtils.ts +0 -263
  527. package/src/core/text-rendering/TrFontManager.ts +0 -183
  528. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +0 -176
  529. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/FontShaper.ts +0 -139
  530. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +0 -173
  531. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +0 -171
  532. package/src/core/text-rendering/font-face-types/TrFontFace.ts +0 -187
  533. package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +0 -94
  534. package/src/core/text-rendering/font-face-types/utils.ts +0 -39
  535. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +0 -509
  536. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +0 -815
  537. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +0 -840
  538. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.test.ts +0 -48
  539. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.ts +0 -66
  540. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/SpecialCodepoints.ts +0 -52
  541. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/constants.ts +0 -32
  542. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +0 -117
  543. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.test.ts +0 -133
  544. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.ts +0 -38
  545. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +0 -408
  546. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +0 -49
  547. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.ts +0 -52
  548. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +0 -205
  549. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.ts +0 -93
  550. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +0 -40
  551. package/src/core/text-rendering/renderers/TextRenderer.ts +0 -550
@@ -20,7 +20,6 @@
20
20
  import {
21
21
  assertTruthy,
22
22
  getNewId,
23
- isProductionEnvironment,
24
23
  mergeColorAlphaPremultiplied,
25
24
  } from '../utils.js';
26
25
  import type { TextureOptions } from './CoreTextureManager.js';
@@ -28,6 +27,7 @@ import type { CoreRenderer } from './renderers/CoreRenderer.js';
28
27
  import type { Stage } from './Stage.js';
29
28
  import {
30
29
  type Texture,
30
+ type TextureCoords,
31
31
  type TextureFailedEventHandler,
32
32
  type TextureFreedEventHandler,
33
33
  type TextureLoadedEventHandler,
@@ -37,6 +37,7 @@ import type {
37
37
  NodeTextureFailedPayload,
38
38
  NodeTextureFreedPayload,
39
39
  NodeTextureLoadedPayload,
40
+ NodeRenderablePayload,
40
41
  } from '../common/CommonTypes.js';
41
42
  import { EventEmitter } from '../common/EventEmitter.js';
42
43
  import {
@@ -56,6 +57,11 @@ import type { IAnimationController } from '../common/IAnimationController.js';
56
57
  import { CoreAnimation } from './animations/CoreAnimation.js';
57
58
  import { CoreAnimationController } from './animations/CoreAnimationController.js';
58
59
  import type { CoreShaderNode } from './renderers/CoreShaderNode.js';
60
+ import {
61
+ bucketSortByZIndex,
62
+ incrementalRepositionByZIndex,
63
+ removeChild,
64
+ } from './lib/collectionUtils.js';
59
65
 
60
66
  export enum CoreNodeRenderState {
61
67
  Init = 0,
@@ -64,6 +70,14 @@ export enum CoreNodeRenderState {
64
70
  InViewport = 8,
65
71
  }
66
72
 
73
+ const NO_CLIPPING_RECT: RectWithValid = {
74
+ x: 0,
75
+ y: 0,
76
+ width: 0,
77
+ height: 0,
78
+ valid: false,
79
+ };
80
+
67
81
  const CoreNodeRenderStateMap: Map<CoreNodeRenderState, string> = new Map();
68
82
  CoreNodeRenderStateMap.set(CoreNodeRenderState.Init, 'init');
69
83
  CoreNodeRenderStateMap.set(CoreNodeRenderState.OutOfBounds, 'outOfBounds');
@@ -77,33 +91,24 @@ export enum UpdateType {
77
91
  Children = 1,
78
92
 
79
93
  /**
80
- * Scale/Rotate transform update
81
- *
82
- * @remarks
83
- * CoreNode Properties Updated:
84
- * - `scaleRotateTransform`
85
- */
86
- ScaleRotate = 2,
87
-
88
- /**
89
- * Translate transform update (x/y/width/height/pivot/mount)
94
+ * localTransform
90
95
  *
91
96
  * @remarks
92
97
  * CoreNode Properties Updated:
93
98
  * - `localTransform`
94
99
  */
95
- Local = 4,
100
+ Local = 2,
96
101
 
97
102
  /**
98
- * Global Transform update
103
+ * globalTransform
99
104
  *
100
- * @remarks
105
+ * * @remarks
101
106
  * CoreNode Properties Updated:
102
107
  * - `globalTransform`
108
+ * - `renderBounds`
103
109
  * - `renderCoords`
104
- * - `renderBound`
105
110
  */
106
- Global = 8,
111
+ Global = 4,
107
112
 
108
113
  /**
109
114
  * Clipping rect update
@@ -112,25 +117,16 @@ export enum UpdateType {
112
117
  * CoreNode Properties Updated:
113
118
  * - `clippingRect`
114
119
  */
115
- Clipping = 16,
120
+ Clipping = 8,
116
121
 
117
122
  /**
118
- * Calculated ZIndex update
119
- *
120
- * @remarks
121
- * CoreNode Properties Updated:
122
- * - `calcZIndex`
123
- */
124
- CalculatedZIndex = 32,
125
-
126
- /**
127
- * Z-Index Sorted Children update
123
+ * Sort Z-Index Children update
128
124
  *
129
125
  * @remarks
130
126
  * CoreNode Properties Updated:
131
127
  * - `children` (sorts children by their `calcZIndex`)
132
128
  */
133
- ZIndexSortedChildren = 64,
129
+ SortZIndexChildren = 16,
134
130
 
135
131
  /**
136
132
  * Premultiplied Colors update
@@ -142,7 +138,7 @@ export enum UpdateType {
142
138
  * - `premultipliedColorBl`
143
139
  * - `premultipliedColorBr`
144
140
  */
145
- PremultipliedColors = 128,
141
+ PremultipliedColors = 32,
146
142
 
147
143
  /**
148
144
  * World Alpha update
@@ -151,7 +147,7 @@ export enum UpdateType {
151
147
  * CoreNode Properties Updated:
152
148
  * - `worldAlpha` = `parent.worldAlpha` * `alpha`
153
149
  */
154
- WorldAlpha = 256,
150
+ WorldAlpha = 64,
155
151
 
156
152
  /**
157
153
  * Render State update
@@ -160,7 +156,7 @@ export enum UpdateType {
160
156
  * CoreNode Properties Updated:
161
157
  * - `renderState`
162
158
  */
163
- RenderState = 512,
159
+ RenderState = 128,
164
160
 
165
161
  /**
166
162
  * Is Renderable update
@@ -169,37 +165,37 @@ export enum UpdateType {
169
165
  * CoreNode Properties Updated:
170
166
  * - `isRenderable`
171
167
  */
172
- IsRenderable = 1024,
168
+ IsRenderable = 256,
173
169
 
174
170
  /**
175
171
  * Render Texture update
176
172
  */
177
- RenderTexture = 2048,
173
+ RenderTexture = 512,
178
174
 
179
175
  /**
180
176
  * Track if parent has render texture
181
177
  */
182
- ParentRenderTexture = 4096,
178
+ ParentRenderTexture = 1024,
183
179
 
184
180
  /**
185
181
  * Render Bounds update
186
182
  */
187
- RenderBounds = 8192,
183
+ RenderBounds = 2048,
188
184
 
189
185
  /**
190
- * None
186
+ * RecalcUniforms
191
187
  */
192
- None = 0,
188
+ RecalcUniforms = 4096,
193
189
 
194
190
  /**
195
- * All
191
+ * None
196
192
  */
197
- All = 14335,
193
+ None = 0,
198
194
 
199
195
  /**
200
- * RecalcUniforms
196
+ * All
201
197
  */
202
- RecalcUniforms = 16384,
198
+ All = 7167,
203
199
  }
204
200
 
205
201
  /**
@@ -240,16 +236,18 @@ export interface CoreNodeProps {
240
236
  y: number;
241
237
  /**
242
238
  * The width of the Node.
239
+ * @warning This will be deprecated in favor of `w` and `h` properties in the future.
243
240
  *
244
241
  * @default `0`
245
242
  */
246
- width: number;
243
+ w: number;
247
244
  /**
248
245
  * The height of the Node.
246
+ * @warning This will be deprecated in favor of `w` and `h` properties in the future.
249
247
  *
250
248
  * @default `0`
251
249
  */
252
- height: number;
250
+ h: number;
253
251
  /**
254
252
  * The alpha opacity of the Node.
255
253
  *
@@ -396,7 +394,11 @@ export interface CoreNodeProps {
396
394
  * The Node's z-index.
397
395
  *
398
396
  * @remarks
399
- * TBD
397
+ * Max z-index of children under the same parent determines which child
398
+ * is rendered on top. Higher z-index means the Node is rendered on top of
399
+ * children with lower z-index.
400
+ *
401
+ * Max value is 1000 and min value is -1000. Values outside of this range will be clamped.
400
402
  */
401
403
  zIndex: number;
402
404
  /**
@@ -424,15 +426,6 @@ export interface CoreNodeProps {
424
426
  */
425
427
  texture: Texture | null;
426
428
 
427
- /**
428
- * [Deprecated]: Prevents the texture from being cleaned up when the Node is removed
429
- *
430
- * @remarks
431
- * Please use the `preventCleanup` property on {@link TextureOptions} instead.
432
- *
433
- * @default false
434
- */
435
- preventCleanup: boolean;
436
429
  /**
437
430
  * Options to associate with the Node's Texture
438
431
  */
@@ -462,7 +455,6 @@ export interface CoreNodeProps {
462
455
  * settings being defaults)
463
456
  */
464
457
  src: string | null;
465
- zIndexLocked: number;
466
458
  /**
467
459
  * Scale to render the Node at
468
460
  *
@@ -683,20 +675,11 @@ export interface CoreNodeProps {
683
675
  */
684
676
  srcY?: number;
685
677
  /**
686
- * By enabling Strict bounds the renderer will not process & render child nodes of a node that is out of the visible area
687
- *
688
- * @remarks
689
- * When enabled out of bound nodes, i.e. nodes that are out of the visible area, will
690
- * **NOT** have their children processed and renderer anymore. This means the children of a out of bound
691
- * node will not receive update processing such as positioning updates and will not be drawn on screen.
692
- * As such the rest of the branch of the update tree that sits below this node will not be processed anymore
693
- *
694
- * This is a big performance gain but may be disabled in cases where the width of the parent node is
695
- * unknown and the render must process the child nodes regardless of the viewport status of the parent node
696
- *
678
+ * Mark the node as interactive so we can perform hit tests on it
679
+ * when pointer events are registered.
697
680
  * @default false
698
681
  */
699
- strictBounds: boolean;
682
+ interactive?: boolean;
700
683
  }
701
684
 
702
685
  /**
@@ -731,11 +714,18 @@ export class CoreNode extends EventEmitter {
731
714
  readonly props: CoreNodeProps;
732
715
 
733
716
  private hasShaderUpdater = false;
717
+ public hasShaderTimeFn = false;
718
+ private hasColorProps = false;
719
+ private zIndexMin = 0;
720
+ private zIndexMax = 0;
721
+
722
+ public previousZIndex = -1;
723
+ public zIndexSortList: CoreNode[] = [];
724
+
734
725
  public updateType = UpdateType.All;
735
726
  public childUpdateType = UpdateType.None;
736
727
 
737
728
  public globalTransform?: Matrix3d;
738
- public scaleRotateTransform?: Matrix3d;
739
729
  public localTransform?: Matrix3d;
740
730
  public sceneGlobalTransform?: Matrix3d;
741
731
  public renderCoords?: RenderCoords;
@@ -750,6 +740,8 @@ export class CoreNode extends EventEmitter {
750
740
  height: 0,
751
741
  valid: false,
752
742
  };
743
+ public textureCoords?: TextureCoords;
744
+ public updateShaderUniforms: boolean = false;
753
745
  public isRenderable = false;
754
746
  public renderState: CoreNodeRenderState = CoreNodeRenderState.Init;
755
747
 
@@ -762,122 +754,176 @@ export class CoreNode extends EventEmitter {
762
754
  public hasRTTupdates = false;
763
755
  public parentHasRenderTexture = false;
764
756
  public rttParent: CoreNode | null = null;
757
+ /**
758
+ * only used when rtt = true
759
+ */
760
+ public framebufferDimensions: Dimensions | null = null;
761
+
762
+ public destroyed = false;
765
763
 
766
764
  constructor(readonly stage: Stage, props: CoreNodeProps) {
767
765
  super();
766
+ const p = (this.props = {} as CoreNodeProps);
767
+ //inital update type
768
+ let initialUpdateType =
769
+ UpdateType.Local | UpdateType.RenderBounds | UpdateType.RenderState;
770
+
771
+ // Fast-path assign only known keys
772
+ p.x = props.x;
773
+ p.y = props.y;
774
+ p.w = props.w;
775
+ p.h = props.h;
776
+ p.alpha = props.alpha;
777
+ p.autosize = props.autosize;
778
+ p.clipping = props.clipping;
779
+
780
+ p.color = props.color;
781
+ p.colorTop = props.colorTop;
782
+ p.colorBottom = props.colorBottom;
783
+ p.colorLeft = props.colorLeft;
784
+ p.colorRight = props.colorRight;
785
+ p.colorTl = props.colorTl;
786
+ p.colorTr = props.colorTr;
787
+ p.colorBl = props.colorBl;
788
+ p.colorBr = props.colorBr;
789
+
790
+ //check if any color props are set for premultiplied color updates
791
+ if (
792
+ props.color > 0 ||
793
+ props.colorTop > 0 ||
794
+ props.colorBottom > 0 ||
795
+ props.colorLeft > 0 ||
796
+ props.colorRight > 0 ||
797
+ props.colorTl > 0 ||
798
+ props.colorTr > 0 ||
799
+ props.colorBl > 0 ||
800
+ props.colorBr > 0
801
+ ) {
802
+ this.hasColorProps = true;
803
+ initialUpdateType |= UpdateType.PremultipliedColors;
804
+ }
768
805
 
769
- this.props = {
770
- ...props,
771
- parent: null,
772
- texture: null,
773
- shader: null,
774
- src: null,
775
- rtt: false,
776
- };
806
+ p.scaleX = props.scaleX;
807
+ p.scaleY = props.scaleY;
808
+ p.rotation = props.rotation;
809
+ p.pivotX = props.pivotX;
810
+ p.pivotY = props.pivotY;
811
+ p.mountX = props.mountX;
812
+ p.mountY = props.mountY;
813
+ p.mount = props.mount;
814
+ p.pivot = props.pivot;
815
+
816
+ p.zIndex = props.zIndex;
817
+ p.textureOptions = props.textureOptions;
818
+
819
+ p.data = props.data;
820
+ p.imageType = props.imageType;
821
+ p.srcX = props.srcX;
822
+ p.srcY = props.srcY;
823
+ p.srcWidth = props.srcWidth;
824
+ p.srcHeight = props.srcHeight;
825
+
826
+ p.parent = props.parent;
827
+ p.texture = null;
828
+ p.shader = null;
829
+ p.src = null;
830
+ p.rtt = false;
831
+ p.boundsMargin = null;
832
+
833
+ // Only set non-default values
834
+ if (props.zIndex !== 0) {
835
+ this.zIndex = props.zIndex;
836
+ }
837
+
838
+ if (props.parent !== null) {
839
+ props.parent.addChild(this);
840
+ }
777
841
 
778
842
  // Assign props to instances
779
- this.parent = props.parent;
780
843
  this.texture = props.texture;
781
844
  this.shader = props.shader;
782
845
  this.src = props.src;
783
846
  this.rtt = props.rtt;
847
+ this.boundsMargin = props.boundsMargin;
848
+ this.interactive = props.interactive;
784
849
 
785
- if (props.boundsMargin) {
786
- this.boundsMargin = Array.isArray(props.boundsMargin)
787
- ? props.boundsMargin
788
- : [
789
- props.boundsMargin,
790
- props.boundsMargin,
791
- props.boundsMargin,
792
- props.boundsMargin,
793
- ];
794
- }
795
-
796
- this.setUpdateType(
797
- UpdateType.ScaleRotate |
798
- UpdateType.Local |
799
- UpdateType.RenderBounds |
800
- UpdateType.RenderState,
801
- );
802
-
803
- if (isProductionEnvironment() === false && props.preventCleanup === true) {
804
- console.warn(
805
- 'CoreNode.preventCleanup: Is deprecated and will be removed in upcoming release, please use textureOptions.preventCleanup instead',
806
- );
807
- }
850
+ this.setUpdateType(initialUpdateType);
808
851
 
809
852
  // if the default texture isn't loaded yet, wait for it to load
810
853
  // this only happens when the node is created before the stage is ready
811
- if (
812
- this.stage.defaultTexture &&
813
- this.stage.defaultTexture.state !== 'loaded'
814
- ) {
815
- this.stage.defaultTexture.once('loaded', () => {
816
- this.setUpdateType(UpdateType.IsRenderable);
817
- });
854
+ const dt = this.stage.defaultTexture;
855
+ if (dt !== null && dt.state !== 'loaded') {
856
+ dt.once('loaded', () => this.setUpdateType(UpdateType.IsRenderable));
818
857
  }
819
858
  }
820
859
 
821
860
  //#region Textures
822
861
  loadTexture(): void {
823
- const { texture } = this.props;
824
- assertTruthy(texture);
862
+ if (this.props.texture === null) {
863
+ return;
864
+ }
825
865
 
826
866
  // If texture is already loaded / failed, trigger loaded event manually
827
867
  // so that users get a consistent event experience.
828
868
  // We do this in a microtask to allow listeners to be attached in the same
829
869
  // synchronous task after calling loadTexture()
830
- queueMicrotask(() => {
831
- if (this.textureOptions.preload === true) {
832
- this.stage.txManager.loadTexture(texture);
833
- }
870
+ queueMicrotask(this.loadTextureTask);
871
+ }
834
872
 
835
- texture.preventCleanup =
836
- this.props.textureOptions?.preventCleanup ?? false;
837
- texture.on('loaded', this.onTextureLoaded);
838
- texture.on('failed', this.onTextureFailed);
839
- texture.on('freed', this.onTextureFreed);
840
-
841
- // If the parent is a render texture, the initial texture status
842
- // will be set to freed until the texture is processed by the
843
- // Render RTT nodes. So we only need to listen fo changes and
844
- // no need to check the texture.state until we restructure how
845
- // textures are being processed.
846
- if (this.parentHasRenderTexture) {
847
- this.notifyParentRTTOfUpdate();
848
- return;
849
- }
873
+ /**
874
+ * Task for queueMicrotask to loadTexture
875
+ *
876
+ * @remarks
877
+ * This method is called in a microtask to release the texture.
878
+ */
879
+ private loadTextureTask = (): void => {
880
+ const texture = this.texture as Texture;
881
+ if (this.textureOptions.preload === true) {
882
+ this.stage.txManager.loadTexture(texture);
883
+ }
850
884
 
851
- if (texture.state === 'loaded') {
852
- assertTruthy(texture.dimensions);
853
- this.onTextureLoaded(texture, texture.dimensions);
854
- } else if (texture.state === 'failed') {
855
- assertTruthy(texture.error);
856
- this.onTextureFailed(texture, texture.error);
857
- } else if (texture.state === 'freed') {
858
- this.onTextureFreed(texture);
859
- }
860
- });
861
- }
885
+ texture.preventCleanup = this.props.textureOptions?.preventCleanup ?? false;
886
+ texture.on('loaded', this.onTextureLoaded);
887
+ texture.on('failed', this.onTextureFailed);
888
+ texture.on('freed', this.onTextureFreed);
889
+
890
+ // If the parent is a render texture, the initial texture status
891
+ // will be set to freed until the texture is processed by the
892
+ // Render RTT nodes. So we only need to listen fo changes and
893
+ // no need to check the texture.state until we restructure how
894
+ // textures are being processed.
895
+ if (this.parentHasRenderTexture) {
896
+ this.notifyParentRTTOfUpdate();
897
+ return;
898
+ }
899
+
900
+ if (texture.state === 'loaded') {
901
+ this.onTextureLoaded(texture, texture.dimensions!);
902
+ } else if (texture.state === 'failed') {
903
+ this.onTextureFailed(texture, texture.error!);
904
+ } else if (texture.state === 'freed') {
905
+ this.onTextureFreed(texture);
906
+ }
907
+ };
862
908
 
863
909
  unloadTexture(): void {
864
- if (this.texture !== null) {
865
- this.texture.off('loaded', this.onTextureLoaded);
866
- this.texture.off('failed', this.onTextureFailed);
867
- this.texture.off('freed', this.onTextureFreed);
868
- this.texture.setRenderableOwner(this, false);
910
+ if (this.texture === null) {
911
+ return;
869
912
  }
913
+
914
+ const texture = this.texture;
915
+ texture.off('loaded', this.onTextureLoaded);
916
+ texture.off('failed', this.onTextureFailed);
917
+ texture.off('freed', this.onTextureFreed);
918
+ texture.setRenderableOwner(this._id, false);
870
919
  }
871
920
 
872
- autosizeNode(dimensions: Dimensions) {
873
- if (this.autosize) {
874
- this.width = dimensions.width;
875
- this.height = dimensions.height;
921
+ protected onTextureLoaded: TextureLoadedEventHandler = (_, dimensions) => {
922
+ if (this.autosize === true) {
923
+ this.w = dimensions.w;
924
+ this.h = dimensions.h;
876
925
  }
877
- }
878
926
 
879
- private onTextureLoaded: TextureLoadedEventHandler = (_, dimensions) => {
880
- this.autosizeNode(dimensions);
881
927
  this.setUpdateType(UpdateType.IsRenderable);
882
928
 
883
929
  // Texture was loaded. In case the RAF loop has already stopped, we request
@@ -890,13 +936,20 @@ export class CoreNode extends EventEmitter {
890
936
  }
891
937
 
892
938
  // ignore 1x1 pixel textures
893
- if (dimensions.width > 1 && dimensions.height > 1) {
939
+ if (dimensions.w > 1 && dimensions.h > 1) {
894
940
  this.emit('loaded', {
895
941
  type: 'texture',
896
942
  dimensions,
897
943
  } satisfies NodeTextureLoadedPayload);
898
944
  }
899
945
 
946
+ if (
947
+ this.stage.calculateTextureCoord === true &&
948
+ this.props.textureOptions !== null
949
+ ) {
950
+ this.textureCoords = this.stage.renderer.getTextureCoords!(this);
951
+ }
952
+
900
953
  // Trigger a local update if the texture is loaded and the resizeMode is 'contain'
901
954
  if (this.props.textureOptions?.resizeMode?.type === 'contain') {
902
955
  this.setUpdateType(UpdateType.Local);
@@ -904,6 +957,10 @@ export class CoreNode extends EventEmitter {
904
957
  };
905
958
 
906
959
  private onTextureFailed: TextureFailedEventHandler = (_, error) => {
960
+ // immediately set isRenderable to false, so that we handle the error
961
+ // without waiting for the next frame loop
962
+ this.isRenderable = false;
963
+ this.updateTextureOwnership(false);
907
964
  this.setUpdateType(UpdateType.IsRenderable);
908
965
 
909
966
  // If parent has a render texture, flag that we need to update
@@ -911,13 +968,22 @@ export class CoreNode extends EventEmitter {
911
968
  this.notifyParentRTTOfUpdate();
912
969
  }
913
970
 
914
- this.emit('failed', {
915
- type: 'texture',
916
- error,
917
- } satisfies NodeTextureFailedPayload);
971
+ if (
972
+ this.texture !== null &&
973
+ this.texture.retryCount > this.texture.maxRetryCount
974
+ ) {
975
+ this.emit('failed', {
976
+ type: 'texture',
977
+ error,
978
+ } satisfies NodeTextureFailedPayload);
979
+ }
918
980
  };
919
981
 
920
982
  private onTextureFreed: TextureFreedEventHandler = () => {
983
+ // immediately set isRenderable to false, so that we handle the error
984
+ // without waiting for the next frame loop
985
+ this.isRenderable = false;
986
+ this.updateTextureOwnership(false);
921
987
  this.setUpdateType(UpdateType.IsRenderable);
922
988
 
923
989
  // If parent has a render texture, flag that we need to update
@@ -945,46 +1011,26 @@ export class CoreNode extends EventEmitter {
945
1011
  const parent = this.props.parent;
946
1012
  if (!parent) return;
947
1013
 
948
- if ((parent.updateType & UpdateType.Children) === 0) {
949
- // Inform the parent if it doesn’t already have a child update
950
- parent.setUpdateType(UpdateType.Children);
951
- }
952
- }
953
-
954
- sortChildren() {
955
- this.children.sort((a, b) => a.calcZIndex - b.calcZIndex);
956
- }
957
-
958
- updateScaleRotateTransform() {
959
- const { rotation, scaleX, scaleY } = this.props;
960
-
961
- // optimize simple translation cases
962
- if (rotation === 0 && scaleX === 1 && scaleY === 1) {
963
- this.scaleRotateTransform = undefined;
964
- return;
965
- }
966
-
967
- this.scaleRotateTransform = Matrix3d.rotate(
968
- rotation,
969
- this.scaleRotateTransform,
970
- ).scale(scaleX, scaleY);
1014
+ parent.setUpdateType(UpdateType.Children);
971
1015
  }
972
1016
 
973
1017
  updateLocalTransform() {
974
- const { x, y, width, height } = this.props;
975
- const mountTranslateX = this.props.mountX * width;
976
- const mountTranslateY = this.props.mountY * height;
1018
+ const p = this.props;
1019
+ const { x, y, w, h } = p;
1020
+ const mountTranslateX = p.mountX * w;
1021
+ const mountTranslateY = p.mountY * h;
977
1022
 
978
- if (this.scaleRotateTransform) {
979
- const pivotTranslateX = this.props.pivotX * width;
980
- const pivotTranslateY = this.props.pivotY * height;
1023
+ if (p.rotation !== 0 || p.scaleX !== 1 || p.scaleY !== 1) {
1024
+ const scaleRotate = Matrix3d.rotate(p.rotation).scale(p.scaleX, p.scaleY);
1025
+ const pivotTranslateX = p.pivotX * w;
1026
+ const pivotTranslateY = p.pivotY * h;
981
1027
 
982
1028
  this.localTransform = Matrix3d.translate(
983
1029
  x - mountTranslateX + pivotTranslateX,
984
1030
  y - mountTranslateY + pivotTranslateY,
985
1031
  this.localTransform,
986
1032
  )
987
- .multiply(this.scaleRotateTransform)
1033
+ .multiply(scaleRotate)
988
1034
  .translate(-pivotTranslateX, -pivotTranslateY);
989
1035
  } else {
990
1036
  this.localTransform = Matrix3d.translate(
@@ -995,35 +1041,35 @@ export class CoreNode extends EventEmitter {
995
1041
  }
996
1042
 
997
1043
  // Handle 'contain' resize mode
998
- const texture = this.props.texture;
1044
+ const texture = p.texture;
999
1045
  if (
1000
1046
  texture &&
1001
1047
  texture.dimensions &&
1002
- this.props.textureOptions?.resizeMode?.type === 'contain'
1048
+ p.textureOptions.resizeMode?.type === 'contain'
1003
1049
  ) {
1004
1050
  let resizeModeScaleX = 1;
1005
1051
  let resizeModeScaleY = 1;
1006
1052
  let extraX = 0;
1007
1053
  let extraY = 0;
1008
- const { width: tw, height: th } = texture.dimensions;
1054
+ const { w: tw, h: th } = texture.dimensions;
1009
1055
  const txAspectRatio = tw / th;
1010
- const nodeAspectRatio = width / height;
1056
+ const nodeAspectRatio = w / h;
1011
1057
  if (txAspectRatio > nodeAspectRatio) {
1012
1058
  // Texture is wider than node
1013
1059
  // Center the node vertically (shift down by extraY)
1014
1060
  // Scale the node vertically to maintain original aspect ratio
1015
- const scaleX = width / tw;
1061
+ const scaleX = w / tw;
1016
1062
  const scaledTxHeight = th * scaleX;
1017
- extraY = (height - scaledTxHeight) / 2;
1018
- resizeModeScaleY = scaledTxHeight / height;
1063
+ extraY = (h - scaledTxHeight) / 2;
1064
+ resizeModeScaleY = scaledTxHeight / h;
1019
1065
  } else {
1020
1066
  // Texture is taller than node (or equal)
1021
1067
  // Center the node horizontally (shift right by extraX)
1022
1068
  // Scale the node horizontally to maintain original aspect ratio
1023
- const scaleY = height / th;
1069
+ const scaleY = h / th;
1024
1070
  const scaledTxWidth = tw * scaleY;
1025
- extraX = (width - scaledTxWidth) / 2;
1026
- resizeModeScaleX = scaledTxWidth / width;
1071
+ extraX = (w - scaledTxWidth) / 2;
1072
+ resizeModeScaleX = scaledTxWidth / w;
1027
1073
  }
1028
1074
 
1029
1075
  // Apply the extra translation and scale to the local transform
@@ -1031,8 +1077,6 @@ export class CoreNode extends EventEmitter {
1031
1077
  .translate(extraX, extraY)
1032
1078
  .scale(resizeModeScaleX, resizeModeScaleY);
1033
1079
  }
1034
-
1035
- this.setUpdateType(UpdateType.Global);
1036
1080
  }
1037
1081
 
1038
1082
  /**
@@ -1040,27 +1084,33 @@ export class CoreNode extends EventEmitter {
1040
1084
  * @param delta
1041
1085
  */
1042
1086
  update(delta: number, parentClippingRect: RectWithValid): void {
1043
- if (this.updateType & UpdateType.ScaleRotate) {
1044
- this.updateScaleRotateTransform();
1045
- this.setUpdateType(UpdateType.Local);
1046
- }
1087
+ const props = this.props;
1088
+ const parent = props.parent;
1089
+ const parentHasRenderTexture = this.parentHasRenderTexture;
1090
+ const hasParent = props.parent !== null;
1091
+
1092
+ let newRenderState: CoreNodeRenderState | null = null;
1093
+
1094
+ let updateType = this.updateType;
1095
+ let childUpdateType = this.childUpdateType;
1096
+ let updateParent = false;
1097
+ // reset update type
1098
+ this.updateType = 0;
1099
+ this.childUpdateType = 0;
1047
1100
 
1048
- if (this.updateType & UpdateType.Local) {
1101
+ if (updateType & UpdateType.Local) {
1049
1102
  this.updateLocalTransform();
1050
- this.setUpdateType(UpdateType.Global);
1051
- }
1052
1103
 
1053
- const parent = this.props.parent;
1054
- let renderState: CoreNodeRenderState | null = null;
1104
+ updateType |= UpdateType.Global;
1105
+ updateParent = hasParent;
1106
+ }
1055
1107
 
1056
1108
  // Handle specific RTT updates at this node level
1057
- if (this.updateType & UpdateType.RenderTexture && this.rtt) {
1109
+ if (updateType & UpdateType.RenderTexture && this.rtt === true) {
1058
1110
  this.hasRTTupdates = true;
1059
1111
  }
1060
1112
 
1061
- if (this.updateType & UpdateType.Global) {
1062
- assertTruthy(this.localTransform);
1063
-
1113
+ if (updateType & UpdateType.Global) {
1064
1114
  if (this.parentHasRenderTexture === true && parent?.rtt === true) {
1065
1115
  // we are at the start of the RTT chain, so we need to reset the globalTransform
1066
1116
  // for correct RTT rendering
@@ -1069,7 +1119,7 @@ export class CoreNode extends EventEmitter {
1069
1119
  // Maintain a full scene global transform for bounds detection
1070
1120
  this.sceneGlobalTransform = Matrix3d.copy(
1071
1121
  parent?.globalTransform || Matrix3d.identity(),
1072
- ).multiply(this.localTransform);
1122
+ ).multiply(this.localTransform!);
1073
1123
  } else if (
1074
1124
  this.parentHasRenderTexture === true &&
1075
1125
  parent?.rtt === false
@@ -1078,179 +1128,178 @@ export class CoreNode extends EventEmitter {
1078
1128
  // so we need to propogate the sceneGlobalTransform of the parent
1079
1129
  // to maintain a full scene global transform for bounds detection
1080
1130
  this.sceneGlobalTransform = Matrix3d.copy(
1081
- parent?.sceneGlobalTransform || this.localTransform,
1082
- ).multiply(this.localTransform);
1131
+ parent?.sceneGlobalTransform || this.localTransform!,
1132
+ ).multiply(this.localTransform!);
1083
1133
 
1084
1134
  this.globalTransform = Matrix3d.copy(
1085
- parent?.globalTransform || this.localTransform,
1135
+ parent?.globalTransform || this.localTransform!,
1086
1136
  this.globalTransform,
1087
1137
  );
1088
1138
  } else {
1089
1139
  this.globalTransform = Matrix3d.copy(
1090
- parent?.globalTransform || this.localTransform,
1140
+ parent?.globalTransform || this.localTransform!,
1091
1141
  this.globalTransform,
1092
1142
  );
1093
1143
  }
1094
1144
 
1095
1145
  if (parent !== null) {
1096
- this.globalTransform.multiply(this.localTransform);
1146
+ this.globalTransform.multiply(this.localTransform!);
1097
1147
  }
1098
1148
  this.calculateRenderCoords();
1099
1149
  this.updateBoundingRect();
1100
1150
 
1101
- this.setUpdateType(
1151
+ updateType |=
1102
1152
  UpdateType.RenderState |
1103
- UpdateType.Children |
1104
- UpdateType.RecalcUniforms,
1105
- );
1106
- this.childUpdateType |= UpdateType.Global;
1153
+ UpdateType.Children |
1154
+ UpdateType.RecalcUniforms;
1155
+ updateParent = hasParent;
1156
+ childUpdateType |= UpdateType.Global;
1107
1157
 
1108
1158
  if (this.clipping === true) {
1109
- this.setUpdateType(UpdateType.Clipping | UpdateType.RenderBounds);
1110
- this.childUpdateType |= UpdateType.RenderBounds;
1159
+ updateType |= UpdateType.Clipping | UpdateType.RenderBounds;
1160
+ updateParent = hasParent;
1161
+ childUpdateType |= UpdateType.RenderBounds;
1111
1162
  }
1112
1163
  }
1113
1164
 
1114
- if (this.updateType & UpdateType.RenderBounds) {
1165
+ if (updateType & UpdateType.RenderBounds) {
1115
1166
  this.createRenderBounds();
1116
- this.setUpdateType(UpdateType.RenderState);
1117
- this.setUpdateType(UpdateType.Children);
1118
1167
 
1119
- this.childUpdateType |= UpdateType.RenderBounds;
1168
+ updateType |= UpdateType.RenderState | UpdateType.Children;
1169
+ updateParent = hasParent;
1170
+ childUpdateType |= UpdateType.RenderBounds;
1120
1171
  }
1121
1172
 
1122
- if (this.updateType & UpdateType.RenderState) {
1123
- renderState = this.checkRenderBounds();
1124
- this.setUpdateType(UpdateType.IsRenderable);
1173
+ if (updateType & UpdateType.RenderState) {
1174
+ newRenderState = this.checkRenderBounds();
1175
+
1176
+ updateType |= UpdateType.IsRenderable;
1177
+ updateParent = hasParent;
1125
1178
 
1126
1179
  // if we're not going out of bounds, update the render state
1127
1180
  // this is done so the update loop can finish before we mark a node
1128
1181
  // as out of bounds
1129
- if (renderState !== CoreNodeRenderState.OutOfBounds) {
1130
- this.updateRenderState(renderState);
1182
+ if (newRenderState !== CoreNodeRenderState.OutOfBounds) {
1183
+ this.updateRenderState(newRenderState);
1131
1184
  }
1132
1185
  }
1133
1186
 
1134
- if (this.updateType & UpdateType.WorldAlpha) {
1135
- if (parent) {
1136
- this.worldAlpha = parent.worldAlpha * this.props.alpha;
1137
- } else {
1138
- this.worldAlpha = this.props.alpha;
1139
- }
1140
- this.setUpdateType(
1187
+ if (updateType & UpdateType.WorldAlpha) {
1188
+ this.worldAlpha = (parent?.worldAlpha ?? 1) * this.props.alpha;
1189
+ updateType |=
1190
+ UpdateType.PremultipliedColors |
1141
1191
  UpdateType.Children |
1142
- UpdateType.PremultipliedColors |
1143
- UpdateType.IsRenderable,
1144
- );
1145
- this.childUpdateType |= UpdateType.WorldAlpha;
1192
+ UpdateType.IsRenderable;
1193
+ updateParent = hasParent;
1194
+ childUpdateType |= UpdateType.WorldAlpha;
1146
1195
  }
1147
1196
 
1148
- if (this.updateType & UpdateType.IsRenderable) {
1197
+ if (updateType & UpdateType.IsRenderable) {
1149
1198
  this.updateIsRenderable();
1150
1199
  }
1151
1200
 
1152
- if (this.updateType & UpdateType.Clipping) {
1201
+ if (updateType & UpdateType.Clipping) {
1153
1202
  this.calculateClippingRect(parentClippingRect);
1154
- this.setUpdateType(UpdateType.Children);
1203
+ updateType |= UpdateType.Children;
1204
+ updateParent = hasParent;
1155
1205
 
1156
- this.childUpdateType |= UpdateType.Clipping;
1157
- this.childUpdateType |= UpdateType.RenderBounds;
1206
+ childUpdateType |= UpdateType.Clipping | UpdateType.RenderBounds;
1158
1207
  }
1159
1208
 
1160
- if (this.updateType & UpdateType.PremultipliedColors) {
1161
- this.premultipliedColorTl = mergeColorAlphaPremultiplied(
1162
- this.props.colorTl,
1163
- this.worldAlpha,
1164
- true,
1165
- );
1209
+ if (updateType & UpdateType.PremultipliedColors) {
1210
+ const alpha = this.worldAlpha;
1166
1211
 
1167
- // If all the colors are the same just sent them all to the same value
1168
- if (
1169
- this.props.colorTl === this.props.colorTr &&
1170
- this.props.colorBl === this.props.colorBr &&
1171
- this.props.colorTl === this.props.colorBl
1172
- ) {
1212
+ const tl = props.colorTl;
1213
+ const tr = props.colorTr;
1214
+ const bl = props.colorBl;
1215
+ const br = props.colorBr;
1216
+
1217
+ // Fast equality check (covers all 4 corners)
1218
+ const same = tl === tr && tl === bl && tl === br;
1219
+
1220
+ const merged = mergeColorAlphaPremultiplied(tl, alpha, true);
1221
+
1222
+ this.premultipliedColorTl = merged;
1223
+
1224
+ if (same === true) {
1173
1225
  this.premultipliedColorTr =
1174
1226
  this.premultipliedColorBl =
1175
1227
  this.premultipliedColorBr =
1176
- this.premultipliedColorTl;
1228
+ merged;
1177
1229
  } else {
1178
1230
  this.premultipliedColorTr = mergeColorAlphaPremultiplied(
1179
- this.props.colorTr,
1180
- this.worldAlpha,
1231
+ tr,
1232
+ alpha,
1181
1233
  true,
1182
1234
  );
1183
1235
  this.premultipliedColorBl = mergeColorAlphaPremultiplied(
1184
- this.props.colorBl,
1185
- this.worldAlpha,
1236
+ bl,
1237
+ alpha,
1186
1238
  true,
1187
1239
  );
1188
1240
  this.premultipliedColorBr = mergeColorAlphaPremultiplied(
1189
- this.props.colorBr,
1190
- this.worldAlpha,
1241
+ br,
1242
+ alpha,
1191
1243
  true,
1192
1244
  );
1193
1245
  }
1194
1246
  }
1195
1247
 
1196
- // No need to update zIndex if there is no parent
1197
- if (parent !== null && this.updateType & UpdateType.CalculatedZIndex) {
1198
- this.calculateZIndex();
1199
- // Tell parent to re-sort children
1200
- parent.setUpdateType(UpdateType.ZIndexSortedChildren);
1248
+ if (this.renderState === CoreNodeRenderState.OutOfBounds) {
1249
+ // Delay updating children until the node is in bounds
1250
+ this.updateType = updateType;
1251
+ this.childUpdateType = childUpdateType;
1252
+ return;
1201
1253
  }
1202
1254
 
1203
- if (
1204
- this.props.strictBounds === true &&
1205
- this.renderState === CoreNodeRenderState.OutOfBounds
1206
- ) {
1207
- this.updateType &= ~UpdateType.RenderBounds; // remove render bounds update
1208
- return;
1255
+ if (updateParent === true) {
1256
+ parent!.setUpdateType(UpdateType.Children);
1209
1257
  }
1210
1258
 
1211
1259
  if (
1212
- this.updateType & UpdateType.RecalcUniforms &&
1260
+ updateType & UpdateType.RecalcUniforms &&
1213
1261
  this.hasShaderUpdater === true
1214
1262
  ) {
1263
+ this.updateShaderUniforms = true;
1264
+ }
1265
+
1266
+ if (this.isRenderable === true && this.updateShaderUniforms === true) {
1267
+ this.updateShaderUniforms = false;
1215
1268
  //this exists because the boolean hasShaderUpdater === true
1216
1269
  this.shader!.update!();
1217
1270
  }
1218
1271
 
1219
- if (this.updateType & UpdateType.Children && this.children.length > 0) {
1272
+ if (updateType & UpdateType.Children && this.children.length > 0) {
1273
+ let childClippingRect = this.clippingRect;
1274
+
1275
+ if (this.rtt === true) {
1276
+ childClippingRect = NO_CLIPPING_RECT;
1277
+ }
1278
+
1220
1279
  for (let i = 0, length = this.children.length; i < length; i++) {
1221
1280
  const child = this.children[i] as CoreNode;
1222
1281
 
1223
- child.setUpdateType(this.childUpdateType);
1282
+ if (childUpdateType !== 0) {
1283
+ child.setUpdateType(childUpdateType);
1284
+ }
1224
1285
 
1225
1286
  if (child.updateType === 0) {
1226
1287
  continue;
1227
1288
  }
1228
1289
 
1229
- let childClippingRect = this.clippingRect;
1230
- if (this.rtt === true) {
1231
- childClippingRect = {
1232
- x: 0,
1233
- y: 0,
1234
- width: 0,
1235
- height: 0,
1236
- valid: false,
1237
- };
1238
- }
1239
-
1240
1290
  child.update(delta, childClippingRect);
1241
1291
  }
1242
1292
  }
1243
1293
 
1244
1294
  // If the node has an RTT parent and requires a texture re-render, inform the RTT parent
1245
- // if (this.parentHasRenderTexture && this.updateType & UpdateType.RenderTexture) {
1295
+ // if (this.parentHasRenderTexture && updateType & UpdateType.RenderTexture) {
1246
1296
  // @TODO have a more scoped down updateType for RTT updates
1247
- if (this.parentHasRenderTexture && this.updateType > 0) {
1297
+ if (parentHasRenderTexture === true) {
1248
1298
  this.notifyParentRTTOfUpdate();
1249
1299
  }
1250
1300
 
1251
- // Sorting children MUST happen after children have been updated so
1252
- // that they have the oppotunity to update their calculated zIndex.
1253
- if (this.updateType & UpdateType.ZIndexSortedChildren) {
1301
+ //Resort children if needed
1302
+ if (updateType & UpdateType.SortZIndexChildren) {
1254
1303
  // reorder z-index
1255
1304
  this.sortChildren();
1256
1305
  }
@@ -1258,24 +1307,19 @@ export class CoreNode extends EventEmitter {
1258
1307
  // If we're out of bounds, apply the render state now
1259
1308
  // this is done so nodes can finish their entire update loop before
1260
1309
  // being marked as out of bounds
1261
- if (renderState === CoreNodeRenderState.OutOfBounds) {
1262
- this.updateRenderState(renderState);
1310
+ if (newRenderState === CoreNodeRenderState.OutOfBounds) {
1311
+ this.updateRenderState(newRenderState);
1263
1312
  this.updateIsRenderable();
1264
1313
 
1265
1314
  if (
1266
1315
  this.rtt === true &&
1267
- renderState === CoreNodeRenderState.OutOfBounds
1316
+ newRenderState === CoreNodeRenderState.OutOfBounds
1268
1317
  ) {
1269
1318
  // notify children that we are going out of bounds
1270
1319
  // we have to do this now before we stop processing the render tree
1271
- this.notifyChildrenRTTOfUpdate(renderState);
1272
- // this.childUpdateType |= UpdateType.RenderState;
1320
+ this.notifyChildrenRTTOfUpdate(newRenderState);
1273
1321
  }
1274
1322
  }
1275
-
1276
- // reset update type
1277
- this.updateType = 0;
1278
- this.childUpdateType = 0;
1279
1323
  }
1280
1324
 
1281
1325
  private findParentRTTNode(): CoreNode | null {
@@ -1286,15 +1330,6 @@ export class CoreNode extends EventEmitter {
1286
1330
  return rttNode;
1287
1331
  }
1288
1332
 
1289
- private getRTTParentRenderState(): CoreNodeRenderState | null {
1290
- const rttNode = this.rttParent || this.findParentRTTNode();
1291
- if (!rttNode) {
1292
- return null;
1293
- }
1294
-
1295
- return rttNode.renderState;
1296
- }
1297
-
1298
1333
  private notifyChildrenRTTOfUpdate(renderState: CoreNodeRenderState) {
1299
1334
  for (const child of this.children) {
1300
1335
  // force child to update render state
@@ -1304,7 +1339,7 @@ export class CoreNode extends EventEmitter {
1304
1339
  }
1305
1340
  }
1306
1341
 
1307
- private notifyParentRTTOfUpdate() {
1342
+ protected notifyParentRTTOfUpdate() {
1308
1343
  if (this.parent === null) {
1309
1344
  return;
1310
1345
  }
@@ -1325,28 +1360,21 @@ export class CoreNode extends EventEmitter {
1325
1360
  }
1326
1361
 
1327
1362
  checkRenderBounds(): CoreNodeRenderState {
1328
- assertTruthy(this.renderBound);
1329
- assertTruthy(this.strictBound);
1330
- assertTruthy(this.preloadBound);
1331
-
1332
- if (boundInsideBound(this.renderBound, this.strictBound)) {
1363
+ if (boundInsideBound(this.renderBound!, this.strictBound!)) {
1333
1364
  return CoreNodeRenderState.InViewport;
1334
1365
  }
1335
1366
 
1336
- if (boundInsideBound(this.renderBound, this.preloadBound)) {
1367
+ if (boundInsideBound(this.renderBound!, this.preloadBound!)) {
1337
1368
  return CoreNodeRenderState.InBounds;
1338
1369
  }
1339
1370
 
1340
1371
  // check if we're larger then our parent, we're definitely in the viewport
1341
- if (boundLargeThanBound(this.renderBound, this.strictBound)) {
1372
+ if (boundLargeThanBound(this.renderBound!, this.strictBound!)) {
1342
1373
  return CoreNodeRenderState.InViewport;
1343
1374
  }
1344
1375
 
1345
1376
  // check if we dont have dimensions, take our parent's render state
1346
- if (
1347
- this.parent !== null &&
1348
- (this.props.width === 0 || this.props.height === 0)
1349
- ) {
1377
+ if (this.parent !== null && (this.props.w === 0 || this.props.h === 0)) {
1350
1378
  return this.parent.renderState;
1351
1379
  }
1352
1380
 
@@ -1354,11 +1382,10 @@ export class CoreNode extends EventEmitter {
1354
1382
  }
1355
1383
 
1356
1384
  updateBoundingRect() {
1357
- const transform = this.sceneGlobalTransform || this.globalTransform;
1358
- const renderCoords = this.sceneRenderCoords || this.renderCoords;
1359
-
1360
- assertTruthy(transform);
1361
- assertTruthy(renderCoords);
1385
+ const transform = (this.sceneGlobalTransform ||
1386
+ this.globalTransform) as Matrix3d;
1387
+ const renderCoords = (this.sceneRenderCoords ||
1388
+ this.renderCoords) as RenderCoords;
1362
1389
 
1363
1390
  if (transform.tb === 0 || transform.tc === 0) {
1364
1391
  this.renderBound = createBound(
@@ -1381,8 +1408,6 @@ export class CoreNode extends EventEmitter {
1381
1408
  }
1382
1409
 
1383
1410
  createRenderBounds(): void {
1384
- assertTruthy(this.stage);
1385
-
1386
1411
  if (this.parent !== null && this.parent.strictBound !== undefined) {
1387
1412
  // we have a parent with a valid bound, copy it
1388
1413
  const parentBound = this.parent.strictBound;
@@ -1420,20 +1445,14 @@ export class CoreNode extends EventEmitter {
1420
1445
  }
1421
1446
 
1422
1447
  // clipping is enabled and we are in bounds create our own bounds
1423
- const { x, y, width, height } = this.props;
1448
+ const { x, y, w, h } = this.props;
1424
1449
 
1425
1450
  // Pick the global transform if available, otherwise use the local transform
1426
1451
  // global transform is only available if the node in an RTT chain
1427
1452
  const { tx, ty } = this.sceneGlobalTransform || this.globalTransform || {};
1428
1453
  const _x = tx ?? x;
1429
1454
  const _y = ty ?? y;
1430
- this.strictBound = createBound(
1431
- _x,
1432
- _y,
1433
- _x + width,
1434
- _y + height,
1435
- this.strictBound,
1436
- );
1455
+ this.strictBound = createBound(_x, _y, _x + w, _y + h, this.strictBound);
1437
1456
 
1438
1457
  this.preloadBound = createPreloadBounds(
1439
1458
  this.strictBound,
@@ -1456,6 +1475,17 @@ export class CoreNode extends EventEmitter {
1456
1475
  });
1457
1476
  }
1458
1477
 
1478
+ /**
1479
+ * Checks if the node is renderable based on world alpha, dimensions and out of bounds status.
1480
+ */
1481
+ checkBasicRenderability(): boolean {
1482
+ if (this.worldAlpha === 0 || this.isOutOfBounds() === true) {
1483
+ return false;
1484
+ } else {
1485
+ return true;
1486
+ }
1487
+ }
1488
+
1459
1489
  /**
1460
1490
  * Updates the `isRenderable` property based on various conditions.
1461
1491
  */
@@ -1471,12 +1501,22 @@ export class CoreNode extends EventEmitter {
1471
1501
  }
1472
1502
 
1473
1503
  if (this.texture !== null) {
1474
- needsTextureOwnership = true;
1504
+ // preemptive check for failed textures this will mark the current node as non-renderable
1505
+ // and will prevent further checks until the texture is reloaded or retry is reset on the texture
1506
+ if (this.texture.retryCount > this.texture.maxRetryCount) {
1507
+ // texture has failed to load, we cannot render
1508
+ this.updateTextureOwnership(false);
1509
+ this.setRenderable(false);
1510
+ return;
1511
+ }
1475
1512
 
1513
+ needsTextureOwnership = true;
1476
1514
  // we're only renderable if the texture state is loaded
1477
1515
  newIsRenderable = this.texture.state === 'loaded';
1478
1516
  } else if (
1479
- (this.hasShader() || this.hasColorProperties() === true) &&
1517
+ // check shader
1518
+ (this.props.shader !== null || this.hasColorProps === true) &&
1519
+ // check dimensions
1480
1520
  this.hasDimensions() === true
1481
1521
  ) {
1482
1522
  // This mean we have dimensions and a color set, so we can render a ColorTexture
@@ -1492,30 +1532,28 @@ export class CoreNode extends EventEmitter {
1492
1532
  this.setRenderable(newIsRenderable);
1493
1533
  }
1494
1534
 
1495
- /**
1496
- * Checks if the node is renderable based on world alpha, dimensions and out of bounds status.
1497
- */
1498
- checkBasicRenderability(): boolean {
1499
- if (this.worldAlpha === 0 || this.isOutOfBounds() === true) {
1500
- return false;
1501
- } else {
1502
- return true;
1503
- }
1504
- }
1505
-
1506
1535
  /**
1507
1536
  * Sets the renderable state and triggers changes if necessary.
1508
1537
  * @param isRenderable - The new renderable state
1509
1538
  */
1510
1539
  setRenderable(isRenderable: boolean) {
1540
+ const previousIsRenderable = this.isRenderable;
1511
1541
  this.isRenderable = isRenderable;
1542
+
1543
+ // Emit event if renderable status has changed
1544
+ if (previousIsRenderable !== isRenderable) {
1545
+ this.emit('renderable', {
1546
+ type: 'renderable',
1547
+ isRenderable,
1548
+ } satisfies NodeRenderablePayload);
1549
+ }
1512
1550
  }
1513
1551
 
1514
1552
  /**
1515
1553
  * Changes the renderable state of the node.
1516
1554
  */
1517
1555
  updateTextureOwnership(isRenderable: boolean) {
1518
- this.texture?.setRenderableOwner(this, isRenderable);
1556
+ this.texture?.setRenderableOwner(this._id, isRenderable);
1519
1557
  }
1520
1558
 
1521
1559
  /**
@@ -1529,38 +1567,24 @@ export class CoreNode extends EventEmitter {
1529
1567
  * Checks if the node has dimensions (width/height)
1530
1568
  */
1531
1569
  hasDimensions(): boolean {
1532
- return this.props.width !== 0 && this.props.height !== 0;
1533
- }
1534
-
1535
- /**
1536
- * Checks if the node has any color properties set.
1537
- */
1538
- hasColorProperties(): boolean {
1539
- return (
1540
- this.props.color !== 0 ||
1541
- this.props.colorTop !== 0 ||
1542
- this.props.colorBottom !== 0 ||
1543
- this.props.colorLeft !== 0 ||
1544
- this.props.colorRight !== 0 ||
1545
- this.props.colorTl !== 0 ||
1546
- this.props.colorTr !== 0 ||
1547
- this.props.colorBl !== 0 ||
1548
- this.props.colorBr !== 0
1549
- );
1550
- }
1551
-
1552
- hasShader(): boolean {
1553
- return this.props.shader !== null;
1570
+ return this.props.w !== 0 && this.props.h !== 0;
1554
1571
  }
1555
1572
 
1556
1573
  calculateRenderCoords() {
1557
- const { width, height } = this;
1558
- const { tx, ty, ta, tb, tc, td } = this.globalTransform!;
1574
+ const { w, h } = this.props;
1575
+
1576
+ const g = this.globalTransform!;
1577
+ const tx = g.tx,
1578
+ ty = g.ty,
1579
+ ta = g.ta,
1580
+ tb = g.tb,
1581
+ tc = g.tc,
1582
+ td = g.td;
1559
1583
  if (tb === 0 && tc === 0) {
1560
1584
  const minX = tx;
1561
- const maxX = tx + width * ta;
1585
+ const maxX = tx + w * ta;
1562
1586
  const minY = ty;
1563
- const maxY = ty + height * td;
1587
+ const maxY = ty + h * td;
1564
1588
  this.renderCoords = RenderCoords.translate(
1565
1589
  //top-left
1566
1590
  minX,
@@ -1582,14 +1606,14 @@ export class CoreNode extends EventEmitter {
1582
1606
  tx,
1583
1607
  ty,
1584
1608
  //top-right
1585
- tx + width * ta,
1586
- ty + width * tc,
1609
+ tx + w * ta,
1610
+ ty + w * tc,
1587
1611
  //bottom-right
1588
- tx + width * ta + height * tb,
1589
- ty + width * tc + height * td,
1612
+ tx + w * ta + h * tb,
1613
+ ty + w * tc + h * td,
1590
1614
  //bottom-left
1591
- tx + height * tb,
1592
- ty + height * td,
1615
+ tx + h * tb,
1616
+ ty + h * td,
1593
1617
  this.renderCoords,
1594
1618
  );
1595
1619
  }
@@ -1607,9 +1631,9 @@ export class CoreNode extends EventEmitter {
1607
1631
  } = this.sceneGlobalTransform;
1608
1632
  if (stb === 0 && stc === 0) {
1609
1633
  const minX = stx;
1610
- const maxX = stx + width * sta;
1634
+ const maxX = stx + w * sta;
1611
1635
  const minY = sty;
1612
- const maxY = sty + height * std;
1636
+ const maxY = sty + h * std;
1613
1637
  this.sceneRenderCoords = RenderCoords.translate(
1614
1638
  //top-left
1615
1639
  minX,
@@ -1631,14 +1655,14 @@ export class CoreNode extends EventEmitter {
1631
1655
  stx,
1632
1656
  sty,
1633
1657
  //top-right
1634
- stx + width * sta,
1635
- sty + width * stc,
1658
+ stx + w * sta,
1659
+ sty + w * stc,
1636
1660
  //bottom-right
1637
- stx + width * sta + height * stb,
1638
- sty + width * stc + height * std,
1661
+ stx + w * sta + h * stb,
1662
+ sty + w * stc + h * std,
1639
1663
  //bottom-left
1640
- stx + height * stb,
1641
- sty + height * std,
1664
+ stx + h * stb,
1665
+ sty + h * std,
1642
1666
  this.sceneRenderCoords,
1643
1667
  );
1644
1668
  }
@@ -1653,16 +1677,15 @@ export class CoreNode extends EventEmitter {
1653
1677
  * Finally, the node's parentClippingRect and clippingRect properties are updated.
1654
1678
  */
1655
1679
  calculateClippingRect(parentClippingRect: RectWithValid) {
1656
- assertTruthy(this.globalTransform);
1657
1680
  const { clippingRect, props, globalTransform: gt } = this;
1658
1681
  const { clipping } = props;
1659
- const isRotated = gt.tb !== 0 || gt.tc !== 0;
1682
+ const isRotated = gt!.tb !== 0 || gt!.tc !== 0;
1660
1683
 
1661
1684
  if (clipping === true && isRotated === false) {
1662
- clippingRect.x = gt.tx;
1663
- clippingRect.y = gt.ty;
1664
- clippingRect.width = this.width * gt.ta;
1665
- clippingRect.height = this.height * gt.td;
1685
+ clippingRect.x = gt!.tx;
1686
+ clippingRect.y = gt!.ty;
1687
+ clippingRect.width = this.props.w * gt!.ta;
1688
+ clippingRect.height = this.props.h * gt!.td;
1666
1689
  clippingRect.valid = true;
1667
1690
  } else {
1668
1691
  clippingRect.valid = false;
@@ -1678,97 +1701,185 @@ export class CoreNode extends EventEmitter {
1678
1701
  }
1679
1702
  }
1680
1703
 
1681
- calculateZIndex(): void {
1682
- const props = this.props;
1683
- const z = props.zIndex || 0;
1684
- const p = props.parent?.zIndex || 0;
1685
-
1686
- let zIndex = z;
1687
- if (props.parent?.zIndexLocked) {
1688
- zIndex = z < p ? z : p;
1689
- }
1690
- this.calcZIndex = zIndex;
1691
- }
1692
-
1693
1704
  /**
1694
1705
  * Destroy the node and cleanup all resources
1695
1706
  */
1696
1707
  destroy(): void {
1697
- this.unloadTexture();
1698
-
1699
- this.clippingRect.valid = false;
1700
- this.isRenderable = false;
1708
+ if (this.destroyed === true) {
1709
+ return;
1710
+ }
1701
1711
 
1702
- this.renderCoords = undefined;
1703
- this.renderBound = undefined;
1704
- this.strictBound = undefined;
1705
- this.preloadBound = undefined;
1706
- this.globalTransform = undefined;
1707
- this.scaleRotateTransform = undefined;
1708
- this.localTransform = undefined;
1712
+ this.removeAllListeners();
1709
1713
 
1710
- this.props.texture = null;
1711
- this.props.shader = null;
1714
+ this.destroyed = true;
1715
+ this.unloadTexture();
1716
+ this.isRenderable = false;
1717
+ if (this.hasShaderTimeFn === true) {
1718
+ this.stage.untrackTimedNode(this);
1719
+ }
1712
1720
 
1721
+ // Kill children
1713
1722
  while (this.children.length > 0) {
1714
- this.children[0]?.destroy();
1723
+ this.children[0]!.destroy();
1715
1724
  }
1716
1725
 
1717
- // This very action will also remove the node from the parent's children array
1718
- this.parent = null;
1726
+ const parent = this.parent;
1727
+ if (parent !== null) {
1728
+ parent.removeChild(this);
1729
+ }
1719
1730
 
1720
- if (this.rtt) {
1731
+ this.props.parent = null;
1732
+ this.props.texture = null;
1733
+
1734
+ if (this.rtt === true) {
1721
1735
  this.stage.renderer.removeRTTNode(this);
1722
1736
  }
1723
-
1724
- this.removeAllListeners();
1737
+ this.stage.requestRender();
1725
1738
  }
1726
1739
 
1727
1740
  renderQuads(renderer: CoreRenderer): void {
1728
- // Prevent quad rendering if parent has a render texture
1729
- // and renderer is not currently rendering to a texture
1730
- if (this.parentHasRenderTexture) {
1731
- if (!renderer.renderToTextureActive) {
1732
- return;
1733
- }
1734
- // Prevent quad rendering if parent render texture is not the active render texture
1735
- if (this.parentRenderTexture !== renderer.activeRttNode) {
1741
+ if (this.parentHasRenderTexture === true) {
1742
+ const rtt = renderer.renderToTextureActive;
1743
+ if (rtt === false || this.parentRenderTexture !== renderer.activeRttNode)
1736
1744
  return;
1737
- }
1738
1745
  }
1739
1746
 
1740
- assertTruthy(this.globalTransform);
1741
- assertTruthy(this.renderCoords);
1747
+ const p = this.props;
1748
+ const t = this.globalTransform!;
1749
+ const coords = this.renderCoords;
1750
+ const texture = p.texture || this.stage.defaultTexture;
1751
+ const textureCoords =
1752
+ this.textureCoords || this.stage.renderer.defaultTextureCoords;
1753
+
1754
+ // There is a race condition where the texture can be null
1755
+ // with RTT nodes. Adding this defensively to avoid errors.
1756
+ if (texture && texture.state !== 'loaded') {
1757
+ return;
1758
+ }
1742
1759
 
1743
- // add to list of renderables to be sorted before rendering
1744
1760
  renderer.addQuad({
1745
- width: this.props.width,
1746
- height: this.props.height,
1761
+ width: p.w,
1762
+ height: p.h,
1747
1763
  colorTl: this.premultipliedColorTl,
1748
1764
  colorTr: this.premultipliedColorTr,
1749
1765
  colorBl: this.premultipliedColorBl,
1750
1766
  colorBr: this.premultipliedColorBr,
1751
- // if we do not have a texture, use the default texture
1752
- // this assumes any renderable node is either a distinct texture or a ColorTexture
1753
- texture: this.texture || this.stage.defaultTexture,
1754
- textureOptions: this.textureOptions,
1755
- zIndex: this.zIndex,
1756
- shader: this.props.shader as CoreShaderNode<any>,
1767
+ texture,
1768
+ textureOptions: p.textureOptions,
1769
+ textureCoords: textureCoords,
1770
+ shader: p.shader as CoreShaderNode<any>,
1757
1771
  alpha: this.worldAlpha,
1758
1772
  clippingRect: this.clippingRect,
1759
- tx: this.globalTransform.tx,
1760
- ty: this.globalTransform.ty,
1761
- ta: this.globalTransform.ta,
1762
- tb: this.globalTransform.tb,
1763
- tc: this.globalTransform.tc,
1764
- td: this.globalTransform.td,
1765
- renderCoords: this.renderCoords,
1766
- rtt: this.rtt,
1773
+ tx: t.tx,
1774
+ ty: t.ty,
1775
+ ta: t.ta,
1776
+ tb: t.tb,
1777
+ tc: t.tc,
1778
+ td: t.td,
1779
+ renderCoords: coords,
1780
+ rtt: p.rtt,
1781
+ zIndex: this.calcZIndex,
1767
1782
  parentHasRenderTexture: this.parentHasRenderTexture,
1768
- framebufferDimensions: this.framebufferDimensions,
1783
+ framebufferDimensions: this.parentHasRenderTexture
1784
+ ? this.parentFramebufferDimensions
1785
+ : null,
1786
+ time: this.hasShaderTimeFn === true ? this.getTimerValue() : null,
1769
1787
  });
1770
1788
  }
1771
1789
 
1790
+ getTimerValue(): number {
1791
+ if (typeof this.shader!.time === 'function') {
1792
+ return this.shader!.time(this.stage);
1793
+ }
1794
+ return this.stage.elapsedTime;
1795
+ }
1796
+
1797
+ sortChildren() {
1798
+ const changedCount = this.zIndexSortList.length;
1799
+ if (changedCount === 0) {
1800
+ return;
1801
+ }
1802
+ const children = this.children;
1803
+ let min = Infinity;
1804
+ let max = -Infinity;
1805
+ // find min and max zIndex
1806
+ for (let i = 0; i < children.length; i++) {
1807
+ const zIndex = children[i]!.props.zIndex;
1808
+ if (zIndex < min) {
1809
+ min = zIndex;
1810
+ }
1811
+ if (zIndex > max) {
1812
+ max = zIndex;
1813
+ }
1814
+ }
1815
+
1816
+ // update min and max zIndex
1817
+ this.zIndexMin = min;
1818
+ this.zIndexMax = max;
1819
+
1820
+ // if min and max are the same, no need to sort
1821
+ if (min === max) {
1822
+ return;
1823
+ }
1824
+
1825
+ const n = children.length;
1826
+ // decide whether to use incremental sort or bucket sort
1827
+ const useIncremental = changedCount <= 2 || changedCount < n * 0.05;
1828
+
1829
+ // when changed count is less than 2 or 5% of total children, use incremental sort
1830
+ if (useIncremental === true) {
1831
+ incrementalRepositionByZIndex(this.zIndexSortList, children);
1832
+ } else {
1833
+ bucketSortByZIndex(children, min);
1834
+ }
1835
+
1836
+ this.zIndexSortList.length = 0;
1837
+ this.zIndexSortList = [];
1838
+ }
1839
+
1840
+ removeChild(node: CoreNode, targetParent: CoreNode | null = null) {
1841
+ if (
1842
+ targetParent === null &&
1843
+ this.props.rtt === true &&
1844
+ this.parentHasRenderTexture === true
1845
+ ) {
1846
+ node.clearRTTInheritance();
1847
+ }
1848
+ removeChild(node, this.children);
1849
+ }
1850
+
1851
+ addChild(node: CoreNode, previousParent: CoreNode | null = null) {
1852
+ const inRttCluster =
1853
+ this.props.rtt === true || this.parentHasRenderTexture === true;
1854
+ const children = this.children;
1855
+ const min = this.zIndexMin;
1856
+ const max = this.zIndexMax;
1857
+ const zIndex = node.zIndex;
1858
+
1859
+ node.parentHasRenderTexture = inRttCluster;
1860
+ if (previousParent !== null) {
1861
+ const previousParentInRttCluster =
1862
+ previousParent.props.rtt === true ||
1863
+ previousParent.parentHasRenderTexture === true;
1864
+ if (inRttCluster === false && previousParentInRttCluster === true) {
1865
+ // update child RTT status
1866
+ node.clearRTTInheritance();
1867
+ }
1868
+ }
1869
+
1870
+ if (inRttCluster === true) {
1871
+ node.markChildrenWithRTT(this);
1872
+ }
1873
+
1874
+ children.push(node);
1875
+
1876
+ if (min !== max || (zIndex !== min && zIndex !== max)) {
1877
+ this.zIndexSortList.push(node);
1878
+ this.setUpdateType(UpdateType.SortZIndexChildren);
1879
+ }
1880
+ this.setUpdateType(UpdateType.Children);
1881
+ }
1882
+
1772
1883
  //#region Properties
1773
1884
  get id(): number {
1774
1885
  return this._id;
@@ -1796,7 +1907,7 @@ export class CoreNode extends EventEmitter {
1796
1907
  get absX(): number {
1797
1908
  return (
1798
1909
  this.props.x +
1799
- -this.props.width * this.props.mountX +
1910
+ -this.props.w * this.props.mountX +
1800
1911
  (this.props.parent?.absX || this.props.parent?.globalTransform?.tx || 0)
1801
1912
  );
1802
1913
  }
@@ -1804,7 +1915,7 @@ export class CoreNode extends EventEmitter {
1804
1915
  get absY(): number {
1805
1916
  return (
1806
1917
  this.props.y +
1807
- -this.props.height * this.props.mountY +
1918
+ -this.props.h * this.props.mountY +
1808
1919
  (this.props.parent?.absY ?? 0)
1809
1920
  );
1810
1921
  }
@@ -1820,40 +1931,42 @@ export class CoreNode extends EventEmitter {
1820
1931
  }
1821
1932
  }
1822
1933
 
1823
- get width(): number {
1824
- return this.props.width;
1934
+ get w(): number {
1935
+ return this.props.w;
1825
1936
  }
1826
1937
 
1827
- set width(value: number) {
1828
- if (this.props.width !== value) {
1829
- this.props.width = value;
1938
+ set w(value: number) {
1939
+ if (this.props.w !== value) {
1940
+ this.props.w = value;
1830
1941
  this.setUpdateType(UpdateType.Local);
1831
1942
 
1832
- if (this.props.rtt) {
1833
- this.texture = this.stage.txManager.createTexture('RenderTexture', {
1834
- width: this.width,
1835
- height: this.height,
1836
- });
1943
+ if (this.props.rtt === true) {
1944
+ this.framebufferDimensions!.w = value;
1945
+ this.texture = this.stage.txManager.createTexture(
1946
+ 'RenderTexture',
1947
+ this.framebufferDimensions!,
1948
+ );
1837
1949
 
1838
1950
  this.setUpdateType(UpdateType.RenderTexture);
1839
1951
  }
1840
1952
  }
1841
1953
  }
1842
1954
 
1843
- get height(): number {
1844
- return this.props.height;
1955
+ get h(): number {
1956
+ return this.props.h;
1845
1957
  }
1846
1958
 
1847
- set height(value: number) {
1848
- if (this.props.height !== value) {
1849
- this.props.height = value;
1959
+ set h(value: number) {
1960
+ if (this.props.h !== value) {
1961
+ this.props.h = value;
1850
1962
  this.setUpdateType(UpdateType.Local);
1851
1963
 
1852
- if (this.props.rtt) {
1853
- this.texture = this.stage.txManager.createTexture('RenderTexture', {
1854
- width: this.width,
1855
- height: this.height,
1856
- });
1964
+ if (this.props.rtt === true) {
1965
+ this.framebufferDimensions!.h = value;
1966
+ this.texture = this.stage.txManager.createTexture(
1967
+ 'RenderTexture',
1968
+ this.framebufferDimensions!,
1969
+ );
1857
1970
 
1858
1971
  this.setUpdateType(UpdateType.RenderTexture);
1859
1972
  }
@@ -1880,7 +1993,7 @@ export class CoreNode extends EventEmitter {
1880
1993
  set scaleX(value: number) {
1881
1994
  if (this.props.scaleX !== value) {
1882
1995
  this.props.scaleX = value;
1883
- this.setUpdateType(UpdateType.ScaleRotate);
1996
+ this.setUpdateType(UpdateType.Local);
1884
1997
  }
1885
1998
  }
1886
1999
 
@@ -1891,7 +2004,7 @@ export class CoreNode extends EventEmitter {
1891
2004
  set scaleY(value: number) {
1892
2005
  if (this.props.scaleY !== value) {
1893
2006
  this.props.scaleY = value;
1894
- this.setUpdateType(UpdateType.ScaleRotate);
2007
+ this.setUpdateType(UpdateType.Local);
1895
2008
  }
1896
2009
  }
1897
2010
 
@@ -1972,7 +2085,7 @@ export class CoreNode extends EventEmitter {
1972
2085
  set rotation(value: number) {
1973
2086
  if (this.props.rotation !== value) {
1974
2087
  this.props.rotation = value;
1975
- this.setUpdateType(UpdateType.ScaleRotate);
2088
+ this.setUpdateType(UpdateType.Local);
1976
2089
  }
1977
2090
  }
1978
2091
 
@@ -2000,11 +2113,20 @@ export class CoreNode extends EventEmitter {
2000
2113
  }
2001
2114
 
2002
2115
  get boundsMargin(): number | [number, number, number, number] | null {
2003
- return (
2004
- this.props.boundsMargin ??
2005
- this.parent?.boundsMargin ??
2006
- this.stage.boundsMargin
2007
- );
2116
+ const props = this.props;
2117
+ if (props.boundsMargin !== null) {
2118
+ return props.boundsMargin;
2119
+ }
2120
+
2121
+ const parent = this.parent;
2122
+ if (parent !== null) {
2123
+ const margin = parent.boundsMargin;
2124
+ if (margin !== undefined) {
2125
+ return margin;
2126
+ }
2127
+ }
2128
+
2129
+ return this.stage.boundsMargin;
2008
2130
  }
2009
2131
 
2010
2132
  set boundsMargin(value: number | [number, number, number, number] | null) {
@@ -2041,11 +2163,18 @@ export class CoreNode extends EventEmitter {
2041
2163
  }
2042
2164
 
2043
2165
  set color(value: number) {
2044
- this.colorTop = value;
2045
- this.colorBottom = value;
2046
- this.colorLeft = value;
2047
- this.colorRight = value;
2048
- this.props.color = value;
2166
+ const p = this.props;
2167
+ if (p.color === value) return;
2168
+
2169
+ p.color = value;
2170
+
2171
+ const has = value > 0;
2172
+ this.hasColorProps = has;
2173
+
2174
+ if (p.colorTop !== value) this.colorTop = value;
2175
+ if (p.colorBottom !== value) this.colorBottom = value;
2176
+ if (p.colorLeft !== value) this.colorLeft = value;
2177
+ if (p.colorRight !== value) this.colorRight = value;
2049
2178
 
2050
2179
  this.setUpdateType(UpdateType.PremultipliedColors);
2051
2180
  }
@@ -2060,6 +2189,7 @@ export class CoreNode extends EventEmitter {
2060
2189
  this.colorTr = value;
2061
2190
  }
2062
2191
  this.props.colorTop = value;
2192
+ this.hasColorProps = value > 0;
2063
2193
  this.setUpdateType(UpdateType.PremultipliedColors);
2064
2194
  }
2065
2195
 
@@ -2073,6 +2203,7 @@ export class CoreNode extends EventEmitter {
2073
2203
  this.colorBr = value;
2074
2204
  }
2075
2205
  this.props.colorBottom = value;
2206
+ this.hasColorProps = value > 0;
2076
2207
  this.setUpdateType(UpdateType.PremultipliedColors);
2077
2208
  }
2078
2209
 
@@ -2086,6 +2217,7 @@ export class CoreNode extends EventEmitter {
2086
2217
  this.colorBl = value;
2087
2218
  }
2088
2219
  this.props.colorLeft = value;
2220
+ this.hasColorProps = value > 0;
2089
2221
  this.setUpdateType(UpdateType.PremultipliedColors);
2090
2222
  }
2091
2223
 
@@ -2099,6 +2231,7 @@ export class CoreNode extends EventEmitter {
2099
2231
  this.colorBr = value;
2100
2232
  }
2101
2233
  this.props.colorRight = value;
2234
+ this.hasColorProps = value > 0;
2102
2235
  this.setUpdateType(UpdateType.PremultipliedColors);
2103
2236
  }
2104
2237
 
@@ -2108,6 +2241,7 @@ export class CoreNode extends EventEmitter {
2108
2241
 
2109
2242
  set colorTl(value: number) {
2110
2243
  this.props.colorTl = value;
2244
+ this.hasColorProps = value > 0;
2111
2245
  this.setUpdateType(UpdateType.PremultipliedColors);
2112
2246
  }
2113
2247
 
@@ -2117,6 +2251,7 @@ export class CoreNode extends EventEmitter {
2117
2251
 
2118
2252
  set colorTr(value: number) {
2119
2253
  this.props.colorTr = value;
2254
+ this.hasColorProps = value > 0;
2120
2255
  this.setUpdateType(UpdateType.PremultipliedColors);
2121
2256
  }
2122
2257
 
@@ -2126,6 +2261,7 @@ export class CoreNode extends EventEmitter {
2126
2261
 
2127
2262
  set colorBl(value: number) {
2128
2263
  this.props.colorBl = value;
2264
+ this.hasColorProps = value > 0;
2129
2265
  this.setUpdateType(UpdateType.PremultipliedColors);
2130
2266
  }
2131
2267
 
@@ -2135,32 +2271,43 @@ export class CoreNode extends EventEmitter {
2135
2271
 
2136
2272
  set colorBr(value: number) {
2137
2273
  this.props.colorBr = value;
2274
+ this.hasColorProps = value > 0;
2138
2275
  this.setUpdateType(UpdateType.PremultipliedColors);
2139
2276
  }
2140
2277
 
2141
- // we're only interested in parent zIndex to test
2142
- // if we should use node zIndex is higher then parent zIndex
2143
- get zIndexLocked(): number {
2144
- return this.props.zIndexLocked || 0;
2145
- }
2146
-
2147
- set zIndexLocked(value: number) {
2148
- this.props.zIndexLocked = value;
2149
- this.setUpdateType(UpdateType.CalculatedZIndex | UpdateType.Children);
2150
- for (let i = 0, length = this.children.length; i < length; i++) {
2151
- this.children[i]!.setUpdateType(UpdateType.CalculatedZIndex);
2152
- }
2153
- }
2154
-
2155
2278
  get zIndex(): number {
2156
2279
  return this.props.zIndex;
2157
2280
  }
2158
2281
 
2159
2282
  set zIndex(value: number) {
2160
- this.props.zIndex = value;
2161
- this.setUpdateType(UpdateType.CalculatedZIndex | UpdateType.Children);
2162
- for (let i = 0, length = this.children.length; i < length; i++) {
2163
- this.children[i]!.setUpdateType(UpdateType.CalculatedZIndex);
2283
+ let sanitizedValue = value;
2284
+ if (isNaN(sanitizedValue) || Number.isFinite(sanitizedValue) === false) {
2285
+ console.warn(
2286
+ `zIndex was set to an invalid value: ${value}, defaulting to 0`,
2287
+ );
2288
+ sanitizedValue = 0;
2289
+ }
2290
+
2291
+ //Clamp to safe integer range
2292
+ if (sanitizedValue > Number.MAX_SAFE_INTEGER) {
2293
+ sanitizedValue = 1000;
2294
+ } else if (sanitizedValue < Number.MIN_SAFE_INTEGER) {
2295
+ sanitizedValue = -1000;
2296
+ }
2297
+
2298
+ if (this.props.zIndex === sanitizedValue) {
2299
+ return;
2300
+ }
2301
+ this.previousZIndex = this.props.zIndex;
2302
+ this.props.zIndex = sanitizedValue;
2303
+ const parent = this.parent;
2304
+ if (parent !== null) {
2305
+ const min = parent.zIndexMin;
2306
+ const max = parent.zIndexMax;
2307
+ if (min !== max || sanitizedValue < min || sanitizedValue > max) {
2308
+ parent.zIndexSortList.push(this);
2309
+ parent.setUpdateType(UpdateType.SortZIndexChildren);
2310
+ }
2164
2311
  }
2165
2312
  }
2166
2313
 
@@ -2175,48 +2322,13 @@ export class CoreNode extends EventEmitter {
2175
2322
  }
2176
2323
  this.props.parent = newParent;
2177
2324
  if (oldParent) {
2178
- const index = oldParent.children.indexOf(this);
2179
- assertTruthy(
2180
- index !== -1,
2181
- "CoreNode.parent: Node not found in old parent's children!",
2182
- );
2183
- oldParent.children.splice(index, 1);
2184
- oldParent.setUpdateType(
2185
- UpdateType.Children | UpdateType.ZIndexSortedChildren,
2186
- );
2187
- }
2188
- if (newParent) {
2189
- newParent.children.push(this);
2190
- // Since this node has a new parent, to be safe, have it do a full update.
2191
- this.setUpdateType(UpdateType.All);
2192
- // Tell parent that it's children need to be updated and sorted.
2193
- newParent.setUpdateType(
2194
- UpdateType.Children | UpdateType.ZIndexSortedChildren,
2195
- );
2196
-
2197
- // If the new parent has an RTT enabled, apply RTT inheritance
2198
- if (newParent.rtt || newParent.parentHasRenderTexture) {
2199
- this.applyRTTInheritance(newParent);
2200
- }
2325
+ oldParent.removeChild(this, newParent);
2201
2326
  }
2202
- this.updateScaleRotateTransform();
2203
-
2204
- // fetch render bounds from parent
2205
- this.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
2206
- }
2207
-
2208
- get preventCleanup(): boolean {
2209
- return this.props.textureOptions.preventCleanup || false;
2210
- }
2211
-
2212
- set preventCleanup(value: boolean) {
2213
- if (isProductionEnvironment() === false) {
2214
- console.warn(
2215
- 'CoreNode.preventCleanup: Is deprecated and will be removed in upcoming release, please use textureOptions.preventCleanup instead',
2216
- );
2327
+ if (newParent !== null) {
2328
+ newParent.addChild(this, oldParent);
2217
2329
  }
2218
-
2219
- this.props.textureOptions.preventCleanup = value;
2330
+ //since this node has a new parent, recalc global and render bounds
2331
+ this.setUpdateType(UpdateType.Global | UpdateType.RenderBounds);
2220
2332
  }
2221
2333
 
2222
2334
  get rtt(): boolean {
@@ -2243,11 +2355,14 @@ export class CoreNode extends EventEmitter {
2243
2355
  }
2244
2356
  }
2245
2357
  private initRenderTexture() {
2246
- this.texture = this.stage.txManager.createTexture('RenderTexture', {
2247
- width: this.width,
2248
- height: this.height,
2249
- });
2250
-
2358
+ this.framebufferDimensions = {
2359
+ w: this.props.w,
2360
+ h: this.props.h,
2361
+ };
2362
+ this.texture = this.stage.txManager.createTexture(
2363
+ 'RenderTexture',
2364
+ this.framebufferDimensions,
2365
+ );
2251
2366
  this.stage.renderer.renderToTexture(this);
2252
2367
  }
2253
2368
 
@@ -2257,6 +2372,7 @@ export class CoreNode extends EventEmitter {
2257
2372
 
2258
2373
  this.hasRTTupdates = false;
2259
2374
  this.texture = null;
2375
+ this.framebufferDimensions = null;
2260
2376
  }
2261
2377
 
2262
2378
  private markChildrenWithRTT(node: CoreNode | null = null) {
@@ -2313,10 +2429,17 @@ export class CoreNode extends EventEmitter {
2313
2429
  }
2314
2430
  if (shader.shaderKey !== 'default') {
2315
2431
  this.hasShaderUpdater = shader.update !== undefined;
2432
+ this.hasShaderTimeFn = shader.time !== undefined;
2316
2433
  shader.attachNode(this);
2317
2434
  }
2435
+
2436
+ if (this.hasShaderTimeFn === true) {
2437
+ this.stage.trackTimedNode(this);
2438
+ } else {
2439
+ this.stage.untrackTimedNode(this);
2440
+ }
2318
2441
  this.props.shader = shader;
2319
- this.setUpdateType(UpdateType.IsRenderable);
2442
+ this.setUpdateType(UpdateType.IsRenderable | UpdateType.RecalcUniforms);
2320
2443
  }
2321
2444
 
2322
2445
  get src(): string | null {
@@ -2337,8 +2460,8 @@ export class CoreNode extends EventEmitter {
2337
2460
 
2338
2461
  this.texture = this.stage.txManager.createTexture('ImageTexture', {
2339
2462
  src: imageUrl,
2340
- width: this.props.width,
2341
- height: this.props.height,
2463
+ w: this.props.w,
2464
+ h: this.props.h,
2342
2465
  type: this.props.imageType,
2343
2466
  sx: this.props.srcX,
2344
2467
  sy: this.props.srcY,
@@ -2392,16 +2515,14 @@ export class CoreNode extends EventEmitter {
2392
2515
  }
2393
2516
 
2394
2517
  /**
2395
- * Returns the framebuffer dimensions of the node.
2396
- * If the node has a render texture, the dimensions are the same as the node's dimensions.
2397
- * If the node does not have a render texture, the dimensions are inherited from the parent.
2398
- * If the node parent has a render texture and the node is a render texture, the nodes dimensions are used.
2518
+ * Returns the framebuffer dimensions of the RTT parent
2399
2519
  */
2400
- get framebufferDimensions(): Dimensions {
2401
- if (this.parentHasRenderTexture && !this.rtt && this.parent) {
2402
- return this.parent.framebufferDimensions;
2520
+ get parentFramebufferDimensions(): Dimensions {
2521
+ if (this.rttParent !== null) {
2522
+ return this.rttParent.framebufferDimensions as Dimensions;
2403
2523
  }
2404
- return { width: this.width, height: this.height };
2524
+ this.rttParent = this.findParentRTTNode() as CoreNode;
2525
+ return this.rttParent.framebufferDimensions as Dimensions;
2405
2526
  }
2406
2527
 
2407
2528
  /**
@@ -2429,13 +2550,13 @@ export class CoreNode extends EventEmitter {
2429
2550
 
2430
2551
  const oldTexture = this.props.texture;
2431
2552
  if (oldTexture) {
2432
- oldTexture.setRenderableOwner(this, false);
2433
2553
  this.unloadTexture();
2434
2554
  }
2435
2555
 
2556
+ this.textureCoords = undefined;
2436
2557
  this.props.texture = value;
2437
2558
  if (value !== null) {
2438
- value.setRenderableOwner(this, this.isRenderable);
2559
+ value.setRenderableOwner(this._id, this.isRenderable);
2439
2560
  this.loadTexture();
2440
2561
  }
2441
2562
 
@@ -2444,24 +2565,30 @@ export class CoreNode extends EventEmitter {
2444
2565
 
2445
2566
  set textureOptions(value: TextureOptions) {
2446
2567
  this.props.textureOptions = value;
2568
+ if (this.stage.calculateTextureCoord === true && value !== null) {
2569
+ this.textureCoords = this.stage.renderer.getTextureCoords!(this);
2570
+ }
2447
2571
  }
2448
2572
 
2449
2573
  get textureOptions(): TextureOptions {
2450
2574
  return this.props.textureOptions;
2451
2575
  }
2452
2576
 
2453
- get strictBounds(): boolean {
2454
- return this.props.strictBounds;
2577
+ set interactive(value: boolean | undefined) {
2578
+ this.props.interactive = value;
2579
+ // Update Stage's interactive Set
2580
+ if (value === true) {
2581
+ this.stage.interactiveNodes.add(this);
2582
+ }
2455
2583
  }
2456
2584
 
2457
- set strictBounds(v) {
2458
- if (v === this.props.strictBounds) {
2459
- return;
2460
- }
2585
+ get interactive(): boolean | undefined {
2586
+ return this.props.interactive;
2587
+ }
2461
2588
 
2462
- this.props.strictBounds = v;
2463
- this.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
2464
- this.childUpdateType |= UpdateType.RenderBounds | UpdateType.Children;
2589
+ setRTTUpdates(type: number) {
2590
+ this.hasRTTupdates = true;
2591
+ this.parent?.setRTTUpdates(type);
2465
2592
  }
2466
2593
 
2467
2594
  animate(