UpdateWorldTransform() public method

Computes the world transform using the parent bone and this bone's local transform.
public UpdateWorldTransform ( ) : void
return void
コード例 #1
0
        /// <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 = (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;
            }
            bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX,
                                      bone.ashearY);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        private void ApplyAbsoluteLocal()
        {
            float num  = rotateMix;
            float num2 = translateMix;
            float num3 = scaleMix;
            float num4 = shearMix;
            Bone  bone = target;

            if (!bone.appliedValid)
            {
                bone.UpdateAppliedTransform();
            }
            Bone[] items = bones.Items;
            int    i     = 0;

            for (int count = bones.Count; i < count; i++)
            {
                Bone bone2 = items[i];
                if (!bone2.appliedValid)
                {
                    bone2.UpdateAppliedTransform();
                }
                float num5 = bone2.arotation;
                if (num != 0f)
                {
                    float num6 = bone.arotation - num5 + data.offsetRotation;
                    num6 -= (float)((16384 - (int)(16384.499999999996 - (double)(num6 / 360f))) * 360);
                    num5 += num6 * num;
                }
                float num7 = bone2.ax;
                float num8 = bone2.ay;
                if (num2 != 0f)
                {
                    num7 += (bone.ax - num7 + data.offsetX) * num2;
                    num8 += (bone.ay - num8 + data.offsetY) * num2;
                }
                float num9  = bone2.ascaleX;
                float num10 = bone2.ascaleY;
                if (num3 > 0f)
                {
                    if (num9 > 1E-05f)
                    {
                        num9 = (num9 + (bone.ascaleX - num9 + data.offsetScaleX) * num3) / num9;
                    }
                    if (num10 > 1E-05f)
                    {
                        num10 = (num10 + (bone.ascaleY - num10 + data.offsetScaleY) * num3) / num10;
                    }
                }
                float ashearY = bone2.ashearY;
                if (num4 > 0f)
                {
                    float num11 = bone.ashearY - ashearY + data.offsetShearY;
                    num11        -= (float)((16384 - (int)(16384.499999999996 - (double)(num11 / 360f))) * 360);
                    bone2.shearY += num11 * num4;
                }
                bone2.UpdateWorldTransform(num7, num8, num5, num9, num10, bone2.ashearX, ashearY);
            }
        }
コード例 #5
0
        void ApplyAbsoluteLocal()
        {
            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)
                {
                    float r = target.arotation - rotation + data.offsetRotation;
                    r        -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
                    rotation += r * rotateMix;
                }

                float x = bone.ax, y = bone.ay;
                if (translateMix != 0)
                {
                    x += (target.ax - x + data.offsetX) * translateMix;
                    y += (target.ay - y + data.offsetY) * translateMix;
                }

                float scaleX = bone.ascaleX, scaleY = bone.ascaleY;
                if (scaleMix != 0)
                {
                    if (scaleX != 0)
                    {
                        scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * scaleMix) / scaleX;
                    }
                    if (scaleY != 0)
                    {
                        scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * scaleMix) / scaleY;
                    }
                }

                float shearY = bone.ashearY;
                if (shearMix != 0)
                {
                    float r = target.ashearY - shearY + data.offsetShearY;
                    r      -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
                    shearY += r * shearMix;
                }

                bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
            }
        }
コード例 #6
0
        private void ApplyRelativeLocal()
        {
            float rotateMix    = this.rotateMix;
            float translateMix = this.translateMix;
            float scaleMix     = this.scaleMix;
            float shearMix     = this.shearMix;
            Bone  target       = this.target;

            if (!target.appliedValid)
            {
                target.UpdateAppliedTransform();
            }
            Bone[] items = this.bones.Items;
            int    index = 0;
            int    count = this.bones.Count;

            while (index < count)
            {
                Bone bone2 = items[index];
                if (!bone2.appliedValid)
                {
                    bone2.UpdateAppliedTransform();
                }
                float arotation = bone2.arotation;
                if (rotateMix != 0f)
                {
                    arotation += (target.arotation + this.data.offsetRotation) * rotateMix;
                }
                float ax = bone2.ax;
                float ay = bone2.ay;
                if (translateMix != 0f)
                {
                    ax += (target.ax + this.data.offsetX) * translateMix;
                    ay += (target.ay + this.data.offsetY) * translateMix;
                }
                float ascaleX = bone2.ascaleX;
                float ascaleY = bone2.ascaleY;
                if (scaleMix > 0f)
                {
                    if (ascaleX > 1E-05f)
                    {
                        ascaleX *= (((target.ascaleX - 1f) + this.data.offsetScaleX) * scaleMix) + 1f;
                    }
                    if (ascaleY > 1E-05f)
                    {
                        ascaleY *= (((target.ascaleY - 1f) + this.data.offsetScaleY) * scaleMix) + 1f;
                    }
                }
                float ashearY = bone2.ashearY;
                if (shearMix > 0f)
                {
                    ashearY += (target.ashearY + this.data.offsetShearY) * shearMix;
                }
                bone2.UpdateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, bone2.ashearX, ashearY);
                index++;
            }
        }
