[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
## 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

View File

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

View File

@ -48,9 +48,9 @@ namespace spine {
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);

View File

@ -51,6 +51,8 @@ namespace spine {
class ClippingAttachment;
class Sequence;
class SP_API AttachmentLoader : public SpineObject {
public:
RTTI_DECL
@ -60,10 +62,10 @@ namespace spine {
virtual ~AttachmentLoader();
/// @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.
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.
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) = 0;

View File

@ -31,6 +31,8 @@
#define Spine_MeshAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/TextureRegion.h>
#include <spine/Sequence.h>
#include <spine/Vector.h>
#include <spine/Color.h>
#include <spine/HasRendererObject.h>
@ -51,7 +53,10 @@ namespace spine {
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();
@ -59,7 +64,7 @@ namespace spine {
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<unsigned short> &getTriangles();
@ -70,52 +75,13 @@ namespace spine {
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);
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);
void setSequence(Sequence *sequence);
MeshAttachment *getParentMesh();
@ -137,22 +103,17 @@ namespace spine {
MeshAttachment *newLinkedMesh();
private:
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
MeshAttachment *_parentMesh;
Vector<float> _uvs;
Vector<float> _regionUVs;
Vector<unsigned short> _triangles;
Vector<unsigned short> _edges;
String _path;
float _regionU;
float _regionV;
float _regionU2;
float _regionV2;
float _width;
float _height;
Color _color;
int _hullLength;
int _regionDegrees;
int _width, _height;
TextureRegion *_region;
Sequence *_sequence;
};
}

View File

@ -33,6 +33,8 @@
#include <spine/Attachment.h>
#include <spine/Vector.h>
#include <spine/Color.h>
#include <spine/Sequence.h>
#include <spine/TextureRegion.h>
#include <spine/HasRendererObject.h>
@ -54,7 +56,9 @@ namespace spine {
public:
explicit RegionAttachment(const String &name);
void updateOffset();
virtual ~RegionAttachment();
void updateRegion();
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 offset The worldVertices index to begin writing values.
/// @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();
@ -101,29 +105,13 @@ namespace spine {
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);
float getRegionWidth();
void setRegionWidth(float inValue);
float getRegionHeight();
void setRegionHeight(float inValue);
float getRegionOriginalWidth();
void setRegionOriginalWidth(float inValue);
float getRegionOriginalHeight();
void setRegionOriginalHeight(float inValue);
void setSequence(Sequence *sequence);
Vector<float> &getOffset();
@ -142,15 +130,12 @@ namespace spine {
static const int BRY;
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
Vector<float> _vertexOffset;
Vector<float> _uvs;
String _path;
float _regionU;
float _regionV;
float _regionU2;
float _regionV2;
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.
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.
/// @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.
@ -204,10 +202,6 @@ namespace spine {
Color &getColor();
float getTime();
void setTime(float inValue);
void setPosition(float x, float y);
float getX();
@ -237,7 +231,6 @@ namespace spine {
Vector<Updatable *> _updateCache;
Skin *_skin;
Color _color;
float _time;
float _scaleX, _scaleY;
float _x, _y;

View File

@ -114,12 +114,12 @@ namespace spine {
void setAttachmentState(int state);
float getAttachmentTime();
void setAttachmentTime(float inValue);
Vector<float> &getDeform();
int getSequenceIndex();
void setSequenceIndex(int index);
private:
SlotData &_data;
Bone &_bone;
@ -129,7 +129,7 @@ namespace spine {
bool _hasDarkColor;
Attachment *_attachment;
int _attachmentState;
float _attachmentTime;
int _sequenceIndex;
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 offset The worldVertices index to begin writing values.
/// @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);
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);
/// Gets a unique ID for this attachment.
@ -79,9 +79,9 @@ namespace spine {
void setWorldVerticesLength(size_t inValue);
VertexAttachment *getDeformAttachment();
Attachment * getTimelineAttachment();
void setDeformAttachment(VertexAttachment *attachment);
void setTimelineAttachment(Attachment *attachment);
void copyTo(VertexAttachment *other);
@ -89,7 +89,7 @@ namespace spine {
Vector <size_t> _bones;
Vector<float> _vertices;
size_t _worldVerticesLength;
VertexAttachment *_deformAttachment;
Attachment *_timelineAttachment;
private:
const int _id;

View File

@ -48,53 +48,44 @@ namespace spine {
AtlasAttachmentLoader::AtlasAttachmentLoader(Atlas *atlas) : AttachmentLoader(), _atlas(atlas) {
}
RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const String &name, const String &path) {
SP_UNUSED(skin);
AtlasRegion *regionP = findRegion(path);
if (!regionP) return NULL;
AtlasRegion &region = *regionP;
RegionAttachment *attachmentP = new (__FILE__, __LINE__) RegionAttachment(name);
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;
bool loadSequence (Atlas *atlas, const String &basePath, Sequence *sequence) {
Vector<TextureRegion *> &regions = sequence->getRegions();
for (int i = 0, n = regions.size(); i < n; i++) {
String path = sequence->getPath(basePath, i);
regions[i] = atlas->findRegion(path);
if (!regions[i]) return false;
regions[i]->rendererObject = regions[i];
}
return true;
}
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);
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);
if (!regionP) return NULL;
MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) {
SP_UNUSED(skin);
MeshAttachment *attachment = new (__FILE__, __LINE__) MeshAttachment(name);
AtlasRegion &region = *regionP;
MeshAttachment *attachmentP = new (__FILE__, __LINE__) MeshAttachment(name);
MeshAttachment &attachment = *attachmentP;
attachment.setRendererObject(regionP);
attachment._regionU = region.u;
attachment._regionV = region.v;
attachment._regionU2 = region.u2;
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;
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;
}
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);
if (attachment->_deformAttachment != _attachment) {
if (attachment->_timelineAttachment != _attachment) {
return;
}

View File

@ -39,43 +39,36 @@ using namespace spine;
RTTI_IMPL(MeshAttachment, VertexAttachment)
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name), HasRendererObject(),
_regionOffsetX(0),
_regionOffsetY(0),
_regionWidth(0),
_regionHeight(0),
_regionOriginalWidth(0),
_regionOriginalHeight(0),
_parentMesh(NULL),
_path(),
_regionU(0),
_regionV(0),
_regionU2(0),
_regionV2(0),
_width(0),
_height(0),
_color(1, 1, 1, 1),
_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()) {
_uvs.setSize(_regionUVs.size(), 0);
}
int i = 0, n = _regionUVs.size();
float u = _regionU, v = _regionV;
float u = _region->u, v = _region->v;
float width = 0, height = 0;
switch (_regionDegrees) {
switch (_region->degrees) {
case 90: {
float textureWidth = _regionHeight / (_regionU2 - _regionU);
float textureHeight = _regionWidth / (_regionV2 - _regionV);
u -= (_regionOriginalHeight - _regionOffsetY - _regionHeight) / textureWidth;
v -= (_regionOriginalWidth - _regionOffsetX - _regionWidth) / textureHeight;
width = _regionOriginalHeight / textureWidth;
height = _regionOriginalWidth / textureHeight;
float textureWidth = _region->height / (_region->u2 - _region->u);
float textureHeight = _region->width / (_region->v2 - _region->v);
u -= (_region->originalHeight - _region->offsetY - _region->height) / textureWidth;
v -= (_region->originalWidth - _region->offsetX - _region->width) / textureHeight;
width = _region->originalHeight / textureWidth;
height = _region->originalWidth / textureHeight;
for (i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i + 1] * width;
_uvs[i + 1] = v + (1 - _regionUVs[i]) * height;
@ -83,12 +76,12 @@ void MeshAttachment::updateUVs() {
return;
}
case 180: {
float textureWidth = _regionWidth / (_regionU2 - _regionU);
float textureHeight = _regionHeight / (_regionV2 - _regionV);
u -= (_regionOriginalWidth - _regionOffsetX - _regionWidth) / textureWidth;
v -= _regionOffsetY / textureHeight;
width = _regionOriginalWidth / textureWidth;
height = _regionOriginalHeight / textureHeight;
float textureWidth = _region->width / (_region->u2 - _region->u);
float textureHeight = _region->height / (_region->v2 - _region->v);
u -= (_region->originalWidth - _region->offsetX - _region->width) / textureWidth;
v -= _region->offsetY / textureHeight;
width = _region->originalWidth / textureWidth;
height = _region->originalHeight / textureHeight;
for (i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i]) * width;
_uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height;
@ -96,12 +89,12 @@ void MeshAttachment::updateUVs() {
return;
}
case 270: {
float textureHeight = _regionHeight / (_regionV2 - _regionV);
float textureWidth = _regionWidth / (_regionU2 - _regionU);
u -= _regionOffsetY / textureWidth;
v -= _regionOffsetX / textureHeight;
width = _regionOriginalHeight / textureWidth;
height = _regionOriginalWidth / textureHeight;
float textureHeight = _region->height / (_region->v2 - _region->v);
float textureWidth = _region->width / (_region->u2 - _region->u);
u -= _region->offsetY / textureWidth;
v -= _region->offsetX / textureHeight;
width = _region->originalHeight / textureWidth;
height = _region->originalWidth / textureHeight;
for (i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i + 1]) * width;
_uvs[i + 1] = v + _regionUVs[i] * height;
@ -109,12 +102,12 @@ void MeshAttachment::updateUVs() {
return;
}
default: {
float textureWidth = _regionWidth / (_regionU2 - _regionU);
float textureHeight = _regionHeight / (_regionV2 - _regionV);
u -= _regionOffsetX / textureWidth;
v -= (_regionOriginalHeight - _regionOffsetY - _regionHeight) / textureHeight;
width = _regionOriginalWidth / textureWidth;
height = _regionOriginalHeight / textureHeight;
float textureWidth = _region->width / (_region->u2 - _region->u);
float textureHeight = _region->height / (_region->v2 - _region->v);
u -= _region->offsetX / textureWidth;
v -= (_region->originalHeight - _region->offsetY - _region->height) / textureHeight;
width = _region->originalWidth / textureWidth;
height = _region->originalHeight / textureHeight;
for (i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i] * width;
_uvs[i + 1] = v + _regionUVs[i + 1] * height;
@ -151,94 +144,6 @@ void MeshAttachment::setPath(const String &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() {
return _parentMesh;
}
@ -287,17 +192,8 @@ Attachment *MeshAttachment::copy() {
MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName());
copy->setRendererObject(getRendererObject());
copy->_regionU = _regionU;
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->setRegion(_region);
copy->setSequence(_sequence != NULL ? _sequence->copy() : NULL);
copy->_path = _path;
copy->_color.set(_color);
@ -317,21 +213,17 @@ Attachment *MeshAttachment::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->_regionDegrees = _regionDegrees;
copy->_regionOffsetX = _regionOffsetX;
copy->_regionOffsetY = _regionOffsetY;
copy->_regionWidth = _regionWidth;
copy->_regionHeight = _regionHeight;
copy->_regionOriginalWidth = _regionOriginalWidth;
copy->_regionOriginalHeight = _regionOriginalHeight;
copy->setRegion(_region);
copy->_path = _path;
copy->_color.set(_color);
copy->_deformAttachment = this->_deformAttachment;
copy->_timelineAttachment = this->_timelineAttachment;
copy->setParentMesh(_parentMesh ? _parentMesh : this);
copy->updateUVs();
if (copy->_region) copy->updateRegion();
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/Bone.h>
#include <spine/Slot.h>
#include <assert.h>
@ -58,29 +59,25 @@ RegionAttachment::RegionAttachment(const String &name) : Attachment(name), HasRe
_scaleY(1),
_width(0),
_height(0),
_regionOffsetX(0),
_regionOffsetY(0),
_regionWidth(0),
_regionHeight(0),
_regionOriginalWidth(0),
_regionOriginalHeight(0),
_path(),
_regionU(0),
_regionV(0),
_regionU2(0),
_regionV2(0),
_color(1, 1, 1, 1) {
_color(1, 1, 1, 1),
_region(NULL),
_sequence(NULL) {
_vertexOffset.setSize(NUM_UVS, 0);
_uvs.setSize(NUM_UVS, 0);
}
void RegionAttachment::updateOffset() {
float regionScaleX = _width / _regionOriginalWidth * _scaleX;
float regionScaleY = _height / _regionOriginalHeight * _scaleY;
float localX = -_width / 2 * _scaleX + _regionOffsetX * regionScaleX;
float localY = -_height / 2 * _scaleY + _regionOffsetY * regionScaleY;
float localX2 = localX + _regionWidth * regionScaleX;
float localY2 = localY + _regionHeight * regionScaleY;
RegionAttachment::~RegionAttachment() {
if (_sequence) delete _sequence;
}
void RegionAttachment::updateRegion() {
float regionScaleX = _width / _region->originalWidth * _scaleX;
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 sin = MathUtil::sinDeg(_rotation);
float localXCos = localX * cos + _x;
@ -100,36 +97,37 @@ void RegionAttachment::updateOffset() {
_vertexOffset[URY] = localY2Cos + localX2Sin;
_vertexOffset[BRX] = localX2Cos - localYSin;
_vertexOffset[BRY] = localYCos + localX2Sin;
}
void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) {
if (degrees == 90) {
_uvs[URX] = u;
_uvs[URY] = v2;
_uvs[BRX] = u;
_uvs[BRY] = v;
_uvs[BLX] = u2;
_uvs[BLY] = v;
_uvs[ULX] = u2;
_uvs[ULY] = v2;
if (_region->degrees == 90) {
_uvs[URX] = _region->u;
_uvs[URY] = _region->v2;
_uvs[BRX] = _region->u;
_uvs[BRY] = _region->v;
_uvs[BLX] = _region->u2;
_uvs[BLY] = _region->v;
_uvs[ULX] = _region->u2;
_uvs[ULY] = _region->v2;
} else {
_uvs[ULX] = u;
_uvs[ULY] = v2;
_uvs[URX] = u;
_uvs[URY] = v;
_uvs[BRX] = u2;
_uvs[BRY] = v;
_uvs[BLX] = u2;
_uvs[BLY] = v2;
_uvs[ULX] = _region->u;
_uvs[ULY] = _region->v2;
_uvs[URX] = _region->u;
_uvs[URY] = _region->v;
_uvs[BRX] = _region->u2;
_uvs[BRY] = _region->v;
_uvs[BLX] = _region->u2;
_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));
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 a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD();
float offsetX, offsetY;
@ -222,52 +220,20 @@ void RegionAttachment::setPath(const String &inValue) {
_path = inValue;
}
float RegionAttachment::getRegionOffsetX() {
return _regionOffsetX;
TextureRegion *RegionAttachment::getRegion() {
return _region;
}
void RegionAttachment::setRegionOffsetX(float inValue) {
_regionOffsetX = inValue;
void RegionAttachment::setRegion(TextureRegion *region) {
_region = region;
}
float RegionAttachment::getRegionOffsetY() {
return _regionOffsetY;
Sequence *RegionAttachment::getSequence() {
return _sequence;
}
void RegionAttachment::setRegionOffsetY(float inValue) {
_regionOffsetY = inValue;
}
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;
void RegionAttachment::setSequence(Sequence *sequence) {
_sequence = sequence;
}
Vector<float> &RegionAttachment::getOffset() {
@ -284,12 +250,7 @@ spine::Color &RegionAttachment::getColor() {
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->_region = _region;
copy->setRendererObject(getRendererObject());
copy->_path = _path;
copy->_x = _x;
@ -302,5 +263,6 @@ Attachment *RegionAttachment::copy() {
copy->_uvs.clearAndAddAll(_uvs);
copy->_vertexOffset.clearAndAddAll(_vertexOffset);
copy->_color.set(_color);
copy->_sequence = _sequence != NULL ? _sequence->copy() : NULL;
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),
_skin(NULL),
_color(1, 1, 1, 1),
_time(0),
_scaleX(1),
_scaleY(1),
_x(0),
@ -427,10 +426,6 @@ PathConstraint *Skeleton::findPathConstraint(const String &constraintName) {
return NULL;
}
void Skeleton::update(float delta) {
_time += delta;
}
void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer) {
float minX = 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) {
outVertexBuffer.setSize(8, 0);
}
regionAttachment->computeWorldVertices(slot->getBone(), outVertexBuffer, 0);
regionAttachment->computeWorldVertices(*slot, outVertexBuffer, 0);
} else if (attachment != NULL && attachment->getRTTI().instanceOf(MeshAttachment::rtti)) {
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);
}
mesh->computeWorldVertices(*slot, 0, verticesLength, outVertexBuffer, 0);
mesh->computeWorldVertices(*slot, 0, verticesLength, outVertexBuffer.buffer(), 0);
}
for (size_t ii = 0; ii < verticesLength; ii += 2) {
@ -523,14 +518,6 @@ Color &Skeleton::getColor() {
return _color;
}
float Skeleton::getTime() {
return _time;
}
void Skeleton::setTime(float inValue) {
_time = inValue;
}
void Skeleton::setPosition(float x, float y) {
_x = x;
_y = y;

View File

@ -298,10 +298,10 @@ 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<VertexAttachment *>(parent)
: linkedMesh->_mesh;
linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh;
linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
linkedMesh->_mesh->updateUVs();
linkedMesh->_mesh->updateRegion();
_attachmentLoader->configureAttachment(linkedMesh->_mesh);
}
ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);
@ -502,7 +502,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
region->_width = readFloat(input) * _scale;
region->_height = readFloat(input) * _scale;
readColor(input, region->getColor());
region->updateOffset();
region->updateRegion();
_attachmentLoader->configureAttachment(region);
return region;
}
@ -537,7 +537,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
readFloatArray(input, vertexCount << 1, 1, mesh->getRegionUVs());
readShortArray(input, mesh->getTriangles());
readVertices(input, static_cast<VertexAttachment *>(mesh), vertexCount);
mesh->updateUVs();
mesh->updateRegion();
mesh->_hullLength = readVarint(input, true) << 1;
if (nonessential) {
readShortArray(input, mesh->getEdges());

View File

@ -569,7 +569,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
color = Json::getString(attachmentMap, "color", 0);
if (color) toColor(region->getColor(), color, true);
region->updateOffset();
region->updateRegion();
_attachmentLoader->configureAttachment(region);
break;
}
@ -610,7 +610,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
readVertices(attachmentMap, mesh, verticesLength);
mesh->updateUVs();
mesh->updateRegion();
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());
return NULL;
}
linkedMesh->_mesh->_deformAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh;
linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh;
linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
linkedMesh->_mesh->updateUVs();
linkedMesh->_mesh->updateRegion();
_attachmentLoader->configureAttachment(linkedMesh->_mesh);
}
ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);

View File

@ -49,7 +49,7 @@ Slot::Slot(SlotData &data, Bone &bone) : _data(data),
_hasDarkColor(data.hasDarkColor()),
_attachment(NULL),
_attachmentState(0),
_attachmentTime(0) {
_sequenceIndex(0) {
setToSetupPose();
}
@ -103,12 +103,13 @@ void Slot::setAttachment(Attachment *inValue) {
!_attachment ||
!inValue->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();
}
_attachment = inValue;
_attachmentTime = _skeleton.getTime();
_sequenceIndex = -1;
}
int Slot::getAttachmentState() {
@ -119,14 +120,14 @@ void Slot::setAttachmentState(int state) {
_attachmentState = state;
}
float Slot::getAttachmentTime() {
return _skeleton.getTime() - _attachmentTime;
}
void Slot::setAttachmentTime(float inValue) {
_attachmentTime = _skeleton.getTime() - inValue;
}
Vector<float> &Slot::getDeform() {
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)
VertexAttachment::VertexAttachment(const String &name) : Attachment(name), _worldVerticesLength(0),
_deformAttachment(this), _id(getNextID()) {
_timelineAttachment(this), _id(getNextID()) {
}
VertexAttachment::~VertexAttachment() {
@ -150,12 +150,12 @@ void VertexAttachment::setWorldVerticesLength(size_t inValue) {
_worldVerticesLength = inValue;
}
VertexAttachment *VertexAttachment::getDeformAttachment() {
return _deformAttachment;
Attachment * VertexAttachment::getTimelineAttachment() {
return _timelineAttachment;
}
void VertexAttachment::setDeformAttachment(VertexAttachment *attachment) {
_deformAttachment = attachment;
void VertexAttachment::setTimelineAttachment(Attachment *attachment) {
_timelineAttachment = attachment;
}
int VertexAttachment::getNextID() {
@ -167,5 +167,5 @@ void VertexAttachment::copyTo(VertexAttachment *other) {
other->_bones.clearAndAddAll(this->_bones);
other->_vertices.clearAndAddAll(this->_vertices);
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) {
SP_UNUSED(atlas);
@ -610,6 +644,7 @@ DebugExtension dbgExtension(SpineExtension::getInstance());
int main() {
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(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);