1
0

SkeletonJson.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. /******************************************************************************
  2. * Spine Runtimes Software License v2.5
  3. *
  4. * Copyright (c) 2013-2016, Esoteric Software
  5. * All rights reserved.
  6. *
  7. * You are granted a perpetual, non-exclusive, non-sublicensable, and
  8. * non-transferable license to use, install, execute, and perform the Spine
  9. * Runtimes software and derivative works solely for personal or internal
  10. * use. Without the written permission of Esoteric Software (see Section 2 of
  11. * the Spine Software License Agreement), you may not (a) modify, translate,
  12. * adapt, or develop new applications using the Spine Runtimes or otherwise
  13. * create derivative works or improvements of the Spine Runtimes or (b) remove,
  14. * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
  15. * or other intellectual property or proprietary rights notices on or in the
  16. * Software, including any copy thereof. Redistributions in binary or source
  17. * form must include this license and terms.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
  25. * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  26. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *****************************************************************************/
  30. #include <spine/SkeletonJson.h>
  31. #include <stdio.h>
  32. #include <locale.h>
  33. #include "Json.h"
  34. #include <spine/extension.h>
  35. #include <spine/AtlasAttachmentLoader.h>
  36. #include <spine/Animation.h>
  37. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
  38. #define strdup _strdup
  39. #endif
  40. typedef struct {
  41. const char* parent;
  42. const char* skin;
  43. int slotIndex;
  44. spMeshAttachment* mesh;
  45. } _spLinkedMesh;
  46. typedef struct {
  47. spSkeletonJson super;
  48. int ownsLoader;
  49. int linkedMeshCount;
  50. int linkedMeshCapacity;
  51. _spLinkedMesh* linkedMeshes;
  52. } _spSkeletonJson;
  53. spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader) {
  54. spSkeletonJson* self = SUPER(NEW(_spSkeletonJson));
  55. self->scale = 1;
  56. self->attachmentLoader = attachmentLoader;
  57. return self;
  58. }
  59. spSkeletonJson* spSkeletonJson_create (spAtlas* atlas) {
  60. spAtlasAttachmentLoader* attachmentLoader = spAtlasAttachmentLoader_create(atlas);
  61. spSkeletonJson* self = spSkeletonJson_createWithLoader(SUPER(attachmentLoader));
  62. SUB_CAST(_spSkeletonJson, self)->ownsLoader = 1;
  63. return self;
  64. }
  65. void spSkeletonJson_dispose (spSkeletonJson* self) {
  66. _spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
  67. if (internal->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader);
  68. FREE(internal->linkedMeshes);
  69. FREE(self->error);
  70. FREE(self);
  71. }
  72. void _spSkeletonJson_setError (spSkeletonJson* self, Json* root, const char* value1, const char* value2) {
  73. char message[256];
  74. int length;
  75. FREE(self->error);
  76. strcpy(message, value1);
  77. length = (int)strlen(value1);
  78. if (value2) strncat(message + length, value2, 255 - length);
  79. MALLOC_STR(self->error, message);
  80. if (root) Json_dispose(root);
  81. }
  82. static float toColor (const char* value, int index) {
  83. char digits[3];
  84. char *error;
  85. int color;
  86. if (strlen(value) != 8) return -1;
  87. value += index * 2;
  88. digits[0] = *value;
  89. digits[1] = *(value + 1);
  90. digits[2] = '\0';
  91. color = (int)strtoul(digits, &error, 16);
  92. if (*error != 0) return -1;
  93. return color / (float)255;
  94. }
  95. static void readCurve (Json* frame, spCurveTimeline* timeline, int frameIndex) {
  96. Json* curve = Json_getItem(frame, "curve");
  97. if (!curve) return;
  98. if (curve->type == Json_String && strcmp(curve->valueString, "stepped") == 0)
  99. spCurveTimeline_setStepped(timeline, frameIndex);
  100. else if (curve->type == Json_Array) {
  101. Json* child0 = curve->child;
  102. Json* child1 = child0->next;
  103. Json* child2 = child1->next;
  104. Json* child3 = child2->next;
  105. spCurveTimeline_setCurve(timeline, frameIndex, child0->valueFloat, child1->valueFloat, child2->valueFloat,
  106. child3->valueFloat);
  107. }
  108. }
  109. static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spMeshAttachment* mesh, const char* skin, int slotIndex,
  110. const char* parent) {
  111. _spLinkedMesh* linkedMesh;
  112. _spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
  113. if (internal->linkedMeshCount == internal->linkedMeshCapacity) {
  114. _spLinkedMesh* linkedMeshes;
  115. internal->linkedMeshCapacity *= 2;
  116. if (internal->linkedMeshCapacity < 8) internal->linkedMeshCapacity = 8;
  117. linkedMeshes = MALLOC(_spLinkedMesh, internal->linkedMeshCapacity);
  118. memcpy(linkedMeshes, internal->linkedMeshes, sizeof(_spLinkedMesh) * internal->linkedMeshCount);
  119. FREE(internal->linkedMeshes);
  120. internal->linkedMeshes = linkedMeshes;
  121. }
  122. linkedMesh = internal->linkedMeshes + internal->linkedMeshCount++;
  123. linkedMesh->mesh = mesh;
  124. linkedMesh->skin = skin;
  125. linkedMesh->slotIndex = slotIndex;
  126. linkedMesh->parent = parent;
  127. }
  128. static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* root, spSkeletonData *skeletonData) {
  129. int frameIndex;
  130. spAnimation* animation;
  131. Json* valueMap;
  132. int timelinesCount = 0;
  133. Json* bones = Json_getItem(root, "bones");
  134. Json* slots = Json_getItem(root, "slots");
  135. Json* ik = Json_getItem(root, "ik");
  136. Json* transform = Json_getItem(root, "transform");
  137. Json* paths = Json_getItem(root, "paths");
  138. Json* deform = Json_getItem(root, "deform");
  139. Json* drawOrder = Json_getItem(root, "drawOrder");
  140. Json* events = Json_getItem(root, "events");
  141. Json *boneMap, *slotMap, *constraintMap;
  142. if (!drawOrder) drawOrder = Json_getItem(root, "draworder");
  143. for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next)
  144. timelinesCount += boneMap->size;
  145. for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next)
  146. timelinesCount += slotMap->size;
  147. timelinesCount += ik ? ik->size : 0;
  148. timelinesCount += transform ? transform->size : 0;
  149. for (constraintMap = paths ? paths->child : 0; constraintMap; constraintMap = constraintMap->next)
  150. timelinesCount += constraintMap->size;
  151. for (constraintMap = deform ? deform->child : 0; constraintMap; constraintMap = constraintMap->next)
  152. for (slotMap = constraintMap->child; slotMap; slotMap = slotMap->next)
  153. timelinesCount += slotMap->size;
  154. if (drawOrder) ++timelinesCount;
  155. if (events) ++timelinesCount;
  156. animation = spAnimation_create(root->name, timelinesCount);
  157. animation->timelinesCount = 0;
  158. /* Slot timelines. */
  159. for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next) {
  160. Json *timelineMap;
  161. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, slotMap->name);
  162. if (slotIndex == -1) {
  163. spAnimation_dispose(animation);
  164. _spSkeletonJson_setError(self, root, "Slot not found: ", slotMap->name);
  165. return 0;
  166. }
  167. for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) {
  168. if (strcmp(timelineMap->name, "color") == 0) {
  169. spColorTimeline *timeline = spColorTimeline_create(timelineMap->size);
  170. timeline->slotIndex = slotIndex;
  171. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  172. const char* s = Json_getString(valueMap, "color", 0);
  173. spColorTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), toColor(s, 0), toColor(s, 1), toColor(s, 2),
  174. toColor(s, 3));
  175. readCurve(valueMap, SUPER(timeline), frameIndex);
  176. }
  177. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  178. animation->duration = MAX(animation->duration, timeline->frames[(timelineMap->size - 1) * COLOR_ENTRIES]);
  179. } else if (strcmp(timelineMap->name, "attachment") == 0) {
  180. spAttachmentTimeline *timeline = spAttachmentTimeline_create(timelineMap->size);
  181. timeline->slotIndex = slotIndex;
  182. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  183. Json* name = Json_getItem(valueMap, "name");
  184. spAttachmentTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
  185. name->type == Json_NULL ? 0 : name->valueString);
  186. }
  187. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  188. animation->duration = MAX(animation->duration, timeline->frames[timelineMap->size - 1]);
  189. } else {
  190. spAnimation_dispose(animation);
  191. _spSkeletonJson_setError(self, 0, "Invalid timeline type for a slot: ", timelineMap->name);
  192. return 0;
  193. }
  194. }
  195. }
  196. /* Bone timelines. */
  197. for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next) {
  198. Json *timelineMap;
  199. int boneIndex = spSkeletonData_findBoneIndex(skeletonData, boneMap->name);
  200. if (boneIndex == -1) {
  201. spAnimation_dispose(animation);
  202. _spSkeletonJson_setError(self, root, "Bone not found: ", boneMap->name);
  203. return 0;
  204. }
  205. for (timelineMap = boneMap->child; timelineMap; timelineMap = timelineMap->next) {
  206. if (strcmp(timelineMap->name, "rotate") == 0) {
  207. spRotateTimeline *timeline = spRotateTimeline_create(timelineMap->size);
  208. timeline->boneIndex = boneIndex;
  209. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  210. spRotateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "angle", 0));
  211. readCurve(valueMap, SUPER(timeline), frameIndex);
  212. }
  213. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  214. animation->duration = MAX(animation->duration, timeline->frames[(timelineMap->size - 1) * ROTATE_ENTRIES]);
  215. } else {
  216. int isScale = strcmp(timelineMap->name, "scale") == 0;
  217. int isTranslate = strcmp(timelineMap->name, "translate") == 0;
  218. int isShear = strcmp(timelineMap->name, "shear") == 0;
  219. if (isScale || isTranslate || isShear) {
  220. float timelineScale = isTranslate ? self->scale: 1;
  221. spTranslateTimeline *timeline = 0;
  222. if (isScale) timeline = spScaleTimeline_create(timelineMap->size);
  223. else if (isTranslate) timeline = spTranslateTimeline_create(timelineMap->size);
  224. else if (isShear) timeline = spShearTimeline_create(timelineMap->size);
  225. timeline->boneIndex = boneIndex;
  226. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  227. spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "x", 0) * timelineScale,
  228. Json_getFloat(valueMap, "y", 0) * timelineScale);
  229. readCurve(valueMap, SUPER(timeline), frameIndex);
  230. }
  231. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  232. animation->duration = MAX(animation->duration, timeline->frames[(timelineMap->size - 1) * TRANSLATE_ENTRIES]);
  233. } else {
  234. spAnimation_dispose(animation);
  235. _spSkeletonJson_setError(self, 0, "Invalid timeline type for a bone: ", timelineMap->name);
  236. return 0;
  237. }
  238. }
  239. }
  240. }
  241. /* IK constraint timelines. */
  242. for (constraintMap = ik ? ik->child : 0; constraintMap; constraintMap = constraintMap->next) {
  243. spIkConstraintData* constraint = spSkeletonData_findIkConstraint(skeletonData, constraintMap->name);
  244. spIkConstraintTimeline* timeline = spIkConstraintTimeline_create(constraintMap->size);
  245. for (frameIndex = 0; frameIndex < skeletonData->ikConstraintsCount; ++frameIndex) {
  246. if (constraint == skeletonData->ikConstraints[frameIndex]) {
  247. timeline->ikConstraintIndex = frameIndex;
  248. break;
  249. }
  250. }
  251. for (valueMap = constraintMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  252. spIkConstraintTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "mix", 1),
  253. Json_getInt(valueMap, "bendPositive", 1) ? 1 : -1);
  254. readCurve(valueMap, SUPER(timeline), frameIndex);
  255. }
  256. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  257. animation->duration = MAX(animation->duration, timeline->frames[(constraintMap->size - 1) * IKCONSTRAINT_ENTRIES]);
  258. }
  259. /* Transform constraint timelines. */
  260. for (constraintMap = transform ? transform->child : 0; constraintMap; constraintMap = constraintMap->next) {
  261. spTransformConstraintData* constraint = spSkeletonData_findTransformConstraint(skeletonData, constraintMap->name);
  262. spTransformConstraintTimeline* timeline = spTransformConstraintTimeline_create(constraintMap->size);
  263. for (frameIndex = 0; frameIndex < skeletonData->transformConstraintsCount; ++frameIndex) {
  264. if (constraint == skeletonData->transformConstraints[frameIndex]) {
  265. timeline->transformConstraintIndex = frameIndex;
  266. break;
  267. }
  268. }
  269. for (valueMap = constraintMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  270. spTransformConstraintTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "rotateMix", 1),
  271. Json_getFloat(valueMap, "translateMix", 1), Json_getFloat(valueMap, "scaleMix", 1), Json_getFloat(valueMap, "shearMix", 1));
  272. readCurve(valueMap, SUPER(timeline), frameIndex);
  273. }
  274. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  275. animation->duration = MAX(animation->duration, timeline->frames[(constraintMap->size - 1) * TRANSFORMCONSTRAINT_ENTRIES]);
  276. }
  277. /** Path constraint timelines. */
  278. for(constraintMap = paths ? paths->child : 0; constraintMap; constraintMap = constraintMap->next ) {
  279. int constraintIndex, i;
  280. Json* timelineMap;
  281. spPathConstraintData* data = spSkeletonData_findPathConstraint(skeletonData, constraintMap->name);
  282. if (!data) {
  283. spAnimation_dispose(animation);
  284. _spSkeletonJson_setError(self, root, "Path constraint not found: ", constraintMap->name);
  285. return 0;
  286. }
  287. for (i = 0; i < skeletonData->pathConstraintsCount; i++) {
  288. if (skeletonData->pathConstraints[i] == data) {
  289. constraintIndex = i;
  290. break;
  291. }
  292. }
  293. for (timelineMap = constraintMap->child; timelineMap; timelineMap = timelineMap->next) {
  294. const char* timelineName = timelineMap->name;
  295. if (strcmp(timelineName, "position") == 0 || strcmp(timelineName, "spacing") == 0) {
  296. spPathConstraintPositionTimeline* timeline;
  297. float timelineScale = 1;
  298. if (strcmp(timelineName, "spacing") == 0) {
  299. timeline = (spPathConstraintPositionTimeline*)spPathConstraintSpacingTimeline_create(timelineMap->size);
  300. if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) timelineScale = self->scale;
  301. } else {
  302. timeline = spPathConstraintPositionTimeline_create(timelineMap->size);
  303. if (data->positionMode == SP_POSITION_MODE_FIXED) timelineScale = self->scale;
  304. }
  305. timeline->pathConstraintIndex = constraintIndex;
  306. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  307. spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, timelineName, 0) * timelineScale);
  308. readCurve(valueMap, SUPER(timeline), frameIndex);
  309. }
  310. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  311. animation->duration = MAX(animation->duration, timeline->frames[(timelineMap->size - 1) * PATHCONSTRAINTPOSITION_ENTRIES]);
  312. } else if (strcmp(timelineName, "mix")) {
  313. spPathConstraintMixTimeline* timeline = spPathConstraintMixTimeline_create(timelineMap->size);
  314. timeline->pathConstraintIndex = constraintIndex;
  315. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  316. spPathConstraintMixTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
  317. Json_getFloat(valueMap, "rotateMix", 1), Json_getFloat(valueMap, "translateMix", 1));
  318. readCurve(valueMap, SUPER(timeline), frameIndex);
  319. }
  320. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  321. animation->duration = MAX(animation->duration, timeline->frames[(timelineMap->size - 1) * PATHCONSTRAINTMIX_ENTRIES]);
  322. }
  323. }
  324. }
  325. /* Deform timelines. */
  326. for (constraintMap = deform ? deform->child : 0; constraintMap; constraintMap = constraintMap->next) {
  327. spSkin* skin = spSkeletonData_findSkin(skeletonData, constraintMap->name);
  328. for (slotMap = constraintMap->child; slotMap; slotMap = slotMap->next) {
  329. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, slotMap->name);
  330. Json* timelineMap;
  331. for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) {
  332. float* tempDeform;
  333. spDeformTimeline *timeline;
  334. int weighted, deformLength;
  335. spVertexAttachment* attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, timelineMap->name));
  336. if (!attachment) {
  337. spAnimation_dispose(animation);
  338. _spSkeletonJson_setError(self, 0, "Attachment not found: ", timelineMap->name);
  339. return 0;
  340. }
  341. weighted = attachment->bones != 0;
  342. deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
  343. tempDeform = MALLOC(float, deformLength);
  344. timeline = spDeformTimeline_create(timelineMap->size, deformLength);
  345. timeline->slotIndex = slotIndex;
  346. timeline->attachment = SUPER(attachment);
  347. for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  348. Json* vertices = Json_getItem(valueMap, "vertices");
  349. float* deform;
  350. if (!vertices) {
  351. if (weighted) {
  352. deform = tempDeform;
  353. memset(deform, 0, sizeof(float) * deformLength);
  354. } else
  355. deform = attachment->vertices;
  356. } else {
  357. int v, start = Json_getInt(valueMap, "offset", 0);
  358. Json* vertex;
  359. deform = tempDeform;
  360. memset(deform, 0, sizeof(float) * start);
  361. if (self->scale == 1) {
  362. for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
  363. deform[v] = vertex->valueFloat;
  364. } else {
  365. for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
  366. deform[v] = vertex->valueFloat * self->scale;
  367. }
  368. memset(deform + v, 0, sizeof(float) * (deformLength - v));
  369. if (!weighted) {
  370. float* vertices = attachment->vertices;
  371. for (v = 0; v < deformLength; ++v)
  372. deform[v] += vertices[v];
  373. }
  374. }
  375. spDeformTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), deform);
  376. readCurve(valueMap, SUPER(timeline), frameIndex);
  377. }
  378. FREE(tempDeform);
  379. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  380. animation->duration = MAX(animation->duration, timeline->frames[timelineMap->size - 1]);
  381. }
  382. }
  383. }
  384. /* Draw order timeline. */
  385. if (drawOrder) {
  386. spDrawOrderTimeline* timeline = spDrawOrderTimeline_create(drawOrder->size, skeletonData->slotsCount);
  387. for (valueMap = drawOrder->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  388. int ii;
  389. int* drawOrder = 0;
  390. Json* offsets = Json_getItem(valueMap, "offsets");
  391. if (offsets) {
  392. Json* offsetMap;
  393. int* unchanged = MALLOC(int, skeletonData->slotsCount - offsets->size);
  394. int originalIndex = 0, unchangedIndex = 0;
  395. drawOrder = MALLOC(int, skeletonData->slotsCount);
  396. for (ii = skeletonData->slotsCount - 1; ii >= 0; --ii)
  397. drawOrder[ii] = -1;
  398. for (offsetMap = offsets->child; offsetMap; offsetMap = offsetMap->next) {
  399. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, Json_getString(offsetMap, "slot", 0));
  400. if (slotIndex == -1) {
  401. spAnimation_dispose(animation);
  402. _spSkeletonJson_setError(self, 0, "Slot not found: ", Json_getString(offsetMap, "slot", 0));
  403. return 0;
  404. }
  405. /* Collect unchanged items. */
  406. while (originalIndex != slotIndex)
  407. unchanged[unchangedIndex++] = originalIndex++;
  408. /* Set changed items. */
  409. drawOrder[originalIndex + Json_getInt(offsetMap, "offset", 0)] = originalIndex;
  410. originalIndex++;
  411. }
  412. /* Collect remaining unchanged items. */
  413. while (originalIndex < skeletonData->slotsCount)
  414. unchanged[unchangedIndex++] = originalIndex++;
  415. /* Fill in unchanged items. */
  416. for (ii = skeletonData->slotsCount - 1; ii >= 0; ii--)
  417. if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
  418. FREE(unchanged);
  419. }
  420. spDrawOrderTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), drawOrder);
  421. FREE(drawOrder);
  422. }
  423. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  424. animation->duration = MAX(animation->duration, timeline->frames[drawOrder->size - 1]);
  425. }
  426. /* Event timeline. */
  427. if (events) {
  428. spEventTimeline* timeline = spEventTimeline_create(events->size);
  429. for (valueMap = events->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
  430. spEvent* event;
  431. const char* stringValue;
  432. spEventData* eventData = spSkeletonData_findEvent(skeletonData, Json_getString(valueMap, "name", 0));
  433. if (!eventData) {
  434. spAnimation_dispose(animation);
  435. _spSkeletonJson_setError(self, 0, "Event not found: ", Json_getString(valueMap, "name", 0));
  436. return 0;
  437. }
  438. event = spEvent_create(Json_getFloat(valueMap, "time", 0), eventData);
  439. event->intValue = Json_getInt(valueMap, "int", eventData->intValue);
  440. event->floatValue = Json_getFloat(valueMap, "float", eventData->floatValue);
  441. stringValue = Json_getString(valueMap, "string", eventData->stringValue);
  442. if (stringValue) MALLOC_STR(event->stringValue, stringValue);
  443. spEventTimeline_setFrame(timeline, frameIndex, event);
  444. }
  445. animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
  446. animation->duration = MAX(animation->duration, timeline->frames[events->size - 1]);
  447. }
  448. return animation;
  449. }
  450. static void _readVertices (spSkeletonJson* self, Json* attachmentMap, spVertexAttachment* attachment, int verticesLength) {
  451. Json* entry;
  452. float* vertices;
  453. int i, b, w, nn, entrySize;
  454. attachment->worldVerticesLength = verticesLength;
  455. entry = Json_getItem(attachmentMap, "vertices");
  456. entrySize = entry->size;
  457. vertices = MALLOC(float, entrySize);
  458. for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
  459. vertices[i] = entry->valueFloat;
  460. if (verticesLength == entrySize) {
  461. if (self->scale != 1)
  462. for (i = 0; i < entrySize; ++i)
  463. vertices[i] *= self->scale;
  464. attachment->verticesCount = verticesLength;
  465. attachment->vertices = vertices;
  466. attachment->bonesCount = 0;
  467. attachment->bones = 0;
  468. } else {
  469. attachment->verticesCount = 0;
  470. attachment->bonesCount = 0;
  471. for (i = 0; i < entrySize;) {
  472. int bonesCount = (int)vertices[i];
  473. attachment->bonesCount += 1 + bonesCount;
  474. attachment->verticesCount += 3 * bonesCount;
  475. i += 1 + bonesCount * 4;
  476. }
  477. attachment->vertices = MALLOC(float, attachment->verticesCount);
  478. attachment->bones = MALLOC(int, attachment->bonesCount);
  479. for (i = 0, b = 0, w = 0; i < entrySize;) {
  480. int bonesCount = (int)vertices[i++];
  481. attachment->bones[b++] = bonesCount;
  482. for (nn = i + bonesCount * 4; i < nn;) {
  483. attachment->bones[b++] = (int)vertices[i++];
  484. attachment->vertices[w++] = vertices[i++] * self->scale;
  485. attachment->vertices[w++] = vertices[i++] * self->scale;
  486. attachment->vertices[w++] = vertices[i++];
  487. }
  488. }
  489. FREE(vertices);
  490. }
  491. }
  492. spSkeletonData* spSkeletonJson_readSkeletonDataFile (spSkeletonJson* self, const char* path) {
  493. int length;
  494. spSkeletonData* skeletonData;
  495. const char* json = _spUtil_readFile(path, &length);
  496. if (length == 0 || !json) {
  497. _spSkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
  498. return 0;
  499. }
  500. skeletonData = spSkeletonJson_readSkeletonData(self, json);
  501. FREE(json);
  502. return skeletonData;
  503. }
  504. spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const char* json) {
  505. int i, ii;
  506. spSkeletonData* skeletonData;
  507. Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events;
  508. char* oldLocale;
  509. _spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
  510. FREE(self->error);
  511. CONST_CAST(char*, self->error) = 0;
  512. internal->linkedMeshCount = 0;
  513. #ifndef __ANDROID__
  514. oldLocale = strdup(setlocale(LC_NUMERIC, NULL));
  515. setlocale(LC_NUMERIC, "C");
  516. #endif
  517. root = Json_create(json);
  518. #ifndef __ANDROID__
  519. setlocale(LC_NUMERIC, oldLocale);
  520. free(oldLocale);
  521. #endif
  522. if (!root) {
  523. _spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
  524. return 0;
  525. }
  526. skeletonData = spSkeletonData_create();
  527. skeleton = Json_getItem(root, "skeleton");
  528. if (skeleton) {
  529. MALLOC_STR(skeletonData->hash, Json_getString(skeleton, "hash", 0));
  530. MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", 0));
  531. skeletonData->width = Json_getFloat(skeleton, "width", 0);
  532. skeletonData->height = Json_getFloat(skeleton, "height", 0);
  533. }
  534. /* Bones. */
  535. bones = Json_getItem(root, "bones");
  536. skeletonData->bones = MALLOC(spBoneData*, bones->size);
  537. for (boneMap = bones->child, i = 0; boneMap; boneMap = boneMap->next, ++i) {
  538. spBoneData* data;
  539. const char* transformMode;
  540. spBoneData* parent = 0;
  541. const char* parentName = Json_getString(boneMap, "parent", 0);
  542. if (parentName) {
  543. parent = spSkeletonData_findBone(skeletonData, parentName);
  544. if (!parent) {
  545. spSkeletonData_dispose(skeletonData);
  546. _spSkeletonJson_setError(self, root, "Parent bone not found: ", parentName);
  547. return 0;
  548. }
  549. }
  550. data = spBoneData_create(skeletonData->bonesCount, Json_getString(boneMap, "name", 0), parent);
  551. data->length = Json_getFloat(boneMap, "length", 0) * self->scale;
  552. data->x = Json_getFloat(boneMap, "x", 0) * self->scale;
  553. data->y = Json_getFloat(boneMap, "y", 0) * self->scale;
  554. data->rotation = Json_getFloat(boneMap, "rotation", 0);
  555. data->scaleX = Json_getFloat(boneMap, "scaleX", 1);
  556. data->scaleY = Json_getFloat(boneMap, "scaleY", 1);
  557. data->shearX = Json_getFloat(boneMap, "shearX", 0);
  558. data->shearY = Json_getFloat(boneMap, "shearY", 0);
  559. transformMode = Json_getString(boneMap, "transform", "normal");
  560. data->transformMode = SP_TRANSFORMMODE_NORMAL;
  561. if (strcmp(transformMode, "normal") == 0)
  562. data->transformMode = SP_TRANSFORMMODE_NORMAL;
  563. if (strcmp(transformMode, "onlyTranslation") == 0)
  564. data->transformMode = SP_TRANSFORMMODE_ONLYTRANSLATION;
  565. if (strcmp(transformMode, "noRotationOrReflection") == 0)
  566. data->transformMode = SP_TRANSFORMMODE_NOROTATIONORREFLECTION;
  567. if (strcmp(transformMode, "noScale") == 0)
  568. data->transformMode = SP_TRANSFORMMODE_NOSCALE;
  569. if (strcmp(transformMode, "noScaleOrReflection") == 0)
  570. data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
  571. skeletonData->bones[i] = data;
  572. skeletonData->bonesCount++;
  573. }
  574. /* Slots. */
  575. slots = Json_getItem(root, "slots");
  576. if (slots) {
  577. Json *slotMap;
  578. skeletonData->slotsCount = slots->size;
  579. skeletonData->slots = MALLOC(spSlotData*, slots->size);
  580. for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
  581. spSlotData* data;
  582. const char* color;
  583. Json *item;
  584. const char* boneName = Json_getString(slotMap, "bone", 0);
  585. spBoneData* boneData = spSkeletonData_findBone(skeletonData, boneName);
  586. if (!boneData) {
  587. spSkeletonData_dispose(skeletonData);
  588. _spSkeletonJson_setError(self, root, "Slot bone not found: ", boneName);
  589. return 0;
  590. }
  591. data = spSlotData_create(i, Json_getString(slotMap, "name", 0), boneData);
  592. color = Json_getString(slotMap, "color", 0);
  593. if (color) {
  594. data->r = toColor(color, 0);
  595. data->g = toColor(color, 1);
  596. data->b = toColor(color, 2);
  597. data->a = toColor(color, 3);
  598. }
  599. item = Json_getItem(slotMap, "attachment");
  600. if (item) spSlotData_setAttachmentName(data, item->valueString);
  601. item = Json_getItem(slotMap, "blend");
  602. if (item) {
  603. if (strcmp(item->valueString, "additive") == 0)
  604. data->blendMode = SP_BLEND_MODE_ADDITIVE;
  605. else if (strcmp(item->valueString, "multiply") == 0)
  606. data->blendMode = SP_BLEND_MODE_MULTIPLY;
  607. else if (strcmp(item->valueString, "screen") == 0)
  608. data->blendMode = SP_BLEND_MODE_SCREEN;
  609. }
  610. skeletonData->slots[i] = data;
  611. }
  612. }
  613. /* IK constraints. */
  614. ik = Json_getItem(root, "ik");
  615. if (ik) {
  616. Json *constraintMap;
  617. skeletonData->ikConstraintsCount = ik->size;
  618. skeletonData->ikConstraints = MALLOC(spIkConstraintData*, ik->size);
  619. for (constraintMap = ik->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
  620. const char* targetName;
  621. spIkConstraintData* data = spIkConstraintData_create(Json_getString(constraintMap, "name", 0));
  622. data->order = Json_getInt(constraintMap, "order", 0);
  623. boneMap = Json_getItem(constraintMap, "bones");
  624. data->bonesCount = boneMap->size;
  625. data->bones = MALLOC(spBoneData*, boneMap->size);
  626. for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
  627. data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
  628. if (!data->bones[ii]) {
  629. spSkeletonData_dispose(skeletonData);
  630. _spSkeletonJson_setError(self, root, "IK bone not found: ", boneMap->valueString);
  631. return 0;
  632. }
  633. }
  634. targetName = Json_getString(constraintMap, "target", 0);
  635. data->target = spSkeletonData_findBone(skeletonData, targetName);
  636. if (!data->target) {
  637. spSkeletonData_dispose(skeletonData);
  638. _spSkeletonJson_setError(self, root, "Target bone not found: ", boneMap->name);
  639. return 0;
  640. }
  641. data->bendDirection = Json_getInt(constraintMap, "bendPositive", 1) ? 1 : -1;
  642. data->mix = Json_getFloat(constraintMap, "mix", 1);
  643. skeletonData->ikConstraints[i] = data;
  644. }
  645. }
  646. /* Transform constraints. */
  647. transform = Json_getItem(root, "transform");
  648. if (transform) {
  649. Json *constraintMap;
  650. skeletonData->transformConstraintsCount = transform->size;
  651. skeletonData->transformConstraints = MALLOC(spTransformConstraintData*, transform->size);
  652. for (constraintMap = transform->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
  653. const char* name;
  654. spTransformConstraintData* data = spTransformConstraintData_create(Json_getString(constraintMap, "name", 0));
  655. data->order = Json_getInt(constraintMap, "order", 0);
  656. boneMap = Json_getItem(constraintMap, "bones");
  657. data->bonesCount = boneMap->size;
  658. CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, boneMap->size);
  659. for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
  660. data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
  661. if (!data->bones[ii]) {
  662. spSkeletonData_dispose(skeletonData);
  663. _spSkeletonJson_setError(self, root, "Transform bone not found: ", boneMap->valueString);
  664. return 0;
  665. }
  666. }
  667. name = Json_getString(constraintMap, "target", 0);
  668. data->target = spSkeletonData_findBone(skeletonData, name);
  669. if (!data->target) {
  670. spSkeletonData_dispose(skeletonData);
  671. _spSkeletonJson_setError(self, root, "Target bone not found: ", boneMap->name);
  672. return 0;
  673. }
  674. data->offsetRotation = Json_getFloat(constraintMap, "rotation", 0);
  675. data->offsetX = Json_getFloat(constraintMap, "x", 0) * self->scale;
  676. data->offsetY = Json_getFloat(constraintMap, "y", 0) * self->scale;
  677. data->offsetScaleX = Json_getFloat(constraintMap, "scaleX", 0);
  678. data->offsetScaleY = Json_getFloat(constraintMap, "scaleY", 0);
  679. data->offsetShearY = Json_getFloat(constraintMap, "shearY", 0);
  680. data->rotateMix = Json_getFloat(constraintMap, "rotateMix", 1);
  681. data->translateMix = Json_getFloat(constraintMap, "translateMix", 1);
  682. data->scaleMix = Json_getFloat(constraintMap, "scaleMix", 1);
  683. data->shearMix = Json_getFloat(constraintMap, "shearMix", 1);
  684. skeletonData->transformConstraints[i] = data;
  685. }
  686. }
  687. /* Path constraints */
  688. path = Json_getItem(root, "path");
  689. if (path) {
  690. Json *constraintMap;
  691. skeletonData->pathConstraintsCount = path->size;
  692. skeletonData->pathConstraints = MALLOC(spPathConstraintData*, path->size);
  693. for (constraintMap = path->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
  694. const char* name;
  695. const char* item;
  696. spPathConstraintData* data = spPathConstraintData_create(Json_getString(constraintMap, "name", 0));
  697. data->order = Json_getInt(constraintMap, "order", 0);
  698. boneMap = Json_getItem(constraintMap, "bones");
  699. data->bonesCount = boneMap->size;
  700. CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, boneMap->size);
  701. for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
  702. data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
  703. if (!data->bones[ii]) {
  704. spSkeletonData_dispose(skeletonData);
  705. _spSkeletonJson_setError(self, root, "Path bone not found: ", boneMap->valueString);
  706. return 0;
  707. }
  708. }
  709. name = Json_getString(constraintMap, "target", 0);
  710. data->target = spSkeletonData_findSlot(skeletonData, name);
  711. if (!data->target) {
  712. spSkeletonData_dispose(skeletonData);
  713. _spSkeletonJson_setError(self, root, "Target slot not found: ", boneMap->name);
  714. return 0;
  715. }
  716. item = Json_getString(constraintMap, "positionMode", "percent");
  717. if (strcmp(item, "fixed") == 0) data->positionMode = SP_POSITION_MODE_FIXED;
  718. else if (strcmp(item, "percent") == 0) data->positionMode = SP_POSITION_MODE_PERCENT;
  719. item = Json_getString(constraintMap, "spacingMode", "length");
  720. if (strcmp(item, "length") == 0) data->spacingMode = SP_SPACING_MODE_LENGTH;
  721. else if (strcmp(item, "fixed") == 0) data->spacingMode = SP_SPACING_MODE_FIXED;
  722. else if (strcmp(item, "percent") == 0) data->spacingMode = SP_SPACING_MODE_PERCENT;
  723. item = Json_getString(constraintMap, "rotateMode", "tangent");
  724. if (strcmp(item, "tangent") == 0) data->rotateMode = SP_ROTATE_MODE_TANGENT;
  725. else if (strcmp(item, "chain") == 0) data->rotateMode = SP_ROTATE_MODE_CHAIN;
  726. else if (strcmp(item, "chainScale") == 0) data->rotateMode = SP_ROTATE_MODE_CHAIN_SCALE;
  727. data->offsetRotation = Json_getFloat(constraintMap, "rotation", 0);
  728. data->position = Json_getFloat(constraintMap, "position", 0);
  729. if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= self->scale;
  730. data->spacing = Json_getFloat(constraintMap, "spacing", 0);
  731. if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= self->scale;
  732. data->rotateMix = Json_getFloat(constraintMap, "rotateMix", 1);
  733. data->translateMix = Json_getFloat(constraintMap, "translateMix", 1);
  734. skeletonData->pathConstraints[i] = data;
  735. }
  736. }
  737. /* Skins. */
  738. skins = Json_getItem(root, "skins");
  739. if (skins) {
  740. Json *skinMap;
  741. skeletonData->skins = MALLOC(spSkin*, skins->size);
  742. for (skinMap = skins->child, i = 0; skinMap; skinMap = skinMap->next, ++i) {
  743. Json *attachmentsMap;
  744. Json *curves;
  745. spSkin *skin = spSkin_create(skinMap->name);
  746. skeletonData->skins[skeletonData->skinsCount++] = skin;
  747. if (strcmp(skinMap->name, "default") == 0) skeletonData->defaultSkin = skin;
  748. for (attachmentsMap = skinMap->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
  749. int slotIndex = spSkeletonData_findSlotIndex(skeletonData, attachmentsMap->name);
  750. Json *attachmentMap;
  751. for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
  752. spAttachment* attachment;
  753. const char* skinAttachmentName = attachmentMap->name;
  754. const char* attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
  755. const char* path = Json_getString(attachmentMap, "path", attachmentName);
  756. const char* color;
  757. Json* entry;
  758. const char* typeString = Json_getString(attachmentMap, "type", "region");
  759. spAttachmentType type;
  760. if (strcmp(typeString, "region") == 0)
  761. type = SP_ATTACHMENT_REGION;
  762. else if (strcmp(typeString, "mesh") == 0)
  763. type = SP_ATTACHMENT_MESH;
  764. else if (strcmp(typeString, "linkedmesh") == 0)
  765. type = SP_ATTACHMENT_LINKED_MESH;
  766. else if (strcmp(typeString, "boundingbox") == 0)
  767. type = SP_ATTACHMENT_BOUNDING_BOX;
  768. else if (strcmp(typeString, "path") == 0)
  769. type = SP_ATTACHMENT_PATH;
  770. else {
  771. spSkeletonData_dispose(skeletonData);
  772. _spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
  773. return 0;
  774. }
  775. attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName, path);
  776. if (!attachment) {
  777. if (self->attachmentLoader->error1) {
  778. spSkeletonData_dispose(skeletonData);
  779. _spSkeletonJson_setError(self, root, self->attachmentLoader->error1, self->attachmentLoader->error2);
  780. return 0;
  781. }
  782. continue;
  783. }
  784. switch (attachment->type) {
  785. case SP_ATTACHMENT_REGION: {
  786. spRegionAttachment* region = SUB_CAST(spRegionAttachment, attachment);
  787. if (path) MALLOC_STR(region->path, path);
  788. region->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
  789. region->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
  790. region->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
  791. region->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
  792. region->rotation = Json_getFloat(attachmentMap, "rotation", 0);
  793. region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
  794. region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
  795. color = Json_getString(attachmentMap, "color", 0);
  796. if (color) {
  797. region->r = toColor(color, 0);
  798. region->g = toColor(color, 1);
  799. region->b = toColor(color, 2);
  800. region->a = toColor(color, 3);
  801. }
  802. spRegionAttachment_updateOffset(region);
  803. spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
  804. break;
  805. }
  806. case SP_ATTACHMENT_MESH:
  807. case SP_ATTACHMENT_LINKED_MESH: {
  808. spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, attachment);
  809. MALLOC_STR(mesh->path, path);
  810. color = Json_getString(attachmentMap, "color", 0);
  811. if (color) {
  812. mesh->r = toColor(color, 0);
  813. mesh->g = toColor(color, 1);
  814. mesh->b = toColor(color, 2);
  815. mesh->a = toColor(color, 3);
  816. }
  817. mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
  818. mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
  819. entry = Json_getItem(attachmentMap, "parent");
  820. if (!entry) {
  821. int verticesLength;
  822. entry = Json_getItem(attachmentMap, "triangles");
  823. mesh->trianglesCount = entry->size;
  824. mesh->triangles = MALLOC(unsigned short, entry->size);
  825. for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
  826. mesh->triangles[ii] = (unsigned short)entry->valueInt;
  827. entry = Json_getItem(attachmentMap, "uvs");
  828. verticesLength = entry->size;
  829. mesh->regionUVs = MALLOC(float, verticesLength);
  830. for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
  831. mesh->regionUVs[ii] = entry->valueFloat;
  832. _readVertices(self, attachmentMap, SUPER(mesh), verticesLength);
  833. spMeshAttachment_updateUVs(mesh);
  834. mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
  835. entry = Json_getItem(attachmentMap, "edges");
  836. if (entry) {
  837. mesh->edgesCount = entry->size;
  838. mesh->edges = MALLOC(int, entry->size);
  839. for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
  840. mesh->edges[ii] = entry->valueInt;
  841. }
  842. spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
  843. } else {
  844. mesh->inheritDeform = Json_getInt(attachmentMap, "deform", 1);
  845. _spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), Json_getString(attachmentMap, "skin", 0), slotIndex,
  846. entry->valueString);
  847. }
  848. break;
  849. }
  850. case SP_ATTACHMENT_BOUNDING_BOX: {
  851. spBoundingBoxAttachment* box = SUB_CAST(spBoundingBoxAttachment, attachment);
  852. int vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
  853. _readVertices(self, attachmentMap, SUPER(box), vertexCount);
  854. box->super.verticesCount = vertexCount;
  855. spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
  856. break;
  857. }
  858. case SP_ATTACHMENT_PATH: {
  859. spPathAttachment* path = SUB_CAST(spPathAttachment, attachment);
  860. int vertexCount = 0;
  861. path->closed = Json_getInt(attachmentMap, "closed", 0);
  862. path->constantSpeed = Json_getInt(attachmentMap, "constantSpeed", 1);
  863. vertexCount = Json_getInt(attachmentMap, "vertexCount", 0);
  864. _readVertices(self, attachmentMap, SUPER(path), vertexCount << 1);
  865. path->lengthsLength = vertexCount / 3;
  866. path->lengths = MALLOC(float, path->lengthsLength);
  867. curves = Json_getItem(attachmentMap, "lengths");
  868. for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii) {
  869. path->lengths[ii] = curves->valueFloat * self->scale;
  870. }
  871. break;
  872. }
  873. }
  874. spSkin_addAttachment(skin, slotIndex, skinAttachmentName, attachment);
  875. }
  876. }
  877. }
  878. }
  879. /* Linked meshes. */
  880. for (i = 0; i < internal->linkedMeshCount; i++) {
  881. spAttachment* parent;
  882. _spLinkedMesh* linkedMesh = internal->linkedMeshes + i;
  883. spSkin* skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
  884. if (!skin) {
  885. spSkeletonData_dispose(skeletonData);
  886. _spSkeletonJson_setError(self, 0, "Skin not found: ", linkedMesh->skin);
  887. return 0;
  888. }
  889. parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
  890. if (!parent) {
  891. spSkeletonData_dispose(skeletonData);
  892. _spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent);
  893. return 0;
  894. }
  895. spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
  896. spMeshAttachment_updateUVs(linkedMesh->mesh);
  897. spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));
  898. }
  899. /* Events. */
  900. events = Json_getItem(root, "events");
  901. if (events) {
  902. Json *eventMap;
  903. const char* stringValue;
  904. skeletonData->eventsCount = events->size;
  905. skeletonData->events = MALLOC(spEventData*, events->size);
  906. for (eventMap = events->child, i = 0; eventMap; eventMap = eventMap->next, ++i) {
  907. spEventData* eventData = spEventData_create(eventMap->name);
  908. eventData->intValue = Json_getInt(eventMap, "int", 0);
  909. eventData->floatValue = Json_getFloat(eventMap, "float", 0);
  910. stringValue = Json_getString(eventMap, "string", 0);
  911. if (stringValue) MALLOC_STR(eventData->stringValue, stringValue);
  912. skeletonData->events[i] = eventData;
  913. }
  914. }
  915. /* Animations. */
  916. animations = Json_getItem(root, "animations");
  917. if (animations) {
  918. Json *animationMap;
  919. skeletonData->animations = MALLOC(spAnimation*, animations->size);
  920. for (animationMap = animations->child; animationMap; animationMap = animationMap->next) {
  921. spAnimation* animation = _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
  922. if (!animation) {
  923. spSkeletonData_dispose(skeletonData);
  924. return 0;
  925. }
  926. skeletonData->animations[skeletonData->animationsCount++] = animation;
  927. }
  928. }
  929. Json_dispose(root);
  930. return skeletonData;
  931. }