コード例 #7
0
        private void ApplyRelativeLocal()
        {
            float num  = rotateMix;
            float num2 = translateMix;
            float num3 = scaleMix;
            float num4 = shearMix;
            Bone  bone = target;

            if (!bone.appliedValid)
            {
                bone.UpdateAppliedTransform();
            }
            Bone[] items = bones.Items;
            int    i     = 0;

            for (int count = bones.Count; i < count; i++)
            {
                Bone bone2 = items[i];
                if (!bone2.appliedValid)
                {
                    bone2.UpdateAppliedTransform();
                }
                float num5 = bone2.arotation;
                if (num != 0f)
                {
                    num5 += (bone.arotation + data.offsetRotation) * num;
                }
                float num6 = bone2.ax;
                float num7 = bone2.ay;
                if (num2 != 0f)
                {
                    num6 += (bone.ax + data.offsetX) * num2;
                    num7 += (bone.ay + data.offsetY) * num2;
                }
                float num8 = bone2.ascaleX;
                float num9 = bone2.ascaleY;
                if (num3 > 0f)
                {
                    if (num8 > 1E-05f)
                    {
                        num8 *= (bone.ascaleX - 1f + data.offsetScaleX) * num3 + 1f;
                    }
                    if (num9 > 1E-05f)
                    {
                        num9 *= (bone.ascaleY - 1f + data.offsetScaleY) * num3 + 1f;
                    }
                }
                float num10 = bone2.ashearY;
                if (num4 > 0f)
                {
                    num10 += (bone.ashearY + data.offsetShearY) * num4;
                }
                bone2.UpdateWorldTransform(num6, num7, num5, num8, num9, bone2.ashearX, num10);
            }
        }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        void ApplyAbsoluteLocal()
        {
            float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
                  mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;

            Bone target = this.target;

            var bones = this.bones.Items;

            for (int i = 0, n = this.bones.Count; i < n; i++)
            {
                Bone bone = bones[i];

                float rotation = bone.arotation;
                if (mixRotate != 0)
                {
                    float r = target.arotation - rotation + data.offsetRotation;
                    r        -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
                    rotation += r * mixRotate;
                }

                float x = bone.ax, y = bone.ay;
                x += (target.ax - x + data.offsetX) * mixX;
                y += (target.ay - y + data.offsetY) * mixY;

                float scaleX = bone.ascaleX, scaleY = bone.ascaleY;
                if (mixScaleX != 0 && scaleX != 0)
                {
                    scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * mixScaleX) / scaleX;
                }
                if (mixScaleY != 0 && scaleY != 0)
                {
                    scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * mixScaleY) / scaleY;
                }

                float shearY = bone.ashearY;
                if (mixShearY != 0)
                {
                    float r = target.ashearY - shearY + data.offsetShearY;
                    r      -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
                    shearY += r * mixShearY;
                }

                bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
            }
        }
コード例 #10
0
ファイル: IkConstraint.cs プロジェクト: Phamdat210/HayDayFarm
        /// <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);
        }
コード例 #11
0
ファイル: IkConstraint.cs プロジェクト: ncqwer/spine-runtimes
        /// <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)
        {
            float parentRotation = bone.parent == null ? 0 : bone.parent.WorldRotationX;
            float rotation       = bone.rotation;
            float rotationIK     = MathUtils.Atan2(targetY - bone.worldY, targetX - bone.worldX) * MathUtils.radDeg - parentRotation;

            if ((bone.worldSignX != bone.worldSignY) != (bone.skeleton.flipX != (bone.skeleton.flipY != Bone.yDown)))
            {
                rotationIK = 360 - rotationIK;
            }
            if (rotationIK > 180)
            {
                rotationIK -= 360;
            }
            else if (rotationIK < -180)
            {
                rotationIK += 360;
            }
            bone.UpdateWorldTransform(bone.x, bone.y, rotation + (rotationIK - rotation) * alpha, bone.appliedScaleX, bone.appliedScaleY);
        }
