Browse Source

Merge branch '3.8-beta' into skin-bones

badlogic 6 năm trước cách đây
mục cha
commit
e03a0ef659
43 tập tin đã thay đổi với 293 bổ sung167 xóa
  1. 1 0
      CHANGELOG.md
  2. BIN
      spine-as3/spine-as3-example/lib/spine-as3.swc
  3. 5 2
      spine-as3/spine-as3/src/spine/animation/AnimationState.as
  4. 4 1
      spine-c/spine-c/src/spine/AnimationState.c
  5. 4 1
      spine-cpp/spine-cpp/src/spine/AnimationState.cpp
  6. 4 1
      spine-csharp/src/AnimationState.cs
  7. 20 15
      spine-csharp/src/Atlas.cs
  8. 4 1
      spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java
  9. 54 54
      spine-lua/Animation.lua
  10. 57 10
      spine-lua/AnimationState.lua
  11. 1 1
      spine-lua/MeshAttachment.lua
  12. 2 2
      spine-lua/Slot.lua
  13. 1 1
      spine-lua/attachments/VertexAttachment.lua
  14. 18 0
      spine-lua/utils.lua
  15. BIN
      spine-starling/spine-starling-example/lib/spine-as3.swc
  16. BIN
      spine-starling/spine-starling/lib/spine-as3.swc
  17. 7 4
      spine-ts/build/spine-all.js
  18. 0 0
      spine-ts/build/spine-all.js.map
  19. 5 2
      spine-ts/build/spine-canvas.js
  20. 0 0
      spine-ts/build/spine-canvas.js.map
  21. 5 2
      spine-ts/build/spine-core.js
  22. 0 0
      spine-ts/build/spine-core.js.map
  23. 5 2
      spine-ts/build/spine-player.js
  24. 0 0
      spine-ts/build/spine-player.js.map
  25. 7 4
      spine-ts/build/spine-threejs.js
  26. 0 0
      spine-ts/build/spine-threejs.js.map
  27. 5 2
      spine-ts/build/spine-webgl.js
  28. 0 0
      spine-ts/build/spine-webgl.js.map
  29. 4 1
      spine-ts/core/src/AnimationState.ts
  30. 2 2
      spine-ts/threejs/src/MeshBatcher.ts
  31. 5 3
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs
  32. 6 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader
  33. 6 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader
  34. 6 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Special-Skeleton-Grayscale.shader
  35. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc
  36. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc
  37. 1 1
      spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader
  38. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader
  39. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader
  40. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader
  41. 6 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader
  42. 6 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader
  43. 7 5
      spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader

+ 1 - 0
CHANGELOG.md

@@ -36,6 +36,7 @@
 
 
 * **Breaking changes**
 * **Breaking changes**
   * **Removed PoseSkeleton() and PoseWithAnimation()** extension methods to prevent issues where animations are not mixed out. Problem was that these methods did not set AnimationState, leaving incorrect state at e.g. attachments enabled at slots when starting subsequent animations. As a replacement you can use `AnimationState.ClearTrack(0);` followed by `var entry = AnimationState.SetAnimation(0, animation, loop); entry.TrackTime = time` to achieve similar behaviour.
   * **Removed PoseSkeleton() and PoseWithAnimation()** extension methods to prevent issues where animations are not mixed out. Problem was that these methods did not set AnimationState, leaving incorrect state at e.g. attachments enabled at slots when starting subsequent animations. As a replacement you can use `AnimationState.ClearTrack(0);` followed by `var entry = AnimationState.SetAnimation(0, animation, loop); entry.TrackTime = time` to achieve similar behaviour.
+  * **The `Shadow alpha cutoff` shader parameter is now respecting slot-color alpha** values at all Spine shaders. A fragment's texture color alpha is multiplied with slot-color alpha before the result is tested against the `Shadow alpha cutoff` threshold.
 
 
 * **Additions**
 * **Additions**
   * **Spine Preferences stored in Assets/Editor/SpineSettings.asset** Now Spine uses the new `SettingsProvider` API, storing settings in a SpineSettings.asset file which can be shared with team members. Your old preferences are automatically migrated to the new system.
   * **Spine Preferences stored in Assets/Editor/SpineSettings.asset** Now Spine uses the new `SettingsProvider` API, storing settings in a SpineSettings.asset file which can be shared with team members. Your old preferences are automatically migrated to the new system.

BIN
spine-as3/spine-as3-example/lib/spine-as3.swc


+ 5 - 2
spine-as3/spine-as3/src/spine/animation/AnimationState.as

