From 9e00e5c701c6d6360c31ad042401d8c7dff40dc9 Mon Sep 17 00:00:00 2001 From: Nathan Sweet Date: Sun, 30 May 2021 17:07:53 -0400 Subject: [PATCH] [as3] Port of fix for applying a constraint reverting changes from other constraints. #1896 --- spine-as3/spine-as3/src/spine/Bone.as | 29 ++++++++++++------- spine-as3/spine-as3/src/spine/IkConstraint.as | 4 --- .../spine-as3/src/spine/PathConstraint.as | 2 +- spine-as3/spine-as3/src/spine/Skeleton.as | 15 +++++++++- spine-as3/spine-as3/src/spine/Slot.as | 10 +++++-- .../src/spine/TransformConstraint.as | 8 ++--- 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/spine-as3/spine-as3/src/spine/Bone.as b/spine-as3/spine-as3/src/spine/Bone.as index 637a39fab..33dda6ccf 100644 --- a/spine-as3/spine-as3/src/spine/Bone.as +++ b/spine-as3/spine-as3/src/spine/Bone.as @@ -48,7 +48,6 @@ package spine { public var ascaleY : Number; public var ashearX : Number; public var ashearY : Number; - public var appliedValid : Boolean; public var a : Number; public var b : Number; public var c : Number; @@ -73,17 +72,21 @@ package spine { return active; } - /** Same as updateWorldTransform(). This method exists for Bone to implement Updatable. */ + /** Computes the world transform using the parent bone and this bone's local applied transform. */ public function update() : void { - updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY); + updateWorldTransformWith(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY); } - /** Computes the world SRT using the parent bone and this bone's local SRT. */ + /** Computes the world transform using the parent bone and this bone's local transform. */ public function updateWorldTransform() : void { updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY); } - /** Computes the world SRT using the parent bone and the specified local SRT. */ + /** 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 in the Spine + * Runtimes Guide. */ public function updateWorldTransformWith(x : Number, y : Number, rotation : Number, scaleX : Number, scaleY : Number, shearX : Number, shearY : Number) : void { ax = x; ay = y; @@ -92,7 +95,6 @@ package spine { ascaleY = scaleY; ashearX = shearX; ashearY = shearY; - appliedValid = true; var rotationY : Number = 0, la : Number = 0, lb : Number = 0, lc : Number = 0, ld : Number = 0; var sin : Number = 0, cos : Number = 0; @@ -240,12 +242,15 @@ package spine { return Math.sqrt(b * b + d * d); } - /** Computes the individual applied transform values from the world transform. This can be useful to perform processing using - * the applied transform after the world transform has been modified directly (eg, by a constraint). + /** Computes the applied transform values from the world transform. *

- * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */ + * 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 another + * constraint). + *

