Bladeren bron

Merge branch '3.6' into 3.7-beta

badlogic 8 jaren geleden
bovenliggende
commit
c06bd8f181
54 gewijzigde bestanden met toevoegingen van 4234 en 6199 verwijderingen
  1. 5 0
      CHANGELOG.md
  2. 3 3
      spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp
  3. 1 1
      spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp
  4. 0 2
      spine-c/spine-c/include/spine/Array.h
  5. 4 0
      spine-c/spine-c/include/spine/Color.h
  6. 84 0
      spine-c/spine-c/include/spine/VertexEffect.h
  7. 15 0
      spine-c/spine-c/include/spine/extension.h
  8. 1 0
      spine-c/spine-c/include/spine/spine.h
  9. 98 0
      spine-c/spine-c/src/spine/VertexEffect.c
  10. 41 0
      spine-c/spine-c/src/spine/extension.c
  11. 5 0
      spine-cocos2d-objc/example/RaptorExample.m
  12. 8 4
      spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj
  13. 2 0
      spine-cocos2d-objc/src/spine/SkeletonRenderer.h
  14. 64 12
      spine-cocos2d-objc/src/spine/SkeletonRenderer.m
  15. 17 1
      spine-cocos2dx/example/Classes/RaptorExample.cpp
  16. 3 0
      spine-cocos2dx/example/Classes/RaptorExample.h
  17. 1 0
      spine-cocos2dx/example/proj.android/jni/Android.mk
  18. 98 0
      spine-cocos2dx/example/proj.ios_mac/VertexEffect.c
  19. 6 0
      spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj
  20. 1 0
      spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj
  21. 156 44
      spine-cocos2dx/src/spine/SkeletonRenderer.cpp
  22. 5 1
      spine-cocos2dx/src/spine/SkeletonRenderer.h
  23. 1 0
      spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java
  24. 1 0
      spine-sfml/CMakeLists.txt
  25. 13 1
      spine-sfml/example/main.cpp
  26. 60 7
      spine-sfml/src/spine/spine-sfml.cpp
  27. 5 0
      spine-sfml/src/spine/spine-sfml.h
  28. 300 296
      spine-ts/build/spine-all.d.ts
  29. 272 936
      spine-ts/build/spine-all.js
  30. 0 0
      spine-ts/build/spine-all.js.map
  31. 244 244
      spine-ts/build/spine-canvas.d.ts
  32. 272 936
      spine-ts/build/spine-canvas.js
  33. 0 0
      spine-ts/build/spine-canvas.js.map
  34. 150 150
      spine-ts/build/spine-core.d.ts
  35. 417 761
      spine-ts/build/spine-core.js
  36. 0 0
      spine-ts/build/spine-core.js.map
  37. 154 150
      spine-ts/build/spine-threejs.d.ts
  38. 417 761
      spine-ts/build/spine-threejs.js
  39. 0 0
      spine-ts/build/spine-threejs.js.map
  40. 166 166
      spine-ts/build/spine-webgl.d.ts
  41. 417 761
      spine-ts/build/spine-webgl.js
  42. 0 0
      spine-ts/build/spine-webgl.js.map
  43. 166 166
      spine-ts/build/spine-widget.d.ts
  44. 417 761
      spine-ts/build/spine-widget.js
  45. 0 0
      spine-ts/build/spine-widget.js.map
  46. 58 8
      spine-ts/threejs/src/SkeletonMesh.ts
  47. 3 0
      spine-unity/Assets/Examples/Other Examples/Mix and Match.unity
  48. 31 0
      spine-unity/Assets/Examples/Scripts/Getting Started Scripts/SpineboyTargetController.cs
  49. 12 0
      spine-unity/Assets/Examples/Scripts/Getting Started Scripts/SpineboyTargetController.cs.meta
  50. 3 1
      spine-unity/Assets/Examples/Scripts/MixAndMatch.cs
  51. 7 4
      spine-unity/Assets/Examples/Scripts/MixAndMatchGraphic.cs
  52. 2 1
      spine-unity/Assets/Examples/Spine/Raptor/raptor_SkeletonData.asset
  53. 2 0
      spine-unity/Assets/Examples/Spine/spineboy-unity/spineboy_Material.mat
  54. 26 21
      spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs

+ 5 - 0
CHANGELOG.md

@@ -46,6 +46,7 @@
   * Added `spSkeletonClipper` and `spTriangulator`, used to implement software clipping of attachments.
   * `AnimationState#apply` returns boolean indicating if any timeline was applied or not.
   * `Animation#apply` and `Timeline#apply`` now take enums `MixPose` and `MixDirection` instead of booleans
+  * Added `spVertexEffect` and corresponding implementations `spJitterVertexEffect` and `spSwirlVertexEffect`. Create/dispose through the corresponding `spXXXVertexEffect_create()/dispose()` functions. Set on framework/engine specific renderer. See changes for spine-c based frameworks/engines below.
 
 ### Cocos2d-X
  * Fixed renderer to work with 3.6 changes
@@ -55,6 +56,7 @@
  * Added mesh debug rendering. Enable/Disable via `SkeletonRenderer::setDebugMeshesEnabled()`.
  * Added support for clipping.
  * SkeletonRenderer now combines the displayed color of the Node (cascaded from all parents) with the skeleton color for tinting.
+ * Added support for vertex effects. See `RaptorExample.cpp`.
 
 ### Cocos2d-Objc
  * Fixed renderer to work with 3.6 changes
@@ -64,6 +66,7 @@
 ### SFML
  * Fixed renderer to work with 3.6 changes. Sadly, two color tinting does not work, as the vertex format in SFML is fixed.
  * Added support for clipping.
+ * Added support for vertex effects. See raptor example.
 
 ### Unreal Engine 4
  * Fixed renderer to work with 3.6 changes
@@ -216,6 +219,7 @@
  * Improved performance by using `DYNAMIC_DRAW` for vertex buffer objects and fixing bug that copied to much data to the GPU each frame in `PolygonBatcher`/`Mesh`.
  * Added two color tinting support, enabled by default. You can disable it via the constructors of `SceneRenderer`, `SkeletonRenderer`and `PolygonBatcher`. Note that you will need to use a shader created via `Shader.newTwoColoredTexturedShader` shader with `SkeletonRenderer` and `PolygonBatcher` if two color tinting is enabled.
  * Added clipping support
+ * Added `VertexEffect` interface, instances of which can be set on `SkeletonRenderer`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`, and the example which allows to set effects.
 
 ### Canvas backend
  * Fixed renderer to work for 3.6 changes. Sadly, we can't support two color tinting via the Canvas API.
@@ -225,6 +229,7 @@
 ### Three.js backend
  * Fixed renderer to work with 3.6 changes. Two color tinting is not supported.
  * Added clipping support
+ * Added `VertexEffect` interface, instances of which can be set on `SkeletonMesh`. Allows to modify vertices before submitting them to GPU. See `SwirlEffect`, `JitterEffect`.
 
 ### Widget backend
  * Fixed WebGL context loss (see WebGL backend changes). Enabled automatically.

+ 3 - 3
spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp

@@ -6,13 +6,13 @@
 
 #include "KMemory.h" // last include
 
-#define SPINEBOY_JSON "testdata/spineboy/spineboy.json"
+#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json"
 #define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas"
 
-#define RAPTOR_JSON "testdata/raptor/raptor.json"
+#define RAPTOR_JSON "testdata/raptor/raptor-pro.json"
 #define RAPTOR_ATLAS "testdata/raptor/raptor.atlas"
 
-#define GOBLINS_JSON "testdata/goblins/goblins.json"
+#define GOBLINS_JSON "testdata/goblins/goblins-pro.json"
 #define GOBLINS_ATLAS "testdata/goblins/goblins.atlas"
 
 #define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution

+ 1 - 1
spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp

@@ -6,7 +6,7 @@
 
 #include "KMemory.h" // last include
 
-#define SPINEBOY_JSON "testdata/spineboy/spineboy.json"
+#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json"
 #define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas"
 
 #define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution

+ 0 - 2
spine-c/spine-c/include/spine/Array.h

@@ -100,7 +100,6 @@ extern "C" {
 	void name##_removeAt(name* self, int index) { \
 		self->size--; \
 		memmove(self->items + index, self->items + index + 1, sizeof(itemType) * (self->size - index)); \
-		self->items[self->size] = 0; \
 	} \
 	int name##_contains(name* self, itemType value) { \
 		itemType* items = self->items; \
@@ -112,7 +111,6 @@ extern "C" {
 	} \
 	itemType name##_pop(name* self) { \
 		itemType item = self->items[--self->size]; \
-		self->items[self->size] = 0; \
 		return item; \
 	} \
 	itemType name##_peek(name* self) { \

+ 4 - 0
spine-c/spine-c/include/spine/Color.h

@@ -42,6 +42,10 @@ typedef struct spColor {
 	spColor() :
 		r(0), g(0), b(0), a(0) {
 	}
+
+	bool operator==(const spColor& rhs) {
+		return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
+	}
 #endif
 } spColor;
 

+ 84 - 0
spine-c/spine-c/include/spine/VertexEffect.h

@@ -0,0 +1,84 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef SPINE_VERTEXEFFECT_H_
+#define SPINE_VERTEXEFFECT_H_
+
+#include <spine/Skeleton.h>
+#include <spine/Color.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct spVertexEffect;
+
+typedef void (*spVertexEffectBegin)(struct spVertexEffect *self, spSkeleton *skeleton);
+
+typedef void (*spVertexEffectTransform)(struct spVertexEffect *self, float *x, float *y, float *u, float *v,
+										spColor *light, spColor *dark);
+
+typedef void (*spVertexEffectEnd)(struct spVertexEffect *self);
+
+typedef struct spVertexEffect {
+	spVertexEffectBegin begin;
+	spVertexEffectTransform transform;
+	spVertexEffectEnd end;
+} spVertexEffect;
+
+typedef struct spJitterVertexEffect {
+	spVertexEffect super;
+	float jitterX;
+	float jitterY;
+} spJitterVertexEffect;
+
+typedef struct spSwirlVertexEffect {
+	spVertexEffect super;
+	float centerX;
+	float centerY;
+	float radius;
+	float angle;
+	float worldX;
+	float worldY;
+} spSwirlVertexEffect;
+
+spJitterVertexEffect *spJitterVertexEffect_create(float jitterX, float jitterY);
+
+void spJitterVertexEffect_dispose(spJitterVertexEffect *effect);
+
+spSwirlVertexEffect *spSwirlVertexEffect_create(float radius);
+
+void spSwirlVertexEffect_dispose(spSwirlVertexEffect *effect);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPINE_VERTEX_EFFECT_H_ */

+ 15 - 0
spine-c/spine-c/include/spine/extension.h

@@ -103,6 +103,7 @@
 #define COS(A) cosf(A)
 #define SQRT(A) sqrtf(A)
 #define ACOS(A) acosf(A)
+#define POW(A,B) pow(A, B)
 #else
 #define FMOD(A,B) (float)fmod(A, B)
 #define ATAN2(A,B) (float)atan2(A, B)
@@ -110,6 +111,7 @@
 #define SIN(A) (float)sin(A)
 #define SQRT(A) (float)sqrt(A)
 #define ACOS(A) (float)acos(A)
+#define POW(A,B) (float)pow(A, B)
 #endif
 
 #define SIN_DEG(A) SIN((A) * DEG_RAD)
@@ -166,14 +168,27 @@ void* _malloc (size_t size, const char* file, int line);
 void* _calloc (size_t num, size_t size, const char* file, int line);
 void* _realloc(void* ptr, size_t size);
 void _free (void* ptr);
