SkeletonJson.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. namespace Spine
  5. {
  6. public class SkeletonJson
  7. {
  8. public SkeletonJson(params Atlas[] atlasArray) : this(new AtlasAttachmentLoader(atlasArray))
  9. {
  10. }
  11. public SkeletonJson(AttachmentLoader attachmentLoader)
  12. {
  13. if (attachmentLoader == null)
  14. {
  15. throw new ArgumentNullException("attachmentLoader cannot be null.");
  16. }
  17. this.attachmentLoader = attachmentLoader;
  18. this.Scale = 1f;
  19. }
  20. public float Scale { get; set; }
  21. public SkeletonData ReadSkeletonData(string path)
  22. {
  23. SkeletonData result;
  24. using (StreamReader streamReader = new StreamReader(path))
  25. {
  26. SkeletonData skeletonData = this.ReadSkeletonData(streamReader);
  27. skeletonData.name = Path.GetFileNameWithoutExtension(path);
  28. result = skeletonData;
  29. }
  30. return result;
  31. }
  32. public SkeletonData ReadSkeletonData(TextReader reader)
  33. {
  34. if (reader == null)
  35. {
  36. throw new ArgumentNullException("reader cannot be null.");
  37. }
  38. SkeletonData skeletonData = new SkeletonData();
  39. Dictionary<string, object> dictionary = Json.Deserialize(reader) as Dictionary<string, object>;
  40. if (dictionary == null)
  41. {
  42. throw new Exception("Invalid JSON.");
  43. }
  44. if (dictionary.ContainsKey("skeleton"))
  45. {
  46. Dictionary<string, object> dictionary2 = (Dictionary<string, object>)dictionary["skeleton"];
  47. skeletonData.hash = (string)dictionary2["hash"];
  48. skeletonData.version = (string)dictionary2["spine"];
  49. skeletonData.width = this.GetFloat(dictionary2, "width", 0f);
  50. skeletonData.height = this.GetFloat(dictionary2, "height", 0f);
  51. }
  52. foreach (object obj in ((List<object>)dictionary["bones"]))
  53. {
  54. Dictionary<string, object> dictionary3 = (Dictionary<string, object>)obj;
  55. BoneData boneData = null;
  56. if (dictionary3.ContainsKey("parent"))
  57. {
  58. boneData = skeletonData.FindBone((string)dictionary3["parent"]);
  59. if (boneData == null)
  60. {
  61. throw new Exception("Parent bone not found: " + dictionary3["parent"]);
  62. }
  63. }
  64. BoneData boneData2 = new BoneData((string)dictionary3["name"], boneData);
  65. boneData2.length = this.GetFloat(dictionary3, "length", 0f) * this.Scale;
  66. boneData2.x = this.GetFloat(dictionary3, "x", 0f) * this.Scale;
  67. boneData2.y = this.GetFloat(dictionary3, "y", 0f) * this.Scale;
  68. boneData2.rotation = this.GetFloat(dictionary3, "rotation", 0f);
  69. boneData2.scaleX = this.GetFloat(dictionary3, "scaleX", 1f);
  70. boneData2.scaleY = this.GetFloat(dictionary3, "scaleY", 1f);
  71. boneData2.flipX = this.GetBoolean(dictionary3, "flipX", false);
  72. boneData2.flipY = this.GetBoolean(dictionary3, "flipY", false);
  73. boneData2.inheritScale = this.GetBoolean(dictionary3, "inheritScale", true);
  74. boneData2.inheritRotation = this.GetBoolean(dictionary3, "inheritRotation", true);
  75. skeletonData.bones.Add(boneData2);
  76. }
  77. if (dictionary.ContainsKey("ik"))
  78. {
  79. foreach (object obj2 in ((List<object>)dictionary["ik"]))
  80. {
  81. Dictionary<string, object> dictionary4 = (Dictionary<string, object>)obj2;
  82. IkConstraintData ikConstraintData = new IkConstraintData((string)dictionary4["name"]);
  83. foreach (object obj3 in ((List<object>)dictionary4["bones"]))
  84. {
  85. string text = (string)obj3;
  86. BoneData boneData3 = skeletonData.FindBone(text);
  87. if (boneData3 == null)
  88. {
  89. throw new Exception("IK bone not found: " + text);
  90. }
  91. ikConstraintData.bones.Add(boneData3);
  92. }
  93. string text2 = (string)dictionary4["target"];
  94. ikConstraintData.target = skeletonData.FindBone(text2);
  95. if (ikConstraintData.target == null)
  96. {
  97. throw new Exception("Target bone not found: " + text2);
  98. }
  99. ikConstraintData.bendDirection = ((!this.GetBoolean(dictionary4, "bendPositive", true)) ? -1 : 1);
  100. ikConstraintData.mix = this.GetFloat(dictionary4, "mix", 1f);
  101. skeletonData.ikConstraints.Add(ikConstraintData);
  102. }
  103. }
  104. if (dictionary.ContainsKey("slots"))
  105. {
  106. foreach (object obj4 in ((List<object>)dictionary["slots"]))
  107. {
  108. Dictionary<string, object> dictionary5 = (Dictionary<string, object>)obj4;
  109. string name = (string)dictionary5["name"];
  110. string text3 = (string)dictionary5["bone"];
  111. BoneData boneData4 = skeletonData.FindBone(text3);
  112. if (boneData4 == null)
  113. {
  114. throw new Exception("Slot bone not found: " + text3);
  115. }
  116. SlotData slotData = new SlotData(name, boneData4);
  117. if (dictionary5.ContainsKey("color"))
  118. {
  119. string hexString = (string)dictionary5["color"];
  120. slotData.r = this.ToColor(hexString, 0);
  121. slotData.g = this.ToColor(hexString, 1);
  122. slotData.b = this.ToColor(hexString, 2);
  123. slotData.a = this.ToColor(hexString, 3);
  124. }
  125. if (dictionary5.ContainsKey("attachment"))
  126. {
  127. slotData.attachmentName = (string)dictionary5["attachment"];
  128. }
  129. if (dictionary5.ContainsKey("blend"))
  130. {
  131. slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (string)dictionary5["blend"], false);
  132. }
  133. else
  134. {
  135. slotData.blendMode = BlendMode.normal;
  136. }
  137. skeletonData.slots.Add(slotData);
  138. }
  139. }
  140. if (dictionary.ContainsKey("skins"))
  141. {
  142. foreach (KeyValuePair<string, object> keyValuePair in ((Dictionary<string, object>)dictionary["skins"]))
  143. {
  144. Skin skin = new Skin(keyValuePair.Key);
  145. foreach (KeyValuePair<string, object> keyValuePair2 in ((Dictionary<string, object>)keyValuePair.Value))
  146. {
  147. int slotIndex = skeletonData.FindSlotIndex(keyValuePair2.Key);
  148. foreach (KeyValuePair<string, object> keyValuePair3 in ((Dictionary<string, object>)keyValuePair2.Value))
  149. {
  150. Attachment attachment = this.ReadAttachment(skin, keyValuePair3.Key, (Dictionary<string, object>)keyValuePair3.Value);
  151. if (attachment != null)
  152. {
  153. skin.AddAttachment(slotIndex, keyValuePair3.Key, attachment);
  154. }
  155. }
  156. }
  157. skeletonData.skins.Add(skin);
  158. if (skin.name == "default")
  159. {
  160. skeletonData.defaultSkin = skin;
  161. }
  162. }
  163. }
  164. if (dictionary.ContainsKey("events"))
  165. {
  166. foreach (KeyValuePair<string, object> keyValuePair4 in ((Dictionary<string, object>)dictionary["events"]))
  167. {
  168. Dictionary<string, object> map = (Dictionary<string, object>)keyValuePair4.Value;
  169. EventData eventData = new EventData(keyValuePair4.Key);
  170. eventData.Int = this.GetInt(map, "int", 0);
  171. eventData.Float = this.GetFloat(map, "float", 0f);
  172. eventData.String = this.GetString(map, "string", null);
  173. skeletonData.events.Add(eventData);
  174. }
  175. }
  176. if (dictionary.ContainsKey("animations"))
  177. {
  178. foreach (KeyValuePair<string, object> keyValuePair5 in ((Dictionary<string, object>)dictionary["animations"]))
  179. {
  180. this.ReadAnimation(keyValuePair5.Key, (Dictionary<string, object>)keyValuePair5.Value, skeletonData);
  181. }
  182. }
  183. skeletonData.bones.TrimExcess();
  184. skeletonData.slots.TrimExcess();
  185. skeletonData.skins.TrimExcess();
  186. skeletonData.events.TrimExcess();
  187. skeletonData.animations.TrimExcess();
  188. skeletonData.ikConstraints.TrimExcess();
  189. return skeletonData;
  190. }
  191. private Attachment ReadAttachment(Skin skin, string name, Dictionary<string, object> map)
  192. {
  193. if (map.ContainsKey("name"))
  194. {
  195. name = (string)map["name"];
  196. }
  197. AttachmentType attachmentType = AttachmentType.region;
  198. if (map.ContainsKey("type"))
  199. {
  200. attachmentType = (AttachmentType)Enum.Parse(typeof(AttachmentType), (string)map["type"], false);
  201. }
  202. string path = name;
  203. if (map.ContainsKey("path"))
  204. {
  205. path = (string)map["path"];
  206. }
  207. switch (attachmentType)
  208. {
  209. case AttachmentType.region:
  210. {
  211. RegionAttachment regionAttachment = this.attachmentLoader.NewRegionAttachment(skin, name, path);
  212. if (regionAttachment == null)
  213. {
  214. return null;
  215. }
  216. regionAttachment.Path = path;
  217. regionAttachment.x = this.GetFloat(map, "x", 0f) * this.Scale;
  218. regionAttachment.y = this.GetFloat(map, "y", 0f) * this.Scale;
  219. regionAttachment.scaleX = this.GetFloat(map, "scaleX", 1f);
  220. regionAttachment.scaleY = this.GetFloat(map, "scaleY", 1f);
  221. regionAttachment.rotation = this.GetFloat(map, "rotation", 0f);
  222. regionAttachment.width = this.GetFloat(map, "width", 32f) * this.Scale;
  223. regionAttachment.height = this.GetFloat(map, "height", 32f) * this.Scale;
  224. regionAttachment.UpdateOffset();
  225. if (map.ContainsKey("color"))
  226. {
  227. string hexString = (string)map["color"];
  228. regionAttachment.r = this.ToColor(hexString, 0);
  229. regionAttachment.g = this.ToColor(hexString, 1);
  230. regionAttachment.b = this.ToColor(hexString, 2);
  231. regionAttachment.a = this.ToColor(hexString, 3);
  232. }
  233. return regionAttachment;
  234. }
  235. case AttachmentType.boundingbox:
  236. {
  237. BoundingBoxAttachment boundingBoxAttachment = this.attachmentLoader.NewBoundingBoxAttachment(skin, name);
  238. if (boundingBoxAttachment == null)
  239. {
  240. return null;
  241. }
  242. boundingBoxAttachment.vertices = this.GetFloatArray(map, "vertices", this.Scale);
  243. return boundingBoxAttachment;
  244. }
  245. case AttachmentType.mesh:
  246. {
  247. MeshAttachment meshAttachment = this.attachmentLoader.NewMeshAttachment(skin, name, path);
  248. if (meshAttachment == null)
  249. {
  250. return null;
  251. }
  252. meshAttachment.Path = path;
  253. meshAttachment.vertices = this.GetFloatArray(map, "vertices", this.Scale);
  254. meshAttachment.triangles = this.GetIntArray(map, "triangles");
  255. meshAttachment.regionUVs = this.GetFloatArray(map, "uvs", 1f);
  256. meshAttachment.UpdateUVs();
  257. if (map.ContainsKey("color"))
  258. {
  259. string hexString2 = (string)map["color"];
  260. meshAttachment.r = this.ToColor(hexString2, 0);
  261. meshAttachment.g = this.ToColor(hexString2, 1);
  262. meshAttachment.b = this.ToColor(hexString2, 2);
  263. meshAttachment.a = this.ToColor(hexString2, 3);
  264. }
  265. meshAttachment.HullLength = this.GetInt(map, "hull", 0) * 2;
  266. if (map.ContainsKey("edges"))
  267. {
  268. meshAttachment.Edges = this.GetIntArray(map, "edges");
  269. }
  270. meshAttachment.Width = (float)this.GetInt(map, "width", 0) * this.Scale;
  271. meshAttachment.Height = (float)this.GetInt(map, "height", 0) * this.Scale;
  272. return meshAttachment;
  273. }
  274. case AttachmentType.skinnedmesh:
  275. {
  276. SkinnedMeshAttachment skinnedMeshAttachment = this.attachmentLoader.NewSkinnedMeshAttachment(skin, name, path);
  277. if (skinnedMeshAttachment == null)
  278. {
  279. return null;
  280. }
  281. skinnedMeshAttachment.Path = path;
  282. float[] floatArray = this.GetFloatArray(map, "uvs", 1f);
  283. float[] floatArray2 = this.GetFloatArray(map, "vertices", 1f);
  284. List<float> list = new List<float>(floatArray.Length * 3 * 3);
  285. List<int> list2 = new List<int>(floatArray.Length * 3);
  286. float scale = this.Scale;
  287. int i = 0;
  288. int num = floatArray2.Length;
  289. while (i < num)
  290. {
  291. int num2 = (int)floatArray2[i++];
  292. list2.Add(num2);
  293. int num3 = i + num2 * 4;
  294. while (i < num3)
  295. {
  296. list2.Add((int)floatArray2[i]);
  297. list.Add(floatArray2[i + 1] * scale);
  298. list.Add(floatArray2[i + 2] * scale);
  299. list.Add(floatArray2[i + 3]);
  300. i += 4;
  301. }
  302. }
  303. skinnedMeshAttachment.bones = list2.ToArray();
  304. skinnedMeshAttachment.weights = list.ToArray();
  305. skinnedMeshAttachment.triangles = this.GetIntArray(map, "triangles");
  306. skinnedMeshAttachment.regionUVs = floatArray;
  307. skinnedMeshAttachment.UpdateUVs();
  308. if (map.ContainsKey("color"))
  309. {
  310. string hexString3 = (string)map["color"];
  311. skinnedMeshAttachment.r = this.ToColor(hexString3, 0);
  312. skinnedMeshAttachment.g = this.ToColor(hexString3, 1);
  313. skinnedMeshAttachment.b = this.ToColor(hexString3, 2);
  314. skinnedMeshAttachment.a = this.ToColor(hexString3, 3);
  315. }
  316. skinnedMeshAttachment.HullLength = this.GetInt(map, "hull", 0) * 2;
  317. if (map.ContainsKey("edges"))
  318. {
  319. skinnedMeshAttachment.Edges = this.GetIntArray(map, "edges");
  320. }
  321. skinnedMeshAttachment.Width = (float)this.GetInt(map, "width", 0) * this.Scale;
  322. skinnedMeshAttachment.Height = (float)this.GetInt(map, "height", 0) * this.Scale;
  323. return skinnedMeshAttachment;
  324. }
  325. default:
  326. return null;
  327. }
  328. }
  329. private float[] GetFloatArray(Dictionary<string, object> map, string name, float scale)
  330. {
  331. List<object> list = (List<object>)map[name];
  332. float[] array = new float[list.Count];
  333. if (scale == 1f)
  334. {
  335. int i = 0;
  336. int count = list.Count;
  337. while (i < count)
  338. {
  339. array[i] = (float)list[i];
  340. i++;
  341. }
  342. }
  343. else
  344. {
  345. int j = 0;
  346. int count2 = list.Count;
  347. while (j < count2)
  348. {
  349. array[j] = (float)list[j] * scale;
  350. j++;
  351. }
  352. }
  353. return array;
  354. }
  355. private int[] GetIntArray(Dictionary<string, object> map, string name)
  356. {
  357. List<object> list = (List<object>)map[name];
  358. int[] array = new int[list.Count];
  359. int i = 0;
  360. int count = list.Count;
  361. while (i < count)
  362. {
  363. array[i] = (int)((float)list[i]);
  364. i++;
  365. }
  366. return array;
  367. }
  368. private float GetFloat(Dictionary<string, object> map, string name, float defaultValue)
  369. {
  370. if (!map.ContainsKey(name))
  371. {
  372. return defaultValue;
  373. }
  374. return (float)map[name];
  375. }
  376. private int GetInt(Dictionary<string, object> map, string name, int defaultValue)
  377. {
  378. if (!map.ContainsKey(name))
  379. {
  380. return defaultValue;
  381. }
  382. return (int)((float)map[name]);
  383. }
  384. private bool GetBoolean(Dictionary<string, object> map, string name, bool defaultValue)
  385. {
  386. if (!map.ContainsKey(name))
  387. {
  388. return defaultValue;
  389. }
  390. return (bool)map[name];
  391. }
  392. private string GetString(Dictionary<string, object> map, string name, string defaultValue)
  393. {
  394. if (!map.ContainsKey(name))
  395. {
  396. return defaultValue;
  397. }
  398. return (string)map[name];
  399. }
  400. private float ToColor(string hexString, int colorIndex)
  401. {
  402. if (hexString.Length != 8)
  403. {
  404. throw new ArgumentException("Color hexidecimal length must be 8, recieved: " + hexString);
  405. }
  406. return (float)Convert.ToInt32(hexString.Substring(colorIndex * 2, 2), 16) / 255f;
  407. }
  408. private void ReadAnimation(string name, Dictionary<string, object> map, SkeletonData skeletonData)
  409. {
  410. List<Timeline> list = new List<Timeline>();
  411. float num = 0f;
  412. float scale = this.Scale;
  413. if (map.ContainsKey("slots"))
  414. {
  415. foreach (KeyValuePair<string, object> keyValuePair in ((Dictionary<string, object>)map["slots"]))
  416. {
  417. string key = keyValuePair.Key;
  418. int slotIndex = skeletonData.FindSlotIndex(key);
  419. Dictionary<string, object> dictionary = (Dictionary<string, object>)keyValuePair.Value;
  420. foreach (KeyValuePair<string, object> keyValuePair2 in dictionary)
  421. {
  422. List<object> list2 = (List<object>)keyValuePair2.Value;
  423. string key2 = keyValuePair2.Key;
  424. if (key2 == "color")
  425. {
  426. ColorTimeline colorTimeline = new ColorTimeline(list2.Count);
  427. colorTimeline.slotIndex = slotIndex;
  428. int num2 = 0;
  429. foreach (object obj in list2)
  430. {
  431. Dictionary<string, object> dictionary2 = (Dictionary<string, object>)obj;
  432. float time = (float)dictionary2["time"];
  433. string hexString = (string)dictionary2["color"];
  434. colorTimeline.SetFrame(num2, time, this.ToColor(hexString, 0), this.ToColor(hexString, 1), this.ToColor(hexString, 2), this.ToColor(hexString, 3));
  435. this.ReadCurve(colorTimeline, num2, dictionary2);
  436. num2++;
  437. }
  438. list.Add(colorTimeline);
  439. num = Math.Max(num, colorTimeline.frames[colorTimeline.FrameCount * 5 - 5]);
  440. }
  441. else
  442. {
  443. if (!(key2 == "attachment"))
  444. {
  445. throw new Exception(string.Concat(new string[]
  446. {
  447. "Invalid timeline type for a slot: ",
  448. key2,
  449. " (",
  450. key,
  451. ")"
  452. }));
  453. }
  454. AttachmentTimeline attachmentTimeline = new AttachmentTimeline(list2.Count);
  455. attachmentTimeline.slotIndex = slotIndex;
  456. int num3 = 0;
  457. foreach (object obj2 in list2)
  458. {
  459. Dictionary<string, object> dictionary3 = (Dictionary<string, object>)obj2;
  460. float time2 = (float)dictionary3["time"];
  461. attachmentTimeline.SetFrame(num3++, time2, (string)dictionary3["name"]);
  462. }
  463. list.Add(attachmentTimeline);
  464. num = Math.Max(num, attachmentTimeline.frames[attachmentTimeline.FrameCount - 1]);
  465. }
  466. }
  467. }
  468. }
  469. if (map.ContainsKey("bones"))
  470. {
  471. foreach (KeyValuePair<string, object> keyValuePair3 in ((Dictionary<string, object>)map["bones"]))
  472. {
  473. string key3 = keyValuePair3.Key;
  474. int num4 = skeletonData.FindBoneIndex(key3);
  475. if (num4 == -1)
  476. {
  477. throw new Exception("Bone not found: " + key3);
  478. }
  479. Dictionary<string, object> dictionary4 = (Dictionary<string, object>)keyValuePair3.Value;
  480. foreach (KeyValuePair<string, object> keyValuePair4 in dictionary4)
  481. {
  482. List<object> list3 = (List<object>)keyValuePair4.Value;
  483. string key4 = keyValuePair4.Key;
  484. if (key4 == "rotate")
  485. {
  486. RotateTimeline rotateTimeline = new RotateTimeline(list3.Count);
  487. rotateTimeline.boneIndex = num4;
  488. int num5 = 0;
  489. foreach (object obj3 in list3)
  490. {
  491. Dictionary<string, object> dictionary5 = (Dictionary<string, object>)obj3;
  492. float time3 = (float)dictionary5["time"];
  493. rotateTimeline.SetFrame(num5, time3, (float)dictionary5["angle"]);
  494. this.ReadCurve(rotateTimeline, num5, dictionary5);
  495. num5++;
  496. }
  497. list.Add(rotateTimeline);
  498. num = Math.Max(num, rotateTimeline.frames[rotateTimeline.FrameCount * 2 - 2]);
  499. }
  500. else if (key4 == "translate" || key4 == "scale")
  501. {
  502. float num6 = 1f;
  503. TranslateTimeline translateTimeline;
  504. if (key4 == "scale")
  505. {
  506. translateTimeline = new ScaleTimeline(list3.Count);
  507. }
  508. else
  509. {
  510. translateTimeline = new TranslateTimeline(list3.Count);
  511. num6 = scale;
  512. }
  513. translateTimeline.boneIndex = num4;
  514. int num7 = 0;
  515. foreach (object obj4 in list3)
  516. {
  517. Dictionary<string, object> dictionary6 = (Dictionary<string, object>)obj4;
  518. float time4 = (float)dictionary6["time"];
  519. float num8 = (!dictionary6.ContainsKey("x")) ? 0f : ((float)dictionary6["x"]);
  520. float num9 = (!dictionary6.ContainsKey("y")) ? 0f : ((float)dictionary6["y"]);
  521. translateTimeline.SetFrame(num7, time4, num8 * num6, num9 * num6);
  522. this.ReadCurve(translateTimeline, num7, dictionary6);
  523. num7++;
  524. }
  525. list.Add(translateTimeline);
  526. num = Math.Max(num, translateTimeline.frames[translateTimeline.FrameCount * 3 - 3]);
  527. }
  528. else
  529. {
  530. if (!(key4 == "flipX") && !(key4 == "flipY"))
  531. {
  532. throw new Exception(string.Concat(new string[]
  533. {
  534. "Invalid timeline type for a bone: ",
  535. key4,
  536. " (",
  537. key3,
  538. ")"
  539. }));
  540. }
  541. bool flag = key4 == "flipX";
  542. FlipXTimeline flipXTimeline = (!flag) ? new FlipYTimeline(list3.Count) : new FlipXTimeline(list3.Count);
  543. flipXTimeline.boneIndex = num4;
  544. string key5 = (!flag) ? "y" : "x";
  545. int num10 = 0;
  546. foreach (object obj5 in list3)
  547. {
  548. Dictionary<string, object> dictionary7 = (Dictionary<string, object>)obj5;
  549. float time5 = (float)dictionary7["time"];
  550. flipXTimeline.SetFrame(num10, time5, dictionary7.ContainsKey(key5) && (bool)dictionary7[key5]);
  551. num10++;
  552. }
  553. list.Add(flipXTimeline);
  554. num = Math.Max(num, flipXTimeline.frames[flipXTimeline.FrameCount * 2 - 2]);
  555. }
  556. }
  557. }
  558. }
  559. if (map.ContainsKey("ik"))
  560. {
  561. foreach (KeyValuePair<string, object> keyValuePair5 in ((Dictionary<string, object>)map["ik"]))
  562. {
  563. IkConstraintData item = skeletonData.FindIkConstraint(keyValuePair5.Key);
  564. List<object> list4 = (List<object>)keyValuePair5.Value;
  565. IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(list4.Count);
  566. ikConstraintTimeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(item);
  567. int num11 = 0;
  568. foreach (object obj6 in list4)
  569. {
  570. Dictionary<string, object> dictionary8 = (Dictionary<string, object>)obj6;
  571. float time6 = (float)dictionary8["time"];
  572. float mix = (!dictionary8.ContainsKey("mix")) ? 1f : ((float)dictionary8["mix"]);
  573. bool flag2 = !dictionary8.ContainsKey("bendPositive") || (bool)dictionary8["bendPositive"];
  574. ikConstraintTimeline.SetFrame(num11, time6, mix, (!flag2) ? -1 : 1);
  575. this.ReadCurve(ikConstraintTimeline, num11, dictionary8);
  576. num11++;
  577. }
  578. list.Add(ikConstraintTimeline);
  579. num = Math.Max(num, ikConstraintTimeline.frames[ikConstraintTimeline.FrameCount * 3 - 3]);
  580. }
  581. }
  582. if (map.ContainsKey("ffd"))
  583. {
  584. foreach (KeyValuePair<string, object> keyValuePair6 in ((Dictionary<string, object>)map["ffd"]))
  585. {
  586. Skin skin = skeletonData.FindSkin(keyValuePair6.Key);
  587. foreach (KeyValuePair<string, object> keyValuePair7 in ((Dictionary<string, object>)keyValuePair6.Value))
  588. {
  589. int slotIndex2 = skeletonData.FindSlotIndex(keyValuePair7.Key);
  590. foreach (KeyValuePair<string, object> keyValuePair8 in ((Dictionary<string, object>)keyValuePair7.Value))
  591. {
  592. List<object> list5 = (List<object>)keyValuePair8.Value;
  593. FFDTimeline ffdtimeline = new FFDTimeline(list5.Count);
  594. Attachment attachment = skin.GetAttachment(slotIndex2, keyValuePair8.Key);
  595. if (attachment == null)
  596. {
  597. throw new Exception("FFD attachment not found: " + keyValuePair8.Key);
  598. }
  599. ffdtimeline.slotIndex = slotIndex2;
  600. ffdtimeline.attachment = attachment;
  601. int num12;
  602. if (attachment is MeshAttachment)
  603. {
  604. num12 = ((MeshAttachment)attachment).vertices.Length;
  605. }
  606. else
  607. {
  608. num12 = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2;
  609. }
  610. int num13 = 0;
  611. foreach (object obj7 in list5)
  612. {
  613. Dictionary<string, object> dictionary9 = (Dictionary<string, object>)obj7;
  614. float[] array;
  615. if (!dictionary9.ContainsKey("vertices"))
  616. {
  617. if (attachment is MeshAttachment)
  618. {
  619. array = ((MeshAttachment)attachment).vertices;
  620. }
  621. else
  622. {
  623. array = new float[num12];
  624. }
  625. }
  626. else
  627. {
  628. List<object> list6 = (List<object>)dictionary9["vertices"];
  629. array = new float[num12];
  630. int @int = this.GetInt(dictionary9, "offset", 0);
  631. if (scale == 1f)
  632. {
  633. int i = 0;
  634. int count = list6.Count;
  635. while (i < count)
  636. {
  637. array[i + @int] = (float)list6[i];
  638. i++;
  639. }
  640. }
  641. else
  642. {
  643. int j = 0;
  644. int count2 = list6.Count;
  645. while (j < count2)
  646. {
  647. array[j + @int] = (float)list6[j] * scale;
  648. j++;
  649. }
  650. }
  651. if (attachment is MeshAttachment)
  652. {
  653. float[] vertices = ((MeshAttachment)attachment).vertices;
  654. for (int k = 0; k < num12; k++)
  655. {
  656. array[k] += vertices[k];
  657. }
  658. }
  659. }
  660. ffdtimeline.SetFrame(num13, (float)dictionary9["time"], array);
  661. this.ReadCurve(ffdtimeline, num13, dictionary9);
  662. num13++;
  663. }
  664. list.Add(ffdtimeline);
  665. num = Math.Max(num, ffdtimeline.frames[ffdtimeline.FrameCount - 1]);
  666. }
  667. }
  668. }
  669. }
  670. if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder"))
  671. {
  672. List<object> list7 = (List<object>)map[(!map.ContainsKey("drawOrder")) ? "draworder" : "drawOrder"];
  673. DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(list7.Count);
  674. int count3 = skeletonData.slots.Count;
  675. int num14 = 0;
  676. foreach (object obj8 in list7)
  677. {
  678. Dictionary<string, object> dictionary10 = (Dictionary<string, object>)obj8;
  679. int[] array2 = null;
  680. if (dictionary10.ContainsKey("offsets"))
  681. {
  682. array2 = new int[count3];
  683. for (int l = count3 - 1; l >= 0; l--)
  684. {
  685. array2[l] = -1;
  686. }
  687. List<object> list8 = (List<object>)dictionary10["offsets"];
  688. int[] array3 = new int[count3 - list8.Count];
  689. int m = 0;
  690. int num15 = 0;
  691. foreach (object obj9 in list8)
  692. {
  693. Dictionary<string, object> dictionary11 = (Dictionary<string, object>)obj9;
  694. int num16 = skeletonData.FindSlotIndex((string)dictionary11["slot"]);
  695. if (num16 == -1)
  696. {
  697. throw new Exception("Slot not found: " + dictionary11["slot"]);
  698. }
  699. while (m != num16)
  700. {
  701. array3[num15++] = m++;
  702. }
  703. int num17 = m + (int)((float)dictionary11["offset"]);
  704. array2[num17] = m++;
  705. }
  706. while (m < count3)
  707. {
  708. array3[num15++] = m++;
  709. }
  710. for (int n = count3 - 1; n >= 0; n--)
  711. {
  712. if (array2[n] == -1)
  713. {
  714. array2[n] = array3[--num15];
  715. }
  716. }
  717. }
  718. drawOrderTimeline.SetFrame(num14++, (float)dictionary10["time"], array2);
  719. }
  720. list.Add(drawOrderTimeline);
  721. num = Math.Max(num, drawOrderTimeline.frames[drawOrderTimeline.FrameCount - 1]);
  722. }
  723. if (map.ContainsKey("events"))
  724. {
  725. List<object> list9 = (List<object>)map["events"];
  726. EventTimeline eventTimeline = new EventTimeline(list9.Count);
  727. int num18 = 0;
  728. foreach (object obj10 in list9)
  729. {
  730. Dictionary<string, object> dictionary12 = (Dictionary<string, object>)obj10;
  731. EventData eventData = skeletonData.FindEvent((string)dictionary12["name"]);
  732. if (eventData == null)
  733. {
  734. throw new Exception("Event not found: " + dictionary12["name"]);
  735. }
  736. Event @event = new Event(eventData);
  737. @event.Int = this.GetInt(dictionary12, "int", eventData.Int);
  738. @event.Float = this.GetFloat(dictionary12, "float", eventData.Float);
  739. @event.String = this.GetString(dictionary12, "string", eventData.String);
  740. eventTimeline.SetFrame(num18++, (float)dictionary12["time"], @event);
  741. }
  742. list.Add(eventTimeline);
  743. num = Math.Max(num, eventTimeline.frames[eventTimeline.FrameCount - 1]);
  744. }
  745. list.TrimExcess();
  746. skeletonData.animations.Add(new Animation(name, list, num));
  747. }
  748. private void ReadCurve(CurveTimeline timeline, int frameIndex, Dictionary<string, object> valueMap)
  749. {
  750. if (!valueMap.ContainsKey("curve"))
  751. {
  752. return;
  753. }
  754. object obj = valueMap["curve"];
  755. if (obj.Equals("stepped"))
  756. {
  757. timeline.SetStepped(frameIndex);
  758. }
  759. else if (obj is List<object>)
  760. {
  761. List<object> list = (List<object>)obj;
  762. timeline.SetCurve(frameIndex, (float)list[0], (float)list[1], (float)list[2], (float)list[3]);
  763. }
  764. }
  765. private AttachmentLoader attachmentLoader;
  766. }
  767. }