mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
[lua] Fixed animation layering. Cause of the bug was a few places using pairs instead of manually iterating through all indices from 0 to len. Closes #1574.
This commit is contained in:
parent
1855870d37
commit
9b801a993e
@ -227,7 +227,10 @@ function AnimationState:update (delta)
|
|||||||
delta = delta * self.timeScale
|
delta = delta * self.timeScale
|
||||||
local tracks = self.tracks
|
local tracks = self.tracks
|
||||||
local queue = self.queue
|
local queue = self.queue
|
||||||
for i,current in pairs(tracks) do
|
local numTracks = #tracks
|
||||||
|
local i = 0
|
||||||
|
while i <= numTracks do
|
||||||
|
current = tracks[i]
|
||||||
if current then
|
if current then
|
||||||
current.animationLast = current.nextAnimationLast
|
current.animationLast = current.nextAnimationLast
|
||||||
current.trackLast = current.nextTrackLast
|
current.trackLast = current.nextTrackLast
|
||||||
@ -290,6 +293,7 @@ function AnimationState:update (delta)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
queue:drain()
|
queue:drain()
|
||||||
@ -329,51 +333,57 @@ function AnimationState:apply (skeleton)
|
|||||||
local queue = self.queue
|
local queue = self.queue
|
||||||
local applied = false
|
local applied = false
|
||||||
|
|
||||||
for i,current in pairs(tracks) do
|
local numTracks = #tracks
|
||||||
if not (current == nil or current.delay > 0) then
|
local i = 0
|
||||||
applied = true
|
while i <= numTracks do
|
||||||
|
current = tracks[i]
|
||||||
|
if current then
|
||||||
|
if not (current == nil or current.delay > 0) then
|
||||||
|
applied = true
|
||||||
|
|
||||||
local blend = current.mixBlend
|
local blend = current.mixBlend
|
||||||
if i == 0 then blend = MixBlend.first end
|
if i == 0 then blend = MixBlend.first end
|
||||||
|
|
||||||
-- Apply mixing from entries first.
|
-- Apply mixing from entries first.
|
||||||
local mix = current.alpha
|
local mix = current.alpha
|
||||||
if current.mixingFrom then
|
if current.mixingFrom then
|
||||||
mix = mix * self:applyMixingFrom(current, skeleton, blend)
|
mix = mix * self:applyMixingFrom(current, skeleton, blend)
|
||||||
elseif current.trackTime >= current.trackEnd and current.next == nil then
|
elseif current.trackTime >= current.trackEnd and current.next == nil then
|
||||||
mix = 0
|
mix = 0
|
||||||
end
|
|
||||||
|
|
||||||
-- Apply current entry.
|
|
||||||
local animationLast = current.animationLast
|
|
||||||
local animationTime = current:getAnimationTime()
|
|
||||||
local timelines = current.animation.timelines
|
|
||||||
if (i == 0 and mix == 1) or blend == MixBlend.add then
|
|
||||||
for i,timeline in ipairs(timelines) do
|
|
||||||
timeline:apply(skeleton, animationLast, animationTime, self.events, mix, blend, MixDirection._in)
|
|
||||||
end
|
end
|
||||||
else
|
|
||||||
local timelineMode = current.timelineMode
|
|
||||||
local firstFrame = #current.timelinesRotation == 0
|
|
||||||
local timelinesRotation = current.timelinesRotation
|
|
||||||
|
|
||||||
for ii,timeline in ipairs(timelines) do
|
-- Apply current entry.
|
||||||
local timelineBlend = MixBlend.setup
|
local animationLast = current.animationLast
|
||||||
if clearBit(timelineMode[ii], NOT_LAST) == SUBSEQUENT then timelineBlend = blend end
|
local animationTime = current:getAnimationTime()
|
||||||
|
local timelines = current.animation.timelines
|
||||||
|
if (i == 0 and mix == 1) or blend == MixBlend.add then
|
||||||
|
for i,timeline in ipairs(timelines) do
|
||||||
|
timeline:apply(skeleton, animationLast, animationTime, self.events, mix, blend, MixDirection._in)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local timelineMode = current.timelineMode
|
||||||
|
local firstFrame = #current.timelinesRotation == 0
|
||||||
|
local timelinesRotation = current.timelinesRotation
|
||||||
|
|
||||||
if timeline.type == Animation.TimelineType.rotate then
|
for ii,timeline in ipairs(timelines) do
|
||||||
self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2,
|
local timelineBlend = MixBlend.setup
|
||||||
firstFrame)
|
if clearBit(timelineMode[ii], NOT_LAST) == SUBSEQUENT then timelineBlend = blend end
|
||||||
else
|
|
||||||
timeline:apply(skeleton, animationLast, animationTime, self.events, mix, timelineBlend, MixDirection._in)
|
if timeline.type == Animation.TimelineType.rotate then
|
||||||
|
self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2,
|
||||||
|
firstFrame)
|
||||||
|
else
|
||||||
|
timeline:apply(skeleton, animationLast, animationTime, self.events, mix, timelineBlend, MixDirection._in)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self:queueEvents(current, animationTime)
|
||||||
|
self.events = {};
|
||||||
|
current.nextAnimationLast = animationTime
|
||||||
|
current.nextTrackLast = current.trackTime
|
||||||
end
|
end
|
||||||
self:queueEvents(current, animationTime)
|
|
||||||
self.events = {};
|
|
||||||
current.nextAnimationLast = animationTime
|
|
||||||
current.nextTrackLast = current.trackTime
|
|
||||||
end
|
end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
queue:drain()
|
queue:drain()
|
||||||
@ -602,7 +612,9 @@ function AnimationState:clearTracks ()
|
|||||||
local tracks = self.tracks
|
local tracks = self.tracks
|
||||||
local oldDrainDisabled = queue.drainDisabled
|
local oldDrainDisabled = queue.drainDisabled
|
||||||
queue.drainDisabled = true;
|
queue.drainDisabled = true;
|
||||||
for i,track in pairs(tracks) do
|
local numTracks = #tracks
|
||||||
|
local i = 0
|
||||||
|
while i <= numTracks do
|
||||||
self:clearTrack(i)
|
self:clearTrack(i)
|
||||||
end
|
end
|
||||||
tracks = {}
|
tracks = {}
|
||||||
@ -751,8 +763,13 @@ function AnimationState:setEmptyAnimations (mixDuration)
|
|||||||
local queue = self.queue
|
local queue = self.queue
|
||||||
local oldDrainDisabled = queue.drainDisabled
|
local oldDrainDisabled = queue.drainDisabled
|
||||||
queue.drainDisabled = true
|
queue.drainDisabled = true
|
||||||
for i,current in pairs(self.tracks) do
|
local tracks = self.tracks
|
||||||
|
local numTracks = #tracks
|
||||||
|
local i = 0
|
||||||
|
while i <= numTracks do
|
||||||
|
current = tracks[i]
|
||||||
if current then self:setEmptyAnimation(current.trackIndex, mixDuration) end
|
if current then self:setEmptyAnimation(current.trackIndex, mixDuration) end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
queue.drainDisabled = oldDrainDisabled
|
queue.drainDisabled = oldDrainDisabled
|
||||||
queue:drain()
|
queue:drain()
|
||||||
@ -814,21 +831,28 @@ function AnimationState:_animationsChanged ()
|
|||||||
self.propertyIDs = {}
|
self.propertyIDs = {}
|
||||||
|
|
||||||
local highestIndex = -1
|
local highestIndex = -1
|
||||||
for i, entry in pairs(self.tracks) do
|
local tracks = self.tracks
|
||||||
if i > highestIndex then highestIndex = i end
|
local numTracks = #tracks
|
||||||
|
local i = 0
|
||||||
|
while i <= numTracks do
|
||||||
|
current = tracks[i]
|
||||||
|
if current then
|
||||||
|
if i > highestIndex then highestIndex = i end
|
||||||
|
|
||||||
if entry then
|
if entry then
|
||||||
while entry.mixingFrom do
|
while entry.mixingFrom do
|
||||||
entry = entry.mixingFrom
|
entry = entry.mixingFrom
|
||||||
end
|
|
||||||
|
|
||||||
repeat
|
|
||||||
if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
|
|
||||||
self:computeHold(entry)
|
|
||||||
end
|
end
|
||||||
entry = entry.mixingTo
|
|
||||||
until (entry == nil)
|
repeat
|
||||||
|
if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
|
||||||
|
self:computeHold(entry)
|
||||||
|
end
|
||||||
|
entry = entry.mixingTo
|
||||||
|
until (entry == nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
self.propertyIDs = {}
|
self.propertyIDs = {}
|
||||||
|
|||||||
@ -174,10 +174,12 @@ function utils.randomTriangularWith(min, max, mode)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function utils.testBit(value, bit)
|
function utils.testBit(value, bit)
|
||||||
|
if (value == nil) then return 0 end
|
||||||
return value % (2 * bit) >= bit
|
return value % (2 * bit) >= bit
|
||||||
end
|
end
|
||||||
|
|
||||||
function utils.setBit(value, bit)
|
function utils.setBit(value, bit)
|
||||||
|
if (value == nil) then return 0 end
|
||||||
if value % (2 * bit) >= bit then
|
if value % (2 * bit) >= bit then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
@ -185,6 +187,7 @@ function utils.setBit(value, bit)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function utils.clearBit(value, bit)
|
function utils.clearBit(value, bit)
|
||||||
|
if (value == nil) then return 0 end
|
||||||
if value % (2 * bit) >= bit then
|
if value % (2 * bit) >= bit then
|
||||||
return value - bit
|
return value - bit
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user