[cpp] Still compute RegionAttachment offsets when the region is null, see #2887

- Includes a massive refactor of the TextureRegion/AtlasRegion hierarchy to be in line with Java implementation
- Exact line by line port of RegionAttachment#updateRegion and MeshAttachment#updateRegion using new region implementations
This commit is contained in:
Mario Zechner 2025-07-15 14:20:49 +02:00
parent 15addc9db5
commit acbcfeb44d
9 changed files with 228 additions and 144 deletions

View File

@ -36,6 +36,8 @@
#include <spine/SpineString.h>
#include <spine/HasRendererObject.h>
#include "TextureRegion.h"
#include "spine/MeshAttachment.h"
#include "spine/RegionAttachment.h"
namespace spine {
enum Format {
@ -102,21 +104,35 @@ namespace spine {
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888),
minFilter(TextureFilter_Nearest),
magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false), index(0), texture(NULL) {
vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false), index(0), texture(nullptr) {
}
};
class SP_API AtlasRegion : public TextureRegion {
friend class Atlas;
friend class RegionAttachment;
friend class MeshAttachment;
RTTI_DECL
public:
AtlasRegion() : TextureRegion(), _page(nullptr), _name(""), _index(0), _x(0), _y(0) {}
AtlasRegion() : TextureRegion(), _page(nullptr), _name(""), _index(0), _x(0), _y(0),
_offsetX(0), _offsetY(0), _packedWidth(0), _packedHeight(0),
_originalWidth(0), _originalHeight(0), _rotate(false), _degrees(0) {}
~AtlasRegion() {}
AtlasPage *getPage() const { return _page; }
String getName() const { return _name; }
int getIndex() const { return _index; }
int getX() const { return _x; }
int getY() const { return _y; }
float getOffsetX() const { return _offsetX; }
float getOffsetY() const { return _offsetY; }
int getPackedWidth() const { return _packedWidth; }
int getPackedHeight() const { return _packedHeight; }
int getOriginalWidth() const { return _originalWidth; }
int getOriginalHeight() const { return _originalHeight; }
bool getRotate() const { return _rotate; }
int getDegrees() const { return _degrees; }
Array<int> &getSplits() { return _splits; }
Array<int> &getPads() { return _pads; }
Array<String> &getNames() { return _names; }
@ -126,6 +142,14 @@ namespace spine {
void setIndex(int value) { _index = value; }
void setX(int value) { _x = value; }
void setY(int value) { _y = value; }
void setOffsetX(float value) { _offsetX = value; }
void setOffsetY(float value) { _offsetY = value; }
void setPackedWidth(int value) { _packedWidth = value; }
void setPackedHeight(int value) { _packedHeight = value; }
void setOriginalWidth(int value) { _originalWidth = value; }
void setOriginalHeight(int value) { _originalHeight = value; }
void setRotate(bool value) { _rotate = value; }
void setDegrees(int value) { _degrees = value; }
void setSplits(const Array<int> &value) { _splits = value; }
void setPads(const Array<int> &value) { _pads = value; }
void setNames(const Array<String> &value) { _names = value; }
@ -135,6 +159,11 @@ namespace spine {
String _name;
int _index;
int _x, _y;
float _offsetX, _offsetY;
int _packedWidth, _packedHeight;
int _originalWidth, _originalHeight;
bool _rotate;
int _degrees;
Array<int> _splits;
Array<int> _pads;
Array<String> _names;
@ -155,7 +184,7 @@ namespace spine {
/// Returns the first region found with the specified name. This method uses String comparison to find the region, so the result
/// should be cached rather than calling this method multiple times.
/// @return The region, or NULL.
/// @return The region, or nullptr.
AtlasRegion *findRegion(const String &name);
Array<AtlasPage *> &getPages();

View File

@ -111,17 +111,19 @@ namespace spine {
MeshAttachment *newLinkedMesh();
private:
MeshAttachment *_parentMesh;
Array<float> _uvs;
Array<float> _regionUVs;
Array<unsigned short> _triangles;
Array<unsigned short> _edges;
TextureRegion *_region;
String _path;
Array<float> _regionUVs;
Array<float> _uvs;
Array<unsigned short> _triangles;
Color _color;
int _hullLength;
int _width, _height;
TextureRegion *_region;
MeshAttachment *_parentMesh;
Sequence *_sequence;
// Nonessential.
Array<unsigned short> _edges;
int _width, _height;
};
}

View File

@ -38,8 +38,6 @@
#include <spine/HasRendererObject.h>
#define NUM_UVS 8
namespace spine {
class Bone;
class Slot;
@ -128,12 +126,12 @@ namespace spine {
static const int BRX;
static const int BRY;
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
Array<float> _offset;
Array<float> _uvs;
String _path;
Color _color;
TextureRegion *_region;
String _path;
float _x, _y, _scaleX, _scaleY, _rotation, _width, _height;
Array<float> _uvs;
Array<float> _offset;
Color _color;
Sequence *_sequence;
};
}

View File

@ -31,6 +31,7 @@
#define Spine_TextureRegion_h
#include <spine/Array.h>
#include <spine/RTTI.h>
namespace spine {
class SP_API TextureRegion : public SpineObject {
@ -40,8 +41,10 @@ namespace spine {
friend class AtlasRegion;
friend class SkeletonRenderer;
RTTI_DECL_NOPARENT
public:
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(): _rendererObject(nullptr), _u(0), _v(0), _u2(0), _v2(0), _regionWidth(0), _regionHeight(0) {};
~TextureRegion() {};
float getU() const { return _u; };
@ -52,28 +55,15 @@ namespace spine {
void setU2(float value) { _u2 = value; }
float getV2() const { return _v2; }
void setV2(float value) { _v2 = value; }
int getDegrees() const { return _degrees; }
void setDegrees(int value) { _degrees = value; }
float getOffsetX() const { return _offsetX; }
void setOffsetX(float value) { _offsetX = value; }
float getOffsetY() const { return _offsetY; }
void setOffsetY(float value) { _offsetY = value; }
int getRegionWidth() const { return _width; };
void setRegionWidth(int value) { _width = value; }
int getRegionHeight() const { return _height; }
void setRegionHeight(int value) { _height = value; }
int getOriginalWidth() const { return _originalWidth; };
void setOriginalWidth(int value) { _originalWidth = value; }
int getOriginalHeight() const { return _originalHeight; };
void setOriginalHeight(int value) { _originalHeight = value; }
int getRegionWidth() const { return _regionWidth; };
void setRegionWidth(int value) { _regionWidth = value; }
int getRegionHeight() const { return _regionHeight; }
void setRegionHeight(int value) { _regionHeight = value; }
private:
void *_rendererObject;
float _u, _v, _u2, _v2;
int _degrees;
float _offsetX, _offsetY;
int _width, _height;
int _originalWidth, _originalHeight;
int _regionWidth, _regionHeight;
};
}

View File

@ -35,6 +35,8 @@
using namespace spine;
RTTI_IMPL(AtlasRegion, TextureRegion)
Atlas::Atlas(const String &path, TextureLoader *textureLoader, bool createTexture) : _textureLoader(textureLoader) {
int dirLength;
char *dir;
@ -88,7 +90,7 @@ void Atlas::flipV() {
AtlasRegion *Atlas::findRegion(const String &name) {
for (size_t i = 0, n = _regions.size(); i < n; ++i)
if (_regions[i]->_name == name) return _regions[i];
return NULL;
return nullptr;
}
Array<AtlasPage *> &Atlas::getPages() {
@ -197,7 +199,7 @@ struct AtlasInput {
}
static int readEntry(SimpleString entry[5], SimpleString *line) {
if (line == NULL) return 0;
if (line == nullptr) return 0;
line->trim();
if (line->length == 0) return 0;
@ -234,24 +236,24 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
AtlasInput reader(begin, length);
SimpleString entry[5];
AtlasPage *page = NULL;
AtlasPage *page = nullptr;
SimpleString *line = reader.readLine();
while (line != NULL && line->length == 0)
while (line != nullptr && line->length == 0)
line = reader.readLine();
while (true) {
if (line == NULL || line->length == 0) break;
if (line == nullptr || line->length == 0) break;
if (reader.readEntry(entry, line) == 0) break;
line = reader.readLine();
}
while (true) {
if (line == NULL) break;
if (line == nullptr) break;
if (line->trim().length == 0) {
page = NULL;
page = nullptr;
line = reader.readLine();
} else if (page == NULL) {
} else if (page == nullptr) {
char *name = line->copy();
char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
memcpy(path, dir, dirLength);
@ -302,13 +304,13 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
region->_x = entry[1].toInt();
region->_y = entry[2].toInt();
} else if (entry[0].equals("size")) {
region->_width = entry[1].toInt();
region->_height = entry[2].toInt();
region->_packedWidth = entry[1].toInt();
region->_packedHeight = entry[2].toInt();
} else if (entry[0].equals("bounds")) {
region->_x = entry[1].toInt();
region->_y = entry[2].toInt();
region->_width = entry[3].toInt();
region->_height = entry[4].toInt();
region->_packedWidth = entry[3].toInt();
region->_packedHeight = entry[4].toInt();
} else if (entry[0].equals("offset")) {
region->_offsetX = entry[1].toInt();
region->_offsetY = entry[2].toInt();
@ -326,6 +328,7 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
} else if (!entry[1].equals("false")) {
region->_degrees = entry[1].toInt();
}
region->_rotate = region->_degrees == 90;
} else if (entry[0].equals("index")) {
region->_index = entry[1].toInt();
} else {
@ -336,19 +339,22 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
}
}
if (region->_originalWidth == 0 && region->_originalHeight == 0) {
region->_originalWidth = region->_width;
region->_originalHeight = region->_height;
region->_originalWidth = region->_packedWidth;
region->_originalHeight = region->_packedHeight;
}
region->_u = (float) region->_x / page->width;
region->_v = (float) region->_y / page->height;
if (region->_degrees == 90) {
region->_u2 = (float) (region->_x + region->_height) / page->width;
region->_v2 = (float) (region->_y + region->_width) / page->height;
region->_u2 = (float) (region->_x + region->_packedHeight) / page->width;
region->_v2 = (float) (region->_y + region->_packedWidth) / page->height;
} else {
region->_u2 = (float) (region->_x + region->_width) / page->width;
region->_v2 = (float) (region->_y + region->_height) / page->height;
region->_u2 = (float) (region->_x + region->_packedWidth) / page->width;
region->_v2 = (float) (region->_y + region->_packedHeight) / page->height;
}
// Calculate regionWidth/Height from UV coordinates
region->_regionWidth = abs((int) ((region->_u2 - region->_u) * page->width));
region->_regionHeight = abs((int) ((region->_v2 - region->_v) * page->height));
_regions.add(region);
}
}

View File

@ -28,6 +28,7 @@
*****************************************************************************/
#include <spine/MeshAttachment.h>
#include <spine/Atlas.h>
#include <spine/Slot.h>
using namespace spine;
@ -35,83 +36,88 @@ using namespace spine;
RTTI_IMPL(MeshAttachment, VertexAttachment)
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name),
_parentMesh(NULL),
_region(NULL),
_path(),
_color(1, 1, 1, 1),
_hullLength(0),
_parentMesh(NULL),
_sequence(NULL),
_width(0),
_height(0),
_region(NULL),
_sequence(NULL) {}
_height(0) {}
MeshAttachment::~MeshAttachment() {
if (_sequence) delete _sequence;
}
void MeshAttachment::updateRegion() {
if (_uvs.size() != _regionUVs.size()) {
_uvs.setSize(_regionUVs.size(), 0);
}
if (_uvs.size() != _regionUVs.size()) _uvs.setSize(_regionUVs.size(), 0);
int n = (int) _regionUVs.size();
float u, v, width, height;
if (_region != nullptr && _region->rtti.instanceOf(AtlasRegion::rtti)) {
AtlasRegion *atlasRegion = static_cast<AtlasRegion *>(_region);
u = _region->_u;
v = _region->_v;
if (_region == nullptr) {
return;
}
float textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u);
float textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v);
int i = 0, n = (int) _regionUVs.size();
float u = _region->_u, v = _region->_v;
float width = 0, height = 0;
switch (_region->_degrees) {
case 90: {
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;
switch (atlasRegion->_degrees) {
case 90: {
textureWidth = atlasRegion->_packedHeight / (_region->_u2 - _region->_u);
textureHeight = atlasRegion->_packedWidth / (_region->_v2 - _region->_v);
u -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / textureWidth;
v -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / textureHeight;
width = atlasRegion->_originalHeight / textureWidth;
height = atlasRegion->_originalWidth / textureHeight;
for (int i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i + 1] * width;
_uvs[i + 1] = v + (1 - _regionUVs[i]) * height;
}
return;
}
return;
}
case 180: {
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;
case 180: {
u -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / textureWidth;
v -= atlasRegion->_offsetY / textureHeight;
width = atlasRegion->_originalWidth / textureWidth;
height = atlasRegion->_originalHeight / textureHeight;
for (int i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i]) * width;
_uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height;
}
return;
}
return;
}
case 270: {
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;
case 270: {
textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v);
textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u);
u -= atlasRegion->_offsetY / textureWidth;
v -= atlasRegion->_offsetX / textureHeight;
width = atlasRegion->_originalHeight / textureWidth;
height = atlasRegion->_originalWidth / textureHeight;
for (int i = 0; i < n; i += 2) {
_uvs[i] = u + (1 - _regionUVs[i + 1]) * width;
_uvs[i + 1] = v + _regionUVs[i] * height;
}
return;
}
return;
}
default: {
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;
default: {
u -= atlasRegion->_offsetX / textureWidth;
v -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / textureHeight;
width = atlasRegion->_originalWidth / textureWidth;
height = atlasRegion->_originalHeight / textureHeight;
}
}
} else if (_region == nullptr) {
u = v = 0;
width = height = 1;
} else {
u = _region->_u;
v = _region->_v;
width = _region->_u2 - u;
height = _region->_v2 - v;
}
for (int i = 0; i < n; i += 2) {
_uvs[i] = u + _regionUVs[i] * width;
_uvs[i + 1] = v + _regionUVs[i + 1] * height;
}
}

