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 SUBSEQUENT = 0
local FIRST = 1
local DIP = 2
local DIP_MIX = 3;
local HOLD = 2
local HOLD_MIX = 3;
local EventType = {
start = 0,
@ -167,75 +167,23 @@ TrackEntry.__index = TrackEntry
function TrackEntry.new ()
local self = {
animation = nil,
next = nil, mixingFrom = nil,
next = nil, mixingFrom = nil, mixingTo = nil,
onStart = nil, onInterrupt = nil, onEnd = nil, onDispose = nil, onComplete = nil, onEvent = nil,
trackIndex = 0,
loop = false,
loop = false, holdPrevious = false,
eventThreshold = 0, attachmentThreshold = 0, drawOrderThreshold = 0,
animationStart = 0, animationEnd = 0, animationLast = 0, nextAnimationLast = 0,
delay = 0, trackTime = 0, trackLast = 0, nextTrackLast = 0, trackEnd = 0, timeScale = 0,
alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0, totalAlpha = 0,
mixBlend = MixBlend.replace,
timelineData = {},
timelineDipMix = {},
timelineMode = {},
timelineHoldMix = {},
timelinesRotation = {}
}
setmetatable(self, TrackEntry)
return self
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 ()
if self.loop then
local duration = self.animationEnd - self.animationStart
@ -325,6 +273,7 @@ function AnimationState:update (delta)
-- End mixing from entries once all have completed.
local from = current.mixingFrom
current.mixingFrom = nil
if from then from.mixingTo = nil end
while from do
queue:_end(from)
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).
if (from.totalAlpha == 0 or to.mixDuration == 0) then
to.mixingFrom = from.mixingFrom
if from.mixingFrom then from.mixingFrom.mixingTo = to end
to.interruptAlpha = from.interruptAlpha
self.queue:_end(from)
end
@ -393,18 +343,18 @@ function AnimationState:apply (skeleton)
local animationLast = current.animationLast
local animationTime = current:getAnimationTime()
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
timeline:apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection._in)
end
else
local timelineData = current.timelineData
local timelineMode = current.timelineMode
local firstFrame = #current.timelinesRotation == 0
local timelinesRotation = current.timelinesRotation
for ii,timeline in ipairs(timelines) do
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
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 animationTime = from:getAnimationTime()
local timelines = from.animation.timelines
local alphaDip = from.alpha * to.interruptAlpha
local alphaMix = alphaDip * (1 - mix)
local alphaHold = from.alpha * to.interruptAlpha
local alphaMix = alphaHold * (1 - mix)
if blend == MixBlend.add then
for i,timeline in ipairs(timelines) do
timeline:apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.out)
end
else
local timelineData = from.timelineData
local timelineDipMix = from.timelineDipMix
local timelineMode = from.timelineMode
local timelineHoldMix = from.timelineHoldMix
local firstFrame = #from.timelinesRotation == 0
local timelinesRotation = from.timelinesRotation
@ -466,21 +416,21 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
local skipSubsequent = false;
local timelineBlend = MixBlend.setup
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 drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end
timelineBlend = blend
alpha = alphaMix
elseif timelineData[i] == FIRST then
elseif timelineMode[i] == FIRST then
timelineBlend = MixBlend.setup
alpha = alphaMix
elseif timelineData[i] == DIP then
elseif timelineMode[i] == HOLD then
timelineBlend = MixBlend.setup
alpha = alphaDip
alpha = alphaHold
else
timelineBlend = MixBlend.setup
local dipMix = timelineDipMix[i]
alpha = alphaDip * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration)
local holdMix = timelineHoldMix[i]
alpha = alphaHold * math_max(0, 1 - holdMix.mixtime / holdMix.mixDuration)
end
if not skipSubsequent then
@ -643,6 +593,7 @@ function AnimationState:clearTrack (trackIndex)
if from == nil then break end
queue:_end(from)
entry.mixingFrom = nil
entry.mixingTo = nil
entry = from
end
@ -660,6 +611,7 @@ function AnimationState:setCurrent (index, current, interrupt)
if from then
if interrupt then queue:interrupt(from) end
current.mixingFrom = from
from.mixingTo = current
current.mixTime = 0
if from.mixingFrom and from.mixDuration > 0 then
@ -783,6 +735,7 @@ function AnimationState:trackEntry (trackIndex, animation, loop, last)
entry.trackIndex = trackIndex
entry.animation = animation
entry.loop = loop
entry.holdPrevious = false
entry.eventThreshold = 0
entry.attachmentThreshold = 0
@ -826,16 +779,82 @@ function AnimationState:_animationsChanged ()
self.animationsChanged = false
self.propertyIDs = {}
local propertyIDs = self.propertyIDs
local mixingTo = self.mixingTo
for i, entry in pairs(self.tracks) do
if entry and (i == 0 or entry.mixBlend ~= MixBlend.add) then
entry:setTimelineData(nil, mixingTo, propertyIDs)
for i, entry in pairs(self.tracks) do
if entry then
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
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)
return self.tracks[trackIndex]
end