Inheritance: VertexAttachment
Exemple #1
0
        private void SortPathConstraintAttachment(Attachment attachment, Bone slotBone)
        {
            PathAttachment pathAttachment = attachment as PathAttachment;

            if (pathAttachment == null)
            {
                return;
            }
            int[] array = pathAttachment.bones;
            if (array == null)
            {
                this.SortBone(slotBone);
            }
            else
            {
                ExposedList <Bone> exposedList = this.bones;
                int i   = 0;
                int num = array.Length;
                while (i < num)
                {
                    this.SortBone(exposedList.Items[array[i]]);
                    i++;
                }
            }
        }
        public override Attachment Copy()
        {
            PathAttachment copy = new PathAttachment(this.Name);

            CopyTo(copy);
            copy.lengths = new float[lengths.Length];
            Array.Copy(lengths, 0, copy.lengths, 0, lengths.Length);
            copy.closed        = closed;
            copy.constantSpeed = constantSpeed;
            return(copy);
        }
Exemple #3
0
        public void Update()
        {
            PathAttachment path = this.target.Attachment as PathAttachment;

            if (path != null)
            {
                float rotateMix    = this.rotateMix;
                float translateMix = this.translateMix;
                bool  flag         = translateMix > 0f;
                bool  flag2        = rotateMix > 0f;
                if (flag || flag2)
                {
                    bool flag6;
                    PathConstraintData data        = this.data;
                    SpacingMode        spacingMode = data.spacingMode;
                    bool                flag3      = spacingMode == SpacingMode.Length;
                    RotateMode          rotateMode = data.rotateMode;
                    bool                tangents   = rotateMode == RotateMode.Tangent;
                    bool                flag5      = rotateMode == RotateMode.ChainScale;
                    int                 count      = this.bones.Count;
                    int                 newSize    = !tangents ? (count + 1) : count;
                    Bone[]              items      = this.bones.Items;
                    ExposedList <float> list       = this.spaces.Resize(newSize);
                    ExposedList <float> list2      = null;
                    float               spacing    = this.spacing;
                    if (flag5 || flag3)
                    {
                        if (flag5)
                        {
                            list2 = this.lengths.Resize(count);
                        }
                        int num6 = 0;
                        int num7 = newSize - 1;
                        while (num6 < num7)
                        {
                            Bone  bone   = items[num6];
                            float length = bone.data.length;
                            if (length < 1E-05f)
                            {
                                if (flag5)
                                {
                                    list2.Items[num6] = 0f;
                                }
                                list.Items[++num6] = 0f;
                            }
                            else
                            {
                                float num9  = length * bone.a;
                                float num10 = length * bone.c;
                                float num11 = (float)Math.Sqrt((double)((num9 * num9) + (num10 * num10)));
                                if (flag5)
                                {
                                    list2.Items[num6] = num11;
                                }
                                list.Items[++num6] = ((!flag3 ? spacing : (length + spacing)) * num11) / length;
                            }
                        }
                    }
                    else
                    {
                        for (int j = 1; j < newSize; j++)
                        {
                            list.Items[j] = spacing;
                        }
                    }
                    float[] numArray       = this.ComputeWorldPositions(path, newSize, tangents, data.positionMode == PositionMode.Percent, spacingMode == SpacingMode.Percent);
                    float   num13          = numArray[0];
                    float   num14          = numArray[1];
                    float   offsetRotation = data.offsetRotation;
                    if (offsetRotation == 0f)
                    {
                        flag6 = rotateMode == RotateMode.Chain;
                    }
                    else
                    {
                        flag6 = false;
                        Bone bone = this.target.bone;
                        offsetRotation *= (((bone.a * bone.d) - (bone.b * bone.c)) <= 0f) ? -0.01745329f : 0.01745329f;
                    }
                    int index = 0;
                    for (int i = 3; index < count; i += 3)
                    {
                        Bone bone3 = items[index];
                        bone3.worldX += (num13 - bone3.worldX) * translateMix;
                        bone3.worldY += (num14 - bone3.worldY) * translateMix;
                        float num18 = numArray[i];
                        float num19 = numArray[i + 1];
                        float x     = num18 - num13;
                        float y     = num19 - num14;
                        if (flag5)
                        {
                            float num22 = list2.Items[index];
                            if (num22 >= 1E-05f)
                            {
                                float num23 = (((((float)Math.Sqrt((double)((x * x) + (y * y)))) / num22) - 1f) * rotateMix) + 1f;
                                bone3.a *= num23;
                                bone3.c *= num23;
                            }
                        }
                        num13 = num18;
                        num14 = num19;
                        if (flag2)
                        {
                            float num28;
                            float num29;
                            float num30;
                            float a = bone3.a;
                            float b = bone3.b;
                            float c = bone3.c;
                            float d = bone3.d;
                            if (tangents)
                            {
                                num28 = numArray[i - 1];
                            }
                            else if (list.Items[index + 1] < 1E-05f)
                            {
                                num28 = numArray[i + 2];
                            }
                            else
                            {
                                num28 = MathUtils.Atan2(y, x);
                            }
                            num28 -= MathUtils.Atan2(c, a);
                            if (flag6)
                            {
                                num29 = MathUtils.Cos(num28);
                                num30 = MathUtils.Sin(num28);
                                float length = bone3.data.length;
                                num13 += ((length * ((num29 * a) - (num30 * c))) - x) * rotateMix;
                                num14 += ((length * ((num30 * a) + (num29 * c))) - y) * rotateMix;
                            }
                            else
                            {
                                num28 += offsetRotation;
                            }
                            if (num28 > 3.141593f)
                            {
                                num28 -= 6.283185f;
                            }
                            else if (num28 < -3.141593f)
                            {
                                num28 += 6.283185f;
                            }
                            num28  *= rotateMix;
                            num29   = MathUtils.Cos(num28);
                            num30   = MathUtils.Sin(num28);
                            bone3.a = (num29 * a) - (num30 * c);
                            bone3.b = (num29 * b) - (num30 * d);
                            bone3.c = (num30 * a) + (num29 * c);
                            bone3.d = (num30 * b) + (num29 * d);
                        }
                        bone3.appliedValid = false;
                        index++;
                    }
                }
            }
        }
