mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-13 02:28:44 +08:00
Posed hierarchy changes
This commit is contained in:
parent
922e94485c
commit
f2e6b9095f
@ -123,6 +123,8 @@ namespace spine {
|
||||
static int search(Vector<float> &values, float target);
|
||||
|
||||
static int search(Vector<float> &values, float target, int step);
|
||||
|
||||
Vector<int> &getBones();
|
||||
private:
|
||||
Vector<Timeline *> _timelines;
|
||||
HashMap<PropertyId, bool> _timelineIds;
|
||||
|
||||
@ -42,7 +42,7 @@ namespace spine {
|
||||
/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
/// constraint or application code modifies the world transform after it was computed from the local transform.
|
||||
class SP_API Bone : public PosedActive<BoneData, BoneLocal, BonePose> {
|
||||
class SP_API Bone : public PosedActiveGeneric<BoneData, BoneLocal, BonePose> {
|
||||
friend class AnimationState;
|
||||
friend class RotateTimeline;
|
||||
friend class IkConstraint;
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <spine/PosedActive.h>
|
||||
#include <spine/Update.h>
|
||||
#include <spine/RTTI.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
namespace spine {
|
||||
class Skeleton;
|
||||
@ -42,14 +43,16 @@ namespace spine {
|
||||
public:
|
||||
Constraint();
|
||||
virtual ~Constraint();
|
||||
|
||||
ConstraintData &getData();
|
||||
};
|
||||
|
||||
template<class T, class D, class P>
|
||||
class SP_API ConstraintGeneric : public PosedActive<D, P, P>, public Constraint {
|
||||
class SP_API ConstraintGeneric : public PosedActiveGeneric<D, P, P>, public Constraint {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
ConstraintGeneric(D& data) : PosedActive<D, P, P>(data), Constraint() {
|
||||
ConstraintGeneric(D& data) : PosedActiveGeneric<D, P, P>(data), Constraint() {
|
||||
}
|
||||
|
||||
virtual ~ConstraintGeneric() {
|
||||
|
||||
@ -55,20 +55,14 @@ namespace spine {
|
||||
friend class SkeletonJson;
|
||||
|
||||
public:
|
||||
ConstraintDataGeneric(const String &name);
|
||||
virtual ~ConstraintDataGeneric();
|
||||
ConstraintDataGeneric(const String &name) : PosedData<P>(name), ConstraintData(name) {
|
||||
}
|
||||
virtual ~ConstraintDataGeneric() {
|
||||
}
|
||||
|
||||
/// Creates a constraint instance.
|
||||
virtual T* create(Skeleton& skeleton) = 0;
|
||||
};
|
||||
|
||||
template<class T, class P>
|
||||
ConstraintDataGeneric<T, P>::ConstraintDataGeneric(const String &name) : PosedData<P>(name), ConstraintData(name) {
|
||||
}
|
||||
|
||||
template<class T, class P>
|
||||
ConstraintDataGeneric<T, P>::~ConstraintDataGeneric() {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Spine_ConstraintData_h */
|
||||
|
||||
@ -35,9 +35,15 @@
|
||||
|
||||
namespace spine {
|
||||
class SP_API Posed {
|
||||
public:
|
||||
Posed() {}
|
||||
virtual ~Posed() {}
|
||||
public:
|
||||
Posed() {}
|
||||
virtual ~Posed() {}
|
||||
|
||||
virtual void resetApplied() = 0;
|
||||
|
||||
virtual void pose() = 0;
|
||||
|
||||
virtual void constrained() = 0;
|
||||
};
|
||||
|
||||
template<class D, class P, class A>
|
||||
@ -72,16 +78,10 @@ namespace spine {
|
||||
friend class InheritTimeline;
|
||||
|
||||
public:
|
||||
Posed(D& data) : _data(data), _pose(), _constrained() {
|
||||
static_assert(std::is_base_of<P, A>::value, "A must extend P");
|
||||
// Match Java behavior: applied initially points to pose
|
||||
// Note: Both _pose and _constrained are stored as type A to match Java's
|
||||
// "new BonePose(), new BonePose()" pattern. For most classes P==A, but
|
||||
// Bone uses P=BoneLocal, A=BonePose where BonePose extends BoneLocal.
|
||||
_applied = &_pose;
|
||||
PosedGeneric(D &data) : _data(data), _pose(), _constrained(), _applied(&_pose) {
|
||||
}
|
||||
|
||||
virtual ~Posed() {
|
||||
virtual ~PosedGeneric() {
|
||||
}
|
||||
|
||||
void setupPose() {
|
||||
@ -89,26 +89,38 @@ namespace spine {
|
||||
}
|
||||
|
||||
/// The constraint's setup pose data.
|
||||
D& getData() {
|
||||
D &getData() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
P& getPose() {
|
||||
P &getPose() {
|
||||
// Upcast A to P (safe due to static_assert that A extends P)
|
||||
// For most classes P==A so this is a no-op, but for Bone it casts BonePose->BoneLocal
|
||||
return _pose;
|
||||
}
|
||||
|
||||
A& getAppliedPose() {
|
||||
A &getAppliedPose() {
|
||||
return *_applied;
|
||||
}
|
||||
|
||||
virtual void resetApplied() {
|
||||
_constrained.set(_pose);
|
||||
}
|
||||
|
||||
virtual void pose() {
|
||||
_applied = &_pose;
|
||||
}
|
||||
|
||||
virtual void constrained() {
|
||||
_applied = &_constrained;
|
||||
}
|
||||
|
||||
protected:
|
||||
D& _data;
|
||||
A _pose; ///< Stored as A type (concrete pose type) to match Java behavior
|
||||
A _constrained; ///< Stored as A type (concrete pose type) to match Java behavior
|
||||
A* _applied; ///< Points to either _pose or _constrained, reassignable like Java
|
||||
D &_data;
|
||||
A _pose; ///< Stored as A type (concrete pose type) to match Java behavior
|
||||
A _constrained;///< Stored as A type (concrete pose type) to match Java behavior
|
||||
A *_applied; ///< Points to either _pose or _constrained, reassignable like Java
|
||||
};
|
||||
}
|
||||
}// namespace spine
|
||||
|
||||
#endif /* Spine_Posed_h */
|
||||
@ -35,33 +35,22 @@
|
||||
|
||||
namespace spine {
|
||||
|
||||
class SP_API PosedActive {
|
||||
public:
|
||||
PosedActive() {}
|
||||
virtual ~PosedActive() {}
|
||||
|
||||
/// Returns false when this constraint won't be updated by
|
||||
/// Skeleton::updateWorldTransform() because a skin is required and the
|
||||
/// active skin does not contain this item.
|
||||
/// @see Skin::getBones()
|
||||
/// @see Skin::getConstraints()
|
||||
/// @see PosedData::getSkinRequired()
|
||||
/// @see Skeleton::updateCache()
|
||||
bool isActive();
|
||||
|
||||
protected:
|
||||
bool _active;
|
||||
};
|
||||
|
||||
template<class D, class P, class A>
|
||||
class SP_API PosedActiveGeneric : public PosedGeneric<D, P, A> {
|
||||
friend class SlotCurveTimeline;
|
||||
|
||||
public:
|
||||
PosedActive(D &data): PosedGeneric<D, P, A>(data), _active(false) {
|
||||
PosedActiveGeneric(D &data): PosedGeneric<D, P, A>(data), _active(false) {
|
||||
this->setupPose();
|
||||
}
|
||||
virtual ~PosedActive() {}
|
||||
virtual ~PosedActiveGeneric() {}
|
||||
|
||||
bool isActive() {
|
||||
return _active;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _active;
|
||||
};
|
||||
}// namespace spine
|
||||
|
||||
|
||||
@ -298,21 +298,20 @@ namespace spine {
|
||||
void update(float delta);
|
||||
|
||||
protected:
|
||||
Vector<Update *> _updateCache;
|
||||
|
||||
private:
|
||||
SkeletonData &_data;
|
||||
Vector<Bone *> _bones;
|
||||
Vector<Slot *> _slots;
|
||||
Vector<Slot *> _drawOrder;
|
||||
Vector<Constraint *> _constraints;
|
||||
Vector<PhysicsConstraint *> _physics;
|
||||
Vector<Update *> _updateCache;
|
||||
Vector<Posed *> _resetCache;
|
||||
Skin *_skin;
|
||||
Color _color;
|
||||
float _scaleX, _scaleY;
|
||||
float _x, _y;
|
||||
float _time;
|
||||
float _scaleX, _scaleY;
|
||||
float _windX, _windY, _gravityX, _gravityY;
|
||||
float _time;
|
||||
int _update;
|
||||
};
|
||||
}// namespace spine
|
||||
|
||||
@ -118,8 +118,7 @@ void Animation::setTimelines(Vector<Timeline *> &timelines) {
|
||||
_timelineIds.put(propertyIds[ii], true);
|
||||
}
|
||||
|
||||
BoneTimeline *boneTimeline = timeline->getRTTI().instanceOf(BoneTimeline1::rtti) ?
|
||||
static_cast<BoneTimeline1 *>(timeline) : NULL;
|
||||
BoneTimeline *boneTimeline = timeline->getRTTI().instanceOf(BoneTimeline1::rtti) ? static_cast<BoneTimeline1 *>(timeline) : NULL;
|
||||
if (boneTimeline) {
|
||||
int boneIndex = boneTimeline->getBoneIndex();
|
||||
if (!boneSet.containsKey(boneIndex)) {
|
||||
|
||||
@ -69,7 +69,7 @@ int TrackEntry::getTrackIndex() { return _trackIndex; }
|
||||
|
||||
Animation *TrackEntry::getAnimation() { return _animation; }
|
||||
|
||||
void TrackEntry::setAnimation(Animation* animation) {
|
||||
void TrackEntry::setAnimation(Animation *animation) {
|
||||
if (animation == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -36,18 +36,18 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(Bone)
|
||||
|
||||
Bone::Bone(BoneData& data, Bone* parent) : PosedActive(data),
|
||||
_parent(parent),
|
||||
_children(),
|
||||
_sorted(false) {
|
||||
Bone::Bone(BoneData &data, Bone *parent) : PosedActiveGeneric(data),
|
||||
_parent(parent),
|
||||
_children(),
|
||||
_sorted(false) {
|
||||
_constrained._bone = this;
|
||||
_applied->_bone = this;
|
||||
}
|
||||
|
||||
Bone* Bone::getParent() {
|
||||
Bone *Bone::getParent() {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
Vector<Bone*>& Bone::getChildren() {
|
||||
Vector<Bone *> &Bone::getChildren() {
|
||||
return _children;
|
||||
}
|
||||
@ -34,12 +34,12 @@
|
||||
using namespace spine;
|
||||
|
||||
BoneData::BoneData(int index, const String &name, BoneData *parent) : PosedData<BoneLocal>(name),
|
||||
_index(index),
|
||||
_parent(parent),
|
||||
_length(0),
|
||||
_color(0.61f, 0.61f, 0.61f, 1.0f),
|
||||
_icon(),
|
||||
_visible(true) {
|
||||
_index(index),
|
||||
_parent(parent),
|
||||
_length(0),
|
||||
_color(0.61f, 0.61f, 0.61f, 1.0f),
|
||||
_icon(),
|
||||
_visible(true) {
|
||||
assert(index >= 0);
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ BoneLocal::BoneLocal() : _x(0), _y(0), _rotation(0), _scaleX(1), _scaleY(1), _sh
|
||||
BoneLocal::~BoneLocal() {
|
||||
}
|
||||
|
||||
void BoneLocal::set(BoneLocal& pose) {
|
||||
void BoneLocal::set(BoneLocal &pose) {
|
||||
_x = pose._x;
|
||||
_y = pose._y;
|
||||
_rotation = pose._rotation;
|
||||
|
||||
@ -42,17 +42,17 @@ BonePose::BonePose() : BoneLocal(), _bone(nullptr), _a(0), _b(0), _worldX(0), _c
|
||||
BonePose::~BonePose() {
|
||||
}
|
||||
|
||||
void BonePose::update(Skeleton& skeleton, Physics physics) {
|
||||
void BonePose::update(Skeleton &skeleton, Physics physics) {
|
||||
if (_world != skeleton._update) updateWorldTransform(skeleton);
|
||||
}
|
||||
|
||||
void BonePose::updateWorldTransform(Skeleton& skeleton) {
|
||||
void BonePose::updateWorldTransform(Skeleton &skeleton) {
|
||||
if (_local == skeleton._update)
|
||||
updateLocalTransform(skeleton);
|
||||
else
|
||||
_world = skeleton._update;
|
||||
|
||||
if (_bone->getParent() == nullptr) { // Root bone.
|
||||
if (_bone->getParent() == nullptr) {// Root bone.
|
||||
float sx = skeleton.getScaleX(), sy = skeleton.getScaleY();
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
@ -65,88 +65,88 @@ void BonePose::updateWorldTransform(Skeleton& skeleton) {
|
||||
return;
|
||||
}
|
||||
|
||||
BonePose& parent = _bone->getParent()->getAppliedPose();
|
||||
BonePose &parent = _bone->getParent()->getAppliedPose();
|
||||
float pa = parent._a, pb = parent._b, pc = parent._c, pd = parent._d;
|
||||
_worldX = pa * _x + pb * _y + parent._worldX;
|
||||
_worldY = pc * _x + pd * _y + parent._worldY;
|
||||
|
||||
switch (_inherit) {
|
||||
case Inherit_Normal: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la + pb * lc;
|
||||
_b = pa * lb + pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
return;
|
||||
}
|
||||
case Inherit_OnlyTranslation: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
_a = MathUtil::cos(rx) * _scaleX;
|
||||
_b = MathUtil::cos(ry) * _scaleY;
|
||||
_c = MathUtil::sin(rx) * _scaleX;
|
||||
_d = MathUtil::sin(ry) * _scaleY;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float sx = 1 / skeleton.getScaleX(), sy = 1 / skeleton.getScaleY();
|
||||
pa *= sx;
|
||||
pc *= sy;
|
||||
float s = pa * pa + pc * pc, prx;
|
||||
if (s > 0.0001f) {
|
||||
s = MathUtil::abs(pa * pd * sy - pb * sx * pc) / s;
|
||||
pb = pc * s;
|
||||
pd = pa * s;
|
||||
prx = MathUtil::atan2(pc, pa) * MathUtil::Rad_Deg;
|
||||
} else {
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
prx = 90 - MathUtil::atan2(pd, pb) * MathUtil::Rad_Deg;
|
||||
case Inherit_Normal: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la + pb * lc;
|
||||
_b = pa * lb + pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
return;
|
||||
}
|
||||
case Inherit_OnlyTranslation: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
_a = MathUtil::cos(rx) * _scaleX;
|
||||
_b = MathUtil::cos(ry) * _scaleY;
|
||||
_c = MathUtil::sin(rx) * _scaleX;
|
||||
_d = MathUtil::sin(ry) * _scaleY;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float sx = 1 / skeleton.getScaleX(), sy = 1 / skeleton.getScaleY();
|
||||
pa *= sx;
|
||||
pc *= sy;
|
||||
float s = pa * pa + pc * pc, prx;
|
||||
if (s > 0.0001f) {
|
||||
s = MathUtil::abs(pa * pd * sy - pb * sx * pc) / s;
|
||||
pb = pc * s;
|
||||
pd = pa * s;
|
||||
prx = MathUtil::atan2(pc, pa) * MathUtil::Rad_Deg;
|
||||
} else {
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
prx = 90 - MathUtil::atan2(pd, pb) * MathUtil::Rad_Deg;
|
||||
}
|
||||
float rx = (_rotation + _shearX - prx) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + _shearY - prx + 90) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la - pb * lc;
|
||||
_b = pa * lb - pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float rot = _rotation * MathUtil::Deg_Rad;
|
||||
float cosRot = MathUtil::cos(rot), sinRot = MathUtil::sin(rot);
|
||||
float za = (pa * cosRot + pb * sinRot) / skeleton.getScaleX();
|
||||
float zc = (pc * cosRot + pd * sinRot) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (_inherit == Inherit_NoScale && (pa * pd - pb * pc < 0) != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
rot = MathUtil::Pi / 2 + MathUtil::atan2(zc, za);
|
||||
float zb = MathUtil::cos(rot) * s;
|
||||
float zd = MathUtil::sin(rot) * s;
|
||||
float _shearXRad = _shearX * MathUtil::Deg_Rad;
|
||||
float _shearYRad = (90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(_shearXRad) * _scaleX;
|
||||
float lb = MathUtil::cos(_shearYRad) * _scaleY;
|
||||
float lc = MathUtil::sin(_shearXRad) * _scaleX;
|
||||
float ld = MathUtil::sin(_shearYRad) * _scaleY;
|
||||
_a = za * la + zb * lc;
|
||||
_b = za * lb + zb * ld;
|
||||
_c = zc * la + zd * lc;
|
||||
_d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
float rx = (_rotation + _shearX - prx) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + _shearY - prx + 90) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la - pb * lc;
|
||||
_b = pa * lb - pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float rot = _rotation * MathUtil::Deg_Rad;
|
||||
float cosRot = MathUtil::cos(rot), sinRot = MathUtil::sin(rot);
|
||||
float za = (pa * cosRot + pb * sinRot) / skeleton.getScaleX();
|
||||
float zc = (pc * cosRot + pd * sinRot) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (_inherit == Inherit_NoScale && (pa * pd - pb * pc < 0) != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
rot = MathUtil::Pi / 2 + MathUtil::atan2(zc, za);
|
||||
float zb = MathUtil::cos(rot) * s;
|
||||
float zd = MathUtil::sin(rot) * s;
|
||||
float _shearXRad = _shearX * MathUtil::Deg_Rad;
|
||||
float _shearYRad = (90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(_shearXRad) * _scaleX;
|
||||
float lb = MathUtil::cos(_shearYRad) * _scaleY;
|
||||
float lc = MathUtil::sin(_shearXRad) * _scaleX;
|
||||
float ld = MathUtil::sin(_shearYRad) * _scaleY;
|
||||
_a = za * la + zb * lc;
|
||||
_b = za * lb + zb * ld;
|
||||
_c = zc * la + zd * lc;
|
||||
_d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_a *= skeleton.getScaleX();
|
||||
_b *= skeleton.getScaleX();
|
||||
@ -154,7 +154,7 @@ void BonePose::updateWorldTransform(Skeleton& skeleton) {
|
||||
_d *= skeleton.getScaleY();
|
||||
}
|
||||
|
||||
void BonePose::updateLocalTransform(Skeleton& skeleton) {
|
||||
void BonePose::updateLocalTransform(Skeleton &skeleton) {
|
||||
_local = 0;
|
||||
_world = skeleton._update;
|
||||
|
||||
@ -170,7 +170,7 @@ void BonePose::updateLocalTransform(Skeleton& skeleton) {
|
||||
return;
|
||||
}
|
||||
|
||||
BonePose& parent = _bone->getParent()->getAppliedPose();
|
||||
BonePose &parent = _bone->getParent()->getAppliedPose();
|
||||
float pa = parent._a, pb = parent._b, pc = parent._c, pd = parent._d;
|
||||
float pid = 1 / (pa * pd - pb * pc);
|
||||
float ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;
|
||||
@ -186,38 +186,38 @@ void BonePose::updateLocalTransform(Skeleton& skeleton) {
|
||||
rd = _d;
|
||||
} else {
|
||||
switch (_inherit) {
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
pb = -pc * skeleton.getScaleX() * s / skeleton.getScaleY();
|
||||
pd = pa * skeleton.getScaleY() * s / skeleton.getScaleX();
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float r = _rotation * MathUtil::Deg_Rad, cosR = MathUtil::cos(r), sinR = MathUtil::sin(r);
|
||||
pa = (pa * cosR + pb * sinR) / skeleton.getScaleX();
|
||||
pc = (pc * cosR + pd * sinR) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
pa *= s;
|
||||
pc *= s;
|
||||
s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (_inherit == Inherit_NoScale && pid < 0 != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
|
||||
pb = MathUtil::cos(r) * s;
|
||||
pd = MathUtil::sin(r) * s;
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
ic = pc * pid;
|
||||
id = pa * pid;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
pb = -pc * skeleton.getScaleX() * s / skeleton.getScaleY();
|
||||
pd = pa * skeleton.getScaleY() * s / skeleton.getScaleX();
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float r = _rotation * MathUtil::Deg_Rad, cosR = MathUtil::cos(r), sinR = MathUtil::sin(r);
|
||||
pa = (pa * cosR + pb * sinR) / skeleton.getScaleX();
|
||||
pc = (pc * cosR + pd * sinR) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
pa *= s;
|
||||
pc *= s;
|
||||
s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (_inherit == Inherit_NoScale && pid < 0 != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
|
||||
pb = MathUtil::cos(r) * s;
|
||||
pd = MathUtil::sin(r) * s;
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
ic = pc * pid;
|
||||
id = pa * pid;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ra = ia * _a - ib * _c;
|
||||
rb = ia * _b - ib * _d;
|
||||
@ -240,11 +240,11 @@ void BonePose::updateLocalTransform(Skeleton& skeleton) {
|
||||
}
|
||||
}
|
||||
|
||||
void BonePose::validateLocalTransform(Skeleton& skeleton) {
|
||||
void BonePose::validateLocalTransform(Skeleton &skeleton) {
|
||||
if (_local == skeleton._update) updateLocalTransform(skeleton);
|
||||
}
|
||||
|
||||
void BonePose::modifyLocal(Skeleton& skeleton) {
|
||||
void BonePose::modifyLocal(Skeleton &skeleton) {
|
||||
if (_local == skeleton._update) updateLocalTransform(skeleton);
|
||||
_world = 0;
|
||||
resetWorld(skeleton._update);
|
||||
@ -257,9 +257,9 @@ void BonePose::modifyWorld(int update) {
|
||||
}
|
||||
|
||||
void BonePose::resetWorld(int update) {
|
||||
Vector<Bone*>& children = _bone->getChildren();
|
||||
Vector<Bone *> &children = _bone->getChildren();
|
||||
for (size_t i = 0, n = children.size(); i < n; i++) {
|
||||
BonePose& child = children[i]->getAppliedPose();
|
||||
BonePose &child = children[i]->getAppliedPose();
|
||||
if (child._world == update) {
|
||||
child._world = 0;
|
||||
child._local = 0;
|
||||
@ -333,19 +333,19 @@ float BonePose::getWorldScaleY() {
|
||||
}
|
||||
|
||||
|
||||
void BonePose::worldToLocal(float worldX, float worldY, float& outLocalX, float& outLocalY) {
|
||||
void BonePose::worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY) {
|
||||
float det = _a * _d - _b * _c;
|
||||
float _x = worldX - _worldX, _y = worldY - _worldY;
|
||||
outLocalX = (_x * _d - _y * _b) / det;
|
||||
outLocalY = (_y * _a - _x * _c) / det;
|
||||
}
|
||||
|
||||
void BonePose::localToWorld(float localX, float localY, float& outWorldX, float& outWorldY) {
|
||||
void BonePose::localToWorld(float localX, float localY, float &outWorldX, float &outWorldY) {
|
||||
outWorldX = localX * _a + localY * _b + _worldX;
|
||||
outWorldY = localX * _c + localY * _d + _worldY;
|
||||
}
|
||||
|
||||
void BonePose::worldToParent(float worldX, float worldY, float& outParentX, float& outParentY) {
|
||||
void BonePose::worldToParent(float worldX, float worldY, float &outParentX, float &outParentY) {
|
||||
if (_bone->getParent() == nullptr) {
|
||||
outParentX = worldX;
|
||||
outParentY = worldY;
|
||||
@ -354,7 +354,7 @@ void BonePose::worldToParent(float worldX, float worldY, float& outParentX, floa
|
||||
}
|
||||
}
|
||||
|
||||
void BonePose::parentToWorld(float parentX, float parentY, float& outWorldX, float& outWorldY) {
|
||||
void BonePose::parentToWorld(float parentX, float parentY, float &outWorldX, float &outWorldY) {
|
||||
if (_bone->getParent() == nullptr) {
|
||||
outWorldX = parentX;
|
||||
outWorldY = parentY;
|
||||
|
||||
@ -42,9 +42,8 @@ RTTI_IMPL_NOPARENT(BoneTimeline)
|
||||
|
||||
RTTI_IMPL(BoneTimeline1, CurveTimeline1)
|
||||
|
||||
BoneTimeline1::BoneTimeline1(size_t frameCount, size_t bezierCount, int boneIndex, Property property) :
|
||||
BoneTimeline(boneIndex),
|
||||
CurveTimeline1(frameCount, bezierCount) {
|
||||
BoneTimeline1::BoneTimeline1(size_t frameCount, size_t bezierCount, int boneIndex, Property property) : BoneTimeline(boneIndex),
|
||||
CurveTimeline1(frameCount, bezierCount) {
|
||||
PropertyId ids[] = {((PropertyId) property << 32) | boneIndex};
|
||||
setPropertyIds(ids, 1);
|
||||
}
|
||||
@ -62,9 +61,8 @@ void BoneTimeline1::apply(Skeleton &skeleton, float lastTime, float time, Vector
|
||||
|
||||
RTTI_IMPL(BoneTimeline2, CurveTimeline2)
|
||||
|
||||
BoneTimeline2::BoneTimeline2(size_t frameCount, size_t bezierCount, int boneIndex, Property property1, Property property2) :
|
||||
BoneTimeline(boneIndex),
|
||||
CurveTimeline2(frameCount, bezierCount) {
|
||||
BoneTimeline2::BoneTimeline2(size_t frameCount, size_t bezierCount, int boneIndex, Property property1, Property property2) : BoneTimeline(boneIndex),
|
||||
CurveTimeline2(frameCount, bezierCount) {
|
||||
PropertyId ids[] = {((PropertyId) property1 << 32) | boneIndex, ((PropertyId) property2 << 32) | boneIndex};
|
||||
setPropertyIds(ids, 2);
|
||||
}
|
||||
|
||||
@ -61,10 +61,10 @@ void RGBATimeline::setFrame(int frame, float time, float r, float g, float b, fl
|
||||
_frames[frame + A] = a;
|
||||
}
|
||||
|
||||
void RGBATimeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, MixBlend blend) {
|
||||
Color& color = pose._color;
|
||||
void RGBATimeline::apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) {
|
||||
Color &color = pose._color;
|
||||
if (time < _frames[0]) {
|
||||
Color& setup = slot._data._setup._color;
|
||||
Color &setup = slot._data._setup._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.set(setup);
|
||||
@ -139,10 +139,10 @@ void RGBTimeline::setFrame(int frame, float time, float r, float g, float b) {
|
||||
_frames[frame + B] = b;
|
||||
}
|
||||
|
||||
void RGBTimeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, MixBlend blend) {
|
||||
Color& color = pose._color;
|
||||
void RGBTimeline::apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) {
|
||||
Color &color = pose._color;
|
||||
if (time < _frames[0]) {
|
||||
Color& setup = slot._data._setup._color;
|
||||
Color &setup = slot._data._setup._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.r = setup.r;
|
||||
@ -194,7 +194,7 @@ void RGBTimeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, Mix
|
||||
color.b = b;
|
||||
} else {
|
||||
if (blend == MixBlend_Setup) {
|
||||
Color& setup = slot._data._setup._color;
|
||||
Color &setup = slot._data._setup._color;
|
||||
color.r = setup.r;
|
||||
color.g = setup.g;
|
||||
color.b = setup.b;
|
||||
@ -225,9 +225,9 @@ void AlphaTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector
|
||||
Slot *slot = skeleton._slots[_slotIndex];
|
||||
if (!slot->_bone._active) return;
|
||||
|
||||
Color& color = (appliedPose ? *slot->_applied : slot->_pose)._color;
|
||||
Color &color = (appliedPose ? *slot->_applied : slot->_pose)._color;
|
||||
if (time < _frames[0]) {
|
||||
Color& setup = slot->_data._setup._color;
|
||||
Color &setup = slot->_data._setup._color;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
color.a = setup.a;
|
||||
@ -274,13 +274,13 @@ void RGBA2Timeline::setFrame(int frame, float time, float r, float g, float b, f
|
||||
_frames[frame + B2] = b2;
|
||||
}
|
||||
|
||||
void RGBA2Timeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, MixBlend blend) {
|
||||
Color& light = pose._color;
|
||||
Color& dark = pose._darkColor;
|
||||
void RGBA2Timeline::apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) {
|
||||
Color &light = pose._color;
|
||||
Color &dark = pose._darkColor;
|
||||
if (time < _frames[0]) {
|
||||
SlotPose& setup = slot._data._setup;
|
||||
Color& setupLight = setup._color;
|
||||
Color& setupDark = setup._darkColor;
|
||||
SlotPose &setup = slot._data._setup;
|
||||
Color &setupLight = setup._color;
|
||||
Color &setupDark = setup._darkColor;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
light.set(setupLight);
|
||||
@ -352,9 +352,9 @@ void RGBA2Timeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, M
|
||||
dark.b = b2;
|
||||
} else {
|
||||
if (blend == MixBlend_Setup) {
|
||||
SlotPose& setup = slot._data._setup;
|
||||
SlotPose &setup = slot._data._setup;
|
||||
light.set(setup._color);
|
||||
Color& setupDark = setup._darkColor;
|
||||
Color &setupDark = setup._darkColor;
|
||||
dark.r = setupDark.r;
|
||||
dark.g = setupDark.g;
|
||||
dark.b = setupDark.b;
|
||||
@ -390,13 +390,13 @@ void RGB2Timeline::setFrame(int frame, float time, float r, float g, float b, fl
|
||||
_frames[frame + B2] = b2;
|
||||
}
|
||||
|
||||
void RGB2Timeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, MixBlend blend) {
|
||||
Color& light = pose._color;
|
||||
Color& dark = pose._darkColor;
|
||||
void RGB2Timeline::apply(Slot &slot, SlotPose &pose, float time, float alpha, MixBlend blend) {
|
||||
Color &light = pose._color;
|
||||
Color &dark = pose._darkColor;
|
||||
if (time < _frames[0]) {
|
||||
SlotPose& setup = slot._data._setup;
|
||||
Color& setupLight = setup._color;
|
||||
Color& setupDark = setup._darkColor;
|
||||
SlotPose &setup = slot._data._setup;
|
||||
Color &setupLight = setup._color;
|
||||
Color &setupDark = setup._darkColor;
|
||||
switch (blend) {
|
||||
case MixBlend_Setup:
|
||||
light.r = setupLight.r;
|
||||
@ -469,7 +469,7 @@ void RGB2Timeline::apply(Slot& slot, SlotPose& pose, float time, float alpha, Mi
|
||||
dark.b = b2;
|
||||
} else {
|
||||
if (blend == MixBlend_Setup) {
|
||||
SlotPose& setup = slot._data._setup;
|
||||
SlotPose &setup = slot._data._setup;
|
||||
light.r = setup._color.r;
|
||||
light.g = setup._color.g;
|
||||
light.b = setup._color.b;
|
||||
|
||||
@ -64,7 +64,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
|
||||
Slot *slotP = skeleton._slots[_slotIndex];
|
||||
Slot &slot = *slotP;
|
||||
if (!slot._bone.isActive()) return;
|
||||
SlotPose& pose = appliedPose ? *slot._applied : slot._pose;
|
||||
SlotPose &pose = appliedPose ? *slot._applied : slot._pose;
|
||||
|
||||
apply(slot, pose, time, alpha, blend);
|
||||
}
|
||||
@ -124,7 +124,7 @@ void DeformTimeline::apply(Slot &slot, SlotPose &pose, float time, float alpha,
|
||||
deformArray.setSize(vertexCount, 0);
|
||||
Vector<float> &deform = deformArray;
|
||||
|
||||
if (time >= frames[frames.size() - 1]) { // Time is after last frame.
|
||||
if (time >= frames[frames.size() - 1]) {// Time is after last frame.
|
||||
Vector<float> &lastVertices = vertices[frames.size() - 1];
|
||||
if (alpha == 1) {
|
||||
if (blend == MixBlend_Add) {
|
||||
@ -266,7 +266,7 @@ void DeformTimeline::setBezier(size_t bezier, size_t frame, float value, float t
|
||||
SP_UNUSED(value2);
|
||||
Vector<float> &curves = _curves;
|
||||
size_t i = getFrameCount() + bezier * BEZIER_SIZE;
|
||||
if (value == 0) curves[frame] = BEZIER + (float)i;
|
||||
if (value == 0) curves[frame] = BEZIER + (float) i;
|
||||
float tmpx = (time1 - cx1 * 2 + cx2) * 0.03f, tmpy = cy2 * 0.03f - cy1 * 0.06f;
|
||||
float dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006f, dddy = (cy1 - cy2 + 0.33333333f) * 0.018f;
|
||||
float ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
|
||||
@ -286,7 +286,7 @@ void DeformTimeline::setBezier(size_t bezier, size_t frame, float value, float t
|
||||
|
||||
float DeformTimeline::getCurvePercent(float time, int frame) {
|
||||
Vector<float> &curves = _curves;
|
||||
int i = (int)curves[frame];
|
||||
int i = (int) curves[frame];
|
||||
switch (i) {
|
||||
case LINEAR: {
|
||||
float x = _frames[frame];
|
||||
|
||||
@ -72,7 +72,7 @@ void EventTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < _frames[0]) return; // Time is before first frame.
|
||||
if (time < _frames[0]) return;// Time is before first frame.
|
||||
|
||||
int i;
|
||||
if (lastTime < _frames[0]) {
|
||||
@ -100,6 +100,6 @@ size_t EventTimeline::getFrameCount() {
|
||||
return _frames.size();
|
||||
}
|
||||
|
||||
Vector<Event *> &EventTimeline::getEvents() {
|
||||
return _events;
|
||||
Vector<Event *> &EventTimeline::getEvents() {
|
||||
return _events;
|
||||
}
|
||||
|
||||
@ -41,52 +41,52 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(IkConstraint, Constraint)
|
||||
|
||||
void IkConstraint::apply(Skeleton& skeleton, BonePose& bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float mix) {
|
||||
void IkConstraint::apply(Skeleton &skeleton, BonePose &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float mix) {
|
||||
bone.modifyLocal(skeleton);
|
||||
BonePose& p = bone._bone->getParent()->getAppliedPose();
|
||||
BonePose &p = bone._bone->getParent()->getAppliedPose();
|
||||
float pa = p._a, pb = p._b, pc = p._c, pd = p._d;
|
||||
float rotationIK = -bone._shearX - bone._rotation, tx, ty;
|
||||
switch (bone._inherit) {
|
||||
case Inherit_OnlyTranslation:
|
||||
tx = (targetX - bone._worldX) * MathUtil::sign(skeleton.getScaleX());
|
||||
ty = (targetY - bone._worldY) * MathUtil::sign(skeleton.getScaleY());
|
||||
break;
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float s = MathUtil::abs(pa * pd - pb * pc) / MathUtil::max(0.0001f, pa * pa + pc * pc);
|
||||
float sa = pa / skeleton.getScaleX();
|
||||
float sc = pc / skeleton.getScaleY();
|
||||
pb = -sc * s * skeleton.getScaleX();
|
||||
pd = sa * s * skeleton.getScaleY();
|
||||
rotationIK += MathUtil::atan2Deg(sc, sa);
|
||||
// Fall through.
|
||||
}
|
||||
default:
|
||||
float x = targetX - p._worldX, y = targetY - p._worldY;
|
||||
float d = pa * pd - pb * pc;
|
||||
if (MathUtil::abs(d) <= 0.0001f) {
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
} else {
|
||||
tx = (x * pd - y * pb) / d - bone._x;
|
||||
ty = (y * pa - x * pc) / d - bone._y;
|
||||
case Inherit_OnlyTranslation:
|
||||
tx = (targetX - bone._worldX) * MathUtil::sign(skeleton.getScaleX());
|
||||
ty = (targetY - bone._worldY) * MathUtil::sign(skeleton.getScaleY());
|
||||
break;
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float s = MathUtil::abs(pa * pd - pb * pc) / MathUtil::max(0.0001f, pa * pa + pc * pc);
|
||||
float sa = pa / skeleton.getScaleX();
|
||||
float sc = pc / skeleton.getScaleY();
|
||||
pb = -sc * s * skeleton.getScaleX();
|
||||
pd = sa * s * skeleton.getScaleY();
|
||||
rotationIK += MathUtil::atan2Deg(sc, sa);
|
||||
// Fall through.
|
||||
}
|
||||
default:
|
||||
float x = targetX - p._worldX, y = targetY - p._worldY;
|
||||
float d = pa * pd - pb * pc;
|
||||
if (MathUtil::abs(d) <= 0.0001f) {
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
} else {
|
||||
tx = (x * pd - y * pb) / d - bone._x;
|
||||
ty = (y * pa - x * pc) / d - bone._y;
|
||||
}
|
||||
}
|
||||
rotationIK += MathUtil::atan2Deg(ty, tx);
|
||||
if (bone._scaleX < 0) rotationIK += 180;
|
||||
if (rotationIK > 180)
|
||||
rotationIK -= 360;
|
||||
else if (rotationIK < -180) //
|
||||
else if (rotationIK < -180)//
|
||||
rotationIK += 360;
|
||||
bone._rotation += rotationIK * mix;
|
||||
if (compress || stretch) {
|
||||
switch (bone._inherit) {
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection:
|
||||
tx = targetX - bone._worldX;
|
||||
ty = targetY - bone._worldY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection:
|
||||
tx = targetX - bone._worldX;
|
||||
ty = targetY - bone._worldY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
float b = bone._bone->getData().getLength() * bone._scaleX;
|
||||
if (b > 0.0001f) {
|
||||
@ -100,8 +100,8 @@ void IkConstraint::apply(Skeleton& skeleton, BonePose& bone, float targetX, floa
|
||||
}
|
||||
}
|
||||
|
||||
void IkConstraint::apply(Skeleton& skeleton, BonePose& parent, BonePose& child, float targetX, float targetY, int bendDir,
|
||||
bool stretch, bool uniform, float softness, float mix) {
|
||||
void IkConstraint::apply(Skeleton &skeleton, BonePose &parent, BonePose &child, float targetX, float targetY, int bendDir,
|
||||
bool stretch, bool uniform, float softness, float mix) {
|
||||
if (parent._inherit != Inherit_Normal || child._inherit != Inherit_Normal) return;
|
||||
parent.modifyLocal(skeleton);
|
||||
child.modifyLocal(skeleton);
|
||||
@ -134,7 +134,7 @@ void IkConstraint::apply(Skeleton& skeleton, BonePose& parent, BonePose& child,
|
||||
cwx = a * child._x + b * child._y + parent._worldX;
|
||||
cwy = c * child._x + d * child._y + parent._worldY;
|
||||
}
|
||||
BonePose& pp = parent._bone->getParent()->getAppliedPose();
|
||||
BonePose &pp = parent._bone->getParent()->getAppliedPose();
|
||||
a = pp._a;
|
||||
b = pp._b;
|
||||
c = pp._c;
|
||||
@ -163,7 +163,7 @@ void IkConstraint::apply(Skeleton& skeleton, BonePose& parent, BonePose& child,
|
||||
dd = tx * tx + ty * ty;
|
||||
}
|
||||
}
|
||||
outer:
|
||||
outer:
|
||||
if (u) {
|
||||
l2 *= psx;
|
||||
float cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||
@ -233,25 +233,24 @@ void IkConstraint::apply(Skeleton& skeleton, BonePose& parent, BonePose& child,
|
||||
a2 = maxAngle * bendDir;
|
||||
}
|
||||
}
|
||||
outer_break:
|
||||
outer_break:
|
||||
float os = MathUtil::atan2(child._y, child._x) * s2;
|
||||
a1 = (a1 - os) * MathUtil::Rad_Deg + os1 - parent._rotation;
|
||||
if (a1 > 180)
|
||||
a1 -= 360;
|
||||
else if (a1 < -180) //
|
||||
else if (a1 < -180)//
|
||||
a1 += 360;
|
||||
parent._rotation += a1 * mix;
|
||||
a2 = ((a2 + os) * MathUtil::Rad_Deg - child._shearX) * s2 + os2 - child._rotation;
|
||||
if (a2 > 180)
|
||||
a2 -= 360;
|
||||
else if (a2 < -180) //
|
||||
else if (a2 < -180)//
|
||||
a2 += 360;
|
||||
child._rotation += a2 * mix;
|
||||
}
|
||||
|
||||
IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) :
|
||||
ConstraintGeneric<IkConstraint, IkConstraintData, IkConstraintPose>(data),
|
||||
_target(skeleton.findBone(data.getTarget()->getName())) {
|
||||
IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) : ConstraintGeneric<IkConstraint, IkConstraintData, IkConstraintPose>(data),
|
||||
_target(skeleton.findBone(data.getTarget()->getName())) {
|
||||
|
||||
_bones.ensureCapacity(data.getBones().size());
|
||||
for (size_t i = 0; i < data.getBones().size(); i++) {
|
||||
@ -260,10 +259,10 @@ IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) :
|
||||
}
|
||||
}
|
||||
|
||||
void IkConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
IkConstraintPose& p = *_applied;
|
||||
void IkConstraint::update(Skeleton &skeleton, Physics physics) {
|
||||
IkConstraintPose &p = *_applied;
|
||||
if (p._mix == 0) return;
|
||||
BonePose& target = _target->getAppliedPose();
|
||||
BonePose &target = _target->getAppliedPose();
|
||||
switch (_bones.size()) {
|
||||
case 1: {
|
||||
apply(skeleton, *_bones[0], target._worldX, target._worldY, p._compress, p._stretch, _data._uniform, p._mix);
|
||||
@ -292,23 +291,23 @@ void IkConstraint::setTarget(Bone *target) {
|
||||
_target = target;
|
||||
}
|
||||
|
||||
void IkConstraint::sort(Skeleton& skeleton) {
|
||||
void IkConstraint::sort(Skeleton &skeleton) {
|
||||
skeleton.sortBone(_target);
|
||||
Bone* parent = _bones[0]->_bone;
|
||||
Bone *parent = _bones[0]->_bone;
|
||||
skeleton.sortBone(parent);
|
||||
skeleton._updateCache.add(this);
|
||||
parent->_sorted = false;
|
||||
skeleton.sortReset(parent->_children);
|
||||
skeleton.constrained(parent);
|
||||
if (_bones.size() > 1) skeleton.constrained(_bones[1]->_bone);
|
||||
skeleton.constrained(*parent);
|
||||
if (_bones.size() > 1) skeleton.constrained(*_bones[1]->_bone);
|
||||
}
|
||||
|
||||
bool IkConstraint::isSourceActive() {
|
||||
return _target->_active;
|
||||
}
|
||||
|
||||
IkConstraint* IkConstraint::copy(Skeleton& skeleton) {
|
||||
IkConstraint* copy = new IkConstraint(_data, skeleton);
|
||||
IkConstraint *IkConstraint::copy(Skeleton &skeleton) {
|
||||
IkConstraint *copy = new IkConstraint(_data, skeleton);
|
||||
copy->_pose.set(_pose);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ IkConstraintPose::IkConstraintPose() : _bendDirection(0), _compress(false), _str
|
||||
IkConstraintPose::~IkConstraintPose() {
|
||||
}
|
||||
|
||||
void IkConstraintPose::set(IkConstraintPose& pose) {
|
||||
void IkConstraintPose::set(IkConstraintPose &pose) {
|
||||
_mix = pose._mix;
|
||||
_softness = pose._softness;
|
||||
_bendDirection = pose._bendDirection;
|
||||
|
||||
@ -51,9 +51,8 @@ const int PathConstraint::NONE = -1;
|
||||
const int PathConstraint::BEFORE = -2;
|
||||
const int PathConstraint::AFTER = -3;
|
||||
|
||||
PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) :
|
||||
ConstraintGeneric<PathConstraint, PathConstraintData, PathConstraintPose>(data),
|
||||
_slot(skeleton._slots.buffer()[data._slot->_index]) {
|
||||
PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) : ConstraintGeneric<PathConstraint, PathConstraintData, PathConstraintPose>(data),
|
||||
_slot(skeleton._slots.buffer()[data._slot->_index]) {
|
||||
|
||||
_bones.ensureCapacity(data.getBones().size());
|
||||
for (size_t i = 0; i < data.getBones().size(); i++) {
|
||||
@ -64,25 +63,25 @@ PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) :
|
||||
_segments.setSize(10, 0);
|
||||
}
|
||||
|
||||
void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
void PathConstraint::update(Skeleton &skeleton, Physics physics) {
|
||||
Attachment *baseAttachment = _slot->getAppliedPose().getAttachment();
|
||||
if (baseAttachment == NULL || !baseAttachment->getRTTI().instanceOf(PathAttachment::rtti)) {
|
||||
return;
|
||||
}
|
||||
PathAttachment *pathAttachment = static_cast<PathAttachment *>(baseAttachment);
|
||||
|
||||
PathConstraintPose& p = *_applied;
|
||||
PathConstraintPose &p = *_applied;
|
||||
float mixRotate = p._mixRotate, mixX = p._mixX, mixY = p._mixY;
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
|
||||
|
||||
PathConstraintData& data = _data;
|
||||
PathConstraintData &data = _data;
|
||||
bool tangents = data.getRotateMode() == RotateMode_Tangent, scale = data.getRotateMode() == RotateMode_ChainScale;
|
||||
size_t boneCount = _bones.size();
|
||||
size_t spacesCount = tangents ? boneCount : boneCount + 1;
|
||||
BonePose** bones = _bones.buffer();
|
||||
BonePose **bones = _bones.buffer();
|
||||
_spaces.setSize(spacesCount, 0);
|
||||
float* spaces = _spaces.buffer();
|
||||
float* lengths = NULL;
|
||||
float *spaces = _spaces.buffer();
|
||||
float *lengths = NULL;
|
||||
if (scale) {
|
||||
_lengths.setSize(boneCount, 0);
|
||||
lengths = _lengths.buffer();
|
||||
@ -93,7 +92,7 @@ void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
case SpacingMode_Percent: {
|
||||
if (scale) {
|
||||
for (size_t i = 0, n = spacesCount - 1; i < n; i++) {
|
||||
BonePose* bone = bones[i];
|
||||
BonePose *bone = bones[i];
|
||||
float setupLength = bone->_bone->getData().getLength();
|
||||
float x = setupLength * bone->_a;
|
||||
float y = setupLength * bone->_c;
|
||||
@ -108,7 +107,7 @@ void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
case SpacingMode_Proportional: {
|
||||
float sum = 0;
|
||||
for (size_t i = 0, n = spacesCount - 1; i < n;) {
|
||||
BonePose* bone = bones[i];
|
||||
BonePose *bone = bones[i];
|
||||
float setupLength = bone->_bone->getData().getLength();
|
||||
if (setupLength < epsilon) {
|
||||
if (scale) lengths[i] = 0;
|
||||
@ -132,7 +131,7 @@ void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
default: {
|
||||
bool lengthSpacing = data.getSpacingMode() == SpacingMode_Length;
|
||||
for (size_t i = 0, n = spacesCount - 1; i < n;) {
|
||||
BonePose* bone = bones[i];
|
||||
BonePose *bone = bones[i];
|
||||
float setupLength = bone->_bone->getData().getLength();
|
||||
if (setupLength < epsilon) {
|
||||
if (scale) lengths[i] = 0;
|
||||
@ -148,20 +147,20 @@ void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
}
|
||||
|
||||
Vector<float> &positions = computeWorldPositions(skeleton, *pathAttachment, (int) spacesCount, tangents);
|
||||
float* positionsBuffer = positions.buffer();
|
||||
float *positionsBuffer = positions.buffer();
|
||||
float boneX = positionsBuffer[0], boneY = positionsBuffer[1], offsetRotation = data.getOffsetRotation();
|
||||
bool tip;
|
||||
if (offsetRotation == 0)
|
||||
tip = data.getRotateMode() == RotateMode_Chain;
|
||||
else {
|
||||
tip = false;
|
||||
BonePose& bone = _slot->getBone().getAppliedPose();
|
||||
BonePose &bone = _slot->getBone().getAppliedPose();
|
||||
offsetRotation *= bone._a * bone._d - bone._b * bone._c > 0 ? MathUtil::Deg_Rad : -MathUtil::Deg_Rad;
|
||||
}
|
||||
for (size_t i = 0, ip = 3; i < boneCount; i++, ip += 3) {
|
||||
// int u = skeleton.update; // TODO: Add int update field to Skeleton class
|
||||
int u = 1; // Temporary placeholder until Skeleton.update is implemented
|
||||
BonePose* bone = bones[i];
|
||||
int u = 1;// Temporary placeholder until Skeleton.update is implemented
|
||||
BonePose *bone = bones[i];
|
||||
bone->_worldX += (boneX - bone->_worldX) * mixX;
|
||||
bone->_worldY += (boneY - bone->_worldY) * mixY;
|
||||
float x = positionsBuffer[ip], y = positionsBuffer[ip + 1], dx = x - boneX, dy = y - boneY;
|
||||
@ -209,17 +208,17 @@ void PathConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
}
|
||||
|
||||
|
||||
void PathConstraint::sort(Skeleton& skeleton) {
|
||||
void PathConstraint::sort(Skeleton &skeleton) {
|
||||
int slotIndex = _slot->getData().getIndex();
|
||||
Bone& slotBone = _slot->getBone();
|
||||
Bone &slotBone = _slot->getBone();
|
||||
if (skeleton.getSkin() != NULL) sortPathSlot(skeleton, *skeleton.getSkin(), slotIndex, slotBone);
|
||||
if (skeleton.getData()->getDefaultSkin() != NULL && skeleton.getData()->getDefaultSkin() != skeleton.getSkin())
|
||||
sortPathSlot(skeleton, *skeleton.getData()->getDefaultSkin(), slotIndex, slotBone);
|
||||
sortPath(skeleton, _slot->getAppliedPose().getAttachment(), slotBone);
|
||||
BonePose** bones = _bones.buffer();
|
||||
BonePose **bones = _bones.buffer();
|
||||
size_t boneCount = _bones.size();
|
||||
for (size_t i = 0; i < boneCount; i++) {
|
||||
Bone* bone = bones[i]->_bone;
|
||||
Bone *bone = bones[i]->_bone;
|
||||
skeleton.sortBone(bone);
|
||||
// skeleton.constrained(bone); // TODO: Add constrained() method to Skeleton class
|
||||
}
|
||||
@ -251,13 +250,13 @@ void PathConstraint::setSlot(Slot *slot) {
|
||||
}
|
||||
|
||||
Vector<float> &
|
||||
PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path, int spacesCount, bool tangents) {
|
||||
PathConstraint::computeWorldPositions(Skeleton &skeleton, PathAttachment &path, int spacesCount, bool tangents) {
|
||||
Slot &slot = *_slot;
|
||||
float position = _applied->_position;
|
||||
float* spaces = _spaces.buffer();
|
||||
float *spaces = _spaces.buffer();
|
||||
_positions.setSize(spacesCount * 3 + 2, 0);
|
||||
Vector<float> &out = _positions;
|
||||
float* outBuffer = out.buffer();
|
||||
float *outBuffer = out.buffer();
|
||||
Vector<float> &world = _world;
|
||||
bool closed = path.isClosed();
|
||||
int verticesLength = (int) path.getWorldVerticesLength();
|
||||
@ -267,7 +266,7 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
float pathLength;
|
||||
if (!path.isConstantSpeed()) {
|
||||
Vector<float> &lengths = path.getLengths();
|
||||
float* lengthsBuffer = lengths.buffer();
|
||||
float *lengthsBuffer = lengths.buffer();
|
||||
curveCount -= closed ? 1 : 2;
|
||||
pathLength = lengthsBuffer[curveCount];
|
||||
if (_data.getPositionMode() == PositionMode_Percent) position *= pathLength;
|
||||
@ -285,7 +284,7 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
}
|
||||
|
||||
world.setSize(8, 0);
|
||||
float* worldBuffer = world.buffer();
|
||||
float *worldBuffer = world.buffer();
|
||||
for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
|
||||
float space = spaces[i] * multiplier;
|
||||
position += space;
|
||||
@ -341,7 +340,7 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
if (closed) {
|
||||
verticesLength += 2;
|
||||
world.setSize(verticesLength, 0);
|
||||
float* worldBuffer = world.buffer();
|
||||
float *worldBuffer = world.buffer();
|
||||
path.computeWorldVertices(skeleton, *_slot, 2, verticesLength - 4, world, 0, 2);
|
||||
path.computeWorldVertices(skeleton, *_slot, 0, 2, world, verticesLength - 4, 2);
|
||||
worldBuffer[verticesLength - 2] = worldBuffer[0];
|
||||
@ -352,11 +351,11 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
world.setSize(verticesLength, 0);
|
||||
path.computeWorldVertices(skeleton, *_slot, 2, verticesLength, world, 0, 2);
|
||||
}
|
||||
float* worldBuffer = world.buffer();
|
||||
float *worldBuffer = world.buffer();
|
||||
|
||||
// Curve lengths.
|
||||
_curves.setSize(curveCount, 0);
|
||||
float* curvesBuffer = _curves.buffer();
|
||||
float *curvesBuffer = _curves.buffer();
|
||||
pathLength = 0;
|
||||
float x1 = worldBuffer[0], y1 = worldBuffer[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
|
||||
float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;
|
||||
@ -405,7 +404,7 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
default:
|
||||
multiplier = 1;
|
||||
}
|
||||
float* segmentsBuffer = _segments.buffer();
|
||||
float *segmentsBuffer = _segments.buffer();
|
||||
|
||||
float curveLength = 0;
|
||||
for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
|
||||
@ -501,8 +500,8 @@ PathConstraint::computeWorldPositions(Skeleton& skeleton, PathAttachment &path,
|
||||
}
|
||||
|
||||
void PathConstraint::addBeforePosition(float p, Vector<float> &temp, int i, Vector<float> &output, int o) {
|
||||
float* tempBuffer = temp.buffer();
|
||||
float* outBuffer = output.buffer();
|
||||
float *tempBuffer = temp.buffer();
|
||||
float *outBuffer = output.buffer();
|
||||
float x1 = tempBuffer[i], y1 = tempBuffer[i + 1], dx = tempBuffer[i + 2] - x1, dy = tempBuffer[i + 3] - y1, r = MathUtil::atan2(dy, dx);
|
||||
outBuffer[o] = x1 + p * MathUtil::cos(r);
|
||||
outBuffer[o + 1] = y1 + p * MathUtil::sin(r);
|
||||
@ -510,8 +509,8 @@ void PathConstraint::addBeforePosition(float p, Vector<float> &temp, int i, Vect
|
||||
}
|
||||
|
||||
void PathConstraint::addAfterPosition(float p, Vector<float> &temp, int i, Vector<float> &output, int o) {
|
||||
float* tempBuffer = temp.buffer();
|
||||
float* outBuffer = output.buffer();
|
||||
float *tempBuffer = temp.buffer();
|
||||
float *outBuffer = output.buffer();
|
||||
float x1 = tempBuffer[i + 2], y1 = tempBuffer[i + 3], dx = x1 - tempBuffer[i], dy = y1 - tempBuffer[i + 1], r = MathUtil::atan2(dy, dx);
|
||||
outBuffer[o] = x1 + p * MathUtil::cos(r);
|
||||
outBuffer[o + 1] = y1 + p * MathUtil::sin(r);
|
||||
@ -520,7 +519,7 @@ void PathConstraint::addAfterPosition(float p, Vector<float> &temp, int i, Vecto
|
||||
|
||||
void PathConstraint::addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2,
|
||||
float y2, Vector<float> &output, int o, bool tangents) {
|
||||
float* outBuffer = output.buffer();
|
||||
float *outBuffer = output.buffer();
|
||||
if (p < epsilon || MathUtil::isNan(p)) {
|
||||
outBuffer[o] = x1;
|
||||
outBuffer[o + 1] = y1;
|
||||
@ -537,11 +536,11 @@ void PathConstraint::addCurvePosition(float p, float x1, float y1, float cx1, fl
|
||||
outBuffer[o + 2] = MathUtil::atan2(cy1 - y1, cx1 - x1);
|
||||
else
|
||||
outBuffer[o + 2] = MathUtil::atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt),
|
||||
x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||
x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||
}
|
||||
}
|
||||
|
||||
void PathConstraint::sortPathSlot(Skeleton& skeleton, Skin& skin, int slotIndex, Bone& slotBone) {
|
||||
void PathConstraint::sortPathSlot(Skeleton &skeleton, Skin &skin, int slotIndex, Bone &slotBone) {
|
||||
// Object[] entries = skin.attachments.orderedItems().items;
|
||||
// for (int i = 0, n = skin.attachments.size; i < n; i++) {
|
||||
// var entry = (SkinEntry)entries[i];
|
||||
@ -550,9 +549,9 @@ void PathConstraint::sortPathSlot(Skeleton& skeleton, Skin& skin, int slotIndex,
|
||||
// TODO: Implement when Skin API is available
|
||||
}
|
||||
|
||||
void PathConstraint::sortPath(Skeleton& skeleton, Attachment* attachment, Bone& slotBone) {
|
||||
void PathConstraint::sortPath(Skeleton &skeleton, Attachment *attachment, Bone &slotBone) {
|
||||
if (attachment == NULL || !attachment->getRTTI().instanceOf(PathAttachment::rtti)) return;
|
||||
PathAttachment* pathAttachment = static_cast<PathAttachment*>(attachment);
|
||||
PathAttachment *pathAttachment = static_cast<PathAttachment *>(attachment);
|
||||
// int[] pathBones = pathAttachment.getBones();
|
||||
// if (pathBones == null)
|
||||
// skeleton.sortBone(slotBone);
|
||||
|
||||
@ -37,50 +37,50 @@ PathConstraintPose::PathConstraintPose() : Pose<PathConstraintPose>(), _position
|
||||
PathConstraintPose::~PathConstraintPose() {
|
||||
}
|
||||
|
||||
void PathConstraintPose::set(PathConstraintPose& pose) {
|
||||
_position = pose._position;
|
||||
_spacing = pose._spacing;
|
||||
_mixRotate = pose._mixRotate;
|
||||
_mixX = pose._mixX;
|
||||
_mixY = pose._mixY;
|
||||
void PathConstraintPose::set(PathConstraintPose &pose) {
|
||||
_position = pose._position;
|
||||
_spacing = pose._spacing;
|
||||
_mixRotate = pose._mixRotate;
|
||||
_mixX = pose._mixX;
|
||||
_mixY = pose._mixY;
|
||||
}
|
||||
|
||||
float PathConstraintPose::getPosition() {
|
||||
return _position;
|
||||
return _position;
|
||||
}
|
||||
|
||||
void PathConstraintPose::setPosition(float position) {
|
||||
_position = position;
|
||||
_position = position;
|
||||
}
|
||||
|
||||
float PathConstraintPose::getSpacing() {
|
||||
return _spacing;
|
||||
return _spacing;
|
||||
}
|
||||
|
||||
void PathConstraintPose::setSpacing(float spacing) {
|
||||
_spacing = spacing;
|
||||
_spacing = spacing;
|
||||
}
|
||||
|
||||
float PathConstraintPose::getMixRotate() {
|
||||
return _mixRotate;
|
||||
return _mixRotate;
|
||||
}
|
||||
|
||||
void PathConstraintPose::setMixRotate(float mixRotate) {
|
||||
_mixRotate = mixRotate;
|
||||
_mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
float PathConstraintPose::getMixX() {
|
||||
return _mixX;
|
||||
return _mixX;
|
||||
}
|
||||
|
||||
void PathConstraintPose::setMixX(float mixX) {
|
||||
_mixX = mixX;
|
||||
_mixX = mixX;
|
||||
}
|
||||
|
||||
float PathConstraintPose::getMixY() {
|
||||
return _mixY;
|
||||
return _mixY;
|
||||
}
|
||||
|
||||
void PathConstraintPose::setMixY(float mixY) {
|
||||
_mixY = mixY;
|
||||
_mixY = mixY;
|
||||
}
|
||||
@ -41,43 +41,42 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(PhysicsConstraint, Constraint)
|
||||
|
||||
PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton) :
|
||||
ConstraintGeneric<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) {
|
||||
PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton) : ConstraintGeneric<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();
|
||||
_bone = &skeleton.getBones()[(size_t) data.getBone()->getIndex()]->getAppliedPose();
|
||||
}
|
||||
|
||||
PhysicsConstraint* PhysicsConstraint::copy(Skeleton& skeleton) {
|
||||
PhysicsConstraint* copy = new (__FILE__, __LINE__) PhysicsConstraint(_data, skeleton);
|
||||
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;
|
||||
void PhysicsConstraint::sort(Skeleton &skeleton) {
|
||||
Bone *bone = _bone->_bone;
|
||||
skeleton.sortBone(bone);
|
||||
skeleton.updateCache.add(this);
|
||||
skeleton._updateCache.add(this);
|
||||
skeleton.sortReset(bone->_children);
|
||||
skeleton.constrained(bone);
|
||||
skeleton.constrained(*bone);
|
||||
}
|
||||
|
||||
bool PhysicsConstraint::isSourceActive() {
|
||||
return _bone->_bone->isActive();
|
||||
}
|
||||
|
||||
BonePose& PhysicsConstraint::getBone() {
|
||||
BonePose &PhysicsConstraint::getBone() {
|
||||
return *_bone;
|
||||
}
|
||||
|
||||
void PhysicsConstraint::setBone(BonePose& bone) {
|
||||
void PhysicsConstraint::setBone(BonePose &bone) {
|
||||
_bone = &bone;
|
||||
}
|
||||
|
||||
void PhysicsConstraint::reset(Skeleton& skeleton) {
|
||||
void PhysicsConstraint::reset(Skeleton &skeleton) {
|
||||
_remaining = 0;
|
||||
_lastTime = skeleton.getTime();
|
||||
_reset = true;
|
||||
@ -95,146 +94,148 @@ void PhysicsConstraint::reset(Skeleton& skeleton) {
|
||||
_scaleVelocity = 0;
|
||||
}
|
||||
|
||||
void PhysicsConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
PhysicsConstraintPose& p = *_applied;
|
||||
void PhysicsConstraint::update(Skeleton &skeleton, Physics physics) {
|
||||
PhysicsConstraintPose &p = *_applied;
|
||||
float mix = p.getMix();
|
||||
if (mix == 0) return;
|
||||
|
||||
bool x = _data.getX() > 0, y = _data.getY() > 0, rotateOrShearX = _data._rotate > 0 || _data._shearX > 0, scaleX = _data.getScaleX() > 0;
|
||||
BonePose* bone = _bone;
|
||||
BonePose *bone = _bone;
|
||||
float l = bone->_bone->getData().getLength(), t = _data.getStep(), z = 0;
|
||||
|
||||
switch (physics) {
|
||||
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();
|
||||
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 = 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 (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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
a = _remaining;
|
||||
if (a >= t) {
|
||||
if (d == -1) {
|
||||
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;
|
||||
}
|
||||
if (y) {
|
||||
_yVelocity -= (ay + _yOffset * e) * m;
|
||||
_yOffset += _yVelocity * t;
|
||||
_yVelocity *= d;
|
||||
}
|
||||
a -= t;
|
||||
} while (a >= t);
|
||||
_xLag = _xOffset - xs;
|
||||
_yLag = _yOffset - ys;
|
||||
}
|
||||
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);
|
||||
if (x) bone->_worldX += (_xOffset - _xLag * z) * mix * _data._x;
|
||||
if (y) bone->_worldY += (_yOffset - _yLag * z) * mix * _data._y;
|
||||
}
|
||||
z = MathUtil::max(0.0f, 1 - a / t);
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
_remaining = a;
|
||||
}
|
||||
_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;
|
||||
}
|
||||
_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) {
|
||||
|
||||
@ -41,11 +41,11 @@ PhysicsConstraintData::PhysicsConstraintData(const String &name) : ConstraintDat
|
||||
_windGlobal(false), _gravityGlobal(false), _mixGlobal(false) {
|
||||
}
|
||||
|
||||
BoneData* PhysicsConstraintData::getBone() {
|
||||
BoneData *PhysicsConstraintData::getBone() {
|
||||
return _bone;
|
||||
}
|
||||
|
||||
void PhysicsConstraintData::setBone(BoneData* bone) {
|
||||
void PhysicsConstraintData::setBone(BoneData *bone) {
|
||||
_bone = bone;
|
||||
}
|
||||
|
||||
|
||||
@ -37,68 +37,68 @@ PhysicsConstraintPose::PhysicsConstraintPose() : Pose<PhysicsConstraintPose>(),
|
||||
PhysicsConstraintPose::~PhysicsConstraintPose() {
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::set(PhysicsConstraintPose& pose) {
|
||||
_inertia = pose._inertia;
|
||||
_strength = pose._strength;
|
||||
_damping = pose._damping;
|
||||
_massInverse = pose._massInverse;
|
||||
_wind = pose._wind;
|
||||
_gravity = pose._gravity;
|
||||
_mix = pose._mix;
|
||||
void PhysicsConstraintPose::set(PhysicsConstraintPose &pose) {
|
||||
_inertia = pose._inertia;
|
||||
_strength = pose._strength;
|
||||
_damping = pose._damping;
|
||||
_massInverse = pose._massInverse;
|
||||
_wind = pose._wind;
|
||||
_gravity = pose._gravity;
|
||||
_mix = pose._mix;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getInertia() {
|
||||
return _inertia;
|
||||
return _inertia;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setInertia(float inertia) {
|
||||
_inertia = inertia;
|
||||
_inertia = inertia;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getStrength() {
|
||||
return _strength;
|
||||
return _strength;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setStrength(float strength) {
|
||||
_strength = strength;
|
||||
_strength = strength;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getDamping() {
|
||||
return _damping;
|
||||
return _damping;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setDamping(float damping) {
|
||||
_damping = damping;
|
||||
_damping = damping;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getMassInverse() {
|
||||
return _massInverse;
|
||||
return _massInverse;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setMassInverse(float massInverse) {
|
||||
_massInverse = massInverse;
|
||||
_massInverse = massInverse;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getWind() {
|
||||
return _wind;
|
||||
return _wind;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setWind(float wind) {
|
||||
_wind = wind;
|
||||
_wind = wind;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getGravity() {
|
||||
return _gravity;
|
||||
return _gravity;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setGravity(float gravity) {
|
||||
_gravity = gravity;
|
||||
_gravity = gravity;
|
||||
}
|
||||
|
||||
float PhysicsConstraintPose::getMix() {
|
||||
return _mix;
|
||||
return _mix;
|
||||
}
|
||||
|
||||
void PhysicsConstraintPose::setMix(float mix) {
|
||||
_mix = mix;
|
||||
_mix = mix;
|
||||
}
|
||||
@ -35,8 +35,7 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(RotateTimeline, BoneTimeline1)
|
||||
|
||||
RotateTimeline::RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_Rotate) {
|
||||
RotateTimeline::RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_Rotate) {
|
||||
}
|
||||
|
||||
void RotateTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
|
||||
@ -42,8 +42,7 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(ScaleTimeline, BoneTimeline2)
|
||||
|
||||
ScaleTimeline::ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline2(frameCount, bezierCount, boneIndex, Property_ScaleX, Property_ScaleY) {
|
||||
ScaleTimeline::ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline2(frameCount, bezierCount, boneIndex, Property_ScaleX, Property_ScaleY) {
|
||||
}
|
||||
|
||||
void ScaleTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -144,8 +143,7 @@ void ScaleTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float a
|
||||
|
||||
RTTI_IMPL(ScaleXTimeline, BoneTimeline1)
|
||||
|
||||
ScaleXTimeline::ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ScaleX) {
|
||||
ScaleXTimeline::ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ScaleX) {
|
||||
}
|
||||
|
||||
void ScaleXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -155,8 +153,7 @@ void ScaleXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float
|
||||
|
||||
RTTI_IMPL(ScaleYTimeline, BoneTimeline1)
|
||||
|
||||
ScaleYTimeline::ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ScaleY) {
|
||||
ScaleYTimeline::ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ScaleY) {
|
||||
}
|
||||
|
||||
void ScaleYTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
|
||||
@ -49,8 +49,8 @@ Sequence::Sequence(int count) : _id(nextID()),
|
||||
Sequence::~Sequence() {
|
||||
}
|
||||
|
||||
Sequence* Sequence::copy() {
|
||||
Sequence* copy = new (__FILE__, __LINE__) Sequence((int)_regions.size());
|
||||
Sequence *Sequence::copy() {
|
||||
Sequence *copy = new (__FILE__, __LINE__) Sequence((int) _regions.size());
|
||||
for (size_t i = 0; i < _regions.size(); i++) {
|
||||
copy->_regions[i] = _regions[i];
|
||||
}
|
||||
@ -60,7 +60,7 @@ Sequence* Sequence::copy() {
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Sequence::apply(SlotPose* slot, Attachment* attachment) {
|
||||
void Sequence::apply(SlotPose *slot, Attachment *attachment) {
|
||||
int index = slot->getSequenceIndex();
|
||||
if (index == -1) index = _setupIndex;
|
||||
if (index >= (int) _regions.size()) index = (int) _regions.size() - 1;
|
||||
|
||||
@ -43,7 +43,7 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(SequenceTimeline, Timeline)
|
||||
|
||||
SequenceTimeline::SequenceTimeline(size_t frameCount, int slotIndex, Attachment *attachment) : Timeline(frameCount, ENTRIES), SlotTimeline(slotIndex), _attachment((HasTextureRegion*)attachment) {
|
||||
SequenceTimeline::SequenceTimeline(size_t frameCount, int slotIndex, Attachment *attachment) : Timeline(frameCount, ENTRIES), SlotTimeline(slotIndex), _attachment((HasTextureRegion *) attachment) {
|
||||
int sequenceId = 0;
|
||||
if (attachment->getRTTI().instanceOf(RegionAttachment::rtti)) sequenceId = ((RegionAttachment *) attachment)->getSequence()->getId();
|
||||
if (attachment->getRTTI().instanceOf(MeshAttachment::rtti)) sequenceId = ((MeshAttachment *) attachment)->getSequence()->getId();
|
||||
@ -70,15 +70,15 @@ void SequenceTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vec
|
||||
|
||||
Slot *slot = skeleton.getSlots()[getSlotIndex()];
|
||||
if (!slot->getBone().isActive()) return;
|
||||
SlotPose& pose = appliedPose ? slot->getAppliedPose() : slot->getPose();
|
||||
SlotPose &pose = appliedPose ? slot->getAppliedPose() : slot->getPose();
|
||||
|
||||
Attachment *slotAttachment = pose.getAttachment();
|
||||
if (slotAttachment != (Attachment*)_attachment) {
|
||||
if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti) || ((VertexAttachment *) slotAttachment)->getTimelineAttachment() != (Attachment*)_attachment) return;
|
||||
if (slotAttachment != (Attachment *) _attachment) {
|
||||
if (slotAttachment == NULL || !slotAttachment->getRTTI().instanceOf(VertexAttachment::rtti) || ((VertexAttachment *) slotAttachment)->getTimelineAttachment() != (Attachment *) _attachment) return;
|
||||
}
|
||||
Sequence *sequence = NULL;
|
||||
if (((Attachment*)_attachment)->getRTTI().instanceOf(RegionAttachment::rtti)) sequence = ((RegionAttachment *) _attachment)->getSequence();
|
||||
if (((Attachment*)_attachment)->getRTTI().instanceOf(MeshAttachment::rtti)) sequence = ((MeshAttachment *) _attachment)->getSequence();
|
||||
if (((Attachment *) _attachment)->getRTTI().instanceOf(RegionAttachment::rtti)) sequence = ((RegionAttachment *) _attachment)->getSequence();
|
||||
if (((Attachment *) _attachment)->getRTTI().instanceOf(MeshAttachment::rtti)) sequence = ((MeshAttachment *) _attachment)->getSequence();
|
||||
if (!sequence) return;
|
||||
|
||||
if (direction == MixDirection_Out) {
|
||||
|
||||
@ -42,8 +42,7 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(ShearTimeline, BoneTimeline2)
|
||||
|
||||
ShearTimeline::ShearTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline2(frameCount, bezierCount, boneIndex, Property_ShearX, Property_ShearY) {
|
||||
ShearTimeline::ShearTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline2(frameCount, bezierCount, boneIndex, Property_ShearX, Property_ShearY) {
|
||||
}
|
||||
|
||||
void ShearTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -106,8 +105,7 @@ void ShearTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float a
|
||||
|
||||
RTTI_IMPL(ShearXTimeline, BoneTimeline1)
|
||||
|
||||
ShearXTimeline::ShearXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ShearX) {
|
||||
ShearXTimeline::ShearXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ShearX) {
|
||||
}
|
||||
|
||||
void ShearXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -117,8 +115,7 @@ void ShearXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float
|
||||
|
||||
RTTI_IMPL(ShearYTimeline, BoneTimeline1)
|
||||
|
||||
ShearYTimeline::ShearYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ShearY) {
|
||||
ShearYTimeline::ShearYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_ShearY) {
|
||||
}
|
||||
|
||||
void ShearYTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
|
||||
@ -251,16 +251,16 @@ Vector<ConstraintData *> &SkeletonData::getConstraints() {
|
||||
// Build unified constraints array by aggregating all constraint types
|
||||
_constraints.clear();
|
||||
for (size_t i = 0, n = _ikConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_ikConstraints[i]));
|
||||
_constraints.add(static_cast<ConstraintData *>(_ikConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _transformConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_transformConstraints[i]));
|
||||
_constraints.add(static_cast<ConstraintData *>(_transformConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _pathConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_pathConstraints[i]));
|
||||
_constraints.add(static_cast<ConstraintData *>(_pathConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _physicsConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_physicsConstraints[i]));
|
||||
_constraints.add(static_cast<ConstraintData *>(_physicsConstraints[i]));
|
||||
}
|
||||
return _constraints;
|
||||
}
|
||||
|
||||
569
spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp
Normal file
569
spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp
Normal file
@ -0,0 +1,569 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/SkeletonData.h>
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
#include <spine/PhysicsConstraintData.h>
|
||||
#include <spine/IkConstraintData.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/IkConstraint.h>
|
||||
#include <spine/PathConstraint.h>
|
||||
#include <spine/PhysicsConstraint.h>
|
||||
#include <spine/TransformConstraint.h>
|
||||
#include <spine/Skin.h>
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/MeshAttachment.h>
|
||||
#include <spine/ClippingAttachment.h>
|
||||
#include <spine/SkeletonClipping.h>
|
||||
#include <spine/MathUtil.h>
|
||||
#include <spine/BonePose.h>
|
||||
#include <spine/SlotPose.h>
|
||||
#include <spine/Posed.h>
|
||||
#include <spine/Update.h>
|
||||
#include <float.h>
|
||||
|
||||
using namespace spine;
|
||||
|
||||
static const unsigned short quadTriangles[] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
Skeleton::Skeleton(SkeletonData &skeletonData) : _data(skeletonData), _skin(NULL), _color(1, 1, 1, 1),
|
||||
_scaleX(1), _scaleY(1), _x(0), _y(0), _time(0), _windX(1), _windY(0), _gravityX(0), _gravityY(1), _update(0) {
|
||||
|
||||
// Create bones
|
||||
_bones.ensureCapacity(_data.getBones().size());
|
||||
Vector<BoneData *> &boneDataArray = _data.getBones();
|
||||
for (size_t i = 0; i < boneDataArray.size(); ++i) {
|
||||
BoneData *boneData = boneDataArray[i];
|
||||
Bone *bone;
|
||||
if (boneData->getParent() == NULL) {
|
||||
bone = new (__FILE__, __LINE__) Bone(*boneData, NULL);
|
||||
} else {
|
||||
Bone *parent = _bones[boneData->getParent()->getIndex()];
|
||||
bone = new (__FILE__, __LINE__) Bone(*boneData, parent);
|
||||
parent->getChildren().add(bone);
|
||||
}
|
||||
_bones.add(bone);
|
||||
}
|
||||
|
||||
// Create slots
|
||||
_slots.ensureCapacity(_data.getSlots().size());
|
||||
_drawOrder.ensureCapacity(_data.getSlots().size());
|
||||
Vector<SlotData *> &slotDataArray = _data.getSlots();
|
||||
for (size_t i = 0; i < slotDataArray.size(); ++i) {
|
||||
SlotData *slotData = slotDataArray[i];
|
||||
Slot *slot = new (__FILE__, __LINE__) Slot(*slotData, *this);
|
||||
_slots.add(slot);
|
||||
_drawOrder.add(slot);
|
||||
}
|
||||
|
||||
// Create constraints and physics
|
||||
_physics.ensureCapacity(8);
|
||||
_constraints.ensureCapacity(_data.getConstraints().size());
|
||||
Vector<ConstraintData *> &constraintDataArray = _data.getConstraints();
|
||||
for (size_t i = 0; i < constraintDataArray.size(); ++i) {
|
||||
ConstraintData *constraintData = constraintDataArray[i];
|
||||
Constraint *constraint = constraintData->create(*this);
|
||||
PhysicsConstraint *physicsConstraint = dynamic_cast<PhysicsConstraint *>(constraint);
|
||||
if (physicsConstraint != NULL) {
|
||||
_physics.add(physicsConstraint);
|
||||
}
|
||||
_constraints.add(constraint);
|
||||
}
|
||||
_physics.shrink();
|
||||
|
||||
updateCache();
|
||||
}
|
||||
|
||||
Skeleton::~Skeleton() {
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
delete _bones[i];
|
||||
}
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
delete _slots[i];
|
||||
}
|
||||
for (size_t i = 0; i < _constraints.size(); ++i) {
|
||||
delete _constraints[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::updateCache() {
|
||||
_updateCache.clear();
|
||||
|
||||
// Reset slot applied poses to current pose
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
Slot *slot = _slots[i];
|
||||
slot->getAppliedPose().set(slot->getPose());
|
||||
}
|
||||
|
||||
// Mark bones based on skin requirements
|
||||
size_t boneCount = _bones.size();
|
||||
for (size_t i = 0; i < boneCount; ++i) {
|
||||
Bone *bone = _bones[i];
|
||||
bone->_sorted = bone->getData().getSkinRequired();
|
||||
bone->_active = !bone->_sorted;
|
||||
bone->getAppliedPose().set(bone->getPose());
|
||||
}
|
||||
|
||||
// Activate bones required by skin
|
||||
if (_skin != NULL) {
|
||||
Vector<BoneData *> &skinBones = _skin->getBones();
|
||||
for (size_t i = 0; i < skinBones.size(); ++i) {
|
||||
Bone *bone = _bones[skinBones[i]->getIndex()];
|
||||
do {
|
||||
bone->_sorted = false;
|
||||
bone->_active = true;
|
||||
bone = bone->getParent();
|
||||
} while (bone != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Set constraint applied poses and mark active constraints
|
||||
for (size_t i = 0; i < _constraints.size(); ++i) {
|
||||
Constraint *constraint = _constraints[i];
|
||||
constraint->getAppliedPose().set(constraint->getPose());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _constraints.size(); ++i) {
|
||||
Constraint *constraint = _constraints[i];
|
||||
constraint->_active = constraint->isSourceActive() &&
|
||||
(!constraint->getData().getSkinRequired() || (_skin != NULL && _skin->getConstraints().contains(&constraint->getData(), true)));
|
||||
if (constraint->_active) {
|
||||
constraint->sort(*this);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort all bones
|
||||
for (size_t i = 0; i < boneCount; ++i) {
|
||||
sortBone(_bones[i]);
|
||||
}
|
||||
|
||||
// Replace bone references in update cache with their applied poses
|
||||
for (size_t i = 0; i < _updateCache.size(); ++i) {
|
||||
Update *updateItem = _updateCache[i];
|
||||
Bone *bone = dynamic_cast<Bone *>(updateItem);
|
||||
if (bone != NULL) {
|
||||
_updateCache[i] = &bone->getAppliedPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::constrained(Posed &object) {
|
||||
if (&object.getPose() == &object.getAppliedPose()) {
|
||||
object.setAppliedPose(object.getConstrainedPose());
|
||||
// Add to reset cache - this would need a resetCache member like Java
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortBone(Bone *bone) {
|
||||
if (bone->_sorted || !bone->_active) return;
|
||||
Bone *parent = bone->getParent();
|
||||
if (parent != NULL) sortBone(parent);
|
||||
bone->_sorted = true;
|
||||
_updateCache.add(bone);
|
||||
}
|
||||
|
||||
void Skeleton::sortReset(Vector<Bone *> &bones) {
|
||||
for (size_t i = 0; i < bones.size(); ++i) {
|
||||
Bone *bone = bones[i];
|
||||
if (bone->_active) {
|
||||
if (bone->_sorted) sortReset(bone->getChildren());
|
||||
bone->_sorted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::updateWorldTransform(Physics physics) {
|
||||
_update++;
|
||||
|
||||
// Reset all applied poses to their base poses
|
||||
// This would require a resetCache implementation like Java has
|
||||
|
||||
// Update all items in update cache
|
||||
for (size_t i = 0; i < _updateCache.size(); ++i) {
|
||||
Update *updateItem = _updateCache[i];
|
||||
updateItem->update(*this, physics);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::updateWorldTransform(Physics physics, BonePose *parent) {
|
||||
if (parent == NULL) return;
|
||||
|
||||
_update++;
|
||||
|
||||
// Reset all applied poses to their base poses
|
||||
// This would require a resetCache implementation like Java has
|
||||
|
||||
// Apply the parent bone transform to the root bone
|
||||
BonePose &rootBone = getRootBone()->getAppliedPose();
|
||||
float pa = parent->getA(), pb = parent->getB(), pc = parent->getC(), pd = parent->getD();
|
||||
rootBone.setWorldX(pa * _x + pb * _y + parent->getWorldX());
|
||||
rootBone.setWorldY(pc * _x + pd * _y + parent->getWorldY());
|
||||
|
||||
float rx = (rootBone.getRotation() + rootBone.getShearX()) * MathUtil::Deg_Rad;
|
||||
float ry = (rootBone.getRotation() + 90 + rootBone.getShearY()) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * rootBone.getScaleX();
|
||||
float lb = MathUtil::cos(ry) * rootBone.getScaleY();
|
||||
float lc = MathUtil::sin(rx) * rootBone.getScaleX();
|
||||
float ld = MathUtil::sin(ry) * rootBone.getScaleY();
|
||||
rootBone.setA((pa * la + pb * lc) * _scaleX);
|
||||
rootBone.setB((pa * lb + pb * ld) * _scaleX);
|
||||
rootBone.setC((pc * la + pd * lc) * _scaleY);
|
||||
rootBone.setD((pc * lb + pd * ld) * _scaleY);
|
||||
|
||||
// Update everything except root bone
|
||||
for (size_t i = 0; i < _updateCache.size(); ++i) {
|
||||
Update *updateItem = _updateCache[i];
|
||||
if (updateItem != &rootBone) {
|
||||
updateItem->update(*this, physics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::setupPose() {
|
||||
setupPoseBones();
|
||||
setupPoseSlots();
|
||||
}
|
||||
|
||||
void Skeleton::setupPoseBones() {
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
_bones[i]->setupPose();
|
||||
}
|
||||
for (size_t i = 0; i < _constraints.size(); ++i) {
|
||||
_constraints[i]->setupPose();
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::setupPoseSlots() {
|
||||
// Copy slots to draw order in setup pose order
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
_drawOrder[i] = _slots[i];
|
||||
}
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
_slots[i]->setupPose();
|
||||
}
|
||||
}
|
||||
|
||||
SkeletonData *Skeleton::getData() {
|
||||
return &_data;
|
||||
}
|
||||
|
||||
Vector<Bone *> &Skeleton::getBones() {
|
||||
return _bones;
|
||||
}
|
||||
|
||||
Vector<Update *> &Skeleton::getUpdateCache() {
|
||||
return _updateCache;
|
||||
}
|
||||
|
||||
Bone *Skeleton::getRootBone() {
|
||||
return _bones.size() == 0 ? NULL : _bones[0];
|
||||
}
|
||||
|
||||
Bone *Skeleton::findBone(const String &boneName) {
|
||||
if (boneName.isEmpty()) return NULL;
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
if (_bones[i]->getData().getName() == boneName) {
|
||||
return _bones[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vector<Slot *> &Skeleton::getSlots() {
|
||||
return _slots;
|
||||
}
|
||||
|
||||
Slot *Skeleton::findSlot(const String &slotName) {
|
||||
if (slotName.isEmpty()) return NULL;
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
if (_slots[i]->getData().getName() == slotName) {
|
||||
return _slots[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vector<Slot *> &Skeleton::getDrawOrder() {
|
||||
return _drawOrder;
|
||||
}
|
||||
|
||||
Skin *Skeleton::getSkin() {
|
||||
return _skin;
|
||||
}
|
||||
|
||||
void Skeleton::setSkin(const String &skinName) {
|
||||
Skin *skin = _data.findSkin(skinName);
|
||||
if (skin == NULL && !skinName.isEmpty()) {
|
||||
// Handle error - skin not found
|
||||
return;
|
||||
}
|
||||
setSkin(skin);
|
||||
}
|
||||
|
||||
void Skeleton::setSkin(Skin *newSkin) {
|
||||
if (newSkin == _skin) return;
|
||||
if (newSkin != NULL) {
|
||||
if (_skin != NULL) {
|
||||
newSkin->attachAll(*this, *_skin);
|
||||
} else {
|
||||
for (size_t i = 0; i < _slots.size(); ++i) {
|
||||
Slot *slot = _slots[i];
|
||||
const String &name = slot->getData().getAttachmentName();
|
||||
if (!name.isEmpty()) {
|
||||
Attachment *attachment = newSkin->getAttachment((int) i, name);
|
||||
if (attachment != NULL) {
|
||||
slot->getPose().setAttachment(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_skin = newSkin;
|
||||
updateCache();
|
||||
}
|
||||
|
||||
Attachment *Skeleton::getAttachment(const String &slotName, const String &attachmentName) {
|
||||
SlotData *slotData = _data.findSlot(slotName);
|
||||
if (slotData == NULL) return NULL;
|
||||
return getAttachment(slotData->getIndex(), attachmentName);
|
||||
}
|
||||
|
||||
Attachment *Skeleton::getAttachment(int slotIndex, const String &attachmentName) {
|
||||
if (attachmentName.isEmpty()) return NULL;
|
||||
if (_skin != NULL) {
|
||||
Attachment *attachment = _skin->getAttachment(slotIndex, attachmentName);
|
||||
if (attachment != NULL) return attachment;
|
||||
}
|
||||
if (_data.getDefaultSkin() != NULL) {
|
||||
return _data.getDefaultSkin()->getAttachment(slotIndex, attachmentName);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Skeleton::setAttachment(const String &slotName, const String &attachmentName) {
|
||||
if (slotName.isEmpty()) return;
|
||||
Slot *slot = findSlot(slotName);
|
||||
if (slot == NULL) return;
|
||||
Attachment *attachment = NULL;
|
||||
if (!attachmentName.isEmpty()) {
|
||||
attachment = getAttachment(slot->getData().getIndex(), attachmentName);
|
||||
if (attachment == NULL) {
|
||||
// Handle error - attachment not found
|
||||
return;
|
||||
}
|
||||
}
|
||||
slot->getPose().setAttachment(attachment);
|
||||
}
|
||||
|
||||
Vector<Constraint *> &Skeleton::getConstraints() {
|
||||
return _constraints;
|
||||
}
|
||||
|
||||
Vector<PhysicsConstraint *> &Skeleton::getPhysicsConstraints() {
|
||||
return _physics;
|
||||
}
|
||||
|
||||
void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer) {
|
||||
getBounds(outX, outY, outWidth, outHeight, outVertexBuffer, NULL);
|
||||
}
|
||||
|
||||
void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector<float> &outVertexBuffer, SkeletonClipping *clipper) {
|
||||
float minX = FLT_MAX, minY = FLT_MAX, maxX = -FLT_MAX, maxY = -FLT_MAX;
|
||||
|
||||
for (size_t i = 0; i < _drawOrder.size(); ++i) {
|
||||
Slot *slot = _drawOrder[i];
|
||||
if (!slot->getBone().isActive()) continue;
|
||||
|
||||
size_t verticesLength = 0;
|
||||
float *vertices = NULL;
|
||||
const unsigned short *triangles = NULL;
|
||||
Attachment *attachment = slot->getPose().getAttachment();
|
||||
|
||||
if (attachment != NULL) {
|
||||
RegionAttachment *region = dynamic_cast<RegionAttachment *>(attachment);
|
||||
if (region != NULL) {
|
||||
verticesLength = 8;
|
||||
outVertexBuffer.setSize(8);
|
||||
vertices = outVertexBuffer.buffer();
|
||||
region->computeWorldVertices(*slot, vertices, 0, 2);
|
||||
triangles = quadTriangles;
|
||||
} else {
|
||||
MeshAttachment *mesh = dynamic_cast<MeshAttachment *>(attachment);
|
||||
if (mesh != NULL) {
|
||||
verticesLength = mesh->getWorldVerticesLength();
|
||||
outVertexBuffer.setSize(verticesLength);
|
||||
vertices = outVertexBuffer.buffer();
|
||||
mesh->computeWorldVertices(*this, *slot, 0, verticesLength, vertices, 0, 2);
|
||||
triangles = mesh->getTriangles().buffer();
|
||||
} else {
|
||||
ClippingAttachment *clip = dynamic_cast<ClippingAttachment *>(attachment);
|
||||
if (clip != NULL && clipper != NULL) {
|
||||
clipper->clipEnd(*slot);
|
||||
clipper->clipStart(*this, *slot, *clip);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices != NULL) {
|
||||
if (clipper != NULL && clipper->isClipping() && clipper->clipTriangles(vertices, triangles, 6)) {
|
||||
vertices = clipper->getClippedVertices().buffer();
|
||||
verticesLength = clipper->getClippedVertices().size();
|
||||
}
|
||||
for (size_t ii = 0; ii < verticesLength; ii += 2) {
|
||||
float x = vertices[ii], y = vertices[ii + 1];
|
||||
minX = MathUtil::min(minX, x);
|
||||
minY = MathUtil::min(minY, y);
|
||||
maxX = MathUtil::max(maxX, x);
|
||||
maxY = MathUtil::max(maxY, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clipper != NULL) clipper->clipEnd(*slot);
|
||||
}
|
||||
if (clipper != NULL) clipper->clipEnd();
|
||||
|
||||
outX = minX;
|
||||
outY = minY;
|
||||
outWidth = maxX - minX;
|
||||
outHeight = maxY - minY;
|
||||
}
|
||||
|
||||
Color &Skeleton::getColor() {
|
||||
return _color;
|
||||
}
|
||||
|
||||
void Skeleton::setColor(Color &color) {
|
||||
_color = color;
|
||||
}
|
||||
|
||||
float Skeleton::getScaleX() {
|
||||
return _scaleX;
|
||||
}
|
||||
|
||||
void Skeleton::setScaleX(float inValue) {
|
||||
_scaleX = inValue;
|
||||
}
|
||||
|
||||
float Skeleton::getScaleY() {
|
||||
return _scaleY;
|
||||
}
|
||||
|
||||
void Skeleton::setScaleY(float inValue) {
|
||||
_scaleY = inValue;
|
||||
}
|
||||
|
||||
void Skeleton::setScale(float scaleX, float scaleY) {
|
||||
_scaleX = scaleX;
|
||||
_scaleY = scaleY;
|
||||
}
|
||||
|
||||
float Skeleton::getX() {
|
||||
return _x;
|
||||
}
|
||||
|
||||
void Skeleton::setX(float inValue) {
|
||||
_x = inValue;
|
||||
}
|
||||
|
||||
float Skeleton::getY() {
|
||||
return _y;
|
||||
}
|
||||
|
||||
void Skeleton::setY(float inValue) {
|
||||
_y = inValue;
|
||||
}
|
||||
|
||||
void Skeleton::setPosition(float x, float y) {
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Skeleton::physicsTranslate(float x, float y) {
|
||||
for (size_t i = 0; i < _physics.size(); ++i) {
|
||||
_physics[i]->translate(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::physicsRotate(float x, float y, float degrees) {
|
||||
for (size_t i = 0; i < _physics.size(); ++i) {
|
||||
_physics[i]->rotate(x, y, degrees);
|
||||
}
|
||||
}
|
||||
|
||||
float Skeleton::getTime() {
|
||||
return _time;
|
||||
}
|
||||
|
||||
void Skeleton::setTime(float time) {
|
||||
_time = time;
|
||||
}
|
||||
|
||||
void Skeleton::update(float delta) {
|
||||
_time += delta;
|
||||
}
|
||||
@ -44,69 +44,30 @@ RTTI_IMPL(Slider, Constraint)
|
||||
|
||||
float Slider::_offsets[6];
|
||||
|
||||
Slider::Slider(SliderData& data, Skeleton& skeleton) : ConstraintGeneric<Slider, SliderData, SliderPose>(data), _bone(NULL) {
|
||||
Slider::Slider(SliderData &data, Skeleton &skeleton) : ConstraintGeneric<Slider, SliderData, SliderPose>(data), _bone(NULL) {
|
||||
if (data.getBone() != NULL) {
|
||||
_bone = skeleton.findBone(data.getBone()->getName());
|
||||
}
|
||||
}
|
||||
|
||||
Slider* Slider::copy(Skeleton& skeleton) {
|
||||
Slider* copy = new (__FILE__, __LINE__) Slider(_data, skeleton);
|
||||
Slider *Slider::copy(Skeleton &skeleton) {
|
||||
Slider *copy = new (__FILE__, __LINE__) Slider(_data, skeleton);
|
||||
copy->_pose.set(_pose);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Slider::update(Skeleton& skeleton, Physics physics) {
|
||||
SliderPose& p = *_applied;
|
||||
if (p.getMix() == 0) return;
|
||||
|
||||
Animation* animation = _data.getAnimation();
|
||||
if (_bone != NULL) {
|
||||
if (!_bone->isActive()) return;
|
||||
if (_data.getLocal()) _bone->getAppliedPose().validateLocalTransform(skeleton);
|
||||
p.setTime((_data.getProperty()->value(_bone->getAppliedPose(), _data.getLocal(), _offsets) - _data.getProperty()->offset) * _data.getScale());
|
||||
if (_data.getLoop()) {
|
||||
// TODO: Implement when Animation is ported
|
||||
p.setTime(animation->getDuration() + MathUtil::fmod(p.getTime(), animation->getDuration()));
|
||||
} else {
|
||||
p.setTime(MathUtil::max(0.0f, p.getTime()));
|
||||
}
|
||||
}
|
||||
|
||||
void Slider::update(Skeleton &skeleton, Physics physics) {
|
||||
// TODO: Implement when Animation is ported
|
||||
// Vector<Bone*>& bones = skeleton.getBones();
|
||||
// Vector<size_t>& indices = animation->getBones();
|
||||
// for (size_t i = 0, n = indices.size(); i < n; i++) {
|
||||
// bones[indices[i]]->getAppliedPose().modifyLocal(skeleton);
|
||||
// }
|
||||
|
||||
// TODO: Implement when Animation is ported
|
||||
// animation->apply(skeleton, p.getTime(), p.getTime(), _data.getLoop(), NULL, p.getMix(),
|
||||
// _data.getAdditive() ? MixBlend_Add : MixBlend_Replace, MixDirection_In);
|
||||
}
|
||||
|
||||
void Slider::sort(Skeleton& skeleton) {
|
||||
void Slider::sort(Skeleton &skeleton) {
|
||||
// TODO: Implement when Animation is ported
|
||||
// if (_bone != NULL && !_data.getLocal()) skeleton.sortBone(_bone);
|
||||
skeleton.getUpdateCacheList().add(this);
|
||||
|
||||
// TODO: Implement when Animation is ported
|
||||
// Vector<Bone*>& bones = skeleton.getBones();
|
||||
// Vector<size_t>& indices = _data.getAnimation()->getBones();
|
||||
// for (size_t i = 0, n = indices.size(); i < n; i++) {
|
||||
// Bone* bone = bones[indices[i]];
|
||||
// bone->setSorted(false);
|
||||
// skeleton.sortReset(bone->getChildren());
|
||||
// skeleton.constrained(bone);
|
||||
// }
|
||||
|
||||
// TODO: Implement when Animation is ported - timeline processing
|
||||
}
|
||||
|
||||
Bone* Slider::getBone() {
|
||||
Bone *Slider::getBone() {
|
||||
return _bone;
|
||||
}
|
||||
|
||||
void Slider::setBone(Bone* bone) {
|
||||
void Slider::setBone(Bone *bone) {
|
||||
_bone = bone;
|
||||
}
|
||||
@ -36,24 +36,24 @@ using namespace spine;
|
||||
RTTI_IMPL(SliderData, ConstraintData)
|
||||
|
||||
SliderData::SliderData(const String &name) : ConstraintDataGeneric<Slider, SliderPose>(name),
|
||||
_animation(NULL),
|
||||
_additive(false),
|
||||
_loop(false),
|
||||
_bone(NULL),
|
||||
_property(NULL),
|
||||
_scale(0.0f),
|
||||
_local(false) {
|
||||
_animation(NULL),
|
||||
_additive(false),
|
||||
_loop(false),
|
||||
_bone(NULL),
|
||||
_property(NULL),
|
||||
_scale(0.0f),
|
||||
_local(false) {
|
||||
}
|
||||
|
||||
Slider* SliderData::create(Skeleton& skeleton) {
|
||||
Slider *SliderData::create(Skeleton &skeleton) {
|
||||
return new (__FILE__, __LINE__) Slider(*this, skeleton);
|
||||
}
|
||||
|
||||
Animation* SliderData::getAnimation() {
|
||||
Animation *SliderData::getAnimation() {
|
||||
return _animation;
|
||||
}
|
||||
|
||||
void SliderData::setAnimation(Animation* animation) {
|
||||
void SliderData::setAnimation(Animation *animation) {
|
||||
_animation = animation;
|
||||
}
|
||||
|
||||
@ -73,19 +73,19 @@ void SliderData::setLoop(bool loop) {
|
||||
_loop = loop;
|
||||
}
|
||||
|
||||
BoneData* SliderData::getBone() {
|
||||
BoneData *SliderData::getBone() {
|
||||
return _bone;
|
||||
}
|
||||
|
||||
void SliderData::setBone(BoneData* bone) {
|
||||
void SliderData::setBone(BoneData *bone) {
|
||||
_bone = bone;
|
||||
}
|
||||
|
||||
FromProperty* SliderData::getProperty() {
|
||||
FromProperty *SliderData::getProperty() {
|
||||
return _property;
|
||||
}
|
||||
|
||||
void SliderData::setProperty(FromProperty* property) {
|
||||
void SliderData::setProperty(FromProperty *property) {
|
||||
_property = property;
|
||||
}
|
||||
|
||||
|
||||
@ -37,23 +37,23 @@ SliderPose::SliderPose() : _time(0), _mix(0) {
|
||||
SliderPose::~SliderPose() {
|
||||
}
|
||||
|
||||
void SliderPose::set(SliderPose& pose) {
|
||||
_time = pose._time;
|
||||
_mix = pose._mix;
|
||||
void SliderPose::set(SliderPose &pose) {
|
||||
_time = pose._time;
|
||||
_mix = pose._mix;
|
||||
}
|
||||
|
||||
float SliderPose::getTime() {
|
||||
return _time;
|
||||
return _time;
|
||||
}
|
||||
|
||||
void SliderPose::setTime(float time) {
|
||||
this->_time = time;
|
||||
this->_time = time;
|
||||
}
|
||||
|
||||
float SliderPose::getMix() {
|
||||
return _mix;
|
||||
return _mix;
|
||||
}
|
||||
|
||||
void SliderPose::setMix(float mix) {
|
||||
this->_mix = mix;
|
||||
this->_mix = mix;
|
||||
}
|
||||
@ -37,12 +37,11 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
Slot::Slot(SlotData &data, Skeleton &skeleton) :
|
||||
Posed<SlotData, SlotPose, SlotPose>(data),
|
||||
_skeleton(skeleton),
|
||||
_bone(*skeleton.getBones()[data.getBoneData().getIndex()]),
|
||||
_attachmentState(0) {
|
||||
|
||||
Slot::Slot(SlotData &data, Skeleton &skeleton) : Posed<SlotData, SlotPose, SlotPose>(data),
|
||||
_skeleton(skeleton),
|
||||
_bone(*skeleton.getBones()[data.getBoneData().getIndex()]),
|
||||
_attachmentState(0) {
|
||||
|
||||
if (data.getSetupPose().hasDarkColor()) {
|
||||
_pose._hasDarkColor = true;
|
||||
_constrained._hasDarkColor = true;
|
||||
|
||||
@ -38,14 +38,14 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(SlotCurveTimeline, CurveTimeline)
|
||||
|
||||
SlotCurveTimeline::SlotCurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount, int slotIndex)
|
||||
SlotCurveTimeline::SlotCurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount, int slotIndex)
|
||||
: CurveTimeline(frameCount, frameEntries, bezierCount), SlotTimeline(slotIndex) {
|
||||
}
|
||||
|
||||
SlotCurveTimeline::~SlotCurveTimeline() {
|
||||
}
|
||||
|
||||
void SlotCurveTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
void SlotCurveTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
|
||||
MixBlend blend, MixDirection direction, bool appliedPose) {
|
||||
SP_UNUSED(lastTime);
|
||||
SP_UNUSED(pEvents);
|
||||
|
||||
@ -35,13 +35,12 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
SlotData::SlotData(int index, const String& name, BoneData& boneData) :
|
||||
PosedData<SlotPose>(name),
|
||||
_index(index),
|
||||
_boneData(boneData),
|
||||
_attachmentName(),
|
||||
_blendMode(BlendMode_Normal),
|
||||
_visible(true) {
|
||||
SlotData::SlotData(int index, const String &name, BoneData &boneData) : PosedData<SlotPose>(name),
|
||||
_index(index),
|
||||
_boneData(boneData),
|
||||
_attachmentName(),
|
||||
_blendMode(BlendMode_Normal),
|
||||
_visible(true) {
|
||||
assert(index >= 0);
|
||||
}
|
||||
|
||||
@ -49,15 +48,15 @@ int SlotData::getIndex() {
|
||||
return _index;
|
||||
}
|
||||
|
||||
BoneData& SlotData::getBoneData() {
|
||||
BoneData &SlotData::getBoneData() {
|
||||
return _boneData;
|
||||
}
|
||||
|
||||
void SlotData::setAttachmentName(const String& attachmentName) {
|
||||
void SlotData::setAttachmentName(const String &attachmentName) {
|
||||
_attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
const String& SlotData::getAttachmentName() {
|
||||
const String &SlotData::getAttachmentName() {
|
||||
return _attachmentName;
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ SlotPose::SlotPose() : _color(1, 1, 1, 1), _darkColor(0, 0, 0, 0), _hasDarkColor
|
||||
SlotPose::~SlotPose() {
|
||||
}
|
||||
|
||||
void SlotPose::set(SlotPose& pose) {
|
||||
void SlotPose::set(SlotPose &pose) {
|
||||
_color.set(pose._color);
|
||||
if (pose._hasDarkColor) _darkColor.set(pose._darkColor);
|
||||
_hasDarkColor = pose._hasDarkColor;
|
||||
@ -49,11 +49,11 @@ void SlotPose::set(SlotPose& pose) {
|
||||
_deform.addAll(pose._deform);
|
||||
}
|
||||
|
||||
Color& SlotPose::getColor() {
|
||||
Color &SlotPose::getColor() {
|
||||
return _color;
|
||||
}
|
||||
|
||||
Color& SlotPose::getDarkColor() {
|
||||
Color &SlotPose::getDarkColor() {
|
||||
return _darkColor;
|
||||
}
|
||||
|
||||
@ -61,11 +61,11 @@ bool SlotPose::hasDarkColor() {
|
||||
return _hasDarkColor;
|
||||
}
|
||||
|
||||
Attachment* SlotPose::getAttachment() {
|
||||
Attachment *SlotPose::getAttachment() {
|
||||
return _attachment;
|
||||
}
|
||||
|
||||
void SlotPose::setAttachment(Attachment* attachment) {
|
||||
void SlotPose::setAttachment(Attachment *attachment) {
|
||||
if (_attachment == attachment) return;
|
||||
|
||||
// Check if we need to clear deform based on timeline attachment
|
||||
@ -73,8 +73,8 @@ void SlotPose::setAttachment(Attachment* attachment) {
|
||||
!_attachment ||
|
||||
!attachment->getRTTI().instanceOf(VertexAttachment::rtti) ||
|
||||
!_attachment->getRTTI().instanceOf(VertexAttachment::rtti) ||
|
||||
static_cast<VertexAttachment*>(attachment)->getTimelineAttachment() !=
|
||||
static_cast<VertexAttachment*>(_attachment)->getTimelineAttachment()) {
|
||||
static_cast<VertexAttachment *>(attachment)->getTimelineAttachment() !=
|
||||
static_cast<VertexAttachment *>(_attachment)->getTimelineAttachment()) {
|
||||
_deform.clear();
|
||||
}
|
||||
_attachment = attachment;
|
||||
@ -89,6 +89,6 @@ void SlotPose::setSequenceIndex(int sequenceIndex) {
|
||||
_sequenceIndex = sequenceIndex;
|
||||
}
|
||||
|
||||
Vector<float>& SlotPose::getDeform() {
|
||||
Vector<float> &SlotPose::getDeform() {
|
||||
return _deform;
|
||||
}
|
||||
@ -41,55 +41,54 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(TransformConstraint, Constraint)
|
||||
|
||||
TransformConstraint::TransformConstraint(TransformConstraintData& data, Skeleton& skeleton) :
|
||||
ConstraintGeneric<TransformConstraint, TransformConstraintData, TransformConstraintPose>(data) {
|
||||
TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton &skeleton) : ConstraintGeneric<TransformConstraint, TransformConstraintData, TransformConstraintPose>(data) {
|
||||
|
||||
_bones.ensureCapacity(data.getBones().size());
|
||||
for (size_t i = 0; i < data.getBones().size(); i++) {
|
||||
BoneData* boneData = data.getBones()[i];
|
||||
BoneData *boneData = data.getBones()[i];
|
||||
_bones.add(&skeleton.findBone(boneData->getName())->getAppliedPose());
|
||||
}
|
||||
|
||||
_source = skeleton.findBone(data.getSource()->getName());
|
||||
}
|
||||
|
||||
TransformConstraint TransformConstraint::copy(Skeleton& skeleton) {
|
||||
TransformConstraint TransformConstraint::copy(Skeleton &skeleton) {
|
||||
TransformConstraint copy(_data, skeleton);
|
||||
copy._applied->set(*_applied);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// Applies the constraint to the constrained bones.
|
||||
void TransformConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
TransformConstraintPose& p = *_applied;
|
||||
void TransformConstraint::update(Skeleton &skeleton, Physics physics) {
|
||||
TransformConstraintPose &p = *_applied;
|
||||
if (p.getMixRotate() == 0 && p.getMixX() == 0 && p.getMixY() == 0 && p.getMixScaleX() == 0 && p.getMixScaleY() == 0 && p.getMixShearY() == 0) return;
|
||||
|
||||
TransformConstraintData& data = _data;
|
||||
TransformConstraintData &data = _data;
|
||||
bool localSource = data.getLocalSource(), localTarget = data.getLocalTarget(), additive = data.getAdditive(), clamp = data.getClamp();
|
||||
float* offsets = data._offsets; // Access friend field directly
|
||||
BonePose& source = _source->getAppliedPose();
|
||||
float *offsets = data._offsets;// Access friend field directly
|
||||
BonePose &source = _source->getAppliedPose();
|
||||
if (localSource) {
|
||||
source.validateLocalTransform(skeleton);
|
||||
}
|
||||
Vector<FromProperty*>& properties = data.getProperties();
|
||||
FromProperty** fromItems = properties.buffer();
|
||||
Vector<FromProperty *> &properties = data.getProperties();
|
||||
FromProperty **fromItems = properties.buffer();
|
||||
size_t fn = properties.size();
|
||||
int update = 1; // TODO: Add skeleton.update field
|
||||
BonePose** bones = _bones.buffer();
|
||||
int update = skeleton._update;
|
||||
BonePose **bones = _bones.buffer();
|
||||
for (size_t i = 0, n = _bones.size(); i < n; i++) {
|
||||
BonePose* bone = bones[i];
|
||||
BonePose *bone = bones[i];
|
||||
if (localTarget) {
|
||||
bone->modifyLocal(skeleton);
|
||||
} else {
|
||||
bone->modifyWorld(update);
|
||||
}
|
||||
for (size_t f = 0; f < fn; f++) {
|
||||
FromProperty* from = fromItems[f];
|
||||
FromProperty *from = fromItems[f];
|
||||
float value = from->value(source, localSource, offsets) - from->offset;
|
||||
Vector<ToProperty*>& toProps = from->to;
|
||||
ToProperty** toItems = toProps.buffer();
|
||||
Vector<ToProperty *> &toProps = from->to;
|
||||
ToProperty **toItems = toProps.buffer();
|
||||
for (size_t t = 0, tn = toProps.size(); t < tn; t++) {
|
||||
ToProperty* to = toItems[t];
|
||||
ToProperty *to = toItems[t];
|
||||
if (to->mix(p) != 0) {
|
||||
float clamped = to->offset + value * to->scale;
|
||||
if (clamp) {
|
||||
@ -105,23 +104,23 @@ void TransformConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
}
|
||||
}
|
||||
|
||||
void TransformConstraint::sort(Skeleton& skeleton) {
|
||||
// if (!_data.getLocalSource()) skeleton.sortBone(_source); // TODO: sortBone is private, need friend access
|
||||
BonePose** bones = _bones.buffer();
|
||||
void TransformConstraint::sort(Skeleton &skeleton) {
|
||||
if (!_data.getLocalSource()) skeleton.sortBone(_source);
|
||||
BonePose **bones = _bones.buffer();
|
||||
size_t boneCount = _bones.size();
|
||||
bool worldTarget = !_data.getLocalTarget();
|
||||
// if (worldTarget) {
|
||||
// for (size_t i = 0; i < boneCount; i++)
|
||||
// skeleton.sortBone(bones[i]->_bone); // TODO: sortBone is private, need friend access
|
||||
// }
|
||||
// skeleton._updateCache.add(this); // TODO: _updateCache is private, need friend access
|
||||
// for (size_t i = 0; i < boneCount; i++) {
|
||||
// Bone* bone = bones[i]->_bone;
|
||||
// skeleton.sortReset(bone->getChildren()); // TODO: sortReset is private, need friend access
|
||||
// // skeleton.constrained(bone); // TODO: Add constrained() method to Skeleton class
|
||||
// }
|
||||
// for (size_t i = 0; i < boneCount; i++)
|
||||
// bones[i]->_bone->_sorted = worldTarget; // TODO: _sorted is private, need friend access
|
||||
if (worldTarget) {
|
||||
for (size_t i = 0; i < boneCount; i++)
|
||||
skeleton.sortBone(bones[i]->_bone);
|
||||
}
|
||||
skeleton._updateCache.add(this);
|
||||
for (size_t i = 0; i < boneCount; i++) {
|
||||
Bone* bone = bones[i]->_bone;
|
||||
skeleton.sortReset(bone->getChildren());
|
||||
skeleton.constrained(*bone);
|
||||
}
|
||||
for (size_t i = 0; i < boneCount; i++)
|
||||
bones[i]->_bone->_sorted = worldTarget;
|
||||
}
|
||||
|
||||
bool TransformConstraint::isSourceActive() {
|
||||
@ -129,15 +128,15 @@ bool TransformConstraint::isSourceActive() {
|
||||
}
|
||||
|
||||
/// The bones that will be modified by this transform constraint.
|
||||
Vector<BonePose*>& TransformConstraint::getBones() {
|
||||
Vector<BonePose *> &TransformConstraint::getBones() {
|
||||
return _bones;
|
||||
}
|
||||
|
||||
/// The bone whose world transform will be copied to the constrained bones.
|
||||
Bone* TransformConstraint::getSource() {
|
||||
Bone *TransformConstraint::getSource() {
|
||||
return _source;
|
||||
}
|
||||
|
||||
void TransformConstraint::setSource(Bone* source) {
|
||||
void TransformConstraint::setSource(Bone *source) {
|
||||
_source = source;
|
||||
}
|
||||
@ -49,15 +49,15 @@ TransformConstraintData::TransformConstraintData(const String &name) : Constrain
|
||||
}
|
||||
}
|
||||
|
||||
Vector<BoneData*>& TransformConstraintData::getBones() {
|
||||
Vector<BoneData *> &TransformConstraintData::getBones() {
|
||||
return _bones;
|
||||
}
|
||||
|
||||
BoneData* TransformConstraintData::getSource() {
|
||||
BoneData *TransformConstraintData::getSource() {
|
||||
return _source;
|
||||
}
|
||||
|
||||
void TransformConstraintData::setSource(BoneData* source) {
|
||||
void TransformConstraintData::setSource(BoneData *source) {
|
||||
_source = source;
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ void TransformConstraintData::setClamp(bool clamp) {
|
||||
_clamp = clamp;
|
||||
}
|
||||
|
||||
Vector<FromProperty*>& TransformConstraintData::getProperties() {
|
||||
Vector<FromProperty *> &TransformConstraintData::getProperties() {
|
||||
return _properties;
|
||||
}
|
||||
|
||||
@ -167,21 +167,20 @@ ToProperty::~ToProperty() {
|
||||
|
||||
// No RTTI for FromRotate
|
||||
|
||||
float FromRotate::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromRotate::value(BonePose &source, bool local, float *offsets) {
|
||||
if (local) return source.getRotation() + offsets[TransformConstraintData::ROTATION];
|
||||
float value = MathUtil::atan2(source._c, source._a) * MathUtil::Rad_Deg
|
||||
+ (source._a * source._d - source._b * source._c > 0 ? offsets[TransformConstraintData::ROTATION] : -offsets[TransformConstraintData::ROTATION]);
|
||||
float value = MathUtil::atan2(source._c, source._a) * MathUtil::Rad_Deg + (source._a * source._d - source._b * source._c > 0 ? offsets[TransformConstraintData::ROTATION] : -offsets[TransformConstraintData::ROTATION]);
|
||||
if (value < 0) value += 360;
|
||||
return value;
|
||||
}
|
||||
|
||||
// No RTTI for ToRotate
|
||||
|
||||
float ToRotate::mix(TransformConstraintPose& pose) {
|
||||
float ToRotate::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixRotate;
|
||||
}
|
||||
|
||||
void ToRotate::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToRotate::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.getRotation();
|
||||
bone.setRotation(bone.getRotation() + value * pose._mixRotate);
|
||||
@ -204,17 +203,17 @@ void ToRotate::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
|
||||
// No RTTI for FromX
|
||||
|
||||
float FromX::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromX::value(BonePose &source, bool local, float *offsets) {
|
||||
return local ? source.getX() + offsets[TransformConstraintData::X] : offsets[TransformConstraintData::X] * source._a + offsets[TransformConstraintData::Y] * source._b + source.getWorldX();
|
||||
}
|
||||
|
||||
// No RTTI for ToX
|
||||
|
||||
float ToX::mix(TransformConstraintPose& pose) {
|
||||
float ToX::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixX;
|
||||
}
|
||||
|
||||
void ToX::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToX::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.getX();
|
||||
bone.setX(bone.getX() + value * pose._mixX);
|
||||
@ -226,17 +225,17 @@ void ToX::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool
|
||||
|
||||
// No RTTI for FromY
|
||||
|
||||
float FromY::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromY::value(BonePose &source, bool local, float *offsets) {
|
||||
return local ? source.getY() + offsets[TransformConstraintData::Y] : offsets[TransformConstraintData::X] * source._c + offsets[TransformConstraintData::Y] * source._d + source.getWorldY();
|
||||
}
|
||||
|
||||
// No RTTI for ToY
|
||||
|
||||
float ToY::mix(TransformConstraintPose& pose) {
|
||||
float ToY::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixY;
|
||||
}
|
||||
|
||||
void ToY::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToY::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.getY();
|
||||
bone.setY(bone.getY() + value * pose._mixY);
|
||||
@ -248,17 +247,17 @@ void ToY::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool
|
||||
|
||||
// No RTTI for FromScaleX
|
||||
|
||||
float FromScaleX::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromScaleX::value(BonePose &source, bool local, float *offsets) {
|
||||
return (local ? source.getScaleX() : MathUtil::sqrt(source._a * source._a + source._c * source._c)) + offsets[TransformConstraintData::SCALEX];
|
||||
}
|
||||
|
||||
// No RTTI for ToScaleX
|
||||
|
||||
float ToScaleX::mix(TransformConstraintPose& pose) {
|
||||
float ToScaleX::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixScaleX;
|
||||
}
|
||||
|
||||
void ToScaleX::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToScaleX::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (additive)
|
||||
bone.setScaleX(bone.getScaleX() * (1 + ((value - 1) * pose._mixScaleX)));
|
||||
@ -279,17 +278,17 @@ void ToScaleX::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
|
||||
// No RTTI for FromScaleY
|
||||
|
||||
float FromScaleY::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromScaleY::value(BonePose &source, bool local, float *offsets) {
|
||||
return (local ? source.getScaleY() : MathUtil::sqrt(source._b * source._b + source._d * source._d)) + offsets[TransformConstraintData::SCALEY];
|
||||
}
|
||||
|
||||
// No RTTI for ToScaleY
|
||||
|
||||
float ToScaleY::mix(TransformConstraintPose& pose) {
|
||||
float ToScaleY::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixScaleY;
|
||||
}
|
||||
|
||||
void ToScaleY::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToScaleY::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (additive)
|
||||
bone.setScaleY(bone.getScaleY() * (1 + ((value - 1) * pose._mixScaleY)));
|
||||
@ -310,17 +309,17 @@ void ToScaleY::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
|
||||
// No RTTI for FromShearY
|
||||
|
||||
float FromShearY::value(BonePose& source, bool local, float* offsets) {
|
||||
float FromShearY::value(BonePose &source, bool local, float *offsets) {
|
||||
return (local ? source.getShearY() : (MathUtil::atan2(source._d, source._b) - MathUtil::atan2(source._c, source._a)) * MathUtil::Rad_Deg - 90) + offsets[TransformConstraintData::SHEARY];
|
||||
}
|
||||
|
||||
// No RTTI for ToShearY
|
||||
|
||||
float ToShearY::mix(TransformConstraintPose& pose) {
|
||||
float ToShearY::mix(TransformConstraintPose &pose) {
|
||||
return pose._mixShearY;
|
||||
}
|
||||
|
||||
void ToShearY::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) {
|
||||
void ToShearY::apply(TransformConstraintPose &pose, BonePose &bone, float value, bool local, bool additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.getShearY();
|
||||
bone.setShearY(bone.getShearY() + value * pose._mixShearY);
|
||||
@ -346,7 +345,7 @@ void ToShearY::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
TransformConstraintData::~TransformConstraintData() {
|
||||
// Clean up all FromProperty objects, which will in turn clean up their ToProperty objects
|
||||
for (size_t i = 0; i < _properties.size(); i++) {
|
||||
FromProperty* fromProp = _properties[i];
|
||||
FromProperty *fromProp = _properties[i];
|
||||
if (fromProp) {
|
||||
// Clean up the ToProperty objects in the FromProperty
|
||||
ContainerUtil::cleanUpVectorOfPointers(fromProp->to);
|
||||
|
||||
@ -31,66 +31,65 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
TransformConstraintPose::TransformConstraintPose() :
|
||||
_mixRotate(0), _mixX(0), _mixY(0), _mixScaleX(0), _mixScaleY(0), _mixShearY(0) {
|
||||
TransformConstraintPose::TransformConstraintPose() : _mixRotate(0), _mixX(0), _mixY(0), _mixScaleX(0), _mixScaleY(0), _mixShearY(0) {
|
||||
}
|
||||
|
||||
TransformConstraintPose::~TransformConstraintPose() {
|
||||
}
|
||||
|
||||
void TransformConstraintPose::set(TransformConstraintPose& pose) {
|
||||
_mixRotate = pose._mixRotate;
|
||||
_mixX = pose._mixX;
|
||||
_mixY = pose._mixY;
|
||||
_mixScaleX = pose._mixScaleX;
|
||||
_mixScaleY = pose._mixScaleY;
|
||||
_mixShearY = pose._mixShearY;
|
||||
void TransformConstraintPose::set(TransformConstraintPose &pose) {
|
||||
_mixRotate = pose._mixRotate;
|
||||
_mixX = pose._mixX;
|
||||
_mixY = pose._mixY;
|
||||
_mixScaleX = pose._mixScaleX;
|
||||
_mixScaleY = pose._mixScaleY;
|
||||
_mixShearY = pose._mixShearY;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixRotate() {
|
||||
return _mixRotate;
|
||||
return _mixRotate;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixRotate(float mixRotate) {
|
||||
this->_mixRotate = mixRotate;
|
||||
this->_mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixX() {
|
||||
return _mixX;
|
||||
return _mixX;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixX(float mixX) {
|
||||
this->_mixX = mixX;
|
||||
this->_mixX = mixX;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixY() {
|
||||
return _mixY;
|
||||
return _mixY;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixY(float mixY) {
|
||||
this->_mixY = mixY;
|
||||
this->_mixY = mixY;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixScaleX() {
|
||||
return _mixScaleX;
|
||||
return _mixScaleX;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixScaleX(float mixScaleX) {
|
||||
this->_mixScaleX = mixScaleX;
|
||||
this->_mixScaleX = mixScaleX;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixScaleY() {
|
||||
return _mixScaleY;
|
||||
return _mixScaleY;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixScaleY(float mixScaleY) {
|
||||
this->_mixScaleY = mixScaleY;
|
||||
this->_mixScaleY = mixScaleY;
|
||||
}
|
||||
|
||||
float TransformConstraintPose::getMixShearY() {
|
||||
return _mixShearY;
|
||||
return _mixShearY;
|
||||
}
|
||||
|
||||
void TransformConstraintPose::setMixShearY(float mixShearY) {
|
||||
this->_mixShearY = mixShearY;
|
||||
this->_mixShearY = mixShearY;
|
||||
}
|
||||
@ -42,8 +42,7 @@ using namespace spine;
|
||||
|
||||
RTTI_IMPL(TranslateTimeline, BoneTimeline2)
|
||||
|
||||
TranslateTimeline::TranslateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline2(frameCount, bezierCount, boneIndex, Property_X, Property_Y) {
|
||||
TranslateTimeline::TranslateTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline2(frameCount, bezierCount, boneIndex, Property_X, Property_Y) {
|
||||
}
|
||||
|
||||
void TranslateTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -106,8 +105,7 @@ void TranslateTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, flo
|
||||
|
||||
RTTI_IMPL(TranslateXTimeline, BoneTimeline1)
|
||||
|
||||
TranslateXTimeline::TranslateXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_X) {
|
||||
TranslateXTimeline::TranslateXTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_X) {
|
||||
}
|
||||
|
||||
void TranslateXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
@ -117,8 +115,7 @@ void TranslateXTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, fl
|
||||
|
||||
RTTI_IMPL(TranslateYTimeline, BoneTimeline1)
|
||||
|
||||
TranslateYTimeline::TranslateYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) :
|
||||
BoneTimeline1(frameCount, bezierCount, boneIndex, Property_Y) {
|
||||
TranslateYTimeline::TranslateYTimeline(size_t frameCount, size_t bezierCount, int boneIndex) : BoneTimeline1(frameCount, bezierCount, boneIndex, Property_Y) {
|
||||
}
|
||||
|
||||
void TranslateYTimeline::apply(BoneLocal &pose, BoneLocal &setup, float time, float alpha, MixBlend blend,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user