Esempio n. 1
0
 public void Initialize(bool overwrite)
 {
     if ((!this.IsValid || overwrite) && (this.skeletonDataAsset != null))
     {
         Spine.SkeletonData skeletonData = this.skeletonDataAsset.GetSkeletonData(false);
         if ((skeletonData != null) && ((this.skeletonDataAsset.atlasAssets.Length > 0) && (this.skeletonDataAsset.atlasAssets[0].materials.Length > 0)))
         {
             this.state = new Spine.AnimationState(this.skeletonDataAsset.GetAnimationStateData());
             if (this.state == null)
             {
                 this.Clear();
             }
             else
             {
                 Spine.Skeleton skeleton = new Spine.Skeleton(skeletonData)
                 {
                     flipX = this.initialFlipX,
                     flipY = this.initialFlipY
                 };
                 this.skeleton    = skeleton;
                 this.meshBuffers = new DoubleBuffered <MeshRendererBuffers.SmartMesh>();
                 base.get_canvasRenderer().SetTexture(this.get_mainTexture());
                 if (!string.IsNullOrEmpty(this.initialSkinName))
                 {
                     this.skeleton.SetSkin(this.initialSkinName);
                 }
                 if (!string.IsNullOrEmpty(this.startingAnimation))
                 {
                     this.state.SetAnimation(0, this.startingAnimation, this.startingLoop);
                     this.Update(0f);
                 }
             }
         }
     }
 }
Esempio n. 2
0
        public Skeleton(SkeletonData data)
        {
            if (data == null) throw new ArgumentNullException("data cannot be null.");
            Data = data;

            Bones = new List<Bone>(Data.Bones.Count);
            foreach (BoneData boneData in Data.Bones) {
                Bone parent = boneData.Parent == null ? null : Bones[Data.Bones.IndexOf(boneData.Parent)];
                Bones.Add(new Bone(boneData, parent));
            }

            Slots = new List<Slot>(Data.Slots.Count);
            DrawOrder = new List<Slot>(Data.Slots.Count);
            foreach (SlotData slotData in Data.Slots) {
                Bone bone = Bones[Data.Bones.IndexOf(slotData.BoneData)];
                Slot slot = new Slot(slotData, this, bone);
                Slots.Add(slot);
                DrawOrder.Add(slot);
            }

            R = 1;
            G = 1;
            B = 1;
            A = 1;
        }
	void OnEnable () {

		SpineEditorUtilities.ConfirmInitialization();

		try {
			atlasAssets = serializedObject.FindProperty("atlasAssets");
			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
			scale = serializedObject.FindProperty("scale");
			fromAnimation = serializedObject.FindProperty("fromAnimation");
			toAnimation = serializedObject.FindProperty("toAnimation");
			duration = serializedObject.FindProperty("duration");
			defaultMix = serializedObject.FindProperty("defaultMix");
			controller = serializedObject.FindProperty("controller");
#if SPINE_TK2D
			spriteCollection = serializedObject.FindProperty("spriteCollection");
#endif

			m_skeletonDataAsset = (SkeletonDataAsset)target;
			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

			EditorApplication.update += Update;
		} catch {


		}

		m_skeletonData = m_skeletonDataAsset.GetSkeletonData(true);

		showUnity = EditorPrefs.GetBool("SkeletonDataAssetInspector_showUnity", true);

		RepopulateWarnings();
	}
 public AnimationPlayer(SkeletonData skeletonData)
 {
     this.skeletonData = skeletonData;
     skeleton = new Skeleton(skeletonData);
     skeleton.SetSlotsToSetupPose();
     animationDataPool = new ObjectPool<AnimationData>(() => new AnimationData(), 10);
 }
