Animation.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. #include <spine/Animation.h>
  30. #include <spine/IkConstraint.h>
  31. #include <limits.h>
  32. #include <spine/extension.h>
  33. spAnimation* spAnimation_create (const char* name, int timelinesCount) {
  34. spAnimation* self = NEW(spAnimation);
  35. MALLOC_STR(self->name, name);
  36. self->timelinesCount = timelinesCount;
  37. self->timelines = MALLOC(spTimeline*, timelinesCount);
  38. return self;
  39. }
  40. void spAnimation_dispose (spAnimation* self) {
  41. int i;
  42. for (i = 0; i < self->timelinesCount; ++i)
  43. spTimeline_dispose(self->timelines[i]);
  44. FREE(self->timelines);
  45. FREE(self->name);
  46. FREE(self);
  47. }
  48. void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
  49. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  50. ) {
  51. int i, n = self->timelinesCount;
  52. if (loop && self->duration) {
  53. time = FMOD(time, self->duration);
  54. if (lastTime > 0) lastTime = FMOD(lastTime, self->duration);
  55. }
  56. for (i = 0; i < n; ++i)
  57. spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha, blend, direction);
  58. }
  59. /**/
  60. typedef struct _spTimelineVtable {
  61. void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  62. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
  63. int (*getPropertyId) (const spTimeline* self);
  64. void (*dispose) (spTimeline* self);
  65. } _spTimelineVtable;
  66. void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
  67. void (*dispose) (spTimeline* self), /**/
  68. void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  69. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
  70. int (*getPropertyId) (const spTimeline* self)
  71. ) {
  72. CONST_CAST(spTimelineType, self->type) = type;
  73. CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
  74. VTABLE(spTimeline, self)->dispose = dispose;
  75. VTABLE(spTimeline, self)->apply = apply;
  76. VTABLE(spTimeline, self)->getPropertyId = getPropertyId;
  77. }
  78. void _spTimeline_deinit (spTimeline* self) {
  79. FREE(self->vtable);
  80. }
  81. void spTimeline_dispose (spTimeline* self) {
  82. VTABLE(spTimeline, self)->dispose(self);
  83. }
  84. void spTimeline_apply (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  85. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
  86. VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, blend, direction);
  87. }
  88. int spTimeline_getPropertyId (const spTimeline* self) {
  89. return VTABLE(spTimeline, self)->getPropertyId(self);
  90. }
  91. /**/
  92. static const float CURVE_LINEAR = 0, CURVE_STEPPED = 1, CURVE_BEZIER = 2;
  93. static const int BEZIER_SIZE = 10 * 2 - 1;
  94. void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/
  95. void (*dispose) (spTimeline* self), /**/
  96. void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  97. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
  98. int (*getPropertyId)(const spTimeline* self)
  99. ) {
  100. _spTimeline_init(SUPER(self), type, dispose, apply, getPropertyId);
  101. self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE);
  102. }
  103. void _spCurveTimeline_deinit (spCurveTimeline* self) {
  104. _spTimeline_deinit(SUPER(self));
  105. FREE(self->curves);
  106. }
  107. void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex) {
  108. self->curves[frameIndex * BEZIER_SIZE] = CURVE_LINEAR;
  109. }
  110. void spCurveTimeline_setStepped (spCurveTimeline* self, int frameIndex) {
  111. self->curves[frameIndex * BEZIER_SIZE] = CURVE_STEPPED;
  112. }
  113. void spCurveTimeline_setCurve (spCurveTimeline* self, int frameIndex, float cx1, float cy1, float cx2, float cy2) {
  114. float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f;
  115. float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f;
  116. float ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
  117. float dfx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dfy = cy1 * 0.3f + tmpy + dddfy * 0.16666667f;
  118. float x = dfx, y = dfy;
  119. int i = frameIndex * BEZIER_SIZE, n = i + BEZIER_SIZE - 1;
  120. self->curves[i++] = CURVE_BEZIER;
  121. for (; i < n; i += 2) {
  122. self->curves[i] = x;
  123. self->curves[i + 1] = y;
  124. dfx += ddfx;
  125. dfy += ddfy;
  126. ddfx += dddfx;
  127. ddfy += dddfy;
  128. x += dfx;
  129. y += dfy;
  130. }
  131. }
  132. float spCurveTimeline_getCurvePercent (const spCurveTimeline* self, int frameIndex, float percent) {
  133. float x, y;
  134. int i = frameIndex * BEZIER_SIZE, start, n;
  135. float type = self->curves[i];
  136. percent = CLAMP(percent, 0, 1);
  137. if (type == CURVE_LINEAR) return percent;
  138. if (type == CURVE_STEPPED) return 0;
  139. i++;
  140. x = 0;
  141. for (start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) {
  142. x = self->curves[i];
  143. if (x >= percent) {
  144. float prevX, prevY;
  145. if (i == start) {
  146. prevX = 0;
  147. prevY = 0;
  148. } else {
  149. prevX = self->curves[i - 2];
  150. prevY = self->curves[i - 1];
  151. }
  152. return prevY + (self->curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
  153. }
  154. }
  155. y = self->curves[i - 1];
  156. return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */
  157. }
  158. /* @param target After the first and before the last entry. */
  159. static int binarySearch (float *values, int valuesLength, float target, int step) {
  160. int low = 0, current;
  161. int high = valuesLength / step - 2;
  162. if (high == 0) return step;
  163. current = high >> 1;
  164. while (1) {
  165. if (values[(current + 1) * step] <= target)
  166. low = current + 1;
  167. else
  168. high = current;
  169. if (low == high) return (low + 1) * step;
  170. current = (low + high) >> 1;
  171. }
  172. return 0;
  173. }
  174. int _spCurveTimeline_binarySearch (float *values, int valuesLength, float target, int step) {
  175. return binarySearch(values, valuesLength, target, step);
  176. }
  177. /* @param target After the first and before the last entry. */
  178. static int binarySearch1 (float *values, int valuesLength, float target) {
  179. int low = 0, current;
  180. int high = valuesLength - 2;
  181. if (high == 0) return 1;
  182. current = high >> 1;
  183. while (1) {
  184. if (values[(current + 1)] <= target)
  185. low = current + 1;
  186. else
  187. high = current;
  188. if (low == high) return low + 1;
  189. current = (low + high) >> 1;
  190. }
  191. return 0;
  192. }
  193. /**/
  194. void _spBaseTimeline_dispose (spTimeline* timeline) {
  195. struct spBaseTimeline* self = SUB_CAST(struct spBaseTimeline, timeline);
  196. _spCurveTimeline_deinit(SUPER(self));
  197. FREE(self->frames);
  198. FREE(self);
  199. }
  200. /* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/
  201. struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/
  202. void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  203. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
  204. int (*getPropertyId) (const spTimeline* self)
  205. ) {
  206. struct spBaseTimeline* self = NEW(struct spBaseTimeline);
  207. _spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply, getPropertyId);
  208. CONST_CAST(int, self->framesCount) = framesCount * frameSize;
  209. CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
  210. return self;
  211. }
  212. /**/
  213. void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  214. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  215. ) {
  216. spBone *bone;
  217. int frame;
  218. float prevRotation, frameTime, percent, r;
  219. spRotateTimeline* self = SUB_CAST(spRotateTimeline, timeline);
  220. bone = skeleton->bones[self->boneIndex];
  221. if (!bone->active) return;
  222. if (time < self->frames[0]) {
  223. switch (blend) {
  224. case SP_MIX_BLEND_SETUP:
  225. bone->rotation = bone->data->rotation;
  226. return;
  227. case SP_MIX_BLEND_FIRST:
  228. r = bone->data->rotation - bone->rotation;
  229. r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
  230. bone->rotation += r * alpha;
  231. case SP_MIX_BLEND_REPLACE:
  232. case SP_MIX_BLEND_ADD:
  233. ; /* to appease compiler */
  234. }
  235. return;
  236. }
  237. if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
  238. r = self->frames[self->framesCount + ROTATE_PREV_ROTATION];
  239. switch (blend) {
  240. case SP_MIX_BLEND_SETUP:
  241. bone->rotation = bone->data->rotation + r * alpha;
  242. break;
  243. case SP_MIX_BLEND_FIRST:
  244. case SP_MIX_BLEND_REPLACE:
  245. r += bone->data->rotation - bone->rotation;
  246. r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; /* Wrap within -180 and 180. */
  247. case SP_MIX_BLEND_ADD:
  248. bone->rotation += r * alpha;
  249. }
  250. return;
  251. }
  252. /* Interpolate between the previous frame and the current frame. */
  253. frame = binarySearch(self->frames, self->framesCount, time, ROTATE_ENTRIES);
  254. prevRotation = self->frames[frame + ROTATE_PREV_ROTATION];
  255. frameTime = self->frames[frame];
  256. percent = spCurveTimeline_getCurvePercent(SUPER(self), (frame >> 1) - 1, 1 - (time - frameTime) / (self->frames[frame + ROTATE_PREV_TIME] - frameTime));
  257. r = self->frames[frame + ROTATE_ROTATION] - prevRotation;
  258. r = prevRotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * percent;
  259. switch (blend) {
  260. case SP_MIX_BLEND_SETUP:
  261. bone->rotation = bone->data->rotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
  262. break;
  263. case SP_MIX_BLEND_FIRST:
  264. case SP_MIX_BLEND_REPLACE:
  265. r += bone->data->rotation - bone->rotation;
  266. case SP_MIX_BLEND_ADD:
  267. bone->rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
  268. }
  269. UNUSED(lastTime);
  270. UNUSED(firedEvents);
  271. UNUSED(eventsCount);
  272. UNUSED(direction);
  273. }
  274. int _spRotateTimeline_getPropertyId (const spTimeline* timeline) {
  275. return (SP_TIMELINE_ROTATE << 25) + SUB_CAST(spRotateTimeline, timeline)->boneIndex;
  276. }
  277. spRotateTimeline* spRotateTimeline_create (int framesCount) {
  278. return _spBaseTimeline_create(framesCount, SP_TIMELINE_ROTATE, ROTATE_ENTRIES, _spRotateTimeline_apply, _spRotateTimeline_getPropertyId);
  279. }
  280. void spRotateTimeline_setFrame (spRotateTimeline* self, int frameIndex, float time, float degrees) {
  281. frameIndex <<= 1;
  282. self->frames[frameIndex] = time;
  283. self->frames[frameIndex + ROTATE_ROTATION] = degrees;
  284. }
  285. /**/
  286. static const int TRANSLATE_PREV_TIME = -3, TRANSLATE_PREV_X = -2, TRANSLATE_PREV_Y = -1;
  287. static const int TRANSLATE_X = 1, TRANSLATE_Y = 2;
  288. void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  289. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  290. ) {
  291. spBone *bone;
  292. int frame;
  293. float frameTime, percent;
  294. float x, y;
  295. float *frames;
  296. int framesCount;
  297. spTranslateTimeline* self = SUB_CAST(spTranslateTimeline, timeline);
  298. bone = skeleton->bones[self->boneIndex];
  299. if (!bone->active) return;
  300. if (time < self->frames[0]) {
  301. switch (blend) {
  302. case SP_MIX_BLEND_SETUP:
  303. bone->x = bone->data->x;
  304. bone->y = bone->data->y;
  305. return;
  306. case SP_MIX_BLEND_FIRST:
  307. bone->x += (bone->data->x - bone->x) * alpha;
  308. bone->y += (bone->data->y - bone->y) * alpha;
  309. case SP_MIX_BLEND_REPLACE:
  310. case SP_MIX_BLEND_ADD:
  311. ; /* to appease compiler */
  312. }
  313. return;
  314. }
  315. frames = self->frames;
  316. framesCount = self->framesCount;
  317. if (time >= frames[framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
  318. x = frames[framesCount + TRANSLATE_PREV_X];
  319. y = frames[framesCount + TRANSLATE_PREV_Y];
  320. } else {
  321. /* Interpolate between the previous frame and the current frame. */
  322. frame = binarySearch(frames, framesCount, time, TRANSLATE_ENTRIES);
  323. x = frames[frame + TRANSLATE_PREV_X];
  324. y = frames[frame + TRANSLATE_PREV_Y];
  325. frameTime = frames[frame];
  326. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
  327. 1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
  328. x += (frames[frame + TRANSLATE_X] - x) * percent;
  329. y += (frames[frame + TRANSLATE_Y] - y) * percent;
  330. }
  331. switch (blend) {
  332. case SP_MIX_BLEND_SETUP:
  333. bone->x = bone->data->x + x * alpha;
  334. bone->y = bone->data->y + y * alpha;
  335. break;
  336. case SP_MIX_BLEND_FIRST:
  337. case SP_MIX_BLEND_REPLACE:
  338. bone->x += (bone->data->x + x - bone->x) * alpha;
  339. bone->y += (bone->data->y + y - bone->y) * alpha;
  340. break;
  341. case SP_MIX_BLEND_ADD:
  342. bone->x += x * alpha;
  343. bone->y += y * alpha;
  344. }
  345. UNUSED(lastTime);
  346. UNUSED(firedEvents);
  347. UNUSED(eventsCount);
  348. UNUSED(direction);
  349. }
  350. int _spTranslateTimeline_getPropertyId (const spTimeline* self) {
  351. return (SP_TIMELINE_TRANSLATE << 24) + SUB_CAST(spTranslateTimeline, self)->boneIndex;
  352. }
  353. spTranslateTimeline* spTranslateTimeline_create (int framesCount) {
  354. return _spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSLATE, TRANSLATE_ENTRIES, _spTranslateTimeline_apply, _spTranslateTimeline_getPropertyId);
  355. }
  356. void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, float time, float x, float y) {
  357. frameIndex *= TRANSLATE_ENTRIES;
  358. self->frames[frameIndex] = time;
  359. self->frames[frameIndex + TRANSLATE_X] = x;
  360. self->frames[frameIndex + TRANSLATE_Y] = y;
  361. }
  362. /**/
  363. void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  364. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  365. ) {
  366. spBone *bone;
  367. int frame;
  368. float frameTime, percent, x, y;
  369. float *frames;
  370. int framesCount;
  371. spScaleTimeline* self = SUB_CAST(spScaleTimeline, timeline);
  372. bone = skeleton->bones[self->boneIndex];
  373. if (!bone->active) return;
  374. if (time < self->frames[0]) {
  375. switch (blend) {
  376. case SP_MIX_BLEND_SETUP:
  377. bone->scaleX = bone->data->scaleX;
  378. bone->scaleY = bone->data->scaleY;
  379. return;
  380. case SP_MIX_BLEND_FIRST:
  381. bone->scaleX += (bone->data->scaleX - bone->scaleX) * alpha;
  382. bone->scaleY += (bone->data->scaleY - bone->scaleY) * alpha;
  383. case SP_MIX_BLEND_REPLACE:
  384. case SP_MIX_BLEND_ADD:
  385. ; /* to appease compiler */
  386. }
  387. return;
  388. }
  389. frames = self->frames;
  390. framesCount = self->framesCount;
  391. if (time >= frames[framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
  392. x = frames[framesCount + TRANSLATE_PREV_X] * bone->data->scaleX;
  393. y = frames[framesCount + TRANSLATE_PREV_Y] * bone->data->scaleY;
  394. } else {
  395. /* Interpolate between the previous frame and the current frame. */
  396. frame = binarySearch(frames, framesCount, time, TRANSLATE_ENTRIES);
  397. x = frames[frame + TRANSLATE_PREV_X];
  398. y = frames[frame + TRANSLATE_PREV_Y];
  399. frameTime = frames[frame];
  400. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
  401. 1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
  402. x = (x + (frames[frame + TRANSLATE_X] - x) * percent) * bone->data->scaleX;
  403. y = (y + (frames[frame + TRANSLATE_Y] - y) * percent) * bone->data->scaleY;
  404. }
  405. if (alpha == 1) {
  406. if (blend == SP_MIX_BLEND_ADD) {
  407. bone->scaleX += x - bone->data->scaleX;
  408. bone->scaleY += y - bone->data->scaleY;
  409. } else {
  410. bone->scaleX = x;
  411. bone->scaleY = y;
  412. }
  413. } else {
  414. float bx, by;
  415. if (direction == SP_MIX_DIRECTION_OUT) {
  416. switch (blend) {
  417. case SP_MIX_BLEND_SETUP:
  418. bx = bone->data->scaleX;
  419. by = bone->data->scaleY;
  420. bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
  421. bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
  422. break;
  423. case SP_MIX_BLEND_FIRST:
  424. case SP_MIX_BLEND_REPLACE:
  425. bx = bone->scaleX;
  426. by = bone->scaleY;
  427. bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
  428. bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
  429. break;
  430. case SP_MIX_BLEND_ADD:
  431. bx = bone->scaleX;
  432. by = bone->scaleY;
  433. bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bone->data->scaleX) * alpha;
  434. bone->scaleY = by + (ABS(y) * SIGNUM(by) - bone->data->scaleY) * alpha;
  435. }
  436. } else {
  437. switch (blend) {
  438. case SP_MIX_BLEND_SETUP:
  439. bx = ABS(bone->data->scaleX) * SIGNUM(x);
  440. by = ABS(bone->data->scaleY) * SIGNUM(y);
  441. bone->scaleX = bx + (x - bx) * alpha;
  442. bone->scaleY = by + (y - by) * alpha;
  443. break;
  444. case SP_MIX_BLEND_FIRST:
  445. case SP_MIX_BLEND_REPLACE:
  446. bx = ABS(bone->scaleX) * SIGNUM(x);
  447. by = ABS(bone->scaleY) * SIGNUM(y);
  448. bone->scaleX = bx + (x - bx) * alpha;
  449. bone->scaleY = by + (y - by) * alpha;
  450. break;
  451. case SP_MIX_BLEND_ADD:
  452. bx = SIGNUM(x);
  453. by = SIGNUM(y);
  454. bone->scaleX = ABS(bone->scaleX) * bx + (x - ABS(bone->data->scaleX) * bx) * alpha;
  455. bone->scaleY = ABS(bone->scaleY) * by + (y - ABS(bone->data->scaleY) * by) * alpha;
  456. }
  457. }
  458. }
  459. UNUSED(lastTime);
  460. UNUSED(firedEvents);
  461. UNUSED(eventsCount);
  462. }
  463. int _spScaleTimeline_getPropertyId (const spTimeline* timeline) {
  464. return (SP_TIMELINE_SCALE << 24) + SUB_CAST(spScaleTimeline, timeline)->boneIndex;
  465. }
  466. spScaleTimeline* spScaleTimeline_create (int framesCount) {
  467. return _spBaseTimeline_create(framesCount, SP_TIMELINE_SCALE, TRANSLATE_ENTRIES, _spScaleTimeline_apply, _spScaleTimeline_getPropertyId);
  468. }
  469. void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time, float x, float y) {
  470. spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
  471. }
  472. /**/
  473. void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  474. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  475. ) {
  476. spBone *bone;
  477. int frame;
  478. float frameTime, percent, x, y;
  479. float *frames;
  480. int framesCount;
  481. spShearTimeline* self = SUB_CAST(spShearTimeline, timeline);
  482. bone = skeleton->bones[self->boneIndex];
  483. if (!bone->active) return;
  484. frames = self->frames;
  485. framesCount = self->framesCount;
  486. if (time < self->frames[0]) {
  487. switch (blend) {
  488. case SP_MIX_BLEND_SETUP:
  489. bone->shearX = bone->data->shearX;
  490. bone->shearY = bone->data->shearY;
  491. return;
  492. case SP_MIX_BLEND_FIRST:
  493. bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
  494. bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
  495. case SP_MIX_BLEND_REPLACE:
  496. case SP_MIX_BLEND_ADD:
  497. ; /* to appease compiler */
  498. }
  499. return;
  500. }
  501. if (time >= frames[framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
  502. x = frames[framesCount + TRANSLATE_PREV_X];
  503. y = frames[framesCount + TRANSLATE_PREV_Y];
  504. } else {
  505. /* Interpolate between the previous frame and the current frame. */
  506. frame = binarySearch(frames, framesCount, time, TRANSLATE_ENTRIES);
  507. x = frames[frame + TRANSLATE_PREV_X];
  508. y = frames[frame + TRANSLATE_PREV_Y];
  509. frameTime = frames[frame];
  510. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
  511. 1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
  512. x = x + (frames[frame + TRANSLATE_X] - x) * percent;
  513. y = y + (frames[frame + TRANSLATE_Y] - y) * percent;
  514. }
  515. switch (blend) {
  516. case SP_MIX_BLEND_SETUP:
  517. bone->shearX = bone->data->shearX + x * alpha;
  518. bone->shearY = bone->data->shearY + y * alpha;
  519. break;
  520. case SP_MIX_BLEND_FIRST:
  521. case SP_MIX_BLEND_REPLACE:
  522. bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
  523. bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
  524. break;
  525. case SP_MIX_BLEND_ADD:
  526. bone->shearX += x * alpha;
  527. bone->shearY += y * alpha;
  528. }
  529. UNUSED(lastTime);
  530. UNUSED(firedEvents);
  531. UNUSED(eventsCount);
  532. UNUSED(direction);
  533. }
  534. int _spShearTimeline_getPropertyId (const spTimeline* timeline) {
  535. return (SP_TIMELINE_SHEAR << 24) + SUB_CAST(spShearTimeline, timeline)->boneIndex;
  536. }
  537. spShearTimeline* spShearTimeline_create (int framesCount) {
  538. return (spShearTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_SHEAR, 3, _spShearTimeline_apply, _spShearTimeline_getPropertyId);
  539. }
  540. void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y) {
  541. spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
  542. }
  543. /**/
  544. static const int COLOR_PREV_TIME = -5, COLOR_PREV_R = -4, COLOR_PREV_G = -3, COLOR_PREV_B = -2, COLOR_PREV_A = -1;
  545. static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4;
  546. void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  547. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  548. ) {
  549. spSlot *slot;
  550. int frame;
  551. float percent, frameTime;
  552. float r, g, b, a;
  553. spColor* color;
  554. spColor* setup;
  555. spColorTimeline* self = (spColorTimeline*)timeline;
  556. slot = skeleton->slots[self->slotIndex];
  557. if (!slot->bone->active) return;
  558. if (time < self->frames[0]) {
  559. switch (blend) {
  560. case SP_MIX_BLEND_SETUP:
  561. spColor_setFromColor(&slot->color, &slot->data->color);
  562. return;
  563. case SP_MIX_BLEND_FIRST:
  564. color = &slot->color;
  565. setup = &slot->data->color;
  566. spColor_addFloats(color, (setup->r - color->r) * alpha, (setup->g - color->g) * alpha, (setup->b - color->b) * alpha,
  567. (setup->a - color->a) * alpha);
  568. case SP_MIX_BLEND_REPLACE:
  569. case SP_MIX_BLEND_ADD:
  570. ; /* to appease compiler */
  571. }
  572. return;
  573. }
  574. if (time >= self->frames[self->framesCount - 5]) { /* Time is after last frame */
  575. int i = self->framesCount;
  576. r = self->frames[i + COLOR_PREV_R];
  577. g = self->frames[i + COLOR_PREV_G];
  578. b = self->frames[i + COLOR_PREV_B];
  579. a = self->frames[i + COLOR_PREV_A];
  580. } else {
  581. /* Interpolate between the previous frame and the current frame. */
  582. frame = binarySearch(self->frames, self->framesCount, time, COLOR_ENTRIES);
  583. r = self->frames[frame + COLOR_PREV_R];
  584. g = self->frames[frame + COLOR_PREV_G];
  585. b = self->frames[frame + COLOR_PREV_B];
  586. a = self->frames[frame + COLOR_PREV_A];
  587. frameTime = self->frames[frame];
  588. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / COLOR_ENTRIES - 1,
  589. 1 - (time - frameTime) / (self->frames[frame + COLOR_PREV_TIME] - frameTime));
  590. r += (self->frames[frame + COLOR_R] - r) * percent;
  591. g += (self->frames[frame + COLOR_G] - g) * percent;
  592. b += (self->frames[frame + COLOR_B] - b) * percent;
  593. a += (self->frames[frame + COLOR_A] - a) * percent;
  594. }
  595. if (alpha == 1) {
  596. spColor_setFromFloats(&slot->color, r, g, b, a);
  597. } else {
  598. if (blend == SP_MIX_BLEND_SETUP) spColor_setFromColor(&slot->color, &slot->data->color);
  599. spColor_addFloats(&slot->color, (r - slot->color.r) * alpha, (g - slot->color.g) * alpha, (b - slot->color.b) * alpha, (a - slot->color.a) * alpha);
  600. }
  601. UNUSED(lastTime);
  602. UNUSED(firedEvents);
  603. UNUSED(eventsCount);
  604. UNUSED(direction);
  605. }
  606. int _spColorTimeline_getPropertyId (const spTimeline* timeline) {
  607. return (SP_TIMELINE_COLOR << 24) + SUB_CAST(spColorTimeline, timeline)->slotIndex;
  608. }
  609. spColorTimeline* spColorTimeline_create (int framesCount) {
  610. return (spColorTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_COLOR, 5, _spColorTimeline_apply, _spColorTimeline_getPropertyId);
  611. }
  612. void spColorTimeline_setFrame (spColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
  613. frameIndex *= COLOR_ENTRIES;
  614. self->frames[frameIndex] = time;
  615. self->frames[frameIndex + COLOR_R] = r;
  616. self->frames[frameIndex + COLOR_G] = g;
  617. self->frames[frameIndex + COLOR_B] = b;
  618. self->frames[frameIndex + COLOR_A] = a;
  619. }
  620. /**/
  621. static const int TWOCOLOR_PREV_TIME = -8, TWOCOLOR_PREV_R = -7, TWOCOLOR_PREV_G = -6, TWOCOLOR_PREV_B = -5, TWOCOLOR_PREV_A = -4;
  622. static const int TWOCOLOR_PREV_R2 = -3, TWOCOLOR_PREV_G2 = -2, TWOCOLOR_PREV_B2 = -1;
  623. static const int TWOCOLOR_R = 1, TWOCOLOR_G = 2, TWOCOLOR_B = 3, TWOCOLOR_A = 4, TWOCOLOR_R2 = 5, TWOCOLOR_G2 = 6, TWOCOLOR_B2 = 7;
  624. void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  625. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  626. ) {
  627. spSlot *slot;
  628. int frame;
  629. float percent, frameTime;
  630. float r, g, b, a, r2, g2, b2;
  631. spColor* light;
  632. spColor* dark;
  633. spColor* setupLight;
  634. spColor* setupDark;
  635. spColorTimeline* self = (spColorTimeline*)timeline;
  636. slot = skeleton->slots[self->slotIndex];
  637. if (!slot->bone->active) return;
  638. if (time < self->frames[0]) {
  639. switch (blend) {
  640. case SP_MIX_BLEND_SETUP:
  641. spColor_setFromColor(&slot->color, &slot->data->color);
  642. spColor_setFromColor(slot->darkColor, slot->data->darkColor);
  643. return;
  644. case SP_MIX_BLEND_FIRST:
  645. light = &slot->color;
  646. dark = slot->darkColor;
  647. setupLight = &slot->data->color;
  648. setupDark = slot->data->darkColor;
  649. spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha, (setupLight->b - light->b) * alpha,
  650. (setupLight->a - light->a) * alpha);
  651. spColor_addFloats(dark, (setupDark->r - dark->r) * alpha, (setupDark->g - dark->g) * alpha, (setupDark->b - dark->b) * alpha, 0);
  652. case SP_MIX_BLEND_REPLACE:
  653. case SP_MIX_BLEND_ADD:
  654. ; /* to appease compiler */
  655. }
  656. return;
  657. }
  658. if (time >= self->frames[self->framesCount - TWOCOLOR_ENTRIES]) { /* Time is after last frame */
  659. int i = self->framesCount;
  660. r = self->frames[i + TWOCOLOR_PREV_R];
  661. g = self->frames[i + TWOCOLOR_PREV_G];
  662. b = self->frames[i + TWOCOLOR_PREV_B];
  663. a = self->frames[i + TWOCOLOR_PREV_A];
  664. r2 = self->frames[i + TWOCOLOR_PREV_R2];
  665. g2 = self->frames[i + TWOCOLOR_PREV_G2];
  666. b2 = self->frames[i + TWOCOLOR_PREV_B2];
  667. } else {
  668. /* Interpolate between the previous frame and the current frame. */
  669. frame = binarySearch(self->frames, self->framesCount, time, TWOCOLOR_ENTRIES);
  670. r = self->frames[frame + TWOCOLOR_PREV_R];
  671. g = self->frames[frame + TWOCOLOR_PREV_G];
  672. b = self->frames[frame + TWOCOLOR_PREV_B];
  673. a = self->frames[frame + TWOCOLOR_PREV_A];
  674. r2 = self->frames[frame + TWOCOLOR_PREV_R2];
  675. g2 = self->frames[frame + TWOCOLOR_PREV_G2];
  676. b2 = self->frames[frame + TWOCOLOR_PREV_B2];
  677. frameTime = self->frames[frame];
  678. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TWOCOLOR_ENTRIES - 1,
  679. 1 - (time - frameTime) / (self->frames[frame + TWOCOLOR_PREV_TIME] - frameTime));
  680. r += (self->frames[frame + TWOCOLOR_R] - r) * percent;
  681. g += (self->frames[frame + TWOCOLOR_G] - g) * percent;
  682. b += (self->frames[frame + TWOCOLOR_B] - b) * percent;
  683. a += (self->frames[frame + TWOCOLOR_A] - a) * percent;
  684. r2 += (self->frames[frame + TWOCOLOR_R2] - r2) * percent;
  685. g2 += (self->frames[frame + TWOCOLOR_G2] - g2) * percent;
  686. b2 += (self->frames[frame + TWOCOLOR_B2] - b2) * percent;
  687. }
  688. if (alpha == 1) {
  689. spColor_setFromFloats(&slot->color, r, g, b, a);
  690. spColor_setFromFloats(slot->darkColor, r2, g2, b2, 1);
  691. } else {
  692. light = &slot->color;
  693. dark = slot->darkColor;
  694. if (blend == SP_MIX_BLEND_SETUP) {
  695. spColor_setFromColor(light, &slot->data->color);
  696. spColor_setFromColor(dark, slot->data->darkColor);
  697. }
  698. spColor_addFloats(light, (r - light->r) * alpha, (g - light->g) * alpha, (b - light->b) * alpha, (a - light->a) * alpha);
  699. spColor_addFloats(dark, (r2 - dark->r) * alpha, (g2 - dark->g) * alpha, (b2 - dark->b) * alpha, 0);
  700. }
  701. UNUSED(lastTime);
  702. UNUSED(firedEvents);
  703. UNUSED(eventsCount);
  704. UNUSED(direction);
  705. }
  706. int _spTwoColorTimeline_getPropertyId (const spTimeline* timeline) {
  707. return (SP_TIMELINE_TWOCOLOR << 24) + SUB_CAST(spTwoColorTimeline, timeline)->slotIndex;
  708. }
  709. spTwoColorTimeline* spTwoColorTimeline_create (int framesCount) {
  710. return (spTwoColorTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TWOCOLOR, TWOCOLOR_ENTRIES, _spTwoColorTimeline_apply, _spTwoColorTimeline_getPropertyId);
  711. }
  712. void spTwoColorTimeline_setFrame (spTwoColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2) {
  713. frameIndex *= TWOCOLOR_ENTRIES;
  714. self->frames[frameIndex] = time;
  715. self->frames[frameIndex + TWOCOLOR_R] = r;
  716. self->frames[frameIndex + TWOCOLOR_G] = g;
  717. self->frames[frameIndex + TWOCOLOR_B] = b;
  718. self->frames[frameIndex + TWOCOLOR_A] = a;
  719. self->frames[frameIndex + TWOCOLOR_R2] = r2;
  720. self->frames[frameIndex + TWOCOLOR_G2] = g2;
  721. self->frames[frameIndex + TWOCOLOR_B2] = b2;
  722. }
  723. /**/
  724. static void _spSetAttachment(spAttachmentTimeline* timeline, spSkeleton* skeleton, spSlot* slot, const char* attachmentName) {
  725. slot->attachment = attachmentName == NULL ? NULL : spSkeleton_getAttachmentForSlotIndex(skeleton, timeline->slotIndex, attachmentName);
  726. }
  727. void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  728. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
  729. const char* attachmentName;
  730. spAttachmentTimeline* self = (spAttachmentTimeline*)timeline;
  731. int frameIndex;
  732. spSlot* slot = skeleton->slots[self->slotIndex];
  733. if (!slot->bone->active) return;
  734. if (direction == SP_MIX_DIRECTION_OUT) {
  735. if (blend == SP_MIX_BLEND_SETUP)
  736. _spSetAttachment(self, skeleton, slot, slot->data->attachmentName);
  737. return;
  738. }
  739. if (time < self->frames[0]) {
  740. if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) {
  741. _spSetAttachment(self, skeleton, slot, slot->data->attachmentName);
  742. }
  743. return;
  744. }
  745. if (time >= self->frames[self->framesCount - 1])
  746. frameIndex = self->framesCount - 1;
  747. else
  748. frameIndex = binarySearch1(self->frames, self->framesCount, time) - 1;
  749. attachmentName = self->attachmentNames[frameIndex];
  750. spSlot_setAttachment(skeleton->slots[self->slotIndex],
  751. attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
  752. UNUSED(lastTime);
  753. UNUSED(firedEvents);
  754. UNUSED(eventsCount);
  755. UNUSED(alpha);
  756. }
  757. int _spAttachmentTimeline_getPropertyId (const spTimeline* timeline) {
  758. return (SP_TIMELINE_ATTACHMENT << 24) + SUB_CAST(spAttachmentTimeline, timeline)->slotIndex;
  759. }
  760. void _spAttachmentTimeline_dispose (spTimeline* timeline) {
  761. spAttachmentTimeline* self = SUB_CAST(spAttachmentTimeline, timeline);
  762. int i;
  763. _spTimeline_deinit(timeline);
  764. for (i = 0; i < self->framesCount; ++i)
  765. FREE(self->attachmentNames[i]);
  766. FREE(self->attachmentNames);
  767. FREE(self->frames);
  768. FREE(self);
  769. }
  770. spAttachmentTimeline* spAttachmentTimeline_create (int framesCount) {
  771. spAttachmentTimeline* self = NEW(spAttachmentTimeline);
  772. _spTimeline_init(SUPER(self), SP_TIMELINE_ATTACHMENT, _spAttachmentTimeline_dispose, _spAttachmentTimeline_apply, _spAttachmentTimeline_getPropertyId);
  773. CONST_CAST(int, self->framesCount) = framesCount;
  774. CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
  775. CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, framesCount);
  776. return self;
  777. }
  778. void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
  779. self->frames[frameIndex] = time;
  780. FREE(self->attachmentNames[frameIndex]);
  781. if (attachmentName)
  782. MALLOC_STR(self->attachmentNames[frameIndex], attachmentName);
  783. else
  784. self->attachmentNames[frameIndex] = 0;
  785. }
  786. /**/
  787. void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  788. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  789. ) {
  790. int frame, i, vertexCount;
  791. float percent, frameTime;
  792. const float* prevVertices;
  793. const float* nextVertices;
  794. float* frames;
  795. int framesCount;
  796. const float** frameVertices;
  797. float* deformArray;
  798. spDeformTimeline* self = (spDeformTimeline*)timeline;
  799. spSlot *slot = skeleton->slots[self->slotIndex];
  800. if (!slot->bone->active) return;
  801. if (!slot->attachment) return;
  802. switch (slot->attachment->type) {
  803. case SP_ATTACHMENT_BOUNDING_BOX:
  804. case SP_ATTACHMENT_CLIPPING:
  805. case SP_ATTACHMENT_MESH:
  806. case SP_ATTACHMENT_PATH: {
  807. spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  808. if (vertexAttachment->deformAttachment != SUB_CAST(spVertexAttachment, self->attachment)) return;
  809. break;
  810. }
  811. default:
  812. return;
  813. }
  814. frames = self->frames;
  815. framesCount = self->framesCount;
  816. vertexCount = self->frameVerticesCount;
  817. if (slot->deformCount < vertexCount) {
  818. if (slot->deformCapacity < vertexCount) {
  819. FREE(slot->deform);
  820. slot->deform = MALLOC(float, vertexCount);
  821. slot->deformCapacity = vertexCount;
  822. }
  823. }
  824. if (slot->deformCount == 0) blend = SP_MIX_BLEND_SETUP;
  825. frameVertices = self->frameVertices;
  826. deformArray = slot->deform;
  827. if (time < frames[0]) { /* Time is before first frame. */
  828. spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  829. switch (blend) {
  830. case SP_MIX_BLEND_SETUP:
  831. slot->deformCount = 0;
  832. return;
  833. case SP_MIX_BLEND_FIRST:
  834. if (alpha == 1) {
  835. slot->deformCount = 0;
  836. return;
  837. }
  838. slot->deformCount = vertexCount;
  839. if (!vertexAttachment->bones) {
  840. float* setupVertices = vertexAttachment->vertices;
  841. for (i = 0; i < vertexCount; i++) {
  842. deformArray[i] += (setupVertices[i] - deformArray[i]) * alpha;
  843. }
  844. } else {
  845. alpha = 1 - alpha;
  846. for (i = 0; i < vertexCount; i++) {
  847. deformArray[i] *= alpha;
  848. }
  849. }
  850. case SP_MIX_BLEND_REPLACE:
  851. case SP_MIX_BLEND_ADD:
  852. ; /* to appease compiler */
  853. }
  854. return;
  855. }
  856. slot->deformCount = vertexCount;
  857. if (time >= frames[framesCount - 1]) { /* Time is after last frame. */
  858. const float* lastVertices = self->frameVertices[framesCount - 1];
  859. if (alpha == 1) {
  860. if (blend == SP_MIX_BLEND_ADD) {
  861. spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  862. if (!vertexAttachment->bones) {
  863. /* Unweighted vertex positions, with alpha. */
  864. float* setupVertices = vertexAttachment->vertices;
  865. for (i = 0; i < vertexCount; i++) {
  866. deformArray[i] += lastVertices[i] - setupVertices[i];
  867. }
  868. } else {
  869. /* Weighted deform offsets, with alpha. */
  870. for (i = 0; i < vertexCount; i++)
  871. deformArray[i] += lastVertices[i];
  872. }
  873. } else {
  874. /* Vertex positions or deform offsets, no alpha. */
  875. memcpy(deformArray, lastVertices, vertexCount * sizeof(float));
  876. }
  877. } else {
  878. spVertexAttachment* vertexAttachment;
  879. switch (blend) {
  880. case SP_MIX_BLEND_SETUP:
  881. vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  882. if (!vertexAttachment->bones) {
  883. /* Unweighted vertex positions, with alpha. */
  884. float* setupVertices = vertexAttachment->vertices;
  885. for (i = 0; i < vertexCount; i++) {
  886. float setup = setupVertices[i];
  887. deformArray[i] = setup + (lastVertices[i] - setup) * alpha;
  888. }
  889. } else {
  890. /* Weighted deform offsets, with alpha. */
  891. for (i = 0; i < vertexCount; i++)
  892. deformArray[i] = lastVertices[i] * alpha;
  893. }
  894. break;
  895. case SP_MIX_BLEND_FIRST:
  896. case SP_MIX_BLEND_REPLACE:
  897. /* Vertex positions or deform offsets, with alpha. */
  898. for (i = 0; i < vertexCount; i++)
  899. deformArray[i] += (lastVertices[i] - deformArray[i]) * alpha;
  900. case SP_MIX_BLEND_ADD:
  901. vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  902. if (!vertexAttachment->bones) {
  903. /* Unweighted vertex positions, with alpha. */
  904. float* setupVertices = vertexAttachment->vertices;
  905. for (i = 0; i < vertexCount; i++) {
  906. deformArray[i] += (lastVertices[i] - setupVertices[i]) * alpha;
  907. }
  908. } else {
  909. for (i = 0; i < vertexCount; i++)
  910. deformArray[i] += lastVertices[i] * alpha;
  911. }
  912. }
  913. }
  914. return;
  915. }
  916. /* Interpolate between the previous frame and the current frame. */
  917. frame = binarySearch(frames, framesCount, time, 1);
  918. prevVertices = frameVertices[frame - 1];
  919. nextVertices = frameVertices[frame];
  920. frameTime = frames[frame];
  921. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
  922. if (alpha == 1) {
  923. if (blend == SP_MIX_BLEND_ADD) {
  924. spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  925. if (!vertexAttachment->bones) {
  926. float* setupVertices = vertexAttachment->vertices;
  927. for (i = 0; i < vertexCount; i++) {
  928. float prev = prevVertices[i];
  929. deformArray[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
  930. }
  931. } else {
  932. for (i = 0; i < vertexCount; i++) {
  933. float prev = prevVertices[i];
  934. deformArray[i] += prev + (nextVertices[i] - prev) * percent;
  935. }
  936. }
  937. } else {
  938. for (i = 0; i < vertexCount; i++) {
  939. float prev = prevVertices[i];
  940. deformArray[i] = prev + (nextVertices[i] - prev) * percent;
  941. }
  942. }
  943. } else {
  944. spVertexAttachment* vertexAttachment;
  945. switch (blend) {
  946. case SP_MIX_BLEND_SETUP:
  947. vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  948. if (!vertexAttachment->bones) {
  949. float *setupVertices = vertexAttachment->vertices;
  950. for (i = 0; i < vertexCount; i++) {
  951. float prev = prevVertices[i], setup = setupVertices[i];
  952. deformArray[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
  953. }
  954. } else {
  955. for (i = 0; i < vertexCount; i++) {
  956. float prev = prevVertices[i];
  957. deformArray[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
  958. }
  959. }
  960. break;
  961. case SP_MIX_BLEND_FIRST:
  962. case SP_MIX_BLEND_REPLACE:
  963. for (i = 0; i < vertexCount; i++) {
  964. float prev = prevVertices[i];
  965. deformArray[i] += (prev + (nextVertices[i] - prev) * percent - deformArray[i]) * alpha;
  966. }
  967. break;
  968. case SP_MIX_BLEND_ADD:
  969. vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
  970. if (!vertexAttachment->bones) {
  971. float *setupVertices = vertexAttachment->vertices;
  972. for (i = 0; i < vertexCount; i++) {
  973. float prev = prevVertices[i];
  974. deformArray[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
  975. }
  976. } else {
  977. for (i = 0; i < vertexCount; i++) {
  978. float prev = prevVertices[i];
  979. deformArray[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
  980. }
  981. }
  982. }
  983. }
  984. UNUSED(lastTime);
  985. UNUSED(firedEvents);
  986. UNUSED(eventsCount);
  987. UNUSED(direction);
  988. }
  989. int _spDeformTimeline_getPropertyId (const spTimeline* timeline) {
  990. return (SP_TIMELINE_DEFORM << 27) + SUB_CAST(spVertexAttachment, SUB_CAST(spDeformTimeline, timeline)->attachment)->id + SUB_CAST(spDeformTimeline, timeline)->slotIndex;
  991. }
  992. void _spDeformTimeline_dispose (spTimeline* timeline) {
  993. spDeformTimeline* self = SUB_CAST(spDeformTimeline, timeline);
  994. int i;
  995. _spCurveTimeline_deinit(SUPER(self));
  996. for (i = 0; i < self->framesCount; ++i)
  997. FREE(self->frameVertices[i]);
  998. FREE(self->frameVertices);
  999. FREE(self->frames);
  1000. FREE(self);
  1001. }
  1002. spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount) {
  1003. spDeformTimeline* self = NEW(spDeformTimeline);
  1004. _spCurveTimeline_init(SUPER(self), SP_TIMELINE_DEFORM, framesCount, _spDeformTimeline_dispose, _spDeformTimeline_apply, _spDeformTimeline_getPropertyId);
  1005. CONST_CAST(int, self->framesCount) = framesCount;
  1006. CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
  1007. CONST_CAST(float**, self->frameVertices) = CALLOC(float*, framesCount);
  1008. CONST_CAST(int, self->frameVerticesCount) = frameVerticesCount;
  1009. return self;
  1010. }
  1011. void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices) {
  1012. self->frames[frameIndex] = time;
  1013. FREE(self->frameVertices[frameIndex]);
  1014. if (!vertices)
  1015. self->frameVertices[frameIndex] = 0;
  1016. else {
  1017. self->frameVertices[frameIndex] = MALLOC(float, self->frameVerticesCount);
  1018. memcpy(CONST_CAST(float*, self->frameVertices[frameIndex]), vertices, self->frameVerticesCount * sizeof(float));
  1019. }
  1020. }
  1021. /**/
  1022. /** Fires events for frames > lastTime and <= time. */
  1023. void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
  1024. int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1025. ) {
  1026. spEventTimeline* self = (spEventTimeline*)timeline;
  1027. int frame;
  1028. if (!firedEvents) return;
  1029. if (lastTime > time) { /* Fire events after last time for looped animations. */
  1030. _spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventsCount, alpha, blend, direction);
  1031. lastTime = -1;
  1032. } else if (lastTime >= self->frames[self->framesCount - 1]) /* Last time is after last frame. */
  1033. return;
  1034. if (time < self->frames[0]) return; /* Time is before first frame. */
  1035. if (lastTime < self->frames[0])
  1036. frame = 0;
  1037. else {
  1038. float frameTime;
  1039. frame = binarySearch1(self->frames, self->framesCount, lastTime);
  1040. frameTime = self->frames[frame];
  1041. while (frame > 0) { /* Fire multiple events with the same frame. */
  1042. if (self->frames[frame - 1] != frameTime) break;
  1043. frame--;
  1044. }
  1045. }
  1046. for (; frame < self->framesCount && time >= self->frames[frame]; ++frame) {
  1047. firedEvents[*eventsCount] = self->events[frame];
  1048. (*eventsCount)++;
  1049. }
  1050. UNUSED(direction);
  1051. }
  1052. int _spEventTimeline_getPropertyId (const spTimeline* timeline) {
  1053. return SP_TIMELINE_EVENT << 24;
  1054. UNUSED(timeline);
  1055. }
  1056. void _spEventTimeline_dispose (spTimeline* timeline) {
  1057. spEventTimeline* self = SUB_CAST(spEventTimeline, timeline);
  1058. int i;
  1059. _spTimeline_deinit(timeline);
  1060. for (i = 0; i < self->framesCount; ++i)
  1061. spEvent_dispose(self->events[i]);
  1062. FREE(self->events);
  1063. FREE(self->frames);
  1064. FREE(self);
  1065. }
  1066. spEventTimeline* spEventTimeline_create (int framesCount) {
  1067. spEventTimeline* self = NEW(spEventTimeline);
  1068. _spTimeline_init(SUPER(self), SP_TIMELINE_EVENT, _spEventTimeline_dispose, _spEventTimeline_apply, _spEventTimeline_getPropertyId);
  1069. CONST_CAST(int, self->framesCount) = framesCount;
  1070. CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
  1071. CONST_CAST(spEvent**, self->events) = CALLOC(spEvent*, framesCount);
  1072. return self;
  1073. }
  1074. void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* event) {
  1075. self->frames[frameIndex] = event->time;
  1076. FREE(self->events[frameIndex]);
  1077. self->events[frameIndex] = event;
  1078. }
  1079. /**/
  1080. void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1081. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1082. ) {
  1083. int i;
  1084. int frame;
  1085. const int* drawOrderToSetupIndex;
  1086. spDrawOrderTimeline* self = (spDrawOrderTimeline*)timeline;
  1087. if (direction == SP_MIX_DIRECTION_OUT ) {
  1088. if (blend == SP_MIX_BLEND_SETUP) memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
  1089. return;
  1090. }
  1091. if (time < self->frames[0]) {
  1092. if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
  1093. return;
  1094. }
  1095. if (time >= self->frames[self->framesCount - 1]) /* Time is after last frame. */
  1096. frame = self->framesCount - 1;
  1097. else
  1098. frame = binarySearch1(self->frames, self->framesCount, time) - 1;
  1099. drawOrderToSetupIndex = self->drawOrders[frame];
  1100. if (!drawOrderToSetupIndex)
  1101. memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
  1102. else {
  1103. for (i = 0; i < self->slotsCount; ++i)
  1104. skeleton->drawOrder[i] = skeleton->slots[drawOrderToSetupIndex[i]];
  1105. }
  1106. UNUSED(lastTime);
  1107. UNUSED(firedEvents);
  1108. UNUSED(eventsCount);
  1109. UNUSED(alpha);
  1110. }
  1111. int _spDrawOrderTimeline_getPropertyId (const spTimeline* timeline) {
  1112. return SP_TIMELINE_DRAWORDER << 24;
  1113. UNUSED(timeline);
  1114. }
  1115. void _spDrawOrderTimeline_dispose (spTimeline* timeline) {
  1116. spDrawOrderTimeline* self = SUB_CAST(spDrawOrderTimeline, timeline);
  1117. int i;
  1118. _spTimeline_deinit(timeline);
  1119. for (i = 0; i < self->framesCount; ++i)
  1120. FREE(self->drawOrders[i]);
  1121. FREE(self->drawOrders);
  1122. FREE(self->frames);
  1123. FREE(self);
  1124. }
  1125. spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount) {
  1126. spDrawOrderTimeline* self = NEW(spDrawOrderTimeline);
  1127. _spTimeline_init(SUPER(self), SP_TIMELINE_DRAWORDER, _spDrawOrderTimeline_dispose, _spDrawOrderTimeline_apply, _spDrawOrderTimeline_getPropertyId);
  1128. CONST_CAST(int, self->framesCount) = framesCount;
  1129. CONST_CAST(float*, self->frames) = CALLOC(float, framesCount);
  1130. CONST_CAST(int**, self->drawOrders) = CALLOC(int*, framesCount);
  1131. CONST_CAST(int, self->slotsCount) = slotsCount;
  1132. return self;
  1133. }
  1134. void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, float time, const int* drawOrder) {
  1135. self->frames[frameIndex] = time;
  1136. FREE(self->drawOrders[frameIndex]);
  1137. if (!drawOrder)
  1138. self->drawOrders[frameIndex] = 0;
  1139. else {
  1140. self->drawOrders[frameIndex] = MALLOC(int, self->slotsCount);
  1141. memcpy(CONST_CAST(int*, self->drawOrders[frameIndex]), drawOrder, self->slotsCount * sizeof(int));
  1142. }
  1143. }
  1144. /**/
  1145. static const int IKCONSTRAINT_PREV_TIME = -6, IKCONSTRAINT_PREV_MIX = -5, IKCONSTRAINT_PREV_SOFTNESS = -4, IKCONSTRAINT_PREV_BEND_DIRECTION = -3, IKCONSTRAINT_PREV_COMPRESS = -2, IKCONSTRAINT_PREV_STRETCH = -1;
  1146. static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_SOFTNESS = 2, IKCONSTRAINT_BEND_DIRECTION = 3, IKCONSTRAINT_COMPRESS = 4, IKCONSTRAINT_STRETCH = 5;
  1147. void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1148. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1149. ) {
  1150. int frame;
  1151. float frameTime, percent, mix, softness;
  1152. float *frames;
  1153. int framesCount;
  1154. spIkConstraint* constraint;
  1155. spIkConstraintTimeline* self = (spIkConstraintTimeline*)timeline;
  1156. constraint = skeleton->ikConstraints[self->ikConstraintIndex];
  1157. if (!constraint->active) return;
  1158. if (time < self->frames[0]) {
  1159. switch (blend) {
  1160. case SP_MIX_BLEND_SETUP:
  1161. constraint->mix = constraint->data->mix;
  1162. constraint->softness = constraint->data->softness;
  1163. constraint->bendDirection = constraint->data->bendDirection;
  1164. constraint->compress = constraint->data->compress;
  1165. constraint->stretch = constraint->data->stretch;
  1166. return;
  1167. case SP_MIX_BLEND_FIRST:
  1168. constraint->mix += (constraint->data->mix - constraint->mix) * alpha;
  1169. constraint->softness += (constraint->data->softness - constraint->softness) * alpha;
  1170. constraint->bendDirection = constraint->data->bendDirection;
  1171. constraint->compress = constraint->data->compress;
  1172. constraint->stretch = constraint->data->stretch;
  1173. case SP_MIX_BLEND_REPLACE:
  1174. case SP_MIX_BLEND_ADD:
  1175. ; /* to appease compiler */
  1176. }
  1177. return;
  1178. }
  1179. frames = self->frames;
  1180. framesCount = self->framesCount;
  1181. if (time >= frames[framesCount - IKCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
  1182. if (blend == SP_MIX_BLEND_SETUP) {
  1183. constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha;
  1184. constraint->softness = constraint->data->softness
  1185. + (frames[framesCount + IKCONSTRAINT_PREV_SOFTNESS] - constraint->data->softness) * alpha;
  1186. if (direction == SP_MIX_DIRECTION_OUT) {
  1187. constraint->bendDirection = constraint->data->bendDirection;
  1188. constraint->compress = constraint->data->compress;
  1189. constraint->stretch = constraint->data->stretch;
  1190. } else {
  1191. constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
  1192. constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
  1193. constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
  1194. }
  1195. } else {
  1196. constraint->mix += (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha;
  1197. constraint->softness += (frames[framesCount + IKCONSTRAINT_PREV_SOFTNESS] - constraint->softness) * alpha;
  1198. if (direction == SP_MIX_DIRECTION_IN) {
  1199. constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
  1200. constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
  1201. constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
  1202. }
  1203. }
  1204. return;
  1205. }
  1206. /* Interpolate between the previous frame and the current frame. */
  1207. frame = binarySearch(self->frames, self->framesCount, time, IKCONSTRAINT_ENTRIES);
  1208. mix = self->frames[frame + IKCONSTRAINT_PREV_MIX];
  1209. softness = frames[frame + IKCONSTRAINT_PREV_SOFTNESS];
  1210. frameTime = self->frames[frame];
  1211. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / IKCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + IKCONSTRAINT_PREV_TIME] - frameTime));
  1212. if (blend == SP_MIX_BLEND_SETUP) {
  1213. constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha;
  1214. constraint->softness = constraint->data->softness
  1215. + (softness + (frames[frame + IKCONSTRAINT_SOFTNESS] - softness) * percent - constraint->data->softness) * alpha;
  1216. if (direction == SP_MIX_DIRECTION_OUT) {
  1217. constraint->bendDirection = constraint->data->bendDirection;
  1218. constraint->compress = constraint->data->compress;
  1219. constraint->stretch = constraint->data->stretch;
  1220. } else {
  1221. constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
  1222. constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
  1223. constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
  1224. }
  1225. } else {
  1226. constraint->mix += (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha;
  1227. constraint->softness += (softness + (frames[frame + IKCONSTRAINT_SOFTNESS] - softness) * percent - constraint->softness) * alpha;
  1228. if (direction == SP_MIX_DIRECTION_IN) {
  1229. constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
  1230. constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
  1231. constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
  1232. }
  1233. }
  1234. UNUSED(lastTime);
  1235. UNUSED(firedEvents);
  1236. UNUSED(eventsCount);
  1237. }
  1238. int _spIkConstraintTimeline_getPropertyId (const spTimeline* timeline) {
  1239. return (SP_TIMELINE_IKCONSTRAINT << 24) + SUB_CAST(spIkConstraintTimeline, timeline)->ikConstraintIndex;
  1240. }
  1241. spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) {
  1242. return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply, _spIkConstraintTimeline_getPropertyId);
  1243. }
  1244. void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, float softness,
  1245. int bendDirection, int /*boolean*/ compress, int /*boolean*/ stretch
  1246. ) {
  1247. frameIndex *= IKCONSTRAINT_ENTRIES;
  1248. self->frames[frameIndex] = time;
  1249. self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
  1250. self->frames[frameIndex + IKCONSTRAINT_SOFTNESS] = softness;
  1251. self->frames[frameIndex + IKCONSTRAINT_BEND_DIRECTION] = (float)bendDirection;
  1252. self->frames[frameIndex + IKCONSTRAINT_COMPRESS] = compress ? 1 : 0;
  1253. self->frames[frameIndex + IKCONSTRAINT_STRETCH] = stretch ? 1 : 0;
  1254. }
  1255. /**/
  1256. static const int TRANSFORMCONSTRAINT_PREV_TIME = -5;
  1257. static const int TRANSFORMCONSTRAINT_PREV_ROTATE = -4;
  1258. static const int TRANSFORMCONSTRAINT_PREV_TRANSLATE = -3;
  1259. static const int TRANSFORMCONSTRAINT_PREV_SCALE = -2;
  1260. static const int TRANSFORMCONSTRAINT_PREV_SHEAR = -1;
  1261. static const int TRANSFORMCONSTRAINT_ROTATE = 1;
  1262. static const int TRANSFORMCONSTRAINT_TRANSLATE = 2;
  1263. static const int TRANSFORMCONSTRAINT_SCALE = 3;
  1264. static const int TRANSFORMCONSTRAINT_SHEAR = 4;
  1265. void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1266. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1267. ) {
  1268. int frame;
  1269. float frameTime, percent, rotate, translate, scale, shear;
  1270. spTransformConstraint* constraint;
  1271. spTransformConstraintTimeline* self = (spTransformConstraintTimeline*)timeline;
  1272. float *frames;
  1273. int framesCount;
  1274. constraint = skeleton->transformConstraints[self->transformConstraintIndex];
  1275. if (!constraint->active) return;
  1276. if (time < self->frames[0]) {
  1277. spTransformConstraintData* data = constraint->data;
  1278. switch (blend) {
  1279. case SP_MIX_BLEND_SETUP:
  1280. constraint->rotateMix = data->rotateMix;
  1281. constraint->translateMix = data->translateMix;
  1282. constraint->scaleMix = data->scaleMix;
  1283. constraint->shearMix = data->shearMix;
  1284. return;
  1285. case SP_MIX_BLEND_FIRST:
  1286. constraint->rotateMix += (data->rotateMix - constraint->rotateMix) * alpha;
  1287. constraint->translateMix += (data->translateMix - constraint->translateMix) * alpha;
  1288. constraint->scaleMix += (data->scaleMix - constraint->scaleMix) * alpha;
  1289. constraint->shearMix += (data->shearMix - constraint->shearMix) * alpha;
  1290. case SP_MIX_BLEND_REPLACE:
  1291. case SP_MIX_BLEND_ADD:
  1292. ; /* to appease compiler */
  1293. }
  1294. return;
  1295. return;
  1296. }
  1297. frames = self->frames;
  1298. framesCount = self->framesCount;
  1299. if (time >= frames[framesCount - TRANSFORMCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
  1300. int i = framesCount;
  1301. rotate = frames[i + TRANSFORMCONSTRAINT_PREV_ROTATE];
  1302. translate = frames[i + TRANSFORMCONSTRAINT_PREV_TRANSLATE];
  1303. scale = frames[i + TRANSFORMCONSTRAINT_PREV_SCALE];
  1304. shear = frames[i + TRANSFORMCONSTRAINT_PREV_SHEAR];
  1305. } else {
  1306. /* Interpolate between the previous frame and the current frame. */
  1307. frame = binarySearch(frames, framesCount, time, TRANSFORMCONSTRAINT_ENTRIES);
  1308. rotate = frames[frame + TRANSFORMCONSTRAINT_PREV_ROTATE];
  1309. translate = frames[frame + TRANSFORMCONSTRAINT_PREV_TRANSLATE];
  1310. scale = frames[frame + TRANSFORMCONSTRAINT_PREV_SCALE];
  1311. shear = frames[frame + TRANSFORMCONSTRAINT_PREV_SHEAR];
  1312. frameTime = frames[frame];
  1313. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSFORMCONSTRAINT_ENTRIES - 1,
  1314. 1 - (time - frameTime) / (frames[frame + TRANSFORMCONSTRAINT_PREV_TIME] - frameTime));
  1315. rotate += (frames[frame + TRANSFORMCONSTRAINT_ROTATE] - rotate) * percent;
  1316. translate += (frames[frame + TRANSFORMCONSTRAINT_TRANSLATE] - translate) * percent;
  1317. scale += (frames[frame + TRANSFORMCONSTRAINT_SCALE] - scale) * percent;
  1318. shear += (frames[frame + TRANSFORMCONSTRAINT_SHEAR] - shear) * percent;
  1319. }
  1320. if (blend == SP_MIX_BLEND_SETUP) {
  1321. spTransformConstraintData* data = constraint->data;
  1322. constraint->rotateMix = data->rotateMix + (rotate - data->rotateMix) * alpha;
  1323. constraint->translateMix = data->translateMix + (translate - data->translateMix) * alpha;
  1324. constraint->scaleMix = data->scaleMix + (scale - data->scaleMix) * alpha;
  1325. constraint->shearMix = data->shearMix + (shear - data->shearMix) * alpha;
  1326. } else {
  1327. constraint->rotateMix += (rotate - constraint->rotateMix) * alpha;
  1328. constraint->translateMix += (translate - constraint->translateMix) * alpha;
  1329. constraint->scaleMix += (scale - constraint->scaleMix) * alpha;
  1330. constraint->shearMix += (shear - constraint->shearMix) * alpha;
  1331. }
  1332. UNUSED(lastTime);
  1333. UNUSED(firedEvents);
  1334. UNUSED(eventsCount);
  1335. UNUSED(direction);
  1336. }
  1337. int _spTransformConstraintTimeline_getPropertyId (const spTimeline* timeline) {
  1338. return (SP_TIMELINE_TRANSFORMCONSTRAINT << 24) + SUB_CAST(spTransformConstraintTimeline, timeline)->transformConstraintIndex;
  1339. }
  1340. spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount) {
  1341. return (spTransformConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSFORMCONSTRAINT,
  1342. TRANSFORMCONSTRAINT_ENTRIES, _spTransformConstraintTimeline_apply, _spTransformConstraintTimeline_getPropertyId);
  1343. }
  1344. void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix,
  1345. float translateMix, float scaleMix, float shearMix
  1346. ) {
  1347. frameIndex *= TRANSFORMCONSTRAINT_ENTRIES;
  1348. self->frames[frameIndex] = time;
  1349. self->frames[frameIndex + TRANSFORMCONSTRAINT_ROTATE] = rotateMix;
  1350. self->frames[frameIndex + TRANSFORMCONSTRAINT_TRANSLATE] = translateMix;
  1351. self->frames[frameIndex + TRANSFORMCONSTRAINT_SCALE] = scaleMix;
  1352. self->frames[frameIndex + TRANSFORMCONSTRAINT_SHEAR] = shearMix;
  1353. }
  1354. /**/
  1355. static const int PATHCONSTRAINTPOSITION_PREV_TIME = -2;
  1356. static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1;
  1357. static const int PATHCONSTRAINTPOSITION_VALUE = 1;
  1358. void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1359. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1360. ) {
  1361. int frame;
  1362. float frameTime, percent, position;
  1363. spPathConstraint* constraint;
  1364. spPathConstraintPositionTimeline* self = (spPathConstraintPositionTimeline*)timeline;
  1365. float* frames;
  1366. int framesCount;
  1367. constraint = skeleton->pathConstraints[self->pathConstraintIndex];
  1368. if (!constraint->active) return;
  1369. if (time < self->frames[0]) {
  1370. switch (blend) {
  1371. case SP_MIX_BLEND_SETUP:
  1372. constraint->position = constraint->data->position;
  1373. return;
  1374. case SP_MIX_BLEND_FIRST:
  1375. constraint->position += (constraint->data->position - constraint->position) * alpha;
  1376. case SP_MIX_BLEND_REPLACE:
  1377. case SP_MIX_BLEND_ADD:
  1378. ; /* to appease compiler */
  1379. }
  1380. return;
  1381. }
  1382. frames = self->frames;
  1383. framesCount = self->framesCount;
  1384. if (time >= frames[framesCount - PATHCONSTRAINTPOSITION_ENTRIES]) /* Time is after last frame. */
  1385. position = frames[framesCount + PATHCONSTRAINTPOSITION_PREV_VALUE];
  1386. else {
  1387. /* Interpolate between the previous frame and the current frame. */
  1388. frame = binarySearch(frames, framesCount, time, PATHCONSTRAINTPOSITION_ENTRIES);
  1389. position = frames[frame + PATHCONSTRAINTPOSITION_PREV_VALUE];
  1390. frameTime = frames[frame];
  1391. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTPOSITION_ENTRIES - 1,
  1392. 1 - (time - frameTime) / (frames[frame + PATHCONSTRAINTPOSITION_PREV_TIME] - frameTime));
  1393. position += (frames[frame + PATHCONSTRAINTPOSITION_VALUE] - position) * percent;
  1394. }
  1395. if (blend == SP_MIX_BLEND_SETUP)
  1396. constraint->position = constraint->data->position + (position - constraint->data->position) * alpha;
  1397. else
  1398. constraint->position += (position - constraint->position) * alpha;
  1399. UNUSED(lastTime);
  1400. UNUSED(firedEvents);
  1401. UNUSED(eventsCount);
  1402. UNUSED(direction);
  1403. }
  1404. int _spPathConstraintPositionTimeline_getPropertyId (const spTimeline* timeline) {
  1405. return (SP_TIMELINE_PATHCONSTRAINTPOSITION << 24) + SUB_CAST(spPathConstraintPositionTimeline, timeline)->pathConstraintIndex;
  1406. }
  1407. spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount) {
  1408. return (spPathConstraintPositionTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTPOSITION,
  1409. PATHCONSTRAINTPOSITION_ENTRIES, _spPathConstraintPositionTimeline_apply, _spPathConstraintPositionTimeline_getPropertyId);
  1410. }
  1411. void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value) {
  1412. frameIndex *= PATHCONSTRAINTPOSITION_ENTRIES;
  1413. self->frames[frameIndex] = time;
  1414. self->frames[frameIndex + PATHCONSTRAINTPOSITION_VALUE] = value;
  1415. }
  1416. /**/
  1417. static const int PATHCONSTRAINTSPACING_PREV_TIME = -2;
  1418. static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1;
  1419. static const int PATHCONSTRAINTSPACING_VALUE = 1;
  1420. void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1421. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1422. ) {
  1423. int frame;
  1424. float frameTime, percent, spacing;
  1425. spPathConstraint* constraint;
  1426. spPathConstraintSpacingTimeline* self = (spPathConstraintSpacingTimeline*)timeline;
  1427. float* frames;
  1428. int framesCount;
  1429. constraint = skeleton->pathConstraints[self->pathConstraintIndex];
  1430. if (!constraint->active) return;
  1431. if (time < self->frames[0]) {
  1432. switch (blend) {
  1433. case SP_MIX_BLEND_SETUP:
  1434. constraint->spacing = constraint->data->spacing;
  1435. return;
  1436. case SP_MIX_BLEND_FIRST:
  1437. constraint->spacing += (constraint->data->spacing - constraint->spacing) * alpha;
  1438. case SP_MIX_BLEND_REPLACE:
  1439. case SP_MIX_BLEND_ADD:
  1440. ; /* to appease compiler */
  1441. }
  1442. return;
  1443. }
  1444. frames = self->frames;
  1445. framesCount = self->framesCount;
  1446. if (time >= frames[framesCount - PATHCONSTRAINTSPACING_ENTRIES]) /* Time is after last frame. */
  1447. spacing = frames[framesCount + PATHCONSTRAINTSPACING_PREV_VALUE];
  1448. else {
  1449. /* Interpolate between the previous frame and the current frame. */
  1450. frame = binarySearch(frames, framesCount, time, PATHCONSTRAINTSPACING_ENTRIES);
  1451. spacing = frames[frame + PATHCONSTRAINTSPACING_PREV_VALUE];
  1452. frameTime = frames[frame];
  1453. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTSPACING_ENTRIES - 1,
  1454. 1 - (time - frameTime) / (frames[frame + PATHCONSTRAINTSPACING_PREV_TIME] - frameTime));
  1455. spacing += (frames[frame + PATHCONSTRAINTSPACING_VALUE] - spacing) * percent;
  1456. }
  1457. if (blend == SP_MIX_BLEND_SETUP)
  1458. constraint->spacing = constraint->data->spacing + (spacing - constraint->data->spacing) * alpha;
  1459. else
  1460. constraint->spacing += (spacing - constraint->spacing) * alpha;
  1461. UNUSED(lastTime);
  1462. UNUSED(firedEvents);
  1463. UNUSED(eventsCount);
  1464. UNUSED(direction);
  1465. }
  1466. int _spPathConstraintSpacingTimeline_getPropertyId (const spTimeline* timeline) {
  1467. return (SP_TIMELINE_PATHCONSTRAINTSPACING << 24) + SUB_CAST(spPathConstraintSpacingTimeline, timeline)->pathConstraintIndex;
  1468. }
  1469. spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount) {
  1470. return (spPathConstraintSpacingTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTSPACING,
  1471. PATHCONSTRAINTSPACING_ENTRIES, _spPathConstraintSpacingTimeline_apply, _spPathConstraintSpacingTimeline_getPropertyId);
  1472. }
  1473. void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value) {
  1474. frameIndex *= PATHCONSTRAINTSPACING_ENTRIES;
  1475. self->frames[frameIndex] = time;
  1476. self->frames[frameIndex + PATHCONSTRAINTSPACING_VALUE] = value;
  1477. }
  1478. /**/
  1479. static const int PATHCONSTRAINTMIX_PREV_TIME = -3;
  1480. static const int PATHCONSTRAINTMIX_PREV_ROTATE = -2;
  1481. static const int PATHCONSTRAINTMIX_PREV_TRANSLATE = -1;
  1482. static const int PATHCONSTRAINTMIX_ROTATE = 1;
  1483. static const int PATHCONSTRAINTMIX_TRANSLATE = 2;
  1484. void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
  1485. spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
  1486. ) {
  1487. int frame;
  1488. float frameTime, percent, rotate, translate;
  1489. spPathConstraint* constraint;
  1490. spPathConstraintMixTimeline* self = (spPathConstraintMixTimeline*)timeline;
  1491. float* frames;
  1492. int framesCount;
  1493. constraint = skeleton->pathConstraints[self->pathConstraintIndex];
  1494. if (!constraint->active) return;
  1495. if (time < self->frames[0]) {
  1496. switch (blend) {
  1497. case SP_MIX_BLEND_SETUP:
  1498. constraint->rotateMix = constraint->data->rotateMix;
  1499. constraint->translateMix = constraint->data->translateMix;
  1500. return;
  1501. case SP_MIX_BLEND_FIRST:
  1502. constraint->rotateMix += (constraint->data->rotateMix - constraint->rotateMix) * alpha;
  1503. constraint->translateMix += (constraint->data->translateMix - constraint->translateMix) * alpha;
  1504. case SP_MIX_BLEND_REPLACE:
  1505. case SP_MIX_BLEND_ADD:
  1506. ; /* to appease compiler */
  1507. }
  1508. return;
  1509. }
  1510. frames = self->frames;
  1511. framesCount = self->framesCount;
  1512. if (time >= frames[framesCount - PATHCONSTRAINTMIX_ENTRIES]) { /* Time is after last frame. */
  1513. rotate = frames[framesCount + PATHCONSTRAINTMIX_PREV_ROTATE];
  1514. translate = frames[framesCount + PATHCONSTRAINTMIX_PREV_TRANSLATE];
  1515. } else {
  1516. /* Interpolate between the previous frame and the current frame. */
  1517. frame = binarySearch(frames, framesCount, time, PATHCONSTRAINTMIX_ENTRIES);
  1518. rotate = frames[frame + PATHCONSTRAINTMIX_PREV_ROTATE];
  1519. translate = frames[frame + PATHCONSTRAINTMIX_PREV_TRANSLATE];
  1520. frameTime = frames[frame];
  1521. percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / PATHCONSTRAINTMIX_ENTRIES - 1,
  1522. 1 - (time - frameTime) / (frames[frame + PATHCONSTRAINTMIX_PREV_TIME] - frameTime));
  1523. rotate += (frames[frame + PATHCONSTRAINTMIX_ROTATE] - rotate) * percent;
  1524. translate += (frames[frame + PATHCONSTRAINTMIX_TRANSLATE] - translate) * percent;
  1525. }
  1526. if (blend == SP_MIX_BLEND_SETUP) {
  1527. constraint->rotateMix = constraint->data->rotateMix + (rotate - constraint->data->rotateMix) * alpha;
  1528. constraint->translateMix = constraint->data->translateMix + (translate - constraint->data->translateMix) * alpha;
  1529. } else {
  1530. constraint->rotateMix += (rotate - constraint->rotateMix) * alpha;
  1531. constraint->translateMix += (translate - constraint->translateMix) * alpha;
  1532. }
  1533. UNUSED(lastTime);
  1534. UNUSED(firedEvents);
  1535. UNUSED(eventsCount);
  1536. UNUSED(direction);
  1537. }
  1538. int _spPathConstraintMixTimeline_getPropertyId (const spTimeline* timeline) {
  1539. return (SP_TIMELINE_PATHCONSTRAINTMIX << 24) + SUB_CAST(spPathConstraintMixTimeline, timeline)->pathConstraintIndex;
  1540. }
  1541. spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount) {
  1542. return (spPathConstraintMixTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTMIX,
  1543. PATHCONSTRAINTMIX_ENTRIES, _spPathConstraintMixTimeline_apply, _spPathConstraintMixTimeline_getPropertyId);
  1544. }
  1545. void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix) {
  1546. frameIndex *= PATHCONSTRAINTMIX_ENTRIES;
  1547. self->frames[frameIndex] = time;
  1548. self->frames[frameIndex + PATHCONSTRAINTMIX_ROTATE] = rotateMix;
  1549. self->frames[frameIndex + PATHCONSTRAINTMIX_TRANSLATE] = translateMix;
  1550. }