From b113966ed432ab3123795d592c102f0e531f152a Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 7 Jun 2019 11:28:47 +0200 Subject: [PATCH] [lua] Ported skin bones/constraints changes. See #1346. --- spine-corona/spine-corona/spine.lua | 118 +++++++++++----------- spine-love/spine-love/spine.lua | 138 +++++++++++++------------- spine-lua/Animation.lua | 22 ++++ spine-lua/AnimationState.lua | 1 + spine-lua/Bone.lua | 3 +- spine-lua/BoneData.lua | 3 +- spine-lua/IkConstraint.lua | 1 + spine-lua/IkConstraintData.lua | 1 + spine-lua/PathConstraint.lua | 3 +- spine-lua/PathConstraintData.lua | 1 + spine-lua/Skeleton.lua | 78 ++++++++++----- spine-lua/SkeletonJson.lua | 42 ++++---- spine-lua/TransformConstraint.lua | 3 +- spine-lua/TransformConstraintData.lua | 1 + spine-lua/utils.lua | 7 ++ 15 files changed, 250 insertions(+), 172 deletions(-) diff --git a/spine-corona/spine-corona/spine.lua b/spine-corona/spine-corona/spine.lua index ffea10d77..de0d937f4 100644 --- a/spine-corona/spine-corona/spine.lua +++ b/spine-corona/spine-corona/spine.lua @@ -161,66 +161,70 @@ function spine.Skeleton:updateWorldTransform() local uvs = nil local numVertices = 0 local indices = nil - if attachment then - if attachment.type == spine.AttachmentType.region then - numVertices = 4 - vertices = worldVertices - attachment:computeWorldVertices(slot.bone, vertices, 0, 2) - uvs = attachment.uvs - indices = QUAD_TRIANGLES - texture = attachment.region.renderObject.texture - blendMode = toCoronaBlendMode(slot.data.blendMode) - elseif attachment.type == spine.AttachmentType.mesh then - numVertices = attachment.worldVerticesLength / 2 - vertices = worldVertices - attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) - uvs = attachment.uvs - indices = attachment.triangles - texture = attachment.region.renderObject.texture - blendMode = toCoronaBlendMode(slot.data.blendMode) - elseif attachment.type == spine.AttachmentType.clipping then - self.clipper:clipStart(slot, attachment) - end + + if slot.bone.active then + + if attachment then + if attachment.type == spine.AttachmentType.region then + numVertices = 4 + vertices = worldVertices + attachment:computeWorldVertices(slot.bone, vertices, 0, 2) + uvs = attachment.uvs + indices = QUAD_TRIANGLES + texture = attachment.region.renderObject.texture + blendMode = toCoronaBlendMode(slot.data.blendMode) + elseif attachment.type == spine.AttachmentType.mesh then + numVertices = attachment.worldVerticesLength / 2 + vertices = worldVertices + attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) + uvs = attachment.uvs + indices = attachment.triangles + texture = attachment.region.renderObject.texture + blendMode = toCoronaBlendMode(slot.data.blendMode) + elseif attachment.type == spine.AttachmentType.clipping then + self.clipper:clipStart(slot, attachment) + end - if texture and vertices and indices then - local skeleton = slot.bone.skeleton - local skeletonColor = skeleton.color - local slotColor = slot.color - local attachmentColor = attachment.color - local alpha = skeletonColor.a * slotColor.a * attachmentColor.a - local multiplier = alpha - if premultipliedAlpha then multiplier = 1 end - color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, - skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, - skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, - alpha) - - if not lastTexture then lastTexture = texture end - if lastColor.r == -1 then lastColor:setFrom(color) end - if not lastBlendMode then lastBlendMode = blendMode end + if texture and vertices and indices then + local skeleton = slot.bone.skeleton + local skeletonColor = skeleton.color + local slotColor = slot.color + local attachmentColor = attachment.color + local alpha = skeletonColor.a * slotColor.a * attachmentColor.a + local multiplier = alpha + if premultipliedAlpha then multiplier = 1 end + color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, + skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, + skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, + alpha) + + if not lastTexture then lastTexture = texture end + if lastColor.r == -1 then lastColor:setFrom(color) end + if not lastBlendMode then lastBlendMode = blendMode end - if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then - self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup) - lastTexture = texture - lastColor:setFrom(color) - lastBlendMode = blendMode - groupVertices = {} - groupUvs = {} - groupIndices = {} - end - - if self.clipper:isClipping() then - self.clipper:clipTriangles(vertices, uvs, indices, #indices) - vertices = self.clipper.clippedVertices - numVertices = #vertices / 2 - uvs = self.clipper.clippedUVs - indices = self.clipper.clippedTriangles - end + if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then + self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup) + lastTexture = texture + lastColor:setFrom(color) + lastBlendMode = blendMode + groupVertices = {} + groupUvs = {} + groupIndices = {} + end + + if self.clipper:isClipping() then + self.clipper:clipTriangles(vertices, uvs, indices, #indices) + vertices = self.clipper.clippedVertices + numVertices = #vertices / 2 + uvs = self.clipper.clippedUVs + indices = self.clipper.clippedTriangles + end - self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) - end - - self.clipper:clipEnd(slot) + self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices) + end + + self.clipper:clipEnd(slot) + end end end diff --git a/spine-love/spine-love/spine.lua b/spine-love/spine-love/spine.lua index f7f85fb6b..074435d52 100644 --- a/spine-love/spine-love/spine.lua +++ b/spine-love/spine-love/spine.lua @@ -320,76 +320,78 @@ function SkeletonRenderer:draw (skeleton) local drawOrder = skeleton.drawOrder for i, slot in ipairs(drawOrder) do - local attachment = slot.attachment - local vertices = worldVertices - local uvs = nil - local indices = nil - local texture = nil - local color = tmpColor - if attachment then - if attachment.type == spine.AttachmentType.region then - numVertices = 4 - attachment:computeWorldVertices(slot.bone, vertices, 0, 2) - uvs = attachment.uvs - indices = SkeletonRenderer.QUAD_TRIANGLES - texture = attachment.region.renderObject.texture - elseif attachment.type == spine.AttachmentType.mesh then - numVertices = attachment.worldVerticesLength / 2 - attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) - uvs = attachment.uvs - indices = attachment.triangles - texture = attachment.region.renderObject.texture - elseif attachment.type == spine.AttachmentType.clipping then - self.clipper:clipStart(slot, attachment) - end + if slot.bone.active then + local attachment = slot.attachment + local vertices = worldVertices + local uvs = nil + local indices = nil + local texture = nil + local color = tmpColor + if attachment then + if attachment.type == spine.AttachmentType.region then + numVertices = 4 + attachment:computeWorldVertices(slot.bone, vertices, 0, 2) + uvs = attachment.uvs + indices = SkeletonRenderer.QUAD_TRIANGLES + texture = attachment.region.renderObject.texture + elseif attachment.type == spine.AttachmentType.mesh then + numVertices = attachment.worldVerticesLength / 2 + attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) + uvs = attachment.uvs + indices = attachment.triangles + texture = attachment.region.renderObject.texture + elseif attachment.type == spine.AttachmentType.clipping then + self.clipper:clipStart(slot, attachment) + end - if texture then - local slotBlendMode = slot.data.blendMode - if lastBlendMode ~= slotBlendMode then - batcher:stop() - batcher:begin() + if texture then + local slotBlendMode = slot.data.blendMode + if lastBlendMode ~= slotBlendMode then + batcher:stop() + batcher:begin() + + if slotBlendMode == spine.BlendMode.normal then + love.graphics.setBlendMode("alpha") + elseif slotBlendMode == spine.BlendMode.additive then + love.graphics.setBlendMode("add") + elseif slotBlendMode == spine.BlendMode.multiply then + love.graphics.setBlendMode("multiply", "premultiplied") + elseif slotBlendMode == spine.BlendMode.screen then + love.graphics.setBlendMode("screen") + end + lastBlendMode = slotBlendMode + end - if slotBlendMode == spine.BlendMode.normal then - love.graphics.setBlendMode("alpha") - elseif slotBlendMode == spine.BlendMode.additive then - love.graphics.setBlendMode("add") - elseif slotBlendMode == spine.BlendMode.multiply then - love.graphics.setBlendMode("multiply", "premultiplied") - elseif slotBlendMode == spine.BlendMode.screen then - love.graphics.setBlendMode("screen") - end - lastBlendMode = slotBlendMode - end - - local skeleton = slot.bone.skeleton - local skeletonColor = skeleton.color - local slotColor = slot.color - local attachmentColor = attachment.color - local alpha = skeletonColor.a * slotColor.a * attachmentColor.a - local multiplier = alpha - if premultipliedAlpha then multiplier = 1 end - color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, - skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, - skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, - alpha) - - local dark = tmpColor2 - if slot.darkColor then dark = slot.darkColor - else dark:set(0, 0, 0, 0) end - - if self.clipper:isClipping() then - self.clipper:clipTriangles(vertices, attachment.uvs, indices, #indices) - vertices = self.clipper.clippedVertices - numVertices = #vertices / 2 - uvs = self.clipper.clippedUVs - indices = self.clipper.clippedTriangles - end - - batcher:draw(texture, vertices, uvs, numVertices, indices, color, dark, self.vertexEffect) - end - - self.clipper:clipEnd(slot) - end + local skeleton = slot.bone.skeleton + local skeletonColor = skeleton.color + local slotColor = slot.color + local attachmentColor = attachment.color + local alpha = skeletonColor.a * slotColor.a * attachmentColor.a + local multiplier = alpha + if premultipliedAlpha then multiplier = 1 end + color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier, + skeletonColor.g * slotColor.g * attachmentColor.g * multiplier, + skeletonColor.b * slotColor.b * attachmentColor.b * multiplier, + alpha) + + local dark = tmpColor2 + if slot.darkColor then dark = slot.darkColor + else dark:set(0, 0, 0, 0) end + + if self.clipper:isClipping() then + self.clipper:clipTriangles(vertices, attachment.uvs, indices, #indices) + vertices = self.clipper.clippedVertices + numVertices = #vertices / 2 + uvs = self.clipper.clippedUVs + indices = self.clipper.clippedTriangles + end + + batcher:draw(texture, vertices, uvs, numVertices, indices, color, dark, self.vertexEffect) + end + + self.clipper:clipEnd(slot) + end + end end batcher:stop() diff --git a/spine-lua/Animation.lua b/spine-lua/Animation.lua index 583f3d3a1..590ca2f99 100644 --- a/spine-lua/Animation.lua +++ b/spine-lua/Animation.lua @@ -259,6 +259,7 @@ function Animation.RotateTimeline.new (frameCount) local frames = self.frames local bone = skeleton.bones[self.boneIndex] + if not bone.active then return end if time < frames[0] then if blend == MixBlend.setup then bone.rotation = bone.data.rotation @@ -334,6 +335,8 @@ function Animation.TranslateTimeline.new (frameCount) local frames = self.frames local bone = skeleton.bones[self.boneIndex] + if not bone.active then return end + if time < frames[0] then if blend == MixBlend.setup then bone.x = bone.data.x @@ -398,6 +401,8 @@ function Animation.ScaleTimeline.new (frameCount) local frames = self.frames local bone = skeleton.bones[self.boneIndex] + if not bone.active then return end + if time < frames[0] then if blend == MixBlend.setup then bone.scaleX = bone.data.scaleX @@ -499,6 +504,8 @@ function Animation.ShearTimeline.new (frameCount) local frames = self.frames local bone = skeleton.bones[self.boneIndex] + if not bone.active then return end + if time < frames[0] then if blend == MixBlend.setup then bone.shearX = bone.data.shearX @@ -577,6 +584,7 @@ function Animation.ColorTimeline.new (frameCount) function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction) local frames = self.frames local slot = skeleton.slots[self.slotIndex] + if not slot.bone.active then return end if time < frames[0] then if blend == MixBlend.setup then slot.color:setFrom(slot.data.color) @@ -668,6 +676,8 @@ function Animation.TwoColorTimeline.new (frameCount) function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction) local frames = self.frames local slot = skeleton.slots[self.slotIndex] + if not slot.bone.active then return end + if time < frames[0] then if blend == MixBlend.setup then slot.color:setFrom(slot.data.color) @@ -758,6 +768,7 @@ function Animation.AttachmentTimeline.new (frameCount) function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction) local slot = skeleton.slots[self.slotIndex] + if not slot.bone.active then return end local attachmentName if direction == MixDirection.out and blend == MixBlend.setup then attachmentName = slot.data.attachmentName @@ -820,6 +831,8 @@ function Animation.DeformTimeline.new (frameCount) function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction) local slot = skeleton.slots[self.slotIndex] + if not slot.bone.active then return end + local slotAttachment = slot.attachment if not slotAttachment then return end if not (slotAttachment.type == AttachmentType.mesh or slotAttachment.type == AttachmentType.linkedmesh or slotAttachment.type == AttachmentType.path or slotAttachment.type == AttachmentType.boundingbox) then return end @@ -1211,6 +1224,7 @@ function Animation.IkConstraintTimeline.new (frameCount) local frames = self.frames local constraint = skeleton.ikConstraints[self.ikConstraintIndex] + if not constraint.active then return end if time < frames[0] then if blend == MixBlend.setup then constraint.mix = constraint.data.mix @@ -1316,6 +1330,8 @@ function Animation.TransformConstraintTimeline.new (frameCount) local frames = self.frames local constraint = skeleton.transformConstraints[self.transformConstraintIndex] + if not constraint.active then return end + if time < frames[0] then local data = constraint.data if blend == MixBlend.setup then @@ -1402,6 +1418,8 @@ function Animation.PathConstraintPositionTimeline.new (frameCount) local frames = self.frames local constraint = skeleton.pathConstraints[self.pathConstraintIndex] + if not constraint.active then return end + if (time < frames[0]) then if blend == MixBlend.setup then constraint.position = constraint.data.position @@ -1461,6 +1479,8 @@ function Animation.PathConstraintSpacingTimeline.new (frameCount) local frames = self.frames local constraint = skeleton.pathConstraints[self.pathConstraintIndex] + if not constraint.active then return end + if (time < frames[0]) then if blend == MixBlend.setup then constraint.spacing = constraint.data.spacing @@ -1524,6 +1544,8 @@ function Animation.PathConstraintMixTimeline.new (frameCount) local frames = self.frames local constraint = skeleton.pathConstraints[self.pathConstraintIndex] + if not constraint.active then return end + if (time < frames[0]) then if blend == MixBlend.setup then constraint.rotateMix = constraint.data.rotateMix diff --git a/spine-lua/AnimationState.lua b/spine-lua/AnimationState.lua index 2e7491552..ff14c9110 100644 --- a/spine-lua/AnimationState.lua +++ b/spine-lua/AnimationState.lua @@ -488,6 +488,7 @@ function AnimationState:applyRotateTimeline (timeline, skeleton, time, alpha, bl local rotateTimeline = timeline local frames = rotateTimeline.frames local bone = skeleton.bones[rotateTimeline.boneIndex] + if not bone.active then return end local r1 = 0 local r2 = 0 if time < frames[0] then diff --git a/spine-lua/Bone.lua b/spine-lua/Bone.lua index 286d0b9d2..67c6edd7f 100644 --- a/spine-lua/Bone.lua +++ b/spine-lua/Bone.lua @@ -69,7 +69,8 @@ function Bone.new (data, skeleton, parent) a = 0, b = 0, worldX = 0, -- a b x c = 0, d = 0, worldY = 0, -- c d y - sorted = false + sorted = false, + active = false } setmetatable(self, Bone) diff --git a/spine-lua/BoneData.lua b/spine-lua/BoneData.lua index 7881ee3b3..304341a2f 100644 --- a/spine-lua/BoneData.lua +++ b/spine-lua/BoneData.lua @@ -46,7 +46,8 @@ function BoneData.new (index, name, parent) scaleX = 1, scaleY = 1, shearX = 0, shearY = 0, inheritRotation = true, - inheritScale = true + inheritScale = true, + skinRequired = false } return self diff --git a/spine-lua/IkConstraint.lua b/spine-lua/IkConstraint.lua index 5872f6da6..ef7126a2d 100644 --- a/spine-lua/IkConstraint.lua +++ b/spine-lua/IkConstraint.lua @@ -54,6 +54,7 @@ function IkConstraint.new (data, skeleton) compress = data.compress, stretch = data.stretch, bendDirection = data.bendDirection, + active = false } setmetatable(self, IkConstraint) diff --git a/spine-lua/IkConstraintData.lua b/spine-lua/IkConstraintData.lua index aeffea74c..57c03e0f6 100644 --- a/spine-lua/IkConstraintData.lua +++ b/spine-lua/IkConstraintData.lua @@ -34,6 +34,7 @@ function IkConstraintData.new (name) local self = { name = name, order = 0, + skinRequired = false, bones = {}, target = nil, bendDirection = 1, diff --git a/spine-lua/PathConstraint.lua b/spine-lua/PathConstraint.lua index 864ade2f8..5e2df0377 100644 --- a/spine-lua/PathConstraint.lua +++ b/spine-lua/PathConstraint.lua @@ -73,7 +73,8 @@ function PathConstraint.new (data, skeleton) world = {}, curves = {}, lengths = {}, - segments = {} + segments = {}, + active = false } setmetatable(self, PathConstraint) diff --git a/spine-lua/PathConstraintData.lua b/spine-lua/PathConstraintData.lua index b96909826..ab99808dc 100644 --- a/spine-lua/PathConstraintData.lua +++ b/spine-lua/PathConstraintData.lua @@ -34,6 +34,7 @@ function PathConstraintData.new (name) local self = { name = name, order = 0, + skinRequired = false, bones = {}, target = nil, positionMode = nil, diff --git a/spine-lua/Skeleton.lua b/spine-lua/Skeleton.lua index ac86e5563..0bb4a25ad 100644 --- a/spine-lua/Skeleton.lua +++ b/spine-lua/Skeleton.lua @@ -113,8 +113,21 @@ function Skeleton:updateCache () local bones = self.bones for _, bone in ipairs(bones) do - bone.sorted = false + bone.sorted = bone.data.skinRequired + bone.active = not bone.sorted end + + if self.skin then + local skinBones = self.skin.bones + for i, boneData in ipairs(skinBones) do + local bone = bones[boneData.index] + while bone do + bone.sorted = false + bone.active = true + bone = bone.parent + end + end + end local ikConstraints = self.ikConstraints local transformConstraints = self.transformConstraints @@ -172,6 +185,9 @@ function Skeleton:updateCache () end function Skeleton:sortIkConstraint (constraint) + constraint.active = constraint.target.active and ((not constraint.data.skinRequired) or (self.skin and utils.arrayContains(self.skin.constraints, constraint))) + if not constraint.active then return end + local target = constraint.target self:sortBone(target) @@ -198,6 +214,9 @@ function Skeleton:sortIkConstraint (constraint) end function Skeleton:sortPathConstraint(constraint) + constraint.active = constraint.target.bone.active and ((not constraint.data.skinRequired) or (self.skin and utils.arrayContains(self.skin.constraints, constraint))) + if not constraint.active then return end + local slot = constraint.target local slotIndex = slot.data.index local slotBone = slot.bone @@ -229,6 +248,9 @@ function Skeleton:sortPathConstraint(constraint) end function Skeleton:sortTransformConstraint(constraint) + constraint.active = constraint.target.active and ((not constraint.data.skinRequired) or (self.skin and utils.arrayContains(self.skin.constraints, constraint))) + if not constraint.active then return end + self:sortBone(constraint.target) local constrained = constraint.bones @@ -301,8 +323,10 @@ end function Skeleton:sortReset(bones) for _, bone in ipairs(bones) do - if bone.sorted then self:sortReset(bone.children) end - bone.sorted = false + if bone.active then + if bone.sorted then self:sortReset(bone.children) end + bone.sorted = false + end end end @@ -412,6 +436,7 @@ function Skeleton:setSkin (skinName) end function Skeleton:setSkinByReference(newSkin) + if (self.skin == newSkin) then return end if newSkin then if self.skin then newSkin:attachAll(self, self.skin) @@ -429,6 +454,7 @@ function Skeleton:setSkinByReference(newSkin) end end self.skin = newSkin + self:updateCache() end function Skeleton:getAttachment (slotName, attachmentName) @@ -498,28 +524,30 @@ function Skeleton:getBounds(offset, size) local maxX = -99999999 local maxY = -99999999 for _, slot in ipairs(drawOrder) do - local vertices = {} - local attachment = slot.attachment - if attachment then - if attachment.type == AttachmentType.region then - attachment:computeWorldVertices(slot.bone, vertices, 0, 2) - elseif attachment.type == AttachmentType.mesh then - attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) - end - end - if #vertices > 0 then - local nn = #vertices - local ii = 1 - while ii <= nn do - local x = vertices[ii] - local y = vertices[ii + 1] - minX = math_min(minX, x) - minY = math_min(minY, y) - maxX = math_max(maxX, x) - maxY = math_max(maxY, y) - ii = ii + 2 - end - end + if slot.bone.active then + local vertices = {} + local attachment = slot.attachment + if attachment then + if attachment.type == AttachmentType.region then + attachment:computeWorldVertices(slot.bone, vertices, 0, 2) + elseif attachment.type == AttachmentType.mesh then + attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2) + end + end + if #vertices > 0 then + local nn = #vertices + local ii = 1 + while ii <= nn do + local x = vertices[ii] + local y = vertices[ii + 1] + minX = math_min(minX, x) + minY = math_min(minY, y) + maxX = math_max(maxX, x) + maxY = math_max(maxY, y) + ii = ii + 2 + end + end + end end offset[1] = minX offset[2] = minY diff --git a/spine-lua/SkeletonJson.lua b/spine-lua/SkeletonJson.lua index 23054ad23..c177fa38d 100644 --- a/spine-lua/SkeletonJson.lua +++ b/spine-lua/SkeletonJson.lua @@ -111,6 +111,7 @@ function SkeletonJson.new (attachmentLoader) data.shearX = getValue(boneMap, "shearX", 0); data.shearY = getValue(boneMap, "shearY", 0); data.transformMode = TransformMode[getValue(boneMap, "transform", "normal")] + data.skinRequired = getValue(boneMap, "skin", false) table_insert(skeletonData.bones, data) end @@ -154,6 +155,7 @@ function SkeletonJson.new (attachmentLoader) for _,constraintMap in ipairs(root["ik"]) do local data = IkConstraintData.new(constraintMap["name"]) data.order = getValue(constraintMap, "order", 0) + data.skinRequired = getValue(constraintMap, "skin", false) for _,boneName in ipairs(constraintMap["bones"]) do local bone = skeletonData:findBone(boneName) @@ -184,6 +186,7 @@ function SkeletonJson.new (attachmentLoader) for _,constraintMap in ipairs(root["transform"]) do local data = TransformConstraintData.new(constraintMap.name) data.order = getValue(constraintMap, "order", 0) + data.skinRequired = getValue(constraintMap, "skin", false) for _,boneName in ipairs(constraintMap.bones) do local bone = skeletonData:findBone(boneName) @@ -216,6 +219,7 @@ function SkeletonJson.new (attachmentLoader) for _,constraintMap in ipairs(root.path) do local data = PathConstraintData.new(constraintMap.name); data.order = getValue(constraintMap, "order", 0) + data.skinRequired = getValue(constraintMap, "skin", false) for _,boneName in ipairs(constraintMap.bones) do local bone = skeletonData:findBone(boneName) @@ -245,8 +249,8 @@ function SkeletonJson.new (attachmentLoader) -- Skins. if root["skins"] then for skinName,skinMap in pairs(root["skins"]) do - local skin = Skin.new(skinName) - for slotName,slotMap in pairs(skinMap) do + local skin = Skin.new(skinMap["name"]) + for slotName,slotMap in pairs(skinMap.attachments) do local slotIndex = skeletonData.slotNameIndices[slotName] for attachmentName,attachmentMap in pairs(slotMap) do local attachment = readAttachment(attachmentMap, skin, slotIndex, attachmentName, skeletonData) @@ -511,7 +515,7 @@ function SkeletonJson.new (attachmentLoader) for _,valueMap in ipairs(values) do local color = valueMap["color"] timeline:setFrame( - frameIndex, valueMap["time"], + frameIndex, getValue(valueMap, "time", 0), tonumber(color:sub(1, 2), 16) / 255, tonumber(color:sub(3, 4), 16) / 255, tonumber(color:sub(5, 6), 16) / 255, @@ -531,7 +535,7 @@ function SkeletonJson.new (attachmentLoader) local light = valueMap["light"] local dark = valueMap["dark"] timeline:setFrame( - frameIndex, valueMap["time"], + frameIndex, getValue(valueMap, "time", 0), tonumber(light:sub(1, 2), 16) / 255, tonumber(light:sub(3, 4), 16) / 255, tonumber(light:sub(5, 6), 16) / 255, @@ -552,7 +556,7 @@ function SkeletonJson.new (attachmentLoader) local frameIndex = 0 for _,valueMap in ipairs(values) do local attachmentName = valueMap["name"] - timeline:setFrame(frameIndex, valueMap["time"], attachmentName) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), attachmentName) frameIndex = frameIndex + 1 end table_insert(timelines, timeline) @@ -579,7 +583,7 @@ function SkeletonJson.new (attachmentLoader) local frameIndex = 0 for _,valueMap in ipairs(values) do - timeline:setFrame(frameIndex, valueMap["time"], valueMap["angle"]) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), getValue(valueMap, "angle", 0)) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -589,8 +593,10 @@ function SkeletonJson.new (attachmentLoader) elseif timelineName == "translate" or timelineName == "scale" or timelineName == "shear" then local timeline local timelineScale = 1 + local defaultValue = 0 if timelineName == "scale" then timeline = Animation.ScaleTimeline.new(#values) + defaultValue = 1 elseif timelineName == "shear" then timeline = Animation.ShearTimeline.new(#values) else @@ -601,9 +607,9 @@ function SkeletonJson.new (attachmentLoader) local frameIndex = 0 for _,valueMap in ipairs(values) do - local x = (valueMap["x"] or 0) * timelineScale - local y = (valueMap["y"] or 0) * timelineScale - timeline:setFrame(frameIndex, valueMap["time"], x, y) + local x = getValue(valueMap, "x", defaultValue) * timelineScale + local y = getValue(valueMap, "y", defaultValue) * timelineScale + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), x, y) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -638,7 +644,7 @@ function SkeletonJson.new (attachmentLoader) 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) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), mix, bendPositive, compress, stretch) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -661,7 +667,7 @@ function SkeletonJson.new (attachmentLoader) end local frameIndex = 0 for _,valueMap in ipairs(values) do - timeline:setFrame(frameIndex, valueMap.time, getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1), getValue(valueMap, "scaleMix", 1), getValue(valueMap, "shearMix", 1)) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1), getValue(valueMap, "scaleMix", 1), getValue(valueMap, "shearMix", 1)) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -690,7 +696,7 @@ function SkeletonJson.new (attachmentLoader) timeline.pathConstraintIndex = index local frameIndex = 0 for _,valueMap in ipairs(timelineMap) do - timeline:setFrame(frameIndex, valueMap.time, getValue(valueMap, timelineName, 0) * timelineScale) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), getValue(valueMap, timelineName, 0) * timelineScale) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -701,7 +707,7 @@ function SkeletonJson.new (attachmentLoader) timeline.pathConstraintIndex = index local frameIndex = 0 for _,valueMap in ipairs(timelineMap) do - timeline:setFrame(frameIndex, valueMap.time, getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1)) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1)) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -761,7 +767,7 @@ function SkeletonJson.new (attachmentLoader) end end - timeline:setFrame(frameIndex, valueMap.time, deform) + timeline:setFrame(frameIndex, getValue(valueMap, "time", 0), deform) readCurve(valueMap, timeline, frameIndex) frameIndex = frameIndex + 1 end @@ -814,7 +820,7 @@ function SkeletonJson.new (attachmentLoader) end end end - timeline:setFrame(frameIndex, drawOrderMap["time"], drawOrder) + timeline:setFrame(frameIndex, getValue(drawOrderMap, "time", 0), drawOrder) frameIndex = frameIndex + 1 end table_insert(timelines, timeline) @@ -829,7 +835,7 @@ function SkeletonJson.new (attachmentLoader) for _,eventMap in ipairs(events) do local eventData = skeletonData:findEvent(eventMap["name"]) if not eventData then error("Event not found: " .. eventMap["name"]) end - local event = Event.new(eventMap["time"], eventData) + local event = Event.new(getValue(eventMap, "time", 0), eventData) if eventMap["int"] ~= nil then event.intValue = eventMap["int"] else @@ -864,8 +870,8 @@ function SkeletonJson.new (attachmentLoader) if not curve then return end if curve == "stepped" then timeline:setStepped(frameIndex) - elseif #curve > 0 then - timeline:setCurve(frameIndex, curve[1], curve[2], curve[3], curve[4]) + else + timeline:setCurve(frameIndex, getValue(map, "curve", 0), getValue(map, "c2", 0), getValue(map, "c3", 1), getValue(map, "c4", 1)) end end diff --git a/spine-lua/TransformConstraint.lua b/spine-lua/TransformConstraint.lua index 8deec63ab..7ceab01c7 100644 --- a/spine-lua/TransformConstraint.lua +++ b/spine-lua/TransformConstraint.lua @@ -54,7 +54,8 @@ function TransformConstraint.new (data, skeleton) bones = {}, target = nil, rotateMix = data.rotateMix, translateMix = data.translateMix, scaleMix = data.scaleMix, shearMix = data.shearMix, - temp = { 0, 0 } + temp = { 0, 0 }, + active = false } setmetatable(self, TransformConstraint) diff --git a/spine-lua/TransformConstraintData.lua b/spine-lua/TransformConstraintData.lua index 18af05f1e..995bee01d 100644 --- a/spine-lua/TransformConstraintData.lua +++ b/spine-lua/TransformConstraintData.lua @@ -34,6 +34,7 @@ function TransformConstraintData.new (name) local self = { name = name, order = 0, + skinRequired = false, bones = {}, target = nil, rotateMix = 0, translateMix = 0, scaleMix = 0, shearMix = 0, diff --git a/spine-lua/utils.lua b/spine-lua/utils.lua index 38ff98b0c..1a7c60419 100644 --- a/spine-lua/utils.lua +++ b/spine-lua/utils.lua @@ -129,6 +129,13 @@ function utils.arrayCopy (src, srcOffset, dst, dstOffset, size) end end +function utils.arrayContains(array, element) + for i, arrayElement in ipairs(array) do + if arrayElement == element then return true end + end + return false +end + function utils.clamp (value, min, max) if value < min then return min end if value > max then return max end