@esotericsoftware/spine-canvas 4.3.9 → 4.3.11

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.
@@ -138,6 +138,7 @@ var spine = (() => {
138
138
  SkeletonClipping: () => SkeletonClipping,
139
139
  SkeletonData: () => SkeletonData,
140
140
  SkeletonJson: () => SkeletonJson,
141
+ SkeletonPhysicsMovement: () => SkeletonPhysicsMovement,
141
142
  SkeletonRenderer: () => SkeletonRenderer,
142
143
  SkeletonRendererCore: () => SkeletonRendererCore,
143
144
  Skin: () => Skin,
@@ -11222,7 +11223,7 @@ ${error}` : ""}`);
11222
11223
  t = triangles[i + 2];
11223
11224
  const x3 = vertices[t * stride], y3 = vertices[t * stride + 1];
11224
11225
  const u3 = uvs[t << 1], v3 = uvs[(t << 1) + 1];
11225
- const d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1, d = 1 / (d0 * d2 + d1 * (y1 - y3));
11226
+ let d0 = 0, d1 = 0, d2 = 0, d4 = 0, d = 0;
11226
11227
  for (let p = 0; p < polygonsCount; p++) {
11227
11228
  let s = clippedVertices.length;
11228
11229
  if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p])) {
@@ -11230,6 +11231,13 @@ ${error}` : ""}`);
11230
11231
  const clipOutputLength = clipOutput.length;
11231
11232
  if (clipOutputLength === 0) continue;
11232
11233
  let clipOutputCount = clipOutputLength >> 1;
11234
+ if (d === 0) {
11235
+ d0 = y2 - y3;
11236
+ d1 = x3 - x2;
11237
+ d2 = x1 - x3;
11238
+ d4 = y3 - y1;
11239
+ d = 1 / (d0 * d2 - d1 * d4);
11240
+ }
11233
11241
  const cv = Utils.setArraySize(clippedVertices, s + clipOutputCount * stride);
11234
11242
  for (let ii = 0; ii < clipOutputLength; ii += 2, s += stride) {
11235
11243
  const x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
@@ -11429,7 +11437,7 @@ ${error}` : ""}`);
11429
11437
  const x3 = vertices[vertexStart + v], y3 = vertices[vertexStart + v + 1];
11430
11438
  uv = t << 1;
11431
11439
  const u3 = uvs[uv], v3 = uvs[uv + 1];
11432
- const d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1, d = 1 / (d0 * d2 + d1 * (y1 - y3));
11440
+ let d0 = 0, d1 = 0, d2 = 0, d4 = 0, d = 0;
11433
11441
  for (let p = 0; p < polygonsCount; p++) {
11434
11442
  let s = this.clippedVerticesLength;
11435
11443
  if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p])) {
@@ -11437,6 +11445,13 @@ ${error}` : ""}`);
11437
11445
  const clipOutputLength = clipOutput.length;
11438
11446
  if (clipOutputLength === 0) continue;
11439
11447
  let clipOutputCount = clipOutputLength >> 1;
11448
+ if (d === 0) {
11449
+ d0 = y2 - y3;
11450
+ d1 = x3 - x2;
11451
+ d2 = x1 - x3;
11452
+ d4 = y3 - y1;
11453
+ d = 1 / (d0 * d2 - d1 * d4);
11454
+ }
11440
11455
  const newLength = s + clipOutputCount * stride;
11441
11456
  if (clippedVertices.length < newLength) {
11442
11457
  this._clippedVerticesTyped = new Float32Array(newLength * 2);
@@ -11553,16 +11568,15 @@ ${error}` : ""}`);
11553
11568
  const edgeX = v[i], edgeY = v[i + 1], ex = edgeX - v[i + 2], ey = edgeY - v[i + 3];
11554
11569
  const outputStart = output.length;
11555
11570
  const iv2 = input;