+float _random ();
 
 void _setMalloc (void* (*_malloc) (size_t size));
 void _setDebugMalloc (void* (*_malloc) (size_t size, const char* file, int line));
 void _setRealloc(void* (*_realloc) (void* ptr, size_t size));
 void _setFree (void (*_free) (void* ptr));
+void _setRandom(float (*_random) ());
 
 char* _readFile (const char* path, int* length);
 
+
+/*
+ * Math utilities
+ */
+float _spMath_random(float min, float max);
+float _spMath_randomTriangular(float min, float max);
+float _spMath_randomTriangularWith(float min, float max, float mode);
+float _spMath_interpolate(float (*apply) (float a), float start, float end, float a);
+float _spMath_pow2_apply(float a);
+float _spMath_pow2out_apply(float a);
+
 /**/
 
 typedef union _spEventQueueItem {

+ 1 - 0
spine-c/spine-c/include/spine/spine.h

@@ -57,5 +57,6 @@
 #include <spine/SkeletonClipping.h>
 #include <spine/Event.h>
 #include <spine/EventData.h>
+#include <spine/VertexEffect.h>
 
 #endif /* SPINE_SPINE_H_ */

+ 98 - 0
spine-c/spine-c/src/spine/VertexEffect.c

@@ -0,0 +1,98 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include <spine/VertexEffect.h>
+#include <spine/extension.h>
+
+void _spJitterVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
+}
+
+void _spJitterVertexEffect_transform(spVertexEffect* self, float* x, float* y, float* u, float* v, spColor* light, spColor* dark) {
+	spJitterVertexEffect* internal = (spJitterVertexEffect*)self;
+	float jitterX = internal->jitterX;
+	float jitterY = internal->jitterY;
+	(*x) += _spMath_randomTriangular(-jitterX, jitterY);
+	(*y) += _spMath_randomTriangular(-jitterX, jitterY);
+}
+
+void _spJitterVertexEffect_end(spVertexEffect* self) {
+}
+
+spJitterVertexEffect* spJitterVertexEffect_create(float jitterX, float jitterY) {
+	spJitterVertexEffect* effect = CALLOC(spJitterVertexEffect, 1);
+	effect->super.begin = _spJitterVertexEffect_begin;
+	effect->super.transform = _spJitterVertexEffect_transform;
+	effect->super.end = _spJitterVertexEffect_end;
+	effect->jitterX = jitterX;
+	effect->jitterY = jitterY;
+	return effect;
+}
+
+void spJitterVertexEffect_dispose(spJitterVertexEffect* effect) {
+	FREE(effect);
+}
+
+void _spSwirlVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
+	spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
+	internal->worldX = skeleton->x + internal->centerX;
+	internal->worldY = skeleton->y + internal->centerY;
+}
+
+void _spSwirlVertexEffect_transform(spVertexEffect* self, float* positionX, float* positionY, float* u, float* v, spColor* light, spColor* dark) {
+	spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
+	float radAngle = internal->angle * DEG_RAD;
+	float x = *positionX - internal->worldX;
+	float y = *positionY - internal->worldY;
+	float dist = SQRT(x * x + y * y);
+	if (dist < internal->radius) {
+		float theta = _spMath_interpolate(_spMath_pow2_apply, 0, radAngle, (internal->radius - dist) / internal->radius);
+		float cosine = COS(theta);
+		float sine = SIN(theta);
+		(*positionX) = cosine * x - sine * y + internal->worldX;
+		(*positionY) = sine * x + cosine * y + internal->worldY;
+	}
+}
+
+void _spSwirlVertexEffect_end(spVertexEffect* self) {
+}
+
+spSwirlVertexEffect* spSwirlVertexEffect_create(float radius) {
+	spSwirlVertexEffect* effect = CALLOC(spSwirlVertexEffect, 1);
+	effect->super.begin = _spSwirlVertexEffect_begin;
+	effect->super.transform = _spSwirlVertexEffect_transform;
+	effect->super.end = _spSwirlVertexEffect_end;
+	effect->radius = radius;
+	return effect;
+}
+
+void spSwirlVertexEffect_dispose(spSwirlVertexEffect* effect) {
+	FREE(effect);
+}
+

+ 41 - 0
spine-c/spine-c/src/spine/extension.c

@@ -31,10 +31,15 @@
 #include <spine/extension.h>
 #include <stdio.h>
 
+float _spRandom () {
+	return rand() / (float)RAND_MAX;
+}
+
 static void* (*mallocFunc) (size_t size) = malloc;
 static void* (*reallocFunc) (void* ptr, size_t size) = realloc;
 static void* (*debugMallocFunc) (size_t size, const char* file, int line) = NULL;
 static void (*freeFunc) (void* ptr) = free;
+static float (*randomFunc) () = _spRandom;
 
 void* _malloc (size_t size, const char* file, int line) {
 	if(debugMallocFunc)
@@ -54,6 +59,10 @@ void _free (void* ptr) {
 	freeFunc(ptr);
 }
 
+float _random () {
+	return randomFunc();
+}
+
 void _setDebugMalloc(void* (*malloc) (size_t size, const char* file, int line)) {
 	debugMallocFunc = malloc;
 }
@@ -70,6 +79,10 @@ void _setFree (void (*free) (void* ptr)) {
 	freeFunc = free;
 }
 
+void _setRandom (float (*random) ()) {
+	randomFunc = random;
+}
+
 char* _readFile (const char* path, int* length) {
 	char *data;
 	FILE *file = fopen(path, "rb");
@@ -85,3 +98,31 @@ char* _readFile (const char* path, int* length) {
 
 	return data;
 }
+
+float _spMath_random(float min, float max) {
+	return min + (max - min) * _random();
+}
+
+float _spMath_randomTriangular(float min, float max) {
+	return _spMath_randomTriangularWith(min, max, (min + max) * 0.5f);
+}
+
+float _spMath_randomTriangularWith(float min, float max, float mode) {
+	float u = _random();
+	float d = max - min;
+	if (u <= (mode - min) / d) return min + SQRT(u * d * (mode - min));
+	return max - SQRT((1 - u) * d * (max - mode));
+}
+
+float _spMath_interpolate(float (*apply) (float a), float start, float end, float a) {
+	return start + (end - start) * apply(a);
+}
+
+float _spMath_pow2_apply(float a) {
+	if (a <= 0.5) return POW(a * 2, 2) / 2;
+	return POW((a - 1) * 2, 2) / -2 + 1;
+}
+
+float _spMath_pow2out_apply(float a) {
+	return POW(a - 1, 2) * -1 + 1;
+}

+ 5 - 0
spine-cocos2d-objc/example/RaptorExample.m

@@ -31,6 +31,8 @@
 #import "RaptorExample.h"
 #import "TankExample.h"
 
+spJitterVertexEffect* effect = 0;
+
 @implementation RaptorExample
 
 + (CCScene*) scene {
@@ -42,9 +44,12 @@
 -(id) init {
     self = [super init];
     if (!self) return nil;
+	
+	if (!effect) effect = spJitterVertexEffect_create(10, 10);
     
     skeletonNode = [SkeletonAnimation skeletonWithFile:@"raptor-pro.json" atlasFile:@"raptor.atlas" scale:0.3f];
     [skeletonNode setAnimationForTrack:0 name:@"walk" loop:YES];
+	[skeletonNode setEffect:&effect->super];
     
     CGSize windowSize = [[CCDirector sharedDirector] viewSize];
     [skeletonNode setPosition:ccp(windowSize.width / 2, 20)];

+ 8 - 4
spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj

@@ -84,6 +84,7 @@
 		76F5BDAD1D2BDFA2005917E5 /* TankExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 76F5BDAC1D2BDFA2005917E5 /* TankExample.m */; };
 		76FAC1961E3FA15E001CCC8C /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC1941E3FA15E001CCC8C /* Color.c */; };
 		76FAC1971E3FA15E001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC1951E3FA15E001CCC8C /* PointAttachment.c */; };
+		76FB151A1F01413B00C5377F /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FB15191F01413B00C5377F /* VertexEffect.c */; };
 		83F1A0EF1986955A001F6B44 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83F1A0EE1986955A001F6B44 /* GLKit.framework */; };
 		9A5D2499170A94DA0030D4DD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A5D2498170A94DA0030D4DD /* QuartzCore.framework */; };
 		9A5D249B170A94DA0030D4DD /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A5D249A170A94DA0030D4DD /* OpenGLES.framework */; };
