[cpp] Initial port of sequences

Loaders require modifications, timeline needs to be added.
This commit is contained in:
Mario Zechner 2021-11-17 15:32:26 +01:00
parent 4ad9c4fa24
commit 1ac6c6bd35
22 changed files with 493 additions and 432 deletions

View File

@ -5,6 +5,18 @@
### SFML ### SFML
## C++ ## C++
* **Additions**
* Support for sequences.
* **Breaking changes**
* `RegionAttachment` and `MeshAttachment` now contain a `TextureRegion*` instead of encoding region fields directly.
* `AttachmentLoader::newRegionAttachment()` and `AttachmentLoader::newMeshAttachment()` now take an additional `Sequence*` parameter.
* `MeshAttachment::updateUVs()` was renamed to `MeshAttachment::updateRegion()`.
* `RegionAttachment::updateOffset()` was renamed to `RegionAttachment::updateRegion()`, `RegionAttachment::setUVs()` was merged into `updateRegion()`.
* `Slot::getAttachmentTime()` and `Slot::setAttachmentTime()` have been removed.
* `VertexAttachment::getDeformAttachment()` was renamed to `VertexAttachment::getTimelineAttachment()`.
* `Skeleton::update()` has been removed.
* `Skeleton::getTime()` has been removed.
### Cocos2d-x ### Cocos2d-x

View File

@ -35,6 +35,7 @@
#include <spine/SpineObject.h> #include <spine/SpineObject.h>
#include <spine/SpineString.h> #include <spine/SpineString.h>
#include <spine/HasRendererObject.h> #include <spine/HasRendererObject.h>
#include "TextureRegion.h"
namespace spine { namespace spine {
enum Format { enum Format {
@ -83,16 +84,12 @@ namespace spine {
} }
}; };
class SP_API AtlasRegion : public SpineObject { class SP_API AtlasRegion : public TextureRegion {
public: public:
AtlasPage *page; AtlasPage *page;
String name; String name;
int x, y, width, height;
float u, v, u2, v2;
float offsetX, offsetY;
int originalWidth, originalHeight;
int index; int index;
int degrees; int x, y;
Vector<int> splits; Vector<int> splits;
Vector<int> pads; Vector<int> pads;
Vector <String> names; Vector <String> names;

View File

@ -48,9 +48,9 @@ namespace spine {
explicit AtlasAttachmentLoader(Atlas *atlas); explicit AtlasAttachmentLoader(Atlas *atlas);
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path); virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence);
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path); virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence);
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name); virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name);

View File

@ -51,6 +51,8 @@ namespace spine {
class ClippingAttachment; class ClippingAttachment;
class Sequence;
class SP_API AttachmentLoader : public SpineObject { class SP_API AttachmentLoader : public SpineObject {
public: public:
RTTI_DECL RTTI_DECL
@ -60,10 +62,10 @@ namespace spine {
virtual ~AttachmentLoader(); virtual ~AttachmentLoader();
/// @return May be NULL to not load any attachment. /// @return May be NULL to not load any attachment.
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path) = 0; virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) = 0;
/// @return May be NULL to not load any attachment. /// @return May be NULL to not load any attachment.
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path) = 0; virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) = 0;
/// @return May be NULL to not load any attachment. /// @return May be NULL to not load any attachment.
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) = 0; virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) = 0;

View File

@ -31,6 +31,8 @@
#define Spine_MeshAttachment_h #define Spine_MeshAttachment_h
#include <spine/VertexAttachment.h> #include <spine/VertexAttachment.h>
#include <spine/TextureRegion.h>
#include <spine/Sequence.h>
#include <spine/Vector.h> #include <spine/Vector.h>
#include <spine/Color.h> #include <spine/Color.h>
#include <spine/HasRendererObject.h> #include <spine/HasRendererObject.h>
@ -51,7 +53,10 @@ namespace spine {
virtual ~MeshAttachment(); virtual ~MeshAttachment();
void updateUVs(); virtual void computeWorldVertices(Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset,
size_t stride = 2);
void updateRegion();
int getHullLength(); int getHullLength();
@ -59,7 +64,7 @@ namespace spine {
Vector<float> &getRegionUVs(); Vector<float> &getRegionUVs();
/// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateUVs /// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateRegion
Vector<float> &getUVs(); Vector<float> &getUVs();
Vector<unsigned short> &getTriangles(); Vector<unsigned short> &getTriangles();
@ -70,52 +75,13 @@ namespace spine {
void setPath(const String &inValue); void setPath(const String &inValue);
float getRegionU(); TextureRegion *getRegion();
void setRegionU(float inValue); void setRegion(TextureRegion *region);
float getRegionV(); Sequence *getSequence();
void setRegionV(float inValue); void setSequence(Sequence *sequence);
float getRegionU2();
void setRegionU2(float inValue);
float getRegionV2();
void setRegionV2(float inValue);
int getRegionDegrees();
void setRegionDegrees(int inValue);
float getRegionOffsetX();
void setRegionOffsetX(float inValue);
// Pixels stripped from the bottom left, unrotated.
float getRegionOffsetY();
void setRegionOffsetY(float inValue);
float getRegionWidth();
void setRegionWidth(float inValue);
// Unrotated, stripped size.
float getRegionHeight();
void setRegionHeight(float inValue);
float getRegionOriginalWidth();
void setRegionOriginalWidth(float inValue);
// Unrotated, unstripped size.
float getRegionOriginalHeight();
void setRegionOriginalHeight(float inValue);
MeshAttachment *getParentMesh(); MeshAttachment *getParentMesh();
@ -137,22 +103,17 @@ namespace spine {
MeshAttachment *newLinkedMesh(); MeshAttachment *newLinkedMesh();
private: private:
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
MeshAttachment *_parentMesh; MeshAttachment *_parentMesh;
Vector<float> _uvs; Vector<float> _uvs;
Vector<float> _regionUVs; Vector<float> _regionUVs;
Vector<unsigned short> _triangles; Vector<unsigned short> _triangles;
Vector<unsigned short> _edges; Vector<unsigned short> _edges;
String _path; String _path;
float _regionU;
float _regionV;
float _regionU2;
float _regionV2;
float _width;
float _height;
Color _color; Color _color;
int _hullLength; int _hullLength;
int _regionDegrees; int _width, _height;
TextureRegion *_region;
Sequence *_sequence;
}; };
} }

