[cpp] 4.3 porting WIP

This commit is contained in:
Mario Zechner 2025-06-11 18:19:05 +02:00
parent c9193f682a
commit 5cd55f83c9
2 changed files with 55 additions and 45 deletions

View File

@ -31,11 +31,12 @@
#define Spine_DeformTimeline_h #define Spine_DeformTimeline_h
#include <spine/CurveTimeline.h> #include <spine/CurveTimeline.h>
#include <spine/SlotTimeline.h>
namespace spine { namespace spine {
class VertexAttachment; class VertexAttachment;
class SP_API DeformTimeline : public CurveTimeline { class SP_API DeformTimeline : public CurveTimeline, public SlotTimeline {
friend class SkeletonBinary; friend class SkeletonBinary;
friend class SkeletonJson; friend class SkeletonJson;
@ -47,28 +48,35 @@ namespace spine {
virtual void virtual void
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend, apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
MixDirection direction); MixDirection direction) override;
/// Sets the time and value of the specified keyframe. /// Sets the time and vertices for the specified frame.
void setFrame(int frameIndex, float time, Vector<float> &vertices); void setFrame(int frameIndex, float time, Vector<float> &vertices);
/// The vertices for each frame.
Vector <Vector<float>> &getVertices(); Vector <Vector<float>> &getVertices();
/// The attachment that will be deformed.
VertexAttachment *getAttachment(); VertexAttachment *getAttachment();
void setAttachment(VertexAttachment *inValue); void setAttachment(VertexAttachment *inValue);
virtual void virtual void
setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2, setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2,
float cy2, float time2, float value2); float cy2, float time2, float value2) override;
float getCurvePercent(float time, int frame); float getCurvePercent(float time, int frame);
int getSlotIndex() { return _slotIndex; } int getSlotIndex() override { return _slotIndex; }
void setSlotIndex(int inValue) { _slotIndex = inValue; } void setSlotIndex(int inValue) { _slotIndex = inValue; }
size_t getFrameCount() { return _frames.size(); }
protected: protected:
void apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend);
private:
int _slotIndex; int _slotIndex;
Vector <Vector<float>> _vertices; Vector <Vector<float>> _vertices;

View File