@@ -137,7 +138,7 @@
 /* Begin PBXFileReference section */
 		43C3282D170B0C19004A9460 /* spine-cocos2d-objc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "spine-cocos2d-objc.m"; path = "src/spine/spine-cocos2d-objc.m"; sourceTree = "<group>"; };
 		43C3282E170B0C19004A9460 /* spine-cocos2d-objc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "spine-cocos2d-objc.h"; path = "src/spine/spine-cocos2d-objc.h"; sourceTree = "<group>"; };
-		43C32868170B0DA6004A9460 /* spineboy-ess.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = spineboy-ess.json; path = Resources/spineboy-ess.json; sourceTree = "<group>"; };
+		43C32868170B0DA6004A9460 /* spineboy-ess.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "spineboy-ess.json"; path = "Resources/spineboy-ess.json"; sourceTree = "<group>"; };
 		43C3286A170B0DA6004A9460 /* spineboy.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = spineboy.atlas; path = Resources/spineboy.atlas; sourceTree = "<group>"; };
 		43C3286B170B0DA6004A9460 /* spineboy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = spineboy.png; path = Resources/spineboy.png; sourceTree = "<group>"; };
 		43C32871170B0DBE004A9460 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "Resources-ios/[email protected]"; sourceTree = "<group>"; };
@@ -175,7 +176,7 @@
 		76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonClipping.c; path = "../spine-c/spine-c/src/spine/SkeletonClipping.c"; sourceTree = "<group>"; };
 		76EE4E451EB36DE6000254F4 /* Triangulator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Triangulator.c; path = "../spine-c/spine-c/src/spine/Triangulator.c"; sourceTree = "<group>"; };
 		76EE4E4E1EB36E53000254F4 /* coin.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = coin.atlas; path = Resources/coin.atlas; sourceTree = "<group>"; };
-		76EE4E4F1EB36E53000254F4 /* coin-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = coin-pro.json; path = Resources/coin-pro.json; sourceTree = "<group>"; };
+		76EE4E4F1EB36E53000254F4 /* coin-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "coin-pro.json"; path = "Resources/coin-pro.json"; sourceTree = "<group>"; };
 		76EE4E501EB36E53000254F4 /* coin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = coin.png; path = Resources/coin.png; sourceTree = "<group>"; };
 		76EE4E541EB36E94000254F4 /* CoinExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoinExample.h; path = example/CoinExample.h; sourceTree = "<group>"; };
 		76EE4E551EB36E94000254F4 /* CoinExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CoinExample.m; path = example/CoinExample.m; sourceTree = "<group>"; };
@@ -214,10 +215,10 @@
 		76F28D141DEC810300CDE54D /* TransformConstraintData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TransformConstraintData.c; path = "../spine-c/spine-c/src/spine/TransformConstraintData.c"; sourceTree = "<group>"; };
 		76F28D151DEC810300CDE54D /* VertexAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexAttachment.c; path = "../spine-c/spine-c/src/spine/VertexAttachment.c"; sourceTree = "<group>"; };
 		76F5BD9C1D2BDE1C005917E5 /* raptor.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = raptor.atlas; path = Resources/raptor.atlas; sourceTree = "<group>"; };
-		76F5BD9D1D2BDE1C005917E5 /* raptor-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = raptor-pro.json; path = Resources/raptor-pro.json; sourceTree = "<group>"; };
+		76F5BD9D1D2BDE1C005917E5 /* raptor-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "raptor-pro.json"; path = "Resources/raptor-pro.json"; sourceTree = "<group>"; };
 		76F5BD9E1D2BDE1C005917E5 /* raptor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = raptor.png; path = Resources/raptor.png; sourceTree = "<group>"; };
 		76F5BD9F1D2BDE1C005917E5 /* tank.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tank.atlas; path = Resources/tank.atlas; sourceTree = "<group>"; };
-		76F5BDA01D2BDE1C005917E5 /* tank-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tank-pro.json; path = Resources/tank-pro.json; sourceTree = "<group>"; };
+		76F5BDA01D2BDE1C005917E5 /* tank-pro.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "tank-pro.json"; path = "Resources/tank-pro.json"; sourceTree = "<group>"; };
 		76F5BDA11D2BDE1C005917E5 /* tank.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tank.png; path = Resources/tank.png; sourceTree = "<group>"; };
 		76F5BDA81D2BDE67005917E5 /* RaptorExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RaptorExample.h; path = example/RaptorExample.h; sourceTree = "<group>"; };
 		76F5BDA91D2BDE67005917E5 /* RaptorExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RaptorExample.m; path = example/RaptorExample.m; sourceTree = "<group>"; };
@@ -225,6 +226,7 @@
 		76F5BDAC1D2BDFA2005917E5 /* TankExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TankExample.m; path = example/TankExample.m; sourceTree = "<group>"; };
 		76FAC1941E3FA15E001CCC8C /* Color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Color.c; path = "../spine-c/spine-c/src/spine/Color.c"; sourceTree = "<group>"; };
 		76FAC1951E3FA15E001CCC8C /* PointAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PointAttachment.c; path = "../spine-c/spine-c/src/spine/PointAttachment.c"; sourceTree = "<group>"; };
+		76FB15191F01413B00C5377F /* VertexEffect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VertexEffect.c; path = "../spine-c/spine-c/src/spine/VertexEffect.c"; sourceTree = "<group>"; };
 		83F1A0EE1986955A001F6B44 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
 		9A5D2495170A94DA0030D4DD /* SpineExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpineExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		9A5D2498170A94DA0030D4DD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
@@ -299,6 +301,7 @@
 		43C32822170B0BC2004A9460 /* spine-c */ = {
 			isa = PBXGroup;
 			children = (
+				76FB15191F01413B00C5377F /* VertexEffect.c */,
 				76EE4E421EB36DE6000254F4 /* Array.c */,
 				76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */,
 				76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */,
@@ -597,6 +600,7 @@
 				76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */,
 				76EE4E481EB36DE6000254F4 /* SkeletonClipping.c in Sources */,
 				43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */,
+				76FB151A1F01413B00C5377F /* VertexEffect.c in Sources */,
 				76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */,
 				76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */,
 				76F28D2F1DEC810300CDE54D /* SkeletonJson.c in Sources */,

+ 2 - 0
spine-cocos2d-objc/src/spine/SkeletonRenderer.h

@@ -47,6 +47,7 @@
 	float* _worldVertices;
 	CCBlendMode* screenMode;
 	spSkeletonClipping* _clipper;
+	spVertexEffect* _effect;
 }
 
 + (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@@ -90,5 +91,6 @@
 @property (nonatomic) bool debugBones;
 @property (nonatomic) bool skipVisibilityCheck;
 @property (nonatomic) spBone* rootBone;
+@property (nonatomic) spVertexEffect* effect;
 
 @end

+ 64 - 12
spine-cocos2d-objc/src/spine/SkeletonRenderer.m

@@ -50,6 +50,7 @@ static bool handlerQueued = false;
 @synthesize twoColorTint = _twoColorTint;
 @synthesize debugSlots = _debugSlots;
 @synthesize debugBones = _debugBones;
+@synthesize effect = _effect;
 
 + (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
 	return [[[self alloc] initWithData:skeletonData ownsSkeletonData:ownsSkeletonData] autorelease];
@@ -91,6 +92,7 @@ static bool handlerQueued = false;
 	];
 	
 	_clipper = spSkeletonClipping_create();
+	_effect = 0;
 }
 
 - (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
@@ -173,6 +175,8 @@ static bool handlerQueued = false;
 		handlerQueued = true;
 	}
 	
+	if (_effect) _effect->begin(_effect, _skeleton);
+	
 	CCColor* nodeColor = self.color;
 	_skeleton->color.r = nodeColor.red;
 	_skeleton->color.g = nodeColor.green;
@@ -288,6 +292,20 @@ static bool handlerQueued = false;
 							vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
 							vertex.color = GLKVector4Make(r, g, b, a);
 							vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]);
+							if (_effect) {
+								spColor light;
+								spColor dark;
+								light.r = r;
+								light.g = g;
+								light.b = b;
+								light.a = a;
+								dark.r = dark.g = dark.b = dark.a = 0;
+								_effect->transform(_effect, &vertex.position.x, &vertex.position.y, &vertex.texCoord1.s, &vertex.texCoord1.t, &light, &dark);
+								vertex.color.r = light.r;
+								vertex.color.g = light.g;
+								vertex.color.b = light.b;
+								vertex.color.a = light.a;
+							}
 							CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform));
 						}
 						for (int j = 0; j * 3 < trianglesCount; ++j) {
@@ -308,18 +326,50 @@ static bool handlerQueued = false;
 						spVertex* verts = &meshPart.mesh->vertices[meshPart.startVertex];
 						unsigned short* indices = &meshPart.mesh->indices[meshPart.startIndex];
 						
-						for (int i = 0; i * 2 < verticesCount; i++, verts++) {
-							CCVertex vertex;
-							vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
-							vertex = CCVertexApplyTransform(vertex, transform);
-							verts->x = vertex.position.x;
-							verts->y = vertex.position.y;
-							verts->z = vertex.position.z;
-							verts->w = vertex.position.w;
-							verts->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24;
-							verts->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(255)) << 24;
-							verts->u = uvs[i * 2];
-							verts->v = 1 - uvs[i * 2 + 1];
+						if (_effect) {
+							spColor light;
+							light.r = r;
+							light.g = g;
+							light.b = b;
+							light.a = a;
+							spColor dark;
+							dark.r = dr;
+							dark.g = dg;
+							dark.b = db;
+							dark.a = 1;
+							for (int i = 0; i * 2 < verticesCount; i++, verts++) {
+								spColor lightCopy = light;
+								spColor darkCopy = dark;
+								
+								CCVertex vertex;
+								vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
+								verts->u = uvs[i * 2];
+								verts->v = 1 - uvs[i * 2 + 1];
+								_effect->transform(_effect, &vertex.position.x, &vertex.position.y, &verts->u, &verts->v, &lightCopy, &darkCopy);
+								
+								vertex = CCVertexApplyTransform(vertex, transform);
+								verts->x = vertex.position.x;
+								verts->y = vertex.position.y;
+								verts->z = vertex.position.z;
+								verts->w = vertex.position.w;
+								verts->color = ((unsigned short)(lightCopy.r * 255))| ((unsigned short)(lightCopy.g * 255)) << 8 | ((unsigned short)(lightCopy.b * 255)) <<16 | ((unsigned short)(lightCopy.a * 255)) << 24;
+								verts->color2 = ((unsigned short)(darkCopy.r * 255)) | ((unsigned short)(darkCopy.g * 255)) << 8 | ((unsigned short)(darkCopy.b * 255)) << 16 | ((unsigned short)(255)) << 24;
+								
+							}
+						} else {
+							for (int i = 0; i * 2 < verticesCount; i++, verts++) {
+								CCVertex vertex;
+								vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
+								vertex = CCVertexApplyTransform(vertex, transform);
+								verts->x = vertex.position.x;
+								verts->y = vertex.position.y;
+								verts->z = vertex.position.z;
+								verts->w = vertex.position.w;
+								verts->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24;
+								verts->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(255)) << 24;
+								verts->u = uvs[i * 2];
+								verts->v = 1 - uvs[i * 2 + 1];
+							}
 						}
 						
 						for (int j = 0; j < trianglesCount; j++, indices++) {
@@ -375,6 +425,8 @@ static bool handlerQueued = false;
 			if (i == 0) [_drawNode drawDot:ccp(bone->worldX, bone->worldY) radius:4 color:[CCColor blueColor]];
 		}
 	}
+	
+	if (_effect) _effect->end(_effect);
 }
 
 - (CCTexture*) getTextureForRegion:(spRegionAttachment*)attachment {

+ 17 - 1
spine-cocos2dx/example/Classes/RaptorExample.cpp

@@ -30,10 +30,13 @@
 
 #include "RaptorExample.h"
 #include "TankExample.h"
+#include <spine/extension.h>
 
 USING_NS_CC;
 using namespace spine;
 
+spSwirlVertexEffect* effect = spSwirlVertexEffect_create(400);
+
 Scene* RaptorExample::scene () {
 	Scene *scene = Scene::create();
 	scene->addChild(RaptorExample::create());
@@ -46,7 +49,13 @@ bool RaptorExample::init () {
 	skeletonNode = SkeletonAnimation::createWithJsonFile("raptor-pro.json", "raptor.atlas", 0.5f);
 	skeletonNode->setAnimation(0, "walk", true);
 	skeletonNode->setAnimation(1, "empty", false);
-	skeletonNode->addAnimation(1, "gungrab", false, 2);	
+	skeletonNode->addAnimation(1, "gungrab", false, 2);
+	skeletonNode->setTwoColorTint(true);
+	
+	effect->centerY = 200;
+	swirlTime = 0;
+	
+	skeletonNode->setVertexEffect(&effect->super);
 
 	skeletonNode->setPosition(Vec2(_contentSize.width / 2, 20));
 	addChild(skeletonNode);
@@ -68,3 +77,10 @@ bool RaptorExample::init () {
 
 	return true;
 }
+
+void RaptorExample::update(float fDelta) {
+	swirlTime += fDelta;
+	float percent = fmod(swirlTime, 2);
+	if (percent > 1) percent = 1 - (percent - 1);
+	effect->angle = _spMath_interpolate(_spMath_pow2_apply, -60, 60, percent);
+}

+ 3 - 0
spine-cocos2dx/example/Classes/RaptorExample.h

@@ -41,9 +41,12 @@ public:
 	CREATE_FUNC(RaptorExample);
 
 	virtual bool init ();
+	
+	virtual void update(float fDelta);
 
 private:
 	spine::SkeletonAnimation* skeletonNode;
+	float swirlTime;
 };
 
 #endif // _RAPTOREXAMPLE_H_

+ 1 - 0
spine-cocos2dx/example/proj.android/jni/Android.mk

@@ -59,6 +59,7 @@ LOCAL_SRC_FILES := hellocpp/main.cpp \
 				   ../../../../spine-c/spine-c/src/spine/TransformConstraint.c \
 				   ../../../../spine-c/spine-c/src/spine/TransformConstraintData.c \
 				   ../../../../spine-c/spine-c/src/spine/VertexAttachment.c \
+				   ../../../../spine-c/spine-c/src/spine/VertexEffect.c \
 				   ../../../../spine-c/spine-c/src/spine/extension.c
 
 

+ 98 - 0
spine-cocos2dx/example/proj.ios_mac/VertexEffect.c

@@ -0,0 +1,98 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include <spine/VertexEffect.h>
+#include <spine/extension.h>
+
+void _spJitterVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
+}
+
+void _spJitterVertexEffect_transform(spVertexEffect* self, float* x, float* y, float* u, float* v, spColor* light, spColor* dark) {
+	spJitterVertexEffect* internal = (spJitterVertexEffect*)self;
+	float jitterX = internal->jitterX;
+	float jitterY = internal->jitterY;
+	(*x) += _spMath_randomTriangular(-jitterX, jitterY);
+	(*y) += _spMath_randomTriangular(-jitterX, jitterY);
+}
+
+void _spJitterVertexEffect_end(spVertexEffect* self) {
+}
+
+spJitterVertexEffect* spJitterVertexEffect_create(float jitterX, float jitterY) {
+	spJitterVertexEffect* effect = CALLOC(spJitterVertexEffect, 1);
+	effect->super.begin = _spJitterVertexEffect_begin;
+	effect->super.transform = _spJitterVertexEffect_transform;
+	effect->super.end = _spJitterVertexEffect_end;
+	effect->jitterX = jitterX;
+	effect->jitterY = jitterY;
+	return effect;
+}
+
+void spJitterVertexEffect_dispose(spJitterVertexEffect* effect) {
+	FREE(effect);
+}
+
+void _spSwirlVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) {
+	spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
+	internal->worldX = skeleton->x + internal->centerX;
+	internal->worldY = skeleton->y + internal->centerY;
+}
+
+void _spSwirlVertexEffect_transform(spVertexEffect* self, float* positionX, float* positionY, float* u, float* v, spColor* light, spColor* dark) {
+	spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self;
+	float radAngle = internal->angle * DEG_RAD;
+	float x = *positionX - internal->worldX;
+	float y = *positionY - internal->worldY;
+	float dist = SQRT(x * x + y * y);
+	if (dist < internal->radius) {
+		float theta = _spMath_interpolate(_spMath_pow2_apply, 0, radAngle, (internal->radius - dist) / internal->radius);
+		float cosine = COS(theta);
+		float sine = SIN(theta);
+		(*positionX) = cosine * x - sine * y + internal->worldX;
+		(*positionY) = sine * x + cosine * y + internal->worldY;
+	}
+}
+
+void _spSwirlVertexEffect_end(spVertexEffect* self) {
+}
+
+spSwirlVertexEffect* spSwirlVertexEffect_create(float radius) {
+	spSwirlVertexEffect* effect = CALLOC(spSwirlVertexEffect, 1);
+	effect->super.begin = _spSwirlVertexEffect_begin;
+	effect->super.transform = _spSwirlVertexEffect_transform;
+	effect->super.end = _spSwirlVertexEffect_end;
+	effect->radius = radius;
+	return effect;
+}
+
+void spSwirlVertexEffect_dispose(spSwirlVertexEffect* effect) {
+	FREE(effect);
+}
+

