Esempio n. 1
0
        public SkeletonData ReadSkeletonData(TextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader cannot be null.");
            }

            var scale        = this.Scale;
            var skeletonData = new SkeletonData();

            var root = Json.Deserialize(reader) as Dictionary <String, Object>;

            if (root == null)
            {
                throw new Exception("Invalid JSON.");
            }

            // Skeleton.
            if (root.ContainsKey("skeleton"))
            {
                var skeletonMap = (Dictionary <String, Object>)root["skeleton"];
                skeletonData.hash    = (String)skeletonMap["hash"];
                skeletonData.version = (String)skeletonMap["spine"];
                skeletonData.width   = GetFloat(skeletonMap, "width", 0);
                skeletonData.height  = GetFloat(skeletonMap, "height", 0);
            }

            // Bones.
            foreach (Dictionary <String, Object> boneMap in (List <Object>)root["bones"])
            {
                BoneData parent = null;
                if (boneMap.ContainsKey("parent"))
                {
                    parent = skeletonData.FindBone((String)boneMap["parent"]);
                    if (parent == null)
                    {
                        throw new Exception("Parent bone not found: " + boneMap["parent"]);
                    }
                }
                var boneData = new BoneData((String)boneMap["name"], parent);
                boneData.length          = GetFloat(boneMap, "length", 0) * scale;
                boneData.x               = GetFloat(boneMap, "x", 0) * scale;
                boneData.y               = GetFloat(boneMap, "y", 0) * scale;
                boneData.rotation        = GetFloat(boneMap, "rotation", 0);
                boneData.scaleX          = GetFloat(boneMap, "scaleX", 1);
                boneData.scaleY          = GetFloat(boneMap, "scaleY", 1);
                boneData.shearX          = GetFloat(boneMap, "shearX", 0);
                boneData.shearY          = GetFloat(boneMap, "shearY", 0);
                boneData.inheritScale    = GetBoolean(boneMap, "inheritScale", true);
                boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
                skeletonData.bones.Add(boneData);
            }

            // IK constraints.
            if (root.ContainsKey("ik"))
            {
                foreach (Dictionary <String, Object> ikMap in (List <Object>)root["ik"])
                {
                    IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]);

                    foreach (String boneName in (List <Object>)ikMap["bones"])
                    {
                        BoneData bone = skeletonData.FindBone(boneName);
                        if (bone == null)
                        {
                            throw new Exception("IK bone not found: " + boneName);
                        }
                        ikConstraintData.bones.Add(bone);
                    }

                    String targetName = (String)ikMap["target"];
                    ikConstraintData.target = skeletonData.FindBone(targetName);
                    if (ikConstraintData.target == null)
                    {
                        throw new Exception("Target bone not found: " + targetName);
                    }

                    ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1;
                    ikConstraintData.mix           = GetFloat(ikMap, "mix", 1);

                    skeletonData.ikConstraints.Add(ikConstraintData);
                }
            }

            // Transform constraints.
            if (root.ContainsKey("transform"))
            {
                foreach (Dictionary <String, Object> transformMap in (List <Object>)root["transform"])
                {
                    TransformConstraintData transformConstraintData = new TransformConstraintData((String)transformMap["name"]);

                    String boneName = (String)transformMap["bone"];
                    transformConstraintData.bone = skeletonData.FindBone(boneName);
                    if (transformConstraintData.bone == null)
                    {
                        throw new Exception("Bone not found: " + boneName);
                    }

                    String targetName = (String)transformMap["target"];
                    transformConstraintData.target = skeletonData.FindBone(targetName);
                    if (transformConstraintData.target == null)
                    {
                        throw new Exception("Target bone not found: " + targetName);
                    }

                    transformConstraintData.offsetRotation = GetFloat(transformMap, "rotation", 0);
                    transformConstraintData.offsetX        = GetFloat(transformMap, "x", 0) * scale;
                    transformConstraintData.offsetY        = GetFloat(transformMap, "y", 0) * scale;
                    transformConstraintData.offsetScaleX   = GetFloat(transformMap, "scaleX", 0);
                    transformConstraintData.offsetScaleY   = GetFloat(transformMap, "scaleY", 0);
                    transformConstraintData.offsetShearY   = GetFloat(transformMap, "shearY", 0);

                    transformConstraintData.rotateMix    = GetFloat(transformMap, "rotateMix", 1);
                    transformConstraintData.translateMix = GetFloat(transformMap, "translateMix", 1);
                    transformConstraintData.scaleMix     = GetFloat(transformMap, "scaleMix", 1);
                    transformConstraintData.shearMix     = GetFloat(transformMap, "shearMix", 1);

                    skeletonData.transformConstraints.Add(transformConstraintData);
                }
            }

            // Slots.
            if (root.ContainsKey("slots"))
            {
                foreach (Dictionary <String, Object> slotMap in (List <Object>)root["slots"])
                {
                    var      slotName = (String)slotMap["name"];
                    var      boneName = (String)slotMap["bone"];
                    BoneData boneData = skeletonData.FindBone(boneName);
                    if (boneData == null)
                    {
                        throw new Exception("Slot bone not found: " + boneName);
                    }
                    var slotData = new SlotData(slotName, boneData);

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

                    if (slotMap.ContainsKey("attachment"))
                    {
                        slotData.attachmentName = (String)slotMap["attachment"];
                    }

                    if (slotMap.ContainsKey("blend"))
                    {
                        slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
                    }
                    else
                    {
                        slotData.blendMode = BlendMode.normal;
                    }

                    skeletonData.slots.Add(slotData);
                }
            }

            // Skins.
            if (root.ContainsKey("skins"))
            {
                foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["skins"])
                {
                    var skin = new Skin(entry.Key);
                    foreach (KeyValuePair <String, Object> slotEntry in (Dictionary <String, Object>)entry.Value)
                    {
                        int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
                        foreach (KeyValuePair <String, Object> attachmentEntry in ((Dictionary <String, Object>)slotEntry.Value))
                        {
                            Attachment attachment = ReadAttachment(skin, slotIndex, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value);
                            if (attachment != null)
                            {
                                skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
                            }
                        }
                    }
                    skeletonData.skins.Add(skin);
                    if (skin.name == "default")
                    {
                        skeletonData.defaultSkin = skin;
                    }
                }
            }

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

            // Events.
            if (root.ContainsKey("events"))
            {
                foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["events"])
                {
                    var entryMap  = (Dictionary <String, Object>)entry.Value;
                    var eventData = new EventData(entry.Key);
                    eventData.Int    = GetInt(entryMap, "int", 0);
                    eventData.Float  = GetFloat(entryMap, "float", 0);
                    eventData.String = GetString(entryMap, "string", null);
                    skeletonData.events.Add(eventData);
                }
            }

            // Animations.
            if (root.ContainsKey("animations"))
            {
                foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["animations"])
                {
                    ReadAnimation(entry.Key, (Dictionary <String, Object>)entry.Value, skeletonData);
                }
            }

            skeletonData.bones.TrimExcess();
            skeletonData.slots.TrimExcess();
            skeletonData.skins.TrimExcess();
            skeletonData.events.TrimExcess();
            skeletonData.animations.TrimExcess();
            skeletonData.ikConstraints.TrimExcess();
            return(skeletonData);
        }
