[c] port of constraint application oder, see #1896

This commit is contained in:
Mario Zechner 2021-06-07 16:57:16 +02:00
parent 857b2b64d8
commit 35650a6bb2
8 changed files with 44 additions and 19 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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