@safe-engine/pixi 8.1.3 → 8.2.2

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 (162) hide show
  1. package/@types/index.d.ts +2 -0
  2. package/@types/safex.d.ts +168 -0
  3. package/README.md +9 -3
  4. package/dist/app.d.ts +1 -2
  5. package/dist/app.d.ts.map +1 -1
  6. package/dist/app.js +25 -24
  7. package/dist/base/EnhancedComponent.d.ts +25 -0
  8. package/dist/base/EnhancedComponent.d.ts.map +1 -0
  9. package/dist/base/EnhancedComponent.js +26 -0
  10. package/dist/base/gworld.d.ts +8 -0
  11. package/dist/base/gworld.d.ts.map +1 -0
  12. package/dist/base/gworld.js +16 -0
  13. package/dist/base/index.d.ts +4 -0
  14. package/dist/base/index.d.ts.map +1 -0
  15. package/dist/base/index.js +3 -0
  16. package/dist/base/utils.d.ts +6 -0
  17. package/dist/base/utils.d.ts.map +1 -0
  18. package/dist/base/utils.js +3 -0
  19. package/dist/collider/CollideComponent.d.ts +63 -0
  20. package/dist/collider/CollideComponent.d.ts.map +1 -0
  21. package/dist/collider/CollideComponent.js +238 -0
  22. package/dist/collider/CollideSystem.d.ts +26 -0
  23. package/dist/collider/CollideSystem.d.ts.map +1 -0
  24. package/dist/collider/CollideSystem.js +159 -0
  25. package/dist/collider/helper/Intersection.d.ts +7 -0
  26. package/dist/collider/helper/Intersection.d.ts.map +1 -0
  27. package/dist/collider/helper/Intersection.js +111 -0
  28. package/dist/collider/helper/utils.d.ts +3 -0
  29. package/dist/collider/helper/utils.d.ts.map +1 -0
  30. package/dist/collider/helper/utils.js +11 -0
  31. package/dist/collider/index.d.ts +3 -0
  32. package/dist/collider/index.d.ts.map +1 -0
  33. package/dist/collider/index.js +2 -0
  34. package/dist/components/BaseComponent.d.ts +6 -5
  35. package/dist/components/BaseComponent.d.ts.map +1 -1
  36. package/dist/components/BaseComponent.js +7 -9
  37. package/dist/components/NodeComp.d.ts +13 -13
  38. package/dist/components/NodeComp.d.ts.map +1 -1
  39. package/dist/components/NodeComp.js +34 -30
  40. package/dist/components/Scene.d.ts +2 -3
  41. package/dist/components/Scene.d.ts.map +1 -1
  42. package/dist/components/Scene.js +6 -10
  43. package/dist/core/Color.d.ts +1 -0
  44. package/dist/core/Color.d.ts.map +1 -1
  45. package/dist/core/Color.js +3 -6
  46. package/dist/core/LoadingBar.js +10 -15
  47. package/dist/core/NodePool.d.ts +9 -0
  48. package/dist/core/NodePool.d.ts.map +1 -0
  49. package/dist/core/NodePool.js +24 -0
  50. package/dist/core/Size.js +1 -4
  51. package/dist/core/director.d.ts +3 -0
  52. package/dist/core/director.d.ts.map +1 -0
  53. package/dist/core/director.js +7 -0
  54. package/dist/core/math.d.ts +4 -0
  55. package/dist/core/math.d.ts.map +1 -0
  56. package/dist/core/math.js +10 -0
  57. package/dist/dragonbones/DragonBonesComponent.d.ts +17 -0
  58. package/dist/dragonbones/DragonBonesComponent.d.ts.map +1 -0
  59. package/dist/dragonbones/DragonBonesComponent.js +18 -0
  60. package/dist/dragonbones/DragonBonesSystem.d.ts +6 -0
  61. package/dist/dragonbones/DragonBonesSystem.d.ts.map +1 -0
  62. package/dist/dragonbones/DragonBonesSystem.js +29 -0
  63. package/dist/dragonbones/index.d.ts +3 -0
  64. package/dist/dragonbones/index.d.ts.map +1 -0
  65. package/dist/dragonbones/index.js +2 -0
  66. package/dist/{components → gui}/GUIComponent.d.ts +29 -23
  67. package/dist/gui/GUIComponent.d.ts.map +1 -0
  68. package/dist/gui/GUIComponent.js +123 -0
  69. package/dist/{systems → gui}/GUISystem.d.ts +1 -1
  70. package/dist/gui/GUISystem.d.ts.map +1 -0
  71. package/dist/gui/GUISystem.js +100 -0
  72. package/dist/helper/html-text-parser.d.ts +19 -29
  73. package/dist/helper/html-text-parser.d.ts.map +1 -1
  74. package/dist/helper/html-text-parser.js +57 -346
  75. package/dist/helper/utils.d.ts +2 -3
  76. package/dist/helper/utils.d.ts.map +1 -1
  77. package/dist/helper/utils.js +18 -23
  78. package/dist/index.d.ts +16 -6
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +22 -28
  81. package/dist/norender/NoRenderComponent.d.ts +35 -0
  82. package/dist/norender/NoRenderComponent.d.ts.map +1 -0
  83. package/dist/norender/NoRenderComponent.js +53 -0
  84. package/dist/norender/NoRenderSystem.d.ts +5 -0
  85. package/dist/norender/NoRenderSystem.d.ts.map +1 -0
  86. package/dist/norender/NoRenderSystem.js +57 -0
  87. package/dist/planck/PhysicsComponent.d.ts +37 -0
  88. package/dist/planck/PhysicsComponent.d.ts.map +1 -0
  89. package/dist/planck/PhysicsComponent.js +52 -0
  90. package/dist/planck/PhysicsSprite.d.ts +16 -0
  91. package/dist/planck/PhysicsSprite.d.ts.map +1 -0
  92. package/dist/planck/PhysicsSprite.js +31 -0
  93. package/dist/planck/PhysicsSystem.d.ts +20 -0
  94. package/dist/planck/PhysicsSystem.d.ts.map +1 -0
  95. package/dist/planck/PhysicsSystem.js +187 -0
  96. package/dist/planck/index.d.ts +4 -0
  97. package/dist/planck/index.d.ts.map +1 -0
  98. package/dist/planck/index.js +3 -0
  99. package/dist/render/RenderComponent.d.ts +52 -0
  100. package/dist/render/RenderComponent.d.ts.map +1 -0
  101. package/dist/render/RenderComponent.js +104 -0
  102. package/dist/render/RenderSystem.d.ts.map +1 -0
  103. package/dist/render/RenderSystem.js +65 -0
  104. package/dist/spine/SpineComponent.d.ts +10 -0
  105. package/dist/spine/SpineComponent.d.ts.map +1 -0
  106. package/dist/spine/SpineComponent.js +3 -0
  107. package/dist/spine/SpineSystem.d.ts +5 -0
  108. package/dist/spine/SpineSystem.d.ts.map +1 -0
  109. package/dist/spine/SpineSystem.js +25 -0
  110. package/dist/spine/index.d.ts +3 -0
  111. package/dist/spine/index.d.ts.map +1 -0
  112. package/dist/spine/index.js +2 -0
  113. package/dist/spine/lib/BatchableSpineSlot.d.ts +59 -0
  114. package/dist/spine/lib/BatchableSpineSlot.d.ts.map +1 -0
  115. package/dist/spine/lib/BatchableSpineSlot.js +86 -0
  116. package/dist/spine/lib/Spine.d.ts +239 -0
  117. package/dist/spine/lib/Spine.d.ts.map +1 -0
  118. package/dist/spine/lib/Spine.js +628 -0
  119. package/dist/spine/lib/SpineDebugRenderer.d.ts +109 -0
  120. package/dist/spine/lib/SpineDebugRenderer.d.ts.map +1 -0
  121. package/dist/spine/lib/SpineDebugRenderer.js +474 -0
  122. package/dist/spine/lib/SpinePipe.d.ts +49 -0
  123. package/dist/spine/lib/SpinePipe.d.ts.map +1 -0
  124. package/dist/spine/lib/SpinePipe.js +148 -0
  125. package/dist/spine/lib/SpineTexture.d.ts +45 -0
  126. package/dist/spine/lib/SpineTexture.d.ts.map +1 -0
  127. package/dist/spine/lib/SpineTexture.js +114 -0
  128. package/dist/spine/lib/assets/atlasLoader.d.ts +34 -0
  129. package/dist/spine/lib/assets/atlasLoader.d.ts.map +1 -0
  130. package/dist/spine/lib/assets/atlasLoader.js +122 -0
  131. package/dist/spine/lib/assets/skeletonLoader.d.ts +30 -0
  132. package/dist/spine/lib/assets/skeletonLoader.d.ts.map +1 -0
  133. package/dist/spine/lib/assets/skeletonLoader.js +70 -0
  134. package/dist/spine/lib/darktint/DarkTintBatchGeometry.d.ts +33 -0
  135. package/dist/spine/lib/darktint/DarkTintBatchGeometry.d.ts.map +1 -0
  136. package/dist/spine/lib/darktint/DarkTintBatchGeometry.js +84 -0
  137. package/dist/spine/lib/darktint/DarkTintBatcher.d.ts +50 -0
  138. package/dist/spine/lib/darktint/DarkTintBatcher.d.ts.map +1 -0
  139. package/dist/spine/lib/darktint/DarkTintBatcher.js +131 -0
  140. package/dist/spine/lib/darktint/DarkTintShader.d.ts +33 -0
  141. package/dist/spine/lib/darktint/DarkTintShader.d.ts.map +1 -0
  142. package/dist/spine/lib/darktint/DarkTintShader.js +59 -0
  143. package/dist/spine/lib/darktint/darkTintBit.d.ts +51 -0
  144. package/dist/spine/lib/darktint/darkTintBit.d.ts.map +1 -0
  145. package/dist/spine/lib/darktint/darkTintBit.js +75 -0
  146. package/dist/spine/lib/index.d.ts +42 -0
  147. package/dist/spine/lib/index.d.ts.map +1 -0
  148. package/dist/spine/lib/index.js +41 -0
  149. package/dist/spine/lib/require-shim.d.ts +34 -0
  150. package/dist/spine/lib/require-shim.d.ts.map +1 -0
  151. package/dist/spine/lib/require-shim.js +38 -0
  152. package/package.json +12 -9
  153. package/dist/components/GUIComponent.d.ts.map +0 -1
  154. package/dist/components/GUIComponent.js +0 -126
  155. package/dist/components/RenderComponent.d.ts +0 -29
  156. package/dist/components/RenderComponent.d.ts.map +0 -1
  157. package/dist/components/RenderComponent.js +0 -58
  158. package/dist/systems/GUISystem.d.ts.map +0 -1
  159. package/dist/systems/GUISystem.js +0 -90
  160. package/dist/systems/RenderSystem.d.ts.map +0 -1
  161. package/dist/systems/RenderSystem.js +0 -67
  162. /package/dist/{systems → render}/RenderSystem.d.ts +0 -0
