Эх сурвалжийг харах

[lua] Ported addition of uniform/compressed IK and rotation fix.

badlogic 7 жил өмнө
parent
commit
3e8cb852bb

+ 21 - 6
spine-lua/Animation.lua

@@ -1169,19 +1169,21 @@ function Animation.DrawOrderTimeline.new (frameCount)
 end
 end
 
 
 Animation.IkConstraintTimeline = {}
 Animation.IkConstraintTimeline = {}
-Animation.IkConstraintTimeline.ENTRIES = 4
+Animation.IkConstraintTimeline.ENTRIES = 5
 function Animation.IkConstraintTimeline.new (frameCount)
 function Animation.IkConstraintTimeline.new (frameCount)
 	local ENTRIES = Animation.IkConstraintTimeline.ENTRIES
 	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 PREV_STRETCH = -1
 	local MIX = 1
 	local MIX = 1
 	local BEND_DIRECTION = 2
 	local BEND_DIRECTION = 2
+	local COMPRESS = 3
 	local STRETCH = 1
 	local STRETCH = 1
 
 
 	local self = Animation.CurveTimeline.new(frameCount)
 	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.ikConstraintIndex = -1
 	self.type = TimelineType.ikConstraint
 	self.type = TimelineType.ikConstraint
 	
 	
@@ -1189,11 +1191,16 @@ function Animation.IkConstraintTimeline.new (frameCount)
 		return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
 		return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
 	end
 	end
 
 
-	function self:setFrame (frameIndex, time, mix, bendDirection, stretch)
+	function self:setFrame (frameIndex, time, mix, bendDirection, compress, stretch)
 		frameIndex = frameIndex * ENTRIES
 		frameIndex = frameIndex * ENTRIES
 		self.frames[frameIndex] = time
 		self.frames[frameIndex] = time
 		self.frames[frameIndex + MIX] = mix
 		self.frames[frameIndex + MIX] = mix
 		self.frames[frameIndex + BEND_DIRECTION] = bendDirection
 		self.frames[frameIndex + BEND_DIRECTION] = bendDirection
+		if (compress) then
+			self.frames[frameIndex + COMPRESS] = 1
+		else
+			self.frames[frameIndex + COMPRESS] = 0
+		end
 		if (stretch) then
 		if (stretch) then
 			self.frames[frameIndex + STRETCH] = 1
 			self.frames[frameIndex + STRETCH] = 1
 		else
 		else
@@ -1209,10 +1216,12 @@ function Animation.IkConstraintTimeline.new (frameCount)
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
 				constraint.mix = constraint.data.mix
 				constraint.mix = constraint.data.mix
 				constraint.bendDirection = constraint.data.bendDirection
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 				constraint.stretch = constraint.data.stretch
 			elseif blend == MixBlend.first then
 			elseif blend == MixBlend.first then
 				constraint.mix = constraint.mix + (constraint.data.mix - constraint.mix) * alpha
 				constraint.mix = constraint.mix + (constraint.data.mix - constraint.mix) * alpha
 				constraint.bendDirection = constraint.data.bendDirection
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 				constraint.stretch = constraint.data.stretch
 			end
 			end
 			return
 			return
@@ -1223,15 +1232,18 @@ function Animation.IkConstraintTimeline.new (frameCount)
 				constraint.mix = constraint.data.mix + (frames[zlen(frames) + PREV_MIX] - constraint.data.mix) * alpha
 				constraint.mix = constraint.data.mix + (frames[zlen(frames) + PREV_MIX] - constraint.data.mix) * alpha
 				if direction == MixDirection.out then 
 				if direction == MixDirection.out then 
 					constraint.bendDirection = constraint.data.bendDirection
 					constraint.bendDirection = constraint.data.bendDirection
+					constraint.compress = constraint.data.compress
 					constraint.stretch = constraint.data.stretch
 					constraint.stretch = constraint.data.stretch
 				else
 				else
 					constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION]);
 					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
 					if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 				end
 				end
 			else
 			else
 				constraint.mix = constraint.mix + (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
 				constraint.mix = constraint.mix + (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
 				if direction == MixDirection._in then 
 				if direction == MixDirection._in then 
 					constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION])
 					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
 					if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 				end
 				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
 			constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha
 			if direction == MixDirection.out then
 			if direction == MixDirection.out then
 				constraint.bendDirection = constraint.data.bendDirection
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 				constraint.stretch = constraint.data.stretch
 			else
 			else
 				constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
 				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
 				if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 			end
 			end
 		else
 		else
 			constraint.mix = constraint.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
 			constraint.mix = constraint.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
 			if direction == MixDirection._in then 
 			if direction == MixDirection._in then 
 				constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
 				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
 				if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 			end
 			end
 		end
 		end

