Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/3.6' into 3.6

NathanSweet 8 gadi atpakaļ
vecāks
revīzija
9df8790c5e

+ 56 - 20
spine-c/spine-c/src/spine/Json.c

@@ -92,29 +92,65 @@ void Json_dispose (Json *c) {
 
 
 /* Parse the input text to generate a number, and populate the result into item. */
 /* Parse the input text to generate a number, and populate the result into item. */
 static const char* parse_number (Json *item, const char* num) {
 static const char* parse_number (Json *item, const char* num) {
-	char * endptr;
-	float n;
-
-	/* Using strtod and strtof is slightly more permissive than RFC4627,
-	 * accepting for example hex-encoded floating point, but either
-	 * is often leagues faster than any manual implementation.
-	 *
-	 * We also already know that this starts with [-0-9] from parse_value.
-	 */
-#if __STDC_VERSION__ >= 199901L
-	n = strtof(num, &endptr);
-#else
-	n = (float)strtod( num, &endptr );
-#endif
-	/* ignore errno's ERANGE, which returns +/-HUGE_VAL */
-	/* n is 0 on any other error */
+	double result = 0.0;
+	int negative = 0;
+	char* ptr = (char*)num;
+
+	if (*ptr == '-') {
+		negative = -1;
+		++ptr;
+	}
+
+	while (*ptr >= '0' && *ptr <= '9') {
+		result = result * 10.0 + (*ptr - '0');
+		++ptr;
+	}
+
+	if (*ptr == '.') {
+		double fraction = 0.0;
+		int n = 0;
+		++ptr;
+
+		while (*ptr >= '0' && *ptr <= '9') {
+			fraction = (fraction * 10.0) + (*ptr - '0');
+			++ptr;
+			++n;
+		}
+		result += fraction / POW(10.0, n);
+	}
+	if (negative) result = -result;
+
+	if (*ptr == 'e' || *ptr == 'E') {
+		double exponent = 0;
+		int expNegative = 0;
+		int n = 0;
+		++ptr;
+
+		if (*ptr == '-') {
+			expNegative = -1;
+			++ptr;
+		} else if (*ptr == '+') {
+			++ptr;
+		}
+
+		while (*ptr >= '0' && *ptr <= '9') {
+			exponent = (exponent * 10.0) + (*ptr - '0');
+			++ptr;
+			++n;
+		}
+
+		if (expNegative)
+			result = result / POW(10, exponent);
+		else
+			result = result * POW(10, exponent);
+	}
 
 
-	if (endptr != num) {
+	if (ptr != num) {
 		/* Parse success, number found. */
 		/* Parse success, number found. */
-		item->valueFloat = n;
-		item->valueInt = (int)n;
+		item->valueFloat = result;
+		item->valueInt = (int)result;
 		item->type = Json_Number;
 		item->type = Json_Number;
-		return endptr;
+		return ptr;
 	} else {
 	} else {
 		/* Parse failure, ep is set. */
 		/* Parse failure, ep is set. */
 		ep = num;
 		ep = num;

+ 0 - 12
spine-c/spine-c/src/spine/SkeletonJson.c

@@ -30,7 +30,6 @@
 
 
 #include <spine/SkeletonJson.h>
 #include <spine/SkeletonJson.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <locale.h>
 #include "Json.h"
 #include "Json.h"
 #include <spine/extension.h>
 #include <spine/extension.h>
 #include <spine/AtlasAttachmentLoader.h>
 #include <spine/AtlasAttachmentLoader.h>
@@ -579,25 +578,14 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
 	int i, ii;
 	int i, ii;
 	spSkeletonData* skeletonData;
 	spSkeletonData* skeletonData;
 	Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events;
 	Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events;
-	char* oldLocale;
 	_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
 	_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
 
 
 	FREE(self->error);
 	FREE(self->error);
 	CONST_CAST(char*, self->error) = 0;
 	CONST_CAST(char*, self->error) = 0;
 	internal->linkedMeshCount = 0;
 	internal->linkedMeshCount = 0;
 
 
-#ifndef __ANDROID__
-	oldLocale = strdup(setlocale(LC_NUMERIC, NULL));
-	setlocale(LC_NUMERIC, "C");
-#endif
-
 	root = Json_create(json);
 	root = Json_create(json);
 
 
-#ifndef __ANDROID__
-	setlocale(LC_NUMERIC, oldLocale);
-	free(oldLocale);
-#endif
-
 	if (!root) {
 	if (!root) {
 		_spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
 		_spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
 		return 0;
 		return 0;

+ 43 - 16
spine-cocos2dx/src/spine/SkeletonRenderer.cpp

@@ -36,12 +36,35 @@
 #include <spine/Cocos2dAttachmentLoader.h>
 #include <spine/Cocos2dAttachmentLoader.h>
 #include <algorithm>
 #include <algorithm>
 
 
+#define INITIAL_WORLD_VERTICES_LENGTH 1000
+// Used for transforming attachments for bounding boxes & debug rendering
+static float* worldVertices = nullptr;
+static size_t worldVerticesLength = 0;
+
+void ensureWorldVerticesCapacity(size_t capacity) {
+	if (worldVerticesLength < capacity) {
+		float* newWorldVertices = new float[capacity];
+		memcpy(newWorldVertices, worldVertices, capacity * sizeof(float));
+		delete[] worldVertices;
+		worldVertices = newWorldVertices;
+		worldVerticesLength = capacity;
+	}
+}
+
 USING_NS_CC;
 USING_NS_CC;
 using std::min;
 using std::min;
 using std::max;
 using std::max;
 
 
 namespace spine {
 namespace spine {
 
 
+void SkeletonRenderer::destroyScratchBuffers() {
+	if (worldVertices) {
+		delete[] worldVertices;
+		worldVertices = nullptr;
+		worldVerticesLength = 0;
+	}
+}
+	
 SkeletonRenderer* SkeletonRenderer::createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) {
 SkeletonRenderer* SkeletonRenderer::createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) {
 	SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData);
 	SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData);
 	node->autorelease();
 	node->autorelease();
@@ -61,7 +84,10 @@ SkeletonRenderer* SkeletonRenderer::createWithFile (const std::string& skeletonD
 }
 }
 
 
 void SkeletonRenderer::initialize () {
 void SkeletonRenderer::initialize () {
-	_worldVertices = new float[1000]; // Max number of vertices per mesh.
+	if (!worldVertices) {
+		worldVertices = new float[INITIAL_WORLD_VERTICES_LENGTH];
+		worldVerticesLength = INITIAL_WORLD_VERTICES_LENGTH;
+	}
 	
 	
 	_clipper = spSkeletonClipping_create();
 	_clipper = spSkeletonClipping_create();
 
 
@@ -131,8 +157,7 @@ SkeletonRenderer::~SkeletonRenderer () {
 	if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
 	if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
 	spSkeleton_dispose(_skeleton);
 	spSkeleton_dispose(_skeleton);
 	if (_atlas) spAtlas_dispose(_atlas);
 	if (_atlas) spAtlas_dispose(_atlas);
-	if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader);
-	delete [] _worldVertices;
+	if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader);	
 	spSkeletonClipping_dispose(_clipper);
 	spSkeletonClipping_dispose(_clipper);
 }
 }
 
 
@@ -613,11 +638,11 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin
             spSlot* slot = _skeleton->drawOrder[i];
             spSlot* slot = _skeleton->drawOrder[i];
             if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
             if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
             spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
             spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
-            spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2);
-            points[0] = Vec2(_worldVertices[0], _worldVertices[1]);
-            points[1] = Vec2(_worldVertices[2], _worldVertices[3]);
-            points[2] = Vec2(_worldVertices[4], _worldVertices[5]);
-            points[3] = Vec2(_worldVertices[6], _worldVertices[7]);
+            spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2);
+            points[0] = Vec2(worldVertices[0], worldVertices[1]);
+            points[1] = Vec2(worldVertices[2], worldVertices[3]);
+            points[2] = Vec2(worldVertices[4], worldVertices[5]);
+            points[3] = Vec2(worldVertices[6], worldVertices[7]);
             drawNode->drawPoly(points, 4, true, Color4F::BLUE);
             drawNode->drawPoly(points, 4, true, Color4F::BLUE);
         }
         }
     }
     }