+ * 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 transform used to compute the world transform, but may not be identical. */ internal function updateAppliedTransform() : void { - appliedValid = true; var parent : Bone = this.parent; if (parent == null) { ax = worldX; @@ -309,6 +314,10 @@ package spine { return Math.atan2(cos * c + sin * d, cos * a + sin * b) * MathUtils.radDeg; } + /** 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. */ public function rotateWorld(degrees : Number) : void { var cos : Number = MathUtils.cosDeg(degrees), sin : Number = MathUtils.sinDeg(degrees); var a : Number = this.a, b : Number = this.b, c : Number = this.c, d : Number = this.d; diff --git a/spine-as3/spine-as3/src/spine/IkConstraint.as b/spine-as3/spine-as3/src/spine/IkConstraint.as index 07996ef20..ffbb8e233 100644 --- a/spine-as3/spine-as3/src/spine/IkConstraint.as +++ b/spine-as3/spine-as3/src/spine/IkConstraint.as @@ -82,9 +82,7 @@ package spine { /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world * coordinate system. */ static public function apply1(bone : Bone, targetX : Number, targetY : Number, compress: Boolean, stretch : Boolean, uniform: Boolean, alpha : Number) : void { - if (!bone.appliedValid) bone.updateAppliedTransform(); var p : Bone = bone.parent; - var pa : Number = p.a, pb : Number = p.b, pc : Number = p.c, pd : Number = p.d; var rotationIK : Number = -bone.ashearX - bone.arotation, tx : Number = 0, ty : Number = 0; switch(bone.data.transformMode) { @@ -135,8 +133,6 @@ package spine { * target is specified in the world coordinate system. * @param child Any descendant bone of the parent. */ static public function apply2(parent : Bone, child : Bone, targetX : Number, targetY : Number, bendDir : int, stretch : Boolean, softness: Number, alpha : Number) : void { - if (!parent.appliedValid) parent.updateAppliedTransform(); - if (!child.appliedValid) child.updateAppliedTransform(); var px : Number = parent.ax, py : Number = parent.ay, psx : Number = parent.ascaleX, sx : Number = psx, psy : Number = parent.ascaleY, csx : Number = child.ascaleX; var os1 : int, os2 : int, s2 : int; if (psx < 0) { diff --git a/spine-as3/spine-as3/src/spine/PathConstraint.as b/spine-as3/spine-as3/src/spine/PathConstraint.as index 1ee1bd12d..633b31d38 100644 --- a/spine-as3/spine-as3/src/spine/PathConstraint.as +++ b/spine-as3/spine-as3/src/spine/PathConstraint.as @@ -205,7 +205,7 @@ package spine { bone.c = sin * a + cos * c; bone.d = sin * b + cos * d; } - bone.appliedValid = false; + bone.updateAppliedTransform(); } } diff --git a/spine-as3/spine-as3/src/spine/Skeleton.as b/spine-as3/spine-as3/src/spine/Skeleton.as index 472b2338d..1d2953228 100644 --- a/spine-as3/spine-as3/src/spine/Skeleton.as +++ b/spine-as3/spine-as3/src/spine/Skeleton.as @@ -298,8 +298,21 @@ package spine { /** Updates the world transform for each bone and applies constraints. */ public function updateWorldTransform() : void { + var bones : Vector. = this.bones; + var i : int, n : int; + for (i = 0, n = bones.length; i < n; i++) { + var bone : 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; + } + var updateCache : Vector. = _updateCache; - for (var i : int = 0, n : int = updateCache.length; i < n; i++) + for (i = 0, n = updateCache.length; i < n; i++) updateCache[i].update(); } diff --git a/spine-as3/spine-as3/src/spine/Slot.as b/spine-as3/spine-as3/src/spine/Slot.as index 288f90786..be0107e67 100644 --- a/spine-as3/spine-as3/src/spine/Slot.as +++ b/spine-as3/spine-as3/src/spine/Slot.as @@ -29,6 +29,7 @@ package spine { import spine.attachments.Attachment; + import spine.attachments.VertexAttachment; public class Slot { internal var _data : SlotData; @@ -67,13 +68,18 @@ package spine { return _attachment; } - /** Sets the attachment and resets {@link #getAttachmentTime()}. + /** 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. */ public function set attachment(attachment : Attachment) : void { if (_attachment == attachment) return; + if (!(attachment is VertexAttachment) || !(this.attachment is VertexAttachment) + || VertexAttachment(attachment).deformAttachment != VertexAttachment(this.attachment).deformAttachment) { + deform.length = 0; + } _attachment = attachment; _attachmentTime = _bone._skeleton.time; - deform.length = 0; } public function set attachmentTime(time : Number) : void { diff --git a/spine-as3/spine-as3/src/spine/TransformConstraint.as b/spine-as3/spine-as3/src/spine/TransformConstraint.as index 8a4ae3761..94784a765 100644 --- a/spine-as3/spine-as3/src/spine/TransformConstraint.as +++ b/spine-as3/spine-as3/src/spine/TransformConstraint.as @@ -139,6 +139,8 @@ package spine { bone.b = Math.cos(r) * s; bone.d = Math.sin(r) * s; } + + bone.updateAppliedTransform(); } } @@ -205,6 +207,8 @@ package spine { bone.b = Math.cos(r) * s; bone.d = Math.sin(r) * s; } + + bone.updateAppliedTransform(); } } @@ -213,12 +217,10 @@ package spine { var mixScaleX : Number = this.mixScaleX, mixScaleY : Number = this.mixScaleY, mixShearY : Number = this.mixShearY; var target : Bone = this.target; - if (!target.appliedValid) target.updateAppliedTransform(); var bones : Vector. = _bones; for (var i : int = 0, n : int = bones.length; i < n; i++) { var bone : Bone = bones[i]; - if (!bone.appliedValid) bone.updateAppliedTransform(); var rotation : Number = bone.arotation; if (mixRotate != 0) { @@ -253,12 +255,10 @@ package spine { var mixScaleX : Number = this.mixScaleX, mixScaleY : Number = this.mixScaleY, mixShearY : Number = this.mixShearY; var target : Bone = this.target; - if (!target.appliedValid) target.updateAppliedTransform(); var bones : Vector. = _bones; for (var i : int = 0, n : int = bones.length; i < n; i++) { var bone : Bone = bones[i]; - if (!bone.appliedValid) bone.updateAppliedTransform(); var rotation : Number = bone.arotation + (target.arotation + _data.offsetRotation) * mixRotate; var x : Number = bone.ax + (target.ax + _data.offsetX) * mixX;