Esempio n. 2
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.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 boneData = new BoneData(name, parent);
                boneData.rotation        = ReadFloat(input);
                boneData.x               = ReadFloat(input) * scale;
                boneData.y               = ReadFloat(input) * scale;
                boneData.scaleX          = ReadFloat(input);
                boneData.scaleY          = ReadFloat(input);
                boneData.shearX          = ReadFloat(input);
                boneData.shearY          = ReadFloat(input);
                boneData.length          = ReadFloat(input) * scale;
                boneData.inheritRotation = ReadBoolean(input);
                boneData.inheritScale    = ReadBoolean(input);
                if (nonessential)
                {
                    ReadInt(input);                               // Skip bone color.
                }
                skeletonData.bones.Add(boneData);
            }

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

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

            // 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(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;
                slotData.attachmentName = ReadString(input);
                slotData.blendMode      = (BlendMode)ReadVarint(input, true);
                skeletonData.slots.Add(slotData);
            }

            // Default skin.
            Skin defaultSkin = ReadSkin(input, "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, 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);
                }
                if (linkedMesh.mesh is MeshAttachment)
                {
                    MeshAttachment mesh = (MeshAttachment)linkedMesh.mesh;
                    mesh.ParentMesh = (MeshAttachment)parent;
                    mesh.UpdateUVs();
                }
                else
                {
                    WeightedMeshAttachment mesh = (WeightedMeshAttachment)linkedMesh.mesh;
                    mesh.ParentMesh = (WeightedMeshAttachment)parent;
                    mesh.UpdateUVs();
                }
            }
            linkedMeshes.Clear();

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

            // 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();
            return(skeletonData);
        }