diff --git a/spine-c/spine-c/include/spine/Animation.h b/spine-c/spine-c/include/spine/Animation.h index a656b8a08..5677fceae 100644 --- a/spine-c/spine-c/include/spine/Animation.h +++ b/spine-c/spine-c/include/spine/Animation.h @@ -452,7 +452,7 @@ typedef struct spIkConstraintTimeline { SP_API spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount); -SP_API void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /**boolean**/ stretch); +SP_API void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ compress, int /**boolean**/ stretch); #ifdef SPINE_SHORT_NAMES typedef spIkConstraintTimeline IkConstraintTimeline; diff --git a/spine-c/spine-c/include/spine/IkConstraint.h b/spine-c/spine-c/include/spine/IkConstraint.h index 33b98087b..65a9bb411 100644 --- a/spine-c/spine-c/include/spine/IkConstraint.h +++ b/spine-c/spine-c/include/spine/IkConstraint.h @@ -49,6 +49,7 @@ typedef struct spIkConstraint { spBone* target; int bendDirection; + int /*boolean*/ compress; int /*boolean*/ stretch; float mix; @@ -70,7 +71,7 @@ SP_API void spIkConstraint_dispose (spIkConstraint* self); SP_API void spIkConstraint_apply (spIkConstraint* self); -SP_API void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ stretch, float alpha); +SP_API void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch, int /*boolean*/ uniform, float alpha); SP_API void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDirection, int /*boolean*/ stretch, float alpha); #ifdef SPINE_SHORT_NAMES diff --git a/spine-c/spine-c/include/spine/IkConstraintData.h b/spine-c/spine-c/include/spine/IkConstraintData.h index 7fa910193..f533a74db 100644 --- a/spine-c/spine-c/include/spine/IkConstraintData.h +++ b/spine-c/spine-c/include/spine/IkConstraintData.h @@ -46,7 +46,9 @@ typedef struct spIkConstraintData { spBoneData* target; int bendDirection; + int /*boolean*/ compress; int /*boolean*/ stretch; + int /*boolean*/ uniform; float mix; #ifdef __cplusplus @@ -56,7 +58,9 @@ typedef struct spIkConstraintData { bones(0), target(0), bendDirection(0), + compress(0), stretch(0), + uniform(0), mix(0) { } #endif diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index 38cc5f249..de85dc7db 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/spine-c/spine-c/src/spine/Animation.c @@ -1282,8 +1282,8 @@ void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, fl /**/ -static const int IKCONSTRAINT_PREV_TIME = -4, IKCONSTRAINT_PREV_MIX = -3, IKCONSTRAINT_PREV_BEND_DIRECTION = -2, IKCONSTRAINT_PREV_STRETCH = -1; -static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2, IKCONSTRAINT_STRETCH = 3; +static const int IKCONSTRAINT_PREV_TIME = -5, IKCONSTRAINT_PREV_MIX = -4, IKCONSTRAINT_PREV_BEND_DIRECTION = -3, IKCONSTRAINT_PREV_COMPRESS = -2, IKCONSTRAINT_PREV_STRETCH = -1; +static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2, IKCONSTRAINT_COMPRESS = 3, IKCONSTRAINT_STRETCH = 4; void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) { @@ -1301,11 +1301,13 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel case SP_MIX_BLEND_SETUP: constraint->mix = constraint->data->mix; constraint->bendDirection = constraint->data->bendDirection; + constraint->compress = constraint->data->compress; constraint->stretch = constraint->data->stretch; return; case SP_MIX_BLEND_FIRST: constraint->mix += (constraint->data->mix - constraint->mix) * alpha; constraint->bendDirection = constraint->data->bendDirection; + constraint->compress = constraint->data->compress; constraint->stretch = constraint->data->stretch; case SP_MIX_BLEND_REPLACE: case SP_MIX_BLEND_ADD: @@ -1321,15 +1323,18 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha; if (direction == SP_MIX_DIRECTION_OUT) { constraint->bendDirection = constraint->data->bendDirection; + constraint->compress = constraint->data->compress; constraint->stretch = constraint->data->stretch; } else { constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION]; + constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0; constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0; } } else { constraint->mix += (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha; if (direction == SP_MIX_DIRECTION_IN) { constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION]; + constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0; constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0; } } @@ -1346,15 +1351,18 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha; if (direction == SP_MIX_DIRECTION_OUT) { constraint->bendDirection = constraint->data->bendDirection; + constraint->compress = constraint->data->compress; constraint->stretch = constraint->data->stretch; } else { constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION]; + constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0; constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0; } } else { constraint->mix += (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha; if (direction == SP_MIX_DIRECTION_IN) { constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION]; + constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0; constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0; } } @@ -1372,11 +1380,12 @@ spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) { return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply, _spIkConstraintTimeline_getPropertyId); } -void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ stretch) { +void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ compress, int /*boolean*/ stretch) { frameIndex *= IKCONSTRAINT_ENTRIES; self->frames[frameIndex] = time; self->frames[frameIndex + IKCONSTRAINT_MIX] = mix; self->frames[frameIndex + IKCONSTRAINT_BEND_DIRECTION] = (float)bendDirection; + self->frames[frameIndex + IKCONSTRAINT_COMPRESS] = compress ? 1 : 0; self->frames[frameIndex + IKCONSTRAINT_STRETCH] = stretch ? 1 : 0; } diff --git a/spine-c/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c index e53206b9c..d54a13225 100644 --- a/spine-c/spine-c/src/spine/AnimationState.c +++ b/spine-c/spine-c/src/spine/AnimationState.c @@ -554,11 +554,11 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* /* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */ r1 = blend == SP_MIX_BLEND_SETUP ? bone->data->rotation : bone->rotation; diff = r2 - r1; + diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360; if (diff == 0) { total = timelinesRotation[i]; } else { float lastTotal, lastDiff; - diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360; if (firstFrame) { lastTotal = 0; lastDiff = diff; diff --git a/spine-c/spine-c/src/spine/IkConstraint.c b/spine-c/spine-c/src/spine/IkConstraint.c index d93bab8b2..06ad400dd 100644 --- a/spine-c/spine-c/src/spine/IkConstraint.c +++ b/spine-c/spine-c/src/spine/IkConstraint.c @@ -39,6 +39,7 @@ spIkConstraint *spIkConstraint_create(spIkConstraintData *data, const spSkeleton spIkConstraint *self = NEW(spIkConstraint); CONST_CAST(spIkConstraintData*, self->data) = data; self->bendDirection = data->bendDirection; + self->compress = data->compress; self->stretch = data->stretch; self->mix = data->mix; @@ -59,7 +60,7 @@ void spIkConstraint_dispose(spIkConstraint *self) { void spIkConstraint_apply(spIkConstraint *self) { switch (self->bonesCount) { case 1: - spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->stretch, self->mix); + spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->compress, self->stretch, self->data->uniform, self->mix); break; case 2: spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY, self->bendDirection, self->stretch, self->mix); @@ -67,9 +68,9 @@ void spIkConstraint_apply(spIkConstraint *self) { } } -void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ stretch, float alpha) { +void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch, int /*boolean*/ uniform, float alpha) { spBone* p = bone->parent; - float id, x, y, tx, ty, rotationIK, sx; + float id, x, y, tx, ty, rotationIK, sx, sy, s; if (!bone->appliedValid) spBone_updateAppliedTransform(bone); id = 1 / (p->a * p->d - p->b * p->c); x = targetX - p->worldX, y = targetY - p->worldY; @@ -79,12 +80,17 @@ void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*bo if (rotationIK > 180) rotationIK -= 360; else if (rotationIK < -180) rotationIK += 360; sx = bone->ascaleX; - if (stretch) { + sy = bone->ascaleY; + if (compress || stretch) { float b = bone->data->length * sx, dd = SQRT(tx * tx + ty * ty); - if (dd > b && b > 0.0001f) sx *= (dd / b - 1) * alpha - 1; + if ((compress && dd < b) || (stretch && dd > b) && (b > 0.0001f)) { + s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) sy *= s; + } } spBone_updateWorldTransformWith(bone, bone->ax, bone->ay, bone->arotation + rotationIK * alpha, sx, - bone->ascaleY, bone->ashearX, bone->ashearY); + sy, bone->ashearX, bone->ashearY); } void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, int /*boolean*/ stretch, float alpha) { diff --git a/spine-c/spine-c/src/spine/IkConstraintData.c b/spine-c/spine-c/src/spine/IkConstraintData.c index dc43dae6c..522012e86 100644 --- a/spine-c/spine-c/src/spine/IkConstraintData.c +++ b/spine-c/spine-c/src/spine/IkConstraintData.c @@ -35,7 +35,9 @@ spIkConstraintData* spIkConstraintData_create (const char* name) { spIkConstraintData* self = NEW(spIkConstraintData); MALLOC_STR(self->name, name); self->bendDirection = 1; + self->compress = 0; self->stretch = 0; + self->uniform = 0; self->mix = 1; return self; } diff --git a/spine-c/spine-c/src/spine/Skeleton.c b/spine-c/spine-c/src/spine/Skeleton.c index 231dc4c65..eb8e47aa1 100644 --- a/spine-c/spine-c/src/spine/Skeleton.c +++ b/spine-c/spine-c/src/spine/Skeleton.c @@ -436,6 +436,7 @@ void spSkeleton_setBonesToSetupPose (const spSkeleton* self) { for (i = 0; i < self->ikConstraintsCount; ++i) { spIkConstraint* ikConstraint = self->ikConstraints[i]; ikConstraint->bendDirection = ikConstraint->data->bendDirection; + ikConstraint->compress = ikConstraint->data->compress; ikConstraint->stretch = ikConstraint->data->stretch; ikConstraint->mix = ikConstraint->data->mix; } diff --git a/spine-c/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c index 37b8ed619..8dbb8675e 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/spine-c/src/spine/SkeletonBinary.c @@ -392,8 +392,9 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con float time = readFloat(input); float mix = readFloat(input); signed char bendDirection = readSByte(input); + int compress = readBoolean(input); int stretch = readBoolean(input); - spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, bendDirection, stretch); + spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, bendDirection, compress, stretch); if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); } spTimelineArray_add(timelines, (spTimeline*)timeline); @@ -956,7 +957,9 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const data->target = skeletonData->bones[readVarint(input, 1)]; data->mix = readFloat(input); data->bendDirection = readSByte(input); + data->compress = readBoolean(input); data->stretch = readBoolean(input); + data->uniform = readBoolean(input); skeletonData->ikConstraints[i] = data; } diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index 5e294e70d..205fc95be 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/spine-c/src/spine/SkeletonJson.c @@ -299,7 +299,7 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r } for (valueMap = constraintMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) { spIkConstraintTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "mix", 1), - Json_getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json_getInt(valueMap, "stretch", 0) ? 1 : 0); + Json_getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json_getInt(valueMap, "compress", 0) ? 1 : 0, Json_getInt(valueMap, "stretch", 0) ? 1 : 0); readCurve(valueMap, SUPER(timeline), frameIndex); } animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline); @@ -737,7 +737,9 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha } data->bendDirection = Json_getInt(constraintMap, "bendPositive", 1) ? 1 : -1; + data->compress = Json_getInt(constraintMap, "compress", 0) ? 1 : 0; data->stretch = Json_getInt(constraintMap, "stretch", 0) ? 1 : 0; + data->uniform = Json_getInt(constraintMap, "uniform", 0) ? 1 : 0; data->mix = Json_getFloat(constraintMap, "mix", 1); skeletonData->ikConstraints[i] = data; diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraint.h b/spine-cpp/spine-cpp/include/spine/IkConstraint.h index 6016dcf4f..805c8bc41 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraint.h @@ -52,7 +52,7 @@ RTTI_DECL public: /// Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified /// in the world coordinate system. - static void apply(Bone &bone, float targetX, float targetY, bool stretch, float alpha); + static void apply(Bone &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha); /// Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as /// possible. The target is specified in the world coordinate system. @@ -80,6 +80,10 @@ public: void setBendDirection(int inValue); + bool getCompress(); + + void setCompress(bool inValue); + bool getStretch(); void setStretch(bool inValue); @@ -92,6 +96,7 @@ private: IkConstraintData &_data; Vector _bones; int _bendDirection; + bool _compress; bool _stretch; float _mix; Bone *_target; diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h index 18ca4aefe..690824ccc 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h @@ -65,8 +65,14 @@ namespace Spine { int getBendDirection(); void setBendDirection(int inValue); + bool getCompress(); + void setCompress(bool inValue); + bool getStretch(); void setStretch(bool inValue); + + bool getUniform(); + void setUniform(bool inValue); float getMix(); void setMix(float inValue); @@ -77,7 +83,9 @@ namespace Spine { Vector _bones; BoneData* _target; int _bendDirection; + bool _compress; bool _stretch; + bool _uniform; float _mix; }; } diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h index 29d13cce6..a7197536a 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h @@ -50,11 +50,11 @@ namespace Spine { virtual int getPropertyId(); /// Sets the time, mix and bend direction of the specified keyframe. - void setFrame (int frameIndex, float time, float mix, int bendDirection, bool stretch); + void setFrame (int frameIndex, float time, float mix, int bendDirection, bool compress, bool stretch); private: - static const int PREV_TIME, PREV_MIX, PREV_BEND_DIRECTION, PREV_STRETCH; - static const int MIX, BEND_DIRECTION, STRETCH; + static const int PREV_TIME, PREV_MIX, PREV_BEND_DIRECTION, PREV_COMPRESS, PREV_STRETCH; + static const int MIX, BEND_DIRECTION, COMPRESS, STRETCH; Vector _frames; int _ikConstraintIndex; diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index 1841a4c6c..9af748fbd 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -714,10 +714,10 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. float r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation; float total, diff = r2 - r1; + diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360; if (diff == 0) { total = timelinesRotation[i]; } else { - diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360; float lastTotal, lastDiff; if (firstFrame) { lastTotal = 0; diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp index 0a1dbcfba..b33cb91b7 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp @@ -40,7 +40,7 @@ using namespace Spine; RTTI_IMPL(IkConstraint, Constraint) -void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool stretch, float alpha) { +void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha) { Bone *p = bone.getParent(); float id, x, y, tx, ty, rotationIK; if (!bone._appliedValid) bone.updateAppliedTransform(); @@ -53,12 +53,17 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool stretch, if (rotationIK > 180) rotationIK -= 360; else if (rotationIK < -180) rotationIK += 360; float sx = bone._ascaleX; - if (stretch) { + float sy = bone._ascaleY; + if (compress || stretch) { float b = bone._data.getLength() * sx, dd = MathUtil::sqrt(tx * tx + ty * ty); - if (dd > b && b > 0.0001f) sx *= (dd / b - 1) * alpha + 1; + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) { + float s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) sy *= s; + } } bone.updateWorldTransform(bone._ax, bone._ay, bone._arotation + rotationIK * alpha, sx, - bone._ascaleY, bone._ashearX, bone._ashearY); + sy, bone._ashearX, bone._ashearY); } void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, float alpha) { @@ -202,6 +207,7 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) : Constraint(), _data(data), _bendDirection(data.getBendDirection()), + _compress(data.getCompress()), _stretch(data.getStretch()), _mix(data.getMix()), _target(skeleton.findBone( @@ -222,7 +228,7 @@ void IkConstraint::update() { switch (_bones.size()) { case 1: { Bone *bone0 = _bones[0]; - apply(*bone0, _target->getWorldX(), _target->getWorldY(), _stretch, _mix); + apply(*bone0, _target->getWorldX(), _target->getWorldY(), _compress, _stretch, _data._uniform, _mix); } break; case 2: { @@ -277,3 +283,11 @@ bool IkConstraint::getStretch() { void IkConstraint::setStretch(bool inValue) { _stretch = inValue; } + +bool IkConstraint::getCompress() { + return _compress; +} + +void IkConstraint::setCompress(bool inValue) { + _compress = inValue; +} diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp index ac643db5c..3b03b1d98 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp @@ -39,7 +39,9 @@ IkConstraintData::IkConstraintData(const String &name) : _order(0), _target(NULL), _bendDirection(1), + _compress(false), _stretch(false), + _uniform(false), _mix(1) { } @@ -90,3 +92,20 @@ bool IkConstraintData::getStretch() { void IkConstraintData::setStretch(bool inValue) { _stretch = inValue; } + +bool IkConstraintData::getCompress() { + return _compress; +} + +void IkConstraintData::setCompress(bool inValue) { + _compress = inValue; +} + + +bool IkConstraintData::getUniform() { + return _uniform; +} + +void IkConstraintData::setUniform(bool inValue) { + _uniform = inValue; +} diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp index e34381776..e3c915bbd 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp @@ -44,14 +44,16 @@ using namespace Spine; RTTI_IMPL(IkConstraintTimeline, CurveTimeline) -const int IkConstraintTimeline::ENTRIES = 4; -const int IkConstraintTimeline::PREV_TIME = -4; -const int IkConstraintTimeline::PREV_MIX = -3; -const int IkConstraintTimeline::PREV_BEND_DIRECTION = -2; +const int IkConstraintTimeline::ENTRIES = 5; +const int IkConstraintTimeline::PREV_TIME = -5; +const int IkConstraintTimeline::PREV_MIX = -4; +const int IkConstraintTimeline::PREV_BEND_DIRECTION = -3; +const int IkConstraintTimeline::PREV_COMPRESS = -2; const int IkConstraintTimeline::PREV_STRETCH = -1; const int IkConstraintTimeline::MIX = 1; const int IkConstraintTimeline::BEND_DIRECTION = 2; -const int IkConstraintTimeline::STRETCH = 3; +const int IkConstraintTimeline::COMPRESS = 3; +const int IkConstraintTimeline::STRETCH = 4; IkConstraintTimeline::IkConstraintTimeline(int frameCount) : CurveTimeline(frameCount), _ikConstraintIndex(0) { _frames.setSize(frameCount * ENTRIES, 0); @@ -69,11 +71,13 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, case MixBlend_Setup: constraint._mix = constraint._data._mix; constraint._bendDirection = constraint._data._bendDirection; + constraint._compress = constraint._data._compress; constraint._stretch = constraint._data._stretch; return; case MixBlend_First: constraint._mix += (constraint._data._mix - constraint._mix) * alpha; constraint._bendDirection = constraint._data._bendDirection; + constraint._compress = constraint._data._compress; constraint._stretch = constraint._data._stretch; return; default: @@ -88,15 +92,18 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, constraint._data._mix + (_frames[_frames.size() + PREV_MIX] - constraint._data._mix) * alpha; if (direction == MixDirection_Out) { constraint._bendDirection = constraint._data._bendDirection; + constraint._compress = constraint._data._compress; constraint._stretch = constraint._data._stretch; } else { constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION]; + constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0; constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0; } } else { constraint._mix += (_frames[_frames.size() + PREV_MIX] - constraint._mix) * alpha; if (direction == MixDirection_In) { constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION]; + constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0; constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0; } } @@ -115,15 +122,18 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, constraint._data._mix + (mix + (_frames[frame + MIX] - mix) * percent - constraint._data._mix) * alpha; if (direction == MixDirection_Out) { constraint._bendDirection = constraint._data._bendDirection; + constraint._compress = constraint._data._compress; constraint._stretch = constraint._data._stretch; } else { constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION]; - constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0; + constraint._compress = _frames[frame + PREV_COMPRESS] != 0; + constraint._stretch = _frames[frame + PREV_STRETCH] != 0; } } else { constraint._mix += (mix + (_frames[frame + MIX] - mix) * percent - constraint._mix) * alpha; if (direction == MixDirection_In) { constraint._bendDirection = (int) _frames[frame + PREV_BEND_DIRECTION]; + constraint._compress = _frames[frame + PREV_COMPRESS] != 0; constraint._stretch = _frames[frame + PREV_STRETCH] != 0; } } @@ -133,10 +143,11 @@ int IkConstraintTimeline::getPropertyId() { return ((int) TimelineType_IkConstraint << 24) + _ikConstraintIndex; } -void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, int bendDirection, bool stretch) { +void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, int bendDirection, bool compress, bool stretch) { frameIndex *= ENTRIES; _frames[frameIndex] = time; _frames[frameIndex + MIX] = mix; _frames[frameIndex + BEND_DIRECTION] = (float)bendDirection; + _frames[frameIndex + COMPRESS] = compress ? 1 : 0; _frames[frameIndex + STRETCH] = stretch ? 1 : 0; } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index 63c004ab6..807919c07 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -226,6 +226,7 @@ void Skeleton::setBonesToSetupPose() { IkConstraint &constraint = *constraintP; constraint._bendDirection = constraint._data._bendDirection; + constraint._compress = constraint._data._compress; constraint._stretch = constraint._data._stretch; constraint._mix = constraint._data._mix; } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index c3a7892b8..e8163c0fd 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -199,7 +199,9 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons data->_target = skeletonData->_bones[readVarint(input, true)]; data->_mix = readFloat(input); data->_bendDirection = readSByte(input); + data->_compress = readBoolean(input); data->_stretch = readBoolean(input); + data->_uniform = readBoolean(input); skeletonData->_ikConstraints[i] = data; } @@ -771,8 +773,9 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S float time = readFloat(input); float mix = readFloat(input); signed char bendDirection = readSByte(input); + bool compress = readBoolean(input); bool stretch = readBoolean(input); - timeline->setFrame(frameIndex, time, mix, bendDirection, stretch); + timeline->setFrame(frameIndex, time, mix, bendDirection, compress, stretch); if (frameIndex < frameCount - 1) { readCurve(input, frameIndex, timeline); } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index 74aa6f8f1..6687f832e 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -281,9 +281,11 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { return NULL; } - data->_bendDirection = Json::getInt(constraintMap, "bendPositive", 1) ? 1 : -1; - data->_stretch = Json::getInt(constraintMap, "stretch", 0) ? true: false; data->_mix = Json::getFloat(constraintMap, "mix", 1); + data->_bendDirection = Json::getInt(constraintMap, "bendPositive", 1) ? 1 : -1; + data->_compress = Json::getInt(constraintMap, "compress", 0) ? true: false; + data->_stretch = Json::getInt(constraintMap, "stretch", 0) ? true: false; + data->_uniform = Json::getInt(constraintMap, "uniform", 0) ? true: false; skeletonData->_ikConstraints[i] = data; } @@ -916,7 +918,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) { } for (valueMap = constraintMap->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { timeline->setFrame(frameIndex, Json::getFloat(valueMap, "time", 0), Json::getFloat(valueMap, "mix", 1), - Json::getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json::getInt(valueMap, "stretch", 0) ? true : false); + Json::getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json::getInt(valueMap, "compress", 0) ? true : false, Json::getInt(valueMap, "stretch", 0) ? true : false); readCurve(valueMap, timeline, frameIndex); } timelines.add(timeline);