View File

@ -33,6 +33,8 @@
#include <spine/Attachment.h> #include <spine/Attachment.h>
#include <spine/Vector.h> #include <spine/Vector.h>
#include <spine/Color.h> #include <spine/Color.h>
#include <spine/Sequence.h>
#include <spine/TextureRegion.h>
#include <spine/HasRendererObject.h> #include <spine/HasRendererObject.h>
@ -54,7 +56,9 @@ namespace spine {
public: public:
explicit RegionAttachment(const String &name); explicit RegionAttachment(const String &name);
void updateOffset(); virtual ~RegionAttachment();
void updateRegion();
void setUVs(float u, float v, float u2, float v2, float degrees); void setUVs(float u, float v, float u2, float v2, float degrees);
@ -63,9 +67,9 @@ namespace spine {
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8. /// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.
/// @param offset The worldVertices index to begin writing values. /// @param offset The worldVertices index to begin writing values.
/// @param stride The number of worldVertices entries between the value pairs written. /// @param stride The number of worldVertices entries between the value pairs written.
void computeWorldVertices(Bone &bone, float *worldVertices, size_t offset, size_t stride = 2); void computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride = 2);
void computeWorldVertices(Bone &bone, Vector<float> &worldVertices, size_t offset, size_t stride = 2); void computeWorldVertices(Slot &slot, Vector<float> &worldVertices, size_t offset, size_t stride = 2);
float getX(); float getX();
@ -101,29 +105,13 @@ namespace spine {
void setPath(const String &inValue); void setPath(const String &inValue);
float getRegionOffsetX(); TextureRegion *getRegion();
void setRegionOffsetX(float inValue); void setRegion(TextureRegion *region);
float getRegionOffsetY(); Sequence *getSequence();
void setRegionOffsetY(float inValue); void setSequence(Sequence *sequence);
float getRegionWidth();
void setRegionWidth(float inValue);
float getRegionHeight();
void setRegionHeight(float inValue);
float getRegionOriginalWidth();
void setRegionOriginalWidth(float inValue);
float getRegionOriginalHeight();
void setRegionOriginalHeight(float inValue);
Vector<float> &getOffset(); Vector<float> &getOffset();
@ -142,15 +130,12 @@ namespace spine {
static const int BRY; static const int BRY;
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height; float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
Vector<float> _vertexOffset; Vector<float> _vertexOffset;
Vector<float> _uvs; Vector<float> _uvs;
String _path; String _path;
float _regionU;
float _regionV;
float _regionU2;
float _regionV2;
Color _color; Color _color;
TextureRegion *_region;
Sequence *_sequence;
}; };
} }

View File

@ -0,0 +1,96 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef Spine_Sequence_h
#define Spine_Sequence_h
#include <spine/Vector.h>
#include <spine/SpineString.h>
#include <spine/TextureRegion.h>
namespace spine {
class Slot;
class Attachment;
class SP_API Sequence : public SpineObject {
public:
explicit Sequence();
Sequence(int id, const Vector<TextureRegion *> &regions, int start, int digits, int setupIndex);
~Sequence();
Sequence *copy();
void apply(Slot *slot, Attachment *attachment);
String getPath(const String &basePath, int index);
int getId() { return _id; }
void setId(int id) { _id = id; }
int getStart() { return _start; }
void setStart(int start) { _start = start; }
int getDigits() { return _digits; }
void setDigits(int digits) { _digits = digits; }
int getSetupIndex() { return _setupIndex; }
void setSetupIndex(int setupIndex) { _setupIndex = setupIndex; }
Vector<TextureRegion *> &getRegions() { return _regions; }
private:
int _id;
Vector<TextureRegion *> _regions;
int _start;
int _digits;
int _setupIndex;
int getNextID();
};
enum SequenceMode {
hold = 0,
once = 1,
loop = 2,
pingpong = 3,
onceReverse = 4,
loopReverse = 5,
pingpongReverse = 6
};
}
#endif

View File