Exemple #4
0
        private float[] ComputeWorldPositions(PathAttachment path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing)
        {
            float[] numArray3;
            float   num5;
            float   num22;
            float   num23;
            float   num24;
            float   num25;
            float   num26;
            float   num27;
            float   num28;
            float   num29;
            Slot    target   = this.target;
            float   position = this.position;

            float[] items  = this.spaces.Items;
            float[] output = this.positions.Resize((spacesCount * 3) + 2).Items;
            bool    closed = path.Closed;
            int     worldVerticesLength = path.WorldVerticesLength;
            int     index = worldVerticesLength / 6;
            int     num4  = -1;

            if (!path.ConstantSpeed)
            {
                float[] lengths = path.Lengths;
                index -= !closed ? 2 : 1;
                num5   = lengths[index];
                if (percentPosition)
                {
                    position *= num5;
                }
                if (percentSpacing)
                {
                    for (int j = 0; j < spacesCount; j++)
                    {
                        items[j] *= num5;
                    }
                }
                numArray3 = this.world.Resize(8).Items;
                int num7 = 0;
                int num8 = 0;
                int num9 = 0;
                while (num7 < spacesCount)
                {
                    float num12;
                    float num10 = items[num7];
                    position += num10;
                    float p = position;
                    if (closed)
                    {
                        p = p % num5;
                        if (p < 0f)
                        {
                            p += num5;
                        }
                        num9 = 0;
                    }
                    else
                    {
                        if (p < 0f)
                        {
                            if (num4 != -2)
                            {
                                num4 = -2;
                                path.ComputeWorldVertices(target, 2, 4, numArray3, 0, 2);
                            }
                            AddBeforePosition(p, numArray3, 0, output, num8);
                            goto Label_0263;
                        }
                        if (p > num5)
                        {
                            if (num4 != -3)
                            {
                                num4 = -3;
                                path.ComputeWorldVertices(target, worldVerticesLength - 6, 4, numArray3, 0, 2);
                            }
                            AddAfterPosition(p - num5, numArray3, 0, output, num8);
                            goto Label_0263;
                        }
                    }
Label_017D:
                    num12 = lengths[num9];
                    if (p <= num12)
                    {
                        if (num9 == 0)
                        {
                            p /= num12;
                        }
                        else
                        {
                            float num13 = lengths[num9 - 1];
                            p = (p - num13) / (num12 - num13);
                        }
                    }
                    else
                    {
                        num9++;
                        goto Label_017D;
                    }
                    if (num9 != num4)
                    {
                        num4 = num9;
                        if (closed && (num9 == index))
                        {
                            path.ComputeWorldVertices(target, worldVerticesLength - 4, 4, numArray3, 0, 2);
                            path.ComputeWorldVertices(target, 0, 4, numArray3, 4, 2);
                        }
                        else
                        {
                            path.ComputeWorldVertices(target, (num9 * 6) + 2, 8, numArray3, 0, 2);
                        }
                    }
                    AddCurvePosition(p, numArray3[0], numArray3[1], numArray3[2], numArray3[3], numArray3[4], numArray3[5], numArray3[6], numArray3[7], output, num8, tangents || ((num7 > 0) && (num10 < 1E-05f)));
Label_0263:
                    num7++;
                    num8 += 3;
                }
                return(output);
            }
            if (closed)
            {
                worldVerticesLength += 2;
                numArray3            = this.world.Resize(worldVerticesLength).Items;
                path.ComputeWorldVertices(target, 2, worldVerticesLength - 4, numArray3, 0, 2);
                path.ComputeWorldVertices(target, 0, 2, numArray3, worldVerticesLength - 4, 2);
                numArray3[worldVerticesLength - 2] = numArray3[0];
                numArray3[worldVerticesLength - 1] = numArray3[1];
            }
            else
            {
                index--;
                worldVerticesLength -= 4;
                numArray3            = this.world.Resize(worldVerticesLength).Items;
                path.ComputeWorldVertices(target, 2, worldVerticesLength, numArray3, 0, 2);
            }
            float[] numArray5 = this.curves.Resize(index).Items;
            num5 = 0f;
            float num14 = numArray3[0];
            float num15 = numArray3[1];
            float num16 = 0f;
            float num17 = 0f;
            float num18 = 0f;
            float num19 = 0f;
            float num20 = 0f;
            float num21 = 0f;
            int   num30 = 0;

            for (int i = 2; num30 < index; i += 6)
            {
                num16            = numArray3[i];
                num17            = numArray3[i + 1];
                num18            = numArray3[i + 2];
                num19            = numArray3[i + 3];
                num20            = numArray3[i + 4];
                num21            = numArray3[i + 5];
                num22            = ((num14 - (num16 * 2f)) + num18) * 0.1875f;
                num23            = ((num15 - (num17 * 2f)) + num19) * 0.1875f;
                num24            = ((((num16 - num18) * 3f) - num14) + num20) * 0.09375f;
                num25            = ((((num17 - num19) * 3f) - num15) + num21) * 0.09375f;
                num26            = (num22 * 2f) + num24;
                num27            = (num23 * 2f) + num25;
                num28            = (((num16 - num14) * 0.75f) + num22) + (num24 * 0.1666667f);
                num29            = (((num17 - num15) * 0.75f) + num23) + (num25 * 0.1666667f);
                num5            += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                num28           += num26;
                num29           += num27;
                num26           += num24;
                num27           += num25;
                num5            += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                num28           += num26;
                num29           += num27;
                num5            += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                num28           += num26 + num24;
                num29           += num27 + num25;
                num5            += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                numArray5[num30] = num5;
                num14            = num20;
                num15            = num21;
                num30++;
            }
            if (percentPosition)
            {
                position *= num5;
            }
            if (percentSpacing)
            {
                for (int j = 0; j < spacesCount; j++)
                {
                    items[j] *= num5;
                }
            }
            float[] segments = this.segments;
            float   num33    = 0f;
            int     num34    = 0;
            int     o        = 0;
            int     num36    = 0;
            int     num37    = 0;

            while (num34 < spacesCount)
            {
                float num40;
                float num38 = items[num34];
                position += num38;
                float p = position;
                if (closed)
                {
                    p = p % num5;
                    if (p < 0f)
                    {
                        p += num5;
                    }
                    num36 = 0;
                }
                else
                {
                    if (p < 0f)
                    {
                        AddBeforePosition(p, numArray3, 0, output, o);
                        goto Label_0883;
                    }
                    if (p > num5)
                    {
                        AddAfterPosition(p - num5, numArray3, worldVerticesLength - 4, output, o);
                        goto Label_0883;
                    }
                }
Label_05CD:
                num40 = numArray5[num36];
                if (p <= num40)
                {
                    if (num36 == 0)
                    {
                        p /= num40;
                    }
                    else
                    {
                        float num41 = numArray5[num36 - 1];
                        p = (p - num41) / (num40 - num41);
                    }
                }
                else
                {
                    num36++;
                    goto Label_05CD;
                }
                if (num36 != num4)
                {
                    num4 = num36;
                    int num42 = num36 * 6;
                    num14       = numArray3[num42];
                    num15       = numArray3[num42 + 1];
                    num16       = numArray3[num42 + 2];
                    num17       = numArray3[num42 + 3];
                    num18       = numArray3[num42 + 4];
                    num19       = numArray3[num42 + 5];
                    num20       = numArray3[num42 + 6];
                    num21       = numArray3[num42 + 7];
                    num22       = ((num14 - (num16 * 2f)) + num18) * 0.03f;
                    num23       = ((num15 - (num17 * 2f)) + num19) * 0.03f;
                    num24       = ((((num16 - num18) * 3f) - num14) + num20) * 0.006f;
                    num25       = ((((num17 - num19) * 3f) - num15) + num21) * 0.006f;
                    num26       = (num22 * 2f) + num24;
                    num27       = (num23 * 2f) + num25;
                    num28       = (((num16 - num14) * 0.3f) + num22) + (num24 * 0.1666667f);
                    num29       = (((num17 - num15) * 0.3f) + num23) + (num25 * 0.1666667f);
                    num33       = (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                    segments[0] = num33;
                    for (num42 = 1; num42 < 8; num42++)
                    {
                        num28          += num26;
                        num29          += num27;
                        num26          += num24;
                        num27          += num25;
                        num33          += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                        segments[num42] = num33;
                    }
                    num28      += num26;
                    num29      += num27;
                    num33      += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                    segments[8] = num33;
                    num28      += num26 + num24;
                    num29      += num27 + num25;
                    num33      += (float)Math.Sqrt((double)((num28 * num28) + (num29 * num29)));
                    segments[9] = num33;
                    num37       = 0;
                }
                p *= num33;
                while (true)
                {
                    float num43 = segments[num37];
                    if (p <= num43)
                    {
                        if (num37 == 0)
                        {
                            p /= num43;
                        }
                        else
                        {
                            float num44 = segments[num37 - 1];
                            p = num37 + ((p - num44) / (num43 - num44));
                        }
                        break;
                    }
                    num37++;
                }
                AddCurvePosition(p * 0.1f, num14, num15, num16, num17, num18, num19, num20, num21, output, o, tangents || ((num34 > 0) && (num38 < 1E-05f)));
Label_0883:
                num34++;
                o += 3;
            }
            return(output);
        }
Exemple #5
0
        public void UpdateCache()
        {
            ExposedList <IUpdatable> exposedList = this.updateCache;

            exposedList.Clear(true);
            ExposedList <Bone> exposedList2 = this.bones;
            int i     = 0;
            int count = exposedList2.Count;

            while (i < count)
            {
                exposedList2.Items[i].sorted = false;
                i++;
            }
            ExposedList <IkConstraint> exposedList3 = this.ikConstraintsSorted;

            exposedList3.Clear(true);
            exposedList3.AddRange(this.ikConstraints);
            int count2 = exposedList3.Count;
            int j      = 0;
            int num    = count2;

            while (j < num)
            {
                IkConstraint ikConstraint = exposedList3.Items[j];
                Bone         parent       = ikConstraint.bones.Items[0].parent;
                int          num2         = 0;
                while (parent != null)
                {
                    parent = parent.parent;
                    num2++;
                }
                ikConstraint.level = num2;
                j++;
            }
            for (int k = 1; k < count2; k++)
            {
                IkConstraint ikConstraint2 = exposedList3.Items[k];
                int          level         = ikConstraint2.level;
                int          l;
                for (l = k - 1; l >= 0; l--)
                {
                    IkConstraint ikConstraint3 = exposedList3.Items[l];
                    if (ikConstraint3.level < level)
                    {
                        break;
                    }
                    exposedList3.Items[l + 1] = ikConstraint3;
                }
                exposedList3.Items[l + 1] = ikConstraint2;
            }
            int m      = 0;
            int count3 = exposedList3.Count;

            while (m < count3)
            {
                IkConstraint ikConstraint4 = exposedList3.Items[m];
                Bone         target        = ikConstraint4.target;
                this.SortBone(target);
                ExposedList <Bone> exposedList4 = ikConstraint4.bones;
                Bone bone = exposedList4.Items[0];
                this.SortBone(bone);
                exposedList.Add(ikConstraint4);
                this.SortReset(bone.children);
                exposedList4.Items[exposedList4.Count - 1].sorted = true;
                m++;
            }
            ExposedList <PathConstraint> exposedList5 = this.pathConstraints;
            int n      = 0;
            int count4 = exposedList5.Count;

            while (n < count4)
            {
                PathConstraint pathConstraint = exposedList5.Items[n];
                Slot           target2        = pathConstraint.target;
                int            index          = target2.data.index;
                Bone           bone2          = target2.bone;
                if (this.skin != null)
                {
                    this.SortPathConstraintAttachment(this.skin, index, bone2);
                }
                if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin)
                {
                    this.SortPathConstraintAttachment(this.data.defaultSkin, index, bone2);
                }
                int num3   = 0;
                int count5 = this.data.skins.Count;
                while (num3 < count5)
                {
                    this.SortPathConstraintAttachment(this.data.skins.Items[num3], index, bone2);
                    num3++;
                }
                PathAttachment pathAttachment = target2.Attachment as PathAttachment;
                if (pathAttachment != null)
                {
                    this.SortPathConstraintAttachment(pathAttachment, bone2);
                }
                ExposedList <Bone> exposedList6 = pathConstraint.bones;
                int count6 = exposedList6.Count;
                for (int num4 = 0; num4 < count6; num4++)
                {
                    this.SortBone(exposedList6.Items[num4]);
                }
                exposedList.Add(pathConstraint);
                for (int num5 = 0; num5 < count6; num5++)
                {
                    this.SortReset(exposedList6.Items[num5].children);
                }
                for (int num6 = 0; num6 < count6; num6++)
                {
                    exposedList6.Items[num6].sorted = true;
                }
                n++;
            }
            ExposedList <TransformConstraint> exposedList7 = this.transformConstraints;
            int num7   = 0;
            int count7 = exposedList7.Count;

            while (num7 < count7)
            {
                TransformConstraint transformConstraint = exposedList7.Items[num7];
                this.SortBone(transformConstraint.target);
                ExposedList <Bone> exposedList8 = transformConstraint.bones;
                int count8 = exposedList8.Count;
                for (int num8 = 0; num8 < count8; num8++)
                {
                    this.SortBone(exposedList8.Items[num8]);
                }
                exposedList.Add(transformConstraint);
                for (int num9 = 0; num9 < count8; num9++)
                {
                    this.SortReset(exposedList8.Items[num9].children);
                }
                for (int num10 = 0; num10 < count8; num10++)
                {
                    exposedList8.Items[num10].sorted = true;
                }
                num7++;
            }
            int num11  = 0;
            int count9 = exposedList2.Count;

            while (num11 < count9)
            {
                this.SortBone(exposedList2.Items[num11]);
                num11++;
            }
        }
		public static void DrawPath (Slot s, PathAttachment p, Transform t, bool includeName) {
			int worldVerticesLength = p.WorldVerticesLength;

			if (pathVertexBuffer == null || pathVertexBuffer.Length < worldVerticesLength)
				pathVertexBuffer = new float[worldVerticesLength];

			float[] pv = pathVertexBuffer;
			p.ComputeWorldVertices(s, pv);

			var ocolor = Handles.color;
			Handles.color = SpineHandles.PathColor;

			Matrix4x4 m = t.localToWorldMatrix;
			const int step = 6;
			int n = worldVerticesLength - step;
			Vector3 p0, p1, p2, p3;
			for (int i = 2; i < n; i += step) {
				p0 = m.MultiplyPoint(new Vector3(pv[i], pv[i+1]));
				p1 = m.MultiplyPoint(new Vector3(pv[i+2], pv[i+3]));
				p2 = m.MultiplyPoint(new Vector3(pv[i+4], pv[i+5]));
				p3 = m.MultiplyPoint(new Vector3(pv[i+6], pv[i+7]));
				DrawCubicBezier(p0, p1, p2, p3);
			}

			n += step;
			if (p.Closed) {
				p0 = m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3]));
				p1 = m.MultiplyPoint(new Vector3(pv[n - 2], pv[n - 1]));
				p2 = m.MultiplyPoint(new Vector3(pv[0], pv[1]));
				p3 = m.MultiplyPoint(new Vector3(pv[2], pv[3]));
				DrawCubicBezier(p0, p1, p2, p3);
			}

			const float endCapSize = 0.05f;
			Vector3 firstPoint = m.MultiplyPoint(new Vector3(pv[2], pv[3]));
			Handles.DotCap(0, firstPoint, Quaternion.identity, endCapSize * HandleUtility.GetHandleSize(firstPoint));
			//			if (!p.Closed) Handles.DotCap(0, m.MultiplyPoint(new Vector3(pv[n - 4], pv[n - 3])), q, endCapSize);
			if (includeName) Handles.Label(firstPoint + new Vector3(0,0.1f), p.Name, PathNameStyle);

			Handles.color = ocolor;
		}
        float[] ComputeWorldPositions(PathAttachment path, int spacesCount, bool tangents, bool percentPosition,
                                      bool percentSpacing)
        {
            Slot  target   = this.target;
            float position = this.position;

            float[] spacesItems = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world;
            bool    closed = path.Closed;
            int     verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE;
            float   pathLength = 0;

            if (!path.ConstantSpeed)
            {
                float[] lengths = path.Lengths;
                curveCount -= closed ? 1 : 2;
                pathLength  = lengths[curveCount];
                if (percentPosition)
                {
                    position *= pathLength;
                }
                if (percentSpacing)
                {
                    for (int i = 1; i < spacesCount; i++)
                    {
                        spacesItems[i] *= pathLength;
                    }
                }
                world = this.world.Resize(8).Items;
                for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3)
                {
                    float space = spacesItems[i];
                    position += space;
                    float p = position;

                    if (closed)
                    {
                        p %= pathLength;
                        if (p < 0)
                        {
                            p += pathLength;
                        }
                        curve = 0;
                    }
                    else if (p < 0)
                    {
                        if (prevCurve != BEFORE)
                        {
                            prevCurve = BEFORE;
                            path.ComputeWorldVertices(target, 2, 4, world, 0, 2);
                        }
                        AddBeforePosition(p, world, 0, output, o);
                        continue;
                    }
                    else if (p > pathLength)
                    {
                        if (prevCurve != AFTER)
                        {
                            prevCurve = AFTER;
                            path.ComputeWorldVertices(target, verticesLength - 6, 4, world, 0, 2);
                        }
                        AddAfterPosition(p - pathLength, world, 0, output, o);
                        continue;
                    }

                    // Determine curve containing position.
                    for (;; curve++)
                    {
                        float length = lengths[curve];
                        if (p > length)
                        {
                            continue;
                        }
                        if (curve == 0)
                        {
                            p /= length;
                        }
                        else
                        {
                            float prev = lengths[curve - 1];
                            p = (p - prev) / (length - prev);
                        }
                        break;
                    }
                    if (curve != prevCurve)
                    {
                        prevCurve = curve;
                        if (closed && curve == curveCount)
                        {
                            path.ComputeWorldVertices(target, verticesLength - 4, 4, world, 0, 2);
                            path.ComputeWorldVertices(target, 0, 4, world, 4, 2);
                        }
                        else
                        {
                            path.ComputeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
                        }
                    }
                    AddCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], output, o,
                                     tangents || (i > 0 && space < PathConstraint.Epsilon));
                }
                return(output);
            }

            // World vertices.
            if (closed)
            {
                verticesLength += 2;
                world           = this.world.Resize(verticesLength).Items;
                path.ComputeWorldVertices(target, 2, verticesLength - 4, world, 0, 2);
                path.ComputeWorldVertices(target, 0, 2, world, verticesLength - 4, 2);
                world[verticesLength - 2] = world[0];
                world[verticesLength - 1] = world[1];
            }
            else
            {
                curveCount--;
                verticesLength -= 4;
                world           = this.world.Resize(verticesLength).Items;
                path.ComputeWorldVertices(target, 2, verticesLength, world, 0, 2);
            }

            // Curve lengths.
            float[] curves = this.curves.Resize(curveCount).Items;
            pathLength = 0;
            float x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
            float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;

            for (int i = 0, w = 2; i < curveCount; i++, w += 6)
            {
                cx1         = world[w];
                cy1         = world[w + 1];
                cx2         = world[w + 2];
                cy2         = world[w + 3];
                x2          = world[w + 4];
                y2          = world[w + 5];
                tmpx        = (x1 - cx1 * 2 + cx2) * 0.1875f;
                tmpy        = (y1 - cy1 * 2 + cy2) * 0.1875f;
                dddfx       = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375f;
                dddfy       = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375f;
                ddfx        = tmpx * 2 + dddfx;
                ddfy        = tmpy * 2 + dddfy;
                dfx         = (cx1 - x1) * 0.75f + tmpx + dddfx * 0.16666667f;
                dfy         = (cy1 - y1) * 0.75f + tmpy + dddfy * 0.16666667f;
                pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                dfx        += ddfx;
                dfy        += ddfy;
                ddfx       += dddfx;
                ddfy       += dddfy;
                pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                dfx        += ddfx;
                dfy        += ddfy;
                pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                dfx        += ddfx + dddfx;
                dfy        += ddfy + dddfy;
                pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                curves[i]   = pathLength;
                x1          = x2;
                y1          = y2;
            }
            if (percentPosition)
            {
                position *= pathLength;
            }
            else
            {
                position *= pathLength / path.lengths[curveCount - 1];
            }

            if (percentSpacing)
            {
                for (int i = 1; i < spacesCount; i++)
                {
                    spacesItems[i] *= pathLength;
                }
            }

            float[] segments    = this.segments;
            float   curveLength = 0;

            for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3)
            {
                float space = spacesItems[i];
                position += space;
                float p = position;

                if (closed)
                {
                    p %= pathLength;
                    if (p < 0)
                    {
                        p += pathLength;
                    }
                    curve = 0;
                }
                else if (p < 0)
                {
                    AddBeforePosition(p, world, 0, output, o);
                    continue;
                }
                else if (p > pathLength)
                {
                    AddAfterPosition(p - pathLength, world, verticesLength - 4, output, o);
                    continue;
                }

                // Determine curve containing position.
                for (;; curve++)
                {
                    float length = curves[curve];
                    if (p > length)
                    {
                        continue;
                    }
                    if (curve == 0)
                    {
                        p /= length;
                    }
                    else
                    {
                        float prev = curves[curve - 1];
                        p = (p - prev) / (length - prev);
                    }
                    break;
                }

                // Curve segment lengths.
                if (curve != prevCurve)
                {
                    prevCurve = curve;
                    int ii = curve * 6;
                    x1          = world[ii];
                    y1          = world[ii + 1];
                    cx1         = world[ii + 2];
                    cy1         = world[ii + 3];
                    cx2         = world[ii + 4];
                    cy2         = world[ii + 5];
                    x2          = world[ii + 6];
                    y2          = world[ii + 7];
                    tmpx        = (x1 - cx1 * 2 + cx2) * 0.03f;
                    tmpy        = (y1 - cy1 * 2 + cy2) * 0.03f;
                    dddfx       = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f;
                    dddfy       = ((cy1 - cy2) * 3 - y1 + y2) * 0.006f;
                    ddfx        = tmpx * 2 + dddfx;
                    ddfy        = tmpy * 2 + dddfy;
                    dfx         = (cx1 - x1) * 0.3f + tmpx + dddfx * 0.16666667f;
                    dfy         = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f;
                    curveLength = (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                    segments[0] = curveLength;
                    for (ii = 1; ii < 8; ii++)
                    {
                        dfx         += ddfx;
                        dfy         += ddfy;
                        ddfx        += dddfx;
                        ddfy        += dddfy;
                        curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                        segments[ii] = curveLength;
                    }
                    dfx         += ddfx;
                    dfy         += ddfy;
                    curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                    segments[8]  = curveLength;
                    dfx         += ddfx + dddfx;
                    dfy         += ddfy + dddfy;
                    curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
                    segments[9]  = curveLength;
                    segment      = 0;
                }

                // Weight by segment length.
                p *= curveLength;
                for (;; segment++)
                {
                    float length = segments[segment];
                    if (p > length)
                    {
                        continue;
                    }
                    if (segment == 0)
                    {
                        p /= length;
                    }
                    else
                    {
                        float prev = segments[segment - 1];
                        p = segment + (p - prev) / (length - prev);
                    }
                    break;
                }
                AddCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, output, o, tangents || (i > 0 && space < PathConstraint.Epsilon));
            }
            return(output);
        }
