Animation.lua 54 KB

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