@lightningjs/renderer 2.12.1 → 2.13.1

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 (185) hide show
  1. package/dist/src/core/CoreNode.d.ts +10 -0
  2. package/dist/src/core/CoreNode.js +90 -14
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextureManager.d.ts +13 -7
  5. package/dist/src/core/CoreTextureManager.js +92 -105
  6. package/dist/src/core/CoreTextureManager.js.map +1 -1
  7. package/dist/src/core/Stage.d.ts +4 -2
  8. package/dist/src/core/Stage.js +23 -7
  9. package/dist/src/core/Stage.js.map +1 -1
  10. package/dist/src/core/TextureMemoryManager.d.ts +16 -6
  11. package/dist/src/core/TextureMemoryManager.js +75 -17
  12. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  13. package/dist/src/core/lib/ImageWorker.d.ts +1 -1
  14. package/dist/src/core/lib/ImageWorker.js +15 -12
  15. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  16. package/dist/src/core/lib/utils.d.ts +4 -0
  17. package/dist/src/core/lib/utils.js +46 -0
  18. package/dist/src/core/lib/utils.js.map +1 -1
  19. package/dist/src/core/lib/validateImageBitmap.d.ts +6 -0
  20. package/dist/src/core/lib/validateImageBitmap.js +68 -0
  21. package/dist/src/core/lib/validateImageBitmap.js.map +1 -0
  22. package/dist/src/core/platform.js +3 -3
  23. package/dist/src/core/platform.js.map +1 -1
  24. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +7 -12
  25. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  26. package/dist/src/core/textures/ImageTexture.d.ts +2 -2
  27. package/dist/src/core/textures/ImageTexture.js +34 -20
  28. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  29. package/dist/src/main-api/ICoreDriver.d.ts +1 -4
  30. package/dist/src/main-api/Inspector.js +16 -2
  31. package/dist/src/main-api/Inspector.js.map +1 -1
  32. package/dist/src/main-api/Renderer.d.ts +27 -1
  33. package/dist/src/main-api/Renderer.js +8 -3
  34. package/dist/src/main-api/Renderer.js.map +1 -1
  35. package/dist/src/main-api/RendererMain.d.ts +5 -2
  36. package/dist/src/main-api/RendererMain.js +6 -4
  37. package/dist/src/main-api/RendererMain.js.map +1 -1
  38. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +1 -1
  39. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +1 -4
  40. package/dist/src/render-drivers/main/MainCoreDriver.js +1 -4
  41. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  42. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +8 -6
  43. package/dist/src/render-drivers/main/MainOnlyNode.js +30 -1
  44. package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
  45. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +1 -1
  46. package/dist/src/render-drivers/main/MainOnlyTextNode.js +2 -3
  47. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  48. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
  49. package/dist/src/render-drivers/threadx/NodeStruct.js +9 -0
  50. package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
  51. package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
  52. package/dist/src/render-drivers/threadx/SharedNode.js +1 -0
  53. package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
  54. package/dist/src/render-drivers/threadx/TextNodeStruct.js +3 -1
  55. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  56. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +1 -4
  57. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +2 -4
  58. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  59. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +8 -4
  60. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +53 -24
  61. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +1 -1
  62. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +7 -5
  63. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +8 -2
  64. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +1 -1
  65. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  66. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +7 -0
  67. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
  68. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +1 -0
  69. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  70. package/dist/src/render-drivers/threadx/worker/renderer.js +2 -0
  71. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  72. package/dist/src/render-drivers/utils.js +6 -1
  73. package/dist/src/render-drivers/utils.js.map +1 -1
  74. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  75. package/dist/tsconfig.tsbuildinfo +1 -0
  76. package/package.json +1 -1
  77. package/src/core/CoreNode.test.ts +155 -152
  78. package/src/core/CoreNode.ts +136 -22
  79. package/src/core/CoreTextureManager.ts +127 -126
  80. package/src/core/Stage.ts +28 -7
  81. package/src/core/TextureMemoryManager.ts +108 -27
  82. package/src/core/lib/ImageWorker.ts +22 -13
  83. package/src/core/lib/utils.ts +74 -0
  84. package/src/core/lib/validateImageBitmap.ts +76 -0
  85. package/src/core/platform.ts +5 -3
  86. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +11 -13
  87. package/src/core/textures/ImageTexture.ts +42 -25
  88. package/src/main-api/Inspector.ts +19 -2
  89. package/src/main-api/Renderer.ts +34 -3
  90. package/dist/src/core/CoreStuff.d.ts +0 -1
  91. package/dist/src/core/CoreStuff.js +0 -138
  92. package/dist/src/core/CoreStuff.js.map +0 -1
  93. package/dist/src/core/CoreTexturizer.d.ts +0 -14
  94. package/dist/src/core/CoreTexturizer.js +0 -47
  95. package/dist/src/core/CoreTexturizer.js.map +0 -1
  96. package/dist/src/core/LngNode.d.ts +0 -736
  97. package/dist/src/core/LngNode.js +0 -1174
  98. package/dist/src/core/LngNode.js.map +0 -1
  99. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  100. package/dist/src/core/Matrix2DContext.js +0 -45
  101. package/dist/src/core/Matrix2DContext.js.map +0 -1
  102. package/dist/src/core/ShaderNode.d.ts +0 -10
  103. package/dist/src/core/ShaderNode.js +0 -30
  104. package/dist/src/core/ShaderNode.js.map +0 -1
  105. package/dist/src/core/TextNode.d.ts +0 -103
  106. package/dist/src/core/TextNode.js +0 -331
  107. package/dist/src/core/TextNode.js.map +0 -1
  108. package/dist/src/core/lib/Coords.d.ts +0 -14
  109. package/dist/src/core/lib/Coords.js +0 -55
  110. package/dist/src/core/lib/Coords.js.map +0 -1
  111. package/dist/src/core/lib/glm/common.d.ts +0 -162
  112. package/dist/src/core/lib/glm/common.js +0 -81
  113. package/dist/src/core/lib/glm/common.js.map +0 -1
  114. package/dist/src/core/lib/glm/index.d.ts +0 -11
  115. package/dist/src/core/lib/glm/index.js +0 -30
  116. package/dist/src/core/lib/glm/index.js.map +0 -1
  117. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  118. package/dist/src/core/lib/glm/mat2.js +0 -396
  119. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  120. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  121. package/dist/src/core/lib/glm/mat2d.js +0 -442
  122. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  123. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  124. package/dist/src/core/lib/glm/mat3.js +0 -680
  125. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  126. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  127. package/dist/src/core/lib/glm/mat4.js +0 -1802
  128. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  129. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  130. package/dist/src/core/lib/glm/quat.js +0 -693
  131. package/dist/src/core/lib/glm/quat.js.map +0 -1
  132. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  133. package/dist/src/core/lib/glm/quat2.js +0 -754
  134. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  135. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  136. package/dist/src/core/lib/glm/vec2.js +0 -569
  137. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  138. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  139. package/dist/src/core/lib/glm/vec3.js +0 -720
  140. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  141. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  142. package/dist/src/core/lib/glm/vec4.js +0 -608
  143. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  144. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  145. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  146. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  147. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  148. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  149. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  150. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  151. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  152. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  153. package/dist/src/core/scene/Scene.d.ts +0 -59
  154. package/dist/src/core/scene/Scene.js +0 -106
  155. package/dist/src/core/scene/Scene.js.map +0 -1
  156. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  157. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  158. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  159. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  160. package/dist/src/main-api/IRenderDriver.js +0 -20
  161. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  162. package/dist/src/main-api/IShaderController.d.ts +0 -14
  163. package/dist/src/main-api/IShaderController.js +0 -30
  164. package/dist/src/main-api/IShaderController.js.map +0 -1
  165. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  166. package/dist/src/main-api/IShaderNode.js +0 -19
  167. package/dist/src/main-api/IShaderNode.js.map +0 -1
  168. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  169. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  170. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  171. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  172. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  173. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  174. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  175. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  176. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  177. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  178. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  179. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  180. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  181. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  182. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  183. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  184. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  185. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