Esempio n. 5
0
		public Skeleton (SkeletonData data) {
			if (data == null) throw new ArgumentNullException("data cannot be null.");
			this.data = data;

			bones = new List<Bone>(data.bones.Count);
			foreach (BoneData boneData in data.bones) {
				Bone parent = boneData.parent == null ? null : bones[data.bones.IndexOf(boneData.parent)];
				bones.Add(new Bone(boneData, this, parent));
			}

			slots = new List<Slot>(data.slots.Count);
			drawOrder = new List<Slot>(data.slots.Count);
			foreach (SlotData slotData in data.slots) {
				Bone bone = bones[data.bones.IndexOf(slotData.boneData)];
				Slot slot = new Slot(slotData, bone);
				slots.Add(slot);
				drawOrder.Add(slot);
			}

			ikConstraints = new List<IkConstraint>(data.ikConstraints.Count);
			foreach (IkConstraintData ikConstraintData in data.ikConstraints)
				ikConstraints.Add(new IkConstraint(ikConstraintData, this));

			UpdateCache();
		}
		void OnEnable () {

			SpineEditorUtilities.ConfirmInitialization();

			try {
				atlasAssets = serializedObject.FindProperty("atlasAssets");
				atlasAssets.isExpanded = true;
				skeletonJSON = serializedObject.FindProperty("skeletonJSON");
				scale = serializedObject.FindProperty("scale");
				fromAnimation = serializedObject.FindProperty("fromAnimation");
				toAnimation = serializedObject.FindProperty("toAnimation");
				duration = serializedObject.FindProperty("duration");
				defaultMix = serializedObject.FindProperty("defaultMix");
				#if SPINE_SKELETON_ANIMATOR
				controller = serializedObject.FindProperty("controller");
				#endif
				#if SPINE_TK2D
				spriteCollection = serializedObject.FindProperty("spriteCollection");
				#endif

				m_skeletonDataAsset = (SkeletonDataAsset)target;
				m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));

				EditorApplication.update += Update;
			} catch {
				// TODO: WARNING: empty catch block supresses errors.

			}

			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(true);

			showBaking = EditorPrefs.GetBool("SkeletonDataAssetInspector_showUnity", false);

			RepopulateWarnings();
		}
		void OnEnable () {
			SpineEditorUtilities.ConfirmInitialization();

			atlasAssets = serializedObject.FindProperty("atlasAssets");
			skeletonJSON = serializedObject.FindProperty("skeletonJSON");
			scale = serializedObject.FindProperty("scale");
			fromAnimation = serializedObject.FindProperty("fromAnimation");
			toAnimation = serializedObject.FindProperty("toAnimation");
			duration = serializedObject.FindProperty("duration");
			defaultMix = serializedObject.FindProperty("defaultMix");

			#if SPINE_SKELETON_ANIMATOR
			controller = serializedObject.FindProperty("controller");
			#endif

			#if SPINE_TK2D
			atlasAssets.isExpanded = false;
			spriteCollection = serializedObject.FindProperty("spriteCollection");
			#else
			atlasAssets.isExpanded = true;
			#endif

			#if SPINE_BAKING
			isBakingExpanded = EditorPrefs.GetBool(ShowBakingPrefsKey, false);
			#endif

			m_skeletonDataAsset = (SkeletonDataAsset)target;
			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
			EditorApplication.update += EditorUpdate;
			m_skeletonData = m_skeletonDataAsset.GetSkeletonData(false);
			RepopulateWarnings();
		}
    /*
     */
    private void MakeSkeletonAndAnimationData()
    {
        if(sprites == null) {
            Debug.LogWarning("Sprite collection not set for skeleton data asset: " + name,this);
            return;
        }

        if(skeletonJSON == null) {
            Debug.LogWarning("Skeleton JSON file not set for skeleton data asset: " + name,this);
            return;
        }

        SkeletonJson json = new SkeletonJson(new tk2dSpineAttachmentLoader(sprites.spriteCollection));
        json.Scale = scale;

        try {
            skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
        } catch (Exception ex) {
            Debug.Log("Error reading skeleton JSON file for skeleton data asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace,this);
            return;
        }

        stateData = new AnimationStateData(skeletonData);
        for(int i = 0, n = fromAnimation.Length; i < n; i++) {
            if(fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue;
            stateData.SetMix(fromAnimation[i],toAnimation[i],duration[i]);
        }
    }
Esempio n. 9
0
		public Skeleton (SkeletonData data) {
			if (data == null) throw new ArgumentNullException("data cannot be null.");
			this.data = data;

			bones = new ExposedList<Bone>(data.bones.Count);
			foreach (BoneData boneData in data.bones) {
				Bone parent = boneData.parent == null ? null : bones.Items[data.bones.IndexOf(boneData.parent)];
				Bone bone = new Bone(boneData, this, parent);
				if (parent != null) parent.children.Add(bone);
				bones.Add(bone);
			}

			slots = new ExposedList<Slot>(data.slots.Count);
			drawOrder = new ExposedList<Slot>(data.slots.Count);
			foreach (SlotData slotData in data.slots) {
				Bone bone = bones.Items[data.bones.IndexOf(slotData.boneData)];
				Slot slot = new Slot(slotData, bone);
				slots.Add(slot);
				drawOrder.Add(slot);
			}

			ikConstraints = new ExposedList<IkConstraint>(data.ikConstraints.Count);
			foreach (IkConstraintData ikConstraintData in data.ikConstraints)
				ikConstraints.Add(new IkConstraint(ikConstraintData, this));

			transformConstraints = new ExposedList<TransformConstraint>(data.transformConstraints.Count);
			foreach (TransformConstraintData transformConstraintData in data.transformConstraints)
				transformConstraints.Add(new TransformConstraint(transformConstraintData, this));

			UpdateCache();
			UpdateWorldTransform();
		}
Esempio n. 10
0
    public static Spine.Attachment GetAttachment(string attachmentPath, Spine.SkeletonData skeletonData)
    {
        var hierarchy = SpineAttachment.GetHierarchy(attachmentPath);

        if (hierarchy.name == "")
        {
            return(null);
        }

        return(skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name));
    }
Esempio n. 11
0
 static int ToString(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         Spine.SkeletonData obj = (Spine.SkeletonData)ToLua.CheckObject <Spine.SkeletonData>(L, 1);
         string             o   = obj.ToString();
         LuaDLL.lua_pushstring(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Esempio n. 12
0
 static int FindPathConstraint(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         Spine.SkeletonData       obj  = (Spine.SkeletonData)ToLua.CheckObject <Spine.SkeletonData>(L, 1);
         string                   arg0 = ToLua.CheckString(L, 2);
         Spine.PathConstraintData o    = obj.FindPathConstraint(arg0);
         ToLua.PushObject(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Esempio n. 13
0
        protected override void LoadContent()
        {
            Effect spriteBatchEffect = Content.Load<Effect>("SpriteBatchEffect");
            spriteBatch = new SpriteBatchEx(GraphicsDevice, spriteBatchEffect);

            Bone.yDown = true;
            skeletonData = Content.Load<SkeletonData>("spineboy/spineboy");
            skeleton = new Skeleton(skeletonData);
            skeleton.SetSlotsToSetupPose();

            AnimationStateData stateData = new AnimationStateData(skeleton.Data);
            animationState = new AnimationState(stateData);
            animationState.SetAnimation(0, "walk", true);

            skeleton.UpdateWorldTransform();
        }
Esempio n. 14
0
 static int FindBoneIndex(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         Spine.SkeletonData obj  = (Spine.SkeletonData)ToLua.CheckObject <Spine.SkeletonData>(L, 1);
         string             arg0 = ToLua.CheckString(L, 2);
         int o = obj.FindBoneIndex(arg0);
         LuaDLL.lua_pushinteger(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Esempio n. 15
0
 static int GetSkeletonData(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         Spine.Unity.SkeletonDataAsset obj = (Spine.Unity.SkeletonDataAsset)ToLua.CheckObject <Spine.Unity.SkeletonDataAsset>(L, 1);
         bool arg0            = LuaDLL.luaL_checkboolean(L, 2);
         Spine.SkeletonData o = obj.GetSkeletonData(arg0);
         ToLua.PushObject(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Esempio n. 16
0
	public SkeletonData GetSkeletonData (bool quiet) {
		if (atlasAsset == null) {
			if (!quiet)
				Debug.LogError("Atlas not set for SkeletonData asset: " + name, this);
			Reset();
			return null;
		}

		// if (skeletonJSON == null) {
        if (string.IsNullOrEmpty(skeletonJsonStr)) {
			if (!quiet)
				Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this);
			Reset();
			return null;
		}

		Atlas atlas = atlasAsset.GetAtlas();
		if (atlas == null) {
			Reset();
			return null;
		}

		if (skeletonData != null)
			return skeletonData;

		SkeletonJson json = new SkeletonJson(atlas);
		json.Scale = scale;
		try {
            // skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
            skeletonData = json.ReadSkeletonData(new StringReader(skeletonJsonStr));
        }
        catch (Exception ex)
        {
			if (!quiet)
				Debug.LogError("Error reading skeleton JSON file for SkeletonData asset: " + name + "\n" + ex.Message + "\n" + ex.StackTrace, this);
			return null;
		}

		stateData = new AnimationStateData(skeletonData);
		stateData.DefaultMix = defaultMix;
		for (int i = 0, n = fromAnimation.Length; i < n; i++) {
			if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue;
			stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
		}

		return skeletonData;
	}
Esempio n. 17
0
    static int set_ImagesPath(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj  = (Spine.SkeletonData)o;
            string             arg0 = ToLua.CheckString(L, 2);
            obj.ImagesPath = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index ImagesPath on a nil value"));
        }
    }
Esempio n. 18
0
    static int get_Data(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.Skeleton     obj = (Spine.Skeleton)o;
            Spine.SkeletonData ret = obj.Data;
            ToLua.PushObject(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index Data on a nil value"));
        }
    }
Esempio n. 19
0
    void Init(GameObject inst)
    {
        anim = inst.GetComponent <SpineAnimation> ();

        Spine.SkeletonData data = anim.skeleton.skeleton.data;

        Spine.Animation up = data.FindAnimation("jump_up");

        Spine.Animation dn = data.FindAnimation("jump_down");

        jumpFlightTime = GetJumpLength(up);
        fallFlightTime = GetJumpLength(dn);

        //Subscribe to events
        anim.skeleton.state.Event    += HandleCustomEvent;
        anim.skeleton.state.Complete += OnJumpEnd;
    }
Esempio n. 20
0
    static int get_PathConstraints(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj = (Spine.SkeletonData)o;
            Spine.ExposedList <Spine.PathConstraintData> ret = obj.PathConstraints;
            ToLua.PushObject(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index PathConstraints on a nil value"));
        }
    }
Esempio n. 21
0
    static int get_ImagesPath(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj = (Spine.SkeletonData)o;
            string             ret = obj.ImagesPath;
            LuaDLL.lua_pushstring(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index ImagesPath on a nil value"));
        }
    }
Esempio n. 22
0
    static int get_Fps(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj = (Spine.SkeletonData)o;
            float ret = obj.Fps;
            LuaDLL.lua_pushnumber(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index Fps on a nil value"));
        }
    }
Esempio n. 23
0
    static int set_DefaultSkin(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj  = (Spine.SkeletonData)o;
            Spine.Skin         arg0 = (Spine.Skin)ToLua.CheckObject <Spine.Skin>(L, 2);
            obj.DefaultSkin = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index DefaultSkin on a nil value"));
        }
    }
Esempio n. 24
0
    static int set_PathConstraints(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj = (Spine.SkeletonData)o;
            Spine.ExposedList <Spine.PathConstraintData> arg0 = (Spine.ExposedList <Spine.PathConstraintData>)ToLua.CheckObject <Spine.ExposedList <Spine.PathConstraintData> >(L, 2);
            obj.PathConstraints = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index PathConstraints on a nil value"));
        }
    }
Esempio n. 25
0
    static int set_Fps(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            Spine.SkeletonData obj = (Spine.SkeletonData)o;
            float arg0             = (float)LuaDLL.luaL_checknumber(L, 2);
            obj.Fps = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index Fps on a nil value"));
        }
    }
Esempio n. 26
0
    public SkeletonData GetSkeletonData(bool quiet)
    {
        if (atlasAsset == null) {
            if (!quiet)
                Debug.LogWarning("Atlas not set for skeleton data asset: " + name, this);
            Clear();
            return null;
        }

        if (skeletonJSON == null) {
            if (!quiet)
                Debug.LogWarning("Skeleton JSON file not set for skeleton data asset: " + name, this);
            Clear();
            return null;
        }

        Atlas atlas = atlasAsset.GetAtlas();
        if (atlas == null) {
            Clear();
            return null;
        }

        if (skeletonData != null)
            return skeletonData;

        SkeletonJson json = new SkeletonJson(atlas);
        json.Scale = scale;
        try {
            skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
        } catch (Exception) {
            if (!quiet)
                Debug.LogException(new Exception("Error reading skeleton JSON file for skeleton data asset: " + name), this);
            return null;
        }

        stateData = new AnimationStateData(skeletonData);
        for (int i = 0, n = fromAnimation.Length; i < n; i++)
            stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);

        return skeletonData;
    }
Esempio n. 27
0
    static int _CreateSpine_SkeletonData(IntPtr L)
    {
        try
        {
            int count = LuaDLL.lua_gettop(L);

            if (count == 0)
            {
                Spine.SkeletonData obj = new Spine.SkeletonData();
                ToLua.PushObject(L, obj);
                return(1);
            }
            else
            {
                return(LuaDLL.luaL_throw(L, "invalid arguments to ctor method: Spine.SkeletonData.New"));
            }
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e));
        }
    }
	public SkeletonData GetSkeletonData (bool quiet) {
		if (spriteCollection == null) {
			if (!quiet)
				Debug.LogWarning("Sprite collection not set for skeleton data asset: " + name, this);
			Clear();
			return null;
		}

		if (skeletonJSON == null) {
			if (!quiet)
				Debug.LogWarning("Skeleton JSON file not set for skeleton data asset: " + name, this);
			Clear();
			return null;
		}

		if (skeletonData != null)
			return skeletonData;

		SkeletonJson json = new SkeletonJson(new SpriteCollectionAttachmentLoader(spriteCollection));
		json.Scale = 1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale;

		try {
			skeletonData = json.ReadSkeletonData(new StringReader(skeletonJSON.text));
		} catch (Exception ex) {
			Debug.Log("Error reading skeleton JSON file for skeleton data asset: " + name + "\n" +
				ex.Message + "\n" + ex.StackTrace, this);
			return null;
		}

		stateData = new AnimationStateData(skeletonData);
		for (int i = 0, n = fromAnimation.Length; i < n; i++) {
			if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
				continue;
			stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
		}

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

            SkeletonData skeletonData = new SkeletonData();

            var root = Json.Deserialize(reader) as Dictionary<String, Object>;
            if (root == null) throw new Exception("Invalid JSON.");

            // 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"]);
                }
                BoneData 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);
                skeletonData.AddBone(boneData);
            }

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

                    if (slotMap.ContainsKey("color")) {
                        String 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"];

                    skeletonData.AddSlot(slotData);
                }
            }

            // Skins.
            if (root.ContainsKey("skins")) {
                Dictionary<String, Object> skinMap = (Dictionary<String, Object>)root["skins"];
                foreach (KeyValuePair<String, Object> entry in skinMap) {
                    Skin 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, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value);
                            skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
                        }
                    }
                    skeletonData.AddSkin(skin);
                    if (skin.Name == "default")
                        skeletonData.DefaultSkin = skin;
                }
            }

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

            skeletonData.Bones.TrimExcess();
            skeletonData.Slots.TrimExcess();
            skeletonData.Skins.TrimExcess();
            skeletonData.Animations.TrimExcess();
            return skeletonData;
        }
 public CCSkeletonAnimation(SkeletonData skeletonData)
     : base(skeletonData,false)
 {
     this.initializer();
 }
		private void ReadAnimation (Dictionary<String, Object> map, String name, SkeletonData skeletonData) {
			var scale = this.Scale;
			var timelines = new ExposedList<Timeline>();
			float duration = 0;

			// Slot timelines.
			if (map.ContainsKey("slots")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
					String slotName = entry.Key;
					int slotIndex = skeletonData.FindSlotIndex(slotName);
					var timelineMap = (Dictionary<String, Object>)entry.Value;
					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						var timelineName = (String)timelineEntry.Key;
						if (timelineName == "color") {
							var timeline = new ColorTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								String c = (String)valueMap["color"];
								timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]);

						} else if (timelineName == "attachment") {
							var timeline = new AttachmentTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);

						} else
							throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
					}
				}
			}

			// Bone timelines.
			if (map.ContainsKey("bones")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
					String boneName = entry.Key;
					int boneIndex = skeletonData.FindBoneIndex(boneName);
					if (boneIndex == -1) throw new Exception("Bone not found: " + boneName);
					var timelineMap = (Dictionary<String, Object>)entry.Value;
					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						var timelineName = (String)timelineEntry.Key;
						if (timelineName == "rotate") {
							var timeline = new RotateTimeline(values.Count);
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]);
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * RotateTimeline.ENTRIES]);

						} else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") {
							TranslateTimeline timeline;
							float timelineScale = 1;
							if (timelineName == "scale")
								timeline = new ScaleTimeline(values.Count);
							else if (timelineName == "shear")
								timeline = new ShearTimeline(values.Count);
							else {
								timeline = new TranslateTimeline(values.Count);
								timelineScale = scale;
							}
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								float x = GetFloat(valueMap, "x", 0);
								float y = GetFloat(valueMap, "y", 0);
								timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale);
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TranslateTimeline.ENTRIES]);

						} else
							throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
					}
				}
			}

			// IK constraint timelines.
			if (map.ContainsKey("ik")) {
				foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["ik"]) {
					IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key);
					var values = (List<Object>)constraintMap.Value;
					var timeline = new IkConstraintTimeline(values.Count);
					timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint);
					int frameIndex = 0;
					foreach (Dictionary<String, Object> valueMap in values) {
						float time = (float)valueMap["time"];
						float mix = GetFloat(valueMap, "mix", 1);
						bool bendPositive = GetBoolean(valueMap, "bendPositive", true);
						timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1);
						ReadCurve(valueMap, timeline, frameIndex);
						frameIndex++;
					}
					timelines.Add(timeline);
					duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * IkConstraintTimeline.ENTRIES]);
				}
			}

			// Transform constraint timelines.
			if (map.ContainsKey("transform")) {
				foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["transform"]) {
					TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key);
					var values = (List<Object>)constraintMap.Value;
					var timeline = new TransformConstraintTimeline(values.Count);
					timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
					int frameIndex = 0;
					foreach (Dictionary<String, Object> valueMap in values) {
						float time = (float)valueMap["time"];
						float rotateMix = GetFloat(valueMap, "rotateMix", 1);
						float translateMix = GetFloat(valueMap, "translateMix", 1);
						float scaleMix = GetFloat(valueMap, "scaleMix", 1);
						float shearMix = GetFloat(valueMap, "shearMix", 1);
						timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix);
						ReadCurve(valueMap, timeline, frameIndex);
						frameIndex++;
					}
					timelines.Add(timeline);
					duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TransformConstraintTimeline.ENTRIES]);
				}
			}

			// Path constraint timelines.
			if (map.ContainsKey("paths")) {
				foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["paths"]) {
					int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
					if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
					PathConstraintData data = skeletonData.pathConstraints.Items[index];
					var timelineMap = (Dictionary<String, Object>)constraintMap.Value;
					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						var timelineName = (String)timelineEntry.Key;
						if (timelineName == "position" || timelineName == "spacing") {
							PathConstraintPositionTimeline timeline;
							float timelineScale = 1;
							if (timelineName == "spacing") {
								timeline = new PathConstraintSpacingTimeline(values.Count);
								if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale;
							}
							else {
								timeline = new PathConstraintPositionTimeline(values.Count);
								if (data.positionMode == PositionMode.Fixed) timelineScale = scale;
							}
							timeline.pathConstraintIndex = index;
							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale);
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
						}
						else if (timelineName == "mix") {
							PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count);
							timeline.pathConstraintIndex = index;
							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
						}
					}
				}
			}

			// Deform timelines.
			if (map.ContainsKey("deform")) {
				foreach (KeyValuePair<String, Object> deformMap in (Dictionary<String, Object>)map["deform"]) {
					Skin skin = skeletonData.FindSkin(deformMap.Key);
					foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)deformMap.Value) {
						int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
						if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key);
						foreach (KeyValuePair<String, Object> timelineMap in (Dictionary<String, Object>)slotMap.Value) {
							var values = (List<Object>)timelineMap.Value;
							VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
							if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key);
							bool weighted = attachment.bones != null;
							float[] vertices = attachment.vertices;
							int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length;

							var timeline = new DeformTimeline(values.Count);
							timeline.slotIndex = slotIndex;
							timeline.attachment = attachment;
							
							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float[] deform;
								if (!valueMap.ContainsKey("vertices")) {
									deform = weighted ? new float[deformLength] : vertices;
								} else {
									deform = new float[deformLength];
									int start = GetInt(valueMap, "offset", 0);
									float[] verticesValue = GetFloatArray(valueMap, "vertices", 1);
									Array.Copy(verticesValue, 0, deform, start, verticesValue.Length);
									if (scale != 1) {
										for (int i = start, n = i + verticesValue.Length; i < n; i++)
											deform[i] *= scale;
									}

									if (!weighted) {
										for (int i = 0; i < deformLength; i++)
											deform[i] += vertices[i];
									}
								}

								timeline.SetFrame(frameIndex, (float)valueMap["time"], deform);
								ReadCurve(valueMap, timeline, frameIndex);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
						}
					}
				}
			}

			// Draw order timeline.
			if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) {
				var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"];
				var timeline = new DrawOrderTimeline(values.Count);
				int slotCount = skeletonData.slots.Count;
				int frameIndex = 0;
				foreach (Dictionary<String, Object> drawOrderMap in values) {
					int[] drawOrder = null;
					if (drawOrderMap.ContainsKey("offsets")) {
						drawOrder = new int[slotCount];
						for (int i = slotCount - 1; i >= 0; i--)
							drawOrder[i] = -1;
						var offsets = (List<Object>)drawOrderMap["offsets"];
						int[] unchanged = new int[slotCount - offsets.Count];
						int originalIndex = 0, unchangedIndex = 0;
						foreach (Dictionary<String, Object> offsetMap in offsets) {
							int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
							if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
							// Collect unchanged items.
							while (originalIndex != slotIndex)
								unchanged[unchangedIndex++] = originalIndex++;
							// Set changed items.
							int index = originalIndex + (int)(float)offsetMap["offset"];
							drawOrder[index] = originalIndex++;
						}
						// Collect remaining unchanged items.
						while (originalIndex < slotCount)
							unchanged[unchangedIndex++] = originalIndex++;
						// Fill in unchanged items.
						for (int i = slotCount - 1; i >= 0; i--)
							if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
					}
					timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			// Event timeline.
			if (map.ContainsKey("events")) {
				var eventsMap = (List<Object>)map["events"];
				var timeline = new EventTimeline(eventsMap.Count);
				int frameIndex = 0;
				foreach (Dictionary<String, Object> eventMap in eventsMap) {
					EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
					var e = new Event((float)eventMap["time"], eventData);
					e.Int = GetInt(eventMap, "int", eventData.Int);
					e.Float = GetFloat(eventMap, "float", eventData.Float);
					e.String = GetString(eventMap, "string", eventData.String);
					timeline.SetFrame(frameIndex++, e);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			timelines.TrimExcess();
			skeletonData.animations.Add(new Animation(name, timelines, duration));
		}
Esempio n. 32
0
        public SkeletonData ReadSkeletonData(Stream input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input cannot be null.");
            }
            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 = ReadInt(input, true); i < n; i++)
            {
                String   name        = ReadString(input);
                BoneData parent      = null;
                int      parentIndex = ReadInt(input, true) - 1;
                if (parentIndex != -1)
                {
                    parent = skeletonData.bones.Items[parentIndex];
                }
                BoneData boneData = new BoneData(name, parent);
                boneData.x               = ReadFloat(input) * scale;
                boneData.y               = ReadFloat(input) * scale;
                boneData.scaleX          = ReadFloat(input);
                boneData.scaleY          = ReadFloat(input);
                boneData.rotation        = ReadFloat(input);
                boneData.length          = ReadFloat(input) * scale;
                boneData.inheritScale    = ReadBoolean(input);
                boneData.inheritRotation = ReadBoolean(input);
                if (nonessential)
                {
                    ReadInt(input);                               // Skip bone color.
                }
                skeletonData.bones.Add(boneData);
            }

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

            // Transform constraints.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                TransformConstraintData transformConstraintData = new TransformConstraintData(ReadString(input));
                transformConstraintData.bone         = skeletonData.bones.Items[ReadInt(input, true)];
                transformConstraintData.target       = skeletonData.bones.Items[ReadInt(input, true)];
                transformConstraintData.translateMix = ReadFloat(input);
                transformConstraintData.x            = ReadFloat(input) * scale;
                transformConstraintData.y            = ReadFloat(input) * scale;
                skeletonData.transformConstraints.Add(transformConstraintData);
            }

            // Slots.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                String   slotName = ReadString(input);
                BoneData boneData = skeletonData.bones.Items[ReadInt(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)ReadInt(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 = ReadInt(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 (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 = ReadInt(input, true); i < n; i++)
            {
                EventData eventData = new EventData(ReadString(input));
                eventData.Int    = ReadInt(input, false);
                eventData.Float  = ReadFloat(input);
                eventData.String = ReadString(input);
                skeletonData.events.Add(eventData);
            }

            // Animations.
            for (int i = 0, n = ReadInt(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);
        }
Esempio n. 33
0
        private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData)
        {
            var   timelines = new List <Timeline>();
            float duration  = 0;

            if (map.ContainsKey("bones"))
            {
                var bonesMap = (Dictionary <String, Object>)map["bones"];
                foreach (KeyValuePair <String, Object> entry in bonesMap)
                {
                    String boneName  = entry.Key;
                    int    boneIndex = skeletonData.FindBoneIndex(boneName);
                    if (boneIndex == -1)
                    {
                        throw new Exception("Bone not found: " + boneName);
                    }

                    var timelineMap = (Dictionary <String, Object>)entry.Value;
                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var    values       = (List <Object>)timelineEntry.Value;
                        String timelineName = (String)timelineEntry.Key;
                        if (timelineName.Equals(TIMELINE_ROTATE))
                        {
                            RotateTimeline timeline = new RotateTimeline(values.Count);
                            timeline.BoneIndex = boneIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 2 - 2]);
                        }
                        else if (timelineName.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE))
                        {
                            TranslateTimeline timeline;
                            float             timelineScale = 1;
                            if (timelineName.Equals(TIMELINE_SCALE))
                            {
                                timeline = new ScaleTimeline(values.Count);
                            }
                            else
                            {
                                timeline      = new TranslateTimeline(values.Count);
                                timelineScale = Scale;
                            }
                            timeline.BoneIndex = boneIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                float x    = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
                                float y    = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
                                timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 3 - 3]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
                        }
                    }
                }
            }

            if (map.ContainsKey("slots"))
            {
                var slotsMap = (Dictionary <String, Object>)map["slots"];
                foreach (KeyValuePair <String, Object> entry in slotsMap)
                {
                    String slotName    = entry.Key;
                    int    slotIndex   = skeletonData.FindSlotIndex(slotName);
                    var    timelineMap = (Dictionary <String, Object>)entry.Value;

                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var    values       = (List <Object>)timelineEntry.Value;
                        String timelineName = (String)timelineEntry.Key;
                        if (timelineName.Equals(TIMELINE_COLOR))
                        {
                            ColorTimeline timeline = new ColorTimeline(values.Count);
                            timeline.SlotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float  time = (float)valueMap["time"];
                                String c    = (String)valueMap["color"];
                                timeline.setFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 5 - 5]);
                        }
                        else if (timelineName.Equals(TIMELINE_ATTACHMENT))
                        {
                            AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
                            timeline.SlotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
                        }
                    }
                }
            }

            timelines.TrimExcess();
            skeletonData.AddAnimation(new Animation(name, timelines, duration));
        }