Exemple #8
0
        private Attachment ReadAttachment(Dictionary <String, Object> map, Skin skin, int slotIndex, String name)
        {
            var scale = this.Scale;

            name = GetString(map, "name", name);

            var typeName = GetString(map, "type", "region");

            if (typeName == "skinnedmesh")
            {
                typeName = "weightedmesh";
            }
            if (typeName == "weightedmesh")
            {
                typeName = "mesh";
            }
            if (typeName == "weightedlinkedmesh")
            {
                typeName = "linkedmesh";
            }
            var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true);

            String path = GetString(map, "path", name);

            switch (type)
            {
            case AttachmentType.Region:
                RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
                if (region == null)
                {
                    return(null);
                }
                region.Path     = path;
                region.x        = GetFloat(map, "x", 0) * scale;
                region.y        = GetFloat(map, "y", 0) * scale;
                region.scaleX   = GetFloat(map, "scaleX", 1);
                region.scaleY   = GetFloat(map, "scaleY", 1);
                region.rotation = GetFloat(map, "rotation", 0);
                region.width    = GetFloat(map, "width", 32) * scale;
                region.height   = GetFloat(map, "height", 32) * scale;
                region.UpdateOffset();

                if (map.ContainsKey("color"))
                {
                    var color = (String)map["color"];
                    region.r = ToColor(color, 0);
                    region.g = ToColor(color, 1);
                    region.b = ToColor(color, 2);
                    region.a = ToColor(color, 3);
                }

                region.UpdateOffset();
                return(region);

            case AttachmentType.Boundingbox:
                BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
                if (box == null)
                {
                    return(null);
                }
                ReadVertices(map, box, GetInt(map, "vertexCount", 0) << 1);
                return(box);

            case AttachmentType.Mesh:
            case AttachmentType.Linkedmesh: {
                MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
                if (mesh == null)
                {
                    return(null);
                }
                mesh.Path = path;

                if (map.ContainsKey("color"))
                {
                    var color = (String)map["color"];
                    mesh.r = ToColor(color, 0);
                    mesh.g = ToColor(color, 1);
                    mesh.b = ToColor(color, 2);
                    mesh.a = ToColor(color, 3);
                }

                mesh.Width  = GetFloat(map, "width", 0) * scale;
                mesh.Height = GetFloat(map, "height", 0) * scale;

                String parent = GetString(map, "parent", null);
                if (parent != null)
                {
                    mesh.InheritDeform = GetBoolean(map, "deform", true);
                    linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent));
                    return(mesh);
                }

                float[] uvs = GetFloatArray(map, "uvs", 1);
                ReadVertices(map, mesh, uvs.Length);
                mesh.triangles = GetIntArray(map, "triangles");
                mesh.regionUVs = uvs;
                mesh.UpdateUVs();

                if (map.ContainsKey("hull"))
                {
                    mesh.HullLength = GetInt(map, "hull", 0) * 2;
                }
                if (map.ContainsKey("edges"))
                {
                    mesh.Edges = GetIntArray(map, "edges");
                }
                return(mesh);
            }

            case AttachmentType.Path: {
                PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, name);
                if (pathAttachment == null)
                {
                    return(null);
                }
                pathAttachment.closed        = GetBoolean(map, "closed", false);
                pathAttachment.constantSpeed = GetBoolean(map, "constantSpeed", true);

                int vertexCount = GetInt(map, "vertexCount", 0);
                ReadVertices(map, pathAttachment, vertexCount << 1);

                // potential BOZO see Java impl
                pathAttachment.lengths = GetFloatArray(map, "lengths", scale);
                return(pathAttachment);
            }
            }
            return(null);
        }
Exemple #9
0
        private Attachment ReadAttachment(Stream input, SkeletonData skeletonData, Skin skin, int slotIndex, string attachmentName, bool nonessential)
        {
            float  scale = Scale;
            string text  = ReadString(input);

            if (text == null)
            {
                text = attachmentName;
            }
            switch (input.ReadByte())
            {
            case 0:
            {
                string text2    = ReadString(input);
                float  rotation = ReadFloat(input);
                float  num3     = ReadFloat(input);
                float  num4     = ReadFloat(input);
                float  scaleX   = ReadFloat(input);
                float  scaleY   = ReadFloat(input);
                float  num5     = ReadFloat(input);
                float  num6     = ReadFloat(input);
                int    num7     = ReadInt(input);
                if (text2 == null)
                {
                    text2 = text;
                }
                RegionAttachment regionAttachment = attachmentLoader.NewRegionAttachment(skin, text, text2);
                if (regionAttachment == null)
                {
                    return(null);
                }
                regionAttachment.Path     = text2;
                regionAttachment.x        = num3 * scale;
                regionAttachment.y        = num4 * scale;
                regionAttachment.scaleX   = scaleX;
                regionAttachment.scaleY   = scaleY;
                regionAttachment.rotation = rotation;
                regionAttachment.width    = num5 * scale;
                regionAttachment.height   = num6 * scale;
                regionAttachment.r        = (float)((num7 & 4278190080u) >> 24) / 255f;
                regionAttachment.g        = (float)((num7 & 0xFF0000) >> 16) / 255f;
                regionAttachment.b        = (float)((num7 & 0xFF00) >> 8) / 255f;
                regionAttachment.a        = (float)(num7 & 0xFF) / 255f;
                regionAttachment.UpdateOffset();
                return(regionAttachment);
            }

            case 1:
            {
                int      num20     = ReadVarint(input, optimizePositive: true);
                Vertices vertices4 = ReadVertices(input, num20);
                if (nonessential)
                {
                    ReadInt(input);
                }
                BoundingBoxAttachment boundingBoxAttachment = attachmentLoader.NewBoundingBoxAttachment(skin, text);
                if (boundingBoxAttachment == null)
                {
                    return(null);
                }
                boundingBoxAttachment.worldVerticesLength = num20 << 1;
                boundingBoxAttachment.vertices            = vertices4.vertices;
                boundingBoxAttachment.bones = vertices4.bones;
                return(boundingBoxAttachment);
            }

            case 2:
            {
                string   text3     = ReadString(input);
                int      num8      = ReadInt(input);
                int      num9      = ReadVarint(input, optimizePositive: true);
                float[]  regionUVs = ReadFloatArray(input, num9 << 1, 1f);
                int[]    triangles = ReadShortArray(input);
                Vertices vertices2 = ReadVertices(input, num9);
                int      num10     = ReadVarint(input, optimizePositive: true);
                int[]    edges     = null;
                float    num11     = 0f;
                float    num12     = 0f;
                if (nonessential)
                {
                    edges = ReadShortArray(input);
                    num11 = ReadFloat(input);
                    num12 = ReadFloat(input);
                }
                if (text3 == null)
                {
                    text3 = text;
                }
                MeshAttachment meshAttachment = attachmentLoader.NewMeshAttachment(skin, text, text3);
                if (meshAttachment == null)
                {
                    return(null);
                }
                meshAttachment.Path                = text3;
                meshAttachment.r                   = (float)((num8 & 4278190080u) >> 24) / 255f;
                meshAttachment.g                   = (float)((num8 & 0xFF0000) >> 16) / 255f;
                meshAttachment.b                   = (float)((num8 & 0xFF00) >> 8) / 255f;
                meshAttachment.a                   = (float)(num8 & 0xFF) / 255f;
                meshAttachment.bones               = vertices2.bones;
                meshAttachment.vertices            = vertices2.vertices;
                meshAttachment.WorldVerticesLength = num9 << 1;
                meshAttachment.triangles           = triangles;
                meshAttachment.regionUVs           = regionUVs;
                meshAttachment.UpdateUVs();
                meshAttachment.HullLength = num10 << 1;
                if (nonessential)
                {
                    meshAttachment.Edges  = edges;
                    meshAttachment.Width  = num11 * scale;
                    meshAttachment.Height = num12 * scale;
                }
                return(meshAttachment);
            }

            case 3:
            {
                string text4         = ReadString(input);
                int    num13         = ReadInt(input);
                string skin2         = ReadString(input);
                string parent        = ReadString(input);
                bool   inheritDeform = ReadBoolean(input);
                float  num14         = 0f;
                float  num15         = 0f;
                if (nonessential)
                {
                    num14 = ReadFloat(input);
                    num15 = ReadFloat(input);
                }
                if (text4 == null)
                {
                    text4 = text;
                }
                MeshAttachment meshAttachment2 = attachmentLoader.NewMeshAttachment(skin, text, text4);
                if (meshAttachment2 == null)
                {
                    return(null);
                }
                meshAttachment2.Path          = text4;
                meshAttachment2.r             = (float)((num13 & 4278190080u) >> 24) / 255f;
                meshAttachment2.g             = (float)((num13 & 0xFF0000) >> 16) / 255f;
                meshAttachment2.b             = (float)((num13 & 0xFF00) >> 8) / 255f;
                meshAttachment2.a             = (float)(num13 & 0xFF) / 255f;
                meshAttachment2.inheritDeform = inheritDeform;
                if (nonessential)
                {
                    meshAttachment2.Width  = num14 * scale;
                    meshAttachment2.Height = num15 * scale;
                }
                linkedMeshes.Add(new SkeletonJson.LinkedMesh(meshAttachment2, skin2, slotIndex, parent));
                return(meshAttachment2);
            }

            case 4:
            {
                bool     closed        = ReadBoolean(input);
                bool     constantSpeed = ReadBoolean(input);
                int      num16         = ReadVarint(input, optimizePositive: true);
                Vertices vertices3     = ReadVertices(input, num16);
                float[]  array         = new float[num16 / 3];
                int      i             = 0;
                for (int num17 = array.Length; i < num17; i++)
                {
                    array[i] = ReadFloat(input) * scale;
                }
                if (nonessential)
                {
                    ReadInt(input);
                }
                PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, text);
                if (pathAttachment == null)
                {
                    return(null);
                }
                pathAttachment.closed              = closed;
                pathAttachment.constantSpeed       = constantSpeed;
                pathAttachment.worldVerticesLength = num16 << 1;
                pathAttachment.vertices            = vertices3.vertices;
                pathAttachment.bones   = vertices3.bones;
                pathAttachment.lengths = array;
                return(pathAttachment);
            }

            case 5:
            {
                float rotation2 = ReadFloat(input);
                float num18     = ReadFloat(input);
                float num19     = ReadFloat(input);
                if (nonessential)
                {
                    ReadInt(input);
                }
                PointAttachment pointAttachment = attachmentLoader.NewPointAttachment(skin, text);
                if (pointAttachment == null)
                {
                    return(null);
                }
                pointAttachment.x        = num18 * scale;
                pointAttachment.y        = num19 * scale;
                pointAttachment.rotation = rotation2;
                return(pointAttachment);
            }

            case 6:
            {
                int      num      = ReadVarint(input, optimizePositive: true);
                int      num2     = ReadVarint(input, optimizePositive: true);
                Vertices vertices = ReadVertices(input, num2);
                if (nonessential)
                {
                    ReadInt(input);
                }
                ClippingAttachment clippingAttachment = attachmentLoader.NewClippingAttachment(skin, text);
                if (clippingAttachment == null)
                {
                    return(null);
                }
                clippingAttachment.EndSlot             = skeletonData.slots.Items[num];
                clippingAttachment.worldVerticesLength = num2 << 1;
                clippingAttachment.vertices            = vertices.vertices;
                clippingAttachment.bones = vertices.bones;
                return(clippingAttachment);
            }

            default:
                return(null);
            }
        }
