mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
[c] port of constraint application oder, see #1896
This commit is contained in:
parent
857b2b64d8
commit
35650a6bb2
@ -48,7 +48,6 @@ struct spBone {
|
||||
spBone **const children;
|
||||
float x, y, rotation, scaleX, scaleY, shearX, shearY;
|
||||
float ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY;
|
||||
int /*bool*/ appliedValid;
|
||||
|
||||
float const a, b, worldX;
|
||||
float const c, d, worldY;
|
||||
@ -68,6 +67,8 @@ SP_API void spBone_dispose(spBone *self);
|
||||
|
||||
SP_API void spBone_setToSetupPose(spBone *self);
|
||||
|
||||
SP_API void spBone_update(spBone *self);
|
||||
|
||||
SP_API void spBone_updateWorldTransform(spBone *self);
|
||||
|
||||
SP_API void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotation, float scaleX, float scaleY,
|
||||
|
||||
@ -57,6 +57,10 @@ void spBone_dispose(spBone *self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void spBone_update(spBone *self) {
|
||||
spBone_updateWorldTransformWith(self, self->ax, self->ay, self->arotation, self->ascaleX, self->ascaleY, self->ashearX, self->ashearY);
|
||||
}
|
||||
|
||||
void spBone_updateWorldTransform(spBone *self) {
|
||||
spBone_updateWorldTransformWith(self, self->x, self->y, self->rotation, self->scaleX, self->scaleY, self->shearX,
|
||||
self->shearY);
|
||||
@ -77,7 +81,6 @@ void spBone_updateWorldTransformWith(spBone *self, float x, float y, float rotat
|
||||
self->ascaleY = scaleY;
|
||||
self->ashearX = shearX;
|
||||
self->ashearY = shearY;
|
||||
self->appliedValid = 1;
|
||||
|
||||
if (!parent) { /* Root bone. */
|
||||
float rotationY = rotation + 90 + shearY;
|
||||
@ -214,7 +217,6 @@ float spBone_getWorldScaleY(spBone *self) {
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
|
||||
void spBone_updateAppliedTransform(spBone *self) {
|
||||
spBone *parent = self->parent;
|
||||
self->appliedValid = 1;
|
||||
if (!parent) {
|
||||
self->ax = self->worldX;
|
||||
self->ay = self->worldY;
|
||||
@ -289,5 +291,4 @@ void spBone_rotateWorld(spBone *self, float degrees) {
|
||||
CONST_CAST(float, self->b) = cosine * b - sine * d;
|
||||
CONST_CAST(float, self->c) = sine * a + cosine * c;
|
||||
CONST_CAST(float, self->d) = sine * b + cosine * d;
|
||||
CONST_CAST(int, self->appliedValid) = 0;
|
||||
}
|
||||
|
||||
@ -78,7 +78,6 @@ spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*
|
||||
float pa = p->a, pb = p->b, pc = p->c, pd = p->d;
|
||||
float rotationIK = -bone->ashearX - bone->arotation;
|
||||
float tx = 0, ty = 0, sx = 0, sy = 0, s = 0, sa = 0, sc = 0;
|
||||
if (!bone->appliedValid) spBone_updateAppliedTransform(bone);
|
||||
|
||||
switch (bone->data->transformMode) {
|
||||
case SP_TRANSFORMMODE_ONLYTRANSLATION:
|
||||
@ -139,8 +138,6 @@ spIkConstraint_apply2(spBone *parent, spBone *child, float targetX, float target
|
||||
float id, x, y;
|
||||
float aa, bb, ll, ta, c0, c1, c2;
|
||||
|
||||
if (!parent->appliedValid) spBone_updateAppliedTransform(parent);
|
||||
if (!child->appliedValid) spBone_updateAppliedTransform(child);
|
||||
px = parent->ax;
|
||||
py = parent->ay;
|
||||
psx = parent->ascaleX;
|
||||
|
||||
@ -221,7 +221,7 @@ void spPathConstraint_update(spPathConstraint *self) {
|
||||
CONST_CAST(float, bone->c) = sine * a + cosine * c;
|
||||
CONST_CAST(float, bone->d) = sine * b + cosine * d;
|
||||
}
|
||||
CONST_CAST(int, bone->appliedValid) = -1;
|
||||
spBone_updateAppliedTransform(bone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -398,13 +398,25 @@ void spSkeleton_updateCache(spSkeleton *self) {
|
||||
}
|
||||
|
||||
void spSkeleton_updateWorldTransform(const spSkeleton *self) {
|
||||
int i;
|
||||
int i, n;
|
||||
_spSkeleton *internal = SUB_CAST(_spSkeleton, self);
|
||||
|
||||
for (i = 0, n = self->bonesCount; i < n; i++) {
|
||||
spBone *bone = self->bones[i];
|
||||
bone->ax = bone->x;
|
||||
bone->ay = bone->y;
|
||||
bone->arotation = bone->rotation;
|
||||
bone->ascaleX = bone->scaleX;
|
||||
bone->ascaleY = bone->scaleY;
|
||||
bone->ashearX = bone->shearX;
|
||||
bone->ashearY = bone->shearY;
|
||||
}
|
||||
|
||||
for (i = 0; i < internal->updateCacheCount; ++i) {
|
||||
_spUpdate *update = internal->updateCache + i;
|
||||
switch (update->type) {
|
||||
case SP_UPDATE_BONE:
|
||||
spBone_updateWorldTransform((spBone *) update->object);
|
||||
spBone_update((spBone *) update->object);
|
||||
break;
|
||||
case SP_UPDATE_IK_CONSTRAINT:
|
||||
spIkConstraint_update((spIkConstraint *) update->object);
|
||||
|
||||
@ -51,11 +51,31 @@ void spSlot_dispose(spSlot *self) {
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
static int isVertexAttachment(spAttachment *attachment) {
|
||||
if (attachment == NULL) return 0;
|
||||
switch (attachment->type) {
|
||||
case SP_ATTACHMENT_BOUNDING_BOX:
|
||||
case SP_ATTACHMENT_CLIPPING:
|
||||
case SP_ATTACHMENT_MESH:
|
||||
case SP_ATTACHMENT_PATH:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void spSlot_setAttachment(spSlot *self, spAttachment *attachment) {
|
||||
if (attachment == self->attachment) return;
|
||||
|
||||
if (!isVertexAttachment(attachment) ||
|
||||
!isVertexAttachment(self->attachment)
|
||||
|| (SUB_CAST(spVertexAttachment, attachment)->deformAttachment !=
|
||||
SUB_CAST(spVertexAttachment, self->attachment)->deformAttachment)) {
|
||||
self->deformCount = 0;
|
||||
}
|
||||
|
||||
CONST_CAST(spAttachment*, self->attachment) = attachment;
|
||||
SUB_CAST(_spSlot, self)->attachmentTime = self->bone->skeleton->time;
|
||||
self->deformCount = 0;
|
||||
}
|
||||
|
||||
void spSlot_setAttachmentTime(spSlot *self, float time) {
|
||||
|
||||
@ -112,7 +112,7 @@ void _spTransformConstraint_applyAbsoluteWorld(spTransformConstraint *self) {
|
||||
CONST_CAST(float, bone->b) = COS(r) * s;
|
||||
CONST_CAST(float, bone->d) = SIN(r) * s;
|
||||
}
|
||||
CONST_CAST(int, bone->appliedValid) = 0;
|
||||
spBone_updateAppliedTransform(bone);
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ void _spTransformConstraint_applyRelativeWorld(spTransformConstraint *self) {
|
||||
CONST_CAST(float, bone->d) = SIN(r) * s;
|
||||
}
|
||||
|
||||
CONST_CAST(int, bone->appliedValid) = 0;
|
||||
spBone_updateAppliedTransform(bone);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,10 +183,8 @@ void _spTransformConstraint_applyAbsoluteLocal(spTransformConstraint *self) {
|
||||
int i;
|
||||
float rotation, r, x, y, scaleX, scaleY, shearY;
|
||||
|
||||
if (!target->appliedValid) spBone_updateAppliedTransform(target);
|
||||
for (i = 0; i < self->bonesCount; ++i) {
|
||||
spBone *bone = self->bones[i];
|
||||
if (!bone->appliedValid) spBone_updateAppliedTransform(bone);
|
||||
|
||||
rotation = bone->arotation;
|
||||
if (mixRotate != 0) {
|
||||
@ -223,11 +221,8 @@ void _spTransformConstraint_applyRelativeLocal(spTransformConstraint *self) {
|
||||
int i;
|
||||
float rotation, x, y, scaleX, scaleY, shearY;
|
||||
|
||||
if (!target->appliedValid) spBone_updateAppliedTransform(target);
|
||||
|
||||
for (i = 0; i < self->bonesCount; ++i) {
|
||||
spBone *bone = self->bones[i];
|
||||
if (!bone->appliedValid) spBone_updateAppliedTransform(bone);
|
||||
|
||||
rotation = bone->arotation + (target->arotation + self->data->offsetRotation) * mixRotate;
|
||||
x = bone->ax + (target->ax + self->data->offsetX) * mixX;
|
||||
|
||||
@ -225,7 +225,6 @@ void ikDemo (spSkeletonData* skeletonData, spAtlas* atlas) {
|
||||
spBone_worldToLocal(crosshair->parent, mouseCoords.x, mouseCoords.y, &boneCoordsX, &boneCoordsY);
|
||||
crosshair->x = boneCoordsX;
|
||||
crosshair->y = boneCoordsY;
|
||||
crosshair->appliedValid = false;
|
||||
|
||||
// Calculate final world transform with the
|
||||
// crosshair bone set to the mouse cursor
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user