@ -172,8 +172,6 @@ namespace spine {
/// @return May be NULL. /// @return May be NULL.
PathConstraint *findPathConstraint(const String &constraintName); PathConstraint *findPathConstraint(const String &constraintName);
void update(float delta);
/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. /// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
/// @param outX The horizontal distance between the skeleton origin and the left side of the AABB. /// @param outX The horizontal distance between the skeleton origin and the left side of the AABB.
/// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB. /// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB.
@ -204,10 +202,6 @@ namespace spine {
Color &getColor(); Color &getColor();
float getTime();
void setTime(float inValue);
void setPosition(float x, float y); void setPosition(float x, float y);
float getX(); float getX();
@ -237,7 +231,6 @@ namespace spine {
Vector<Updatable *> _updateCache; Vector<Updatable *> _updateCache;
Skin *_skin; Skin *_skin;
Color _color; Color _color;
float _time;
float _scaleX, _scaleY; float _scaleX, _scaleY;
float _x, _y; float _x, _y;

View File

@ -114,12 +114,12 @@ namespace spine {
void setAttachmentState(int state); void setAttachmentState(int state);
float getAttachmentTime();
void setAttachmentTime(float inValue);
Vector<float> &getDeform(); Vector<float> &getDeform();
int getSequenceIndex();
void setSequenceIndex(int index);
private: private:
SlotData &_data; SlotData &_data;
Bone &_bone; Bone &_bone;
@ -129,7 +129,7 @@ namespace spine {
bool _hasDarkColor; bool _hasDarkColor;
Attachment *_attachment; Attachment *_attachment;
int _attachmentState; int _attachmentState;
float _attachmentTime; int _sequenceIndex;
Vector<float> _deform; Vector<float> _deform;
}; };
} }

View File

@ -0,0 +1,50 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef Spine_TextureRegion_h
#define Spine_TextureRegion_h
#include <spine/Vector.h>
namespace spine {
class SP_API TextureRegion : public SpineObject {
public:
void *rendererObject;
float u, v, u2, v2;
int degrees;
float offsetX, offsetY;
int width, height;
int originalWidth, originalHeight;
TextureRegion(): rendererObject(NULL), u(0), v(0), u2(0), v2(0), degrees(0), offsetX(0), offsetY(0), width(0), height(0), originalWidth(0), originalHeight(0) {};
~TextureRegion() {};
};
}
#endif

View File

@ -62,10 +62,10 @@ namespace spine {
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + count. /// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + count.
/// @param offset The worldVertices index to begin writing values. /// @param offset The worldVertices index to begin writing values.
/// @param stride The number of worldVertices entries between the value pairs written. /// @param stride The number of worldVertices entries between the value pairs written.
void computeWorldVertices(Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset, virtual void computeWorldVertices(Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset,
size_t stride = 2); size_t stride = 2);
void computeWorldVertices(Slot &slot, size_t start, size_t count, Vector<float> &worldVertices, size_t offset, virtual void computeWorldVertices(Slot &slot, size_t start, size_t count, Vector<float> &worldVertices, size_t offset,
size_t stride = 2); size_t stride = 2);
/// Gets a unique ID for this attachment. /// Gets a unique ID for this attachment.
@ -79,9 +79,9 @@ namespace spine {
void setWorldVerticesLength(size_t inValue); void setWorldVerticesLength(size_t inValue);
VertexAttachment *getDeformAttachment(); Attachment * getTimelineAttachment();
void setDeformAttachment(VertexAttachment *attachment); void setTimelineAttachment(Attachment *attachment);
void copyTo(VertexAttachment *other); void copyTo(VertexAttachment *other);
@ -89,7 +89,7 @@ namespace spine {
Vector <size_t> _bones; Vector <size_t> _bones;
Vector<float> _vertices; Vector<float> _vertices;
size_t _worldVerticesLength; size_t _worldVerticesLength;
VertexAttachment *_deformAttachment; Attachment *_timelineAttachment;
private: private:
const int _id; const int _id;

View File

@ -48,53 +48,44 @@ namespace spine {
AtlasAttachmentLoader::AtlasAttachmentLoader(Atlas *atlas) : AttachmentLoader(), _atlas(atlas) { AtlasAttachmentLoader::AtlasAttachmentLoader(Atlas *atlas) : AttachmentLoader(), _atlas(atlas) {
} }
RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const String &name, const String &path) { bool loadSequence (Atlas *atlas, const String &basePath, Sequence *sequence) {
SP_UNUSED(skin); Vector<TextureRegion *> &regions = sequence->getRegions();
for (int i = 0, n = regions.size(); i < n; i++) {
AtlasRegion *regionP = findRegion(path); String path = sequence->getPath(basePath, i);
if (!regionP) return NULL; regions[i] = atlas->findRegion(path);
if (!regions[i]) return false;
AtlasRegion &region = *regionP; regions[i]->rendererObject = regions[i];
}
RegionAttachment *attachmentP = new (__FILE__, __LINE__) RegionAttachment(name); return true;
RegionAttachment &attachment = *attachmentP;
attachment.setRendererObject(regionP);
attachment.setUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment._regionOffsetX = region.offsetX;
attachment._regionOffsetY = region.offsetY;
attachment._regionWidth = (float) region.width;
attachment._regionHeight = (float) region.height;
attachment._regionOriginalWidth = (float) region.originalWidth;
attachment._regionOriginalHeight = (float) region.originalHeight;
return attachmentP;
} }
MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const String &name, const String &path) { RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) {
SP_UNUSED(skin); SP_UNUSED(skin);
RegionAttachment *attachment = new(__FILE__, __LINE__) RegionAttachment(name);
if (sequence) {
if (!loadSequence(_atlas, path, sequence)) return NULL;
} else {
AtlasRegion *region = findRegion(path);
if (!region) return NULL;
attachment->setRendererObject(region);
attachment->setRegion(region);
}
return attachment;
}
AtlasRegion *regionP = findRegion(path); MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) {
if (!regionP) return NULL; SP_UNUSED(skin);
MeshAttachment *attachment = new (__FILE__, __LINE__) MeshAttachment(name);
AtlasRegion &region = *regionP; if (sequence) {
if (!loadSequence(_atlas, path, sequence)) return NULL;
MeshAttachment *attachmentP = new (__FILE__, __LINE__) MeshAttachment(name); } else {
AtlasRegion *region = findRegion(path);
MeshAttachment &attachment = *attachmentP; if (!region) return NULL;
attachment.setRendererObject(regionP); attachment->setRendererObject(region);
attachment._regionU = region.u; attachment->setRegion(region);
attachment._regionV = region.v; }
attachment._regionU2 = region.u2; return attachment;
attachment._regionV2 = region.v2;
attachment._regionDegrees = region.degrees;
attachment._regionOffsetX = region.offsetX;
attachment._regionOffsetY = region.offsetY;
attachment._regionWidth = (float) region.width;
attachment._regionHeight = (float) region.height;
attachment._regionOriginalWidth = (float) region.originalWidth;
attachment._regionOriginalHeight = (float) region.originalHeight;
return attachmentP;
} }
BoundingBoxAttachment *AtlasAttachmentLoader::newBoundingBoxAttachment(Skin &skin, const String &name) { BoundingBoxAttachment *AtlasAttachmentLoader::newBoundingBoxAttachment(Skin &skin, const String &name) {

View File

@ -76,7 +76,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} }
VertexAttachment *attachment = static_cast<VertexAttachment *>(slotAttachment); VertexAttachment *attachment = static_cast<VertexAttachment *>(slotAttachment);
if (attachment->_deformAttachment != _attachment) { if (attachment->_timelineAttachment != _attachment) {
return; return;
} }

View File

@ -39,43 +39,36 @@ using namespace spine;
RTTI_IMPL(MeshAttachment, VertexAttachment) RTTI_IMPL(MeshAttachment, VertexAttachment)
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name), HasRendererObject(), MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name), HasRendererObject(),
_regionOffsetX(0),
_regionOffsetY(0),
_regionWidth(0),
_regionHeight(0),
_regionOriginalWidth(0),
_regionOriginalHeight(0),
_parentMesh(NULL), _parentMesh(NULL),
_path(), _path(),
_regionU(0),
_regionV(0),
_regionU2(0),
_regionV2(0),
_width(0),
_height(0),
_color(1, 1, 1, 1), _color(1, 1, 1, 1),
_hullLength(0), _hullLength(0),
_regionDegrees(0) {} _width(0),
_height(0),
_region(NULL),
_sequence(NULL) {}
MeshAttachment::~MeshAttachment() {} MeshAttachment::~MeshAttachment() {
if (_sequence) delete _sequence;
}
void MeshAttachment::updateUVs() { void MeshAttachment::updateRegion() {
if (_uvs.size() != _regionUVs.size()) { if (_uvs.size() != _regionUVs.size()) {
_uvs.setSize(_regionUVs.size(), 0); _uvs.setSize(_regionUVs.size(), 0);
} }
int i = 0, n = _regionUVs.size(); int i = 0, n = _regionUVs.size();
float u = _regionU, v = _regionV; float u = _region->u, v = _region->v;
float width = 0, height = 0; float width = 0, height = 0;
switch (_regionDegrees) { switch (_region->degrees) {
case 90: { case 90: {
float textureWidth = _regionHeight / (_regionU2 - _regionU); float textureWidth = _region->height / (_region->u2 - _region->u);
float textureHeight = _regionWidth / (_regionV2 - _regionV); float textureHeight = _region->width / (_region->v2 - _region->v);
u -= (_regionOriginalHeight - _regionOffsetY - _regionHeight) / textureWidth; u -= (_region->originalHeight - _region->offsetY - _region->height) / textureWidth;
v -= (_regionOriginalWidth - _regionOffsetX - _regionWidth) / textureHeight; v -= (_region->originalWidth - _region->offsetX - _region->width) / textureHeight;
width = _regionOriginalHeight / textureWidth; width = _region->originalHeight / textureWidth;
height = _regionOriginalWidth / textureHeight; height = _region->originalWidth / textureHeight;
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i + 1] * width; _uvs[i] = u + _regionUVs[i + 1] * width;
_uvs[i + 1] = v + (1 - _regionUVs[i]) * height; _uvs[i + 1] = v + (1 - _regionUVs[i]) * height;
@ -83,12 +76,12 @@ void MeshAttachment::updateUVs() {
return; return;
} }
case 180: { case 180: {
float textureWidth = _regionWidth / (_regionU2 - _regionU); float textureWidth = _region->width / (_region->u2 - _region->u);
float textureHeight = _regionHeight / (_regionV2 - _regionV); float textureHeight = _region->height / (_region->v2 - _region->v);
u -= (_regionOriginalWidth - _regionOffsetX - _regionWidth) / textureWidth; u -= (_region->originalWidth - _region->offsetX - _region->width) / textureWidth;
v -= _regionOffsetY / textureHeight; v -= _region->offsetY / textureHeight;
width = _regionOriginalWidth / textureWidth; width = _region->originalWidth / textureWidth;
height = _regionOriginalHeight / textureHeight; height = _region->originalHeight / textureHeight;
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i]) * width; _uvs[i] = u + (1 - _regionUVs[i]) * width;
_uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height; _uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height;
@ -96,12 +89,12 @@ void MeshAttachment::updateUVs() {
return; return;
} }
case 270: { case 270: {
float textureHeight = _regionHeight / (_regionV2 - _regionV); float textureHeight = _region->height / (_region->v2 - _region->v);
float textureWidth = _regionWidth / (_regionU2 - _regionU); float textureWidth = _region->width / (_region->u2 - _region->u);
u -= _regionOffsetY / textureWidth; u -= _region->offsetY / textureWidth;
v -= _regionOffsetX / textureHeight; v -= _region->offsetX / textureHeight;
width = _regionOriginalHeight / textureWidth; width = _region->originalHeight / textureWidth;
height = _regionOriginalWidth / textureHeight; height = _region->originalWidth / textureHeight;
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i + 1]) * width; _uvs[i] = u + (1 - _regionUVs[i + 1]) * width;
_uvs[i + 1] = v + _regionUVs[i] * height; _uvs[i + 1] = v + _regionUVs[i] * height;
@ -109,12 +102,12 @@ void MeshAttachment::updateUVs() {
return; return;
} }
default: { default: {
float textureWidth = _regionWidth / (_regionU2 - _regionU); float textureWidth = _region->width / (_region->u2 - _region->u);
float textureHeight = _regionHeight / (_regionV2 - _regionV); float textureHeight = _region->height / (_region->v2 - _region->v);
u -= _regionOffsetX / textureWidth; u -= _region->offsetX / textureWidth;
v -= (_regionOriginalHeight - _regionOffsetY - _regionHeight) / textureHeight; v -= (_region->originalHeight - _region->offsetY - _region->height) / textureHeight;
width = _regionOriginalWidth / textureWidth; width = _region->originalWidth / textureWidth;
height = _regionOriginalHeight / textureHeight; height = _region->originalHeight / textureHeight;
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i] * width; _uvs[i] = u + _regionUVs[i] * width;
_uvs[i + 1] = v + _regionUVs[i + 1] * height; _uvs[i + 1] = v + _regionUVs[i + 1] * height;
@ -151,94 +144,6 @@ void MeshAttachment::setPath(const String &inValue) {
_path = inValue; _path = inValue;
} }
float MeshAttachment::getRegionU() {
return _regionU;
}
void MeshAttachment::setRegionU(float inValue) {
_regionU = inValue;
}
float MeshAttachment::getRegionV() {
return _regionV;
}
void MeshAttachment::setRegionV(float inValue) {
_regionV = inValue;
}
float MeshAttachment::getRegionU2() {
return _regionU2;
}
void MeshAttachment::setRegionU2(float inValue) {
_regionU2 = inValue;
}
float MeshAttachment::getRegionV2() {
return _regionV2;
}
void MeshAttachment::setRegionV2(float inValue) {
_regionV2 = inValue;
}
int MeshAttachment::getRegionDegrees() {
return _regionDegrees;
}
void MeshAttachment::setRegionDegrees(int inValue) {
_regionDegrees = inValue;
}
float MeshAttachment::getRegionOffsetX() {
return _regionOffsetX;
}
void MeshAttachment::setRegionOffsetX(float inValue) {
_regionOffsetX = inValue;
}
float MeshAttachment::getRegionOffsetY() {
return _regionOffsetY;
}
void MeshAttachment::setRegionOffsetY(float inValue) {
_regionOffsetY = inValue;
}
float MeshAttachment::getRegionWidth() {
return _regionWidth;
}
void MeshAttachment::setRegionWidth(float inValue) {
_regionWidth = inValue;
}
float MeshAttachment::getRegionHeight() {
return _regionHeight;
}
void MeshAttachment::setRegionHeight(float inValue) {
_regionHeight = inValue;
}
float MeshAttachment::getRegionOriginalWidth() {
return _regionOriginalWidth;
}
void MeshAttachment::setRegionOriginalWidth(float inValue) {
_regionOriginalWidth = inValue;
}
float MeshAttachment::getRegionOriginalHeight() {
return _regionOriginalHeight;
}
void MeshAttachment::setRegionOriginalHeight(float inValue) {
_regionOriginalHeight = inValue;
}
MeshAttachment *MeshAttachment::getParentMesh() { MeshAttachment *MeshAttachment::getParentMesh() {
return _parentMesh; return _parentMesh;
} }
@ -287,17 +192,8 @@ Attachment *MeshAttachment::copy() {
MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName()); MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName());
copy->setRendererObject(getRendererObject()); copy->setRendererObject(getRendererObject());
copy->_regionU = _regionU; copy->setRegion(_region);
copy->_regionV = _regionV; copy->setSequence(_sequence != NULL ? _sequence->copy() : NULL);
copy->_regionU2 = _regionU2;
copy->_regionV2 = _regionV2;
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->_path = _path;
copy->_color.set(_color); copy->_color.set(_color);
@ -317,21 +213,17 @@ Attachment *MeshAttachment::copy() {
MeshAttachment *MeshAttachment::newLinkedMesh() { MeshAttachment *MeshAttachment::newLinkedMesh() {
MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName()); MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName());
copy->setRendererObject(getRendererObject()); copy->setRendererObject(getRendererObject());
copy->_regionU = _regionU; copy->setRegion(_region);
copy->_regionV = _regionV;
copy->_regionU2 = _regionU2;
copy->_regionV2 = _regionV2;
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->_path = _path;
copy->_color.set(_color); copy->_color.set(_color);
copy->_deformAttachment = this->_deformAttachment; copy->_timelineAttachment = this->_timelineAttachment;
copy->setParentMesh(_parentMesh ? _parentMesh : this); copy->setParentMesh(_parentMesh ? _parentMesh : this);
copy->updateUVs(); if (copy->_region) copy->updateRegion();
return copy; return copy;
} }
void MeshAttachment::computeWorldVertices(Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset,
size_t stride) {
if (_sequence) _sequence->apply(&slot, this);
VertexAttachment::computeWorldVertices(slot, start, count, worldVertices, offset, stride);
}

