- Modifié
Keyed Draw Order bug iOS 7.0.5
Hi,
To replicate the bug:
You need iOS 7.0.5 (if you have latest xcode you will be able to replicate on 64 bit iphone 4 inch) note 64 bit because it works on 32 bit iphone 4 inch).
Otherwise use iPhone 5s with the latest iOS.
- Create an animation which contains a keyed draw order mid way through
- Play animation in cocos2d scene
- Some texture regions will disappear once you setToSetupPose (reset the animation)
In our case, we moved the right arm behind the body during the animation.
Once the animation finishes we stop actions animations and setToSetupPose.
When the avatar ends in starting pose, the torso is missing.
If you play the same animation it stars with no torso, the torso shows when it hits the keyed draw order frame, it then goes back to setup pose without torso.
Any ideas?
The torso is visible in the setup pose, right?
Is it hidden through draw order or through an attachment key?
When you start off, the torso is visible (as the animation has not been run yet)
The torso stops being visible in the setup pose after the animation with draw order finishes.
When i run the animation again, the torso shows briefly during the animation and then disappears.
I suspect that the function which is at fault is this: spAnimation* _spSkeletonJson_readAnimation
Once again, it all works perfect in 32 bit. 64 bit is the one that does not work.
There is probably something wrong here:
if (drawOrder) {
Json* frame;
float duration;
spDrawOrderTimeline* timeline = spDrawOrderTimeline_create(drawOrder->size, skeletonData->slotCount);
for (frame = drawOrder->child, i = 0; frame; frame = frame->next, ++i) {
int ii;
int* drawOrder = 0;
Json* offsets = Json_getItem(frame, "offsets");
if (offsets) {
Json* offsetMap;
int* unchanged = MALLOC(int, skeletonData->slotCount - offsets->size);
int originalIndex = 0, unchangedIndex = 0;
drawOrder = MALLOC(int, skeletonData->slotCount);
for (ii = skeletonData->slotCount - 1; ii >= 0;
ii)
drawOrder[ii] = -1;
for (offsetMap = offsets->child; offsetMap; offsetMap = offsetMap->next) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, Json_getString(offsetMap, "slot", 0));
if (slotIndex == -1) {
spAnimation_dispose(animation);
_spSkeletonJson_setError(self, 0, "Slot not found: ", Json_getString(offsetMap, "slot", 0));
return 0;
}
/* Collect unchanged items. */
while (originalIndex != slotIndex)
unchanged[unchangedIndex++] = originalIndex++;
/* Set changed items. */
drawOrder[originalIndex + Json_getInt(offsetMap, "offset", 0)] = originalIndex;
++originalIndex;
}
/* Collect remaining unchanged items. */
while (originalIndex < skeletonData->slotCount)
unchanged[unchangedIndex++] = originalIndex++;
/* Fill in unchanged items. */
for (ii = skeletonData->slotCount - 1; ii >= 0; ii
)
if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[
unchangedIndex];
FREE(unchanged);
}
spDrawOrderTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), drawOrder);
FREE(drawOrder);
}
I checked the above code and it seams to be fine so not sure which bit is going wrong :-)
Loading draw order is quite tricky. Pretty sure it is correct though.
32 bit works, 64 doesn't. :o I'm guessing memory is getting stomped somewhere. spSkeleton_setSlotsToSetupPose uses memcpy with sizeof(int), but it isn't an array of int (I think it used to be). Fixed in Git, thanks!
Thanks Nate that fixed it,
for everyone else:
- memcpy(self->drawOrder, self->slots, self->slotCount * sizeof(int));
- memcpy(self->drawOrder, self->slots, self->slotCount * sizeof(spSlot*));