From 1f669462b05fbf5d63605a0243636bb91a0998a2 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 20 Oct 2016 13:07:13 +0200 Subject: [PATCH] [lua][love] Finished porting 3.5 --- spine-love/main.lua | 12 +-- spine-lua/Bone.lua | 16 +-- spine-lua/Skeleton.lua | 227 ++++++++++++++++++++++++----------------- 3 files changed, 149 insertions(+), 106 deletions(-) diff --git a/spine-love/main.lua b/spine-love/main.lua index b20db3976..ef2b2917f 100644 --- a/spine-love/main.lua +++ b/spine-love/main.lua @@ -75,13 +75,13 @@ end function love.load(arg) if arg[#arg] == "-debug" then require("mobdebug").start() end - --table.insert(skeletons, loadSkeleton("test", "test", "animation", nil, 0.5, 400, 300)) - --table.insert(skeletons, loadSkeleton("spineboy", "spineboy", "walk", nil, 0.5, 400, 500)) + table.insert(skeletons, loadSkeleton("test", "test", "animation", nil, 0.5, 400, 300)) + table.insert(skeletons, loadSkeleton("spineboy", "spineboy", "walk", nil, 0.5, 400, 500)) table.insert(skeletons, loadSkeleton("raptor", "raptor", "walk", nil, 0.3, 400, 500)) - --table.insert(skeletons, loadSkeleton("goblins-mesh", "goblins", "walk", "goblin", 1, 400, 500)) - --table.insert(skeletons, loadSkeleton("tank", "tank", "drive", nil, 0.2, 600, 500)) - --table.insert(skeletons, loadSkeleton("vine", "vine", "animation", nil, 0.3, 400, 500)) - --table.insert(skeletons, loadSkeleton("stretchyman", "stretchyman", "sneak", nil, 0.3, 200, 500)) + table.insert(skeletons, loadSkeleton("goblins-mesh", "goblins", "walk", "goblin", 1, 400, 500)) + table.insert(skeletons, loadSkeleton("tank", "tank", "drive", nil, 0.2, 600, 500)) + table.insert(skeletons, loadSkeleton("vine", "vine", "animation", nil, 0.3, 400, 500)) + table.insert(skeletons, loadSkeleton("stretchyman", "stretchyman", "sneak", nil, 0.3, 200, 500)) skeletonRenderer = spine.SkeletonRenderer.new() end diff --git a/spine-lua/Bone.lua b/spine-lua/Bone.lua index b3a4bef93..2e26cd0b2 100644 --- a/spine-lua/Bone.lua +++ b/spine-lua/Bone.lua @@ -35,6 +35,8 @@ local math_sin = math.sin local math_cos = math.cos local math_atan2 = math.atan2 local math_sqrt = math.sqrt +local math_abs = math.abs +local math_pi = math.pi local TransformMode = require "spine-lua.TransformMode" @@ -167,10 +169,10 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, local lb = math_cos(math_rad(ry)) * scaleY local lc = math_sin(math_rad(rx)) * scaleX local ld = math_sin(math_rad(ry)) * scaleY - a = pa * la - pb * lc - b = pa * lb - pb * ld - c = pc * la + pd * lc - d = pc * lb + pd * ld + self.a = pa * la - pb * lc + self.b = pa * lb - pb * ld + self.c = pc * la + pd * lc + self.d = pc * lb + pd * ld elseif transformMode == TransformMode.noScale or transformMode == TransformMode.noScaleOrReflection then local cos = math_cos(math_rad(rotation)) local sin = math_sin(math_rad(rotation)) @@ -192,7 +194,7 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, self.b = za * lb + zb * ld self.c = zc * la + zd * lc self.d = zc * lb + zd * ld - local flip = skeleton.flipX ~= skeleton.flipY + local flip = self.skeleton.flipX ~= self.skeleton.flipY if transformMode ~= TransformMode.noScaleOrReflection then flip = pa * pd - pb * pc < 0 end if flip then self.b = -self.b @@ -201,11 +203,11 @@ function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, return end - if skeleton.flipX then + if self.skeleton.flipX then self.a = -self.a self.b = -self.b end - if skeleton.flipY then + if self.skeleton.flipY then self.c = -self.c self.d = -self.d end diff --git a/spine-lua/Skeleton.lua b/spine-lua/Skeleton.lua index fc3d99d8c..a96666d6d 100644 --- a/spine-lua/Skeleton.lua +++ b/spine-lua/Skeleton.lua @@ -114,108 +114,137 @@ function Skeleton:updateCache () bone.sorted = false end - local ikConstraints = {} - self.ikConstraintsSorted = ikConstraints - for i, constraint in ipairs(self.ikConstraints) do - table_insert(ikConstraints, constraint) - end - - local level = 0 - for i, ik in ipairs(ikConstraints) do - local bone = ik.bones[1].parent - level = 0 - while bone do - bone = bone.parent - level = level + 1 - end - ik.level = level - end - - local i = 1 + local ikConstraints = self.ikConstraints + local transformConstraints = self.transformConstraints + local pathConstraints = self.pathConstraints local ikCount = #ikConstraints - while i < ikCount do - local ik = ikConstraints[i + 1] - local level = ik.level - local ii = i - 1 - while ii >= 0 do - local other = ikConstraints[ii + 1] - if other.level < level then break end - ikConstraints[ii + 1 + 1] = other - ii = ii - 1 + local transformCount = #transformConstraints + local pathCount = #pathConstraints + local constraintCount = ikCount + transformCount + pathCount + + local i = 0 + while i < constraintCount do + local found = false + local ii = 1 + while ii <= ikCount do + local constraint = ikConstraints[ii] + if constraint.data.order == i then + self:sortIkConstraint(constraint) + found = true + break + end + ii = ii + 1 end - ikConstraints[ii + 1 + 1] = ik + + if not found then + ii = 1 + while ii <= transformCount do + local constraint = transformConstraints[ii] + if constraint.data.order == i then + self:sortTransformConstraint(constraint) + found = true + break + end + ii = ii + 1 + end + end + + if not found then + ii = 1 + while ii <= pathCount do + local constraint = pathConstraints[ii] + if constraint.data.order == i then + self:sortPathConstraint(constraint) + break + end + ii = ii + 1 + end + end + i = i + 1 end - - for i, constraint in ipairs(ikConstraints) do - local target = constraint.target - self:sortBone(target) - - local constrained = constraint.bones - local parent = constrained[1] - self:sortBone(parent) - - table_insert(updateCache, constraint) - - self:sortReset(parent.children) - constrained[#constrained].sorted = true - end - - -- path constraints - local pathConstraints = self.pathConstraints - for i,constraint in ipairs(pathConstraints) do - local slot = constraint.target - local slotIndex = slot.data.index - local slotBone = slot.bone - if self.skin then self:sortPathConstraintAttachment(self.skin, slotIndex, slotBone) end - if self.data.defaultSkin and self.data.defaultSkin ~= self.skin then self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone) end - for i,skin in ipairs(self.data.skins) do - self:sortPathConstraintAttachment(skin, slotIndex, slotBone) - end - - local attachment = slot.attachment - if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end - - local constrained = constraint.bones - for i,c in ipairs(constrained) do - self:sortBone(c) - end - - table_insert(updateCache, constraint) - - for i,c in ipairs(constrained) do - self:sortReset(c.children) - end - for i,c in ipairs(constrained) do - c.sorted = true - end - end - - -- transform constraints - local transformConstraints = self.transformConstraints - for i, constraint in ipairs(transformConstraints) do - self:sortBone(constraint.target) - - local constrained = constraint.bones - for i,c in ipairs(constrained) do - self:sortBone(c) - end - - table_insert(updateCache, constraint) - - for i,c in ipairs(constrained) do - self:sortReset(c.children) - end - for i,c in ipairs(constrained) do - c.sorted = true - end - end - + for i, bone in ipairs(self.bones) do self:sortBone(bone) end end +function Skeleton:sortIkConstraint (constraint) + local target = constraint.target + self:sortBone(target) + + local constrained = constraint.bones + local parent = constrained[1] + self:sortBone(parent) + + if #constrained > 1 then + local child = constrained[#constrained] + local contains = false + for i,updatable in ipairs(self._updateCache) do + if updatable == child then + contains = true + break + end + end + if not contains then table_insert(self.updateCacheReset, child) end + end + + table_insert(self._updateCache, constraint) + + self:sortReset(parent.children) + constrained[#constrained].sorted = true +end + +function Skeleton:sortPathConstraint(constraint) + local slot = constraint.target + local slotIndex = slot.data.index + local slotBone = slot.bone + if self.skin then self:sortPathConstraintAttachment(skin, slotIndex, slotBone) end + if self.data.defaultSkin and not (self.data.defaultSkin == skin) then + self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone) + end + for ii,skin in ipairs(self.data.skins) do + self:sortPathConstraintAttachment(skin, slotIndex, slotBone) + end + + local attachment = slot.attachment + if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end + + local constrained = constraint.bones + for ii,bone in ipairs(constrained) do + self:sortBone(bone) + end + + table_insert(self._updateCache, constraint) + + for i,bone in ipairs(constrained) do + self:sortReset(bone.children) + end + + for i,bone in ipairs(constrained) do + bone.sorted = true + end +end + +function Skeleton:sortTransformConstraint(constraint) + self:sortBone(constraint.target) + + local constrained = constraint.bones + for ii,bone in ipairs(constrained) do + self:sortBone(bone) + end + + table_insert(self._updateCache, constraint) + + for i,bone in ipairs(constrained) do + self:sortReset(bone.children) + end + + for i,bone in ipairs(constrained) do + bone.sorted = true + end +end + function Skeleton:sortPathConstraintAttachment(skin, slotIndex, slotBone) local attachments = skin.attachments[slotIndex] if not attachments then return end @@ -262,6 +291,18 @@ end -- Updates the world transform for each bone and applies IK constraints. function Skeleton:updateWorldTransform () + local updateCacheReset = self.updateCacheReset + for i,bone in ipairs(updateCacheReset) do + bone.ax = bone.x + bone.ay = bone.y + bone.arotation = bone.rotation + bone.ascaleX = bone.scaleX + bone.ascaleY = bone.scaleY + bone.ashearX = bone.shearX + bone.ashearY = bone.shearY + bone.appliedValid = true + end + local updateCache = self._updateCache for i, updatable in ipairs(updateCache) do updatable:update()