Esempio n. 34
0
		private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) {
			var timelines = new List<Timeline>();
			float duration = 0;

			if (map.ContainsKey("bones")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
					String boneName = entry.Key;
					int boneIndex = skeletonData.FindBoneIndex(boneName);
					if (boneIndex == -1)
						throw new Exception("Bone not found: " + boneName);

					var timelineMap = (Dictionary<String, Object>)entry.Value;
					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						String timelineName = (String)timelineEntry.Key;
						if (timelineName.Equals(TIMELINE_ROTATE)) {
							RotateTimeline timeline = new RotateTimeline(values.Count);
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);

						} else if (timelineName.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) {
							TranslateTimeline timeline;
							float timelineScale = 1;
							if (timelineName.Equals(TIMELINE_SCALE))
								timeline = new ScaleTimeline(values.Count);
							else {
								timeline = new TranslateTimeline(values.Count);
								timelineScale = Scale;
							}
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
								float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
								timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);

						} else
							throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
					}
				}
			}

			if (map.ContainsKey("slots")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
					String slotName = entry.Key;
					int slotIndex = skeletonData.FindSlotIndex(slotName);
					var timelineMap = (Dictionary<String, Object>)entry.Value;

					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						String timelineName = (String)timelineEntry.Key;
						if (timelineName.Equals(TIMELINE_COLOR)) {
							ColorTimeline timeline = new ColorTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								String c = (String)valueMap["color"];
								timeline.setFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);

						} else if (timelineName.Equals(TIMELINE_ATTACHMENT)) {
							AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);

						} else
							throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
					}
				}
			}

			if (map.ContainsKey("events")) {
				var eventsMap = (List<Object>)map["events"];
				EventTimeline timeline = new EventTimeline(eventsMap.Count);
				int frameIndex = 0;
				foreach (Dictionary<String, Object> eventMap in eventsMap) {
					EventData eventData = skeletonData.findEvent((String)eventMap["name"]);
					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
					Event e = new Event(eventData);
					e.Int = GetInt(eventMap, "int", eventData.Int);
					e.Float = GetFloat(eventMap, "float", eventData.Float);
					e.String = GetString(eventMap, "string", eventData.String);
					timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			if (map.ContainsKey("draworder")) {
				var values = (List<Object>)map["draworder"];
				DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count);
				int slotCount = skeletonData.slots.Count;
				int frameIndex = 0;
				foreach (Dictionary<String, Object> drawOrderMap in values) {
					int[] drawOrder = null;
					if (drawOrderMap.ContainsKey("offsets")) {
						drawOrder = new int[slotCount];
						for (int i = slotCount - 1; i >= 0; i--)
							drawOrder[i] = -1;
						List<Object> offsets = (List<Object>)drawOrderMap["offsets"];
						int[] unchanged = new int[slotCount - offsets.Count];
						int originalIndex = 0, unchangedIndex = 0;
						foreach (Dictionary<String, Object> offsetMap in offsets) {
							int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
							if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
							// Collect unchanged items.
							while (originalIndex != slotIndex)
								unchanged[unchangedIndex++] = originalIndex++;
							// Set changed items.
							drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = originalIndex++;
						}
						// Collect remaining unchanged items.
						while (originalIndex < slotCount)
							unchanged[unchangedIndex++] = originalIndex++;
						// Fill in unchanged items.
						for (int i = slotCount - 1; i >= 0; i--)
							if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
					}
					timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			timelines.TrimExcess();
			skeletonData.AddAnimation(new Animation(name, timelines, duration));
		}
Esempio n. 35
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 = ReadInt(input, true); i < n; i++) {
				int slotIndex = ReadInt(input, true);
				for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
					int timelineType = input.ReadByte();
					int frameCount = ReadInt(input, true);
					switch (timelineType) {
					case TIMELINE_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[frameCount * 5 - 5]);
						break;
					}
					case TIMELINE_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;
					}
					}
				}
			}

			// Bone timelines.
			for (int i = 0, n = ReadInt(input, true); i < n; i++) {
				int boneIndex = ReadInt(input, true);
				for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
					int timelineType = input.ReadByte();
					int frameCount = ReadInt(input, true);
					switch (timelineType) {
					case TIMELINE_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 * 2 - 2]);
						break;
					}
					case TIMELINE_TRANSLATE:
					case TIMELINE_SCALE: {
						TranslateTimeline timeline;
						float timelineScale = 1;
						if (timelineType == TIMELINE_SCALE)
							timeline = new ScaleTimeline(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 * 3 - 3]);
						break;
					}
					case TIMELINE_FLIPX:
					case TIMELINE_FLIPY: {
						FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline(
							frameCount);
						timeline.boneIndex = boneIndex;
						for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
							timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input));
						timelines.Add(timeline);
						duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]);
						break;
					}
					}
				}
			}

			// IK timelines.
			for (int i = 0, n = ReadInt(input, true); i < n; i++) {
				IkConstraintData ikConstraint = skeletonData.ikConstraints.Items[ReadInt(input, true)];
				int frameCount = ReadInt(input, true);
				IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
				timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint);
				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 * 3 - 3]);
			}

			// FFD timelines.
			for (int i = 0, n = ReadInt(input, true); i < n; i++) {
				Skin skin = skeletonData.skins.Items[ReadInt(input, true)];
				for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
					int slotIndex = ReadInt(input, true);
					for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++) {
						Attachment attachment = skin.GetAttachment(slotIndex, ReadString(input));
						int frameCount = ReadInt(input, true);
						FFDTimeline timeline = new FFDTimeline(frameCount);
						timeline.slotIndex = slotIndex;
						timeline.attachment = attachment;
						for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
							float time = ReadFloat(input);

							float[] vertices;
							int vertexCount;
							if (attachment is MeshAttachment)
								vertexCount = ((MeshAttachment)attachment).vertices.Length;
							else
								vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2;

							int end = ReadInt(input, true);
							if (end == 0) {
								if (attachment is MeshAttachment)
									vertices = ((MeshAttachment)attachment).vertices;
								else
									vertices = new float[vertexCount];
							} else {
								vertices = new float[vertexCount];
								int start = ReadInt(input, true);
								end += start;
								if (scale == 1) {
									for (int v = start; v < end; v++)
										vertices[v] = ReadFloat(input);
								} else {
									for (int v = start; v < end; v++)
										vertices[v] = ReadFloat(input) * scale;
								}
								if (attachment is MeshAttachment) {
									float[] meshVertices = ((MeshAttachment)attachment).vertices;
									for (int v = 0, vn = vertices.Length; v < vn; v++)
										vertices[v] += meshVertices[v];
								}
							}

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

			// Draw order timeline.
			int drawOrderCount = ReadInt(input, true);
			if (drawOrderCount > 0) {
				DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
				int slotCount = skeletonData.slots.Count;
				for (int i = 0; i < drawOrderCount; i++) {
					int offsetCount = ReadInt(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 = ReadInt(input, true);
						// Collect unchanged items.
						while (originalIndex != slotIndex)
							unchanged[unchangedIndex++] = originalIndex++;
						// Set changed items.
						drawOrder[originalIndex + ReadInt(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, ReadFloat(input), drawOrder);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]);
			}

			// Event timeline.
			int eventCount = ReadInt(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[ReadInt(input, true)];
					Event e = new Event(eventData);
					e.Int = ReadInt(input, false);
					e.Float = ReadFloat(input);
					e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
					timeline.SetFrame(i, time, e);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[eventCount - 1]);
			}

			timelines.TrimExcess();
			skeletonData.animations.Add(new Animation(name, timelines, duration));
		}
