This commit is contained in:
pharan 2017-05-24 19:31:21 +08:00
commit 6b27e295b7

View File

@ -49,6 +49,7 @@ local EMPTY_ANIMATION = Animation.new("<empty>", {}, 0)
local SUBSEQUENT = 0 local SUBSEQUENT = 0
local FIRST = 1 local FIRST = 1
local DIP = 2 local DIP = 2
local DIP_MIX = 3;
local EventType = { local EventType = {
start = 0, start = 0,
@ -171,7 +172,7 @@ function TrackEntry.new ()
eventThreshold = 0, attachmentThreshold = 0, drawOrderThreshold = 0, eventThreshold = 0, attachmentThreshold = 0, drawOrderThreshold = 0,
animationStart = 0, animationEnd = 0, animationLast = 0, nextAnimationLast = 0, animationStart = 0, animationEnd = 0, animationLast = 0, nextAnimationLast = 0,
delay = 0, trackTime = 0, trackLast = 0, nextTrackLast = 0, trackEnd = 0, timeScale = 0, delay = 0, trackTime = 0, trackLast = 0, nextTrackLast = 0, trackEnd = 0, timeScale = 0,
alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0, alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0, totalAlpha = 0,
timelineData = {}, timelineData = {},
timelineDipMix = {}, timelineDipMix = {},
timelinesRotation = {} timelinesRotation = {}
@ -201,19 +202,22 @@ function TrackEntry:setTimelineData(to, mixingToArray, propertyIDs)
elseif (to == nil or not to:hasTimeline(id)) then elseif (to == nil or not to:hasTimeline(id)) then
timelineData[i] = FIRST timelineData[i] = FIRST
else else
timelineData[i] = DIP
local ii = mixingToLast local ii = mixingToLast
while ii > 0 do while ii > 0 do
local entry = mixingTo[ii] local entry = mixingTo[ii]
local skip = false local skip = false
if not entry:hasTimeline(id) then if not entry:hasTimeline(id) then
if entry.mixDuration > 0 then timelineDipMix[i] = entry end if entry.mixDuration > 0 then
timelineData[i] = DIP_MIX
timelineDipMix[i] = entry
skip = true skip = true
break break
end end
break;
end
ii = ii - 1 ii = ii - 1
end end
if not skip then timelineDipMix[i] = nil end if not skip then timelineData[i] = DIP end
end end
i = i + 1 i = i + 1
end end
@ -313,7 +317,7 @@ function AnimationState:update (delta)
end end
if not skip then if not skip then
if current.mixingFrom and self:updateMixingFrom(current, delta, 2) then if current.mixingFrom and self:updateMixingFrom(current, delta) then
-- End mixing from entries once all have completed. -- End mixing from entries once all have completed.
local from = current.mixingFrom local from = current.mixingFrom
current.mixingFrom = nil current.mixingFrom = nil
@ -332,21 +336,18 @@ function AnimationState:update (delta)
queue:drain() queue:drain()
end end
function AnimationState:updateMixingFrom (entry, delta, animationCount) function AnimationState:updateMixingFrom (to, delta)
local from = entry.mixingFrom local from = to.mixingFrom
if from == nil then return true end if from == nil then return true end
local finished = self:updateMixingFrom(from, delta, animationCount + 1) local finished = self:updateMixingFrom(from, delta)
-- Require mixTime > 0 to ensure the mixing from entry was applied at least once. -- Require mixTime > 0 to ensure the mixing from entry was applied at least once.
if (entry.mixTime > 0 and (entry.mixTime >= entry.mixDuration or entry.timeScale == 0)) then if (to.mixTime > 0 and (to.mixTime >= to.mixDuration or to.timeScale == 0)) then
if (animationCount > 5 and from.mixingFrom == nil) then if (from.totalAlpha == 0) then
-- Limit linked list by speeding up and removing old entries. to.mixingFrom = from.mixingFrom
entry.interruptAlpha = math_max(0, entry.interruptAlpha - delta * 0.66) to.interruptAlpha = from.interruptAlpha
if entry.interruptAlpha <= 0 then self.queue:_end(from)
entry.mixingFrom = nil
queue._end(from)
end
end end
return finished return finished
end end
@ -354,7 +355,7 @@ function AnimationState:updateMixingFrom (entry, delta, animationCount)
from.animationLast = from.nextAnimationLast from.animationLast = from.nextAnimationLast
from.trackLast = from.nextTrackLast from.trackLast = from.nextTrackLast
from.trackTime = from.trackTime + delta * from.timeScale from.trackTime = from.trackTime + delta * from.timeScale
entry.mixTime = entry.mixTime + delta * entry.timeScale to.mixTime = to.mixTime + delta * to.timeScale
return false; return false;
end end
@ -391,10 +392,10 @@ function AnimationState:apply (skeleton)
for i,timeline in ipairs(timelines) do for i,timeline in ipairs(timelines) do
if timeline.type == Animation.TimelineType.rotate then if timeline.type == Animation.TimelineType.rotate then
self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[i] > 0, timelinesRotation, i * 2, self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[i] >= FIRST, timelinesRotation, i * 2,
firstFrame) -- FIXME passing ii * 2, indexing correct? firstFrame) -- FIXME passing ii * 2, indexing correct?
else else
timeline:apply(skeleton, animationLast, animationTime, events, mix, timelineData[i] > 0, false) timeline:apply(skeleton, animationLast, animationTime, events, mix, timelineData[i] >= FIRST, false)
end end
end end
end end
@ -437,7 +438,7 @@ function AnimationState:applyMixingFrom (to, skeleton)
local alphaDip = from.alpha * to.interruptAlpha local alphaDip = from.alpha * to.interruptAlpha
local alphaMix = alphaDip * (1 - mix) local alphaMix = alphaDip * (1 - mix)
local alpha = 0 local alpha = 0
from.totalAlpha = 0;
local skip = false local skip = false
for i,timeline in ipairs(timelines) do for i,timeline in ipairs(timelines) do
@ -447,13 +448,16 @@ function AnimationState:applyMixingFrom (to, skeleton)
elseif timelineData[i] == FIRST then elseif timelineData[i] == FIRST then
first = true first = true
alpha = alphaMix alpha = alphaMix
elseif timelineData[i] == DIP then
first = true
alpha = alphaDip
else else
first = true first = true
alpha = alphaDip alpha = alphaDip
local dipMix = timelineDipMix[i] local dipMix = timelineDipMix[i]
if dipMix then alpha = alpha * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration) end alpha = alpha * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration)
end end
from.totalAlpha = from.totalAlpha + alpha
if timeline.type == Animation.TimelineType.rotate then if timeline.type == Animation.TimelineType.rotate then
self:applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i * 2, firstFrame) self:applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i * 2, firstFrame)
else else