Exemple #10
0
        private float[] ComputeWorldPositions(PathAttachment path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing)
        {
            Slot  slot = this.target;
            float num  = this.position;

            float[] items  = this.spaces.Items;
            float[] items2 = this.positions.Resize(spacesCount * 3 + 2).Items;
            bool    closed = path.Closed;
            int     num2   = path.WorldVerticesLength;
            int     num3   = num2 / 6;
            int     num4   = -1;
            float   num5;

            float[] items3;
            if (!path.ConstantSpeed)
            {
                float[] array = path.Lengths;
                num3 -= ((!closed) ? 2 : 1);
                num5  = array[num3];
                if (percentPosition)
                {
                    num *= num5;
                }
                if (percentSpacing)
                {
                    for (int i = 0; i < spacesCount; i++)
                    {
                        items[i] *= num5;
                    }
                }
                items3 = this.world.Resize(8).Items;
                int j    = 0;
                int num6 = 0;
                int num7 = 0;
                while (j < spacesCount)
                {
                    float num8 = items[j];
                    num += num8;
                    float num9 = num;
                    if (closed)
                    {
                        num9 %= num5;
                        if (num9 < 0f)
                        {
                            num9 += num5;
                        }
                        num7 = 0;
                        goto IL_178;
                    }
                    if (num9 < 0f)
                    {
                        if (num4 != -2)
                        {
                            num4 = -2;
                            path.ComputeWorldVertices(slot, 2, 4, items3, 0);
                        }
                        this.AddBeforePosition(num9, items3, 0, items2, num6);
                    }
                    else
                    {
                        if (num9 <= num5)
                        {
                            goto IL_178;
                        }
                        if (num4 != -3)
                        {
                            num4 = -3;
                            path.ComputeWorldVertices(slot, num2 - 6, 4, items3, 0);
                        }
                        this.AddAfterPosition(num9 - num5, items3, 0, items2, num6);
                    }
IL_261:
                    j++;
                    num6 += 3;
                    continue;
IL_178:
                    float num10;
                    for (;;)
                    {
                        num10 = array[num7];
                        if (num9 <= num10)
                        {
                            break;
                        }
                        num7++;
                    }
                    if (num7 == 0)
                    {
                        num9 /= num10;
                    }
                    else
                    {
                        float num11 = array[num7 - 1];
                        num9 = (num9 - num11) / (num10 - num11);
                    }
                    if (num7 != num4)
                    {
                        num4 = num7;
                        if (closed && num7 == num3)
                        {
                            path.ComputeWorldVertices(slot, num2 - 4, 4, items3, 0);
                            path.ComputeWorldVertices(slot, 0, 4, items3, 4);
                        }
                        else
                        {
                            path.ComputeWorldVertices(slot, num7 * 6 + 2, 8, items3, 0);
                        }
                    }
                    this.AddCurvePosition(num9, items3[0], items3[1], items3[2], items3[3], items3[4], items3[5], items3[6], items3[7], items2, num6, tangents || (j > 0 && num8 == 0f));
                    goto IL_261;
                }
                return(items2);
            }
            if (closed)
            {
                num2  += 2;
                items3 = this.world.Resize(num2).Items;
                path.ComputeWorldVertices(slot, 2, num2 - 4, items3, 0);
                path.ComputeWorldVertices(slot, 0, 2, items3, num2 - 4);
                items3[num2 - 2] = items3[0];
                items3[num2 - 1] = items3[1];
            }
            else
            {
                num3--;
                num2  -= 4;
                items3 = this.world.Resize(num2).Items;
                path.ComputeWorldVertices(slot, 2, num2, items3, 0);
            }
            float[] items4 = this.curves.Resize(num3).Items;
            num5 = 0f;
            float num12 = items3[0];
            float num13 = items3[1];
            float num14 = 0f;
            float num15 = 0f;
            float num16 = 0f;
            float num17 = 0f;
            float num18 = 0f;
            float num19 = 0f;
            int   k     = 0;
            int   num20 = 2;

            while (k < num3)
            {
                num14 = items3[num20];
                num15 = items3[num20 + 1];
                num16 = items3[num20 + 2];
                num17 = items3[num20 + 3];
                num18 = items3[num20 + 4];
                num19 = items3[num20 + 5];
                float num21 = (num12 - num14 * 2f + num16) * 0.1875f;
                float num22 = (num13 - num15 * 2f + num17) * 0.1875f;
                float num23 = ((num14 - num16) * 3f - num12 + num18) * 0.09375f;
                float num24 = ((num15 - num17) * 3f - num13 + num19) * 0.09375f;
                float num25 = num21 * 2f + num23;
                float num26 = num22 * 2f + num24;
                float num27 = (num14 - num12) * 0.75f + num21 + num23 * 0.166666672f;
                float num28 = (num15 - num13) * 0.75f + num22 + num24 * 0.166666672f;
                num5     += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                num27    += num25;
                num28    += num26;
                num25    += num23;
                num26    += num24;
                num5     += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                num27    += num25;
                num28    += num26;
                num5     += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                num27    += num25 + num23;
                num28    += num26 + num24;
                num5     += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                items4[k] = num5;
                num12     = num18;
                num13     = num19;
                k++;
                num20 += 6;
            }
            if (percentPosition)
            {
                num *= num5;
            }
            if (percentSpacing)
            {
                for (int l = 0; l < spacesCount; l++)
                {
                    items[l] *= num5;
                }
            }
            float[] array2 = this.segments;
            float   num29  = 0f;
            int     m      = 0;
            int     num30  = 0;
            int     num31  = 0;
            int     num32  = 0;

            while (m < spacesCount)
            {
                float num33 = items[m];
                num += num33;
                float num34 = num;
                if (closed)
                {
                    num34 %= num5;
                    if (num34 < 0f)
                    {
                        num34 += num5;
                    }
                    num31 = 0;
                    goto IL_5C5;
                }
                if (num34 < 0f)
                {
                    this.AddBeforePosition(num34, items3, 0, items2, num30);
                }
                else
                {
                    if (num34 <= num5)
                    {
                        goto IL_5C5;
                    }
                    this.AddAfterPosition(num34 - num5, items3, num2 - 4, items2, num30);
                }
IL_881:
                m++;
                num30 += 3;
                continue;
IL_5C5:
                float num35;
                for (;;)
                {
                    num35 = items4[num31];
                    if (num34 <= num35)
                    {
                        break;
                    }
                    num31++;
                }
                if (num31 == 0)
                {
                    num34 /= num35;
                }
                else
                {
                    float num36 = items4[num31 - 1];
                    num34 = (num34 - num36) / (num35 - num36);
                }
                if (num31 != num4)
                {
                    num4 = num31;
                    int n = num31 * 6;
                    num12 = items3[n];
                    num13 = items3[n + 1];
                    num14 = items3[n + 2];
                    num15 = items3[n + 3];
                    num16 = items3[n + 4];
                    num17 = items3[n + 5];
                    num18 = items3[n + 6];
                    num19 = items3[n + 7];
                    float num21 = (num12 - num14 * 2f + num16) * 0.03f;
                    float num22 = (num13 - num15 * 2f + num17) * 0.03f;
                    float num23 = ((num14 - num16) * 3f - num12 + num18) * 0.006f;
                    float num24 = ((num15 - num17) * 3f - num13 + num19) * 0.006f;
                    float num25 = num21 * 2f + num23;
                    float num26 = num22 * 2f + num24;
                    float num27 = (num14 - num12) * 0.3f + num21 + num23 * 0.166666672f;
                    float num28 = (num15 - num13) * 0.3f + num22 + num24 * 0.166666672f;
                    num29     = (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                    array2[0] = num29;
                    for (n = 1; n < 8; n++)
                    {
                        num27    += num25;
                        num28    += num26;
                        num25    += num23;
                        num26    += num24;
                        num29    += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                        array2[n] = num29;
                    }
                    num27    += num25;
                    num28    += num26;
                    num29    += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                    array2[8] = num29;
                    num27    += num25 + num23;
                    num28    += num26 + num24;
                    num29    += (float)Math.Sqrt((double)(num27 * num27 + num28 * num28));
                    array2[9] = num29;
                    num32     = 0;
                }
                num34 *= num29;
                float num37;
                for (;;)
                {
                    num37 = array2[num32];
                    if (num34 <= num37)
                    {
                        break;
                    }
                    num32++;
                }
                if (num32 == 0)
                {
                    num34 /= num37;
                }
                else
                {
                    float num38 = array2[num32 - 1];
                    num34 = (float)num32 + (num34 - num38) / (num37 - num38);
                }
                this.AddCurvePosition(num34 * 0.1f, num12, num13, num14, num15, num16, num17, num18, num19, items2, num30, tangents || (m > 0 && num33 == 0f));
                goto IL_881;
            }
            return(items2);
        }
Exemple #11
0
        public void Update()
        {
            PathAttachment pathAttachment = this.target.Attachment as PathAttachment;

            if (pathAttachment == null)
            {
                return;
            }
            float num   = this.rotateMix;
            float num2  = this.translateMix;
            bool  flag  = num2 > 0f;
            bool  flag2 = num > 0f;

            if (!flag && !flag2)
            {
                return;
            }
            PathConstraintData pathConstraintData = this.data;
            SpacingMode        spacingMode        = pathConstraintData.spacingMode;
            bool       flag3      = spacingMode == SpacingMode.Length;
            RotateMode rotateMode = pathConstraintData.rotateMode;
            bool       flag4      = rotateMode == RotateMode.Tangent;
            bool       flag5      = rotateMode == RotateMode.ChainScale;
            int        count      = this.bones.Count;
            int        num3       = (!flag4) ? (count + 1) : count;

            Bone[] items = this.bones.Items;
            ExposedList <float> exposedList  = this.spaces.Resize(num3);
            ExposedList <float> exposedList2 = null;
            float num4 = this.spacing;

            if (flag5 || flag3)
            {
                if (flag5)
                {
                    exposedList2 = this.lengths.Resize(count);
                }
                int i    = 0;
                int num5 = num3 - 1;
                while (i < num5)
                {
                    Bone  bone = items[i];
                    float num6 = bone.data.length;
                    float num7 = num6 * bone.a;
                    float num8 = num6 * bone.c;
                    num6 = (float)Math.Sqrt((double)(num7 * num7 + num8 * num8));
                    if (flag5)
                    {
                        exposedList2.Items[i] = num6;
                    }
                    exposedList.Items[++i] = ((!flag3) ? num4 : Math.Max(0f, num6 + num4));
                }
            }
            else
            {
                for (int j = 1; j < num3; j++)
                {
                    exposedList.Items[j] = num4;
                }
            }
            float[]  array          = this.ComputeWorldPositions(pathAttachment, num3, flag4, pathConstraintData.positionMode == PositionMode.Percent, spacingMode == SpacingMode.Percent);
            Skeleton skeleton       = this.target.Skeleton;
            float    x              = skeleton.x;
            float    y              = skeleton.y;
            float    num9           = array[0];
            float    num10          = array[1];
            float    offsetRotation = pathConstraintData.offsetRotation;
            bool     flag6          = rotateMode == RotateMode.Chain && offsetRotation == 0f;
            int      k              = 0;
            int      num11          = 3;

            while (k < count)
            {
                Bone bone2 = items[k];
                bone2.worldX += (num9 - x - bone2.worldX) * num2;
                bone2.worldY += (num10 - y - bone2.worldY) * num2;
                float num12 = array[num11];
                float num13 = array[num11 + 1];
                float num14 = num12 - num9;
                float num15 = num13 - num10;
                if (flag5)
                {
                    float num16 = exposedList2.Items[k];
                    if (num16 != 0f)
                    {
                        float num17 = ((float)Math.Sqrt((double)(num14 * num14 + num15 * num15)) / num16 - 1f) * num + 1f;
                        bone2.a *= num17;
                        bone2.c *= num17;
                    }
                }
                num9  = num12;
                num10 = num13;
                if (flag2)
                {
                    float a = bone2.a;
                    float b = bone2.b;
                    float c = bone2.c;
                    float d = bone2.d;
                    float num18;
                    if (flag4)
                    {
                        num18 = array[num11 - 1];
                    }
                    else if (exposedList.Items[k + 1] == 0f)
                    {
                        num18 = array[num11 + 2];
                    }
                    else
                    {
                        num18 = MathUtils.Atan2(num15, num14);
                    }
                    num18 -= MathUtils.Atan2(c, a) - offsetRotation * 0.0174532924f;
                    float num19;
                    float num20;
                    if (flag6)
                    {
                        num19 = MathUtils.Cos(num18);
                        num20 = MathUtils.Sin(num18);
                        float length = bone2.data.length;
                        num9  += (length * (num19 * a - num20 * c) - num14) * num;
                        num10 += (length * (num20 * a + num19 * c) - num15) * num;
                    }
                    if (num18 > 3.14159274f)
                    {
                        num18 -= 6.28318548f;
                    }
                    else if (num18 < -3.14159274f)
                    {
                        num18 += 6.28318548f;
                    }
                    num18  *= num;
                    num19   = MathUtils.Cos(num18);
                    num20   = MathUtils.Sin(num18);
                    bone2.a = num19 * a - num20 * c;
                    bone2.b = num19 * b - num20 * d;
                    bone2.c = num20 * a + num19 * c;
                    bone2.d = num20 * b + num19 * d;
                }
                k++;
                num11 += 3;
            }
        }
        /// <returns>May be null to not load any attachment</returns>
        public PathAttachment NewPathAttachment(Skin skin, string name)
        {
            var attachment = new PathAttachment(name);

            return(attachment);
        }
        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();
            }
        }