+ 6 - 0
spine-cocos2dx/example/proj.ios_mac/spine-cocos2d-x.xcodeproj/project.pbxproj

@@ -170,6 +170,8 @@
 		76FAC18D1E3F97D2001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; };
 		76FAC18F1E3F98A0001CCC8C /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18A1E3F97D2001CCC8C /* Color.c */; };
 		76FAC1901E3F98A0001CCC8C /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */; };
+		76FB150F1F01377200C5377F /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FB150E1F01377200C5377F /* VertexEffect.c */; };
+		76FB15111F0139B400C5377F /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 76FB150E1F01377200C5377F /* VertexEffect.c */; };
 		8262943E1AAF051F00CB7CF7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8262943D1AAF051F00CB7CF7 /* Security.framework */; };
 		BF171245129291EC00B8313A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB012928DE900B8313A /* OpenGLES.framework */; };
 		BF1712471292920000B8313A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BF170DB412928DE900B8313A /* libz.dylib */; };
@@ -335,6 +337,7 @@
 		76F5BD541D2BD7D3005917E5 /* TankExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TankExample.h; sourceTree = "<group>"; };
 		76FAC18A1E3F97D2001CCC8C /* Color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Color.c; path = "../../../spine-c/spine-c/src/spine/Color.c"; sourceTree = "<group>"; };
 		76FAC18B1E3F97D2001CCC8C /* PointAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PointAttachment.c; path = "../../../spine-c/spine-c/src/spine/PointAttachment.c"; sourceTree = "<group>"; };
+		76FB150E1F01377200C5377F /* VertexEffect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = VertexEffect.c; sourceTree = "<group>"; };
 		8262943D1AAF051F00CB7CF7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
 		BF170DB012928DE900B8313A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
 		BF170DB412928DE900B8313A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
@@ -552,6 +555,7 @@
 		76AAA3B21D180F7300C54FCB /* spine */ = {
 			isa = PBXGroup;
 			children = (
+				76FB150E1F01377200C5377F /* VertexEffect.c */,
 				76D520E11EB3625700572471 /* Array.c */,
 				76D520D71EB3611300572471 /* ClippingAttachment.c */,
 				76D520D81EB3611300572471 /* SkeletonClipping.c */,
@@ -803,6 +807,7 @@
 				76F28CB81DEC7EBB00CDE54D /* Bone.c in Sources */,
 				76F28CB61DEC7EBB00CDE54D /* Attachment.c in Sources */,
 				503AE10217EB989F00D1A890 /* RootViewController.mm in Sources */,
+				76FB150F1F01377200C5377F /* VertexEffect.c in Sources */,
 				503AE10117EB989F00D1A890 /* main.m in Sources */,
 				76D520DB1EB3611300572471 /* SkeletonClipping.c in Sources */,
 				76F28CCB1DEC7EBB00CDE54D /* Skin.c in Sources */,
@@ -820,6 +825,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				76FB15111F0139B400C5377F /* VertexEffect.c in Sources */,
 				76D520E71EB3634600572471 /* CoinExample.cpp in Sources */,
 				76D520E31EB3625B00572471 /* Array.c in Sources */,
 				76D520DE1EB3619800572471 /* ClippingAttachment.c in Sources */,

+ 1 - 0
spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj

@@ -179,6 +179,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
     <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraint.c" />
     <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\TransformConstraintData.c" />
     <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\VertexAttachment.c" />
+    <ClCompile Include="..\..\..\spine-c\spine-c\src\spine\VertexEffect.c" />
     <ClCompile Include="..\..\src\spine\AttachmentVertices.cpp" />
     <ClCompile Include="..\..\src\spine\Cocos2dAttachmentLoader.cpp" />
     <ClCompile Include="..\..\src\spine\SkeletonAnimation.cpp" />

+ 156 - 44
spine-cocos2dx/src/spine/SkeletonRenderer.cpp

@@ -77,21 +77,21 @@ void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsS
 }
 
 SkeletonRenderer::SkeletonRenderer ()
-	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) {
+	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
 }
 
 SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkeletonData)
-	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) {
+	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
 	initWithData(skeletonData, ownsSkeletonData);
 }
 
 SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale)
-	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) {
+	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
 	initWithJsonFile(skeletonDataFile, atlas, scale);
 }
 
 SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale)
-	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1) {
+	: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _timeScale(1), _effect(nullptr) {
 	initWithJsonFile(skeletonDataFile, atlasFile, scale);
 }
 
@@ -183,6 +183,8 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
 	SkeletonBatch* batch = SkeletonBatch::getInstance();
 	SkeletonTwoColorBatch* twoColorBatch = SkeletonTwoColorBatch::getInstance();
 	bool isTwoColorTint = this->isTwoColorTint();
+	
+	if (_effect) _effect->begin(_effect, _skeleton);
 
 	Color4F nodeColor;
 	nodeColor.r = getDisplayedColor().r / (float)255;
@@ -321,26 +323,70 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
 				
 				float* verts = _clipper->clippedVertices->items;
 				float* uvs = _clipper->clippedUVs->items;
-				for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
-					V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
-					vertex->vertices.x = verts[vv];
-					vertex->vertices.y = verts[vv + 1];
-					vertex->texCoords.u = uvs[vv];
-					vertex->texCoords.v = uvs[vv + 1];
-					vertex->colors.r = (GLubyte)color.r;
-					vertex->colors.g = (GLubyte)color.g;
-					vertex->colors.b = (GLubyte)color.b;
-					vertex->colors.a = (GLubyte)color.a;
+				if (_effect) {
+					spColor light;
+					spColor dark;
+					light.r = color.r / 255.0f;
+					light.g = color.g / 255.0f;
+					light.b = color.b / 255.0f;
+					light.a = color.a / 255.0f;
+					dark.r = dark.g = dark.b = dark.a = 0;
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
+						V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						spColor lightCopy = light;
+						spColor darkCopy = dark;
+						vertex->vertices.x = verts[vv];
+						vertex->vertices.y = verts[vv + 1];
+						vertex->texCoords.u = uvs[vv];
+						vertex->texCoords.v = uvs[vv + 1];
+						_effect->transform(_effect, &vertex->vertices.x, &vertex->vertices.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
+						vertex->colors.r = (GLubyte)(lightCopy.r * 255);
+						vertex->colors.g = (GLubyte)(lightCopy.g * 255);
+						vertex->colors.b = (GLubyte)(lightCopy.b * 255);
+						vertex->colors.a = (GLubyte)(lightCopy.a * 255);
+					}
+				} else {
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv+=2) {
+						V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						vertex->vertices.x = verts[vv];
+						vertex->vertices.y = verts[vv + 1];
+						vertex->texCoords.u = uvs[vv];
+						vertex->texCoords.v = uvs[vv + 1];
+						vertex->colors.r = (GLubyte)color.r;
+						vertex->colors.g = (GLubyte)color.g;
+						vertex->colors.b = (GLubyte)color.b;
+						vertex->colors.a = (GLubyte)color.a;
+					}
 				}
 			} else {
 				cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
 				
-				for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
-					V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
-					vertex->colors.r = (GLubyte)color.r;
-					vertex->colors.g = (GLubyte)color.g;
-					vertex->colors.b = (GLubyte)color.b;
-					vertex->colors.a = (GLubyte)color.a;
+				if (_effect) {
+					spColor light;
+					spColor dark;
+					light.r = color.r / 255.0f;
+					light.g = color.g / 255.0f;
+					light.b = color.b / 255.0f;
+					light.a = color.a / 255.0f;
+					dark.r = dark.g = dark.b = dark.a = 0;
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
+						V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						spColor lightCopy = light;
+						spColor darkCopy = dark;
+						_effect->transform(_effect, &vertex->vertices.x, &vertex->vertices.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
+						vertex->colors.r = (GLubyte)(lightCopy.r * 255);
+						vertex->colors.g = (GLubyte)(lightCopy.g * 255);
+						vertex->colors.b = (GLubyte)(lightCopy.b * 255);
+						vertex->colors.a = (GLubyte)(lightCopy.a * 255);
+					}
+				} else {
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
+						V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						vertex->colors.r = (GLubyte)color.r;
+						vertex->colors.g = (GLubyte)color.g;
+						vertex->colors.b = (GLubyte)color.b;
+						vertex->colors.a = (GLubyte)color.a;
+					}
 				}
 			}
 		} else {
@@ -361,34 +407,94 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
 				
 				float* verts = _clipper->clippedVertices->items;
 				float* uvs = _clipper->clippedUVs->items;
-				for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
-					V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
-					vertex->position.x = verts[vv];
-					vertex->position.y = verts[vv + 1];
-					vertex->texCoords.u = uvs[vv];
-					vertex->texCoords.v = uvs[vv + 1];
-					vertex->color.r = (GLubyte)color.r;
-					vertex->color.g = (GLubyte)color.g;
-					vertex->color.b = (GLubyte)color.b;
-					vertex->color.a = (GLubyte)color.a;
-					vertex->color2.r = (GLubyte)darkColor.r;
-					vertex->color2.g = (GLubyte)darkColor.g;
-					vertex->color2.b = (GLubyte)darkColor.b;
-					vertex->color2.a = 1;
+				
+				if (_effect) {
+					spColor light;
+					spColor dark;
+					light.r = color.r / 255.0f;
+					light.g = color.g / 255.0f;
+					light.b = color.b / 255.0f;
+					light.a = color.a / 255.0f;
+					dark.r = darkColor.r / 255.0f;
+					dark.g = darkColor.g / 255.0f;
+					dark.b = darkColor.b / 255.0f;
+					dark.a = darkColor.a / 255.0f;
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
+						V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						spColor lightCopy = light;
+						spColor darkCopy = dark;
+						vertex->position.x = verts[vv];
+						vertex->position.y = verts[vv + 1];
+						vertex->texCoords.u = uvs[vv];
+						vertex->texCoords.v = uvs[vv + 1];
+						_effect->transform(_effect, &vertex->position.x, &vertex->position.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
+						vertex->color.r = (GLubyte)(lightCopy.r * 255);
+						vertex->color.g = (GLubyte)(lightCopy.g * 255);
+						vertex->color.b = (GLubyte)(lightCopy.b * 255);
+						vertex->color.a = (GLubyte)(lightCopy.a * 255);
+						vertex->color2.r = (GLubyte)(darkCopy.r * 255);
+						vertex->color2.g = (GLubyte)(darkCopy.g * 255);
+						vertex->color2.b = (GLubyte)(darkCopy.b * 255);
+						vertex->color2.a = 1;
+					}
+				} else {
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2) {
+						V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						vertex->position.x = verts[vv];
+						vertex->position.y = verts[vv + 1];
+						vertex->texCoords.u = uvs[vv];
+						vertex->texCoords.v = uvs[vv + 1];
+						vertex->color.r = (GLubyte)color.r;
+						vertex->color.g = (GLubyte)color.g;
+						vertex->color.b = (GLubyte)color.b;
+						vertex->color.a = (GLubyte)color.a;
+						vertex->color2.r = (GLubyte)darkColor.r;
+						vertex->color2.g = (GLubyte)darkColor.g;
+						vertex->color2.b = (GLubyte)darkColor.b;
+						vertex->color2.a = 1;
+					}
 				}
 			} else {
 				TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
 				
-				for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
-					V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
-					vertex->color.r = (GLubyte)color.r;
-					vertex->color.g = (GLubyte)color.g;
-					vertex->color.b = (GLubyte)color.b;
-					vertex->color.a = (GLubyte)color.a;
-					vertex->color2.r = (GLubyte)darkColor.r;
-					vertex->color2.g = (GLubyte)darkColor.g;
-					vertex->color2.b = (GLubyte)darkColor.b;
-					vertex->color2.a = 1;
+				if (_effect) {
+					spColor light;
+					spColor dark;
+					light.r = color.r / 255.0f;
+					light.g = color.g / 255.0f;
+					light.b = color.b / 255.0f;
+					light.a = color.a / 255.0f;
+					dark.r = darkColor.r / 255.0f;
+					dark.g = darkColor.g / 255.0f;
+					dark.b = darkColor.b / 255.0f;
+					dark.a = darkColor.a / 255.0f;
+					
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
+						V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						spColor lightCopy = light;
+						spColor darkCopy = dark;
+						_effect->transform(_effect, &vertex->position.x, &vertex->position.y, &vertex->texCoords.u, &vertex->texCoords.v, &lightCopy, &darkCopy);
+						vertex->color.r = (GLubyte)(lightCopy.r * 255);
+						vertex->color.g = (GLubyte)(lightCopy.g * 255);
+						vertex->color.b = (GLubyte)(lightCopy.b * 255);
+						vertex->color.a = (GLubyte)(lightCopy.a * 255);
+						vertex->color2.r = (GLubyte)(darkCopy.r * 255);
+						vertex->color2.g = (GLubyte)(darkCopy.g * 255);
+						vertex->color2.b = (GLubyte)(darkCopy.b * 255);
+						vertex->color2.a = 1;
+					}
+				} else {
+					for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v) {
+						V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts + v;
+						vertex->color.r = (GLubyte)color.r;
+						vertex->color.g = (GLubyte)color.g;
+						vertex->color.b = (GLubyte)color.b;
+						vertex->color.a = (GLubyte)color.a;
+						vertex->color2.r = (GLubyte)darkColor.r;
+						vertex->color2.g = (GLubyte)darkColor.g;
+						vertex->color2.b = (GLubyte)darkColor.b;
+						vertex->color2.a = 1;
+					}
 				}
 			}
 		}
