UpdateAppliedTransform() 개인적인 메소드

Computes the individual applied transform values from the world transform. This can be useful to perform processing using the applied transform after the world transform has been modified directly (eg, by a constraint).. Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation.
private UpdateAppliedTransform ( ) : void
리턴 void
예제 #1
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);
        }
예제 #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(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);
        }
예제 #3
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);
            }
        }
		/// <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);
		}
예제 #5
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.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);
        }
예제 #6
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.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);
		}
예제 #8
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);
        }
예제 #9
0
        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();
            }
        }
예제 #10
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);
        }