コード例 #1
0
 /// <summary>
 /// <para>Attachments from the new skin are attached if the corresponding attachment from the old skin was attached.
 /// If there was no old skin, each slot's setup mode attachment is attached from the new skin.</para>
 /// <para>After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
 /// <see cref="Skeleton.SetSlotsToSetupPose()"/>.
 /// Also, often <see cref="AnimationState.Apply(Skeleton)"/> is called before the next time the
 /// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.</para>
 /// </summary>
 /// <param name="newSkin">May be null.</param>
 public void SetSkin(Skin newSkin)
 {
     if (newSkin != null)
     {
         if (skin != null)
         {
             newSkin.AttachAll(this, skin);
         }
         else
         {
             ExposedList <Slot> slots = this.slots;
             for (int i = 0, n = slots.Count; i < n; i++)
             {
                 Slot   slot = slots.Items[i];
                 string name = slot.data.attachmentName;
                 if (name != null)
                 {
                     Attachment attachment = newSkin.GetAttachment(i, name);
                     if (attachment != null)
                     {
                         slot.Attachment = attachment;
                     }
                 }
             }
         }
     }
     skin = newSkin;
 }
コード例 #2
0
 /// <returns>May be null.</returns>
 public Attachment GetAttachment(int slotIndex, string attachmentName)
 {
     if (attachmentName == null)
     {
         throw new ArgumentNullException("attachmentName", "attachmentName cannot be null.");
     }
     if (skin != null)
     {
         Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
         if (attachment != null)
         {
             return(attachment);
         }
     }
     return(data.defaultSkin != null?data.defaultSkin.GetAttachment(slotIndex, attachmentName) : null);
 }
