コード例 #1
0
        public override Attachment Copy()
        {
            ClippingAttachment copy = new ClippingAttachment(this.Name);

            CopyTo(copy);
            copy.endSlot = endSlot;
            return(copy);
        }
コード例 #2
0
 public void ClipEnd()
 {
     if (this.clipAttachment != null)
     {
         this.clipAttachment   = null;
         this.clippingPolygons = null;
         this.clippedVertices.Clear(true);
         this.clippedTriangles.Clear(true);
         this.clippingPolygon.Clear(true);
     }
 }
コード例 #3
0
 public void ClipEnd()
 {
     if (clipAttachment == null)
     {
         return;
     }
     clipAttachment   = null;
     clippingPolygons = null;
     clippedVertices.Clear();
     clippedTriangles.Clear();
     clippingPolygon.Clear();
 }
コード例 #4
0
        public int ClipStart(Slot slot, ClippingAttachment clip)
        {
            if (this.clipAttachment != null)
            {
                return(0);
            }
            this.clipAttachment = clip;
            int worldVerticesLength = clip.worldVerticesLength;

            float[] items = this.clippingPolygon.Resize(worldVerticesLength).Items;
            clip.ComputeWorldVertices(slot, 0, worldVerticesLength, items, 0, 2);
            MakeClockwise(this.clippingPolygon);
            this.clippingPolygons = this.triangulator.Decompose(this.clippingPolygon, this.triangulator.Triangulate(this.clippingPolygon));
            foreach (ExposedList <float> list in this.clippingPolygons)
            {
                MakeClockwise(list);
                list.Add(list.Items[0]);
                list.Add(list.Items[1]);
            }
            return(this.clippingPolygons.Count);
        }
コード例 #5
0
        public int ClipStart(Slot slot, ClippingAttachment clip)
        {
            if (clipAttachment != null)
            {
                return(0);
            }
            clipAttachment = clip;

            int n = clip.worldVerticesLength;

            float[] vertices = clippingPolygon.Resize(n).Items;
            clip.ComputeWorldVertices(slot, 0, n, vertices, 0, 2);
            MakeClockwise(clippingPolygon);
            clippingPolygons = triangulator.Decompose(clippingPolygon, triangulator.Triangulate(clippingPolygon));
            foreach (var polygon in clippingPolygons)
            {
                MakeClockwise(polygon);
                polygon.Add(polygon.Items[0]);
                polygon.Add(polygon.Items[1]);
            }
            return(clippingPolygons.Count);
        }
コード例 #6
0
        private Attachment ReadAttachment(Stream input, SkeletonData skeletonData, 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;
                }
                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);
            }

            case AttachmentType.Point: {
                float rotation = ReadFloat(input);
                float x        = ReadFloat(input);
                float y        = ReadFloat(input);
                if (nonessential)
                {
                    ReadInt(input);                                       //int color = nonessential ? ReadInt(input) : 0;
                }
                PointAttachment point = attachmentLoader.NewPointAttachment(skin, name);
                if (point == null)
                {
                    return(null);
                }
                point.x        = x * scale;
                point.y        = y * scale;
                point.rotation = rotation;
                //if (nonessential) point.color = color;
                return(point);
            }

            case AttachmentType.Clipping: {
                int      endSlotIndex = ReadVarint(input, true);
                int      vertexCount  = ReadVarint(input, true);
                Vertices vertices     = ReadVertices(input, vertexCount);
                if (nonessential)
                {
                    ReadInt(input);
                }

                ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name);
                if (clip == null)
                {
                    return(null);
                }
                clip.EndSlot             = skeletonData.slots.Items[endSlotIndex];
                clip.worldVerticesLength = vertexCount << 1;
                clip.vertices            = vertices.vertices;
                clip.bones = vertices.bones;
                return(clip);
            }
            }
            return(null);
        }
