Animation.lua 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569
  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 Owelp,F
  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. -- FIXME
  31. -- All the indexing in this file is zero based. We use zlen()
  32. -- instead of the # operator. Initialization of number arrays
  33. -- is performed via utils.newNumberArrayZero. This needs
  34. -- to be rewritten using one-based indexing for better performance
  35. local utils = require "spine-lua.utils"
  36. local AttachmentType = require "spine-lua.attachments.AttachmentType"
  37. local math_floor = math.floor
  38. local math_abs = math.abs
  39. local math_signum = utils.signum
  40. local function zlen(array)
  41. return #array + 1
  42. end
  43. local Animation = {}
  44. function Animation.new (name, timelines, duration)
  45. if not timelines then error("timelines cannot be nil", 2) end
  46. local self = {
  47. name = name,
  48. timelines = timelines,
  49. duration = duration
  50. }
  51. function self:apply (skeleton, lastTime, time, loop, events, alpha, blend, direction)
  52. if not skeleton then error("skeleton cannot be nil.", 2) end
  53. if loop and duration > 0 then
  54. time = time % self.duration
  55. if lastTime > 0 then lastTime = lastTime % self.duration end
  56. end
  57. for i,timeline in ipairs(self.timelines) do
  58. timeline:apply(skeleton, lastTime, time, events, alpha, blend, direction)
  59. end
  60. end
  61. return self
  62. end
  63. local function binarySearch (values, target, step)
  64. local low = 0
  65. local high = math.floor(zlen(values) / step - 2)
  66. if high == 0 then return step end
  67. local current = math.floor(high / 2)
  68. while true do
  69. if values[(current + 1) * step] <= target then
  70. low = current + 1
  71. else
  72. high = current
  73. end
  74. if low == high then return (low + 1) * step end
  75. current = math.floor((low + high) / 2)
  76. end
  77. end
  78. Animation.binarySearch = binarySearch
  79. local function binarySearch1 (values, target)
  80. local low = 0
  81. local high = math.floor(zlen(values) - 2)
  82. if high == 0 then return 1 end
  83. local current = math.floor(high / 2)
  84. while true do
  85. if values[current + 1] <= target then
  86. low = current + 1
  87. else
  88. high = current
  89. end
  90. if low == high then return low + 1 end
  91. current = math.floor((low + high) / 2)
  92. end
  93. end
  94. local function linearSearch (values, target, step)
  95. local i = 0
  96. local last = zlen(values) - step
  97. while i <= last do
  98. if (values[i] > target) then return i end
  99. i = i + step
  100. end
  101. return -1
  102. end
  103. Animation.MixBlend = {
  104. setup = 0,
  105. first = 1,
  106. replace = 2,
  107. add = 3
  108. }
  109. local MixBlend = Animation.MixBlend
  110. Animation.MixDirection = {
  111. _in = 0, out = 1
  112. }
  113. local MixDirection = Animation.MixDirection
  114. Animation.TimelineType = {
  115. rotate = 0, translate = 1, scale = 2, shear = 3,
  116. attachment = 4, color = 5, deform = 6,
  117. event = 7, drawOrder = 8,
  118. ikConstraint = 9, transformConstraint = 10,
  119. pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13,
  120. twoColor = 14
  121. }
  122. local TimelineType = Animation.TimelineType
  123. local SHL_24 = 16777216
  124. local SHL_27 = 134217728
  125. Animation.CurveTimeline = {}
  126. function Animation.CurveTimeline.new (frameCount)
  127. local LINEAR = 0
  128. local STEPPED = 1
  129. local BEZIER = 2
  130. local BEZIER_SIZE = 10 * 2 - 1
  131. local self = {
  132. curves = utils.newNumberArrayZero((frameCount - 1) * BEZIER_SIZE) -- type, x, y, ...
  133. }
  134. function self:getFrameCount ()
  135. return math.floor(zlen(self.curves) / BEZIER_SIZE) + 1
  136. end
  137. function self:setStepped (frameIndex)
  138. self.curves[frameIndex * BEZIER_SIZE] = STEPPED
  139. end
  140. function self:getCurveType (frameIndex)
  141. local index = frameIndex * BEZIER_SIZE
  142. if index == zlen(self.curves) then return LINEAR end
  143. local type = self.curves[index]
  144. if type == LINEAR then return LINEAR end
  145. if type == STEPPED then return STEPPED end
  146. return BEZIER
  147. end
  148. function self:setCurve (frameIndex, cx1, cy1, cx2, cy2)
  149. local tmpx = (-cx1 * 2 + cx2) * 0.03
  150. local tmpy = (-cy1 * 2 + cy2) * 0.03
  151. local dddfx = ((cx1 - cx2) * 3 + 1) * 0.006
  152. local dddfy = ((cy1 - cy2) * 3 + 1) * 0.006
  153. local ddfx = tmpx * 2 + dddfx
  154. local ddfy = tmpy * 2 + dddfy
  155. local dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667
  156. local dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667
  157. local i = frameIndex * BEZIER_SIZE
  158. local curves = self.curves
  159. curves[i] = BEZIER
  160. i = i + 1
  161. local x = dfx
  162. local y = dfy
  163. local n = i + BEZIER_SIZE - 1
  164. while i < n do
  165. curves[i] = x
  166. curves[i + 1] = y
  167. dfx = dfx + ddfx
  168. dfy = dfy + ddfy
  169. ddfx = ddfx + dddfx
  170. ddfy = ddfy + dddfy
  171. x = x + dfx
  172. y = y + dfy
  173. i = i + 2
  174. end
  175. end
  176. function self:getCurvePercent (frameIndex, percent)
  177. percent = utils.clamp(percent, 0, 1)
  178. local curves = self.curves
  179. local i = frameIndex * BEZIER_SIZE
  180. local type = curves[i]
  181. if type == LINEAR then return percent end
  182. if type == STEPPED then return 0 end
  183. i = i + 1
  184. local x
  185. local n = i + BEZIER_SIZE - 1
  186. local start = i
  187. while i < n do
  188. x = curves[i]
  189. if x >= percent then
  190. local prevX, prevY
  191. if i == start then
  192. prevX = 0
  193. prevY = 0
  194. else
  195. prevX = curves[i - 2]
  196. prevY = curves[i - 1]
  197. end
  198. return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX)
  199. end
  200. i = i + 2
  201. end
  202. local y = curves[i - 1]
  203. return y + (1 - y) * (percent - x) / (1 - x) -- Last point is 1,1.
  204. end
  205. return self
  206. end
  207. Animation.RotateTimeline = {}
  208. Animation.RotateTimeline.ENTRIES = 2
  209. Animation.RotateTimeline.PREV_TIME = -2
  210. Animation.RotateTimeline.PREV_ROTATION = -1
  211. Animation.RotateTimeline.ROTATION = 1
  212. function Animation.RotateTimeline.new (frameCount)
  213. local ENTRIES = Animation.RotateTimeline.ENTRIES
  214. local PREV_TIME = Animation.RotateTimeline.PREV_TIME
  215. local PREV_ROTATION = Animation.RotateTimeline.PREV_ROTATION
  216. local ROTATION = Animation.RotateTimeline.ROTATION
  217. local self = Animation.CurveTimeline.new(frameCount)
  218. self.boneIndex = -1
  219. self.frames = utils.newNumberArrayZero(frameCount * 2)
  220. self.type = TimelineType.rotate
  221. function self:getPropertyId ()
  222. return TimelineType.rotate * SHL_24 + self.boneIndex
  223. end
  224. function self:setFrame (frameIndex, time, degrees)
  225. frameIndex = frameIndex * 2
  226. self.frames[frameIndex] = time
  227. self.frames[frameIndex + ROTATION] = degrees
  228. end
  229. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  230. local frames = self.frames
  231. local bone = skeleton.bones[self.boneIndex]
  232. if time < frames[0] then
  233. if blend == MixBlend.setup then
  234. bone.rotation = bone.data.rotation
  235. elseif blend == MixBlend.first then
  236. local r = bone.data.rotation - bone.rotation
  237. bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
  238. end
  239. return
  240. end
  241. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  242. local r = frames[zlen(frames) + PREV_ROTATION]
  243. if blend == MixBlend.setup then
  244. bone.rotation = bone.data.rotation + r * alpha
  245. elseif blend == MixBlend.first or blend == MixBlend.replace then
  246. r = r + bone.data.rotation - bone.rotation
  247. r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 -- Wrap within -180 and 180.
  248. bone.rotation = bone.rotation + r * alpha;
  249. elseif blend == MixBlend.add then
  250. bone.rotation = bone.rotation + r * alpha;
  251. end
  252. return;
  253. end
  254. -- Interpolate between the last frame and the current frame.
  255. local frame = binarySearch(frames, time, ENTRIES)
  256. local prevRotation = frames[frame + PREV_ROTATION]
  257. local frameTime = frames[frame]
  258. local percent = self:getCurvePercent((math.floor(frame / 2)) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  259. local r = frames[frame + ROTATION] - prevRotation
  260. r = prevRotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * percent
  261. if blend == MixBlend.setup then
  262. bone.rotation = bone.data.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
  263. elseif blend == MixBlend.first or blend == MixBlend.replace then
  264. r = r + bone.data.rotation - bone.rotation;
  265. bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
  266. elseif blend == MixBlend.add then
  267. bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
  268. end
  269. end
  270. return self
  271. end
  272. Animation.TranslateTimeline = {}
  273. Animation.TranslateTimeline.ENTRIES = 3
  274. function Animation.TranslateTimeline.new (frameCount)
  275. local ENTRIES = Animation.TranslateTimeline.ENTRIES
  276. local PREV_TIME = -3
  277. local PREV_X = -2
  278. local PREV_Y = -1
  279. local X = 1
  280. local Y = 2
  281. local self = Animation.CurveTimeline.new(frameCount)
  282. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  283. self.boneIndex = -1
  284. self.type = TimelineType.translate
  285. function self:getPropertyId ()
  286. return TimelineType.translate * SHL_24 + self.boneIndex
  287. end
  288. function self:setFrame (frameIndex, time, x, y)
  289. frameIndex = frameIndex * ENTRIES
  290. self.frames[frameIndex] = time
  291. self.frames[frameIndex + X] = x
  292. self.frames[frameIndex + Y] = y
  293. end
  294. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  295. local frames = self.frames
  296. local bone = skeleton.bones[self.boneIndex]
  297. if time < frames[0] then
  298. if blend == MixBlend.setup then
  299. bone.x = bone.data.x
  300. bone.y = bone.data.y
  301. elseif blend == MixBlend.first then
  302. bone.x = bone.x + (bone.data.x - bone.x) * alpha
  303. bone.y = bone.y + (bone.data.y - bone.y) * alpha
  304. end
  305. return
  306. end
  307. local x = 0
  308. local y = 0
  309. if time >= frames[zlen(frames) - ENTRIES] then -- // Time is after last frame.
  310. x = frames[zlen(frames) + PREV_X];
  311. y = frames[zlen(frames) + PREV_Y];
  312. else
  313. -- Interpolate between the previous frame and the current frame.
  314. local frame = binarySearch(frames, time, ENTRIES)
  315. x = frames[frame + PREV_X]
  316. y = frames[frame + PREV_Y]
  317. local frameTime = frames[frame]
  318. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  319. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
  320. x = x + (frames[frame + X] - x) * percent
  321. y = y + (frames[frame + Y] - y) * percent
  322. end
  323. if blend == MixBlend.setup then
  324. bone.x = bone.data.x + x * alpha
  325. bone.y = bone.data.y + y * alpha
  326. elseif blend == MixBlend.first or blend == MixBlend.replace then
  327. bone.x = bone.x + (bone.data.x + x - bone.x) * alpha
  328. bone.y = bone.y + (bone.data.y + y - bone.y) * alpha
  329. elseif blend == MixBlend.add then
  330. bone.x = bone.x + x * alpha
  331. bone.y = bone.y + y * alpha
  332. end
  333. end
  334. return self
  335. end
  336. Animation.ScaleTimeline = {}
  337. Animation.ScaleTimeline.ENTRIES = Animation.TranslateTimeline.ENTRIES
  338. function Animation.ScaleTimeline.new (frameCount)
  339. local ENTRIES = Animation.ScaleTimeline.ENTRIES
  340. local PREV_TIME = -3
  341. local PREV_X = -2
  342. local PREV_Y = -1
  343. local X = 1
  344. local Y = 2
  345. local self = Animation.TranslateTimeline.new(frameCount)
  346. self.type = TimelineType.scale
  347. function self:getPropertyId ()
  348. return TimelineType.scale * SHL_24 + self.boneIndex
  349. end
  350. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  351. local frames = self.frames
  352. local bone = skeleton.bones[self.boneIndex]
  353. if time < frames[0] then
  354. if blend == MixBlend.setup then
  355. bone.scaleX = bone.data.scaleX
  356. bone.scaleY = bone.data.scaleY
  357. elseif blend == MixBlend.first then
  358. bone.scaleX = bone.scaleX + (bone.data.scaleX - bone.scaleX) * alpha
  359. bone.scaleY = bone.scaleY + (bone.data.scaleY - bone.scaleY) * alpha
  360. end
  361. return
  362. end
  363. local x = 0
  364. local y = 0
  365. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  366. x = frames[zlen(frames) + PREV_X] * bone.data.scaleX
  367. y = frames[zlen(frames) + PREV_Y] * bone.data.scaleY
  368. else
  369. -- Interpolate between the previous frame and the current frame.
  370. local frame = binarySearch(frames, time, ENTRIES)
  371. x = frames[frame + PREV_X]
  372. y = frames[frame + PREV_Y]
  373. local frameTime = frames[frame]
  374. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  375. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  376. x = (x + (frames[frame + X] - x) * percent) * bone.data.scaleX
  377. y = (y + (frames[frame + Y] - y) * percent) * bone.data.scaleY
  378. end
  379. if alpha == 1 then
  380. if blend == MixBlend.add then
  381. bone.scaleX = bone.scaleX + x - bone.data.scaleX
  382. bone.scaleY = bone.scaleY + y - bone.data.scaleY
  383. else
  384. bone.scaleX = x
  385. bone.scaleY = y
  386. end
  387. else
  388. local bx = 0
  389. local by = 0
  390. if direction == MixDirection.out then
  391. if blend == MixBlend.setup then
  392. bx = bone.data.scaleX
  393. by = bone.data.scaleY
  394. bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bx) * alpha
  395. bone.scaleY = by + (math_abs(y) * math_signum(by) - by) * alpha
  396. elseif blend == MixBlend.first or blend == MixBlend.replace then
  397. bx = bone.scaleX
  398. by = bone.scaleY
  399. bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bx) * alpha
  400. bone.scaleY = by + (math_abs(y) * math_signum(by) - by) * alpha
  401. elseif blend == MixBlend.add then
  402. bx = bone.scaleX
  403. by = bone.scaleY
  404. bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bone.data.scaleX) * alpha
  405. bone.scaleY = by + (math_abs(y) * math_signum(by) - bone.data.scaleY) * alpha
  406. end
  407. else
  408. if blend == MixBlend.setup then
  409. bx = math_abs(bone.data.scaleX) * math_signum(x)
  410. by = math_abs(bone.data.scaleY) * math_signum(y)
  411. bone.scaleX = bx + (x - bx) * alpha
  412. bone.scaleY = by + (y - by) * alpha
  413. elseif blend == MixBlend.first or blend == MixBlend.replace then
  414. bx = math_abs(bone.scaleX) * math_signum(x)
  415. by = math_abs(bone.scaleY) * math_signum(y)
  416. bone.scaleX = bx + (x - bx) * alpha
  417. bone.scaleY = by + (y - by) * alpha
  418. elseif blend == MixBlend.add then
  419. bx = math_signum(x)
  420. by = math_signum(y)
  421. bone.scaleX = math_abs(bone.scaleX) * bx + (x - math_abs(bone.data.scaleX) * bx) * alpha
  422. bone.scaleY = math_abs(bone.scaleY) * by + (y - math_abs(bone.data.scaleY) * by) * alpha
  423. end
  424. end
  425. end
  426. end
  427. return self
  428. end
  429. Animation.ShearTimeline = {}
  430. Animation.ShearTimeline.ENTRIES = Animation.TranslateTimeline.ENTRIES
  431. function Animation.ShearTimeline.new (frameCount)
  432. local ENTRIES = Animation.ShearTimeline.ENTRIES
  433. local PREV_TIME = -3
  434. local PREV_X = -2
  435. local PREV_Y = -1
  436. local X = 1
  437. local Y = 2
  438. local self = Animation.TranslateTimeline.new(frameCount)
  439. self.type = TimelineType.shear
  440. function self:getPropertyId ()
  441. return TimelineType.shear * SHL_24 + self.boneIndex
  442. end
  443. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  444. local frames = self.frames
  445. local bone = skeleton.bones[self.boneIndex]
  446. if time < frames[0] then
  447. if blend == MixBlend.setup then
  448. bone.shearX = bone.data.shearX
  449. bone.shearY = bone.data.shearY
  450. elseif blend == MixBlend.first then
  451. bone.shearX = bone.shearX + (bone.data.shearX - bone.shearX) * alpha
  452. bone.shearY = bone.shearX + (bone.data.shearY - bone.shearY) * alpha
  453. end
  454. return
  455. end
  456. local x = 0
  457. local y = 0
  458. if time >= frames[zlen(frames) - ENTRIES] then -- // Time is after last frame.
  459. x = frames[zlen(frames) + PREV_X]
  460. y = frames[zlen(frames) + PREV_Y]
  461. else
  462. -- Interpolate between the previous frame and the current frame.
  463. local frame = binarySearch(frames, time, ENTRIES)
  464. x = frames[frame + PREV_X]
  465. y = frames[frame + PREV_Y]
  466. local frameTime = frames[frame]
  467. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  468. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  469. x = x + (frames[frame + X] - x) * percent
  470. y = y + (frames[frame + Y] - y) * percent
  471. end
  472. if blend == MixBlend.setup then
  473. bone.shearX = bone.data.shearX + x * alpha
  474. bone.shearY = bone.data.shearY + y * alpha
  475. elseif blend == MixBlend.first or blend == MixBlend.replace then
  476. bone.shearX = bone.shearX + (bone.data.shearX + x - bone.shearX) * alpha
  477. bone.shearY = bone.shearY + (bone.data.shearY + y - bone.shearY) * alpha
  478. elseif blend == MixBlend.add then
  479. bone.shearX = bone.shearX + x * alpha
  480. bone.shearY = bone.shearY + y * alpha
  481. end
  482. end
  483. return self
  484. end
  485. Animation.ColorTimeline = {}
  486. Animation.ColorTimeline.ENTRIES = 5
  487. function Animation.ColorTimeline.new (frameCount)
  488. local ENTRIES = Animation.ColorTimeline.ENTRIES
  489. local PREV_TIME = -5
  490. local PREV_R = -4
  491. local PREV_G = -3
  492. local PREV_B = -2
  493. local PREV_A = -1
  494. local R = 1
  495. local G = 2
  496. local B = 3
  497. local A = 4
  498. local self = Animation.CurveTimeline.new(frameCount)
  499. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  500. self.slotIndex = -1
  501. self.type = TimelineType.color
  502. function self:getPropertyId ()
  503. return TimelineType.color * SHL_24 + self.slotIndex
  504. end
  505. function self:setFrame (frameIndex, time, r, g, b, a)
  506. frameIndex = frameIndex * ENTRIES
  507. self.frames[frameIndex] = time
  508. self.frames[frameIndex + R] = r
  509. self.frames[frameIndex + G] = g
  510. self.frames[frameIndex + B] = b
  511. self.frames[frameIndex + A] = a
  512. end
  513. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  514. local frames = self.frames
  515. local slot = skeleton.slots[self.slotIndex]
  516. if time < frames[0] then
  517. if blend == MixBlend.setup then
  518. slot.color:setFrom(slot.data.color)
  519. elseif blend == MixBlend.first then
  520. local color = slot.color
  521. local setup = slot.data.color
  522. color:add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
  523. (setup.a - color.a) * alpha)
  524. end
  525. return
  526. end
  527. local r, g, b, a
  528. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  529. local i = zlen(frames)
  530. r = frames[i + PREV_R]
  531. g = frames[i + PREV_G]
  532. b = frames[i + PREV_B]
  533. a = frames[i + PREV_A]
  534. else
  535. -- Interpolate between the last frame and the current frame.
  536. local frame = binarySearch(frames, time, ENTRIES)
  537. r = frames[frame + PREV_R]
  538. g = frames[frame + PREV_G]
  539. b = frames[frame + PREV_B]
  540. a = frames[frame + PREV_A]
  541. local frameTime = frames[frame]
  542. local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
  543. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  544. r = r + (frames[frame + R] - r) * percent
  545. g = g + (frames[frame + G] - g) * percent
  546. b = b + (frames[frame + B] - b) * percent
  547. a = a + (frames[frame + A] - a) * percent
  548. end
  549. if alpha == 1 then
  550. slot.color:set(r, g, b, a)
  551. else
  552. local color = slot.color
  553. if blend == MixBlend.setup then color:setFrom(slot.data.color) end
  554. color:add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha)
  555. end
  556. end
  557. return self
  558. end
  559. Animation.TwoColorTimeline = {}
  560. Animation.TwoColorTimeline.ENTRIES = 8
  561. function Animation.TwoColorTimeline.new (frameCount)
  562. local ENTRIES = Animation.TwoColorTimeline.ENTRIES
  563. local PREV_TIME = -8
  564. local PREV_R = -7
  565. local PREV_G = -6
  566. local PREV_B = -5
  567. local PREV_A = -4
  568. local PREV_R2 = -3
  569. local PREV_G2 = -2
  570. local PREV_B2 = -1
  571. local R = 1
  572. local G = 2
  573. local B = 3
  574. local A = 4
  575. local R2 = 5
  576. local G2 = 6
  577. local B2 = 7
  578. local self = Animation.CurveTimeline.new(frameCount)
  579. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  580. self.slotIndex = -1
  581. self.type = TimelineType.twoColor
  582. function self:getPropertyId ()
  583. return TimelineType.twoColor * SHL_24 + self.slotIndex
  584. end
  585. function self:setFrame (frameIndex, time, r, g, b, a, r2, g2, b2)
  586. frameIndex = frameIndex * ENTRIES
  587. self.frames[frameIndex] = time
  588. self.frames[frameIndex + R] = r
  589. self.frames[frameIndex + G] = g
  590. self.frames[frameIndex + B] = b
  591. self.frames[frameIndex + A] = a
  592. self.frames[frameIndex + R2] = r2
  593. self.frames[frameIndex + G2] = g2
  594. self.frames[frameIndex + B2] = b2
  595. end
  596. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  597. local frames = self.frames
  598. local slot = skeleton.slots[self.slotIndex]
  599. if time < frames[0] then
  600. if blend == MixBlend.setup then
  601. slot.color:setFrom(slot.data.color)
  602. slot.darkColor:setFrom(slot.data.darkColor)
  603. elseif blend == MixBlend.first then
  604. local light = slot.color
  605. local dark = slot.darkColor
  606. local setupLight = slot.data.color
  607. local setupDark = slot.data.darkColor
  608. light:add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha,
  609. (setupLight.a - light.a) * alpha)
  610. dark:add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0)
  611. end
  612. return
  613. end
  614. local r, g, b, a, r2, g2, b2
  615. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  616. local i = zlen(frames)
  617. r = frames[i + PREV_R]
  618. g = frames[i + PREV_G]
  619. b = frames[i + PREV_B]
  620. a = frames[i + PREV_A]
  621. r2 = frames[i + PREV_R2]
  622. g2 = frames[i + PREV_G2]
  623. b2 = frames[i + PREV_B2]
  624. else
  625. -- Interpolate between the last frame and the current frame.
  626. local frame = binarySearch(frames, time, ENTRIES)
  627. r = frames[frame + PREV_R]
  628. g = frames[frame + PREV_G]
  629. b = frames[frame + PREV_B]
  630. a = frames[frame + PREV_A]
  631. r2 = frames[frame + PREV_R2]
  632. g2 = frames[frame + PREV_G2]
  633. b2 = frames[frame + PREV_B2]
  634. local frameTime = frames[frame]
  635. local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
  636. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  637. r = r + (frames[frame + R] - r) * percent
  638. g = g + (frames[frame + G] - g) * percent
  639. b = b + (frames[frame + B] - b) * percent
  640. a = a + (frames[frame + A] - a) * percent
  641. r2 = r2 + (frames[frame + R2] - r2) * percent
  642. g2 = g2 + (frames[frame + G2] - g2) * percent
  643. b2 = b2 + (frames[frame + B2] - b2) * percent
  644. end
  645. if alpha == 1 then
  646. slot.color:set(r, g, b, a)
  647. slot.darkColor:set(r2, g2, b2, 1)
  648. else
  649. local light = slot.color
  650. local dark = slot.darkColor
  651. if blend == MixBlend.setup then
  652. light:setFrom(slot.data.color)
  653. dark:setFrom(slot.data.darkColor)
  654. end
  655. light:add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha)
  656. dark:add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0)
  657. end
  658. end
  659. return self
  660. end
  661. Animation.AttachmentTimeline = {}
  662. function Animation.AttachmentTimeline.new (frameCount)
  663. local self = {
  664. frames = utils.newNumberArrayZero(frameCount), -- time, ...
  665. attachmentNames = {},
  666. slotIndex = -1,
  667. type = TimelineType.attachment
  668. }
  669. function self:getFrameCount ()
  670. return zlen(self.frames)
  671. end
  672. function self:setFrame (frameIndex, time, attachmentName)
  673. self.frames[frameIndex] = time
  674. self.attachmentNames[frameIndex] = attachmentName
  675. end
  676. function self:getPropertyId ()
  677. return TimelineType.attachment * SHL_24 + self.slotIndex
  678. end
  679. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  680. local slot = skeleton.slots[self.slotIndex]
  681. local attachmentName
  682. if direction == MixDirection.out and blend == MixBlend.setup then
  683. attachmentName = slot.data.attachmentName
  684. if not attachmentName then
  685. slot:setAttachment(nil)
  686. else
  687. slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
  688. end
  689. return;
  690. end
  691. local frames = self.frames
  692. if time < frames[0] then
  693. if blend == MixBlend.setup or blend == MixBlend.first then
  694. attachmentName = slot.data.attachmentName
  695. if not attachmentName then
  696. slot:setAttachment(nil)
  697. else
  698. slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
  699. end
  700. end
  701. return
  702. end
  703. local frameIndex = 0
  704. if time >= frames[zlen(frames) - 1] then
  705. frameIndex = zlen(frames) - 1
  706. else
  707. frameIndex = binarySearch(frames, time, 1) - 1
  708. end
  709. attachmentName = self.attachmentNames[frameIndex]
  710. if not attachmentName then
  711. slot:setAttachment(nil)
  712. else
  713. slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
  714. end
  715. end
  716. return self
  717. end
  718. Animation.DeformTimeline = {}
  719. function Animation.DeformTimeline.new (frameCount)
  720. local self = Animation.CurveTimeline.new(frameCount)
  721. self.frames = utils.newNumberArrayZero(frameCount)
  722. self.frameVertices = utils.newNumberArrayZero(frameCount)
  723. self.slotIndex = -1
  724. self.attachment = nil
  725. self.type = TimelineType.deform
  726. function self:getPropertyId ()
  727. return TimelineType.deform * SHL_27 + self.attachment.id + self.slotIndex
  728. end
  729. function self:setFrame (frameIndex, time, vertices)
  730. self.frames[frameIndex] = time
  731. self.frameVertices[frameIndex] = vertices
  732. end
  733. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  734. local slot = skeleton.slots[self.slotIndex]
  735. local slotAttachment = slot.attachment
  736. if not slotAttachment then return end
  737. if not (slotAttachment.type == AttachmentType.mesh or slotAttachment.type == AttachmentType.linkedmesh or slotAttachment.type == AttachmentType.path or slotAttachment.type == AttachmentType.boundingbox) then return end
  738. if not slotAttachment:applyDeform(self.attachment) then return end
  739. local frames = self.frames
  740. local verticesArray = slot.attachmentVertices
  741. if #(verticesArray) == 0 then blend = MixBlend.setup end
  742. local frameVertices = self.frameVertices
  743. local vertexCount = #(frameVertices[0])
  744. if time < frames[0] then
  745. local vertexAttachment = slotAttachment;
  746. if blend == MixBlend.setup then
  747. slot.attachmentVertices = {}
  748. return;
  749. elseif blend == MixBlend.first then
  750. if (alpha == 1) then
  751. slot.attachmentVertices = {}
  752. return;
  753. end
  754. local vertices = utils.setArraySize(verticesArray, vertexCount)
  755. if (vertexAttachment.bones == nil) then
  756. local setupVertices = vertexAttachment.vertices
  757. local i = 1
  758. while i <= vertexCount do
  759. vertices[i] = vertices[i] + (setupVertices[i] - vertices[i]) * alpha
  760. i = i + 1
  761. end
  762. else
  763. alpha = 1 - alpha
  764. local i = 1
  765. while i <= vertexCount do
  766. vertices[i] = vertices[i] * alpha
  767. i = i + 1
  768. end
  769. end
  770. end
  771. return
  772. end
  773. local vertices = utils.setArraySize(verticesArray, vertexCount)
  774. if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
  775. local lastVertices = frameVertices[zlen(frames) - 1]
  776. if alpha == 1 then
  777. if blend == MixBlend.add then
  778. local vertexAttachment = slotAttachment
  779. if vertexAttachment.bones == nil then
  780. -- Unweighted vertex positions, with alpha.
  781. local setupVertices = vertexAttachment.vertices
  782. local i = 1
  783. while i <= vertexCount do
  784. vertices[i] = vertices[i] + lastVertices[i] - setupVertices[i]
  785. i = i + 1
  786. end
  787. else
  788. -- Weighted deform offsets, with alpha.
  789. local i = 1
  790. while i <= vertexCount do
  791. vertices[i] = vertices[i] + lastVertices[i]
  792. i = i + 1
  793. end
  794. end
  795. else
  796. local i = 1
  797. while i <= vertexCount do
  798. vertices[i] = lastVertices[i]
  799. i = i + 1
  800. end
  801. end
  802. else
  803. if blend == MixBlend.setup then
  804. local vertexAttachment = slotAttachment
  805. if vertexAttachment.bones == nil then
  806. -- Unweighted vertex positions, with alpha.
  807. local setupVertices = vertexAttachment.vertices
  808. local i = 1
  809. while i <= vertexCount do
  810. local setup = setupVertices[i]
  811. vertices[i] = setup + (lastVertices[i] - setup) * alpha
  812. i = i + 1
  813. end
  814. else
  815. -- Weighted deform offsets, with alpha.
  816. local i = 1
  817. while i <= vertexCount do
  818. vertices[i] = lastVertices[i] * alpha
  819. i = i + 1
  820. end
  821. end
  822. elseif blend == MixBlend.first or blend == MixBlend.replace then
  823. local i = 1
  824. while i <= vertexCount do
  825. vertices[i] = vertices[i] + (lastVertices[i] - vertices[i]) * alpha
  826. i = i + 1
  827. end
  828. local vertexAttachment = slotAttachment
  829. if vertexAttachment.bones == nil then
  830. local setupVertices = vertexAttachment.vertices
  831. local i = 1
  832. while i <= vertexCount do
  833. vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
  834. i = i + 1
  835. end
  836. else
  837. -- Weighted deform offsets, with alpha.
  838. local i = 1
  839. while i <= vertexCount do
  840. vertices[i] = vertices[i] + lastVertices[i] * alpha
  841. i = i + 1
  842. end
  843. end
  844. elseif blend == MixBlend.add then
  845. local vertexAttachment = slotAttachment
  846. if vertexAttachment.bones == nil then
  847. local setupVertices = vertexAttachment.vertices
  848. local i = 1
  849. while i <= vertexCount do
  850. vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
  851. i = i + 1
  852. end
  853. else
  854. -- Weighted deform offsets, with alpha.
  855. local i = 1
  856. while i <= vertexCount do
  857. vertices[i] = vertices[i] + lastVertices[i] * alpha
  858. i = i + 1
  859. end
  860. end
  861. end
  862. end
  863. return;
  864. end
  865. -- Interpolate between the previous frame and the current frame.
  866. local frame = binarySearch(frames, time, 1)
  867. local prevVertices = frameVertices[frame - 1]
  868. local nextVertices = frameVertices[frame]
  869. local frameTime = frames[frame]
  870. local percent = self:getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime))
  871. if alpha == 1 then
  872. if blend == MixBlend.add then
  873. local vertexAttachment = slotAttachment
  874. if vertexAttachment.bones == nil then
  875. -- Unweighted vertex positions, with alpha.
  876. local setupVertices = vertexAttachment.vertices
  877. local i = 1
  878. while i <= vertexCount do
  879. local prev = prevVertices[i]
  880. vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * precent - setupVertices[i]
  881. i = i + 1
  882. end
  883. else
  884. -- Weighted deform offsets, with alpha.
  885. local i = 1
  886. while i <= vertexCount do
  887. local prev = prevVertices[i]
  888. vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * percent
  889. i = i + 1
  890. end
  891. end
  892. else
  893. local i = 1
  894. while i <= vertexCount do
  895. local prev = prevVertices[i]
  896. vertices[i] = prev + (nextVertices[i] - prev) * percent
  897. i = i + 1
  898. end
  899. end
  900. else
  901. if blend == MixBlend.setup then
  902. local vertexAttachment = slotAttachment
  903. if vertexAttachment.bones == nil then
  904. -- Unweighted vertex positions, with alpha.
  905. local setupVertices = vertexAttachment.vertices
  906. local i = 1
  907. while i <= vertexCount do
  908. local prev = prevVertices[i]
  909. local setup = setupVertices[i]
  910. vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha
  911. i = i + 1
  912. end
  913. else
  914. -- Weighted deform offsets, with alpha.
  915. local i = 1
  916. while i <= vertexCount do
  917. local prev = prevVertices[i]
  918. vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha
  919. i = i + 1
  920. end
  921. end
  922. elseif blend == MixBlend.first or blend == MixBlend.replace then
  923. local i = 1
  924. while i <= vertexCount do
  925. local prev = prevVertices[i]
  926. vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha
  927. i = i + 1
  928. end
  929. elseif blend == MixBlend.add then
  930. local vertexAttachment = slotAttachment
  931. if vertexAttachment.bones == nil then
  932. local setupVertices = vertexAttachment.vertices
  933. local i = 1
  934. while i <= vertexCount do
  935. local prev = prevVertices[i]
  936. vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha
  937. i = i + 1
  938. end
  939. else
  940. -- Weighted deform offsets, with alpha.
  941. local i = 1
  942. while i <= vertexCount do
  943. local prev = prevVertices[i]
  944. vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent) * alpha
  945. i = i + 1
  946. end
  947. end
  948. end
  949. end
  950. end
  951. return self
  952. end
  953. Animation.EventTimeline = {}
  954. function Animation.EventTimeline.new (frameCount)
  955. local self = {
  956. frames = utils.newNumberArrayZero(frameCount),
  957. events = {},
  958. type = TimelineType.event
  959. }
  960. function self:getPropertyId ()
  961. return TimelineType.event * SHL_24
  962. end
  963. function self:getFrameCount ()
  964. return zlen(self.frames)
  965. end
  966. function self:setFrame (frameIndex, event)
  967. self.frames[frameIndex] = event.time
  968. self.events[frameIndex] = event
  969. end
  970. -- Fires events for frames > lastTime and <= time.
  971. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  972. if not firedEvents then return end
  973. local frames = self.frames
  974. local frameCount = zlen(frames)
  975. if lastTime > time then -- Fire events after last time for looped animations.
  976. self:apply(skeleton, lastTime, 999999, firedEvents, alpha, blend, direction)
  977. lastTime = -1
  978. elseif lastTime >= frames[frameCount - 1] then -- Last time is after last frame.
  979. return
  980. end
  981. if time < frames[0] then return end -- Time is before first frame.
  982. local frame
  983. if lastTime < frames[0] then
  984. frame = 0
  985. else
  986. frame = binarySearch1(frames, lastTime)
  987. local frame = frames[frame]
  988. while frame > 0 do -- Fire multiple events with the same frame.
  989. if frames[frame - 1] ~= frame then break end
  990. frame = frame - 1
  991. end
  992. end
  993. local events = self.events
  994. while frame < frameCount and time >= frames[frame] do
  995. table.insert(firedEvents, events[frame])
  996. frame = frame + 1
  997. end
  998. end
  999. return self
  1000. end
  1001. Animation.DrawOrderTimeline = {}
  1002. function Animation.DrawOrderTimeline.new (frameCount)
  1003. local self = {
  1004. frames = utils.newNumberArrayZero(frameCount),
  1005. drawOrders = {},
  1006. type = TimelineType.drawOrder
  1007. }
  1008. function self:getPropertyId ()
  1009. return TimelineType.drawOrder * SHL_24
  1010. end
  1011. function self:getFrameCount ()
  1012. return zlen(self.frames)
  1013. end
  1014. function self:setFrame (frameIndex, time, drawOrder)
  1015. self.frames[frameIndex] = time
  1016. self.drawOrders[frameIndex] = drawOrder
  1017. end
  1018. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1019. local drawOrder = skeleton.drawOrder
  1020. local slots = skeleton.slots
  1021. if direction == MixDirection.out and blend == MixBlend.setup then
  1022. for i,slot in ipairs(slots) do
  1023. drawOrder[i] = slots[i]
  1024. end
  1025. return;
  1026. end
  1027. local frames = self.frames
  1028. if time < frames[0] then
  1029. if blend == MixBlend.setup or blend == MixBlend.first then
  1030. for i,slot in ipairs(slots) do
  1031. drawOrder[i] = slots[i]
  1032. end
  1033. end
  1034. return
  1035. end
  1036. local frame
  1037. if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
  1038. frame = zlen(frames) - 1
  1039. else
  1040. frame = binarySearch1(frames, time) - 1
  1041. end
  1042. local drawOrderToSetupIndex = self.drawOrders[frame]
  1043. if not drawOrderToSetupIndex then
  1044. for i,slot in ipairs(slots) do
  1045. drawOrder[i] = slots[i]
  1046. end
  1047. else
  1048. for i,setupIndex in ipairs(drawOrderToSetupIndex) do
  1049. drawOrder[i] = skeleton.slots[setupIndex]
  1050. end
  1051. end
  1052. end
  1053. return self
  1054. end
  1055. Animation.IkConstraintTimeline = {}
  1056. Animation.IkConstraintTimeline.ENTRIES = 5
  1057. function Animation.IkConstraintTimeline.new (frameCount)
  1058. local ENTRIES = Animation.IkConstraintTimeline.ENTRIES
  1059. local PREV_TIME = -5
  1060. local PREV_MIX = -4
  1061. local PREV_BEND_DIRECTION = -3
  1062. local PREV_COMPRESS = -2
  1063. local PREV_STRETCH = -1
  1064. local MIX = 1
  1065. local BEND_DIRECTION = 2
  1066. local COMPRESS = 3
  1067. local STRETCH = 1
  1068. local self = Animation.CurveTimeline.new(frameCount)
  1069. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, compress, stretch, ...
  1070. self.ikConstraintIndex = -1
  1071. self.type = TimelineType.ikConstraint
  1072. function self:getPropertyId ()
  1073. return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
  1074. end
  1075. function self:setFrame (frameIndex, time, mix, bendDirection, compress, stretch)
  1076. frameIndex = frameIndex * ENTRIES
  1077. self.frames[frameIndex] = time
  1078. self.frames[frameIndex + MIX] = mix
  1079. self.frames[frameIndex + BEND_DIRECTION] = bendDirection
  1080. if (compress) then
  1081. self.frames[frameIndex + COMPRESS] = 1
  1082. else
  1083. self.frames[frameIndex + COMPRESS] = 0
  1084. end
  1085. if (stretch) then
  1086. self.frames[frameIndex + STRETCH] = 1
  1087. else
  1088. self.frames[frameIndex + STRETCH] = 0
  1089. end
  1090. end
  1091. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1092. local frames = self.frames
  1093. local constraint = skeleton.ikConstraints[self.ikConstraintIndex]
  1094. if time < frames[0] then
  1095. if blend == MixBlend.setup then
  1096. constraint.mix = constraint.data.mix
  1097. constraint.bendDirection = constraint.data.bendDirection
  1098. constraint.compress = constraint.data.compress
  1099. constraint.stretch = constraint.data.stretch
  1100. elseif blend == MixBlend.first then
  1101. constraint.mix = constraint.mix + (constraint.data.mix - constraint.mix) * alpha
  1102. constraint.bendDirection = constraint.data.bendDirection
  1103. constraint.compress = constraint.data.compress
  1104. constraint.stretch = constraint.data.stretch
  1105. end
  1106. return
  1107. end
  1108. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  1109. if blend == MixBlend.setup then
  1110. constraint.mix = constraint.data.mix + (frames[zlen(frames) + PREV_MIX] - constraint.data.mix) * alpha
  1111. if direction == MixDirection.out then
  1112. constraint.bendDirection = constraint.data.bendDirection
  1113. constraint.compress = constraint.data.compress
  1114. constraint.stretch = constraint.data.stretch
  1115. else
  1116. constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION]);
  1117. if (math_floor(frames[zlen(frames) + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
  1118. if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
  1119. end
  1120. else
  1121. constraint.mix = constraint.mix + (frames[zlen(frames) + PREV_MIX] - constraint.mix) * alpha;
  1122. if direction == MixDirection._in then
  1123. constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION])
  1124. if (math_floor(frames[zlen(frames) + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
  1125. if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
  1126. end
  1127. end
  1128. return
  1129. end
  1130. -- Interpolate between the previous frame and the current frame.
  1131. local frame = binarySearch(frames, time, ENTRIES)
  1132. local mix = frames[frame + PREV_MIX]
  1133. local frameTime = frames[frame]
  1134. local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
  1135. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  1136. if blend == MixBlend.setup then
  1137. constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha
  1138. if direction == MixDirection.out then
  1139. constraint.bendDirection = constraint.data.bendDirection
  1140. constraint.compress = constraint.data.compress
  1141. constraint.stretch = constraint.data.stretch
  1142. else
  1143. constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
  1144. if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
  1145. if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
  1146. end
  1147. else
  1148. constraint.mix = constraint.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
  1149. if direction == MixDirection._in then
  1150. constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
  1151. if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
  1152. if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
  1153. end
  1154. end
  1155. end
  1156. return self
  1157. end
  1158. Animation.TransformConstraintTimeline = {}
  1159. Animation.TransformConstraintTimeline.ENTRIES = 5
  1160. function Animation.TransformConstraintTimeline.new (frameCount)
  1161. local ENTRIES = Animation.TransformConstraintTimeline.ENTRIES
  1162. local PREV_TIME = -5
  1163. local PREV_ROTATE = -4
  1164. local PREV_TRANSLATE = -3
  1165. local PREV_SCALE = -2
  1166. local PREV_SHEAR = -1
  1167. local ROTATE = 1
  1168. local TRANSLATE = 2
  1169. local SCALE = 3
  1170. local SHEAR = 4
  1171. local self = Animation.CurveTimeline.new(frameCount)
  1172. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  1173. self.transformConstraintIndex = -1
  1174. self.type = TimelineType.transformConstraint
  1175. function self:getPropertyId ()
  1176. return TimelineType.transformConstraint * SHL_24 + self.transformConstraintIndex
  1177. end
  1178. function self:setFrame (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix)
  1179. frameIndex = frameIndex * ENTRIES
  1180. self.frames[frameIndex] = time
  1181. self.frames[frameIndex + ROTATE] = rotateMix
  1182. self.frames[frameIndex + TRANSLATE] = translateMix
  1183. self.frames[frameIndex + SCALE] = scaleMix
  1184. self.frames[frameIndex + SHEAR] = shearMix
  1185. end
  1186. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1187. local frames = self.frames
  1188. local constraint = skeleton.transformConstraints[self.transformConstraintIndex]
  1189. if time < frames[0] then
  1190. local data = constraint.data
  1191. if blend == MixBlend.setup then
  1192. constraint.rotateMix = data.rotateMix
  1193. constraint.translateMix = data.translateMix
  1194. constraint.scaleMix = data.scaleMix
  1195. constraint.shearMix = data.shearMix
  1196. elseif blend == MixBlend.first then
  1197. constraint.rotateMix = constraint.rotateMix + (data.rotateMix - constraint.rotateMix) * alpha
  1198. constraint.translateMix = constraint.translateMix + (data.translateMix - constraint.translateMix) * alpha
  1199. constraint.scaleMix = constraint.scaleMix + (data.scaleMix - constraint.scaleMix) * alpha
  1200. constraint.shearMix = constraint.shearMix + (data.shearMix - constraint.shearMix) * alpha
  1201. end
  1202. return
  1203. end
  1204. local rotate = 0
  1205. local translate = 0
  1206. local scale = 0
  1207. local shear = 0
  1208. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  1209. local i = zlen(frames.length)
  1210. rotate = frames[i + PREV_ROTATE]
  1211. translate = frames[i + PREV_TRANSLATE]
  1212. scale = frames[i + PREV_SCALE]
  1213. shear = frames[i + PREV_SHEAR]
  1214. else
  1215. -- Interpolate between the previous frame and the current frame.
  1216. local frame = binarySearch(frames, time, ENTRIES)
  1217. rotate = frames[frame + PREV_ROTATE]
  1218. translate = frames[frame + PREV_TRANSLATE]
  1219. scale = frames[frame + PREV_SCALE]
  1220. shear = frames[frame + PREV_SHEAR]
  1221. local frameTime = frames[frame]
  1222. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  1223. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
  1224. rotate = rotate + (frames[frame + ROTATE] - rotate) * percent
  1225. translate = translate + (frames[frame + TRANSLATE] - translate) * percent
  1226. scale = scale + (frames[frame + SCALE] - scale) * percent
  1227. shear = shear + (frames[frame + SHEAR] - shear) * percent
  1228. end
  1229. if blend == MixBlend.setup then
  1230. local data = constraint.data
  1231. constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha
  1232. constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha
  1233. constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha
  1234. constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha
  1235. else
  1236. constraint.rotateMix = constraint.rotateMix + (rotate - constraint.rotateMix) * alpha
  1237. constraint.translateMix = constraint.translateMix + (translate - constraint.translateMix) * alpha
  1238. constraint.scaleMix = constraint.scaleMix + (scale - constraint.scaleMix) * alpha
  1239. constraint.shearMix = constraint.shearMix + (shear - constraint.shearMix) * alpha
  1240. end
  1241. end
  1242. return self
  1243. end
  1244. Animation.PathConstraintPositionTimeline = {}
  1245. Animation.PathConstraintPositionTimeline.ENTRIES = 2
  1246. function Animation.PathConstraintPositionTimeline.new (frameCount)
  1247. local ENTRIES = Animation.PathConstraintPositionTimeline.ENTRIES
  1248. local PREV_TIME = -2
  1249. local PREV_VALUE = -1
  1250. local VALUE = 1
  1251. local self = Animation.CurveTimeline.new(frameCount)
  1252. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  1253. self.pathConstraintIndex = -1
  1254. self.type = TimelineType.pathConstraintPosition
  1255. function self:getPropertyId ()
  1256. return TimelineType.pathConstraintPosition * SHL_24 + self.pathConstraintIndex
  1257. end
  1258. function self:setFrame (frameIndex, time, value)
  1259. frameIndex = frameIndex * ENTRIES
  1260. self.frames[frameIndex] = time
  1261. self.frames[frameIndex + VALUE] = value
  1262. end
  1263. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1264. local frames = self.frames
  1265. local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
  1266. if (time < frames[0]) then
  1267. if blend == MixBlend.setup then
  1268. constraint.position = constraint.data.position
  1269. elseif blend == MixBlend.first then
  1270. constraint.position = constraint.position + (constraint.data.position - constraint.position) * alpha
  1271. end
  1272. return
  1273. end
  1274. local position = 0
  1275. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  1276. position = frames[zlen(frames) + PREV_VALUE]
  1277. else
  1278. -- Interpolate between the previous frame and the current frame.
  1279. local frame = binarySearch(frames, time, ENTRIES)
  1280. position = frames[frame + PREV_VALUE]
  1281. local frameTime = frames[frame]
  1282. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  1283. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  1284. position = position + (frames[frame + VALUE] - position) * percent
  1285. end
  1286. if blend == MixBlend.setup then
  1287. constraint.position = constraint.data.position + (position - constraint.data.position) * alpha
  1288. else
  1289. constraint.position = constraint.position + (position - constraint.position) * alpha
  1290. end
  1291. end
  1292. return self
  1293. end
  1294. Animation.PathConstraintSpacingTimeline = {}
  1295. Animation.PathConstraintSpacingTimeline.ENTRIES = 2
  1296. function Animation.PathConstraintSpacingTimeline.new (frameCount)
  1297. local ENTRIES = Animation.PathConstraintSpacingTimeline.ENTRIES
  1298. local PREV_TIME = -2
  1299. local PREV_VALUE = -1
  1300. local VALUE = 1
  1301. local self = Animation.CurveTimeline.new(frameCount)
  1302. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  1303. self.pathConstraintIndex = -1
  1304. self.type = TimelineType.pathConstraintSpacing
  1305. function self:getPropertyId ()
  1306. return TimelineType.pathConstraintSpacing * SHL_24 + self.pathConstraintIndex
  1307. end
  1308. function self:setFrame (frameIndex, time, value)
  1309. frameIndex = frameIndex * ENTRIES
  1310. self.frames[frameIndex] = time
  1311. self.frames[frameIndex + VALUE] = value
  1312. end
  1313. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1314. local frames = self.frames
  1315. local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
  1316. if (time < frames[0]) then
  1317. if blend == MixBlend.setup then
  1318. constraint.spacing = constraint.data.spacing
  1319. elseif blend == MixBlend.first then
  1320. constraint.spacing = constraint.spacing + (constraint.data.spacing - constraint.spacing) * alpha
  1321. end
  1322. return
  1323. end
  1324. local spacing = 0
  1325. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  1326. spacing = frames[zlen(frames) + PREV_VALUE]
  1327. else
  1328. -- Interpolate between the previous frame and the current frame.
  1329. local frame = binarySearch(frames, time, ENTRIES)
  1330. spacing = frames[frame + PREV_VALUE]
  1331. local frameTime = frames[frame]
  1332. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  1333. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  1334. spacing = spacing + (frames[frame + VALUE] - spacing) * percent
  1335. end
  1336. if blend == MixBlend.setup then
  1337. constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha
  1338. else
  1339. constraint.spacing = constraint.spacing + (spacing - constraint.spacing) * alpha
  1340. end
  1341. end
  1342. return self
  1343. end
  1344. Animation.PathConstraintMixTimeline = {}
  1345. Animation.PathConstraintMixTimeline.ENTRIES = 3
  1346. function Animation.PathConstraintMixTimeline.new (frameCount)
  1347. local ENTRIES = Animation.PathConstraintMixTimeline.ENTRIES
  1348. local PREV_TIME = -3
  1349. local PREV_ROTATE = -2
  1350. local PREV_TRANSLATE = -1
  1351. local ROTATE = 1
  1352. local TRANSLATE = 2
  1353. local self = Animation.CurveTimeline.new(frameCount)
  1354. self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
  1355. self.pathConstraintIndex = -1
  1356. self.type = TimelineType.pathConstraintMix
  1357. function self:getPropertyId ()
  1358. return TimelineType.pathConstraintMix * SHL_24 + self.pathConstraintIndex
  1359. end
  1360. function self:setFrame (frameIndex, time, rotateMix, translateMix)
  1361. frameIndex = frameIndex * ENTRIES
  1362. self.frames[frameIndex] = time
  1363. self.frames[frameIndex + ROTATE] = rotateMix
  1364. self.frames[frameIndex + TRANSLATE] = translateMix
  1365. end
  1366. function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
  1367. local frames = self.frames
  1368. local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
  1369. if (time < frames[0]) then
  1370. if blend == MixBlend.setup then
  1371. constraint.rotateMix = constraint.data.rotateMix
  1372. constraint.translateMix = constraint.data.translateMix
  1373. elseif blend == MixBlend.first then
  1374. constraint.rotateMix = constraint.rotateMix + (constraint.data.rotateMix - constraint.rotateMix) * alpha
  1375. constraint.translateMix = constraint.translateMix + (constraint.data.translateMix - constraint.translateMix) * alpha
  1376. end
  1377. return
  1378. end
  1379. local rotate = 0
  1380. local translate = 0
  1381. if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
  1382. rotate = frames[zlen(frames) + PREV_ROTATE]
  1383. translate = frames[zlen(frames) + PREV_TRANSLATE]
  1384. else
  1385. -- Interpolate between the previous frame and the current frame.
  1386. local frame = binarySearch(frames, time, ENTRIES)
  1387. rotate = frames[frame + PREV_ROTATE]
  1388. translate = frames[frame + PREV_TRANSLATE]
  1389. local frameTime = frames[frame]
  1390. local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
  1391. 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
  1392. rotate = rotate + (frames[frame + ROTATE] - rotate) * percent
  1393. translate = translate + (frames[frame + TRANSLATE] - translate) * percent
  1394. end
  1395. if blend == MixBlend.setup then
  1396. constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha
  1397. constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha
  1398. else
  1399. constraint.rotateMix = constraint.rotateMix + (rotate - constraint.rotateMix) * alpha
  1400. constraint.translateMix = constraint.translateMix + (translate - constraint.translateMix) * alpha
  1401. end
  1402. end
  1403. return self
  1404. end
  1405. return Animation