mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[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:
parent
15addc9db5
commit
acbcfeb44d
@ -36,6 +36,8 @@
|
|||||||
#include <spine/SpineString.h>
|
#include <spine/SpineString.h>
|
||||||
#include <spine/HasRendererObject.h>
|
#include <spine/HasRendererObject.h>
|
||||||
#include "TextureRegion.h"
|
#include "TextureRegion.h"
|
||||||
|
#include "spine/MeshAttachment.h"
|
||||||
|
#include "spine/RegionAttachment.h"
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
enum Format {
|
enum Format {
|
||||||
@ -102,21 +104,35 @@ namespace spine {
|
|||||||
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888),
|
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888),
|
||||||
minFilter(TextureFilter_Nearest),
|
minFilter(TextureFilter_Nearest),
|
||||||
magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
|
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 {
|
class SP_API AtlasRegion : public TextureRegion {
|
||||||
friend class Atlas;
|
friend class Atlas;
|
||||||
|
friend class RegionAttachment;
|
||||||
|
friend class MeshAttachment;
|
||||||
|
|
||||||
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
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() {}
|
~AtlasRegion() {}
|
||||||
AtlasPage *getPage() const { return _page; }
|
AtlasPage *getPage() const { return _page; }
|
||||||
String getName() const { return _name; }
|
String getName() const { return _name; }
|
||||||
int getIndex() const { return _index; }
|
int getIndex() const { return _index; }
|
||||||
int getX() const { return _x; }
|
int getX() const { return _x; }
|
||||||
int getY() const { return _y; }
|
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> &getSplits() { return _splits; }
|
||||||
Array<int> &getPads() { return _pads; }
|
Array<int> &getPads() { return _pads; }
|
||||||
Array<String> &getNames() { return _names; }
|
Array<String> &getNames() { return _names; }
|
||||||
@ -126,6 +142,14 @@ namespace spine {
|
|||||||
void setIndex(int value) { _index = value; }
|
void setIndex(int value) { _index = value; }
|
||||||
void setX(int value) { _x = value; }
|
void setX(int value) { _x = value; }
|
||||||
void setY(int value) { _y = 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 setSplits(const Array<int> &value) { _splits = value; }
|
||||||
void setPads(const Array<int> &value) { _pads = value; }
|
void setPads(const Array<int> &value) { _pads = value; }
|
||||||
void setNames(const Array<String> &value) { _names = value; }
|
void setNames(const Array<String> &value) { _names = value; }
|
||||||
@ -135,6 +159,11 @@ namespace spine {
|
|||||||
String _name;
|
String _name;
|
||||||
int _index;
|
int _index;
|
||||||
int _x, _y;
|
int _x, _y;
|
||||||
|
float _offsetX, _offsetY;
|
||||||
|
int _packedWidth, _packedHeight;
|
||||||
|
int _originalWidth, _originalHeight;
|
||||||
|
bool _rotate;
|
||||||
|
int _degrees;
|
||||||
Array<int> _splits;
|
Array<int> _splits;
|
||||||
Array<int> _pads;
|
Array<int> _pads;
|
||||||
Array<String> _names;
|
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
|
/// 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.
|
/// 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);
|
AtlasRegion *findRegion(const String &name);
|
||||||
|
|
||||||
Array<AtlasPage *> &getPages();
|
Array<AtlasPage *> &getPages();
|
||||||
|
|||||||
@ -111,17 +111,19 @@ namespace spine {
|
|||||||
MeshAttachment *newLinkedMesh();
|
MeshAttachment *newLinkedMesh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MeshAttachment *_parentMesh;
|
TextureRegion *_region;
|
||||||
Array<float> _uvs;
|
|
||||||
Array<float> _regionUVs;
|
|
||||||
Array<unsigned short> _triangles;
|
|
||||||
Array<unsigned short> _edges;
|
|
||||||
String _path;
|
String _path;
|
||||||
|
Array<float> _regionUVs;
|
||||||
|
Array<float> _uvs;
|
||||||
|
Array<unsigned short> _triangles;
|
||||||
Color _color;
|
Color _color;
|
||||||
int _hullLength;
|
int _hullLength;
|
||||||
int _width, _height;
|
MeshAttachment *_parentMesh;
|
||||||
TextureRegion *_region;
|
|
||||||
Sequence *_sequence;
|
Sequence *_sequence;
|
||||||
|
|
||||||
|
// Nonessential.
|
||||||
|
Array<unsigned short> _edges;
|
||||||
|
int _width, _height;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,8 +38,6 @@
|
|||||||
|
|
||||||
#include <spine/HasRendererObject.h>
|
#include <spine/HasRendererObject.h>
|
||||||
|
|
||||||
#define NUM_UVS 8
|
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Bone;
|
class Bone;
|
||||||
class Slot;
|
class Slot;
|
||||||
@ -128,12 +126,12 @@ namespace spine {
|
|||||||
static const int BRX;
|
static const int BRX;
|
||||||
static const int BRY;
|
static const int BRY;
|
||||||
|
|
||||||
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
|
|
||||||
Array<float> _offset;
|
|
||||||
Array<float> _uvs;
|
|
||||||
String _path;
|
|
||||||
Color _color;
|
|
||||||
TextureRegion *_region;
|
TextureRegion *_region;
|
||||||
|
String _path;
|
||||||
|
float _x, _y, _scaleX, _scaleY, _rotation, _width, _height;
|
||||||
|
Array<float> _uvs;
|
||||||
|
Array<float> _offset;
|
||||||
|
Color _color;
|
||||||
Sequence *_sequence;
|
Sequence *_sequence;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#define Spine_TextureRegion_h
|
#define Spine_TextureRegion_h
|
||||||
|
|
||||||
#include <spine/Array.h>
|
#include <spine/Array.h>
|
||||||
|
#include <spine/RTTI.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API TextureRegion : public SpineObject {
|
class SP_API TextureRegion : public SpineObject {
|
||||||
@ -40,8 +41,10 @@ namespace spine {
|
|||||||
friend class AtlasRegion;
|
friend class AtlasRegion;
|
||||||
friend class SkeletonRenderer;
|
friend class SkeletonRenderer;
|
||||||
|
|
||||||
|
RTTI_DECL_NOPARENT
|
||||||
|
|
||||||
public:
|
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() {};
|
~TextureRegion() {};
|
||||||
|
|
||||||
float getU() const { return _u; };
|
float getU() const { return _u; };
|
||||||
@ -52,28 +55,15 @@ namespace spine {
|
|||||||
void setU2(float value) { _u2 = value; }
|
void setU2(float value) { _u2 = value; }
|
||||||
float getV2() const { return _v2; }
|
float getV2() const { return _v2; }
|
||||||
void setV2(float value) { _v2 = value; }
|
void setV2(float value) { _v2 = value; }
|
||||||
int getDegrees() const { return _degrees; }
|
int getRegionWidth() const { return _regionWidth; };
|
||||||
void setDegrees(int value) { _degrees = value; }
|
void setRegionWidth(int value) { _regionWidth = value; }
|
||||||
float getOffsetX() const { return _offsetX; }
|
int getRegionHeight() const { return _regionHeight; }
|
||||||
void setOffsetX(float value) { _offsetX = value; }
|
void setRegionHeight(int value) { _regionHeight = 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; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *_rendererObject;
|
void *_rendererObject;
|
||||||
float _u, _v, _u2, _v2;
|
float _u, _v, _u2, _v2;
|
||||||
int _degrees;
|
int _regionWidth, _regionHeight;
|
||||||
float _offsetX, _offsetY;
|
|
||||||
int _width, _height;
|
|
||||||
int _originalWidth, _originalHeight;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
using namespace spine;
|
using namespace spine;
|
||||||
|
|
||||||
|
RTTI_IMPL(AtlasRegion, TextureRegion)
|
||||||
|
|
||||||
Atlas::Atlas(const String &path, TextureLoader *textureLoader, bool createTexture) : _textureLoader(textureLoader) {
|
Atlas::Atlas(const String &path, TextureLoader *textureLoader, bool createTexture) : _textureLoader(textureLoader) {
|
||||||
int dirLength;
|
int dirLength;
|
||||||
char *dir;
|
char *dir;
|
||||||
@ -88,7 +90,7 @@ void Atlas::flipV() {
|
|||||||
AtlasRegion *Atlas::findRegion(const String &name) {
|
AtlasRegion *Atlas::findRegion(const String &name) {
|
||||||
for (size_t i = 0, n = _regions.size(); i < n; ++i)
|
for (size_t i = 0, n = _regions.size(); i < n; ++i)
|
||||||
if (_regions[i]->_name == name) return _regions[i];
|
if (_regions[i]->_name == name) return _regions[i];
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<AtlasPage *> &Atlas::getPages() {
|
Array<AtlasPage *> &Atlas::getPages() {
|
||||||
@ -197,7 +199,7 @@ struct AtlasInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int readEntry(SimpleString entry[5], SimpleString *line) {
|
static int readEntry(SimpleString entry[5], SimpleString *line) {
|
||||||
if (line == NULL) return 0;
|
if (line == nullptr) return 0;
|
||||||
line->trim();
|
line->trim();
|
||||||
if (line->length == 0) return 0;
|
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] != '\\';
|
int needsSlash = dirLength > 0 && dir[dirLength - 1] != '/' && dir[dirLength - 1] != '\\';
|
||||||
AtlasInput reader(begin, length);
|
AtlasInput reader(begin, length);
|
||||||
SimpleString entry[5];
|
SimpleString entry[5];
|
||||||
AtlasPage *page = NULL;
|
AtlasPage *page = nullptr;
|
||||||
|
|
||||||
SimpleString *line = reader.readLine();
|
SimpleString *line = reader.readLine();
|
||||||
while (line != NULL && line->length == 0)
|
while (line != nullptr && line->length == 0)
|
||||||
line = reader.readLine();
|
line = reader.readLine();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (line == NULL || line->length == 0) break;
|
if (line == nullptr || line->length == 0) break;
|
||||||
if (reader.readEntry(entry, line) == 0) break;
|
if (reader.readEntry(entry, line) == 0) break;
|
||||||
line = reader.readLine();
|
line = reader.readLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (line == NULL) break;
|
if (line == nullptr) break;
|
||||||
if (line->trim().length == 0) {
|
if (line->trim().length == 0) {
|
||||||
page = NULL;
|
page = nullptr;
|
||||||
line = reader.readLine();
|
line = reader.readLine();
|
||||||
} else if (page == NULL) {
|
} else if (page == nullptr) {
|
||||||
char *name = line->copy();
|
char *name = line->copy();
|
||||||
char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
|
char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
|
||||||
memcpy(path, dir, dirLength);
|
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->_x = entry[1].toInt();
|
||||||
region->_y = entry[2].toInt();
|
region->_y = entry[2].toInt();
|
||||||
} else if (entry[0].equals("size")) {
|
} else if (entry[0].equals("size")) {
|
||||||
region->_width = entry[1].toInt();
|
region->_packedWidth = entry[1].toInt();
|
||||||
region->_height = entry[2].toInt();
|
region->_packedHeight = entry[2].toInt();
|
||||||
} else if (entry[0].equals("bounds")) {
|
} else if (entry[0].equals("bounds")) {
|
||||||
region->_x = entry[1].toInt();
|
region->_x = entry[1].toInt();
|
||||||
region->_y = entry[2].toInt();
|
region->_y = entry[2].toInt();
|
||||||
region->_width = entry[3].toInt();
|
region->_packedWidth = entry[3].toInt();
|
||||||
region->_height = entry[4].toInt();
|
region->_packedHeight = entry[4].toInt();
|
||||||
} else if (entry[0].equals("offset")) {
|
} else if (entry[0].equals("offset")) {
|
||||||
region->_offsetX = entry[1].toInt();
|
region->_offsetX = entry[1].toInt();
|
||||||
region->_offsetY = entry[2].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")) {
|
} else if (!entry[1].equals("false")) {
|
||||||
region->_degrees = entry[1].toInt();
|
region->_degrees = entry[1].toInt();
|
||||||
}
|
}
|
||||||
|
region->_rotate = region->_degrees == 90;
|
||||||
} else if (entry[0].equals("index")) {
|
} else if (entry[0].equals("index")) {
|
||||||
region->_index = entry[1].toInt();
|
region->_index = entry[1].toInt();
|
||||||
} else {
|
} 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) {
|
if (region->_originalWidth == 0 && region->_originalHeight == 0) {
|
||||||
region->_originalWidth = region->_width;
|
region->_originalWidth = region->_packedWidth;
|
||||||
region->_originalHeight = region->_height;
|
region->_originalHeight = region->_packedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
region->_u = (float) region->_x / page->width;
|
region->_u = (float) region->_x / page->width;
|
||||||
region->_v = (float) region->_y / page->height;
|
region->_v = (float) region->_y / page->height;
|
||||||
if (region->_degrees == 90) {
|
if (region->_degrees == 90) {
|
||||||
region->_u2 = (float) (region->_x + region->_height) / page->width;
|
region->_u2 = (float) (region->_x + region->_packedHeight) / page->width;
|
||||||
region->_v2 = (float) (region->_y + region->_width) / page->height;
|
region->_v2 = (float) (region->_y + region->_packedWidth) / page->height;
|
||||||
} else {
|
} else {
|
||||||
region->_u2 = (float) (region->_x + region->_width) / page->width;
|
region->_u2 = (float) (region->_x + region->_packedWidth) / page->width;
|
||||||
region->_v2 = (float) (region->_y + region->_height) / page->height;
|
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);
|
_regions.add(region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <spine/MeshAttachment.h>
|
#include <spine/MeshAttachment.h>
|
||||||
|
#include <spine/Atlas.h>
|
||||||
#include <spine/Slot.h>
|
#include <spine/Slot.h>
|
||||||
|
|
||||||
using namespace spine;
|
using namespace spine;
|
||||||
@ -35,83 +36,88 @@ using namespace spine;
|
|||||||
RTTI_IMPL(MeshAttachment, VertexAttachment)
|
RTTI_IMPL(MeshAttachment, VertexAttachment)
|
||||||
|
|
||||||
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name),
|
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name),
|
||||||
_parentMesh(NULL),
|
_region(NULL),
|
||||||
_path(),
|
_path(),
|
||||||
_color(1, 1, 1, 1),
|
_color(1, 1, 1, 1),
|
||||||
_hullLength(0),
|
_hullLength(0),
|
||||||
|
_parentMesh(NULL),
|
||||||
|
_sequence(NULL),
|
||||||
_width(0),
|
_width(0),
|
||||||
_height(0),
|
_height(0) {}
|
||||||
_region(NULL),
|
|
||||||
_sequence(NULL) {}
|
|
||||||
|
|
||||||
MeshAttachment::~MeshAttachment() {
|
MeshAttachment::~MeshAttachment() {
|
||||||
if (_sequence) delete _sequence;
|
if (_sequence) delete _sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshAttachment::updateRegion() {
|
void MeshAttachment::updateRegion() {
|
||||||
if (_uvs.size() != _regionUVs.size()) {
|
if (_uvs.size() != _regionUVs.size()) _uvs.setSize(_regionUVs.size(), 0);
|
||||||
_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) {
|
float textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u);
|
||||||
return;
|
float textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v);
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0, n = (int) _regionUVs.size();
|
switch (atlasRegion->_degrees) {
|
||||||
float u = _region->_u, v = _region->_v;
|
case 90: {
|
||||||
float width = 0, height = 0;
|
textureWidth = atlasRegion->_packedHeight / (_region->_u2 - _region->_u);
|
||||||
switch (_region->_degrees) {
|
textureHeight = atlasRegion->_packedWidth / (_region->_v2 - _region->_v);
|
||||||
case 90: {
|
u -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / textureWidth;
|
||||||
float textureWidth = _region->_height / (_region->_u2 - _region->_u);
|
v -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / textureHeight;
|
||||||
float textureHeight = _region->_width / (_region->_v2 - _region->_v);
|
width = atlasRegion->_originalHeight / textureWidth;
|
||||||
u -= (_region->_originalHeight - _region->_offsetY - _region->_height) / textureWidth;
|
height = atlasRegion->_originalWidth / textureHeight;
|
||||||
v -= (_region->_originalWidth - _region->_offsetX - _region->_width) / textureHeight;
|
for (int i = 0; i < n; i += 2) {
|
||||||
width = _region->_originalHeight / textureWidth;
|
_uvs[i] = u + _regionUVs[i + 1] * width;
|
||||||
height = _region->_originalWidth / textureHeight;
|
_uvs[i + 1] = v + (1 - _regionUVs[i]) * height;
|
||||||
for (i = 0; i < n; i += 2) {
|
}
|
||||||
_uvs[i] = u + _regionUVs[i + 1] * width;
|
return;
|
||||||
_uvs[i + 1] = v + (1 - _regionUVs[i]) * height;
|
|
||||||
}
|
}
|
||||||
return;
|
case 180: {
|
||||||
}
|
u -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedWidth) / textureWidth;
|
||||||
case 180: {
|
v -= atlasRegion->_offsetY / textureHeight;
|
||||||
float textureWidth = _region->_width / (_region->_u2 - _region->_u);
|
width = atlasRegion->_originalWidth / textureWidth;
|
||||||
float textureHeight = _region->_height / (_region->_v2 - _region->_v);
|
height = atlasRegion->_originalHeight / textureHeight;
|
||||||
u -= (_region->_originalWidth - _region->_offsetX - _region->_width) / textureWidth;
|
for (int i = 0; i < n; i += 2) {
|
||||||
v -= _region->_offsetY / textureHeight;
|
_uvs[i] = u + (1 - _regionUVs[i]) * width;
|
||||||
width = _region->_originalWidth / textureWidth;
|
_uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height;
|
||||||
height = _region->_originalHeight / textureHeight;
|
}
|
||||||
for (i = 0; i < n; i += 2) {
|
return;
|
||||||
_uvs[i] = u + (1 - _regionUVs[i]) * width;
|
|
||||||
_uvs[i + 1] = v + (1 - _regionUVs[i + 1]) * height;
|
|
||||||
}
|
}
|
||||||
return;
|
case 270: {
|
||||||
}
|
textureHeight = atlasRegion->_packedHeight / (_region->_v2 - _region->_v);
|
||||||
case 270: {
|
textureWidth = atlasRegion->_packedWidth / (_region->_u2 - _region->_u);
|
||||||
float textureHeight = _region->_height / (_region->_v2 - _region->_v);
|
u -= atlasRegion->_offsetY / textureWidth;
|
||||||
float textureWidth = _region->_width / (_region->_u2 - _region->_u);
|
v -= atlasRegion->_offsetX / textureHeight;
|
||||||
u -= _region->_offsetY / textureWidth;
|
width = atlasRegion->_originalHeight / textureWidth;
|
||||||
v -= _region->_offsetX / textureHeight;
|
height = atlasRegion->_originalWidth / textureHeight;
|
||||||
width = _region->_originalHeight / textureWidth;
|
for (int i = 0; i < n; i += 2) {
|
||||||
height = _region->_originalWidth / textureHeight;
|
_uvs[i] = u + (1 - _regionUVs[i + 1]) * width;
|
||||||
for (i = 0; i < n; i += 2) {
|
_uvs[i + 1] = v + _regionUVs[i] * height;
|
||||||
_uvs[i] = u + (1 - _regionUVs[i + 1]) * width;
|
}
|
||||||
_uvs[i + 1] = v + _regionUVs[i] * height;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
default: {
|
||||||
}
|
u -= atlasRegion->_offsetX / textureWidth;
|
||||||
default: {
|
v -= (atlasRegion->_originalHeight - atlasRegion->_offsetY - atlasRegion->_packedHeight) / textureHeight;
|
||||||
float textureWidth = _region->_width / (_region->_u2 - _region->_u);
|
width = atlasRegion->_originalWidth / textureWidth;
|
||||||
float textureHeight = _region->_height / (_region->_v2 - _region->_v);
|
height = atlasRegion->_originalHeight / textureHeight;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <spine/RegionAttachment.h>
|
#include <spine/RegionAttachment.h>
|
||||||
|
|
||||||
|
#include <spine/Atlas.h>
|
||||||
#include <spine/Bone.h>
|
#include <spine/Bone.h>
|
||||||
#include <spine/Slot.h>
|
#include <spine/Slot.h>
|
||||||
|
|
||||||
@ -48,19 +49,19 @@ const int RegionAttachment::BRX = 6;
|
|||||||
const int RegionAttachment::BRY = 7;
|
const int RegionAttachment::BRY = 7;
|
||||||
|
|
||||||
RegionAttachment::RegionAttachment(const String &name) : Attachment(name),
|
RegionAttachment::RegionAttachment(const String &name) : Attachment(name),
|
||||||
|
_region(NULL),
|
||||||
|
_path(),
|
||||||
_x(0),
|
_x(0),
|
||||||
_y(0),
|
_y(0),
|
||||||
_rotation(0),
|
|
||||||
_scaleX(1),
|
_scaleX(1),
|
||||||
_scaleY(1),
|
_scaleY(1),
|
||||||
|
_rotation(0),
|
||||||
_width(0),
|
_width(0),
|
||||||
_height(0),
|
_height(0),
|
||||||
_path(),
|
|
||||||
_color(1, 1, 1, 1),
|
_color(1, 1, 1, 1),
|
||||||
_region(NULL),
|
|
||||||
_sequence(NULL) {
|
_sequence(NULL) {
|
||||||
_offset.setSize(NUM_UVS, 0);
|
_offset.setSize(8, 0);
|
||||||
_uvs.setSize(NUM_UVS, 0);
|
_uvs.setSize(8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionAttachment::~RegionAttachment() {
|
RegionAttachment::~RegionAttachment() {
|
||||||
@ -68,24 +69,33 @@ RegionAttachment::~RegionAttachment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegionAttachment::updateRegion() {
|
void RegionAttachment::updateRegion() {
|
||||||
if (_region == NULL) {
|
float width = getWidth(), height = getHeight();
|
||||||
_uvs[BLX] = 0;
|
float localX2 = width / 2;
|
||||||
_uvs[BLY] = 0;
|
float localY2 = height / 2;
|
||||||
_uvs[ULX] = 0;
|
float localX = -localX2;
|
||||||
_uvs[ULY] = 1;
|
float localY = -localY2;
|
||||||
_uvs[URX] = 1;
|
bool rotated = false;
|
||||||
_uvs[URY] = 1;
|
AtlasRegion *atlasRegion = NULL;
|
||||||
_uvs[BRX] = 1;
|
if (_region != NULL) {
|
||||||
_uvs[BRY] = 0;
|
atlasRegion = _region->rtti.isExactly(AtlasRegion::rtti) ? static_cast<AtlasRegion *>(_region) : NULL;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (atlasRegion) {
|
||||||
float regionScaleX = _width / _region->_originalWidth * _scaleX;
|
localX += atlasRegion->_offsetX / atlasRegion->_originalWidth * width;
|
||||||
float regionScaleY = _height / _region->_originalHeight * _scaleY;
|
localY += atlasRegion->_offsetY / atlasRegion->_originalHeight * height;
|
||||||
float localX = -_width / 2 * _scaleX + _region->_offsetX * regionScaleX;
|
if (atlasRegion->_degrees == 90) {
|
||||||
float localY = -_height / 2 * _scaleY + _region->_offsetY * regionScaleY;
|
rotated = true;
|
||||||
float localX2 = localX + _region->_width * regionScaleX;
|
localX2 -= (atlasRegion->_originalWidth - atlasRegion->_offsetX - atlasRegion->_packedHeight) / atlasRegion->_originalWidth * width;
|
||||||
float localY2 = localY + _region->_height * regionScaleY;
|
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 cos = MathUtil::cosDeg(_rotation);
|
||||||
float sin = MathUtil::sinDeg(_rotation);
|
float sin = MathUtil::sinDeg(_rotation);
|
||||||
float localXCos = localX * cos + _x;
|
float localXCos = localX * cos + _x;
|
||||||
@ -106,24 +116,33 @@ void RegionAttachment::updateRegion() {
|
|||||||
_offset[BRX] = localX2Cos - localYSin;
|
_offset[BRX] = localX2Cos - localYSin;
|
||||||
_offset[BRY] = localYCos + localX2Sin;
|
_offset[BRY] = localYCos + localX2Sin;
|
||||||
|
|
||||||
if (_region->_degrees == 90) {
|
if (_region == NULL) {
|
||||||
_uvs[URX] = _region->_u;
|
_uvs[BLX] = 0;
|
||||||
_uvs[URY] = _region->_v2;
|
_uvs[BLY] = 0;
|
||||||
_uvs[BRX] = _region->_u;
|
_uvs[ULX] = 0;
|
||||||
_uvs[BRY] = _region->_v;
|
_uvs[ULY] = 1;
|
||||||
|
_uvs[URX] = 1;
|
||||||
|
_uvs[URY] = 1;
|
||||||
|
_uvs[BRX] = 1;
|
||||||
|
_uvs[BRY] = 0;
|
||||||
|
} else if (rotated) {
|
||||||
_uvs[BLX] = _region->_u2;
|
_uvs[BLX] = _region->_u2;
|
||||||
_uvs[BLY] = _region->_v;
|
_uvs[BLY] = _region->_v;
|
||||||
_uvs[ULX] = _region->_u2;
|
_uvs[ULX] = _region->_u2;
|
||||||
_uvs[ULY] = _region->_v2;
|
_uvs[ULY] = _region->_v2;
|
||||||
|
_uvs[URX] = _region->_u;
|
||||||
|
_uvs[URY] = _region->_v2;
|
||||||
|
_uvs[BRX] = _region->_u;
|
||||||
|
_uvs[BRY] = _region->_v;
|
||||||
} else {
|
} else {
|
||||||
|
_uvs[BLX] = _region->_u2;
|
||||||
|
_uvs[BLY] = _region->_v2;
|
||||||
_uvs[ULX] = _region->_u;
|
_uvs[ULX] = _region->_u;
|
||||||
_uvs[ULY] = _region->_v2;
|
_uvs[ULY] = _region->_v2;
|
||||||
_uvs[URX] = _region->_u;
|
_uvs[URX] = _region->_u;
|
||||||
_uvs[URY] = _region->_v;
|
_uvs[URY] = _region->_v;
|
||||||
_uvs[BRX] = _region->_u2;
|
_uvs[BRX] = _region->_u2;
|
||||||
_uvs[BRY] = _region->_v;
|
_uvs[BRY] = _region->_v;
|
||||||
_uvs[BLX] = _region->_u2;
|
|
||||||
_uvs[BLY] = _region->_v2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
spine-cpp/src/spine/TextureRegion.cpp
Normal file
34
spine-cpp/src/spine/TextureRegion.cpp
Normal 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)
|
||||||
@ -106,7 +106,7 @@ public class Animation {
|
|||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntArray getBones() {
|
public IntArray getBones () {
|
||||||
return bones;
|
return bones;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user