Exemple #14
0
        private float[] ComputeWorldPositions(PathAttachment path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing)
        {
            Slot  slot = target;
            float num  = position;

            float[] items  = spaces.Items;
            float[] items2 = positions.Resize(spacesCount * 3 + 2).Items;
            bool    closed = path.Closed;
            int     worldVerticesLength = path.WorldVerticesLength;
            int     num2 = worldVerticesLength / 6;
            int     num3 = -1;

            float[] items3;
            float   num4;

            if (!path.ConstantSpeed)
            {
                float[] array = path.Lengths;
                num2 -= (closed ? 1 : 2);
                num4  = array[num2];
                if (percentPosition)
                {
                    num *= num4;
                }
                if (percentSpacing)
                {
                    for (int i = 0; i < spacesCount; i++)
                    {
                        items[i] *= num4;
                    }
                }
                items3 = world.Resize(8).Items;
                int j    = 0;
                int k    = 0;
                int num5 = 0;
                for (; j < spacesCount; j++, k += 3)
                {
                    float num6 = items[j];
                    num += num6;
                    float num7 = num;
                    if (closed)
                    {
                        num7 %= num4;
                        if (num7 < 0f)
                        {
                            num7 += num4;
                        }
                        num5 = 0;
                    }
                    else
                    {
                        if (num7 < 0f)
                        {
                            if (num3 != -2)
                            {
                                num3 = -2;
                                path.ComputeWorldVertices(slot, 2, 4, items3, 0);
                            }
                            AddBeforePosition(num7, items3, 0, items2, k);
                            continue;
                        }
                        if (num7 > num4)
                        {
                            if (num3 != -3)
                            {
                                num3 = -3;
                                path.ComputeWorldVertices(slot, worldVerticesLength - 6, 4, items3, 0);
                            }
                            AddAfterPosition(num7 - num4, items3, 0, items2, k);
                            continue;
                        }
                    }
                    float num8;
                    while (true)
                    {
                        num8 = array[num5];
                        if (!(num7 > num8))
                        {
                            break;
                        }
                        num5++;
                    }
                    if (num5 == 0)
                    {
                        num7 /= num8;
                    }
                    else
                    {
                        float num9 = array[num5 - 1];
                        num7 = (num7 - num9) / (num8 - num9);
                    }
                    if (num5 != num3)
                    {
                        num3 = num5;
                        if (closed && num5 == num2)
                        {
                            path.ComputeWorldVertices(slot, worldVerticesLength - 4, 4, items3, 0);
                            path.ComputeWorldVertices(slot, 0, 4, items3, 4);
                        }
                        else
                        {
                            path.ComputeWorldVertices(slot, num5 * 6 + 2, 8, items3, 0);
                        }
                    }
                    AddCurvePosition(num7, items3[0], items3[1], items3[2], items3[3], items3[4], items3[5], items3[6], items3[7], items2, k, tangents || (j > 0 && num6 == 0f));
                }
                return(items2);
            }
            if (closed)
            {
                worldVerticesLength += 2;
                items3 = world.Resize(worldVerticesLength).Items;
                path.ComputeWorldVertices(slot, 2, worldVerticesLength - 4, items3, 0);
                path.ComputeWorldVertices(slot, 0, 2, items3, worldVerticesLength - 4);
                items3[worldVerticesLength - 2] = items3[0];
                items3[worldVerticesLength - 1] = items3[1];
            }
            else
            {
                num2--;
                worldVerticesLength -= 4;
                items3 = world.Resize(worldVerticesLength).Items;
                path.ComputeWorldVertices(slot, 2, worldVerticesLength, items3, 0);
            }
            float[] items4 = curves.Resize(num2).Items;
            num4 = 0f;
            float num10 = items3[0];
            float num11 = items3[1];
            float num12 = 0f;
            float num13 = 0f;
            float num14 = 0f;
            float num15 = 0f;
            float num16 = 0f;
            float num17 = 0f;
            int   num18 = 0;
            int   num19 = 2;

            while (num18 < num2)
            {
                num12 = items3[num19];
                num13 = items3[num19 + 1];
                num14 = items3[num19 + 2];
                num15 = items3[num19 + 3];
                num16 = items3[num19 + 4];
                num17 = items3[num19 + 5];
                float num20 = (num10 - num12 * 2f + num14) * 0.1875f;
                float num21 = (num11 - num13 * 2f + num15) * 0.1875f;
                float num22 = ((num12 - num14) * 3f - num10 + num16) * (3f / 32f);
                float num23 = ((num13 - num15) * 3f - num11 + num17) * (3f / 32f);
                float num24 = num20 * 2f + num22;
                float num25 = num21 * 2f + num23;
                float num26 = (num12 - num10) * 0.75f + num20 + num22 * (355f / (678f * (float)Math.PI));
                float num27 = (num13 - num11) * 0.75f + num21 + num23 * (355f / (678f * (float)Math.PI));
                num4  += (float)Math.Sqrt(num26 * num26 + num27 * num27);
                num26 += num24;
                num27 += num25;
                num24 += num22;
                num25 += num23;
                num4  += (float)Math.Sqrt(num26 * num26 + num27 * num27);
                num26 += num24;
                num27 += num25;
                num4  += (float)Math.Sqrt(num26 * num26 + num27 * num27);
                num26 += num24 + num22;
                num27 += num25 + num23;
                num4   = (items4[num18] = num4 + (float)Math.Sqrt(num26 * num26 + num27 * num27));
                num10  = num16;
                num11  = num17;
                num18++;
                num19 += 6;
            }
            if (percentPosition)
            {
                num *= num4;
            }
            if (percentSpacing)
            {
                for (int l = 0; l < spacesCount; l++)
                {
                    items[l] *= num4;
                }
            }
            float[] array2 = segments;
            float   num28  = 0f;
            int     m      = 0;
            int     n      = 0;
            int     num29  = 0;
            int     num30  = 0;

            for (; m < spacesCount; m++, n += 3)
            {
                float num31 = items[m];
                num += num31;
                float num32 = num;
                if (closed)
                {
                    num32 %= num4;
                    if (num32 < 0f)
                    {
                        num32 += num4;
                    }
                    num29 = 0;
                }
                else
                {
                    if (num32 < 0f)
                    {
                        AddBeforePosition(num32, items3, 0, items2, n);
                        continue;
                    }
                    if (num32 > num4)
                    {
                        AddAfterPosition(num32 - num4, items3, worldVerticesLength - 4, items2, n);
                        continue;
                    }
                }
                float num33;
                while (true)
                {
                    num33 = items4[num29];
                    if (!(num32 > num33))
                    {
                        break;
                    }
                    num29++;
                }
                if (num29 == 0)
                {
                    num32 /= num33;
                }
                else
                {
                    float num34 = items4[num29 - 1];
                    num32 = (num32 - num34) / (num33 - num34);
                }
                if (num29 != num3)
                {
                    num3 = num29;
                    int num35 = num29 * 6;
                    num10 = items3[num35];
                    num11 = items3[num35 + 1];
                    num12 = items3[num35 + 2];
                    num13 = items3[num35 + 3];
                    num14 = items3[num35 + 4];
                    num15 = items3[num35 + 5];
                    num16 = items3[num35 + 6];
                    num17 = items3[num35 + 7];
                    float num20 = (num10 - num12 * 2f + num14) * 0.03f;
                    float num21 = (num11 - num13 * 2f + num15) * 0.03f;
                    float num22 = ((num12 - num14) * 3f - num10 + num16) * 0.006f;
                    float num23 = ((num13 - num15) * 3f - num11 + num17) * 0.006f;
                    float num24 = num20 * 2f + num22;
                    float num25 = num21 * 2f + num23;
                    float num26 = (num12 - num10) * 0.3f + num20 + num22 * (355f / (678f * (float)Math.PI));
                    float num27 = (num13 - num11) * 0.3f + num21 + num23 * (355f / (678f * (float)Math.PI));
                    num28 = (array2[0] = (float)Math.Sqrt(num26 * num26 + num27 * num27));
                    for (num35 = 1; num35 < 8; num35++)
                    {
                        num26 += num24;
                        num27 += num25;
                        num24 += num22;
                        num25 += num23;
                        num28  = (array2[num35] = num28 + (float)Math.Sqrt(num26 * num26 + num27 * num27));
                    }
                    num26 += num24;
                    num27 += num25;
                    num28  = (array2[8] = num28 + (float)Math.Sqrt(num26 * num26 + num27 * num27));
                    num26 += num24 + num22;
                    num27 += num25 + num23;
                    num28  = (array2[9] = num28 + (float)Math.Sqrt(num26 * num26 + num27 * num27));
                    num30  = 0;
                }
                num32 *= num28;
                float num36;
                while (true)
                {
                    num36 = array2[num30];
                    if (!(num32 > num36))
                    {
                        break;
                    }
                    num30++;
                }
                if (num30 == 0)
                {
                    num32 /= num36;
                }
                else
                {
                    float num37 = array2[num30 - 1];
                    num32 = (float)num30 + (num32 - num37) / (num36 - num37);
                }
                AddCurvePosition(num32 * 0.1f, num10, num11, num12, num13, num14, num15, num16, num17, items2, n, tangents || (m > 0 && num31 == 0f));
            }
            return(items2);
        }