@@ -246,8 +246,11 @@ package spine.animation {
 					var timelineBlend: MixBlend;
 					var timelineBlend: MixBlend;
 					var alpha : Number = 0;
 					var alpha : Number = 0;
 					switch (timelineMode[i] & (NOT_LAST - 1)) {
 					switch (timelineMode[i] & (NOT_LAST - 1)) {
-					case SUBSEQUENT:
-						if (!attachments && timeline is AttachmentTimeline) continue;
+					case SUBSEQUENT:						
+						if (!attachments && timeline is AttachmentTimeline) {
+							if ((timelineMode[i] & NOT_LAST) == NOT_LAST) continue;
+							blend = MixBlend.setup;
+						}
 						if (!drawOrder && timeline is DrawOrderTimeline) continue;
 						if (!drawOrder && timeline is DrawOrderTimeline) continue;
 						timelineBlend = blend;
 						timelineBlend = blend;
 						alpha = alphaMix;
 						alpha = alphaMix;

+ 4 - 1
spine-c/spine-c/src/spine/AnimationState.c

@@ -468,7 +468,10 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
 
 
 			switch (timelineMode->items[i] & (NOT_LAST - 1)) {
 			switch (timelineMode->items[i] & (NOT_LAST - 1)) {
 				case SUBSEQUENT:
 				case SUBSEQUENT:
-					if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) continue;
+					if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) {
+						if ((timelineMode->items[i] & NOT_LAST) == NOT_LAST) continue;
+						blend = SP_MIX_BLEND_SETUP;
+					}
 					if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
 					if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
 					timelineBlend = blend;
 					timelineBlend = blend;
 					alpha = alphaMix;
 					alpha = alphaMix;

+ 4 - 1
spine-cpp/spine-cpp/src/spine/AnimationState.cpp

@@ -814,7 +814,10 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
 			float alpha;
 			float alpha;
 			switch (timelineMode[i] & (NotLast - 1)) {
 			switch (timelineMode[i] & (NotLast - 1)) {
 				case Subsequent:
 				case Subsequent:
-					if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) continue;
+					if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) {
+						if ((timelineMode[i] & NotLast) == NotLast) continue;
+						blend = MixBlend_Setup;
+					}
 					if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue;
 					if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue;
 					timelineBlend = blend;
 					timelineBlend = blend;
 					alpha = alphaMix;
 					alpha = alphaMix;

+ 4 - 1
spine-csharp/src/AnimationState.cs

@@ -299,7 +299,10 @@ namespace Spine {
 					float alpha;
 					float alpha;
 					switch (timelineMode[i] & AnimationState.NotLast - 1) {
 					switch (timelineMode[i] & AnimationState.NotLast - 1) {
 						case AnimationState.Subsequent:
 						case AnimationState.Subsequent:
-							if (!attachments && timeline is AttachmentTimeline) continue;
+							if (!attachments && timeline is AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NotLast) == AnimationState.NotLast) continue;
+								blend = MixBlend.Setup;
+							}
 							if (!drawOrder && timeline is DrawOrderTimeline) continue;
 							if (!drawOrder && timeline is DrawOrderTimeline) continue;
 							timelineBlend = blend;
 							timelineBlend = blend;
 							alpha = alphaMix;
 							alpha = alphaMix;

+ 20 - 15
spine-csharp/src/Atlas.cs

@@ -33,6 +33,7 @@
 
 
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Reflection;
 using System.Reflection;
 
 
@@ -123,8 +124,8 @@ namespace Spine {
 					page.name = line;
 					page.name = line;
 
 
 					if (ReadTuple(reader, tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
 					if (ReadTuple(reader, tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
-						page.width = int.Parse(tuple[0]);
-						page.height = int.Parse(tuple[1]);
+						page.width = int.Parse(tuple[0], CultureInfo.InvariantCulture);
+						page.height = int.Parse(tuple[1], CultureInfo.InvariantCulture);
 						ReadTuple(reader, tuple);
 						ReadTuple(reader, tuple);
 					}
 					}
 					page.format = (Format)Enum.Parse(typeof(Format), tuple[0], false);
 					page.format = (Format)Enum.Parse(typeof(Format), tuple[0], false);
@@ -162,12 +163,12 @@ namespace Spine {
 					region.rotate = region.degrees == 90;
 					region.rotate = region.degrees == 90;
 
 
 					ReadTuple(reader, tuple);
 					ReadTuple(reader, tuple);
-					int x = int.Parse(tuple[0]);
-					int y = int.Parse(tuple[1]);
+					int x = int.Parse(tuple[0], CultureInfo.InvariantCulture);
+					int y = int.Parse(tuple[1], CultureInfo.InvariantCulture);
 
 
 					ReadTuple(reader, tuple);
 					ReadTuple(reader, tuple);
-					int width = int.Parse(tuple[0]);
-					int height = int.Parse(tuple[1]);
+					int width = int.Parse(tuple[0], CultureInfo.InvariantCulture);
+					int height = int.Parse(tuple[1], CultureInfo.InvariantCulture);
 
 
 					region.u = x / (float)page.width;
 					region.u = x / (float)page.width;
 					region.v = y / (float)page.height;
 					region.v = y / (float)page.height;
@@ -184,25 +185,29 @@ namespace Spine {
 					region.height = Math.Abs(height);
 					region.height = Math.Abs(height);
 
 
 					if (ReadTuple(reader, tuple) == 4) { // split is optional
 					if (ReadTuple(reader, tuple) == 4) { // split is optional
-						region.splits = new [] {int.Parse(tuple[0]), int.Parse(tuple[1]),
-								int.Parse(tuple[2]), int.Parse(tuple[3])};
+						region.splits = new [] {int.Parse(tuple[0], CultureInfo.InvariantCulture),
+												int.Parse(tuple[1], CultureInfo.InvariantCulture),
+												int.Parse(tuple[2], CultureInfo.InvariantCulture),
+												int.Parse(tuple[3], CultureInfo.InvariantCulture)};
 
 
 						if (ReadTuple(reader, tuple) == 4) { // pad is optional, but only present with splits
 						if (ReadTuple(reader, tuple) == 4) { // pad is optional, but only present with splits
-							region.pads = new [] {int.Parse(tuple[0]), int.Parse(tuple[1]),
-									int.Parse(tuple[2]), int.Parse(tuple[3])};
+							region.pads = new [] {int.Parse(tuple[0], CultureInfo.InvariantCulture),
+												int.Parse(tuple[1], CultureInfo.InvariantCulture),
+												int.Parse(tuple[2], CultureInfo.InvariantCulture),
+												int.Parse(tuple[3], CultureInfo.InvariantCulture)};
 
 
 							ReadTuple(reader, tuple);
 							ReadTuple(reader, tuple);
 						}
 						}
 					}
 					}
 
 
-					region.originalWidth = int.Parse(tuple[0]);
-					region.originalHeight = int.Parse(tuple[1]);
+					region.originalWidth = int.Parse(tuple[0], CultureInfo.InvariantCulture);
+					region.originalHeight = int.Parse(tuple[1], CultureInfo.InvariantCulture);
 
 
 					ReadTuple(reader, tuple);
 					ReadTuple(reader, tuple);
-					region.offsetX = int.Parse(tuple[0]);
-					region.offsetY = int.Parse(tuple[1]);
+					region.offsetX = int.Parse(tuple[0], CultureInfo.InvariantCulture);
+					region.offsetY = int.Parse(tuple[1], CultureInfo.InvariantCulture);
 
 
-					region.index = int.Parse(ReadValue(reader));
+					region.index = int.Parse(ReadValue(reader), CultureInfo.InvariantCulture);
 
 
 					regions.Add(region);
 					regions.Add(region);
 				}
 				}

+ 4 - 1
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -293,7 +293,10 @@ public class AnimationState {
 				float alpha;
 				float alpha;
 				switch (timelineMode[i] & NOT_LAST - 1) {
 				switch (timelineMode[i] & NOT_LAST - 1) {
 				case SUBSEQUENT:
 				case SUBSEQUENT:
-					if (!attachments && timeline instanceof AttachmentTimeline) continue;
+					if (!attachments && timeline instanceof AttachmentTimeline) {
+						if ((timelineMode[i] & NOT_LAST) == NOT_LAST) continue;
+						blend = MixBlend.setup;
+					}
 					if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
 					if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
 					timelineBlend = blend;
 					timelineBlend = blend;
 					alpha = alphaMix;
 					alpha = alphaMix;

+ 54 - 54
spine-lua/Animation.lua

@@ -278,7 +278,7 @@ function Animation.RotateTimeline.new (frameCount)
 				r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 -- Wrap within -180 and 180.
 				r = r - (16384 - math_floor(16384.499999999996 - r / 360)) * 360 -- Wrap within -180 and 180.
 				bone.rotation = bone.rotation + r * alpha;
 				bone.rotation = bone.rotation + r * alpha;
 			elseif blend == MixBlend.add then
 			elseif blend == MixBlend.add then
-				bone.rotation = bone.rotation + r * alpha;				
+				bone.rotation = bone.rotation + r * alpha;
 			end
 			end
 			return;
 			return;
 		end
 		end
@@ -318,7 +318,7 @@ function Animation.TranslateTimeline.new (frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.boneIndex = -1
 	self.boneIndex = -1
 	self.type = TimelineType.translate
 	self.type = TimelineType.translate
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.translate * SHL_24 + self.boneIndex
 		return TimelineType.translate * SHL_24 + self.boneIndex
 	end
 	end
@@ -334,7 +334,7 @@ function Animation.TranslateTimeline.new (frameCount)
 		local frames = self.frames
 		local frames = self.frames
 
 
 		local bone = skeleton.bones[self.boneIndex]
 		local bone = skeleton.bones[self.boneIndex]
-		if time < frames[0] then 
+		if time < frames[0] then
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
 				bone.x = bone.data.x
 				bone.x = bone.data.x
 				bone.y = bone.data.y
 				bone.y = bone.data.y
@@ -389,7 +389,7 @@ function Animation.ScaleTimeline.new (frameCount)
 
 
 	local self = Animation.TranslateTimeline.new(frameCount)
 	local self = Animation.TranslateTimeline.new(frameCount)
 	self.type = TimelineType.scale
 	self.type = TimelineType.scale
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.scale * SHL_24 + self.boneIndex
 		return TimelineType.scale * SHL_24 + self.boneIndex
 	end
 	end
@@ -437,7 +437,7 @@ function Animation.ScaleTimeline.new (frameCount)
 		else
 		else
 			local bx = 0
 			local bx = 0
 			local by = 0
 			local by = 0
-			if direction == MixDirection.out then 
+			if direction == MixDirection.out then
 				if blend == MixBlend.setup then
 				if blend == MixBlend.setup then
 					bx = bone.data.scaleX
 					bx = bone.data.scaleX
 					by = bone.data.scaleY
 					by = bone.data.scaleY
@@ -490,7 +490,7 @@ function Animation.ShearTimeline.new (frameCount)
 
 
 	local self = Animation.TranslateTimeline.new(frameCount)
 	local self = Animation.TranslateTimeline.new(frameCount)
 	self.type = TimelineType.shear
 	self.type = TimelineType.shear
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.shear * SHL_24 + self.boneIndex
 		return TimelineType.shear * SHL_24 + self.boneIndex
 	end
 	end
@@ -560,7 +560,7 @@ function Animation.ColorTimeline.new (frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.slotIndex = -1
 	self.slotIndex = -1
 	self.type = TimelineType.color
 	self.type = TimelineType.color
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.color * SHL_24 + self.slotIndex
 		return TimelineType.color * SHL_24 + self.slotIndex
 	end
 	end
@@ -577,7 +577,7 @@ function Animation.ColorTimeline.new (frameCount)
 	function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
 	function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
 		local frames = self.frames
 		local frames = self.frames
 		local slot = skeleton.slots[self.slotIndex]
 		local slot = skeleton.slots[self.slotIndex]
-		if time < frames[0] then 
+		if time < frames[0] then
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
 				slot.color:setFrom(slot.data.color)
 				slot.color:setFrom(slot.data.color)
 			elseif blend == MixBlend.first then
 			elseif blend == MixBlend.first then
@@ -648,7 +648,7 @@ function Animation.TwoColorTimeline.new (frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.slotIndex = -1
 	self.slotIndex = -1
 	self.type = TimelineType.twoColor
 	self.type = TimelineType.twoColor
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.twoColor * SHL_24 + self.slotIndex
 		return TimelineType.twoColor * SHL_24 + self.slotIndex
 	end
 	end
@@ -668,7 +668,7 @@ function Animation.TwoColorTimeline.new (frameCount)
 	function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
 	function self:apply (skeleton, lastTime, time, firedEvents, alpha, blend, direction)
 		local frames = self.frames
 		local frames = self.frames
 		local slot = skeleton.slots[self.slotIndex]
 		local slot = skeleton.slots[self.slotIndex]
-		if time < frames[0] then 
+		if time < frames[0] then
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
 				slot.color:setFrom(slot.data.color)
 				slot.color:setFrom(slot.data.color)
 				slot.darkColor:setFrom(slot.data.darkColor)
 				slot.darkColor:setFrom(slot.data.darkColor)
@@ -722,7 +722,7 @@ function Animation.TwoColorTimeline.new (frameCount)
 		else
 		else
 			local light = slot.color
 			local light = slot.color
 			local dark = slot.darkColor
 			local dark = slot.darkColor
-			if blend == MixBlend.setup then 
+			if blend == MixBlend.setup then
 				light:setFrom(slot.data.color)
 				light:setFrom(slot.data.color)
 				dark:setFrom(slot.data.darkColor)
 				dark:setFrom(slot.data.darkColor)
 			end
 			end
@@ -751,7 +751,7 @@ function Animation.AttachmentTimeline.new (frameCount)
 		self.frames[frameIndex] = time
 		self.frames[frameIndex] = time
 		self.attachmentNames[frameIndex] = attachmentName
 		self.attachmentNames[frameIndex] = attachmentName
 	end
 	end
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.attachment * SHL_24 + self.slotIndex
 		return TimelineType.attachment * SHL_24 + self.slotIndex
 	end
 	end
@@ -768,9 +768,9 @@ function Animation.AttachmentTimeline.new (frameCount)
 			end
 			end
 			return;
 			return;
 		end
 		end
-		
+
 		local frames = self.frames
 		local frames = self.frames
-		if time < frames[0] then 
+		if time < frames[0] then
 			if blend == MixBlend.setup or blend == MixBlend.first then
 			if blend == MixBlend.setup or blend == MixBlend.first then
 				attachmentName = slot.data.attachmentName
 				attachmentName = slot.data.attachmentName
 				if not attachmentName then
 				if not attachmentName then
@@ -826,36 +826,36 @@ function Animation.DeformTimeline.new (frameCount)
 		if not slotAttachment:applyDeform(self.attachment) then return end
 		if not slotAttachment:applyDeform(self.attachment) then return end
 
 
 		local frames = self.frames
 		local frames = self.frames
-		local verticesArray = slot.attachmentVertices
-    if #(verticesArray) == 0 then blend = MixBlend.setup end
+		local deformArray = slot.deform
+    if #(deformArray) == 0 then blend = MixBlend.setup end
 
 
 		local frameVertices = self.frameVertices
 		local frameVertices = self.frameVertices
-		local vertexCount = #(frameVertices[0])		
-		
+		local vertexCount = #(frameVertices[0])
+
 		if time < frames[0] then
 		if time < frames[0] then
 			local vertexAttachment = slotAttachment;
 			local vertexAttachment = slotAttachment;
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
-        slot.attachmentVertices = {}
+        slot.deform = {}
         return;
         return;
 			elseif blend == MixBlend.first then
 			elseif blend == MixBlend.first then
         if (alpha == 1) then
         if (alpha == 1) then
-          slot.attachmentVertices = {}
+          slot.deform = {}
           return;
           return;
         end
         end
 
 
-        local vertices = utils.setArraySize(verticesArray, vertexCount)
+        local deform = utils.setArraySize(deformArray, vertexCount)
         if (vertexAttachment.bones == nil) then
         if (vertexAttachment.bones == nil) then
           local setupVertices = vertexAttachment.vertices
           local setupVertices = vertexAttachment.vertices
           local i = 1
           local i = 1
           while i <= vertexCount do
           while i <= vertexCount do
-            vertices[i] = vertices[i] + (setupVertices[i] - vertices[i]) * alpha
+            deform[i] = deform[i] + (setupVertices[i] - deform[i]) * alpha
             i = i + 1
             i = i + 1
           end
           end
         else
         else
           alpha = 1 - alpha
           alpha = 1 - alpha
           local i = 1
           local i = 1
           while i <= vertexCount do
           while i <= vertexCount do
-            vertices[i] = vertices[i] * alpha
+            deform[i] = deform[i] * alpha
             i = i + 1
             i = i + 1
           end
           end
         end
         end
@@ -863,7 +863,7 @@ function Animation.DeformTimeline.new (frameCount)
 			return
 			return
 		end
 		end
 
 
-    local vertices = utils.setArraySize(verticesArray, vertexCount)
+    local deform = utils.setArraySize(deformArray, vertexCount)
 		if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
 		if time >= frames[zlen(frames) - 1] then -- Time is after last frame.
 			local lastVertices = frameVertices[zlen(frames) - 1]
 			local lastVertices = frameVertices[zlen(frames) - 1]
 			if alpha == 1 then
 			if alpha == 1 then
@@ -874,21 +874,21 @@ function Animation.DeformTimeline.new (frameCount)
 						local setupVertices = vertexAttachment.vertices
 						local setupVertices = vertexAttachment.vertices
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + lastVertices[i] - setupVertices[i]
+							deform[i] = deform[i] + lastVertices[i] - setupVertices[i]
 							i = i + 1
 							i = i + 1
 						end
 						end
 					else
 					else
 						-- Weighted deform offsets, with alpha.
 						-- Weighted deform offsets, with alpha.
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + lastVertices[i]
+							deform[i] = deform[i] + lastVertices[i]
 							i = i + 1
 							i = i + 1
 						end
 						end
 					end
 					end
 				else
 				else
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
-						vertices[i] = lastVertices[i]
+						deform[i] = lastVertices[i]
 						i = i + 1
 						i = i + 1
 					end
 					end
 				end
 				end
@@ -901,21 +901,21 @@ function Animation.DeformTimeline.new (frameCount)
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
 							local setup = setupVertices[i]
 							local setup = setupVertices[i]
-							vertices[i] = setup + (lastVertices[i] - setup) * alpha
+							deform[i] = setup + (lastVertices[i] - setup) * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					else
 					else
 						-- Weighted deform offsets, with alpha.
 						-- Weighted deform offsets, with alpha.
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = lastVertices[i] * alpha
+							deform[i] = lastVertices[i] * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					end
 					end
 				elseif blend == MixBlend.first or blend == MixBlend.replace then
 				elseif blend == MixBlend.first or blend == MixBlend.replace then
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
-						vertices[i] = vertices[i] + (lastVertices[i] - vertices[i]) * alpha
+						deform[i] = deform[i] + (lastVertices[i] - deform[i]) * alpha
 						i = i + 1
 						i = i + 1
 					end
 					end
 					local vertexAttachment = slotAttachment
 					local vertexAttachment = slotAttachment
@@ -923,14 +923,14 @@ function Animation.DeformTimeline.new (frameCount)
 						local setupVertices = vertexAttachment.vertices
 						local setupVertices = vertexAttachment.vertices
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
+							deform[i] = deform[i] + (lastVertices[i] - setupVertices[i]) * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					else
 					else
 						-- Weighted deform offsets, with alpha.
 						-- Weighted deform offsets, with alpha.
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + lastVertices[i] * alpha
+							deform[i] = deform[i] + lastVertices[i] * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					end
 					end
@@ -940,14 +940,14 @@ function Animation.DeformTimeline.new (frameCount)
 						local setupVertices = vertexAttachment.vertices
 						local setupVertices = vertexAttachment.vertices
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + (lastVertices[i] - setupVertices[i]) * alpha
+							deform[i] = deform[i] + (lastVertices[i] - setupVertices[i]) * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					else
 					else
 						-- Weighted deform offsets, with alpha.
 						-- Weighted deform offsets, with alpha.
 						local i = 1
 						local i = 1
 						while i <= vertexCount do
 						while i <= vertexCount do
-							vertices[i] = vertices[i] + lastVertices[i] * alpha
+							deform[i] = deform[i] + lastVertices[i] * alpha
 							i = i + 1
 							i = i + 1
 						end
 						end
 					end
 					end
@@ -972,7 +972,7 @@ function Animation.DeformTimeline.new (frameCount)
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
-						vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * precent - setupVertices[i]
+						deform[i] = deform[i] + prev + (nextVertices[i] - prev) * precent - setupVertices[i]
 						i = i + 1
 						i = i + 1
 					end
 					end
 				else
 				else
@@ -980,7 +980,7 @@ function Animation.DeformTimeline.new (frameCount)
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
-						vertices[i] = vertices[i] + prev + (nextVertices[i] - prev) * percent
+						deform[i] = deform[i] + prev + (nextVertices[i] - prev) * percent
 						i = i + 1
 						i = i + 1
 					end
 					end
 				end
 				end
@@ -988,7 +988,7 @@ function Animation.DeformTimeline.new (frameCount)
 				local i = 1
 				local i = 1
 				while i <= vertexCount do
 				while i <= vertexCount do
 					local prev = prevVertices[i]
 					local prev = prevVertices[i]
-					vertices[i] = prev + (nextVertices[i] - prev) * percent
+					deform[i] = prev + (nextVertices[i] - prev) * percent
 					i = i + 1
 					i = i + 1
 				end
 				end
 			end
 			end
@@ -1002,7 +1002,7 @@ function Animation.DeformTimeline.new (frameCount)
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
 						local setup = setupVertices[i]
 						local setup = setupVertices[i]
-						vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha
+						deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha
 						i = i + 1
 						i = i + 1
 					end
 					end
 				else
 				else
@@ -1010,7 +1010,7 @@ function Animation.DeformTimeline.new (frameCount)
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
-						vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha
+						deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha
 						i = i + 1
 						i = i + 1
 					end
 					end
 				end
 				end
@@ -1018,7 +1018,7 @@ function Animation.DeformTimeline.new (frameCount)
 				local i = 1
 				local i = 1
 				while i <= vertexCount do
 				while i <= vertexCount do
 					local prev = prevVertices[i]
 					local prev = prevVertices[i]
-					vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha
+					deform[i] = deform[i] + (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha
 					i = i + 1
 					i = i + 1
 				end
 				end
 			elseif blend == MixBlend.add then
 			elseif blend == MixBlend.add then
@@ -1028,7 +1028,7 @@ function Animation.DeformTimeline.new (frameCount)
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
-						vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha
+						deform[i] = deform[i] + (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha
 						i = i + 1
 						i = i + 1
 					end
 					end
 				else
 				else
@@ -1036,7 +1036,7 @@ function Animation.DeformTimeline.new (frameCount)
 					local i = 1
 					local i = 1
 					while i <= vertexCount do
 					while i <= vertexCount do
 						local prev = prevVertices[i]
 						local prev = prevVertices[i]
-						vertices[i] = vertices[i] + (prev + (nextVertices[i] - prev) * percent) * alpha
+						deform[i] = deform[i] + (prev + (nextVertices[i] - prev) * percent) * alpha
 						i = i + 1
 						i = i + 1
 					end
 					end
 				end
 				end
@@ -1054,7 +1054,7 @@ function Animation.EventTimeline.new (frameCount)
 		events = {},
 		events = {},
 		type = TimelineType.event
 		type = TimelineType.event
 	}
 	}
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.event * SHL_24
 		return TimelineType.event * SHL_24
 	end
 	end
@@ -1111,7 +1111,7 @@ function Animation.DrawOrderTimeline.new (frameCount)
 		drawOrders = {},
 		drawOrders = {},
 		type = TimelineType.drawOrder
 		type = TimelineType.drawOrder
 	}
 	}
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.drawOrder * SHL_24
 		return TimelineType.drawOrder * SHL_24
 	end
 	end
@@ -1134,9 +1134,9 @@ function Animation.DrawOrderTimeline.new (frameCount)
 			end
 			end
 			return;
 			return;
 		end
 		end
-		
+
 		local frames = self.frames
 		local frames = self.frames
-		if time < frames[0] then 
+		if time < frames[0] then
 			if blend == MixBlend.setup or blend == MixBlend.first then
 			if blend == MixBlend.setup or blend == MixBlend.first then
 				for i,slot in ipairs(slots) do
 				for i,slot in ipairs(slots) do
 					drawOrder[i] = slots[i]
 					drawOrder[i] = slots[i]
@@ -1179,13 +1179,13 @@ function Animation.IkConstraintTimeline.new (frameCount)
 	local MIX = 1
 	local MIX = 1
 	local BEND_DIRECTION = 2
 	local BEND_DIRECTION = 2
 	local COMPRESS = 3
 	local COMPRESS = 3
-	local STRETCH = 1
+	local STRETCH = 4
 
 
 	local self = Animation.CurveTimeline.new(frameCount)
 	local self = Animation.CurveTimeline.new(frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, compress, stretch, ...
 	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
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
 		return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
 	end
 	end
@@ -1229,7 +1229,7 @@ function Animation.IkConstraintTimeline.new (frameCount)
 		if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
 		if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
 				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.compress = constraint.data.compress
 					constraint.stretch = constraint.data.stretch
 					constraint.stretch = constraint.data.stretch
@@ -1240,7 +1240,7 @@ function Animation.IkConstraintTimeline.new (frameCount)
 				end
 				end
 			else
 			else
 				constraint.mix = constraint.mix + (frames[zlen(frames) + PREV_MIX] - constraint.mix) * alpha;
 				constraint.mix = constraint.mix + (frames[zlen(frames) + 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_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
 					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
@@ -1269,7 +1269,7 @@ function Animation.IkConstraintTimeline.new (frameCount)
 			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_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
@@ -1298,7 +1298,7 @@ function Animation.TransformConstraintTimeline.new (frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.transformConstraintIndex = -1
 	self.transformConstraintIndex = -1
 	self.type = TimelineType.transformConstraint
 	self.type = TimelineType.transformConstraint
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.transformConstraint * SHL_24 + self.transformConstraintIndex
 		return TimelineType.transformConstraint * SHL_24 + self.transformConstraintIndex
 	end
 	end
@@ -1404,7 +1404,7 @@ function Animation.PathConstraintPositionTimeline.new (frameCount)
 		local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
 		local constraint = skeleton.pathConstraints[self.pathConstraintIndex]
 		if (time < frames[0]) then
 		if (time < frames[0]) then
 			if blend == MixBlend.setup then
 			if blend == MixBlend.setup then
-				constraint.position = constraint.data.position	
+				constraint.position = constraint.data.position
 			elseif blend == MixBlend.first then
 			elseif blend == MixBlend.first then
 				constraint.position = constraint.position + (constraint.data.position - constraint.position) * alpha
 				constraint.position = constraint.position + (constraint.data.position - constraint.position) * alpha
 			end
 			end
@@ -1508,7 +1508,7 @@ function Animation.PathConstraintMixTimeline.new (frameCount)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES)
 	self.pathConstraintIndex = -1
 	self.pathConstraintIndex = -1
 	self.type = TimelineType.pathConstraintMix
 	self.type = TimelineType.pathConstraintMix
-	
+
 	function self:getPropertyId ()
 	function self:getPropertyId ()
 		return TimelineType.pathConstraintMix * SHL_24 + self.pathConstraintIndex
 		return TimelineType.pathConstraintMix * SHL_24 + self.pathConstraintIndex
 	end
 	end

+ 57 - 10
spine-lua/AnimationState.lua

@@ -41,6 +41,9 @@ local math_signum = utils.signum
 local math_floor = math.floor
 local math_floor = math.floor
 local math_ceil = math.ceil
 local math_ceil = math.ceil
 local math_mod = utils.mod
 local math_mod = utils.mod
+local testBit = utils.testBit
+local setBit = utils.setBit
+local clearBit = utils.clearBit
 
 
 local function zlen(array)
 local function zlen(array)
 	return #array + 1
 	return #array + 1
@@ -50,7 +53,8 @@ local EMPTY_ANIMATION = Animation.new("<empty>", {}, 0)
 local SUBSEQUENT = 0
 local SUBSEQUENT = 0
 local FIRST = 1
 local FIRST = 1
 local HOLD = 2
 local HOLD = 2
-local HOLD_MIX = 3;
+local HOLD_MIX = 3
+local NOT_LAST = 4
 
 
 local EventType = {
 local EventType = {
 	start = 0,
 	start = 0,
@@ -357,7 +361,7 @@ function AnimationState:apply (skeleton)
 
 
 				for ii,timeline in ipairs(timelines) do
 				for ii,timeline in ipairs(timelines) do
 					local timelineBlend = MixBlend.setup
 					local timelineBlend = MixBlend.setup
-					if timelineMode[ii] == SUBSEQUENT then timelineBlend = blend end
+					if clearBit(timelineMode[ii], NOT_LAST) == SUBSEQUENT then timelineBlend = blend end
 
 
 					if timeline.type == Animation.TimelineType.rotate then
 					if timeline.type == Animation.TimelineType.rotate then
 						self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2,
 						self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii * 2,
@@ -421,15 +425,21 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
       local direction = MixDirection.out;
       local direction = MixDirection.out;
 			local timelineBlend = MixBlend.setup
 			local timelineBlend = MixBlend.setup
 			local alpha = 0
 			local alpha = 0
-			if timelineMode[i] == SUBSEQUENT then
-				if not attachments and timeline.type == Animation.TimelineType.attachment then skipSubsequent = true end
+			if clearBit(timelineMode[i], NOT_LAST) == SUBSEQUENT then
+				if not attachments and timeline.type == Animation.TimelineType.attachment then
+					if testBit(timelineMode[i], NOT_LAST) then 
+						skipSubsequent = true
+					else
+						blend = MixBlend.setup
+					end
+				end
 				if not drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end
 				if not drawOrder and timeline.type == Animation.TimelineType.drawOrder then skipSubsequent = true end
 				timelineBlend = blend
 				timelineBlend = blend
 				alpha = alphaMix
 				alpha = alphaMix
-			elseif timelineMode[i] == FIRST then
+			elseif clearBit(timelineMode[i], NOT_LAST) == FIRST then
 				timelineBlend = MixBlend.setup
 				timelineBlend = MixBlend.setup
 				alpha = alphaMix
 				alpha = alphaMix
-			elseif timelineMode[i] == HOLD then
+			elseif clearBit(timelineMode[i], NOT_LAST) == HOLD then
 				timelineBlend = MixBlend.setup
 				timelineBlend = MixBlend.setup
 				alpha = alphaHold
 				alpha = alphaHold
 			else
 			else
@@ -445,7 +455,7 @@ function AnimationState:applyMixingFrom (to, skeleton, blend)
 				else
 				else
           if timelineBlend == MixBlend.setup then
           if timelineBlend == MixBlend.setup then
             if timeline.type == Animation.TimelineType.attachment then
             if timeline.type == Animation.TimelineType.attachment then
-              if attachments then direction = MixDirection._in end
+              if attachments or testBit(timelineMode[i], NOT_LAST) then direction = MixDirection._in end
             elseif timeline.type == Animation.TimelineType.drawOrder then
             elseif timeline.type == Animation.TimelineType.drawOrder then
               if drawOrder then direction = MixDirection._in end
               if drawOrder then direction = MixDirection._in end
             end
             end
@@ -803,7 +813,10 @@ function AnimationState:_animationsChanged ()
 
 
 	self.propertyIDs = {}
 	self.propertyIDs = {}
 
 
+	local highestIndex = -1
 	for i, entry in pairs(self.tracks) do
 	for i, entry in pairs(self.tracks) do
+		if i > highestIndex then highestIndex = i end
+
 		if entry then
 		if entry then
 			while entry.mixingFrom do
 			while entry.mixingFrom do
 				entry = entry.mixingFrom
 				entry = entry.mixingFrom
@@ -811,15 +824,45 @@ function AnimationState:_animationsChanged ()
 
 
 			repeat
 			repeat
 				if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
 				if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
-					self:setTimelineModes(entry)
+					self:computeHold(entry)
 				end
 				end
 				entry = entry.mixingTo
 				entry = entry.mixingTo
 			until (entry == nil)
 			until (entry == nil)
 		end
 		end
 	end
 	end
+
+	self.propertyIDs = {}
+	for i = highestIndex, 0, -1 do
+		entry = self.tracks[i]
+		while entry do
+			self:computeNotLast(entry)
+			entry = entry.mixingFrom
+		end
+	end
+end
+
+function AnimationState:computeNotLast(entry)
+	local timelines = entry.animation.timelines
+	local timelinesCount = #entry.animation.timelines
+	local timelineMode = entry.timelineMode
+	local propertyIDs = self.propertyIDs
+ 
+	local i = 1
+	while i <= timelinesCount do
+		local timeline = timelines[i]
+		if (timeline.type == Animation.TimelineType.attachment) then
+			local slotIndex = timeline.slotIndex
+			if not (propertyIDs[slotIndex] == nil) then
+				timelineMode[i] = setBit(timelineMode[i], NOT_LAST)
+			else
+				propertyIDs[slotIndex] = true
+			end
+		end
+		i = i + 1
+	end
 end
 end
 
 
-function AnimationState:setTimelineModes(entry)
+function AnimationState:computeHold(entry)
 	local to = entry.mixingTo
 	local to = entry.mixingTo
 	local timelines = entry.animation.timelines
 	local timelines = entry.animation.timelines
 	local timelinesCount = #entry.animation.timelines
 	local timelinesCount = #entry.animation.timelines
@@ -847,7 +890,11 @@ function AnimationState:setTimelineModes(entry)
 			timelineMode[i] = SUBSEQUENT
 			timelineMode[i] = SUBSEQUENT
 		else
 		else
 			propertyIDs[id] = id
 			propertyIDs[id] = id
-			if to == nil or not self:hasTimeline(to, id) then
+			local timeline = timelines[i]
+			if to == nil or timeline.type == Animation.TimelineType.attachment 
+				or timeline.type == Animation.TimelineType.drawOrder 
+				or timeline.type == Animation.TimelineType.event 
+				or not self:hasTimeline(to, id) then
 				timelineMode[i] = FIRST
 				timelineMode[i] = FIRST
 			else
 			else
 				local next = to.mixingTo
 				local next = to.mixingTo

+ 1 - 1
spine-lua/MeshAttachment.lua

@@ -79,7 +79,7 @@ x,y=slot.bone.skeleton.x,slot.bone.skeleton.y
 		local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
 		local m00, m01, m10, m11 = bone.m00, bone.m01, bone.m10, bone.m11
 		local vertices = self.vertices
 		local vertices = self.vertices
 		local verticesCount = #vertices
 		local verticesCount = #vertices
-		if slot.attachmentVertices and #slot.attachmentVertices == verticesCount then vertices = slot.attachmentVertices end
+		if slot.deform and #slot.deform == verticesCount then vertices = slot.deform end
 		for i = 1, verticesCount, 2 do
 		for i = 1, verticesCount, 2 do
 			local vx = vertices[i]
 			local vx = vertices[i]
 			local vy = vertices[i + 1]
 			local vy = vertices[i + 1]

+ 2 - 2
spine-lua/Slot.lua

@@ -45,7 +45,7 @@ function Slot.new (data, bone)
 		darkColor = nil,
 		darkColor = nil,
 		attachment = nil,
 		attachment = nil,
 		attachmentTime = 0,
 		attachmentTime = 0,
-		attachmentVertices = {}
+		deform = {}
 	}	
 	}	
 
 
 	setmetatable(self, Slot)
 	setmetatable(self, Slot)
@@ -61,7 +61,7 @@ function Slot:setAttachment (attachment)
 	if self.attachment == attachment then return end
 	if self.attachment == attachment then return end
 	self.attachment = attachment
 	self.attachment = attachment
 	self.attachmentTime = self.bone.skeleton.time
 	self.attachmentTime = self.bone.skeleton.time
-	self.attachmentVertices = {}
+	self.deform = {}
 end
 end
 
 
 function Slot:setAttachmentTime (time)
 function Slot:setAttachmentTime (time)

+ 1 - 1
spine-lua/attachments/VertexAttachment.lua

@@ -60,7 +60,7 @@ end
 function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
 function VertexAttachment:computeWorldVertices (slot, start, count, worldVertices, offset, stride)
 	count = offset + (count / 2) * stride
 	count = offset + (count / 2) * stride
 	local skeleton = slot.bone.skeleton
 	local skeleton = slot.bone.skeleton
-	local deformArray = slot.attachmentVertices
+	local deformArray = slot.deform
 	local vertices = self.vertices
 	local vertices = self.vertices
 	local bones = self.bones
 	local bones = self.bones
 	if not bones then
 	if not bones then

+ 18 - 0
spine-lua/utils.lua

@@ -166,4 +166,22 @@ function utils.randomTriangularWith(min, max, mode)
 	return max - math_sqrt((1 - u) * d * (max - mode))
 	return max - math_sqrt((1 - u) * d * (max - mode))
 end
 end
 
 
+function utils.testBit(value, bit)
+  return value % (2 * bit) >= bit
+end
+
+function utils.setBit(value, bit)
+  if value % (2 * bit) >= bit then
+    return value
+  end
+  return value + bit
+end
+
+function utils.clearBit(value, bit)
+  if value % (2 * bit) >= bit then
+    return value - bit
+  end
+  return value
+end
+
 return utils
 return utils

BIN
spine-starling/spine-starling-example/lib/spine-as3.swc


BIN
spine-starling/spine-starling/lib/spine-as3.swc


+ 7 - 4
spine-ts/build/spine-all.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;
@@ -10075,11 +10078,11 @@ var spine;
 				this.indicesLength += indicesLength;
 				this.indicesLength += indicesLength;
 			};
 			};
 			MeshBatcher.prototype.end = function () {
 			MeshBatcher.prototype.end = function () {
-				this.vertexBuffer.needsUpdate = true;
+				this.vertexBuffer.needsUpdate = this.verticesLength > 0;
 				this.vertexBuffer.updateRange.offset = 0;
 				this.vertexBuffer.updateRange.offset = 0;
 				this.vertexBuffer.updateRange.count = this.verticesLength;
 				this.vertexBuffer.updateRange.count = this.verticesLength;
 				var geo = this.geometry;
 				var geo = this.geometry;
-				geo.getIndex().needsUpdate = true;
+				geo.getIndex().needsUpdate = this.indicesLength > 0;
 				geo.getIndex().updateRange.offset = 0;
 				geo.getIndex().updateRange.offset = 0;
 				geo.getIndex().updateRange.count = this.indicesLength;
 				geo.getIndex().updateRange.count = this.indicesLength;
 				geo.drawRange.start = 0;
 				geo.drawRange.start = 0;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 5 - 2
spine-ts/build/spine-canvas.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 5 - 2
spine-ts/build/spine-core.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 5 - 2
spine-ts/build/spine-player.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-player.js.map


+ 7 - 4
spine-ts/build/spine-threejs.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;
@@ -7205,11 +7208,11 @@ var spine;
 				this.indicesLength += indicesLength;
 				this.indicesLength += indicesLength;
 			};
 			};
 			MeshBatcher.prototype.end = function () {
 			MeshBatcher.prototype.end = function () {
-				this.vertexBuffer.needsUpdate = true;
+				this.vertexBuffer.needsUpdate = this.verticesLength > 0;
 				this.vertexBuffer.updateRange.offset = 0;
 				this.vertexBuffer.updateRange.offset = 0;
 				this.vertexBuffer.updateRange.count = this.verticesLength;
 				this.vertexBuffer.updateRange.count = this.verticesLength;
 				var geo = this.geometry;
 				var geo = this.geometry;
-				geo.getIndex().needsUpdate = true;
+				geo.getIndex().needsUpdate = this.indicesLength > 0;
 				geo.getIndex().updateRange.offset = 0;
 				geo.getIndex().updateRange.offset = 0;
 				geo.getIndex().updateRange.count = this.indicesLength;
 				geo.getIndex().updateRange.count = this.indicesLength;
 				geo.drawRange.start = 0;
 				geo.drawRange.start = 0;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 5 - 2
spine-ts/build/spine-webgl.js

@@ -1475,8 +1475,11 @@ var spine;
 					var alpha = 0;
 					var alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 						case AnimationState.SUBSEQUENT:
 						case AnimationState.SUBSEQUENT:
-							if (!attachments && timeline instanceof spine.AttachmentTimeline)
-								continue;
+							if (!attachments && timeline instanceof spine.AttachmentTimeline) {
+								if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST)
+									continue;
+								blend = spine.MixBlend.setup;
+							}
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 							if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
 								continue;
 								continue;
 							timelineBlend = blend;
 							timelineBlend = blend;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 4 - 1
spine-ts/core/src/AnimationState.ts

@@ -230,7 +230,10 @@ module spine {
 					let alpha = 0;
 					let alpha = 0;
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					switch (timelineMode[i] & (AnimationState.NOT_LAST - 1)) {
 					case AnimationState.SUBSEQUENT:
 					case AnimationState.SUBSEQUENT:
-						if (!attachments && timeline instanceof AttachmentTimeline) continue;
+						if (!attachments && timeline instanceof AttachmentTimeline) {
+							if ((timelineMode[i] & AnimationState.NOT_LAST) == AnimationState.NOT_LAST) continue;
+							blend = MixBlend.setup;
+						}
 						if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
 						if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
 						timelineBlend = blend;
 						timelineBlend = blend;
 						alpha = alphaMix;
 						alpha = alphaMix;

+ 2 - 2
spine-ts/threejs/src/MeshBatcher.ts

@@ -98,11 +98,11 @@ module spine.threejs {
 		}
 		}
 
 
 		end () {
 		end () {
-			this.vertexBuffer.needsUpdate = true;
+			this.vertexBuffer.needsUpdate = this.verticesLength > 0;
 			this.vertexBuffer.updateRange.offset = 0;
 			this.vertexBuffer.updateRange.offset = 0;
 			this.vertexBuffer.updateRange.count = this.verticesLength;
 			this.vertexBuffer.updateRange.count = this.verticesLength;
 			let geo = (<THREE.BufferGeometry>this.geometry);
 			let geo = (<THREE.BufferGeometry>this.geometry);
-			geo.getIndex().needsUpdate = true;
+			geo.getIndex().needsUpdate = this.indicesLength > 0;
 			geo.getIndex().updateRange.offset = 0;
 			geo.getIndex().updateRange.offset = 0;
 			geo.getIndex().updateRange.count = this.indicesLength;
 			geo.getIndex().updateRange.count = this.indicesLength;
 			geo.drawRange.start = 0;
 			geo.drawRange.start = 0;

+ 5 - 3
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs

@@ -28,6 +28,7 @@
  *****************************************************************************/
  *****************************************************************************/
 
 
 #pragma warning disable 0219
 #pragma warning disable 0219
+#pragma warning disable 0618 // for 3.7 branch only. Avoids "PreferenceItem' is obsolete: '[PreferenceItem] is deprecated. Use [SettingsProvider] instead."
 
 
 // Original contribution by: Mitch Thompson
 // Original contribution by: Mitch Thompson
 
 
@@ -60,6 +61,7 @@ using System.IO;
 using System.Text;
 using System.Text;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
+using System.Globalization;
 
 
 namespace Spine.Unity.Editor {
 namespace Spine.Unity.Editor {
 	using EventType = UnityEngine.EventType;
 	using EventType = UnityEngine.EventType;
@@ -1254,10 +1256,10 @@ namespace Spine.Unity.Editor {
 						string[] versionSplit = rawVersion.Split('.');
 						string[] versionSplit = rawVersion.Split('.');
 						bool match = false;
 						bool match = false;
 						foreach (var version in compatibleVersions) {
 						foreach (var version in compatibleVersions) {
-							bool primaryMatch = version[0] == int.Parse(versionSplit[0]);
-							bool secondaryMatch = version[1] == int.Parse(versionSplit[1]);
+							bool primaryMatch = version[0] == int.Parse(versionSplit[0], CultureInfo.InvariantCulture);
+							bool secondaryMatch = version[1] == int.Parse(versionSplit[1], CultureInfo.InvariantCulture);
 
 
-							// if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2]);
+							// if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2], CultureInfo.InvariantCulture);
 
 
 							if (primaryMatch && secondaryMatch) {
 							if (primaryMatch && secondaryMatch) {
 								match = true;
 								match = true;

+ 6 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader

@@ -91,19 +91,20 @@ Shader "Spine/Skeleton Fill" {
 
 
 			struct VertexOutput { 
 			struct VertexOutput { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
-			VertexOutput vert (appdata_base v) {
+			VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
 				VertexOutput o;
 				VertexOutput o;
-				o.uv = v.texcoord;
+				o.uvAndAlpha = v.texcoord;
+				o.uvAndAlpha.a = vertexColor.a;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
 				return o;
 				return o;
 			}
 			}
 
 
 			float4 frag (VertexOutput i) : COLOR {
 			float4 frag (VertexOutput i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 6 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader

@@ -94,19 +94,20 @@ Shader "Spine/Skeleton Tint" {
 
 
 			struct VertexOutput { 
 			struct VertexOutput { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
-			VertexOutput vert (appdata_base v) {
+			VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
 				VertexOutput o;
 				VertexOutput o;
-				o.uv = v.texcoord;
+				o.uvAndAlpha = v.texcoord;
+				o.uvAndAlpha.a = vertexColor.a;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
 				return o;
 				return o;
 			}
 			}
 
 
 			float4 frag (VertexOutput i) : COLOR {
 			float4 frag (VertexOutput i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 6 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Spine-Special-Skeleton-Grayscale.shader

@@ -91,19 +91,20 @@ Shader "Spine/Special/Skeleton Grayscale" {
 
 
 			struct VertexOutput { 
 			struct VertexOutput { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
-			VertexOutput vert (appdata_base v) {
+			VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
 				VertexOutput o;
 				VertexOutput o;
-				o.uv = v.texcoord;
+				o.uvAndAlpha = v.texcoord;
+				o.uvAndAlpha.a = vertexColor.a;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
 				return o;
 				return o;
 			}
 			}
 
 
 			float4 frag (VertexOutput i) : COLOR {
 			float4 frag (VertexOutput i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteShadows.cginc

@@ -16,18 +16,20 @@ struct vertexInput
 struct vertexOutput
 struct vertexOutput
 { 
 { 
 	V2F_SHADOW_CASTER;
 	V2F_SHADOW_CASTER;
-	float2 texcoord : TEXCOORD1;
+	float4 texcoordAndAlpha : TEXCOORD1;
 };
 };
 
 
 ////////////////////////////////////////
 ////////////////////////////////////////
 // Vertex program
 // Vertex program
 //
 //
 
 
-vertexOutput vert(vertexInput v)
+vertexOutput vert(vertexInput v, float4 vertexColor : COLOR)
 {
 {
 	vertexOutput o;
 	vertexOutput o;
 	TRANSFER_SHADOW_CASTER(o)
 	TRANSFER_SHADOW_CASTER(o)
-	o.texcoord = calculateTextureCoord(v.texcoord);
+	o.texcoordAndAlpha.xy = calculateTextureCoord(v.texcoord);
+	o.texcoordAndAlpha.z = 0;
+	o.texcoordAndAlpha.a = vertexColor.a;
 	return o;
 	return o;
 }
 }
 
 
@@ -40,8 +42,8 @@ uniform fixed _ShadowAlphaCutoff;
 
 
 fixed4 frag(vertexOutput IN) : COLOR 
 fixed4 frag(vertexOutput IN) : COLOR 
 {
 {
-	fixed4 texureColor = calculateTexturePixel(IN.texcoord);
-	clip(texureColor.a - _ShadowAlphaCutoff);
+	fixed4 texureColor = calculateTexturePixel(IN.texcoordAndAlpha.xy);
+	clip(texureColor.a * IN.texcoordAndAlpha.a - _ShadowAlphaCutoff);
 	
 	
 	SHADOW_CASTER_FRAGMENT(IN)
 	SHADOW_CASTER_FRAGMENT(IN)
 }
 }

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpriteShadows.cginc

@@ -16,7 +16,7 @@ struct vertexInput
 struct vertexOutput
 struct vertexOutput
 { 
 { 
 	V2F_SHADOW_CASTER;
 	V2F_SHADOW_CASTER;
-	float4 texcoord : TEXCOORD1;
+	float4 texcoordAndAlpha : TEXCOORD1;
 };
 };
 
 
 ////////////////////////////////////////
 ////////////////////////////////////////
@@ -26,11 +26,13 @@ struct vertexOutput
 uniform sampler2D _MainTex;
 uniform sampler2D _MainTex;
 uniform fixed4 _MainTex_ST;
 uniform fixed4 _MainTex_ST;
 
 
-vertexOutput vert(vertexInput v)
+vertexOutput vert(vertexInput v, float4 vertexColor : COLOR)
 {
 {
 	vertexOutput o;
 	vertexOutput o;
 	TRANSFER_SHADOW_CASTER(o)
 	TRANSFER_SHADOW_CASTER(o)
-	o.texcoord = float4(TRANSFORM_TEX(v.texcoord, _MainTex), 0, 0);
+	o.texcoordAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
+	o.texcoordAndAlpha.z = 0;
+	o.texcoordAndAlpha.a = vertexColor.a;
 	return o;
 	return o;
 }
 }
 
 
@@ -43,8 +45,8 @@ uniform fixed _ShadowAlphaCutoff;
 
 
 fixed4 frag(vertexOutput IN) : COLOR 
 fixed4 frag(vertexOutput IN) : COLOR 
 {
 {
-	fixed4 texureColor = tex2D(_MainTex, IN.texcoord.xy);
-	clip(texureColor.a - _ShadowAlphaCutoff);
+	fixed4 texureColor = tex2D(_MainTex, IN.texcoordAndAlpha.xy);
+	clip(texureColor.a * IN.texcoordAndAlpha.a - _ShadowAlphaCutoff);
 	
 	
 	SHADOW_CASTER_FRAGMENT(IN)
 	SHADOW_CASTER_FRAGMENT(IN)
 }
 }

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Shaders/Sprite/SpritesUnlit.shader

@@ -80,7 +80,7 @@ Shader "Spine/Sprite/Unlit"
 			Cull Off
 			Cull Off
 			Lighting Off
 			Lighting Off
 			
 			
-			CGPROGRAM		
+			CGPROGRAM
 				#pragma fragmentoption ARB_precision_hint_fastest
 				#pragma fragmentoption ARB_precision_hint_fastest
 				#pragma multi_compile_shadowcaster
 				#pragma multi_compile_shadowcaster
 				#pragma multi_compile _ PIXELSNAP_ON
 				#pragma multi_compile _ PIXELSNAP_ON

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader

@@ -88,15 +88,17 @@ Shader "Spine/Blend Modes/Skeleton PMA Additive" {
 			#include "UnityCG.cginc"
 			#include "UnityCG.cginc"
 			struct v2f { 
 			struct v2f { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
 			uniform float4 _MainTex_ST;
 			uniform float4 _MainTex_ST;
 
 
-			v2f vert (appdata_base v) {
+			v2f vert (appdata_base v, float4 vertexColor : COLOR) {
 				v2f o;
 				v2f o;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
-				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.z = 0;
+				o.uvAndAlpha.a = vertexColor.a;
 				return o;
 				return o;
 			}
 			}
 
 
@@ -104,8 +106,8 @@ Shader "Spine/Blend Modes/Skeleton PMA Additive" {
 			uniform fixed _Cutoff;
 			uniform fixed _Cutoff;
 
 
 			float4 frag (v2f i) : COLOR {
 			float4 frag (v2f i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader

@@ -88,15 +88,17 @@ Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
 			#include "UnityCG.cginc"
 			#include "UnityCG.cginc"
 			struct v2f { 
 			struct v2f { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
 			uniform float4 _MainTex_ST;
 			uniform float4 _MainTex_ST;
 
 
-			v2f vert (appdata_base v) {
+			v2f vert (appdata_base v, float4 vertexColor : COLOR) {
 				v2f o;
 				v2f o;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
-				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.z = 0;
+				o.uvAndAlpha.a = vertexColor.a;
 				return o;
 				return o;
 			}
 			}
 
 
@@ -104,8 +106,8 @@ Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
 			uniform fixed _Cutoff;
 			uniform fixed _Cutoff;
 
 
 			float4 frag (v2f i) : COLOR {
 			float4 frag (v2f i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader

@@ -88,15 +88,17 @@ Shader "Spine/Blend Modes/Skeleton PMA Screen" {
 			#include "UnityCG.cginc"
 			#include "UnityCG.cginc"
 			struct v2f { 
 			struct v2f { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
 			uniform float4 _MainTex_ST;
 			uniform float4 _MainTex_ST;
 
 
-			v2f vert (appdata_base v) {
+			v2f vert (appdata_base v, float4 vertexColor : COLOR) {
 				v2f o;
 				v2f o;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
-				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.z = 0;
+				o.uvAndAlpha.a = vertexColor.a;
 				return o;
 				return o;
 			}
 			}
 
 
@@ -104,8 +106,8 @@ Shader "Spine/Blend Modes/Skeleton PMA Screen" {
 			uniform fixed _Cutoff;
 			uniform fixed _Cutoff;
 
 
 			float4 frag (v2f i) : COLOR {
 			float4 frag (v2f i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 6 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader

@@ -100,19 +100,20 @@ Shader "Spine/Skeleton Tint Black" {
 
 
 			struct v2f { 
 			struct v2f { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
-			v2f vert (appdata_base v) {
+			v2f vert (appdata_base v, float4 vertexColor : COLOR) {
 				v2f o;
 				v2f o;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
-				o.uv = v.texcoord;
+				o.uvAndAlpha = v.texcoord;
+				o.uvAndAlpha.a = vertexColor.a;
 				return o;
 				return o;
 			}
 			}
 
 
 			float4 frag (v2f i) : COLOR {
 			float4 frag (v2f i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 6 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader

@@ -84,19 +84,20 @@ Shader "Spine/Skeleton" {
 
 
 			struct VertexOutput { 
 			struct VertexOutput { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2 uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
-			VertexOutput vert (appdata_base v) {
+			VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
 				VertexOutput o;
 				VertexOutput o;
-				o.uv = v.texcoord;
+				o.uvAndAlpha = v.texcoord;
+				o.uvAndAlpha.a = vertexColor.a;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
 				return o;
 				return o;
 			}
 			}
 
 
 			float4 frag (VertexOutput i) : COLOR {
 			float4 frag (VertexOutput i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

+ 7 - 5
spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-SkeletonLit.shader

@@ -179,15 +179,17 @@ Shader "Spine/Skeleton Lit" {
 			#include "UnityCG.cginc"
 			#include "UnityCG.cginc"
 			struct v2f { 
 			struct v2f { 
 				V2F_SHADOW_CASTER;
 				V2F_SHADOW_CASTER;
-				float2  uv : TEXCOORD1;
+				float4 uvAndAlpha : TEXCOORD1;
 			};
 			};
 
 
 			uniform float4 _MainTex_ST;
 			uniform float4 _MainTex_ST;
 
 
-			v2f vert (appdata_base v) {
+			v2f vert (appdata_base v, float4 vertexColor : COLOR) {
 				v2f o;
 				v2f o;
 				TRANSFER_SHADOW_CASTER(o)
 				TRANSFER_SHADOW_CASTER(o)
-				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
+				o.uvAndAlpha.z = 0;
+				o.uvAndAlpha.a = vertexColor.a;
 				return o;
 				return o;
 			}
 			}
 
 
@@ -195,8 +197,8 @@ Shader "Spine/Skeleton Lit" {
 			uniform fixed _Cutoff;
 			uniform fixed _Cutoff;
 
 
 			float4 frag (v2f i) : COLOR {
 			float4 frag (v2f i) : COLOR {
-				fixed4 texcol = tex2D(_MainTex, i.uv);
-				clip(texcol.a - _Cutoff);
+				fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
+				clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
 				SHADOW_CASTER_FRAGMENT(i)
 				SHADOW_CASTER_FRAGMENT(i)
 			}
 			}
 			ENDCG
 			ENDCG

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác