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

Changed bone sorting so transform behavior is consistent when IK and transform constraints are mixed. (#550)

based on : https://github.com/EsotericSoftware/spine-runtimes/commit/b0eec6f411fbfe88bd413151e0c9cb4f06f86115
John 9 жил өмнө
parent
commit
f65ca667b3

+ 20 - 10
spine-c/src/spine/Skeleton.c

@@ -143,22 +143,15 @@ void spSkeleton_updateCache (const spSkeleton* self) {
 
 	FREE(internal->updateCache);
 	FREE(internal->updateCacheType);
-	internal->updateCache = MALLOC(void*, self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount);
-	internal->updateCacheType = MALLOC(_spUpdateType, self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount);
+	int capacity = self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount;
+	internal->updateCache = MALLOC(void*, capacity);
+	internal->updateCacheType = MALLOC(_spUpdateType, capacity);
 	internal->updateCacheCount = 0;
 
 	for (i = 0; i < self->bonesCount; ++i) {
 		spBone* bone = self->bones[i];
 		internal->updateCache[internal->updateCacheCount] = bone;
 		internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_BONE;
-		for (ii = 0; ii < self->transformConstraintsCount; ++ii) {
-			spTransformConstraint* transformConstraint = self->transformConstraints[ii];
-			if (bone == transformConstraint->bone) {
-				internal->updateCache[internal->updateCacheCount] = transformConstraint;
-				internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_TRANSFORM_CONSTRAINT;
-				break;
-			}
-		}
 		for (ii = 0; ii < self->ikConstraintsCount; ++ii) {
 			spIkConstraint* ikConstraint = self->ikConstraints[ii];
 			if (bone == ikConstraint->bones[ikConstraint->bonesCount - 1]) {
@@ -168,6 +161,23 @@ void spSkeleton_updateCache (const spSkeleton* self) {
 			}
 		}
 	}
+
+	for (i = 0; i < self->transformConstraintsCount; ++i) {
+		spTransformConstraint* transformConstraint = self->transformConstraints[i];
+		for (ii = internal->updateCacheCount - 1; ii >= 0; --ii) {
+			void* updatable = internal->updateCache[ii];
+			if (updatable == transformConstraint->bone || updatable == transformConstraint->target) {
+				int insertIndex = ii + 1;
+				int moveCount = (capacity-2) - insertIndex;
+				memmove(internal->updateCache + (insertIndex+1), internal->updateCache + insertIndex, moveCount * sizeof(void*));
+				memmove(internal->updateCacheType + (insertIndex+1), internal->updateCacheType + insertIndex, moveCount * sizeof(_spUpdateType));
+				internal->updateCacheCount++;
+				internal->updateCache[insertIndex] = transformConstraint;
+				internal->updateCacheType[insertIndex] = SP_UPDATE_TRANSFORM_CONSTRAINT;
+				break;
+			}
+		}
+	}
 }
 
 void spSkeleton_updateWorldTransform (const spSkeleton* self) {