diff --git a/spine-ts/core/src/Bone.ts b/spine-ts/core/src/Bone.ts index cdf936eee..c30b6c9d0 100644 --- a/spine-ts/core/src/Bone.ts +++ b/spine-ts/core/src/Bone.ts @@ -89,26 +89,22 @@ module spine { /** The applied local shearY. */ ashearY = 0; - /** If true, the applied transform matches the world transform. If false, the world transform has been modified since it was - * computed and {@link #updateAppliedTransform()} must be called before accessing the applied transform. */ - appliedValid = false; - - /** Part of the world transform matrix for the X axis. If changed, {@link #appliedValid} should be set to false. */ + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ a = 0; - /** Part of the world transform matrix for the Y axis. If changed, {@link #appliedValid} should be set to false. */ + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ b = 0; - /** Part of the world transform matrix for the X axis. If changed, {@link #appliedValid} should be set to false. */ + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ c = 0; - /** Part of the world transform matrix for the Y axis. If changed, {@link #appliedValid} should be set to false. */ + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ d = 0; - /** The world X position. If changed, {@link #appliedValid} should be set to false. */ + /** The world X position. If changed, {@link #updateAppliedTransform()} should be called. */ worldY = 0; - /** The world Y position. If changed, {@link #appliedValid} should be set to false. */ + /** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */ worldX = 0; sorted = false; @@ -130,9 +126,9 @@ module spine { return this.active; } - /** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */ + /** Computes the world transform using the parent bone and this bone's local applied transform. */ update () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); } /** Computes the world transform using the parent bone and this bone's local transform. @@ -142,7 +138,8 @@ module spine { this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); } - /** Computes the world transform using the parent bone and the specified local transform. Child bones are not updated. + /** Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the + * specified local transform. Child bones are not updated. * * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine * Runtimes Guide. */ @@ -154,7 +151,6 @@ module spine { this.ascaleY = scaleY; this.ashearX = shearX; this.ashearY = shearY; - this.appliedValid = true; let parent = this.parent; if (parent == null) { // Root bone. @@ -288,16 +284,15 @@ module spine { return Math.sqrt(this.b * this.b + this.d * this.d); } - /** Computes the applied transform values from the world transform. This allows the applied transform to be accessed after the - * world transform has been modified (by a constraint, {@link #rotateWorld()}, etc). + /** Computes the applied transform values from the world transform. * - * If {@link #updateWorldTransform()} has been called for a bone and {@link #appliedValid} is false, then - * {@link #updateAppliedTransform()} must be called before accessing the applied transform. + * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so + * the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply other + * constraints). * * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after - * calling this method is equivalent to the local tranform used to compute the world transform, but may not be identical. */ + * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */ updateAppliedTransform () { - this.appliedValid = true; let parent = this.parent; if (parent == null) { this.ax = this.worldX; @@ -367,8 +362,10 @@ module spine { return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg; } - /** Rotates the world transform the specified amount and sets {@link #appliedValid} to false. - * {@link #updateWorldTransform()} will need to be called on any child bones, recursively, and any constraints reapplied. */ + /** Rotates the world transform the specified amount. + *

+ * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will + * need to be called on any child bones, recursively. */ rotateWorld (degrees: number) { let a = this.a, b = this.b, c = this.c, d = this.d; let cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); @@ -376,7 +373,6 @@ module spine { this.b = cos * b - sin * d; this.c = sin * a + cos * c; this.d = sin * b + cos * d; - this.appliedValid = false; } } } diff --git a/spine-ts/core/src/IkConstraint.ts b/spine-ts/core/src/IkConstraint.ts index 62e85e432..997511a4c 100644 --- a/spine-ts/core/src/IkConstraint.ts +++ b/spine-ts/core/src/IkConstraint.ts @@ -96,9 +96,7 @@ module spine { /** Applies 1 bone IK. The target is specified in the world coordinate system. */ apply1 (bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number) { - if (!bone.appliedValid) bone.updateAppliedTransform(); let p = bone.parent; - let pa = p.a, pb = p.b, pc = p.c, pd = p.d; let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; @@ -148,8 +146,6 @@ module spine { /** Applies 2 bone IK. The target is specified in the world coordinate system. * @param child A direct descendant of the parent bone. */ apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, softness: number, alpha: number) { - if (!parent.appliedValid) parent.updateAppliedTransform(); - if (!child.appliedValid) child.updateAppliedTransform(); let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; let os1 = 0, os2 = 0, s2 = 0; if (psx < 0) { diff --git a/spine-ts/core/src/PathConstraint.ts b/spine-ts/core/src/PathConstraint.ts index 7141980dd..70e3c0c31 100644 --- a/spine-ts/core/src/PathConstraint.ts +++ b/spine-ts/core/src/PathConstraint.ts @@ -208,7 +208,7 @@ module spine { bone.c = sin * a + cos * c; bone.d = sin * b + cos * d; } - bone.appliedValid = false; + bone.updateAppliedTransform(); } } diff --git a/spine-ts/core/src/Skeleton.ts b/spine-ts/core/src/Skeleton.ts index 4292dcec4..d4e34517b 100644 --- a/spine-ts/core/src/Skeleton.ts +++ b/spine-ts/core/src/Skeleton.ts @@ -321,6 +321,18 @@ module spine { * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine * Runtimes Guide. */ updateWorldTransform () { + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + let updateCache = this._updateCache; for (let i = 0, n = updateCache.length; i < n; i++) updateCache[i].update(); diff --git a/spine-ts/core/src/Slot.ts b/spine-ts/core/src/Slot.ts index 7f62a6077..79105422b 100644 --- a/spine-ts/core/src/Slot.ts +++ b/spine-ts/core/src/Slot.ts @@ -79,13 +79,18 @@ module spine { return this.attachment; } - /** Sets the slot's attachment and, if the attachment changed, resets {@link #attachmentTime} and clears {@link #deform}. + /** Sets the slot's attachment and, if the attachment changed, resets {@link #attachmentTime} and clears the {@link #deform}. + * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getDeformAttachment()} as the specified + * attachment. * @param attachment May be null. */ setAttachment (attachment: Attachment) { if (this.attachment == attachment) return; + if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) + || (attachment).deformAttachment != (this.attachment).deformAttachment) { + this.deform.length = 0; + } this.attachment = attachment; this.attachmentTime = this.bone.skeleton.time; - this.deform.length = 0; } setAttachmentTime (time: number) { diff --git a/spine-ts/core/src/TransformConstraint.ts b/spine-ts/core/src/TransformConstraint.ts index 8a25df320..19e547a05 100644 --- a/spine-ts/core/src/TransformConstraint.ts +++ b/spine-ts/core/src/TransformConstraint.ts @@ -149,7 +149,7 @@ module spine { bone.d = Math.sin(r) * s; } - bone.appliedValid = false; + bone.updateAppliedTransform(); } } @@ -213,7 +213,7 @@ module spine { bone.d = Math.sin(r) * s; } - bone.appliedValid = false; + bone.updateAppliedTransform(); } } @@ -222,12 +222,10 @@ module spine { mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; let target = this.target; - if (!target.appliedValid) target.updateAppliedTransform(); let bones = this.bones; for (let i = 0, n = bones.length; i < n; i++) { let bone = bones[i]; - if (!bone.appliedValid) bone.updateAppliedTransform(); let rotation = bone.arotation; if (mixRotate != 0) { @@ -262,11 +260,10 @@ module spine { mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; let target = this.target; - if (!target.appliedValid) target.updateAppliedTransform(); + let bones = this.bones; for (let i = 0, n = bones.length; i < n; i++) { let bone = bones[i]; - if (!bone.appliedValid) bone.updateAppliedTransform(); let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; let x = bone.ax + (target.ax + this.data.offsetX) * mixX;