diff --git a/spine-cpp/spine-cpp/include/spine/Attachment.h b/spine-cpp/spine-cpp/include/spine/Attachment.h index 65945d254..643c78486 100644 --- a/spine-cpp/spine-cpp/include/spine/Attachment.h +++ b/spine-cpp/spine-cpp/include/spine/Attachment.h @@ -45,8 +45,15 @@ public: const String &getName() const; + virtual Attachment* copy() = 0; + + int getRefCount(); + void reference(); + void dereference(); + private: const String _name; + int _refCount; }; } diff --git a/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h b/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h index 5d96b54ae..9fd8d3651 100644 --- a/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h @@ -39,6 +39,8 @@ namespace spine { RTTI_DECL explicit BoundingBoxAttachment(const String& name); + + virtual Attachment* copy(); }; } diff --git a/spine-cpp/spine-cpp/include/spine/ClippingAttachment.h b/spine-cpp/spine-cpp/include/spine/ClippingAttachment.h index 7eceae5eb..712948d36 100644 --- a/spine-cpp/spine-cpp/include/spine/ClippingAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/ClippingAttachment.h @@ -48,6 +48,8 @@ namespace spine { SlotData* getEndSlot(); void setEndSlot(SlotData* inValue); + + virtual Attachment* copy(); private: SlotData* _endSlot; diff --git a/spine-cpp/spine-cpp/include/spine/LinkedMesh.h b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h index 4776c0bb0..175e38f74 100644 --- a/spine-cpp/spine-cpp/include/spine/LinkedMesh.h +++ b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h @@ -42,13 +42,14 @@ class SP_API LinkedMesh : public SpineObject { friend class SkeletonJson; public: - LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent); + LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent, bool inheritDeform); private: MeshAttachment *_mesh; String _skin; size_t _slotIndex; String _parent; + bool _inheritDeform; }; } diff --git a/spine-cpp/spine-cpp/include/spine/MeshAttachment.h b/spine-cpp/spine-cpp/include/spine/MeshAttachment.h index 236200774..1bf05ec0e 100644 --- a/spine-cpp/spine-cpp/include/spine/MeshAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/MeshAttachment.h @@ -50,8 +50,6 @@ namespace spine { virtual ~MeshAttachment(); void updateUVs(); - - virtual bool applyDeform(VertexAttachment* sourceAttachment); int getHullLength(); void setHullLength(int inValue); @@ -104,9 +102,6 @@ namespace spine { float getRegionOriginalHeight(); void setRegionOriginalHeight(float inValue); - bool getInheritDeform(); - void setInheritDeform(bool inValue); - MeshAttachment* getParentMesh(); void setParentMesh(MeshAttachment* inValue); @@ -117,6 +112,10 @@ namespace spine { float getHeight(); void setHeight(float inValue); + virtual Attachment* copy(); + + MeshAttachment* newLinkedMesh(); + private: float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight; MeshAttachment* _parentMesh; @@ -133,7 +132,6 @@ namespace spine { float _height; Color _color; int _hullLength; - bool _inheritDeform; bool _regionRotate; int _regionDegrees; }; diff --git a/spine-cpp/spine-cpp/include/spine/PathAttachment.h b/spine-cpp/spine-cpp/include/spine/PathAttachment.h index 1060d3d83..0bf389a21 100644 --- a/spine-cpp/spine-cpp/include/spine/PathAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/PathAttachment.h @@ -48,7 +48,8 @@ namespace spine { void setClosed(bool inValue); bool isConstantSpeed(); void setConstantSpeed(bool inValue); - + + virtual Attachment* copy(); private: Vector _lengths; bool _closed; diff --git a/spine-cpp/spine-cpp/include/spine/PointAttachment.h b/spine-cpp/spine-cpp/include/spine/PointAttachment.h index 2b800bcb6..92f645f37 100644 --- a/spine-cpp/spine-cpp/include/spine/PointAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/PointAttachment.h @@ -63,6 +63,8 @@ namespace spine { float getRotation(); void setRotation(float inValue); + + virtual Attachment* copy(); private: float _x, _y, _rotation; diff --git a/spine-cpp/spine-cpp/include/spine/RegionAttachment.h b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h index f79db881f..4ca28fab7 100644 --- a/spine-cpp/spine-cpp/include/spine/RegionAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h @@ -105,6 +105,8 @@ namespace spine { Vector& getOffset(); Vector& getUVs(); + + virtual Attachment* copy(); private: static const int BLX; diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index 6a4a6b6e0..ce22369f5 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -117,7 +117,7 @@ public: /// Adds an attachment to the skin for the specified slot index and name. /// If the name already exists for the slot, the previous value is replaced. - void addAttachment(size_t slotIndex, const String &name, Attachment *attachment); + void setAttachment(size_t slotIndex, const String &name, Attachment *attachment); /// Returns the attachment for the specified slot index and name, or NULL. Attachment *getAttachment(size_t slotIndex, const String &name); @@ -134,6 +134,12 @@ public: const String &getName(); + /// Adds all attachments, bones, and constraints from the specified skin to this skin. + void addSkin(Skin* other); + + /// Adds all attachments, bones, and constraints from the specified skin to this skin. Attachments are deep copied. + void copySkin(Skin* other); + AttachmentMap::Entries getAttachments(); private: diff --git a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h index 30b7e1598..015ae02e9 100644 --- a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h @@ -62,9 +62,6 @@ namespace spine { void computeWorldVertices(Slot& slot, size_t start, size_t count, float* worldVertices, size_t offset, size_t stride = 2); void computeWorldVertices(Slot& slot, size_t start, size_t count, Vector& worldVertices, size_t offset, size_t stride = 2); - /// @return true if a deform originally applied to the specified attachment should be applied to this attachment. - virtual bool applyDeform(VertexAttachment* sourceAttachment); - /// Gets a unique ID for this attachment. int getId(); @@ -74,11 +71,17 @@ namespace spine { size_t getWorldVerticesLength(); void setWorldVerticesLength(size_t inValue); + + VertexAttachment* getDeformAttachment(); + void setDeformAttachment(VertexAttachment* attachment); + + void copyTo(VertexAttachment* other); protected: Vector _bones; Vector _vertices; size_t _worldVerticesLength; + VertexAttachment* _deformAttachment; private: const int _id; diff --git a/spine-cpp/spine-cpp/src/spine/Attachment.cpp b/spine-cpp/spine-cpp/src/spine/Attachment.cpp index 8a0147861..eef1e5020 100644 --- a/spine-cpp/spine-cpp/src/spine/Attachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/Attachment.cpp @@ -39,7 +39,7 @@ using namespace spine; RTTI_IMPL_NOPARENT(Attachment) -Attachment::Attachment(const String &name) : _name(name) { +Attachment::Attachment(const String &name) : _name(name), _refCount(0) { assert(_name.length() > 0); } @@ -49,3 +49,15 @@ Attachment::~Attachment() { const String &Attachment::getName() const { return _name; } + +int Attachment::getRefCount() { + return _refCount; +} + +void Attachment::reference() { + _refCount++; +} + +void Attachment::dereference() { + _refCount--; +} diff --git a/spine-cpp/spine-cpp/src/spine/BoundingBoxAttachment.cpp b/spine-cpp/spine-cpp/src/spine/BoundingBoxAttachment.cpp index 3504be5f6..04ec03f32 100644 --- a/spine-cpp/spine-cpp/src/spine/BoundingBoxAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/BoundingBoxAttachment.cpp @@ -39,3 +39,9 @@ RTTI_IMPL(BoundingBoxAttachment, VertexAttachment) BoundingBoxAttachment::BoundingBoxAttachment(const String &name) : VertexAttachment(name) { } + +Attachment* BoundingBoxAttachment::copy() { + BoundingBoxAttachment* copy = new (__FILE__, __LINE__) BoundingBoxAttachment(getName()); + copyTo(copy); + return copy; +} diff --git a/spine-cpp/spine-cpp/src/spine/ClippingAttachment.cpp b/spine-cpp/spine-cpp/src/spine/ClippingAttachment.cpp index 6857f40e1..e79ccf7f0 100644 --- a/spine-cpp/spine-cpp/src/spine/ClippingAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/ClippingAttachment.cpp @@ -49,3 +49,10 @@ SlotData *ClippingAttachment::getEndSlot() { void ClippingAttachment::setEndSlot(SlotData *inValue) { _endSlot = inValue; } + +Attachment* ClippingAttachment::copy() { + ClippingAttachment* copy = new (__FILE__, __LINE__) ClippingAttachment(getName()); + copyTo(copy); + copy->_endSlot = _endSlot; + return copy; +} diff --git a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp index b8fe586a0..3917af3df 100644 --- a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp @@ -74,7 +74,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto } VertexAttachment *attachment = static_cast(slotAttachment); - if (!attachment->applyDeform(_attachment)) { + if (attachment->_deformAttachment != _attachment) { return; } diff --git a/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp b/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp index b6edb261c..f84549e38 100644 --- a/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp +++ b/spine-cpp/spine-cpp/src/spine/LinkedMesh.cpp @@ -37,9 +37,10 @@ using namespace spine; -LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent) : +LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent, bool inheritDeform) : _mesh(mesh), _skin(skin), _slotIndex(slotIndex), - _parent(parent) { + _parent(parent), + _inheritDeform(inheritDeform) { } diff --git a/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp b/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp index 1e2fdbe98..b08610954 100644 --- a/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp @@ -55,7 +55,6 @@ MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name), Has _height(0), _color(1, 1, 1, 1), _hullLength(0), - _inheritDeform(false), _regionRotate(false), _regionDegrees(0) { } @@ -126,10 +125,6 @@ void MeshAttachment::updateUVs() { } } -bool MeshAttachment::applyDeform(VertexAttachment *sourceAttachment) { - return this == sourceAttachment || (_inheritDeform && _parentMesh == sourceAttachment); -} - int MeshAttachment::getHullLength() { return _hullLength; } @@ -246,14 +241,6 @@ void MeshAttachment::setRegionOriginalHeight(float inValue) { _regionOriginalHeight = inValue; } -bool MeshAttachment::getInheritDeform() { - return _inheritDeform; -} - -void MeshAttachment::setInheritDeform(bool inValue) { - _inheritDeform = inValue; -} - MeshAttachment *MeshAttachment::getParentMesh() { return _parentMesh; } @@ -296,3 +283,59 @@ void MeshAttachment::setHeight(float inValue) { spine::Color &MeshAttachment::getColor() { return _color; } + +Attachment* MeshAttachment::copy() { + if (_parentMesh) return newLinkedMesh(); + + MeshAttachment* copy = new (__FILE__, __LINE__) MeshAttachment(getName()); + copy->setRendererObject(getRendererObject()); + copy->_regionU = _regionU; + copy->_regionV = _regionV; + copy->_regionU2 = _regionU2; + copy->_regionV2 = _regionV2; + copy->_regionRotate = _regionRotate; + copy->_regionDegrees = _regionDegrees; + copy->_regionOffsetX = _regionOffsetX; + copy->_regionOffsetY = _regionOffsetY; + copy->_regionWidth = _regionWidth; + copy->_regionHeight = _regionHeight; + copy->_regionOriginalWidth = _regionOriginalWidth; + copy->_regionOriginalHeight = _regionOriginalHeight; + copy->_path = _path; + copy->_color.set(_color); + + copyTo(copy); + copy->_regionUVs.clearAndAddAll(_regionUVs); + copy->_uvs.clearAndAddAll(_uvs); + copy->_triangles.clearAndAddAll(_triangles); + copy->_hullLength = _hullLength; + + // Nonessential. + copy->_edges.clearAndAddAll(copy->_edges); + copy->_width = _width; + copy->_height = _height; + return copy; +} + +MeshAttachment* MeshAttachment::newLinkedMesh() { + MeshAttachment* copy = new (__FILE__, __LINE__) MeshAttachment(getName()); + copy->setRendererObject(getRendererObject()); + copy->_regionU = _regionU; + copy->_regionV = _regionV; + copy->_regionU2 = _regionU2; + copy->_regionV2 = _regionV2; + copy->_regionRotate = _regionRotate; + copy->_regionDegrees = _regionDegrees; + copy->_regionOffsetX = _regionOffsetX; + copy->_regionOffsetY = _regionOffsetY; + copy->_regionWidth = _regionWidth; + copy->_regionHeight = _regionHeight; + copy->_regionOriginalWidth = _regionOriginalWidth; + copy->_regionOriginalHeight = _regionOriginalHeight; + copy->_path = _path; + copy->_color.set(_color); + copy->_deformAttachment = this->_deformAttachment; + copy->setParentMesh(_parentMesh ? _parentMesh : this); + copy->updateUVs(); + return copy; +} diff --git a/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp b/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp index f3bd42670..fa837f469 100644 --- a/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp @@ -58,3 +58,12 @@ bool PathAttachment::isConstantSpeed() { void PathAttachment::setConstantSpeed(bool inValue) { _constantSpeed = inValue; } + +Attachment* PathAttachment::copy() { + PathAttachment* copy = new (__FILE__, __LINE__) PathAttachment(getName()); + copyTo(copy); + copy->_lengths.clearAndAddAll(_lengths); + copy->_closed = _closed; + copy->_constantSpeed = _constantSpeed; + return copy; +} diff --git a/spine-cpp/spine-cpp/src/spine/PointAttachment.cpp b/spine-cpp/spine-cpp/src/spine/PointAttachment.cpp index 5ea8cfad8..d3fed1772 100644 --- a/spine-cpp/spine-cpp/src/spine/PointAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/PointAttachment.cpp @@ -80,3 +80,11 @@ float PointAttachment::getRotation() { void PointAttachment::setRotation(float inValue) { _rotation = inValue; } + +Attachment* PointAttachment::copy() { + PointAttachment* copy = new(__FILE__, __LINE__) PointAttachment(getName()); + copy->_x = _x; + copy->_y = _y; + copy->_rotation = _rotation; + return copy; +} diff --git a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp index 85c72dce5..0ae286bb6 100644 --- a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp @@ -281,3 +281,26 @@ Vector &RegionAttachment::getUVs() { spine::Color &RegionAttachment::getColor() { return _color; } + +Attachment* RegionAttachment::copy() { + RegionAttachment* copy = new (__FILE__, __LINE__) RegionAttachment(getName()); + copy->_regionWidth = _regionWidth; + copy->_regionHeight = _regionHeight; + copy->_regionOffsetX = _regionOffsetX; + copy->_regionOffsetY = _regionOffsetY; + copy->_regionOriginalWidth = _regionOriginalWidth; + copy->_regionOriginalHeight = _regionOriginalHeight; + copy->setRendererObject(getRendererObject()); + copy->_path = _path; + copy->_x = _x; + copy->_y = _y; + copy->_scaleX = _scaleX; + copy->_scaleY = _scaleY; + copy->_rotation = _rotation; + copy->_width = _width; + copy->_height = _height; + copy->_uvs.clearAndAddAll(_uvs); + copy->_vertexOffset.clearAndAddAll(_vertexOffset); + copy->_color.set(_color); + return copy; +} \ No newline at end of file diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index cc204e060..fcde5bb46 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -300,6 +300,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons setError("Parent mesh not found: ", linkedMesh->_parent.buffer()); return NULL; } + linkedMesh->_mesh->_deformAttachment = linkedMesh->_inheritDeform ? static_cast(parent) : linkedMesh->_mesh; linkedMesh->_mesh->setParentMesh(static_cast(parent)); linkedMesh->_mesh->updateUVs(); _attachmentLoader->configureAttachment(linkedMesh->_mesh); @@ -455,7 +456,7 @@ SkeletonBinary::readSkin(DataInput *input, const String &skinName, SkeletonData for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) { String name(readString(input), true); Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential); - if (attachment) skin->addAttachment(slotIndex, String(name), attachment); + if (attachment) skin->setAttachment(slotIndex, String(name), attachment); } } return skin; @@ -531,14 +532,14 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo readColor(input, mesh->getColor()); String skinName(readString(input), true); String parent(readString(input), true); - mesh->_inheritDeform = readBoolean(input); + bool inheritDeform = readBoolean(input); if (nonessential) { mesh->_width = readFloat(input) * _scale; mesh->_height = readFloat(input) * _scale; } LinkedMesh *linkedMesh = new(__FILE__, __LINE__) LinkedMesh(mesh, String(skinName), slotIndex, - String(parent)); + String(parent), inheritDeform); _linkedMeshes.add(linkedMesh); return mesh; } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index 8204f3869..d1109bba3 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -569,13 +569,13 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { } _attachmentLoader->configureAttachment(mesh); } else { - mesh->_inheritDeform = Json::getInt(attachmentMap, "deform", 1) ? true : false; + bool inheritDeform = Json::getInt(attachmentMap, "deform", 1) ? true : false; LinkedMesh *linkedMesh = new(__FILE__, __LINE__) LinkedMesh(mesh, String(Json::getString( attachmentMap, "skin", 0)), slotIndex, - String(entry->_valueString)); + String(entry->_valueString), inheritDeform); _linkedMeshes.add(linkedMesh); } break; @@ -640,7 +640,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { } } - skin->addAttachment(slotIndex, skinAttachmentName, attachment); + skin->setAttachment(slotIndex, skinAttachmentName, attachment); } } } @@ -663,6 +663,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { setError(root, "Parent mesh not found: ", linkedMesh->_parent.buffer()); return NULL; } + linkedMesh->_mesh->_deformAttachment = linkedMesh->_inheritDeform ? static_cast(parent) : linkedMesh->_mesh; linkedMesh->_mesh->setParentMesh(static_cast(parent)); linkedMesh->_mesh->updateUVs(); _attachmentLoader->configureAttachment(linkedMesh->_mesh); diff --git a/spine-cpp/spine-cpp/src/spine/Skin.cpp b/spine-cpp/spine-cpp/src/spine/Skin.cpp index 4f2c8152f..6e3256ee3 100644 --- a/spine-cpp/spine-cpp/src/spine/Skin.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skin.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -44,12 +45,20 @@ using namespace spine; Skin::AttachmentMap::AttachmentMap() { } +static void disposeAttachment(Attachment* attachment) { + if (!attachment) return; + attachment->dereference(); + if (attachment->getRefCount() == 0) delete attachment; +} + void Skin::AttachmentMap::put(size_t slotIndex, const String &attachmentName, Attachment *attachment) { if (slotIndex >= _buckets.size()) _buckets.setSize(slotIndex + 1, Vector()); Vector &bucket = _buckets[slotIndex]; int existing = findInBucket(bucket, attachmentName); + attachment->reference(); if (existing >= 0) { + disposeAttachment(bucket[existing]._attachment); bucket[existing]._attachment = attachment; } else { bucket.add(Entry(slotIndex, attachmentName, attachment)); @@ -65,7 +74,10 @@ Attachment *Skin::AttachmentMap::get(size_t slotIndex, const String &attachmentN void Skin::AttachmentMap::remove(size_t slotIndex, const String &attachmentName) { if (slotIndex >= _buckets.size()) return; int existing = findInBucket(_buckets[slotIndex], attachmentName); - if (existing >= 0) _buckets[slotIndex].removeAt(existing); + if (existing >= 0) { + disposeAttachment(_buckets[slotIndex][existing]._attachment); + _buckets[slotIndex].removeAt(existing); + } } int Skin::AttachmentMap::findInBucket(Vector &bucket, const String &attachmentName) { @@ -86,11 +98,11 @@ Skin::~Skin() { Skin::AttachmentMap::Entries entries = _attachments.getEntries(); while (entries.hasNext()) { Skin::AttachmentMap::Entry entry = entries.next(); - delete entry._attachment; + disposeAttachment(entry._attachment); } } -void Skin::addAttachment(size_t slotIndex, const String &name, Attachment *attachment) { +void Skin::setAttachment(size_t slotIndex, const String &name, Attachment *attachment) { assert(attachment); _attachments.put(slotIndex, name, attachment); } @@ -143,3 +155,23 @@ void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) { } } } + +void Skin::addSkin(Skin* other) { + AttachmentMap::Entries entries = other->getAttachments(); + while(entries.hasNext()) { + AttachmentMap::Entry& entry = entries.next(); + setAttachment(entry._slotIndex, entry._name, entry._attachment); + } +} + +void Skin::copySkin(Skin* other) { + AttachmentMap::Entries entries = other->getAttachments(); + while(entries.hasNext()) { + AttachmentMap::Entry& entry = entries.next(); + if (entry._attachment->getRTTI().isExactly(MeshAttachment::rtti)) { + setAttachment(entry._slotIndex, entry._name, static_cast(entry._attachment)->newLinkedMesh()); + } else { + setAttachment(entry._slotIndex, entry._name, entry._attachment->copy()); + } + } +} diff --git a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp index 0d8f23294..539b75a97 100644 --- a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp @@ -42,7 +42,7 @@ using namespace spine; RTTI_IMPL(VertexAttachment, Attachment) -VertexAttachment::VertexAttachment(const String &name) : Attachment(name), _worldVerticesLength(0), _id(getNextID()) { +VertexAttachment::VertexAttachment(const String &name) : Attachment(name), _worldVerticesLength(0), _deformAttachment(this), _id(getNextID()) { } VertexAttachment::~VertexAttachment() { @@ -131,10 +131,6 @@ void VertexAttachment::computeWorldVertices(Slot &slot, size_t start, size_t cou } } -bool VertexAttachment::applyDeform(VertexAttachment *sourceAttachment) { - return this == sourceAttachment; -} - int VertexAttachment::getId() { return _id; } @@ -155,8 +151,23 @@ void VertexAttachment::setWorldVerticesLength(size_t inValue) { _worldVerticesLength = inValue; } +VertexAttachment* VertexAttachment::getDeformAttachment() { + return _deformAttachment; +} + +void VertexAttachment::setDeformAttachment(VertexAttachment* attachment) { + _deformAttachment = attachment; +} + int VertexAttachment::getNextID() { static int nextID = 0; return (nextID++ & 65535) << 11; } + +void VertexAttachment::copyTo(VertexAttachment* other) { + other->_bones.clearAndAddAll(this->_bones); + other->_vertices.clearAndAddAll(this->_vertices); + other->_worldVerticesLength = this->_worldVerticesLength; + other->_deformAttachment = this->_deformAttachment; +} diff --git a/spine-sfml/cpp/example/main.cpp b/spine-sfml/cpp/example/main.cpp index 6e9936087..c4ca18e69 100644 --- a/spine-sfml/cpp/example/main.cpp +++ b/spine-sfml/cpp/example/main.cpp @@ -163,7 +163,13 @@ void goblins (SkeletonData* skeletonData, Atlas* atlas) { drawable.setUsePremultipliedAlpha(true); Skeleton* skeleton = drawable.skeleton; - skeleton->setSkin("goblin"); + + Skin* skin = skeleton->getData()->findSkin("goblingirl"); + Skin copy("test"); + + copy.copySkin(skin); + + skeleton->setSkin(©); skeleton->setSlotsToSetupPose(); skeleton->setPosition(320, 590); @@ -466,7 +472,8 @@ int main () { DebugExtension dbgExtension(SpineExtension::getInstance()); SpineExtension::setInstance(&dbgExtension); - testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl-pma.atlas", 0.5f); + testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f); + /*testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl-pma.atlas", 0.5f); testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f); testcase(stretchymanStrechyIk, "data/stretchyman-stretchy-ik-pro.json", "data/stretchyman-stretchy-ik-pro.skel", "data/stretchyman-pma.atlas", 0.6f); testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor-pma.atlas", 0.5f); @@ -474,8 +481,7 @@ int main () { testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f); testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank-pma.atlas", 0.2f); testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor-pma.atlas", 0.5f); - testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f); - testcase(stretchyman, "data/stretchyman-pro.json", "data/stretchyman-pro.skel", "data/stretchyman-pma.atlas", 0.6f); + testcase(stretchyman, "data/stretchyman-pro.json", "data/stretchyman-pro.skel", "data/stretchyman-pma.atlas", 0.6f);*/ dbgExtension.reportLeaks(); return 0;