Esempio n. 36
0
 public AnimationStateData(SkeletonData skeletonData)
 {
     this.skeletonData = skeletonData;
 }
Esempio n. 37
0
        public SkeletonData ReadSkeletonData(Stream input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input cannot be null.");
            }
            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 = ReadInt(input, true); i < n; i++)
            {
                String   name        = ReadString(input);
                BoneData parent      = null;
                int      parentIndex = ReadInt(input, true) - 1;
                if (parentIndex != -1)
                {
                    parent = skeletonData.bones[parentIndex];
                }
                BoneData boneData = new BoneData(name, parent);
                boneData.x               = ReadFloat(input) * scale;
                boneData.y               = ReadFloat(input) * scale;
                boneData.scaleX          = ReadFloat(input);
                boneData.scaleY          = ReadFloat(input);
                boneData.rotation        = ReadFloat(input);
                boneData.length          = ReadFloat(input) * scale;
                boneData.flipX           = ReadBoolean(input);
                boneData.flipY           = ReadBoolean(input);
                boneData.inheritScale    = ReadBoolean(input);
                boneData.inheritRotation = ReadBoolean(input);
                if (nonessential)
                {
                    ReadInt(input);                               // Skip bone color.
                }
                skeletonData.bones.Add(boneData);
            }

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

            // Slots.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                String   slotName = ReadString(input);
                BoneData boneData = skeletonData.bones[ReadInt(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.additiveBlending = ReadBoolean(input);
                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 = ReadInt(input, true); i < n; i++)
            {
                skeletonData.skins.Add(ReadSkin(input, ReadString(input), nonessential));
            }

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

            // Animations.
            for (int i = 0, n = ReadInt(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);
        }
Esempio n. 38
0
        private void ReadAnimation(String name, Stream input, SkeletonData skeletonData)
        {
            var   timelines = new List <Timeline>();
            float scale     = Scale;
            float duration  = 0;

            // Slot timelines.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                int slotIndex = ReadInt(input, true);
                for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++)
                {
                    int timelineType = input.ReadByte();
                    int frameCount   = ReadInt(input, true);
                    switch (timelineType)
                    {
                    case TIMELINE_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[frameCount * 5 - 5]);
                        break;
                    }

                    case TIMELINE_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;
                    }
                    }
                }
            }

            // Bone timelines.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                int boneIndex = ReadInt(input, true);
                for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++)
                {
                    int timelineType = input.ReadByte();
                    int frameCount   = ReadInt(input, true);
                    switch (timelineType)
                    {
                    case TIMELINE_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 * 2 - 2]);
                        break;
                    }

                    case TIMELINE_TRANSLATE:
                    case TIMELINE_SCALE: {
                        TranslateTimeline timeline;
                        float             timelineScale = 1;
                        if (timelineType == TIMELINE_SCALE)
                        {
                            timeline = new ScaleTimeline(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 * 3 - 3]);
                        break;
                    }

                    case TIMELINE_FLIPX:
                    case TIMELINE_FLIPY: {
                        FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline(
                            frameCount);
                        timeline.boneIndex = boneIndex;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input));
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]);
                        break;
                    }
                    }
                }
            }

            // IK timelines.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                IkConstraintData ikConstraint = skeletonData.ikConstraints[ReadInt(input, true)];
                int frameCount = ReadInt(input, true);
                IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
                timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint);
                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 * 3 - 3]);
            }

            // FFD timelines.
            for (int i = 0, n = ReadInt(input, true); i < n; i++)
            {
                Skin skin = skeletonData.skins[ReadInt(input, true)];
                for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++)
                {
                    int slotIndex = ReadInt(input, true);
                    for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++)
                    {
                        Attachment  attachment = skin.GetAttachment(slotIndex, ReadString(input));
                        int         frameCount = ReadInt(input, true);
                        FFDTimeline timeline   = new FFDTimeline(frameCount);
                        timeline.slotIndex  = slotIndex;
                        timeline.attachment = attachment;
                        for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                        {
                            float time = ReadFloat(input);

                            float[] vertices;
                            int     vertexCount;
                            if (attachment is MeshAttachment)
                            {
                                vertexCount = ((MeshAttachment)attachment).vertices.Length;
                            }
                            else
                            {
                                vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2;
                            }

                            int end = ReadInt(input, true);
                            if (end == 0)
                            {
                                if (attachment is MeshAttachment)
                                {
                                    vertices = ((MeshAttachment)attachment).vertices;
                                }
                                else
                                {
                                    vertices = new float[vertexCount];
                                }
                            }
                            else
                            {
                                vertices = new float[vertexCount];
                                int start = ReadInt(input, true);
                                end += start;
                                if (scale == 1)
                                {
                                    for (int v = start; v < end; v++)
                                    {
                                        vertices[v] = ReadFloat(input);
                                    }
                                }
                                else
                                {
                                    for (int v = start; v < end; v++)
                                    {
                                        vertices[v] = ReadFloat(input) * scale;
                                    }
                                }
                                if (attachment is MeshAttachment)
                                {
                                    float[] meshVertices = ((MeshAttachment)attachment).vertices;
                                    for (int v = 0, vn = vertices.Length; v < vn; v++)
                                    {
                                        vertices[v] += meshVertices[v];
                                    }
                                }
                            }

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

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

            if (drawOrderCount > 0)
            {
                DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
                int slotCount = skeletonData.slots.Count;
                for (int i = 0; i < drawOrderCount; i++)
                {
                    int   offsetCount = ReadInt(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 = ReadInt(input, true);
                        // Collect unchanged items.
                        while (originalIndex != slotIndex)
                        {
                            unchanged[unchangedIndex++] = originalIndex++;
                        }
                        // Set changed items.
                        drawOrder[originalIndex + ReadInt(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, ReadFloat(input), drawOrder);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]);
            }

            // Event timeline.
            int eventCount = ReadInt(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[ReadInt(input, true)];
                    Event     e         = new Event(eventData);
                    e.Int    = ReadInt(input, false);
                    e.Float  = ReadFloat(input);
                    e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
                    timeline.SetFrame(i, time, e);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[eventCount - 1]);
            }

            timelines.TrimExcess();
            skeletonData.animations.Add(new Animation(name, timelines, duration));
        }
Esempio n. 39
0
        private void ReadAnimation(IDictionary <String, Object> map, String name, SkeletonData skeletonData)
        {
            var   scale     = this.Scale;
            var   timelines = new ExposedList <Timeline>();
            float duration  = 0;

            // Slot timelines.
            if (map.ContainsKey("slots"))
            {
                foreach (KeyValuePair <String, Object> entry in (IDictionary <String, Object>)map["slots"])
                {
                    String slotName    = entry.Key;
                    int    slotIndex   = skeletonData.FindSlotIndex(slotName);
                    var    timelineMap = (IDictionary <String, Object>)entry.Value;
                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var values       = (IList <Object>)timelineEntry.Value;
                        var timelineName = (String)timelineEntry.Key;
                        if (timelineName == "color")
                        {
                            var timeline = new ColorTimeline(values.Count);
                            timeline.slotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                float  time = (float)valueMap["time"];
                                String c    = (String)valueMap["color"];
                                timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1] * ColorTimeline.ENTRIES);
                        }
                        else if (timelineName == "attachment")
                        {
                            var timeline = new AttachmentTimeline(values.Count);
                            timeline.slotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
                        }
                    }
                }
            }

            // Bone timelines.
            if (map.ContainsKey("bones"))
            {
                foreach (KeyValuePair <String, Object> entry in (IDictionary <String, Object>)map["bones"])
                {
                    String boneName  = entry.Key;
                    int    boneIndex = skeletonData.FindBoneIndex(boneName);
                    if (boneIndex == -1)
                    {
                        throw new Exception("Bone not found: " + boneName);
                    }
                    var timelineMap = (IDictionary <String, Object>)entry.Value;
                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var values       = (IList <Object>)timelineEntry.Value;
                        var timelineName = (String)timelineEntry.Key;
                        if (timelineName == "rotate")
                        {
                            var timeline = new RotateTimeline(values.Count);
                            timeline.boneIndex = boneIndex;
                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]);
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * RotateTimeline.ENTRIES]);
                        }
                        else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear")
                        {
                            TranslateTimeline timeline;
                            float             timelineScale = 1;
                            if (timelineName == "scale")
                            {
                                timeline = new ScaleTimeline(values.Count);
                            }
                            else if (timelineName == "shear")
                            {
                                timeline = new ShearTimeline(values.Count);
                            }
                            else
                            {
                                timeline      = new TranslateTimeline(values.Count);
                                timelineScale = scale;
                            }
                            timeline.boneIndex = boneIndex;

                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                float x    = GetFloat(valueMap, "x", 0);
                                float y    = GetFloat(valueMap, "y", 0);
                                timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale);
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TranslateTimeline.ENTRIES]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
                        }
                    }
                }
            }

            // IK constraint timelines.
            if (map.ContainsKey("ik"))
            {
                foreach (KeyValuePair <String, Object> constraintMap in (IDictionary <String, Object>)map["ik"])
                {
                    IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key);
                    var values   = (IList <Object>)constraintMap.Value;
                    var timeline = new IkConstraintTimeline(values.Count);
                    timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint);
                    int frameIndex = 0;
                    foreach (IDictionary <String, Object> valueMap in values)
                    {
                        float time         = (float)valueMap["time"];
                        float mix          = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1;
                        bool  bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true;
                        timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1);
                        ReadCurve(valueMap, timeline, frameIndex);
                        frameIndex++;
                    }
                    timelines.Add(timeline);
                    duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * IkConstraintTimeline.ENTRIES]);
                }
            }

            // Transform constraint timelines.
            if (map.ContainsKey("transform"))
            {
                foreach (KeyValuePair <String, Object> constraintMap in (IDictionary <String, Object>)map["transform"])
                {
                    TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key);
                    var values   = (IList <Object>)constraintMap.Value;
                    var timeline = new TransformConstraintTimeline(values.Count);
                    timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
                    int frameIndex = 0;
                    foreach (IDictionary <String, Object> valueMap in values)
                    {
                        float time         = (float)valueMap["time"];
                        float rotateMix    = GetFloat(valueMap, "rotateMix", 1);
                        float translateMix = GetFloat(valueMap, "translateMix", 1);
                        float scaleMix     = GetFloat(valueMap, "scaleMix", 1);
                        float shearMix     = GetFloat(valueMap, "shearMix", 1);
                        timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix);
                        ReadCurve(valueMap, timeline, frameIndex);
                        frameIndex++;
                    }
                    timelines.Add(timeline);
                    duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TransformConstraintTimeline.ENTRIES]);
                }
            }

            // Path constraint timelines.
            if (map.ContainsKey("paths"))
            {
                foreach (KeyValuePair <String, Object> constraintMap in (IDictionary <String, Object>)map["paths"])
                {
                    int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
                    if (index == -1)
                    {
                        throw new Exception("Path constraint not found: " + constraintMap.Key);
                    }
                    PathConstraintData data = skeletonData.pathConstraints.Items[index];
                    var timelineMap         = (IDictionary <String, Object>)constraintMap.Value;
                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var values       = (IList <Object>)timelineEntry.Value;
                        var timelineName = (String)timelineEntry.Key;
                        if (timelineName == "position" || timelineName == "spacing")
                        {
                            PathConstraintPositionTimeline timeline;
                            float timelineScale = 1;
                            if (timelineName == "spacing")
                            {
                                timeline = new PathConstraintSpacingTimeline(values.Count);
                                if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)
                                {
                                    timelineScale = scale;
                                }
                            }
                            else
                            {
                                timeline = new PathConstraintPositionTimeline(values.Count);
                                if (data.positionMode == PositionMode.Fixed)
                                {
                                    timelineScale = scale;
                                }
                            }
                            timeline.pathConstraintIndex = index;
                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale);
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
                        }
                        else if (timelineName == "mix")
                        {
                            PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count);
                            timeline.pathConstraintIndex = index;
                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
                        }
                    }
                }
            }

            // Deform timelines.
            if (map.ContainsKey("deform"))
            {
                foreach (KeyValuePair <String, Object> deformMap in (IDictionary <String, Object>)map["deform"])
                {
                    Skin skin = skeletonData.FindSkin(deformMap.Key);
                    foreach (KeyValuePair <String, Object> slotMap in (IDictionary <String, Object>)deformMap.Value)
                    {
                        int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
                        if (slotIndex == -1)
                        {
                            throw new Exception("Slot not found: " + slotMap.Key);
                        }
                        foreach (KeyValuePair <String, Object> timelineMap in (IDictionary <String, Object>)slotMap.Value)
                        {
                            var values = (IList <Object>)timelineMap.Value;
                            VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
                            if (attachment == null)
                            {
                                throw new Exception("Deform attachment not found: " + timelineMap.Key);
                            }
                            bool    weighted     = attachment.bones != null;
                            float[] vertices     = attachment.vertices;
                            int     deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length;

                            var timeline = new DeformTimeline(values.Count);
                            timeline.slotIndex  = slotIndex;
                            timeline.attachment = attachment;

                            int frameIndex = 0;
                            foreach (IDictionary <String, Object> valueMap in values)
                            {
                                float[] deform;
                                if (!valueMap.ContainsKey("vertices"))
                                {
                                    deform = weighted ? new float[deformLength] : vertices;
                                }
                                else
                                {
                                    deform = new float[deformLength];
                                    int     start         = GetInt(valueMap, "offset", 0);
                                    float[] verticesValue = GetFloatArray(valueMap, "vertices", 1);
                                    Array.Copy(verticesValue, 0, deform, start, verticesValue.Length);
                                    if (scale != 1)
                                    {
                                        for (int i = start, n = i + verticesValue.Length; i < n; i++)
                                        {
                                            deform[i] *= scale;
                                        }
                                    }

                                    if (!weighted)
                                    {
                                        for (int i = 0; i < deformLength; i++)
                                        {
                                            deform[i] += vertices[i];
                                        }
                                    }
                                }

                                timeline.SetFrame(frameIndex, (float)valueMap["time"], deform);
                                ReadCurve(valueMap, timeline, frameIndex);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
                        }
                    }
                }
            }

            // Draw order timeline.
            if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder"))
            {
                var values     = (IList <Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"];
                var timeline   = new DrawOrderTimeline(values.Count);
                int slotCount  = skeletonData.slots.Count;
                int frameIndex = 0;
                foreach (IDictionary <String, Object> drawOrderMap in values)
                {
                    int[] drawOrder = null;
                    if (drawOrderMap.ContainsKey("offsets"))
                    {
                        drawOrder = new int[slotCount];
                        for (int i = slotCount - 1; i >= 0; i--)
                        {
                            drawOrder[i] = -1;
                        }
                        var   offsets = (IList <Object>)drawOrderMap["offsets"];
                        int[] unchanged = new int[slotCount - offsets.Count];
                        int   originalIndex = 0, unchangedIndex = 0;
                        foreach (IDictionary <String, Object> offsetMap in offsets)
                        {
                            int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
                            if (slotIndex == -1)
                            {
                                throw new Exception("Slot not found: " + offsetMap["slot"]);
                            }
                            // Collect unchanged items.
                            while (originalIndex != slotIndex)
                            {
                                unchanged[unchangedIndex++] = originalIndex++;
                            }
                            // Set changed items.
                            int index = originalIndex + (int)(float)offsetMap["offset"];
                            drawOrder[index] = originalIndex++;
                        }
                        // Collect remaining unchanged items.
                        while (originalIndex < slotCount)
                        {
                            unchanged[unchangedIndex++] = originalIndex++;
                        }
                        // Fill in unchanged items.
                        for (int i = slotCount - 1; i >= 0; i--)
                        {
                            if (drawOrder[i] == -1)
                            {
                                drawOrder[i] = unchanged[--unchangedIndex];
                            }
                        }
                    }
                    timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
            }

            // Event timeline.
            if (map.ContainsKey("events"))
            {
                var eventsMap  = (IList <Object>)map["events"];
                var timeline   = new EventTimeline(eventsMap.Count);
                int frameIndex = 0;
                foreach (IDictionary <String, Object> eventMap in eventsMap)
                {
                    EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
                    if (eventData == null)
                    {
                        throw new Exception("Event not found: " + eventMap["name"]);
                    }
                    var e = new Event((float)eventMap["time"], eventData);
                    e.Int    = GetInt(eventMap, "int", eventData.Int);
                    e.Float  = GetFloat(eventMap, "float", eventData.Float);
                    e.String = GetString(eventMap, "string", eventData.String);
                    timeline.SetFrame(frameIndex++, e);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
            }

            timelines.TrimExcess();
            skeletonData.animations.Add(new Animation(name, timelines, duration));
        }
        /// <summary><see cref="Spine.Skin.FindAttachmentsForSlot(int,List)"/></summary>
        public static void FindAttachmentsForSlot(this Skin skin, string slotName, SkeletonData skeletonData, List <Attachment> results)
        {
            int slotIndex = skeletonData.FindSlotIndex(slotName);

            skin.FindAttachmentsForSlot(slotIndex, results);
        }
Esempio n. 41
0
        public SkeletonData ReadSkeletonData(Stream input, Atlas[] atlasArray = null)
        {
            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);
            }
            if (atlasArray != null)
            {
                                #if TJ_SPINE_TOOL
                skeletonData.changeSlotSort(atlasArray);
                                #endif
            }

            // 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);
        }
Esempio n. 42
0
		public SkeletonData ReadSkeletonData (TextReader reader) {
			if (reader == null) throw new ArgumentNullException("reader cannot be null.");

			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.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["ik"]) {
					TransformConstraintData transformConstraintData = new TransformConstraintData((String)transformMap["name"]);

					String boneName = (String)transformMap["bone"];
					transformConstraintData.target = skeletonData.FindBone(boneName);
					if (transformConstraintData.target == 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.translateMix = GetFloat(transformMap, "mix", 1);
					transformConstraintData.x = GetFloat(transformMap, "x", 0);
					transformConstraintData.y = GetFloat(transformMap, "y", 0);

					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, 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;
				}
			}

			// 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. 43
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);
        }
 public void Reset()
 {
     skeletonData = null;
     stateData = null;
 }