Exemple #15
0
        public void Update()
        {
            PathAttachment pathAttachment = target.Attachment as PathAttachment;

            if (pathAttachment == null)
            {
                return;
            }
            float num   = rotateMix;
            float num2  = translateMix;
            bool  flag  = num2 > 0f;
            bool  flag2 = num > 0f;

            if (!flag && !flag2)
            {
                return;
            }
            PathConstraintData pathConstraintData = data;
            SpacingMode        spacingMode        = pathConstraintData.spacingMode;
            bool       flag3      = spacingMode == SpacingMode.Length;
            RotateMode rotateMode = pathConstraintData.rotateMode;
            bool       flag4      = rotateMode == RotateMode.Tangent;
            bool       flag5      = rotateMode == RotateMode.ChainScale;
            int        count      = bones.Count;
            int        num3       = (!flag4) ? (count + 1) : count;

            Bone[] items = bones.Items;
            ExposedList <float> exposedList  = spaces.Resize(num3);
            ExposedList <float> exposedList2 = null;
            float num4 = spacing;

            if (flag5 || flag3)
            {
                if (flag5)
                {
                    exposedList2 = lengths.Resize(count);
                }
                int num5 = 0;
                int num6 = num3 - 1;
                while (num5 < num6)
                {
                    Bone  bone = items[num5];
                    float num7 = bone.data.length;
                    if (num7 == 0f)
                    {
                        num7 = 1E-09f;
                    }
                    float num8  = num7 * bone.a;
                    float num9  = num7 * bone.c;
                    float num10 = (float)Math.Sqrt(num8 * num8 + num9 * num9);
                    if (flag5)
                    {
                        exposedList2.Items[num5] = num7;
                    }
                    exposedList.Items[++num5] = ((!flag3) ? num4 : Math.Max(0f, num7 + num4)) * num10 / num7;
                }
            }
            else
            {
                for (int i = 1; i < num3; i++)
                {
                    exposedList.Items[i] = num4;
                }
            }
            float[] array = ComputeWorldPositions(pathAttachment, num3, flag4, pathConstraintData.positionMode == PositionMode.Percent, spacingMode == SpacingMode.Percent);
            float   num11 = array[0];
            float   num12 = array[1];
            float   num13 = pathConstraintData.offsetRotation;
            bool    flag6;

            if (num13 == 0f)
            {
                flag6 = (rotateMode == RotateMode.Chain);
            }
            else
            {
                flag6 = false;
                Bone bone2 = target.bone;
                num13 *= ((!(bone2.a * bone2.d - bone2.b * bone2.c > 0f)) ? (-(float)Math.PI / 180f) : ((float)Math.PI / 180f));
            }
            int num14 = 0;
            int num15 = 3;

            while (num14 < count)
            {
                Bone bone3 = items[num14];
                bone3.worldX += (num11 - bone3.worldX) * num2;
                bone3.worldY += (num12 - bone3.worldY) * num2;
                float num16 = array[num15];
                float num17 = array[num15 + 1];
                float num18 = num16 - num11;
                float num19 = num17 - num12;
                if (flag5)
                {
                    float num20 = exposedList2.Items[num14];
                    if (num20 != 0f)
                    {
                        float num21 = ((float)Math.Sqrt(num18 * num18 + num19 * num19) / num20 - 1f) * num + 1f;
                        bone3.a *= num21;
                        bone3.c *= num21;
                    }
                }
                num11 = num16;
                num12 = num17;
                if (flag2)
                {
                    float a     = bone3.a;
                    float b     = bone3.b;
                    float c     = bone3.c;
                    float d     = bone3.d;
                    float num22 = flag4 ? array[num15 - 1] : ((exposedList.Items[num14 + 1] != 0f) ? MathUtils.Atan2(num19, num18) : array[num15 + 2]);
                    num22 -= MathUtils.Atan2(c, a);
                    float num23;
                    float num24;
                    if (flag6)
                    {
                        num23 = MathUtils.Cos(num22);
                        num24 = MathUtils.Sin(num22);
                        float length = bone3.data.length;
                        num11 += (length * (num23 * a - num24 * c) - num18) * num;
                        num12 += (length * (num24 * a + num23 * c) - num19) * num;
                    }
                    else
                    {
                        num22 += num13;
                    }
                    if (num22 > (float)Math.PI)
                    {
                        num22 -= (float)Math.PI * 2f;
                    }
                    else if (num22 < -(float)Math.PI)
                    {
                        num22 += (float)Math.PI * 2f;
                    }
                    num22  *= num;
                    num23   = MathUtils.Cos(num22);
                    num24   = MathUtils.Sin(num22);
                    bone3.a = num23 * a - num24 * c;
                    bone3.b = num23 * b - num24 * d;
                    bone3.c = num24 * a + num23 * c;
                    bone3.d = num24 * b + num23 * d;
                }
                bone3.appliedValid = false;
                num14++;
                num15 += 3;
            }
        }
Exemple #16
0
        /// <summary>Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added
        /// or removed.</summary>
        public void UpdateCache()
        {
            ExposedList <IUpdatable> updateCache = this.updateCache;

            updateCache.Clear();

            ExposedList <Bone> bones = this.bones;

            for (int i = 0, n = bones.Count; i < n; i++)
            {
                bones.Items[i].sorted = false;
            }

            ExposedList <IkConstraint> ikConstraints = this.ikConstraintsSorted;

            ikConstraints.Clear();
            ikConstraints.AddRange(this.ikConstraints);
            int ikCount = ikConstraints.Count;

            for (int i = 0, level, n = ikCount; i < n; i++)
            {
                IkConstraint ik   = ikConstraints.Items[i];
                Bone         bone = ik.bones.Items[0].parent;
                for (level = 0; bone != null; level++)
                {
                    bone = bone.parent;
                }
                ik.level = level;
            }
            for (int i = 1, ii; i < ikCount; i++)
            {
                IkConstraint ik    = ikConstraints.Items[i];
                int          level = ik.level;
                for (ii = i - 1; ii >= 0; ii--)
                {
                    IkConstraint other = ikConstraints.Items[ii];
                    if (other.level < level)
                    {
                        break;
                    }
                    ikConstraints.Items[ii + 1] = other;
                }
                ikConstraints.Items[ii + 1] = ik;
            }
            for (int i = 0, n = ikConstraints.Count; i < n; i++)
            {
                IkConstraint constraint = ikConstraints.Items[i];
                Bone         target     = constraint.target;
                SortBone(target);

                ExposedList <Bone> constrained = constraint.bones;
                Bone parent = constrained.Items[0];
                SortBone(parent);

                updateCache.Add(constraint);

                SortReset(parent.children);
                constrained.Items[constrained.Count - 1].sorted = true;
            }

            ExposedList <PathConstraint> pathConstraints = this.pathConstraints;

            for (int i = 0, n = pathConstraints.Count; i < n; i++)
            {
                PathConstraint constraint = pathConstraints.Items[i];

                Slot slot      = constraint.target;
                int  slotIndex = slot.data.index;
                Bone slotBone  = slot.bone;
                if (skin != null)
                {
                    SortPathConstraintAttachment(skin, slotIndex, slotBone);
                }
                if (data.defaultSkin != null && data.defaultSkin != skin)
                {
                    SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
                }
                for (int ii = 0, nn = data.skins.Count; ii < nn; ii++)
                {
                    SortPathConstraintAttachment(data.skins.Items[ii], slotIndex, slotBone);
                }

                PathAttachment attachment = slot.Attachment as PathAttachment;
                if (attachment != null)
                {
                    SortPathConstraintAttachment(attachment, slotBone);
                }

                ExposedList <Bone> constrained = constraint.bones;
                int boneCount = constrained.Count;
                for (int ii = 0; ii < boneCount; ii++)
                {
                    SortBone(constrained.Items[ii]);
                }

                updateCache.Add(constraint);

                for (int ii = 0; ii < boneCount; ii++)
                {
                    SortReset(constrained.Items[ii].children);
                }
                for (int ii = 0; ii < boneCount; ii++)
                {
                    constrained.Items[ii].sorted = true;
                }
            }

            ExposedList <TransformConstraint> transformConstraints = this.transformConstraints;

            for (int i = 0, n = transformConstraints.Count; i < n; i++)
            {
                TransformConstraint constraint = transformConstraints.Items[i];

                SortBone(constraint.target);

                ExposedList <Bone> constrained = constraint.bones;
                int boneCount = constrained.Count;
                for (int ii = 0; ii < boneCount; ii++)
                {
                    SortBone(constrained.Items[ii]);
                }

                updateCache.Add(constraint);

                for (int ii = 0; ii < boneCount; ii++)
                {
                    SortReset(constrained.Items[ii].children);
                }
                for (int ii = 0; ii < boneCount; ii++)
                {
                    constrained.Items[ii].sorted = true;
                }
            }

            for (int i = 0, n = bones.Count; i < n; i++)
            {
                SortBone(bones.Items[i]);
            }
        }
        private Attachment ReadAttachment(NewStream input, Skin skin, int slotIndex, String attachmentName, bool nonessential)
        {
            float scale = Scale;

            String name = ReadString(input);

            if (name == null)
            {
                name = attachmentName;
            }

            AttachmentType type = (AttachmentType)input.ReadByte();

            switch (type)
            {
            case AttachmentType.Region: {
                String path     = ReadString(input);
                float  rotation = ReadFloat(input);
                float  x        = ReadFloat(input);
                float  y        = ReadFloat(input);
                float  scaleX   = ReadFloat(input);
                float  scaleY   = ReadFloat(input);
                float  width    = ReadFloat(input);
                float  height   = ReadFloat(input);
                int    color    = ReadInt(input);

                if (path == null)
                {
                    path = name;
                }
                RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
                if (region == null)
                {
                    return(null);
                }
                region.Path     = path;
                region.x        = x * scale;
                region.y        = y * scale;
                region.scaleX   = scaleX;
                region.scaleY   = scaleY;
                region.rotation = rotation;
                region.width    = width * scale;
                region.height   = height * scale;
                region.r        = ((color & 0xff000000) >> 24) / 255f;
                region.g        = ((color & 0x00ff0000) >> 16) / 255f;
                region.b        = ((color & 0x0000ff00) >> 8) / 255f;
                region.a        = ((color & 0x000000ff)) / 255f;
                region.UpdateOffset();
                return(region);
            }

            case AttachmentType.Boundingbox: {
                int      vertexCount = ReadVarint(input, true);
                Vertices vertices    = ReadVertices(input, vertexCount);
                if (nonessential)
                {
                    ReadInt(input);                                       //int color = nonessential ? ReadInt(input) : 0; // Avoid unused local warning.
                }
                BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
                if (box == null)
                {
                    return(null);
                }
                box.worldVerticesLength = vertexCount << 1;
                box.vertices            = vertices.vertices;
                box.bones = vertices.bones;
                return(box);
            }

            case AttachmentType.Mesh: {
                String   path = ReadString(input);
                int      color = ReadInt(input);
                int      vertexCount = ReadVarint(input, true);
                float[]  uvs = ReadFloatArray(input, vertexCount << 1, 1);
                int[]    triangles = ReadShortArray(input);
                Vertices vertices = ReadVertices(input, vertexCount);
                int      hullLength = ReadVarint(input, true);
                int[]    edges = null;
                float    width = 0, height = 0;
                if (nonessential)
                {
                    edges  = ReadShortArray(input);
                    width  = ReadFloat(input);
                    height = ReadFloat(input);
                }

                if (path == null)
                {
                    path = name;
                }
                MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
                if (mesh == null)
                {
                    return(null);
                }
                mesh.Path                = path;
                mesh.r                   = ((color & 0xff000000) >> 24) / 255f;
                mesh.g                   = ((color & 0x00ff0000) >> 16) / 255f;
                mesh.b                   = ((color & 0x0000ff00) >> 8) / 255f;
                mesh.a                   = ((color & 0x000000ff)) / 255f;
                mesh.bones               = vertices.bones;
                mesh.vertices            = vertices.vertices;
                mesh.WorldVerticesLength = vertexCount << 1;
                mesh.triangles           = triangles;
                mesh.regionUVs           = uvs;
                mesh.UpdateUVs();
                mesh.HullLength = hullLength << 1;
                if (nonessential)
                {
                    mesh.Edges  = edges;
                    mesh.Width  = width * scale;
                    mesh.Height = height * scale;
                }
                return(mesh);
            }

            case AttachmentType.Linkedmesh: {
                String path = ReadString(input);
                int    color = ReadInt(input);
                String skinName = ReadString(input);
                String parent = ReadString(input);
                bool   inheritDeform = ReadBoolean(input);
                float  width = 0, height = 0;
                if (nonessential)
                {
                    width  = ReadFloat(input);
                    height = ReadFloat(input);
                }

                if (path == null)
                {
                    path = name;
                }
                MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
                if (mesh == null)
                {
                    return(null);
                }
                mesh.Path          = path;
                mesh.r             = ((color & 0xff000000) >> 24) / 255f;
                mesh.g             = ((color & 0x00ff0000) >> 16) / 255f;
                mesh.b             = ((color & 0x0000ff00) >> 8) / 255f;
                mesh.a             = ((color & 0x000000ff)) / 255f;
                mesh.inheritDeform = inheritDeform;
                if (nonessential)
                {
                    mesh.Width  = width * scale;
                    mesh.Height = height * scale;
                }
                linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent));
                return(mesh);
            }

            case AttachmentType.Path: {
                bool     closed        = ReadBoolean(input);
                bool     constantSpeed = ReadBoolean(input);
                int      vertexCount   = ReadVarint(input, true);
                Vertices vertices      = ReadVertices(input, vertexCount);
                float[]  lengths       = new float[vertexCount / 3];
                for (int i = 0, n = lengths.Length; i < n; i++)
                {
                    lengths[i] = ReadFloat(input) * scale;
                }
                if (nonessential)
                {
                    ReadInt(input);                                       //int color = nonessential ? ReadInt(input) : 0; // Avoid unused local warning.
                }
                PathAttachment path = attachmentLoader.NewPathAttachment(skin, name);
                if (path == null)
                {
                    return(null);
                }
                path.closed              = closed;
                path.constantSpeed       = constantSpeed;
                path.worldVerticesLength = vertexCount << 1;
                path.vertices            = vertices.vertices;
                path.bones   = vertices.bones;
                path.lengths = lengths;
                return(path);
            }
            }
            return(null);
        }
        public void Update()
        {
            PathAttachment attachment = target.Attachment as PathAttachment;

            if (attachment == null)
            {
                return;
            }

            float rotateMix = this.rotateMix, translateMix = this.translateMix;
            bool  translate = translateMix > 0, rotate = rotateMix > 0;

            if (!translate && !rotate)
            {
                return;
            }

            PathConstraintData data = this.data;
            SpacingMode        spacingMode = data.spacingMode;
            bool       lengthSpacing = spacingMode == SpacingMode.Length;
            RotateMode rotateMode = data.rotateMode;
            bool       tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale;
            int        boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1;

            Bone[] bones = this.bones.Items;
            ExposedList <float> spaces = this.spaces.Resize(spacesCount), lengths = null;
            float spacing = this.spacing;

            if (scale || lengthSpacing)
            {
                if (scale)
                {
                    lengths = this.lengths.Resize(boneCount);
                }
                for (int i = 0, n = spacesCount - 1; i < n;)
                {
                    Bone  bone = bones[i];
                    float length = bone.data.length, x = length * bone.a, y = length * bone.c;
                    length = (float)Math.Sqrt(x * x + y * y);
                    if (scale)
                    {
                        lengths.Items[i] = length;
                    }
                    spaces.Items[++i] = lengthSpacing ? Math.Max(0, length + spacing) : spacing;
                }
            }
            else
            {
                for (int i = 1; i < spacesCount; i++)
                {
                    spaces.Items[i] = spacing;
                }
            }

            float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents,
                                                      data.positionMode == PositionMode.Percent, spacingMode == SpacingMode.Percent);
            Skeleton skeleton = target.Skeleton;
            float    skeletonX = skeleton.x, skeletonY = skeleton.y;
            float    boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
            bool     tip = rotateMode == RotateMode.Chain && offsetRotation == 0;

            for (int i = 0, p = 3; i < boneCount; i++, p += 3)
            {
                Bone bone = (Bone)bones[i];
                bone.worldX += (boneX - skeletonX - bone.worldX) * translateMix;
                bone.worldY += (boneY - skeletonY - bone.worldY) * translateMix;
                float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
                if (scale)
                {
                    float length = lengths.Items[i];
                    if (length != 0)
                    {
                        float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
                        bone.a *= s;
                        bone.c *= s;
                    }
                }
                boneX = x;
                boneY = y;
                if (rotate)
                {
                    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.Items[i + 1] == 0)
                    {
                        r = positions[p + 2];
                    }
                    else
                    {
                        r = MathUtils.Atan2(dy, dx);
                    }
                    r -= MathUtils.Atan2(c, a) - offsetRotation * MathUtils.degRad;
                    if (tip)
                    {
                        cos = MathUtils.Cos(r);
                        sin = MathUtils.Sin(r);
                        float length = bone.data.length;
                        boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
                        boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
                    }
                    if (r > MathUtils.PI)
                    {
                        r -= MathUtils.PI2;
                    }
                    else if (r < -MathUtils.PI)                     //
                    {
                        r += MathUtils.PI2;
                    }
                    r     *= rotateMix;
                    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;
                }
            }
        }
        public void Update()
        {
            PathAttachment attachment = target.Attachment as PathAttachment;

            if (attachment == null)
            {
                return;
            }

            float rotateMix = this.rotateMix, translateMix = this.translateMix;
            bool  translate = translateMix > 0, rotate = rotateMix > 0;

            if (!translate && !rotate)
            {
                return;
            }

            PathConstraintData data = this.data;
            bool       percentSpacing = data.spacingMode == SpacingMode.Percent;
            RotateMode rotateMode = data.rotateMode;
            bool       tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale;
            int        boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1;

            Bone[] bonesItems = this.bones.Items;
            ExposedList <float> spaces = this.spaces.Resize(spacesCount), lengths = null;
            float spacing = this.spacing;

            if (scale || !percentSpacing)
            {
                if (scale)
                {
                    lengths = this.lengths.Resize(boneCount);
                }
                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.Items[i] = 0;
                        }
                        spaces.Items[++i] = 0;
                    }
                    else if (percentSpacing)
                    {
                        if (scale)
                        {
                            float x = setupLength * bone.a, y = setupLength * bone.c;
                            float length = (float)Math.Sqrt(x * x + y * y);
                            lengths.Items[i] = length;
                        }
                        spaces.Items[++i] = spacing;
                    }
                    else
                    {
                        float x = setupLength * bone.a, y = setupLength * bone.c;
                        float length = (float)Math.Sqrt(x * x + y * y);
                        if (scale)
                        {
                            lengths.Items[i] = length;
                        }
                        spaces.Items[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
                    }
                }
            }
            else
            {
                for (int i = 1; i < spacesCount; i++)
                {
                    spaces.Items[i] = spacing;
                }
            }

            float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents,
                                                      data.positionMode == PositionMode.Percent, percentSpacing);
            float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
            bool  tip;

            if (offsetRotation == 0)
            {
                tip = 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) * translateMix;
                bone.worldY += (boneY - bone.worldY) * translateMix;
                float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
                if (scale)
                {
                    float length = lengths.Items[i];
                    if (length >= PathConstraint.Epsilon)
                    {
                        float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
                        bone.a *= s;
                        bone.c *= s;
                    }
                }
                boneX = x;
                boneY = y;
                if (rotate)
                {
                    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.Items[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) * rotateMix;
                        boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
                    }
                    else
                    {
                        r += offsetRotation;
                    }
                    if (r > MathUtils.PI)
                    {
                        r -= MathUtils.PI2;
                    }
                    else if (r < -MathUtils.PI)                     //
                    {
                        r += MathUtils.PI2;
                    }
                    r     *= rotateMix;
                    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.appliedValid = false;
            }
        }