コード例 #12
0
        /// <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)
        {
            Bone  pp = bone.parent;
            float id = 1 / (pp.a * pp.d - pp.b * pp.c);
            float x = targetX - pp.worldX, y = targetY - pp.worldY;
            float tx = (x * pp.d - y * pp.b) * id - bone.x, ty = (y * pp.a - x * pp.c) * id - bone.y;
            float rotationIK = MathUtils.Atan2(ty, tx) * MathUtils.radDeg - bone.shearX - bone.rotation;

            if (bone.scaleX < 0)
            {
                rotationIK += 180;
            }
            if (rotationIK > 180)
            {
                rotationIK -= 360;
            }
            else if (rotationIK < -180)
            {
                rotationIK += 360;
            }
            bone.UpdateWorldTransform(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY,
                                      bone.shearX, bone.shearY);
        }
コード例 #13
0
        void ApplyRelativeLocal()
        {
            float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
                  mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;

            Bone target = this.target;

            var bones = this.bones.Items;

            for (int i = 0, n = this.bones.Count; i < n; i++)
            {
                Bone bone = bones[i];

                float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate;
                float x        = bone.ax + (target.ax + data.offsetX) * mixX;
                float y        = bone.ay + (target.ay + data.offsetY) * mixY;
                float scaleX   = bone.ascaleX * (((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1);
                float scaleY   = bone.ascaleY * (((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1);
                float shearY   = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY;

                bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
            }
        }
コード例 #14
0
        public static void Apply(Bone bone, float targetX, float targetY, float alpha)
        {
            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 x      = (num2 * parent.d - num3 * parent.b) * num - bone.x;
            float y      = (num3 * parent.a - num2 * parent.c) * num - bone.y;
            float num4   = MathUtils.Atan2(y, x) * 57.2957764f - bone.shearX - bone.rotation;

            if (bone.scaleX < 0f)
            {
                num4 += 180f;
            }
            if (num4 > 180f)
            {
                num4 -= 360f;
            }
            else if (num4 < -180f)
            {
                num4 += 360f;
            }
            bone.UpdateWorldTransform(bone.x, bone.y, bone.rotation + num4 * alpha, bone.scaleX, bone.scaleY, bone.shearX, bone.shearY);
        }
コード例 #15
0
ファイル: IkConstraint.cs プロジェクト: czlc/spine-runtimes
		/// <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) {
			float parentRotation = bone.parent == null ? 0 : bone.parent.WorldRotationX;
			float rotation = bone.rotation;
			float rotationIK = MathUtils.Atan2(targetY - bone.worldY, targetX - bone.worldX) * MathUtils.radDeg - parentRotation;
			if ((bone.worldSignX != bone.worldSignY) != (bone.skeleton.flipX != (bone.skeleton.flipY != Bone.yDown)))
				rotationIK = 360 - rotationIK;
			if (rotationIK > 180) rotationIK -= 360;
			else if (rotationIK < -180) rotationIK += 360;
			bone.UpdateWorldTransform(bone.x, bone.y, rotation + (rotationIK - rotation) * alpha, bone.scaleX, bone.scaleY);
		}
コード例 #16
0
        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);
        }
コード例 #17
0
ファイル: IkConstraint.cs プロジェクト: ncqwer/spine-runtimes
        /// <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)
            {
                return;
            }
            float px = parent.x, py = parent.y, psx = parent.appliedScaleX, psy = parent.appliedScaleY;
            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;
            }
            float cx = child.x, cy = child.y, csx = child.appliedScaleX;
            bool  u = Math.Abs(psx - psy) <= 0.0001f;

            if (!u && cy != 0)
            {
                child.worldX = parent.a * cx + parent.worldX;
                child.worldY = parent.c * cx + parent.worldY;
                cy           = 0;
            }
            if (csx < 0)
            {
                csx = -csx;
                os2 = 180;
            }
            else
            {
                os2 = 0;
            }
            Bone  pp = parent.parent;
            float tx, ty, dx, dy;

            if (pp == null)
            {
                tx = targetX - px;
                ty = targetY - py;
                dx = child.worldX - px;
                dy = child.worldY - py;
            }
            else
            {
                float a = pp.a, b = pp.b, c = pp.c, d = pp.d, invDet = 1 / (a * d - b * c);
                float wx = pp.worldX, wy = pp.worldY, x = targetX - wx, y = targetY - wy;
                tx = (x * d - y * b) * invDet - px;
                ty = (y * a - x * c) * invDet - py;
                x  = child.worldX - wx;
                y  = child.worldY - wy;
                dx = (x * d - y * b) * invDet - px;
                dy = (y * a - x * c) * invDet - 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;
                float a = l1 + l2 * cos, o = l2 * MathUtils.Sin(a2);
                a1 = MathUtils.Atan2(ty * a - tx * o, tx * a + ty * o);
            }
            else
            {
                float a = psx * l2, b = psy * l2, ta = MathUtils.Atan2(ty, tx);
                float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty;
                float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
                float d = c1 * c1 - 4 * c2 * c0;
                if (d >= 0)
                {
                    float q = (float)Math.Sqrt(d);
                    if (c1 < 0)
                    {
                        q = -q;
                    }
                    q = -(c1 + q) / 2;
                    float r0 = q / c2, r1 = c0 / q;
                    float r = Math.Abs(r0) < Math.Abs(r1) ? r0 : r1;
                    if (r * r <= dd)
                    {
                        float y1 = (float)Math.Sqrt(dd - r * r) * bendDir;
                        a1 = ta - MathUtils.Atan2(y1, r);
                        a2 = MathUtils.Atan2(y1 / 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;
                float x = l1 + a, dist = x * x;
                if (dist > maxDist)
                {
                    maxAngle = 0;
                    maxDist  = dist;
                    maxX     = x;
                }
                x    = l1 - a;
                dist = x * x;
                if (dist < minDist)
                {
                    minAngle = MathUtils.PI;
                    minDist  = dist;
                    minX     = x;
                }
                float angle = (float)Math.Acos(-a * l1 / (aa - bb));
                x = a * MathUtils.Cos(angle) + l1;
                float y = b * MathUtils.Sin(angle);
                dist = x * x + y * y;
                if (dist < minDist)
                {
                    minAngle = angle;
                    minDist  = dist;
                    minX     = x;
                    minY     = y;
                }
                if (dist > maxDist)
                {
                    maxAngle = angle;
                    maxDist  = dist;
                    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;

            a1 = (a1 - os) * MathUtils.radDeg + os1;
            a2 = (a2 + os) * MathUtils.radDeg * s2 + os2;
            if (a1 > 180)
            {
                a1 -= 360;
            }
            else if (a1 < -180)
            {
                a1 += 360;
            }
            if (a2 > 180)
            {
                a2 -= 360;
            }
            else if (a2 < -180)
            {
                a2 += 360;
            }
            float rotation = parent.rotation;

            parent.UpdateWorldTransform(px, py, rotation + (a1 - rotation) * alpha, parent.appliedScaleX, parent.appliedScaleY);
            rotation = child.rotation;
            child.UpdateWorldTransform(cx, cy, rotation + (a2 - rotation) * alpha, child.appliedScaleX, child.appliedScaleY);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        /// <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 * (float)Math.Sin(a2);
                a1 = (float)Math.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 = (float)Math.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 - (float)Math.Atan2(y, r);
                        a2 = (float)Math.Atan2(y / psy, (r - l1) / psx);
                        goto break_outer;                         // break outer;
                    }
                }
                float minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
                float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
                c = -a * l1 / (aa - bb);
                if (c >= -1 && c <= 1)
                {
                    c = (float)Math.Acos(c);
                    x = a * (float)Math.Cos(c) + l1;
                    y = b * (float)Math.Sin(c);
                    d = x * x + y * y;
                    if (d < minDist)
                    {
                        minAngle = c;
                        minDist  = d;
                        minX     = x;
                        minY     = y;
                    }
                    if (d > maxDist)
                    {
                        maxAngle = c;
                        maxDist  = d;
                        maxX     = x;
                        maxY     = y;
                    }
                }
                if (dd <= (minDist + maxDist) / 2)
                {
                    a1 = ta - (float)Math.Atan2(minY * bendDir, minX);
                    a2 = minAngle * bendDir;
                }
                else
                {
                    a1 = ta - (float)Math.Atan2(maxY * bendDir, maxX);
                    a2 = maxAngle * bendDir;
                }
            }
break_outer:
            float os = (float)Math.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);
        }