@@ -432,6 +538,8 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
 			}
 		}
 	}
+	
+	if (_effect) _effect->end(_effect);
 
 	if (_debugSlots || _debugBones || _debugMeshes) {
         drawDebug(renderer, transform, transformFlags);
@@ -595,6 +703,10 @@ void SkeletonRenderer::setTwoColorTint(bool enabled) {
 bool SkeletonRenderer::isTwoColorTint() {
 	return getGLProgramState() == SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState();
 }
+	
+void SkeletonRenderer::setVertexEffect(spVertexEffect *effect) {
+	this->_effect = effect;
+}
 
 spSkeleton* SkeletonRenderer::getSkeleton () {
 	return _skeleton;

+ 5 - 1
spine-cocos2dx/src/spine/SkeletonRenderer.h

@@ -99,6 +99,9 @@ public:
 	void setTwoColorTint(bool enabled);
 	/* Whether two color tinting is enabled */
 	bool isTwoColorTint();
+	
+	/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
+	void setVertexEffect(spVertexEffect* effect);
 
     // --- BlendProtocol
     virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc)override;
@@ -125,7 +128,7 @@ CC_CONSTRUCTOR_ACCESS:
 protected:
 	void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData);
 	virtual AttachmentVertices* getAttachmentVertices (spRegionAttachment* attachment) const;
-	virtual AttachmentVertices* getAttachmentVertices (spMeshAttachment* attachment) const;
+	virtual AttachmentVertices* getAttachmentVertices (spMeshAttachment* attachment) const;	
 
 	bool _ownsSkeletonData;
 	spAtlas* _atlas;
@@ -140,6 +143,7 @@ protected:
 	bool _debugBones;
 	bool _debugMeshes;
 	spSkeletonClipping* _clipper;
+	spVertexEffect* _effect;
 };
 
 }

+ 1 - 0
spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java

@@ -39,6 +39,7 @@ import com.badlogic.gdx.graphics.OrthographicCamera;
 import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
 import com.badlogic.gdx.graphics.g2d.TextureAtlas;
 import com.badlogic.gdx.math.Interpolation;
+import com.esotericsoftware.spine.vertexeffects.JitterEffect;
 import com.esotericsoftware.spine.vertexeffects.SwirlEffect;
 
 public class VertexEffectTest extends ApplicationAdapter {

+ 1 - 0
spine-sfml/CMakeLists.txt

@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 2.8.9)
 #
 # First download and extract SFML 2.3.2 for the respective OS we are on
 #

+ 13 - 1
spine-sfml/example/main.cpp

@@ -204,6 +204,10 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) {
 	SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData);
 	drawable->timeScale = 1;
 
+	spSwirlVertexEffect* effect = spSwirlVertexEffect_create(400);
+	effect->centerY = -200;
+	drawable->vertexEffect = &effect->super;
+
 	Skeleton* skeleton = drawable->skeleton;
 	skeleton->x = 320;
 	skeleton->y = 590;