+ 1 - 1
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
   if blend == MixBlend.setup then r1 = bone.data.rotation end
   local total = 0
   local total = 0
   local diff = r2 - r1
   local diff = r2 - r1
+	diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360
   if diff == 0 then
   if diff == 0 then
     total = timelinesRotation[i]
     total = timelinesRotation[i]
   else
   else
-    diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360
     local lastTotal = 0
     local lastTotal = 0
     local lastDiff = 0
     local lastDiff = 0
     if firstFrame then
     if firstFrame then

+ 12 - 5
spine-lua/IkConstraint.lua

@@ -52,6 +52,7 @@ function IkConstraint.new (data, skeleton)
 		bones = {},
 		bones = {},
 		target = nil,
 		target = nil,
 		mix = data.mix,
 		mix = data.mix,
+		compress = data.compress,
 		stretch = data.stretch,
 		stretch = data.stretch,
 		bendDirection = data.bendDirection,
 		bendDirection = data.bendDirection,
 	}
 	}
@@ -75,13 +76,13 @@ function IkConstraint:update ()
 	local bones = self.bones
 	local bones = self.bones
 	local boneCount = #bones
 	local boneCount = #bones
 	if boneCount == 1 then
 	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
 	elseif boneCount == 2 then
 		self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.mix)
 		self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.mix)
 	end
 	end
 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
 	if not bone.appliedValid then bone:updateAppliedTransform() end
 	local p = bone.parent
 	local p = bone.parent
 	local id = 1 / (p.a * p.d - p.b * p.c)
 	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
 		rotationIK = rotationIK + 360
 	end
 	end
 	local sx = bone.ascaleX
 	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)
 		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
 	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
 end
 
 
 function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, alpha)
 function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, alpha)

+ 2 - 0
spine-lua/IkConstraintData.lua

@@ -38,7 +38,9 @@ function IkConstraintData.new (name)
 		bones = {},
 		bones = {},
 		target = nil,
 		target = nil,
 		bendDirection = 1,
 		bendDirection = 1,
+		compress = false,
 		stretch = false,
 		stretch = false,
+		uniform = false,
 		mix = 1
 		mix = 1
 	}
 	}
 
 

+ 2 - 1
spine-lua/Skeleton.lua

@@ -338,9 +338,10 @@ function Skeleton:setBonesToSetupPose ()
 	end
 	end
 
 
 	for _,ikConstraint in ipairs(self.ikConstraints) do
 	for _,ikConstraint in ipairs(self.ikConstraints) do
+		ikConstraint.mix = ikConstraint.data.mix
 		ikConstraint.bendDirection = ikConstraint.data.bendDirection
 		ikConstraint.bendDirection = ikConstraint.data.bendDirection
+		ikConstraint.compress = ikConstraint.data.compress
 		ikConstraint.stretch = ikConstraint.data.stretch
 		ikConstraint.stretch = ikConstraint.data.stretch
-		ikConstraint.mix = ikConstraint.data.mix
 	end
 	end
 
 
 	local transformConstraints = self.transformConstraints
 	local transformConstraints = self.transformConstraints

+ 9 - 5
spine-lua/SkeletonJson.lua

@@ -164,9 +164,11 @@ function SkeletonJson.new (attachmentLoader)
 				data.target = skeletonData:findBone(targetName)
 				data.target = skeletonData:findBone(targetName)
 				if not data.target then error("Target bone not found: " .. targetName) end
 				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)
 				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)
 				table_insert(skeletonData.ikConstraints, data)
 			end
 			end
@@ -613,9 +615,11 @@ function SkeletonJson.new (attachmentLoader)
 					if valueMap["mix"] ~= nil then mix = valueMap["mix"] end
 					if valueMap["mix"] ~= nil then mix = valueMap["mix"] end
 					local bendPositive = 1
 					local bendPositive = 1
 					if valueMap["bendPositive"] == false then bendPositive = -1 end
 					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)
 					readCurve(valueMap, timeline, frameIndex)
 					frameIndex = frameIndex + 1
 					frameIndex = frameIndex + 1
 				end
 				end