From df2292460ff67cae440613dc6a9add0f47598b11 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 12 Jun 2025 00:54:41 +0200 Subject: [PATCH] [cpp] 4.3 porting WIP --- .../include/spine/PhysicsConstraint.h | 193 ++---- .../include/spine/PhysicsConstraintPose.h | 2 + spine-cpp/spine-cpp/include/spine/Skeleton.h | 19 + .../spine-cpp/src/spine/PhysicsConstraint.cpp | 568 ++++++------------ spine-cpp/spine-cpp/src/spine/Skeleton.cpp | 18 +- 5 files changed, 267 insertions(+), 533 deletions(-) diff --git a/spine-cpp/spine-cpp/include/spine/PhysicsConstraint.h b/spine-cpp/spine-cpp/include/spine/PhysicsConstraint.h index b63060ee7..7e670e00e 100644 --- a/spine-cpp/spine-cpp/include/spine/PhysicsConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/PhysicsConstraint.h @@ -30,168 +30,65 @@ #ifndef Spine_PhysicsConstraint_h #define Spine_PhysicsConstraint_h -#include - +#include +#include +#include +#include #include namespace spine { - class PhysicsConstraintData; - class Skeleton; + class BonePose; + class PhysicsConstraintPose; - class Bone; + /// Stores the current pose for a physics constraint. A physics constraint applies physics to bones. + /// + /// See https://esotericsoftware.com/spine-physics-constraints Physics constraints in the Spine User Guide. + class SP_API PhysicsConstraint : public Constraint { + friend class Skeleton; + friend class PhysicsConstraintTimeline; + friend class PhysicsConstraintInertiaTimeline; + friend class PhysicsConstraintStrengthTimeline; + friend class PhysicsConstraintDampingTimeline; + friend class PhysicsConstraintMassTimeline; + friend class PhysicsConstraintWindTimeline; + friend class PhysicsConstraintGravityTimeline; + friend class PhysicsConstraintMixTimeline; + friend class PhysicsConstraintResetTimeline; - class SP_API PhysicsConstraint : public Updatable { + public: + RTTI_DECL - friend class Skeleton; + PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton); - friend class PhysicsConstraintTimeline; + void update(Skeleton& skeleton, Physics physics) override; + void sort(Skeleton& skeleton); + bool isSourceActive(); + PhysicsConstraint* copy(Skeleton& skeleton); - friend class PhysicsConstraintInertiaTimeline; + /// Translates the physics constraint so next update() forces are applied as if the bone moved an additional amount in world space. + void translate(float x, float y); - friend class PhysicsConstraintStrengthTimeline; + /// Rotates the physics constraint so next update() forces are applied as if the bone rotated around the specified point in world space. + void rotate(float x, float y, float degrees); - friend class PhysicsConstraintDampingTimeline; + void reset(Skeleton& skeleton); - friend class PhysicsConstraintMassTimeline; + /// The bone constrained by this physics constraint. + BonePose& getBone(); + void setBone(BonePose& bone); - friend class PhysicsConstraintWindTimeline; + private: + BonePose* _bone; - friend class PhysicsConstraintGravityTimeline; - - friend class PhysicsConstraintMixTimeline; - - friend class PhysicsConstraintResetTimeline; - - RTTI_DECL - - public: - PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton); - - PhysicsConstraintData &getData(); - - void setBone(Bone* bone); - Bone* getBone(); - - void setInertia(float value); - float getInertia(); - - void setStrength(float value); - float getStrength(); - - void setDamping(float value); - float getDamping(); - - void setMassInverse(float value); - float getMassInverse(); - - void setWind(float value); - float getWind(); - - void setGravity(float value); - float getGravity(); - - void setMix(float value); - float getMix(); - - void setReset(bool value); - bool getReset(); - - void setUx(float value); - float getUx(); - - void setUy(float value); - float getUy(); - - void setCx(float value); - float getCx(); - - void setCy(float value); - float getCy(); - - void setTx(float value); - float getTx(); - - void setTy(float value); - float getTy(); - - void setXOffset(float value); - float getXOffset(); - - void setXVelocity(float value); - float getXVelocity(); - - void setYOffset(float value); - float getYOffset(); - - void setYVelocity(float value); - float getYVelocity(); - - void setRotateOffset(float value); - float getRotateOffset(); - - void setRotateVelocity(float value); - float getRotateVelocity(); - - void setScaleOffset(float value); - float getScaleOffset(); - - void setScaleVelocity(float value); - float getScaleVelocity(); - - void setActive(bool value); - bool isActive(); - - void setRemaining(float value); - float getRemaining(); - - void setLastTime(float value); - float getLastTime(); - - void reset(); - - void setToSetupPose(); - - virtual void update(Physics physics); - - void translate(float x, float y); - - void rotate(float x, float y, float degrees); - - private: - PhysicsConstraintData& _data; - Bone* _bone; - - float _inertia; - float _strength; - float _damping; - float _massInverse; - float _wind; - float _gravity; - float _mix; - - bool _reset; - float _ux; - float _uy; - float _cx; - float _cy; - float _tx; - float _ty; - float _xOffset; - float _xVelocity; - float _yOffset; - float _yVelocity; - float _rotateOffset; - float _rotateVelocity; - float _scaleOffset; - float _scaleVelocity; - - bool _active; - - Skeleton& _skeleton; - float _remaining; - float _lastTime; - }; + bool _reset; + float _ux, _uy, _cx, _cy, _tx, _ty; + float _xOffset, _xLag, _xVelocity; + float _yOffset, _yLag, _yVelocity; + float _rotateOffset, _rotateLag, _rotateVelocity; + float _scaleOffset, _scaleLag, _scaleVelocity; + float _remaining, _lastTime; + }; } #endif /* Spine_PhysicsConstraint_h */ diff --git a/spine-cpp/spine-cpp/include/spine/PhysicsConstraintPose.h b/spine-cpp/spine-cpp/include/spine/PhysicsConstraintPose.h index b5a57633e..e52dfe0ee 100644 --- a/spine-cpp/spine-cpp/include/spine/PhysicsConstraintPose.h +++ b/spine-cpp/spine-cpp/include/spine/PhysicsConstraintPose.h @@ -37,6 +37,8 @@ namespace spine { /// Stores a pose for a physics constraint. class SP_API PhysicsConstraintPose : public Pose { RTTI_DECL + + friend class PhysicsConstraint; private: float _inertia; diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index 135714c6b..603e3bebb 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.h @@ -122,6 +122,8 @@ namespace spine { friend class TwoColorTimeline; + friend class PhysicsConstraint; + public: explicit Skeleton(SkeletonData *skeletonData); @@ -246,6 +248,22 @@ namespace spine { void update(float delta); + float getWindX(); + + void setWindX(float windX); + + float getWindY(); + + void setWindY(float windY); + + float getGravityX(); + + void setGravityX(float gravityX); + + float getGravityY(); + + void setGravityY(float gravityY); + /// Rotates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone rotated around the /// specified point in world space. void physicsTranslate(float x, float y); @@ -268,6 +286,7 @@ namespace spine { float _scaleX, _scaleY; float _x, _y; float _time; + float _windX, _windY, _gravityX, _gravityY; void sortIkConstraint(IkConstraint *constraint); diff --git a/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp b/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp index adf9d8f63..b68be6faf 100644 --- a/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp @@ -29,416 +29,216 @@ #include #include - -#include +#include +#include #include #include #include +#include +#include using namespace spine; -RTTI_IMPL(PhysicsConstraint, Updatable) +RTTI_IMPL_NOPARENT(PhysicsConstraint) -PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton) - : _data(data), _skeleton(skeleton) { - _bone = skeleton.getBones()[data.getBone()->getIndex()]; - _inertia = data.getInertia(); - _strength = data.getStrength(); - _damping = data.getDamping(); - _massInverse = data.getMassInverse(); - _wind = data.getWind(); - _gravity = data.getGravity(); - _mix = data.getMix(); +PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton) : + Constraint(data), + _reset(true), _ux(0), _uy(0), _cx(0), _cy(0), _tx(0), _ty(0), + _xOffset(0), _xLag(0), _xVelocity(0), _yOffset(0), _yLag(0), _yVelocity(0), + _rotateOffset(0), _rotateLag(0), _rotateVelocity(0), _scaleOffset(0), _scaleLag(0), _scaleVelocity(0), + _remaining(0), _lastTime(0) { + + _bone = &skeleton.getBones()[(size_t)data.getBone()->getIndex()]->getAppliedPose(); +} - _reset = true; - _ux = 0; - _uy = 0; - _cx = 0; - _cy = 0; - _tx = 0; - _ty = 0; - _xOffset = 0; - _xVelocity = 0; - _yOffset = 0; - _yVelocity = 0; - _rotateOffset = 0; - _rotateVelocity = 0; - _scaleOffset = 0; - _scaleVelocity = 0; - _active = false; +PhysicsConstraint* PhysicsConstraint::copy(Skeleton& skeleton) { + PhysicsConstraint* copy = new (__FILE__, __LINE__) PhysicsConstraint(_data, skeleton); + copy->_applied->set(*_applied); + return copy; +} + +void PhysicsConstraint::sort(Skeleton& skeleton) { + Bone* bone = _bone->_bone; + skeleton.sortBone(bone); + skeleton.updateCache.add(this); + skeleton.sortReset(bone->_children); + skeleton.constrained(bone); +} + +bool PhysicsConstraint::isSourceActive() { + return _bone->_bone->isActive(); +} + +BonePose& PhysicsConstraint::getBone() { + return *_bone; +} + +void PhysicsConstraint::setBone(BonePose& bone) { + _bone = &bone; +} + +void PhysicsConstraint::reset(Skeleton& skeleton) { _remaining = 0; - _lastTime = 0; -} - -PhysicsConstraintData &PhysicsConstraint::getData() { - return _data; -} - -void PhysicsConstraint::setBone(Bone *bone) { - _bone = bone; -} - -Bone *PhysicsConstraint::getBone() { - return _bone; -} - -void PhysicsConstraint::setInertia(float value) { - _inertia = value; -} - -float PhysicsConstraint::getInertia() { - return _inertia; -} - -void PhysicsConstraint::setStrength(float value) { - _strength = value; -} - -float PhysicsConstraint::getStrength() { - return _strength; -} - -void PhysicsConstraint::setDamping(float value) { - _damping = value; -} - -float PhysicsConstraint::getDamping() { - return _damping; -} - -void PhysicsConstraint::setMassInverse(float value) { - _massInverse = value; -} - -float PhysicsConstraint::getMassInverse() { - return _massInverse; -} - -void PhysicsConstraint::setWind(float value) { - _wind = value; -} - -float PhysicsConstraint::getWind() { - return _wind; -} - -void PhysicsConstraint::setGravity(float value) { - _gravity = value; -} - -float PhysicsConstraint::getGravity() { - return _gravity; -} - -void PhysicsConstraint::setMix(float value) { - _mix = value; -} - -float PhysicsConstraint::getMix() { - return _mix; -} - -void PhysicsConstraint::setReset(bool value) { - _reset = value; -} - -bool PhysicsConstraint::getReset() { - return _reset; -} - -void PhysicsConstraint::setUx(float value) { - _ux = value; -} - -float PhysicsConstraint::getUx() { - return _ux; -} - -void PhysicsConstraint::setUy(float value) { - _uy = value; -} - -float PhysicsConstraint::getUy() { - return _uy; -} - -void PhysicsConstraint::setCx(float value) { - _cx = value; -} - -float PhysicsConstraint::getCx() { - return _cx; -} - -void PhysicsConstraint::setCy(float value) { - _cy = value; -} - -float PhysicsConstraint::getCy() { - return _cy; -} - -void PhysicsConstraint::setTx(float value) { - _tx = value; -} - -float PhysicsConstraint::getTx() { - return _tx; -} - -void PhysicsConstraint::setTy(float value) { - _ty = value; -} - -float PhysicsConstraint::getTy() { - return _ty; -} - -void PhysicsConstraint::setXOffset(float value) { - _xOffset = value; -} - -float PhysicsConstraint::getXOffset() { - return _xOffset; -} - -void PhysicsConstraint::setXVelocity(float value) { - _xVelocity = value; -} - -float PhysicsConstraint::getXVelocity() { - return _xVelocity; -} - -void PhysicsConstraint::setYOffset(float value) { - _yOffset = value; -} - -float PhysicsConstraint::getYOffset() { - return _yOffset; -} - -void PhysicsConstraint::setYVelocity(float value) { - _yVelocity = value; -} - -float PhysicsConstraint::getYVelocity() { - return _yVelocity; -} - -void PhysicsConstraint::setRotateOffset(float value) { - _rotateOffset = value; -} - -float PhysicsConstraint::getRotateOffset() { - return _rotateOffset; -} - -void PhysicsConstraint::setRotateVelocity(float value) { - _rotateVelocity = value; -} - -float PhysicsConstraint::getRotateVelocity() { - return _rotateVelocity; -} - -void PhysicsConstraint::setScaleOffset(float value) { - _scaleOffset = value; -} - -float PhysicsConstraint::getScaleOffset() { - return _scaleOffset; -} - -void PhysicsConstraint::setScaleVelocity(float value) { - _scaleVelocity = value; -} - -float PhysicsConstraint::getScaleVelocity() { - return _scaleVelocity; -} - -void PhysicsConstraint::setActive(bool value) { - _active = value; -} - -bool PhysicsConstraint::isActive() { - return _active; -} - -void PhysicsConstraint::setRemaining(float value) { - _remaining = value; -} - -float PhysicsConstraint::getRemaining() { - return _remaining; -} - -void PhysicsConstraint::setLastTime(float value) { - _lastTime = value; -} - -float PhysicsConstraint::getLastTime() { - return _lastTime; -} - -void PhysicsConstraint::reset() { - _remaining = 0; - _lastTime = _skeleton.getTime(); + _lastTime = skeleton.getTime(); _reset = true; _xOffset = 0; + _xLag = 0; _xVelocity = 0; _yOffset = 0; + _yLag = 0; _yVelocity = 0; _rotateOffset = 0; + _rotateLag = 0; _rotateVelocity = 0; _scaleOffset = 0; + _scaleLag = 0; _scaleVelocity = 0; } -void PhysicsConstraint::setToSetupPose() { - _inertia = _data.getInertia(); - _strength = _data.getStrength(); - _damping = _data.getDamping(); - _massInverse = _data.getMassInverse(); - _wind = _data.getWind(); - _gravity = _data.getGravity(); - _mix = _data.getMix(); -} -void PhysicsConstraint::update(Physics physics) { - float mix = _mix; +void PhysicsConstraint::update(Skeleton& skeleton, Physics physics) { + PhysicsConstraintPose& p = *_applied; + float mix = p.getMix(); if (mix == 0) return; - bool x = _data._x > 0; - bool y = _data._y > 0; - bool rotateOrShearX = _data._rotate > 0 || _data._shearX > 0; - bool scaleX = _data._scaleX > 0; - - Bone *bone = _bone; - float l = bone->_data.getLength(); + bool x = _data.getX() > 0, y = _data.getY() > 0, rotateOrShearX = _data._rotate > 0 || _data._shearX > 0, scaleX = _data.getScaleX() > 0; + BonePose* bone = _bone; + float l = bone->_bone->getData().getLength(), t = _data.getStep(), z = 0; switch (physics) { - case Physics::Physics_None: - return; - case Physics::Physics_Reset: - reset(); - // Fall through. - case Physics::Physics_Update: { - float delta = MathUtil::max(_skeleton.getTime() - _lastTime, 0.0f); - _remaining += delta; - _lastTime = _skeleton.getTime(); + case Physics_None: + return; + case Physics_Reset: + reset(skeleton); + // Fall through. + case Physics_Update: { + float delta = MathUtil::max(skeleton.getTime() - _lastTime, 0.0f), aa = _remaining; + _remaining += delta; + _lastTime = skeleton.getTime(); - float bx = bone->_worldX, by = bone->_worldY; - if (_reset) { - _reset = false; - _ux = bx; - _uy = by; - } else { - float a = _remaining, i = _inertia, t = _data._step, f = _skeleton.getData()->getReferenceScale(); - float qx = _data._limit * delta, qy = qx * MathUtil::abs(_skeleton.getScaleX()); - qx *= MathUtil::abs(_skeleton.getScaleY()); - if (x || y) { - if (x) { - float u = (_ux - bx) * i; - _xOffset += u > qx ? qx : u < -qx ? -qx - : u; - _ux = bx; - } - if (y) { - float u = (_uy - by) * i; - _yOffset += u > qy ? qy : u < -qy ? -qy - : u; - _uy = by; - } - if (a >= t) { - float d = MathUtil::pow(_damping, 60 * t); - float m = _massInverse * t, e = _strength, w = _wind * f * _skeleton.getScaleX(), g = _gravity * f * _skeleton.getScaleY(); - do { - if (x) { - _xVelocity += (w - _xOffset * e) * m; - _xOffset += _xVelocity * t; - _xVelocity *= d; - } - if (y) { - _yVelocity -= (g + _yOffset * e) * m; - _yOffset += _yVelocity * t; - _yVelocity *= d; - } - a -= t; - } while (a >= t); - } - if (x) bone->_worldX += _xOffset * mix * _data._x; - if (y) bone->_worldY += _yOffset * mix * _data._y; + float bx = bone->_worldX, by = bone->_worldY; + if (_reset) { + _reset = false; + _ux = bx; + _uy = by; + } else { + float a = _remaining, i = p.getInertia(), f = skeleton.getData()->getReferenceScale(), d = -1, m = 0, e = 0, qx = _data.getLimit() * delta, + qy = qx * MathUtil::abs(skeleton.getScaleY()); + qx *= MathUtil::abs(skeleton.getScaleX()); + if (x || y) { + if (x) { + float u = (_ux - bx) * i; + _xOffset += u > qx ? qx : u < -qx ? -qx : u; + _ux = bx; } - - if (rotateOrShearX || scaleX) { - float ca = MathUtil::atan2(bone->_c, bone->_a), c, s, mr = 0; - float dx = _cx - bone->_worldX, dy = _cy - bone->_worldY; - if (dx > qx) - dx = qx; - else if (dx < -qx)// - dx = -qx; - if (dy > qy) - dy = qy; - else if (dy < -qy)// - dy = -qy; - if (rotateOrShearX) { - mr = (_data._rotate + _data._shearX) * mix; - float r = MathUtil::atan2(dy + _ty, dx + _tx) - ca - _rotateOffset * mr; - _rotateOffset += (r - MathUtil::ceil(r * MathUtil::InvPi_2 - 0.5f) * MathUtil::Pi_2) * i; - r = _rotateOffset * mr + ca; - c = MathUtil::cos(r); - s = MathUtil::sin(r); - if (scaleX) { - r = l * bone->getWorldScaleX(); - if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; + if (y) { + float u = (_uy - by) * i; + _yOffset += u > qy ? qy : u < -qy ? -qy : u; + _uy = by; + } + if (a >= t) { + float xs = _xOffset, ys = _yOffset; + d = MathUtil::pow(p._damping, 60 * t); + m = t * p._massInverse; + e = p._strength; + float w = f * p._wind * skeleton.getScaleX(), g = f * p._gravity * skeleton.getScaleY(), + ax = w * skeleton.getWindX() + g * skeleton.getGravityX(), ay = w * skeleton.getWindY() + g * skeleton.getGravityY(); + do { + if (x) { + _xVelocity += (ax - _xOffset * e) * m; + _xOffset += _xVelocity * t; + _xVelocity *= d; } - } else { - c = MathUtil::cos(ca); - s = MathUtil::sin(ca); - float r = l * bone->getWorldScaleX(); + if (y) { + _yVelocity -= (ay + _yOffset * e) * m; + _yOffset += _yVelocity * t; + _yVelocity *= d; + } + a -= t; + } while (a >= t); + _xLag = _xOffset - xs; + _yLag = _yOffset - ys; + } + z = MathUtil::max(0.0f, 1 - a / t); + if (x) bone->_worldX += (_xOffset - _xLag * z) * mix * _data._x; + if (y) bone->_worldY += (_yOffset - _yLag * z) * mix * _data._y; + } + if (rotateOrShearX || scaleX) { + float ca = MathUtil::atan2(bone->_c, bone->_a), c, s, mr = 0, dx = _cx - bone->_worldX, dy = _cy - bone->_worldY; + if (dx > qx) + dx = qx; + else if (dx < -qx) + dx = -qx; + if (dy > qy) + dy = qy; + else if (dy < -qy) + dy = -qy; + if (rotateOrShearX) { + mr = (_data._rotate + _data._shearX) * mix; + z = _rotateLag * MathUtil::max(0.0f, 1 - aa / t); + float r = MathUtil::atan2(dy + _ty, dx + _tx) - ca - (_rotateOffset - z) * mr; + _rotateOffset += (r - MathUtil::ceil(r * MathUtil::InvPi_2 - 0.5f) * MathUtil::Pi_2) * i; + r = (_rotateOffset - z) * mr + ca; + c = MathUtil::cos(r); + s = MathUtil::sin(r); + if (scaleX) { + r = l * bone->getWorldScaleX(); if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; } - a = _remaining; - if (a >= t) { - float m = _massInverse * t, e = _strength, w = _wind, g = _gravity * (Bone::yDown ? -1 : 1), h = l / f; - float d = MathUtil::pow(_damping, 60 * t); - while (true) { - a -= t; - if (scaleX) { - _scaleVelocity += (w * c - g * s - _scaleOffset * e) * m; - _scaleOffset += _scaleVelocity * t; - _scaleVelocity *= d; - } - if (rotateOrShearX) { - _rotateVelocity -= ((w * s + g * c) * h + _rotateOffset * e) * m; - _rotateOffset += _rotateVelocity * t; - _rotateVelocity *= d; - if (a < t) break; - float r = _rotateOffset * mr + ca; - c = MathUtil::cos(r); - s = MathUtil::sin(r); - } else if (a < t)// - break; - } - } + } else { + c = MathUtil::cos(ca); + s = MathUtil::sin(ca); + float r = l * bone->getWorldScaleX() - _scaleLag * MathUtil::max(0.0f, 1 - aa / t); + if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; } - _remaining = a; + a = _remaining; + if (a >= t) { + if (d == -1) { + d = MathUtil::pow(p._damping, 60 * t); + m = t * p._massInverse; + e = p._strength; + } + float rs = _rotateOffset, ss = _scaleOffset, h = l / f, + ax = p._wind * skeleton.getWindX() + p._gravity * skeleton.getGravityX(), + ay = p._wind * skeleton.getWindY() + p._gravity * skeleton.getGravityY(); + while (true) { + a -= t; + if (scaleX) { + _scaleVelocity += (ax * c - ay * s - _scaleOffset * e) * m; + _scaleOffset += _scaleVelocity * t; + _scaleVelocity *= d; + } + if (rotateOrShearX) { + _rotateVelocity -= ((ax * s + ay * c) * h + _rotateOffset * e) * m; + _rotateOffset += _rotateVelocity * t; + _rotateVelocity *= d; + if (a < t) break; + float r = _rotateOffset * mr + ca; + c = MathUtil::cos(r); + s = MathUtil::sin(r); + } else if (a < t) + break; + } + _rotateLag = _rotateOffset - rs; + _scaleLag = _scaleOffset - ss; + } + z = MathUtil::max(0.0f, 1 - a / t); } - - _cx = bone->_worldX; - _cy = bone->_worldY; - break; - } - case Physics::Physics_Pose: { - if (x) bone->_worldX += _xOffset * mix * _data._x; - if (y) bone->_worldY += _yOffset * mix * _data._y; - break; + _remaining = a; } + _cx = bone->_worldX; + _cy = bone->_worldY; + break; + } + case Physics_Pose: { + z = MathUtil::max(0.0f, 1 - _remaining / t); + if (x) bone->_worldX += (_xOffset - _xLag * z) * mix * _data._x; + if (y) bone->_worldY += (_yOffset - _yLag * z) * mix * _data._y; + break; + } } if (rotateOrShearX) { - float o = _rotateOffset * mix, s = 0, c = 0, a = 0; + float o = (_rotateOffset - _rotateLag * z) * mix, s, c, a; if (_data._shearX > 0) { float r = 0; if (_data._rotate > 0) { @@ -468,21 +268,15 @@ void PhysicsConstraint::update(Physics physics) { } } if (scaleX) { - float s = 1 + _scaleOffset * mix * _data._scaleX; + float s = 1 + (_scaleOffset - _scaleLag * z) * mix * _data._scaleX; bone->_a *= s; bone->_c *= s; } - if (physics != Physics::Physics_Pose) { + if (physics != Physics_Pose) { _tx = l * bone->_a; _ty = l * bone->_c; } - bone->updateAppliedTransform(); -} - -void PhysicsConstraint::rotate(float x, float y, float degrees) { - float r = degrees * MathUtil::Deg_Rad, cos = MathUtil::cos(r), sin = MathUtil::sin(r); - float dx = _cx - x, dy = _cy - y; - translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy); + // bone->modifyWorld(skeleton.getUpdate()); // TODO: Implement getUpdate method in Skeleton } void PhysicsConstraint::translate(float x, float y) { @@ -491,3 +285,9 @@ void PhysicsConstraint::translate(float x, float y) { _cx -= x; _cy -= y; } + +void PhysicsConstraint::rotate(float x, float y, float degrees) { + float r = degrees * MathUtil::Deg_Rad, cosVal = MathUtil::cos(r), sinVal = MathUtil::sin(r); + float dx = _cx - x, dy = _cy - y; + translate(dx * cosVal - dy * sinVal - dx, dx * sinVal + dy * cosVal - dy); +} \ No newline at end of file diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index 84292a918..28996733a 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -59,7 +59,7 @@ using namespace spine; Skeleton::Skeleton(SkeletonData *skeletonData) : _data(skeletonData), _skin(NULL), _color(1, 1, 1, 1), _scaleX(1), - _scaleY(1), _x(0), _y(0), _time(0) { + _scaleY(1), _x(0), _y(0), _time(0), _windX(1), _windY(0), _gravityX(0), _gravityY(1) { _bones.ensureCapacity(_data->getBones().size()); for (size_t i = 0; i < _data->getBones().size(); ++i) { BoneData *data = _data->getBones()[i]; @@ -772,3 +772,19 @@ void Skeleton::physicsRotate(float x, float y, float degrees) { _physicsConstraints[i]->rotate(x, y, degrees); } } + +float Skeleton::getWindX() { return _windX; } + +void Skeleton::setWindX(float windX) { _windX = windX; } + +float Skeleton::getWindY() { return _windY; } + +void Skeleton::setWindY(float windY) { _windY = windY; } + +float Skeleton::getGravityX() { return _gravityX; } + +void Skeleton::setGravityX(float gravityX) { _gravityX = gravityX; } + +float Skeleton::getGravityY() { return _gravityY; } + +void Skeleton::setGravityY(float gravityY) { _gravityY = gravityY; }