mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-25 22:23:42 +08:00
[cpp] More 4.0 porting, all of animation and timelines.
This commit is contained in:
parent
bc20f546cc
commit
7b154fb92f
@ -54,7 +54,15 @@ class SP_API Animation : public SpineObject {
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class ColorTimeline;
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class DeformTimeline;
|
||||
|
||||
|
||||
@ -50,23 +50,24 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit AttachmentTimeline(int frameCount);
|
||||
explicit AttachmentTimeline(size_t frameCount, int slotIndex);
|
||||
|
||||
virtual ~AttachmentTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, const String& attachmentName);
|
||||
void setFrame(int frame, float time, const String& attachmentName);
|
||||
|
||||
size_t getSlotIndex();
|
||||
void setSlotIndex(size_t inValue);
|
||||
Vector<float>& getFrames();
|
||||
Vector<String>& getAttachmentNames();
|
||||
size_t getFrameCount();
|
||||
private:
|
||||
size_t _slotIndex;
|
||||
Vector<float> _frames;
|
||||
|
||||
int getSlotIndex() { return _slotIndex; }
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
Vector<String> _attachmentNames;
|
||||
|
||||
void setAttachment(Skeleton& skeleton, Slot& slot, String* attachmentName);
|
||||
|
||||
@ -63,6 +63,18 @@ class SP_API Bone : public Updatable {
|
||||
|
||||
friend class PointAttachment;
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class ScaleTimeline;
|
||||
|
||||
friend class ScaleXTimeline;
|
||||
@ -71,6 +83,10 @@ class SP_API Bone : public Updatable {
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class ShearXTimeline;
|
||||
|
||||
friend class ShearYTimeline;
|
||||
|
||||
friend class TranslateTimeline;
|
||||
|
||||
friend class TranslateXTimeline;
|
||||
|
||||
@ -52,6 +52,10 @@ class SP_API BoneData : public SpineObject {
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class ShearXTimeline;
|
||||
|
||||
friend class ShearYTimeline;
|
||||
|
||||
friend class TranslateTimeline;
|
||||
|
||||
friend class TranslateXTimeline;
|
||||
|
||||
@ -51,6 +51,14 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &set(float _r, float _g, float _b) {
|
||||
this->r = _r;
|
||||
this->g = _g;
|
||||
this->b = _b;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &set(const Color &other) {
|
||||
r = other.r;
|
||||
g = other.g;
|
||||
@ -69,6 +77,14 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(float _r, float _g, float _b) {
|
||||
this->r += _r;
|
||||
this->g += _g;
|
||||
this->b += _b;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(const Color &other) {
|
||||
r += other.r;
|
||||
g += other.g;
|
||||
|
||||
@ -33,48 +33,165 @@
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API ColorTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
class SP_API RGBATimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
public:
|
||||
explicit RGBATimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
explicit ColorTimeline(int frameCount);
|
||||
virtual ~RGBATimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float a);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float r, float g, float b, float a);
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
int getSlotIndex();
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
void setSlotIndex(int inValue);
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
Vector<float> &getFrames();
|
||||
static const int ENTRIES = 5;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int A = 4;
|
||||
};
|
||||
|
||||
protected:
|
||||
static const int PREV_TIME;
|
||||
static const int PREV_R;
|
||||
static const int PREV_G;
|
||||
static const int PREV_B;
|
||||
static const int PREV_A;
|
||||
static const int R;
|
||||
static const int G;
|
||||
static const int B;
|
||||
static const int A;
|
||||
class SP_API RGBTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
private:
|
||||
int _slotIndex;
|
||||
Vector<float> _frames;
|
||||
};
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGBTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGBTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 4;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
};
|
||||
|
||||
class SP_API AlphaTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit AlphaTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~AlphaTimeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
};
|
||||
|
||||
class SP_API RGBA2Timeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGBA2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGBA2Timeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float a, float r2, float g2, float b2);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 8;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int A = 4;
|
||||
static const int R2 = 5;
|
||||
static const int G2 = 6;
|
||||
static const int B2 = 7;
|
||||
};
|
||||
|
||||
class SP_API RGB2Timeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit RGB2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
|
||||
|
||||
virtual ~RGB2Timeline();
|
||||
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frame, float time, float r, float g, float b, float r2, float g2, float b2);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; };
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
static const int ENTRIES = 7;
|
||||
static const int R = 1;
|
||||
static const int G = 2;
|
||||
static const int B = 3;
|
||||
static const int R2 = 4;
|
||||
static const int G2 = 5;
|
||||
static const int B2 = 6;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ColorTimeline_h */
|
||||
|
||||
@ -72,8 +72,8 @@ namespace spine {
|
||||
|
||||
float getCurveValue(float time);
|
||||
protected:
|
||||
static const int ENTRIES;
|
||||
static const int VALUE;
|
||||
static const int ENTRIES = 2;
|
||||
static const int VALUE = 1;
|
||||
};
|
||||
|
||||
class SP_API CurveTimeline2 : public CurveTimeline {
|
||||
@ -88,9 +88,9 @@ namespace spine {
|
||||
|
||||
float getCurveValue(float time);
|
||||
protected:
|
||||
static const int ENTRIES;
|
||||
static const int VALUE1;
|
||||
static const int VALUE2;
|
||||
static const int ENTRIES = 3;
|
||||
static const int VALUE1 = 1;
|
||||
static const int VALUE2 = 2;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -33,37 +33,47 @@
|
||||
#include <spine/CurveTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class VertexAttachment;
|
||||
class VertexAttachment;
|
||||
|
||||
class SP_API DeformTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
class SP_API DeformTimeline : public CurveTimeline {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
RTTI_DECL
|
||||
friend class SkeletonJson;
|
||||
|
||||
public:
|
||||
explicit DeformTimeline(int frameCount);
|
||||
RTTI_DECL
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
public:
|
||||
explicit DeformTimeline(size_t frameCount, size_t bezierCount, int slotIndex, VertexAttachment *attachment);
|
||||
|
||||
virtual int getPropertyId();
|
||||
virtual void
|
||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||
MixDirection direction);
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, Vector<float>& vertices);
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, Vector<float> &vertices);
|
||||
|
||||
int getSlotIndex();
|
||||
void setSlotIndex(int inValue);
|
||||
Vector<float>& getFrames();
|
||||
Vector< Vector<float> >& getVertices();
|
||||
VertexAttachment* getAttachment();
|
||||
void setAttachment(VertexAttachment* inValue);
|
||||
Vector <Vector<float>> &getVertices();
|
||||
|
||||
private:
|
||||
int _slotIndex;
|
||||
Vector<float> _frames;
|
||||
Vector< Vector<float> > _frameVertices;
|
||||
VertexAttachment* _attachment;
|
||||
};
|
||||
VertexAttachment *getAttachment();
|
||||
|
||||
void setAttachment(VertexAttachment *inValue);
|
||||
|
||||
void setBezier(int bezier, int frame, float value, float time1, float value1, float cx1, float cy1,
|
||||
float cx2, float cy2, float time2, float value2);
|
||||
|
||||
float getCurvePercent(float time, int frame);
|
||||
|
||||
int getSlotIndex() { return _slotIndex; }
|
||||
|
||||
void setSlotIndex(int inValue) { _slotIndex = inValue; }
|
||||
|
||||
protected:
|
||||
int _slotIndex;
|
||||
|
||||
Vector <Vector<float>> _vertices;
|
||||
|
||||
VertexAttachment *_attachment;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_DeformTimeline_h */
|
||||
|
||||
@ -40,22 +40,17 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit DrawOrderTimeline(int frameCount);
|
||||
explicit DrawOrderTimeline(size_t frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
/// @param drawOrder May be NULL to use bind pose draw order
|
||||
void setFrame(size_t frameIndex, float time, Vector<int>& drawOrder);
|
||||
void setFrame(size_t frame, float time, Vector<int>& drawOrder);
|
||||
|
||||
Vector<float>& getFrames();
|
||||
Vector< Vector<int> >& getDrawOrders();
|
||||
size_t getFrameCount();
|
||||
|
||||
private:
|
||||
Vector<float> _frames;
|
||||
Vector< Vector<int> > _drawOrders;
|
||||
};
|
||||
}
|
||||
|
||||
@ -40,23 +40,18 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit EventTimeline(int frameCount);
|
||||
explicit EventTimeline(size_t frameCount);
|
||||
|
||||
~EventTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(size_t frameIndex, Event* event);
|
||||
void setFrame(size_t frame, Event* event);
|
||||
|
||||
Vector<float> getFrames();
|
||||
Vector<Event*>& getEvents();
|
||||
size_t getFrameCount();
|
||||
|
||||
private:
|
||||
Vector<float> _frames;
|
||||
Vector<Event*> _events;
|
||||
};
|
||||
}
|
||||
|
||||
@ -41,32 +41,25 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
explicit IkConstraintTimeline(int frameCount);
|
||||
explicit IkConstraintTimeline(size_t frameCount, size_t bezierCount, int ikConstraintIndex);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time, mix and bend direction of the specified keyframe.
|
||||
void setFrame (int frameIndex, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
|
||||
void setFrame (int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
|
||||
|
||||
int getIkConstraintIndex() { return _ikConstraintIndex; }
|
||||
|
||||
void setIkConstraintIndex(int inValue) { _ikConstraintIndex = inValue; }
|
||||
private:
|
||||
static const int PREV_TIME;
|
||||
static const int PREV_MIX;
|
||||
static const int PREV_SOFTNESS;
|
||||
static const int PREV_BEND_DIRECTION;
|
||||
static const int PREV_COMPRESS;
|
||||
static const int PREV_STRETCH;
|
||||
static const int MIX;
|
||||
static const int SOFTNESS;
|
||||
static const int BEND_DIRECTION;
|
||||
static const int COMPRESS;
|
||||
static const int STRETCH;
|
||||
int _ikConstraintIndex;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _ikConstraintIndex;
|
||||
static const int ENTRIES = 6;
|
||||
static const int MIX = 1;
|
||||
static const int SOFTNESS = 2;
|
||||
static const int BEND_DIRECTION = 3;
|
||||
static const int COMPRESS = 4;
|
||||
static const int STRETCH = 5;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -42,26 +42,23 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
explicit PathConstraintMixTimeline(int frameCount);
|
||||
explicit PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
/// Sets the time and mixes of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float mixRotate, float mixX, float mixY);
|
||||
|
||||
int getPathConstraintIndex() { return _pathConstraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; }
|
||||
private:
|
||||
static const int PREV_TIME;
|
||||
static const int PREV_ROTATE;
|
||||
static const int PREV_TRANSLATE;
|
||||
static const int ROTATE;
|
||||
static const int TRANSLATE;
|
||||
int _pathConstraintIndex;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _pathConstraintIndex;
|
||||
|
||||
/// Sets the time and mixes of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float rotateMix, float translateMix);
|
||||
static const int ENTRIES = 4;
|
||||
static const int ROTATE = 1;
|
||||
static const int X = 2;
|
||||
static const int Y = 2;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API PathConstraintPositionTimeline : public CurveTimeline {
|
||||
class SP_API PathConstraintPositionTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
@ -43,23 +43,16 @@ namespace spine {
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
explicit PathConstraintPositionTimeline(int frameCount);
|
||||
explicit PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual ~PathConstraintPositionTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float value);
|
||||
int getPathConstraintIndex() { return _pathConstraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; }
|
||||
protected:
|
||||
static const int PREV_TIME;
|
||||
static const int PREV_VALUE;
|
||||
static const int VALUE;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _pathConstraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
@ -33,18 +33,22 @@
|
||||
#include <spine/PathConstraintPositionTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API PathConstraintSpacingTimeline : public PathConstraintPositionTimeline {
|
||||
class SP_API PathConstraintSpacingTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit PathConstraintSpacingTimeline(int frameCount);
|
||||
explicit PathConstraintSpacingTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
int getPathConstraintIndex() { return _pathConstraintIndex; }
|
||||
|
||||
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; }
|
||||
protected:
|
||||
int _pathConstraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ enum Property {
|
||||
Property_TransformConstraint = 1 << 15,
|
||||
Property_PathConstraintPosition = 1 << 16,
|
||||
Property_PathConstraintSpacing = 1 << 17,
|
||||
Property_OathConstraintMix = 1 << 18
|
||||
Property_PathConstraintMix = 1 << 18
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -33,19 +33,65 @@
|
||||
#include <spine/TranslateTimeline.h>
|
||||
|
||||
namespace spine {
|
||||
class SP_API ShearTimeline : public TranslateTimeline {
|
||||
class SP_API ShearTimeline : public CurveTimeline2 {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ShearTimeline(int frameCount);
|
||||
explicit ShearTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ShearTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
|
||||
class SP_API ShearXTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ShearXTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ShearXTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
|
||||
class SP_API ShearYTimeline : public CurveTimeline1 {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
explicit ShearYTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
|
||||
|
||||
virtual ~ShearYTimeline();
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
int getBoneIndex() { return _boneIndex; }
|
||||
|
||||
void setBoneIndex(int inValue) { _boneIndex = inValue; }
|
||||
private:
|
||||
int _boneIndex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_ShearTimeline_h */
|
||||
|
||||
@ -64,7 +64,15 @@ class SP_API Skeleton : public SpineObject {
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class ColorTimeline;
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class DeformTimeline;
|
||||
|
||||
@ -88,6 +96,10 @@ class SP_API Skeleton : public SpineObject {
|
||||
|
||||
friend class ShearTimeline;
|
||||
|
||||
friend class ShearXTimeline;
|
||||
|
||||
friend class ShearYTimeline;
|
||||
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
friend class RotateTimeline;
|
||||
|
||||
@ -54,7 +54,15 @@ class SP_API Slot : public SpineObject {
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class ColorTimeline;
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class DeformTimeline;
|
||||
|
||||
|
||||
@ -45,7 +45,15 @@ class SP_API SlotData : public SpineObject {
|
||||
|
||||
friend class AttachmentTimeline;
|
||||
|
||||
friend class ColorTimeline;
|
||||
friend class RGBATimeline;
|
||||
|
||||
friend class RGBTimeline;
|
||||
|
||||
friend class AlphaTimeline;
|
||||
|
||||
friend class RGBA2Timeline;
|
||||
|
||||
friend class RGB2Timeline;
|
||||
|
||||
friend class DeformTimeline;
|
||||
|
||||
|
||||
@ -41,29 +41,27 @@ namespace spine {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
explicit TransformConstraintTimeline(int frameCount);
|
||||
explicit TransformConstraintTimeline(size_t frameCount, size_t bezierCount, int transformConstraintIndex);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
void setFrame(size_t frameIndex, float time, float mixRotate, float mixX, float mixY, float mixScaleX, float mixScaleY, float mixShearY);
|
||||
|
||||
void setFrame(size_t frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
|
||||
int getTransformConstraintIndex() { return _transformConstraintIndex; }
|
||||
|
||||
private:
|
||||
static const int PREV_TIME;
|
||||
static const int PREV_ROTATE;
|
||||
static const int PREV_TRANSLATE;
|
||||
static const int PREV_SCALE;
|
||||
static const int PREV_SHEAR;
|
||||
static const int ROTATE;
|
||||
static const int TRANSLATE;
|
||||
static const int SCALE;
|
||||
static const int SHEAR;
|
||||
void setTransformConstraintIndex(int inValue) { _transformConstraintIndex = inValue; }
|
||||
private:
|
||||
int _transformConstraintIndex;
|
||||
|
||||
static const int ENTRIES = 7;
|
||||
static const int ROTATE = 1;
|
||||
static const int X = 2;
|
||||
static const int Y = 3;
|
||||
static const int SCALEX = 4;
|
||||
static const int SCALEY = 5;
|
||||
static const int SHEARY = 6;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _transformConstraintIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -46,13 +46,12 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(AttachmentTimeline, Timeline)
|
||||
|
||||
AttachmentTimeline::AttachmentTimeline(int frameCount) : Timeline(), _slotIndex(0) {
|
||||
_frames.ensureCapacity(frameCount);
|
||||
AttachmentTimeline::AttachmentTimeline(size_t frameCount, int slotIndex) : Timeline(frameCount, 1), _slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Attachment << 32) | slotIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
|
||||
_attachmentNames.ensureCapacity(frameCount);
|
||||
|
||||
_frames.setSize(frameCount, 0);
|
||||
|
||||
for (int i = 0; i < frameCount; ++i) {
|
||||
for (size_t i = 0; i < frameCount; ++i) {
|
||||
_attachmentNames.add(String());
|
||||
}
|
||||
}
|
||||
@ -68,63 +67,37 @@ void AttachmentTimeline::apply(Skeleton &skeleton, float lastTime, float time, V
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(alpha);
|
||||
|
||||
assert(_slotIndex < skeleton._slots.size());
|
||||
|
||||
String *attachmentName;
|
||||
Slot *slotP = skeleton._slots[_slotIndex];
|
||||
Slot &slot = *slotP;
|
||||
if (!slot._bone.isActive()) return;
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
if (direction == MixDirection_Out) {
|
||||
if (blend == MixBlend_Setup) setAttachment(skeleton, slot, &slot._data._attachmentName);
|
||||
if (blend == MixBlend_Setup) setAttachment(skeleton, *slot, &slot->_data._attachmentName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < _frames[0]) {
|
||||
// Time is before first frame.
|
||||
if (blend == MixBlend_Setup || blend == MixBlend_First) {
|
||||
setAttachment(skeleton, slot, &slot._data._attachmentName);
|
||||
setAttachment(skeleton, *slot, &slot->_data._attachmentName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
size_t frameIndex;
|
||||
if (time >= _frames[_frames.size() - 1]) {
|
||||
// Time is after last frame.
|
||||
frameIndex = _frames.size() - 1;
|
||||
} else {
|
||||
frameIndex = Animation::binarySearch(_frames, time, 1) - 1;
|
||||
}
|
||||
if (time < _frames[0]) {
|
||||
if (blend == MixBlend_Setup || blend == MixBlend_First) setAttachment(skeleton, *slot, &slot->_data._attachmentName);
|
||||
return;
|
||||
}
|
||||
|
||||
attachmentName = &_attachmentNames[frameIndex];
|
||||
slot.setAttachment(attachmentName->length() == 0 ? NULL : skeleton.getAttachment(_slotIndex, *attachmentName));
|
||||
setAttachment(skeleton, *slot, &_attachmentNames[Animation::search(_frames, time)]);
|
||||
}
|
||||
|
||||
int AttachmentTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_Attachment << 24) + _slotIndex;
|
||||
}
|
||||
|
||||
void AttachmentTimeline::setFrame(int frameIndex, float time, const String &attachmentName) {
|
||||
_frames[frameIndex] = time;
|
||||
_attachmentNames[frameIndex] = attachmentName;
|
||||
}
|
||||
|
||||
size_t AttachmentTimeline::getSlotIndex() {
|
||||
return _slotIndex;
|
||||
}
|
||||
|
||||
void AttachmentTimeline::setSlotIndex(size_t inValue) {
|
||||
_slotIndex = inValue;
|
||||
}
|
||||
|
||||
Vector<float> &AttachmentTimeline::getFrames() {
|
||||
return _frames;
|
||||
void AttachmentTimeline::setFrame(int frame, float time, const String &attachmentName) {
|
||||
_frames[frame] = time;
|
||||
_attachmentNames[frame] = attachmentName;
|
||||
}
|
||||
|
||||
Vector<String> &AttachmentTimeline::getAttachmentNames() {
|
||||
return _attachmentNames;
|
||||
}
|
||||
|
||||
size_t AttachmentTimeline::getFrameCount() {
|
||||
return _frames.size();
|
||||
}
|
||||
|
||||
@ -44,102 +44,461 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL(ColorTimeline, CurveTimeline)
|
||||
RTTI_IMPL(RGBATimeline, CurveTimeline)
|
||||
|
||||
const int ColorTimeline::ENTRIES = 5;
|
||||
const int ColorTimeline::PREV_TIME = -5;
|
||||
const int ColorTimeline::PREV_R = -4;
|
||||
const int ColorTimeline::PREV_G = -3;
|
||||
const int ColorTimeline::PREV_B = -2;
|
||||
const int ColorTimeline::PREV_A = -1;
|
||||
const int ColorTimeline::R = 1;
|
||||
const int ColorTimeline::G = 2;
|
||||
const int ColorTimeline::B = 3;
|
||||
const int ColorTimeline::A = 4;
|
||||
|
||||
ColorTimeline::ColorTimeline(int frameCount) : CurveTimeline(frameCount), _slotIndex(0) {
|
||||
_frames.setSize(frameCount * ENTRIES, 0);
|
||||
RGBATimeline::RGBATimeline(size_t frameCount, size_t bezierCount, int slotIndex) : CurveTimeline(frameCount,
|
||||
RGBATimeline::ENTRIES,
|
||||
bezierCount),
|
||||
_slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Rgb << 32) | slotIndex,
|
||||
((PropertyId) Property_Alpha << 32) | slotIndex};
|
||||
setPropertyIds(ids, 2);
|
||||
}
|
||||
|
||||
void ColorTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
RGBATimeline::~RGBATimeline() {
|
||||
}
|
||||
|
||||
void RGBATimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slotP = skeleton._slots[_slotIndex];
|
||||
Slot &slot = *slotP;
|
||||
if (!slot._bone.isActive()) return;
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
slot._color.set(slot._data._color);
|
||||
return;
|
||||
case MixBlend_First: {
|
||||
Color &color = slot._color, setup = slot._data._color;
|
||||
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
|
||||
(setup.a - color.a) * alpha);
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
float r, g, b, a;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
size_t i = _frames.size();
|
||||
r = _frames[i + PREV_R];
|
||||
g = _frames[i + PREV_G];
|
||||
b = _frames[i + PREV_B];
|
||||
a = _frames[i + PREV_A];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
size_t frame = (size_t)Animation::binarySearch(_frames, time, ENTRIES);
|
||||
r = _frames[frame + PREV_R];
|
||||
g = _frames[frame + PREV_G];
|
||||
b = _frames[frame + PREV_B];
|
||||
a = _frames[frame + PREV_A];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
if (time < _frames[0]) {
|
||||
Color &color = slot->_color, &setup = slot->_data._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.set(setup);
|
||||
return;
|
||||
case MixBlend_First:
|
||||
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
|
||||
(setup.a - color.a) * alpha);
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
r += (_frames[frame + R] - r) * percent;
|
||||
g += (_frames[frame + G] - g) * percent;
|
||||
b += (_frames[frame + B] - b) * percent;
|
||||
a += (_frames[frame + A] - a) * percent;
|
||||
}
|
||||
|
||||
if (alpha == 1) {
|
||||
slot.getColor().set(r, g, b, a);
|
||||
} else {
|
||||
Color &color = slot.getColor();
|
||||
if (blend == MixBlend_Setup) color.set(slot.getData().getColor());
|
||||
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
|
||||
}
|
||||
float r = 0, g = 0, b = 0, a = 0;
|
||||
int i = Animation::search(_frames, time, RGBATimeline::ENTRIES);
|
||||
int curveType = (int) _curves[i / RGBATimeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case RGBATimeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
r = _frames[i + RGBATimeline::R];
|
||||
g = _frames[i + RGBATimeline::G];
|
||||
b = _frames[i + RGBATimeline::B];
|
||||
a = _frames[i + RGBATimeline::A];
|
||||
float t = (time - before) / (_frames[i + RGBATimeline::ENTRIES] - before);
|
||||
r += (_frames[i + RGBATimeline::ENTRIES + RGBATimeline::R] - r) * t;
|
||||
g += (_frames[i + RGBATimeline::ENTRIES + RGBATimeline::G] - g) * t;
|
||||
b += (_frames[i + RGBATimeline::ENTRIES + RGBATimeline::B] - b) * t;
|
||||
a += (_frames[i + RGBATimeline::ENTRIES + RGBATimeline::A] - a) * t;
|
||||
break;
|
||||
}
|
||||
case RGBATimeline::STEPPED: {
|
||||
r = _frames[i + RGBATimeline::R];
|
||||
g = _frames[i + RGBATimeline::G];
|
||||
b = _frames[i + RGBATimeline::B];
|
||||
a = _frames[i + RGBATimeline::A];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
r = getBezierValue(time, i, RGBATimeline::R, curveType - RGBATimeline::BEZIER);
|
||||
g = getBezierValue(time, i, RGBATimeline::G,
|
||||
curveType + RGBATimeline::BEZIER_SIZE - RGBATimeline::BEZIER);
|
||||
b = getBezierValue(time, i, RGBATimeline::B,
|
||||
curveType + RGBATimeline::BEZIER_SIZE * 2 - RGBATimeline::BEZIER);
|
||||
a = getBezierValue(time, i, RGBATimeline::A,
|
||||
curveType + RGBATimeline::BEZIER_SIZE * 3 - RGBATimeline::BEZIER);
|
||||
}
|
||||
}
|
||||
Color &color = slot->_color;
|
||||
if (alpha == 1)
|
||||
color.set(r, g, b, a);
|
||||
else {
|
||||
if (blend == MixBlend_Setup) color.set(slot->_data._color);
|
||||
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
int ColorTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_Color << 24) + _slotIndex;
|
||||
void RGBATimeline::setFrame(int frame, float time, float r, float g, float b, float a) {
|
||||
frame *= ENTRIES;
|
||||
_frames[frame] = time;
|
||||
_frames[frame + R] = r;
|
||||
_frames[frame + G] = g;
|
||||
_frames[frame + B] = b;
|
||||
_frames[frame + A] = a;
|
||||
}
|
||||
|
||||
void ColorTimeline::setFrame(int frameIndex, float time, float r, float g, float b, float a) {
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + R] = r;
|
||||
_frames[frameIndex + G] = g;
|
||||
_frames[frameIndex + B] = b;
|
||||
_frames[frameIndex + A] = a;
|
||||
RTTI_IMPL(RGBTimeline, CurveTimeline)
|
||||
|
||||
RGBTimeline::RGBTimeline(size_t frameCount, size_t bezierCount, int slotIndex) : CurveTimeline(frameCount,
|
||||
RGBTimeline::ENTRIES,
|
||||
bezierCount),
|
||||
_slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Rgb << 32) | slotIndex};
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
int ColorTimeline::getSlotIndex() {
|
||||
return _slotIndex;
|
||||
RGBTimeline::~RGBTimeline() {
|
||||
}
|
||||
|
||||
void ColorTimeline::setSlotIndex(int inValue) {
|
||||
_slotIndex = inValue;
|
||||
void RGBTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
Color &color = slot->_color, &setup = slot->_data._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.set(setup);
|
||||
return;
|
||||
case MixBlend_First:
|
||||
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
|
||||
(setup.a - color.a) * alpha);
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float r = 0, g = 0, b = 0;
|
||||
int i = Animation::search(_frames, time, RGBTimeline::ENTRIES);
|
||||
int curveType = (int) _curves[i / RGBTimeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case RGBTimeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
r = _frames[i + RGBTimeline::R];
|
||||
g = _frames[i + RGBTimeline::G];
|
||||
b = _frames[i + RGBTimeline::B];
|
||||
float t = (time - before) / (_frames[i + RGBTimeline::ENTRIES] - before);
|
||||
r += (_frames[i + RGBTimeline::ENTRIES + RGBTimeline::R] - r) * t;
|
||||
g += (_frames[i + RGBTimeline::ENTRIES + RGBTimeline::G] - g) * t;
|
||||
b += (_frames[i + RGBTimeline::ENTRIES + RGBTimeline::B] - b) * t;
|
||||
break;
|
||||
}
|
||||
case RGBTimeline::STEPPED: {
|
||||
r = _frames[i + RGBTimeline::R];
|
||||
g = _frames[i + RGBTimeline::G];
|
||||
b = _frames[i + RGBTimeline::B];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
r = getBezierValue(time, i, RGBTimeline::R, curveType - RGBTimeline::BEZIER);
|
||||
g = getBezierValue(time, i, RGBTimeline::G,
|
||||
curveType + RGBTimeline::BEZIER_SIZE - RGBTimeline::BEZIER);
|
||||
b = getBezierValue(time, i, RGBTimeline::B,
|
||||
curveType + RGBTimeline::BEZIER_SIZE * 2 - RGBTimeline::BEZIER);
|
||||
}
|
||||
}
|
||||
Color &color = slot->_color;
|
||||
if (alpha == 1)
|
||||
color.set(r, g, b);
|
||||
else {
|
||||
Color &setup = slot->_data._color;
|
||||
if (blend == MixBlend_Setup) color.set(setup.r, setup.g, setup.b);
|
||||
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<float> &ColorTimeline::getFrames() {
|
||||
return _frames;
|
||||
void RGBTimeline::setFrame(int frame, float time, float r, float g, float b) {
|
||||
frame *= ENTRIES;
|
||||
_frames[frame] = time;
|
||||
_frames[frame + R] = r;
|
||||
_frames[frame + G] = g;
|
||||
_frames[frame + B] = b;
|
||||
}
|
||||
|
||||
RTTI_IMPL(AlphaTimeline, CurveTimeline1)
|
||||
|
||||
AlphaTimeline::AlphaTimeline(size_t frameCount, size_t bezierCount, int slotIndex) : CurveTimeline1(frameCount,
|
||||
bezierCount),
|
||||
_slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Alpha << 32) | slotIndex};
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
AlphaTimeline::~AlphaTimeline() {
|
||||
}
|
||||
|
||||
void AlphaTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
if (time < _frames[0]) { // Time is before first frame.
|
||||
Color &color = slot->_color, &setup = slot->_data._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.a = setup.a;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
color.a += (setup.a - color.a) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float a = getCurveValue(time);
|
||||
if (alpha == 1)
|
||||
slot->_color.a = a;
|
||||
else {
|
||||
if (blend == MixBlend_Setup) slot->_color.a = slot->_data._color.a;
|
||||
slot->_color.a += (a - slot->_color.a) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(RGBA2Timeline, CurveTimeline)
|
||||
|
||||
RGBA2Timeline::RGBA2Timeline(size_t frameCount, size_t bezierCount, int slotIndex) : CurveTimeline(frameCount,
|
||||
RGBA2Timeline::ENTRIES,
|
||||
bezierCount),
|
||||
_slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Rgb << 32) | slotIndex,
|
||||
((PropertyId) Property_Alpha << 32) | slotIndex,
|
||||
((PropertyId) Property_Rgb2 << 32) | slotIndex};
|
||||
setPropertyIds(ids, 3);
|
||||
}
|
||||
|
||||
RGBA2Timeline::~RGBA2Timeline() {
|
||||
}
|
||||
|
||||
void RGBA2Timeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
Color &light = slot->_color, &dark = slot->_darkColor, &setupLight = slot->_data._color, &setupDark = slot->_data._darkColor;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
light.set(setupLight);
|
||||
dark.set(setupDark.r, setupDark.g, setupDark.b);
|
||||
return;
|
||||
case MixBlend_First:
|
||||
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha,
|
||||
(setupLight.b - light.b) * alpha,
|
||||
(setupLight.a - light.a) * alpha);
|
||||
dark.r += (setupDark.r - dark.r) * alpha;
|
||||
dark.g += (setupDark.g - dark.g) * alpha;
|
||||
dark.b += (setupDark.b - dark.b) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
|
||||
int i = Animation::search(_frames, time, RGBA2Timeline::ENTRIES);
|
||||
int curveType = (int) _curves[i / RGBA2Timeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case RGBA2Timeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
r = _frames[i + RGBA2Timeline::R];
|
||||
g = _frames[i + RGBA2Timeline::G];
|
||||
b = _frames[i + RGBA2Timeline::B];
|
||||
a = _frames[i + RGBA2Timeline::A];
|
||||
r2 = _frames[i + RGBA2Timeline::R2];
|
||||
g2 = _frames[i + RGBA2Timeline::G2];
|
||||
b2 = _frames[i + RGBA2Timeline::B2];
|
||||
float t = (time - before) / (_frames[i + RGBA2Timeline::ENTRIES] - before);
|
||||
r += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::R] - r) * t;
|
||||
g += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::G] - g) * t;
|
||||
b += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::B] - b) * t;
|
||||
a += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::A] - a) * t;
|
||||
r2 += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::R2] - r2) * t;
|
||||
g2 += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::G2] - g2) * t;
|
||||
b2 += (_frames[i + RGBA2Timeline::ENTRIES + RGBA2Timeline::B2] - b2) * t;
|
||||
break;
|
||||
}
|
||||
case RGBA2Timeline::STEPPED: {
|
||||
r = _frames[i + RGBA2Timeline::R];
|
||||
g = _frames[i + RGBA2Timeline::G];
|
||||
b = _frames[i + RGBA2Timeline::B];
|
||||
a = _frames[i + RGBA2Timeline::A];
|
||||
r2 = _frames[i + RGBA2Timeline::R2];
|
||||
g2 = _frames[i + RGBA2Timeline::G2];
|
||||
b2 = _frames[i + RGBA2Timeline::B2];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
r = getBezierValue(time, i, RGBA2Timeline::R, curveType - RGBA2Timeline::BEZIER);
|
||||
g = getBezierValue(time, i, RGBA2Timeline::G,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE - RGBA2Timeline::BEZIER);
|
||||
b = getBezierValue(time, i, RGBA2Timeline::B,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE * 2 - RGBA2Timeline::BEZIER);
|
||||
a = getBezierValue(time, i, RGBA2Timeline::A,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE * 3 - RGBA2Timeline::BEZIER);
|
||||
r2 = getBezierValue(time, i, RGBA2Timeline::R2,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE * 4 - RGBA2Timeline::BEZIER);
|
||||
g2 = getBezierValue(time, i, RGBA2Timeline::G2,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE * 5 - RGBA2Timeline::BEZIER);
|
||||
b2 = getBezierValue(time, i, RGBA2Timeline::B2,
|
||||
curveType + RGBA2Timeline::BEZIER_SIZE * 6 - RGBA2Timeline::BEZIER);
|
||||
}
|
||||
}
|
||||
Color &light = slot->_color, &dark = slot->_darkColor;
|
||||
if (alpha == 1) {
|
||||
light.set(r, g, b, a);
|
||||
dark.set(r2, g2, b2);
|
||||
} else {
|
||||
if (blend == MixBlend_Setup) {
|
||||
light.set(slot->_data._color);
|
||||
dark.set(slot->_data._darkColor);
|
||||
}
|
||||
light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
|
||||
dark.r += (r2 - dark.r) * alpha;
|
||||
dark.g += (g2 - dark.g) * alpha;
|
||||
dark.b += (b2 - dark.b) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RGBA2Timeline::setFrame(int frame, float time, float r, float g, float b, float a, float r2, float g2, float b2) {
|
||||
frame *= ENTRIES;
|
||||
_frames[frame] = time;
|
||||
_frames[frame + R] = r;
|
||||
_frames[frame + G] = g;
|
||||
_frames[frame + B] = b;
|
||||
_frames[frame + A] = a;
|
||||
_frames[frame + R2] = r2;
|
||||
_frames[frame + G2] = g2;
|
||||
_frames[frame + B2] = b2;
|
||||
}
|
||||
|
||||
RTTI_IMPL(RGB2Timeline, CurveTimeline)
|
||||
|
||||
RGB2Timeline::RGB2Timeline(size_t frameCount, size_t bezierCount, int slotIndex) : CurveTimeline(frameCount,
|
||||
RGB2Timeline::ENTRIES,
|
||||
bezierCount),
|
||||
_slotIndex(slotIndex) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Rgb << 32) | slotIndex,
|
||||
((PropertyId) Property_Rgb2 << 32) | slotIndex};
|
||||
setPropertyIds(ids, 2);
|
||||
}
|
||||
|
||||
RGB2Timeline::~RGB2Timeline() {
|
||||
}
|
||||
|
||||
void RGB2Timeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
Color &light = slot->_color, &dark = slot->_darkColor, &setupLight = slot->_data._color, &setupDark = slot->_data._darkColor;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
light.set(setupLight.r, setupLight.g, setupLight.b);
|
||||
dark.set(setupDark.r, setupDark.g, setupDark.b);
|
||||
return;
|
||||
case MixBlend_First:
|
||||
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha,
|
||||
(setupLight.b - light.b) * alpha);
|
||||
dark.r += (setupDark.r - dark.r) * alpha;
|
||||
dark.g += (setupDark.g - dark.g) * alpha;
|
||||
dark.b += (setupDark.b - dark.b) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float r = 0, g = 0, b = 0, r2 = 0, g2 = 0, b2 = 0;
|
||||
int i = Animation::search(_frames, time, RGB2Timeline::ENTRIES);
|
||||
int curveType = (int) _curves[i / RGB2Timeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case RGB2Timeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
r = _frames[i + RGB2Timeline::R];
|
||||
g = _frames[i + RGB2Timeline::G];
|
||||
b = _frames[i + RGB2Timeline::B];
|
||||
r2 = _frames[i + RGB2Timeline::R2];
|
||||
g2 = _frames[i + RGB2Timeline::G2];
|
||||
b2 = _frames[i + RGB2Timeline::B2];
|
||||
float t = (time - before) / (_frames[i + RGB2Timeline::ENTRIES] - before);
|
||||
r += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::R] - r) * t;
|
||||
g += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::G] - g) * t;
|
||||
b += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::B] - b) * t;
|
||||
r2 += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::R2] - r2) * t;
|
||||
g2 += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::G2] - g2) * t;
|
||||
b2 += (_frames[i + RGB2Timeline::ENTRIES + RGB2Timeline::B2] - b2) * t;
|
||||
break;
|
||||
}
|
||||
case RGB2Timeline::STEPPED: {
|
||||
r = _frames[i + RGB2Timeline::R];
|
||||
g = _frames[i + RGB2Timeline::G];
|
||||
b = _frames[i + RGB2Timeline::B];
|
||||
r2 = _frames[i + RGB2Timeline::R2];
|
||||
g2 = _frames[i + RGB2Timeline::G2];
|
||||
b2 = _frames[i + RGB2Timeline::B2];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
r = getBezierValue(time, i, RGB2Timeline::R, curveType - RGB2Timeline::BEZIER);
|
||||
g = getBezierValue(time, i, RGB2Timeline::G,
|
||||
curveType + RGB2Timeline::BEZIER_SIZE - RGB2Timeline::BEZIER);
|
||||
b = getBezierValue(time, i, RGB2Timeline::B,
|
||||
curveType + RGB2Timeline::BEZIER_SIZE * 2 - RGB2Timeline::BEZIER);
|
||||
r2 = getBezierValue(time, i, RGB2Timeline::R2,
|
||||
curveType + RGB2Timeline::BEZIER_SIZE * 4 - RGB2Timeline::BEZIER);
|
||||
g2 = getBezierValue(time, i, RGB2Timeline::G2,
|
||||
curveType + RGB2Timeline::BEZIER_SIZE * 5 - RGB2Timeline::BEZIER);
|
||||
b2 = getBezierValue(time, i, RGB2Timeline::B2,
|
||||
curveType + RGB2Timeline::BEZIER_SIZE * 6 - RGB2Timeline::BEZIER);
|
||||
}
|
||||
}
|
||||
Color &light = slot->_color, &dark = slot->_darkColor;
|
||||
if (alpha == 1) {
|
||||
light.set(r, g, b);
|
||||
dark.set(r2, g2, b2);
|
||||
} else {
|
||||
if (blend == MixBlend_Setup) {
|
||||
light.set(slot->_data._color.r, slot->_data._color.g, slot->_data._color.b);
|
||||
dark.set(slot->_data._darkColor);
|
||||
}
|
||||
light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha);
|
||||
dark.r += (r2 - dark.r) * alpha;
|
||||
dark.g += (g2 - dark.g) * alpha;
|
||||
dark.b += (b2 - dark.b) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RGB2Timeline::setFrame(int frame, float time, float r, float g, float b, float r2, float g2, float b2) {
|
||||
frame *= ENTRIES;
|
||||
_frames[frame] = time;
|
||||
_frames[frame + R] = r;
|
||||
_frames[frame + G] = g;
|
||||
_frames[frame + B] = b;
|
||||
_frames[frame + R2] = r2;
|
||||
_frames[frame + G2] = g2;
|
||||
_frames[frame + B2] = b2;
|
||||
}
|
||||
|
||||
@ -93,8 +93,7 @@ float CurveTimeline::getBezierValue(float time, size_t frame, size_t valueOffset
|
||||
}
|
||||
|
||||
RTTI_IMPL(CurveTimeline1, CurveTimeline)
|
||||
const int CurveTimeline1::ENTRIES = 2;
|
||||
const int CurveTimeline1::VALUE = 1;
|
||||
|
||||
|
||||
CurveTimeline1::CurveTimeline1(size_t frameCount, size_t bezierCount): CurveTimeline(frameCount, CurveTimeline1::ENTRIES, bezierCount) {
|
||||
}
|
||||
@ -131,9 +130,6 @@ float CurveTimeline1::getCurveValue(float time) {
|
||||
}
|
||||
|
||||
RTTI_IMPL(CurveTimeline2, CurveTimeline)
|
||||
const int CurveTimeline2::ENTRIES = 3;
|
||||
const int CurveTimeline2::VALUE1 = 1;
|
||||
const int CurveTimeline2::VALUE2 = 2;
|
||||
|
||||
CurveTimeline2::CurveTimeline2(size_t frameCount, size_t bezierCount): CurveTimeline(frameCount, CurveTimeline2::ENTRIES, bezierCount) {
|
||||
}
|
||||
|
||||
@ -48,251 +48,284 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(DeformTimeline, CurveTimeline)
|
||||
|
||||
DeformTimeline::DeformTimeline(int frameCount) : CurveTimeline(frameCount), _slotIndex(0), _attachment(NULL) {
|
||||
_frames.ensureCapacity(frameCount);
|
||||
_frameVertices.ensureCapacity(frameCount);
|
||||
DeformTimeline::DeformTimeline(size_t frameCount, size_t bezierCount, int slotIndex, VertexAttachment *attachment)
|
||||
: CurveTimeline(frameCount, 1, bezierCount), _slotIndex(slotIndex), _attachment(attachment) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Deform << 32) | ((slotIndex << 16 | attachment->_id) & 0xffffffff)};
|
||||
setPropertyIds(ids, 1);
|
||||
|
||||
_frames.setSize(frameCount, 0);
|
||||
|
||||
for (int i = 0; i < frameCount; ++i) {
|
||||
Vector<float> vec;
|
||||
_frameVertices.add(vec);
|
||||
}
|
||||
_vertices.ensureCapacity(frameCount);
|
||||
for (size_t i = 0; i < frameCount; ++i) {
|
||||
Vector<float> vec;
|
||||
_vertices.add(vec);
|
||||
}
|
||||
}
|
||||
|
||||
void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Slot *slotP = skeleton._slots[_slotIndex];
|
||||
Slot &slot = *slotP;
|
||||
if (!slot._bone.isActive()) return;
|
||||
Slot *slotP = skeleton._slots[_slotIndex];
|
||||
Slot &slot = *slotP;
|
||||
if (!slot._bone.isActive()) return;
|
||||
|
||||
Attachment *slotAttachment = slot.getAttachment();
|
||||
if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
Attachment *slotAttachment = slot.getAttachment();
|
||||
if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
|
||||
VertexAttachment *attachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (attachment->_deformAttachment != _attachment) {
|
||||
return;
|
||||
}
|
||||
VertexAttachment *attachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (attachment->_deformAttachment != _attachment) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<float> &deformArray = slot._deform;
|
||||
if (deformArray.size() == 0) {
|
||||
blend = MixBlend_Setup;
|
||||
}
|
||||
Vector<float> &deformArray = slot._deform;
|
||||
if (deformArray.size() == 0) {
|
||||
blend = MixBlend_Setup;
|
||||
}
|
||||
|
||||
Vector< Vector<float> > &frameVertices = _frameVertices;
|
||||
size_t vertexCount = frameVertices[0].size();
|
||||
Vector<Vector<float> > &vertices = _vertices;
|
||||
size_t vertexCount = vertices[0].size();
|
||||
|
||||
Vector<float> &frames = _frames;
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
deformArray.clear();
|
||||
return;
|
||||
case MixBlend_First: {
|
||||
if (alpha == 1) {
|
||||
deformArray.clear();
|
||||
return;
|
||||
}
|
||||
deformArray.setSize(vertexCount, 0);
|
||||
Vector<float> &deformInner = deformArray;
|
||||
if (attachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions.
|
||||
Vector<float> &setupVertices = attachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deformInner[i] += (setupVertices[i] - deformInner[i]) * alpha;
|
||||
} else {
|
||||
// Weighted deform offsets.
|
||||
alpha = 1 - alpha;
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deformInner[i] *= alpha;
|
||||
}
|
||||
}
|
||||
case MixBlend_Replace:
|
||||
case MixBlend_Add:
|
||||
return;
|
||||
}
|
||||
}
|
||||
Vector<float> &frames = _frames;
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
deformArray.clear();
|
||||
return;
|
||||
case MixBlend_First: {
|
||||
if (alpha == 1) {
|
||||
deformArray.clear();
|
||||
return;
|
||||
}
|
||||
deformArray.setSize(vertexCount, 0);
|
||||
Vector<float> &deformInner = deformArray;
|
||||
if (attachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions.
|
||||
Vector<float> &setupVertices = attachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deformInner[i] += (setupVertices[i] - deformInner[i]) * alpha;
|
||||
} else {
|
||||
// Weighted deform offsets.
|
||||
alpha = 1 - alpha;
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deformInner[i] *= alpha;
|
||||
}
|
||||
}
|
||||
case MixBlend_Replace:
|
||||
case MixBlend_Add:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
deformArray.setSize(vertexCount, 0);
|
||||
Vector<float> &deform = deformArray;
|
||||
deformArray.setSize(vertexCount, 0);
|
||||
Vector<float> &deform = deformArray;
|
||||
|
||||
if (time >= frames[frames.size() - 1]) { // Time is after last frame.
|
||||
Vector<float> &lastVertices = frameVertices[frames.size() - 1];
|
||||
if (alpha == 1) {
|
||||
if (blend == MixBlend_Add) {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment*>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i] - setupVertices[i];
|
||||
} else {
|
||||
// Weighted deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i];
|
||||
}
|
||||
} else {
|
||||
// Vertex positions or deform offsets, no alpha.
|
||||
memcpy(deform.buffer(), lastVertices.buffer(), vertexCount * sizeof(float));
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup: {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float setup = setupVertices[i];
|
||||
deform[i] = setup + (lastVertices[i] - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] = lastVertices[i] * alpha;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
// Vertex positions or deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += (lastVertices[i] - deform[i]) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
||||
} else {
|
||||
// Weighted deform offsets, alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i] * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (time >= frames[frames.size() - 1]) { // Time is after last frame.
|
||||
Vector<float> &lastVertices = vertices[frames.size() - 1];
|
||||
if (alpha == 1) {
|
||||
if (blend == MixBlend_Add) {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i] - setupVertices[i];
|
||||
} else {
|
||||
// Weighted deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i];
|
||||
}
|
||||
} else {
|
||||
// Vertex positions or deform offsets, no alpha.
|
||||
memcpy(deform.buffer(), lastVertices.buffer(), vertexCount * sizeof(float));
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup: {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float setup = setupVertices[i];
|
||||
deform[i] = setup + (lastVertices[i] - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] = lastVertices[i] * alpha;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
// Vertex positions or deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += (lastVertices[i] - deform[i]) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
||||
} else {
|
||||
// Weighted deform offsets, alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
deform[i] += lastVertices[i] * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(frames, time);
|
||||
Vector<float> &prevVertices = frameVertices[frame - 1];
|
||||
Vector<float> &nextVertices = frameVertices[frame];
|
||||
float frameTime = frames[frame];
|
||||
float percent = getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::search(frames, time);
|
||||
float percent = getCurvePercent(time, frame);
|
||||
Vector<float> &prevVertices = vertices[frame];
|
||||
Vector<float> &nextVertices = vertices[frame + 1];
|
||||
|
||||
if (alpha == 1) {
|
||||
if (blend == MixBlend_Add) {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Vertex positions or deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] = prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup: {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i], setup = setupVertices[i];
|
||||
deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
// Vertex positions or deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;
|
||||
}
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (alpha == 1) {
|
||||
if (blend == MixBlend_Add) {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, no alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Vertex positions or deform offsets, no alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] = prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup: {
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i], setup = setupVertices[i];
|
||||
deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
// Vertex positions or deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;
|
||||
}
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
|
||||
if (vertexAttachment->getBones().size() == 0) {
|
||||
// Unweighted vertex positions, with alpha.
|
||||
Vector<float> &setupVertices = vertexAttachment->getVertices();
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||
}
|
||||
} else {
|
||||
// Weighted deform offsets, with alpha.
|
||||
for (size_t i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DeformTimeline::getPropertyId() {
|
||||
assert(_attachment != NULL);
|
||||
return ((int) TimelineType_Deform << 24) + _attachment->_id + _slotIndex;
|
||||
void DeformTimeline::setBezier(int bezier, int frame, float value, float time1, float value1, float cx1, float cy1,
|
||||
float cx2, float cy2, float time2, float value2) {
|
||||
SP_UNUSED(value1);
|
||||
SP_UNUSED(value2);
|
||||
size_t i = getFrameCount() + bezier * DeformTimeline::BEZIER_SIZE;
|
||||
if (value == 0) _curves[frame] = DeformTimeline::BEZIER + i;
|
||||
float tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06;
|
||||
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = (cy1 - cy2 + 0.33333333) * 0.018;
|
||||
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 x = time1 + dx, y = dy;
|
||||
for (size_t n = i + DeformTimeline::BEZIER_SIZE; i < n; i += 2) {
|
||||
_curves[i] = x;
|
||||
_curves[i + 1] = y;
|
||||
dx += ddx;
|
||||
dy += ddy;
|
||||
ddx += dddx;
|
||||
ddy += dddy;
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
float DeformTimeline::getCurvePercent(float time, int frame) {
|
||||
int i = (int)_curves[frame];
|
||||
switch (i) {
|
||||
case DeformTimeline::LINEAR: {
|
||||
float x = _frames[frame];
|
||||
return (time - x) / (_frames[frame + getFrameEntries()] - x);
|
||||
}
|
||||
case DeformTimeline::STEPPED: {
|
||||
return 0;
|
||||
}
|
||||
default: {}
|
||||
}
|
||||
i -= DeformTimeline::BEZIER;
|
||||
if (_curves[i] > time) {
|
||||
float x = _frames[frame];
|
||||
return _curves[i + 1] * (time - x) / (_curves[i] - x);
|
||||
}
|
||||
int n = i + DeformTimeline::BEZIER_SIZE;
|
||||
for (i += 2; i < n; i += 2) {
|
||||
if (_curves[i] >= time) {
|
||||
float x = _curves[i - 2], y = _curves[i - 1];
|
||||
return y + (time - x) / (_curves[i] - x) * (_curves[i + 1] - y);
|
||||
}
|
||||
}
|
||||
float x = _curves[n - 2], y = _curves[n - 1];
|
||||
return y + (1 - y) * (time - x) / (_frames[frame + getFrameEntries()] - x);
|
||||
}
|
||||
|
||||
void DeformTimeline::setFrame(int frameIndex, float time, Vector<float> &vertices) {
|
||||
_frames[frameIndex] = time;
|
||||
_frameVertices[frameIndex].clear();
|
||||
_frameVertices[frameIndex].addAll(vertices);
|
||||
}
|
||||
|
||||
int DeformTimeline::getSlotIndex() {
|
||||
return _slotIndex;
|
||||
}
|
||||
|
||||
void DeformTimeline::setSlotIndex(int inValue) {
|
||||
_slotIndex = inValue;
|
||||
}
|
||||
|
||||
Vector<float> &DeformTimeline::getFrames() {
|
||||
return _frames;
|
||||
_frames[frameIndex] = time;
|
||||
_vertices[frameIndex].clear();
|
||||
_vertices[frameIndex].addAll(vertices);
|
||||
}
|
||||
|
||||
Vector<Vector<float> > &DeformTimeline::getVertices() {
|
||||
return _frameVertices;
|
||||
return _vertices;
|
||||
}
|
||||
|
||||
VertexAttachment *DeformTimeline::getAttachment() {
|
||||
return _attachment;
|
||||
return _attachment;
|
||||
}
|
||||
|
||||
void DeformTimeline::setAttachment(VertexAttachment *inValue) {
|
||||
_attachment = inValue;
|
||||
_attachment = inValue;
|
||||
}
|
||||
|
||||
@ -45,13 +45,12 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(DrawOrderTimeline, Timeline)
|
||||
|
||||
DrawOrderTimeline::DrawOrderTimeline(int frameCount) : Timeline() {
|
||||
_frames.ensureCapacity(frameCount);
|
||||
DrawOrderTimeline::DrawOrderTimeline(size_t frameCount) : Timeline(frameCount, 1) {
|
||||
PropertyId ids[] = {((PropertyId) Property_DrawOrder << 32)};
|
||||
setPropertyIds(ids, 1);
|
||||
|
||||
_drawOrders.ensureCapacity(frameCount);
|
||||
|
||||
_frames.setSize(frameCount, 0);
|
||||
|
||||
for (int i = 0; i < frameCount; ++i) {
|
||||
for (size_t i = 0; i < frameCount; ++i) {
|
||||
Vector<int> vec;
|
||||
_drawOrders.add(vec);
|
||||
}
|
||||
@ -86,14 +85,7 @@ void DrawOrderTimeline::apply(Skeleton &skeleton, float lastTime, float time, Ve
|
||||
return;
|
||||
}
|
||||
|
||||
size_t frame;
|
||||
if (time >= _frames[_frames.size() - 1]) {
|
||||
// Time is after last frame.
|
||||
frame = _frames.size() - 1;
|
||||
} else
|
||||
frame = (size_t)Animation::binarySearch(_frames, time) - 1;
|
||||
|
||||
Vector<int> &drawOrderToSetupIndex = _drawOrders[frame];
|
||||
Vector<int> &drawOrderToSetupIndex = _drawOrders[Animation::search(_frames, time)];
|
||||
if (drawOrderToSetupIndex.size() == 0) {
|
||||
drawOrder.clear();
|
||||
for (size_t i = 0, n = slots.size(); i < n; ++i)
|
||||
@ -104,24 +96,12 @@ void DrawOrderTimeline::apply(Skeleton &skeleton, float lastTime, float time, Ve
|
||||
}
|
||||
}
|
||||
|
||||
int DrawOrderTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_DrawOrder << 24);
|
||||
}
|
||||
|
||||
void DrawOrderTimeline::setFrame(size_t frameIndex, float time, Vector<int> &drawOrder) {
|
||||
_frames[frameIndex] = time;
|
||||
_drawOrders[frameIndex].clear();
|
||||
_drawOrders[frameIndex].addAll(drawOrder);
|
||||
}
|
||||
|
||||
Vector<float> &DrawOrderTimeline::getFrames() {
|
||||
return _frames;
|
||||
void DrawOrderTimeline::setFrame(size_t frame, float time, Vector<int> &drawOrder) {
|
||||
_frames[frame] = time;
|
||||
_drawOrders[frame].clear();
|
||||
_drawOrders[frame].addAll(drawOrder);
|
||||
}
|
||||
|
||||
Vector<Vector<int> > &DrawOrderTimeline::getDrawOrders() {
|
||||
return _drawOrders;
|
||||
}
|
||||
|
||||
size_t DrawOrderTimeline::getFrameCount() {
|
||||
return _frames.size();
|
||||
}
|
||||
|
||||
@ -49,8 +49,9 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(EventTimeline, Timeline)
|
||||
|
||||
EventTimeline::EventTimeline(int frameCount) : Timeline() {
|
||||
_frames.setSize(frameCount, 0);
|
||||
EventTimeline::EventTimeline(size_t frameCount) : Timeline(frameCount, 1) {
|
||||
PropertyId ids[] = {((PropertyId) Property_Event << 32)};
|
||||
setPropertyIds(ids, 1);
|
||||
_events.setSize(frameCount, NULL);
|
||||
}
|
||||
|
||||
@ -72,40 +73,32 @@ void EventTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector
|
||||
apply(skeleton, lastTime, FLT_MAX, pEvents, alpha, blend, direction);
|
||||
lastTime = -1.0f;
|
||||
} else if (lastTime >= _frames[frameCount - 1]) {
|
||||
// Last time is after last frame.
|
||||
// Last time is after last i.
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < _frames[0]) return; // Time is before first frame.
|
||||
if (time < _frames[0]) return; // Time is before first i.
|
||||
|
||||
int frame;
|
||||
int i;
|
||||
if (lastTime < _frames[0]) {
|
||||
frame = 0;
|
||||
i = 0;
|
||||
} else {
|
||||
frame = Animation::binarySearch(_frames, lastTime);
|
||||
float frameTime = _frames[frame];
|
||||
while (frame > 0) {
|
||||
// Fire multiple events with the same frame.
|
||||
if (_frames[frame - 1] != frameTime) break;
|
||||
frame--;
|
||||
i = Animation::search(_frames, lastTime) + 1;
|
||||
float frameTime = _frames[i];
|
||||
while (i > 0) {
|
||||
// Fire multiple events with the same i.
|
||||
if (_frames[i - 1] != frameTime) break;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
for (; (size_t)frame < frameCount && time >= _frames[frame]; ++frame)
|
||||
events.add(_events[frame]);
|
||||
for (; (size_t)i < frameCount && time >= _frames[i]; i++)
|
||||
events.add(_events[i]);
|
||||
}
|
||||
|
||||
int EventTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_Event << 24);
|
||||
void EventTimeline::setFrame(size_t frame, Event *event) {
|
||||
_frames[frame] = event->getTime();
|
||||
_events[frame] = event;
|
||||
}
|
||||
|
||||
void EventTimeline::setFrame(size_t frameIndex, Event *event) {
|
||||
_frames[frameIndex] = event->getTime();
|
||||
_events[frameIndex] = event;
|
||||
}
|
||||
|
||||
Vector<float> EventTimeline::getFrames() { return _frames; }
|
||||
|
||||
Vector<Event *> &EventTimeline::getEvents() { return _events; }
|
||||
|
||||
size_t EventTimeline::getFrameCount() { return _frames.size(); }
|
||||
|
||||
@ -47,21 +47,9 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(IkConstraintTimeline, CurveTimeline)
|
||||
|
||||
const int IkConstraintTimeline::ENTRIES = 6;
|
||||
const int IkConstraintTimeline::PREV_TIME = -6;
|
||||
const int IkConstraintTimeline::PREV_MIX = -5;
|
||||
const int IkConstraintTimeline::PREV_SOFTNESS = -4;
|
||||
const int IkConstraintTimeline::PREV_BEND_DIRECTION = -3;
|
||||
const int IkConstraintTimeline::PREV_COMPRESS = -2;
|
||||
const int IkConstraintTimeline::PREV_STRETCH = -1;
|
||||
const int IkConstraintTimeline::MIX = 1;
|
||||
const int IkConstraintTimeline::SOFTNESS = 2;
|
||||
const int IkConstraintTimeline::BEND_DIRECTION = 3;
|
||||
const int IkConstraintTimeline::COMPRESS = 4;
|
||||
const int IkConstraintTimeline::STRETCH = 5;
|
||||
|
||||
IkConstraintTimeline::IkConstraintTimeline(int frameCount) : CurveTimeline(frameCount), _ikConstraintIndex(0) {
|
||||
_frames.setSize(frameCount * ENTRIES, 0);
|
||||
IkConstraintTimeline::IkConstraintTimeline(size_t frameCount, size_t bezierCount, int ikConstraintIndex) : CurveTimeline(frameCount, IkConstraintTimeline::ENTRIES, bezierCount), _ikConstraintIndex(ikConstraintIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_IkConstraint << 32) | ikConstraintIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
@ -94,77 +82,62 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time,
|
||||
}
|
||||
}
|
||||
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
if (blend == MixBlend_Setup) {
|
||||
constraint._mix =
|
||||
constraint._data._mix + (_frames[_frames.size() + PREV_MIX] - constraint._data._mix) * alpha;
|
||||
constraint._softness = constraint._data._softness
|
||||
+ (_frames[_frames.size() + PREV_SOFTNESS] - constraint._data._softness) * alpha;
|
||||
if (direction == MixDirection_Out) {
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
constraint._compress = constraint._data._compress;
|
||||
constraint._stretch = constraint._data._stretch;
|
||||
} else {
|
||||
constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
|
||||
constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0;
|
||||
constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0;
|
||||
}
|
||||
} else {
|
||||
constraint._mix += (_frames[_frames.size() + PREV_MIX] - constraint._mix) * alpha;
|
||||
constraint._softness += (_frames[_frames.size() + PREV_SOFTNESS] - constraint._softness) * alpha;
|
||||
if (direction == MixDirection_In) {
|
||||
constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
|
||||
constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0;
|
||||
constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
float mix = 0, softness = 0;
|
||||
int i = Animation::search(_frames, time, IkConstraintTimeline::ENTRIES);
|
||||
int curveType = (int)_curves[i / IkConstraintTimeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case IkConstraintTimeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
mix = _frames[i + IkConstraintTimeline::MIX];
|
||||
softness = _frames[i + IkConstraintTimeline::SOFTNESS];
|
||||
float t = (time - before) / (_frames[i + IkConstraintTimeline::ENTRIES] - before);
|
||||
mix += (_frames[i + IkConstraintTimeline::ENTRIES + IkConstraintTimeline::MIX] - mix) * t;
|
||||
softness += (_frames[i + IkConstraintTimeline::ENTRIES + IkConstraintTimeline::SOFTNESS] - softness) * t;
|
||||
break;
|
||||
}
|
||||
case IkConstraintTimeline::STEPPED: {
|
||||
mix = _frames[i + IkConstraintTimeline::MIX];
|
||||
softness = _frames[i + IkConstraintTimeline::SOFTNESS];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
mix = getBezierValue(time, i, IkConstraintTimeline::MIX, curveType - IkConstraintTimeline::BEZIER);
|
||||
softness = getBezierValue(time, i, IkConstraintTimeline::SOFTNESS,
|
||||
curveType + IkConstraintTimeline::BEZIER_SIZE -
|
||||
IkConstraintTimeline::BEZIER);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
float mix = _frames[frame + PREV_MIX];
|
||||
float softness = _frames[frame + PREV_SOFTNESS];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
if (blend == MixBlend_Setup) {
|
||||
constraint._mix = constraint._data._mix + (mix - constraint._data._mix) * alpha;
|
||||
constraint._softness = constraint._data._softness + (softness - constraint._data._softness) * alpha;
|
||||
|
||||
if (blend == MixBlend_Setup) {
|
||||
constraint._mix =
|
||||
constraint._data._mix + (mix + (_frames[frame + MIX] - mix) * percent - constraint._data._mix) * alpha;
|
||||
constraint._softness = constraint._data._softness
|
||||
+ (softness + (_frames[frame + SOFTNESS] - softness) * percent - constraint._data._softness) * alpha;
|
||||
if (direction == MixDirection_Out) {
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
constraint._compress = constraint._data._compress;
|
||||
constraint._stretch = constraint._data._stretch;
|
||||
} else {
|
||||
constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
|
||||
constraint._compress = _frames[frame + PREV_COMPRESS] != 0;
|
||||
constraint._stretch = _frames[frame + PREV_STRETCH] != 0;
|
||||
}
|
||||
} else {
|
||||
constraint._mix += (mix + (_frames[frame + MIX] - mix) * percent - constraint._mix) * alpha;
|
||||
constraint._softness += (softness + (_frames[frame + SOFTNESS] - softness) * percent - constraint._softness) * alpha;
|
||||
if (direction == MixDirection_In) {
|
||||
constraint._bendDirection = (int) _frames[frame + PREV_BEND_DIRECTION];
|
||||
constraint._compress = _frames[frame + PREV_COMPRESS] != 0;
|
||||
constraint._stretch = _frames[frame + PREV_STRETCH] != 0;
|
||||
}
|
||||
}
|
||||
if (direction == MixDirection_Out) {
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
constraint._compress = constraint._data._compress;
|
||||
constraint._stretch = constraint._data._stretch;
|
||||
} else {
|
||||
constraint._bendDirection = _frames[i + IkConstraintTimeline::BEND_DIRECTION];
|
||||
constraint._compress = _frames[i + IkConstraintTimeline::COMPRESS] != 0;
|
||||
constraint._stretch = _frames[i + IkConstraintTimeline::STRETCH] != 0;
|
||||
}
|
||||
} else {
|
||||
constraint._mix += (mix - constraint._mix) * alpha;
|
||||
constraint._softness += (softness - constraint._softness) * alpha;
|
||||
if (direction == MixDirection_In) {
|
||||
constraint._bendDirection = _frames[i + IkConstraintTimeline::BEND_DIRECTION];
|
||||
constraint._compress = _frames[i + IkConstraintTimeline::COMPRESS] != 0;
|
||||
constraint._stretch = _frames[i + IkConstraintTimeline::STRETCH] != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int IkConstraintTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_IkConstraint << 24) + _ikConstraintIndex;
|
||||
}
|
||||
|
||||
void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, float softness, int bendDirection, bool compress, bool stretch) {
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + MIX] = mix;
|
||||
_frames[frameIndex + SOFTNESS] = softness;
|
||||
_frames[frameIndex + BEND_DIRECTION] = (float)bendDirection;
|
||||
_frames[frameIndex + COMPRESS] = compress ? 1 : 0;
|
||||
_frames[frameIndex + STRETCH] = stretch ? 1 : 0;
|
||||
void IkConstraintTimeline::setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch) {
|
||||
frame *= ENTRIES;
|
||||
_frames[frame] = time;
|
||||
_frames[frame + MIX] = mix;
|
||||
_frames[frame + SOFTNESS] = softness;
|
||||
_frames[frame + BEND_DIRECTION] = (float)bendDirection;
|
||||
_frames[frame + COMPRESS] = compress ? 1 : 0;
|
||||
_frames[frame + STRETCH] = stretch ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -47,17 +47,10 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(PathConstraintMixTimeline, CurveTimeline)
|
||||
|
||||
const int PathConstraintMixTimeline::ENTRIES = 3;
|
||||
const int PathConstraintMixTimeline::PREV_TIME = -3;
|
||||
const int PathConstraintMixTimeline::PREV_ROTATE = -2;
|
||||
const int PathConstraintMixTimeline::PREV_TRANSLATE = -1;
|
||||
const int PathConstraintMixTimeline::ROTATE = 1;
|
||||
const int PathConstraintMixTimeline::TRANSLATE = 2;
|
||||
|
||||
PathConstraintMixTimeline::PathConstraintMixTimeline(int frameCount) : CurveTimeline(frameCount),
|
||||
_pathConstraintIndex(0)
|
||||
{
|
||||
_frames.setSize(frameCount * ENTRIES, 0);
|
||||
PathConstraintMixTimeline::PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex) : CurveTimeline(frameCount, PathConstraintMixTimeline::ENTRIES, bezierCount),
|
||||
_pathConstraintIndex(pathConstraintIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_PathConstraintMix << 32) | pathConstraintIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
void PathConstraintMixTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
@ -71,56 +64,66 @@ void PathConstraintMixTimeline::apply(Skeleton &skeleton, float lastTime, float
|
||||
PathConstraint &constraint = *constraintP;
|
||||
if (!constraint.isActive()) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
constraint._rotateMix = constraint._data._rotateMix;
|
||||
constraint._translateMix = constraint._data._translateMix;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
constraint._rotateMix += (constraint._data._rotateMix - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (constraint._data._translateMix - constraint._translateMix) * alpha;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
constraint._mixRotate = constraint._data._mixRotate;
|
||||
constraint._mixX = constraint._data._mixX;
|
||||
constraint._mixY = constraint._data._mixY;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
constraint._mixRotate += (constraint._data._mixRotate - constraint._mixRotate) * alpha;
|
||||
constraint._mixX += (constraint._data._mixX - constraint._mixX) * alpha;
|
||||
constraint._mixY += (constraint._data._mixY - constraint._mixY) * alpha;
|
||||
default: {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float rotate, translate;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
rotate = _frames[_frames.size() + PREV_ROTATE];
|
||||
translate = _frames[_frames.size() + PREV_TRANSLATE];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
rotate = _frames[frame + PREV_ROTATE];
|
||||
translate = _frames[frame + PREV_TRANSLATE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
float rotate, x, y;
|
||||
int i = Animation::search(_frames, time, PathConstraintMixTimeline::ENTRIES);
|
||||
int curveType = (int)_curves[i >> 2];
|
||||
switch (curveType) {
|
||||
case LINEAR: {
|
||||
float before = _frames[i];
|
||||
rotate = _frames[i + ROTATE];
|
||||
x = _frames[i + X];
|
||||
y = _frames[i + Y];
|
||||
float t = (time - before) / (_frames[i + ENTRIES] - before);
|
||||
rotate += (_frames[i + ENTRIES + ROTATE] - rotate) * t;
|
||||
x += (_frames[i + ENTRIES + X] - x) * t;
|
||||
y += (_frames[i + ENTRIES + Y] - y) * t;
|
||||
break;
|
||||
}
|
||||
case STEPPED: {
|
||||
rotate = _frames[i + ROTATE];
|
||||
x = _frames[i + X];
|
||||
y = _frames[i + Y];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER);
|
||||
x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER);
|
||||
y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER);
|
||||
}
|
||||
}
|
||||
|
||||
rotate += (_frames[frame + ROTATE] - rotate) * percent;
|
||||
translate += (_frames[frame + TRANSLATE] - translate) * percent;
|
||||
}
|
||||
|
||||
if (blend == MixBlend_Setup) {
|
||||
constraint._rotateMix = constraint._data._rotateMix + (rotate - constraint._data._rotateMix) * alpha;
|
||||
constraint._translateMix =
|
||||
constraint._data._translateMix + (translate - constraint._data._translateMix) * alpha;
|
||||
} else {
|
||||
constraint._rotateMix += (rotate - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (translate - constraint._translateMix) * alpha;
|
||||
}
|
||||
if (blend == MixBlend_Setup) {
|
||||
PathConstraintData data = constraint._data;
|
||||
constraint._mixRotate = data._mixRotate + (rotate - data._mixRotate) * alpha;
|
||||
constraint._mixX = data._mixX + (x - data._mixX) * alpha;
|
||||
constraint._mixY = data._mixY + (y - data._mixY) * alpha;
|
||||
} else {
|
||||
constraint._mixRotate += (rotate - constraint._mixRotate) * alpha;
|
||||
constraint._mixX += (x - constraint._mixX) * alpha;
|
||||
constraint._mixY += (y - constraint._mixY) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int PathConstraintMixTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_PathConstraintMix << 24) + _pathConstraintIndex;
|
||||
}
|
||||
|
||||
void PathConstraintMixTimeline::setFrame(int frameIndex, float time, float rotateMix, float translateMix) {
|
||||
void PathConstraintMixTimeline::setFrame(int frameIndex, float time, float mixRotate, float mixX, float mixY) {
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + ROTATE] = rotateMix;
|
||||
_frames[frameIndex + TRANSLATE] = translateMix;
|
||||
_frames[frameIndex + ROTATE] = mixRotate;
|
||||
_frames[frameIndex + X] = mixX;
|
||||
_frames[frameIndex + Y] = mixY;
|
||||
}
|
||||
|
||||
@ -45,17 +45,12 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL(PathConstraintPositionTimeline, CurveTimeline)
|
||||
RTTI_IMPL(PathConstraintPositionTimeline, CurveTimeline1)
|
||||
|
||||
const int PathConstraintPositionTimeline::ENTRIES = 2;
|
||||
const int PathConstraintPositionTimeline::PREV_TIME = -2;
|
||||
const int PathConstraintPositionTimeline::PREV_VALUE = -1;
|
||||
const int PathConstraintPositionTimeline::VALUE = 1;
|
||||
|
||||
PathConstraintPositionTimeline::PathConstraintPositionTimeline(int frameCount) : CurveTimeline(frameCount),
|
||||
_pathConstraintIndex(0)
|
||||
{
|
||||
_frames.setSize(frameCount * ENTRIES, 0);
|
||||
PathConstraintPositionTimeline::PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex) : CurveTimeline1(frameCount, bezierCount),
|
||||
_pathConstraintIndex(pathConstraintIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_PathConstraintPosition << 32) | pathConstraintIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
PathConstraintPositionTimeline::~PathConstraintPositionTimeline() {
|
||||
@ -85,32 +80,10 @@ void PathConstraintPositionTimeline::apply(Skeleton &skeleton, float lastTime, f
|
||||
}
|
||||
}
|
||||
|
||||
float position;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
position = _frames[_frames.size() + PREV_VALUE];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
position = _frames[frame + PREV_VALUE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
float position = getCurveValue(time);
|
||||
|
||||
position += (_frames[frame + VALUE] - position) * percent;
|
||||
}
|
||||
if (blend == MixBlend_Setup)
|
||||
constraint._position = constraint._data._position + (position - constraint._data._position) * alpha;
|
||||
else
|
||||
constraint._position += (position - constraint._position) * alpha;
|
||||
}
|
||||
|
||||
int PathConstraintPositionTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_PathConstraintPosition << 24) + _pathConstraintIndex;
|
||||
}
|
||||
|
||||
void PathConstraintPositionTimeline::setFrame(int frameIndex, float time, float value) {
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + VALUE] = value;
|
||||
}
|
||||
|
||||
@ -47,8 +47,9 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(PathConstraintSpacingTimeline, PathConstraintPositionTimeline)
|
||||
|
||||
PathConstraintSpacingTimeline::PathConstraintSpacingTimeline(int frameCount) : PathConstraintPositionTimeline(
|
||||
frameCount) {
|
||||
PathConstraintSpacingTimeline::PathConstraintSpacingTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex) : CurveTimeline1(frameCount, bezierCount), _pathConstraintIndex(pathConstraintIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_PathConstraintSpacing << 32) | pathConstraintIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
void PathConstraintSpacingTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents,
|
||||
@ -75,27 +76,10 @@ void PathConstraintSpacingTimeline::apply(Skeleton &skeleton, float lastTime, fl
|
||||
}
|
||||
}
|
||||
|
||||
float spacing;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
spacing = _frames[_frames.size() + PREV_VALUE];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
spacing = _frames[frame + PREV_VALUE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
float spacing = getCurveValue(time);
|
||||
|
||||
spacing += (_frames[frame + VALUE] - spacing) * percent;
|
||||
}
|
||||
|
||||
if (blend == MixBlend_Setup)
|
||||
constraint._spacing = constraint._data._spacing + (spacing - constraint._data._spacing) * alpha;
|
||||
else
|
||||
constraint._spacing += (spacing - constraint._spacing) * alpha;
|
||||
}
|
||||
|
||||
int PathConstraintSpacingTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_PathConstraintSpacing << 24) + _pathConstraintIndex;
|
||||
if (blend == MixBlend_Setup)
|
||||
constraint._spacing = constraint._data._spacing + (spacing - constraint._data._spacing) * alpha;
|
||||
else
|
||||
constraint._spacing += (spacing - constraint._spacing) * alpha;
|
||||
}
|
||||
|
||||
@ -43,9 +43,15 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL(ShearTimeline, TranslateTimeline)
|
||||
RTTI_IMPL(ShearTimeline, CurveTimeline2)
|
||||
|
||||
ShearTimeline::ShearTimeline(int frameCount) : TranslateTimeline(frameCount) {
|
||||
ShearTimeline::ShearTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline2(frameCount, bezierCount), _boneIndex(boneIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_ShearX << 32) | boneIndex,
|
||||
((PropertyId)Property_ShearY << 32) | boneIndex};
|
||||
setPropertyIds(ids, 2);
|
||||
}
|
||||
|
||||
ShearTimeline::~ShearTimeline() {
|
||||
}
|
||||
|
||||
void ShearTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
@ -55,58 +61,152 @@ void ShearTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Bone *boneP = skeleton._bones[_boneIndex];
|
||||
Bone &bone = *boneP;
|
||||
if (!bone._active) return;
|
||||
Bone *bone = skeleton._bones[_boneIndex];
|
||||
if (!bone->_active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone._shearX = bone._data._shearX;
|
||||
bone._shearY = bone._data._shearY;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
bone._shearX += (bone._data._shearX - bone._shearX) * alpha;
|
||||
bone._shearY += (bone._data._shearY - bone._shearY) * alpha;
|
||||
default: {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearX = bone->_data._shearX;
|
||||
bone->_shearY = bone->_data._shearY;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
bone->_shearX += (bone->_data._shearX - bone->_shearX) * alpha;
|
||||
bone->_shearY += (bone->_data._shearY - bone->_shearY) * alpha;
|
||||
default: {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float x, y;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
x = _frames[_frames.size() + PREV_X];
|
||||
y = _frames[_frames.size() + PREV_Y];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
x = _frames[frame + PREV_X];
|
||||
y = _frames[frame + PREV_Y];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
float x, y;
|
||||
int i = Animation::search(_frames, time, CurveTimeline2::ENTRIES);
|
||||
int curveType = (int)_curves[i / CurveTimeline2::ENTRIES];
|
||||
switch (curveType) {
|
||||
case CurveTimeline2::LINEAR: {
|
||||
float before = _frames[i];
|
||||
x = _frames[i + CurveTimeline2::VALUE1];
|
||||
y = _frames[i + CurveTimeline2::VALUE2];
|
||||
float t = (time - before) / (_frames[i + CurveTimeline2::ENTRIES] - before);
|
||||
x += (_frames[i + CurveTimeline2::ENTRIES + CurveTimeline2::VALUE1] - x) * t;
|
||||
y += (_frames[i + CurveTimeline2::ENTRIES + CurveTimeline2::VALUE2] - y) * t;
|
||||
break;
|
||||
}
|
||||
case CurveTimeline2::STEPPED: {
|
||||
x = _frames[i + CurveTimeline2::VALUE1];
|
||||
y = _frames[i + CurveTimeline2::VALUE2];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
x = getBezierValue(time, i, CurveTimeline2::VALUE1, curveType - CurveTimeline2::BEZIER);
|
||||
y = getBezierValue(time, i, CurveTimeline2::VALUE2,
|
||||
curveType + CurveTimeline2::BEZIER_SIZE - CurveTimeline2::BEZIER);
|
||||
}
|
||||
}
|
||||
|
||||
x = x + (_frames[frame + X] - x) * percent;
|
||||
y = y + (_frames[frame + Y] - y) * percent;
|
||||
}
|
||||
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone._shearX = bone._data._shearX + x * alpha;
|
||||
bone._shearY = bone._data._shearY + y * alpha;
|
||||
break;
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
bone._shearX += (bone._data._shearX + x - bone._shearX) * alpha;
|
||||
bone._shearY += (bone._data._shearY + y - bone._shearY) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
bone._shearX += x * alpha;
|
||||
bone._shearY += y * alpha;
|
||||
}
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearX = bone->_data._shearX + x * alpha;
|
||||
bone->_shearY = bone->_data._shearY + y * alpha;
|
||||
break;
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
bone->_shearX += (bone->_data._shearX + x - bone->_shearX) * alpha;
|
||||
bone->_shearY += (bone->_data._shearY + y - bone->_shearY) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
bone->_shearX += x * alpha;
|
||||
bone->_shearY += y * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int ShearTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_Shear << 24) + _boneIndex;
|
||||
RTTI_IMPL(ShearXTimeline, CurveTimeline1)
|
||||
|
||||
ShearXTimeline::ShearXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_ShearX << 32) | boneIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
ShearXTimeline::~ShearXTimeline() {
|
||||
}
|
||||
|
||||
void ShearXTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Bone *bone = skeleton._bones[_boneIndex];
|
||||
if (!bone->_active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearX = bone->_data._shearX;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
bone->_shearX += (bone->_data._shearX - bone->_shearX) * alpha;
|
||||
default: {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float x = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearX = bone->_data._shearX + x * alpha;
|
||||
break;
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
bone->_shearX += (bone->_data._shearX + x - bone->_shearX) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
bone->_shearX += x * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(ShearYTimeline, CurveTimeline1)
|
||||
|
||||
ShearYTimeline::ShearYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_ShearX << 32) | boneIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
ShearYTimeline::~ShearYTimeline() {
|
||||
}
|
||||
|
||||
void ShearYTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction
|
||||
) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
SP_UNUSED(direction);
|
||||
|
||||
Bone *bone = skeleton._bones[_boneIndex];
|
||||
if (!bone->_active) return;
|
||||
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearY = bone->_data._shearY;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
bone->_shearY += (bone->_data._shearY - bone->_shearY) * alpha;
|
||||
default: {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float y = getCurveValue(time);
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
bone->_shearY = bone->_data._shearY + y * alpha;
|
||||
break;
|
||||
case MixBlend_First:
|
||||
case MixBlend_Replace:
|
||||
bone->_shearY += (bone->_data._shearY + y - bone->_shearY) * alpha;
|
||||
break;
|
||||
case MixBlend_Add:
|
||||
bone->_shearY += y * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,21 +47,10 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(TransformConstraintTimeline, CurveTimeline)
|
||||
|
||||
const int TransformConstraintTimeline::ENTRIES = 5;
|
||||
const int TransformConstraintTimeline::PREV_TIME = -5;
|
||||
const int TransformConstraintTimeline::PREV_ROTATE = -4;
|
||||
const int TransformConstraintTimeline::PREV_TRANSLATE = -3;
|
||||
const int TransformConstraintTimeline::PREV_SCALE = -2;
|
||||
const int TransformConstraintTimeline::PREV_SHEAR = -1;
|
||||
const int TransformConstraintTimeline::ROTATE = 1;
|
||||
const int TransformConstraintTimeline::TRANSLATE = 2;
|
||||
const int TransformConstraintTimeline::SCALE = 3;
|
||||
const int TransformConstraintTimeline::SHEAR = 4;
|
||||
|
||||
TransformConstraintTimeline::TransformConstraintTimeline(int frameCount) : CurveTimeline(frameCount),
|
||||
_transformConstraintIndex(0)
|
||||
{
|
||||
_frames.setSize(frameCount * ENTRIES, 0);
|
||||
TransformConstraintTimeline::TransformConstraintTimeline(size_t frameCount, size_t bezierCount, int transformConstraintIndex) : CurveTimeline(frameCount, TransformConstraintTimeline::ENTRIES, bezierCount),
|
||||
_transformConstraintIndex(transformConstraintIndex) {
|
||||
PropertyId ids[] = { ((PropertyId)Property_TransformConstraint << 32) | transformConstraintIndex };
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
|
||||
void TransformConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents,
|
||||
@ -74,75 +63,94 @@ void TransformConstraintTimeline::apply(Skeleton &skeleton, float lastTime, floa
|
||||
TransformConstraint &constraint = *constraintP;
|
||||
if (!constraint.isActive()) return;
|
||||
|
||||
TransformConstraintData &data = constraint._data;
|
||||
if (time < _frames[0]) {
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
constraint._rotateMix = constraint._data._rotateMix;
|
||||
constraint._translateMix = constraint._data._translateMix;
|
||||
constraint._scaleMix = constraint._data._scaleMix;
|
||||
constraint._shearMix = constraint._data._shearMix;
|
||||
constraint._mixRotate = data._mixRotate;
|
||||
constraint._mixX = data._mixX;
|
||||
constraint._mixY = data._mixY;
|
||||
constraint._mixScaleX = data._mixScaleX;
|
||||
constraint._mixScaleY = data._mixScaleY;
|
||||
constraint._mixShearY = data._mixShearY;
|
||||
return;
|
||||
case MixBlend_First:
|
||||
constraint._rotateMix += (constraint._data._rotateMix - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (constraint._data._translateMix - constraint._translateMix) * alpha;
|
||||
constraint._scaleMix += (constraint._data._scaleMix - constraint._scaleMix) * alpha;
|
||||
constraint._shearMix += (constraint._data._shearMix - constraint._shearMix) * alpha;
|
||||
constraint._mixRotate += (data._mixRotate - constraint._mixRotate) * alpha;
|
||||
constraint._mixX += (data._mixX - constraint._mixX) * alpha;
|
||||
constraint._mixY += (data._mixY - constraint._mixY) * alpha;
|
||||
constraint._mixScaleX += (data._mixScaleX - constraint._mixScaleX) * alpha;
|
||||
constraint._mixScaleY += (data._mixScaleY - constraint._mixScaleY) * alpha;
|
||||
constraint._mixShearY += (data._mixShearY - constraint._mixShearY) * alpha;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float rotate, translate, scale, shear;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) {
|
||||
// Time is after last frame.
|
||||
size_t i = _frames.size();
|
||||
rotate = _frames[i + PREV_ROTATE];
|
||||
translate = _frames[i + PREV_TRANSLATE];
|
||||
scale = _frames[i + PREV_SCALE];
|
||||
shear = _frames[i + PREV_SHEAR];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
rotate = _frames[frame + PREV_ROTATE];
|
||||
translate = _frames[frame + PREV_TRANSLATE];
|
||||
scale = _frames[frame + PREV_SCALE];
|
||||
shear = _frames[frame + PREV_SHEAR];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
float rotate, x, y, scaleX, scaleY, shearY;
|
||||
int i = Animation::search(_frames, time, TransformConstraintTimeline::ENTRIES);
|
||||
int curveType = (int)_curves[i / TransformConstraintTimeline::ENTRIES];
|
||||
switch (curveType) {
|
||||
case TransformConstraintTimeline::LINEAR: {
|
||||
float before = _frames[i];
|
||||
rotate = _frames[i + ROTATE];
|
||||
x = _frames[i + X];
|
||||
y = _frames[i + Y];
|
||||
scaleX = _frames[i + SCALEX];
|
||||
scaleY = _frames[i + SCALEY];
|
||||
shearY = _frames[i + SHEARY];
|
||||
float t = (time - before) / (_frames[i + ENTRIES] - before);
|
||||
rotate += (_frames[i + ENTRIES + ROTATE] - rotate) * t;
|
||||
x += (_frames[i + ENTRIES + X] - x) * t;
|
||||
y += (_frames[i + ENTRIES + Y] - y) * t;
|
||||
scaleX += (_frames[i + ENTRIES + SCALEX] - scaleX) * t;
|
||||
scaleY += (_frames[i + ENTRIES + SCALEY] - scaleY) * t;
|
||||
shearY += (_frames[i + ENTRIES + SHEARY] - shearY) * t;
|
||||
break;
|
||||
}
|
||||
case TransformConstraintTimeline::STEPPED: {
|
||||
rotate = _frames[i + ROTATE];
|
||||
x = _frames[i + X];
|
||||
y = _frames[i + Y];
|
||||
scaleX = _frames[i + SCALEX];
|
||||
scaleY = _frames[i + SCALEY];
|
||||
shearY = _frames[i + SHEARY];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rotate = getBezierValue(time, i, ROTATE, curveType - BEZIER);
|
||||
x = getBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER);
|
||||
y = getBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER);
|
||||
scaleX = getBezierValue(time, i, SCALEX, curveType + BEZIER_SIZE * 3 - BEZIER);
|
||||
scaleY = getBezierValue(time, i, SCALEY, curveType + BEZIER_SIZE * 4 - BEZIER);
|
||||
shearY = getBezierValue(time, i, SHEARY, curveType + BEZIER_SIZE * 5 - BEZIER);
|
||||
}
|
||||
}
|
||||
|
||||
rotate += (_frames[frame + ROTATE] - rotate) * percent;
|
||||
translate += (_frames[frame + TRANSLATE] - translate) * percent;
|
||||
scale += (_frames[frame + SCALE] - scale) * percent;
|
||||
shear += (_frames[frame + SHEAR] - shear) * percent;
|
||||
}
|
||||
|
||||
if (blend == MixBlend_Setup) {
|
||||
TransformConstraintData &data = constraint._data;
|
||||
constraint._rotateMix = data._rotateMix + (rotate - data._rotateMix) * alpha;
|
||||
constraint._translateMix = data._translateMix + (translate - data._translateMix) * alpha;
|
||||
constraint._scaleMix = data._scaleMix + (scale - data._scaleMix) * alpha;
|
||||
constraint._shearMix = data._shearMix + (shear - data._shearMix) * alpha;
|
||||
} else {
|
||||
constraint._rotateMix += (rotate - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (translate - constraint._translateMix) * alpha;
|
||||
constraint._scaleMix += (scale - constraint._scaleMix) * alpha;
|
||||
constraint._shearMix += (shear - constraint._shearMix) * alpha;
|
||||
}
|
||||
if (blend == MixBlend_Setup) {
|
||||
constraint._mixRotate = data._mixRotate + (rotate - data._mixRotate) * alpha;
|
||||
constraint._mixX = data._mixX + (x - data._mixX) * alpha;
|
||||
constraint._mixY = data._mixY + (y - data._mixY) * alpha;
|
||||
constraint._mixScaleX = data._mixScaleX + (scaleX - data._mixScaleX) * alpha;
|
||||
constraint._mixScaleY = data._mixScaleY + (scaleY - data._mixScaleY) * alpha;
|
||||
constraint._mixShearY = data._mixShearY + (shearY - data._mixShearY) * alpha;
|
||||
} else {
|
||||
constraint._mixRotate += (rotate - constraint._mixRotate) * alpha;
|
||||
constraint._mixX += (x - constraint._mixX) * alpha;
|
||||
constraint._mixY += (y - constraint._mixY) * alpha;
|
||||
constraint._mixScaleX += (scaleX - constraint._mixScaleX) * alpha;
|
||||
constraint._mixScaleY += (scaleY - constraint._mixScaleY) * alpha;
|
||||
constraint._mixShearY += (shearY - constraint._mixShearY) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int TransformConstraintTimeline::getPropertyId() {
|
||||
return ((int) TimelineType_TransformConstraint << 24) + _transformConstraintIndex;
|
||||
}
|
||||
|
||||
void TransformConstraintTimeline::setFrame(size_t frameIndex, float time, float rotateMix, float translateMix, float scaleMix,
|
||||
float shearMix
|
||||
) {
|
||||
void TransformConstraintTimeline::setFrame(size_t frameIndex, float time, float mixRotate, float mixX, float mixY, float mixScaleX, float mixScaleY, float mixShearY) {
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + ROTATE] = rotateMix;
|
||||
_frames[frameIndex + TRANSLATE] = translateMix;
|
||||
_frames[frameIndex + SCALE] = scaleMix;
|
||||
_frames[frameIndex + SHEAR] = shearMix;
|
||||
_frames[frameIndex + ROTATE] = mixRotate;
|
||||
_frames[frameIndex + X] = mixX;
|
||||
_frames[frameIndex + Y] = mixY;
|
||||
_frames[frameIndex + SCALEX] = mixScaleX;
|
||||
_frames[frameIndex + SCALEY] = mixScaleY;
|
||||
_frames[frameIndex + SHEARY] = mixShearY;
|
||||
}
|
||||
|
||||
@ -1034,7 +1034,7 @@ module spine {
|
||||
|
||||
/** Changes a slot's {@link Slot#color}. */
|
||||
export class RGBTimeline extends CurveTimeline implements SlotTimeline {
|
||||
static ENTRIES = 5;
|
||||
static ENTRIES = 4;
|
||||
|
||||
static R = 1; static G = 2; static B = 3;
|
||||
|
||||
@ -1264,7 +1264,7 @@ module spine {
|
||||
|
||||
let light = slot.color, dark = slot.darkColor;
|
||||
if (alpha == 1) {
|
||||
slot.color.set(r, g, b, a);
|
||||
light.set(r, g, b, a);
|
||||
dark.r = r2;
|
||||
dark.g = g2;
|
||||
dark.b = b2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user