+ * Some redundant information is lost by the world transform, such as -1,-1 scale versus 180 rotation. The computed local
+ * transform values may differ from the original values but are functionally the same. */
+ public function updateLocalTransform () : void {
+ var parent:Bone = this.parent;
+ if (parent == null) {
+ x = worldX;
+ y = worldY;
+ rotation = Math.atan2(c, a) * MathUtils.radDeg;
+ scaleX = Math.sqrt(a * a + c * c);
+ scaleY = Math.sqrt(b * b + d * d);
+ var det:Number = a * d - b * c;
+ shearX = 0;
+ shearY = Math.atan2(a * b + c * d, det) * MathUtils.radDeg;
+ return;
+ }
+ var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d;
+ var pid:Number = 1 / (pa * pd - pb * pc);
+ var dx:Number = worldX - parent.worldX, dy:Number = worldY - parent.worldY;
+ x = (dx * pd * pid - dy * pb * pid);
+ y = (dy * pa * pid - dx * pc * pid);
+ var ia:Number = pid * pd;
+ var id:Number = pid * pa;
+ var ib:Number = pid * pb;
+ var ic:Number = pid * pc;
+ var ra:Number = ia * a - ib * c;
+ var rb:Number = ia * b - ib * d;
+ var rc:Number = id * c - ic * a;
+ var rd:Number = id * d - ic * b;
+ shearX = 0;
+ scaleX = Math.sqrt(ra * ra + rc * rc);
+ if (scaleX > 0.0001) {
+ det = ra * rd - rb * rc;
+ scaleY = det / scaleX;
+ shearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
+ rotation = Math.atan2(rc, ra) * MathUtils.radDeg;
+ } else {
+ scaleX = 0;
+ scaleY = Math.sqrt(rb * rb + rd * rd);
+ shearY = 0;
+ rotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
+ }
+ appliedRotation = rotation;
+ }
public function worldToLocal (world:Vector.
+ * Some redundant information is lost by the world transform, such as -1,-1 scale versus 180 rotation. The computed local
+ * transform values may differ from the original values but are functionally the same. */
+void spBone_updateLocalTransform (spBone* self) {
+ spBone* parent = self->parent;
+ if (!parent) {
+ float det = self->a * self->d - self->b * self->c;
+ self->x = self->worldX;
+ self->y = self->worldY;
+ self->rotation = ATAN2(self->c, self->a) * RAD_DEG;
+ self->scaleX = SQRT(self->a * self->a + self->c * self->c);
+ self->scaleY = SQRT(self->b * self->b + self->d * self->d);
+ self->shearX = 0;
+ self->shearY = ATAN2(self->a * self->b + self->c * self->d, det) * RAD_DEG;
+ } else {
+ float pa = parent->a, pb = parent->b, pc = parent->c, pd = parent->d;
+ float pid = 1 / (pa * pd - pb * pc);
+ float dx = self->worldX - parent->worldX, dy = self->worldY - parent->worldY;
+ float ia = pid * pd;
+ float id = pid * pa;
+ float ib = pid * pb;
+ float ic = pid * pc;
+ float ra = ia * self->a - ib * self->c;
+ float rb = ia * self->b - ib * self->d;
+ float rc = id * self->c - ic * self->a;
+ float rd = id * self->d - ic * self->b;
+ self->x = (dx * pd * pid - dy * pb * pid);
+ self->y = (dy * pa * pid - dx * pc * pid);
+ self->shearX = 0;
+ self->scaleX = SQRT(ra * ra + rc * rc);
+ if (self->scaleX > 0.0001f) {
+ float det = ra * rd - rb * rc;
+ self->scaleY = det / self->scaleX;
+ self->shearY = ATAN2(ra * rb + rc * rd, det) * RAD_DEG;
+ self->rotation = ATAN2(rc, ra) * RAD_DEG;
+ } else {
+ self->scaleX = 0;
+ self->scaleY = SQRT(rb * rb + rd * rd);
+ self->shearY = 0;
+ self->rotation = 90 - ATAN2(rd, rb) * RAD_DEG;
+ }
+ self->appliedRotation = self->rotation;
+ }
+}
+
void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY) {
- float x = worldX - self->worldX, y = worldY - self->worldY;
float a = self->a, b = self->b, c = self->c, d = self->d;
float invDet = 1 / (a * d - b * c);
+ float x = worldX - self->worldX, y = worldY - self->worldY;
*localX = (x * d * invDet - y * b * invDet);
*localY = (y * a * invDet - x * c * invDet);
}
diff --git a/spine-c/src/spine/BoneData.c b/spine-c/src/spine/BoneData.c
index 1d102f504..10df35eca 100644
--- a/spine-c/src/spine/BoneData.c
+++ b/spine-c/src/spine/BoneData.c
@@ -32,14 +32,15 @@
#include