mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-05 10:16:54 +08:00
parent
0544e14102
commit
07d3633881
@ -67,7 +67,7 @@ spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*
|
|||||||
int /*boolean*/ uniform, float alpha);
|
int /*boolean*/ uniform, float alpha);
|
||||||
|
|
||||||
SP_API void spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float targetY, int bendDirection,
|
SP_API void spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float targetY, int bendDirection,
|
||||||
int /*boolean*/ stretch, float softness, float alpha);
|
int /*boolean*/ stretch, int /*boolean*/ uniform, float softness, float alpha);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ void spIkConstraint_update(spIkConstraint *self) {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY,
|
spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY,
|
||||||
self->bendDirection, self->stretch, self->softness, self->mix);
|
self->bendDirection, self->stretch, self->data->uniform, self->softness, self->mix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,9 +128,9 @@ spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*
|
|||||||
|
|
||||||
void
|
void
|
||||||
spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float targetY, int bendDir, int /*boolean*/ stretch,
|
spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float targetY, int bendDir, int /*boolean*/ stretch,
|
||||||
float softness, float alpha) {
|
int /*boolean*/ uniform, float softness, float alpha) {
|
||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
float px, py, psx, sx, psy;
|
float px, py, psx, psy, sx, sy;
|
||||||
float cx, cy, csx, cwx, cwy;
|
float cx, cy, csx, cwx, cwy;
|
||||||
int o1, o2, s2, u;
|
int o1, o2, s2, u;
|
||||||
spBone *pp = parent->parent;
|
spBone *pp = parent->parent;
|
||||||
@ -141,8 +141,9 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
px = parent->ax;
|
px = parent->ax;
|
||||||
py = parent->ay;
|
py = parent->ay;
|
||||||
psx = parent->ascaleX;
|
psx = parent->ascaleX;
|
||||||
sx = psx;
|
|
||||||
psy = parent->ascaleY;
|
psy = parent->ascaleY;
|
||||||
|
sx = psx;
|
||||||
|
sy = psy;
|
||||||
csx = child->ascaleX;
|
csx = child->ascaleX;
|
||||||
if (psx < 0) {
|
if (psx < 0) {
|
||||||
psx = -psx;
|
psx = -psx;
|
||||||
@ -164,7 +165,7 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
r = psx - psy;
|
r = psx - psy;
|
||||||
cx = child->ax;
|
cx = child->ax;
|
||||||
u = (r < 0 ? -r : r) <= 0.0001f;
|
u = (r < 0 ? -r : r) <= 0.0001f;
|
||||||
if (!u) {
|
if (!u || stretch) {
|
||||||
cy = 0;
|
cy = 0;
|
||||||
cwx = parent->a * cx + parent->worldX;
|
cwx = parent->a * cx + parent->worldX;
|
||||||
cwy = parent->c * cx + parent->worldY;
|
cwy = parent->c * cx + parent->worldY;
|
||||||
@ -196,7 +197,7 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
ty = (y * a - x * c) * id - py;
|
ty = (y * a - x * c) * id - py;
|
||||||
dd = tx * tx + ty * ty;
|
dd = tx * tx + ty * ty;
|
||||||
if (softness != 0) {
|
if (softness != 0) {
|
||||||
softness *= psx * (csx + 1) / 2;
|
softness *= psx * (csx + 1) * 0.5f;
|
||||||
td = SQRT(dd);
|
td = SQRT(dd);
|
||||||
sd = td - l1 - l2 * psx + softness;
|
sd = td - l1 - l2 * psx + softness;
|
||||||
if (sd > 0) {
|
if (sd > 0) {
|
||||||
@ -211,12 +212,19 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
float cosine;
|
float cosine;
|
||||||
l2 *= psx;
|
l2 *= psx;
|
||||||
cosine = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
cosine = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||||
if (cosine < -1) cosine = -1;
|
if (cosine < -1) {
|
||||||
else if (cosine > 1) {
|
cosine = -1;
|
||||||
|
a2 = PI * bendDir;
|
||||||
|
} else if (cosine > 1) {
|
||||||
cosine = 1;
|
cosine = 1;
|
||||||
if (stretch) sx *= (SQRT(dd) / (l1 + l2) - 1) * alpha + 1;
|
a2 = 0;
|
||||||
}
|
if (stretch) {
|
||||||
a2 = ACOS(cosine) * bendDir;
|
a = (SQRT(dd) / (l1 + l2) - 1) * alpha + 1;
|
||||||
|
sx *= a;
|
||||||
|
if (uniform) sy *= a;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
a2 = ACOS(cosine) * bendDir;
|
||||||
a = l1 + l2 * cosine;
|
a = l1 + l2 * cosine;
|
||||||
b = l2 * SIN(a2);
|
b = l2 * SIN(a2);
|
||||||
a1 = ATAN2(ty * a - tx * b, tx * a + ty * b);
|
a1 = ATAN2(ty * a - tx * b, tx * a + ty * b);
|
||||||
@ -229,7 +237,7 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
if (d >= 0) {
|
if (d >= 0) {
|
||||||
float q = SQRT(d), r0, r1;
|
float q = SQRT(d), r0, r1;
|
||||||
if (c1 < 0) q = -q;
|
if (c1 < 0) q = -q;
|
||||||
q = -(c1 + q) / 2;
|
q = -(c1 + q) * 0.5f;
|
||||||
r0 = q / c2;
|
r0 = q / c2;
|
||||||
r1 = c0 / q;
|
r1 = c0 / q;
|
||||||
r = ABS(r0) < ABS(r1) ? r0 : r1;
|
r = ABS(r0) < ABS(r1) ? r0 : r1;
|
||||||
@ -262,7 +270,7 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
maxY = y;
|
maxY = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dd <= (minDist + maxDist) / 2) {
|
if (dd <= (minDist + maxDist) * 0.5f) {
|
||||||
a1 = ta - ATAN2(minY * bendDir, minX);
|
a1 = ta - ATAN2(minY * bendDir, minX);
|
||||||
a2 = minAngle * bendDir;
|
a2 = minAngle * bendDir;
|
||||||
} else {
|
} else {
|
||||||
@ -274,14 +282,16 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
|||||||
break_outer:
|
break_outer:
|
||||||
{
|
{
|
||||||
float os = ATAN2(cy, cx) * s2;
|
float os = ATAN2(cy, cx) * s2;
|
||||||
a1 = (a1 - os) * RAD_DEG + o1 - parent->arotation;
|
float rotation = parent->arotation;
|
||||||
|
a1 = (a1 - os) * RAD_DEG + o1 -rotation;
|
||||||
if (a1 > 180) a1 -= 360;
|
if (a1 > 180) a1 -= 360;
|
||||||
else if (a1 < -180) a1 += 360;
|
else if (a1 < -180) a1 += 360;
|
||||||
spBone_updateWorldTransformWith(parent, px, py, parent->arotation + a1 * alpha, sx, parent->ascaleY, 0, 0);
|
spBone_updateWorldTransformWith(parent, px, py, rotation + a1 * alpha, sx, sy, 0, 0);
|
||||||
a2 = ((a2 + os) * RAD_DEG - child->ashearX) * s2 + o2 - child->arotation;
|
rotation = child->arotation;
|
||||||
|
a2 = ((a2 + os) * RAD_DEG - child->ashearX) * s2 + o2 - rotation;
|
||||||
if (a2 > 180) a2 -= 360;
|
if (a2 > 180) a2 -= 360;
|
||||||
else if (a2 < -180) a2 += 360;
|
else if (a2 < -180) a2 += 360;
|
||||||
spBone_updateWorldTransformWith(child, cx, cy, child->arotation + a2 * alpha, child->ascaleX, child->ascaleY,
|
spBone_updateWorldTransformWith(child, cx, cy, rotation + a2 * alpha, child->ascaleX, child->ascaleY,
|
||||||
child->ashearX, child->ashearY);
|
child->ashearX, child->ashearY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,7 @@ namespace spine {
|
|||||||
/// possible. The target is specified in the world coordinate system.
|
/// possible. The target is specified in the world coordinate system.
|
||||||
/// @param child A direct descendant of the parent bone.
|
/// @param child A direct descendant of the parent bone.
|
||||||
static void
|
static void
|
||||||
apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, float softness,
|
apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, bool uniform, float softness,
|
||||||
float alpha);
|
float alpha);
|
||||||
|
|
||||||
IkConstraint(IkConstraintData &data, Skeleton &skeleton);
|
IkConstraint(IkConstraintData &data, Skeleton &skeleton);
|
||||||
|
|||||||
@ -95,10 +95,10 @@ IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, float softness,
|
IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, bool uniform, float softness,
|
||||||
float alpha) {
|
float alpha) {
|
||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
float px, py, psx, sx, psy;
|
float px, py, psx, psy, sx, sy;
|
||||||
float cx, cy, csx, cwx, cwy;
|
float cx, cy, csx, cwx, cwy;
|
||||||
int o1, o2, s2, u;
|
int o1, o2, s2, u;
|
||||||
Bone *pp = parent.getParent();
|
Bone *pp = parent.getParent();
|
||||||
@ -107,8 +107,9 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
px = parent._ax;
|
px = parent._ax;
|
||||||
py = parent._ay;
|
py = parent._ay;
|
||||||
psx = parent._ascaleX;
|
psx = parent._ascaleX;
|
||||||
sx = psx;
|
|
||||||
psy = parent._ascaleY;
|
psy = parent._ascaleY;
|
||||||
|
sx = psx;
|
||||||
|
sy = psy;
|
||||||
csx = child._ascaleX;
|
csx = child._ascaleX;
|
||||||
if (psx < 0) {
|
if (psx < 0) {
|
||||||
psx = -psx;
|
psx = -psx;
|
||||||
@ -130,7 +131,7 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
r = psx - psy;
|
r = psx - psy;
|
||||||
cx = child._ax;
|
cx = child._ax;
|
||||||
u = (r < 0 ? -r : r) <= 0.0001f;
|
u = (r < 0 ? -r : r) <= 0.0001f;
|
||||||
if (!u) {
|
if (!u || stretch) {
|
||||||
cy = 0;
|
cy = 0;
|
||||||
cwx = parent._a * cx + parent._worldX;
|
cwx = parent._a * cx + parent._worldX;
|
||||||
cwy = parent._c * cx + parent._worldY;
|
cwy = parent._c * cx + parent._worldY;
|
||||||
@ -160,7 +161,7 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
|
tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
|
||||||
dd = tx * tx + ty * ty;
|
dd = tx * tx + ty * ty;
|
||||||
if (softness != 0) {
|
if (softness != 0) {
|
||||||
softness *= psx * (csx + 1) / 2;
|
softness *= psx * (csx + 1) * 0.5f;
|
||||||
td = MathUtil::sqrt(dd), sd = td - l1 - l2 * psx + softness;
|
td = MathUtil::sqrt(dd), sd = td - l1 - l2 * psx + softness;
|
||||||
if (sd > 0) {
|
if (sd > 0) {
|
||||||
p = MathUtil::min(1.0f, sd / (softness * 2)) - 1;
|
p = MathUtil::min(1.0f, sd / (softness * 2)) - 1;
|
||||||
@ -174,12 +175,19 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
float cosine;
|
float cosine;
|
||||||
l2 *= psx;
|
l2 *= psx;
|
||||||
cosine = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
cosine = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||||
if (cosine < -1) cosine = -1;
|
if (cosine < -1) {
|
||||||
else if (cosine > 1) {
|
cosine = -1;
|
||||||
|
a2 = MathUtil::Pi * bendDir;
|
||||||
|
} else if (cosine > 1) {
|
||||||
cosine = 1;
|
cosine = 1;
|
||||||
if (stretch) sx *= (MathUtil::sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
|
a2 = 0;
|
||||||
}
|
if (stretch) {
|
||||||
a2 = MathUtil::acos(cosine) * bendDir;
|
a = (MathUtil::sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
|
||||||
|
sx *= a;
|
||||||
|
if (uniform) sy *= a;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
a2 = MathUtil::acos(cosine) * bendDir;
|
||||||
a = l1 + l2 * cosine;
|
a = l1 + l2 * cosine;
|
||||||
b = l2 * MathUtil::sin(a2);
|
b = l2 * MathUtil::sin(a2);
|
||||||
a1 = MathUtil::atan2(ty * a - tx * b, tx * a + ty * b);
|
a1 = MathUtil::atan2(ty * a - tx * b, tx * a + ty * b);
|
||||||
@ -191,7 +199,7 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
if (d >= 0) {
|
if (d >= 0) {
|
||||||
float q = MathUtil::sqrt(d), r0, r1;
|
float q = MathUtil::sqrt(d), r0, r1;
|
||||||
if (c1 < 0) q = -q;
|
if (c1 < 0) q = -q;
|
||||||
q = -(c1 + q) / 2;
|
q = -(c1 + q) * 0.5f;
|
||||||
r0 = q / c2;
|
r0 = q / c2;
|
||||||
r1 = c0 / q;
|
r1 = c0 / q;
|
||||||
r = MathUtil::abs(r0) < MathUtil::abs(r1) ? r0 : r1;
|
r = MathUtil::abs(r0) < MathUtil::abs(r1) ? r0 : r1;
|
||||||
@ -224,7 +232,7 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
maxY = y;
|
maxY = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dd <= (minDist + maxDist) / 2) {
|
if (dd <= (minDist + maxDist) * 0.5f) {
|
||||||
a1 = ta - MathUtil::atan2(minY * bendDir, minX);
|
a1 = ta - MathUtil::atan2(minY * bendDir, minX);
|
||||||
a2 = minAngle * bendDir;
|
a2 = minAngle * bendDir;
|
||||||
} else {
|
} else {
|
||||||
@ -239,7 +247,7 @@ IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int
|
|||||||
a1 = (a1 - os) * MathUtil::Rad_Deg + o1 - parent._arotation;
|
a1 = (a1 - os) * MathUtil::Rad_Deg + o1 - parent._arotation;
|
||||||
if (a1 > 180) a1 -= 360;
|
if (a1 > 180) a1 -= 360;
|
||||||
else if (a1 < -180) a1 += 360;
|
else if (a1 < -180) a1 += 360;
|
||||||
parent.updateWorldTransform(px, py, parent._arotation + a1 * alpha, sx, parent._ascaleY, 0, 0);
|
parent.updateWorldTransform(px, py, parent._arotation + a1 * alpha, sx, sy, 0, 0);
|
||||||
a2 = ((a2 + os) * MathUtil::Rad_Deg - child._ashearX) * s2 + o2 - child._arotation;
|
a2 = ((a2 + os) * MathUtil::Rad_Deg - child._ashearX) * s2 + o2 - child._arotation;
|
||||||
if (a2 > 180) a2 -= 360;
|
if (a2 > 180) a2 -= 360;
|
||||||
else if (a2 < -180) a2 += 360;
|
else if (a2 < -180) a2 += 360;
|
||||||
@ -276,7 +284,7 @@ void IkConstraint::update() {
|
|||||||
case 2: {
|
case 2: {
|
||||||
Bone *bone0 = _bones[0];
|
Bone *bone0 = _bones[0];
|
||||||
Bone *bone1 = _bones[1];
|
Bone *bone1 = _bones[1];
|
||||||
apply(*bone0, *bone1, _target->getWorldX(), _target->getWorldY(), _bendDirection, _stretch, _softness,
|
apply(*bone0, *bone1, _target->getWorldX(), _target->getWorldY(), _bendDirection, _stretch, _data._uniform, _softness,
|
||||||
_mix);
|
_mix);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user