@@ -0,0 +1,628 @@
1
+ /** ****************************************************************************
2
+ * Spine Runtimes License Agreement
3
+ * Last updated July 28, 2023. Replaces all prior versions.
4
+ *
5
+ * Copyright (c) 2013-2023, Esoteric Software LLC
6
+ *
7
+ * Integration of the Spine Runtimes into software or otherwise creating
8
+ * derivative works of the Spine Runtimes is permitted under the terms and
9
+ * conditions of Section 2 of the Spine Editor License Agreement:
10
+ * http://esotericsoftware.com/spine-editor-license
11
+ *
12
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software or
13
+ * otherwise create derivative works of the Spine Runtimes (collectively,
14
+ * "Products"), provided that each user of the Products must obtain their own
15
+ * Spine Editor license and redistribution of the Products in any form must
16
+ * include this license and copyright notice.
17
+ *
18
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
19
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
24
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
27
+ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ *****************************************************************************/
29
+ import { Assets, Cache, Container, DEG_TO_RAD, fastCopy, Graphics, Texture, Ticker, ViewContainer, } from 'pixi.js';
30
+ import { AnimationState, AnimationStateData, AtlasAttachmentLoader, ClippingAttachment, Color, MeshAttachment, Physics, Pool, RegionAttachment, Skeleton, SkeletonBinary, SkeletonBounds, SkeletonClipping, SkeletonData, SkeletonJson, Vector2, } from '@esotericsoftware/spine-core';
31
+ ;
32
+ const vectorAux = new Vector2();
33
+ Skeleton.yDown = true;
34
+ const clipper = new SkeletonClipping();
35
+ ;
36
+ const maskPool = new Pool(() => new Graphics);
37
+ /**
38
+ * The class to instantiate a {@link Spine} game object in Pixi.
39
+ * The static method {@link Spine.from} should be used to instantiate a Spine game object.
40
+ */
41
+ export class Spine extends ViewContainer {
42
+ getSlotFromRef(slotRef) {
43
+ let slot;
44
+ if (typeof slotRef === 'number')
45
+ slot = this.skeleton.slots[slotRef];
46
+ else if (typeof slotRef === 'string')
47
+ slot = this.skeleton.findSlot(slotRef);
48
+ else
49
+ slot = slotRef;
50
+ if (!slot)
51
+ throw new Error(`No slot found with the given slot reference: ${slotRef}`);
52
+ return slot;
53
+ }
54
+ get debug() {
55
+ return this._debug;
56
+ }
57
+ /** Pass a {@link SpineDebugRenderer} or create your own {@link ISpineDebugRenderer} to render bones, meshes, ...
58
+ * @example spineGO.debug = new SpineDebugRenderer();
59
+ */
60
+ set debug(value) {
61
+ if (this._debug) {
62
+ this._debug.unregisterSpine(this);
63
+ }
64
+ if (value) {
65
+ value.registerSpine(this);
66
+ }
67
+ this._debug = value;
68
+ }
69
+ get autoUpdate() {
70
+ return this._autoUpdate;
71
+ }
72
+ /** When `true`, the Spine AnimationState and the Skeleton will be automatically updated using the {@link Ticker.shared} instance. */
73
+ set autoUpdate(value) {
74
+ if (value) {
75
+ Ticker.shared.add(this.internalUpdate, this);
76
+ }
77
+ else {
78
+ Ticker.shared.remove(this.internalUpdate, this);
79
+ }
80
+ this._autoUpdate = value;
81
+ }
82
+ constructor(options) {
83
+ var _a;
84
+ if (options instanceof SkeletonData) {
85
+ options = {
86
+ skeletonData: options,
87
+ };
88
+ }
89
+ super();
90
+ // Pixi properties
91
+ this.batched = true;
92
+ this.buildId = 0;
93
+ this.renderPipeId = 'spine';
94
+ this._didSpineUpdate = false;
95
+ this.beforeUpdateWorldTransforms = () => { };
96
+ this.afterUpdateWorldTransforms = () => { };
97
+ this.darkTint = false;
98
+ this._debug = undefined;
99
+ this._slotsObject = Object.create(null);
100
+ this.clippingSlotToPixiMasks = Object.create(null);
101
+ this.spineAttachmentsDirty = true;
102
+ this.spineTexturesDirty = true;
103
+ this._lastAttachments = [];
104
+ this._stateChanged = true;
105
+ this.attachmentCacheData = [];
106
+ this._autoUpdate = true;
107
+ this.hasNeverUpdated = true;
108
+ const skeletonData = options instanceof SkeletonData ? options : options.skeletonData;
109
+ this.skeleton = new Skeleton(skeletonData);
110
+ this.state = new AnimationState(new AnimationStateData(skeletonData));
111
+ this.autoUpdate = (_a = options === null || options === void 0 ? void 0 : options.autoUpdate) !== null && _a !== void 0 ? _a : true;
112
+ // dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
113
+ this.darkTint = (options === null || options === void 0 ? void 0 : options.darkTint) === undefined
114
+ ? this.skeleton.slots.some(slot => !!slot.data.darkColor)
115
+ : options === null || options === void 0 ? void 0 : options.darkTint;
116
+ const slots = this.skeleton.slots;
117
+ for (let i = 0; i < slots.length; i++) {
118
+ this.attachmentCacheData[i] = Object.create(null);
119
+ }
120
+ }
121
+ /** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
122
+ update(dt) {
123
+ this.internalUpdate(0, dt);
124
+ }
125
+ internalUpdate(_deltaFrame, deltaSeconds) {
126
+ // Because reasons, pixi uses deltaFrames at 60fps.
127
+ // We ignore the default deltaFrames and use the deltaSeconds from pixi ticker.
128
+ this._updateAndApplyState(deltaSeconds !== null && deltaSeconds !== void 0 ? deltaSeconds : Ticker.shared.deltaMS / 1000);
129
+ }
130
+ get bounds() {
131
+ if (this._boundsDirty) {
132
+ this.updateBounds();
133
+ }
134
+ return this._bounds;
135
+ }
136
+ /**
137
+ * Set the position of the bone given in input through a {@link IPointData}.
138
+ * @param bone: the bone name or the bone instance to set the position
139
+ * @param outPos: the new position of the bone.
140
+ * @throws {Error}: if the given bone is not found in the skeleton, an error is thrown
141
+ */
142
+ setBonePosition(bone, position) {
143
+ const boneAux = bone;
144
+ if (typeof bone === 'string') {
145
+ bone = this.skeleton.findBone(bone);
146
+ }
147
+ if (!bone)
148
+ throw Error(`Cant set bone position, bone ${String(boneAux)} not found`);
149
+ vectorAux.set(position.x, position.y);
150
+ if (bone.parent) {
151
+ const aux = bone.parent.worldToLocal(vectorAux);
152
+ bone.x = aux.x;
153
+ bone.y = -aux.y;
154
+ }
155
+ else {
156
+ bone.x = vectorAux.x;
157
+ bone.y = vectorAux.y;
158
+ }
159
+ }
160
+ /**
161
+ * Return the position of the bone given in input into an {@link IPointData}.
162
+ * @param bone: the bone name or the bone instance to get the position from
163
+ * @param outPos: an optional {@link IPointData} to use to return the bone position, rathern than instantiating a new object.
164
+ * @returns {IPointData | undefined}: the position of the bone, or undefined if no matching bone is found in the skeleton
165
+ */
166
+ getBonePosition(bone, outPos) {
167
+ const boneAux = bone;
168
+ if (typeof bone === 'string') {
169
+ bone = this.skeleton.findBone(bone);
170
+ }
171
+ if (!bone) {
172
+ console.error(`Cant set bone position! Bone ${String(boneAux)} not found`);
173
+ return outPos;
174
+ }
175
+ if (!outPos) {
176
+ outPos = { x: 0, y: 0 };
177
+ }
178
+ outPos.x = bone.worldX;
179
+ outPos.y = bone.worldY;
180
+ return outPos;
181
+ }
182
+ /**
183
+ * Advance the state and skeleton by the given time, then update slot objects too.
184
+ * The container transform is not updated.
185
+ *
186
+ * @param time the time at which to set the state
187
+ */
188
+ _updateAndApplyState(time) {
189
+ this.hasNeverUpdated = false;
190
+ this.state.update(time);
191
+ this.skeleton.update(time);
192
+ const { skeleton } = this;
193
+ this.state.apply(skeleton);
194
+ this.beforeUpdateWorldTransforms(this);
195
+ skeleton.updateWorldTransform(Physics.update);
196
+ this.afterUpdateWorldTransforms(this);
197
+ this.updateSlotObjects();
198
+ this._stateChanged = true;
199
+ this._boundsDirty = true;
200
+ this.onViewUpdate();
201
+ }
202
+ /**
203
+ * - validates the attachments - to flag if the attachments have changed this state
204
+ * - transforms the attachments - to update the vertices of the attachments based on the new positions
205
+ * @internal
206
+ */
207
+ _validateAndTransformAttachments() {
208
+ if (!this._stateChanged)
209
+ return;
210
+ this._stateChanged = false;
211
+ this.validateAttachments();
212
+ this.transformAttachments();
213
+ }
214
+ validateAttachments() {
215
+ const currentDrawOrder = this.skeleton.drawOrder;
216
+ const lastAttachments = this._lastAttachments;
217
+ let index = 0;
218
+ let spineAttachmentsDirty = false;
219
+ for (let i = 0; i < currentDrawOrder.length; i++) {
220
+ const slot = currentDrawOrder[i];
221
+ const attachment = slot.getAttachment();
222
+ if (attachment) {
223
+ if (attachment !== lastAttachments[index]) {
224
+ spineAttachmentsDirty = true;
225
+ lastAttachments[index] = attachment;
226
+ }
227
+ index++;
228
+ }
229
+ }
230
+ if (index !== lastAttachments.length) {
231
+ spineAttachmentsDirty = true;
232
+ lastAttachments.length = index;
233
+ }
234
+ this.spineAttachmentsDirty || (this.spineAttachmentsDirty = spineAttachmentsDirty);
235
+ }
236
+ updateAndSetPixiMask(slot, last) {
237
+ var _a, _b;
238
+ // assign/create the currentClippingSlot
239
+ const attachment = slot.attachment;
240
+ if (attachment && attachment instanceof ClippingAttachment) {
241
+ const clip = ((_a = this.clippingSlotToPixiMasks)[_b = slot.data.name] || (_a[_b] = { slot, vertices: new Array() }));
242
+ clip.maskComputed = false;
243
+ this.currentClippingSlot = this.clippingSlotToPixiMasks[slot.data.name];
244
+ return;
245
+ }
246
+ // assign the currentClippingSlot mask to the slot object
247
+ let currentClippingSlot = this.currentClippingSlot;
248
+ let slotObject = this._slotsObject[slot.data.name];
249
+ if (currentClippingSlot && slotObject) {
250
+ let slotClipping = currentClippingSlot.slot;
251
+ let clippingAttachment = slotClipping.attachment;
252
+ // create the pixi mask, only the first time and if the clipped slot is the first one clipped by this currentClippingSlot
253
+ let mask = currentClippingSlot.mask;
254
+ if (!mask) {
255
+ mask = maskPool.obtain();
256
+ currentClippingSlot.mask = mask;
257
+ this.addChild(mask);
258
+ }
259
+ // compute the pixi mask polygon, if the clipped slot is the first one clipped by this currentClippingSlot
260
+ if (!currentClippingSlot.maskComputed) {
261
+ currentClippingSlot.maskComputed = true;
262
+ const worldVerticesLength = clippingAttachment.worldVerticesLength;
263
+ const vertices = currentClippingSlot.vertices;
264
+ clippingAttachment.computeWorldVertices(slotClipping, 0, worldVerticesLength, vertices, 0, 2);
265
+ mask.clear().poly(vertices).stroke({ width: 0 }).fill({ alpha: .25 });
266
+ }
267
+ slotObject.container.mask = mask;
268
+ }
269
+ else if (slotObject === null || slotObject === void 0 ? void 0 : slotObject.container.mask) {
270
+ // remove the mask, if slot object has a mask, but currentClippingSlot is undefined
271
+ slotObject.container.mask = null;
272
+ }
273
+ // if current slot is the ending one of the currentClippingSlot mask, set currentClippingSlot to undefined
274
+ if (currentClippingSlot && currentClippingSlot.slot.attachment.endSlot == slot.data) {
275
+ this.currentClippingSlot = undefined;
276
+ }
277
+ // clean up unused masks
278
+ if (last) {
279
+ for (const key in this.clippingSlotToPixiMasks) {
280
+ const clippingSlotToPixiMask = this.clippingSlotToPixiMasks[key];
281
+ if ((!(clippingSlotToPixiMask.slot.attachment instanceof ClippingAttachment) || !clippingSlotToPixiMask.maskComputed) && clippingSlotToPixiMask.mask) {
282
+ this.removeChild(clippingSlotToPixiMask.mask);
283
+ maskPool.free(clippingSlotToPixiMask.mask);
284
+ clippingSlotToPixiMask.mask = undefined;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ transformAttachments() {
290
+ var _a;
291
+ const currentDrawOrder = this.skeleton.drawOrder;
292
+ for (let i = 0; i < currentDrawOrder.length; i++) {
293
+ const slot = currentDrawOrder[i];
294
+ this.updateAndSetPixiMask(slot, i === currentDrawOrder.length - 1);
295
+ const attachment = slot.getAttachment();
296
+ if (attachment) {
297
+ if (attachment instanceof MeshAttachment || attachment instanceof RegionAttachment) {
298
+ const cacheData = this._getCachedData(slot, attachment);
299
+ if (attachment instanceof RegionAttachment) {
300
+ attachment.computeWorldVertices(slot, cacheData.vertices, 0, 2);
301
+ }
302
+ else {
303
+ attachment.computeWorldVertices(slot, 0, attachment.worldVerticesLength, cacheData.vertices, 0, 2);
304
+ }
305
+ // sequences uvs are known only after computeWorldVertices is invoked
306
+ if (cacheData.uvs.length < attachment.uvs.length) {
307
+ cacheData.uvs = new Float32Array(attachment.uvs.length);
308
+ }
309
+ // need to copy because attachments uvs are shared among skeletons using the same atlas
310
+ fastCopy(attachment.uvs.buffer, cacheData.uvs.buffer);
311
+ const skeleton = slot.bone.skeleton;
312
+ const skeletonColor = skeleton.color;
313
+ const slotColor = slot.color;
314
+ const attachmentColor = attachment.color;
315
+ cacheData.color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, skeletonColor.a * slotColor.a * attachmentColor.a);
316
+ if (slot.darkColor) {
317
+ cacheData.darkColor.setFromColor(slot.darkColor);
318
+ }
319
+ cacheData.skipRender = cacheData.clipped = false;
320
+ const texture = ((_a = attachment.region) === null || _a === void 0 ? void 0 : _a.texture.texture) || Texture.EMPTY;
321
+ if (cacheData.texture !== texture) {
322
+ cacheData.texture = texture;
323
+ this.spineTexturesDirty = true;
324
+ }
325
+ if (clipper.isClipping()) {
326
+ this.updateClippingData(cacheData);
327
+ }
328
+ }
329
+ else if (attachment instanceof ClippingAttachment) {
330
+ clipper.clipStart(slot, attachment);
331
+ continue;
332
+ }
333
+ }
334
+ clipper.clipEndWithSlot(slot);
335
+ }
336
+ clipper.clipEnd();
337
+ }
338
+ updateClippingData(cacheData) {
339
+ cacheData.clipped = true;
340
+ clipper.clipTrianglesUnpacked(cacheData.vertices, cacheData.indices, cacheData.indices.length, cacheData.uvs);
341
+ const { clippedVertices, clippedUVs, clippedTriangles } = clipper;
342
+ const verticesCount = clippedVertices.length / 2;
343
+ const indicesCount = clippedTriangles.length;
344
+ if (!cacheData.clippedData) {
345
+ cacheData.clippedData = {
346
+ vertices: new Float32Array(verticesCount * 2),
347
+ uvs: new Float32Array(verticesCount * 2),
348
+ vertexCount: verticesCount,
349
+ indices: new Uint16Array(indicesCount),
350
+ indicesCount,
351
+ };
352
+ this.spineAttachmentsDirty = true;
353
+ }
354
+ const clippedData = cacheData.clippedData;
355
+ const sizeChange = clippedData.vertexCount !== verticesCount || indicesCount !== clippedData.indicesCount;
356
+ cacheData.skipRender = verticesCount === 0;
357
+ if (sizeChange) {
358
+ this.spineAttachmentsDirty = true;
359
+ if (clippedData.vertexCount < verticesCount) {
360
+ // buffer reuse!
361
+ clippedData.vertices = new Float32Array(verticesCount * 2);
362
+ clippedData.uvs = new Float32Array(verticesCount * 2);
363
+ }
364
+ if (clippedData.indices.length < indicesCount) {
365
+ clippedData.indices = new Uint16Array(indicesCount);
366
+ }
367
+ }
368
+ const { vertices, uvs, indices } = clippedData;
369
+ for (let i = 0; i < verticesCount; i++) {
370
+ vertices[i * 2] = clippedVertices[i * 2];
371
+ vertices[(i * 2) + 1] = clippedVertices[(i * 2) + 1];
372
+ uvs[i * 2] = clippedUVs[(i * 2)];
373
+ uvs[(i * 2) + 1] = clippedUVs[(i * 2) + 1];
374
+ }
375
+ clippedData.vertexCount = verticesCount;
376
+ for (let i = 0; i < indicesCount; i++) {
377
+ if (indices[i] !== clippedTriangles[i]) {
378
+ this.spineAttachmentsDirty = true;
379
+ indices[i] = clippedTriangles[i];
380
+ }
381
+ }
382
+ clippedData.indicesCount = indicesCount;
383
+ }
384
+ /**
385
+ * ensure that attached containers map correctly to their slots
386
+ * along with their position, rotation, scale, and visibility.
387
+ */
388
+ updateSlotObjects() {
389
+ for (const i in this._slotsObject) {
390
+ const slotAttachment = this._slotsObject[i];
391
+ if (!slotAttachment)
392
+ continue;
393
+ this.updateSlotObject(slotAttachment);
394
+ }
395
+ }
396
+ updateSlotObject(slotAttachment) {
397
+ const { slot, container } = slotAttachment;
398
+ container.visible = this.skeleton.drawOrder.includes(slot);
399
+ if (container.visible) {
400
+ const bone = slot.bone;
401
+ container.position.set(bone.worldX, bone.worldY);
402
+ container.scale.x = bone.getWorldScaleX();
403
+ container.scale.y = bone.getWorldScaleY();
404
+ container.rotation = bone.getWorldRotationX() * DEG_TO_RAD;
405
+ container.alpha = this.skeleton.color.a * slot.color.a;
406
+ }
407
+ }
408
+ /** @internal */
409
+ _getCachedData(slot, attachment) {
410
+ return this.attachmentCacheData[slot.data.index][attachment.name] || this.initCachedData(slot, attachment);
411
+ }
412
+ initCachedData(slot, attachment) {
413
+ var _a, _b;
414
+ let vertices;
415
+ if (attachment instanceof RegionAttachment) {
416
+ vertices = new Float32Array(8);
417
+ this.attachmentCacheData[slot.data.index][attachment.name] = {
418
+ id: `${slot.data.index}-${attachment.name}`,
419
+ vertices,
420
+ clipped: false,
421
+ indices: [0, 1, 2, 0, 2, 3],
422
+ uvs: new Float32Array(attachment.uvs.length),
423
+ color: new Color(1, 1, 1, 1),
424
+ darkColor: new Color(0, 0, 0, 0),
425
+ darkTint: this.darkTint,
426
+ skipRender: false,
427
+ texture: (_a = attachment.region) === null || _a === void 0 ? void 0 : _a.texture.texture,
428
+ };
429
+ }
430
+ else {
431
+ vertices = new Float32Array(attachment.worldVerticesLength);
432
+ this.attachmentCacheData[slot.data.index][attachment.name] = {
433
+ id: `${slot.data.index}-${attachment.name}`,
434
+ vertices,
435
+ clipped: false,
436
+ indices: attachment.triangles,
437
+ uvs: new Float32Array(attachment.uvs.length),
438
+ color: new Color(1, 1, 1, 1),
439
+ darkColor: new Color(0, 0, 0, 0),
440
+ darkTint: this.darkTint,
441
+ skipRender: false,
442
+ texture: (_b = attachment.region) === null || _b === void 0 ? void 0 : _b.texture.texture,
443
+ };
444
+ }
445
+ return this.attachmentCacheData[slot.data.index][attachment.name];
446
+ }
447
+ onViewUpdate() {
448
+ var _a;
449
+ // increment from the 12th bit!
450
+ this._didViewChangeTick++;
451
+ this._boundsDirty = true;
452
+ if (this.didViewUpdate)
453
+ return;
454
+ this.didViewUpdate = true;
455
+ const renderGroup = this.renderGroup || this.parentRenderGroup;
456
+ if (renderGroup) {
457
+ renderGroup.onChildViewUpdate(this);
458
+ }
459
+ (_a = this.debug) === null || _a === void 0 ? void 0 : _a.renderDebug(this);
460
+ }
461
+ /**
462
+ * Attaches a PixiJS container to a specified slot. This will map the world transform of the slots bone
463
+ * to the attached container. A container can only be attached to one slot at a time.
464
+ *
465
+ * @param container - The container to attach to the slot
466
+ * @param slotRef - The slot id or slot to attach to
467
+ */
468
+ addSlotObject(slot, container) {
469
+ var _a;
470
+ slot = this.getSlotFromRef(slot);
471
+ // need to check in on the container too...
472
+ for (const i in this._slotsObject) {
473
+ if (((_a = this._slotsObject[i]) === null || _a === void 0 ? void 0 : _a.container) === container) {
474
+ this.removeSlotObject(this._slotsObject[i].slot);
475
+ }
476
+ }
477
+ this.removeSlotObject(slot);
478
+ container.includeInBuild = false;
479
+ // TODO only add once??
480
+ this.addChild(container);
481
+ const slotObject = { container, slot };
482
+ this._slotsObject[slot.data.name] = slotObject;
483
+ this.updateSlotObject(slotObject);
484
+ }
485
+ /**
486
+ * Removes a PixiJS container from the slot it is attached to.
487
+ *
488
+ * @param container - The container to detach from the slot
489
+ * @param slotOrContainer - The container, slot id or slot to detach from
490
+ */
491
+ removeSlotObject(slotOrContainer) {
492
+ var _a, _b;
493
+ let containerToRemove;
494
+ if (slotOrContainer instanceof Container) {
495
+ for (const i in this._slotsObject) {
496
+ if (((_a = this._slotsObject[i]) === null || _a === void 0 ? void 0 : _a.container) === slotOrContainer) {
497
+ this._slotsObject[i] = null;
498
+ containerToRemove = slotOrContainer;
499
+ break;
500
+ }
501
+ }
502
+ }
503
+ else {
504
+ const slot = this.getSlotFromRef(slotOrContainer);
505
+ containerToRemove = (_b = this._slotsObject[slot.data.name]) === null || _b === void 0 ? void 0 : _b.container;
506
+ this._slotsObject[slot.data.name] = null;
507
+ }
508
+ if (containerToRemove) {
509
+ this.removeChild(containerToRemove);
510
+ containerToRemove.includeInBuild = true;
511
+ }
512
+ }
513
+ /**
514
+ * Returns a container attached to a slot, or undefined if no container is attached.
515
+ *
516
+ * @param slotRef - The slot id or slot to get the attachment from
517
+ * @returns - The container attached to the slot
518
+ */
519
+ getSlotObject(slot) {
520
+ var _a;
521
+ slot = this.getSlotFromRef(slot);
522
+ return (_a = this._slotsObject[slot.data.name]) === null || _a === void 0 ? void 0 : _a.container;
523
+ }
524
+ updateBounds() {
525
+ this._boundsDirty = false;
526
+ this.skeletonBounds || (this.skeletonBounds = new SkeletonBounds());
527
+ const skeletonBounds = this.skeletonBounds;
528
+ skeletonBounds.update(this.skeleton, true);
529
+ if (skeletonBounds.minX === Infinity) {
530
+ if (this.hasNeverUpdated) {
531
+ this._updateAndApplyState(0);
532
+ this._boundsDirty = false;
533
+ }
534
+ this._validateAndTransformAttachments();
535
+ const drawOrder = this.skeleton.drawOrder;
536
+ const bounds = this._bounds;
537
+ bounds.clear();
538
+ for (let i = 0; i < drawOrder.length; i++) {
539
+ const slot = drawOrder[i];
540
+ const attachment = slot.getAttachment();
541
+ if (attachment && (attachment instanceof RegionAttachment || attachment instanceof MeshAttachment)) {
542
+ const cacheData = this._getCachedData(slot, attachment);
543
+ bounds.addVertexData(cacheData.vertices, 0, cacheData.vertices.length);
544
+ }
545
+ }
546
+ }
547
+ else {
548
+ this._bounds.minX = skeletonBounds.minX;
549
+ this._bounds.minY = skeletonBounds.minY;
550
+ this._bounds.maxX = skeletonBounds.maxX;
551
+ this._bounds.maxY = skeletonBounds.maxY;
552
+ }
553
+ }
554
+ /** @internal */
555
+ addBounds(bounds) {
556
+ bounds.addBounds(this.bounds);
557
+ }
558
+ /**
559
+ * Destroys this sprite renderable and optionally its texture.
560
+ * @param options - Options parameter. A boolean will act as if all options
561
+ * have been set to that value
562
+ * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well
563
+ * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well
564
+ */
565
+ destroy(options = false) {
566
+ super.destroy(options);
567
+ Ticker.shared.remove(this.internalUpdate, this);
568
+ this.state.clearListeners();
569
+ this.debug = undefined;
570
+ this.skeleton = null;
571
+ this.state = null;
572
+ this._slotsObject = null;
573
+ this._lastAttachments.length = 0;
574
+ this.attachmentCacheData = null;
575
+ }
576
+ /** Converts a point from the skeleton coordinate system to the Pixi world coordinate system. */
577
+ skeletonToPixiWorldCoordinates(point) {
578
+ this.worldTransform.apply(point, point);
579
+ }
580
+ /** Converts a point from the Pixi world coordinate system to the skeleton coordinate system. */
581
+ pixiWorldCoordinatesToSkeleton(point) {
582
+ this.worldTransform.applyInverse(point, point);
583
+ }
584
+ /** Converts a point from the Pixi world coordinate system to the bone's local coordinate system. */
585
+ pixiWorldCoordinatesToBone(point, bone) {
586
+ this.pixiWorldCoordinatesToSkeleton(point);
587
+ if (bone.parent) {
588
+ bone.parent.worldToLocal(point);
589
+ }
590
+ else {
591
+ bone.worldToLocal(point);
592
+ }
593
+ }
594
+ /**
595
+ * Use this method to instantiate a Spine game object.
596
+ * Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
597
+ * ```
598
+ * PIXI.Assets.add("sackData", "./assets/sack-pro.skel");
599
+ * PIXI.Assets.add("sackAtlas", "./assets/sack-pma.atlas");
600
+ * await PIXI.Assets.load(["sackData", "sackAtlas"]);
601
+ * ```
602
+ * Once a Spine game object is created, its skeleton data is cached into {@link Cache} using the key:
603
+ * `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
604
+ *
605
+ * @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
606
+ * @returns {Spine} The Spine game object instantiated
607
+ */
608
+ static from({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true }) {
609
+ const cacheKey = `${skeleton}-${atlas}-${scale}`;
610
+ if (Cache.has(cacheKey)) {
611
+ return new Spine(Cache.get(cacheKey));
612
+ }
613
+ const skeletonAsset = Assets.get(skeleton);
614
+ const atlasAsset = Assets.get(atlas);
615
+ const attachmentLoader = new AtlasAttachmentLoader(atlasAsset);
616
+ const parser = skeletonAsset instanceof Uint8Array
617
+ ? new SkeletonBinary(attachmentLoader)
618
+ : new SkeletonJson(attachmentLoader);
619
+ parser.scale = scale;
620
+ const skeletonData = parser.readSkeletonData(skeletonAsset);
621
+ Cache.set(cacheKey, skeletonData);
622
+ return new Spine({
623
+ skeletonData,
624
+ darkTint,
625
+ autoUpdate,
626
+ });
627
+ }
628
+ }