Exemple #20
0
        private Attachment ReadAttachment(Stream input, Skin skin, int slotIndex, string attachmentName, bool nonessential)
        {
            float  scale = this.Scale;
            string text  = this.ReadString(input);

            if (text == null)
            {
                text = attachmentName;
            }
            switch (input.ReadByte())
            {
            case 0:
            {
                string text2    = this.ReadString(input);
                float  rotation = this.ReadFloat(input);
                float  num      = this.ReadFloat(input);
                float  num2     = this.ReadFloat(input);
                float  scaleX   = this.ReadFloat(input);
                float  scaleY   = this.ReadFloat(input);
                float  num3     = this.ReadFloat(input);
                float  num4     = this.ReadFloat(input);
                int    num5     = SkeletonBinary.ReadInt(input);
                if (text2 == null)
                {
                    text2 = text;
                }
                RegionAttachment regionAttachment = this.attachmentLoader.NewRegionAttachment(skin, text, text2);
                if (regionAttachment == null)
                {
                    return(null);
                }
                regionAttachment.Path     = text2;
                regionAttachment.x        = num * scale;
                regionAttachment.y        = num2 * scale;
                regionAttachment.scaleX   = scaleX;
                regionAttachment.scaleY   = scaleY;
                regionAttachment.rotation = rotation;
                regionAttachment.width    = num3 * scale;
                regionAttachment.height   = num4 * scale;
                regionAttachment.r        = (float)((num5 & 4278190080u) >> 24) / 255f;
                regionAttachment.g        = (float)((num5 & 16711680) >> 16) / 255f;
                regionAttachment.b        = (float)((num5 & 65280) >> 8) / 255f;
                regionAttachment.a        = (float)(num5 & 255) / 255f;
                regionAttachment.UpdateOffset();
                return(regionAttachment);
            }

            case 1:
            {
                int      num6     = SkeletonBinary.ReadVarint(input, true);
                Vertices vertices = this.ReadVertices(input, num6);
                if (nonessential)
                {
                    SkeletonBinary.ReadInt(input);
                }
                BoundingBoxAttachment boundingBoxAttachment = this.attachmentLoader.NewBoundingBoxAttachment(skin, text);
                if (boundingBoxAttachment == null)
                {
                    return(null);
                }
                boundingBoxAttachment.worldVerticesLength = num6 << 1;
                boundingBoxAttachment.vertices            = vertices.vertices;
                boundingBoxAttachment.bones = vertices.bones;
                return(boundingBoxAttachment);
            }

            case 2:
            {
                string   text3     = this.ReadString(input);
                int      num7      = SkeletonBinary.ReadInt(input);
                int      num8      = SkeletonBinary.ReadVarint(input, true);
                float[]  regionUVs = this.ReadFloatArray(input, num8 << 1, 1f);
                int[]    triangles = this.ReadShortArray(input);
                Vertices vertices2 = this.ReadVertices(input, num8);
                int      num9      = SkeletonBinary.ReadVarint(input, true);
                int[]    edges     = null;
                float    num10     = 0f;
                float    num11     = 0f;
                if (nonessential)
                {
                    edges = this.ReadShortArray(input);
                    num10 = this.ReadFloat(input);
                    num11 = this.ReadFloat(input);
                }
                if (text3 == null)
                {
                    text3 = text;
                }
                MeshAttachment meshAttachment = this.attachmentLoader.NewMeshAttachment(skin, text, text3);
                if (meshAttachment == null)
                {
                    return(null);
                }
                meshAttachment.Path                = text3;
                meshAttachment.r                   = (float)((num7 & 4278190080u) >> 24) / 255f;
                meshAttachment.g                   = (float)((num7 & 16711680) >> 16) / 255f;
                meshAttachment.b                   = (float)((num7 & 65280) >> 8) / 255f;
                meshAttachment.a                   = (float)(num7 & 255) / 255f;
                meshAttachment.bones               = vertices2.bones;
                meshAttachment.vertices            = vertices2.vertices;
                meshAttachment.WorldVerticesLength = num8 << 1;
                meshAttachment.triangles           = triangles;
                meshAttachment.regionUVs           = regionUVs;
                meshAttachment.UpdateUVs();
                meshAttachment.HullLength = num9 << 1;
                if (nonessential)
                {
                    meshAttachment.Edges  = edges;
                    meshAttachment.Width  = num10 * scale;
                    meshAttachment.Height = num11 * scale;
                }
                return(meshAttachment);
            }

            case 3:
            {
                string text4         = this.ReadString(input);
                int    num12         = SkeletonBinary.ReadInt(input);
                string skin2         = this.ReadString(input);
                string parent        = this.ReadString(input);
                bool   inheritDeform = SkeletonBinary.ReadBoolean(input);
                float  num13         = 0f;
                float  num14         = 0f;
                if (nonessential)
                {
                    num13 = this.ReadFloat(input);
                    num14 = this.ReadFloat(input);
                }
                if (text4 == null)
                {
                    text4 = text;
                }
                MeshAttachment meshAttachment2 = this.attachmentLoader.NewMeshAttachment(skin, text, text4);
                if (meshAttachment2 == null)
                {
                    return(null);
                }
                meshAttachment2.Path          = text4;
                meshAttachment2.r             = (float)((num12 & 4278190080u) >> 24) / 255f;
                meshAttachment2.g             = (float)((num12 & 16711680) >> 16) / 255f;
                meshAttachment2.b             = (float)((num12 & 65280) >> 8) / 255f;
                meshAttachment2.a             = (float)(num12 & 255) / 255f;
                meshAttachment2.inheritDeform = inheritDeform;
                if (nonessential)
                {
                    meshAttachment2.Width  = num13 * scale;
                    meshAttachment2.Height = num14 * scale;
                }
                this.linkedMeshes.Add(new SkeletonJson.LinkedMesh(meshAttachment2, skin2, slotIndex, parent));
                return(meshAttachment2);
            }

            case 4:
            {
                bool     closed        = SkeletonBinary.ReadBoolean(input);
                bool     constantSpeed = SkeletonBinary.ReadBoolean(input);
                int      num15         = SkeletonBinary.ReadVarint(input, true);
                Vertices vertices3     = this.ReadVertices(input, num15);
                float[]  array         = new float[num15 / 3];
                int      i             = 0;
                int      num16         = array.Length;
                while (i < num16)
                {
                    array[i] = this.ReadFloat(input) * scale;
                    i++;
                }
                if (nonessential)
                {
                    SkeletonBinary.ReadInt(input);
                }
                PathAttachment pathAttachment = this.attachmentLoader.NewPathAttachment(skin, text);
                if (pathAttachment == null)
                {
                    return(null);
                }
                pathAttachment.closed              = closed;
                pathAttachment.constantSpeed       = constantSpeed;
                pathAttachment.worldVerticesLength = num15 << 1;
                pathAttachment.vertices            = vertices3.vertices;
                pathAttachment.bones   = vertices3.bones;
                pathAttachment.lengths = array;
                return(pathAttachment);
            }

            default:
                return(null);
            }
        }
		float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents, bool percentPosition,
			bool percentSpacing) {

			Slot target = this.target;
			float position = this.position;
			float[] spaces = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world;
			bool closed = path.Closed;
			int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE;

			float pathLength;
			if (!path.ConstantSpeed) {
				float[] lengths = path.Lengths;
				curveCount -= closed ? 1 : 2;
				pathLength = lengths[curveCount];
				if (percentPosition) position *= pathLength;
				if (percentSpacing) {
					for (int i = 0; i < spacesCount; i++)
						spaces[i] *= pathLength;
				}
				world = this.world.Resize(8).Items;
				for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
					float space = spaces[i];
					position += space;
					float p = position;

					if (closed) {
						p %= pathLength;
						if (p < 0) p += pathLength;
						curve = 0;
					} else if (p < 0) {
						if (prevCurve != BEFORE) {
							prevCurve = BEFORE;
							path.ComputeWorldVertices(target, 2, 4, world, 0);
						}
						AddBeforePosition(p, world, 0, output, o);
						continue;
					} else if (p > pathLength) {
						if (prevCurve != AFTER) {
							prevCurve = AFTER;
							path.ComputeWorldVertices(target, verticesLength - 6, 4, world, 0);
						}
						AddAfterPosition(p - pathLength, world, 0, output, o);
						continue;
					}

					// Determine curve containing position.
					for (;; curve++) {
						float length = lengths[curve];
						if (p > length) continue;
						if (curve == 0)
							p /= length;
						else {
							float prev = lengths[curve - 1];
							p = (p - prev) / (length - prev);
						}
						break;
					}
					if (curve != prevCurve) {
						prevCurve = curve;
						if (closed && curve == curveCount) {
							path.ComputeWorldVertices(target, verticesLength - 4, 4, world, 0);
							path.ComputeWorldVertices(target, 0, 4, world, 4);
						} else
							path.ComputeWorldVertices(target, curve * 6 + 2, 8, world, 0);
					}
					AddCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], output, o,
						tangents || (i > 0 && space == 0));
				}
				return output;
			}

			// World vertices.
			if (closed) {
				verticesLength += 2;
				world = this.world.Resize(verticesLength).Items;
				path.ComputeWorldVertices(target, 2, verticesLength - 4, world, 0);
				path.ComputeWorldVertices(target, 0, 2, world, verticesLength - 4);
				world[verticesLength - 2] = world[0];
				world[verticesLength - 1] = world[1];
			} else {
				curveCount--;
				verticesLength -= 4;
				world = this.world.Resize(verticesLength).Items;
				path.ComputeWorldVertices(target, 2, verticesLength, world, 0);
			}

			// Curve lengths.
			float[] curves = this.curves.Resize(curveCount).Items;
			pathLength = 0;
			float x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
			float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;
			for (int i = 0, w = 2; i < curveCount; i++, w += 6) {
				cx1 = world[w];
				cy1 = world[w + 1];
				cx2 = world[w + 2];
				cy2 = world[w + 3];
				x2 = world[w + 4];
				y2 = world[w + 5];
				tmpx = (x1 - cx1 * 2 + cx2) * 0.1875f;
				tmpy = (y1 - cy1 * 2 + cy2) * 0.1875f;
				dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375f;
				dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375f;
				ddfx = tmpx * 2 + dddfx;
				ddfy = tmpy * 2 + dddfy;
				dfx = (cx1 - x1) * 0.75f + tmpx + dddfx * 0.16666667f;
				dfy = (cy1 - y1) * 0.75f + tmpy + dddfy * 0.16666667f;
				pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
				dfx += ddfx;
				dfy += ddfy;
				ddfx += dddfx;
				ddfy += dddfy;
				pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
				dfx += ddfx;
				dfy += ddfy;
				pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
				dfx += ddfx + dddfx;
				dfy += ddfy + dddfy;
				pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
				curves[i] = pathLength;
				x1 = x2;
				y1 = y2;
			}
			if (percentPosition) position *= pathLength;
			if (percentSpacing) {
				for (int i = 0; i < spacesCount; i++)
					spaces[i] *= pathLength;
			}

			float[] segments = this.segments;
			float curveLength = 0;
			for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
				float space = spaces[i];
				position += space;
				float p = position;

				if (closed) {
					p %= pathLength;
					if (p < 0) p += pathLength;
					curve = 0;
				} else if (p < 0) {
					AddBeforePosition(p, world, 0, output, o);
					continue;
				} else if (p > pathLength) {
					AddAfterPosition(p - pathLength, world, verticesLength - 4, output, o);
					continue;
				}

				// Determine curve containing position.
				for (;; curve++) {
					float length = curves[curve];
					if (p > length) continue;
					if (curve == 0)
						p /= length;
					else {
						float prev = curves[curve - 1];
						p = (p - prev) / (length - prev);
					}
					break;
				}

				// Curve segment lengths.
				if (curve != prevCurve) {
					prevCurve = curve;
					int ii = curve * 6;
					x1 = world[ii];
					y1 = world[ii + 1];
					cx1 = world[ii + 2];
					cy1 = world[ii + 3];
					cx2 = world[ii + 4];
					cy2 = world[ii + 5];
					x2 = world[ii + 6];
					y2 = world[ii + 7];
					tmpx = (x1 - cx1 * 2 + cx2) * 0.03f;
					tmpy = (y1 - cy1 * 2 + cy2) * 0.03f;
					dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f;
					dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006f;
					ddfx = tmpx * 2 + dddfx;
					ddfy = tmpy * 2 + dddfy;
					dfx = (cx1 - x1) * 0.3f + tmpx + dddfx * 0.16666667f;
					dfy = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f;
					curveLength = (float)Math.Sqrt(dfx * dfx + dfy * dfy);
					segments[0] = curveLength;
					for (ii = 1; ii < 8; ii++) {
						dfx += ddfx;
						dfy += ddfy;
						ddfx += dddfx;
						ddfy += dddfy;
						curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
						segments[ii] = curveLength;
					}
					dfx += ddfx;
					dfy += ddfy;
					curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
					segments[8] = curveLength;
					dfx += ddfx + dddfx;
					dfy += ddfy + dddfy;
					curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
					segments[9] = curveLength;
					segment = 0;
				}

				// Weight by segment length.
				p *= curveLength;
				for (;; segment++) {
					float length = segments[segment];
					if (p > length) continue;
					if (segment == 0)
						p /= length;
					else {
						float prev = segments[segment - 1];
						p = segment + (p - prev) / (length - prev);
					}
					break;
				}
				AddCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, output, o, tangents || (i > 0 && space == 0));
			}
			return output;
		}
