@esotericsoftware/spine-pixi-v8 4.2.71 → 4.2.73

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.
@@ -7022,7 +7022,7 @@ var PhysicsConstraint = class {
7022
7022
  }
7023
7023
  if (a >= t) {
7024
7024
  d = Math.pow(this.damping, 60 * t);
7025
- const m = this.massInverse * t, e = this.strength, w = this.wind * f * skeleton.scaleX, g = (Skeleton.yDown ? -this.gravity : this.gravity) * f * skeleton.scaleY;
7025
+ const m = this.massInverse * t, e = this.strength, w = this.wind * f * skeleton.scaleX, g = this.gravity * f * skeleton.scaleY;
7026
7026
  do {
7027
7027
  if (x) {
7028
7028
  this.xVelocity += (w - this.xOffset * e) * m;
@@ -7977,10 +7977,10 @@ var _Skeleton = class {
7977
7977
  }
7978
7978
  /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`.
7979
7979
  * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */
7980
- getBoundsRect() {
7980
+ getBoundsRect(clipper2) {
7981
7981
  let offset = new Vector2();
7982
7982
  let size = new Vector2();
7983
- this.getBounds(offset, size);
7983
+ this.getBounds(offset, size, void 0, clipper2);
7984
7984
  return { x: offset.x, y: offset.y, width: size.x, height: size.y };
7985
7985
  }
7986
7986
  /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
@@ -12381,6 +12381,97 @@ import {
12381
12381
  var vectorAux = new Vector2();
12382
12382
  Skeleton.yDown = true;
12383
12383
  var clipper = new SkeletonClipping();
12384
+ var AABBRectangleBoundsProvider = class {
12385
+ constructor(x, y, width, height) {
12386
+ this.x = x;
12387
+ this.y = y;
12388
+ this.width = width;
12389
+ this.height = height;
12390
+ }
12391
+ calculateBounds() {
12392
+ return { x: this.x, y: this.y, width: this.width, height: this.height };
12393
+ }
12394
+ };
12395
+ var SetupPoseBoundsProvider = class {
12396
+ /**
12397
+ * @param clipping If true, clipping attachments are used to compute the bounds. False, by default.
12398
+ */
12399
+ constructor(clipping = false) {
12400
+ this.clipping = clipping;
12401
+ }
12402
+ calculateBounds(gameObject) {
12403
+ if (!gameObject.skeleton)
12404
+ return { x: 0, y: 0, width: 0, height: 0 };
12405
+ const skeleton = new Skeleton(gameObject.skeleton.data);
12406
+ skeleton.setToSetupPose();
12407
+ skeleton.updateWorldTransform(2 /* update */);
12408
+ const bounds = skeleton.getBoundsRect(this.clipping ? new SkeletonClipping() : void 0);
12409
+ return bounds.width == Number.NEGATIVE_INFINITY ? { x: 0, y: 0, width: 0, height: 0 } : bounds;
12410
+ }
12411
+ };
12412
+ var SkinsAndAnimationBoundsProvider = class {
12413
+ /**
12414
+ * @param animation The animation to use for calculating the bounds. If null, the setup pose is used.
12415
+ * @param skins The skins to use for calculating the bounds. If empty, the default skin is used.
12416
+ * @param timeStep The time step to use for calculating the bounds. A smaller time step means more precision, but slower calculation.
12417
+ * @param clipping If true, clipping attachments are used to compute the bounds. False, by default.
12418
+ */
12419
+ constructor(animation, skins = [], timeStep = 0.05, clipping = false) {
12420
+ this.animation = animation;
12421
+ this.skins = skins;
12422
+ this.timeStep = timeStep;
12423
+ this.clipping = clipping;
12424
+ }
12425
+ calculateBounds(gameObject) {
12426
+ if (!gameObject.skeleton || !gameObject.state)
12427
+ return { x: 0, y: 0, width: 0, height: 0 };
12428
+ const animationState = new AnimationState(gameObject.state.data);
12429
+ const skeleton = new Skeleton(gameObject.skeleton.data);
12430
+ const clipper2 = this.clipping ? new SkeletonClipping() : void 0;
12431
+ const data = skeleton.data;
12432
+ if (this.skins.length > 0) {
12433
+ let customSkin = new Skin("custom-skin");
12434
+ for (const skinName of this.skins) {
12435
+ const skin = data.findSkin(skinName);
12436
+ if (skin == null)
12437
+ continue;
12438
+ customSkin.addSkin(skin);
12439
+ }
12440
+ skeleton.setSkin(customSkin);
12441
+ }
12442
+ skeleton.setToSetupPose();
12443
+ const animation = this.animation != null ? data.findAnimation(this.animation) : null;
12444
+ if (animation == null) {
12445
+ skeleton.updateWorldTransform(2 /* update */);
12446
+ const bounds = skeleton.getBoundsRect(clipper2);
12447
+ return bounds.width == Number.NEGATIVE_INFINITY ? { x: 0, y: 0, width: 0, height: 0 } : bounds;
12448
+ } else {
12449
+ let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
12450
+ animationState.clearTracks();
12451
+ animationState.setAnimationWith(0, animation, false);
12452
+ const steps = Math.max(animation.duration / this.timeStep, 1);
12453
+ for (let i = 0; i < steps; i++) {
12454
+ const delta = i > 0 ? this.timeStep : 0;
12455
+ animationState.update(delta);
12456
+ animationState.apply(skeleton);
12457
+ skeleton.update(delta);
12458
+ skeleton.updateWorldTransform(2 /* update */);
12459
+ const bounds2 = skeleton.getBoundsRect(clipper2);
12460
+ minX = Math.min(minX, bounds2.x);
12461
+ minY = Math.min(minY, bounds2.y);
12462
+ maxX = Math.max(maxX, bounds2.x + bounds2.width);
12463
+ maxY = Math.max(maxY, bounds2.y + bounds2.height);
12464
+ }
12465
+ const bounds = {
12466
+ x: minX,
12467
+ y: minY,
12468
+ width: maxX - minX,
12469
+ height: maxY - minY
12470
+ };
12471
+ return bounds.width == Number.NEGATIVE_INFINITY ? { x: 0, y: 0, width: 0, height: 0 } : bounds;
12472
+ }
12473
+ }
12474
+ };
12384
12475
  var maskPool = new Pool(() => new Graphics());
12385
12476
  var Spine = class extends ViewContainer {
12386
12477
  // Pixi properties
@@ -12447,6 +12538,18 @@ var Spine = class extends ViewContainer {
12447
12538
  }
12448
12539
  this._autoUpdate = value;
12449
12540
  }
12541
+ _boundsProvider;
12542
+ /** The bounds provider to use. If undefined the bounds will be dynamic, calculated when requested and based on the current frame. */
12543
+ get boundsProvider() {
12544
+ return this._boundsProvider;
12545
+ }
12546
+ set boundsProvider(value) {
12547
+ this._boundsProvider = value;
12548
+ if (value) {
12549
+ this._boundsDirty = false;
12550
+ }
12551
+ this.updateBounds();
12552
+ }
12450
12553
  hasNeverUpdated = true;
12451
12554
  constructor(options) {
12452
12555
  if (options instanceof SkeletonData) {
@@ -12464,6 +12567,7 @@ var Spine = class extends ViewContainer {
12464
12567
  for (let i = 0; i < slots.length; i++) {
12465
12568
  this.attachmentCacheData[i] = /* @__PURE__ */ Object.create(null);
12466
12569
  }
12570
+ this._boundsProvider = options.boundsProvider;
12467
12571
  }
12468
12572
  /** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
12469
12573
  update(dt) {
@@ -12540,7 +12644,6 @@ var Spine = class extends ViewContainer {
12540
12644
  this.afterUpdateWorldTransforms(this);
12541
12645
  this.updateSlotObjects();
12542
12646
  this._stateChanged = true;
12543
- this._boundsDirty = true;
12544
12647
  this.onViewUpdate();
12545
12648
  }
12546
12649
  /**
@@ -12792,7 +12895,9 @@ var Spine = class extends ViewContainer {
12792
12895
  }
12793
12896
  onViewUpdate() {
12794
12897
  this._didViewChangeTick++;
12795
- this._boundsDirty = true;
12898
+ if (!this._boundsProvider) {
12899
+ this._boundsDirty = true;
12900
+ }
12796
12901
  if (this.didViewUpdate)
12797
12902
  return;
12798
12903
  this.didViewUpdate = true;
@@ -12880,7 +12985,15 @@ var Spine = class extends ViewContainer {
12880
12985
  this.skeletonBounds ||= new SkeletonBounds();
12881
12986
  const skeletonBounds = this.skeletonBounds;
12882
12987
  skeletonBounds.update(this.skeleton, true);
12883
- if (skeletonBounds.minX === Infinity) {
12988
+ if (this._boundsProvider) {
12989
+ const boundsSpine = this._boundsProvider.calculateBounds(this);
12990
+ const bounds = this._bounds;
12991
+ bounds.clear();
12992
+ bounds.x = boundsSpine.x;
12993
+ bounds.y = boundsSpine.y;
12994
+ bounds.width = boundsSpine.width;
12995
+ bounds.height = boundsSpine.height;
12996
+ } else if (skeletonBounds.minX === Infinity) {
12884
12997
  if (this.hasNeverUpdated) {
12885
12998
  this._updateAndApplyState(0);
12886
12999
  this._boundsDirty = false;
@@ -12957,10 +13070,15 @@ var Spine = class extends ViewContainer {
12957
13070
  * @param options - Options to configure the Spine game object. See {@link SpineFromOptions}
12958
13071
  * @returns {Spine} The Spine game object instantiated
12959
13072
  */
12960
- static from({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true }) {
13073
+ static from({ skeleton, atlas, scale = 1, darkTint, autoUpdate = true, boundsProvider }) {
12961
13074
  const cacheKey = `${skeleton}-${atlas}-${scale}`;
12962
13075
  if (Cache.has(cacheKey)) {
12963
- return new Spine(Cache.get(cacheKey));
13076
+ return new Spine({
13077
+ skeletonData: Cache.get(cacheKey),
13078
+ darkTint,
13079
+ autoUpdate,
13080
+ boundsProvider
13081
+ });
12964
13082
  }
12965
13083
  const skeletonAsset = Assets.get(skeleton);
12966
13084
  const atlasAsset = Assets.get(atlas);
@@ -12972,7 +13090,8 @@ var Spine = class extends ViewContainer {
12972
13090
  return new Spine({
12973
13091
  skeletonData,
12974
13092
  darkTint,
12975
- autoUpdate
13093
+ autoUpdate,
13094
+ boundsProvider
12976
13095
  });
12977
13096
  }
12978
13097
  };
@@ -13366,6 +13485,7 @@ var SpineDebugRenderer = class {
13366
13485
  }
13367
13486
  };
13368
13487
  export {
13488
+ AABBRectangleBoundsProvider,
13369
13489
  AlphaTimeline,
13370
13490
  Animation,
13371
13491
  AnimationState,
@@ -13446,6 +13566,7 @@ export {
13446
13566
  ScaleXTimeline,
13447
13567
  ScaleYTimeline,
13448
13568
  SequenceTimeline,
13569
+ SetupPoseBoundsProvider,
13449
13570
  ShearTimeline,
13450
13571
  ShearXTimeline,
13451
13572
  ShearYTimeline,
@@ -13457,6 +13578,7 @@ export {
13457
13578
  SkeletonJson,
13458
13579
  Skin,
13459
13580
  SkinEntry,
13581
+ SkinsAndAnimationBoundsProvider,
13460
13582
  Slot,
13461
13583
  SlotData,
13462
13584
  SpacingMode,