@@ -216,6 +220,7 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) {
 	window.setFramerateLimit(60);
 	sf::Event event;
 	sf::Clock deltaClock;
+	float swirlTime = 0;
 	while (window.isOpen()) {
 		while (window.pollEvent(event))
 			if (event.type == sf::Event::Closed) window.close();
@@ -223,12 +228,18 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) {
 		float delta = deltaClock.getElapsedTime().asSeconds();
 		deltaClock.restart();
 
+		swirlTime += delta;
+		float percent = fmod(swirlTime, 2);
+		if (percent > 1) percent = 1 - (percent - 1);
+		effect->angle = _spMath_interpolate(_spMath_pow2_apply, -60, 60, percent);
+
 		drawable->update(delta);
 
 		window.clear();
 		window.draw(*drawable);
 		window.display();
 	}
+	spSwirlVertexEffect_dispose(effect);
 }
 
 void tank (SkeletonData* skeletonData, Atlas* atlas) {
@@ -338,6 +349,7 @@ void coin (SkeletonData* skeletonData, Atlas* atlas) {
 	window.setFramerateLimit(60);
 	sf::Event event;
 	sf::Clock deltaClock;
+	float swirlTime = 0;
 	while (window.isOpen()) {
 		while (window.pollEvent(event))
 			if (event.type == sf::Event::Closed) window.close();
@@ -384,7 +396,7 @@ int main () {
 	testcase(test, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 1.0f);
 	testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin.atlas", 0.5f);
 	testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine.atlas", 0.5f);
-	testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 0.2f);
+	testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 0.2f);*/
 	testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor.atlas", 0.5f);
 	testcase(spineboy, "data/spineboy-ess.json", "data/spineboy-ess.skel", "data/spineboy.atlas", 0.6f);
 	testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins.atlas", 1.4f);

+ 60 - 7
spine-sfml/src/spine/spine-sfml.cpp

@@ -36,6 +36,8 @@
 
 using namespace sf;
 
+_SP_ARRAY_IMPLEMENT_TYPE(spColorArray, spColor)
+
 void _AtlasPage_createTexture (AtlasPage* self, const char* path){
 	Texture* texture = new Texture();
 	if (!texture->loadFromFile(path)) return;
@@ -64,10 +66,13 @@ namespace spine {
 SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) :
 		timeScale(1),
 		vertexArray(new VertexArray(Triangles, skeletonData->bonesCount * 4)),
+		vertexEffect(0),
 		worldVertices(0), clipper(0) {
 	Bone_setYDown(true);
 	worldVertices = MALLOC(float, SPINE_MESH_VERTEX_COUNT_MAX);
 	skeleton = Skeleton_create(skeletonData);
+	tempUvs = spFloatArray_create(16);
+	tempColors = spColorArray_create(16);
 
 	ownsAnimationStateData = stateData == 0;
 	if (ownsAnimationStateData) stateData = AnimationStateData_create(skeletonData);
@@ -84,6 +89,8 @@ SkeletonDrawable::~SkeletonDrawable () {
 	AnimationState_dispose(state);
 	Skeleton_dispose(skeleton);
 	spSkeletonClipping_dispose(clipper);
+	spFloatArray_dispose(tempUvs);
+	spColorArray_dispose(tempColors);
 }
 
 void SkeletonDrawable::update (float deltaTime) {
@@ -98,6 +105,8 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
 	states.texture = 0;
 	unsigned short quadIndices[6] = { 0, 1, 2, 2, 3, 0 };
 
+	if (vertexEffect != 0) vertexEffect->begin(vertexEffect, skeleton);
+
 	sf::Vertex vertex;
 	Texture* texture = 0;
 	for (int i = 0; i < skeleton->slotsCount; ++i) {
@@ -147,6 +156,12 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
 		vertex.color.b = b;
 		vertex.color.a = a;
 
+		spColor light;
+		light.r = r / 255.0f;
+		light.g = g / 255.0f;
+		light.b = b / 255.0f;
+		light.a = a / 255.0f;
+
 		sf::BlendMode blend;
 		switch (slot->data->blendMode) {
 			case BLEND_MODE_ADDITIVE:
@@ -179,19 +194,57 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
 		}
 
 		Vector2u size = texture->getSize();
-		for (int i = 0; i < indicesCount; ++i) {
-			int index = indices[i] << 1;
-			vertex.position.x = vertices[index];
-			vertex.position.y = vertices[index + 1];
-			vertex.texCoords.x = uvs[index] * size.x;
-			vertex.texCoords.y = uvs[index + 1] * size.y;
-			vertexArray->append(vertex);
+
+		if (vertexEffect != 0) {
+			spFloatArray_clear(tempUvs);
+			spColorArray_clear(tempColors);
+			for (int i = 0; i < verticesCount; i++) {
+				spColor vertexColor = light;
+				spColor dark;
+				dark.r = dark.g = dark.b = dark.a = 0;
+				int index = i << 1;
+				float x = vertices[index];
+				float y = vertices[index + 1];
+				float u = uvs[index];
+				float v = uvs[index + 1];
+				vertexEffect->transform(vertexEffect, &x, &y, &u, &v, &vertexColor, &dark);
+				vertices[index] = x;
+				vertices[index + 1] = y;
+				spFloatArray_add(tempUvs, u);
+				spFloatArray_add(tempUvs, v);
+				spColorArray_add(tempColors, vertexColor);
+			}
+
+			for (int i = 0; i < indicesCount; ++i) {
+				int index = indices[i] << 1;
+				vertex.position.x = vertices[index];
+				vertex.position.y = vertices[index + 1];
+				vertex.texCoords.x = uvs[index] * size.x;
+				vertex.texCoords.y = uvs[index + 1] * size.y;
+				spColor vertexColor = tempColors->items[index >> 1];
+				vertex.color.r = static_cast<Uint8>(vertexColor.r * 255);
+				vertex.color.g = static_cast<Uint8>(vertexColor.g * 255);
+				vertex.color.b = static_cast<Uint8>(vertexColor.b * 255);
+				vertex.color.a = static_cast<Uint8>(vertexColor.a * 255);
+				vertexArray->append(vertex);
+			}
+		} else {
+			for (int i = 0; i < indicesCount; ++i) {
+				int index = indices[i] << 1;
+				vertex.position.x = vertices[index];
+				vertex.position.y = vertices[index + 1];
+				vertex.texCoords.x = uvs[index] * size.x;
+				vertex.texCoords.y = uvs[index + 1] * size.y;
+				vertexArray->append(vertex);
+			}
 		}
 
 		spSkeletonClipping_clipEnd(clipper, slot);
 	}
 	target.draw(*vertexArray, states);
 	spSkeletonClipping_clipEnd2(clipper);
+
+	if (vertexEffect != 0) vertexEffect->end(vertexEffect);
 }
 
 } /* namespace spine */

+ 5 - 0
spine-sfml/src/spine/spine-sfml.h

@@ -40,6 +40,8 @@
 #include <SFML/Graphics/RenderTarget.hpp>
 #include <SFML/Graphics/RenderStates.hpp>
 
+_SP_ARRAY_DECLARE_TYPE(spColorArray, spColor)
+
 namespace spine {
 
 class SkeletonDrawable: public sf::Drawable {
@@ -48,6 +50,7 @@ public:
 	AnimationState* state;
 	float timeScale;
 	sf::VertexArray* vertexArray;
+	spVertexEffect* vertexEffect;
 
 	SkeletonDrawable (SkeletonData* skeleton, AnimationStateData* stateData = 0);
 	~SkeletonDrawable ();
@@ -58,6 +61,8 @@ public:
 private:
 	bool ownsAnimationStateData;
 	float* worldVertices;
+	spFloatArray* tempUvs;
+	spColorArray* tempColors;
 	spSkeletonClipping* clipper;
 };
 

+ 300 - 296
spine-ts/build/spine-all.d.ts

@@ -1,97 +1,3 @@
-declare module spine {
-	class AssetManager implements Disposable {
-		private pathPrefix;
-		private textureLoader;
-		private assets;
-		private errors;
-		private toLoad;
-		private loaded;
-		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
-		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		get(path: string): any;
-		remove(path: string): void;
-		removeAll(): void;
-		isLoadingComplete(): boolean;
-		getToLoad(): number;
-		getLoaded(): number;
-		dispose(): void;
-		hasErrors(): boolean;
-		getErrors(): Map<string>;
-	}
-}
-declare module spine.canvas {
-	class AssetManager extends spine.AssetManager {
-		constructor(pathPrefix?: string);
-	}
-}
-declare module spine {
-	abstract class Texture {
-		protected _image: HTMLImageElement;
-		constructor(image: HTMLImageElement);
-		getImage(): HTMLImageElement;
-		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		abstract dispose(): void;
-		static filterFromString(text: string): TextureFilter;
-		static wrapFromString(text: string): TextureWrap;
-	}
-	enum TextureFilter {
-		Nearest = 9728,
-		Linear = 9729,
-		MipMap = 9987,
-		MipMapNearestNearest = 9984,
-		MipMapLinearNearest = 9985,
-		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
-	}
-	enum TextureWrap {
-		MirroredRepeat = 33648,
-		ClampToEdge = 33071,
-		Repeat = 10497,
-	}
-	class TextureRegion {
-		renderObject: any;
-		u: number;
-		v: number;
-		u2: number;
-		v2: number;
-		width: number;
-		height: number;
-		rotate: boolean;
-		offsetX: number;
-		offsetY: number;
-		originalWidth: number;
-		originalHeight: number;
-	}
-}
-declare module spine.canvas {
-	class CanvasTexture extends Texture {
-		constructor(image: HTMLImageElement);
-		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		dispose(): void;
-	}
-}
-declare module spine.canvas {
-	class SkeletonRenderer {
-		static QUAD_TRIANGLES: number[];
-		static VERTEX_SIZE: number;
-		private ctx;
-		triangleRendering: boolean;
-		debugRendering: boolean;
-		private vertices;
-		private tempColor;
-		constructor(context: CanvasRenderingContext2D);
-		draw(skeleton: Skeleton): void;
-		private drawImages(skeleton);
-		private drawTriangles(skeleton);
-		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
-		private computeRegionVertices(slot, region, pma);
-		private computeMeshVertices(slot, mesh, pma);
-	}
-}
 declare module spine {
 	class Animation {
 		name: string;
@@ -459,35 +365,32 @@ declare module spine {
 	}
 }
 declare module spine {
-	class AtlasAttachmentLoader implements AttachmentLoader {
-		atlas: TextureAtlas;
-		constructor(atlas: TextureAtlas);
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	class AssetManager implements Disposable {
+		private pathPrefix;
+		private textureLoader;
+		private assets;
+		private errors;
+		private toLoad;
+		private loaded;
+		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
+		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
+		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		get(path: string): any;
+		remove(path: string): void;
+		removeAll(): void;
+		isLoadingComplete(): boolean;
+		getToLoad(): number;
+		getLoaded(): number;
+		dispose(): void;
+		hasErrors(): boolean;
+		getErrors(): Map<string>;
 	}
 }
 declare module spine {
-	interface AttachmentLoader {
+	class AtlasAttachmentLoader implements AttachmentLoader {
+		atlas: TextureAtlas;
+		constructor(atlas: TextureAtlas);
 		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
 		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
@@ -496,130 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1005,6 +784,46 @@ declare module spine {
 		constructor(index: number, name: string, boneData: BoneData);
 	}
 }
+declare module spine {
+	abstract class Texture {
+		protected _image: HTMLImageElement;
+		constructor(image: HTMLImageElement);
+		getImage(): HTMLImageElement;
+		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		abstract dispose(): void;
+		static filterFromString(text: string): TextureFilter;
+		static wrapFromString(text: string): TextureWrap;
+	}
+	enum TextureFilter {
+		Nearest = 9728,
+		Linear = 9729,
+		MipMap = 9987,
+		MipMapNearestNearest = 9984,
+		MipMapLinearNearest = 9985,
+		MipMapNearestLinear = 9986,
+		MipMapLinearLinear = 9987,
+	}
+	enum TextureWrap {
+		MirroredRepeat = 33648,
+		ClampToEdge = 33071,
+		Repeat = 10497,
+	}
+	class TextureRegion {
+		renderObject: any;
+		u: number;
+		v: number;
+		u2: number;
+		v2: number;
+		width: number;
+		height: number;
+		rotate: boolean;
+		offsetX: number;
+		offsetY: number;
+		originalWidth: number;
+		originalHeight: number;
+	}
+}
 declare module spine {
 	class TextureAtlas implements Disposable {
 		pages: TextureAtlasPage[];
@@ -1222,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;
@@ -1247,52 +1216,35 @@ declare module spine {
 		end(): void;
 	}
 }
-declare module spine.threejs {
+declare module spine.canvas {
 	class AssetManager extends spine.AssetManager {
 		constructor(pathPrefix?: string);
 	}
 }
-declare module spine.threejs {
-	class MeshBatcher {
-		mesh: THREE.Mesh;
-		private static VERTEX_SIZE;
-		private vertexBuffer;
-		private vertices;
-		private verticesLength;
-		private indices;
-		private indicesLength;
-		constructor(mesh: THREE.Mesh, maxVertices?: number);
-		begin(): void;
-		batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
-		end(): void;
+declare module spine.canvas {
+	class CanvasTexture extends Texture {
+		constructor(image: HTMLImageElement);
+		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		dispose(): void;
 	}
 }
-declare module spine.threejs {
-	class SkeletonMesh extends THREE.Mesh {
-		skeleton: Skeleton;
-		state: AnimationState;
-		zOffset: number;
-		vertexEffect: VertexEffect;
-		private batcher;
-		private clipper;
+declare module spine.canvas {
+	class SkeletonRenderer {
 		static QUAD_TRIANGLES: number[];
 		static VERTEX_SIZE: number;
+		private ctx;
+		triangleRendering: boolean;
+		debugRendering: boolean;
 		private vertices;
 		private tempColor;
-		constructor(skeletonData: SkeletonData);
-		update(deltaTime: number): void;
-		private updateGeometry();
-	}
-}
-declare module spine.threejs {
-	class ThreeJsTexture extends Texture {
-		texture: THREE.Texture;
-		constructor(image: HTMLImageElement);
-		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		dispose(): void;
-		static toThreeJsTextureFilter(filter: TextureFilter): THREE.TextureFilter;
-		static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping;
+		constructor(context: CanvasRenderingContext2D);
+		draw(skeleton: Skeleton): void;
+		private drawImages(skeleton);
+		private drawTriangles(skeleton);
+		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
+		private computeRegionVertices(slot, region, pma);
+		private computeMeshVertices(slot, mesh, pma);
 	}
 }
 declare module spine.webgl {
@@ -1386,22 +1338,22 @@ declare module spine.webgl {
 	}
 }
 declare module spine.webgl {
-	const M00: number;
-	const M01: number;
-	const M02: number;
-	const M03: number;
-	const M10: number;
-	const M11: number;
-	const M12: number;
-	const M13: number;
-	const M20: number;
-	const M21: number;
-	const M22: number;
-	const M23: number;
-	const M30: number;
-	const M31: number;
-	const M32: number;
-	const M33: number;
+	const M00 = 0;
+	const M01 = 4;
+	const M02 = 8;
+	const M03 = 12;
+	const M10 = 1;
+	const M11 = 5;
+	const M12 = 9;
+	const M13 = 13;
+	const M20 = 2;
+	const M21 = 6;
+	const M22 = 10;
+	const M23 = 14;
+	const M30 = 3;
+	const M31 = 7;
+	const M32 = 11;
+	const M33 = 15;
 	class Matrix4 {
 		temp: Float32Array;
 		values: Float32Array;
@@ -1725,6 +1677,58 @@ declare module spine.webgl {
 		static getSourceGLBlendMode(blendMode: BlendMode, premultipliedAlpha?: boolean): number;
 	}
 }
+declare module spine.threejs {
+	class AssetManager extends spine.AssetManager {
+		constructor(pathPrefix?: string);
+	}
+}
+declare module spine.threejs {
+	class MeshBatcher {
+		mesh: THREE.Mesh;
+		private static VERTEX_SIZE;
+		private vertexBuffer;
+		private vertices;
+		private verticesLength;
+		private indices;
+		private indicesLength;
+		constructor(mesh: THREE.Mesh, maxVertices?: number);
+		begin(): void;
+		batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z?: number): void;
+		end(): void;
+	}
+}
+declare module spine.threejs {
+	class SkeletonMesh extends THREE.Mesh {
+		tempPos: Vector2;
+		tempUv: Vector2;
+		tempLight: Color;
+		tempDark: Color;
+		skeleton: Skeleton;
+		state: AnimationState;
+		zOffset: number;
+		vertexEffect: VertexEffect;
+		private batcher;
+		private clipper;
+		static QUAD_TRIANGLES: number[];
+		static VERTEX_SIZE: number;
+		private vertices;
+		private tempColor;
+		constructor(skeletonData: SkeletonData);
+		update(deltaTime: number): void;
+		private updateGeometry();
+	}
+}
+declare module spine.threejs {
+	class ThreeJsTexture extends Texture {
+		texture: THREE.Texture;
+		constructor(image: HTMLImageElement);
+		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		dispose(): void;
+		static toThreeJsTextureFilter(filter: TextureFilter): THREE.TextureFilter;
+		static toThreeJsTextureWrap(wrap: TextureWrap): THREE.Wrapping;
+	}
+}
 declare module spine {
 	class SpineWidget {
 		skeleton: Skeleton;

File diff suppressed because it is too large
+ 272 - 936
spine-ts/build/spine-all.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 244 - 244
spine-ts/build/spine-canvas.d.ts

@@ -1,97 +1,3 @@
-declare module spine {
-	class AssetManager implements Disposable {
-		private pathPrefix;
-		private textureLoader;
-		private assets;
-		private errors;
-		private toLoad;
-		private loaded;
-		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
-		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		get(path: string): any;
-		remove(path: string): void;
-		removeAll(): void;
-		isLoadingComplete(): boolean;
-		getToLoad(): number;
-		getLoaded(): number;
-		dispose(): void;
-		hasErrors(): boolean;
-		getErrors(): Map<string>;
-	}
-}
-declare module spine.canvas {
-	class AssetManager extends spine.AssetManager {
-		constructor(pathPrefix?: string);
-	}
-}
-declare module spine {
-	abstract class Texture {
-		protected _image: HTMLImageElement;
-		constructor(image: HTMLImageElement);
-		getImage(): HTMLImageElement;
-		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		abstract dispose(): void;
-		static filterFromString(text: string): TextureFilter;
-		static wrapFromString(text: string): TextureWrap;
-	}
-	enum TextureFilter {
-		Nearest = 9728,
-		Linear = 9729,
-		MipMap = 9987,
-		MipMapNearestNearest = 9984,
-		MipMapLinearNearest = 9985,
-		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987,
-	}
-	enum TextureWrap {
-		MirroredRepeat = 33648,
-		ClampToEdge = 33071,
-		Repeat = 10497,
-	}
-	class TextureRegion {
-		renderObject: any;
-		u: number;
-		v: number;
-		u2: number;
-		v2: number;
-		width: number;
-		height: number;
-		rotate: boolean;
-		offsetX: number;
-		offsetY: number;
-		originalWidth: number;
-		originalHeight: number;
-	}
-}
-declare module spine.canvas {
-	class CanvasTexture extends Texture {
-		constructor(image: HTMLImageElement);
-		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		dispose(): void;
-	}
-}
-declare module spine.canvas {
-	class SkeletonRenderer {
-		static QUAD_TRIANGLES: number[];
-		static VERTEX_SIZE: number;
-		private ctx;
-		triangleRendering: boolean;
-		debugRendering: boolean;
-		private vertices;
-		private tempColor;
-		constructor(context: CanvasRenderingContext2D);
-		draw(skeleton: Skeleton): void;
-		private drawImages(skeleton);
-		private drawTriangles(skeleton);
-		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
-		private computeRegionVertices(slot, region, pma);
-		private computeMeshVertices(slot, mesh, pma);
-	}
-}
 declare module spine {
 	class Animation {
 		name: string;
@@ -459,35 +365,32 @@ declare module spine {
 	}
 }
 declare module spine {
-	class AtlasAttachmentLoader implements AttachmentLoader {
-		atlas: TextureAtlas;
-		constructor(atlas: TextureAtlas);
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	class AssetManager implements Disposable {
+		private pathPrefix;
+		private textureLoader;
+		private assets;
+		private errors;
+		private toLoad;
+		private loaded;
+		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
+		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
+		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		get(path: string): any;
+		remove(path: string): void;
+		removeAll(): void;
+		isLoadingComplete(): boolean;
+		getToLoad(): number;
+		getLoaded(): number;
+		dispose(): void;
+		hasErrors(): boolean;
+		getErrors(): Map<string>;
 	}
 }
 declare module spine {
-	interface AttachmentLoader {
+	class AtlasAttachmentLoader implements AttachmentLoader {
+		atlas: TextureAtlas;
+		constructor(atlas: TextureAtlas);
 		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
 		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
@@ -496,130 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1005,6 +784,46 @@ declare module spine {
 		constructor(index: number, name: string, boneData: BoneData);
 	}
 }
+declare module spine {
+	abstract class Texture {
+		protected _image: HTMLImageElement;
+		constructor(image: HTMLImageElement);
+		getImage(): HTMLImageElement;
+		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		abstract dispose(): void;
+		static filterFromString(text: string): TextureFilter;
+		static wrapFromString(text: string): TextureWrap;
+	}
+	enum TextureFilter {
+		Nearest = 9728,
+		Linear = 9729,
+		MipMap = 9987,
+		MipMapNearestNearest = 9984,
+		MipMapLinearNearest = 9985,
+		MipMapNearestLinear = 9986,
+		MipMapLinearLinear = 9987,
+	}
+	enum TextureWrap {
+		MirroredRepeat = 33648,
+		ClampToEdge = 33071,
+		Repeat = 10497,
+	}
+	class TextureRegion {
+		renderObject: any;
+		u: number;
+		v: number;
+		u2: number;
+		v2: number;
+		width: number;
+		height: number;
+		rotate: boolean;
+		offsetX: number;
+		offsetY: number;
+		originalWidth: number;
+		originalHeight: number;
+	}
+}
 declare module spine {
 	class TextureAtlas implements Disposable {
 		pages: TextureAtlasPage[];
@@ -1222,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;
@@ -1247,3 +1216,34 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine.canvas {
+	class AssetManager extends spine.AssetManager {
+		constructor(pathPrefix?: string);
+	}
+}
+declare module spine.canvas {
+	class CanvasTexture extends Texture {
+		constructor(image: HTMLImageElement);
+		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		dispose(): void;
+	}
+}
+declare module spine.canvas {
+	class SkeletonRenderer {
+		static QUAD_TRIANGLES: number[];
+		static VERTEX_SIZE: number;
+		private ctx;
+		triangleRendering: boolean;
+		debugRendering: boolean;
+		private vertices;
+		private tempColor;
+		constructor(context: CanvasRenderingContext2D);
+		draw(skeleton: Skeleton): void;
+		private drawImages(skeleton);
+		private drawTriangles(skeleton);
+		private drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
+		private computeRegionVertices(slot, region, pma);
+		private computeMeshVertices(slot, mesh, pma);
+	}
+}

File diff suppressed because it is too large
+ 272 - 936
spine-ts/build/spine-canvas.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 150 - 150
spine-ts/build/spine-core.d.ts

@@ -399,156 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-	}
-}
-declare module spine {
-	interface AttachmentLoader {
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1191,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;

File diff suppressed because it is too large
+ 417 - 761
spine-ts/build/spine-core.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 154 - 150
spine-ts/build/spine-threejs.d.ts

@@ -399,156 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-	}
-}
-declare module spine {
-	interface AttachmentLoader {
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1191,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;
@@ -1238,6 +1238,10 @@ declare module spine.threejs {
 }
 declare module spine.threejs {
 	class SkeletonMesh extends THREE.Mesh {
+		tempPos: Vector2;
+		tempUv: Vector2;
+		tempLight: Color;
+		tempDark: Color;
 		skeleton: Skeleton;
 		state: AnimationState;
 		zOffset: number;

File diff suppressed because it is too large
+ 417 - 761
spine-ts/build/spine-threejs.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 166 - 166
spine-ts/build/spine-webgl.d.ts

@@ -399,156 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-	}
-}
-declare module spine {
-	interface AttachmentLoader {
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1191,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;
@@ -1307,22 +1307,22 @@ declare module spine.webgl {
 	}
 }
 declare module spine.webgl {
-	const M00: number;
-	const M01: number;
-	const M02: number;
-	const M03: number;
-	const M10: number;
-	const M11: number;
-	const M12: number;
-	const M13: number;
-	const M20: number;
-	const M21: number;
-	const M22: number;
-	const M23: number;
-	const M30: number;
-	const M31: number;
-	const M32: number;
-	const M33: number;
+	const M00 = 0;
+	const M01 = 4;
+	const M02 = 8;
+	const M03 = 12;
+	const M10 = 1;
+	const M11 = 5;
+	const M12 = 9;
+	const M13 = 13;
+	const M20 = 2;
+	const M21 = 6;
+	const M22 = 10;
+	const M23 = 14;
+	const M30 = 3;
+	const M31 = 7;
+	const M32 = 11;
+	const M33 = 15;
 	class Matrix4 {
 		temp: Float32Array;
 		values: Float32Array;

File diff suppressed because it is too large
+ 417 - 761
spine-ts/build/spine-webgl.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 166 - 166
spine-ts/build/spine-widget.d.ts

@@ -399,156 +399,6 @@ declare module spine {
 		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
-declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-	}
-}
-declare module spine {
-	interface AttachmentLoader {
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
-}
-declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5,
-	}
-}
-declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
-}
-declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
-}
-declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
-}
-declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
-}
 declare module spine {
 	enum BlendMode {
 		Normal = 0,
@@ -1191,6 +1041,156 @@ declare module spine {
 		end(): void;
 	}
 }
+declare module spine {
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		private static nextID;
+		id: number;
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
+}
+declare module spine {
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
+}
+declare module spine {
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
+}
+declare module spine {
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
+}
+declare module spine {
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
+}
+declare module spine {
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
+}
+declare module spine {
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
+}
 declare module spine {
 	class JitterEffect implements VertexEffect {
 		jitterX: number;
@@ -1307,22 +1307,22 @@ declare module spine.webgl {
 	}
 }
 declare module spine.webgl {
-	const M00: number;
-	const M01: number;
-	const M02: number;
-	const M03: number;
-	const M10: number;
-	const M11: number;
-	const M12: number;
-	const M13: number;
-	const M20: number;
-	const M21: number;
-	const M22: number;
-	const M23: number;
-	const M30: number;
-	const M31: number;
-	const M32: number;
-	const M33: number;
+	const M00 = 0;
+	const M01 = 4;
+	const M02 = 8;
+	const M03 = 12;
+	const M10 = 1;
+	const M11 = 5;
+	const M12 = 9;
+	const M13 = 13;
+	const M20 = 2;
+	const M21 = 6;
+	const M22 = 10;
+	const M23 = 14;
+	const M30 = 3;
+	const M31 = 7;
+	const M32 = 11;
+	const M33 = 15;
 	class Matrix4 {
 		temp: Float32Array;
 		values: Float32Array;

File diff suppressed because it is too large
+ 417 - 761
spine-ts/build/spine-widget.js


File diff suppressed because it is too large
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 58 - 8
spine-ts/threejs/src/SkeletonMesh.ts

@@ -30,7 +30,10 @@
 
 module spine.threejs {
 	export class SkeletonMesh extends THREE.Mesh {
-
+		tempPos: Vector2 = new Vector2();
+		tempUv: Vector2 = new Vector2();
+		tempLight = new Color();
+		tempDark = new Color();
 		skeleton: Skeleton;
 		state: AnimationState;
 		zOffset: number = 0.1;
@@ -71,6 +74,11 @@ module spine.threejs {
 		}
 
 		private updateGeometry() {
+			let tempPos = this.tempPos;
+			let tempUv = this.tempUv;
+			let tempLight = this.tempLight;
+			let tempDark = this.tempDark;
+
 			let geometry = <THREE.BufferGeometry>this.geometry;
 			var numVertices = 0;
 			var verticesLength = 0;
@@ -148,16 +156,58 @@ module spine.threejs {
 						clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, null, false);
 						let clippedVertices = clipper.clippedVertices;
 						let clippedTriangles = clipper.clippedTriangles;
+						if (this.vertexEffect != null) {
+							let vertexEffect = this.vertexEffect;
+							let verts = clippedVertices;
+							for (let v = 0, n = clippedVertices.length; v < n; v += vertexSize) {
+								tempPos.x = verts[v];
+								tempPos.y = verts[v + 1];
+								tempLight.setFromColor(color);
+								tempDark.set(0, 0, 0, 0);
+								tempUv.x = verts[v + 6];
+								tempUv.y = verts[v + 7];
+								vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
+								verts[v] = tempPos.x;
+								verts[v + 1] = tempPos.y;
+								verts[v + 2] = tempLight.r;
+								verts[v + 3] = tempLight.g;
+								verts[v + 4] = tempLight.b;
+								verts[v + 5] = tempLight.a;
+								verts[v + 6] = tempUv.x;
+								verts[v + 7] = tempUv.y;
+							}
+						}
 						batcher.batch(clippedVertices, clippedVertices.length, clippedTriangles, clippedTriangles.length, z);
 					} else {
 						let verts = vertices;
-						for (let v = 2, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {
-							verts[v] = color.r;
-							verts[v + 1] = color.g;
-							verts[v + 2] = color.b;
-							verts[v + 3] = color.a;
-							verts[v + 4] = uvs[u];
-							verts[v + 5] = uvs[u + 1];
+						if (this.vertexEffect != null) {
+							let vertexEffect = this.vertexEffect;
+							for (let v = 0, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {
+								tempPos.x = verts[v];
+								tempPos.y = verts[v + 1];
+								tempLight.setFromColor(color);
+								tempDark.set(0, 0, 0, 0);
+								tempUv.x = uvs[u];
+								tempUv.y = uvs[u + 1];
+								vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
+								verts[v] = tempPos.x;
+								verts[v + 1] = tempPos.y;
+								verts[v + 2] = tempLight.r;
+								verts[v + 3] = tempLight.g;
+								verts[v + 4] = tempLight.b;
+								verts[v + 5] = tempLight.a;
+								verts[v + 6] = tempUv.x;
+								verts[v + 7] = tempUv.y;
+							}
+						} else {
+							for (let v = 2, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {
+								verts[v] = color.r;
+								verts[v + 1] = color.g;
+								verts[v + 2] = color.b;
+								verts[v + 3] = color.a;
+								verts[v + 4] = uvs[u];
+								verts[v + 5] = uvs[u + 1];
+							}
 						}
 						batcher.batch(vertices, numFloats, triangles, triangles.length, z);
 					}

+ 3 - 0
spine-unity/Assets/Examples/Other Examples/Mix and Match.unity

@@ -592,6 +592,7 @@ SpriteRenderer:
   m_Size: {x: 1, y: 1}
   m_AdaptiveModeThreshold: 0.5
   m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1
 --- !u!1 &1262477660
 GameObject:
   m_ObjectHideFlags: 0
@@ -1075,6 +1076,7 @@ Material:
   m_ShaderKeywords: 
   m_LightmapFlags: 5
   m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
   m_CustomRenderQueue: -1
   stringTagMap: {}
   disabledShaderPasses: []
@@ -1296,3 +1298,4 @@ SpriteRenderer:
   m_Size: {x: 1, y: 1}
   m_AdaptiveModeThreshold: 0.5
   m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1

+ 31 - 0
spine-unity/Assets/Examples/Scripts/Getting Started Scripts/SpineboyTargetController.cs

@@ -0,0 +1,31 @@
+using UnityEngine;
+
+namespace Spine.Unity.Examples {
+	public class SpineboyTargetController : MonoBehaviour {
+
+		public SkeletonAnimation skeletonAnimation;
+
+		[SpineBone(dataField:"skeletonAnimation")]
+		public string boneName;
+		public new Camera camera;
+
+		Bone bone;
+
+		void OnValidate () {
+			if (skeletonAnimation == null) skeletonAnimation = GetComponent<SkeletonAnimation>();
+		}
+
+		void Start () {
+			bone = skeletonAnimation.Skeleton.FindBone(boneName);
+		}
+
+		void Update () {
+			var mousePosition = Input.mousePosition;
+			var worldMousePosition = camera.ScreenToWorldPoint(mousePosition);
+			var skeletonSpacePoint = skeletonAnimation.transform.InverseTransformPoint(worldMousePosition);
+			if (skeletonAnimation.Skeleton.FlipX) skeletonSpacePoint.x *= -1;
+			bone.SetPosition(skeletonSpacePoint);
+		}
+	}
+
+}

+ 12 - 0
spine-unity/Assets/Examples/Scripts/Getting Started Scripts/SpineboyTargetController.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: af275876c7b01264b85161629a9bc217
+timeCreated: 1489915484
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
spine-unity/Assets/Examples/Scripts/MixAndMatch.cs

@@ -30,6 +30,7 @@
 
 using UnityEngine;
 using Spine.Unity.Modules.AttachmentTools;
+using System.Collections;
 
 namespace Spine.Unity.Examples {
 
@@ -69,7 +70,8 @@ namespace Spine.Unity.Examples {
 			}
 		}
 
-		void Start () {
+		IEnumerator Start () {
+			yield return new WaitForSeconds(1f); // Delay for one second before applying. For testing.
 			Apply();
 		}
 

+ 7 - 4
spine-unity/Assets/Examples/Scripts/MixAndMatchGraphic.cs

@@ -30,6 +30,7 @@
 
 using UnityEngine;
 using Spine.Unity.Modules.AttachmentTools;
+using System.Collections;
 
 namespace Spine.Unity.Examples {
 
@@ -69,10 +70,12 @@ namespace Spine.Unity.Examples {
 			}
 		}
 
-		void Start () {
+		IEnumerator Start () {
+			yield return new WaitForSeconds(1f); // Delay for 1 second. For testing.
 			Apply();
 		}
 
+		[ContextMenu("Apply")]
 		void Apply () {
 			var skeletonGraphic = GetComponent<SkeletonGraphic>();
 			var skeleton = skeletonGraphic.Skeleton;
@@ -81,7 +84,7 @@ namespace Spine.Unity.Examples {
 			// Let's prepare a new skin to be our custom skin with equips/customizations. We get a clone so our original skins are unaffected.
 			customSkin = customSkin ?? new Skin("custom skin"); // This requires that all customizations are done with skin placeholders defined in Spine.
 			//customSkin = customSkin ?? skeleton.UnshareSkin(true, false, skeletonAnimation.AnimationState); // use this if you are not customizing on the default skin and don't plan to remove 
-			// Next let's 
+			// Next let's get the skin that contains our source attachments. These are the attachments that 
 			var baseSkin = skeleton.Data.FindSkin(baseSkinName);
 
 			// STEP 1: "EQUIP" ITEMS USING SPRITES
@@ -113,7 +116,6 @@ namespace Spine.Unity.Examples {
 			// 				Repacking requires that you set all source textures/sprites/atlases to be Read/Write enabled in the inspector.
 			// 				Combine all the attachment sources into one skin. Usually this means the default skin and the custom skin.
 			// 				call Skin.GetRepackedSkin to get a cloned skin with cloned attachments that all use one texture.
-			//				Under the hood, this relies on 
 			if (repack)	{
 				var repackedSkin = new Skin("repacked skin");
 				repackedSkin.Append(skeleton.Data.DefaultSkin);
@@ -124,7 +126,8 @@ namespace Spine.Unity.Examples {
 				skeleton.SetSkin(customSkin);
 			}
 
-			skeleton.SetSlotsToSetupPose();
+			//skeleton.SetSlotsToSetupPose();
+			skeleton.SetToSetupPose();
 			skeletonGraphic.Update(0);
 			skeletonGraphic.OverrideTexture = runtimeAtlas;
 

+ 2 - 1
spine-unity/Assets/Examples/Spine/Raptor/raptor_SkeletonData.asset

@@ -13,8 +13,9 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   atlasAssets:
   - {fileID: 11400000, guid: d5fc231712b346f459c8583fa224a669, type: 2}
-  skeletonJSON: {fileID: 4900000, guid: 3ae635b4540c450408d30a8afb9f75a7, type: 3}
+  spriteCollection: {fileID: 0}
   scale: 0.01
+  skeletonJSON: {fileID: 4900000, guid: 3ae635b4540c450408d30a8afb9f75a7, type: 3}
   fromAnimation: []
   toAnimation: []
   duration: []

+ 2 - 0
spine-unity/Assets/Examples/Spine/spineboy-unity/spineboy_Material.mat

@@ -11,6 +11,7 @@ Material:
   m_ShaderKeywords: 
   m_LightmapFlags: 5
   m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
   m_CustomRenderQueue: -1
   stringTagMap: {}
   disabledShaderPasses: []
@@ -29,5 +30,6 @@ Material:
     - _RefractionStrength: 0.01
     - _node_3476: 0
     m_Colors:
+    - _Black: {r: 0, g: 0, b: 0, a: 0}
     - _Color: {r: 1, g: 1, b: 1, a: 1}
     - _FillColor: {r: 1, g: 1, b: 1, a: 1}

+ 26 - 21
spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs

@@ -198,6 +198,32 @@ namespace Spine.Unity.Editor {
 				EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel);
 				EditorGUILayout.PropertyField(spriteCollection, true);
 				#endif
+
+				{
+					bool hasNulls = false;
+					foreach (var a in m_skeletonDataAsset.atlasAssets) {
+						if (a == null) {
+							hasNulls = true;
+							break;
+						}
+					}
+					if (hasNulls) {
+						if (m_skeletonDataAsset.atlasAssets.Length == 1) {
+							EditorGUILayout.HelpBox("Atlas array cannot have null entries!", MessageType.None);
+						} else {
+							EditorGUILayout.HelpBox("Atlas array should not have null entries!", MessageType.Error);
+							if (SpineInspectorUtility.CenteredButton(SpineInspectorUtility.TempContent("Remove null entries"))) {
+								var trimmedAtlasAssets = new List<AtlasAsset>();
+								foreach (var a in m_skeletonDataAsset.atlasAssets) {
+									if (a != null) trimmedAtlasAssets.Add(a);
+								}
+								m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray();
+								serializedObject.Update();
+							}
+						}
+
+					}
+				}
 			}
 
 			if (EditorGUI.EndChangeCheck()) {
@@ -446,25 +472,6 @@ namespace Spine.Unity.Editor {
 		void RepopulateWarnings () {
 			warnings.Clear();
 
-			// Clear null entries.
-			{
-				bool hasNulls = false;
-				foreach (var a in m_skeletonDataAsset.atlasAssets) {
-					if (a == null) {
-						hasNulls = true;
-						break;
-					}
-				}
-				if (hasNulls) {
-					var trimmedAtlasAssets = new List<AtlasAsset>();
-					foreach (var a in m_skeletonDataAsset.atlasAssets) {
-						if (a != null) trimmedAtlasAssets.Add(a);
-					}
-					m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray();
-				}
-				serializedObject.Update();
-			}
-
 			if (skeletonJSON.objectReferenceValue == null) {
 				warnings.Add("Missing Skeleton JSON");
 			} else {
@@ -475,8 +482,6 @@ namespace Spine.Unity.Editor {
 					bool searchForSpineAtlasAssets = true;
 					bool isSpriteCollectionNull = spriteCollection.objectReferenceValue == null;
 					if (!isSpriteCollectionNull) searchForSpineAtlasAssets = false;
-					//else
-					//	warnings.Add("Your sprite collection may have missing images.");
 					#else
 					const bool searchForSpineAtlasAssets = true;
 					#endif

Some files were not shown because too many files changed in this diff