コード例 #7
0
        public void Draw(Skeleton skeleton)
        {
            var   drawOrder = skeleton.DrawOrder;
            var   drawOrderItems = skeleton.DrawOrder.Items;
            float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A;
            Color color = new Color();

            if (VertexEffect != null)
            {
                VertexEffect.Begin(skeleton);
            }

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrderItems[i];
                Attachment attachment = slot.Attachment;

                float     attachmentColorR, attachmentColorG, attachmentColorB, attachmentColorA;
                Texture2D texture       = null;
                int       verticesCount = 0;
                float[]   vertices      = this.vertices;
                int       indicesCount  = 0;
                int[]     indices       = null;
                float[]   uvs           = null;

                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;
                    attachmentColorR = regionAttachment.R; attachmentColorG = regionAttachment.G; attachmentColorB = regionAttachment.B; attachmentColorA = regionAttachment.A;
                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    texture       = (Texture2D)region.page.rendererObject;
                    verticesCount = 4;
                    regionAttachment.ComputeWorldVertices(slot.Bone, vertices, 0, 2);
                    indicesCount = 6;
                    indices      = quadTriangles;
                    uvs          = regionAttachment.UVs;
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh = (MeshAttachment)attachment;
                    attachmentColorR = mesh.R; attachmentColorG = mesh.G; attachmentColorB = mesh.B; attachmentColorA = mesh.A;
                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    texture = (Texture2D)region.page.rendererObject;
                    int vertexCount = mesh.WorldVerticesLength;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    verticesCount = vertexCount >> 1;
                    mesh.ComputeWorldVertices(slot, vertices);
                    indicesCount = mesh.Triangles.Length;
                    indices      = mesh.Triangles;
                    uvs          = mesh.UVs;
                }
                else if (attachment is ClippingAttachment)
                {
                    ClippingAttachment clip = (ClippingAttachment)attachment;
                    clipper.ClipStart(slot, clip);
                    continue;
                }
                else
                {
                    continue;
                }

                // set blend state
                BlendState blend = slot.Data.BlendMode == BlendMode.Additive ? BlendState.Additive : defaultBlendState;
                if (device.BlendState != blend)
                {
                    //End();
                    //device.BlendState = blend;
                }

                // calculate color
                float a = skeletonA * slot.A * attachmentColorA;
                if (premultipliedAlpha)
                {
                    color = new Color(
                        skeletonR * slot.R * attachmentColorR * a,
                        skeletonG * slot.G * attachmentColorG * a,
                        skeletonB * slot.B * attachmentColorB * a, a);
                }
                else
                {
                    color = new Color(
                        skeletonR * slot.R * attachmentColorR,
                        skeletonG * slot.G * attachmentColorG,
                        skeletonB * slot.B * attachmentColorB, a);
                }

                Color darkColor = new Color();
                if (slot.HasSecondColor)
                {
                    if (premultipliedAlpha)
                    {
                        darkColor = new Color(slot.R2 * a, slot.G2 * a, slot.B2 * a);
                    }
                    else
                    {
                        darkColor = new Color(slot.R2 * a, slot.G2 * a, slot.B2 * a);
                    }
                }
                darkColor.A = premultipliedAlpha ? (byte)255 : (byte)0;

                // clip
                if (clipper.IsClipping)
                {
                    clipper.ClipTriangles(vertices, verticesCount << 1, indices, indicesCount, uvs);
                    vertices      = clipper.ClippedVertices.Items;
                    verticesCount = clipper.ClippedVertices.Count >> 1;
                    indices       = clipper.ClippedTriangles.Items;
                    indicesCount  = clipper.ClippedTriangles.Count;
                    uvs           = clipper.ClippedUVs.Items;
                }

                if (verticesCount == 0 || indicesCount == 0)
                {
                    continue;
                }

                // submit to batch
                MeshItem item = batcher.NextItem(verticesCount, indicesCount);
                item.texture = texture;
                for (int ii = 0, nn = indicesCount; ii < nn; ii++)
                {
                    item.triangles[ii] = indices[ii];
                }
                VertexPositionColorTextureColor[] itemVertices = item.vertices;
                for (int ii = 0, v = 0, nn = verticesCount << 1; v < nn; ii++, v += 2)
                {
                    itemVertices[ii].Color               = color;
                    itemVertices[ii].Color2              = darkColor;
                    itemVertices[ii].Position.X          = vertices[v];
                    itemVertices[ii].Position.Y          = vertices[v + 1];
                    itemVertices[ii].Position.Z          = 0;
                    itemVertices[ii].TextureCoordinate.X = uvs[v];
                    itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
                    if (VertexEffect != null)
                    {
                        VertexEffect.Transform(ref itemVertices[ii]);
                    }
                }

                clipper.ClipEnd(slot);
            }
            clipper.ClipEnd();
            if (VertexEffect != null)
            {
                VertexEffect.End();
            }
        }
コード例 #8
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);
            }
        }
コード例 #9
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);
            }
        }