update method
Implementation
@override
void update() {
if (target!.getAttachment() is! PathAttachment) return;
final PathAttachment attachment = target!.getAttachment() as PathAttachment;
final double rotateMix = this.rotateMix, translateMix = this.translateMix;
final bool translate = translateMix > 0, rotate = rotateMix > 0;
if (!translate && !rotate) return;
final PathConstraintData data = this.data;
final SpacingMode? spacingMode = data.spacingMode;
final bool lengthSpacing = spacingMode == SpacingMode.length;
final RotateMode? rotateMode = data.rotateMode;
final bool tangents = rotateMode == RotateMode.tangent,
scale = rotateMode == RotateMode.chainScale;
final int boneCount = this.bones.length,
spacesCount = tangents ? boneCount : boneCount + 1;
final List<Bone> bones = this.bones;
final Float32List spaces = ArrayUtils.copyWithNewArraySize(
this.spaces, spacesCount, double.infinity) as Float32List;
late Float32List lengths;
final double spacing = this.spacing;
if (scale || lengthSpacing) {
if (scale) {
lengths = ArrayUtils.copyWithNewArraySize(
this.lengths, boneCount, double.infinity) as Float32List;
}
final int n = spacesCount - 1;
for (int i = 0; i < n;) {
final Bone bone = bones[i];
final double setupLength = bone.data.length;
if (setupLength < PathConstraint.epsilon) {
if (scale) lengths[i] = 0.0;
spaces[++i] = 0.0;
} else {
final double x = setupLength * bone.a, y = setupLength * bone.c;
final double length = math.sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) *
length /
setupLength;
}
}
} else {
for (int i = 1; i < spacesCount; i++) {
spaces[i] = spacing;
}
}
final Float32List positions = computeWorldPositions(
attachment,
spacesCount,
tangents,
data.positionMode == PositionMode.percent,
spacingMode == SpacingMode.percent);
double boneX = positions[0],
boneY = positions[1],
offsetRotation = data.offsetRotation;
bool tip = false;
if (offsetRotation == 0) {
tip = rotateMode == RotateMode.chain;
} else {
tip = false;
final Bone p = target!.bone;
offsetRotation = offsetRotation *
(p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad);
}
for (int i = 0, p = 3; i < boneCount; i++, p += 3) {
final Bone bone = bones[i];
bone
..worldX += (boneX - bone.worldX) * translateMix
..worldY += (boneY - bone.worldY) * translateMix;
final double x = positions[p],
y = positions[p + 1],
dx = x - boneX,
dy = y - boneY;
if (scale) {
final double length = lengths[i];
if (length != 0) {
final double s =
(math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
bone
..a *= s
..c *= s;
}
}
boneX = x;
boneY = y;
if (rotate) {
final double a = bone.a, b = bone.b, c = bone.c, d = bone.d;
double r = 0.0, cos = 0.0, sin = 0.0;
if (tangents) {
r = positions[p - 1];
} else if (spaces[i + 1] == 0) {
r = positions[p + 2];
} else {
r = math.atan2(dy, dx);
}
r -= math.atan2(c, a);
if (tip) {
cos = math.cos(r);
sin = math.sin(r);
final double length = bone.data.length;
boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
} else {
r += offsetRotation;
}
if (r > math.pi) {
r -= math.pi * 2;
} else if (r < -math.pi) {
r += math.pi * 2;
}
r *= rotateMix;
cos = math.cos(r);
sin = math.sin(r);
bone
..a = cos * a - sin * c
..b = cos * b - sin * d
..c = sin * a + cos * c
..d = sin * b + cos * d;
}
bone.appliedValid = false;
}
}