@safe-engine/pixi 8.4.6 → 8.5.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.
- package/README.md +14 -23
- package/dist/box2d-wasm/ContactListener.d.ts +1 -1
- package/dist/box2d-wasm/ContactListener.d.ts.map +1 -1
- package/dist/box2d-wasm/ContactListener.js +50 -18
- package/dist/box2d-wasm/PhysicsComponent.d.ts +27 -30
- package/dist/box2d-wasm/PhysicsComponent.d.ts.map +1 -1
- package/dist/box2d-wasm/PhysicsComponent.js +44 -11
- package/dist/box2d-wasm/PhysicsSprite.d.ts +3 -0
- package/dist/box2d-wasm/PhysicsSprite.d.ts.map +1 -1
- package/dist/box2d-wasm/PhysicsSprite.js +24 -3
- package/dist/box2d-wasm/PhysicsSystem.d.ts +4 -2
- package/dist/box2d-wasm/PhysicsSystem.d.ts.map +1 -1
- package/dist/box2d-wasm/PhysicsSystem.js +134 -44
- package/dist/collider/CollideComponent.d.ts +27 -10
- package/dist/collider/CollideComponent.d.ts.map +1 -1
- package/dist/collider/CollideComponent.js +10 -12
- package/dist/collider/helper/Intersection.d.ts +6 -6
- package/dist/collider/helper/Intersection.d.ts.map +1 -1
- package/dist/collider/helper/Intersection.js +4 -4
- package/dist/components/NodeComp.js +1 -1
- package/dist/helper/utils.d.ts +0 -6
- package/dist/helper/utils.d.ts.map +1 -1
- package/dist/helper/utils.js +0 -12
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/{src/spine/lib/require-shim.ts → dist/spine/lib/assets/atlasLoader.d.ts} +5 -14
- package/dist/spine/lib/assets/atlasLoader.d.ts.map +1 -0
- package/dist/spine/lib/assets/atlasLoader.js +122 -0
- package/{src/spine/lib/darktint/DarkTintShader.ts → dist/spine/lib/assets/skeletonLoader.d.ts} +3 -47
- package/dist/spine/lib/assets/skeletonLoader.d.ts.map +1 -0
- package/dist/spine/lib/assets/skeletonLoader.js +70 -0
- package/package.json +6 -2
- package/.github/workflows/npm-publish.yml +0 -35
- package/dist/@types/safex.d.ts +0 -15
- package/src/@types/index.d.ts +0 -2
- package/src/app.ts +0 -91
- package/src/base/EnhancedComponent.ts +0 -38
- package/src/base/gworld.ts +0 -20
- package/src/base/index.ts +0 -14
- package/src/base/utils.ts +0 -23
- package/src/box2d-wasm/ContactListener.ts +0 -66
- package/src/box2d-wasm/PhysicsComponent.ts +0 -83
- package/src/box2d-wasm/PhysicsSprite.ts +0 -42
- package/src/box2d-wasm/PhysicsSystem.ts +0 -142
- package/src/box2d-wasm/debugDraw.ts +0 -249
- package/src/box2d-wasm/index.ts +0 -19
- package/src/collider/CollideComponent.ts +0 -257
- package/src/collider/CollideSystem.ts +0 -166
- package/src/collider/helper/Intersection.ts +0 -139
- package/src/collider/helper/utils.ts +0 -37
- package/src/collider/index.ts +0 -16
- package/src/components/BaseComponent.ts +0 -17
- package/src/components/NodeComp.ts +0 -442
- package/src/components/Scene.ts +0 -17
- package/src/core/Color.ts +0 -7
- package/src/core/LoadingBar.ts +0 -63
- package/src/core/NodePool.ts +0 -28
- package/src/core/Size.ts +0 -21
- package/src/core/Vec2.ts +0 -108
- package/src/core/director.ts +0 -11
- package/src/core/index.ts +0 -7
- package/src/core/loader.ts +0 -14
- package/src/core/math.ts +0 -22
- package/src/dragonbones/DragonBonesComponent.ts +0 -32
- package/src/dragonbones/DragonBonesSystem.ts +0 -35
- package/src/dragonbones/index.ts +0 -11
- package/src/gui/GUIComponent.ts +0 -155
- package/src/gui/GUISystem.ts +0 -125
- package/src/helper/utils.ts +0 -50
- package/src/index.ts +0 -19
- package/src/norender/NoRenderComponent.ts +0 -60
- package/src/norender/NoRenderSystem.ts +0 -67
- package/src/norender/Touch.ts +0 -37
- package/src/planck/PhysicsComponent.ts +0 -83
- package/src/planck/PhysicsSprite.ts +0 -43
- package/src/planck/PhysicsSystem.ts +0 -201
- package/src/planck/index.ts +0 -3
- package/src/render/RenderComponent.ts +0 -132
- package/src/render/RenderSystem.ts +0 -64
- package/src/richtext/RichTextComp.ts +0 -50
- package/src/richtext/RichTextSystem.ts +0 -26
- package/src/richtext/html-text-parser.ts +0 -87
- package/src/richtext/index.ts +0 -8
- package/src/spine/SpineComponent.ts +0 -18
- package/src/spine/SpineSystem.ts +0 -30
- package/src/spine/index.ts +0 -11
- package/src/spine/lib/BatchableSpineSlot.ts +0 -138
- package/src/spine/lib/Spine.ts +0 -894
- package/src/spine/lib/SpineDebugRenderer.ts +0 -615
- package/src/spine/lib/SpinePipe.ts +0 -203
- package/src/spine/lib/SpineTexture.ts +0 -143
- package/src/spine/lib/darktint/DarkTintBatchGeometry.ts +0 -92
- package/src/spine/lib/darktint/DarkTintBatcher.ts +0 -186
- package/src/spine/lib/darktint/darkTintBit.ts +0 -77
- package/src/spine/lib/index.ts +0 -43
- package/tsconfig.json +0 -18
- /package/{dist/@types → @types}/index.d.ts +0 -0
package/src/spine/lib/Spine.ts
DELETED
|
@@ -1,894 +0,0 @@
|
|
|
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
|
-
|
|
30
|
-
import {
|
|
31
|
-
AnimationState,
|
|
32
|
-
AnimationStateData,
|
|
33
|
-
AtlasAttachmentLoader,
|
|
34
|
-
Attachment,
|
|
35
|
-
Bone,
|
|
36
|
-
ClippingAttachment,
|
|
37
|
-
Color,
|
|
38
|
-
MeshAttachment,
|
|
39
|
-
Physics,
|
|
40
|
-
Pool,
|
|
41
|
-
RegionAttachment,
|
|
42
|
-
Skeleton,
|
|
43
|
-
SkeletonBinary,
|
|
44
|
-
SkeletonBounds,
|
|
45
|
-
SkeletonClipping,
|
|
46
|
-
SkeletonData,
|
|
47
|
-
SkeletonJson,
|
|
48
|
-
Slot,
|
|
49
|
-
type TextureAtlas,
|
|
50
|
-
TrackEntry,
|
|
51
|
-
Vector2,
|
|
52
|
-
} from '@esotericsoftware/spine-core'
|
|
53
|
-
import {
|
|
54
|
-
Assets,
|
|
55
|
-
Bounds,
|
|
56
|
-
Cache,
|
|
57
|
-
Container,
|
|
58
|
-
ContainerChild,
|
|
59
|
-
ContainerOptions,
|
|
60
|
-
DEG_TO_RAD,
|
|
61
|
-
DestroyOptions,
|
|
62
|
-
fastCopy,
|
|
63
|
-
Graphics,
|
|
64
|
-
PointData,
|
|
65
|
-
Texture,
|
|
66
|
-
Ticker,
|
|
67
|
-
ViewContainer,
|
|
68
|
-
} from 'pixi.js'
|
|
69
|
-
import { ISpineDebugRenderer } from './SpineDebugRenderer.js'
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Options to create a {@link Spine} using {@link Spine.from}.
|
|
73
|
-
*/
|
|
74
|
-
export interface SpineFromOptions {
|
|
75
|
-
/** the asset name for the skeleton `.skel` or `.json` file previously loaded into the Assets */
|
|
76
|
-
skeleton: string
|
|
77
|
-
|
|
78
|
-
/** the asset name for the atlas file previously loaded into the Assets */
|
|
79
|
-
atlas: string
|
|
80
|
-
|
|
81
|
-
/** The value passed to the skeleton reader. If omitted, 1 is passed. See {@link SkeletonBinary.scale} for details. */
|
|
82
|
-
scale?: number
|
|
83
|
-
|
|
84
|
-
/** Set the {@link Spine.autoUpdate} value. If omitted, it is set to `true`. */
|
|
85
|
-
autoUpdate?: boolean
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* If `true`, use the dark tint renderer to render the skeleton
|
|
89
|
-
* If `false`, use the default pixi renderer to render the skeleton
|
|
90
|
-
* If `undefined`, use the dark tint renderer if at least one slot has tint black
|
|
91
|
-
*/
|
|
92
|
-
darkTint?: boolean
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const vectorAux = new Vector2()
|
|
96
|
-
|
|
97
|
-
Skeleton.yDown = true
|
|
98
|
-
|
|
99
|
-
const clipper = new SkeletonClipping()
|
|
100
|
-
|
|
101
|
-
export interface SpineOptions extends ContainerOptions {
|
|
102
|
-
/** the {@link SkeletonData} used to instantiate the skeleton */
|
|
103
|
-
skeletonData: SkeletonData
|
|
104
|
-
|
|
105
|
-
/** See {@link SpineFromOptions.autoUpdate}. */
|
|
106
|
-
autoUpdate?: boolean
|
|
107
|
-
|
|
108
|
-
/** See {@link SpineFromOptions.darkTint}. */
|
|
109
|
-
darkTint?: boolean
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* AnimationStateListener {@link https://en.esotericsoftware.com/spine-api-reference#AnimationStateListener events} exposed for Pixi.
|
|
114
|
-
*/
|
|
115
|
-
export interface SpineEvents {
|
|
116
|
-
complete: [trackEntry: TrackEntry]
|
|
117
|
-
dispose: [trackEntry: TrackEntry]
|
|
118
|
-
end: [trackEntry: TrackEntry]
|
|
119
|
-
event: [trackEntry: TrackEntry, event: Event]
|
|
120
|
-
interrupt: [trackEntry: TrackEntry]
|
|
121
|
-
start: [trackEntry: TrackEntry]
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface AttachmentCacheData {
|
|
125
|
-
id: string
|
|
126
|
-
clipped: boolean
|
|
127
|
-
vertices: Float32Array
|
|
128
|
-
uvs: Float32Array
|
|
129
|
-
indices: number[]
|
|
130
|
-
color: Color
|
|
131
|
-
darkColor: Color
|
|
132
|
-
darkTint: boolean
|
|
133
|
-
skipRender: boolean
|
|
134
|
-
texture: Texture
|
|
135
|
-
clippedData?: {
|
|
136
|
-
vertices: Float32Array
|
|
137
|
-
uvs: Float32Array
|
|
138
|
-
indices: Uint16Array
|
|
139
|
-
vertexCount: number
|
|
140
|
-
indicesCount: number
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
interface SlotsToClipping {
|
|
145
|
-
slot: Slot
|
|
146
|
-
mask?: Graphics
|
|
147
|
-
maskComputed?: boolean
|
|
148
|
-
vertices: Array<number>
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const maskPool = new Pool<Graphics>(() => new Graphics())
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* The class to instantiate a {@link Spine} game object in Pixi.
|
|
155
|
-
* The static method {@link Spine.from} should be used to instantiate a Spine game object.
|
|
156
|
-
*/
|
|
157
|
-
export class Spine extends ViewContainer {
|
|
158
|
-
// Pixi properties
|
|
159
|
-
public batched = true
|
|
160
|
-
public buildId = 0
|
|
161
|
-
public override readonly renderPipeId = 'spine'
|
|
162
|
-
public _didSpineUpdate = false
|
|
163
|
-
|
|
164
|
-
public beforeUpdateWorldTransforms: (object: Spine) => void = () => {
|
|
165
|
-
/** */
|
|
166
|
-
}
|
|
167
|
-
public afterUpdateWorldTransforms: (object: Spine) => void = () => {
|
|
168
|
-
/** */
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Spine properties
|
|
172
|
-
/** The skeleton for this Spine game object. */
|
|
173
|
-
public skeleton: Skeleton
|
|
174
|
-
/** The animation state for this Spine game object. */
|
|
175
|
-
public state: AnimationState
|
|
176
|
-
public skeletonBounds?: SkeletonBounds
|
|
177
|
-
|
|
178
|
-
private darkTint = false
|
|
179
|
-
private _debug?: ISpineDebugRenderer | undefined = undefined
|
|
180
|
-
|
|
181
|
-
readonly _slotsObject: Record<string, { slot: Slot; container: Container } | null> = Object.create(null)
|
|
182
|
-
private clippingSlotToPixiMasks: Record<string, SlotsToClipping> = Object.create(null)
|
|
183
|
-
|
|
184
|
-
private getSlotFromRef(slotRef: number | string | Slot): Slot {
|
|
185
|
-
let slot: Slot | null
|
|
186
|
-
|
|
187
|
-
if (typeof slotRef === 'number') slot = this.skeleton.slots[slotRef]
|
|
188
|
-
else if (typeof slotRef === 'string') slot = this.skeleton.findSlot(slotRef)
|
|
189
|
-
else slot = slotRef
|
|
190
|
-
|
|
191
|
-
if (!slot) throw new Error(`No slot found with the given slot reference: ${slotRef}`)
|
|
192
|
-
|
|
193
|
-
return slot
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public spineAttachmentsDirty = true
|
|
197
|
-
public spineTexturesDirty = true
|
|
198
|
-
|
|
199
|
-
private _lastAttachments: Attachment[] = []
|
|
200
|
-
|
|
201
|
-
private _stateChanged = true
|
|
202
|
-
private attachmentCacheData: Record<string, AttachmentCacheData>[] = []
|
|
203
|
-
|
|
204
|
-
public get debug(): ISpineDebugRenderer | undefined {
|
|
205
|
-
return this._debug
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/** Pass a {@link SpineDebugRenderer} or create your own {@link ISpineDebugRenderer} to render bones, meshes, ...
|
|
209
|
-
* @example spineGO.debug = new SpineDebugRenderer();
|
|
210
|
-
*/
|
|
211
|
-
public set debug(value: ISpineDebugRenderer | undefined) {
|
|
212
|
-
if (this._debug) {
|
|
213
|
-
this._debug.unregisterSpine(this)
|
|
214
|
-
}
|
|
215
|
-
if (value) {
|
|
216
|
-
value.registerSpine(this)
|
|
217
|
-
}
|
|
218
|
-
this._debug = value
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private _autoUpdate = true
|
|
222
|
-
|
|
223
|
-
public get autoUpdate(): boolean {
|
|
224
|
-
return this._autoUpdate
|
|
225
|
-
}
|
|
226
|
-
/** When `true`, the Spine AnimationState and the Skeleton will be automatically updated using the {@link Ticker.shared} instance. */
|
|
227
|
-
public set autoUpdate(value: boolean) {
|
|
228
|
-
if (value) {
|
|
229
|
-
Ticker.shared.add(this.internalUpdate, this)
|
|
230
|
-
} else {
|
|
231
|
-
Ticker.shared.remove(this.internalUpdate, this)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
this._autoUpdate = value
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
private hasNeverUpdated = true
|
|
238
|
-
constructor(options: SpineOptions | SkeletonData) {
|
|
239
|
-
if (options instanceof SkeletonData) {
|
|
240
|
-
options = {
|
|
241
|
-
skeletonData: options,
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
super(options)
|
|
246
|
-
|
|
247
|
-
const skeletonData = options instanceof SkeletonData ? options : options.skeletonData
|
|
248
|
-
|
|
249
|
-
this.skeleton = new Skeleton(skeletonData)
|
|
250
|
-
this.state = new AnimationState(new AnimationStateData(skeletonData))
|
|
251
|
-
this.autoUpdate = options?.autoUpdate ?? true
|
|
252
|
-
|
|
253
|
-
// dark tint can be enabled by options, otherwise is enable if at least one slot has tint black
|
|
254
|
-
this.darkTint = options?.darkTint === undefined ? this.skeleton.slots.some((slot) => !!slot.data.darkColor) : options?.darkTint
|
|
255
|
-
|
|
256
|
-
const slots = this.skeleton.slots
|
|
257
|
-
|
|
258
|
-
for (let i = 0; i < slots.length; i++) {
|
|
259
|
-
this.attachmentCacheData[i] = Object.create(null)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
|
|
264
|
-
public update(dt: number): void {
|
|
265
|
-
this.internalUpdate(0, dt)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
protected internalUpdate(_deltaFrame: any, deltaSeconds?: number): void {
|
|
269
|
-
// Because reasons, pixi uses deltaFrames at 60fps.
|
|
270
|
-
// We ignore the default deltaFrames and use the deltaSeconds from pixi ticker.
|
|
271
|
-
this._updateAndApplyState(deltaSeconds ?? Ticker.shared.deltaMS / 1000)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
override get bounds() {
|
|
275
|
-
if (this._boundsDirty) {
|
|
276
|
-
this.updateBounds()
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return this._bounds
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Set the position of the bone given in input through a {@link IPointData}.
|
|
284
|
-
* @param bone: the bone name or the bone instance to set the position
|
|
285
|
-
* @param outPos: the new position of the bone.
|
|
286
|
-
* @throws {Error}: if the given bone is not found in the skeleton, an error is thrown
|
|
287
|
-
*/
|
|
288
|
-
public setBonePosition(bone: string | Bone, position: PointData): void {
|
|
289
|
-
const boneAux = bone
|
|
290
|
-
|
|
291
|
-
if (typeof bone === 'string') {
|
|
292
|
-
bone = this.skeleton.findBone(bone) as Bone
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (!bone) throw Error(`Cant set bone position, bone ${String(boneAux)} not found`)
|
|
296
|
-
vectorAux.set(position.x, position.y)
|
|
297
|
-
|
|
298
|
-
if (bone.parent) {
|
|
299
|
-
const aux = bone.parent.worldToLocal(vectorAux)
|
|
300
|
-
|
|
301
|
-
bone.x = aux.x
|
|
302
|
-
bone.y = -aux.y
|
|
303
|
-
} else {
|
|
304
|
-
bone.x = vectorAux.x
|
|
305
|
-
bone.y = vectorAux.y
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Return the position of the bone given in input into an {@link IPointData}.
|
|
311
|
-
* @param bone: the bone name or the bone instance to get the position from
|
|
312
|
-
* @param outPos: an optional {@link IPointData} to use to return the bone position, rathern than instantiating a new object.
|
|
313
|
-
* @returns {IPointData | undefined}: the position of the bone, or undefined if no matching bone is found in the skeleton
|
|
314
|
-
*/
|
|
315
|
-
public getBonePosition(bone: string | Bone, outPos?: PointData): PointData | undefined {
|
|
316
|
-
const boneAux = bone
|
|
317
|
-
|
|
318
|
-
if (typeof bone === 'string') {
|
|
319
|
-
bone = this.skeleton.findBone(bone) as Bone
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (!bone) {
|
|
323
|
-
console.error(`Cant set bone position! Bone ${String(boneAux)} not found`)
|
|
324
|
-
|
|
325
|
-
return outPos
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (!outPos) {
|
|
329
|
-
outPos = { x: 0, y: 0 }
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
outPos.x = bone.worldX
|
|
333
|
-
outPos.y = bone.worldY
|
|
334
|
-
|
|
335
|
-
return outPos
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Advance the state and skeleton by the given time, then update slot objects too.
|
|
340
|
-
* The container transform is not updated.
|
|
341
|
-
*
|
|
342
|
-
* @param time the time at which to set the state
|
|
343
|
-
*/
|
|
344
|
-
private _updateAndApplyState(time: number) {
|
|
345
|
-
this.hasNeverUpdated = false
|
|
346
|
-
|
|
347
|
-
this.state.update(time)
|
|
348
|
-
this.skeleton.update(time)
|
|
349
|
-
|
|
350
|
-
const { skeleton } = this
|
|
351
|
-
|
|
352
|
-
this.state.apply(skeleton)
|
|
353
|
-
|
|
354
|
-
this.beforeUpdateWorldTransforms(this)
|
|
355
|
-
skeleton.updateWorldTransform(Physics.update)
|
|
356
|
-
this.afterUpdateWorldTransforms(this)
|
|
357
|
-
|
|
358
|
-
this.updateSlotObjects()
|
|
359
|
-
|
|
360
|
-
this._stateChanged = true
|
|
361
|
-
|
|
362
|
-
this._boundsDirty = true
|
|
363
|
-
|
|
364
|
-
this.onViewUpdate()
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* - validates the attachments - to flag if the attachments have changed this state
|
|
369
|
-
* - transforms the attachments - to update the vertices of the attachments based on the new positions
|
|
370
|
-
* @internal
|
|
371
|
-
*/
|
|
372
|
-
_validateAndTransformAttachments() {
|
|
373
|
-
if (!this._stateChanged) return
|
|
374
|
-
this._stateChanged = false
|
|
375
|
-
|
|
376
|
-
this.validateAttachments()
|
|
377
|
-
|
|
378
|
-
this.transformAttachments()
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
private validateAttachments() {
|
|
382
|
-
const currentDrawOrder = this.skeleton.drawOrder
|
|
383
|
-
|
|
384
|
-
const lastAttachments = this._lastAttachments
|
|
385
|
-
|
|
386
|
-
let index = 0
|
|
387
|
-
|
|
388
|
-
let spineAttachmentsDirty = false
|
|
389
|
-
|
|
390
|
-
for (let i = 0; i < currentDrawOrder.length; i++) {
|
|
391
|
-
const slot = currentDrawOrder[i]
|
|
392
|
-
const attachment = slot.getAttachment()
|
|
393
|
-
|
|
394
|
-
if (attachment) {
|
|
395
|
-
if (attachment !== lastAttachments[index]) {
|
|
396
|
-
spineAttachmentsDirty = true
|
|
397
|
-
lastAttachments[index] = attachment
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
index++
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (index !== lastAttachments.length) {
|
|
405
|
-
spineAttachmentsDirty = true
|
|
406
|
-
lastAttachments.length = index
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
this.spineAttachmentsDirty ||= spineAttachmentsDirty
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
private updateAndSetPixiMask(slot: Slot, last: boolean) {
|
|
413
|
-
// assign/create the currentClippingSlot
|
|
414
|
-
const attachment = slot.attachment
|
|
415
|
-
if (attachment && attachment instanceof ClippingAttachment) {
|
|
416
|
-
const clip = (this.clippingSlotToPixiMasks[slot.data.name] ||= { slot, vertices: new Array<number>() })
|
|
417
|
-
clip.maskComputed = false
|
|
418
|
-
this.currentClippingSlot = this.clippingSlotToPixiMasks[slot.data.name]
|
|
419
|
-
return
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// assign the currentClippingSlot mask to the slot object
|
|
423
|
-
const currentClippingSlot = this.currentClippingSlot
|
|
424
|
-
const slotObject = this._slotsObject[slot.data.name]
|
|
425
|
-
if (currentClippingSlot && slotObject) {
|
|
426
|
-
const slotClipping = currentClippingSlot.slot
|
|
427
|
-
const clippingAttachment = slotClipping.attachment as ClippingAttachment
|
|
428
|
-
|
|
429
|
-
// create the pixi mask, only the first time and if the clipped slot is the first one clipped by this currentClippingSlot
|
|
430
|
-
let mask = currentClippingSlot.mask as Graphics
|
|
431
|
-
if (!mask) {
|
|
432
|
-
mask = maskPool.obtain()
|
|
433
|
-
currentClippingSlot.mask = mask
|
|
434
|
-
this.addChild(mask)
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// compute the pixi mask polygon, if the clipped slot is the first one clipped by this currentClippingSlot
|
|
438
|
-
if (!currentClippingSlot.maskComputed) {
|
|
439
|
-
currentClippingSlot.maskComputed = true
|
|
440
|
-
const worldVerticesLength = clippingAttachment.worldVerticesLength
|
|
441
|
-
const vertices = currentClippingSlot.vertices
|
|
442
|
-
clippingAttachment.computeWorldVertices(slotClipping, 0, worldVerticesLength, vertices, 0, 2)
|
|
443
|
-
mask.clear().poly(vertices).stroke({ width: 0 }).fill({ alpha: 0.25 })
|
|
444
|
-
}
|
|
445
|
-
slotObject.container.mask = mask
|
|
446
|
-
} else if (slotObject?.container.mask) {
|
|
447
|
-
// remove the mask, if slot object has a mask, but currentClippingSlot is undefined
|
|
448
|
-
slotObject.container.mask = null
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// if current slot is the ending one of the currentClippingSlot mask, set currentClippingSlot to undefined
|
|
452
|
-
if (currentClippingSlot && (currentClippingSlot.slot.attachment as ClippingAttachment).endSlot == slot.data) {
|
|
453
|
-
this.currentClippingSlot = undefined
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// clean up unused masks
|
|
457
|
-
if (last) {
|
|
458
|
-
for (const key in this.clippingSlotToPixiMasks) {
|
|
459
|
-
const clippingSlotToPixiMask = this.clippingSlotToPixiMasks[key]
|
|
460
|
-
if (
|
|
461
|
-
(!(clippingSlotToPixiMask.slot.attachment instanceof ClippingAttachment) || !clippingSlotToPixiMask.maskComputed) &&
|
|
462
|
-
clippingSlotToPixiMask.mask
|
|
463
|
-
) {
|
|
464
|
-
this.removeChild(clippingSlotToPixiMask.mask)
|
|
465
|
-
maskPool.free(clippingSlotToPixiMask.mask)
|
|
466
|
-
clippingSlotToPixiMask.mask = undefined
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
private currentClippingSlot: SlotsToClipping | undefined
|
|
473
|
-
private transformAttachments() {
|
|
474
|
-
const currentDrawOrder = this.skeleton.drawOrder
|
|
475
|
-
|
|
476
|
-
for (let i = 0; i < currentDrawOrder.length; i++) {
|
|
477
|
-
const slot = currentDrawOrder[i]
|
|
478
|
-
|
|
479
|
-
this.updateAndSetPixiMask(slot, i === currentDrawOrder.length - 1)
|
|
480
|
-
|
|
481
|
-
const attachment = slot.getAttachment()
|
|
482
|
-
|
|
483
|
-
if (attachment) {
|
|
484
|
-
if (attachment instanceof MeshAttachment || attachment instanceof RegionAttachment) {
|
|
485
|
-
const cacheData = this._getCachedData(slot, attachment)
|
|
486
|
-
|
|
487
|
-
if (attachment instanceof RegionAttachment) {
|
|
488
|
-
attachment.computeWorldVertices(slot, cacheData.vertices, 0, 2)
|
|
489
|
-
} else {
|
|
490
|
-
attachment.computeWorldVertices(slot, 0, attachment.worldVerticesLength, cacheData.vertices, 0, 2)
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// sequences uvs are known only after computeWorldVertices is invoked
|
|
494
|
-
if (cacheData.uvs.length < attachment.uvs.length) {
|
|
495
|
-
cacheData.uvs = new Float32Array(attachment.uvs.length)
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// need to copy because attachments uvs are shared among skeletons using the same atlas
|
|
499
|
-
fastCopy((attachment.uvs as Float32Array).buffer, cacheData.uvs.buffer)
|
|
500
|
-
|
|
501
|
-
const skeleton = slot.bone.skeleton
|
|
502
|
-
const skeletonColor = skeleton.color
|
|
503
|
-
const slotColor = slot.color
|
|
504
|
-
|
|
505
|
-
const attachmentColor = attachment.color
|
|
506
|
-
|
|
507
|
-
cacheData.color.set(
|
|
508
|
-
skeletonColor.r * slotColor.r * attachmentColor.r,
|
|
509
|
-
skeletonColor.g * slotColor.g * attachmentColor.g,
|
|
510
|
-
skeletonColor.b * slotColor.b * attachmentColor.b,
|
|
511
|
-
skeletonColor.a * slotColor.a * attachmentColor.a,
|
|
512
|
-
)
|
|
513
|
-
|
|
514
|
-
if (slot.darkColor) {
|
|
515
|
-
cacheData.darkColor.setFromColor(slot.darkColor)
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
cacheData.skipRender = cacheData.clipped = false
|
|
519
|
-
|
|
520
|
-
const texture = attachment.region?.texture.texture || Texture.EMPTY
|
|
521
|
-
|
|
522
|
-
if (cacheData.texture !== texture) {
|
|
523
|
-
cacheData.texture = texture
|
|
524
|
-
this.spineTexturesDirty = true
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (clipper.isClipping()) {
|
|
528
|
-
this.updateClippingData(cacheData)
|
|
529
|
-
}
|
|
530
|
-
} else if (attachment instanceof ClippingAttachment) {
|
|
531
|
-
clipper.clipStart(slot, attachment)
|
|
532
|
-
continue
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
clipper.clipEndWithSlot(slot)
|
|
536
|
-
}
|
|
537
|
-
clipper.clipEnd()
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
private updateClippingData(cacheData: AttachmentCacheData) {
|
|
541
|
-
cacheData.clipped = true
|
|
542
|
-
|
|
543
|
-
clipper.clipTrianglesUnpacked(cacheData.vertices, cacheData.indices, cacheData.indices.length, cacheData.uvs)
|
|
544
|
-
|
|
545
|
-
const { clippedVertices, clippedUVs, clippedTriangles } = clipper
|
|
546
|
-
|
|
547
|
-
const verticesCount = clippedVertices.length / 2
|
|
548
|
-
const indicesCount = clippedTriangles.length
|
|
549
|
-
|
|
550
|
-
if (!cacheData.clippedData) {
|
|
551
|
-
cacheData.clippedData = {
|
|
552
|
-
vertices: new Float32Array(verticesCount * 2),
|
|
553
|
-
uvs: new Float32Array(verticesCount * 2),
|
|
554
|
-
vertexCount: verticesCount,
|
|
555
|
-
indices: new Uint16Array(indicesCount),
|
|
556
|
-
indicesCount,
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
this.spineAttachmentsDirty = true
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const clippedData = cacheData.clippedData
|
|
563
|
-
|
|
564
|
-
const sizeChange = clippedData.vertexCount !== verticesCount || indicesCount !== clippedData.indicesCount
|
|
565
|
-
|
|
566
|
-
cacheData.skipRender = verticesCount === 0
|
|
567
|
-
|
|
568
|
-
if (sizeChange) {
|
|
569
|
-
this.spineAttachmentsDirty = true
|
|
570
|
-
|
|
571
|
-
if (clippedData.vertexCount < verticesCount) {
|
|
572
|
-
// buffer reuse!
|
|
573
|
-
clippedData.vertices = new Float32Array(verticesCount * 2)
|
|
574
|
-
clippedData.uvs = new Float32Array(verticesCount * 2)
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
if (clippedData.indices.length < indicesCount) {
|
|
578
|
-
clippedData.indices = new Uint16Array(indicesCount)
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
const { vertices, uvs, indices } = clippedData
|
|
583
|
-
|
|
584
|
-
for (let i = 0; i < verticesCount; i++) {
|
|
585
|
-
vertices[i * 2] = clippedVertices[i * 2]
|
|
586
|
-
vertices[i * 2 + 1] = clippedVertices[i * 2 + 1]
|
|
587
|
-
|
|
588
|
-
uvs[i * 2] = clippedUVs[i * 2]
|
|
589
|
-
uvs[i * 2 + 1] = clippedUVs[i * 2 + 1]
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
clippedData.vertexCount = verticesCount
|
|
593
|
-
|
|
594
|
-
for (let i = 0; i < indicesCount; i++) {
|
|
595
|
-
if (indices[i] !== clippedTriangles[i]) {
|
|
596
|
-
this.spineAttachmentsDirty = true
|
|
597
|
-
indices[i] = clippedTriangles[i]
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
clippedData.indicesCount = indicesCount
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* ensure that attached containers map correctly to their slots
|
|
606
|
-
* along with their position, rotation, scale, and visibility.
|
|
607
|
-
*/
|
|
608
|
-
private updateSlotObjects() {
|
|
609
|
-
for (const i in this._slotsObject) {
|
|
610
|
-
const slotAttachment = this._slotsObject[i]
|
|
611
|
-
|
|
612
|
-
if (!slotAttachment) continue
|
|
613
|
-
|
|
614
|
-
this.updateSlotObject(slotAttachment)
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
private updateSlotObject(slotAttachment: { slot: Slot; container: Container }) {
|
|
619
|
-
const { slot, container } = slotAttachment
|
|
620
|
-
|
|
621
|
-
container.visible = this.skeleton.drawOrder.includes(slot)
|
|
622
|
-
|
|
623
|
-
if (container.visible) {
|
|
624
|
-
const bone = slot.bone
|
|
625
|
-
|
|
626
|
-
container.position.set(bone.worldX, bone.worldY)
|
|
627
|
-
|
|
628
|
-
container.scale.x = bone.getWorldScaleX()
|
|
629
|
-
container.scale.y = bone.getWorldScaleY()
|
|
630
|
-
|
|
631
|
-
container.rotation = bone.getWorldRotationX() * DEG_TO_RAD
|
|
632
|
-
|
|
633
|
-
container.alpha = this.skeleton.color.a * slot.color.a
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/** @internal */
|
|
638
|
-
_getCachedData(slot: Slot, attachment: RegionAttachment | MeshAttachment): AttachmentCacheData {
|
|
639
|
-
return this.attachmentCacheData[slot.data.index][attachment.name] || this.initCachedData(slot, attachment)
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
private initCachedData(slot: Slot, attachment: RegionAttachment | MeshAttachment): AttachmentCacheData {
|
|
643
|
-
let vertices: Float32Array
|
|
644
|
-
|
|
645
|
-
if (attachment instanceof RegionAttachment) {
|
|
646
|
-
vertices = new Float32Array(8)
|
|
647
|
-
|
|
648
|
-
this.attachmentCacheData[slot.data.index][attachment.name] = {
|
|
649
|
-
id: `${slot.data.index}-${attachment.name}`,
|
|
650
|
-
vertices,
|
|
651
|
-
clipped: false,
|
|
652
|
-
indices: [0, 1, 2, 0, 2, 3],
|
|
653
|
-
uvs: new Float32Array(attachment.uvs.length),
|
|
654
|
-
color: new Color(1, 1, 1, 1),
|
|
655
|
-
darkColor: new Color(0, 0, 0, 0),
|
|
656
|
-
darkTint: this.darkTint,
|
|
657
|
-
skipRender: false,
|
|
658
|
-
texture: attachment.region?.texture.texture,
|
|
659
|
-
}
|
|
660
|
-
} else {
|
|
661
|
-
vertices = new Float32Array(attachment.worldVerticesLength)
|
|
662
|
-
|
|
663
|
-
this.attachmentCacheData[slot.data.index][attachment.name] = {
|
|
664
|
-
id: `${slot.data.index}-${attachment.name}`,
|
|
665
|
-
vertices,
|
|
666
|
-
clipped: false,
|
|
667
|
-
indices: attachment.triangles,
|
|
668
|
-
uvs: new Float32Array(attachment.uvs.length),
|
|
669
|
-
color: new Color(1, 1, 1, 1),
|
|
670
|
-
darkColor: new Color(0, 0, 0, 0),
|
|
671
|
-
darkTint: this.darkTint,
|
|
672
|
-
skipRender: false,
|
|
673
|
-
texture: attachment.region?.texture.texture,
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
return this.attachmentCacheData[slot.data.index][attachment.name]
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
protected onViewUpdate() {
|
|
681
|
-
// increment from the 12th bit!
|
|
682
|
-
this._didViewChangeTick++
|
|
683
|
-
this._boundsDirty = true
|
|
684
|
-
|
|
685
|
-
if (this.didViewUpdate) return
|
|
686
|
-
this.didViewUpdate = true
|
|
687
|
-
|
|
688
|
-
const renderGroup = this.renderGroup || this.parentRenderGroup
|
|
689
|
-
|
|
690
|
-
if (renderGroup) {
|
|
691
|
-
renderGroup.onChildViewUpdate(this)
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
this.debug?.renderDebug(this)
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
/**
|
|
698
|
-
* Attaches a PixiJS container to a specified slot. This will map the world transform of the slots bone
|
|
699
|
-
* to the attached container. A container can only be attached to one slot at a time.
|
|
700
|
-
*
|
|
701
|
-
* @param container - The container to attach to the slot
|
|
702
|
-
* @param slotRef - The slot id or slot to attach to
|
|
703
|
-
*/
|
|
704
|
-
public addSlotObject(slot: number | string | Slot, container: Container) {
|
|
705
|
-
slot = this.getSlotFromRef(slot)
|
|
706
|
-
|
|
707
|
-
// need to check in on the container too...
|
|
708
|
-
for (const i in this._slotsObject) {
|
|
709
|
-
if (this._slotsObject[i]?.container === container) {
|
|
710
|
-
this.removeSlotObject(this._slotsObject[i].slot)
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
this.removeSlotObject(slot)
|
|
715
|
-
|
|
716
|
-
container.includeInBuild = false
|
|
717
|
-
|
|
718
|
-
// TODO only add once??
|
|
719
|
-
this.addChild(container)
|
|
720
|
-
|
|
721
|
-
const slotObject = { container, slot }
|
|
722
|
-
this._slotsObject[slot.data.name] = slotObject
|
|
723
|
-
|
|
724
|
-
this.updateSlotObject(slotObject)
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
/**
|
|
728
|
-
* Removes a PixiJS container from the slot it is attached to.
|
|
729
|
-
*
|
|
730
|
-
* @param container - The container to detach from the slot
|
|
731
|
-
* @param slotOrContainer - The container, slot id or slot to detach from
|
|
732
|
-
*/
|
|
733
|
-
public removeSlotObject(slotOrContainer: number | string | Slot | Container) {
|
|
734
|
-
let containerToRemove: Container | undefined
|
|
735
|
-
|
|
736
|
-
if (slotOrContainer instanceof Container) {
|
|
737
|
-
for (const i in this._slotsObject) {
|
|
738
|
-
if (this._slotsObject[i]?.container === slotOrContainer) {
|
|
739
|
-
this._slotsObject[i] = null
|
|
740
|
-
|
|
741
|
-
containerToRemove = slotOrContainer
|
|
742
|
-
break
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
} else {
|
|
746
|
-
const slot = this.getSlotFromRef(slotOrContainer)
|
|
747
|
-
|
|
748
|
-
containerToRemove = this._slotsObject[slot.data.name]?.container
|
|
749
|
-
this._slotsObject[slot.data.name] = null
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
if (containerToRemove) {
|
|
753
|
-
this.removeChild(containerToRemove)
|
|
754
|
-
|
|
755
|
-
containerToRemove.includeInBuild = true
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* Returns a container attached to a slot, or undefined if no container is attached.
|
|
761
|
-
*
|
|
762
|
-
* @param slotRef - The slot id or slot to get the attachment from
|
|
763
|
-
* @returns - The container attached to the slot
|
|
764
|
-
*/
|
|
765
|
-
public getSlotObject(slot: number | string | Slot): Container<ContainerChild> {
|
|
766
|
-
slot = this.getSlotFromRef(slot)
|
|
767
|
-
|
|
768
|
-
return this._slotsObject[slot.data.name]?.container
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
protected updateBounds() {
|
|
772
|
-
this._boundsDirty = false
|
|
773
|
-
|
|
774
|
-
this.skeletonBounds ||= new SkeletonBounds()
|
|
775
|
-
|
|
776
|
-
const skeletonBounds = this.skeletonBounds
|
|
777
|
-
|
|
778
|
-
skeletonBounds.update(this.skeleton, true)
|
|
779
|
-
|
|
780
|
-
if (skeletonBounds.minX === Infinity) {
|
|
781
|
-
if (this.hasNeverUpdated) {
|
|
782
|
-
this._updateAndApplyState(0)
|
|
783
|
-
this._boundsDirty = false
|
|
784
|
-
}
|
|
785
|
-
this._validateAndTransformAttachments()
|
|
786
|
-
|
|
787
|
-
const drawOrder = this.skeleton.drawOrder
|
|
788
|
-
const bounds = this._bounds
|
|
789
|
-
|
|
790
|
-
bounds.clear()
|
|
791
|
-
|
|
792
|
-
for (let i = 0; i < drawOrder.length; i++) {
|
|
793
|
-
const slot = drawOrder[i]
|
|
794
|
-
|
|
795
|
-
const attachment = slot.getAttachment()
|
|
796
|
-
|
|
797
|
-
if (attachment && (attachment instanceof RegionAttachment || attachment instanceof MeshAttachment)) {
|
|
798
|
-
const cacheData = this._getCachedData(slot, attachment)
|
|
799
|
-
|
|
800
|
-
bounds.addVertexData(cacheData.vertices, 0, cacheData.vertices.length)
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
} else {
|
|
804
|
-
this._bounds.minX = skeletonBounds.minX
|
|
805
|
-
this._bounds.minY = skeletonBounds.minY
|
|
806
|
-
this._bounds.maxX = skeletonBounds.maxX
|
|
807
|
-
this._bounds.maxY = skeletonBounds.maxY
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
/** @internal */
|
|
812
|
-
addBounds(bounds: Bounds) {
|
|
813
|
-
bounds.addBounds(this.bounds)
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
/**
|
|
817
|
-
* Destroys this sprite renderable and optionally its texture.
|
|
818
|
-
* @param options - Options parameter. A boolean will act as if all options
|
|
819
|
-
* have been set to that value
|
|
820
|
-
* @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well
|
|
821
|
-
* @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well
|
|
822
|
-
*/
|
|
823
|
-
public override destroy(options: DestroyOptions = false) {
|
|
824
|
-
super.destroy(options)
|
|
825
|
-
|
|
826
|
-
Ticker.shared.remove(this.internalUpdate, this)
|
|
827
|
-
this.state.clearListeners()
|
|
828
|
-
this.debug = undefined
|
|
829
|
-
this.skeleton = null as any
|
|
830
|
-
this.state = null as any
|
|
831
|
-
;(this._slotsObject as any) = null
|
|
832
|
-
this._lastAttachments.length = 0
|
|
833
|
-
this.attachmentCacheData = null as any
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
/** Converts a point from the skeleton coordinate system to the Pixi world coordinate system. */
|
|
837
|
-
public skeletonToPixiWorldCoordinates(point: { x: number; y: number }) {
|
|
838
|
-
this.worldTransform.apply(point, point)
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
/** Converts a point from the Pixi world coordinate system to the skeleton coordinate system. */
|
|
842
|
-
public pixiWorldCoordinatesToSkeleton(point: { x: number; y: number }) {
|
|
843
|
-
this.worldTransform.applyInverse(point, point)
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
/** Converts a point from the Pixi world coordinate system to the bone's local coordinate system. */
|
|
847
|
-
public pixiWorldCoordinatesToBone(point: { x: number; y: number }, bone: Bone) {
|
|
848
|
-
this.pixiWorldCoordinatesToSkeleton(point)
|
|
849
|
-
if (bone.parent) {
|
|
850
|
-
bone.parent.worldToLocal(point as Vector2)
|
|
851
|
-
} else {
|
|
852
|
-
bone.worldToLocal(point as Vector2)
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
/**
|
|
857
|
-
* Use this method to instantiate a Spine game object.
|
|
858
|
-
* Before instantiating a Spine game object, the skeleton (`.skel` or `.json`) and the atlas text files must be loaded into the Assets. For example:
|
|
859
|
-
* ```
|
|
860
|
-
* PIXI.Assets.add("sackData", "./assets/sack-pro.skel");
|
|
861
|
-
* PIXI.Assets.add("sackAtlas", "./assets/sack-pma.atlas");
|
|
862
|
-
* await PIXI.Assets.load(["sackData", "sackAtlas"]);
|
|
863
|
-
* ```
|
|
864
|
-
* Once a Spine game object is created, its skeleton data is cached into {@link Cache} using the key:
|
|
865
|
-
* `${skeletonAssetName}-${atlasAssetName}-${options?.scale ?? 1}`
|
|
866
|
-
*
|
|
867
|
-
* @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
|
|
868
|
-
* @returns {Spine} The Spine game object instantiated
|
|
869
|
-
*/
|
|
870
|
-
static from({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true }: SpineFromOptions) {
|
|
871
|
-
const cacheKey = `${skeleton}-${atlas}-${scale}`
|
|
872
|
-
|
|
873
|
-
if (Cache.has(cacheKey)) {
|
|
874
|
-
return new Spine(Cache.get<SkeletonData>(cacheKey))
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
const skeletonAsset = Assets.get<any | Uint8Array>(skeleton)
|
|
878
|
-
|
|
879
|
-
const atlasAsset = Assets.get<TextureAtlas>(atlas)
|
|
880
|
-
const attachmentLoader = new AtlasAttachmentLoader(atlasAsset)
|
|
881
|
-
const parser = skeletonAsset instanceof Uint8Array ? new SkeletonBinary(attachmentLoader) : new SkeletonJson(attachmentLoader)
|
|
882
|
-
|
|
883
|
-
parser.scale = scale
|
|
884
|
-
const skeletonData = parser.readSkeletonData(skeletonAsset)
|
|
885
|
-
|
|
886
|
-
Cache.set(cacheKey, skeletonData)
|
|
887
|
-
|
|
888
|
-
return new Spine({
|
|
889
|
-
skeletonData,
|
|
890
|
-
darkTint,
|
|
891
|
-
autoUpdate,
|
|
892
|
-
})
|
|
893
|
-
}
|
|
894
|
-
}
|