@@ -26,174 +26,177 @@ import { type BaseShaderController } from '../main-api/ShaderController';
26
26
  import { createBound } from './lib/utils.js';
27
27
  import { ImageTexture } from './textures/ImageTexture.js';
28
28
 
29
- const defaultProps: CoreNodeProps = {
30
- alpha: 0,
31
- autosize: false,
32
- clipping: false,
33
- color: 0,
34
- colorBl: 0,
35
- colorBottom: 0,
36
- colorBr: 0,
37
- colorLeft: 0,
38
- colorRight: 0,
39
- colorTl: 0,
40
- colorTop: 0,
41
- colorTr: 0,
42
- height: 0,
43
- mount: 0,
44
- mountX: 0,
45
- mountY: 0,
46
- parent: null,
47
- pivot: 0,
48
- pivotX: 0,
49
- pivotY: 0,
50
- rotation: 0,
51
- rtt: false,
52
- scale: 0,
53
- scaleX: 0,
54
- scaleY: 0,
55
- shader: mock<BaseShaderController>(),
56
- src: '',
57
- texture: null,
58
- textureOptions: {} as TextureOptions,
59
- width: 0,
60
- x: 0,
61
- y: 0,
62
- zIndex: 0,
63
- zIndexLocked: 0,
64
- preventCleanup: false,
65
- strictBounds: false,
66
- };
67
-
68
- const clippingRect = {
69
- x: 0,
70
- y: 0,
71
- width: 200,
72
- height: 200,
73
- valid: false,
74
- };
75
-
76
- const stage = mock<Stage>({
77
- strictBound: createBound(0, 0, 200, 200),
78
- preloadBound: createBound(0, 0, 200, 200),
79
- defaultTexture: {
80
- state: 'loaded',
81
- },
82
- });
83
-
84
29
  describe('set color()', () => {
85
- it('should set all color subcomponents.', () => {
86
- const node = new CoreNode(stage, defaultProps);
87
- node.colorBl = 0x99aabbff;
88
- node.colorBr = 0xaabbccff;
89
- node.colorTl = 0xbbcceeff;
90
- node.colorTr = 0xcceeffff;
91
-
92
- node.color = 0xffffffff;
93
-
94
- expect(node.color).toBe(0xffffffff);
95
- expect(node.colorBl).toBe(0xffffffff);
96
- expect(node.colorBr).toBe(0xffffffff);
97
- expect(node.colorTl).toBe(0xffffffff);
98
- expect(node.colorTr).toBe(0xffffffff);
99
- expect(node.colorLeft).toBe(0xffffffff);
100
- expect(node.colorRight).toBe(0xffffffff);
101
- expect(node.colorTop).toBe(0xffffffff);
102
- expect(node.colorBottom).toBe(0xffffffff);
103
- });
104
-
105
- it('should set update type.', () => {
106
- const node = new CoreNode(stage, defaultProps);
107
- node.updateType = 0;
108
-
109
- node.color = 0xffffffff;
110
-
111
- expect(node.updateType).toBe(UpdateType.PremultipliedColors);
112
- });
113
- });
114
-
115
- describe('isRenderable checks', () => {
116
- it('should return false if node is not renderable', () => {
117
- const node = new CoreNode(stage, defaultProps);
118
- expect(node.isRenderable).toBe(false);
119
- });
120
-
121
- it('visible node that is a color texture', () => {
122
- const node = new CoreNode(stage, defaultProps);
123
- node.alpha = 1;
124
- node.x = 0;
125
- node.y = 0;
126
- node.width = 100;
127
- node.height = 100;
128
- node.color = 0xffffffff;
129
-
130
- node.update(0, clippingRect);
131
- expect(node.isRenderable).toBe(true);
30
+ const defaultProps: CoreNodeProps = {
31
+ alpha: 0,
32
+ autosize: false,
33
+ boundsMargin: null,
34
+ clipping: false,
35
+ color: 0,
36
+ colorBl: 0,
37
+ colorBottom: 0,
38
+ colorBr: 0,
39
+ colorLeft: 0,
40
+ colorRight: 0,
41
+ colorTl: 0,
42
+ colorTop: 0,
43
+ colorTr: 0,
44
+ height: 0,
45
+ mount: 0,
46
+ mountX: 0,
47
+ mountY: 0,
48
+ parent: null,
49
+ pivot: 0,
50
+ pivotX: 0,
51
+ pivotY: 0,
52
+ rotation: 0,
53
+ rtt: false,
54
+ scale: 0,
55
+ scaleX: 0,
56
+ scaleY: 0,
57
+ shader: mock<BaseShaderController>(),
58
+ src: '',
59
+ texture: null,
60
+ textureOptions: {} as TextureOptions,
61
+ width: 0,
62
+ x: 0,
63
+ y: 0,
64
+ zIndex: 0,
65
+ zIndexLocked: 0,
66
+ preventCleanup: false,
67
+ strictBounds: false,
68
+ };
69
+
70
+ const clippingRect = {
71
+ x: 0,
72
+ y: 0,
73
+ width: 200,
74
+ height: 200,
75
+ valid: false,
76
+ };
77
+
78
+ const stage = mock<Stage>({
79
+ strictBound: createBound(0, 0, 200, 200),
80
+ preloadBound: createBound(0, 0, 200, 200),
81
+ defaultTexture: {
82
+ state: 'loaded',
83
+ },
132
84
  });
133
85
 
134
- it('visible node that is a texture', () => {
135
- const node = new CoreNode(stage, defaultProps);
136
- node.alpha = 1;
137
- node.x = 0;
138
- node.y = 0;
139
- node.width = 100;
140
- node.height = 100;
141
- node.texture = mock<ImageTexture>({
142
- state: 'initial',
86
+ describe('set color()', () => {
87
+ it('should set all color subcomponents.', () => {
88
+ const node = new CoreNode(stage, defaultProps);
89
+ node.colorBl = 0x99aabbff;
90
+ node.colorBr = 0xaabbccff;
91
+ node.colorTl = 0xbbcceeff;
92
+ node.colorTr = 0xcceeffff;
93
+
94
+ node.color = 0xffffffff;
95
+
96
+ expect(node.color).toBe(0xffffffff);
97
+ expect(node.colorBl).toBe(0xffffffff);
98
+ expect(node.colorBr).toBe(0xffffffff);
99
+ expect(node.colorTl).toBe(0xffffffff);
100
+ expect(node.colorTr).toBe(0xffffffff);
101
+ expect(node.colorLeft).toBe(0xffffffff);
102
+ expect(node.colorRight).toBe(0xffffffff);
103
+ expect(node.colorTop).toBe(0xffffffff);
104
+ expect(node.colorBottom).toBe(0xffffffff);
143
105
  });
144
106
 
145
- node.update(0, clippingRect);
146
- expect(node.isRenderable).toBe(false);
107
+ it('should set update type.', () => {
108
+ const node = new CoreNode(stage, defaultProps);
109
+ node.updateType = 0;
147
110
 
148
- node.texture.state = 'loaded';
149
- node.setUpdateType(UpdateType.IsRenderable);
150
- node.update(1, clippingRect);
111
+ node.color = 0xffffffff;
151
112
 
152
- expect(node.isRenderable).toBe(true);
113
+ expect(node.updateType).toBe(UpdateType.PremultipliedColors);
114
+ });
153
115
  });
154
116
 
155
- it('a node with a texture with alpha 0 should not be renderable', () => {
156
- const node = new CoreNode(stage, defaultProps);
157
- node.alpha = 0;
158
- node.x = 0;
159
- node.y = 0;
160
- node.width = 100;
161
- node.height = 100;
162
- node.texture = mock<ImageTexture>({
163
- state: 'loaded',
117
+ describe('isRenderable checks', () => {
118
+ it('should return false if node is not renderable', () => {
119
+ const node = new CoreNode(stage, defaultProps);
120
+ expect(node.isRenderable).toBe(false);
164
121
  });
165
122
 
166
- node.update(0, clippingRect);
167
- expect(node.isRenderable).toBe(false);
168
- });
123
+ it('visible node that is a color texture', () => {
124
+ const node = new CoreNode(stage, defaultProps);
125
+ node.alpha = 1;
126
+ node.x = 0;
127
+ node.y = 0;
128
+ node.width = 100;
129
+ node.height = 100;
130
+ node.color = 0xffffffff;
131
+
132
+ node.update(0, clippingRect);
133
+ expect(node.isRenderable).toBe(true);
134
+ });
169
135
 
170
- it('a node with a texture that is OutOfBounds should not be renderable', () => {
171
- const node = new CoreNode(stage, defaultProps);
172
- node.alpha = 1;
173
- node.x = 300;
174
- node.y = 300;
175
- node.width = 100;
176
- node.height = 100;
177
- node.texture = mock<ImageTexture>({
178
- state: 'loaded',
136
+ it('visible node that is a texture', () => {
137
+ const node = new CoreNode(stage, defaultProps);
138
+ node.alpha = 1;
139
+ node.x = 0;
140
+ node.y = 0;
141
+ node.width = 100;
142
+ node.height = 100;
143
+ node.texture = mock<ImageTexture>({
144
+ state: 'initial',
145
+ });
146
+
147
+ node.update(0, clippingRect);
148
+ expect(node.isRenderable).toBe(false);
149
+
150
+ node.texture.state = 'loaded';
151
+ node.setUpdateType(UpdateType.IsRenderable);
152
+ node.update(1, clippingRect);
153
+
154
+ expect(node.isRenderable).toBe(true);
179
155
  });
180
156
 
181
- node.update(0, clippingRect);
182
- expect(node.isRenderable).toBe(false);
183
- });
157
+ it('a node with a texture with alpha 0 should not be renderable', () => {
158
+ const node = new CoreNode(stage, defaultProps);
159
+ node.alpha = 0;
160
+ node.x = 0;
161
+ node.y = 0;
162
+ node.width = 100;
163
+ node.height = 100;
164
+ node.texture = mock<ImageTexture>({
165
+ state: 'loaded',
166
+ });
167
+
168
+ node.update(0, clippingRect);
169
+ expect(node.isRenderable).toBe(false);
170
+ });
184
171
 
185
- it('a node with a freed texture should not be renderable', () => {
186
- const node = new CoreNode(stage, defaultProps);
187
- node.alpha = 1;
188
- node.x = 0;
189
- node.y = 0;
190
- node.width = 100;
191
- node.height = 100;
192
- node.texture = mock<ImageTexture>({
193
- state: 'freed',
172
+ it('a node with a texture that is OutOfBounds should not be renderable', () => {
173
+ const node = new CoreNode(stage, defaultProps);
174
+ node.alpha = 1;
175
+ node.x = 300;
176
+ node.y = 300;
177
+ node.width = 100;
178
+ node.height = 100;
179
+ node.texture = mock<ImageTexture>({
180
+ state: 'loaded',
181
+ });
182
+
183
+ node.update(0, clippingRect);
184
+ expect(node.isRenderable).toBe(false);
194
185
  });
195
186
 
196
- node.update(0, clippingRect);
197
- expect(node.isRenderable).toBe(false);
187
+ it('a node with a freed texture should not be renderable', () => {
188
+ const node = new CoreNode(stage, defaultProps);
189
+ node.alpha = 1;
190
+ node.x = 0;
191
+ node.y = 0;
192
+ node.width = 100;
193
+ node.height = 100;
194
+ node.texture = mock<ImageTexture>({
195
+ state: 'freed',
196
+ });
197
+
198
+ node.update(0, clippingRect);
199
+ expect(node.isRenderable).toBe(false);
200
+ });
198
201
  });
199
202
  });
@@ -268,6 +268,12 @@ export interface CoreNodeProps {
268
268
  * @default `false`
269
269
  */
270
270
  autosize: boolean;
271
+ /**
272
+ * Margin around the Node's bounds for preloading
273
+ *
274
+ * @default `null`
275
+ */
276
+ boundsMargin: number | [number, number, number, number] | null;
271
277
  /**
272
278
  * Clipping Mode
273
279
  *
@@ -725,7 +731,9 @@ export class CoreNode extends EventEmitter {
725
731
  public globalTransform?: Matrix3d;
726
732
  public scaleRotateTransform?: Matrix3d;
727
733
  public localTransform?: Matrix3d;
734
+ public sceneGlobalTransform?: Matrix3d;
728
735
  public renderCoords?: RenderCoords;
736
+ public sceneRenderCoords?: RenderCoords;
729
737
  public renderBound?: Bound;
730
738
  public strictBound?: Bound;
731
739
  public preloadBound?: Bound;
@@ -766,6 +774,17 @@ export class CoreNode extends EventEmitter {
766
774
  this.src = props.src;
767
775
  this.rtt = props.rtt;
768
776
 
777
+ if (props.boundsMargin) {
778
+ this.boundsMargin = Array.isArray(props.boundsMargin)
779
+ ? props.boundsMargin
780
+ : [
781
+ props.boundsMargin,
782
+ props.boundsMargin,
783
+ props.boundsMargin,
784
+ props.boundsMargin,
785
+ ];
786
+ }
787
+
769
788
  this.setUpdateType(
770
789
  UpdateType.ScaleRotate |
771
790
  UpdateType.Local |
@@ -1034,19 +1053,40 @@ export class CoreNode extends EventEmitter {
1034
1053
  if (this.updateType & UpdateType.Global) {
1035
1054
  assertTruthy(this.localTransform);
1036
1055
 
1037
- this.globalTransform = Matrix3d.copy(
1038
- parent?.globalTransform || this.localTransform,
1039
- this.globalTransform,
1040
- );
1041
-
1042
- if (this.parentHasRenderTexture && this.props.parent?.rtt) {
1056
+ if (this.parentHasRenderTexture === true && parent?.rtt === true) {
1057
+ // we are at the start of the RTT chain, so we need to reset the globalTransform
1058
+ // for correct RTT rendering
1043
1059
  this.globalTransform = Matrix3d.identity();
1060
+
1061
+ // Maintain a full scene global transform for bounds detection
1062
+ this.sceneGlobalTransform = Matrix3d.copy(
1063
+ parent?.globalTransform || Matrix3d.identity(),
1064
+ ).multiply(this.localTransform);
1065
+ } else if (
1066
+ this.parentHasRenderTexture === true &&
1067
+ parent?.rtt === false
1068
+ ) {
1069
+ // we're part of an RTT chain but our parent is not the main RTT node
1070
+ // so we need to propogate the sceneGlobalTransform of the parent
1071
+ // to maintain a full scene global transform for bounds detection
1072
+ this.sceneGlobalTransform = Matrix3d.copy(
1073
+ parent?.sceneGlobalTransform || this.localTransform,
1074
+ ).multiply(this.localTransform);
1075
+
1076
+ this.globalTransform = Matrix3d.copy(
1077
+ parent?.globalTransform || this.localTransform,
1078
+ this.globalTransform,
1079
+ );
1080
+ } else {
1081
+ this.globalTransform = Matrix3d.copy(
1082
+ parent?.globalTransform || this.localTransform,
1083
+ this.globalTransform,
1084
+ );
1044
1085
  }
1045
1086
 
1046
- if (parent) {
1087
+ if (parent !== null) {
1047
1088
  this.globalTransform.multiply(this.localTransform);
1048
1089
  }
1049
-
1050
1090
  this.calculateRenderCoords();
1051
1091
  this.updateBoundingRect();
1052
1092
 
@@ -1063,6 +1103,8 @@ export class CoreNode extends EventEmitter {
1063
1103
  this.createRenderBounds();
1064
1104
  this.setUpdateType(UpdateType.RenderState);
1065
1105
  this.setUpdateType(UpdateType.Children);
1106
+
1107
+ this.childUpdateType |= UpdateType.RenderBounds;
1066
1108
  }
1067
1109
 
1068
1110
  if (this.updateType & UpdateType.RenderState) {
@@ -1150,6 +1192,7 @@ export class CoreNode extends EventEmitter {
1150
1192
  this.props.strictBounds === true &&
1151
1193
  this.renderState === CoreNodeRenderState.OutOfBounds
1152
1194
  ) {
1195
+ this.updateType &= ~UpdateType.RenderBounds; // remove render bounds update
1153
1196
  return;
1154
1197
  }
1155
1198
 
@@ -1266,11 +1309,6 @@ export class CoreNode extends EventEmitter {
1266
1309
  assertTruthy(this.strictBound);
1267
1310
  assertTruthy(this.preloadBound);
1268
1311
 
1269
- // if we are part of a parent render texture, we're always in bounds
1270
- if (this.parentHasRenderTexture === true) {
1271
- return this.getRTTParentRenderState() || CoreNodeRenderState.OutOfBounds;
1272
- }
1273
-
1274
1312
  if (boundInsideBound(this.renderBound, this.strictBound)) {
1275
1313
  return CoreNodeRenderState.InViewport;
1276
1314
  }
@@ -1296,7 +1334,9 @@ export class CoreNode extends EventEmitter {
1296
1334
  }
1297
1335
 
1298
1336
  updateBoundingRect() {
1299
- const { renderCoords, globalTransform: transform } = this;
1337
+ const transform = this.sceneGlobalTransform || this.globalTransform;
1338
+ const renderCoords = this.sceneRenderCoords || this.renderCoords;
1339
+
1300
1340
  assertTruthy(transform);
1301
1341
  assertTruthy(renderCoords);
1302
1342
 
@@ -1331,7 +1371,7 @@ export class CoreNode extends EventEmitter {
1331
1371
 
1332
1372
  this.preloadBound = createPreloadBounds(
1333
1373
  this.strictBound,
1334
- this.stage.boundsMargin,
1374
+ this.boundsMargin as [number, number, number, number],
1335
1375
  );
1336
1376
  } else {
1337
1377
  // no parent or parent does not have a bound, take the stage boundaries
@@ -1357,7 +1397,10 @@ export class CoreNode extends EventEmitter {
1357
1397
 
1358
1398
  // clipping is enabled and we are in bounds create our own bounds
1359
1399
  const { x, y, width, height } = this.props;
1360
- const { tx, ty } = this.globalTransform || {};
1400
+
1401
+ // Pick the global transform if available, otherwise use the local transform
1402
+ // global transform is only available if the node in an RTT chain
1403
+ const { tx, ty } = this.sceneGlobalTransform || this.globalTransform || {};
1361
1404
  const _x = tx ?? x;
1362
1405
  const _y = ty ?? y;
1363
1406
  this.strictBound = createBound(
@@ -1370,7 +1413,7 @@ export class CoreNode extends EventEmitter {
1370
1413
 
1371
1414
  this.preloadBound = createPreloadBounds(
1372
1415
  this.strictBound,
1373
- this.stage.boundsMargin,
1416
+ this.boundsMargin as [number, number, number, number],
1374
1417
  );
1375
1418
  }
1376
1419
 
@@ -1487,13 +1530,11 @@ export class CoreNode extends EventEmitter {
1487
1530
  }
1488
1531
 
1489
1532
  calculateRenderCoords() {
1490
- const { width, height, globalTransform: transform } = this;
1491
- assertTruthy(transform);
1492
- const { tx, ty, ta, tb, tc, td } = transform;
1533
+ const { width, height } = this;
1534
+ const { tx, ty, ta, tb, tc, td } = this.globalTransform!;
1493
1535
  if (tb === 0 && tc === 0) {
1494
1536
  const minX = tx;
1495
1537
  const maxX = tx + width * ta;
1496
-
1497
1538
  const minY = ty;
1498
1539
  const maxY = ty + height * td;
1499
1540
  this.renderCoords = RenderCoords.translate(
@@ -1528,6 +1569,55 @@ export class CoreNode extends EventEmitter {
1528
1569
  this.renderCoords,
1529
1570
  );
1530
1571
  }
1572
+ if (this.sceneGlobalTransform === undefined) {
1573
+ return;
1574
+ }
1575
+
1576
+ const {
1577
+ tx: stx,
1578
+ ty: sty,
1579
+ ta: sta,
1580
+ tb: stb,
1581
+ tc: stc,
1582
+ td: std,
1583
+ } = this.sceneGlobalTransform;
1584
+ if (stb === 0 && stc === 0) {
1585
+ const minX = stx;
1586
+ const maxX = stx + width * sta;
1587
+ const minY = sty;
1588
+ const maxY = sty + height * std;
1589
+ this.sceneRenderCoords = RenderCoords.translate(
1590
+ //top-left
1591
+ minX,
1592
+ minY,
1593
+ //top-right
1594
+ maxX,
1595
+ minY,
1596
+ //bottom-right
1597
+ maxX,
1598
+ maxY,
1599
+ //bottom-left
1600
+ minX,
1601
+ maxY,
1602
+ this.sceneRenderCoords,
1603
+ );
1604
+ } else {
1605
+ this.sceneRenderCoords = RenderCoords.translate(
1606
+ //top-left
1607
+ stx,
1608
+ sty,
1609
+ //top-right
1610
+ stx + width * sta,
1611
+ sty + width * stc,
1612
+ //bottom-right
1613
+ stx + width * sta + height * stb,
1614
+ sty + width * stc + height * std,
1615
+ //bottom-left
1616
+ stx + height * stb,
1617
+ sty + height * std,
1618
+ this.sceneRenderCoords,
1619
+ );
1620
+ }
1531
1621
  }
1532
1622
 
1533
1623
  /**
@@ -1542,7 +1632,6 @@ export class CoreNode extends EventEmitter {
1542
1632
  assertTruthy(this.globalTransform);
1543
1633
  const { clippingRect, props, globalTransform: gt } = this;
1544
1634
  const { clipping } = props;
1545
-
1546
1635
  const isRotated = gt.tb !== 0 || gt.tc !== 0;
1547
1636
 
1548
1637
  if (clipping === true && isRotated === false) {
@@ -1887,6 +1976,31 @@ export class CoreNode extends EventEmitter {
1887
1976
  this.props.autosize = value;
1888
1977
  }
1889
1978
 
1979
+ get boundsMargin(): number | [number, number, number, number] | null {
1980
+ return (
1981
+ this.props.boundsMargin ??
1982
+ this.parent?.boundsMargin ??
1983
+ this.stage.boundsMargin
1984
+ );
1985
+ }
1986
+
1987
+ set boundsMargin(value: number | [number, number, number, number] | null) {
1988
+ if (value === this.props.boundsMargin) {
1989
+ return;
1990
+ }
1991
+
1992
+ if (value === null) {
1993
+ this.props.boundsMargin = value;
1994
+ } else {
1995
+ const bm: [number, number, number, number] = Array.isArray(value)
1996
+ ? value
1997
+ : [value, value, value, value];
1998
+
1999
+ this.props.boundsMargin = bm;
2000
+ }
2001
+ this.setUpdateType(UpdateType.RenderBounds);
2002
+ }
2003
+
1890
2004
  get clipping(): boolean {
1891
2005
  return this.props.clipping;
1892
2006
  }