diff --git a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj index ec0df170f..f49ed95ab 100644 --- a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj +++ b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj @@ -286,7 +286,7 @@ xcopy "$(ProjectDir)..\Resources" "$(OutDir)\Resources" /D /E /I /F /Y - + diff --git a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters index ec494f191..69d347b70 100644 --- a/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters +++ b/spine-cocos2dx/example/proj.win32/spine-cocos2d-x.vcxproj.filters @@ -491,7 +491,7 @@ spine - + spine diff --git a/spine-cpp/spine-cpp/include/spine/Animation.h b/spine-cpp/spine-cpp/include/spine/Animation.h index 9e4004fcb..edfaa3275 100644 --- a/spine-cpp/spine-cpp/include/spine/Animation.h +++ b/spine-cpp/spine-cpp/include/spine/Animation.h @@ -36,6 +36,7 @@ #include #include #include +#include namespace spine { class Timeline; @@ -79,6 +80,10 @@ class SP_API Animation : public SpineObject { friend class TranslateTimeline; + friend class TranslateXTimeline; + + friend class TranslateYTimeline; + friend class TwoColorTimeline; public: @@ -95,27 +100,22 @@ public: Vector &getTimelines(); - bool hasTimeline(int id); + bool hasTimeline(Vector ids); float getDuration(); void setDuration(float inValue); - - private: Vector _timelines; - HashMap _timelineIds; + HashMap _timelineIds; float _duration; String _name; /// @param target After the first and before the last entry. - static int binarySearch(Vector &values, float target, int step); + static int search(Vector &values, float target); - /// @param target After the first and before the last entry. - static int binarySearch(Vector &values, float target); - - static int linearSearch(Vector &values, float target, int step); + static int search(Vector &values, float target, int step); }; } diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index 148c6c5c6..411c88fa5 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.h @@ -65,10 +65,18 @@ class SP_API Bone : public Updatable { friend class ScaleTimeline; + friend class ScaleXTimeline; + + friend class ScaleYTimeline; + friend class ShearTimeline; friend class TranslateTimeline; + friend class TranslateXTimeline; + + friend class TranslateYTimeline; + RTTI_DECL public: diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index bd997f651..a26889b0d 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -46,10 +46,18 @@ class SP_API BoneData : public SpineObject { friend class ScaleTimeline; + friend class ScaleXTimeline; + + friend class ScaleYTimeline; + friend class ShearTimeline; friend class TranslateTimeline; + friend class TranslateXTimeline; + + friend class TranslateYTimeline; + public: BoneData(int index, const String &name, BoneData *parent = NULL); diff --git a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h b/spine-cpp/spine-cpp/include/spine/CurveTimeline.h index 9d739d4bb..fe8a8ecaa 100644 --- a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/CurveTimeline.h @@ -39,38 +39,59 @@ namespace spine { RTTI_DECL public: - explicit CurveTimeline(int frameCount); + explicit CurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount); virtual ~CurveTimeline(); - virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector* pEvents, float alpha, MixBlend blend, MixDirection direction) = 0; + void setLinear(size_t frame); - virtual int getPropertyId() = 0; + void setStepped(size_t frame); - size_t getFrameCount(); + void setBezier (size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2); - void setLinear(size_t frameIndex); - - void setStepped(size_t frameIndex); - - /// Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. - /// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of - /// the difference between the keyframe's values. - void setCurve(size_t frameIndex, float cx1, float cy1, float cx2, float cy2); - - float getCurvePercent(size_t frameIndex, float percent); - - float getCurveType(size_t frameIndex); + float getBezierValue(float time, size_t frame, size_t valueOffset, size_t i); protected: - static const float LINEAR; - static const float STEPPED; - static const float BEZIER; - static const int BEZIER_SIZE; + static const int LINEAR = 0; + static const int STEPPED = 1; + static const int BEZIER = 2; + static const int BEZIER_SIZE = 18; - private: Vector _curves; // type, x, y, ... }; + + class SP_API CurveTimeline1 : public CurveTimeline { + RTTI_DECL + + public: + explicit CurveTimeline1(size_t frameCount, size_t bezierCount); + + virtual ~CurveTimeline1(); + + void setFrame(size_t frame, float time, float value); + + float getCurveValue(float time); + protected: + static const int ENTRIES; + static const int VALUE; + }; + + class SP_API CurveTimeline2 : public CurveTimeline { + RTTI_DECL + + public: + explicit CurveTimeline2(size_t frameCount, size_t bezierCount); + + virtual ~CurveTimeline2(); + + void setFrame(size_t frame, float time, float value1, float value2); + + float getCurveValue(float time); + protected: + static const int ENTRIES; + static const int VALUE1; + static const int VALUE2; + }; } #endif /* Spine_CurveTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraint.h b/spine-cpp/spine-cpp/include/spine/PathConstraint.h index 470d89997..149887bb8 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraint.h @@ -65,11 +65,14 @@ namespace spine { float getSpacing(); void setSpacing(float inValue); - float getRotateMix(); - void setRotateMix(float inValue); + float getMixRotate(); + void setMixRotate(float inValue); - float getTranslateMix(); - void setTranslateMix(float inValue); + float getMixX(); + void setMixX(float inValue); + + float getMixY(); + void setMixY(float inValue); Vector& getBones(); @@ -91,7 +94,8 @@ namespace spine { PathConstraintData& _data; Vector _bones; Slot* _target; - float _position, _spacing, _rotateMix, _translateMix; + float _position, _spacing; + float _mixRotate, _mixX, _mixY; Vector _spaces; Vector _positions; @@ -102,7 +106,7 @@ namespace spine { bool _active; - Vector& computeWorldPositions(PathAttachment& path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing); + Vector& computeWorldPositions(PathAttachment& path, int spacesCount, bool tangents); static void addBeforePosition(float p, Vector& temp, int i, Vector& output, int o); diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h index 97f8b84cc..b5bc30890 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h @@ -78,11 +78,14 @@ namespace spine { float getSpacing(); void setSpacing(float inValue); - float getRotateMix(); - void setRotateMix(float inValue); + float getMixRotate(); + void setMixRotate(float inValue); - float getTranslateMix(); - void setTranslateMix(float inValue); + float getMixX(); + void setMixX(float inValue); + + float getMixY(); + void setMixY(float inValue); private: Vector _bones; @@ -91,7 +94,8 @@ namespace spine { SpacingMode _spacingMode; RotateMode _rotateMode; float _offsetRotation; - float _position, _spacing, _rotateMix, _translateMix; + float _position, _spacing; + float _mixRotate, _mixX, _mixY; }; } diff --git a/spine-cpp/spine-cpp/include/spine/TimelineType.h b/spine-cpp/spine-cpp/include/spine/Property.h similarity index 69% rename from spine-cpp/spine-cpp/include/spine/TimelineType.h rename to spine-cpp/spine-cpp/include/spine/Property.h index b1f07811e..2883e6300 100644 --- a/spine-cpp/spine-cpp/include/spine/TimelineType.h +++ b/spine-cpp/spine-cpp/include/spine/Property.h @@ -27,27 +27,32 @@ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -#ifndef Spine_TimelineType_h -#define Spine_TimelineType_h +#ifndef Spine_Property_h +#define Spine_Property_h namespace spine { -enum TimelineType { - TimelineType_Rotate = 0, - TimelineType_Translate, - TimelineType_Scale, - TimelineType_Shear, - TimelineType_Attachment, - TimelineType_Color, - TimelineType_Deform, - TimelineType_Event, - TimelineType_DrawOrder, - TimelineType_IkConstraint, - TimelineType_TransformConstraint, - TimelineType_PathConstraintPosition, - TimelineType_PathConstraintSpacing, - TimelineType_PathConstraintMix, - TimelineType_TwoColor +typedef long long PropertyId; +enum Property { + Property_Rotate = 1 << 0, + Property_X = 1 << 1, + Property_Y = 1 << 2, + Property_ScaleX = 1 << 3, + Property_ScaleY = 1 << 4, + Property_ShearX = 1 << 5, + Property_ShearY = 1 << 6, + Property_Rgb = 1 << 7, + Property_Alpha = 1 << 8, + Property_Rgb2 = 1 << 9, + Property_Attachment = 1 << 10, + Property_Deform = 1 << 11, + Property_Event = 1 << 12, + Property_DrawOrder = 1 << 13, + Property_IkConstraint = 1 << 14, + Property_TransformConstraint = 1 << 15, + Property_PathConstraintPosition = 1 << 16, + Property_PathConstraintSpacing = 1 << 17, + Property_OathConstraintMix = 1 << 18 }; } -#endif /* Spine_TimelineType_h */ +#endif /* Spine_Property_h */ diff --git a/spine-cpp/spine-cpp/include/spine/RegionAttachment.h b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h index fe8720706..e6975d922 100644 --- a/spine-cpp/spine-cpp/include/spine/RegionAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h @@ -54,7 +54,7 @@ namespace spine { void updateOffset(); - void setUVs(float u, float v, float u2, float v2, bool rotate); + void setUVs(float u, float v, float u2, float v2, float degrees); /// Transforms the attachment's four vertices to world coordinates. /// @param bone The parent bone. diff --git a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h index 0c6f89b31..9681e9ad6 100644 --- a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h @@ -33,7 +33,7 @@ #include namespace spine { - class SP_API RotateTimeline : public CurveTimeline { + class SP_API RotateTimeline : public CurveTimeline1 { friend class SkeletonBinary; friend class SkeletonJson; friend class AnimationState; @@ -41,29 +41,15 @@ namespace spine { RTTI_DECL public: - static const int ENTRIES = 2; - - explicit RotateTimeline(int frameCount); + explicit RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex); 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 degrees); - - int getBoneIndex(); - void setBoneIndex(int inValue); - - Vector& getFrames(); + int getBoneIndex() { return _boneIndex; } + void setBoneIndex(int inValue) { _boneIndex = inValue; } private: - static const int PREV_TIME = -2; - static const int PREV_ROTATION = -1; - static const int ROTATION = 1; - int _boneIndex; - Vector _frames; // time, angle, ... }; } diff --git a/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h b/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h index 984b9d72c..1c2f52679 100644 --- a/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h @@ -33,19 +33,65 @@ #include namespace spine { - class SP_API ScaleTimeline : public TranslateTimeline { + class SP_API ScaleTimeline : public CurveTimeline2 { friend class SkeletonBinary; friend class SkeletonJson; RTTI_DECL public: - explicit ScaleTimeline(int frameCount); + explicit ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex); + + virtual ~ScaleTimeline(); 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 ScaleXTimeline : public CurveTimeline1 { + friend class SkeletonBinary; + friend class SkeletonJson; + + RTTI_DECL + + public: + explicit ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex); + + virtual ~ScaleXTimeline(); + + 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 ScaleYTimeline : public CurveTimeline1 { + friend class SkeletonBinary; + friend class SkeletonJson; + + RTTI_DECL + + public: + explicit ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex); + + virtual ~ScaleYTimeline(); + + 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_ScaleTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index 27a3d8393..685eeaf22 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.h @@ -82,12 +82,22 @@ class SP_API Skeleton : public SpineObject { friend class ScaleTimeline; + friend class ScaleXTimeline; + + friend class ScaleYTimeline; + friend class ShearTimeline; friend class TransformConstraintTimeline; + friend class RotateTimeline; + friend class TranslateTimeline; + friend class TranslateXTimeline; + + friend class TranslateYTimeline; + friend class TwoColorTimeline; public: @@ -104,6 +114,8 @@ public: /// Updates the world transform for each bone and applies constraints. void updateWorldTransform(); + void updateWorldTransform(Bone* parent); + /// Sets the bones, constraints, and slots to their setup pose values. void setToSetupPose(); @@ -217,7 +229,6 @@ private: Vector _transformConstraints; Vector _pathConstraints; Vector _updateCache; - Vector _updateCacheReset; Skin *_skin; Color _color; float _time; diff --git a/spine-cpp/spine-cpp/include/spine/SpacingMode.h b/spine-cpp/spine-cpp/include/spine/SpacingMode.h index c76d6dbfa..e46756056 100644 --- a/spine-cpp/spine-cpp/include/spine/SpacingMode.h +++ b/spine-cpp/spine-cpp/include/spine/SpacingMode.h @@ -34,7 +34,8 @@ namespace spine { enum SpacingMode { SpacingMode_Length = 0, SpacingMode_Fixed, - SpacingMode_Percent + SpacingMode_Percent, + SpacingMode_Proportional }; } diff --git a/spine-cpp/spine-cpp/include/spine/Timeline.h b/spine-cpp/spine-cpp/include/spine/Timeline.h index cc98353e5..df92d847d 100644 --- a/spine-cpp/spine-cpp/include/spine/Timeline.h +++ b/spine-cpp/spine-cpp/include/spine/Timeline.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace spine { class Skeleton; @@ -45,7 +46,7 @@ class SP_API Timeline : public SpineObject { RTTI_DECL public: - Timeline(); + Timeline(size_t frameCount, size_t frameEntries); virtual ~Timeline(); @@ -63,7 +64,22 @@ public: apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, MixBlend blend, MixDirection direction) = 0; - virtual int getPropertyId() = 0; + size_t getFrameEntries(); + + size_t getFrameCount(); + + Vector &getFrames(); + + float getDuration(); + + virtual Vector &getPropertyIds(); + +protected: + void setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount); + + Vector _propertyIds; + Vector _frames; + size_t _frameEntries; }; } diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraint.h b/spine-cpp/spine-cpp/include/spine/TransformConstraint.h index e271e5cfb..92604d927 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraint.h @@ -48,8 +48,6 @@ namespace spine { public: TransformConstraint(TransformConstraintData& data, Skeleton& skeleton); - void apply(); - virtual void update(); virtual int getOrder(); @@ -61,17 +59,23 @@ namespace spine { Bone* getTarget(); void setTarget(Bone* inValue); - float getRotateMix(); - void setRotateMix(float inValue); + float getMixRotate(); + void setMixRotate(float inValue); - float getTranslateMix(); - void setTranslateMix(float inValue); + float getMixX(); + void setMixX(float inValue); - float getScaleMix(); - void setScaleMix(float inValue); + float getMixY(); + void setMixY(float inValue); - float getShearMix(); - void setShearMix(float inValue); + float getMixScaleX(); + void setMixScaleX(float inValue); + + float getMixScaleY(); + void setMixScaleY(float inValue); + + float getMixShearY(); + void setMixShearY(float inValue); bool isActive(); @@ -81,8 +85,8 @@ namespace spine { TransformConstraintData& _data; Vector _bones; Bone* _target; - float _rotateMix, _translateMix, _scaleMix, _shearMix; - bool _active; + float _mixRotate, _mixX, _mixY, _mixScaleX, _mixScaleY, _mixShearY; + bool _active; void applyAbsoluteWorld(); diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h index 783eaacc1..ccf58c008 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h @@ -51,10 +51,12 @@ namespace spine { Vector& getBones(); BoneData* getTarget(); - float getRotateMix(); - float getTranslateMix(); - float getScaleMix(); - float getShearMix(); + float getMixRotate(); + float getMixX(); + float getMixY(); + float getMixScaleX(); + float getMixScaleY(); + float getMixShearY(); float getOffsetRotation(); float getOffsetX(); @@ -69,7 +71,7 @@ namespace spine { private: Vector _bones; BoneData* _target; - float _rotateMix, _translateMix, _scaleMix, _shearMix; + float _mixRotate, _mixX, _mixY, _mixScaleX, _mixScaleY, _mixShearY; float _offsetRotation, _offsetX, _offsetY, _offsetScaleX, _offsetScaleY, _offsetShearY; bool _relative, _local; }; diff --git a/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h b/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h index 88f1dfb5b..aa73602ae 100644 --- a/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h @@ -33,40 +33,69 @@ #include #include -#include +#include namespace spine { - class SP_API TranslateTimeline : public CurveTimeline { + class SP_API TranslateTimeline : public CurveTimeline2 { friend class SkeletonBinary; friend class SkeletonJson; RTTI_DECL public: - static const int ENTRIES; - - explicit TranslateTimeline(int frameCount); + explicit TranslateTimeline(size_t frameCount, size_t bezierCount, int boneIndex); virtual ~TranslateTimeline(); virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector* pEvents, float alpha, MixBlend blend, MixDirection direction); - virtual int getPropertyId(); + int getBoneIndex() { return _boneIndex; } - /// Sets the time and value of the specified keyframe. - void setFrame(int frameIndex, float time, float x, float y); - - protected: - static const int PREV_TIME; - static const int PREV_X; - static const int PREV_Y; - static const int X; - static const int Y; - - Vector _frames; - int _boneIndex; + void setBoneIndex(int inValue) { _boneIndex = inValue; } + private: + int _boneIndex; }; + + class SP_API TranslateXTimeline : public CurveTimeline1 { + friend class SkeletonBinary; + friend class SkeletonJson; + + RTTI_DECL + + public: + explicit TranslateXTimeline(size_t frameCount, size_t bezierCount, int boneIndex); + + virtual ~TranslateXTimeline(); + + 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 TranslateYTimeline : public CurveTimeline1 { + friend class SkeletonBinary; + friend class SkeletonJson; + + RTTI_DECL + + public: + explicit TranslateYTimeline(size_t frameCount, size_t bezierCount, int boneIndex); + + virtual ~TranslateYTimeline(); + + 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_TranslateTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/spine.h b/spine-cpp/spine-cpp/include/spine/spine.h index 39d989bef..fcfe22588 100644 --- a/spine-cpp/spine-cpp/include/spine/spine.h +++ b/spine-cpp/spine-cpp/include/spine/spine.h @@ -95,7 +95,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/Animation.cpp b/spine-cpp/spine-cpp/src/spine/Animation.cpp index bc4156cce..40fcebf99 100644 --- a/spine-cpp/spine-cpp/src/spine/Animation.cpp +++ b/spine-cpp/spine-cpp/src/spine/Animation.cpp @@ -48,12 +48,18 @@ Animation::Animation(const String &name, Vector &timelines, float du _duration(duration), _name(name) { assert(_name.length() > 0); - for (int i = 0; i < (int)timelines.size(); i++) - _timelineIds.put(timelines[i]->getPropertyId(), true); + for (size_t i = 0; i < timelines.size(); i++) { + Vector propertyIds = timelines[i]->getPropertyIds(); + for (size_t ii = 0; ii < propertyIds.size(); ii++) + _timelineIds.put(propertyIds[ii], true); + } } -bool Animation::hasTimeline(int id) { - return _timelineIds.containsKey(id); +bool Animation::hasTimeline(Vector ids) { + for (size_t i = 0; i < ids.size(); i++) { + if (_timelineIds.containsKey(ids[i])) return true; + } + return false; } Animation::~Animation() { @@ -91,52 +97,17 @@ void Animation::setDuration(float inValue) { _duration = inValue; } -int Animation::binarySearch(Vector &values, float target, int step) { - int low = 0; - int size = (int)values.size(); - int high = size / step - 2; - if (high == 0) { - return step; - } - - int current = (int) (static_cast(high) >> 1); - while (true) { - if (values[(current + 1) * step] <= target) - low = current + 1; - else - high = current; - - if (low == high) return (low + 1) * step; - - current = (int) (static_cast(low + high) >> 1); - } +int Animation::search(Vector &frames, float target) { + size_t n = (int)frames.size(); + for (size_t i = 1; i < n; i++) { + if (frames[i] > target) return i - 1; + } + return n - 1; } -int Animation::binarySearch(Vector &values, float target) { - int low = 0; - int size = (int)values.size(); - int high = size - 2; - if (high == 0) return 1; - - int current = (int) (static_cast(high) >> 1); - while (true) { - if (values[(current + 1)] <= target) - low = current + 1; - else - high = current; - - if (low == high) return (low + 1); - - current = (int) (static_cast(low + high) >> 1); - } -} - -int Animation::linearSearch(Vector &values, float target, int step) { - for (int i = 0, last = (int)values.size() - step; i <= last; i += step) { - if (values[i] > target) { - return i; - } - } - - return -1; +int Animation::search(Vector &frames, float target, int step) { + size_t n = frames.size(); + for (size_t i = step; i < n; i += step) + if (frames[i] > target) return i - step; + return n - step; } diff --git a/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp b/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp index 06e83013b..4c4d348b8 100644 --- a/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/AttachmentTimeline.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp b/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp index b01bd29fd..1047cb638 100644 --- a/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/ColorTimeline.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp index 92e9a08d5..9dd757e7c 100644 --- a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp @@ -39,89 +39,111 @@ using namespace spine; RTTI_IMPL(CurveTimeline, Timeline) -const float CurveTimeline::LINEAR = 0; -const float CurveTimeline::STEPPED = 1; -const float CurveTimeline::BEZIER = 2; -const int CurveTimeline::BEZIER_SIZE = 10 * 2 - 1; - -CurveTimeline::CurveTimeline(int frameCount) { - assert(frameCount > 0); - - _curves.setSize((frameCount - 1) * BEZIER_SIZE, 0); +CurveTimeline::CurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount): Timeline(frameCount, frameEntries) { + _curves.setSize(frameCount + bezierCount * BEZIER_SIZE, 0); + _curves[frameCount - 1] = STEPPED; } CurveTimeline::~CurveTimeline() { } -size_t CurveTimeline::getFrameCount() { - return _curves.size() / BEZIER_SIZE + 1; +void CurveTimeline::setLinear(size_t frame) { + _curves[frame] = LINEAR; } -void CurveTimeline::setLinear(size_t frameIndex) { - _curves[frameIndex * BEZIER_SIZE] = LINEAR; +void CurveTimeline::setStepped(size_t frame) { + _curves[frame] = STEPPED; } -void CurveTimeline::setStepped(size_t frameIndex) { - _curves[frameIndex * BEZIER_SIZE] = STEPPED; +void CurveTimeline::setBezier (size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2) { + size_t i = getFrameCount() + bezier * BEZIER_SIZE; + if (value == 0) _curves[frame] = BEZIER + i; + float tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03; + float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 0.006; + float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + float dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667; + float x = time1 + dx, y = value1 + dy; + for (size_t n = i + 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; + } } -void CurveTimeline::setCurve(size_t frameIndex, float cx1, float cy1, float cx2, float cy2) { - float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f; - float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f; - float ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; - float dfx = cx1 * 0.3f + tmpx + dddfx * 0.16666667f, dfy = cy1 * 0.3f + tmpy + dddfy * 0.16666667f; - - size_t i = frameIndex * BEZIER_SIZE; - _curves[i++] = BEZIER; - - float x = dfx, y = dfy; - for (size_t n = i + BEZIER_SIZE - 1; i < n; i += 2) { - _curves[i] = x; - _curves[i + 1] = y; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } +float CurveTimeline::getBezierValue(float time, size_t frame, size_t valueOffset, size_t i) { + if (_curves[i] > time) { + float x = _frames[frame], y = _frames[frame + valueOffset]; + return y + (time - x) / (_curves[i] - x) * (_curves[i + 1] - y); + } + size_t n = i + 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); + } + } + frame += getFrameEntries(); + float x = _curves[n - 2], y = _curves[n - 1]; + return y + (time - x) / (_frames[frame] - x) * (_frames[frame + valueOffset] - y); } -float CurveTimeline::getCurvePercent(size_t frameIndex, float percent) { - percent = MathUtil::clamp(percent, 0, 1); - size_t i = frameIndex * BEZIER_SIZE; - float type = _curves[i]; +RTTI_IMPL(CurveTimeline1, CurveTimeline) +const int CurveTimeline1::ENTRIES = 2; +const int CurveTimeline1::VALUE = 1; - if (type == LINEAR) { - return percent; - } - - if (type == STEPPED) { - return 0; - } - - i++; - float x = 0; - for (size_t start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) { - x = _curves[i]; - if (x >= percent) { - float prevX, prevY; - if (i == start) { - prevX = 0; - prevY = 0; - } else { - prevX = _curves[i - 2]; - prevY = _curves[i - 1]; - } - return prevY + (_curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); - } - } - - float y = _curves[i - 1]; - - return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. +CurveTimeline1::CurveTimeline1(size_t frameCount, size_t bezierCount): CurveTimeline(frameCount, CurveTimeline1::ENTRIES, bezierCount) { } -float CurveTimeline::getCurveType(size_t frameIndex) { - return _curves[frameIndex * BEZIER_SIZE]; +CurveTimeline1::~CurveTimeline1() { +} + +void CurveTimeline1::setFrame(size_t frame, float time, float value) { + frame <<= 1; + _frames[frame] = time; + _frames[frame + CurveTimeline1::VALUE] = value; +} + +float CurveTimeline1::getCurveValue(float time) { + int i = _frames.size() - 2; + for (int ii = 2; ii <= i; ii += 2) { + if (_frames[ii] > time) { + i = ii - 2; + break; + } + } + + int curveType = (int)_curves[i >> 1]; + switch (curveType) { + case CurveTimeline::LINEAR: { + float before = _frames[i], value = _frames[i + CurveTimeline1::VALUE]; + return value + (time - before) / (_frames[i + CurveTimeline1::ENTRIES] - before) * + (_frames[i + CurveTimeline1::ENTRIES + CurveTimeline1::VALUE] - value); + } + case CurveTimeline::STEPPED: + return _frames[i + CurveTimeline1::VALUE]; + } + return getBezierValue(time, i, CurveTimeline1::VALUE, curveType - CurveTimeline1::BEZIER); +} + +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) { +} + +CurveTimeline2::~CurveTimeline2() { +} + +void CurveTimeline2::setFrame(size_t frame, float time, float value1, float value2) { + frame *= CurveTimeline2::ENTRIES; + _frames[frame] = time; + _frames[frame + CurveTimeline2::VALUE1] = value1; + _frames[frame + CurveTimeline2::VALUE2] = value2; } diff --git a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp index bdec6e440..b49033476 100644 --- a/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/DeformTimeline.cpp @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp b/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp index c0c2c8dbd..0204d9cf6 100644 --- a/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/DrawOrderTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp b/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp index f05552375..709caf54a 100644 --- a/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/EventTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp index fcb543f84..05ccbc9ab 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp @@ -101,10 +101,6 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY Bone *pp = parent.getParent(); float tx, ty, dx, dy, dd, l1, l2, a1, a2, r, td, sd, p; float id, x, y; - if (alpha == 0) { - child.updateWorldTransform(); - return; - } if (!parent._appliedValid) parent.updateAppliedTransform(); if (!child._appliedValid) child.updateAppliedTransform(); px = parent._ax; @@ -268,12 +264,8 @@ IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) : Updatab } } -/// Applies the constraint to the constrained bones. -void IkConstraint::apply() { - update(); -} - void IkConstraint::update() { + if (_mix == 0) return; switch (_bones.size()) { case 1: { Bone *bone0 = _bones[0]; diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp index f0e817a5d..3c4a0e019 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp index b28f80fed..e7ec0fb1c 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp @@ -57,8 +57,9 @@ PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) : U data.getTarget()->getName())), _position(data.getPosition()), _spacing(data.getSpacing()), - _rotateMix(data.getRotateMix()), - _translateMix(data.getTranslateMix()), + _mixRotate(data.getMixRotate()), + _mixX(data.getMixX()), + _mixY(data.getMixY()), _active(false) { _bones.ensureCapacity(_data.getBones().size()); @@ -70,77 +71,95 @@ PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) : U _segments.setSize(10, 0); } -void PathConstraint::apply() { - update(); -} - void PathConstraint::update() { Attachment *baseAttachment = _target->getAttachment(); if (baseAttachment == NULL || !baseAttachment->getRTTI().instanceOf(PathAttachment::rtti)) { return; } - PathAttachment *attachment = static_cast(baseAttachment); - float rotateMix = _rotateMix; - float translateMix = _translateMix; - bool translate = translateMix > 0; - bool rotate = rotateMix > 0; - if (!translate && !rotate) { - return; - } + float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY; + if (mixRotate == 0 && mixX == 0 && mixY == 0) return; PathConstraintData &data = _data; - bool percentSpacing = data._spacingMode == SpacingMode_Percent; - RotateMode rotateMode = data._rotateMode; - bool tangents = rotateMode == RotateMode_Tangent, scale = rotateMode == RotateMode_ChainScale; + bool tangents = data._rotateMode == RotateMode_Tangent, scale = data._rotateMode == RotateMode_ChainScale; size_t boneCount = _bones.size(); size_t spacesCount = tangents ? boneCount : boneCount + 1; _spaces.setSize(spacesCount, 0); + if (scale) _lengths.setSize(boneCount, 0); float spacing = _spacing; - if (scale || !percentSpacing) { - if (scale) _lengths.setSize(boneCount, 0); - bool lengthSpacing = data._spacingMode == SpacingMode_Length; - for (size_t i = 0, n = spacesCount - 1; i < n;) { - Bone *boneP = _bones[i]; - Bone &bone = *boneP; - float setupLength = bone._data.getLength(); - if (setupLength < PathConstraint::EPSILON) { - if (scale) _lengths[i] = 0; - _spaces[++i] = 0; - } else if (percentSpacing) { - if (scale) { - float x = setupLength * bone._a, y = setupLength * bone._c; - float length = MathUtil::sqrt(x * x + y * y); - _lengths[i] = length; - } - _spaces[++i] = spacing; - } else { - float x = setupLength * bone._a; - float y = setupLength * bone._c; - float length = MathUtil::sqrt(x * x + y * y); - if (scale) { - _lengths[i] = length; - } - - _spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; - } - } - } else { - for (size_t i = 1; i < spacesCount; ++i) { - _spaces[i] = spacing; - } + switch(data._spacingMode) { + case SpacingMode_Percent: { + if (scale) { + for (size_t i = 0, n = spacesCount - 1; i < n; i++) { + Bone *boneP = _bones[i]; + Bone &bone = *boneP; + float setupLength = bone._data.getLength(); + if (setupLength < PathConstraint::EPSILON) { + _lengths[i] = 0; + } else { + float x = setupLength * bone._a, y = setupLength * bone._c; + _lengths[i] = MathUtil::sqrt(x * x + y * y); + } + } + } + for (size_t i = 1; i < spacesCount; ++i) { + _spaces[i] = spacing; + } + break; + } + case SpacingMode_Proportional: { + float sum = 0; + for (size_t i = 0; i < boneCount;) { + Bone *boneP = _bones[i]; + Bone &bone = *boneP; + float setupLength = bone._data.getLength(); + if (setupLength < PathConstraint::EPSILON) { + if (scale) _lengths[i] = 0; + _spaces[++i] = spacing; + } else { + float x = setupLength * bone._a, y = setupLength * bone._c; + float length = MathUtil::sqrt(x * x + y * y); + if (scale) _lengths[i] = length; + _spaces[++i] = length; + sum += length; + } + } + if (sum > 0) { + sum = spacesCount / sum * spacing; + for (size_t i = 1; i < spacesCount; i++) { + _spaces[i] *= sum; + } + } + break; + } + default: { + bool lengthSpacing = data._spacingMode == SpacingMode_Length; + for (size_t i = 0, n = spacesCount - 1; i < n;) { + Bone *boneP = _bones[i]; + Bone &bone = *boneP; + float setupLength = bone._data.getLength(); + if (setupLength < PathConstraint::EPSILON) { + if (scale) _lengths[i] = 0; + _spaces[++i] = spacing; + } else { + float x = setupLength * bone._a, y = setupLength * bone._c; + float length = MathUtil::sqrt(x * x + y * y); + if (scale) _lengths[i] = length; + _spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } } - Vector& positions = computeWorldPositions(*attachment, spacesCount, tangents, - data.getPositionMode() == PositionMode_Percent, percentSpacing); + Vector& positions = computeWorldPositions(*attachment, spacesCount, tangents); float boneX = positions[0]; float boneY = positions[1]; float offsetRotation = data.getOffsetRotation(); bool tip; if (offsetRotation == 0) { - tip = rotateMode == RotateMode_Chain; + tip = data._rotateMode == RotateMode_Chain; } else { tip = false; Bone &p = _target->getBone(); @@ -150,8 +169,8 @@ void PathConstraint::update() { for (size_t i = 0, p = 3; i < boneCount; i++, p += 3) { Bone *boneP = _bones[i]; Bone &bone = *boneP; - bone._worldX += (boneX - bone._worldX) * translateMix; - bone._worldY += (boneY - bone._worldY) * translateMix; + bone._worldX += (boneX - bone._worldX) * mixX; + bone._worldY += (boneY - bone._worldY) * mixY; float x = positions[p]; float y = positions[p + 1]; float dx = x - boneX; @@ -159,7 +178,7 @@ void PathConstraint::update() { if (scale) { float length = _lengths[i]; if (length >= PathConstraint::EPSILON) { - float s = (MathUtil::sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; + float s = (MathUtil::sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1; bone._a *= s; bone._c *= s; } @@ -168,7 +187,7 @@ void PathConstraint::update() { boneX = x; boneY = y; - if (rotate) { + if (mixRotate > 0) { float a = bone._a, b = bone._b, c = bone._c, d = bone._d, r, cos, sin; if (tangents) r = positions[p - 1]; @@ -183,8 +202,8 @@ void PathConstraint::update() { cos = MathUtil::cos(r); sin = MathUtil::sin(r); float length = bone._data.getLength(); - boneX += (length * (cos * a - sin * c) - dx) * rotateMix; - boneY += (length * (sin * a + cos * c) - dy) * rotateMix; + boneX += (length * (cos * a - sin * c) - dx) * mixRotate; + boneY += (length * (sin * a + cos * c) - dy) * mixRotate; } else r += offsetRotation; @@ -193,7 +212,7 @@ void PathConstraint::update() { else if (r < -MathUtil::Pi) r += MathUtil::Pi_2; - r *= rotateMix; + r *= mixRotate; cos = MathUtil::cos(r); sin = MathUtil::sin(r); bone._a = cos * a - sin * c; @@ -226,20 +245,28 @@ void PathConstraint::setSpacing(float inValue) { _spacing = inValue; } -float PathConstraint::getRotateMix() { - return _rotateMix; +float PathConstraint::getMixRotate() { + return _mixRotate; } -void PathConstraint::setRotateMix(float inValue) { - _rotateMix = inValue; +void PathConstraint::setMixRotate(float inValue) { + _mixRotate = inValue; } -float PathConstraint::getTranslateMix() { - return _translateMix; +float PathConstraint::getMixX() { + return _mixX; } -void PathConstraint::setTranslateMix(float inValue) { - _translateMix = inValue; +void PathConstraint::setMixX(float inValue) { + _mixX = inValue; +} + +float PathConstraint::getMixY() { + return _mixY; +} + +void PathConstraint::setMixY(float inValue) { + _mixY = inValue; } Vector &PathConstraint::getBones() { @@ -259,7 +286,7 @@ PathConstraintData &PathConstraint::getData() { } Vector& -PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing) { +PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, bool tangents) { Slot &target = *_target; float position = _position; _positions.setSize(spacesCount * 3 + 2, 0); @@ -275,16 +302,23 @@ PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, boo Vector &lengths = path.getLengths(); curveCount -= closed ? 1 : 2; pathLength = lengths[curveCount]; - if (percentPosition) position *= pathLength; + if (_data._positionMode == PositionMode_Percent) position *= pathLength; - if (percentSpacing) { - for (int i = 1; i < spacesCount; ++i) - _spaces[i] *= pathLength; - } + float multiplier = 0; + switch (_data._spacingMode) { + case SpacingMode_Percent: + multiplier = pathLength; + break; + case SpacingMode_Proportional: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + } world.setSize(8, 0); for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { - float space = _spaces[i]; + float space = _spaces[i] * multiplier; position += space; float p = position; @@ -393,19 +427,23 @@ PathConstraint::computeWorldPositions(PathAttachment &path, int spacesCount, boo y1 = y2; } - if (percentPosition) - position *= pathLength; - else - position *= pathLength / path.getLengths()[curveCount - 1]; + if (_data._positionMode == PositionMode_Percent) position *= pathLength; - if (percentSpacing) { - for (int i = 1; i < spacesCount; ++i) - _spaces[i] *= pathLength; - } + float multiplier = 0; + switch (_data._spacingMode) { + case SpacingMode_Percent: + multiplier = pathLength; + break; + case SpacingMode_Proportional: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + } float curveLength = 0; for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { - float space = _spaces[i]; + float space = _spaces[i] * multiplier; position += space; float p = position; diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintData.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintData.cpp index 55f69dbf3..105ff9de7 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintData.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintData.cpp @@ -41,90 +41,99 @@ using namespace spine; PathConstraintData::PathConstraintData(const String &name) : - ConstraintData(name), - _target(NULL), - _positionMode(PositionMode_Fixed), - _spacingMode(SpacingMode_Length), - _rotateMode(RotateMode_Tangent), - _offsetRotation(0), - _position(0), - _spacing(0), - _rotateMix(0), - _translateMix(0) { + ConstraintData(name), + _target(NULL), + _positionMode(PositionMode_Fixed), + _spacingMode(SpacingMode_Length), + _rotateMode(RotateMode_Tangent), + _offsetRotation(0), + _position(0), + _spacing(0), + _mixRotate(0), + _mixX(0), + _mixY(0) { } Vector &PathConstraintData::getBones() { - return _bones; + return _bones; } SlotData *PathConstraintData::getTarget() { - return _target; + return _target; } void PathConstraintData::setTarget(SlotData *inValue) { - _target = inValue; + _target = inValue; } PositionMode PathConstraintData::getPositionMode() { - return _positionMode; + return _positionMode; } void PathConstraintData::setPositionMode(PositionMode inValue) { - _positionMode = inValue; + _positionMode = inValue; } SpacingMode PathConstraintData::getSpacingMode() { - return _spacingMode; + return _spacingMode; } void PathConstraintData::setSpacingMode(SpacingMode inValue) { - _spacingMode = inValue; + _spacingMode = inValue; } RotateMode PathConstraintData::getRotateMode() { - return _rotateMode; + return _rotateMode; } void PathConstraintData::setRotateMode(RotateMode inValue) { - _rotateMode = inValue; + _rotateMode = inValue; } float PathConstraintData::getOffsetRotation() { - return _offsetRotation; + return _offsetRotation; } void PathConstraintData::setOffsetRotation(float inValue) { - _offsetRotation = inValue; + _offsetRotation = inValue; } float PathConstraintData::getPosition() { - return _position; + return _position; } void PathConstraintData::setPosition(float inValue) { - _position = inValue; + _position = inValue; } float PathConstraintData::getSpacing() { - return _spacing; + return _spacing; } void PathConstraintData::setSpacing(float inValue) { - _spacing = inValue; + _spacing = inValue; } -float PathConstraintData::getRotateMix() { - return _rotateMix; +float PathConstraintData::getMixRotate() { + return _mixRotate; } -void PathConstraintData::setRotateMix(float inValue) { - _rotateMix = inValue; +void PathConstraintData::setMixRotate(float inValue) { + _mixRotate = inValue; } -float PathConstraintData::getTranslateMix() { - return _translateMix; +float PathConstraintData::getMixX() { + return _mixX; } -void PathConstraintData::setTranslateMix(float inValue) { - _translateMix = inValue; +void PathConstraintData::setMixX(float inValue) { + _mixX = inValue; +} + +float PathConstraintData::getMixY() { + return _mixY; +} + +void PathConstraintData::setMixY(float inValue) { + _mixY = inValue; } diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp index 5d4404e58..ae4e93b25 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintMixTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp index f470e4f0b..83790dd0e 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintPositionTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp index b84f46b12..edd65968f 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp index 461a5a9f0..524e2139f 100644 --- a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp @@ -103,8 +103,8 @@ void RegionAttachment::updateOffset() { _vertexOffset[BRY] = localYCos + localX2Sin; } -void RegionAttachment::setUVs(float u, float v, float u2, float v2, bool rotate) { - if (rotate) { +void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) { + if (degrees == 90) { _uvs[URX] = u; _uvs[URY] = v2; _uvs[BRX] = u; diff --git a/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp b/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp index 037363917..b6eda65f0 100644 --- a/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp @@ -39,101 +39,48 @@ #include #include #include -#include +#include using namespace spine; -RTTI_IMPL(RotateTimeline, CurveTimeline) +RTTI_IMPL(RotateTimeline, CurveTimeline1) -RotateTimeline::RotateTimeline(int frameCount) : CurveTimeline(frameCount), _boneIndex(0) { - _frames.setSize(frameCount << 1, 0); +RotateTimeline::RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_Rotate << 32) | boneIndex }; + setPropertyIds(ids, 1); } void RotateTimeline::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); - Bone *bone = skeleton.getBones()[_boneIndex]; - if (!bone->_active) return; + Bone* bone = skeleton._bones[_boneIndex]; + if (!bone->_active) return; - if (time < _frames[0]) { - switch (blend) { - case MixBlend_Setup: { - bone->_rotation = bone->_data._rotation; - break; - } - case MixBlend_First: { - float r = bone->_data._rotation - bone->_rotation; - bone->_rotation += (r - (16384 - (int) (16384.499999999996 - r / 360)) * 360) * alpha; - break; - } - default: { - // TODO? - break; - } - } - return; - } + if (time < _frames[0]) { + switch (blend) { + case MixBlend_Setup: + bone->_rotation = bone->_data._rotation; + return; + case MixBlend_First: + bone->_rotation += (bone->_data._rotation - bone->_rotation) * alpha; + default: {} + } + return; + } - if (time >= _frames[_frames.size() - ENTRIES]) { - float r = _frames[_frames.size() + PREV_ROTATION]; - switch (blend) { - case MixBlend_Setup: - bone->_rotation = bone->_data._rotation + r * alpha; - break; - case MixBlend_First: - case MixBlend_Replace: - r += bone->_data._rotation - bone->_rotation; - r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; - // Fall through. - case MixBlend_Add: - bone->_rotation += r * alpha; - } - return; - } - - // Interpolate between the previous frame and the current frame. - int frame = Animation::binarySearch(_frames, time, ENTRIES); - float prevRotation = _frames[frame + PREV_ROTATION]; - float frameTime = _frames[frame]; - float percent = getCurvePercent((frame >> 1) - 1, - 1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime)); - float r = _frames[frame + ROTATION] - prevRotation; - r = prevRotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * percent; - switch (blend) { - case MixBlend_Setup: - bone->_rotation = bone->_data._rotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha; - break; - case MixBlend_First: - case MixBlend_Replace: - r += bone->_data._rotation - bone->_rotation; - // Fall through. - case MixBlend_Add: - bone->_rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha; - } -} - -int RotateTimeline::getPropertyId() { - return ((int) TimelineType_Rotate << 24) + _boneIndex; -} - -void RotateTimeline::setFrame(int frameIndex, float time, float degrees) { - frameIndex <<= 1; - _frames[frameIndex] = time; - _frames[frameIndex + ROTATION] = degrees; -} - -int RotateTimeline::getBoneIndex() { - return _boneIndex; -} - -void RotateTimeline::setBoneIndex(int inValue) { - _boneIndex = inValue; -} - -Vector &RotateTimeline::getFrames() { - return _frames; -} + float r = getCurveValue(time); + switch (blend) { + case MixBlend_Setup: + bone->_rotation = bone->_data._rotation + r * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + r += bone->_data._rotation - bone->_rotation; + case MixBlend_Add: + bone->_rotation += r * alpha; + } +} \ No newline at end of file diff --git a/spine-cpp/spine-cpp/src/spine/ScaleTimeline.cpp b/spine-cpp/spine-cpp/src/spine/ScaleTimeline.cpp index f00e0320c..1ae428323 100644 --- a/spine-cpp/spine-cpp/src/spine/ScaleTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/ScaleTimeline.cpp @@ -43,9 +43,12 @@ using namespace spine; -RTTI_IMPL(ScaleTimeline, TranslateTimeline) +RTTI_IMPL(ScaleTimeline, CurveTimeline2) -ScaleTimeline::ScaleTimeline(int frameCount) : TranslateTimeline(frameCount) { +ScaleTimeline::ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline2(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_ScaleX << 32) | boneIndex, + ((PropertyId)Property_ScaleY << 32) | boneIndex}; + setPropertyIds(ids, 2); } void ScaleTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, @@ -54,100 +57,244 @@ void ScaleTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector SP_UNUSED(lastTime); SP_UNUSED(pEvents); - Bone *boneP = skeleton._bones[_boneIndex]; - Bone &bone = *boneP; + Bone *bone = skeleton._bones[_boneIndex]; + if (!bone->_active) return; - if (!bone._active) return; + if (time < _frames[0]) { + switch (blend) { + case MixBlend_Setup: + bone->_scaleX = bone->_data._scaleX; + bone->_scaleY = bone->_data._scaleY; + return; + case MixBlend_First: + bone->_scaleX += (bone->_data._scaleX - bone->_scaleX) * alpha; + bone->_scaleY += (bone->_data._scaleY - bone->_scaleY) * alpha; + default: {} + } + return; + } - if (time < _frames[0]) { - switch (blend) { - case MixBlend_Setup: - bone._scaleX = bone._data._scaleX; - bone._scaleY = bone._data._scaleY; - return; - case MixBlend_First: - bone._scaleX += (bone._data._scaleX - bone._scaleX) * alpha; - bone._scaleY += (bone._data._scaleY - bone._scaleY) * alpha; - default: {} - } - return; - } + float x, y; + int i = Animation::search(_frames, time, CurveTimeline2::ENTRIES); + int curveType = (int)_curves[i / CurveTimeline2::ENTRIES]; + switch (curveType) { + case CurveTimeline::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 CurveTimeline::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 *= bone->_data._scaleX; + y *= bone->_data._scaleY; - float x, y; - if (time >= _frames[_frames.size() - ENTRIES]) { - // Time is after last frame. - x = _frames[_frames.size() + PREV_X] * bone._data._scaleX; - y = _frames[_frames.size() + PREV_Y] * bone._data._scaleY; - } 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)); - - x = (x + (_frames[frame + X] - x) * percent) * bone._data._scaleX; - y = (y + (_frames[frame + Y] - y) * percent) * bone._data._scaleY; - } - - if (alpha == 1) { - if (blend == MixBlend_Add) { - bone._scaleX += x - bone._data._scaleX; - bone._scaleY += y - bone._data._scaleY; - } else { - bone._scaleX = x; - bone._scaleY = y; - } - } else { - // Mixing out uses sign of setup or current pose, else use sign of key. - float bx, by; - if (direction == MixDirection_Out) { - switch (blend) { - case MixBlend_Setup: - bx = bone._data._scaleX; - by = bone._data._scaleY; - bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; - bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; - break; - case MixBlend_First: - case MixBlend_Replace: - bx = bone._scaleX; - by = bone._scaleY; - bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; - bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; - break; - case MixBlend_Add: - bx = bone._scaleX; - by = bone._scaleY; - bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bone._data._scaleX) * alpha; - bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - bone._data._scaleY) * alpha; - } - } else { - switch (blend) { - case MixBlend_Setup: - bx = MathUtil::abs(bone._data._scaleX) * MathUtil::sign(x); - by = MathUtil::abs(bone._data._scaleY) * MathUtil::sign(y); - bone._scaleX = bx + (x - bx) * alpha; - bone._scaleY = by + (y - by) * alpha; - break; - case MixBlend_First: - case MixBlend_Replace: - bx = MathUtil::abs(bone._scaleX) * MathUtil::sign(x); - by = MathUtil::abs(bone._scaleY) * MathUtil::sign(y); - bone._scaleX = bx + (x - bx) * alpha; - bone._scaleY = by + (y - by) * alpha; - break; - case MixBlend_Add: - bx = MathUtil::sign(x); - by = MathUtil::sign(y); - bone._scaleX = MathUtil::abs(bone._scaleX) * bx + (x - MathUtil::abs(bone._data._scaleX) * bx) * alpha; - bone._scaleY = MathUtil::abs(bone._scaleY) * by + (y - MathUtil::abs(bone._data._scaleY) * by) * alpha; - } - } - } + if (alpha == 1) { + if (blend == MixBlend_Add) { + bone->_scaleX += x - bone->_data._scaleX; + bone->_scaleY += y - bone->_data._scaleY; + } else { + bone->_scaleX = x; + bone->_scaleY = y; + } + } else { + float bx, by; + if (direction == MixDirection_Out) { + switch (blend) { + case MixBlend_Setup: + bx = bone->_data._scaleX; + by = bone->_data._scaleY; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bx = bone->_scaleX; + by = bone->_scaleY; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; + break; + case MixBlend_Add: + bx = bone->_scaleX; + by = bone->_scaleY; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bone->_data._scaleX) * alpha; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - bone->_data._scaleY) * alpha; + } + } else { + switch (blend) { + case MixBlend_Setup: + bx = MathUtil::abs(bone->_data._scaleX) * MathUtil::sign(x); + by = MathUtil::abs(bone->_data._scaleY) * MathUtil::sign(y); + bone->_scaleX = bx + (x - bx) * alpha; + bone->_scaleY = by + (y - by) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bx = MathUtil::abs(bone->_scaleX) * MathUtil::sign(x); + by = MathUtil::abs(bone->_scaleY) * MathUtil::sign(y); + bone->_scaleX = bx + (x - bx) * alpha; + bone->_scaleY = by + (y - by) * alpha; + break; + case MixBlend_Add: + bx = MathUtil::sign(x); + by = MathUtil::sign(y); + bone->_scaleX = MathUtil::abs(bone->_scaleX) * bx + (x - MathUtil::abs(bone->_data._scaleX) * bx) * alpha; + bone->_scaleY = MathUtil::abs(bone->_scaleY) * by + (y - MathUtil::abs(bone->_data._scaleY) * by) * alpha; + } + } + } } -int ScaleTimeline::getPropertyId() { - return ((int) TimelineType_Scale << 24) + _boneIndex; +RTTI_IMPL(ScaleXTimeline, CurveTimeline1) + +ScaleXTimeline::ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_ScaleX << 32) | boneIndex }; + setPropertyIds(ids, 1); +} + +void ScaleXTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, + MixBlend blend, MixDirection direction +) { + SP_UNUSED(lastTime); + SP_UNUSED(pEvents); + + Bone *bone = skeleton._bones[_boneIndex]; + if (!bone->_active) return; + + if (time < _frames[0]) { + switch (blend) { + case MixBlend_Setup: + bone->_scaleX = bone->_data._scaleX; + return; + case MixBlend_First: + bone->_scaleX += (bone->_data._scaleX - bone->_scaleX) * alpha; + default: {} + } + return; + } + + float x = getCurveValue(time) * bone->_data._scaleX; + if (alpha == 1) { + if (blend == MixBlend_Add) + bone->_scaleX += x - bone->_data._scaleX; + else + bone->_scaleX = x; + } else { + // Mixing out uses sign of setup or current pose, else use sign of key. + float bx; + if (direction == MixDirection_Out) { + switch (blend) { + case MixBlend_Setup: + bx = bone->_data._scaleX; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bx = bone->_scaleX; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha; + break; + case MixBlend_Add: + bx = bone->_scaleX; + bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bone->_data._scaleX) * alpha; + } + } else { + switch (blend) { + case MixBlend_Setup: + bx = MathUtil::abs(bone->_data._scaleX) * MathUtil::sign(x); + bone->_scaleX = bx + (x - bx) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bx = MathUtil::abs(bone->_scaleX) * MathUtil::sign(x); + bone->_scaleX = bx + (x - bx) * alpha; + break; + case MixBlend_Add: + bx = MathUtil::sign(x); + bone->_scaleX = MathUtil::abs(bone->_scaleX) * bx + (x - MathUtil::abs(bone->_data._scaleX) * bx) * alpha; + } + } + } +} + +RTTI_IMPL(ScaleYTimeline, CurveTimeline1) + +ScaleYTimeline::ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_ScaleY << 32) | boneIndex }; + setPropertyIds(ids, 1); +} + +void ScaleYTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, + MixBlend blend, MixDirection direction +) { + SP_UNUSED(lastTime); + SP_UNUSED(pEvents); + + Bone *bone = skeleton._bones[_boneIndex]; + if (!bone->_active) return; + + if (time < _frames[0]) { + switch (blend) { + case MixBlend_Setup: + bone->_scaleY = bone->_data._scaleY; + return; + case MixBlend_First: + bone->_scaleY += (bone->_data._scaleY - bone->_scaleY) * alpha; + default: {} + } + return; + } + + float y = getCurveValue(time) * bone->_data._scaleY; + if (alpha == 1) { + if (blend == MixBlend_Add) + bone->_scaleY += y - bone->_data._scaleY; + else + bone->_scaleY = y; + } else { + // Mixing out uses sign of setup or current pose, else use sign of key. + float by = 0; + if (direction == MixDirection_Out) { + switch (blend) { + case MixBlend_Setup: + by = bone->_data._scaleY; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + by = bone->_scaleY; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha; + break; + case MixBlend_Add: + by = bone->_scaleY; + bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - bone->_data._scaleY) * alpha; + } + } else { + switch (blend) { + case MixBlend_Setup: + by = MathUtil::abs(bone->_data._scaleY) * MathUtil::sign(y); + bone->_scaleY = by + (y - by) * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + by = MathUtil::abs(bone->_scaleY) * MathUtil::sign(y); + bone->_scaleY = by + (y - by) * alpha; + break; + case MixBlend_Add: + by = MathUtil::sign(y); + bone->_scaleY = MathUtil::abs(bone->_scaleY) * by + (y - MathUtil::abs(bone->_data._scaleY) * by) * alpha; + } + } + } } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index f9927daad..4006966d7 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -134,7 +134,6 @@ Skeleton::~Skeleton() { void Skeleton::updateCache() { _updateCache.clear(); - _updateCacheReset.clear(); for (size_t i = 0, n = _bones.size(); i < n; ++i) { Bone* bone = _bones[i]; @@ -213,24 +212,36 @@ void Skeleton::printUpdateCache() { } void Skeleton::updateWorldTransform() { - for (size_t i = 0, n = _updateCacheReset.size(); i < n; ++i) { - Bone *boneP = _updateCacheReset[i]; - Bone &bone = *boneP; - bone._ax = bone._x; - bone._ay = bone._y; - bone._arotation = bone._rotation; - bone._ascaleX = bone._scaleX; - bone._ascaleY = bone._scaleY; - bone._ashearX = bone._shearX; - bone._ashearY = bone._shearY; - bone._appliedValid = true; - } - for (size_t i = 0, n = _updateCache.size(); i < n; ++i) { _updateCache[i]->update(); } } +void Skeleton::updateWorldTransform(Bone* parent) { + // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. + Bone& rootBone = *getRootBone(); + float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d; + rootBone._worldX = pa * _x + pb * _y + parent->_worldX; + rootBone._worldY = pc * _x + pd * _y + parent->_worldY; + + float rotationY = rootBone._rotation + 90 + rootBone._shearY; + float la = MathUtil::cosDeg(rootBone._rotation + rootBone._shearX) * rootBone._scaleX; + float lb = MathUtil::cosDeg(rotationY) * rootBone._scaleY; + float lc = MathUtil::sinDeg(rootBone._rotation + rootBone._shearX) * rootBone._scaleX; + float ld = MathUtil::sinDeg(rotationY) * rootBone._scaleY; + rootBone._a = (pa * la + pb * lc) * _scaleX; + rootBone._b = (pa * lb + pb * ld) * _scaleX; + rootBone._c = (pc * la + pd * lc) * _scaleY; + rootBone._d = (pc * lb + pd * ld) * _scaleY; + + // Update everything except root bone. + Bone *rb = getRootBone(); + for (size_t i = 0, n = _updateCache.size(); i < n; i++) { + Updatable *updatable = _updateCache[i]; + if (updatable != rb) updatable->update(); + } +} + void Skeleton::setToSetupPose() { setBonesToSetupPose(); setSlotsToSetupPose(); @@ -257,10 +268,12 @@ void Skeleton::setBonesToSetupPose() { TransformConstraint &constraint = *constraintP; TransformConstraintData &constraintData = constraint._data; - constraint._rotateMix = constraintData._rotateMix; - constraint._translateMix = constraintData._translateMix; - constraint._scaleMix = constraintData._scaleMix; - constraint._shearMix = constraintData._shearMix; + constraint._mixRotate = constraintData._mixRotate; + constraint._mixX = constraintData._mixX; + constraint._mixY = constraintData._mixY; + constraint._mixScaleX = constraintData._mixScaleX; + constraint._mixScaleY = constraintData._mixScaleY; + constraint._mixShearY = constraintData._mixShearY; } for (size_t i = 0, n = _pathConstraints.size(); i < n; ++i) { @@ -270,8 +283,9 @@ void Skeleton::setBonesToSetupPose() { constraint._position = constraintData._position; constraint._spacing = constraintData._spacing; - constraint._rotateMix = constraintData._rotateMix; - constraint._translateMix = constraintData._translateMix; + constraint._mixRotate = constraintData._mixRotate; + constraint._mixX = constraintData._mixX; + constraint._mixY = constraintData._mixY; } } @@ -563,15 +577,18 @@ void Skeleton::sortIkConstraint(IkConstraint *constraint) { Bone *parent = constrained[0]; sortBone(parent); - if (constrained.size() > 1) { - Bone *child = constrained[constrained.size() - 1]; - if (!_updateCache.contains(child)) _updateCacheReset.add(child); + if (constrained.size() == 1) { + _updateCache.add(constraint); + sortReset(parent->_children); + } else { + Bone* child = constrained[constrained.size() - 1]; + sortBone(child); + + _updateCache.add(constraint); + + sortReset(parent->_children); + child->_sorted = true; } - - _updateCache.add(constraint); - - sortReset(parent->getChildren()); - constrained[constrained.size() - 1]->_sorted = true; } void Skeleton::sortPathConstraint(PathConstraint *constraint) { @@ -617,7 +634,7 @@ void Skeleton::sortTransformConstraint(TransformConstraint *constraint) { for (size_t i = 0; i < boneCount; i++) { Bone *child = constrained[i]; sortBone(child->getParent()); - if (!_updateCache.contains(child)) _updateCacheReset.add(child); + sortBone(child); } } else { for (size_t i = 0; i < boneCount; ++i) { diff --git a/spine-cpp/spine-cpp/src/spine/Timeline.cpp b/spine-cpp/spine-cpp/src/spine/Timeline.cpp index 23bf723ef..9fa9eda2a 100644 --- a/spine-cpp/spine-cpp/src/spine/Timeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/Timeline.cpp @@ -39,10 +39,39 @@ namespace spine { RTTI_IMPL_NOPARENT(Timeline) -Timeline::Timeline() { +Timeline::Timeline(size_t frameCount, size_t frameEntries): _propertyIds(), _frames(), _frameEntries(frameEntries) { + _frames.setSize(frameCount * frameEntries, 0); } Timeline::~Timeline() { } +Vector &Timeline::getPropertyIds() { + return _propertyIds; +} + +void Timeline::setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount) { + _propertyIds.clear(); + _propertyIds.ensureCapacity(propertyIdsCount); + for (size_t i = 0; i < propertyIdsCount; i++) { + _propertyIds.add(propertyIds[i]); + } +} + +size_t Timeline::getFrameCount() { + return _frames.size() / _frameEntries; +} + +Vector &Timeline::getFrames() { + return _frames; +} + +size_t Timeline::getFrameEntries() { + return _frameEntries; +} + +float Timeline::getDuration() { + return _frames[_frames.size() - getFrameEntries()]; +} + } diff --git a/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp b/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp index c2ac1b5ab..db173cd03 100644 --- a/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp @@ -45,18 +45,14 @@ RTTI_IMPL(TransformConstraint, Updatable) TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton &skeleton) : Updatable(), _data(data), - _target(skeleton.findBone( - data.getTarget()->getName())), - _rotateMix( - data.getRotateMix()), - _translateMix( - data.getTranslateMix()), - _scaleMix( - data.getScaleMix()), - _shearMix( - data.getShearMix()), - _active(false) -{ + _target(skeleton.findBone(data.getTarget()->getName())), + _mixRotate(data.getMixRotate()), + _mixX(data.getMixX()), + _mixY(data.getMixY()), + _mixScaleX(data.getMixScaleX()), + _mixScaleY(data.getMixScaleY()), + _mixShearY(data.getMixShearY()), + _active(false) { _bones.ensureCapacity(_data.getBones().size()); for (size_t i = 0; i < _data.getBones().size(); ++i) { BoneData *boneData = _data.getBones()[i]; @@ -64,11 +60,9 @@ TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton } } -void TransformConstraint::apply() { - update(); -} - void TransformConstraint::update() { + if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleX == 0 && _mixShearY == 0) return; + if (_data.isLocal()) { if (_data.isRelative()) applyRelativeLocal(); @@ -102,40 +96,57 @@ void TransformConstraint::setTarget(Bone *inValue) { _target = inValue; } -float TransformConstraint::getRotateMix() { - return _rotateMix; +float TransformConstraint::getMixRotate() { + return _mixRotate; } -void TransformConstraint::setRotateMix(float inValue) { - _rotateMix = inValue; +void TransformConstraint::setMixRotate(float inValue) { + _mixRotate = inValue; } -float TransformConstraint::getTranslateMix() { - return _translateMix; +float TransformConstraint::getMixX() { + return _mixX; } -void TransformConstraint::setTranslateMix(float inValue) { - _translateMix = inValue; +void TransformConstraint::setMixX(float inValue) { + _mixX = inValue; } -float TransformConstraint::getScaleMix() { - return _scaleMix; +float TransformConstraint::getMixY() { + return _mixY; } -void TransformConstraint::setScaleMix(float inValue) { - _scaleMix = inValue; +void TransformConstraint::setMixY(float inValue) { + _mixY = inValue; } -float TransformConstraint::getShearMix() { - return _shearMix; +void TransformConstraint::setMixScaleX(float inValue) { + _mixScaleX = inValue; } -void TransformConstraint::setShearMix(float inValue) { - _shearMix = inValue; +float TransformConstraint::getMixScaleX() { + return _mixScaleX; +} + +float TransformConstraint::getMixScaleY() { + return _mixScaleY; +} + +void TransformConstraint::setMixScaleY(float inValue) { + _mixScaleY = inValue; +} + +float TransformConstraint::getMixShearY() { + return _mixShearY; +} + +void TransformConstraint::setMixShearY(float inValue) { + _mixShearY = inValue; } void TransformConstraint::applyAbsoluteWorld() { - float rotateMix = _rotateMix, translateMix = _translateMix, scaleMix = _scaleMix, shearMix = _shearMix; + float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY; + bool translate = mixX != 0 || mixY != 0; Bone &target = *_target; float ta = target._a, tb = target._b, tc = target._c, td = target._d; float degRadReflect = ta * td - tb * tc > 0 ? MathUtil::Deg_Rad : -MathUtil::Deg_Rad; @@ -145,9 +156,7 @@ void TransformConstraint::applyAbsoluteWorld() { Bone *item = _bones[i]; Bone &bone = *item; - bool modified = false; - - if (rotateMix != 0) { + if (mixRotate != 0) { float a = bone._a, b = bone._b, c = bone._c, d = bone._d; float r = MathUtil::atan2(tc, ta) - MathUtil::atan2(c, a) + offsetRotation; if (r > MathUtil::Pi) @@ -155,38 +164,36 @@ void TransformConstraint::applyAbsoluteWorld() { else if (r < -MathUtil::Pi) r += MathUtil::Pi_2; - r *= rotateMix; + r *= mixRotate; float cos = MathUtil::cos(r), sin = MathUtil::sin(r); bone._a = cos * a - sin * c; bone._b = cos * b - sin * d; bone._c = sin * a + cos * c; bone._d = sin * b + cos * d; - modified = true; } - if (translateMix != 0) { + if (translate) { float tx, ty; target.localToWorld(_data._offsetX, _data._offsetY, tx, ty); - bone._worldX += (tx - bone._worldX) * translateMix; - bone._worldY += (ty - bone._worldY) * translateMix; - modified = true; + bone._worldX += (tx - bone._worldX) * mixX; + bone._worldY += (ty - bone._worldY) * mixY; } - if (scaleMix > 0) { + if (mixScaleX > 0) { float s = MathUtil::sqrt(bone._a * bone._a + bone._c * bone._c); - - if (s > 0.00001f) s = (s + (MathUtil::sqrt(ta * ta + tc * tc) - s + _data._offsetScaleX) * scaleMix) / s; + if (s != 0) s = (s + (MathUtil::sqrt(ta * ta + tc * tc) - s + _data._offsetScaleX) * mixScaleX) / s; bone._a *= s; bone._c *= s; - s = MathUtil::sqrt(bone._b * bone._b + bone._d * bone._d); - - if (s > 0.00001f) s = (s + (MathUtil::sqrt(tb * tb + td * td) - s + _data._offsetScaleY) * scaleMix) / s; - bone._b *= s; - bone._d *= s; - modified = true; } - if (shearMix > 0) { + if (mixScaleY > 0) { + float s = MathUtil::sqrt(bone._b * bone._b + bone._d * bone._d); + if (s != 0) s = (s + (MathUtil::sqrt(tb * tb + td * td) - s + _data._offsetScaleY) * mixScaleY) / s; + bone._b *= s; + bone._d *= s; + } + + if (mixShearY > 0) { float b = bone._b, d = bone._d; float by = MathUtil::atan2(d, b); float r = MathUtil::atan2(td, tb) - MathUtil::atan2(tc, ta) - (by - MathUtil::atan2(bone._c, bone._a)); @@ -195,19 +202,19 @@ void TransformConstraint::applyAbsoluteWorld() { else if (r < -MathUtil::Pi) r += MathUtil::Pi_2; - r = by + (r + offsetShearY) * shearMix; + r = by + (r + offsetShearY) * mixShearY; float s = MathUtil::sqrt(b * b + d * d); bone._b = MathUtil::cos(r) * s; bone._d = MathUtil::sin(r) * s; - modified = true; } - if (modified) bone._appliedValid = false; + bone._appliedValid = false; } } void TransformConstraint::applyRelativeWorld() { - float rotateMix = _rotateMix, translateMix = _translateMix, scaleMix = _scaleMix, shearMix = _shearMix; + float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY; + bool translate = mixX != 0 || mixY != 0; Bone &target = *_target; float ta = target._a, tb = target._b, tc = target._c, td = target._d; float degRadReflect = ta * td - tb * tc > 0 ? MathUtil::Deg_Rad : -MathUtil::Deg_Rad; @@ -216,9 +223,7 @@ void TransformConstraint::applyRelativeWorld() { Bone *item = _bones[i]; Bone &bone = *item; - bool modified = false; - - if (rotateMix != 0) { + if (mixRotate != 0) { float a = bone._a, b = bone._b, c = bone._c, d = bone._d; float r = MathUtil::atan2(tc, ta) + offsetRotation; if (r > MathUtil::Pi) @@ -226,34 +231,33 @@ void TransformConstraint::applyRelativeWorld() { else if (r < -MathUtil::Pi) r += MathUtil::Pi_2; - r *= rotateMix; + r *= mixRotate; float cos = MathUtil::cos(r), sin = MathUtil::sin(r); bone._a = cos * a - sin * c; bone._b = cos * b - sin * d; bone._c = sin * a + cos * c; bone._d = sin * b + cos * d; - modified = true; } - if (translateMix != 0) { + if (translate) { float tx, ty; target.localToWorld(_data._offsetX, _data._offsetY, tx, ty); - bone._worldX += tx * translateMix; - bone._worldY += ty * translateMix; - modified = true; + bone._worldX += tx * mixX; + bone._worldY += ty * mixY; } - if (scaleMix > 0) { - float s = (MathUtil::sqrt(ta * ta + tc * tc) - 1 + _data._offsetScaleX) * scaleMix + 1; - bone._a *= s; - bone._c *= s; - s = (MathUtil::sqrt(tb * tb + td * td) - 1 + _data._offsetScaleY) * scaleMix + 1; - bone._b *= s; - bone._d *= s; - modified = true; - } + if (mixScaleX != 0) { + float s = (MathUtil::sqrt(ta * ta + tc * tc) - 1 + _data._offsetScaleX) * mixScaleX + 1; + bone._a *= s; + bone._c *= s; + } + if (mixScaleY != 0) { + float s = (MathUtil::sqrt(tb * tb + td * td) - 1 + _data._offsetScaleY) * mixScaleY + 1; + bone._b *= s; + bone._d *= s; + } - if (shearMix > 0) { + if (mixShearY > 0) { float r = MathUtil::atan2(td, tb) - MathUtil::atan2(tc, ta); if (r > MathUtil::Pi) r -= MathUtil::Pi_2; @@ -261,19 +265,18 @@ void TransformConstraint::applyRelativeWorld() { r += MathUtil::Pi_2; float b = bone._b, d = bone._d; - r = MathUtil::atan2(d, b) + (r - MathUtil::Pi / 2 + offsetShearY) * shearMix; + r = MathUtil::atan2(d, b) + (r - MathUtil::Pi / 2 + offsetShearY) * mixShearY; float s = MathUtil::sqrt(b * b + d * d); bone._b = MathUtil::cos(r) * s; bone._d = MathUtil::sin(r) * s; - modified = true; } - if (modified) bone._appliedValid = false; + bone._appliedValid = false; } } void TransformConstraint::applyAbsoluteLocal() { - float rotateMix = _rotateMix, translateMix = _translateMix, scaleMix = _scaleMix, shearMix = _shearMix; + float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY; Bone &target = *_target; if (!target._appliedValid) target.updateAppliedTransform(); @@ -284,29 +287,27 @@ void TransformConstraint::applyAbsoluteLocal() { if (!bone._appliedValid) bone.updateAppliedTransform(); float rotation = bone._arotation; - if (rotateMix != 0) { + if (mixRotate != 0) { float r = target._arotation - rotation + _data._offsetRotation; r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360; - rotation += r * rotateMix; + rotation += r * mixRotate; } float x = bone._ax, y = bone._ay; - if (translateMix != 0) { - x += (target._ax - x + _data._offsetX) * translateMix; - y += (target._ay - y + _data._offsetY) * translateMix; - } + x += (target._ax - x + _data._offsetX) * mixX; + y += (target._ay - y + _data._offsetY) * mixY; float scaleX = bone._ascaleX, scaleY = bone._ascaleY; - if (scaleMix != 0) { - if (scaleX > 0.00001f) scaleX = (scaleX + (target._ascaleX - scaleX + _data._offsetScaleX) * scaleMix) / scaleX; - if (scaleY > 0.00001f) scaleY = (scaleY + (target._ascaleY - scaleY + _data._offsetScaleY) * scaleMix) / scaleY; - } + if (mixScaleX != 0 && scaleX != 0) + scaleX = (scaleX + (target._ascaleX - scaleX + _data._offsetScaleX) * mixScaleX) / scaleX; + if (mixScaleY != 0 && scaleY != 0) + scaleY = (scaleY + (target._ascaleY - scaleY + _data._offsetScaleY) * mixScaleY) / scaleY; - float shearY = bone._ashearY; - if (shearMix != 0) { + float shearY = bone._ashearY; + if (mixShearY != 0) { float r = target._ashearY - shearY + _data._offsetShearY; r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360; - bone._shearY += r * shearMix; + bone._shearY += r * mixShearY; } bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY); @@ -314,7 +315,7 @@ void TransformConstraint::applyAbsoluteLocal() { } void TransformConstraint::applyRelativeLocal() { - float rotateMix = _rotateMix, translateMix = _translateMix, scaleMix = _scaleMix, shearMix = _shearMix; + float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY; Bone &target = *_target; if (!target._appliedValid) target.updateAppliedTransform(); @@ -324,25 +325,14 @@ void TransformConstraint::applyRelativeLocal() { if (!bone._appliedValid) bone.updateAppliedTransform(); - float rotation = bone._arotation; - if (rotateMix != 0) rotation += (target._arotation + _data._offsetRotation) * rotateMix; + float rotation = bone._arotation + (target._arotation + _data._offsetRotation) * mixRotate; + float x = bone._ax + (target._ax + _data._offsetX) * mixX; + float y = bone._ay + (target._ay + _data._offsetY) * mixY; + float scaleX = (bone._ascaleX * ((target._ascaleX - 1 + _data._offsetScaleX) * mixScaleX) + 1); + float scaleY = (bone._ascaleY * ((target._ascaleY - 1 + _data._offsetScaleY) * mixScaleY) + 1); + float shearY = bone._ashearY + (target._ashearY + _data._offsetShearY) * mixShearY; - float x = bone._ax, y = bone._ay; - if (translateMix != 0) { - x += (target._ax + _data._offsetX) * translateMix; - y += (target._ay + _data._offsetY) * translateMix; - } - - float scaleX = bone._ascaleX, scaleY = bone._ascaleY; - if (scaleMix != 0) { - if (scaleX > 0.00001f) scaleX *= ((target._ascaleX - 1 + _data._offsetScaleX) * scaleMix) + 1; - if (scaleY > 0.00001f) scaleY *= ((target._ascaleY - 1 + _data._offsetScaleY) * scaleMix) + 1; - } - - float shearY = bone._ashearY; - if (shearMix != 0) shearY += (target._ashearY + _data._offsetShearY) * shearMix; - - bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY); + bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY); } } diff --git a/spine-cpp/spine-cpp/src/spine/TransformConstraintData.cpp b/spine-cpp/spine-cpp/src/spine/TransformConstraintData.cpp index 52cf4540d..d53d0b957 100644 --- a/spine-cpp/spine-cpp/src/spine/TransformConstraintData.cpp +++ b/spine-cpp/spine-cpp/src/spine/TransformConstraintData.cpp @@ -41,10 +41,12 @@ using namespace spine; TransformConstraintData::TransformConstraintData(const String &name) : ConstraintData(name), _target(NULL), - _rotateMix(0), - _translateMix(0), - _scaleMix(0), - _shearMix(0), + _mixRotate(0), + _mixX(0), + _mixY(0), + _mixScaleX(0), + _mixScaleY(0), + _mixShearY(0), _offsetRotation(0), _offsetX(0), _offsetY(0), @@ -63,20 +65,28 @@ BoneData *TransformConstraintData::getTarget() { return _target; } -float TransformConstraintData::getRotateMix() { - return _rotateMix; +float TransformConstraintData::getMixRotate() { + return _mixRotate; } -float TransformConstraintData::getTranslateMix() { - return _translateMix; +float TransformConstraintData::getMixX() { + return _mixX; } -float TransformConstraintData::getScaleMix() { - return _scaleMix; +float TransformConstraintData::getMixY() { + return _mixY; } -float TransformConstraintData::getShearMix() { - return _shearMix; +float TransformConstraintData::getMixScaleX() { + return _mixScaleX; +} + +float TransformConstraintData::getMixScaleY() { + return _mixScaleY; +} + +float TransformConstraintData::getMixShearY() { + return _mixShearY; } float TransformConstraintData::getOffsetRotation() { diff --git a/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp index 2da77e8b4..e2a5b03dd 100644 --- a/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/TransformConstraintTimeline.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/TranslateTimeline.cpp b/spine-cpp/spine-cpp/src/spine/TranslateTimeline.cpp index 09f9b065f..4661b42b7 100644 --- a/spine-cpp/spine-cpp/src/spine/TranslateTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/TranslateTimeline.cpp @@ -43,18 +43,12 @@ using namespace spine; -RTTI_IMPL(TranslateTimeline, CurveTimeline) +RTTI_IMPL(TranslateTimeline, CurveTimeline2) -const int TranslateTimeline::ENTRIES = 3; -const int TranslateTimeline::PREV_TIME = -3; -const int TranslateTimeline::PREV_X = -2; -const int TranslateTimeline::PREV_Y = -1; -const int TranslateTimeline::X = 1; -const int TranslateTimeline::Y = 2; - -TranslateTimeline::TranslateTimeline(int frameCount) : CurveTimeline(frameCount), _boneIndex(0) { - _frames.ensureCapacity(frameCount * ENTRIES); - _frames.setSize(frameCount * ENTRIES, 0); +TranslateTimeline::TranslateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline2(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_X << 32) | boneIndex, + ((PropertyId)Property_Y << 32) | boneIndex}; + setPropertyIds(ids, 2); } TranslateTimeline::~TranslateTimeline() { @@ -67,65 +61,152 @@ void TranslateTimeline::apply(Skeleton &skeleton, float lastTime, float time, Ve 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._x = bone._data._x; - bone._y = bone._data._y; - return; - case MixBlend_First: - bone._x += (bone._data._x - bone._x) * alpha; - bone._y += (bone._data._y - bone._y) * alpha; - default: {} - } - return; - } + if (time < _frames[0]) { + switch (blend) { + case MixBlend_Setup: + bone->_x = bone->_data._x; + bone->_y = bone->_data._y; + return; + case MixBlend_First: + bone->_x += (bone->_data._x - bone->_x) * alpha; + bone->_y += (bone->_data._y - bone->_y) * 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 = 0, y = 0; + int i = Animation::search(_frames, time, CurveTimeline2::ENTRIES); + int curveType = (int)_curves[i / CurveTimeline2::ENTRIES]; + switch (curveType) { + case CurveTimeline::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 CurveTimeline::STEPPED: { + x = _frames[i + CurveTimeline2::VALUE1]; + y = _frames[i + CurveTimeline2::VALUE2]; + break; + } + default: { + x = getBezierValue(time, i, CurveTimeline2::VALUE1, curveType - CurveTimeline::BEZIER); + y = getBezierValue(time, i, CurveTimeline2::VALUE2, + curveType + CurveTimeline::BEZIER_SIZE - CurveTimeline::BEZIER); + } + } - x += (_frames[frame + X] - x) * percent; - y += (_frames[frame + Y] - y) * percent; - } - - switch (blend) { - case MixBlend_Setup: - bone._x = bone._data._x + x * alpha; - bone._y = bone._data._y + y * alpha; - break; - case MixBlend_First: - case MixBlend_Replace: - bone._x += (bone._data._x + x - bone._x) * alpha; - bone._y += (bone._data._y + y - bone._y) * alpha; - break; - case MixBlend_Add: - bone._x += x * alpha; - bone._y += y * alpha; - } + switch (blend) { + case MixBlend_Setup: + bone->_x = bone->_data._x + x * alpha; + bone->_y = bone->_data._y + y * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bone->_x += (bone->_data._x + x - bone->_x) * alpha; + bone->_y += (bone->_data._y + y - bone->_y) * alpha; + break; + case MixBlend_Add: + bone->_x += x * alpha; + bone->_y += y * alpha; + } } -int TranslateTimeline::getPropertyId() { - return ((int) TimelineType_Translate << 24) + _boneIndex; +RTTI_IMPL(TranslateXTimeline, CurveTimeline1) + +TranslateXTimeline::TranslateXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_X << 32) | boneIndex }; + setPropertyIds(ids, 1); } -void TranslateTimeline::setFrame(int frameIndex, float time, float x, float y) { - frameIndex *= ENTRIES; - _frames[frameIndex] = time; - _frames[frameIndex + X] = x; - _frames[frameIndex + Y] = y; +TranslateXTimeline::~TranslateXTimeline() { +} + +void TranslateXTimeline::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->_x = bone->_data._x; + return; + case MixBlend_First: + bone->_x += (bone->_data._x - bone->_x) * alpha; + default: {} + } + return; + } + + float x = getCurveValue(time); + switch (blend) { + case MixBlend_Setup: + bone->_x = bone->_data._x + x * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bone->_x += (bone->_data._x + x - bone->_x) * alpha; + break; + case MixBlend_Add: + bone->_x += x * alpha; + } +} + +RTTI_IMPL(TranslateYTimeline, CurveTimeline1) + +TranslateYTimeline::TranslateYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : CurveTimeline1(frameCount, bezierCount), _boneIndex(boneIndex) { + PropertyId ids[] = { ((PropertyId)Property_Y << 32) | boneIndex }; + setPropertyIds(ids, 1); +} + +TranslateYTimeline::~TranslateYTimeline() { +} + +void TranslateYTimeline::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->_y = bone->_data._y; + return; + case MixBlend_First: + bone->_y += (bone->_data._y - bone->_y) * alpha; + default: {} + } + return; + } + + float y = getCurveValue(time); + switch (blend) { + case MixBlend_Setup: + bone->_y = bone->_data._y + y * alpha; + break; + case MixBlend_First: + case MixBlend_Replace: + bone->_y += (bone->_data._y + y - bone->_y) * alpha; + break; + case MixBlend_Add: + bone->_y += y * alpha; + } } diff --git a/spine-cpp/spine-cpp/src/spine/TwoColorTimeline.cpp b/spine-cpp/spine-cpp/src/spine/TwoColorTimeline.cpp index 89d34d85e..e06221318 100644 --- a/spine-cpp/spine-cpp/src/spine/TwoColorTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/TwoColorTimeline.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp index 9ff2cdaf7..8aa974e20 100644 --- a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp @@ -157,8 +157,7 @@ void VertexAttachment::setDeformAttachment(VertexAttachment* attachment) { int VertexAttachment::getNextID() { static int nextID = 0; - - return (nextID++ & 65535) << 11; + return nextID++; } void VertexAttachment::copyTo(VertexAttachment* other) { diff --git a/spine-sfml/cpp/CMakeLists.txt b/spine-sfml/cpp/CMakeLists.txt index f3052e87c..864bcc7f5 100644 --- a/spine-sfml/cpp/CMakeLists.txt +++ b/spine-sfml/cpp/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8.9) # -# First download and extract SFML 2.3.2 for the respective OS we are on +# First download and extract SFML 2.4.1 for the respective OS we are on # set(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/dependencies/") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")