From 946a97d67a890b5e2e73912db0acd449f5c32d93 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 23 Feb 2017 13:52:04 +0100 Subject: [PATCH] [lua] Ported 3.6 changes of TransformConstraint --- spine-lua/TransformConstraint.lua | 196 ++++++++++++++++++++++++++++-- 1 file changed, 188 insertions(+), 8 deletions(-) diff --git a/spine-lua/TransformConstraint.lua b/spine-lua/TransformConstraint.lua index 7ae6efcdf..5f97b8936 100644 --- a/spine-lua/TransformConstraint.lua +++ b/spine-lua/TransformConstraint.lua @@ -71,6 +71,22 @@ function TransformConstraint:apply () end function TransformConstraint:update () + if self.data.local_ then + if self.data.relative then + self:applyRelativeLocal() + else + self:applyAbsoluteLocal() + end + else + if self.data.relative then + self:applyRelativeWorld() + else + self:applyAbsoluteWorld() + end + end +end + +function TransformConstraint:applyAbsoluteWorld () local rotateMix = self.rotateMix local translateMix = self.translateMix local scaleMix = self.scaleMix @@ -119,19 +135,17 @@ function TransformConstraint:update () end if scaleMix > 0 then - local bs = math_sqrt(bone.a * bone.a + bone.c * bone.c) + local s = math_sqrt(bone.a * bone.a + bone.c * bone.c) local ts = math_sqrt(ta * ta + tc * tc) - local s = 0 - if bs > 0.00001 then - s = (bs + (ts - bs + self.data.offsetScaleX) * scaleMix) / bs + if s > 0.00001 then + s = (s + (ts - s + self.data.offsetScaleX) * scaleMix) / s end bone.a = bone.a * s bone.c = bone.c * s - bs = math_sqrt(bone.b * bone.b + bone.d * bone.d) + s = math_sqrt(bone.b * bone.b + bone.d * bone.d) ts = math_sqrt(tb * tb + td * td) - s = 0 - if bs > 0.00001 then - s = (bs + (ts - bs + self.data.offsetScaleY) * scaleMix) / bs + if s > 0.00001 then + s = (s + (ts - s + self.data.offsetScaleY) * scaleMix) / s end bone.b = bone.b * s bone.d = bone.d * s @@ -159,4 +173,170 @@ function TransformConstraint:update () end end +function TransformConstraint:applyRelativeWorld () + local rotateMix = self.rotateMix + local translateMix = self.translateMix + local scaleMix = self.scaleMix + local shearMix = self.shearMix + local target = self.target + local ta = target.a + local tb = target.b + local tc = target.c + local td = target.d + local degRadReflect = 0; + if ta * td - tb * tc > 0 then degRadReflect = utils.degRad else degRadReflect = -utils.degRad end + local offsetRotation = self.data.offsetRotation * degRadReflect + local offsetShearY = self.data.offsetShearY * degRadReflect + local bones = self.bones + for i, bone in ipairs(bones) do + local modified = false + + if rotateMix ~= 0 then + local a = bone.a + local b = bone.b + local c = bone.c + local d = bone.d + local r = math_atan2(tc, ta) + offsetRotation + if r > math_pi then + r = r - math_pi2 + elseif r < -math_pi then + r = r + math_pi2 + end + r = r * rotateMix + local cos = math_cos(r) + local sin = math_sin(r) + bone.a = cos * a - sin * c + bone.b = cos * b - sin * d + bone.c = sin * a + cos * c + bone.d = sin * b + cos * d + modified = true + end + + if translateMix ~= 0 then + local temp = self.temp + temp[1] = self.data.offsetX + temp[2] = self.data.offsetY + target:localToWorld(temp) + bone.worldX = bone.worldX + temp[1] * translateMix + bone.worldY = bone.worldY + temp[2] * translateMix + modified = true + end + + if scaleMix > 0 then + local s = (math_sqrt(ta * ta + tc * tc) - 1 + self.data.offsetScaleX) * scaleMix + 1 + bone.a = bone.a * s + bone.c = bone.c * s + local s = (math_sqrt(tb * tb + td * td) - 1 + self.data.offsetScaleY) * scaleMix + 1 + bone.b = bone.b * s + bone.d = bone.d * s + modified = true + end + + if shearMix > 0 then + local r = math_atan2(td, tb) - math_atan2(tc, ta) + if r > math_pi then + r = r - math_pi2 + elseif r < -math_pi then + r = r + math_pi2 + end + local b = bone.b + local d = bone.d + r = math_atan2(d, b) + (r - math_pi / 2 + offsetShearY) * shearMix; + local s = math_sqrt(b * b + d * d) + bone.b = math_cos(r) * s + bone.d = math_sin(r) * s + modified = true + end + + if modified then bone.appliedValid = false end + end +end + +function TransformConstraint:applyAbsoluteLocal () + local rotateMix = self.rotateMix + local translateMix = self.translateMix + local scaleMix = self.scaleMix + local shearMix = self.shearMix + local target = self.target + if not target.appliedValid then target:updatedAppliedTransform() end + local bones = self.bones + for i, bone in ipairs(bones) do + local modified = false + if not bone.appliedValid then bone:updateAppliedTransform() end + + local rotation = bone.arotation + if rotateMix ~= 0 then + local r = target.arotation - rotation + self.data.offsetRotation + r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 + rotation = rotation + r * rotateMix + end + + local x = bone.ax + local y = bone.ay + if translateMix ~= 0 then + x = x + (target.ax - x + self.data.offsetX) * translateMix + y = x + (target.ay - y + self.data.offsetY) * translateMix + end + + local scaleX = bone.ascaleX + local scaleY = bone.ascaleY + if scaleMix > 0 then + if scaleX > 0.00001 then + scaleX = (scaleX + (target.ascaleX - scaleX + self.data.offsetScaleX) * scaleMix) / scaleX + end + if scaleY > 0.00001 then + scaleY = (scaleY + (target.ascaleY - scaleY + self.data.offsetScaleY) * scaleMix) / scaleY + end + end + + local shearY = bone.ashearY + if shearMix > 0 then + local r = target.ashearY - shearY + self.data.offsetShearY + r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 + bone.shearY = bone.shearY + r * shearMix + end + + bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + end +end + +function TransformConstraint:applyRelativeLocal () + local rotateMix = self.rotateMix + local translateMix = self.translateMix + local scaleMix = self.scaleMix + local shearMix = self.shearMix + local target = self.target + if not target.appliedValid then target:updateAppliedTransform() end + local bones = self.bones + for i, bone in ipairs(bones) do + if not bone.appliedValid then bone:updateAppliedTransform() end + + local rotation = bone.arotation + if rotateMix ~= 0 then rotation = rotation + (target.arotation + self.data.offsetRotation) * rotateMix end + + local x = bone.ax + local y = bone.ay + if translateMix ~= 0 then + x = x + (target.ax + self.data.offsetX) * translateMix + y = y + (target.ay + self.data.offsetY) * translateMix + end + + local scaleX = bone.ascaleX + local scaleY = bone.ascaleY + if scaleMix > 0 then + if scaleX > 0.00001 then + scaleX = scaleX * (((target.ascaleX - 1 + self.data.offsetScaleX) * scaleMix) + 1) + end + if scaleY > 0.00001 then + scaleY = scaleY * (((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1) + end + end + + local shearY = bone.ashearY + if shearMix > 0 then shearY = shearY + (target.ashearY + self.data.offsetShearY) * shearMix end + + bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY) + end +end + return TransformConstraint