@ -31,14 +31,13 @@
#include <spine/Event.h> #include <spine/Event.h>
#include <spine/Skeleton.h> #include <spine/Skeleton.h>
#include <spine/VertexAttachment.h> #include <spine/VertexAttachment.h>
#include <spine/Animation.h> #include <spine/Animation.h>
#include <spine/Bone.h> #include <spine/Bone.h>
#include <spine/Property.h> #include <spine/Property.h>
#include <spine/Slot.h> #include <spine/Slot.h>
#include <spine/SlotData.h> #include <spine/SlotData.h>
#include <spine/SlotPose.h>
using namespace spine; using namespace spine;
@ -66,17 +65,21 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Slot &slot = *slotP; Slot &slot = *slotP;
if (!slot._bone.isActive()) return; if (!slot._bone.isActive()) return;
Attachment *slotAttachment = slot.getAttachment(); apply(slot, slot._pose, time, alpha, blend);
}
void DeformTimeline::apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) {
Attachment *slotAttachment = pose.attachment;
if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti)) { if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti)) {
return; return;
} }
VertexAttachment *attachment = static_cast<VertexAttachment *>(slotAttachment); VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (attachment->_timelineAttachment != _attachment) { if (vertexAttachment->getTimelineAttachment() != _attachment) {
return; return;
} }
Vector<float> &deformArray = slot._deform; Vector<float> &deformArray = pose.deform;
if (deformArray.size() == 0) { if (deformArray.size() == 0) {
blend = MixBlend_Setup; blend = MixBlend_Setup;
} }
@ -85,7 +88,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
size_t vertexCount = vertices[0].size(); size_t vertexCount = vertices[0].size();
Vector<float> &frames = _frames; Vector<float> &frames = _frames;
if (time < _frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case MixBlend_Setup: case MixBlend_Setup:
deformArray.clear(); deformArray.clear();
@ -97,9 +100,9 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} }
deformArray.setSize(vertexCount, 0); deformArray.setSize(vertexCount, 0);
Vector<float> &deform = deformArray; Vector<float> &deform = deformArray;
if (attachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions. // Unweighted vertex positions.
Vector<float> &setupVertices = attachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
deform[i] += (setupVertices[i] - deform[i]) * alpha; deform[i] += (setupVertices[i] - deform[i]) * alpha;
} else { } else {
@ -108,10 +111,11 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
deform[i] *= alpha; deform[i] *= alpha;
} }
break;
} }
case MixBlend_Replace: case MixBlend_Replace:
case MixBlend_Add: { case MixBlend_Add:
} break;
} }
return; return;
} }
@ -119,11 +123,10 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
deformArray.setSize(vertexCount, 0); deformArray.setSize(vertexCount, 0);
Vector<float> &deform = deformArray; Vector<float> &deform = deformArray;
if (time >= frames[frames.size() - 1]) {// Time is after last frame. if (time >= frames[frames.size() - 1]) { // Time is after last frame.
Vector<float> &lastVertices = vertices[frames.size() - 1]; Vector<float> &lastVertices = vertices[frames.size() - 1];
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend_Add) { if (blend == MixBlend_Add) {
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
@ -141,7 +144,6 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} else { } else {
switch (blend) { switch (blend) {
case MixBlend_Setup: { case MixBlend_Setup: {
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
@ -163,9 +165,8 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
deform[i] += (lastVertices[i] - deform[i]) * alpha; deform[i] += (lastVertices[i] - deform[i]) * alpha;
break; break;
case MixBlend_Add: case MixBlend_Add:
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, with alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha; deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
@ -174,6 +175,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
deform[i] += lastVertices[i] * alpha; deform[i] += lastVertices[i] * alpha;
} }
break;
} }
} }
return; return;
@ -187,7 +189,6 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend_Add) { if (blend == MixBlend_Add) {
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
@ -202,6 +203,8 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
deform[i] += prev + (nextVertices[i] - prev) * percent; deform[i] += prev + (nextVertices[i] - prev) * percent;
} }
} }
} else if (percent == 0) {
memcpy(deform.buffer(), prevVertices.buffer(), vertexCount * sizeof(float));
} else { } else {
// Vertex positions or deform offsets, no alpha. // Vertex positions or deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
@ -212,7 +215,6 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} else { } else {
switch (blend) { switch (blend) {
case MixBlend_Setup: { case MixBlend_Setup: {
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
@ -238,7 +240,6 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} }
break; break;
case MixBlend_Add: case MixBlend_Add:
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
if (vertexAttachment->getBones().size() == 0) { if (vertexAttachment->getBones().size() == 0) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
@ -253,6 +254,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
break;
} }
} }
} }
@ -261,16 +263,17 @@ void DeformTimeline::setBezier(size_t bezier, size_t frame, float value, float t
float cx2, float cy2, float time2, float value2) { float cx2, float cy2, float time2, float value2) {
SP_UNUSED(value1); SP_UNUSED(value1);
SP_UNUSED(value2); SP_UNUSED(value2);
size_t i = getFrameCount() + bezier * DeformTimeline::BEZIER_SIZE; Vector<float> &curves = _curves;
if (value == 0) _curves[frame] = DeformTimeline::BEZIER + i; size_t i = getFrameCount() + bezier * BEZIER_SIZE;
float tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06; if (value == 0) curves[frame] = BEZIER + (float)i;
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = (cy1 - cy2 + 0.33333333) * 0.018; float tmpx = (time1 - cx1 * 2 + cx2) * 0.03f, tmpy = cy2 * 0.03f - cy1 * 0.06f;
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006f, dddy = (cy1 - cy2 + 0.33333333f) * 0.018f;
float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
float dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667; float dx = (cx1 - time1) * 0.3f + tmpx + dddx * 0.16666667f, dy = cy1 * 0.3f + tmpy + dddy * 0.16666667f;
float x = time1 + dx, y = dy; float x = time1 + dx, y = dy;
for (size_t n = i + DeformTimeline::BEZIER_SIZE; i < n; i += 2) { for (size_t n = i + BEZIER_SIZE; i < n; i += 2) {
_curves[i] = x; curves[i] = x;
_curves[i + 1] = y; curves[i + 1] = y;
dx += ddx; dx += ddx;
dy += ddy; dy += ddy;
ddx += dddx; ddx += dddx;
@ -281,31 +284,30 @@ void DeformTimeline::setBezier(size_t bezier, size_t frame, float value, float t
} }
float DeformTimeline::getCurvePercent(float time, int frame) { float DeformTimeline::getCurvePercent(float time, int frame) {
int i = (int) _curves[frame]; Vector<float> &curves = _curves;
int i = (int)curves[frame];
switch (i) { switch (i) {
case DeformTimeline::LINEAR: { case LINEAR: {
float x = _frames[frame]; float x = _frames[frame];
return (time - x) / (_frames[frame + getFrameEntries()] - x); return (time - x) / (_frames[frame + getFrameEntries()] - x);
} }
case DeformTimeline::STEPPED: { case STEPPED: {
return 0; return 0;
} }
default: {
}
} }
i -= DeformTimeline::BEZIER; i -= BEZIER;
if (_curves[i] > time) { if (curves[i] > time) {
float x = _frames[frame]; float x = _frames[frame];
return _curves[i + 1] * (time - x) / (_curves[i] - x); return curves[i + 1] * (time - x) / (curves[i] - x);
} }
int n = i + DeformTimeline::BEZIER_SIZE; int n = i + BEZIER_SIZE;
for (i += 2; i < n; i += 2) { for (i += 2; i < n; i += 2) {
if (_curves[i] >= time) { if (curves[i] >= time) {
float x = _curves[i - 2], y = _curves[i - 1]; float x = curves[i - 2], y = curves[i - 1];
return y + (time - x) / (_curves[i] - x) * (_curves[i + 1] - y); return y + (time - x) / (curves[i] - x) * (curves[i + 1] - y);
} }
} }
float x = _curves[n - 2], y = _curves[n - 1]; float x = curves[n - 2], y = curves[n - 1];
return y + (1 - y) * (time - x) / (_frames[frame + getFrameEntries()] - x); return y + (1 - y) * (time - x) / (_frames[frame + getFrameEntries()] - x);
} }