コード例 #20
0
ファイル: IkConstraint.cs プロジェクト: DeStiCap/Dim-Mind
        /// <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);
        }
コード例 #21
0
ファイル: SkeletonBaker.cs プロジェクト: wenhaoisbad/kxsm
	static Bone GetExtractionBone () {
		if (extractionBone != null)
			return extractionBone;

		SkeletonData skelData = new SkeletonData();
		BoneData data = new BoneData("temp", null);
		data.ScaleX = 1;
		data.ScaleY = 1;
		data.Length = 100;

		skelData.Bones.Add(data);

		Skeleton skeleton = new Skeleton(skelData);

		Bone bone = new Bone(data, skeleton, null);
		bone.UpdateWorldTransform();

		extractionBone = bone;

		return extractionBone;
	}
コード例 #22
0
        /// <summary>Applies 2 bone IK. 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, bool stretch, bool uniform,
                                 float softness, float alpha)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent", "parent cannot be null.");
            }
            if (child == null)
            {
                throw new ArgumentNullException("child", "child cannot be null.");
            }
            float px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, 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 || stretch)
            {
                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 = 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 (l1 < 0.0001f)
            {
                Apply(parent, targetX, targetY, false, stretch, false, alpha);
                child.UpdateWorldTransform(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
                return;
            }
            x = targetX - pp.worldX;
            y = targetY - pp.worldY;
            float tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
            float dd = tx * tx + ty * ty;

            if (softness != 0)
            {
                softness *= psx * (csx + 1) * 0.5f;
                float td = (float)Math.Sqrt(dd), sd = td - l1 - l2 * psx + softness;
                if (sd > 0)
                {
                    float p = Math.Min(1, sd / (softness * 2)) - 1;
                    p   = (sd - softness * (1 - p * p)) / td;
                    tx -= p * tx;
                    ty -= p * ty;
                    dd  = tx * tx + ty * ty;
                }
            }
            if (u)
            {
                l2 *= psx;
                float cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
                if (cos < -1)
                {
                    cos = -1;
                    a2  = MathUtils.PI * bendDir;
                }
                else if (cos > 1)
                {
                    cos = 1;
                    a2  = 0;
                    if (stretch)
                    {
                        a   = ((float)Math.Sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
                        sx *= a;
                        if (uniform)
                        {
                            sy *= a;
                        }
                    }
                }
                else
                {
                    a2 = (float)Math.Acos(cos) * bendDir;
                }
                a  = l1 + l2 * cos;
                b  = l2 * (float)Math.Sin(a2);
                a1 = (float)Math.Atan2(ty * a - tx * b, tx * a + ty * b);
            }
            else
            {
                a = psx * l2;
                b = psy * l2;
                float aa = a * a, bb = b * b, ta = (float)Math.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) * 0.5f;
                    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 - (float)Math.Atan2(y, r);
                        a2 = (float)Math.Atan2(y / psy, (r - l1) / psx);
                        goto break_outer;                         // break outer;
                    }
                }
                float minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
                float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
                c = -a * l1 / (aa - bb);
                if (c >= -1 && c <= 1)
                {
                    c = (float)Math.Acos(c);
                    x = a * (float)Math.Cos(c) + l1;
                    y = b * (float)Math.Sin(c);
                    d = x * x + y * y;
                    if (d < minDist)
                    {
                        minAngle = c;
                        minDist  = d;
                        minX     = x;
                        minY     = y;
                    }
                    if (d > maxDist)
                    {
                        maxAngle = c;
                        maxDist  = d;
                        maxX     = x;
                        maxY     = y;
                    }
                }
                if (dd <= (minDist + maxDist) * 0.5f)
                {
                    a1 = ta - (float)Math.Atan2(minY * bendDir, minX);
                    a2 = minAngle * bendDir;
                }
                else
                {
                    a1 = ta - (float)Math.Atan2(maxY * bendDir, maxX);
                    a2 = maxAngle * bendDir;
                }
            }
