diff --git a/spine-lua/Animation.lua b/spine-lua/Animation.lua index b4af403e4..b555dcc25 100644 --- a/spine-lua/Animation.lua +++ b/spine-lua/Animation.lua @@ -1169,19 +1169,21 @@ function Animation.DrawOrderTimeline.new (frameCount) end Animation.IkConstraintTimeline = {} -Animation.IkConstraintTimeline.ENTRIES = 4 +Animation.IkConstraintTimeline.ENTRIES = 5 function Animation.IkConstraintTimeline.new (frameCount) local ENTRIES = Animation.IkConstraintTimeline.ENTRIES - local PREV_TIME = -4 - local PREV_MIX = -3 - local PREV_BEND_DIRECTION = -2 + 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, ... + self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, compress, stretch, ... self.ikConstraintIndex = -1 self.type = TimelineType.ikConstraint @@ -1189,11 +1191,16 @@ function Animation.IkConstraintTimeline.new (frameCount) return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex end - function self:setFrame (frameIndex, time, mix, bendDirection, stretch) + 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 @@ -1209,10 +1216,12 @@ function Animation.IkConstraintTimeline.new (frameCount) 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 @@ -1223,15 +1232,18 @@ function Animation.IkConstraintTimeline.new (frameCount) 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[frames.length + 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_COMPRES]) == 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 @@ -1249,15 +1261,18 @@ function Animation.IkConstraintTimeline.new (frameCount) 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 diff --git a/spine-lua/AnimationState.lua b/spine-lua/AnimationState.lua index d8780737d..eb34ad584 100644 --- a/spine-lua/AnimationState.lua +++ b/spine-lua/AnimationState.lua @@ -543,10 +543,10 @@ function AnimationState:applyRotateTimeline (timeline, skeleton, time, alpha, bl if blend == MixBlend.setup then r1 = bone.data.rotation end local total = 0 local diff = r2 - r1 + diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360 if diff == 0 then total = timelinesRotation[i] else - diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360 local lastTotal = 0 local lastDiff = 0 if firstFrame then diff --git a/spine-lua/IkConstraint.lua b/spine-lua/IkConstraint.lua index 8bba44edf..d491af759 100644 --- a/spine-lua/IkConstraint.lua +++ b/spine-lua/IkConstraint.lua @@ -52,6 +52,7 @@ function IkConstraint.new (data, skeleton) bones = {}, target = nil, mix = data.mix, + compress = data.compress, stretch = data.stretch, bendDirection = data.bendDirection, } @@ -75,13 +76,13 @@ function IkConstraint:update () local bones = self.bones local boneCount = #bones if boneCount == 1 then - self:apply1(bones[1], target.worldX, target.worldY, self.stretch, self.mix) + self:apply1(bones[1], target.worldX, target.worldY, self.compress, self.stretch, self.data.uniform, self.mix) elseif boneCount == 2 then self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.mix) end end -function IkConstraint:apply1 (bone, targetX, targetY, stretch, alpha) +function IkConstraint:apply1 (bone, targetX, targetY, compress, stretch, uniform, alpha) if not bone.appliedValid then bone:updateAppliedTransform() end local p = bone.parent local id = 1 / (p.a * p.d - p.b * p.c) @@ -97,11 +98,17 @@ function IkConstraint:apply1 (bone, targetX, targetY, stretch, alpha) rotationIK = rotationIK + 360 end local sx = bone.ascaleX - if stretch then + local sy = bone.ascaleY + if compress or stretch then + local b = bone.data.length * sx local dd = math_sqrt(tx * tx + ty * ty) - if dd > bone.data.length * sx then sx = sx * ((dd / (bone.data.length * sx) - 1) * alpha + 1) end + if (compress and dd < b) or (stretch and dd > b) and b > 0.0001 then + local s = (dd / b - 1) * alpha + 1 + sx = sx * s + if uniform then sy = sy * s end + end end - bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY) + bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY) end function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, alpha) diff --git a/spine-lua/IkConstraintData.lua b/spine-lua/IkConstraintData.lua index 842fef327..9e68afab2 100644 --- a/spine-lua/IkConstraintData.lua +++ b/spine-lua/IkConstraintData.lua @@ -38,7 +38,9 @@ function IkConstraintData.new (name) bones = {}, target = nil, bendDirection = 1, + compress = false, stretch = false, + uniform = false, mix = 1 } diff --git a/spine-lua/Skeleton.lua b/spine-lua/Skeleton.lua index 1e2ae96e1..03de1cfe9 100644 --- a/spine-lua/Skeleton.lua +++ b/spine-lua/Skeleton.lua @@ -338,9 +338,10 @@ function Skeleton:setBonesToSetupPose () end for _,ikConstraint in ipairs(self.ikConstraints) do - ikConstraint.bendDirection = ikConstraint.data.bendDirection - ikConstraint.stretch = ikConstraint.data.stretch ikConstraint.mix = ikConstraint.data.mix + ikConstraint.bendDirection = ikConstraint.data.bendDirection + ikConstraint.compress = ikConstraint.data.compress + ikConstraint.stretch = ikConstraint.data.stretch end local transformConstraints = self.transformConstraints diff --git a/spine-lua/SkeletonJson.lua b/spine-lua/SkeletonJson.lua index 536f526db..cca4836fa 100644 --- a/spine-lua/SkeletonJson.lua +++ b/spine-lua/SkeletonJson.lua @@ -164,9 +164,11 @@ function SkeletonJson.new (attachmentLoader) data.target = skeletonData:findBone(targetName) if not data.target then error("Target bone not found: " .. targetName) end - if constraintMap["bendPositive"] == false then data.bendDirection = -1 else data.bendDirection = 1 end - if constraintMap["stretch"] == false then data.stretch = false else data.stretch = true end data.mix = getValue(constraintMap, "mix", 1) + if constraintMap["bendPositive"] == nil or constraintMap["bendPositive"] == false then data.bendDirection = -1 else data.bendDirection = 1 end + if constraintMap["compress"] == nil or constraintMap["compress"] == false then data.compress = false else data.compress = true end + if constraintMap["stretch"] == nil or constraintMap["stretch"] == false then data.stretch = false else data.stretch = true end + if constraintMap["uniform"] == nil or constraintMap["uniform"] == false then data.uniform = false else data.uniform = true end table_insert(skeletonData.ikConstraints, data) end @@ -613,9 +615,11 @@ function SkeletonJson.new (attachmentLoader) if valueMap["mix"] ~= nil then mix = valueMap["mix"] end local bendPositive = 1 if valueMap["bendPositive"] == false then bendPositive = -1 end - local stretch = true - if valueMap["stretch"] == false then stretch = false end - timeline:setFrame(frameIndex, valueMap["time"], mix, bendPositive, stretch) + local stretch = false + if valueMap["stretch"] ~= nil then stretch = valueMap["stretch"] end + local compress = false + if valueMap["compress"] ~= nil then compress = valueMap["compress"] end + timeline:setFrame(frameIndex, valueMap["time"], mix, bendPositive, compress, stretch) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end