View File

@ -34,6 +34,7 @@
#include <spine/RegionAttachment.h> #include <spine/RegionAttachment.h>
#include <spine/Bone.h> #include <spine/Bone.h>
#include <spine/Slot.h>
#include <assert.h> #include <assert.h>
@ -58,29 +59,25 @@ RegionAttachment::RegionAttachment(const String &name) : Attachment(name), HasRe
_scaleY(1), _scaleY(1),
_width(0), _width(0),
_height(0), _height(0),
_regionOffsetX(0),
_regionOffsetY(0),
_regionWidth(0),
_regionHeight(0),
_regionOriginalWidth(0),
_regionOriginalHeight(0),
_path(), _path(),
_regionU(0), _color(1, 1, 1, 1),
_regionV(0), _region(NULL),
_regionU2(0), _sequence(NULL) {
_regionV2(0),
_color(1, 1, 1, 1) {
_vertexOffset.setSize(NUM_UVS, 0); _vertexOffset.setSize(NUM_UVS, 0);
_uvs.setSize(NUM_UVS, 0); _uvs.setSize(NUM_UVS, 0);
} }
void RegionAttachment::updateOffset() { RegionAttachment::~RegionAttachment() {
float regionScaleX = _width / _regionOriginalWidth * _scaleX; if (_sequence) delete _sequence;
float regionScaleY = _height / _regionOriginalHeight * _scaleY; }
float localX = -_width / 2 * _scaleX + _regionOffsetX * regionScaleX;
float localY = -_height / 2 * _scaleY + _regionOffsetY * regionScaleY; void RegionAttachment::updateRegion() {
float localX2 = localX + _regionWidth * regionScaleX; float regionScaleX = _width / _region->originalWidth * _scaleX;
float localY2 = localY + _regionHeight * regionScaleY; float regionScaleY = _height / _region->originalHeight * _scaleY;
float localX = -_width / 2 * _scaleX + _region->offsetX * regionScaleX;
float localY = -_height / 2 * _scaleY + _region->offsetY * regionScaleY;
float localX2 = localX + _region->width * regionScaleX;
float localY2 = localY + _region->height * regionScaleY;
float cos = MathUtil::cosDeg(_rotation); float cos = MathUtil::cosDeg(_rotation);
float sin = MathUtil::sinDeg(_rotation); float sin = MathUtil::sinDeg(_rotation);
float localXCos = localX * cos + _x; float localXCos = localX * cos + _x;
@ -100,36 +97,37 @@ void RegionAttachment::updateOffset() {
_vertexOffset[URY] = localY2Cos + localX2Sin; _vertexOffset[URY] = localY2Cos + localX2Sin;
_vertexOffset[BRX] = localX2Cos - localYSin; _vertexOffset[BRX] = localX2Cos - localYSin;
_vertexOffset[BRY] = localYCos + localX2Sin; _vertexOffset[BRY] = localYCos + localX2Sin;
}
void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) { if (_region->degrees == 90) {
if (degrees == 90) { _uvs[URX] = _region->u;
_uvs[URX] = u; _uvs[URY] = _region->v2;
_uvs[URY] = v2; _uvs[BRX] = _region->u;
_uvs[BRX] = u; _uvs[BRY] = _region->v;
_uvs[BRY] = v; _uvs[BLX] = _region->u2;
_uvs[BLX] = u2; _uvs[BLY] = _region->v;
_uvs[BLY] = v; _uvs[ULX] = _region->u2;
_uvs[ULX] = u2; _uvs[ULY] = _region->v2;
_uvs[ULY] = v2;
} else { } else {
_uvs[ULX] = u; _uvs[ULX] = _region->u;
_uvs[ULY] = v2; _uvs[ULY] = _region->v2;
_uvs[URX] = u; _uvs[URX] = _region->u;
_uvs[URY] = v; _uvs[URY] = _region->v;
_uvs[BRX] = u2; _uvs[BRX] = _region->u2;
_uvs[BRY] = v; _uvs[BRY] = _region->v;
_uvs[BLX] = u2; _uvs[BLX] = _region->u2;
_uvs[BLY] = v2; _uvs[BLY] = _region->v2;
} }
} }
void RegionAttachment::computeWorldVertices(Bone &bone, Vector<float> &worldVertices, size_t offset, size_t stride) { void RegionAttachment::computeWorldVertices(Slot &slot, Vector<float> &worldVertices, size_t offset, size_t stride) {
assert(worldVertices.size() >= (offset + 8)); assert(worldVertices.size() >= (offset + 8));
computeWorldVertices(bone, worldVertices.buffer(), offset, stride); computeWorldVertices(slot, worldVertices.buffer(), offset, stride);
} }
void RegionAttachment::computeWorldVertices(Bone &bone, float *worldVertices, size_t offset, size_t stride) { void RegionAttachment::computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride) {
if (_sequence) _sequence->apply(&slot, this);
Bone &bone = slot.getBone();
float x = bone.getWorldX(), y = bone.getWorldY(); float x = bone.getWorldX(), y = bone.getWorldY();
float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD(); float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD();
float offsetX, offsetY; float offsetX, offsetY;
@ -222,52 +220,20 @@ void RegionAttachment::setPath(const String &inValue) {
_path = inValue; _path = inValue;
} }
float RegionAttachment::getRegionOffsetX() { TextureRegion *RegionAttachment::getRegion() {
return _regionOffsetX; return _region;
} }
void RegionAttachment::setRegionOffsetX(float inValue) { void RegionAttachment::setRegion(TextureRegion *region) {
_regionOffsetX = inValue; _region = region;
} }
float RegionAttachment::getRegionOffsetY() { Sequence *RegionAttachment::getSequence() {
return _regionOffsetY; return _sequence;
} }
void RegionAttachment::setRegionOffsetY(float inValue) { void RegionAttachment::setSequence(Sequence *sequence) {
_regionOffsetY = inValue; _sequence = sequence;
}
float RegionAttachment::getRegionWidth() {
return _regionWidth;
}
void RegionAttachment::setRegionWidth(float inValue) {
_regionWidth = inValue;
}
float RegionAttachment::getRegionHeight() {
return _regionHeight;
}
void RegionAttachment::setRegionHeight(float inValue) {
_regionHeight = inValue;
}
float RegionAttachment::getRegionOriginalWidth() {
return _regionOriginalWidth;
}
void RegionAttachment::setRegionOriginalWidth(float inValue) {
_regionOriginalWidth = inValue;
}
float RegionAttachment::getRegionOriginalHeight() {
return _regionOriginalHeight;
}
void RegionAttachment::setRegionOriginalHeight(float inValue) {
_regionOriginalHeight = inValue;
} }
Vector<float> &RegionAttachment::getOffset() { Vector<float> &RegionAttachment::getOffset() {
@ -284,12 +250,7 @@ spine::Color &RegionAttachment::getColor() {
Attachment *RegionAttachment::copy() { Attachment *RegionAttachment::copy() {
RegionAttachment *copy = new (__FILE__, __LINE__) RegionAttachment(getName()); RegionAttachment *copy = new (__FILE__, __LINE__) RegionAttachment(getName());
copy->_regionWidth = _regionWidth; copy->_region = _region;
copy->_regionHeight = _regionHeight;
copy->_regionOffsetX = _regionOffsetX;
copy->_regionOffsetY = _regionOffsetY;
copy->_regionOriginalWidth = _regionOriginalWidth;
copy->_regionOriginalHeight = _regionOriginalHeight;
copy->setRendererObject(getRendererObject()); copy->setRendererObject(getRendererObject());
copy->_path = _path; copy->_path = _path;
copy->_x = _x; copy->_x = _x;
@ -302,5 +263,6 @@ Attachment *RegionAttachment::copy() {
copy->_uvs.clearAndAddAll(_uvs); copy->_uvs.clearAndAddAll(_uvs);
copy->_vertexOffset.clearAndAddAll(_vertexOffset); copy->_vertexOffset.clearAndAddAll(_vertexOffset);
copy->_color.set(_color); copy->_color.set(_color);
copy->_sequence = _sequence != NULL ? _sequence->copy() : NULL;
return copy; return copy;
} }

View File

@ -0,0 +1,97 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/Sequence.h>
#include <spine/Slot.h>
#include <spine/Attachment.h>
#include <spine/RegionAttachment.h>
#include <spine/MeshAttachment.h>
using namespace spine;
Sequence::Sequence() : _id(Sequence::getNextID()),
_regions(),
_start(0),
_digits(0),
_setupIndex(0) {
}
Sequence::~Sequence() {
}
Sequence *Sequence::copy() {
Sequence *copy = new (__FILE__, __LINE__) Sequence();
for (size_t i = 0; i < _regions.size(); i++) {
copy->_regions.add(_regions[i]);
}
copy->_start = _start;
copy->_digits = _digits;
copy->_setupIndex = _setupIndex;
return copy;
}
void Sequence::apply(Slot *slot, Attachment *attachment) {
int index = slot->getSequenceIndex();
if (index == -1) index = _setupIndex;
if (index >= (int)_regions.size()) index = _regions.size() - 1;
TextureRegion *region = _regions[index];
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment *regionAttachment = static_cast<RegionAttachment *>(attachment);
if (regionAttachment->getRegion() != region) {
regionAttachment->setRegion(region);
regionAttachment->updateRegion();
}
}
if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
MeshAttachment *meshAttachment = static_cast<MeshAttachment *>(attachment);
if (meshAttachment->getRegion() != region) {
meshAttachment->setRegion(region);
meshAttachment->updateRegion();
}
}
}
String Sequence::getPath(const String &basePath, int index) {
String result(basePath);
String frame;
frame.append(_start + index);
for (int i = _digits - frame.length(); i > 0; i--)
result.append("0");
result.append(frame);
return result;
}
int Sequence::getNextID() {
static int _nextID = 0;
return _nextID;
}

View File

@ -60,7 +60,6 @@ using namespace spine;
Skeleton::Skeleton(SkeletonData *skeletonData) : _data(skeletonData), Skeleton::Skeleton(SkeletonData *skeletonData) : _data(skeletonData),
_skin(NULL), _skin(NULL),
_color(1, 1, 1, 1), _color(1, 1, 1, 1),
_time(0),
_scaleX(1), _scaleX(1),
_scaleY(1), _scaleY(1),
_x(0), _x(0),
@ -427,10 +426,6 @@ PathConstraint *Skeleton::findPathConstraint(const String &constraintName) {
return NULL; return NULL;
} }
void Skeleton::update(float delta) {
_time += delta;
}
void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer) { void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer) {
float minX = FLT_MAX; float minX = FLT_MAX;
float minY = FLT_MAX; float minY = FLT_MAX;
@ -450,7 +445,7 @@ void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHe
if (outVertexBuffer.size() < 8) { if (outVertexBuffer.size() < 8) {
outVertexBuffer.setSize(8, 0); outVertexBuffer.setSize(8, 0);
} }
regionAttachment->computeWorldVertices(slot->getBone(), outVertexBuffer, 0); regionAttachment->computeWorldVertices(*slot, outVertexBuffer, 0);
} else if (attachment != NULL && attachment->getRTTI().instanceOf(MeshAttachment::rtti)) { } else if (attachment != NULL && attachment->getRTTI().instanceOf(MeshAttachment::rtti)) {
MeshAttachment *mesh = static_cast<MeshAttachment *>(attachment); MeshAttachment *mesh = static_cast<MeshAttachment *>(attachment);
@ -459,7 +454,7 @@ void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHe
outVertexBuffer.setSize(verticesLength, 0); outVertexBuffer.setSize(verticesLength, 0);
} }
mesh->computeWorldVertices(*slot, 0, verticesLength, outVertexBuffer, 0); mesh->computeWorldVertices(*slot, 0, verticesLength, outVertexBuffer.buffer(), 0);
} }
for (size_t ii = 0; ii < verticesLength; ii += 2) { for (size_t ii = 0; ii < verticesLength; ii += 2) {
@ -523,14 +518,6 @@ Color &Skeleton::getColor() {
return _color; return _color;
} }
float Skeleton::getTime() {
return _time;
}
void Skeleton::setTime(float inValue) {
_time = inValue;
}
void Skeleton::setPosition(float x, float y) { void Skeleton::setPosition(float x, float y) {
_x = x; _x = x;
_y = y; _y = y;

View File

@ -298,10 +298,10 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
setError("Parent mesh not found: ", linkedMesh->_parent.buffer()); setError("Parent mesh not found: ", linkedMesh->_parent.buffer());
return NULL; return NULL;
} }
linkedMesh->_mesh->_deformAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent) linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh; : linkedMesh->_mesh;
linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent)); linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
linkedMesh->_mesh->updateUVs(); linkedMesh->_mesh->updateRegion();
_attachmentLoader->configureAttachment(linkedMesh->_mesh); _attachmentLoader->configureAttachment(linkedMesh->_mesh);
} }
ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);
@ -502,7 +502,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
region->_width = readFloat(input) * _scale; region->_width = readFloat(input) * _scale;
region->_height = readFloat(input) * _scale; region->_height = readFloat(input) * _scale;
readColor(input, region->getColor()); readColor(input, region->getColor());
region->updateOffset(); region->updateRegion();
_attachmentLoader->configureAttachment(region); _attachmentLoader->configureAttachment(region);
return region; return region;
} }
@ -537,7 +537,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
readFloatArray(input, vertexCount << 1, 1, mesh->getRegionUVs()); readFloatArray(input, vertexCount << 1, 1, mesh->getRegionUVs());
readShortArray(input, mesh->getTriangles()); readShortArray(input, mesh->getTriangles());
readVertices(input, static_cast<VertexAttachment *>(mesh), vertexCount); readVertices(input, static_cast<VertexAttachment *>(mesh), vertexCount);
mesh->updateUVs(); mesh->updateRegion();
mesh->_hullLength = readVarint(input, true) << 1; mesh->_hullLength = readVarint(input, true) << 1;
if (nonessential) { if (nonessential) {
readShortArray(input, mesh->getEdges()); readShortArray(input, mesh->getEdges());

View File

@ -569,7 +569,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
color = Json::getString(attachmentMap, "color", 0); color = Json::getString(attachmentMap, "color", 0);
if (color) toColor(region->getColor(), color, true); if (color) toColor(region->getColor(), color, true);
region->updateOffset(); region->updateRegion();
_attachmentLoader->configureAttachment(region); _attachmentLoader->configureAttachment(region);
break; break;
} }
@ -610,7 +610,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
readVertices(attachmentMap, mesh, verticesLength); readVertices(attachmentMap, mesh, verticesLength);
mesh->updateUVs(); mesh->updateRegion();
mesh->_hullLength = Json::getInt(attachmentMap, "hull", 0); mesh->_hullLength = Json::getInt(attachmentMap, "hull", 0);
@ -722,10 +722,10 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
setError(root, "Parent mesh not found: ", linkedMesh->_parent.buffer()); setError(root, "Parent mesh not found: ", linkedMesh->_parent.buffer());
return NULL; return NULL;
} }
linkedMesh->_mesh->_deformAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent) linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh; : linkedMesh->_mesh;
linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent)); linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
linkedMesh->_mesh->updateUVs(); linkedMesh->_mesh->updateRegion();
_attachmentLoader->configureAttachment(linkedMesh->_mesh); _attachmentLoader->configureAttachment(linkedMesh->_mesh);
} }
ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);