break_outer:
            float os = (float)Math.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, sx, sy, 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);
        }
コード例 #23
0
		/// <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;
			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.x, 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.y;
				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.rotation;
			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.scaleY, 0, 0);
			rotation = child.rotation;
			a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - rotation;
			if (a2 > 180)
				a2 -= 360;
			else if (a2 < -180) a2 += 360;
			child.UpdateWorldTransform(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
		}
コード例 #24
0
        /// <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 == null)
            {
                throw new ArgumentNullException("bone", "bone cannot be null.");
            }
            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: {
                float s  = Math.Abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
                float sa = pa / bone.skeleton.ScaleX;
                float sc = pc / bone.skeleton.ScaleY;
                pb          = -sc * s * bone.skeleton.ScaleX;
                pd          = sa * s * bone.skeleton.ScaleY;
                rotationIK += (float)Math.Atan2(sc, sa) * MathUtils.RadDeg;
                goto default;                 // Fall through.
            }

            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:
                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);
        }
コード例 #25
0
        private void ApplyAbsoluteLocal()
        {
            float rotateMix    = this.rotateMix;
            float translateMix = this.translateMix;
            float scaleMix     = this.scaleMix;
            float shearMix     = this.shearMix;
            Bone  target       = this.target;

            if (!target.appliedValid)
            {
                target.UpdateAppliedTransform();
            }
            Bone[] items = this.bones.Items;
            int    index = 0;
            int    count = this.bones.Count;

            while (index < count)
            {
                Bone bone2 = items[index];
                if (!bone2.appliedValid)
                {
                    bone2.UpdateAppliedTransform();
                }
                float arotation = bone2.arotation;
                if (rotateMix != 0f)
                {
                    float num8 = (target.arotation - arotation) + this.data.offsetRotation;
                    num8      -= (0x4000 - ((int)(16384.499999999996 - (num8 / 360f)))) * 360;
                    arotation += num8 * rotateMix;
                }
                float ax = bone2.ax;
                float ay = bone2.ay;
                if (translateMix != 0f)
                {
                    ax += ((target.ax - ax) + this.data.offsetX) * translateMix;
                    ay += ((target.ay - ay) + this.data.offsetY) * translateMix;
                }
                float ascaleX = bone2.ascaleX;
                float ascaleY = bone2.ascaleY;
                if (scaleMix > 0f)
                {
                    if (ascaleX > 1E-05f)
                    {
                        ascaleX = (ascaleX + (((target.ascaleX - ascaleX) + this.data.offsetScaleX) * scaleMix)) / ascaleX;
                    }
                    if (ascaleY > 1E-05f)
                    {
                        ascaleY = (ascaleY + (((target.ascaleY - ascaleY) + this.data.offsetScaleY) * scaleMix)) / ascaleY;
                    }
                }
                float ashearY = bone2.ashearY;
                if (shearMix > 0f)
                {
                    float num14 = (target.ashearY - ashearY) + this.data.offsetShearY;
                    num14        -= (0x4000 - ((int)(16384.499999999996 - (num14 / 360f)))) * 360;
                    bone2.shearY += num14 * shearMix;
                }
                bone2.UpdateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, bone2.ashearX, ashearY);
                index++;
            }
        }