View File

@ -29,6 +29,7 @@
#include <spine/RegionAttachment.h>
#include <spine/Atlas.h>
#include <spine/Bone.h>
#include <spine/Slot.h>
@ -48,19 +49,19 @@ const int RegionAttachment::BRX = 6;
const int RegionAttachment::BRY = 7;
RegionAttachment::RegionAttachment(const String &name) : Attachment(name),
_region(NULL),
_path(),
_x(0),
_y(0),
_rotation(0),
_scaleX(1),
_scaleY(1),
_rotation(0),
_width(0),
_height(0),
_path(),
_color(1, 1, 1, 1),
_region(NULL),
_sequence(NULL) {
_offset.setSize(NUM_UVS, 0);
_uvs.setSize(NUM_UVS, 0);
_offset.setSize(8, 0);
_uvs.setSize(8, 0);
}
RegionAttachment::~RegionAttachment() {
@ -68,24 +69,33 @@ RegionAttachment::~RegionAttachment() {
}
void RegionAttachment::updateRegion() {
if (_region == NULL) {
_uvs[BLX] = 0;
_uvs[BLY] = 0;
_uvs[ULX] = 0;
_uvs[ULY] = 1;
_uvs[URX] = 1;
_uvs[URY] = 1;
_uvs[BRX] = 1;
_uvs[BRY] = 0;
return;
float width = getWidth(), height = getHeight();
float localX2 = width / 2;
float localY2 = height / 2;
float localX = -localX2;
float localY = -localY2;
bool rotated = false;
AtlasRegion *atlasRegion = NULL;
if (_region != NULL) {
atlasRegion = _region->rtti.isExactly(AtlasRegion::rtti) ? static_cast<AtlasRegion *>(_region) : NULL;
}
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;
if (atlasRegion) {
localX += atlasRegion->_offsetX / atlasRegion->_originalWidth * width;
localY += atlasRegion->_offsetY / atlasRegion->_originalHeight * height;
if (atlasRegion->_degrees == 90) {
rotated = true;
localX2 -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedHeight) / atlasRegion->_originalWidth * width;
localY2 -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedWidth) / atlasRegion->_originalHeight * height;
} else {
localX2 -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / atlasRegion->_originalWidth * width;
localY2 -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / atlasRegion->_originalHeight * height;
}
}
float scaleX = getScaleX(), scaleY = getScaleY();
localX *= scaleX;
localY *= scaleY;
localX2 *= scaleX;
localY2 *= scaleY;
float cos = MathUtil::cosDeg(_rotation);
float sin = MathUtil::sinDeg(_rotation);
float localXCos = localX * cos + _x;
@ -106,24 +116,33 @@ void RegionAttachment::updateRegion() {
_offset[BRX] = localX2Cos - localYSin;
_offset[BRY] = localYCos + localX2Sin;
if (_region->_degrees == 90) {
_uvs[URX] = _region->_u;
_uvs[URY] = _region->_v2;
_uvs[BRX] = _region->_u;
_uvs[BRY] = _region->_v;
if (_region == NULL) {
_uvs[BLX] = 0;
_uvs[BLY] = 0;
_uvs[ULX] = 0;
_uvs[ULY] = 1;
_uvs[URX] = 1;
_uvs[URY] = 1;
_uvs[BRX] = 1;
_uvs[BRY] = 0;
} else if (rotated) {
_uvs[BLX] = _region->_u2;
_uvs[BLY] = _region->_v;
_uvs[ULX] = _region->_u2;
_uvs[ULY] = _region->_v2;
_uvs[URX] = _region->_u;
_uvs[URY] = _region->_v2;
_uvs[BRX] = _region->_u;
_uvs[BRY] = _region->_v;
} else {
_uvs[BLX] = _region->_u2;
_uvs[BLY] = _region->_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;
}
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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/TextureRegion.h>
using namespace spine;
RTTI_IMPL_NOPARENT(TextureRegion)

View File

@ -106,7 +106,7 @@ public class Animation {
this.duration = duration;
}
public IntArray getBones() {
public IntArray getBones () {
return bones;
}