123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569 |
- -------------------------------------------------------------------------------
- -- Spine Runtimes Software License v2.5
- --
- -- Copyright (c) 2013-2016, Esoteric Software
- -- All rights reserved.
- --
- -- You are granted a perpetual, non-exclusive, non-sublicensable, and
- -- non-transferable license to use, install, execute, and perform the Spine
- -- Runtimes software and derivative works solely for personal or internal
- -- use. Without the written permission of Esoteric Software (see Section 2 of
- -- the Spine Software License Agreement), you may not (a) modify, translate,
- -- adapt, or develop new applications using the Spine Runtimes or otherwise
- -- create derivative works or improvements of the Spine Runtimes or (b) remove,
- -- delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- -- or other intellectual property or proprietary rights notices on or in the
- -- Software, including any copy thereof. Redistributions in binary or source
- -- form must include this license and terms.
- --
- -- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- -- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- -- EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS Owelp,F
- -- USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- -- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- -- POSSIBILITY OF SUCH DAMAGE.
- -------------------------------------------------------------------------------
- -- FIXME
- -- All the indexing in this file is zero based. We use zlen()
- -- instead of the # operator. Initialization of number arrays
- -- is performed via utils.newNumberArrayZero. This needs
- -- to be rewritten using one-based indexing for better performance
- local utils = require "spine-lua.utils"
- local AttachmentType = require "spine-lua.attachments.AttachmentType"
- local math_floor = math.floor
- local math_abs = math.abs
- local math_signum = utils.signum
- local function zlen(array)
- return #array + 1
- end
- local Animation = {}
- function Animation.new (name, timelines, duration)
- if not timelines then error("timelines cannot be nil", 2) end
- local self = {
- name = name,
- timelines = timelines,
- duration = duration
- }
- function self:apply (skeleton, lastTime, time, loop, events, alpha, blend, direction)
- if not skeleton then error("skeleton cannot be nil.", 2) end
- if loop and duration > 0 then
- time = time % self.duration
- if lastTime > 0 then lastTime = lastTime % self.duration end
- end
- for i,timeline in ipairs(self.timelines) do
- timeline:apply(skeleton, lastTime, time, events, alpha, blend, direction)
- end
- end
- return self
- end
- local function binarySearch (values, target, step)
- local low = 0
- local high = math.floor(zlen(values) / step - 2)
- if high == 0 then return step end
- local current = math.floor(high / 2)
- while true do
- if values[(current + 1) * step] <= target then
- low = current + 1
- else
- high = current
- end
- if low == high then return (low + 1) * step end
- current = math.floor((low + high) / 2)
- end
- end
- Animation.binarySearch = binarySearch
- local function binarySearch1 (values, target)
- local low = 0
- local high = math.floor(zlen(values) - 2)
- if high == 0 then return 1 end
- local current = math.floor(high / 2)
- while true do
- if values[current + 1] <= target then
- low = current + 1
- else
- high = current
- end
- if low == high then return low + 1 end
- current = math.floor((low + high) / 2)
- end
- end
- local function linearSearch (values, target, step)
- local i = 0
- local last = zlen(values) - step
- while i <= last do
- if (values[i] > target) then return i end
- i = i + step
- end
- return -1
- end
- Animation.MixBlend = {
- setup = 0,
- first = 1,
- replace = 2,
- add = 3
- }
- local MixBlend = Animation.MixBlend
- Animation.MixDirection = {
- _in = 0, out = 1
- }
- local MixDirection = Animation.MixDirection
- Animation.TimelineType = {
- rotate = 0, translate = 1, scale = 2, shear = 3,
- attachment = 4, color = 5, deform = 6,
- event = 7, drawOrder = 8,
- ikConstraint = 9, transformConstraint = 10,
- pathConstraintPosition = 11, pathConstraintSpacing = 12, pathConstraintMix = 13,
- twoColor = 14
- }
- local TimelineType = Animation.TimelineType
- local SHL_24 = 16777216
- local SHL_27 = 134217728
- Animation.CurveTimeline = {}
- function Animation.CurveTimeline.new (frameCount)
- local LINEAR = 0
- local STEPPED = 1
- local BEZIER = 2
- local BEZIER_SIZE = 10 * 2 - 1
- local self = {
- curves = utils.newNumberArrayZero((frameCount - 1) * BEZIER_SIZE) -- type, x, y, ...
- }
- function self:getFrameCount ()
- return math.floor(zlen(self.curves) / BEZIER_SIZE) + 1
- end
- function self:setStepped (frameIndex)
- self.curves[frameIndex * BEZIER_SIZE] = STEPPED
- end
- function self:getCurveType (frameIndex)
- local index = frameIndex * BEZIER_SIZE
- if index == zlen(self.curves) then return LINEAR end
- local type = self.curves[index]
- if type == LINEAR then return LINEAR end
- if type == STEPPED then return STEPPED end
- return BEZIER
- end
- function self:setCurve (frameIndex, cx1, cy1, cx2, cy2)
- local tmpx = (-cx1 * 2 + cx2) * 0.03
- local tmpy = (-cy1 * 2 + cy2) * 0.03
- local dddfx = ((cx1 - cx2) * 3 + 1) * 0.006
- local dddfy = ((cy1 - cy2) * 3 + 1) * 0.006
- local ddfx = tmpx * 2 + dddfx
- local ddfy = tmpy * 2 + dddfy
- local dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667
- local dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667
- local i = frameIndex * BEZIER_SIZE
- local curves = self.curves
- curves[i] = BEZIER
- i = i + 1
- local x = dfx
- local y = dfy
- local n = i + BEZIER_SIZE - 1
- while i < n do
- curves[i] = x
- curves[i + 1] = y
- dfx = dfx + ddfx
- dfy = dfy + ddfy
- ddfx = ddfx + dddfx
- ddfy = ddfy + dddfy
- x = x + dfx
- y = y + dfy
- i = i + 2
- end
- end
- function self:getCurvePercent (frameIndex, percent)
- percent = utils.clamp(percent, 0, 1)
- local curves = self.curves
- local i = frameIndex * BEZIER_SIZE
- local type = curves[i]
- if type == LINEAR then return percent end
- if type == STEPPED then return 0 end
- i = i + 1
- local x
- local n = i + BEZIER_SIZE - 1
- local start = i
- while i < n do
- x = curves[i]
- if x >= percent then
- local prevX, prevY
- if i == start then
- prevX = 0
- prevY = 0
- else
- prevX = curves[i - 2]
- prevY = curves[i - 1]
- end
- return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX)
- end
- i = i + 2
- end
- local y = curves[i - 1]
- return y + (1 - y) * (percent - x) / (1 - x) -- Last point is 1,1.
- end
- return self
- end
- Animation.RotateTimeline = {}
- Animation.RotateTimeline.ENTRIES = 2
- Animation.RotateTimeline.PREV_TIME = -2
- Animation.RotateTimeline.PREV_ROTATION = -1
- Animation.RotateTimeline.ROTATION = 1
- function Animation.RotateTimeline.new (frameCount)
- local ENTRIES = Animation.RotateTimeline.ENTRIES
- local PREV_TIME = Animation.RotateTimeline.PREV_TIME
- local PREV_ROTATION = Animation.RotateTimeline.PREV_ROTATION
- local ROTATION = Animation.RotateTimeline.ROTATION
- local self = Animation.CurveTimeline.new(frameCount)
- self.boneIndex = -1
- self.frames = utils.newNumberArrayZero(frameCount * 2)
- self.type = TimelineType.rotate
- function self:getPropertyId ()
- return TimelineType.rotate * SHL_24 + self.boneIndex
- end
- function self:setFrame (frameIndex, time, degrees)
- frameIndex = frameIndex * 2
- self.frames[frameIndex] = time
- self.frames[frameIndex + ROTATION] = degrees
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local bone = skeleton.bones[self.boneIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- bone.rotation = bone.data.rotation
- elseif blend == MixBlend.first then
- local r = bone.data.rotation - bone.rotation
- bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
- end
- return
- end
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- local r = frames[zlen(frames) + PREV_ROTATION]
- if blend == MixBlend.setup then
- bone.rotation = bone.data.rotation + r * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- r = r + bone.data.rotation - bone.rotation
- r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 -- Wrap within -180 and 180.
- bone.rotation = bone.rotation + r * alpha;
- elseif blend == MixBlend.add then
- bone.rotation = bone.rotation + r * alpha;
- end
- return;
- end
- -- Interpolate between the last frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- local prevRotation = frames[frame + PREV_ROTATION]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent((math.floor(frame / 2)) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- local r = frames[frame + ROTATION] - prevRotation
- r = prevRotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * percent
- if blend == MixBlend.setup then
- bone.rotation = bone.data.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- r = r + bone.data.rotation - bone.rotation;
- bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
- elseif blend == MixBlend.add then
- bone.rotation = bone.rotation + (r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360) * alpha
- end
- end
- return self
- end
- Animation.TranslateTimeline = {}
- Animation.TranslateTimeline.ENTRIES = 3
- function Animation.TranslateTimeline.new (frameCount)
- local ENTRIES = Animation.TranslateTimeline.ENTRIES
- local PREV_TIME = -3
- local PREV_X = -2
- local PREV_Y = -1
- local X = 1
- local Y = 2
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.boneIndex = -1
- self.type = TimelineType.translate
-
- function self:getPropertyId ()
- return TimelineType.translate * SHL_24 + self.boneIndex
- end
- function self:setFrame (frameIndex, time, x, y)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + X] = x
- self.frames[frameIndex + Y] = y
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local bone = skeleton.bones[self.boneIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- bone.x = bone.data.x
- bone.y = bone.data.y
- elseif blend == MixBlend.first then
- bone.x = bone.x + (bone.data.x - bone.x) * alpha
- bone.y = bone.y + (bone.data.y - bone.y) * alpha
- end
- return
- end
- local x = 0
- local y = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- // Time is after last frame.
- x = frames[zlen(frames) + PREV_X];
- y = frames[zlen(frames) + PREV_Y];
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- x = frames[frame + PREV_X]
- y = frames[frame + PREV_Y]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
- x = x + (frames[frame + X] - x) * percent
- y = y + (frames[frame + Y] - y) * percent
- end
- if blend == MixBlend.setup then
- bone.x = bone.data.x + x * alpha
- bone.y = bone.data.y + y * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- bone.x = bone.x + (bone.data.x + x - bone.x) * alpha
- bone.y = bone.y + (bone.data.y + y - bone.y) * alpha
- elseif blend == MixBlend.add then
- bone.x = bone.x + x * alpha
- bone.y = bone.y + y * alpha
- end
- end
- return self
- end
- Animation.ScaleTimeline = {}
- Animation.ScaleTimeline.ENTRIES = Animation.TranslateTimeline.ENTRIES
- function Animation.ScaleTimeline.new (frameCount)
- local ENTRIES = Animation.ScaleTimeline.ENTRIES
- local PREV_TIME = -3
- local PREV_X = -2
- local PREV_Y = -1
- local X = 1
- local Y = 2
- local self = Animation.TranslateTimeline.new(frameCount)
- self.type = TimelineType.scale
-
- function self:getPropertyId ()
- return TimelineType.scale * SHL_24 + self.boneIndex
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local bone = skeleton.bones[self.boneIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- bone.scaleX = bone.data.scaleX
- bone.scaleY = bone.data.scaleY
- elseif blend == MixBlend.first then
- bone.scaleX = bone.scaleX + (bone.data.scaleX - bone.scaleX) * alpha
- bone.scaleY = bone.scaleY + (bone.data.scaleY - bone.scaleY) * alpha
- end
- return
- end
- local x = 0
- local y = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- x = frames[zlen(frames) + PREV_X] * bone.data.scaleX
- y = frames[zlen(frames) + PREV_Y] * bone.data.scaleY
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- x = frames[frame + PREV_X]
- y = frames[frame + PREV_Y]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- x = (x + (frames[frame + X] - x) * percent) * bone.data.scaleX
- y = (y + (frames[frame + Y] - y) * percent) * bone.data.scaleY
- end
- if alpha == 1 then
- if blend == MixBlend.add then
- bone.scaleX = bone.scaleX + x - bone.data.scaleX
- bone.scaleY = bone.scaleY + y - bone.data.scaleY
- else
- bone.scaleX = x
- bone.scaleY = y
- end
- else
- local bx = 0
- local by = 0
- if direction == MixDirection.out then
- if blend == MixBlend.setup then
- bx = bone.data.scaleX
- by = bone.data.scaleY
- bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bx) * alpha
- bone.scaleY = by + (math_abs(y) * math_signum(by) - by) * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- bx = bone.scaleX
- by = bone.scaleY
- bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bx) * alpha
- bone.scaleY = by + (math_abs(y) * math_signum(by) - by) * alpha
- elseif blend == MixBlend.add then
- bx = bone.scaleX
- by = bone.scaleY
- bone.scaleX = bx + (math_abs(x) * math_signum(bx) - bone.data.scaleX) * alpha
- bone.scaleY = by + (math_abs(y) * math_signum(by) - bone.data.scaleY) * alpha
- end
- else
- if blend == MixBlend.setup then
- bx = math_abs(bone.data.scaleX) * math_signum(x)
- by = math_abs(bone.data.scaleY) * math_signum(y)
- bone.scaleX = bx + (x - bx) * alpha
- bone.scaleY = by + (y - by) * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- bx = math_abs(bone.scaleX) * math_signum(x)
- by = math_abs(bone.scaleY) * math_signum(y)
- bone.scaleX = bx + (x - bx) * alpha
- bone.scaleY = by + (y - by) * alpha
- elseif blend == MixBlend.add then
- bx = math_signum(x)
- by = math_signum(y)
- bone.scaleX = math_abs(bone.scaleX) * bx + (x - math_abs(bone.data.scaleX) * bx) * alpha
- bone.scaleY = math_abs(bone.scaleY) * by + (y - math_abs(bone.data.scaleY) * by) * alpha
- end
- end
- end
- end
- return self
- end
- Animation.ShearTimeline = {}
- Animation.ShearTimeline.ENTRIES = Animation.TranslateTimeline.ENTRIES
- function Animation.ShearTimeline.new (frameCount)
- local ENTRIES = Animation.ShearTimeline.ENTRIES
- local PREV_TIME = -3
- local PREV_X = -2
- local PREV_Y = -1
- local X = 1
- local Y = 2
- local self = Animation.TranslateTimeline.new(frameCount)
- self.type = TimelineType.shear
-
- function self:getPropertyId ()
- return TimelineType.shear * SHL_24 + self.boneIndex
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local bone = skeleton.bones[self.boneIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- bone.shearX = bone.data.shearX
- bone.shearY = bone.data.shearY
- elseif blend == MixBlend.first then
- bone.shearX = bone.shearX + (bone.data.shearX - bone.shearX) * alpha
- bone.shearY = bone.shearX + (bone.data.shearY - bone.shearY) * alpha
- end
- return
- end
- local x = 0
- local y = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- // Time is after last frame.
- x = frames[zlen(frames) + PREV_X]
- y = frames[zlen(frames) + PREV_Y]
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- x = frames[frame + PREV_X]
- y = frames[frame + PREV_Y]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- x = x + (frames[frame + X] - x) * percent
- y = y + (frames[frame + Y] - y) * percent
- end
- if blend == MixBlend.setup then
- bone.shearX = bone.data.shearX + x * alpha
- bone.shearY = bone.data.shearY + y * alpha
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- bone.shearX = bone.shearX + (bone.data.shearX + x - bone.shearX) * alpha
- bone.shearY = bone.shearY + (bone.data.shearY + y - bone.shearY) * alpha
- elseif blend == MixBlend.add then
- bone.shearX = bone.shearX + x * alpha
- bone.shearY = bone.shearY + y * alpha
- end
- end
- return self
- end
- Animation.ColorTimeline = {}
- Animation.ColorTimeline.ENTRIES = 5
- function Animation.ColorTimeline.new (frameCount)
- local ENTRIES = Animation.ColorTimeline.ENTRIES
- local PREV_TIME = -5
- local PREV_R = -4
- local PREV_G = -3
- local PREV_B = -2
- local PREV_A = -1
- local R = 1
- local G = 2
- local B = 3
- local A = 4
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.slotIndex = -1
- self.type = TimelineType.color
-
- function self:getPropertyId ()
- return TimelineType.color * SHL_24 + self.slotIndex
- end
- function self:setFrame (frameIndex, time, r, g, b, a)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + R] = r
- self.frames[frameIndex + G] = g
- self.frames[frameIndex + B] = b
- self.frames[frameIndex + A] = a
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local slot = skeleton.slots[self.slotIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- slot.color:setFrom(slot.data.color)
- elseif blend == MixBlend.first then
- local color = slot.color
- local setup = slot.data.color
- color:add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
- (setup.a - color.a) * alpha)
- end
- return
- end
- local r, g, b, a
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- local i = zlen(frames)
- r = frames[i + PREV_R]
- g = frames[i + PREV_G]
- b = frames[i + PREV_B]
- a = frames[i + PREV_A]
- else
- -- Interpolate between the last frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- r = frames[frame + PREV_R]
- g = frames[frame + PREV_G]
- b = frames[frame + PREV_B]
- a = frames[frame + PREV_A]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- r = r + (frames[frame + R] - r) * percent
- g = g + (frames[frame + G] - g) * percent
- b = b + (frames[frame + B] - b) * percent
- a = a + (frames[frame + A] - a) * percent
- end
- if alpha == 1 then
- slot.color:set(r, g, b, a)
- else
- local color = slot.color
- if blend == MixBlend.setup then color:setFrom(slot.data.color) end
- color:add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha)
- end
- end
- return self
- end
- Animation.TwoColorTimeline = {}
- Animation.TwoColorTimeline.ENTRIES = 8
- function Animation.TwoColorTimeline.new (frameCount)
- local ENTRIES = Animation.TwoColorTimeline.ENTRIES
- local PREV_TIME = -8
- local PREV_R = -7
- local PREV_G = -6
- local PREV_B = -5
- local PREV_A = -4
- local PREV_R2 = -3
- local PREV_G2 = -2
- local PREV_B2 = -1
- local R = 1
- local G = 2
- local B = 3
- local A = 4
- local R2 = 5
- local G2 = 6
- local B2 = 7
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.slotIndex = -1
- self.type = TimelineType.twoColor
-
- function self:getPropertyId ()
- return TimelineType.twoColor * SHL_24 + self.slotIndex
- end
- function self:setFrame (frameIndex, time, r, g, b, a, r2, g2, b2)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + R] = r
- self.frames[frameIndex + G] = g
- self.frames[frameIndex + B] = b
- self.frames[frameIndex + A] = a
- self.frames[frameIndex + R2] = r2
- self.frames[frameIndex + G2] = g2
- self.frames[frameIndex + B2] = b2
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local slot = skeleton.slots[self.slotIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- slot.color:setFrom(slot.data.color)
- slot.darkColor:setFrom(slot.data.darkColor)
- elseif blend == MixBlend.first then
- local light = slot.color
- local dark = slot.darkColor
- local setupLight = slot.data.color
- local setupDark = slot.data.darkColor
- light:add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha,
- (setupLight.a - light.a) * alpha)
- dark:add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0)
- end
- return
- end
- local r, g, b, a, r2, g2, b2
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- local i = zlen(frames)
- r = frames[i + PREV_R]
- g = frames[i + PREV_G]
- b = frames[i + PREV_B]
- a = frames[i + PREV_A]
- r2 = frames[i + PREV_R2]
- g2 = frames[i + PREV_G2]
- b2 = frames[i + PREV_B2]
- else
- -- Interpolate between the last frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- r = frames[frame + PREV_R]
- g = frames[frame + PREV_G]
- b = frames[frame + PREV_B]
- a = frames[frame + PREV_A]
- r2 = frames[frame + PREV_R2]
- g2 = frames[frame + PREV_G2]
- b2 = frames[frame + PREV_B2]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- r = r + (frames[frame + R] - r) * percent
- g = g + (frames[frame + G] - g) * percent
- b = b + (frames[frame + B] - b) * percent
- a = a + (frames[frame + A] - a) * percent
- r2 = r2 + (frames[frame + R2] - r2) * percent
- g2 = g2 + (frames[frame + G2] - g2) * percent
- b2 = b2 + (frames[frame + B2] - b2) * percent
- end
- if alpha == 1 then
- slot.color:set(r, g, b, a)
- slot.darkColor:set(r2, g2, b2, 1)
- else
- local light = slot.color
- local dark = slot.darkColor
- if blend == MixBlend.setup then
- light:setFrom(slot.data.color)
- dark:setFrom(slot.data.darkColor)
- end
- light:add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha)
- dark:add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0)
- end
- end
- return self
- end
- Animation.AttachmentTimeline = {}
- function Animation.AttachmentTimeline.new (frameCount)
- local self = {
- frames = utils.newNumberArrayZero(frameCount), -- time, ...
- attachmentNames = {},
- slotIndex = -1,
- type = TimelineType.attachment
- }
- function self:getFrameCount ()
- return zlen(self.frames)
- end
- function self:setFrame (frameIndex, time, attachmentName)
- self.frames[frameIndex] = time
- self.attachmentNames[frameIndex] = attachmentName
- end
-
- function self:getPropertyId ()
- return TimelineType.attachment * SHL_24 + self.slotIndex
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local slot = skeleton.slots[self.slotIndex]
- local attachmentName
- if direction == MixDirection.out and blend == MixBlend.setup then
- attachmentName = slot.data.attachmentName
- if not attachmentName then
- slot:setAttachment(nil)
- else
- slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
- end
- return;
- end
-
- local frames = self.frames
- if time < frames[0] then
- if blend == MixBlend.setup or blend == MixBlend.first then
- attachmentName = slot.data.attachmentName
- if not attachmentName then
- slot:setAttachment(nil)
- else
- slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
- end
- end
- return
- end
- local frameIndex = 0
- if time >= frames[zlen(frames) - 1] then
- frameIndex = zlen(frames) - 1
- else
- frameIndex = binarySearch(frames, time, 1) - 1
- end
- attachmentName = self.attachmentNames[frameIndex]
- if not attachmentName then
- slot:setAttachment(nil)
- else
- slot:setAttachment(skeleton:getAttachmentByIndex(self.slotIndex, attachmentName))
- end
- end
- return self
- end
- Animation.DeformTimeline = {}
- function Animation.DeformTimeline.new (frameCount)
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount)
- self.frameVertices = utils.newNumberArrayZero(frameCount)
- self.slotIndex = -1
- self.attachment = nil
- self.type = TimelineType.deform
- function self:getPropertyId ()
- return TimelineType.deform * SHL_27 + self.attachment.id + self.slotIndex
- end
- function self:setFrame (frameIndex, time, vertices)
- self.frames[frameIndex] = time
- self.frameVertices[frameIndex] = vertices
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local slot = skeleton.slots[self.slotIndex]
- local slotAttachment = slot.attachment
- if not slotAttachment then return end
- if not (slotAttachment.type == AttachmentType.mesh or slotAttachment.type == AttachmentType.linkedmesh or slotAttachment.type == AttachmentType.path or slotAttachment.type == AttachmentType.boundingbox) then return end
- if not slotAttachment:applyDeform(self.attachment) then return end
- local frames = self.frames
- local verticesArray = slot.attachmentVertices
- if #(verticesArray) == 0 then blend = MixBlend.setup end
- local frameVertices = self.frameVertices
- local vertexCount = #(frameVertices[0])
-
- if time < frames[0] then
- local vertexAttachment = slotAttachment;
- if blend == MixBlend.setup then
- slot.attachmentVertices = {}
- return;
- elseif blend == MixBlend.first then
- if (alpha == 1) then
- slot.attachmentVertices = {}
- return;
- end
- local vertices = utils.setArraySize(verticesArray, vertexCount)
- if (vertexAttachment.bones == nil) then
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + (setupVertices[i] - vertices[i]) * alpha
- i = i + 1
- end
- else
- alpha = 1 - alpha
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] * alpha
- i = i + 1
- end
- end
- end
- return
- end
- local vertices = utils.setArraySize(verticesArray, vertexCount)
- if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
- local lastVertices = frameVertices[zlen(frames) - 1]
- if alpha == 1 then
- if blend == MixBlend.add then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- -- Unweighted vertex positions, with alpha.
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + lastVertices[i] - setupVertices[i]
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + lastVertices[i]
- i = i + 1
- end
- end
- else
- local i = 1
- while i <= vertexCount do
- vertices[i] = lastVertices[i]
- i = i + 1
- end
- end
- else
- if blend == MixBlend.setup then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- -- Unweighted vertex positions, with alpha.
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- local setup = setupVertices[i]
- vertices[i] = setup + (lastVertices[i] - setup) * alpha
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- vertices[i] = lastVertices[i] * alpha
- i = i + 1
- end
- end
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + (lastVertices[i] - vertices[i]) * alpha
- i = i + 1
- end
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + lastVertices[i] * alpha
- i = i + 1
- end
- end
- elseif blend == MixBlend.add then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- vertices[i] = vertices[i] + lastVertices[i] * alpha
- i = i + 1
- end
- end
- end
- end
- return;
- end
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, 1)
- local prevVertices = frameVertices[frame - 1]
- local nextVertices = frameVertices[frame]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime))
- if alpha == 1 then
- if blend == MixBlend.add then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- -- Unweighted vertex positions, with alpha.
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * precent - setupVertices[i]
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * percent
- i = i + 1
- end
- end
- else
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = prev + (nextVertices[i] - prev) * percent
- i = i + 1
- end
- end
- else
- if blend == MixBlend.setup then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- -- Unweighted vertex positions, with alpha.
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- local setup = setupVertices[i]
- vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha
- i = i + 1
- end
- end
- elseif blend == MixBlend.first or blend == MixBlend.replace then
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha
- i = i + 1
- end
- elseif blend == MixBlend.add then
- local vertexAttachment = slotAttachment
- if vertexAttachment.bones == nil then
- local setupVertices = vertexAttachment.vertices
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha
- i = i + 1
- end
- else
- -- Weighted deform offsets, with alpha.
- local i = 1
- while i <= vertexCount do
- local prev = prevVertices[i]
- vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent) * alpha
- i = i + 1
- end
- end
- end
- end
- end
- return self
- end
- Animation.EventTimeline = {}
- function Animation.EventTimeline.new (frameCount)
- local self = {
- frames = utils.newNumberArrayZero(frameCount),
- events = {},
- type = TimelineType.event
- }
-
- function self:getPropertyId ()
- return TimelineType.event * SHL_24
- end
- function self:getFrameCount ()
- return zlen(self.frames)
- end
- function self:setFrame (frameIndex, event)
- self.frames[frameIndex] = event.time
- self.events[frameIndex] = event
- end
- -- Fires events for frames > lastTime and <= time.
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- if not firedEvents then return end
- local frames = self.frames
- local frameCount = zlen(frames)
- if lastTime > time then -- Fire events after last time for looped animations.
- self:apply(skeleton, lastTime, 999999, firedEvents, alpha, blend, direction)
- lastTime = -1
- elseif lastTime >= frames[frameCount - 1] then -- Last time is after last frame.
- return
- end
- if time < frames[0] then return end -- Time is before first frame.
- local frame
- if lastTime < frames[0] then
- frame = 0
- else
- frame = binarySearch1(frames, lastTime)
- local frame = frames[frame]
- while frame > 0 do -- Fire multiple events with the same frame.
- if frames[frame - 1] ~= frame then break end
- frame = frame - 1
- end
- end
- local events = self.events
- while frame < frameCount and time >= frames[frame] do
- table.insert(firedEvents, events[frame])
- frame = frame + 1
- end
- end
- return self
- end
- Animation.DrawOrderTimeline = {}
- function Animation.DrawOrderTimeline.new (frameCount)
- local self = {
- frames = utils.newNumberArrayZero(frameCount),
- drawOrders = {},
- type = TimelineType.drawOrder
- }
-
- function self:getPropertyId ()
- return TimelineType.drawOrder * SHL_24
- end
- function self:getFrameCount ()
- return zlen(self.frames)
- end
- function self:setFrame (frameIndex, time, drawOrder)
- self.frames[frameIndex] = time
- self.drawOrders[frameIndex] = drawOrder
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local drawOrder = skeleton.drawOrder
- local slots = skeleton.slots
- if direction == MixDirection.out and blend == MixBlend.setup then
- for i,slot in ipairs(slots) do
- drawOrder[i] = slots[i]
- end
- return;
- end
-
- local frames = self.frames
- if time < frames[0] then
- if blend == MixBlend.setup or blend == MixBlend.first then
- for i,slot in ipairs(slots) do
- drawOrder[i] = slots[i]
- end
- end
- return
- end
- local frame
- if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
- frame = zlen(frames) - 1
- else
- frame = binarySearch1(frames, time) - 1
- end
- local drawOrderToSetupIndex = self.drawOrders[frame]
- if not drawOrderToSetupIndex then
- for i,slot in ipairs(slots) do
- drawOrder[i] = slots[i]
- end
- else
- for i,setupIndex in ipairs(drawOrderToSetupIndex) do
- drawOrder[i] = skeleton.slots[setupIndex]
- end
- end
- end
- return self
- end
- Animation.IkConstraintTimeline = {}
- Animation.IkConstraintTimeline.ENTRIES = 5
- function Animation.IkConstraintTimeline.new (frameCount)
- local ENTRIES = Animation.IkConstraintTimeline.ENTRIES
- local PREV_TIME = -5
- local PREV_MIX = -4
- local PREV_BEND_DIRECTION = -3
- local PREV_COMPRESS = -2
- local PREV_STRETCH = -1
- local MIX = 1
- local BEND_DIRECTION = 2
- local COMPRESS = 3
- local STRETCH = 1
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, compress, stretch, ...
- self.ikConstraintIndex = -1
- self.type = TimelineType.ikConstraint
-
- function self:getPropertyId ()
- return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
- end
- function self:setFrame (frameIndex, time, mix, bendDirection, compress, stretch)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + MIX] = mix
- self.frames[frameIndex + BEND_DIRECTION] = bendDirection
- if (compress) then
- self.frames[frameIndex + COMPRESS] = 1
- else
- self.frames[frameIndex + COMPRESS] = 0
- end
- if (stretch) then
- self.frames[frameIndex + STRETCH] = 1
- else
- self.frames[frameIndex + STRETCH] = 0
- end
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local constraint = skeleton.ikConstraints[self.ikConstraintIndex]
- if time < frames[0] then
- if blend == MixBlend.setup then
- constraint.mix = constraint.data.mix
- constraint.bendDirection = constraint.data.bendDirection
- constraint.compress = constraint.data.compress
- constraint.stretch = constraint.data.stretch
- elseif blend == MixBlend.first then
- constraint.mix = constraint.mix + (constraint.data.mix - constraint.mix) * alpha
- constraint.bendDirection = constraint.data.bendDirection
- constraint.compress = constraint.data.compress
- constraint.stretch = constraint.data.stretch
- end
- return
- end
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- if blend == MixBlend.setup then
- constraint.mix = constraint.data.mix + (frames[zlen(frames) + PREV_MIX] - constraint.data.mix) * alpha
- if direction == MixDirection.out then
- constraint.bendDirection = constraint.data.bendDirection
- constraint.compress = constraint.data.compress
- constraint.stretch = constraint.data.stretch
- else
- constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION]);
- if (math_floor(frames[zlen(frames) + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
- if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
- end
- else
- constraint.mix = constraint.mix + (frames[zlen(frames) + PREV_MIX] - constraint.mix) * alpha;
- if direction == MixDirection._in then
- constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION])
- if (math_floor(frames[zlen(frames) + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
- if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
- end
- end
- return
- end
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- local mix = frames[frame + PREV_MIX]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math.floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- if blend == MixBlend.setup then
- constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha
- if direction == MixDirection.out then
- constraint.bendDirection = constraint.data.bendDirection
- constraint.compress = constraint.data.compress
- constraint.stretch = constraint.data.stretch
- else
- constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
- if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
- if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
- end
- else
- constraint.mix = constraint.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
- if direction == MixDirection._in then
- constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
- if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
- if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
- end
- end
- end
- return self
- end
- Animation.TransformConstraintTimeline = {}
- Animation.TransformConstraintTimeline.ENTRIES = 5
- function Animation.TransformConstraintTimeline.new (frameCount)
- local ENTRIES = Animation.TransformConstraintTimeline.ENTRIES
- local PREV_TIME = -5
- local PREV_ROTATE = -4
- local PREV_TRANSLATE = -3
- local PREV_SCALE = -2
- local PREV_SHEAR = -1
- local ROTATE = 1
- local TRANSLATE = 2
- local SCALE = 3
- local SHEAR = 4
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.transformConstraintIndex = -1
- self.type = TimelineType.transformConstraint
-
- function self:getPropertyId ()
- return TimelineType.transformConstraint * SHL_24 + self.transformConstraintIndex
- end
- function self:setFrame (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + ROTATE] = rotateMix
- self.frames[frameIndex + TRANSLATE] = translateMix
- self.frames[frameIndex + SCALE] = scaleMix
- self.frames[frameIndex + SHEAR] = shearMix
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local constraint = skeleton.transformConstraints[self.transformConstraintIndex]
- if time < frames[0] then
- local data = constraint.data
- if blend == MixBlend.setup then
- constraint.rotateMix = data.rotateMix
- constraint.translateMix = data.translateMix
- constraint.scaleMix = data.scaleMix
- constraint.shearMix = data.shearMix
- elseif blend == MixBlend.first then
- constraint.rotateMix = constraint.rotateMix + (data.rotateMix - constraint.rotateMix) * alpha
- constraint.translateMix = constraint.translateMix + (data.translateMix - constraint.translateMix) * alpha
- constraint.scaleMix = constraint.scaleMix + (data.scaleMix - constraint.scaleMix) * alpha
- constraint.shearMix = constraint.shearMix + (data.shearMix - constraint.shearMix) * alpha
- end
- return
- end
- local rotate = 0
- local translate = 0
- local scale = 0
- local shear = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- local i = zlen(frames.length)
- rotate = frames[i + PREV_ROTATE]
- translate = frames[i + PREV_TRANSLATE]
- scale = frames[i + PREV_SCALE]
- shear = frames[i + PREV_SHEAR]
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- rotate = frames[frame + PREV_ROTATE]
- translate = frames[frame + PREV_TRANSLATE]
- scale = frames[frame + PREV_SCALE]
- shear = frames[frame + PREV_SHEAR]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
- rotate = rotate + (frames[frame + ROTATE] - rotate) * percent
- translate = translate + (frames[frame + TRANSLATE] - translate) * percent
- scale = scale + (frames[frame + SCALE] - scale) * percent
- shear = shear + (frames[frame + SHEAR] - shear) * percent
- end
- if blend == MixBlend.setup then
- local data = constraint.data
- constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha
- constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha
- constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha
- constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha
- else
- constraint.rotateMix = constraint.rotateMix + (rotate - constraint.rotateMix) * alpha
- constraint.translateMix = constraint.translateMix + (translate - constraint.translateMix) * alpha
- constraint.scaleMix = constraint.scaleMix + (scale - constraint.scaleMix) * alpha
- constraint.shearMix = constraint.shearMix + (shear - constraint.shearMix) * alpha
- end
- end
- return self
- end
- Animation.PathConstraintPositionTimeline = {}
- Animation.PathConstraintPositionTimeline.ENTRIES = 2
- function Animation.PathConstraintPositionTimeline.new (frameCount)
- local ENTRIES = Animation.PathConstraintPositionTimeline.ENTRIES
- local PREV_TIME = -2
- local PREV_VALUE = -1
- local VALUE = 1
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.pathConstraintIndex = -1
- self.type = TimelineType.pathConstraintPosition
- function self:getPropertyId ()
- return TimelineType.pathConstraintPosition * SHL_24 + self.pathConstraintIndex
- end
- function self:setFrame (frameIndex, time, value)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + VALUE] = value
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
- if (time < frames[0]) then
- if blend == MixBlend.setup then
- constraint.position = constraint.data.position
- elseif blend == MixBlend.first then
- constraint.position = constraint.position + (constraint.data.position - constraint.position) * alpha
- end
- return
- end
- local position = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- position = frames[zlen(frames) + PREV_VALUE]
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- position = frames[frame + PREV_VALUE]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- position = position + (frames[frame + VALUE] - position) * percent
- end
- if blend == MixBlend.setup then
- constraint.position = constraint.data.position + (position - constraint.data.position) * alpha
- else
- constraint.position = constraint.position + (position - constraint.position) * alpha
- end
- end
- return self
- end
- Animation.PathConstraintSpacingTimeline = {}
- Animation.PathConstraintSpacingTimeline.ENTRIES = 2
- function Animation.PathConstraintSpacingTimeline.new (frameCount)
- local ENTRIES = Animation.PathConstraintSpacingTimeline.ENTRIES
- local PREV_TIME = -2
- local PREV_VALUE = -1
- local VALUE = 1
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.pathConstraintIndex = -1
- self.type = TimelineType.pathConstraintSpacing
- function self:getPropertyId ()
- return TimelineType.pathConstraintSpacing * SHL_24 + self.pathConstraintIndex
- end
- function self:setFrame (frameIndex, time, value)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + VALUE] = value
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
- if (time < frames[0]) then
- if blend == MixBlend.setup then
- constraint.spacing = constraint.data.spacing
- elseif blend == MixBlend.first then
- constraint.spacing = constraint.spacing + (constraint.data.spacing - constraint.spacing) * alpha
- end
- return
- end
- local spacing = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- spacing = frames[zlen(frames) + PREV_VALUE]
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- spacing = frames[frame + PREV_VALUE]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- spacing = spacing + (frames[frame + VALUE] - spacing) * percent
- end
- if blend == MixBlend.setup then
- constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha
- else
- constraint.spacing = constraint.spacing + (spacing - constraint.spacing) * alpha
- end
- end
- return self
- end
- Animation.PathConstraintMixTimeline = {}
- Animation.PathConstraintMixTimeline.ENTRIES = 3
- function Animation.PathConstraintMixTimeline.new (frameCount)
- local ENTRIES = Animation.PathConstraintMixTimeline.ENTRIES
- local PREV_TIME = -3
- local PREV_ROTATE = -2
- local PREV_TRANSLATE = -1
- local ROTATE = 1
- local TRANSLATE = 2
- local self = Animation.CurveTimeline.new(frameCount)
- self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
- self.pathConstraintIndex = -1
- self.type = TimelineType.pathConstraintMix
-
- function self:getPropertyId ()
- return TimelineType.pathConstraintMix * SHL_24 + self.pathConstraintIndex
- end
- function self:setFrame (frameIndex, time, rotateMix, translateMix)
- frameIndex = frameIndex * ENTRIES
- self.frames[frameIndex] = time
- self.frames[frameIndex + ROTATE] = rotateMix
- self.frames[frameIndex + TRANSLATE] = translateMix
- end
- function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
- local frames = self.frames
- local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
- if (time < frames[0]) then
- if blend == MixBlend.setup then
- constraint.rotateMix = constraint.data.rotateMix
- constraint.translateMix = constraint.data.translateMix
- elseif blend == MixBlend.first then
- constraint.rotateMix = constraint.rotateMix + (constraint.data.rotateMix - constraint.rotateMix) * alpha
- constraint.translateMix = constraint.translateMix + (constraint.data.translateMix - constraint.translateMix) * alpha
- end
- return
- end
- local rotate = 0
- local translate = 0
- if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
- rotate = frames[zlen(frames) + PREV_ROTATE]
- translate = frames[zlen(frames) + PREV_TRANSLATE]
- else
- -- Interpolate between the previous frame and the current frame.
- local frame = binarySearch(frames, time, ENTRIES)
- rotate = frames[frame + PREV_ROTATE]
- translate = frames[frame + PREV_TRANSLATE]
- local frameTime = frames[frame]
- local percent = self:getCurvePercent(math_floor(frame / ENTRIES) - 1,
- 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime))
- rotate = rotate + (frames[frame + ROTATE] - rotate) * percent
- translate = translate + (frames[frame + TRANSLATE] - translate) * percent
- end
- if blend == MixBlend.setup then
- constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha
- constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha
- else
- constraint.rotateMix = constraint.rotateMix + (rotate - constraint.rotateMix) * alpha
- constraint.translateMix = constraint.translateMix + (translate - constraint.translateMix) * alpha
- end
- end
- return self
- end
- return Animation
|