11556
- for (let ii = 0, nn = input.length - 2; ii < nn; ) {
11557
- x1 = iv2[ii];
11558
- y1 = iv2[ii + 1];
11559
- ii += 2;
11571
+ x1 = iv2[0];
11572
+ y1 = iv2[1];
11573
+ let s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
11574
+ for (let ii = 2, nn = input.length - 2; ii <= nn; ii += 2) {
11560
11575
  x2 = iv2[ii];
11561
11576
  y2 = iv2[ii + 1];
11562
- const s2 = ey * (edgeX - x2) > ex * (edgeY - y2);
11563
- const s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
11577
+ const s2 = ey * (edgeX - x2) - ex * (edgeY - y2);
11564
11578
  if (s1 > 0) {
11565
- if (s2)
11579
+ if (s2 > 0)
11566
11580
  output.push(x2, y2);
11567
11581
  else {
11568
11582
  const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
@@ -11572,7 +11586,7 @@ ${error}` : ""}`);
11572
11586
  } else
11573
11587
  output.push(x2, y2);
11574
11588
  }
11575
- } else if (s2) {
11589
+ } else if (s2 > 0) {
11576
11590
  const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
11577
11591
  if (t >= 0 && t <= 1) {
11578
11592
  output.push(x1 + ix * t, y1 + iy * t, x2, y2);
@@ -11581,6 +11595,9 @@ ${error}` : ""}`);
11581
11595
  output.push(x2, y2);
11582
11596
  } else
11583
11597
  clipped = true;
11598
+ x1 = x2;
11599
+ y1 = y2;
11600
+ s1 = s2;
11584
11601
  }
11585
11602
  if (outputStart === output.length) {
11586
11603
  originalOutput.length = 0;
@@ -11628,16 +11645,15 @@ ${error}` : ""}`);
11628
11645
  const outputStart = output.length, fragmentStart = this.inverseVertices.length;
11629
11646
  this.inverseVertices.push(0);
11630
11647
  iv = input;
11631
- for (let ii = 0, nn = input.length - 2; ii < nn; ) {
11632
- x1 = iv[ii];
11633
- y1 = iv[ii + 1];
11634
- ii += 2;
11648
+ x1 = iv[0];
11649
+ y1 = iv[1];
11650
+ let s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
11651
+ for (let ii = 2, nn = input.length - 2; ii <= nn; ii += 2) {
11635
11652
  x2 = iv[ii];
11636
11653
  y2 = iv[ii + 1];
11637
- const s2 = ey * (edgeX - x2) > ex * (edgeY - y2);
11638
- const s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
11654
+ const s2 = ey * (edgeX - x2) - ex * (edgeY - y2);
11639
11655
  if (s1 > 0) {
11640
- if (s2)
11656
+ if (s2 > 0)
11641
11657
  output.push(x2, y2);
11642
11658
  else {
11643
11659
  const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
@@ -11648,16 +11664,19 @@ ${error}` : ""}`);
11648
11664
  } else
11649
11665
  output.push(x2, y2);
11650
11666
  }
11651
- } else if (s2) {
11652
- const dx = x2 - x1, dy = y2 - y1, t = s1 / (dx * ey - dy * ex);
11667
+ } else if (s2 > 0) {
11668
+ const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
11653
11669
  if (t >= 0 && t <= 1) {
11654
- const cx = x1 + dx * t, cy = y1 + dy * t;
11670
+ const cx = x1 + ix * t, cy = y1 + iy * t;
11655
11671
  this.inverseVertices.push(cx, cy);
11656
11672
  output.push(cx, cy, x2, y2);
11657
11673
  } else
11658
11674
  output.push(x2, y2);
11659
11675
  } else
11660
11676
  this.inverseVertices.push(x2, y2);
11677
+ x1 = x2;
11678
+ y1 = y2;
11679
+ s1 = s2;
11661
11680
  }
11662
11681
  const fragmentSize = this.inverseVertices.length - fragmentStart - 1;
11663
11682
  if (fragmentSize >= 6)
@@ -13012,6 +13031,151 @@ ${error}` : ""}`);
13012
13031
  return map[property] !== void 0 ? map[property] : defaultValue;
13013
13032
  }
13014
13033
 