Exemple #22
0
        private Attachment ReadAttachment(Dictionary <string, object> map, Skin skin, int slotIndex, string name, SkeletonData skeletonData)
        {
            float scale = Scale;

            name = GetString(map, "name", name);
            string text = GetString(map, "type", "region");

            if (text == "skinnedmesh")
            {
                text = "weightedmesh";
            }
            if (text == "weightedmesh")
            {
                text = "mesh";
            }
            if (text == "weightedlinkedmesh")
            {
                text = "linkedmesh";
            }
            AttachmentType attachmentType = (AttachmentType)Enum.Parse(typeof(AttachmentType), text, ignoreCase: true);
            string         @string        = GetString(map, "path", name);

            switch (attachmentType)
            {
            case AttachmentType.Region:
            {
                RegionAttachment regionAttachment = attachmentLoader.NewRegionAttachment(skin, name, @string);
                if (regionAttachment == null)
                {
                    return(null);
                }
                regionAttachment.Path     = @string;
                regionAttachment.x        = GetFloat(map, "x", 0f) * scale;
                regionAttachment.y        = GetFloat(map, "y", 0f) * scale;
                regionAttachment.scaleX   = GetFloat(map, "scaleX", 1f);
                regionAttachment.scaleY   = GetFloat(map, "scaleY", 1f);
                regionAttachment.rotation = GetFloat(map, "rotation", 0f);
                regionAttachment.width    = GetFloat(map, "width", 32f) * scale;
                regionAttachment.height   = GetFloat(map, "height", 32f) * scale;
                regionAttachment.UpdateOffset();
                if (map.ContainsKey("color"))
                {
                    string hexString2 = (string)map["color"];
                    regionAttachment.r = ToColor(hexString2, 0);
                    regionAttachment.g = ToColor(hexString2, 1);
                    regionAttachment.b = ToColor(hexString2, 2);
                    regionAttachment.a = ToColor(hexString2, 3);
                }
                regionAttachment.UpdateOffset();
                return(regionAttachment);
            }

            case AttachmentType.Boundingbox:
            {
                BoundingBoxAttachment boundingBoxAttachment = attachmentLoader.NewBoundingBoxAttachment(skin, name);
                if (boundingBoxAttachment == null)
                {
                    return(null);
                }
                ReadVertices(map, boundingBoxAttachment, GetInt(map, "vertexCount", 0) << 1);
                return(boundingBoxAttachment);
            }

            case AttachmentType.Mesh:
            case AttachmentType.Linkedmesh:
            {
                MeshAttachment meshAttachment = attachmentLoader.NewMeshAttachment(skin, name, @string);
                if (meshAttachment == null)
                {
                    return(null);
                }
                meshAttachment.Path = @string;
                if (map.ContainsKey("color"))
                {
                    string hexString = (string)map["color"];
                    meshAttachment.r = ToColor(hexString, 0);
                    meshAttachment.g = ToColor(hexString, 1);
                    meshAttachment.b = ToColor(hexString, 2);
                    meshAttachment.a = ToColor(hexString, 3);
                }
                meshAttachment.Width  = GetFloat(map, "width", 0f) * scale;
                meshAttachment.Height = GetFloat(map, "height", 0f) * scale;
                string string3 = GetString(map, "parent", null);
                if (string3 != null)
                {
                    meshAttachment.InheritDeform = GetBoolean(map, "deform", defaultValue: true);
                    linkedMeshes.Add(new LinkedMesh(meshAttachment, GetString(map, "skin", null), slotIndex, string3));
                    return(meshAttachment);
                }
                float[] floatArray = GetFloatArray(map, "uvs", 1f);
                ReadVertices(map, meshAttachment, floatArray.Length);
                meshAttachment.triangles = GetIntArray(map, "triangles");
                meshAttachment.regionUVs = floatArray;
                meshAttachment.UpdateUVs();
                if (map.ContainsKey("hull"))
                {
                    meshAttachment.HullLength = GetInt(map, "hull", 0) * 2;
                }
                if (map.ContainsKey("edges"))
                {
                    meshAttachment.Edges = GetIntArray(map, "edges");
                }
                return(meshAttachment);
            }

            case AttachmentType.Path:
            {
                PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, name);
                if (pathAttachment == null)
                {
                    return(null);
                }
                pathAttachment.closed        = GetBoolean(map, "closed", defaultValue: false);
                pathAttachment.constantSpeed = GetBoolean(map, "constantSpeed", defaultValue: true);
                int @int = GetInt(map, "vertexCount", 0);
                ReadVertices(map, pathAttachment, @int << 1);
                pathAttachment.lengths = GetFloatArray(map, "lengths", scale);
                return(pathAttachment);
            }

            case AttachmentType.Point:
            {
                PointAttachment pointAttachment = attachmentLoader.NewPointAttachment(skin, name);
                if (pointAttachment == null)
                {
                    return(null);
                }
                pointAttachment.x        = GetFloat(map, "x", 0f) * scale;
                pointAttachment.y        = GetFloat(map, "y", 0f) * scale;
                pointAttachment.rotation = GetFloat(map, "rotation", 0f);
                return(pointAttachment);
            }

            case AttachmentType.Clipping:
            {
                ClippingAttachment clippingAttachment = attachmentLoader.NewClippingAttachment(skin, name);
                if (clippingAttachment == null)
                {
                    return(null);
                }
                string string2 = GetString(map, "end", null);
                if (string2 != null)
                {
                    SlotData slotData = skeletonData.FindSlot(string2);
                    if (slotData == null)
                    {
                        throw new Exception("Clipping end slot not found: " + string2);
                    }
                    clippingAttachment.EndSlot = slotData;
                }
                ReadVertices(map, clippingAttachment, GetInt(map, "vertexCount", 0) << 1);
                return(clippingAttachment);
            }

            default:
                return(null);
            }
        }