diff --git a/spine-cpp/include/spine/PhysicsConstraintTimeline.h b/spine-cpp/include/spine/PhysicsConstraintTimeline.h index 2eb7ea4f4..94c6dbe37 100644 --- a/spine-cpp/include/spine/PhysicsConstraintTimeline.h +++ b/spine-cpp/include/spine/PhysicsConstraintTimeline.h @@ -67,6 +67,7 @@ namespace spine { virtual bool global(PhysicsConstraintData &constraintData) = 0; int _constraintIndex; + bool _additive; }; /// Changes a physics constraint's PhysicsConstraintPose::getInertia(). @@ -184,7 +185,7 @@ namespace spine { public: explicit PhysicsConstraintWindTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex) - : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) {}; + : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) { _additive = true; }; protected: float get(PhysicsConstraintPose &pose) override { @@ -210,7 +211,7 @@ namespace spine { public: explicit PhysicsConstraintGravityTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex) - : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) {}; + : PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) { _additive = true; }; protected: float get(PhysicsConstraintPose &pose) override { diff --git a/spine-cpp/src/spine/ColorTimeline.cpp b/spine-cpp/src/spine/ColorTimeline.cpp index 999a2c755..49a837ae4 100644 --- a/spine-cpp/src/spine/ColorTimeline.cpp +++ b/spine-cpp/src/spine/ColorTimeline.cpp @@ -136,6 +136,7 @@ void RGBTimeline::setFrame(int frame, float time, float r, float g, float b) { void RGBTimeline::_apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) { Color &color = pose._color; + float r, g, b; if (time < _frames[0]) { Color &setup = slot._data._setup._color; switch (blend) { @@ -145,59 +146,58 @@ void RGBTimeline::_apply(Slot &slot, SlotPose &pose, float time, float alpha, Mi color.b = setup.b; return; case MixBlend_First: - color.r += (setup.r - color.r) * alpha; - color.g += (setup.g - color.g) * alpha; - color.b += (setup.b - color.b) * alpha; - return; + r = color.r + (setup.r - color.r) * alpha; + g = color.g + (setup.g - color.g) * alpha; + b = color.b + (setup.b - color.b) * alpha; + break; default: return; } - } - - float r, g, b; - int i = Animation::search(_frames, time, ENTRIES); - int curveType = (int) _curves[i >> 2]; - switch (curveType) { - case LINEAR: { - float before = _frames[i]; - r = _frames[i + R]; - g = _frames[i + G]; - b = _frames[i + B]; - float t = (time - before) / (_frames[i + ENTRIES] - before); - r += (_frames[i + ENTRIES + R] - r) * t; - g += (_frames[i + ENTRIES + G] - g) * t; - b += (_frames[i + ENTRIES + B] - b) * t; - break; - } - case STEPPED: { - r = _frames[i + R]; - g = _frames[i + G]; - b = _frames[i + B]; - break; - } - default: { - r = getBezierValue(time, i, R, curveType - BEZIER); - g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); - b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); - break; - } - } - - if (alpha == 1) { - color.r = r; - color.g = g; - color.b = b; } else { - if (blend == MixBlend_Setup) { - Color &setup = slot._data._setup._color; - color.r = setup.r; - color.g = setup.g; - color.b = setup.b; + int i = Animation::search(_frames, time, ENTRIES); + int curveType = (int) _curves[i >> 2]; + switch (curveType) { + case LINEAR: { + float before = _frames[i]; + r = _frames[i + R]; + g = _frames[i + G]; + b = _frames[i + B]; + float t = (time - before) / (_frames[i + ENTRIES] - before); + r += (_frames[i + ENTRIES + R] - r) * t; + g += (_frames[i + ENTRIES + G] - g) * t; + b += (_frames[i + ENTRIES + B] - b) * t; + break; + } + case STEPPED: { + r = _frames[i + R]; + g = _frames[i + G]; + b = _frames[i + B]; + break; + } + default: { + r = getBezierValue(time, i, R, curveType - BEZIER); + g = getBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER); + b = getBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER); + break; + } + } + + if (alpha != 1) { + if (blend == MixBlend_Setup) { + Color &setup = slot._data._setup._color; + r = setup.r + (r - setup.r) * alpha; + g = setup.g + (g - setup.g) * alpha; + b = setup.b + (b - setup.b) * alpha; + } else { + r = color.r + (r - color.r) * alpha; + g = color.g + (g - color.g) * alpha; + b = color.b + (b - color.b) * alpha; + } } - color.r += (r - color.r) * alpha; - color.g += (g - color.g) * alpha; - color.b += (b - color.b) * alpha; } + color.r = r < 0 ? 0 : (r > 1 ? 1 : r); + color.g = g < 0 ? 0 : (g > 1 ? 1 : g); + color.b = b < 0 ? 0 : (b > 1 ? 1 : b); } RTTI_IMPL(AlphaTimeline, SlotCurveTimeline) @@ -229,6 +229,7 @@ void AlphaTimeline::apply(Skeleton &skeleton, float lastTime, float time, Array< if (!slot->_bone._active) return; Color &color = (appliedPose ? *slot->_applied : slot->_pose)._color; + float a; if (time < _frames[0]) { Color &setup = slot->_data._setup._color; switch (blend) { @@ -236,20 +237,22 @@ void AlphaTimeline::apply(Skeleton &skeleton, float lastTime, float time, Array< color.a = setup.a; return; case MixBlend_First: - color.a += (setup.a - color.a) * alpha; - return; + a = color.a + (setup.a - color.a) * alpha; + break; default: return; } + } else { + a = getCurveValue(time); + if (alpha != 1) { + if (blend == MixBlend_Setup) { + Color &setup = slot->_data._setup._color; + a = setup.a + (a - setup.a) * alpha; + } else + a = color.a + (a - color.a) * alpha; + } } - - float a = getCurveValue(time); - if (alpha == 1) - color.a = a; - else { - if (blend == MixBlend_Setup) color.a = slot->_data._setup._color.a; - color.a += (a - color.a) * alpha; - } + color.a = a < 0 ? 0 : (a > 1 ? 1 : a); } RTTI_IMPL(RGBA2Timeline, SlotCurveTimeline) diff --git a/spine-cpp/src/spine/IkConstraintTimeline.cpp b/spine-cpp/src/spine/IkConstraintTimeline.cpp index 0f2ef415e..07e1707b9 100644 --- a/spine-cpp/src/spine/IkConstraintTimeline.cpp +++ b/spine-cpp/src/spine/IkConstraintTimeline.cpp @@ -108,30 +108,20 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, } } - switch (blend) { - case MixBlend_Setup: { - IkConstraintPose &setup = constraint->_data._setup; - pose._mix = setup._mix + (mix - setup._mix) * alpha; - pose._softness = setup._softness + (softness - setup._softness) * alpha; - if (direction == MixDirection_Out) { - pose._bendDirection = setup._bendDirection; - pose._compress = setup._compress; - pose._stretch = setup._stretch; - return; - } - break; + if (blend == MixBlend_Setup) { + IkConstraintPose &setup = constraint->_data._setup; + pose._mix = setup._mix + (mix - setup._mix) * alpha; + pose._softness = setup._softness + (softness - setup._softness) * alpha; + if (direction == MixDirection_Out) { + pose._bendDirection = setup._bendDirection; + pose._compress = setup._compress; + pose._stretch = setup._stretch; + return; } - case MixBlend_First: - case MixBlend_Replace: - pose._mix += (mix - pose._mix) * alpha; - pose._softness += (softness - pose._softness) * alpha; - if (direction == MixDirection_Out) return; - break; - case MixBlend_Add: - pose._mix += mix * alpha; - pose._softness += softness * alpha; - if (direction == MixDirection_Out) return; - break; + } else { + pose._mix += (mix - pose._mix) * alpha; + pose._softness += (softness - pose._softness) * alpha; + if (direction == MixDirection_Out) return; } pose._bendDirection = (int) _frames[i + BEND_DIRECTION]; pose._compress = _frames[i + COMPRESS] != 0; diff --git a/spine-cpp/src/spine/PathConstraintMixTimeline.cpp b/spine-cpp/src/spine/PathConstraintMixTimeline.cpp index b812d297a..3e741e61a 100644 --- a/spine-cpp/src/spine/PathConstraintMixTimeline.cpp +++ b/spine-cpp/src/spine/PathConstraintMixTimeline.cpp @@ -109,25 +109,15 @@ void PathConstraintMixTimeline::apply(Skeleton &skeleton, float lastTime, float } } - switch (blend) { - case MixBlend_Setup: { - PathConstraintPose &setup = constraint->_data._setup; - pose._mixRotate = setup._mixRotate + (rotate - setup._mixRotate) * alpha; - pose._mixX = setup._mixX + (x - setup._mixX) * alpha; - pose._mixY = setup._mixY + (y - setup._mixY) * alpha; - break; - } - case MixBlend_First: - case MixBlend_Replace: - pose._mixRotate += (rotate - pose._mixRotate) * alpha; - pose._mixX += (x - pose._mixX) * alpha; - pose._mixY += (y - pose._mixY) * alpha; - break; - case MixBlend_Add: - pose._mixRotate += rotate * alpha; - pose._mixX += x * alpha; - pose._mixY += y * alpha; - break; + if (blend == MixBlend_Setup) { + PathConstraintPose &setup = constraint->_data._setup; + pose._mixRotate = setup._mixRotate + (rotate - setup._mixRotate) * alpha; + pose._mixX = setup._mixX + (x - setup._mixX) * alpha; + pose._mixY = setup._mixY + (y - setup._mixY) * alpha; + } else { + pose._mixRotate += (rotate - pose._mixRotate) * alpha; + pose._mixX += (x - pose._mixX) * alpha; + pose._mixY += (y - pose._mixY) * alpha; } } diff --git a/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp b/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp index 4e5827b23..3e6d0c438 100644 --- a/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp +++ b/spine-cpp/src/spine/PathConstraintSpacingTimeline.cpp @@ -60,6 +60,6 @@ void PathConstraintSpacingTimeline::apply(Skeleton &skeleton, float lastTime, fl if (constraint->isActive()) { PathConstraintPose &pose = appliedPose ? *constraint->_applied : constraint->_pose; PathConstraintData &data = constraint->_data; - pose._spacing = getAbsoluteValue(time, alpha, blend, pose._spacing, data._setup._spacing); + pose._spacing = getAbsoluteValue(time, alpha, blend == MixBlend_Add ? MixBlend_Replace : blend, pose._spacing, data._setup._spacing); } } diff --git a/spine-cpp/src/spine/PhysicsConstraintTimeline.cpp b/spine-cpp/src/spine/PhysicsConstraintTimeline.cpp index a4c987ad0..179899b86 100644 --- a/spine-cpp/src/spine/PhysicsConstraintTimeline.cpp +++ b/spine-cpp/src/spine/PhysicsConstraintTimeline.cpp @@ -52,13 +52,14 @@ RTTI_IMPL(PhysicsConstraintMixTimeline, PhysicsConstraintTimeline) RTTI_IMPL_MULTI(PhysicsConstraintResetTimeline, Timeline, ConstraintTimeline) PhysicsConstraintTimeline::PhysicsConstraintTimeline(size_t frameCount, size_t bezierCount, int constraintIndex, Property property) - : CurveTimeline1(frameCount, bezierCount), ConstraintTimeline(), _constraintIndex(constraintIndex) { + : CurveTimeline1(frameCount, bezierCount), ConstraintTimeline(), _constraintIndex(constraintIndex), _additive(false) { PropertyId ids[] = {((PropertyId) property << 32) | constraintIndex}; setPropertyIds(ids, 1); } void PhysicsConstraintTimeline::apply(Skeleton &skeleton, float, float time, Array *, float alpha, MixBlend blend, MixDirection direction, bool appliedPose) { + if (blend == MixBlend_Add && !_additive) blend = MixBlend_Replace; if (_constraintIndex == -1) { float value = time >= _frames[0] ? getCurveValue(time) : 0;