public void update() { float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; Bone target = this.target; float ta = target.a, tb = target.b, tc = target.c, td = target.d; float degRadReflect = ta * td - tb * tc > 0 ? degRad : -degRad; float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect; Array<Bone> bones = this.bones; for (int i = 0, n = bones.size; i < n; i++) { Bone bone = bones.get(i); boolean modified = false; if (rotateMix != 0) { float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float r = atan2(tc, ta) - atan2(c, a) + offsetRotation; if (r > PI) r -= PI2; else if (r < -PI) r += PI2; r *= rotateMix; float cos = cos(r), sin = sin(r); bone.a = cos * a - sin * c; bone.b = cos * b - sin * d; bone.c = sin * a + cos * c; bone.d = sin * b + cos * d; modified = true; } if (translateMix != 0) { Vector2 temp = this.temp; target.localToWorld(temp.set(data.offsetX, data.offsetY)); bone.worldX += (temp.x - bone.worldX) * translateMix; bone.worldY += (temp.y - bone.worldY) * translateMix; modified = true; } if (scaleMix > 0) { float s = (float) Math.sqrt(bone.a * bone.a + bone.c * bone.c); float ts = (float) Math.sqrt(ta * ta + tc * tc); if (s > 0.00001f) s = (s + (ts - s + data.offsetScaleX) * scaleMix) / s; bone.a *= s; bone.c *= s; s = (float) Math.sqrt(bone.b * bone.b + bone.d * bone.d); ts = (float) Math.sqrt(tb * tb + td * td); if (s > 0.00001f) s = (s + (ts - s + data.offsetScaleY) * scaleMix) / s; bone.b *= s; bone.d *= s; modified = true; } if (shearMix > 0) { float b = bone.b, d = bone.d; float by = atan2(d, b); float r = atan2(td, tb) - atan2(tc, ta) - (by - atan2(bone.c, bone.a)); if (r > PI) r -= PI2; else if (r < -PI) r += PI2; r = by + (r + offsetShearY) * shearMix; float s = (float) Math.sqrt(b * b + d * d); bone.b = cos(r) * s; bone.d = sin(r) * s; modified = true; } if (modified) bone.appliedValid = false; } }