Merge branch '3.7-beta' into 3.7-beta-cpp

This commit is contained in:
badlogic 2018-09-11 16:11:57 +02:00
commit 9ef0323472

View File

@ -50,8 +50,8 @@ end
local EMPTY_ANIMATION = Animation.new("<empty>", {}, 0) local EMPTY_ANIMATION = Animation.new("<empty>", {}, 0)
local SUBSEQUENT = 0 local SUBSEQUENT = 0
local FIRST = 1 local FIRST = 1
local DIP = 2 local HOLD = 2
local DIP_MIX = 3; local HOLD_MIX = 3;
local EventType = { local EventType = {
start = 0, start = 0,
@ -167,75 +167,23 @@ TrackEntry.__index = TrackEntry
function TrackEntry.new () function TrackEntry.new ()
local self = { local self = {
animation = nil, animation = nil,
next = nil, mixingFrom = nil, next = nil, mixingFrom = nil, mixingTo = nil,
onStart = nil, onInterrupt = nil, onEnd = nil, onDispose = nil, onComplete = nil, onEvent = nil, onStart = nil, onInterrupt = nil, onEnd = nil, onDispose = nil, onComplete = nil, onEvent = nil,
trackIndex = 0, trackIndex = 0,
loop = false, loop = false, holdPrevious = false,
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, totalAlpha = 0, alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0, totalAlpha = 0,
mixBlend = MixBlend.replace, mixBlend = MixBlend.replace,
timelineData = {}, timelineMode = {},
timelineDipMix = {}, timelineHoldMix = {},
timelinesRotation = {} timelinesRotation = {}
} }
setmetatable(self, TrackEntry) setmetatable(self, TrackEntry)
return self return self
end end
function TrackEntry:setTimelineData(to, mixingToArray, propertyIDs)
if to then table_insert(mixingToArray, to) end
local lastEntry = self
if self.mixingFrom then lastEntry = self.mixingFrom:setTimelineData(self, mixingToArray, propertyIDs) end
if to then mixingToArray[#mixingToArray] = nil end
local mixingTo = mixingToArray
local mixingToLast = #mixingToArray
local timelines = self.animation.timelines
local timelinesCount = #self.animation.timelines
local timelineData = self.timelineData
local timelineDipMix = self.timelineDipMix
local i = 1
local skip
while i <= timelinesCount do
local id = "" .. timelines[i]:getPropertyId()
if not (propertyIDs[id] == nil) then
timelineData[i] = SUBSEQUENT
elseif (to == nil or not to:hasTimeline(id)) then
timelineData[i] = FIRST
else
local ii = mixingToLast
while ii > 0 do
local entry = mixingTo[ii]
skip = false
if not entry:hasTimeline(id) then
if entry.mixDuration > 0 then
timelineData[i] = DIP_MIX
timelineDipMix[i] = entry
skip = true
break
end
break;
end
ii = ii - 1
end
if not skip then timelineData[i] = DIP end
end
i = i + 1
end
return lastEntry
end
function TrackEntry:hasTimeline(id)
local timelines = self.animation.timelines
for i,timeline in ipairs(timelines) do
if timeline:getPropertyId() == id then return true end
end
return false
end
function TrackEntry:getAnimationTime () function TrackEntry:getAnimationTime ()
if self.loop then if self.loop then
local duration = self.animationEnd - self.animationStart local duration = self.animationEnd - self.animationStart
@ -325,6 +273,7 @@ function AnimationState:update (delta)
-- 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
if from then from.mixingTo = nil end
while from do while from do
queue:_end(from) queue:_end(from)
from = from.mixingFrom from = from.mixingFrom
@ -354,6 +303,7 @@ function AnimationState:updateMixingFrom (to, delta)
-- Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame). -- Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).
if (from.totalAlpha == 0 or to.mixDuration == 0) then if (from.totalAlpha == 0 or to.mixDuration == 0) then
to.mixingFrom = from.mixingFrom to.mixingFrom = from.mixingFrom
if from.mixingFrom then from.mixingFrom.mixingTo = to end
to.interruptAlpha = from.interruptAlpha to.interruptAlpha = from.interruptAlpha
self.queue:_end(from) self.queue:_end(from)
end end
@ -393,18 +343,18 @@ function AnimationState:apply (skeleton)
local animationLast = current.animationLast local animationLast = current.animationLast
local animationTime = current:getAnimationTime() local animationTime = current:getAnimationTime()
local timelines = current.animation.timelines local timelines = current.animation.timelines
if mix == 1 or blend == MixBlend.add then if i == 0 and (mix == 1 or blend == MixBlend.add) then
for i,timeline in ipairs(timelines) do for i,timeline in ipairs(timelines) do
timeline:apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection._in) timeline:apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection._in)
end end
else else
local timelineData = current.timelineData local timelineMode = current.timelineMode
local firstFrame = #current.timelinesRotation == 0 local firstFrame = #current.timelinesRotation == 0
local timelinesRotation = current.timelinesRotation local timelinesRotation = current.timelinesRotation
for ii,timeline in ipairs(timelines) do for ii,timeline in ipairs(timelines) do
local timelineBlend = MixBlend.setup local timelineBlend = MixBlend.setup
if timelineData[ii] == SUBSEQUENT then timelineBlend = blend end if timelineMode[ii] == SUBSEQUENT then timelineBlend = blend end
if timeline.type == Animation.TimelineType.rotate then if timeline.type == Animation.TimelineType.rotate then
self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2, self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2,
@ -446,16 +396,16 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
local animationLast = from.animationLast local animationLast = from.animationLast
local animationTime = from:getAnimationTime() local animationTime = from:getAnimationTime()
local timelines = from.animation.timelines local timelines = from.animation.timelines
local alphaDip = from.alpha * to.interruptAlpha local alphaHold = from.alpha * to.interruptAlpha
local alphaMix = alphaDip * (1 - mix) local alphaMix = alphaHold * (1 - mix)
if blend == MixBlend.add then if blend == MixBlend.add then
for i,timeline in ipairs(timelines) do for i,timeline in ipairs(timelines) do
timeline:apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.out) timeline:apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.out)
end end
else else
local timelineData = from.timelineData local timelineMode = from.timelineMode
local timelineDipMix = from.timelineDipMix local timelineHoldMix = from.timelineHoldMix
local firstFrame = #from.timelinesRotation == 0 local firstFrame = #from.timelinesRotation == 0
local timelinesRotation = from.timelinesRotation local timelinesRotation = from.timelinesRotation
@ -466,21 +416,21 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
local skipSubsequent = false; local skipSubsequent = false;
local timelineBlend = MixBlend.setup local timelineBlend = MixBlend.setup
local alpha = 0 local alpha = 0
if timelineData[i] == SUBSEQUENT then if timelineMode[i] == SUBSEQUENT then
if not attachments and timeline.type == Animation.TimelineType.attachment then skipSubsequent = true end if not attachments and timeline.type == Animation.TimelineType.attachment then skipSubsequent = true end
if not drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end if not drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end
timelineBlend = blend timelineBlend = blend
alpha = alphaMix alpha = alphaMix
elseif timelineData[i] == FIRST then elseif timelineMode[i] == FIRST then
timelineBlend = MixBlend.setup timelineBlend = MixBlend.setup
alpha = alphaMix alpha = alphaMix
elseif timelineData[i] == DIP then elseif timelineMode[i] == HOLD then
timelineBlend = MixBlend.setup timelineBlend = MixBlend.setup
alpha = alphaDip alpha = alphaHold
else else
timelineBlend = MixBlend.setup timelineBlend = MixBlend.setup
local dipMix = timelineDipMix[i] local holdMix = timelineHoldMix[i]
alpha = alphaDip * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration) alpha = alphaHold * math_max(0, 1 - holdMix.mixtime / holdMix.mixDuration)
end end
if not skipSubsequent then if not skipSubsequent then
@ -643,6 +593,7 @@ function AnimationState:clearTrack (trackIndex)
if from == nil then break end if from == nil then break end
queue:_end(from) queue:_end(from)
entry.mixingFrom = nil entry.mixingFrom = nil
entry.mixingTo = nil
entry = from entry = from
end end
@ -660,6 +611,7 @@ function AnimationState:setCurrent (index, current, interrupt)
if from then if from then
if interrupt then queue:interrupt(from) end if interrupt then queue:interrupt(from) end
current.mixingFrom = from current.mixingFrom = from
from.mixingTo = current
current.mixTime = 0 current.mixTime = 0
if from.mixingFrom and from.mixDuration > 0 then if from.mixingFrom and from.mixDuration > 0 then
@ -783,6 +735,7 @@ function AnimationState:trackEntry (trackIndex, animation, loop, last)
entry.trackIndex = trackIndex entry.trackIndex = trackIndex
entry.animation = animation entry.animation = animation
entry.loop = loop entry.loop = loop
entry.holdPrevious = false
entry.eventThreshold = 0 entry.eventThreshold = 0
entry.attachmentThreshold = 0 entry.attachmentThreshold = 0
@ -826,16 +779,82 @@ function AnimationState:_animationsChanged ()
self.animationsChanged = false self.animationsChanged = false
self.propertyIDs = {} self.propertyIDs = {}
local propertyIDs = self.propertyIDs
local mixingTo = self.mixingTo
for i, entry in pairs(self.tracks) do for i, entry in pairs(self.tracks) do
if entry and (i == 0 or entry.mixBlend ~= MixBlend.add) then if entry then
entry:setTimelineData(nil, mixingTo, propertyIDs) while entry.mixingFrom do
entry = entry.mixingFrom
end
repeat
if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
self:setTimelineModes(entry)
end
entry = entry.mixingTo
until (entry == nil)
end end
end end
end end
function AnimationState:setTimelineModes(entry)
local to = entry.mixingTo
local timelines = entry.animation.timelines
local timelinesCount = #entry.animation.timelines
local timelineMode = entry.timelineMode
local timelineHoldMix = entry.timelineHoldMix
local propertyIDs = self.propertyIDs
if (to and to.holdPrevious) then
local i = 1
while i <= timelinesCount do
local id = "" .. timelines[i]:getPropertyId()
if propertyIDs[id] == nil then
propertyIDs[id] = id
end
timelineMode[i] = HOLD
end
return
end
local i = 1
local skip
while i <= timelinesCount do
local id = "" .. timelines[i]:getPropertyId()
if not (propertyIDs[id] == nil) then
timelineMode[i] = SUBSEQUENT
else
propertyIDs[id] = id
if (to == nil or not self:hasTimeline(to, id)) then
timelineMode[i] = FIRST
else
local next = to.mixingTo
while next do
skip = false
if not self:hasTimeline(id) then
if entry.mixDuration > 0 then
timelineMode[i] = HOLD_MIX
timelineHoldMix[i] = next
skip = true
break
end
end
next = next.mixingTo
end
if not skip then timelineMode[i] = HOLD end
end
end
i = i + 1
end
end
function AnimationState:hasTimeline(entry, id)
local timelines = entry.animation.timelines
for i,timeline in ipairs(timelines) do
if timeline:getPropertyId() == id then return true end
end
return false
end
function AnimationState:getCurrent (trackIndex) function AnimationState:getCurrent (trackIndex)
return self.tracks[trackIndex] return self.tracks[trackIndex]
end end