mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[c] Port of #2150
This commit is contained in:
parent
0827d88b7b
commit
52376a0a24
@ -175,7 +175,6 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
|
|||||||
CONST_CAST(float, self->b) = za * lb + zb * ld;
|
CONST_CAST(float, self->b) = za * lb + zb * ld;
|
||||||
CONST_CAST(float, self->c) = zc * la + zd * lc;
|
CONST_CAST(float, self->c) = zc * la + zd * lc;
|
||||||
CONST_CAST(float, self->d) = zc * lb + zd * ld;
|
CONST_CAST(float, self->d) = zc * lb + zd * ld;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +215,14 @@ float spBone_getWorldScaleY(spBone *self) {
|
|||||||
* <p>
|
* <p>
|
||||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
|
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
|
||||||
void spBone_updateAppliedTransform(spBone *self) {
|
void spBone_updateAppliedTransform(spBone *self) {
|
||||||
|
float pa, pb, pc, pd;
|
||||||
|
float pid;
|
||||||
|
float ia, ib, ic, id;
|
||||||
|
float dx, dy;
|
||||||
|
float ra, rb, rc, rd;
|
||||||
|
float s, r, sa, sc;
|
||||||
|
float cosine, sine;
|
||||||
|
|
||||||
spBone *parent = self->parent;
|
spBone *parent = self->parent;
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
self->ax = self->worldX - self->skeleton->x;
|
self->ax = self->worldX - self->skeleton->x;
|
||||||
@ -225,33 +232,74 @@ void spBone_updateAppliedTransform(spBone *self) {
|
|||||||
self->ascaleY = SQRT(self->b * self->b + self->d * self->d);
|
self->ascaleY = SQRT(self->b * self->b + self->d * self->d);
|
||||||
self->ashearX = 0;
|
self->ashearX = 0;
|
||||||
self->ashearY = ATAN2(self->a * self->b + self->c * self->d, self->a * self->d - self->b * self->c) * RAD_DEG;
|
self->ashearY = ATAN2(self->a * self->b + self->c * self->d, self->a * self->d - self->b * self->c) * RAD_DEG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pa = parent->a, pb = parent->b, pc = parent->c, pd = parent->d;
|
||||||
|
pid = 1 / (pa * pd - pb * pc);
|
||||||
|
ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;
|
||||||
|
dx = self->worldX - parent->worldX, dy = self->worldY - parent->worldY;
|
||||||
|
self->ax = (dx * ia - dy * ib);
|
||||||
|
self->ay = (dy * id - dx * ic);
|
||||||
|
|
||||||
|
if (self->data->transformMode == SP_TRANSFORMMODE_ONLYTRANSLATION) {
|
||||||
|
ra = self->a;
|
||||||
|
rb = self->b;
|
||||||
|
rc = self->c;
|
||||||
|
rd = self->d;
|
||||||
} else {
|
} else {
|
||||||
float pa = parent->a, pb = parent->b, pc = parent->c, pd = parent->d;
|
switch (self->data->transformMode) {
|
||||||
float pid = 1 / (pa * pd - pb * pc);
|
case SP_TRANSFORMMODE_NOROTATIONORREFLECTION: {
|
||||||
float dx = self->worldX - parent->worldX, dy = self->worldY - parent->worldY;
|
s = ABS(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||||
float ia = pid * pd;
|
sa = pa / self->skeleton->scaleX;
|
||||||
float id = pid * pa;
|
sc = pc / self->skeleton->scaleY;
|
||||||
float ib = pid * pb;
|
pb = -sc * s * self->skeleton->scaleX;
|
||||||
float ic = pid * pc;
|
pd = sa * s * self->skeleton->scaleY;
|
||||||
float ra = ia * self->a - ib * self->c;
|
pid = 1 / (pa * pd - pb * pc);
|
||||||
float rb = ia * self->b - ib * self->d;
|
ia = pd * pid;
|
||||||
float rc = id * self->c - ic * self->a;
|
ib = pb * pid;
|
||||||
float rd = id * self->d - ic * self->b;
|
break;
|
||||||
self->ax = (dx * pd * pid - dy * pb * pid);
|
}
|
||||||
self->ay = (dy * pa * pid - dx * pc * pid);
|
case SP_TRANSFORMMODE_NOSCALE:
|
||||||
self->ashearX = 0;
|
case SP_TRANSFORMMODE_NOSCALEORREFLECTION:
|
||||||
self->ascaleX = SQRT(ra * ra + rc * rc);
|
cosine = COS_DEG(self->rotation), sine = SIN_DEG(self->rotation);
|
||||||
if (self->ascaleX > 0.0001f) {
|
pa = (pa * cosine + pb * sine) / self->skeleton->scaleX;
|
||||||
float det = ra * rd - rb * rc;
|
pc = (pc * cosine + pd * sine) / self->skeleton->scaleY;
|
||||||
self->ascaleY = det / self->ascaleX;
|
s = SQRT(pa * pa + pc * pc);
|
||||||
self->ashearY = ATAN2(ra * rb + rc * rd, det) * RAD_DEG;
|
if (s > 0.00001f) s = 1 / s;
|
||||||
self->arotation = ATAN2(rc, ra) * RAD_DEG;
|
pa *= s;
|
||||||
} else {
|
pc *= s;
|
||||||
self->ascaleX = 0;
|
s = SQRT(pa * pa + pc * pc);
|
||||||
self->ascaleY = SQRT(rb * rb + rd * rd);
|
if (self->data->transformMode == SP_TRANSFORMMODE_NOSCALE &&
|
||||||
self->ashearY = 0;
|
pid < 0 != (self->skeleton->scaleX < 0 != self->skeleton->scaleY < 0))
|
||||||
self->arotation = 90 - ATAN2(rd, rb) * RAD_DEG;
|
s = -s;
|
||||||
|
r = PI / 2 + ATAN2(pc, pa);
|
||||||
|
pb = COS(r) * s;
|
||||||
|
pd = SIN(r) * s;
|
||||||
|
pid = 1 / (pa * pd - pb * pc);
|
||||||
|
ia = pd * pid;
|
||||||
|
ib = pb * pid;
|
||||||
|
ic = pc * pid;
|
||||||
|
id = pa * pid;
|
||||||
}
|
}
|
||||||
|
ra = ia * self->a - ib * self->c;
|
||||||
|
rb = ia * self->b - ib * self->d;
|
||||||
|
rc = id * self->c - ic * self->a;
|
||||||
|
rd = id * self->d - ic * self->b;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->ashearX = 0;
|
||||||
|
self->ascaleX = SQRT(ra * ra + rc * rc);
|
||||||
|
if (self->ascaleX > 0.0001f) {
|
||||||
|
float det = ra * rd - rb * rc;
|
||||||
|
self->ascaleY = det / self->ascaleX;
|
||||||
|
self->ashearY = -ATAN2(ra * rb + rc * rd, det) * RAD_DEG;
|
||||||
|
self->arotation = ATAN2(rc, ra) * RAD_DEG;
|
||||||
|
} else {
|
||||||
|
self->ascaleX = 0;
|
||||||
|
self->ascaleY = SQRT(rb * rb + rd * rd);
|
||||||
|
self->ashearY = 0;
|
||||||
|
self->arotation = 90 - ATAN2(rd, rb) * RAD_DEG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -192,7 +192,6 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX,
|
|||||||
_b = za * lb + zb * ld;
|
_b = za * lb + zb * ld;
|
||||||
_c = zc * la + zd * lc;
|
_c = zc * la + zd * lc;
|
||||||
_d = zc * lb + zd * ld;
|
_d = zc * lb + zd * ld;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_a *= _skeleton.getScaleX();
|
_a *= _skeleton.getScaleX();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user