13034
+ // spine-core/src/SkeletonPhysicsMovement.ts
13035
+ var SkeletonPhysicsMovement = class {
13036
+ /**
13037
+ * Creates a movement tracker for a skeleton displayed by a host runtime object.
13038
+ * @param skeleton The skeleton whose physics constraints receive inherited movement.
13039
+ * @param adapter Runtime-specific hooks used to read and convert the host object's transform.
13040
+ * @param options Initial movement inheritance values.
13041
+ */
13042
+ constructor(skeleton, adapter, options = {}) {
13043
+ this.skeleton = skeleton;
13044
+ this.adapter = adapter;
13045
+ this.positionInheritanceFactorX = options.positionInheritanceX ?? 0;
13046
+ this.positionInheritanceFactorY = options.positionInheritanceY ?? 0;
13047
+ this.rotationInheritanceFactor = options.rotationInheritance ?? 0;
13048
+ }
13049
+ positionInheritanceFactorX = 0;
13050
+ positionInheritanceFactorY = 0;
13051
+ rotationInheritanceFactor = 0;
13052
+ hasLastTransform = false;
13053
+ lastX = 0;
13054
+ lastY = 0;
13055
+ lastZ = 0;
13056
+ lastRotation = 0;
13057
+ currentTransform = { x: 0, y: 0, z: 0, rotation: 0 };
13058
+ currentPosition = { x: 0, y: 0, z: 0 };
13059
+ lastPosition = { x: 0, y: 0, z: 0 };
13060
+ /** Horizontal position inheritance factor. `0` disables horizontal position inheritance. */
13061
+ get positionInheritanceX() {
13062
+ return this.positionInheritanceFactorX;
13063
+ }
13064
+ /** Vertical position inheritance factor. `0` disables vertical position inheritance. */
13065
+ get positionInheritanceY() {
13066
+ return this.positionInheritanceFactorY;
13067
+ }
13068
+ /**
13069
+ * Sets how much host object translation is inherited by skeleton physics constraints.
13070
+ * Use `(1, 1)` for normal inheritance, or `(0, 0)` to disable position inheritance.
13071
+ * @param x The horizontal position inheritance factor.
13072
+ * @param y The vertical position inheritance factor.
13073
+ */
13074
+ setPositionInheritance(x, y) {
13075
+ const wasDisabled = this.positionInheritanceFactorX === 0 && this.positionInheritanceFactorY === 0;
13076
+ const isEnabled = x !== 0 || y !== 0;
13077
+ this.positionInheritanceFactorX = x;
13078
+ this.positionInheritanceFactorY = y;
13079
+ if (wasDisabled && isEnabled) this.resetPosition();
13080
+ }
13081
+ /** Rotation inheritance factor. `0` disables rotation inheritance. */
13082
+ get rotationInheritance() {
13083
+ return this.rotationInheritanceFactor;
13084
+ }
13085
+ /**
13086
+ * Sets how much host object rotation is inherited by skeleton physics constraints.
13087
+ * @param value The rotation inheritance factor.
13088
+ */
13089
+ set rotationInheritance(value) {
13090
+ const wasDisabled = this.rotationInheritanceFactor === 0;
13091
+ this.rotationInheritanceFactor = value;
13092
+ if (wasDisabled && value !== 0) this.resetRotation();
13093
+ }
13094
+ /** Resets the previous position used to calculate inherited translation. */
13095
+ resetPosition() {
13096
+ const transform = this.currentTransform;
13097
+ const readRotation = !this.hasLastTransform && this.rotationInheritanceFactor !== 0;
13098
+ this.adapter.readTransform(transform, readRotation);
13099
+ this.lastX = transform.x;
13100
+ this.lastY = transform.y;
13101
+ this.lastZ = transform.z;
13102
+ if (readRotation) this.lastRotation = transform.rotation;
13103
+ this.hasLastTransform = true;
13104
+ }
13105
+ /** Resets the previous rotation used to calculate inherited rotation. */
13106
+ resetRotation() {
13107
+ const transform = this.currentTransform;
13108
+ this.adapter.readTransform(transform, true);
13109
+ this.lastRotation = transform.rotation;
13110
+ if (!this.hasLastTransform) {
13111
+ this.lastX = transform.x;
13112
+ this.lastY = transform.y;
13113
+ this.lastZ = transform.z;
13114
+ }
13115
+ this.hasLastTransform = true;
13116
+ }
13117
+ /** Resets both previous position and previous rotation. */
13118
+ resetTransform() {
13119
+ const transform = this.currentTransform;
13120
+ this.adapter.readTransform(transform, true);
13121
+ this.setLastTransform(transform.x, transform.y, transform.z, transform.rotation);
13122
+ }
13123
+ /**
13124
+ * Applies host object transform movement since the previous call to the skeleton's physics constraints.
13125
+ *
13126
+ * The first call records the current transform as the baseline and does not apply movement.
13127
+ */
13128
+ applyTransformMovement() {
13129
+ const inheritPosition = this.positionInheritanceFactorX !== 0 || this.positionInheritanceFactorY !== 0;
13130
+ const inheritRotation = this.rotationInheritanceFactor !== 0;
13131
+ if (!inheritPosition && !inheritRotation) return;
13132
+ const transform = this.currentTransform;
13133
+ this.adapter.readTransform(transform, inheritRotation);
13134
+ const { x, y, z } = transform;
13135
+ const currentRotation = inheritRotation ? transform.rotation : this.lastRotation;
13136
+ const positionChanged = x !== this.lastX || y !== this.lastY || z !== this.lastZ;
13137
+ if (this.hasLastTransform) {
13138
+ if (!positionChanged && currentRotation === this.lastRotation) return;
13139
+ if (inheritPosition && positionChanged) this.applyPositionMovement(x, y, z);
13140
+ if (inheritRotation && currentRotation !== this.lastRotation) this.applyRotationMovement(currentRotation);
13141
+ }
13142
+ this.setLastTransform(x, y, z, currentRotation);
13143
+ }
13144
+ applyPositionMovement(currentX, currentY, currentZ) {
13145
+ const currentPosition = this.currentPosition;
13146
+ currentPosition.x = currentX;
13147
+ currentPosition.y = currentY;
13148
+ currentPosition.z = currentZ;
13149
+ this.adapter.worldToSkeleton(currentPosition);
13150
+ const lastPosition = this.lastPosition;
13151
+ lastPosition.x = this.lastX;
13152
+ lastPosition.y = this.lastY;
13153
+ lastPosition.z = this.lastZ;
13154
+ this.adapter.worldToSkeleton(lastPosition);
13155
+ this.skeleton.physicsTranslate(
13156
+ (currentPosition.x - lastPosition.x) * this.positionInheritanceFactorX,
13157
+ (currentPosition.y - lastPosition.y) * this.positionInheritanceFactorY
13158
+ );
13159
+ }
13160
+ applyRotationMovement(currentRotation) {
13161
+ const rotationFactor = this.rotationInheritanceFactor;
13162
+ if (rotationFactor === 0) return;
13163
+ this.skeleton.physicsRotate(0, 0, this.getRotationDelta(currentRotation, this.lastRotation) * rotationFactor);
13164
+ }
13165
+ setLastTransform(x, y, z, rotation) {
13166
+ this.lastX = x;
13167
+ this.lastY = y;
13168
+ this.lastZ = z;
13169
+ this.lastRotation = rotation;
13170
+ this.hasLastTransform = true;
13171
+ }
13172
+ getRotationDelta(current, previous) {
13173
+ let delta = current - previous;
13174
+ delta = (delta + 180) % 360 - 180;
13175
+ return delta < -180 ? delta + 360 : delta;
13176
+ }
13177
+ };
13178
+
13015
13179
  // spine-core/src/SkeletonRendererCore.ts
