Update spine to 4.1-fc05ecf

This commit is contained in:
halx99 2023-05-07 21:15:56 +08:00
parent e1c64d8e4c
commit d347a454a7
42 changed files with 330 additions and 142 deletions

View File

@ -71,7 +71,6 @@ namespace spine {
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom *eventCustom) {
this->update(0);
});
;
}
SkeletonBatch::~SkeletonBatch() {

View File

@ -269,7 +269,7 @@ namespace spine {
Color darkColor;
const float darkPremultipliedAlpha = _premultipliedAlpha ? 1.f : 0;
TwoColorTrianglesCommand *lastTwoColorTrianglesCommand = nullptr;
for (int i = 0, n = _skeleton->getSlots().size(); i < n; ++i) {
for (int i = 0, n = (int)_skeleton->getSlots().size(); i < n; ++i) {
Slot *slot = _skeleton->getDrawOrder()[i];
if (nothingToDraw(*slot, _startSlotIndex, _endSlotIndex)) {
@ -284,7 +284,7 @@ namespace spine {
if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment *attachment = static_cast<RegionAttachment *>(slot->getAttachment());
texture = (Texture2D*)((AtlasRegion*)attachment->getRegion())->page->getRendererObject();
texture = (Texture2D*)((AtlasRegion*)attachment->getRegion())->page->texture;
float *dstTriangleVertices = nullptr;
int dstStride = 0;// in floats
@ -322,7 +322,7 @@ namespace spine {
color = attachment->getColor();
} else if (slot->getAttachment()->getRTTI().isExactly(MeshAttachment::rtti)) {
MeshAttachment *attachment = (MeshAttachment *) slot->getAttachment();
texture = (Texture2D*)((AtlasRegion*)attachment->getRegion())->page->getRendererObject();
texture = (Texture2D*)((AtlasRegion*)attachment->getRegion())->page->texture;
float *dstTriangleVertices = nullptr;
int dstStride = 0;// in floats
@ -330,8 +330,8 @@ namespace spine {
if (hasSingleTint) {
triangles.indices = attachment->getTriangles().buffer();
triangles.indexCount = (unsigned short)attachment->getTriangles().size();
triangles.verts = batch->allocateVertices(attachment->getWorldVerticesLength() / 2);
triangles.vertCount = attachment->getWorldVerticesLength() / 2;
triangles.verts = batch->allocateVertices((int)attachment->getWorldVerticesLength() / 2);
triangles.vertCount = (int)attachment->getWorldVerticesLength() / 2;
for (int v = 0, i = 0; v < triangles.vertCount; v++, i += 2) {
auto &texCoords = triangles.verts[v].texCoords;
texCoords.u = attachment->getUVs()[i];
@ -343,8 +343,8 @@ namespace spine {
} else {
trianglesTwoColor.indices = attachment->getTriangles().buffer();
trianglesTwoColor.indexCount = (unsigned short)attachment->getTriangles().size();
trianglesTwoColor.verts = twoColorBatch->allocateVertices(attachment->getWorldVerticesLength() / 2);
trianglesTwoColor.vertCount = attachment->getWorldVerticesLength() / 2;
trianglesTwoColor.verts = twoColorBatch->allocateVertices((int)attachment->getWorldVerticesLength() / 2);
trianglesTwoColor.vertCount = (int)attachment->getWorldVerticesLength() / 2;
for (int v = 0, i = 0; v < trianglesTwoColor.vertCount; v++, i += 2) {
auto &texCoords = trianglesTwoColor.verts[v].texCoords;
texCoords.u = attachment->getUVs()[i];
@ -408,9 +408,9 @@ namespace spine {
continue;
}
triangles.vertCount = _clipper->getClippedVertices().size() / 2;
triangles.vertCount = (int)_clipper->getClippedVertices().size() / 2;
triangles.verts = batch->allocateVertices(triangles.vertCount);
triangles.indexCount = _clipper->getClippedTriangles().size();
triangles.indexCount = (int)_clipper->getClippedTriangles().size();
triangles.indices = batch->allocateIndices(triangles.indexCount);
memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
@ -454,9 +454,9 @@ namespace spine {
continue;
}
trianglesTwoColor.vertCount = _clipper->getClippedVertices().size() / 2;
trianglesTwoColor.vertCount = (int)_clipper->getClippedVertices().size() / 2;
trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount);
trianglesTwoColor.indexCount = _clipper->getClippedTriangles().size();
trianglesTwoColor.indexCount = (int)_clipper->getClippedTriangles().size();
trianglesTwoColor.indices = twoColorBatch->allocateIndices(trianglesTwoColor.indexCount);
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
@ -576,7 +576,7 @@ namespace spine {
drawNode->setLineWidth(2.0f);
#endif
V3F_C4B_T2F_Quad quad;
for (int i = 0, n = _skeleton->getSlots().size(); i < n; i++) {
for (int i = 0, n = (int)_skeleton->getSlots().size(); i < n; i++) {
Slot *slot = _skeleton->getDrawOrder()[i];
if (!slot->getBone().isActive()) continue;
@ -606,7 +606,7 @@ namespace spine {
#else
drawNode->setLineWidth(2.0f);
#endif
for (int i = 0, n = _skeleton->getBones().size(); i < n; i++) {
for (int i = 0, n = (int)_skeleton->getBones().size(); i < n; i++) {
Bone *bone = _skeleton->getBones()[i];
if (!bone->isActive()) continue;
float x = bone->getData().getLength() * bone->getA() + bone->getWorldX();
@ -615,7 +615,7 @@ namespace spine {
}
// Bone origins.
auto color = Color4F::BLUE;// Root bone is blue.
for (int i = 0, n = _skeleton->getBones().size(); i < n; i++) {
for (int i = 0, n = (int)_skeleton->getBones().size(); i < n; i++) {
Bone *bone = _skeleton->getBones()[i];
if (!bone->isActive()) continue;
drawNode->drawPoint(Vec2(bone->getWorldX(), bone->getWorldY()), 4, color);
@ -630,7 +630,7 @@ namespace spine {
#else
drawNode->setLineWidth(2.0f);
#endif
for (int i = 0, n = _skeleton->getSlots().size(); i < n; ++i) {
for (int i = 0, n = (int)_skeleton->getSlots().size(); i < n; ++i) {
Slot *slot = _skeleton->getDrawOrder()[i];
if (!slot->getBone().isActive()) continue;
if (!slot->getAttachment() || !slot->getAttachment()->getRTTI().isExactly(MeshAttachment::rtti)) continue;

View File

@ -35,8 +35,6 @@
namespace spine {
// class AttachmentVertices;
/* Draws a skeleton. */
class SP_API SkeletonRenderer : public cocos2d::Node, public cocos2d::BlendProtocol {
public:
@ -153,8 +151,6 @@ namespace spine {
int _startSlotIndex;
int _endSlotIndex;
bool _twoColorTint;
//Pool<AttachmentVertices*> _verticesPool;
};
}// namespace spine

View File

@ -319,7 +319,7 @@ namespace spine {
unsigned short *SkeletonTwoColorBatch::allocateIndices(uint32_t numIndices) {
if (_indices.getCapacity() - _indices.size() < numIndices) {
unsigned short *oldData = _indices.buffer();
int oldSize = _indices.size();
int oldSize = (int)_indices.size();
_indices.ensureCapacity(_indices.size() + numIndices);
unsigned short *newData = _indices.buffer();
for (uint32_t i = 0; i < this->_nextFreeCommand; i++) {
@ -404,8 +404,8 @@ namespace spine {
TwoColorTrianglesCommand *SkeletonTwoColorBatch::nextFreeCommand() {
if (_commandsPool.size() <= _nextFreeCommand) {
unsigned int newSize = _commandsPool.size() * 2 + 1;
for (int i = _commandsPool.size(); i < newSize; i++) {
unsigned int newSize = (int)_commandsPool.size() * 2 + 1;
for (int i = (int)_commandsPool.size(); i < newSize; i++) {
_commandsPool.push_back(new TwoColorTrianglesCommand());
}
}

View File

@ -45,7 +45,7 @@
namespace spine {
enum EventType {
EventType_Start,
EventType_Start = 0,
EventType_Interrupt,
EventType_End,
EventType_Complete,
@ -311,14 +311,13 @@ namespace spine {
private:
Vector<EventQueueEntry> _eventQueueEntries;
AnimationState &_state;
Pool<TrackEntry> &_trackEntryPool;
bool _drainDisabled;
static EventQueue *newEventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool);
static EventQueue *newEventQueue(AnimationState &state);
static EventQueueEntry newEventQueueEntry(EventType eventType, TrackEntry *entry, Event *event = NULL);
EventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool);
EventQueue(AnimationState &state);
~EventQueue();
@ -429,6 +428,12 @@ namespace spine {
void enableQueue();
void setManualTrackEntryDisposal(bool inValue);
bool getManualTrackEntryDisposal();
void disposeTrackEntry(TrackEntry *entry);
private:
static const int Subsequent = 0;
static const int First = 1;
@ -456,6 +461,8 @@ namespace spine {
float _timeScale;
bool _manualTrackEntryDisposal;
static Animation *getEmptyAnimation();
static void

View File

@ -73,7 +73,7 @@ namespace spine {
TextureWrap_Repeat
};
class SP_API AtlasPage : public SpineObject, public HasRendererObject {
class SP_API AtlasPage : public SpineObject {
public:
String name;
String texturePath;
@ -84,11 +84,13 @@ namespace spine {
TextureWrap vWrap;
int width, height;
bool pma;
int index;
void *texture;
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) {
vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false), index(0), texture(NULL) {
}
};

View File

@ -113,6 +113,12 @@ namespace spine {
void
updateWorldTransform(float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY);
/// Computes the individual applied transform values from the world transform. This can be useful to perform processing using
/// the applied transform after the world transform has been modified directly (eg, by a constraint)..
///
/// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation.
void updateAppliedTransform();
void setToSetupPose();
void worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY);
@ -260,12 +266,6 @@ namespace spine {
float _c, _d, _worldY;
bool _sorted;
bool _active;
/// Computes the individual applied transform values from the world transform. This can be useful to perform processing using
/// the applied transform after the world transform has been modified directly (eg, by a constraint)..
///
/// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation.
void updateAppliedTransform();
};
}

View File

@ -34,9 +34,11 @@
#include <spine/SpineString.h>
namespace spine {
/// The interface for all constraints.
/// The interface for all constraints.
class SP_API ConstraintData : public SpineObject {
RTTI_DECL
public:
ConstraintData(const String &name);

View File

@ -37,7 +37,7 @@
namespace spine {
class DebugExtension : public SpineExtension {
class SP_API DebugExtension : public SpineExtension {
struct Allocation {
void *address;
size_t size;
@ -62,7 +62,7 @@ namespace spine {
it->second.address);
}
printf("allocations: %zu, reallocations: %zu, frees: %zu\n", _allocations, _reallocations, _frees);
if (_allocated.empty()) printf("No leaks detected");
if (_allocated.empty()) printf("No leaks detected\n");
}
void clearAllocations() {

View File

@ -64,9 +64,6 @@ namespace spine {
IkConstraint(IkConstraintData &data, Skeleton &skeleton);
/// Applies the constraint to the constrained bones.
void apply();
virtual void update();
virtual int getOrder();

View File

@ -50,6 +50,8 @@ namespace spine {
friend class IkConstraintTimeline;
public:
RTTI_DECL
explicit IkConstraintData(const String &name);
/// The bones that are constrained by this IK Constraint.

View File

@ -33,6 +33,9 @@
#include <spine/SpineObject.h>
#include <string.h>
// Needed for older MSVC versions
#undef min
#undef max
namespace spine {

View File

@ -39,7 +39,7 @@
namespace spine {
/// Attachment that displays a texture region using a mesh.
class SP_API MeshAttachment : public VertexAttachment, public HasRendererObject {
class SP_API MeshAttachment : public VertexAttachment {
friend class SkeletonBinary;
friend class SkeletonJson;

View File

@ -59,13 +59,18 @@ namespace spine {
public:
PathConstraint(PathConstraintData &data, Skeleton &skeleton);
/// Applies the constraint to the constrained bones.
void apply();
virtual void update();
virtual int getOrder();
PathConstraintData &getData();
Vector<Bone *> &getBones();
Slot *getTarget();
void setTarget(Slot *inValue);
float getPosition();
void setPosition(float inValue);
@ -86,14 +91,6 @@ namespace spine {
void setMixY(float inValue);
Vector<Bone *> &getBones();
Slot *getTarget();
void setTarget(Slot *inValue);
PathConstraintData &getData();
bool isActive();
void setActive(bool inValue);

View File

@ -57,8 +57,9 @@ namespace spine {
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
public:
RTTI_DECL
explicit PathConstraintData(const String &name);
Vector<BoneData *> &getBones();

View File

@ -44,7 +44,7 @@ namespace spine {
class Bone;
/// Attachment that displays a texture region.
class SP_API RegionAttachment : public Attachment, public HasRendererObject {
class SP_API RegionAttachment : public Attachment {
friend class SkeletonBinary;
friend class SkeletonJson;
@ -61,7 +61,7 @@ namespace spine {
void updateRegion();
/// Transforms the attachment's four vertices to world coordinates.
/// @param bone The parent bone.
/// @param slot The parent slot.
/// @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.

View File

@ -147,7 +147,7 @@ namespace spine {
Attachment *readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
SkeletonData *skeletonData, bool nonessential);
void readVertices(DataInput *input, Vector<float> &vertices, Vector<size_t> &bones, int vertexCount);
void readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, int vertexCount);
void readFloatArray(DataInput *input, int n, float scale, Vector<float> &array);

View File

@ -81,8 +81,19 @@ namespace spine {
/// Returns true if the polygon contains the line segment.
bool intersectsSegment(Polygon *polygon, float x1, float y1, float x2, float y2);
/// Returns the polygon for the given bounding box attachment or null if no
/// polygon can be found for the attachment. Requires a call to update() first.
Polygon *getPolygon(BoundingBoxAttachment *attachment);
/// Returns the bounding box for the given polygon or null. Requires a call to update() first.
BoundingBoxAttachment * getBoundingBox(Polygon *polygon);
/// Returns all polygons or an empty vector. Requires a call to update() first.
Vector<Polygon *> &getPolygons();
/// Returns all bounding boxes. Requires a call to update() first.
Vector<BoundingBoxAttachment *> &getBoundingBoxes();
float getWidth();
float getHeight();

View File

@ -36,11 +36,6 @@
#include <string.h>
#include <stdio.h>
// Required for sprintf on MSVC
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
namespace spine {
class SP_API String : public SpineObject {
public:
@ -170,14 +165,14 @@ namespace spine {
String &append(int other) {
char str[100];
sprintf(str, "%i", other);
snprintf(str, 100, "%i", other);
append(str);
return *this;
}
String &append(float other) {
char str[100];
sprintf(str, "%f", other);
snprintf(str, 100, "%f", other);
append(str);
return *this;
}

View File

@ -50,40 +50,72 @@ namespace spine {
friend class TransformConstraintTimeline;
public:
RTTI_DECL
explicit TransformConstraintData(const String &name);
Vector<BoneData *> &getBones();
BoneData *getTarget();
void setTarget(BoneData *target);
float getMixRotate();
void setMixRotate(float mixRotate);
float getMixX();
void setMixX(float mixX);
float getMixY();
void setMixY(float mixY);
float getMixScaleX();
void setMixScaleX(float mixScaleX);
float getMixScaleY();
void setMixScaleY(float mixScaleY);
float getMixShearY();
void setMixShearY(float mixShearY);
float getOffsetRotation();
void setOffsetRotation(float offsetRotation);
float getOffsetX();
void setOffsetX(float offsetX);
float getOffsetY();
void setOffsetY(float offsetY);
float getOffsetScaleX();
void setOffsetScaleX(float offsetScaleX);
float getOffsetScaleY();
void setOffsetScaleY(float offsetScaleY);
float getOffsetShearY();
void setOffsetShearY(float offsetShearY);
bool isRelative();
void setRelative(bool isRelative);
bool isLocal();
void setLocal(bool isLocal);
private:
Vector<BoneData *> _bones;
BoneData *_target;

View File

@ -71,7 +71,7 @@ namespace spine {
/// Gets a unique ID for this attachment.
int getId();
Vector <size_t> &getBones();
Vector<int> &getBones();
Vector<float> &getVertices();
@ -86,7 +86,7 @@ namespace spine {
void copyTo(VertexAttachment *other);
protected:
Vector <size_t> _bones;
Vector <int> _bones;
Vector<float> _vertices;
size_t _worldVerticesLength;
Attachment *_timelineAttachment;

View File

@ -35,7 +35,7 @@
namespace spine {
class SP_API Vertices : public SpineObject {
public:
Vector <size_t> _bones;
Vector <int> _bones;
Vector<float> _vertices;
};
}

View File

@ -211,17 +211,16 @@ EventQueueEntry::EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Ev
_event(event) {
}
EventQueue *EventQueue::newEventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool) {
return new (__FILE__, __LINE__) EventQueue(state, trackEntryPool);
EventQueue *EventQueue::newEventQueue(AnimationState &state) {
return new (__FILE__, __LINE__) EventQueue(state);
}
EventQueueEntry EventQueue::newEventQueueEntry(EventType eventType, TrackEntry *entry, Event *event) {
return EventQueueEntry(eventType, entry, event);
}
EventQueue::EventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool) : _state(state),
_trackEntryPool(trackEntryPool),
_drainDisabled(false) {
EventQueue::EventQueue(AnimationState &state) : _state(state),
_drainDisabled(false) {
}
EventQueue::~EventQueue() {
@ -295,8 +294,7 @@ void EventQueue::drain() {
else
state._listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
trackEntry->reset();
_trackEntryPool.free(trackEntry);
if (!_state.getManualTrackEntryDisposal()) _state.disposeTrackEntry(trackEntry);
break;
case EventType_Event:
if (!trackEntry->_listenerObject)
@ -315,12 +313,13 @@ void EventQueue::drain() {
}
AnimationState::AnimationState(AnimationStateData *data) : _data(data),
_queue(EventQueue::newEventQueue(*this, _trackEntryPool)),
_queue(EventQueue::newEventQueue(*this)),
_animationsChanged(false),
_listener(dummyOnAnimationEventFunc),
_listenerObject(NULL),
_unkeyedState(0),
_timeScale(1) {
_timeScale(1),
_manualTrackEntryDisposal(false) {
}
AnimationState::~AnimationState() {
@ -666,6 +665,19 @@ void AnimationState::enableQueue() {
_queue->_drainDisabled = false;
}
void AnimationState::setManualTrackEntryDisposal(bool inValue) {
_manualTrackEntryDisposal = inValue;
}
bool AnimationState::getManualTrackEntryDisposal() {
return _manualTrackEntryDisposal;
}
void AnimationState::disposeTrackEntry(TrackEntry *entry) {
entry->reset();
_trackEntryPool.free(entry);
}
Animation *AnimationState::getEmptyAnimation() {
static Vector<Timeline *> timelines;
static Animation ret(String("<empty>"), timelines, 0);

View File

@ -69,7 +69,7 @@ Atlas::Atlas(const char *data, int length, const char *dir, TextureLoader *textu
Atlas::~Atlas() {
if (_textureLoader) {
for (size_t i = 0, n = _pages.size(); i < n; ++i) {
_textureLoader->unload(_pages[i]->getRendererObject());
_textureLoader->unload(_pages[i]->texture);
}
}
ContainerUtil::cleanUpVectorOfPointers(_pages);
@ -108,21 +108,21 @@ struct SimpleString {
while (isspace((unsigned char) *start) && start < end)
start++;
if (start == end) {
length = end - start;
length = (int) (end - start);
return *this;
}
end--;
while (((unsigned char) *end == '\r') && end >= start)
end--;
end++;
length = end - start;
length = (int) (end - start);
return *this;
}
int indexOf(char needle) {
char *c = start;
while (c < end) {
if (*c == needle) return c - start;
if (*c == needle) return (int) (c - start);
c++;
}
return -1;
@ -131,7 +131,7 @@ struct SimpleString {
int indexOf(char needle, int at) {
char *c = start + at;
while (c < end) {
if (*c == needle) return c - start;
if (*c == needle) return (int) (c - start);
c++;
}
return -1;
@ -150,7 +150,7 @@ struct SimpleString {
SimpleString result;
result.start = start + s;
result.end = end;
result.length = result.end - result.start;
result.length = (int) (result.end - result.start);
return result;
}
@ -286,10 +286,12 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
} else {
page->texturePath = String(path, true);
}
page->index = (int) _pages.size();
_pages.add(page);
} else {
AtlasRegion *region = new (__FILE__, __LINE__) AtlasRegion();
region->page = page;
region->rendererObject = page->texture;
region->name = String(line->copy(), true);
while (true) {
line = reader.readLine();

View File

@ -63,7 +63,6 @@ namespace spine {
} else {
AtlasRegion *region = findRegion(path);
if (!region) return NULL;
attachment->setRendererObject(region);
attachment->setRegion(region);
}
return attachment;
@ -78,7 +77,6 @@ namespace spine {
} else {
AtlasRegion *region = findRegion(path);
if (!region) return NULL;
attachment->setRendererObject(region);
attachment->setRegion(region);
}
return attachment;

View File

@ -192,7 +192,6 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX,
_b = za * lb + zb * ld;
_c = zc * la + zd * lc;
_d = zc * lb + zd * ld;
break;
}
}
_a *= _skeleton.getScaleX();
@ -496,33 +495,75 @@ void Bone::updateAppliedTransform() {
_ascaleY = MathUtil::sqrt(_b * _b + _d * _d);
_ashearX = 0;
_ashearY = MathUtil::atan2(_a * _b + _c * _d, _a * _d - _b * _c) * MathUtil::Rad_Deg;
}
float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d;
float pid = 1 / (pa * pd - pb * pc);
float ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;
float dx = _worldX - parent->_worldX, dy = _worldY - parent->_worldY;
_ax = (dx * ia - dy * ib);
_ay = (dy * id - dx * ic);
float ra, rb, rc, rd;
if (_data.getTransformMode() == TransformMode_OnlyTranslation) {
ra = _a;
rb = _b;
rc = _c;
rd = _d;
} else {
float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d;
float pid = 1 / (pa * pd - pb * pc);
float dx = _worldX - parent->_worldX, dy = _worldY - parent->_worldY;
float ia = pid * pd;
float id = pid * pa;
float ib = pid * pb;
float ic = pid * pc;
float ra = ia * _a - ib * _c;
float rb = ia * _b - ib * _d;
float rc = id * _c - ic * _a;
float rd = id * _d - ic * _b;
_ax = (dx * pd * pid - dy * pb * pid);
_ay = (dy * pa * pid - dx * pc * pid);
_ashearX = 0;
_ascaleX = MathUtil::sqrt(ra * ra + rc * rc);
if (_ascaleX > 0.0001f) {
float det = ra * rd - rb * rc;
_ascaleY = det / _ascaleX;
_ashearY = MathUtil::atan2(ra * rb + rc * rd, det) * MathUtil::Rad_Deg;
_arotation = MathUtil::atan2(rc, ra) * MathUtil::Rad_Deg;
} else {
_ascaleX = 0;
_ascaleY = MathUtil::sqrt(rb * rb + rd * rd);
_ashearY = 0;
_arotation = 90 - MathUtil::atan2(rd, rb) * MathUtil::Rad_Deg;
switch (_data.getTransformMode()) {
case TransformMode_NoRotationOrReflection: {
float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
float sa = pa / _skeleton.getScaleX();
float sc = pc / _skeleton.getScaleY();
pb = -sc * s * _skeleton.getScaleX();
pd = sa * s * _skeleton.getScaleY();
pid = 1 / (pa * pd - pb * pc);
ia = pd * pid;
ib = pb * pid;
break;
}
case TransformMode_NoScale:
case TransformMode_NoScaleOrReflection: {
float cos = MathUtil::cosDeg(_rotation), sin = MathUtil::sinDeg(_rotation);
pa = (pa * cos + pb * sin) / _skeleton.getScaleX();
pc = (pc * cos + pd * sin) / _skeleton.getScaleY();
float s = MathUtil::sqrt(pa * pa + pc * pc);
if (s > 0.00001f) s = 1 / s;
pa *= s;
pc *= s;
s = MathUtil::sqrt(pa * pa + pc * pc);
if (_data.getTransformMode() == TransformMode_NoScale && pid < 0 != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0)) s = -s;
float r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
pb = MathUtil::cos(r) * s;
pd = MathUtil::sin(r) * s;
pid = 1 / (pa * pd - pb * pc);
ia = pd * pid;
ib = pb * pid;
ic = pc * pid;
id = pa * pid;
break;
}
default:
break;
}
ra = ia * _a - ib * _c;
rb = ia * _b - ib * _d;
rc = id * _c - ic * _a;
rd = id * _d - ic * _b;
}
_ashearX = 0;
_ascaleX = MathUtil::sqrt(ra * ra + rc * rc);
if (_ascaleX > 0.0001f) {
float det = ra * rd - rb * rc;
_ascaleY = det / _ascaleX;
_ashearY = -MathUtil::atan2(ra * rb + rc * rd, det) * MathUtil::Rad_Deg;
_arotation = MathUtil::atan2(rc, ra) * MathUtil::Rad_Deg;
} else {
_ascaleX = 0;
_ascaleY = MathUtil::sqrt(rb * rb + rd * rd);
_ashearY = 0;
_arotation = 90 - MathUtil::atan2(rd, rb) * MathUtil::Rad_Deg;
}
}

View File

@ -31,6 +31,8 @@
using namespace spine;
RTTI_IMPL_NOPARENT(ConstraintData)
ConstraintData::ConstraintData(const String &name) : _name(name), _order(0), _skinRequired(false) {
}

View File

@ -104,6 +104,7 @@ void DefaultSpineExtension::_free(void *mem, const char *file, int line) {
}
char *DefaultSpineExtension::_readFile(const String &path, int *length) {
#ifndef __EMSCRIPTEN__
char *data;
FILE *file = fopen(path.buffer(), "rb");
if (!file) return 0;
@ -117,6 +118,9 @@ char *DefaultSpineExtension::_readFile(const String &path, int *length) {
fclose(file);
return data;
#else
return nullptr;
#endif
}
DefaultSpineExtension::DefaultSpineExtension() : SpineExtension() {

View File

@ -51,7 +51,7 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress
ty = targetY - bone._worldY;
break;
case TransformMode_NoRotationOrReflection: {
float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
float s = MathUtil::abs(pa * pd - pb * pc) / MathUtil::max(0.0001f, pa * pa + pc * pc);
float sa = pa / bone._skeleton.getScaleX();
float sc = pc / bone._skeleton.getScaleY();
pb = -sc * s * bone._skeleton.getScaleX();
@ -61,8 +61,13 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress
default:
float x = targetX - p->_worldX, y = targetY - p->_worldY;
float d = pa * pd - pb * pc;
tx = (x * pd - y * pb) / d - bone._ax;
ty = (y * pa - x * pc) / d - bone._ay;
if (MathUtil::abs(d) <= 0.0001f) {
tx = 0;
ty = 0;
} else {
tx = (x * pd - y * pb) / d - bone._ax;
ty = (y * pa - x * pc) / d - bone._ay;
}
}
rotationIK += MathUtil::atan2(ty, tx) * MathUtil::Rad_Deg;
if (bone._ascaleX < 0) rotationIK += 180;
@ -140,7 +145,8 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY
b = pp->_b;
c = pp->_c;
d = pp->_d;
id = 1 / (a * d - b * c);
id = a * d - b * c;
id = MathUtil::abs(id) <= 0.0001f ? 0 : 1 / id;
x = cwx - pp->_worldX;
y = cwy - pp->_worldY;
dx = (x * d - y * b) * id - px;
@ -154,11 +160,13 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY
}
x = targetX - pp->_worldX;
y = targetY - pp->_worldY;
tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
tx = (x * d - y * b) * id - px;
ty = (y * a - x * c) * id - py;
dd = tx * tx + ty * ty;
if (softness != 0) {
softness *= psx * (csx + 1) * 0.5f;
td = MathUtil::sqrt(dd), sd = td - l1 - l2 * psx + softness;
td = MathUtil::sqrt(dd);
sd = td - l1 - l2 * psx + softness;
if (sd > 0) {
p = MathUtil::min(1.0f, sd / (softness * 2)) - 1;
p = (sd - softness * (1 - p * p)) / td;
@ -188,7 +196,8 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY
b = l2 * MathUtil::sin(a2);
a1 = MathUtil::atan2(ty * a - tx * b, tx * a + ty * b);
} else {
a = psx * l2, b = psy * l2;
a = psx * l2;
b = psy * l2;
float aa = a * a, bb = b * b, ll = l1 * l1, ta = MathUtil::atan2(ty, tx);
float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c0;

View File

@ -33,6 +33,8 @@
using namespace spine;
RTTI_IMPL(IkConstraintData, ConstraintData)
IkConstraintData::IkConstraintData(const String &name) : ConstraintData(name),
_target(NULL),
_bendDirection(1),

View File

@ -28,13 +28,12 @@
*****************************************************************************/
#include <spine/MeshAttachment.h>
#include <spine/HasRendererObject.h>
using namespace spine;
RTTI_IMPL(MeshAttachment, VertexAttachment)
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name), HasRendererObject(),
MeshAttachment::MeshAttachment(const String &name) : VertexAttachment(name),
_parentMesh(NULL),
_path(),
_color(1, 1, 1, 1),
@ -53,10 +52,13 @@ void MeshAttachment::updateRegion() {
_uvs.setSize(_regionUVs.size(), 0);
}
if (_region == nullptr) {
return;
}
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);
@ -203,7 +205,6 @@ Attachment *MeshAttachment::copy() {
if (_parentMesh) return newLinkedMesh();
MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName());
copy->setRendererObject(getRendererObject());
copy->setRegion(_region);
copy->setSequence(_sequence != NULL ? _sequence->copy() : NULL);
copy->_path = _path;
@ -224,7 +225,6 @@ Attachment *MeshAttachment::copy() {
MeshAttachment *MeshAttachment::newLinkedMesh() {
MeshAttachment *copy = new (__FILE__, __LINE__) MeshAttachment(getName());
copy->setRendererObject(getRendererObject());
copy->setRegion(_region);
copy->_path = _path;
copy->_color.set(_color);

View File

@ -36,6 +36,8 @@
using namespace spine;
RTTI_IMPL(PathConstraintData, ConstraintData)
PathConstraintData::PathConstraintData(const String &name) : ConstraintData(name),
_target(NULL),
_positionMode(PositionMode_Fixed),

View File

@ -47,7 +47,7 @@ const int RegionAttachment::URY = 5;
const int RegionAttachment::BRX = 6;
const int RegionAttachment::BRY = 7;
RegionAttachment::RegionAttachment(const String &name) : Attachment(name), HasRendererObject(),
RegionAttachment::RegionAttachment(const String &name) : Attachment(name),
_x(0),
_y(0),
_rotation(0),
@ -259,7 +259,6 @@ spine::Color &RegionAttachment::getColor() {
Attachment *RegionAttachment::copy() {
RegionAttachment *copy = new (__FILE__, __LINE__) RegionAttachment(getName());
copy->_region = _region;
copy->setRendererObject(getRendererObject());
copy->_path = _path;
copy->_x = _x;
copy->_y = _y;

View File

@ -66,7 +66,6 @@ void Sequence::apply(Slot *slot, Attachment *attachment) {
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment *regionAttachment = static_cast<RegionAttachment *>(attachment);
if (regionAttachment->getRegion() != region) {
regionAttachment->setRendererObject(region);
regionAttachment->setRegion(region);
regionAttachment->updateRegion();
}
@ -75,7 +74,6 @@ void Sequence::apply(Slot *slot, Attachment *attachment) {
if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
MeshAttachment *meshAttachment = static_cast<MeshAttachment *>(attachment);
if (meshAttachment->getRegion() != region) {
meshAttachment->setRendererObject(region);
meshAttachment->setRegion(region);
meshAttachment->updateRegion();
}

View File

@ -425,8 +425,8 @@ PathConstraint *Skeleton::findPathConstraint(const String &constraintName) {
void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer) {
float minX = FLT_MAX;
float minY = FLT_MAX;
float maxX = FLT_MIN;
float maxY = FLT_MIN;
float maxX = -FLT_MAX;
float maxY = -FLT_MAX;
for (size_t i = 0; i < _drawOrder.size(); ++i) {
Slot *slot = _drawOrder[i];
@ -653,7 +653,7 @@ void Skeleton::sortPathConstraintAttachment(Skin *skin, size_t slotIndex, Bone &
void Skeleton::sortPathConstraintAttachment(Attachment *attachment, Bone &slotBone) {
if (attachment == NULL || !attachment->getRTTI().instanceOf(PathAttachment::rtti)) return;
Vector<size_t> &pathBones = static_cast<PathAttachment *>(attachment)->getBones();
Vector<int> &pathBones = static_cast<PathAttachment *>(attachment)->getBones();
if (pathBones.size() == 0)
sortBone(&slotBone);
else {

View File

@ -109,9 +109,9 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
int lowHash = readInt(input);
int hightHash = readInt(input);
String hashString;
sprintf(buffer, "%x", hightHash);
snprintf(buffer, 16, "%x", hightHash);
hashString.append(buffer);
sprintf(buffer, "%x", lowHash);
snprintf(buffer, 16, "%x", lowHash);
hashString.append(buffer);
skeletonData->_hash = hashString;
@ -120,7 +120,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
if (!skeletonData->_version.startsWith(SPINE_VERSION_STRING)) {
char errorMsg[255];
sprintf(errorMsg, "Skeleton version %s does not match runtime version %s", skeletonData->_version.buffer(), SPINE_VERSION_STRING);
snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->_version.buffer(), SPINE_VERSION_STRING);
setError(errorMsg, "");
return NULL;
}
@ -564,7 +564,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
Vector<float> uvs;
Vector<unsigned short> triangles;
Vector<float> vertices;
Vector<size_t> bones;
Vector<int> bones;
int hullLength;
Sequence *sequence;
float width = 0;
@ -702,7 +702,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
return NULL;
}
void SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vector<size_t> &bones, int vertexCount) {
void SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, int vertexCount) {
float scale = _scale;
int verticesLength = vertexCount << 1;
@ -1010,7 +1010,7 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
timeline->setFrame(frame, time, a);
if (frame == frameLast) break;
float time2 = readFloat(input);
float a2 = readByte(input) / 255;
float a2 = readByte(input) / 255.0;
switch (readSByte(input)) {
case CURVE_STEPPED:
timeline->setStepped(frame);
@ -1249,13 +1249,13 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
setError("Attachment not found: ", attachmentName);
return NULL;
}
VertexAttachment *attachment = static_cast<VertexAttachment *>(baseAttachment);
unsigned int timelineType = readByte(input);
int frameCount = readVarint(input, true);
int frameLast = frameCount - 1;
switch (timelineType) {
case ATTACHMENT_DEFORM: {
VertexAttachment *attachment = static_cast<VertexAttachment *>(baseAttachment);
bool weighted = attachment->_bones.size() > 0;
Vector<float> &vertices = attachment->_vertices;
int deformLength = weighted ? (int) vertices.size() / 3 * 2 : (int) vertices.size();
@ -1311,7 +1311,7 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
break;
}
case ATTACHMENT_SEQUENCE: {
SequenceTimeline *timeline = new (__FILE__, __LINE__) SequenceTimeline(frameCount, slotIndex, attachment);
SequenceTimeline *timeline = new (__FILE__, __LINE__) SequenceTimeline(frameCount, slotIndex, baseAttachment);
for (int frame = 0; frame < frameCount; frame++) {
float time = readFloat(input);
int modeAndIndex = readInt(input);

View File

@ -185,6 +185,19 @@ spine::Polygon *SkeletonBounds::getPolygon(BoundingBoxAttachment *attachment) {
return index == -1 ? NULL : _polygons[index];
}
BoundingBoxAttachment *SkeletonBounds::getBoundingBox(Polygon *polygon) {
int index = _polygons.indexOf(polygon);
return index == -1 ? NULL : _boundingBoxes[index];
}
Vector<Polygon *> &SkeletonBounds::getPolygons() {
return _polygons;
}
Vector<BoundingBoxAttachment *> &SkeletonBounds::getBoundingBoxes() {
return _boundingBoxes;
}
float SkeletonBounds::getWidth() {
return _maxX - _minX;
}

View File

@ -152,7 +152,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
skeletonData->_version = Json::getString(skeleton, "spine", 0);
if (!skeletonData->_version.startsWith(SPINE_VERSION_STRING)) {
char errorMsg[255];
sprintf(errorMsg, "Skeleton version %s does not match runtime version %s", skeletonData->_version.buffer(), SPINE_VERSION_STRING);
snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->_version.buffer(), SPINE_VERSION_STRING);
setError(NULL, errorMsg, "");
return NULL;
}

View File

@ -62,7 +62,7 @@ TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton
}
void TransformConstraint::update() {
if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleX == 0 && _mixShearY == 0) return;
if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleY == 0 && _mixShearY == 0) return;
if (_data.isLocal()) {
if (_data.isRelative())

View File

@ -35,6 +35,8 @@
using namespace spine;
RTTI_IMPL(TransformConstraintData, ConstraintData)
TransformConstraintData::TransformConstraintData(const String &name) : ConstraintData(name),
_target(NULL),
_mixRotate(0),
@ -116,3 +118,63 @@ bool TransformConstraintData::isRelative() {
bool TransformConstraintData::isLocal() {
return _local;
}
void TransformConstraintData::setTarget(BoneData *target) {
_target = target;
}
void TransformConstraintData::setMixRotate(float mixRotate) {
_mixRotate = mixRotate;
}
void TransformConstraintData::setMixX(float mixX) {
_mixX = mixX;
}
void TransformConstraintData::setMixY(float mixY) {
_mixY = mixY;
}
void TransformConstraintData::setMixScaleX(float mixScaleX) {
_mixScaleX = mixScaleX;
}
void TransformConstraintData::setMixScaleY(float mixScaleY) {
_mixScaleY = mixScaleY;
}
void TransformConstraintData::setMixShearY(float mixShearY) {
_mixShearY = mixShearY;
}
void TransformConstraintData::setOffsetRotation(float offsetRotation) {
_offsetRotation = offsetRotation;
}
void TransformConstraintData::setOffsetX(float offsetX) {
_offsetX = offsetX;
}
void TransformConstraintData::setOffsetY(float offsetY) {
_offsetY = offsetY;
}
void TransformConstraintData::setOffsetScaleX(float offsetScaleX) {
_offsetScaleX = offsetScaleX;
}
void TransformConstraintData::setOffsetScaleY(float offsetScaleY) {
_offsetScaleY = offsetScaleY;
}
void TransformConstraintData::setOffsetShearY(float offsetShearY) {
_offsetShearY = offsetShearY;
}
void TransformConstraintData::setRelative(bool isRelative) {
_relative = isRelative;
}
void TransformConstraintData::setLocal(bool isLocal) {
_local = isLocal;
}

View File

@ -64,7 +64,7 @@ void VertexAttachment::computeWorldVertices(Slot &slot, size_t start, size_t cou
Skeleton &skeleton = slot._bone._skeleton;
Vector<float> *deformArray = &slot.getDeform();
Vector<float> *vertices = &_vertices;
Vector<size_t> &bones = _bones;
Vector<int> &bones = _bones;
if (bones.size() == 0) {
if (deformArray->size() > 0) vertices = deformArray;
@ -130,7 +130,7 @@ int VertexAttachment::getId() {
return _id;
}
Vector<size_t> &VertexAttachment::getBones() {
Vector<int> &VertexAttachment::getBones() {
return _bones;
}

View File

@ -114,7 +114,7 @@ void Cocos2dTextureLoader::load(AtlasPage &page, const spine::String &path) {
#endif
texture->setTexParameters(textureParams);
page.setRendererObject(texture);
page.texture = texture;
page.width = texture->getPixelsWide();
page.height = texture->getPixelsHigh();
}