Esempio n. 45
0
		public SkeletonData ReadSkeletonData (Stream input) {
			if (input == null) throw new ArgumentNullException("input cannot be null.");
			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 = ReadInt(input, true); i < n; i++) {
				String name = ReadString(input);
				BoneData parent = null;
				int parentIndex = ReadInt(input, true) - 1;
				if (parentIndex != -1) parent = skeletonData.bones.Items[parentIndex];
				BoneData boneData = new BoneData(name, parent);
				boneData.x = ReadFloat(input) * scale;
				boneData.y = ReadFloat(input) * scale;
				boneData.scaleX = ReadFloat(input);
				boneData.scaleY = ReadFloat(input);
				boneData.rotation = ReadFloat(input);
				boneData.length = ReadFloat(input) * scale;
				boneData.flipX = ReadBoolean(input);
				boneData.flipY = ReadBoolean(input);
				boneData.inheritScale = ReadBoolean(input);
				boneData.inheritRotation = ReadBoolean(input);
				if (nonessential) ReadInt(input); // Skip bone color.
				skeletonData.bones.Add(boneData);
			}

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

			// Slots.
			for (int i = 0, n = ReadInt(input, true); i < n; i++) {
				String slotName = ReadString(input);
				BoneData boneData = skeletonData.bones.Items[ReadInt(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)ReadInt(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 = ReadInt(input, true); i < n; i++)
				skeletonData.skins.Add(ReadSkin(input, ReadString(input), nonessential));

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

			// Animations.
			for (int i = 0, n = ReadInt(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;
		}
Esempio n. 46
0
		public AnimationStateData (SkeletonData skeletonData) {
			this.skeletonData = skeletonData;
		}
Esempio n. 47
0
		public SkeletonData ReadSkeletonData (TextReader reader) {
			if (reader == null) throw new ArgumentNullException("reader cannot be null.");

			SkeletonData skeletonData = new SkeletonData();

			var root = Json.Deserialize(reader) as Dictionary<String, Object>;
			if (root == null) throw new Exception("Invalid JSON.");

			// 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"]);
				}
				BoneData 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.inheritScale = GetBoolean(boneMap, "inheritScale", true);
				boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
				skeletonData.AddBone(boneData);
			}

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

					if (slotMap.ContainsKey("color")) {
						String 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("additive"))
						slotData.additiveBlending = (bool)slotMap["additive"];

					skeletonData.AddSlot(slotData);
				}
			}

			// Skins.
			if (root.ContainsKey("skins")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) {
					Skin 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, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value);
							if (attachment != null) skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
						}
					}
					skeletonData.AddSkin(skin);
					if (skin.name == "default")
						skeletonData.defaultSkin = skin;
				}
			}

			// Events.
			if (root.ContainsKey("events")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
					var entryMap = (Dictionary<String, Object>)entry.Value;
					EventData eventData = new EventData(entry.Key);
					eventData.Int = GetInt(entryMap, "int", 0);
					eventData.Float = GetFloat(entryMap, "float", 0);
					eventData.String = GetString(entryMap, "string", null);
					skeletonData.AddEvent(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.animations.TrimExcess();
			return skeletonData;
		}
Esempio n. 48
0
        public SkeletonData ReadSkeletonData(TextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader cannot be null.");
            }

            var skeletonData = new SkeletonData();

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

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

            // 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.inheritScale    = GetBoolean(boneMap, "inheritScale", true);
                boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
                skeletonData.AddBone(boneData);
            }

            // 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("additive"))
                    {
                        slotData.additiveBlending = (bool)slotMap["additive"];
                    }

                    skeletonData.AddSlot(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, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value);
                            if (attachment != null)
                            {
                                skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
                            }
                        }
                    }
                    skeletonData.AddSkin(skin);
                    if (skin.name == "default")
                    {
                        skeletonData.defaultSkin = skin;
                    }
                }
            }

            // 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.AddEvent(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.animations.TrimExcess();
            return(skeletonData);
        }