13016
13180
  var SkeletonRendererCore = class {
13017
13181
  commandPool = new CommandPool();
@@ -13024,17 +13188,21 @@ ${error}` : ""}`);
13024
13188
  this.renderCommands.length = 0;
13025
13189
  const clipper = this.clipping;
13026
13190
  const drawOrder = skeleton.drawOrder.appliedPose;
13027
- for (let i = 0; i < skeleton.slots.length; i++) {
13191
+ for (let i = 0, n = drawOrder.length; i < n; i++) {
13028
13192
  const slot = drawOrder[i];
13029
- const attachment = slot.appliedPose.attachment;
13030
- if (!attachment) {
13193
+ if (!slot.bone.active) {
13031
13194
  clipper.clipEnd(slot);
13032
13195
  continue;
13033
13196
  }
13034
13197
  const pose = slot.appliedPose;
13198
+ const attachment = pose.attachment;
13199
+ if (!attachment) {
13200
+ clipper.clipEnd(slot);
13201
+ continue;
13202
+ }
13035
13203
  const slotColor = pose.color;
13036
13204
  const alpha = slotColor.a;
13037
- if ((alpha === 0 || !slot.bone.active) && !(attachment instanceof ClippingAttachment)) {
13205
+ if (alpha === 0 && !(attachment instanceof ClippingAttachment)) {
13038
13206
  clipper.clipEnd(slot);
13039
13207
  continue;
13040
13208
  }
@@ -13078,9 +13246,15 @@ ${error}` : ""}`);
13078
13246
  indicesCount = indices.length;
13079
13247
  texture = sequence.regions[sequenceIndex]?.texture;
13080
13248
  } else if (attachment instanceof ClippingAttachment) {
13249
+ clipper.clipEnd(slot);
13081
13250
  clipper.clipStart(skeleton, slot, attachment);
13082
13251
  continue;
13083
13252
  } else {
13253
+ clipper.clipEnd(slot);
13254
+ continue;
13255
+ }
13256
+ if (!texture) {
13257
+ clipper.clipEnd(slot);
13084
13258
  continue;
13085
13259
  }
13086
13260
  const skelColor = skeleton.color;