View File

@ -49,7 +49,7 @@ Slot::Slot(SlotData &data, Bone &bone) : _data(data),
_hasDarkColor(data.hasDarkColor()), _hasDarkColor(data.hasDarkColor()),
_attachment(NULL), _attachment(NULL),
_attachmentState(0), _attachmentState(0),
_attachmentTime(0) { _sequenceIndex(0) {
setToSetupPose(); setToSetupPose();
} }
@ -103,12 +103,13 @@ void Slot::setAttachment(Attachment *inValue) {
!_attachment || !_attachment ||
!inValue->getRTTI().instanceOf(VertexAttachment::rtti) || !inValue->getRTTI().instanceOf(VertexAttachment::rtti) ||
!_attachment->getRTTI().instanceOf(VertexAttachment::rtti) || !_attachment->getRTTI().instanceOf(VertexAttachment::rtti) ||
static_cast<VertexAttachment *>(inValue)->getDeformAttachment() != static_cast<VertexAttachment *>(_attachment)->getDeformAttachment()) { static_cast<VertexAttachment *>(inValue)->getTimelineAttachment() !=
static_cast<VertexAttachment *>(_attachment)->getTimelineAttachment()) {
_deform.clear(); _deform.clear();
} }
_attachment = inValue; _attachment = inValue;
_attachmentTime = _skeleton.getTime(); _sequenceIndex = -1;
} }
int Slot::getAttachmentState() { int Slot::getAttachmentState() {
@ -119,14 +120,14 @@ void Slot::setAttachmentState(int state) {
_attachmentState = state; _attachmentState = state;
} }
float Slot::getAttachmentTime() {
return _skeleton.getTime() - _attachmentTime;
}
void Slot::setAttachmentTime(float inValue) {
_attachmentTime = _skeleton.getTime() - inValue;
}
Vector<float> &Slot::getDeform() { Vector<float> &Slot::getDeform() {
return _deform; return _deform;
} }
int Slot::getSequenceIndex() {
return _sequenceIndex;
}
void Slot::setSequenceIndex(int index) {
_sequenceIndex = index;
}

View File

@ -43,7 +43,7 @@ using namespace spine;
RTTI_IMPL(VertexAttachment, Attachment) RTTI_IMPL(VertexAttachment, Attachment)
VertexAttachment::VertexAttachment(const String &name) : Attachment(name), _worldVerticesLength(0), VertexAttachment::VertexAttachment(const String &name) : Attachment(name), _worldVerticesLength(0),
_deformAttachment(this), _id(getNextID()) { _timelineAttachment(this), _id(getNextID()) {
} }
VertexAttachment::~VertexAttachment() { VertexAttachment::~VertexAttachment() {
@ -150,12 +150,12 @@ void VertexAttachment::setWorldVerticesLength(size_t inValue) {
_worldVerticesLength = inValue; _worldVerticesLength = inValue;
} }
VertexAttachment *VertexAttachment::getDeformAttachment() { Attachment * VertexAttachment::getTimelineAttachment() {
return _deformAttachment; return _timelineAttachment;
} }
void VertexAttachment::setDeformAttachment(VertexAttachment *attachment) { void VertexAttachment::setTimelineAttachment(Attachment *attachment) {
_deformAttachment = attachment; _timelineAttachment = attachment;
} }
int VertexAttachment::getNextID() { int VertexAttachment::getNextID() {
@ -167,5 +167,5 @@ void VertexAttachment::copyTo(VertexAttachment *other) {
other->_bones.clearAndAddAll(this->_bones); other->_bones.clearAndAddAll(this->_bones);
other->_vertices.clearAndAddAll(this->_vertices); other->_vertices.clearAndAddAll(this->_vertices);
other->_worldVerticesLength = this->_worldVerticesLength; other->_worldVerticesLength = this->_worldVerticesLength;
other->_deformAttachment = this->_deformAttachment; other->_timelineAttachment = this->_timelineAttachment;
} }

View File

@ -479,6 +479,40 @@ void coin(SkeletonData *skeletonData, Atlas *atlas) {
} }
} }
void dragon(SkeletonData *skeletonData, Atlas *atlas) {
SP_UNUSED(atlas);
SkeletonDrawable drawable(skeletonData);
drawable.timeScale = 1;
drawable.setUsePremultipliedAlpha(true);
Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 320);
skeleton->updateWorldTransform();
drawable.state->setAnimation(0, "flying", true);
sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - dragon");
window.setFramerateLimit(60);
sf::Event event;
sf::Clock deltaClock;
while (window.isOpen()) {
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) window.close();
}
float delta = deltaClock.getElapsedTime().asSeconds();
deltaClock.restart();
drawable.update(delta);
window.clear();
window.draw(drawable);
window.display();
}
}
void owl(SkeletonData *skeletonData, Atlas *atlas) { void owl(SkeletonData *skeletonData, Atlas *atlas) {
SP_UNUSED(atlas); SP_UNUSED(atlas);
@ -610,6 +644,7 @@ DebugExtension dbgExtension(SpineExtension::getInstance());
int main() { int main() {
SpineExtension::setInstance(&dbgExtension); SpineExtension::setInstance(&dbgExtension);
testcase(dragon, "data/dragon-ess.json", "data/dragon-ess.skel", "data/dragon-pma.atlas", 0.6f);
testcase(ikDemo, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f); testcase(ikDemo, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
testcase(mixAndMatch, "data/mix-and-match-pro.json", "data/mix-and-match-pro.skel", "data/mix-and-match-pma.atlas", 0.5f); testcase(mixAndMatch, "data/mix-and-match-pro.json", "data/mix-and-match-pro.skel", "data/mix-and-match-pma.atlas", 0.5f);
testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin-pma.atlas", 0.5f); testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin-pma.atlas", 0.5f);