コード例 #3
0
        private void ReadAnimation(String name, Stream input, SkeletonData skeletonData)
        {
            var   timelines = new ExposedList <Timeline>();
            float scale     = Scale;
            float duration  = 0;

            // Slot timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                int slotIndex = ReadVarint(input, true);
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    int timelineType = input.ReadByte();
                    int frameCount   = ReadVarint(input, true);
                    switch (timelineType)
                    {
                    case SLOT_ATTACHMENT: {
                        AttachmentTimeline timeline = new AttachmentTimeline(frameCount);
                        timeline.slotIndex = slotIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input));
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[frameCount - 1]);
                        break;
                    }

                    case SLOT_COLOR: {
                        ColorTimeline timeline = new ColorTimeline(frameCount);
                        timeline.slotIndex = slotIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            float time  = ReadFloat(input);
                            int   color = ReadInt(input);
                            float r     = ((color & 0xff000000) >> 24) / 255f;
                            float g     = ((color & 0x00ff0000) >> 16) / 255f;
                            float b     = ((color & 0x0000ff00) >> 8) / 255f;
                            float a     = ((color & 0x000000ff)) / 255f;
                            timeline.SetFrame(frameIndex, time, r, g, b, a);
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]);
                        break;
                    }

                    case SLOT_TWO_COLOR: {
                        TwoColorTimeline timeline = new TwoColorTimeline(frameCount);
                        timeline.slotIndex = slotIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            float time   = ReadFloat(input);
                            int   color  = ReadInt(input);
                            float r      = ((color & 0xff000000) >> 24) / 255f;
                            float g      = ((color & 0x00ff0000) >> 16) / 255f;
                            float b      = ((color & 0x0000ff00) >> 8) / 255f;
                            float a      = ((color & 0x000000ff)) / 255f;
                            int   color2 = ReadInt(input);                                   // 0x00rrggbb
                            float r2     = ((color2 & 0x00ff0000) >> 16) / 255f;
                            float g2     = ((color2 & 0x0000ff00) >> 8) / 255f;
                            float b2     = ((color2 & 0x000000ff)) / 255f;

                            timeline.SetFrame(frameIndex, time, r, g, b, a, r2, g2, b2);
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TwoColorTimeline.ENTRIES]);
                        break;
                    }
                    }
                }
            }

            // Bone timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                int boneIndex = ReadVarint(input, true);
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    int timelineType = input.ReadByte();
                    int frameCount   = ReadVarint(input, true);
                    switch (timelineType)
                    {
                    case BONE_ROTATE: {
                        RotateTimeline timeline = new RotateTimeline(frameCount);
                        timeline.boneIndex = boneIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input));
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]);
                        break;
                    }

                    case BONE_TRANSLATE:
                    case BONE_SCALE:
                    case BONE_SHEAR: {
                        TranslateTimeline timeline;
                        float             timelineScale = 1;
                        if (timelineType == BONE_SCALE)
                        {
                            timeline = new ScaleTimeline(frameCount);
                        }
                        else if (timelineType == BONE_SHEAR)
                        {
                            timeline = new ShearTimeline(frameCount);
                        }
                        else
                        {
                            timeline      = new TranslateTimeline(frameCount);
                            timelineScale = scale;
                        }
                        timeline.boneIndex = boneIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input)
                                              * timelineScale);
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]);
                        break;
                    }
                    }
                }
            }

            // IK timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                int index      = ReadVarint(input, true);
                int frameCount = ReadVarint(input, true);
                IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
                timeline.ikConstraintIndex = index;
                for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                {
                    timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input));
                    if (frameIndex < frameCount - 1)
                    {
                        ReadCurve(input, frameIndex, timeline);
                    }
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]);
            }

            // Transform constraint timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                int index      = ReadVarint(input, true);
                int frameCount = ReadVarint(input, true);
                TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount);
                timeline.transformConstraintIndex = index;
                for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                {
                    timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input));
                    if (frameIndex < frameCount - 1)
                    {
                        ReadCurve(input, frameIndex, timeline);
                    }
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]);
            }

            // Path constraint timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                int index = ReadVarint(input, true);
                PathConstraintData data = skeletonData.pathConstraints.Items[index];
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    int timelineType = ReadSByte(input);
                    int frameCount   = ReadVarint(input, true);
                    switch (timelineType)
                    {
                    case PATH_POSITION:
                    case PATH_SPACING: {
                        PathConstraintPositionTimeline timeline;
                        float timelineScale = 1;
                        if (timelineType == PATH_SPACING)
                        {
                            timeline = new PathConstraintSpacingTimeline(frameCount);
                            if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)
                            {
                                timelineScale = scale;
                            }
                        }
                        else
                        {
                            timeline = new PathConstraintPositionTimeline(frameCount);
                            if (data.positionMode == PositionMode.Fixed)
                            {
                                timelineScale = scale;
                            }
                        }
                        timeline.pathConstraintIndex = index;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale);
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
                        break;
                    }

                    case PATH_MIX: {
                        PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount);
                        timeline.pathConstraintIndex = index;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input));
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
                        break;
                    }
                    }
                }
            }

            // Deform timelines.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                Skin skin = skeletonData.skins.Items[ReadVarint(input, true)];
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    int slotIndex = ReadVarint(input, true);
                    for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++)
                    {
                        VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input));
                        bool             weighted   = attachment.bones != null;
                        float[]          vertices   = attachment.vertices;
                        int deformLength            = weighted ? vertices.Length / 3 * 2 : vertices.Length;

                        int            frameCount = ReadVarint(input, true);
                        DeformTimeline timeline   = new DeformTimeline(frameCount);
                        timeline.slotIndex  = slotIndex;
                        timeline.attachment = attachment;

                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            float   time = ReadFloat(input);
                            float[] deform;
                            int     end = ReadVarint(input, true);
                            if (end == 0)
                            {
                                deform = weighted ? new float[deformLength] : vertices;
                            }
                            else
                            {
                                deform = new float[deformLength];
                                int start = ReadVarint(input, true);
                                end += start;
                                if (scale == 1)
                                {
                                    for (int v = start; v < end; v++)
                                    {
                                        deform[v] = ReadFloat(input);
                                    }
                                }
                                else
                                {
                                    for (int v = start; v < end; v++)
                                    {
                                        deform[v] = ReadFloat(input) * scale;
                                    }
                                }
                                if (!weighted)
                                {
                                    for (int v = 0, vn = deform.Length; v < vn; v++)
                                    {
                                        deform[v] += vertices[v];
                                    }
                                }
                            }

                            timeline.SetFrame(frameIndex, time, deform);
                            if (frameIndex < frameCount - 1)
                            {
                                ReadCurve(input, frameIndex, timeline);
                            }
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[frameCount - 1]);
                    }
                }
            }

            // Draw order timeline.
            int drawOrderCount = ReadVarint(input, true);

            if (drawOrderCount > 0)
            {
                DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
                int slotCount = skeletonData.slots.Count;
                for (int i = 0; i < drawOrderCount; i++)
                {
                    float time        = ReadFloat(input);
                    int   offsetCount = ReadVarint(input, true);
                    int[] drawOrder   = new int[slotCount];
                    for (int ii = slotCount - 1; ii >= 0; ii--)
                    {
                        drawOrder[ii] = -1;
                    }
                    int[] unchanged = new int[slotCount - offsetCount];
                    int   originalIndex = 0, unchangedIndex = 0;
                    for (int ii = 0; ii < offsetCount; ii++)
                    {
                        int slotIndex = ReadVarint(input, true);
                        // Collect unchanged items.
                        while (originalIndex != slotIndex)
                        {
                            unchanged[unchangedIndex++] = originalIndex++;
                        }
                        // Set changed items.
                        drawOrder[originalIndex + ReadVarint(input, true)] = originalIndex++;
                    }
                    // Collect remaining unchanged items.
                    while (originalIndex < slotCount)
                    {
                        unchanged[unchangedIndex++] = originalIndex++;
                    }
                    // Fill in unchanged items.
                    for (int ii = slotCount - 1; ii >= 0; ii--)
                    {
                        if (drawOrder[ii] == -1)
                        {
                            drawOrder[ii] = unchanged[--unchangedIndex];
                        }
                    }
                    timeline.SetFrame(i, time, drawOrder);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]);
            }

            // Event timeline.
            int eventCount = ReadVarint(input, true);

            if (eventCount > 0)
            {
                EventTimeline timeline = new EventTimeline(eventCount);
                for (int i = 0; i < eventCount; i++)
                {
                    float     time      = ReadFloat(input);
                    EventData eventData = skeletonData.events.Items[ReadVarint(input, true)];
                    Event     e         = new Event(time, eventData);
                    e.Int    = ReadVarint(input, false);
                    e.Float  = ReadFloat(input);
                    e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
                    timeline.SetFrame(i, e);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[eventCount - 1]);
            }

            timelines.TrimExcess();
            skeletonData.animations.Add(new Animation(name, timelines, duration));
        }
