From 7b154fb92f0afdf05438a030c6bd768321b3895e Mon Sep 17 00:00:00 2001 From: badlogic Date: Wed, 3 Mar 2021 16:46:54 +0100 Subject: [PATCH] [cpp] More 4.0 porting, all of animation and timelines. --- spine-cpp/spine-cpp/include/spine/Animation.h | 10 +- .../include/spine/AttachmentTimeline.h | 23 +- spine-cpp/spine-cpp/include/spine/Bone.h | 16 + spine-cpp/spine-cpp/include/spine/BoneData.h | 4 + spine-cpp/spine-cpp/include/spine/Color.h | 16 + .../spine-cpp/include/spine/ColorTimeline.h | 177 +++++- .../spine-cpp/include/spine/CurveTimeline.h | 10 +- .../spine-cpp/include/spine/DeformTimeline.h | 56 +- .../include/spine/DrawOrderTimeline.h | 9 +- .../spine-cpp/include/spine/EventTimeline.h | 9 +- .../include/spine/IkConstraintTimeline.h | 31 +- .../include/spine/PathConstraintMixTimeline.h | 25 +- .../spine/PathConstraintPositionTimeline.h | 15 +- .../spine/PathConstraintSpacingTimeline.h | 10 +- spine-cpp/spine-cpp/include/spine/Property.h | 2 +- .../spine-cpp/include/spine/ShearTimeline.h | 52 +- spine-cpp/spine-cpp/include/spine/Skeleton.h | 14 +- spine-cpp/spine-cpp/include/spine/Slot.h | 10 +- spine-cpp/spine-cpp/include/spine/SlotData.h | 10 +- .../spine/TransformConstraintTimeline.h | 30 +- .../src/spine/AttachmentTimeline.cpp | 61 +- .../spine-cpp/src/spine/ColorTimeline.cpp | 521 +++++++++++++++--- .../spine-cpp/src/spine/CurveTimeline.cpp | 6 +- .../spine-cpp/src/spine/DeformTimeline.cpp | 469 ++++++++-------- .../spine-cpp/src/spine/DrawOrderTimeline.cpp | 40 +- .../spine-cpp/src/spine/EventTimeline.cpp | 43 +- .../src/spine/IkConstraintTimeline.cpp | 141 ++--- .../src/spine/PathConstraintMixTimeline.cpp | 117 ++-- .../spine/PathConstraintPositionTimeline.cpp | 39 +- .../spine/PathConstraintSpacingTimeline.cpp | 32 +- .../spine-cpp/src/spine/ShearTimeline.cpp | 202 +++++-- .../src/spine/TransformConstraintTimeline.cpp | 148 ++--- spine-ts/core/src/Animation.ts | 4 +- 33 files changed, 1474 insertions(+), 878 deletions(-) diff --git a/spine-cpp/spine-cpp/include/spine/Animation.h b/spine-cpp/spine-cpp/include/spine/Animation.h index edfaa3275..ab2c606b4 100644 --- a/spine-cpp/spine-cpp/include/spine/Animation.h +++ b/spine-cpp/spine-cpp/include/spine/Animation.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h index 3aed1015c..849147f7d 100644 --- a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h @@ -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* 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& getFrames(); Vector& getAttachmentNames(); - size_t getFrameCount(); - private: - size_t _slotIndex; - Vector _frames; + + int getSlotIndex() { return _slotIndex; } + + void setSlotIndex(int inValue) { _slotIndex = inValue; } + + protected: + int _slotIndex; + Vector _attachmentNames; void setAttachment(Skeleton& skeleton, Slot& slot, String* attachmentName); diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index 411c88fa5..9aba070d4 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index a26889b0d..94b0008bb 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/Color.h b/spine-cpp/spine-cpp/include/spine/Color.h index 1f288f7a8..225c5af6c 100644 --- a/spine-cpp/spine-cpp/include/spine/Color.h +++ b/spine-cpp/spine-cpp/include/spine/Color.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/ColorTimeline.h b/spine-cpp/spine-cpp/include/spine/ColorTimeline.h index 3d3540060..5533fb987 100644 --- a/spine-cpp/spine-cpp/include/spine/ColorTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ColorTimeline.h @@ -33,48 +33,165 @@ #include 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 *pEvents, float alpha, MixBlend blend, - MixDirection direction); + virtual void + apply(Skeleton &skeleton, float lastTime, float time, Vector *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 &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 _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 *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 *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 *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 *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 */ diff --git a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h b/spine-cpp/spine-cpp/include/spine/CurveTimeline.h index fe8a8ecaa..7a5595efe 100644 --- a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/CurveTimeline.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; }; } diff --git a/spine-cpp/spine-cpp/include/spine/DeformTimeline.h b/spine-cpp/spine-cpp/include/spine/DeformTimeline.h index 05632c301..499e975a5 100644 --- a/spine-cpp/spine-cpp/include/spine/DeformTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/DeformTimeline.h @@ -33,37 +33,47 @@ #include 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* 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 *pEvents, float alpha, MixBlend blend, + MixDirection direction); - /// Sets the time and value of the specified keyframe. - void setFrame(int frameIndex, float time, Vector& vertices); + /// Sets the time and value of the specified keyframe. + void setFrame(int frameIndex, float time, Vector &vertices); - int getSlotIndex(); - void setSlotIndex(int inValue); - Vector& getFrames(); - Vector< Vector >& getVertices(); - VertexAttachment* getAttachment(); - void setAttachment(VertexAttachment* inValue); + Vector > &getVertices(); - private: - int _slotIndex; - Vector _frames; - Vector< Vector > _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 > _vertices; + + VertexAttachment *_attachment; + }; } #endif /* Spine_DeformTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h b/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h index 867e94e97..239ffefdb 100644 --- a/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.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* 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& drawOrder); + void setFrame(size_t frame, float time, Vector& drawOrder); - Vector& getFrames(); Vector< Vector >& getDrawOrders(); - size_t getFrameCount(); private: - Vector _frames; Vector< Vector > _drawOrders; }; } diff --git a/spine-cpp/spine-cpp/include/spine/EventTimeline.h b/spine-cpp/spine-cpp/include/spine/EventTimeline.h index 6d39a7467..92aa5fff6 100644 --- a/spine-cpp/spine-cpp/include/spine/EventTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/EventTimeline.h @@ -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* 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 getFrames(); Vector& getEvents(); - size_t getFrameCount(); private: - Vector _frames; Vector _events; }; } diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h index c710b78c7..f987f1ff3 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h @@ -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* 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 _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; }; } diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h index 9537ff06b..7f657e857 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h @@ -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* 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 _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; }; } diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h index 3c11bf19b..22234cf71 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h @@ -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* 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 _frames; int _pathConstraintIndex; }; } diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h index d3e9bd979..591a4cd38 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h @@ -33,18 +33,22 @@ #include 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* pEvents, float alpha, MixBlend blend, MixDirection direction); - virtual int getPropertyId(); + int getPathConstraintIndex() { return _pathConstraintIndex; } + + void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; } + protected: + int _pathConstraintIndex; }; } diff --git a/spine-cpp/spine-cpp/include/spine/Property.h b/spine-cpp/spine-cpp/include/spine/Property.h index 2883e6300..5462334d0 100644 --- a/spine-cpp/spine-cpp/include/spine/Property.h +++ b/spine-cpp/spine-cpp/include/spine/Property.h @@ -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 }; } diff --git a/spine-cpp/spine-cpp/include/spine/ShearTimeline.h b/spine-cpp/spine-cpp/include/spine/ShearTimeline.h index 4f6f12f7e..4e20c2051 100644 --- a/spine-cpp/spine-cpp/include/spine/ShearTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ShearTimeline.h @@ -33,19 +33,65 @@ #include 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* 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* 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* pEvents, float alpha, MixBlend blend, MixDirection direction); + + int getBoneIndex() { return _boneIndex; } + + void setBoneIndex(int inValue) { _boneIndex = inValue; } + private: + int _boneIndex; + }; } #endif /* Spine_ShearTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index 685eeaf22..9a9cab2b3 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.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; diff --git a/spine-cpp/spine-cpp/include/spine/Slot.h b/spine-cpp/spine-cpp/include/spine/Slot.h index f75fbbf0a..d45ccdda2 100644 --- a/spine-cpp/spine-cpp/include/spine/Slot.h +++ b/spine-cpp/spine-cpp/include/spine/Slot.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/SlotData.h b/spine-cpp/spine-cpp/include/spine/SlotData.h index 24919be57..76d5b5d6f 100644 --- a/spine-cpp/spine-cpp/include/spine/SlotData.h +++ b/spine-cpp/spine-cpp/include/spine/SlotData.h @@ -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; diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h index 317323822..4aabb7ae9 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h @@ -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* 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 _frames; - int _transformConstraintIndex; }; } diff --git a/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp b/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp index 4c4d348b8..556f99010 100644 --- a/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp @@ -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 &AttachmentTimeline::getFrames() { - return _frames; +void AttachmentTimeline::setFrame(int frame, float time, const String &attachmentName) { + _frames[frame] = time; + _attachmentNames[frame] = attachmentName; } Vector &AttachmentTimeline::getAttachmentNames() { return _attachmentNames; } - -size_t AttachmentTimeline::getFrameCount() { - return _frames.size(); -} diff --git a/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp b/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp index 1047cb638..607b32309 100644 --- a/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp @@ -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 *pEvents, float alpha, - MixBlend blend, MixDirection direction +RGBATimeline::~RGBATimeline() { +} + +void RGBATimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *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 *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 &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 *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 *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 *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; } diff --git a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp index 9dd757e7c..50156ccc1 100644 --- a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp @@ -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) { } diff --git a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp index b49033476..96723ba8e 100644 --- a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp @@ -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 vec; - _frameVertices.add(vec); - } + _vertices.ensureCapacity(frameCount); + for (size_t i = 0; i < frameCount; ++i) { + Vector vec; + _vertices.add(vec); + } } void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *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(slotAttachment); - if (attachment->_deformAttachment != _attachment) { - return; - } + VertexAttachment *attachment = static_cast(slotAttachment); + if (attachment->_deformAttachment != _attachment) { + return; + } - Vector &deformArray = slot._deform; - if (deformArray.size() == 0) { - blend = MixBlend_Setup; - } + Vector &deformArray = slot._deform; + if (deformArray.size() == 0) { + blend = MixBlend_Setup; + } - Vector< Vector > &frameVertices = _frameVertices; - size_t vertexCount = frameVertices[0].size(); + Vector > &vertices = _vertices; + size_t vertexCount = vertices[0].size(); - Vector &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 &deformInner = deformArray; - if (attachment->getBones().size() == 0) { - // Unweighted vertex positions. - Vector &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 &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 &deformInner = deformArray; + if (attachment->getBones().size() == 0) { + // Unweighted vertex positions. + Vector &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 &deform = deformArray; + deformArray.setSize(vertexCount, 0); + Vector &deform = deformArray; - if (time >= frames[frames.size() - 1]) { // Time is after last frame. - Vector &lastVertices = frameVertices[frames.size() - 1]; - if (alpha == 1) { - if (blend == MixBlend_Add) { - VertexAttachment *vertexAttachment = static_cast(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, no alpha. - Vector &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(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, with alpha. - Vector &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(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, no alpha. - Vector &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 &lastVertices = vertices[frames.size() - 1]; + if (alpha == 1) { + if (blend == MixBlend_Add) { + VertexAttachment *vertexAttachment = static_cast(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, no alpha. + Vector &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(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, with alpha. + Vector &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(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, no alpha. + Vector &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 &prevVertices = frameVertices[frame - 1]; - Vector &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 &prevVertices = vertices[frame]; + Vector &nextVertices = vertices[frame + 1]; - if (alpha == 1) { - if (blend == MixBlend_Add) { - VertexAttachment *vertexAttachment = static_cast(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, no alpha. - Vector &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(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, with alpha. - Vector &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(slotAttachment); - if (vertexAttachment->getBones().size() == 0) { - // Unweighted vertex positions, with alpha. - Vector &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(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, no alpha. + Vector &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(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, with alpha. + Vector &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(slotAttachment); + if (vertexAttachment->getBones().size() == 0) { + // Unweighted vertex positions, with alpha. + Vector &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 &vertices) { - _frames[frameIndex] = time; - _frameVertices[frameIndex].clear(); - _frameVertices[frameIndex].addAll(vertices); -} - -int DeformTimeline::getSlotIndex() { - return _slotIndex; -} - -void DeformTimeline::setSlotIndex(int inValue) { - _slotIndex = inValue; -} - -Vector &DeformTimeline::getFrames() { - return _frames; + _frames[frameIndex] = time; + _vertices[frameIndex].clear(); + _vertices[frameIndex].addAll(vertices); } Vector > &DeformTimeline::getVertices() { - return _frameVertices; + return _vertices; } VertexAttachment *DeformTimeline::getAttachment() { - return _attachment; + return _attachment; } void DeformTimeline::setAttachment(VertexAttachment *inValue) { - _attachment = inValue; + _attachment = inValue; } diff --git a/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp b/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp index 0204d9cf6..2048b2286 100644 --- a/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp @@ -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 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 &drawOrderToSetupIndex = _drawOrders[frame]; + Vector &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 &drawOrder) { - _frames[frameIndex] = time; - _drawOrders[frameIndex].clear(); - _drawOrders[frameIndex].addAll(drawOrder); -} - -Vector &DrawOrderTimeline::getFrames() { - return _frames; +void DrawOrderTimeline::setFrame(size_t frame, float time, Vector &drawOrder) { + _frames[frame] = time; + _drawOrders[frame].clear(); + _drawOrders[frame].addAll(drawOrder); } Vector > &DrawOrderTimeline::getDrawOrders() { return _drawOrders; } - -size_t DrawOrderTimeline::getFrameCount() { - return _frames.size(); -} diff --git a/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp b/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp index 709caf54a..4b1e17816 100644 --- a/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp @@ -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 EventTimeline::getFrames() { return _frames; } - Vector &EventTimeline::getEvents() { return _events; } - -size_t EventTimeline::getFrameCount() { return _frames.size(); } diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp index 3c4a0e019..bfb0dad2f 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp @@ -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 *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; } diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp index ae4e93b25..145a84e17 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp @@ -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 *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; } diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp index 83790dd0e..5615cbf2a 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp @@ -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; -} diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp index edd65968f..9918ea0fc 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp @@ -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 *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; } diff --git a/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp b/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp index 046d057ad..0eac1bb80 100644 --- a/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp @@ -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 *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 *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 *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; + } } diff --git a/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp index e2a5b03dd..f7fd54073 100644 --- a/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp @@ -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 *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; } diff --git a/spine-ts/core/src/Animation.ts b/spine-ts/core/src/Animation.ts index 3209d49a3..e12ef090d 100644 --- a/spine-ts/core/src/Animation.ts +++ b/spine-ts/core/src/Animation.ts @@ -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;