Esempio n. 49
0
        private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData)
        {
            var   timelines = new List <Timeline>();
            float duration  = 0;
            float scale     = Scale;

            if (map.ContainsKey("bones"))
            {
                foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["bones"])
                {
                    String boneName  = entry.Key;
                    int    boneIndex = skeletonData.FindBoneIndex(boneName);
                    if (boneIndex == -1)
                    {
                        throw new Exception("Bone not found: " + boneName);
                    }

                    var timelineMap = (Dictionary <String, Object>)entry.Value;
                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var values       = (List <Object>)timelineEntry.Value;
                        var timelineName = (String)timelineEntry.Key;
                        if (timelineName.Equals("rotate"))
                        {
                            var timeline = new RotateTimeline(values.Count);
                            timeline.boneIndex = boneIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);
                        }
                        else if (timelineName.Equals("translate") || timelineName.Equals("scale"))
                        {
                            TranslateTimeline timeline;
                            float             timelineScale = 1;
                            if (timelineName.Equals("scale"))
                            {
                                timeline = new ScaleTimeline(values.Count);
                            }
                            else
                            {
                                timeline      = new TranslateTimeline(values.Count);
                                timelineScale = scale;
                            }
                            timeline.boneIndex = boneIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                float x    = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
                                float y    = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
                                timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
                        }
                    }
                }
            }

            if (map.ContainsKey("slots"))
            {
                foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["slots"])
                {
                    String slotName    = entry.Key;
                    int    slotIndex   = skeletonData.FindSlotIndex(slotName);
                    var    timelineMap = (Dictionary <String, Object>)entry.Value;

                    foreach (KeyValuePair <String, Object> timelineEntry in timelineMap)
                    {
                        var values       = (List <Object>)timelineEntry.Value;
                        var timelineName = (String)timelineEntry.Key;
                        if (timelineName.Equals("color"))
                        {
                            var timeline = new ColorTimeline(values.Count);
                            timeline.slotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float  time = (float)valueMap["time"];
                                String c    = (String)valueMap["color"];
                                timeline.setFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);
                        }
                        else if (timelineName.Equals("attachment"))
                        {
                            var timeline = new AttachmentTimeline(values.Count);
                            timeline.slotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float time = (float)valueMap["time"];
                                timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
                        }
                        else
                        {
                            throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
                        }
                    }
                }
            }

            if (map.ContainsKey("ffd"))
            {
                foreach (KeyValuePair <String, Object> ffdMap in (Dictionary <String, Object>)map["ffd"])
                {
                    Skin skin = skeletonData.FindSkin(ffdMap.Key);
                    foreach (KeyValuePair <String, Object> slotMap in (Dictionary <String, Object>)ffdMap.Value)
                    {
                        int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
                        foreach (KeyValuePair <String, Object> meshMap in (Dictionary <String, Object>)slotMap.Value)
                        {
                            var        values     = (List <Object>)meshMap.Value;
                            var        timeline   = new FFDTimeline(values.Count);
                            Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key);
                            if (attachment == null)
                            {
                                throw new Exception("FFD attachment not found: " + meshMap.Key);
                            }
                            timeline.slotIndex  = slotIndex;
                            timeline.attachment = attachment;

                            int frameIndex = 0;
                            foreach (Dictionary <String, Object> valueMap in values)
                            {
                                float[] vertices;
                                int     vertexCount;
                                if (attachment is MeshAttachment)
                                {
                                    vertexCount = ((MeshAttachment)attachment).vertices.Length;
                                }
                                // BOZO
                                else
                                {
                                    vertexCount = 0;
                                }
                                // else
                                //	vertexCount = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2;

                                if (!valueMap.ContainsKey("vertices"))
                                {
                                    if (attachment is MeshAttachment)
                                    {
                                        vertices = ((MeshAttachment)attachment).vertices;
                                    }
                                    else
                                    {
                                        vertices = new float[vertexCount];
                                    }
                                }
                                else
                                {
                                    var verticesValue = (List <Object>)valueMap["vertices"];
                                    vertices = new float[vertexCount];
                                    int start = GetInt(valueMap, "offset", 0);
                                    if (scale == 1)
                                    {
                                        for (int i = 0, n = verticesValue.Count; i < n; i++)
                                        {
                                            vertices[i + start] = (float)verticesValue[i];
                                        }
                                    }
                                    else
                                    {
                                        for (int i = 0, n = verticesValue.Count; i < n; i++)
                                        {
                                            vertices[i + start] = (float)verticesValue[i] * scale;
                                        }
                                    }
                                    if (attachment is MeshAttachment)
                                    {
                                        float[] meshVertices = ((MeshAttachment)attachment).vertices;
                                        for (int i = 0, n = vertices.Length; i < n; i++)
                                        {
                                            vertices[i] += meshVertices[i];
                                        }
                                    }
                                }

                                timeline.setFrame(frameIndex, (float)valueMap["time"], vertices);
                                ReadCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
                        }
                    }
                }
            }

            if (map.ContainsKey("draworder"))
            {
                var values     = (List <Object>)map["draworder"];
                var timeline   = new DrawOrderTimeline(values.Count);
                int slotCount  = skeletonData.slots.Count;
                int frameIndex = 0;
                foreach (Dictionary <String, Object> drawOrderMap in values)
                {
                    int[] drawOrder = null;
                    if (drawOrderMap.ContainsKey("offsets"))
                    {
                        drawOrder = new int[slotCount];
                        for (int i = slotCount - 1; i >= 0; i--)
                        {
                            drawOrder[i] = -1;
                        }
                        var   offsets = (List <Object>)drawOrderMap["offsets"];
                        int[] unchanged = new int[slotCount - offsets.Count];
                        int   originalIndex = 0, unchangedIndex = 0;
                        foreach (Dictionary <String, Object> offsetMap in offsets)
                        {
                            int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
                            if (slotIndex == -1)
                            {
                                throw new Exception("Slot not found: " + offsetMap["slot"]);
                            }
                            // Collect unchanged items.
                            while (originalIndex != slotIndex)
                            {
                                unchanged[unchangedIndex++] = originalIndex++;
                            }
                            // Set changed items.
                            drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = originalIndex++;
                        }
                        // Collect remaining unchanged items.
                        while (originalIndex < slotCount)
                        {
                            unchanged[unchangedIndex++] = originalIndex++;
                        }
                        // Fill in unchanged items.
                        for (int i = slotCount - 1; i >= 0; i--)
                        {
                            if (drawOrder[i] == -1)
                            {
                                drawOrder[i] = unchanged[--unchangedIndex];
                            }
                        }
                    }
                    timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
            }

            if (map.ContainsKey("events"))
            {
                var eventsMap  = (List <Object>)map["events"];
                var timeline   = new EventTimeline(eventsMap.Count);
                int frameIndex = 0;
                foreach (Dictionary <String, Object> eventMap in eventsMap)
                {
                    EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
                    if (eventData == null)
                    {
                        throw new Exception("Event not found: " + eventMap["name"]);
                    }
                    var e = new Event(eventData);
                    e.Int    = GetInt(eventMap, "int", eventData.Int);
                    e.Float  = GetFloat(eventMap, "float", eventData.Float);
                    e.String = GetString(eventMap, "string", eventData.String);
                    timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
                }
                timelines.Add(timeline);
                duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
            }

            timelines.TrimExcess();
            skeletonData.AddAnimation(new Animation(name, timelines, duration));
        }
Esempio n. 50
0
        public SkeletonData ReadSkeletonData(TextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader cannot be null.");
            }

            SkeletonData skeletonData = new SkeletonData();

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

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

            // 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"]);
                    }
                }
                BoneData 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.InheritScale    = GetBoolean(boneMap, "inheritScale", true);
                boneData.InheritRotation = GetBoolean(boneMap, "inheritRotation", true);
                skeletonData.AddBone(boneData);
            }

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

                    if (slotMap.ContainsKey("color"))
                    {
                        String 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"];
                    }

                    skeletonData.AddSlot(slotData);
                }
            }

            // Skins.
            if (root.ContainsKey("skins"))
            {
                var skinMap = (Dictionary <String, Object>)root["skins"];
                foreach (KeyValuePair <String, Object> entry in skinMap)
                {
                    Skin 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, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value);
                            skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
                        }
                    }
                    skeletonData.AddSkin(skin);
                    if (skin.Name == "default")
                    {
                        skeletonData.DefaultSkin = skin;
                    }
                }
            }


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

            skeletonData.Bones.TrimExcess();
            skeletonData.Slots.TrimExcess();
            skeletonData.Skins.TrimExcess();
            skeletonData.Animations.TrimExcess();
            return(skeletonData);
        }
		void CreatePreviewInstances () {
			this.DestroyPreviewInstances();

			var skeletonDataAsset = (SkeletonDataAsset)target;
			if (skeletonDataAsset.GetSkeletonData(false) == null)
				return;

			if (this.m_previewInstance == null) {
				string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
				m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation(skeletonDataAsset, skinName).gameObject;

				if (m_previewInstance != null) {
					m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
					m_previewInstance.layer = 0x1f;
					m_skeletonAnimation = m_previewInstance.GetComponent<SkeletonAnimation>();
					m_skeletonAnimation.initialSkinName = skinName;
					m_skeletonAnimation.LateUpdate();
					m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
					m_previewInstance.GetComponent<Renderer>().enabled = false;
					m_initialized = true;
				}

				AdjustCameraGoals(true);
			}
		}