コード例 #4
0
        public SkeletonData ReadSkeletonData(Stream input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            float scale = Scale;

            var skeletonData = new SkeletonData();

            skeletonData.hash = ReadString(input);
            if (skeletonData.hash.Length == 0)
            {
                skeletonData.hash = null;
            }
            skeletonData.version = ReadString(input);
            if (skeletonData.version.Length == 0)
            {
                skeletonData.version = null;
            }
            skeletonData.width  = ReadFloat(input);
            skeletonData.height = ReadFloat(input);

            bool nonessential = ReadBoolean(input);

            if (nonessential)
            {
                skeletonData.fps        = ReadFloat(input);
                skeletonData.imagesPath = ReadString(input);
                if (skeletonData.imagesPath.Length == 0)
                {
                    skeletonData.imagesPath = null;
                }
            }

            // Bones.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                String   name   = ReadString(input);
                BoneData parent = i == 0 ? null : skeletonData.bones.Items[ReadVarint(input, true)];
                BoneData data   = new BoneData(i, name, parent);
                data.rotation      = ReadFloat(input);
                data.x             = ReadFloat(input) * scale;
                data.y             = ReadFloat(input) * scale;
                data.scaleX        = ReadFloat(input);
                data.scaleY        = ReadFloat(input);
                data.shearX        = ReadFloat(input);
                data.shearY        = ReadFloat(input);
                data.length        = ReadFloat(input) * scale;
                data.transformMode = TransformModeValues[ReadVarint(input, true)];
                if (nonessential)
                {
                    ReadInt(input);                               // Skip bone color.
                }
                skeletonData.bones.Add(data);
            }

            // Slots.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                String   slotName = ReadString(input);
                BoneData boneData = skeletonData.bones.Items[ReadVarint(input, true)];
                SlotData slotData = new SlotData(i, slotName, boneData);
                int      color    = ReadInt(input);
                slotData.r = ((color & 0xff000000) >> 24) / 255f;
                slotData.g = ((color & 0x00ff0000) >> 16) / 255f;
                slotData.b = ((color & 0x0000ff00) >> 8) / 255f;
                slotData.a = ((color & 0x000000ff)) / 255f;

                int darkColor = ReadInt(input);                 // 0x00rrggbb
                if (darkColor != -1)
                {
                    slotData.hasSecondColor = true;
                    slotData.r2             = ((darkColor & 0x00ff0000) >> 16) / 255f;
                    slotData.g2             = ((darkColor & 0x0000ff00) >> 8) / 255f;
                    slotData.b2             = ((darkColor & 0x000000ff)) / 255f;
                }

                slotData.attachmentName = ReadString(input);
                slotData.blendMode      = (BlendMode)ReadVarint(input, true);
                skeletonData.slots.Add(slotData);
            }

            // IK constraints.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                IkConstraintData data = new IkConstraintData(ReadString(input));
                data.order = ReadVarint(input, true);
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
                }
                data.target        = skeletonData.bones.Items[ReadVarint(input, true)];
                data.mix           = ReadFloat(input);
                data.bendDirection = ReadSByte(input);
                skeletonData.ikConstraints.Add(data);
            }

            // Transform constraints.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                TransformConstraintData data = new TransformConstraintData(ReadString(input));
                data.order = ReadVarint(input, true);
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
                }
                data.target         = skeletonData.bones.Items[ReadVarint(input, true)];
                data.local          = ReadBoolean(input);
                data.relative       = ReadBoolean(input);
                data.offsetRotation = ReadFloat(input);
                data.offsetX        = ReadFloat(input) * scale;
                data.offsetY        = ReadFloat(input) * scale;
                data.offsetScaleX   = ReadFloat(input);
                data.offsetScaleY   = ReadFloat(input);
                data.offsetShearY   = ReadFloat(input);
                data.rotateMix      = ReadFloat(input);
                data.translateMix   = ReadFloat(input);
                data.scaleMix       = ReadFloat(input);
                data.shearMix       = ReadFloat(input);
                skeletonData.transformConstraints.Add(data);
            }

            // Path constraints
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                PathConstraintData data = new PathConstraintData(ReadString(input));
                data.order = ReadVarint(input, true);
                for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
                {
                    data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
                }
                data.target         = skeletonData.slots.Items[ReadVarint(input, true)];
                data.positionMode   = (PositionMode)Enum.GetValues(typeof(PositionMode)).GetValue(ReadVarint(input, true));
                data.spacingMode    = (SpacingMode)Enum.GetValues(typeof(SpacingMode)).GetValue(ReadVarint(input, true));
                data.rotateMode     = (RotateMode)Enum.GetValues(typeof(RotateMode)).GetValue(ReadVarint(input, true));
                data.offsetRotation = ReadFloat(input);
                data.position       = ReadFloat(input);
                if (data.positionMode == PositionMode.Fixed)
                {
                    data.position *= scale;
                }
                data.spacing = ReadFloat(input);
                if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)
                {
                    data.spacing *= scale;
                }
                data.rotateMix    = ReadFloat(input);
                data.translateMix = ReadFloat(input);
                skeletonData.pathConstraints.Add(data);
            }

            // Default skin.
            Skin defaultSkin = ReadSkin(input, skeletonData, "default", nonessential);

            if (defaultSkin != null)
            {
                skeletonData.defaultSkin = defaultSkin;
                skeletonData.skins.Add(defaultSkin);
            }

            // Skins.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                skeletonData.skins.Add(ReadSkin(input, skeletonData, ReadString(input), nonessential));
            }

            // Linked meshes.
            for (int i = 0, n = linkedMeshes.Count; i < n; i++)
            {
                SkeletonJson.LinkedMesh linkedMesh = linkedMeshes[i];
                Skin skin = linkedMesh.skin == null ? skeletonData.DefaultSkin : skeletonData.FindSkin(linkedMesh.skin);
                if (skin == null)
                {
                    throw new Exception("Skin not found: " + linkedMesh.skin);
                }
                Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent);
                if (parent == null)
                {
                    throw new Exception("Parent mesh not found: " + linkedMesh.parent);
                }
                linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
                linkedMesh.mesh.UpdateUVs();
            }
            linkedMeshes.Clear();

            // Events.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                EventData data = new EventData(ReadString(input));
                data.Int    = ReadVarint(input, false);
                data.Float  = ReadFloat(input);
                data.String = ReadString(input);
                skeletonData.events.Add(data);
            }

            // Animations.
            for (int i = 0, n = ReadVarint(input, true); i < n; i++)
            {
                ReadAnimation(ReadString(input), input, skeletonData);
            }

            skeletonData.bones.TrimExcess();
            skeletonData.slots.TrimExcess();
            skeletonData.skins.TrimExcess();
            skeletonData.events.TrimExcess();
            skeletonData.animations.TrimExcess();
            skeletonData.ikConstraints.TrimExcess();
            skeletonData.pathConstraints.TrimExcess();
            return(skeletonData);
        }