+ * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
+ public function updateAppliedTransform():Void {
+ var parent:Bone = parent;
+ if (parent == null) {
+ ax = worldX - skeleton.x;
+ ay = worldY - skeleton.y;
+ arotation = Math.atan2(c, a) * MathUtils.radDeg;
+ ascaleX = Math.sqrt(a * a + c * c);
+ ascaleY = Math.sqrt(b * b + d * d);
+ ashearX = 0;
+ ashearY = Math.atan2(a * b + c * d, a * d - b * c) * MathUtils.radDeg;
+ return;
+ }
+ var pa:Float = parent.a,
+ pb:Float = parent.b,
+ pc:Float = parent.c,
+ pd:Float = parent.d;
+ var pid:Float = 1 / (pa * pd - pb * pc);
+ var dx:Float = worldX - parent.worldX,
+ dy:Float = worldY - parent.worldY;
+ ax = (dx * pd * pid - dy * pb * pid);
+ ay = (dy * pa * pid - dx * pc * pid);
+ var ia:Float = pid * pd;
+ var id:Float = pid * pa;
+ var ib:Float = pid * pb;
+ var ic:Float = pid * pc;
+ var ra:Float = ia * a - ib * c;
+ var rb:Float = ia * b - ib * d;
+ var rc:Float = id * c - ic * a;
+ var rd:Float = id * d - ic * b;
+ ashearX = 0;
+ ascaleX = Math.sqrt(ra * ra + rc * rc);
+ if (scaleX > 0.0001) {
+ var det:Float = ra * rd - rb * rc;
+ ascaleY = det / ascaleX;
+ ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
+ arotation = Math.atan2(rc, ra) * MathUtils.radDeg;
+ } else {
+ ascaleX = 0;
+ ascaleY = Math.sqrt(rb * rb + rd * rd);
+ ashearY = 0;
+ arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
+ }
+ }
+
+ public function worldToLocal(world:Vector