[cpp] 4.3 porting WIP

This commit is contained in:
Mario Zechner 2025-06-12 00:54:41 +02:00
parent a497bb39c5
commit df2292460f
5 changed files with 267 additions and 533 deletions

View File

@ -30,168 +30,65 @@
#ifndef Spine_PhysicsConstraint_h
#define Spine_PhysicsConstraint_h
#include <spine/ConstraintData.h>
#include <spine/Constraint.h>
#include <spine/PhysicsConstraintData.h>
#include <spine/PhysicsConstraintPose.h>
#include <spine/BonePose.h>
#include <spine/Vector.h>
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<PhysicsConstraint, PhysicsConstraintData, PhysicsConstraintPose> {
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 */

View File

@ -37,6 +37,8 @@ namespace spine {
/// Stores a pose for a physics constraint.
class SP_API PhysicsConstraintPose : public Pose<PhysicsConstraintPose> {
RTTI_DECL
friend class PhysicsConstraint;
private:
float _inertia;

View File

@ -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);

View File

@ -29,416 +29,216 @@
#include <spine/PhysicsConstraint.h>
#include <spine/PhysicsConstraintData.h>
#include <spine/Bone.h>
#include <spine/PhysicsConstraintPose.h>
#include <spine/BonePose.h>
#include <spine/Skeleton.h>
#include <spine/SkeletonData.h>
#include <spine/BoneData.h>
#include <spine/Bone.h>
#include <spine/MathUtil.h>
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<PhysicsConstraint, PhysicsConstraintData, PhysicsConstraintPose>(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);
}

View File

@ -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; }