mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[cpp] 4.3 porting WIP
This commit is contained in:
parent
a497bb39c5
commit
df2292460f
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user