Esempio n. 52
0
	static Bone GetExtractionBone () {
		if (extractionBone != null)
			return extractionBone;

		SkeletonData skelData = new SkeletonData();
		BoneData data = new BoneData("temp", null);
		data.ScaleX = 1;
		data.ScaleY = 1;
		data.Length = 100;

		skelData.Bones.Add(data);

		Skeleton skeleton = new Skeleton(skelData);

		Bone bone = new Bone(data, skeleton, null);
		bone.UpdateWorldTransform();

		extractionBone = bone;

		return extractionBone;
	}
		public SkeletonData ReadSkeletonData (TextReader reader) {
			if (reader == null) throw new ArgumentNullException("reader", "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);
				skeletonData.fps = GetFloat(skeletonMap, "fps", 0);
				skeletonData.imagesPath = GetString(skeletonMap, "images", null);
			}

			// 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 data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent);
				data.length = GetFloat(boneMap, "length", 0) * scale;
				data.x = GetFloat(boneMap, "x", 0) * scale;
				data.y = GetFloat(boneMap, "y", 0) * scale;
				data.rotation = GetFloat(boneMap, "rotation", 0);
				data.scaleX = GetFloat(boneMap, "scaleX", 1);
				data.scaleY = GetFloat(boneMap, "scaleY", 1);
				data.shearX = GetFloat(boneMap, "shearX", 0);
				data.shearY = GetFloat(boneMap, "shearY", 0);

				string tm = GetString(boneMap, "transform", TransformMode.Normal.ToString());
				data.transformMode = (TransformMode)Enum.Parse(typeof(TransformMode), tm, true);

				skeletonData.bones.Add(data);
			}

			// 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 data = new SlotData(skeletonData.Slots.Count, slotName, boneData);

					if (slotMap.ContainsKey("color")) {
						var color = (String)slotMap["color"];
						data.r = ToColor(color, 0);
						data.g = ToColor(color, 1);
						data.b = ToColor(color, 2);
						data.a = ToColor(color, 3);
					}
						
					data.attachmentName = GetString(slotMap, "attachment", null);
					if (slotMap.ContainsKey("blend"))
						data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
					else
						data.blendMode = BlendMode.normal;
					skeletonData.slots.Add(data);
				}
			}

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

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

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

					skeletonData.ikConstraints.Add(data);
				}
			}

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

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

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

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

					data.rotateMix = GetFloat(constraintMap, "rotateMix", 1);
					data.translateMix = GetFloat(constraintMap, "translateMix", 1);
					data.scaleMix = GetFloat(constraintMap, "scaleMix", 1);
					data.shearMix = GetFloat(constraintMap, "shearMix", 1);

					skeletonData.transformConstraints.Add(data);
				}
			}

			// Path constraints.
			if(root.ContainsKey("path")) {
				foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["path"]) {
					PathConstraintData data = new PathConstraintData((String)constraintMap["name"]);
					data.order = GetInt(constraintMap, "order", 0);

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

					String targetName = (String)constraintMap["target"];
					data.target = skeletonData.FindSlot(targetName);
					if (data.target == null) throw new Exception("Target slot not found: " + targetName);

					data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true);
					data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true);
					data.rotateMode = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(constraintMap, "rotateMode", "tangent"), true);
					data.offsetRotation = GetFloat(constraintMap, "rotation", 0);
					data.position = GetFloat(constraintMap, "position", 0);
					if (data.positionMode == PositionMode.Fixed) data.position *= scale;
					data.spacing = GetFloat(constraintMap, "spacing", 0);
					if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale;
					data.rotateMix = GetFloat(constraintMap, "rotateMix", 1);
					data.translateMix = GetFloat(constraintMap, "translateMix", 1);

					skeletonData.pathConstraints.Add(data);
				}
			}

			// Skins.
			if (root.ContainsKey("skins")) {
					foreach (KeyValuePair<String, Object> skinMap in (Dictionary<String, Object>)root["skins"]) {
					var skin = new Skin(skinMap.Key);
					foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)skinMap.Value) {
						int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
						foreach (KeyValuePair<String, Object> entry in ((Dictionary<String, Object>)slotEntry.Value)) {
							try {
								Attachment attachment = ReadAttachment((Dictionary<String, Object>)entry.Value, skin, slotIndex, entry.Key);
								if (attachment != null) skin.AddAttachment(slotIndex, entry.Key, attachment);
							} catch (Exception e) {
								throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
							}
						} 
					}
					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);
				linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
				linkedMesh.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 data = new EventData(entry.Key);
					data.Int = GetInt(entryMap, "int", 0);
					data.Float = GetFloat(entryMap, "float", 0);
					data.String = GetString(entryMap, "string", string.Empty);
					skeletonData.events.Add(data);
				}
			}

			// Animations.
			if (root.ContainsKey("animations")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) {
					try {
						ReadAnimation((Dictionary<String, Object>)entry.Value, entry.Key, skeletonData);
					} catch (Exception e) {
						throw new Exception("Error reading animation: " + entry.Key, e);
					}
				}   
			}

			skeletonData.bones.TrimExcess();
			skeletonData.slots.TrimExcess();
			skeletonData.skins.TrimExcess();
			skeletonData.events.TrimExcess();
			skeletonData.animations.TrimExcess();
			skeletonData.ikConstraints.TrimExcess();
			return skeletonData;
		}
Esempio n. 54
0
	static Mesh ExtractSkinnedMeshAttachment (string name, SkinnedMeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {

		Skeleton skeleton = new Skeleton(skeletonData);
		skeleton.UpdateWorldTransform();

		float[] floatVerts = new float[attachment.UVs.Length];
		attachment.ComputeWorldVertices(skeleton.Slots[slotIndex], floatVerts);

		Vector2[] uvs = ExtractUV(attachment.UVs);
		Vector3[] verts = ExtractVerts(floatVerts);

		int[] triangles = attachment.Triangles;
		Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);

		if (mesh == null)
			mesh = new Mesh();

		mesh.triangles = new int[0];

		mesh.vertices = verts;
		mesh.uv = uvs;
		mesh.triangles = triangles;
		Color[] colors = new Color[verts.Length];
		for (int i = 0; i < verts.Length; i++)
			colors[i] = color;

		mesh.colors = colors;
		mesh.name = name;
		mesh.RecalculateNormals();
		mesh.RecalculateBounds();

		//Handle weights and binding
		Dictionary<int, BoneWeightContainer> weightTable = new Dictionary<int, BoneWeightContainer>();
		System.Text.StringBuilder warningBuilder = new System.Text.StringBuilder();

		int[] bones = attachment.Bones;
		float[] weights = attachment.Weights;
		for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) {

			int nn = bones[v++] + v;
			for (; v < nn; v++, b += 3) {
				Transform boneTransform = boneList[bones[v]];
				int vIndex = w / 2;

				float weight = weights[b + 2];

				BoneWeightContainer container;
				if (weightTable.ContainsKey(vIndex))
					container = weightTable[vIndex];
				else {
					container = new BoneWeightContainer();
					weightTable.Add(vIndex, container);
				}


				container.Add(boneTransform, weight);
			}
		}

		BoneWeight[] boneWeights = new BoneWeight[weightTable.Count];

		for (int i = 0; i < weightTable.Count; i++) {
			BoneWeight bw = new BoneWeight();
			var container = weightTable[i];

			var pairs = container.pairs.OrderByDescending(pair => pair.weight).ToList();

			for (int b = 0; b < pairs.Count; b++) {
				if (b > 3) {
					if (warningBuilder.Length == 0)
						warningBuilder.Insert(0, "[SkinnedMeshAttachment " + name + "]\r\nUnity only supports 4 weight influences per vertex!  The 4 strongest influences will be used.\r\n");

					warningBuilder.AppendFormat("{0} ignored on vertex {1}!\r\n", pairs[b].bone.name, i);
					continue;
				}

				int boneIndex = boneList.IndexOf(pairs[b].bone);
				float weight = pairs[b].weight;

				switch (b) {
					case 0:
						bw.boneIndex0 = boneIndex;
						bw.weight0 = weight;
						break;
					case 1:
						bw.boneIndex1 = boneIndex;
						bw.weight1 = weight;
						break;
					case 2:
						bw.boneIndex2 = boneIndex;
						bw.weight2 = weight;
						break;
					case 3:
						bw.boneIndex3 = boneIndex;
						bw.weight3 = weight;
						break;
				}
			}

			boneWeights[i] = bw;
		}

		Matrix4x4[] bindPoses = new Matrix4x4[boneList.Count];
		for (int i = 0; i < boneList.Count; i++) {
			bindPoses[i] = boneList[i].worldToLocalMatrix;
		}

		mesh.boneWeights = boneWeights;
		mesh.bindposes = bindPoses;

		string warningString = warningBuilder.ToString();
		if (warningString.Length > 0)
			Debug.LogWarning(warningString);


		return mesh;
	}
Esempio n. 55
0
        private void readAnimation(String name, Dictionary<String, Object> map, SkeletonData skeletonData)
        {
            var timelines = new List<Timeline>();
            float duration = 0;

            var bonesMap = (Dictionary<String, Object>)map["bones"];
            foreach (KeyValuePair<String, Object> entry in bonesMap) {
                String boneName = entry.Key;
                int boneIndex = skeletonData.FindBoneIndex(boneName);
                if (boneIndex == -1)
                    throw new Exception("Bone not found: " + boneName);

                Dictionary<String, Object> timelineMap = (Dictionary<String, Object>)entry.Value;
                foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
                    List<Object> values = (List<Object>)timelineEntry.Value;
                    String timelineName = (String)timelineEntry.Key;
                    if (timelineName.Equals(TIMELINE_ROTATE)) {
                        RotateTimeline timeline = new RotateTimeline(values.Count);
                        timeline.BoneIndex = boneIndex;

                        int frameIndex = 0;
                        foreach (Dictionary<String, Object> valueMap in values) {
                            float time = (float)valueMap["time"];
                            timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
                            readCurve(timeline, frameIndex, valueMap);
                            frameIndex++;
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 2 - 2]);

                    } else if (timelineName.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) {
                        TranslateTimeline timeline;
                        float timelineScale = 1;
                        if (timelineName.Equals(TIMELINE_SCALE))
                            timeline = new ScaleTimeline(values.Count);
                        else {
                            timeline = new TranslateTimeline(values.Count);
                            timelineScale = Scale;
                        }
                        timeline.BoneIndex = boneIndex;

                        int frameIndex = 0;
                        foreach (Dictionary<String, Object> valueMap in values) {
                            float time = (float)valueMap["time"];
                            float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
                            float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
                            timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
                            readCurve(timeline, frameIndex, valueMap);
                            frameIndex++;
                        }
                        timelines.Add(timeline);
                        duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 3 - 3]);

                    } else
                        throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
                }
            }

            if (map.ContainsKey("slots")) {
                Dictionary<String, Object> slotsMap = (Dictionary<String, Object>)map["slots"];
                foreach (KeyValuePair<String, Object> entry in slotsMap) {
                    String slotName = entry.Key;
                    int slotIndex = skeletonData.FindSlotIndex(slotName);
                    Dictionary<String, Object> timelineMap = (Dictionary<String, Object>)entry.Value;

                    foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
                        List<Object> values = (List<Object>)timelineEntry.Value;
                        String timelineName = (String)timelineEntry.Key;
                        if (timelineName.Equals(TIMELINE_COLOR)) {
                            ColorTimeline timeline = new ColorTimeline(values.Count);
                            timeline.SlotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary<String, Object> valueMap in values) {
                                float time = (float)valueMap["time"];
                                String c = (String)valueMap["color"];
                                timeline.setFrame(frameIndex, time, toColor(c, 0), toColor(c, 1), toColor(c, 2), toColor(c, 3));
                                readCurve(timeline, frameIndex, valueMap);
                                frameIndex++;
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 5 - 5]);

                        } else if (timelineName.Equals(TIMELINE_ATTACHMENT)) {
                            AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
                            timeline.SlotIndex = slotIndex;

                            int frameIndex = 0;
                            foreach (Dictionary<String, Object> valueMap in values) {
                                float time = (float)valueMap["time"];
                                timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
                            }
                            timelines.Add(timeline);
                            duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]);

                        } else
                            throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
                    }
                }
            }

            timelines.TrimExcess();
            skeletonData.AddAnimation(new Animation(name, timelines, duration));
        }
Esempio n. 56
0
	static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary<int, List<string>> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) {
		var animation = skeletonData.FindAnimation(name);

		var timelines = animation.Timelines;

		if (clip == null) {
			clip = new AnimationClip();
		} else {
			clip.ClearCurves();
			AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);
		}

#if UNITY_5

#else
		AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);
#endif

		clip.name = name;

		Skeleton skeleton = new Skeleton(skeletonData);

		List<int> ignoreRotateTimelineIndexes = new List<int>();

		if (bakeIK) {
			foreach (IkConstraint i in skeleton.IkConstraints) {
				foreach (Bone b in i.Bones) {
					int index = skeleton.FindBoneIndex(b.Data.Name);
					ignoreRotateTimelineIndexes.Add(index);
					BakeBone(b, animation, clip);
				}
			}
		}

		foreach (Bone b in skeleton.Bones) {
			if (b.Data.InheritRotation == false) {
				int index = skeleton.FindBoneIndex(b.Data.Name);

				if (ignoreRotateTimelineIndexes.Contains(index) == false) {
					ignoreRotateTimelineIndexes.Add(index);
					BakeBone(b, animation, clip);
				}
			}
		}

		foreach (Timeline t in timelines) {
			skeleton.SetToSetupPose();

			if (t is ScaleTimeline) {
				ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip);
			} else if (t is TranslateTimeline) {
				ParseTranslateTimeline(skeleton, (TranslateTimeline)t, clip);
			} else if (t is RotateTimeline) {
				//bypass any rotation keys if they're going to get baked anyway to prevent localEulerAngles vs Baked collision
				if (ignoreRotateTimelineIndexes.Contains(((RotateTimeline)t).BoneIndex) == false)
					ParseRotateTimeline(skeleton, (RotateTimeline)t, clip);
			} else if (t is AttachmentTimeline) {
				ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip);
			} else if (t is EventTimeline) {
				ParseEventTimeline((EventTimeline)t, clip, eventOptions);
			}

		}

		var settings = AnimationUtility.GetAnimationClipSettings(clip);
		settings.loopTime = true;
		settings.stopTime = Mathf.Max(clip.length, 0.001f);

		SetAnimationSettings(clip, settings);

		clip.EnsureQuaternionContinuity();

		EditorUtility.SetDirty(clip);

		return clip;
	}
