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")