@@ -645,12 +670,13 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin
 		for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) {
 		for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) {
 			spSlot* slot = _skeleton->drawOrder[i];
 			spSlot* slot = _skeleton->drawOrder[i];
 			if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_MESH) continue;
 			if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_MESH) continue;
-			spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;			
-			spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, _worldVertices, 0, 2);
+			spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
+			ensureWorldVerticesCapacity(attachment->super.worldVerticesLength);
+			spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, worldVertices, 0, 2);
 			for (int ii = 0; ii < attachment->trianglesCount;) {
 			for (int ii = 0; ii < attachment->trianglesCount;) {
-				Vec2 v1(_worldVertices + (attachment->triangles[ii++] * 2));
-				Vec2 v2(_worldVertices + (attachment->triangles[ii++] * 2));
-				Vec2 v3(_worldVertices + (attachment->triangles[ii++] * 2));
+				Vec2 v1(worldVertices + (attachment->triangles[ii++] * 2));
+				Vec2 v2(worldVertices + (attachment->triangles[ii++] * 2));
+				Vec2 v3(worldVertices + (attachment->triangles[ii++] * 2));
 				drawNode->drawLine(v1, v2, Color4F::YELLOW);
 				drawNode->drawLine(v1, v2, Color4F::YELLOW);
 				drawNode->drawLine(v2, v3, Color4F::YELLOW);
 				drawNode->drawLine(v2, v3, Color4F::YELLOW);
 				drawNode->drawLine(v3, v1, Color4F::YELLOW);
 				drawNode->drawLine(v3, v1, Color4F::YELLOW);
@@ -680,16 +706,17 @@ Rect SkeletonRenderer::getBoundingBox () const {
 		int verticesCount;
 		int verticesCount;
 		if (slot->attachment->type == SP_ATTACHMENT_REGION) {
 		if (slot->attachment->type == SP_ATTACHMENT_REGION) {
 			spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
 			spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
-			spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2);
+			spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2);
 			verticesCount = 8;
 			verticesCount = 8;
 		} else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
 		} else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
 			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
-			spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, _worldVertices, 0, 2);
+			ensureWorldVerticesCapacity(mesh->super.worldVerticesLength);
+			spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2);
 			verticesCount = mesh->super.worldVerticesLength;
 			verticesCount = mesh->super.worldVerticesLength;
 		} else
 		} else
 			continue;
 			continue;
 		for (int ii = 0; ii < verticesCount; ii += 2) {
 		for (int ii = 0; ii < verticesCount; ii += 2) {
-			float x = _worldVertices[ii] * scaleX, y = _worldVertices[ii + 1] * scaleY;
+			float x = worldVertices[ii] * scaleX, y = worldVertices[ii + 1] * scaleY;
 			minX = min(minX, x);
 			minX = min(minX, x);
 			minY = min(minY, y);
 			minY = min(minY, y);
 			maxX = max(maxX, x);
 			maxX = max(maxX, x);

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

@@ -108,6 +108,9 @@ public:
 	virtual const cocos2d::BlendFunc& getBlendFunc () const override;
 	virtual const cocos2d::BlendFunc& getBlendFunc () const override;
 	virtual void setOpacityModifyRGB (bool value) override;
 	virtual void setOpacityModifyRGB (bool value) override;
 	virtual bool isOpacityModifyRGB () const override;
 	virtual bool isOpacityModifyRGB () const override;
+	
+	// Frees global memory used for temporay vertex transformations.
+	static void destroyScratchBuffers();
 
 
 CC_CONSTRUCTOR_ACCESS:
 CC_CONSTRUCTOR_ACCESS:
 	SkeletonRenderer ();
 	SkeletonRenderer ();
@@ -136,7 +139,6 @@ protected:
 	spAttachmentLoader* _attachmentLoader;
 	spAttachmentLoader* _attachmentLoader;
 	cocos2d::CustomCommand _debugCommand;
 	cocos2d::CustomCommand _debugCommand;
 	cocos2d::BlendFunc _blendFunc;
 	cocos2d::BlendFunc _blendFunc;
-	float* _worldVertices;
 	bool _premultipliedAlpha;
 	bool _premultipliedAlpha;
 	spSkeleton* _skeleton;
 	spSkeleton* _skeleton;
 	float _timeScale;
 	float _timeScale;