public static void Apply(Bone bone, float targetX, float targetY, float alpha) { if (!bone.appliedValid) { bone.UpdateAppliedTransform(); } Bone parent = bone.parent; float num = 1f / ((parent.a * parent.d) - (parent.b * parent.c)); float num2 = targetX - parent.worldX; float num3 = targetY - parent.worldY; float num4 = (((num2 * parent.d) - (num3 * parent.b)) * num) - bone.ax; float num5 = (((num3 * parent.a) - (num2 * parent.c)) * num) - bone.ay; float num6 = ((((float)Math.Atan2((double)num5, (double)num4)) * 57.29578f) - bone.ashearX) - bone.arotation; if (bone.ascaleX < 0f) { num6 += 180f; } if (num6 > 180f) { num6 -= 360f; } else if (num6 < -180f) { num6 += 360f; } bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + (num6 * alpha), bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); }
public static void Apply(Bone bone, float targetX, float targetY, float alpha) { if (!bone.appliedValid) { bone.UpdateAppliedTransform(); } Bone parent = bone.parent; float num = 1f / (parent.a * parent.d - parent.b * parent.c); float num2 = targetX - parent.worldX; float num3 = targetY - parent.worldY; float num4 = (num2 * parent.d - num3 * parent.b) * num - bone.ax; float num5 = (num3 * parent.a - num2 * parent.c) * num - bone.ay; float num6 = (float)Math.Atan2(num5, num4) * (180f / (float)Math.PI) - bone.ashearX - bone.arotation; if (bone.ascaleX < 0f) { num6 += 180f; } if (num6 > 180f) { num6 -= 360f; } else if (num6 < -180f) { num6 += 360f; } bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + num6 * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); }
void ApplyRelativeLocal() { float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; Bone target = this.target; if (!target.appliedValid) { target.UpdateAppliedTransform(); } var bonesItems = this.bones.Items; for (int i = 0, n = this.bones.Count; i < n; i++) { Bone bone = bonesItems[i]; if (!bone.appliedValid) { bone.UpdateAppliedTransform(); } float rotation = bone.arotation; if (rotateMix != 0) { rotation += (target.arotation + data.offsetRotation) * rotateMix; } float x = bone.ax, y = bone.ay; if (translateMix != 0) { x += (target.ax + data.offsetX) * translateMix; y += (target.ay + data.offsetY) * translateMix; } float scaleX = bone.ascaleX, scaleY = bone.ascaleY; if (scaleMix != 0) { if (scaleX > 0.00001f) { scaleX *= ((target.ascaleX - 1 + data.offsetScaleX) * scaleMix) + 1; } if (scaleY > 0.00001f) { scaleY *= ((target.ascaleY - 1 + data.offsetScaleY) * scaleMix) + 1; } } float shearY = bone.ashearY; if (shearMix != 0) { shearY += (target.ashearY + data.offsetShearY) * shearMix; } bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); } }
/// <summary>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.</summary> static public void Apply (Bone bone, float targetX, float targetY, float alpha) { if (!bone.appliedValid) bone.UpdateAppliedTransform(); Bone p = bone.parent; float id = 1 / (p.a * p.d - p.b * p.c); float x = targetX - p.worldX, y = targetY - p.worldY; float tx = (x * p.d - y * p.b) * id - bone.ax, ty = (y * p.a - x * p.c) * id - bone.ay; float rotationIK = MathUtils.Atan2(ty, tx) * MathUtils.RadDeg - bone.ashearX - bone.arotation; if (bone.ascaleX < 0) rotationIK += 180; if (rotationIK > 180) rotationIK -= 360; else if (rotationIK < -180) rotationIK += 360; bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); }
/// <summary>Applies 1 bone IK. The target is specified in the world coordinate system.</summary> static public void Apply(Bone bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha) { if (!bone.appliedValid) { bone.UpdateAppliedTransform(); } Bone p = bone.parent; float id = 1 / (p.a * p.d - p.b * p.c); float x = targetX - p.worldX, y = targetY - p.worldY; float tx = (x * p.d - y * p.b) * id - bone.ax, ty = (y * p.a - x * p.c) * id - bone.ay; float rotationIK = (float)Math.Atan2(ty, tx) * MathUtils.RadDeg - bone.ashearX - bone.arotation; if (bone.ascaleX < 0) { rotationIK += 180; } if (rotationIK > 180) { rotationIK -= 360; } else if (rotationIK < -180) // { rotationIK += 360; } float sx = bone.ascaleX, sy = bone.ascaleY; if (compress || stretch) { float b = bone.data.length * sx, dd = (float)Math.Sqrt(tx * tx + ty * ty); if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) { float s = (dd / b - 1) * alpha + 1; sx *= s; if (uniform) { sy *= s; } } } bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); }
/// <summary>Applies 1 bone IK. The target is specified in the world coordinate system.</summary> static public void Apply(Bone bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha) { if (!bone.appliedValid) { bone.UpdateAppliedTransform(); } Bone p = bone.parent; float pa = p.a, pb = p.b, pc = p.c, pd = p.d; float rotationIK = -bone.ashearX - bone.arotation; float tx = 0, ty = 0; switch (bone.data.transformMode) { case TransformMode.OnlyTranslation: tx = targetX - bone.worldX; ty = targetY - bone.worldY; break; case TransformMode.NoRotationOrReflection: { rotationIK += (float)Math.Atan2(pc, pa) * MathUtils.RadDeg; float ps = Math.Abs(pa * pd - pb * pc) / (pa * pa + pc * pc); pb = -pc * ps; pd = pa * ps; float x = targetX - p.worldX, y = targetY - p.worldY; float d = pa * pd - pb * pc; tx = (x * pd - y * pb) / d - bone.ax; ty = (y * pa - x * pc) / d - bone.ay; break; } default: { float x = targetX - p.worldX, y = targetY - p.worldY; float d = pa * pd - pb * pc; tx = (x * pd - y * pb) / d - bone.ax; ty = (y * pa - x * pc) / d - bone.ay; break; } } rotationIK += (float)Math.Atan2(ty, tx) * MathUtils.RadDeg; if (bone.ascaleX < 0) { rotationIK += 180; } if (rotationIK > 180) { rotationIK -= 360; } else if (rotationIK < -180) // { rotationIK += 360; } float sx = bone.ascaleX, sy = bone.ascaleY; if (compress || stretch) { switch (bone.data.transformMode) { case TransformMode.NoScale: tx = targetX - bone.worldX; ty = targetY - bone.worldY; break; case TransformMode.NoScaleOrReflection: tx = targetX - bone.worldX; ty = targetY - bone.worldY; break; } float b = bone.data.length * sx, dd = (float)Math.Sqrt(tx * tx + ty * ty); if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) { float s = (dd / b - 1) * alpha + 1; sx *= s; if (uniform) { sy *= s; } } } bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); }
/// <summary>Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as /// possible. The target is specified in the world coordinate system.</summary> /// <param name="child">A direct descendant of the parent bone.</param> static public void Apply (Bone parent, Bone child, float targetX, float targetY, int bendDir, float alpha) { if (alpha == 0) { child.UpdateWorldTransform (); return; } //float px = parent.x, py = parent.y, psx = parent.scaleX, psy = parent.scaleY, csx = child.scaleX; if (!parent.appliedValid) parent.UpdateAppliedTransform(); if (!child.appliedValid) child.UpdateAppliedTransform(); float px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; int os1, os2, s2; if (psx < 0) { psx = -psx; os1 = 180; s2 = -1; } else { os1 = 0; s2 = 1; } if (psy < 0) { psy = -psy; s2 = -s2; } if (csx < 0) { csx = -csx; os2 = 180; } else os2 = 0; float cx = child.ax, cy, cwx, cwy, a = parent.a, b = parent.b, c = parent.c, d = parent.d; bool u = Math.Abs(psx - psy) <= 0.0001f; if (!u) { cy = 0; cwx = a * cx + parent.worldX; cwy = c * cx + parent.worldY; } else { cy = child.ay; cwx = a * cx + b * cy + parent.worldX; cwy = c * cx + d * cy + parent.worldY; } Bone pp = parent.parent; a = pp.a; b = pp.b; c = pp.c; d = pp.d; float id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; float tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; x = cwx - pp.worldX; y = cwy - pp.worldY; float dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; float l1 = (float)Math.Sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; if (u) { l2 *= psx; float cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); if (cos < -1) cos = -1; else if (cos > 1) cos = 1; a2 = (float)Math.Acos(cos) * bendDir; a = l1 + l2 * cos; b = l2 * MathUtils.Sin(a2); a1 = MathUtils.Atan2(ty * a - tx * b, tx * a + ty * b); } else { a = psx * l2; b = psy * l2; float aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = MathUtils.Atan2(ty, tx); c = bb * l1 * l1 + aa * dd - aa * bb; float c1 = -2 * bb * l1, c2 = bb - aa; d = c1 * c1 - 4 * c2 * c; if (d >= 0) { float q = (float)Math.Sqrt(d); if (c1 < 0) q = -q; q = -(c1 + q) / 2; float r0 = q / c2, r1 = c / q; float r = Math.Abs(r0) < Math.Abs(r1) ? r0 : r1; if (r * r <= dd) { y = (float)Math.Sqrt(dd - r * r) * bendDir; a1 = ta - MathUtils.Atan2(y, r); a2 = MathUtils.Atan2(y / psy, (r - l1) / psx); goto outer; } } float minAngle = 0, minDist = float.MaxValue, minX = 0, minY = 0; float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0; x = l1 + a; d = x * x; if (d > maxDist) { maxAngle = 0; maxDist = d; maxX = x; } x = l1 - a; d = x * x; if (d < minDist) { minAngle = MathUtils.PI; minDist = d; minX = x; } float angle = (float)Math.Acos(-a * l1 / (aa - bb)); x = a * MathUtils.Cos(angle) + l1; y = b * MathUtils.Sin(angle); d = x * x + y * y; if (d < minDist) { minAngle = angle; minDist = d; minX = x; minY = y; } if (d > maxDist) { maxAngle = angle; maxDist = d; maxX = x; maxY = y; } if (dd <= (minDist + maxDist) / 2) { a1 = ta - MathUtils.Atan2(minY * bendDir, minX); a2 = minAngle * bendDir; } else { a1 = ta - MathUtils.Atan2(maxY * bendDir, maxX); a2 = maxAngle * bendDir; } } outer: float os = MathUtils.Atan2(cy, cx) * s2; float rotation = parent.arotation; a1 = (a1 - os) * MathUtils.RadDeg + os1 - rotation; if (a1 > 180) a1 -= 360; else if (a1 < -180) a1 += 360; parent.UpdateWorldTransform(px, py, rotation + a1 * alpha, parent.scaleX, parent.ascaleY, 0, 0); rotation = child.arotation; a2 = ((a2 + os) * MathUtils.RadDeg - child.ashearX) * s2 + os2 - rotation; if (a2 > 180) a2 -= 360; else if (a2 < -180) a2 += 360; child.UpdateWorldTransform(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); }
public static void Apply(Bone parent, Bone child, float targetX, float targetY, int bendDir, float alpha) { int num6; int num7; int num8; float num10; float num11; float num12; float num26; float num27; float num47; if (alpha == 0f) { child.UpdateWorldTransform(); return; } if (!parent.appliedValid) { parent.UpdateAppliedTransform(); } if (!child.appliedValid) { child.UpdateAppliedTransform(); } float ax = parent.ax; float ay = parent.ay; float ascaleX = parent.ascaleX; float ascaleY = parent.ascaleY; float num5 = child.ascaleX; if (ascaleX < 0f) { ascaleX = -ascaleX; num6 = 180; num8 = -1; } else { num6 = 0; num8 = 1; } if (ascaleY < 0f) { ascaleY = -ascaleY; num8 = -num8; } if (num5 < 0f) { num5 = -num5; num7 = 180; } else { num7 = 0; } float x = child.ax; float a = parent.a; float b = parent.b; float c = parent.c; float d = parent.d; bool flag = Math.Abs((float)(ascaleX - ascaleY)) <= 0.0001f; if (!flag) { num10 = 0f; num11 = (a * x) + parent.worldX; num12 = (c * x) + parent.worldY; } else { num10 = child.ay; num11 = ((a * x) + (b * num10)) + parent.worldX; num12 = ((c * x) + (d * num10)) + parent.worldY; } Bone bone = parent.parent; a = bone.a; b = bone.b; c = bone.c; d = bone.d; float num17 = 1f / ((a * d) - (b * c)); float num18 = targetX - bone.worldX; float num19 = targetY - bone.worldY; float num20 = (((num18 * d) - (num19 * b)) * num17) - ax; float num21 = (((num19 * a) - (num18 * c)) * num17) - ay; num18 = num11 - bone.worldX; num19 = num12 - bone.worldY; float num22 = (((num18 * d) - (num19 * b)) * num17) - ax; float num23 = (((num19 * a) - (num18 * c)) * num17) - ay; float num24 = (float)Math.Sqrt((double)((num22 * num22) + (num23 * num23))); float num25 = child.data.length * num5; if (flag) { num25 *= ascaleX; float num28 = ((((num20 * num20) + (num21 * num21)) - (num24 * num24)) - (num25 * num25)) / ((2f * num24) * num25); if (num28 < -1f) { num28 = -1f; } else if (num28 > 1f) { num28 = 1f; } num27 = ((float)Math.Acos((double)num28)) * bendDir; a = num24 + (num25 * num28); b = num25 * ((float)Math.Sin((double)num27)); num26 = (float)Math.Atan2((double)((num21 * a) - (num20 * b)), (double)((num20 * a) + (num21 * b))); } else { a = ascaleX * num25; b = ascaleY * num25; float num29 = a * a; float num30 = b * b; float num31 = (num20 * num20) + (num21 * num21); float num32 = (float)Math.Atan2((double)num21, (double)num20); c = (((num30 * num24) * num24) + (num29 * num31)) - (num29 * num30); float num33 = (-2f * num30) * num24; float num34 = num30 - num29; d = (num33 * num33) - ((4f * num34) * c); if (d >= 0f) { float num35 = (float)Math.Sqrt((double)d); if (num33 < 0f) { num35 = -num35; } num35 = -(num33 + num35) / 2f; float num36 = num35 / num34; float num37 = c / num35; float num38 = (Math.Abs(num36) >= Math.Abs(num37)) ? num37 : num36; if ((num38 * num38) <= num31) { num19 = ((float)Math.Sqrt((double)(num31 - (num38 * num38)))) * bendDir; num26 = num32 - ((float)Math.Atan2((double)num19, (double)num38)); num27 = (float)Math.Atan2((double)(num19 / ascaleY), (double)((num38 - num24) / ascaleX)); goto Label_0504; } } float num39 = 3.141593f; float num40 = num24 - a; float num41 = num40 * num40; float num42 = 0f; float num43 = 0f; float num44 = num24 + a; float num45 = num44 * num44; float num46 = 0f; c = (-a * num24) / (num29 - num30); if ((c >= -1f) && (c <= 1f)) { c = (float)Math.Acos((double)c); num18 = (a * ((float)Math.Cos((double)c))) + num24; num19 = b * ((float)Math.Sin((double)c)); d = (num18 * num18) + (num19 * num19); if (d < num41) { num39 = c; num41 = d; num40 = num18; num42 = num19; } if (d > num45) { num43 = c; num45 = d; num44 = num18; num46 = num19; } } if (num31 <= ((num41 + num45) / 2f)) { num26 = num32 - ((float)Math.Atan2((double)(num42 * bendDir), (double)num40)); num27 = num39 * bendDir; } else { num26 = num32 - ((float)Math.Atan2((double)(num46 * bendDir), (double)num44)); num27 = num43 * bendDir; } } Label_0504: num47 = ((float)Math.Atan2((double)num10, (double)x)) * num8; float arotation = parent.arotation; num26 = (((num26 - num47) * 57.29578f) + num6) - arotation; if (num26 > 180f) { num26 -= 360f; } else if (num26 < -180f) { num26 += 360f; } parent.UpdateWorldTransform(ax, ay, arotation + (num26 * alpha), parent.scaleX, parent.ascaleY, 0f, 0f); arotation = child.arotation; num27 = (((((num27 + num47) * 57.29578f) - child.ashearX) * num8) + num7) - arotation; if (num27 > 180f) { num27 -= 360f; } else if (num27 < -180f) { num27 += 360f; } child.UpdateWorldTransform(x, num10, arotation + (num27 * alpha), child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); }
public void Update() { PathAttachment attachment = target.Attachment as PathAttachment; if (attachment == null) { return; } float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; if (mixRotate == 0 && mixX == 0 && mixY == 0) { return; } PathConstraintData data = this.data; bool tangents = data.rotateMode == RotateMode.Tangent, scale = data.rotateMode == RotateMode.ChainScale; int boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1; Bone[] bonesItems = this.bones.Items; float[] spaces = this.spaces.Resize(spacesCount).Items, lengths = scale ? this.lengths.Resize(boneCount).Items : null; float spacing = this.spacing; switch (data.spacingMode) { case SpacingMode.Percent: if (scale) { for (int i = 0, n = spacesCount - 1; i < n; i++) { Bone bone = bonesItems[i]; float setupLength = bone.data.length; if (setupLength < PathConstraint.Epsilon) { lengths[i] = 0; } else { float x = setupLength * bone.a, y = setupLength * bone.c; lengths[i] = (float)Math.Sqrt(x * x + y * y); } } } ArraysFill(spaces, 1, spacesCount, spacing); break; case SpacingMode.Proportional: { float sum = 0; for (int i = 0, n = spacesCount - 1; i < n;) { Bone bone = bonesItems[i]; float setupLength = bone.data.length; if (setupLength < PathConstraint.Epsilon) { if (scale) { lengths[i] = 0; } spaces[++i] = spacing; } else { float x = setupLength * bone.a, y = setupLength * bone.c; float length = (float)Math.Sqrt(x * x + y * y); if (scale) { lengths[i] = length; } spaces[++i] = length; sum += length; } } if (sum > 0) { sum = spacesCount / sum * spacing; for (int i = 1; i < spacesCount; i++) { spaces[i] *= sum; } } break; } default: { bool lengthSpacing = data.spacingMode == SpacingMode.Length; for (int i = 0, n = spacesCount - 1; i < n;) { Bone bone = bonesItems[i]; float setupLength = bone.data.length; if (setupLength < PathConstraint.Epsilon) { if (scale) { lengths[i] = 0; } spaces[++i] = spacing; } else { float x = setupLength * bone.a, y = setupLength * bone.c; float length = (float)Math.Sqrt(x * x + y * y); if (scale) { lengths[i] = length; } spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; } } break; } } float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents); float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; bool tip; if (offsetRotation == 0) { tip = data.rotateMode == RotateMode.Chain; } else { tip = false; Bone p = target.bone; 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) { Bone bone = bonesItems[i]; bone.worldX += (boneX - bone.worldX) * mixX; bone.worldY += (boneY - bone.worldY) * mixY; float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; if (scale) { float length = lengths[i]; if (length >= PathConstraint.Epsilon) { float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1; bone.a *= s; bone.c *= s; } } boneX = x; boneY = y; if (mixRotate > 0) { float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin; if (tangents) { r = positions[p - 1]; } else if (spaces[i + 1] < PathConstraint.Epsilon) { r = positions[p + 2]; } else { r = MathUtils.Atan2(dy, dx); } r -= MathUtils.Atan2(c, a); if (tip) { cos = MathUtils.Cos(r); sin = MathUtils.Sin(r); float length = bone.data.length; boneX += (length * (cos * a - sin * c) - dx) * mixRotate; boneY += (length * (sin * a + cos * c) - dy) * mixRotate; } else { r += offsetRotation; } if (r > MathUtils.PI) { r -= MathUtils.PI2; } else if (r < -MathUtils.PI) // { r += MathUtils.PI2; } r *= mixRotate; cos = MathUtils.Cos(r); sin = MathUtils.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; } bone.UpdateAppliedTransform(); } }
public static void Apply(Bone parent, Bone child, float targetX, float targetY, int bendDir, float alpha) { if (alpha == 0f) { child.UpdateWorldTransform(); return; } if (!parent.appliedValid) { parent.UpdateAppliedTransform(); } if (!child.appliedValid) { child.UpdateAppliedTransform(); } float ax = parent.ax; float ay = parent.ay; float num = parent.ascaleX; float num2 = parent.ascaleY; float num3 = child.ascaleX; int num4; int num5; if (num < 0f) { num = 0f - num; num4 = 180; num5 = -1; } else { num4 = 0; num5 = 1; } if (num2 < 0f) { num2 = 0f - num2; num5 = -num5; } int num6; if (num3 < 0f) { num3 = 0f - num3; num6 = 180; } else { num6 = 0; } float ax2 = child.ax; float a = parent.a; float b = parent.b; float c = parent.c; float d = parent.d; bool flag = Math.Abs(num - num2) <= 0.0001f; float num7; float num8; float num9; if (!flag) { num7 = 0f; num8 = a * ax2 + parent.worldX; num9 = c * ax2 + parent.worldY; } else { num7 = child.ay; num8 = a * ax2 + b * num7 + parent.worldX; num9 = c * ax2 + d * num7 + parent.worldY; } Bone parent2 = parent.parent; a = parent2.a; b = parent2.b; c = parent2.c; d = parent2.d; float num10 = 1f / (a * d - b * c); float num11 = targetX - parent2.worldX; float num12 = targetY - parent2.worldY; float num13 = (num11 * d - num12 * b) * num10 - ax; float num14 = (num12 * a - num11 * c) * num10 - ay; num11 = num8 - parent2.worldX; num12 = num9 - parent2.worldY; float num15 = (num11 * d - num12 * b) * num10 - ax; float num16 = (num12 * a - num11 * c) * num10 - ay; float num17 = (float)Math.Sqrt(num15 * num15 + num16 * num16); float num18 = child.data.length * num3; float num21; float num20; if (flag) { num18 *= num; float num19 = (num13 * num13 + num14 * num14 - num17 * num17 - num18 * num18) / (2f * num17 * num18); if (num19 < -1f) { num19 = -1f; } else if (num19 > 1f) { num19 = 1f; } num20 = (float)Math.Acos(num19) * (float)bendDir; a = num17 + num18 * num19; b = num18 * (float)Math.Sin(num20); num21 = (float)Math.Atan2(num14 * a - num13 * b, num13 * a + num14 * b); } else { a = num * num18; b = num2 * num18; float num22 = a * a; float num23 = b * b; float num24 = num13 * num13 + num14 * num14; float num25 = (float)Math.Atan2(num14, num13); c = num23 * num17 * num17 + num22 * num24 - num22 * num23; float num26 = -2f * num23 * num17; float num27 = num23 - num22; d = num26 * num26 - 4f * num27 * c; if (d >= 0f) { float num28 = (float)Math.Sqrt(d); if (num26 < 0f) { num28 = 0f - num28; } num28 = (0f - (num26 + num28)) / 2f; float num29 = num28 / num27; float num30 = c / num28; float num31 = (!(Math.Abs(num29) < Math.Abs(num30))) ? num30 : num29; if (num31 * num31 <= num24) { num12 = (float)Math.Sqrt(num24 - num31 * num31) * (float)bendDir; num21 = num25 - (float)Math.Atan2(num12, num31); num20 = (float)Math.Atan2(num12 / num2, (num31 - num17) / num); goto IL_0504; } } float num32 = (float)Math.PI; float num33 = num17 - a; float num34 = num33 * num33; float num35 = 0f; float num36 = 0f; float num37 = num17 + a; float num38 = num37 * num37; float num39 = 0f; c = (0f - a) * num17 / (num22 - num23); if (c >= -1f && c <= 1f) { c = (float)Math.Acos(c); num11 = a * (float)Math.Cos(c) + num17; num12 = b * (float)Math.Sin(c); d = num11 * num11 + num12 * num12; if (d < num34) { num32 = c; num34 = d; num33 = num11; num35 = num12; } if (d > num38) { num36 = c; num38 = d; num37 = num11; num39 = num12; } } if (num24 <= (num34 + num38) / 2f) { num21 = num25 - (float)Math.Atan2(num35 * (float)bendDir, num33); num20 = num32 * (float)bendDir; } else { num21 = num25 - (float)Math.Atan2(num39 * (float)bendDir, num37); num20 = num36 * (float)bendDir; } } goto IL_0504; IL_0504: float num40 = (float)Math.Atan2(num7, ax2) * (float)num5; float arotation = parent.arotation; num21 = (num21 - num40) * (180f / (float)Math.PI) + (float)num4 - arotation; if (num21 > 180f) { num21 -= 360f; } else if (num21 < -180f) { num21 += 360f; } parent.UpdateWorldTransform(ax, ay, arotation + num21 * alpha, parent.scaleX, parent.ascaleY, 0f, 0f); arotation = child.arotation; num20 = ((num20 + num40) * (180f / (float)Math.PI) - child.ashearX) * (float)num5 + (float)num6 - arotation; if (num20 > 180f) { num20 -= 360f; } else if (num20 < -180f) { num20 += 360f; } child.UpdateWorldTransform(ax2, num7, arotation + num20 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); }