[as3] Port of fix for applying a constraint reverting changes from other constraints.

#1896
This commit is contained in:
Nathan Sweet 2021-05-30 17:07:53 -04:00
parent 6ab69e62fc
commit 9e00e5c701
6 changed files with 46 additions and 22 deletions

View File

@ -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.
* <p>
* See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> 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.
* <p>
* 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).
* <p>
* 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.
* <p>
* 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;

View File

@ -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) {

View File

@ -205,7 +205,7 @@ package spine {
bone.c = sin * a + cos * c;
bone.d = sin * b + cos * d;
}
bone.appliedValid = false;
bone.updateAppliedTransform();
}
}

View File

@ -298,8 +298,21 @@ package spine {
/** Updates the world transform for each bone and applies constraints. */
public function updateWorldTransform() : void {
var bones : Vector.<Bone> = 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.<Updatable> = _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();
}

View File

@ -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 {

View File

@ -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.<Bone> = _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.<Bone> = _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;