diff --git a/extensions/spine/SkeletonBatch.cpp b/extensions/spine/SkeletonBatch.cpp index 0ce3a63c92..34dc83cee2 100644 --- a/extensions/spine/SkeletonBatch.cpp +++ b/extensions/spine/SkeletonBatch.cpp @@ -163,10 +163,11 @@ cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer CCASSERT(programState, "programState should not be null"); auto& pipelinePS = command->getPipelineDescriptor().programState; - if (pipelinePS == nullptr || pipelinePS->getProgram() != programState->getProgram()) + if (pipelinePS == nullptr || pipelinePS->getProgram() != programState->getProgram()) { CC_SAFE_RELEASE(pipelinePS); pipelinePS = programState->clone(); + updateProgramStateLayout(pipelinePS); } diff --git a/extensions/spine/runtime/include/spine/AnimationState.h b/extensions/spine/runtime/include/spine/AnimationState.h index 8f165da52f..300edf0a36 100644 --- a/extensions/spine/runtime/include/spine/AnimationState.h +++ b/extensions/spine/runtime/include/spine/AnimationState.h @@ -387,6 +387,14 @@ namespace spine { void enableQueue(); private: + static const int Subsequent = 0; + static const int First = 1; + static const int HoldSubsequent = 2; + static const int HoldFirst = 3; + static const int HoldMix = 4; + + static const int Setup = 1; + static const int Current = 2; AnimationStateData* _data; diff --git a/extensions/spine/runtime/include/spine/Atlas.h b/extensions/spine/runtime/include/spine/Atlas.h index 257942d692..816366162d 100644 --- a/extensions/spine/runtime/include/spine/Atlas.h +++ b/extensions/spine/runtime/include/spine/Atlas.h @@ -115,6 +115,8 @@ public: Vector &getPages(); + Vector &getRegions(); + private: Vector _pages; Vector _regions; @@ -149,8 +151,6 @@ private: static int equals(Str *str, const char *other); static int toInt(Str *str); - - static Atlas *abortAtlas(Atlas *atlas); }; } diff --git a/extensions/spine/runtime/include/spine/Debug.h b/extensions/spine/runtime/include/spine/Debug.h index 551158e7b7..61c3d3bb6e 100644 --- a/extensions/spine/runtime/include/spine/Debug.h +++ b/extensions/spine/runtime/include/spine/Debug.h @@ -35,7 +35,7 @@ #include namespace spine { -class DebugExtension : public SpineExtension { +class SP_API DebugExtension : public SpineExtension { struct Allocation { void *address; size_t size; diff --git a/extensions/spine/runtime/src/spine/AnimationState.cpp b/extensions/spine/runtime/src/spine/AnimationState.cpp index 845c5e206e..6185b88552 100644 --- a/extensions/spine/runtime/src/spine/AnimationState.cpp +++ b/extensions/spine/runtime/src/spine/AnimationState.cpp @@ -288,14 +288,6 @@ void EventQueue::drain() { _drainDisabled = false; } -const int Subsequent = 0; -const int First = 1; -const int Hold = 2; -const int HoldMix = 3; - -const int Setup = 1; -const int Current = 2; - AnimationState::AnimationState(AnimationStateData *data) : _data(data), _queue(EventQueue::newEventQueue(*this, _trackEntryPool)), @@ -836,7 +828,11 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle timelineBlend = MixBlend_Setup; alpha = alphaMix; break; - case Hold: + case HoldSubsequent: + timelineBlend = blend; + alpha = alphaHold; + break; + case HoldFirst: timelineBlend = MixBlend_Setup; alpha = alphaHold; break; @@ -1007,8 +1003,12 @@ void AnimationState::computeHold(TrackEntry *entry) { if (to != NULL && to->_holdPrevious) { for (size_t i = 0; i < timelinesCount; i++) { int id = timelines[i]->getPropertyId(); - if (!_propertyIDs.containsKey(id)) _propertyIDs.put(id, true); - timelineMode[i] = Hold; + if (!_propertyIDs.containsKey(id)) { + _propertyIDs.put(id, true); + timelineMode[i] = HoldFirst; + } else { + timelineMode[i] = HoldSubsequent; + } } return; } @@ -1039,7 +1039,7 @@ void AnimationState::computeHold(TrackEntry *entry) { } break; } - timelineMode[i] = Hold; + timelineMode[i] = HoldFirst; } } } diff --git a/extensions/spine/runtime/src/spine/Atlas.cpp b/extensions/spine/runtime/src/spine/Atlas.cpp index bd5484b6f3..e658c9c1e7 100644 --- a/extensions/spine/runtime/src/spine/Atlas.cpp +++ b/extensions/spine/runtime/src/spine/Atlas.cpp @@ -98,6 +98,10 @@ Vector &Atlas::getPages() { return _pages; } +Vector &Atlas::getRegions() { + return _regions; +} + void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) { static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"}; static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest", diff --git a/extensions/spine/runtime/src/spine/Bone.cpp b/extensions/spine/runtime/src/spine/Bone.cpp index fb1b14133f..7c0627dacc 100644 --- a/extensions/spine/runtime/src/spine/Bone.cpp +++ b/extensions/spine/runtime/src/spine/Bone.cpp @@ -479,7 +479,7 @@ void Bone::setWorldY(float inValue) { } float Bone::getWorldRotationX() { - return MathUtil::atan2(_c, _a) * MathUtil::MathUtil::Rad_Deg; + return MathUtil::atan2(_c, _a) * MathUtil::Rad_Deg; } float Bone::getWorldRotationY() { diff --git a/extensions/spine/runtime/src/spine/IkConstraint.cpp b/extensions/spine/runtime/src/spine/IkConstraint.cpp index 284b628577..fcb543f849 100644 --- a/extensions/spine/runtime/src/spine/IkConstraint.cpp +++ b/extensions/spine/runtime/src/spine/IkConstraint.cpp @@ -242,7 +242,7 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY a1 = (a1 - os) * MathUtil::Rad_Deg + o1 - parent._arotation; if (a1 > 180) a1 -= 360; else if (a1 < -180) a1 += 360; - parent.updateWorldTransform(px, py, parent._rotation + a1 * alpha, sx, parent._ascaleY, 0, 0); + parent.updateWorldTransform(px, py, parent._arotation + a1 * alpha, sx, parent._ascaleY, 0, 0); a2 = ((a2 + os) * MathUtil::Rad_Deg - child._ashearX) * s2 + o2 - child._arotation; if (a2 > 180) a2 -= 360; else if (a2 < -180) a2 += 360; diff --git a/extensions/spine/runtime/src/spine/SkeletonBinary.cpp b/extensions/spine/runtime/src/spine/SkeletonBinary.cpp index fd266ee1b9..f26398a774 100644 --- a/extensions/spine/runtime/src/spine/SkeletonBinary.cpp +++ b/extensions/spine/runtime/src/spine/SkeletonBinary.cpp @@ -281,8 +281,16 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons } /* Skins. */ - for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i) - skeletonData->_skins.add(readSkin(input, false, skeletonData, nonessential)); + for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i) { + Skin* skin = readSkin(input, false, skeletonData, nonessential); + if (skin) + skeletonData->_skins.add(skin); + else { + delete input; + delete skeletonData; + return NULL; + } + } /* Linked meshes. */ for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) { @@ -380,7 +388,7 @@ char *SkeletonBinary::readString(DataInput *input) { char* SkeletonBinary::readStringRef(DataInput* input, SkeletonData* skeletonData) { int index = readVarint(input, true); - return index == 0 ? nullptr : skeletonData->_strings[index - 1]; + return index == 0 ? NULL : skeletonData->_strings[index - 1]; } float SkeletonBinary::readFloat(DataInput *input) { @@ -470,7 +478,12 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) { String name(readStringRef(input, skeletonData)); Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential); - if (attachment) skin->setAttachment(slotIndex, String(name), attachment); + if (attachment) + skin->setAttachment(slotIndex, String(name), attachment); + else { + delete skin; + return nullptr; + } } } return skin; @@ -488,6 +501,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo String path(readStringRef(input, skeletonData)); if (path.isEmpty()) path = name; RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path)); + if (!region) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } region->_path = path; region->_rotation = readFloat(input); region->_x = readFloat(input) * _scale; @@ -504,6 +521,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo case AttachmentType_Boundingbox: { int vertexCount = readVarint(input, true); BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name)); + if (!box) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } readVertices(input, static_cast(box), vertexCount); if (nonessential) { /* Skip color. */ @@ -519,6 +540,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo if (path.isEmpty()) path = name; mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path)); + if (!mesh) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } mesh->_path = path; readColor(input, mesh->getColor()); vertexCount = readVarint(input, true); @@ -543,6 +568,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo if (path.isEmpty()) path = name; MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path)); + if (!mesh) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } mesh->_path = path; readColor(input, mesh->getColor()); String skinName(readStringRef(input, skeletonData)); @@ -559,7 +588,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo return mesh; } case AttachmentType_Path: { - PathAttachment *path = _attachmentLoader->newPathAttachment(*skin, String(name)); + PathAttachment* path = _attachmentLoader->newPathAttachment(*skin, String(name)); + if (!path) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } path->_closed = readBoolean(input); path->_constantSpeed = readBoolean(input); int vertexCount = readVarint(input, true); @@ -577,7 +610,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo return path; } case AttachmentType_Point: { - PointAttachment *point = _attachmentLoader->newPointAttachment(*skin, String(name)); + PointAttachment* point = _attachmentLoader->newPointAttachment(*skin, String(name)); + if (!point) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } point->_rotation = readFloat(input); point->_x = readFloat(input) * _scale; point->_y = readFloat(input) * _scale; @@ -592,7 +629,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo case AttachmentType_Clipping: { int endSlotIndex = readVarint(input, true); int vertexCount = readVarint(input, true); - ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name); + ClippingAttachment* clip = _attachmentLoader->newClippingAttachment(*skin, name); + if (!clip) { + setError("Error reading attachment: ", name.buffer()); + return nullptr; + } readVertices(input, static_cast(clip), vertexCount); clip->_endSlot = skeletonData->_slots[endSlotIndex]; if (nonessential) { @@ -603,7 +644,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo return clip; } } - return NULL; + return nullptr; } void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) { diff --git a/extensions/spine/runtime/src/spine/Slot.cpp b/extensions/spine/runtime/src/spine/Slot.cpp index f45d88c46c..4edf8b76fd 100644 --- a/extensions/spine/runtime/src/spine/Slot.cpp +++ b/extensions/spine/runtime/src/spine/Slot.cpp @@ -55,6 +55,7 @@ Slot::Slot(SlotData &data, Bone &bone) : void Slot::setToSetupPose() { _color.set(_data.getColor()); + if (_hasDarkColor) _darkColor.set(_data.getDarkColor()); const String &attachmentName = _data.getAttachmentName(); if (attachmentName.length() > 0) {