SkeletonJson.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /******************************************************************************
  2. * Spine Runtimes Software License
  3. * Version 2
  4. *
  5. * Copyright (c) 2013, Esoteric Software
  6. * All rights reserved.
  7. *
  8. * You are granted a perpetual, non-exclusive, non-sublicensable and
  9. * non-transferable license to install, execute and perform the Spine Runtimes
  10. * Software (the "Software") solely for internal use. Without the written
  11. * permission of Esoteric Software, you may not (a) modify, translate, adapt or
  12. * otherwise create derivative works, improvements of the Software or develop
  13. * new applications using the Software or (b) remove, delete, alter or obscure
  14. * any trademarks or any copyright, trademark, patent or other intellectual
  15. * property or proprietary rights notices on or in the Software, including
  16. * any copy thereof. Redistributions in binary or source form must include
  17. * this license and terms. THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE
  18. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  19. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY
  21. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *****************************************************************************/
  28. #include <spine/SkeletonJson.h>
  29. #include <stdio.h>
  30. #include "Json.h"
  31. #include <spine/extension.h>
  32. #include <spine/RegionAttachment.h>
  33. #include <spine/AtlasAttachmentLoader.h>
  34. typedef struct {
  35. spSkeletonJson super;
  36. int ownsLoader;
  37. } _spSkeletonJson;
  38. spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader) {
  39. spSkeletonJson* self = SUPER(NEW(_spSkeletonJson));
  40. self->scale = 1;
  41. self->attachmentLoader = attachmentLoader;
  42. return self;
  43. }
  44. spSkeletonJson* spSkeletonJson_create (spAtlas* atlas) {
  45. spAtlasAttachmentLoader* attachmentLoader = spAtlasAttachmentLoader_create(atlas);
  46. spSkeletonJson* self = spSkeletonJson_createWithLoader(SUPER(attachmentLoader));
  47. SUB_CAST(_spSkeletonJson, self)->ownsLoader = 1;
  48. return self;
  49. }
  50. void spSkeletonJson_dispose (spSkeletonJson* self) {
  51. if (SUB_CAST(_spSkeletonJson, self)->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader);
  52. FREE(self->error);
  53. FREE(self);
  54. }
  55. void _spSkeletonJson_setError (spSkeletonJson* self, Json* root, const char* value1, const char* value2) {
  56. char message[256];
  57. int length;
  58. FREE(self->error);
  59. strcpy(message, value1);
  60. length = (int)strlen(value1);
  61. if (value2) strncat(message + length, value2, 256 - length);
  62. MALLOC_STR(self->error, message);
  63. if (root) Json_dispose(root);
  64. }
  65. static float toColor (const char* value, int index) {
  66. char digits[3];
  67. char *error;
  68. int color;
  69. if (strlen(value) != 8) return -1;
  70. value += index * 2;
  71. digits[0] = *value;
  72. digits[1] = *(value + 1);
  73. digits[2] = '\0';
  74. color = strtoul(digits, &error, 16);
  75. if (*error != 0) return -1;
  76. return color / (float)255;
  77. }
  78. static void readCurve (spCurveTimeline* timeline, int frameIndex, Json* frame) {
  79. Json* curve = Json_getItem(frame, "curve");
  80. if (!curve) return;
  81. if (curve->type == Json_String && strcmp(curve->valueString, "stepped") == 0)
  82. spCurveTimeline_setStepped(timeline, frameIndex);
  83. else if (curve->type == Json_Array) {
  84. Json* child0 = curve->child;
  85. Json* child1 = child0->next;
  86. Json* child2 = child1->next;
  87. Json* child3 = child2->next;
  88. spCurveTimeline_setCurve(timeline, frameIndex, child0->valueFloat, child1->valueFloat, child2->valueFloat,
  89. child3->valueFloat);
  90. }
  91. }
  92. static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* root, spSkeletonData *skeletonData) {
  93. int i;
  94. spAnimation* animation;
  95. Json* bones = Json_getItem(root, "bones");
  96. Json* slots = Json_getItem(root, "slots");
  97. Json* drawOrder = Json_getItem(root, "draworder");
  98. Json* events = Json_getItem(root, "events");
  99. Json *boneMap, *slotMap;
  100. int timelineCount = 0;
  101. for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next)
  102. timelineCount += boneMap->size;
  103. for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next)
  104. timelineCount += slotMap->size;
  105. if (events) ++timelineCount;
  106. if (drawOrder) ++timelineCount;
  107. animation = spAnimation_create(root->name, timelineCount);
  108. animation->timelineCount = 0;
  109. skeletonData->animations[skeletonData->animationCount] = animation;
  110. ++skeletonData->animationCount;
  111. for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next) {
  112. Json *timelineArray;
  113. int boneIndex = spSkeletonData_findBoneIndex(skeletonData, boneMap->name);
  114. if (boneIndex == -1) {
  115. spAnimation_dispose(animation);
  116. _spSkeletonJson_setError(self, root, "spBone not found: ", boneMap->name);
  117. return 0;
  118. }
  119. for (timelineArray = boneMap->child; timelineArray; timelineArray = timelineArray->next) {
  120. Json* frame;
  121. float duration;
  122. if (strcmp(timelineArray->name, "rotate") == 0) {
  123. spRotateTimeline *timeline = spRotateTimeline_create(timelineArray->size);
  124. timeline->boneIndex = boneIndex;
  125. for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i) {
  126. spRotateTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), Json_getFloat(frame, "angle", 0));
  127. readCurve(SUPER(timeline), i, frame);
  128. }
  129. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  130. duration = timeline->frames[timelineArray->size * 2 - 2];
  131. if (duration > animation->duration) animation->duration = duration;
  132. } else {
  133. int isScale = strcmp(timelineArray->name, "scale") == 0;
  134. if (isScale || strcmp(timelineArray->name, "translate") == 0) {
  135. float scale = isScale ? 1 : self->scale;
  136. spTranslateTimeline *timeline =
  137. isScale ? spScaleTimeline_create(timelineArray->size) : spTranslateTimeline_create(timelineArray->size);
  138. timeline->boneIndex = boneIndex;
  139. for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i) {
  140. spTranslateTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), Json_getFloat(frame, "x", 0) * scale,
  141. Json_getFloat(frame, "y", 0) * scale);
  142. readCurve(SUPER(timeline), i, frame);
  143. }
  144. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  145. duration = timeline->frames[timelineArray->size * 3 - 3];
  146. if (duration > animation->duration) animation->duration = duration;
  147. } else {
  148. spAnimation_dispose(animation);
  149. _spSkeletonJson_setError(self, 0, "Invalid timeline type for a bone: ", timelineArray->name);
  150. return 0;
  151. }
  152. }
  153. }
  154. }
  155. for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next) {
  156. Json *timelineArray;
  157. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, slotMap->name);
  158. if (slotIndex == -1) {
  159. spAnimation_dispose(animation);
  160. _spSkeletonJson_setError(self, root, "Slot not found: ", slotMap->name);
  161. return 0;
  162. }
  163. for (timelineArray = slotMap->child; timelineArray; timelineArray = timelineArray->next) {
  164. Json* frame;
  165. float duration;
  166. if (strcmp(timelineArray->name, "color") == 0) {
  167. spColorTimeline *timeline = spColorTimeline_create(timelineArray->size);
  168. timeline->slotIndex = slotIndex;
  169. for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i) {
  170. const char* s = Json_getString(frame, "color", 0);
  171. spColorTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), toColor(s, 0), toColor(s, 1), toColor(s, 2),
  172. toColor(s, 3));
  173. readCurve(SUPER(timeline), i, frame);
  174. }
  175. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  176. duration = timeline->frames[timelineArray->size * 5 - 5];
  177. if (duration > animation->duration) animation->duration = duration;
  178. } else if (strcmp(timelineArray->name, "attachment") == 0) {
  179. spAttachmentTimeline *timeline = spAttachmentTimeline_create(timelineArray->size);
  180. timeline->slotIndex = slotIndex;
  181. for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i) {
  182. Json* name = Json_getItem(frame, "name");
  183. spAttachmentTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0),
  184. name->type == Json_NULL ? 0 : name->valueString);
  185. }
  186. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  187. duration = timeline->frames[timelineArray->size - 1];
  188. if (duration > animation->duration) animation->duration = duration;
  189. } else {
  190. spAnimation_dispose(animation);
  191. _spSkeletonJson_setError(self, 0, "Invalid timeline type for a slot: ", timelineArray->name);
  192. return 0;
  193. }
  194. }
  195. }
  196. if (events) {
  197. Json* frame;
  198. float duration;
  199. spEventTimeline* timeline = spEventTimeline_create(events->size);
  200. for (frame = events->child, i = 0; frame; frame = frame->next, ++i) {
  201. spEvent* event;
  202. const char* stringValue;
  203. spEventData* eventData = spSkeletonData_findEvent(skeletonData, Json_getString(frame, "name", 0));
  204. if (!eventData) {
  205. spAnimation_dispose(animation);
  206. _spSkeletonJson_setError(self, 0, "Event not found: ", Json_getString(frame, "name", 0));
  207. return 0;
  208. }
  209. event = spEvent_create(eventData);
  210. event->intValue = Json_getInt(frame, "int", eventData->intValue);
  211. event->floatValue = Json_getFloat(frame, "float", eventData->floatValue);
  212. stringValue = Json_getString(frame, "string", eventData->stringValue);
  213. if (stringValue) MALLOC_STR(event->stringValue, stringValue);
  214. spEventTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), event);
  215. }
  216. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  217. duration = timeline->frames[events->size - 1];
  218. if (duration > animation->duration) animation->duration = duration;
  219. }
  220. if (drawOrder) {
  221. Json* frame;
  222. float duration;
  223. spDrawOrderTimeline* timeline = spDrawOrderTimeline_create(drawOrder->size, skeletonData->slotCount);
  224. for (frame = drawOrder->child, i = 0; frame; frame = frame->next, ++i) {
  225. int ii;
  226. int* drawOrder = 0;
  227. Json* offsets = Json_getItem(frame, "offsets");
  228. if (offsets) {
  229. Json* offsetMap;
  230. int* unchanged = MALLOC(int, skeletonData->slotCount - offsets->size);
  231. int originalIndex = 0, unchangedIndex = 0;
  232. drawOrder = MALLOC(int, skeletonData->slotCount);
  233. for (ii = skeletonData->slotCount - 1; ii >= 0; --ii)
  234. drawOrder[ii] = -1;
  235. for (offsetMap = offsets->child; offsetMap; offsetMap = offsetMap->next) {
  236. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, Json_getString(offsetMap, "slot", 0));
  237. if (slotIndex == -1) {
  238. spAnimation_dispose(animation);
  239. _spSkeletonJson_setError(self, 0, "Slot not found: ", Json_getString(offsetMap, "slot", 0));
  240. return 0;
  241. }
  242. /* Collect unchanged items. */
  243. while (originalIndex != slotIndex)
  244. unchanged[unchangedIndex++] = originalIndex++;
  245. /* Set changed items. */
  246. drawOrder[originalIndex + Json_getInt(offsetMap, "offset", 0)] = originalIndex;
  247. ++originalIndex;
  248. }
  249. /* Collect remaining unchanged items. */
  250. while (originalIndex < skeletonData->slotCount)
  251. unchanged[unchangedIndex++] = originalIndex++;
  252. /* Fill in unchanged items. */
  253. for (ii = skeletonData->slotCount - 1; ii >= 0; ii--)
  254. if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
  255. FREE(unchanged);
  256. }
  257. spDrawOrderTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), drawOrder);
  258. FREE(drawOrder);
  259. }
  260. animation->timelines[animation->timelineCount++] = (spTimeline*)timeline;
  261. duration = timeline->frames[drawOrder->size - 1];
  262. if (duration > animation->duration) animation->duration = duration;
  263. }
  264. return animation;
  265. }
  266. spSkeletonData* spSkeletonJson_readSkeletonDataFile (spSkeletonJson* self, const char* path) {
  267. int length;
  268. spSkeletonData* skeletonData;
  269. const char* json = _spUtil_readFile(path, &length);
  270. if (!json) {
  271. _spSkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
  272. return 0;
  273. }
  274. skeletonData = spSkeletonJson_readSkeletonData(self, json);
  275. FREE(json);
  276. return skeletonData;
  277. }
  278. spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const char* json) {
  279. int i;
  280. spSkeletonData* skeletonData;
  281. Json *root, *bones, *boneMap, *slots, *skins, *animations, *events;
  282. FREE(self->error);
  283. CONST_CAST(char*, self->error) = 0;
  284. root = Json_create(json);
  285. if (!root) {
  286. _spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
  287. return 0;
  288. }
  289. skeletonData = spSkeletonData_create();
  290. bones = Json_getItem(root, "bones");
  291. skeletonData->bones = MALLOC(spBoneData*, bones->size);
  292. for (boneMap = bones->child, i = 0; boneMap; boneMap = boneMap->next, ++i) {
  293. spBoneData* boneData;
  294. spBoneData* parent = 0;
  295. const char* parentName = Json_getString(boneMap, "parent", 0);
  296. if (parentName) {
  297. parent = spSkeletonData_findBone(skeletonData, parentName);
  298. if (!parent) {
  299. spSkeletonData_dispose(skeletonData);
  300. _spSkeletonJson_setError(self, root, "Parent bone not found: ", parentName);
  301. return 0;
  302. }
  303. }
  304. boneData = spBoneData_create(Json_getString(boneMap, "name", 0), parent);
  305. boneData->length = Json_getFloat(boneMap, "length", 0) * self->scale;
  306. boneData->x = Json_getFloat(boneMap, "x", 0) * self->scale;
  307. boneData->y = Json_getFloat(boneMap, "y", 0) * self->scale;
  308. boneData->rotation = Json_getFloat(boneMap, "rotation", 0);
  309. boneData->scaleX = Json_getFloat(boneMap, "scaleX", 1);
  310. boneData->scaleY = Json_getFloat(boneMap, "scaleY", 1);
  311. boneData->inheritScale = Json_getInt(boneMap, "inheritScale", 1);
  312. boneData->inheritRotation = Json_getInt(boneMap, "inheritRotation", 1);
  313. skeletonData->bones[i] = boneData;
  314. ++skeletonData->boneCount;
  315. }
  316. slots = Json_getItem(root, "slots");
  317. if (slots) {
  318. Json *slotMap;
  319. skeletonData->slots = MALLOC(spSlotData*, slots->size);
  320. for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
  321. spSlotData* slotData;
  322. const char* color;
  323. Json *attachmentItem;
  324. const char* boneName = Json_getString(slotMap, "bone", 0);
  325. spBoneData* boneData = spSkeletonData_findBone(skeletonData, boneName);
  326. if (!boneData) {
  327. spSkeletonData_dispose(skeletonData);
  328. _spSkeletonJson_setError(self, root, "spSlot bone not found: ", boneName);
  329. return 0;
  330. }
  331. slotData = spSlotData_create(Json_getString(slotMap, "name", 0), boneData);
  332. color = Json_getString(slotMap, "color", 0);
  333. if (color) {
  334. slotData->r = toColor(color, 0);
  335. slotData->g = toColor(color, 1);
  336. slotData->b = toColor(color, 2);
  337. slotData->a = toColor(color, 3);
  338. }
  339. attachmentItem = Json_getItem(slotMap, "attachment");
  340. if (attachmentItem) spSlotData_setAttachmentName(slotData, attachmentItem->valueString);
  341. slotData->additiveBlending = Json_getInt(slotMap, "additive", 0);
  342. skeletonData->slots[i] = slotData;
  343. ++skeletonData->slotCount;
  344. }
  345. }
  346. skins = Json_getItem(root, "skins");
  347. if (skins) {
  348. Json *slotMap;
  349. skeletonData->skins = MALLOC(spSkin*, skins->size);
  350. for (slotMap = skins->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
  351. Json *attachmentsMap;
  352. spSkin *skin = spSkin_create(slotMap->name);
  353. skeletonData->skins[i] = skin;
  354. ++skeletonData->skinCount;
  355. if (strcmp(slotMap->name, "default") == 0) skeletonData->defaultSkin = skin;
  356. for (attachmentsMap = slotMap->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
  357. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, attachmentsMap->name);
  358. Json *attachmentMap;
  359. for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
  360. spAttachment* attachment;
  361. const char* skinAttachmentName = attachmentMap->name;
  362. const char* attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
  363. const char* typeString = Json_getString(attachmentMap, "type", "region");
  364. spAttachmentType type;
  365. if (strcmp(typeString, "region") == 0)
  366. type = ATTACHMENT_REGION;
  367. else if (strcmp(typeString, "boundingbox") == 0)
  368. type = ATTACHMENT_BOUNDING_BOX;
  369. else if (strcmp(typeString, "regionsequence") == 0)
  370. type = ATTACHMENT_REGION_SEQUENCE;
  371. else {
  372. spSkeletonData_dispose(skeletonData);
  373. _spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
  374. return 0;
  375. }
  376. attachment = spAttachmentLoader_newAttachment(self->attachmentLoader, skin, type, attachmentName);
  377. if (!attachment) {
  378. if (self->attachmentLoader->error1) {
  379. spSkeletonData_dispose(skeletonData);
  380. _spSkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2);
  381. return 0;
  382. }
  383. continue;
  384. }
  385. switch (attachment->type) {
  386. case ATTACHMENT_REGION:
  387. case ATTACHMENT_REGION_SEQUENCE: {
  388. spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;
  389. regionAttachment->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
  390. regionAttachment->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
  391. regionAttachment->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
  392. regionAttachment->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
  393. regionAttachment->rotation = Json_getFloat(attachmentMap, "rotation", 0);
  394. regionAttachment->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
  395. regionAttachment->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
  396. spRegionAttachment_updateOffset(regionAttachment);
  397. break;
  398. }
  399. case ATTACHMENT_BOUNDING_BOX: {
  400. spBoundingBoxAttachment* box = (spBoundingBoxAttachment*)attachment;
  401. Json* verticesArray = Json_getItem(attachmentMap, "vertices");
  402. Json* vertex;
  403. int i;
  404. box->verticesCount = verticesArray->size;
  405. box->vertices = MALLOC(float, verticesArray->size);
  406. for (vertex = verticesArray->child, i = 0; vertex; vertex = vertex->next, ++i)
  407. box->vertices[i] = vertex->valueFloat * self->scale;
  408. break;
  409. }
  410. }
  411. spSkin_addAttachment(skin, slotIndex, skinAttachmentName, attachment);
  412. }
  413. }
  414. }
  415. }
  416. /* Events. */
  417. events = Json_getItem(root, "events");
  418. if (events) {
  419. Json *eventMap;
  420. const char* stringValue;
  421. skeletonData->events = MALLOC(spEventData*, events->size);
  422. for (eventMap = events->child; eventMap; eventMap = eventMap->next) {
  423. spEventData* eventData = spEventData_create(eventMap->name);
  424. eventData->intValue = Json_getInt(eventMap, "int", 0);
  425. eventData->floatValue = Json_getFloat(eventMap, "float", 0);
  426. stringValue = Json_getString(eventMap, "string", 0);
  427. if (stringValue) MALLOC_STR(eventData->stringValue, stringValue);
  428. skeletonData->events[skeletonData->eventCount++] = eventData;
  429. }
  430. }
  431. /* Animations. */
  432. animations = Json_getItem(root, "animations");
  433. if (animations) {
  434. Json *animationMap;
  435. skeletonData->animations = MALLOC(spAnimation*, animations->size);
  436. for (animationMap = animations->child; animationMap; animationMap = animationMap->next)
  437. _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
  438. }
  439. Json_dispose(root);
  440. return skeletonData;
  441. }