コード例 #26
0
		/// <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) {
			Bone pp = bone.parent;
			float id = 1 / (pp.a * pp.d - pp.b * pp.c);
			float x = targetX - pp.worldX, y = targetY - pp.worldY;
			float tx = (x * pp.d - y * pp.b) * id - bone.x, ty = (y * pp.a - x * pp.c) * id - bone.y;
			float rotationIK = MathUtils.Atan2(ty, tx) * MathUtils.radDeg - bone.shearX - bone.rotation;
			if (bone.scaleX < 0) rotationIK += 180;
			if (rotationIK > 180)
				rotationIK -= 360;
			else if (rotationIK < -180) rotationIK += 360;
			bone.UpdateWorldTransform(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY,
				bone.shearX, bone.shearY);
		}
コード例 #27
0
ファイル: IkConstraint.cs プロジェクト: czlc/spine-runtimes
		/// <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) return;
			float px = parent.x, py = parent.y, psx = parent.scaleX, psy = parent.scaleY, csx = child.scaleX, cy = child.y;
			int offset1, offset2, sign2;
			if (psx < 0) {
				psx = -psx;
				offset1 = 180;
				sign2 = -1;
			} else {
				offset1 = 0;
				sign2 = 1;
			}
			if (psy < 0) {
				psy = -psy;
				sign2 = -sign2;
			}
			if (csx < 0) {
				csx = -csx;
				offset2 = 180;
			} else
				offset2 = 0;
			Bone pp = parent.parent;
			float tx, ty, dx, dy;
			if (pp == null) {
				tx = targetX - px;
				ty = targetY - py;
				dx = child.worldX - px;
				dy = child.worldY - py;
			} else {
				float a = pp.a, b = pp.b, c = pp.c, d = pp.d, invDet = 1 / (a * d - b * c);
				float wx = pp.worldX, wy = pp.worldY, x = targetX - wx, y = targetY - wy;
				tx = (x * d - y * b) * invDet - px;
				ty = (y * a - x * c) * invDet - py;
				x = child.worldX - wx;
				y = child.worldY - wy;
				dx = (x * d - y * b) * invDet - px;
				dy = (y * a - x * c) * invDet - py;
			}
			float l1 = (float)Math.Sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2;
			if (Math.Abs(psx - psy) <= 0.0001f) {
				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;
				float a = l1 + l2 * cos, o = l2 * MathUtils.Sin(a2);
				a1 = MathUtils.Atan2(ty * a - tx * o, tx * a + ty * o);
			} else {
				cy = 0;
				float a = psx * l2, b = psy * l2, ta = MathUtils.Atan2(ty, tx);
				float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty;
				float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
				float d = c1 * c1 - 4 * c2 * c0;
				if (d >= 0) {
					float q = (float)Math.Sqrt(d);
					if (c1 < 0) q = -q;
					q = -(c1 + q) / 2;
					float r0 = q / c2, r1 = c0 / q;
					float r = Math.Abs(r0) < Math.Abs(r1) ? r0 : r1;
					if (r * r <= dd) {
						float y1 = (float)Math.Sqrt(dd - r * r) * bendDir;
						a1 = ta - MathUtils.Atan2(y1, r);
						a2 = MathUtils.Atan2(y1 / 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;
				float x = l1 + a, dist = x * x;
				if (dist > maxDist) {
					maxAngle = 0;
					maxDist = dist;
					maxX = x;
				}
				x = l1 - a;
				dist = x * x;
				if (dist < minDist) {
					minAngle = MathUtils.PI;
					minDist = dist;
					minX = x;
				}
				float angle = (float)Math.Acos(-a * l1 / (aa - bb));
				x = a * MathUtils.Cos(angle) + l1;
				float y = b * MathUtils.Sin(angle);
				dist = x * x + y * y;
				if (dist < minDist) {
					minAngle = angle;
					minDist = dist;
					minX = x;
					minY = y;
				}
				if (dist > maxDist) {
					maxAngle = angle;
					maxDist = dist;
					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 offset = MathUtils.Atan2(cy, child.x) * sign2;
			a1 = (a1 - offset) * MathUtils.radDeg + offset1;
			a2 = (a2 + offset) * MathUtils.radDeg * sign2 + offset2;
			if (a1 > 180) a1 -= 360;
			else if (a1 < -180) a1 += 360;
			if (a2 > 180) a2 -= 360;
			else if (a2 < -180) a2 += 360;
			float rotation = parent.rotation;
			parent.UpdateWorldTransform(parent.x, parent.y, rotation + (a1 - rotation) * alpha, parent.scaleX, parent.scaleY);
			rotation = child.rotation;
			child.UpdateWorldTransform(child.x, cy, rotation + (a2 - rotation) * alpha, child.scaleX, child.scaleY);
		}
コード例 #28
0
        public static void Apply(Bone parent, Bone child, float targetX, float targetY, int bendDir, float alpha)
        {
            if (alpha == 0f)
            {
                child.UpdateWorldTransform();
                return;
            }
            float x    = parent.x;
            float y    = parent.y;
            float num  = parent.scaleX;
            float num2 = parent.scaleY;
            float num3 = child.scaleX;
            int   num4;
            int   num5;

            if (num < 0f)
            {
                num  = -num;
                num4 = 180;
                num5 = -1;
            }
            else
            {
                num4 = 0;
                num5 = 1;
            }
            if (num2 < 0f)
            {
                num2 = -num2;
                num5 = -num5;
            }
            int num6;

            if (num3 < 0f)
            {
                num3 = -num3;
                num6 = 180;
            }
            else
            {
                num6 = 0;
            }
            float x2    = child.x;
            float num7  = parent.a;
            float num8  = parent.b;
            float num9  = parent.c;
            float num10 = parent.d;
            bool  flag  = Math.Abs(num - num2) <= 0.0001f;
            float num11;
            float num12;
            float num13;

            if (!flag)
            {
                num11 = 0f;
                num12 = num7 * x2 + parent.worldX;
                num13 = num9 * x2 + parent.worldY;
            }
            else
            {
                num11 = child.y;
                num12 = num7 * x2 + num8 * num11 + parent.worldX;
                num13 = num9 * x2 + num10 * num11 + parent.worldY;
            }
            Bone parent2 = parent.parent;

            num7  = parent2.a;
            num8  = parent2.b;
            num9  = parent2.c;
            num10 = parent2.d;
            float num14 = 1f / (num7 * num10 - num8 * num9);
            float num15 = targetX - parent2.worldX;
            float num16 = targetY - parent2.worldY;
            float num17 = (num15 * num10 - num16 * num8) * num14 - x;
            float num18 = (num16 * num7 - num15 * num9) * num14 - y;

            num15 = num12 - parent2.worldX;
            num16 = num13 - parent2.worldY;
            float num19 = (num15 * num10 - num16 * num8) * num14 - x;
            float num20 = (num16 * num7 - num15 * num9) * num14 - y;
            float num21 = (float)Math.Sqrt((double)(num19 * num19 + num20 * num20));
            float num22 = child.data.length * num3;
            float num24;
            float num25;

            if (flag)
            {
                num22 *= num;
                float num23 = (num17 * num17 + num18 * num18 - num21 * num21 - num22 * num22) / (2f * num21 * num22);
                if (num23 < -1f)
                {
                    num23 = -1f;
                }
                else if (num23 > 1f)
                {
                    num23 = 1f;
                }
                num24 = (float)Math.Acos((double)num23) * (float)bendDir;
                num7  = num21 + num22 * num23;
                num8  = num22 * MathUtils.Sin(num24);
                num25 = MathUtils.Atan2(num18 * num7 - num17 * num8, num17 * num7 + num18 * num8);
            }
            else
            {
                num7 = num * num22;
                num8 = num2 * num22;
                float num26 = num7 * num7;
                float num27 = num8 * num8;
                float num28 = num17 * num17 + num18 * num18;
                float num29 = MathUtils.Atan2(num18, num17);
                num9 = num27 * num21 * num21 + num26 * num28 - num26 * num27;
                float num30 = -2f * num27 * num21;
                float num31 = num27 - num26;
                num10 = num30 * num30 - 4f * num31 * num9;
                if (num10 >= 0f)
                {
                    float num32 = (float)Math.Sqrt((double)num10);
                    if (num30 < 0f)
                    {
                        num32 = -num32;
                    }
                    num32 = -(num30 + num32) / 2f;
                    float num33 = num32 / num31;
                    float num34 = num9 / num32;
                    float num35 = (Math.Abs(num33) >= Math.Abs(num34)) ? num34 : num33;
                    if (num35 * num35 <= num28)
                    {
                        num16 = (float)Math.Sqrt((double)(num28 - num35 * num35)) * (float)bendDir;
                        num25 = num29 - MathUtils.Atan2(num16, num35);
                        num24 = MathUtils.Atan2(num16 / num2, (num35 - num21) / num);
                        goto IL_4FA;
                    }
                }
                float num36 = 0f;
                float num37 = float.MaxValue;
                float x3    = 0f;
                float num38 = 0f;
                float num39 = 0f;
                float num40 = 0f;
                float x4    = 0f;
                float num41 = 0f;
                num15 = num21 + num7;
                num10 = num15 * num15;
                if (num10 > num40)
                {
                    num39 = 0f;
                    num40 = num10;
                    x4    = num15;
                }
                num15 = num21 - num7;
                num10 = num15 * num15;
                if (num10 < num37)
                {
                    num36 = 3.14159274f;
                    num37 = num10;
                    x3    = num15;
                }
                float num42 = (float)Math.Acos((double)(-(double)num7 * num21 / (num26 - num27)));
                num15 = num7 * MathUtils.Cos(num42) + num21;
                num16 = num8 * MathUtils.Sin(num42);
                num10 = num15 * num15 + num16 * num16;
                if (num10 < num37)
                {
                    num36 = num42;
                    num37 = num10;
                    x3    = num15;
                    num38 = num16;
                }
                if (num10 > num40)
                {
                    num39 = num42;
                    num40 = num10;
                    x4    = num15;
                    num41 = num16;
                }
                if (num28 <= (num37 + num40) / 2f)
                {
                    num25 = num29 - MathUtils.Atan2(num38 * (float)bendDir, x3);
                    num24 = num36 * (float)bendDir;
                }
                else
                {
                    num25 = num29 - MathUtils.Atan2(num41 * (float)bendDir, x4);
                    num24 = num39 * (float)bendDir;
                }
            }
IL_4FA:
            float num43 = MathUtils.Atan2(num11, x2) * (float)num5;
            float rotation = parent.rotation;

            num25 = (num25 - num43) * 57.2957764f + (float)num4 - rotation;
            if (num25 > 180f)
            {
                num25 -= 360f;
            }
            else if (num25 < -180f)
            {
                num25 += 360f;
            }
            parent.UpdateWorldTransform(x, y, rotation + num25 * alpha, parent.scaleX, parent.scaleY, 0f, 0f);
            rotation = child.rotation;
            num24    = ((num24 + num43) * 57.2957764f - child.shearX) * (float)num5 + (float)num6 - rotation;
            if (num24 > 180f)
            {
                num24 -= 360f;
            }
            else if (num24 < -180f)
            {
                num24 += 360f;
            }
            child.UpdateWorldTransform(x2, num11, rotation + num24 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
        }