Esempio n. 57
0
		private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) {
			var timelines = new ExposedList<Timeline>();
			float duration = 0;
			float scale = Scale;

			if (map.ContainsKey("slots")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
					String slotName = entry.Key;
					int slotIndex = skeletonData.FindSlotIndex(slotName);
					var timelineMap = (Dictionary<String, Object>)entry.Value;

					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						var timelineName = (String)timelineEntry.Key;
						if (timelineName == "color") {
							var timeline = new ColorTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								String c = (String)valueMap["color"];
								timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);

						} else if (timelineName == "attachment") {
							var timeline = new AttachmentTimeline(values.Count);
							timeline.slotIndex = slotIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);

						} else
							throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
					}
				}
			}

			if (map.ContainsKey("bones")) {
				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
					String boneName = entry.Key;
					int boneIndex = skeletonData.FindBoneIndex(boneName);
					if (boneIndex == -1)
						throw new Exception("Bone not found: " + boneName);

					var timelineMap = (Dictionary<String, Object>)entry.Value;
					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
						var values = (List<Object>)timelineEntry.Value;
						var timelineName = (String)timelineEntry.Key;
						if (timelineName == "rotate") {
							var timeline = new RotateTimeline(values.Count);
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);

						} else if (timelineName == "translate" || timelineName == "scale") {
							TranslateTimeline timeline;
							float timelineScale = 1;
							if (timelineName == "scale")
								timeline = new ScaleTimeline(values.Count);
							else {
								timeline = new TranslateTimeline(values.Count);
								timelineScale = scale;
							}
							timeline.boneIndex = boneIndex;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float time = (float)valueMap["time"];
								float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
								float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
								timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);

						} else
							throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
					}
				}
			}

			if (map.ContainsKey("ik")) {
				foreach (KeyValuePair<String, Object> ikMap in (Dictionary<String, Object>)map["ik"]) {
					IkConstraintData ikConstraint = skeletonData.FindIkConstraint(ikMap.Key);
					var values = (List<Object>)ikMap.Value;
					var timeline = new IkConstraintTimeline(values.Count);
					timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint);
					int frameIndex = 0;
					foreach (Dictionary<String, Object> valueMap in values) {
						float time = (float)valueMap["time"];
						float mix = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1;
						bool bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true;
						timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1);
						ReadCurve(timeline, frameIndex, valueMap);
						frameIndex++;
					}
					timelines.Add(timeline);
					duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
				}
			}

			if (map.ContainsKey("ffd")) {
				foreach (KeyValuePair<String, Object> ffdMap in (Dictionary<String, Object>)map["ffd"]) {
					Skin skin = skeletonData.FindSkin(ffdMap.Key);
					foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)ffdMap.Value) {
						int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
						foreach (KeyValuePair<String, Object> meshMap in (Dictionary<String, Object>)slotMap.Value) {
							var values = (List<Object>)meshMap.Value;
							var timeline = new FFDTimeline(values.Count);
							Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key);
							if (attachment == null) throw new Exception("FFD attachment not found: " + meshMap.Key);
							timeline.slotIndex = slotIndex;
							timeline.attachment = attachment;

							int vertexCount;
							if (attachment is MeshAttachment)
								vertexCount = ((MeshAttachment)attachment).vertices.Length;
							else
								vertexCount = ((WeightedMeshAttachment)attachment).Weights.Length / 3 * 2;

							int frameIndex = 0;
							foreach (Dictionary<String, Object> valueMap in values) {
								float[] vertices;
								if (!valueMap.ContainsKey("vertices")) {
									if (attachment is MeshAttachment)
										vertices = ((MeshAttachment)attachment).vertices;
									else
										vertices = new float[vertexCount];
								} else {
									var verticesValue = (List<Object>)valueMap["vertices"];
									vertices = new float[vertexCount];
									int start = GetInt(valueMap, "offset", 0);
									if (scale == 1) {
										for (int i = 0, n = verticesValue.Count; i < n; i++)
											vertices[i + start] = (float)verticesValue[i];
									} else {
										for (int i = 0, n = verticesValue.Count; i < n; i++)
											vertices[i + start] = (float)verticesValue[i] * scale;
									}
									if (attachment is MeshAttachment) {
										float[] meshVertices = ((MeshAttachment)attachment).vertices;
										for (int i = 0; i < vertexCount; i++)
											vertices[i] += meshVertices[i];
									}
								}

								timeline.SetFrame(frameIndex, (float)valueMap["time"], vertices);
								ReadCurve(timeline, frameIndex, valueMap);
								frameIndex++;
							}
							timelines.Add(timeline);
							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
						}
					}
				}
			}

			if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) {
				var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"];
				var timeline = new DrawOrderTimeline(values.Count);
				int slotCount = skeletonData.slots.Count;
				int frameIndex = 0;
				foreach (Dictionary<String, Object> drawOrderMap in values) {
					int[] drawOrder = null;
					if (drawOrderMap.ContainsKey("offsets")) {
						drawOrder = new int[slotCount];
						for (int i = slotCount - 1; i >= 0; i--)
							drawOrder[i] = -1;
						var offsets = (List<Object>)drawOrderMap["offsets"];
						int[] unchanged = new int[slotCount - offsets.Count];
						int originalIndex = 0, unchangedIndex = 0;
						foreach (Dictionary<String, Object> offsetMap in offsets) {
							int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
							if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
							// Collect unchanged items.
							while (originalIndex != slotIndex)
								unchanged[unchangedIndex++] = originalIndex++;
							// Set changed items.
							int index = originalIndex + (int)(float)offsetMap["offset"];
							drawOrder[index] = originalIndex++;
						}
						// Collect remaining unchanged items.
						while (originalIndex < slotCount)
							unchanged[unchangedIndex++] = originalIndex++;
						// Fill in unchanged items.
						for (int i = slotCount - 1; i >= 0; i--)
							if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
					}
					timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			if (map.ContainsKey("events")) {
				var eventsMap = (List<Object>)map["events"];
				var timeline = new EventTimeline(eventsMap.Count);
				int frameIndex = 0;
				foreach (Dictionary<String, Object> eventMap in eventsMap) {
					EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
					float time = (float)eventMap["time"];
					var e = new Event(time, eventData);
					e.Int = GetInt(eventMap, "int", eventData.Int);
					e.Float = GetFloat(eventMap, "float", eventData.Float);
					e.String = GetString(eventMap, "string", eventData.String);
					timeline.SetFrame(frameIndex++, time, e);
				}
				timelines.Add(timeline);
				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
			}

			timelines.TrimExcess();
			skeletonData.animations.Add(new Animation(name, timelines, duration));
		}
Esempio n. 58
0
	public void Clear () {
		skeletonData = null;
		stateData = null;
	}
Esempio n. 59
0
        public SkeletonData ReadSkeletonData(IDictionary <String, Object> root)
        {
            if (root == null)
            {
                throw new Exception("Invalid JSON.");
            }

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

            // Skeleton.
            if (root.ContainsKey("skeleton"))
            {
                var skeletonMap = (IDictionary <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 (IDictionary <String, Object> boneMap in (IList <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 data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent);
                data.length          = GetFloat(boneMap, "length", 0) * scale;
                data.x               = GetFloat(boneMap, "x", 0) * scale;
                data.y               = GetFloat(boneMap, "y", 0) * scale;
                data.rotation        = GetFloat(boneMap, "rotation", 0);
                data.scaleX          = GetFloat(boneMap, "scaleX", 1);
                data.scaleY          = GetFloat(boneMap, "scaleY", 1);
                data.shearX          = GetFloat(boneMap, "shearX", 0);
                data.shearY          = GetFloat(boneMap, "shearY", 0);
                data.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
                data.inheritScale    = GetBoolean(boneMap, "inheritScale", true);

                skeletonData.bones.Add(data);
            }

            // Slots.
            if (root.ContainsKey("slots"))
            {
                foreach (IDictionary <String, Object> slotMap in (IList <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 data = new SlotData(skeletonData.Slots.Count, slotName, boneData);

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

                    data.attachmentName = GetString(slotMap, "attachment", null);
                    if (slotMap.ContainsKey("blend"))
                    {
                        data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
                    }
                    else
                    {
                        data.blendMode = BlendMode.normal;
                    }
                    skeletonData.slots.Add(data);
                }
            }

            // IK constraints.
            if (root.ContainsKey("ik"))
            {
                foreach (IDictionary <String, Object> constraintMap in (IList <Object>)root["ik"])
                {
                    IkConstraintData data = new IkConstraintData((String)constraintMap ["name"]);

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

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

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

                    skeletonData.ikConstraints.Add(data);
                }
            }

            // Transform constraints.
            if (root.ContainsKey("transform"))
            {
                foreach (IDictionary <String, Object> constraintMap in (IList <Object>)root["transform"])
                {
                    TransformConstraintData data = new TransformConstraintData((String)constraintMap ["name"]);

                    foreach (String boneName in (IList <Object>)constraintMap["bones"])
                    {
                        BoneData bone = skeletonData.FindBone(boneName);
                        if (bone == null)
                        {
                            throw new Exception("Transform constraint bone not found: " + boneName);
                        }
                        data.bones.Add(bone);
                    }

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

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

                    data.rotateMix    = GetFloat(constraintMap, "rotateMix", 1);
                    data.translateMix = GetFloat(constraintMap, "translateMix", 1);
                    data.scaleMix     = GetFloat(constraintMap, "scaleMix", 1);
                    data.shearMix     = GetFloat(constraintMap, "shearMix", 1);

                    skeletonData.transformConstraints.Add(data);
                }
            }

            // Path constraints.
            if (root.ContainsKey("path"))
            {
                foreach (IDictionary <String, Object> constraintMap in (IList <Object>)root["path"])
                {
                    PathConstraintData data = new PathConstraintData((String)constraintMap["name"]);

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

                    String targetName = (String)constraintMap["target"];
                    data.target = skeletonData.FindSlot(targetName);
                    if (data.target == null)
                    {
                        throw new Exception("Target slot not found: " + targetName);
                    }

                    data.positionMode   = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true);
                    data.spacingMode    = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true);
                    data.rotateMode     = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(constraintMap, "rotateMode", "tangent"), true);
                    data.offsetRotation = GetFloat(constraintMap, "rotation", 0);
                    data.position       = GetFloat(constraintMap, "position", 0);
                    if (data.positionMode == PositionMode.Fixed)
                    {
                        data.position *= scale;
                    }
                    data.spacing = GetFloat(constraintMap, "spacing", 0);
                    if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)
                    {
                        data.spacing *= scale;
                    }
                    data.rotateMix    = GetFloat(constraintMap, "rotateMix", 1);
                    data.translateMix = GetFloat(constraintMap, "translateMix", 1);

                    skeletonData.pathConstraints.Add(data);
                }
            }

            // Skins.
            if (root.ContainsKey("skins"))
            {
                foreach (KeyValuePair <String, Object> skinMap in (IDictionary <String, Object>)root["skins"])
                {
                    var skin = new Skin(skinMap.Key);
                    foreach (KeyValuePair <String, Object> slotEntry in (IDictionary <String, Object>)skinMap.Value)
                    {
                        int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
                        foreach (KeyValuePair <String, Object> entry in ((IDictionary <String, Object>)slotEntry.Value))
                        {
                            try {
                                Attachment attachment = ReadAttachment((IDictionary <String, Object>)entry.Value, skin, slotIndex, entry.Key);
                                if (attachment != null)
                                {
                                    skin.AddAttachment(slotIndex, entry.Key, attachment);
                                }
                            } catch (Exception e) {
                                throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
                            }
                        }
                    }
                    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);
                }
                linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
                linkedMesh.mesh.UpdateUVs();
            }
            linkedMeshes.Clear();

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

            // Animations.
            if (root.ContainsKey("animations"))
            {
                foreach (KeyValuePair <String, Object> entry in (IDictionary <String, Object>)root["animations"])
                {
                    try {
                        ReadAnimation((IDictionary <String, Object>)entry.Value, entry.Key, skeletonData);
                    } catch (Exception e) {
                        throw new Exception("Error reading animation: " + entry.Key, e);
                    }
                }
            }

            skeletonData.bones.TrimExcess();
            skeletonData.slots.TrimExcess();
            skeletonData.skins.TrimExcess();
            skeletonData.events.TrimExcess();
            skeletonData.animations.TrimExcess();
            skeletonData.ikConstraints.TrimExcess();
            return(skeletonData);
        }
Esempio n. 60
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;
                        timeline.slotName  = skeletonData.slots.Items[slotIndex].name;
                        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));
        }