mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[c] More 4.2 porting, only loaders left.
This commit is contained in:
parent
430758eb9b
commit
f7f4d5cbe7
@ -101,8 +101,17 @@ typedef enum {
|
||||
SP_TIMELINE_TRANSLATE,
|
||||
SP_TIMELINE_DEFORM,
|
||||
SP_TIMELINE_SEQUENCE,
|
||||
SP_TIMELINE_INHERIT,
|
||||
SP_TIMELINE_IKCONSTRAINT,
|
||||
SP_TIMELINE_PATHCONSTRAINTMIX,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_MASS,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_WIND,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_MIX,
|
||||
SP_TIMELINE_PHYSICSCONSTRAINT_RESET,
|
||||
SP_TIMELINE_RGB2,
|
||||
SP_TIMELINE_RGBA2,
|
||||
SP_TIMELINE_RGBA,
|
||||
@ -122,19 +131,28 @@ typedef enum {
|
||||
SP_PROPERTY_SCALEY = 1 << 4,
|
||||
SP_PROPERTY_SHEARX = 1 << 5,
|
||||
SP_PROPERTY_SHEARY = 1 << 6,
|
||||
SP_PROPERTY_RGB = 1 << 7,
|
||||
SP_PROPERTY_ALPHA = 1 << 8,
|
||||
SP_PROPERTY_RGB2 = 1 << 9,
|
||||
SP_PROPERTY_ATTACHMENT = 1 << 10,
|
||||
SP_PROPERTY_DEFORM = 1 << 11,
|
||||
SP_PROPERTY_EVENT = 1 << 12,
|
||||
SP_PROPERTY_DRAWORDER = 1 << 13,
|
||||
SP_PROPERTY_IKCONSTRAINT = 1 << 14,
|
||||
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 15,
|
||||
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 16,
|
||||
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 17,
|
||||
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18,
|
||||
SP_PROPERTY_SEQUENCE = 1 << 19
|
||||
SP_PROPERTY_INHERIT = 1 << 7,
|
||||
SP_PROPERTY_RGB = 1 << 8,
|
||||
SP_PROPERTY_ALPHA = 1 << 9,
|
||||
SP_PROPERTY_RGB2 = 1 << 10,
|
||||
SP_PROPERTY_ATTACHMENT = 1 << 11,
|
||||
SP_PROPERTY_DEFORM = 1 << 12,
|
||||
SP_PROPERTY_EVENT = 1 << 13,
|
||||
SP_PROPERTY_DRAWORDER = 1 << 14,
|
||||
SP_PROPERTY_IKCONSTRAINT = 1 << 15,
|
||||
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 16,
|
||||
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 17,
|
||||
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 18,
|
||||
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 19,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_INERTIA = 1 << 20,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_STRENGTH = 1 << 21,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_DAMPING = 1 << 22,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_MASS = 1 << 23,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_WIND = 1 << 24,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_GRAVITY = 1 << 25,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_MIX = 1 << 26,
|
||||
SP_PROPERTY_PHYSICSCONSTRAINT_RESET = 1 << 27,
|
||||
SP_PROPERTY_SEQUENCE = 1 << 28
|
||||
} spProperty;
|
||||
|
||||
#define SP_MAX_PROPERTY_IDS 3
|
||||
@ -196,6 +214,14 @@ SP_API void spCurveTimeline1_setFrame(spCurveTimeline1 *self, int frame, float t
|
||||
|
||||
SP_API float spCurveTimeline1_getCurveValue(spCurveTimeline1 *self, float time);
|
||||
|
||||
SP_API float spCurveTimeline1_getRelativeValue(spCurveTimeline1 *timeline, float time, float alpha, spMixBlend blend, float current, float setup);
|
||||
|
||||
SP_API float spCurveTimeline1_getAbsoluteValue(spCurveTimeline1 *timeline, float time, float alpha, spMixBlend blend, float current, float setup);
|
||||
|
||||
SP_API float spCurveTimeline1_getAbsoluteValue2(spCurveTimeline1 *timeline, float time, float alpha, spMixBlend blend, float current, float setup, float value);
|
||||
|
||||
SP_API float spCurveTimeline1_getScaleValue (spCurveTimeline1 *timeline, float time, float alpha, spMixBlend blend, spMixDirection direction, float current, float setup);
|
||||
|
||||
typedef struct spCurveTimeline spCurveTimeline2;
|
||||
|
||||
SP_API void spCurveTimeline2_setFrame(spCurveTimeline1 *self, int frame, float time, float value1, float value2);
|
||||
@ -437,6 +463,18 @@ SP_API spDrawOrderTimeline *spDrawOrderTimeline_create(int framesCount, int slot
|
||||
|
||||
SP_API void spDrawOrderTimeline_setFrame(spDrawOrderTimeline *self, int frameIndex, float time, const int *drawOrder);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct spInheritTimeline {
|
||||
spTimeline super;
|
||||
int boneIndex;
|
||||
} spInheritTimeline;
|
||||
|
||||
SP_API spInheritTimeline *spInheritTimeline_create(int framesCount, int boneIndex);
|
||||
|
||||
SP_API void spInheritTimeline_setFrame(spDrawOrderTimeline *self, int frameIndex, float time, spInherit inherit);
|
||||
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct spIkConstraintTimeline {
|
||||
@ -508,6 +546,27 @@ spPathConstraintMixTimeline_setFrame(spPathConstraintMixTimeline *self, int fram
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct spPhysicsConstraintTimeline {
|
||||
spCurveTimeline super;
|
||||
int physicsConstraintIndex;
|
||||
} spPhysicsConstraintTimeline;
|
||||
|
||||
SP_API spPhysicsConstraintTimeline *
|
||||
spPhysicsConstraintTimeline_create(int framesCount, int bezierCount, int physicsConstraintIndex, spTimelineType type);
|
||||
|
||||
SP_API void spPhysicsConstraintTimeline_setFrame(spPhysicsConstraintTimeline *self, int frame, float time, float value);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct spPhysicsConstraintResetTimeline {
|
||||
spTimeline super;
|
||||
int physicsConstraintIndex;
|
||||
} spPhysicsConstraintResetTimeline;
|
||||
|
||||
SP_API spPhysicsConstraintResetTimeline *spPhysicsConstraintResetTimeline_create(int framesCount, int boneIndex);
|
||||
|
||||
SP_API void spPhysicsConstraintResetTimeline_setFrame(spPhysicsConstraintResetTimeline *self, int frameIndex, float time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -69,7 +69,7 @@ struct spTrackEntry {
|
||||
int /*boolean*/ holdPrevious;
|
||||
int /*boolean*/ reverse;
|
||||
int /*boolean*/ shortestRotation;
|
||||
float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
||||
float eventThreshold, mixAttachmentThreshold, alphaAttachmentThreshold, mixDrawOrderThreshold;
|
||||
float animationStart, animationEnd, animationLast, nextAnimationLast;
|
||||
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
|
||||
float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha;
|
||||
@ -146,6 +146,10 @@ SP_API void spTrackEntry_resetRotationDirections(spTrackEntry *entry);
|
||||
|
||||
SP_API float spTrackEntry_getTrackComplete(spTrackEntry *entry);
|
||||
|
||||
SP_API void spTrackEntry_setMixDuration(spTrackEntry *entry, float mixDuration, float delay);
|
||||
|
||||
SP_API int/*bool*/ spTrackEntry_wasApplied(spTrackEntry *entry);
|
||||
|
||||
SP_API void spAnimationState_clearNext(spAnimationState *self, spTrackEntry *entry);
|
||||
|
||||
/** Use this to dispose static memory before your app exits to appease your memory leak detector*/
|
||||
|
||||
@ -62,6 +62,8 @@ SP_API void spIkConstraint_dispose(spIkConstraint *self);
|
||||
|
||||
SP_API void spIkConstraint_update(spIkConstraint *self);
|
||||
|
||||
SP_API void spIkConstraint_setToSetupPose(spIkConstraint *self);
|
||||
|
||||
SP_API void
|
||||
spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch,
|
||||
int /*boolean*/ uniform, float alpha);
|
||||
|
||||
@ -78,6 +78,8 @@ SP_API void spPathConstraint_dispose(spPathConstraint *self);
|
||||
|
||||
SP_API void spPathConstraint_update(spPathConstraint *self);
|
||||
|
||||
SP_API void spPathConstraint_setToSetupPose(spPathConstraint *self);
|
||||
|
||||
SP_API float *spPathConstraint_computeWorldPositions(spPathConstraint *self, spPathAttachment *path, int spacesCount,
|
||||
int/*bool*/ tangents);
|
||||
|
||||
|
||||
@ -130,6 +130,10 @@ SP_API spPathConstraint *spSkeleton_findPathConstraint(const spSkeleton *self, c
|
||||
/* Returns 0 if the physics constraint was not found. */
|
||||
SP_API spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, const char *constraintName);
|
||||
|
||||
SP_API void spSkeleton_physicsTranslate(spSkeleton *self, float x, float y);
|
||||
|
||||
SP_API void spSkeleton_physicsRotate(spSkeleton *self, float x, float y, float degrees);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <spine/IkConstraintData.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
#include <spine/PhysicsConstraintData.h>
|
||||
#include <spine/Array.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -54,6 +55,8 @@ _SP_ARRAY_DECLARE_TYPE(spTransformConstraintDataArray, spTransformConstraintData
|
||||
|
||||
_SP_ARRAY_DECLARE_TYPE(spPathConstraintDataArray, spPathConstraintData*)
|
||||
|
||||
_SP_ARRAY_DECLARE_TYPE(spPhysicsConstraintDataArray, spPhysicsConstraintData*)
|
||||
|
||||
typedef struct spSkin {
|
||||
char *name;
|
||||
|
||||
@ -61,6 +64,7 @@ typedef struct spSkin {
|
||||
spIkConstraintDataArray *ikConstraints;
|
||||
spTransformConstraintDataArray *transformConstraints;
|
||||
spPathConstraintDataArray *pathConstraints;
|
||||
spPhysicsConstraintDataArray *physicsConstraints;
|
||||
spColor color;
|
||||
} spSkin;
|
||||
|
||||
|
||||
@ -56,6 +56,8 @@ SP_API void spTransformConstraint_dispose(spTransformConstraint *self);
|
||||
|
||||
SP_API void spTransformConstraint_update(spTransformConstraint *self);
|
||||
|
||||
SP_API void spTransformConstraint_setToSetupPose(spTransformConstraint *self);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -298,6 +298,110 @@ float spCurveTimeline1_getCurveValue(spCurveTimeline1 *self, float time) {
|
||||
return _spCurveTimeline_getBezierValue(self, time, i, CURVE1_VALUE, curveType - CURVE_BEZIER);
|
||||
}
|
||||
|
||||
float spCurveTimeline1_getRelativeValue(spCurveTimeline1 *self, float time, float alpha, spMixBlend blend, float current, float setup) {
|
||||
float *frames = self->super.frames->items;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
return current + (setup - current) * alpha;
|
||||
default:
|
||||
return current;
|
||||
}
|
||||
}
|
||||
float value = spCurveTimeline1_getCurveValue(self, time);
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup + value * alpha;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
value += setup - current;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
break;
|
||||
}
|
||||
return current + value * alpha;
|
||||
}
|
||||
|
||||
float spCurveTimeline1_getAbsoluteValue(spCurveTimeline1 *self, float time, float alpha, spMixBlend blend, float current, float setup) {
|
||||
float *frames = self->super.frames->items;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
return current + (setup - current) * alpha;
|
||||
default:
|
||||
return current;
|
||||
}
|
||||
}
|
||||
float value = spCurveTimeline1_getCurveValue(self, time);
|
||||
if (blend == SP_MIX_BLEND_SETUP) return setup + (value - setup) * alpha;
|
||||
return current + (value - current) * alpha;
|
||||
}
|
||||
|
||||
float spCurveTimeline1_getAbsoluteValue2(spCurveTimeline1 *self, float time, float alpha, spMixBlend blend, float current, float setup, float value) {
|
||||
float *frames = self->super.frames->items;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
return current + (setup - current) * alpha;
|
||||
default:
|
||||
return current;
|
||||
}
|
||||
}
|
||||
if (blend == SP_MIX_BLEND_SETUP) return setup + (value - setup) * alpha;
|
||||
return current + (value - current) * alpha;
|
||||
}
|
||||
|
||||
float spCurveTimeline1_getScaleValue (spCurveTimeline1 *self, float time, float alpha, spMixBlend blend, spMixDirection direction, float current, float setup) {
|
||||
float *frames = self->super.frames->items;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
return current + (setup - current) * alpha;
|
||||
default:
|
||||
return current;
|
||||
}
|
||||
}
|
||||
float value = spCurveTimeline1_getCurveValue(self, time) * setup;
|
||||
if (alpha == 1) {
|
||||
if (blend == SP_MIX_BLEND_ADD) return current + value - setup;
|
||||
return value;
|
||||
}
|
||||
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
return setup + (ABS(value) * SIGNUM(setup) - setup) * alpha;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
return current + (ABS(value) * SIGNUM(current) - current) * alpha;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
float s;
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
s = ABS(setup) * SIGNUM(value);
|
||||
return s + (value - s) * alpha;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
s = ABS(current) * SIGNUM(value);
|
||||
return s + (value - s) * alpha;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return current + (value - setup) * alpha;
|
||||
}
|
||||
|
||||
#define CURVE2_ENTRIES 3
|
||||
#define CURVE2_VALUE1 1
|
||||
#define CURVE2_VALUE2 2
|
||||
@ -314,40 +418,11 @@ SP_API void spCurveTimeline2_setFrame(spCurveTimeline1 *self, int frame, float t
|
||||
|
||||
void _spRotateTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents,
|
||||
int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
||||
spBone *bone;
|
||||
float r;
|
||||
spRotateTimeline *self = SUB_CAST(spRotateTimeline, timeline);
|
||||
float *frames = self->super.super.frames->items;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
if (bone->active) bone->rotation = spCurveTimeline1_getRelativeValue(SUPER(self), time, alpha, blend, bone->rotation, bone->data->rotation);
|
||||
|
||||
bone = skeleton->bones[self->boneIndex];
|
||||
if (!bone->active) return;
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->rotation = bone->data->rotation;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
bone->rotation += (bone->data->rotation - bone->rotation) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
r = spCurveTimeline1_getCurveValue(SUPER(self), time);
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->rotation = bone->data->rotation + r * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
r += bone->data->rotation - bone->rotation;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->rotation += r * alpha;
|
||||
}
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
@ -709,69 +784,12 @@ void spScaleTimeline_setFrame(spScaleTimeline *self, int frame, float time, floa
|
||||
void _spScaleXTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spBone *bone;
|
||||
float x;
|
||||
|
||||
spScaleXTimeline *self = SUB_CAST(spScaleXTimeline, timeline);
|
||||
float *frames = self->super.super.frames->items;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
bone = skeleton->bones[self->boneIndex];
|
||||
if (!bone->active) return;
|
||||
if (bone->active) bone->scaleX = spCurveTimeline1_getScaleValue(SUPER(self), time, alpha, blend, direction, bone->scaleX, bone->data->scaleX);
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->scaleX = bone->data->scaleX;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
bone->scaleX += (bone->data->scaleX - bone->scaleX) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
x = spCurveTimeline1_getCurveValue(SUPER(self), time) * bone->data->scaleX;
|
||||
if (alpha == 1) {
|
||||
if (blend == SP_MIX_BLEND_ADD)
|
||||
bone->scaleX += x - bone->data->scaleX;
|
||||
else
|
||||
bone->scaleX = x;
|
||||
} else {
|
||||
/* Mixing out uses sign of setup or current pose, else use sign of key. */
|
||||
float bx;
|
||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bx = bone->data->scaleX;
|
||||
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
bx = bone->scaleX;
|
||||
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->scaleX += (x - bone->data->scaleX) * alpha;
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bx = ABS(bone->data->scaleX) * SIGNUM(x);
|
||||
bone->scaleX = bx + (x - bx) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
bx = ABS(bone->scaleX) * SIGNUM(x);
|
||||
bone->scaleX = bx + (x - bx) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->scaleX += (x - bone->data->scaleX) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
}
|
||||
@ -795,69 +813,12 @@ void spScaleXTimeline_setFrame(spScaleXTimeline *self, int frame, float time, fl
|
||||
void _spScaleYTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spBone *bone;
|
||||
float y;
|
||||
|
||||
spScaleYTimeline *self = SUB_CAST(spScaleYTimeline, timeline);
|
||||
float *frames = self->super.super.frames->items;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
bone = skeleton->bones[self->boneIndex];
|
||||
if (!bone->active) return;
|
||||
if (bone->active) bone->scaleY = spCurveTimeline1_getScaleValue(SUPER(self), time, alpha, blend, direction, bone->scaleX, bone->data->scaleY);
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->scaleY = bone->data->scaleY;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
bone->scaleY += (bone->data->scaleY - bone->scaleY) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
y = spCurveTimeline1_getCurveValue(SUPER(self), time) * bone->data->scaleY;
|
||||
if (alpha == 1) {
|
||||
if (blend == SP_MIX_BLEND_ADD)
|
||||
bone->scaleY += y - bone->data->scaleY;
|
||||
else
|
||||
bone->scaleY = y;
|
||||
} else {
|
||||
/* Mixing out uses sign of setup or current pose, else use sign of key. */
|
||||
float by = 0;
|
||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
by = bone->data->scaleY;
|
||||
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
by = bone->scaleY;
|
||||
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->scaleY += (y - bone->data->scaleY) * alpha;
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
by = ABS(bone->data->scaleY) * SIGNUM(y);
|
||||
bone->scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
by = ABS(bone->scaleY) * SIGNUM(y);
|
||||
bone->scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->scaleY += (y - bone->data->scaleY) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
}
|
||||
@ -970,41 +931,12 @@ void spShearTimeline_setFrame(spShearTimeline *self, int frame, float time, floa
|
||||
void _spShearXTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spBone *bone;
|
||||
float x;
|
||||
|
||||
spShearXTimeline *self = SUB_CAST(spShearXTimeline, timeline);
|
||||
float *frames = self->super.super.frames->items;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
bone = skeleton->bones[self->boneIndex];
|
||||
if (!bone->active) return;
|
||||
if (bone->active) bone->shearX = spCurveTimeline1_getRelativeValue(SUPER(self), time, alpha, blend, bone->shearX, bone->data->shearX);
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->shearX = bone->data->shearX;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
x = spCurveTimeline1_getCurveValue(SUPER(self), time);
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->shearX = bone->data->shearX + x * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->shearX += x * alpha;
|
||||
}
|
||||
UNUSED(lastTime);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
@ -1029,42 +961,12 @@ void spShearXTimeline_setFrame(spShearXTimeline *self, int frame, float time, fl
|
||||
void _spShearYTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spBone *bone;
|
||||
float y;
|
||||
|
||||
spShearYTimeline *self = SUB_CAST(spShearYTimeline, timeline);
|
||||
float *frames = self->super.super.frames->items;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
|
||||
bone = skeleton->bones[self->boneIndex];
|
||||
if (!bone->active) return;
|
||||
if (bone->active) bone->shearY = spCurveTimeline1_getRelativeValue(SUPER(self), time, alpha, blend, bone->shearY, bone->data->shearY);
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->shearY = bone->data->shearY;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
y = spCurveTimeline1_getCurveValue(SUPER(self), time);
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
bone->shearY = bone->data->shearY + y * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
bone->shearY += y * alpha;
|
||||
}
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
@ -2053,7 +1955,7 @@ void _spSequenceTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float
|
||||
count = sequence->regions->size;
|
||||
mode = modeAndIndex & 0xf;
|
||||
if (mode != SP_SEQUENCE_MODE_HOLD) {
|
||||
index += (int) (((time - before) / delay + 0.00001));
|
||||
index += (int) (((time - before) / delay + 0.0001));
|
||||
switch (mode) {
|
||||
case SP_SEQUENCE_MODE_ONCE:
|
||||
index = MIN(count - 1, index);
|
||||
@ -2252,6 +2154,53 @@ void spDrawOrderTimeline_setFrame(spDrawOrderTimeline *self, int frame, float ti
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void _spInheritTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spInheritTimeline *self = (spInheritTimeline *)timeline;
|
||||
spBone *bone = skeleton->bones[self->boneIndex];
|
||||
float *frames = self->super.frames->items;
|
||||
if (!bone->active) return;
|
||||
|
||||
if (time < frames[0]) {
|
||||
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) bone->inherit = bone->data->inherit;
|
||||
return;
|
||||
}
|
||||
int idx = search2(self->super.frames, time, 2) + 1;
|
||||
bone->inherit = (spInherit) frames[idx];
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(alpha);
|
||||
UNUSED(direction);
|
||||
}
|
||||
|
||||
void _spInheritTimeline_dispose(spTimeline *timeline) {
|
||||
// no-op, spTimeline_dispose disposes frames.
|
||||
UNUSED(timeline);
|
||||
}
|
||||
|
||||
spInheritTimeline *spInheritTimeline_create(int framesCount, int boneIndex) {
|
||||
spInheritTimeline *self = NEW(spInheritTimeline);
|
||||
spPropertyId ids[1];
|
||||
ids[0] = (spPropertyId) SP_PROPERTY_INHERIT << 32;
|
||||
_spTimeline_init(SUPER(self), framesCount, 2, ids, 1, SP_TIMELINE_INHERIT, _spInheritTimeline_dispose,
|
||||
_spInheritTimeline_apply, 0);
|
||||
|
||||
self->boneIndex = boneIndex;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void spInheritTimeline_setFrame(spDrawOrderTimeline *self, int frame, float time, spInherit inherit) {
|
||||
frame *= 2;
|
||||
self->super.frames->items[frame] = time;
|
||||
self->super.frames->items[frame + 1] = inherit;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
|
||||
static const int IKCONSTRAINT_ENTRIES = 6;
|
||||
@ -2515,35 +2464,9 @@ static const int PATHCONSTRAINTPOSITION_VALUE = 1;
|
||||
void _spPathConstraintPositionTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
float position;
|
||||
spPathConstraint *constraint;
|
||||
spPathConstraintPositionTimeline *self = (spPathConstraintPositionTimeline *) timeline;
|
||||
float *frames;
|
||||
|
||||
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||
if (!constraint->active) return;
|
||||
|
||||
frames = self->super.super.frames->items;
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
constraint->position = constraint->data->position;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
constraint->position += (constraint->data->position - constraint->position) * alpha;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
position = spCurveTimeline1_getCurveValue(SUPER(self), time);
|
||||
|
||||
if (blend == SP_MIX_BLEND_SETUP)
|
||||
constraint->position = constraint->data->position + (position - constraint->data->position) * alpha;
|
||||
else
|
||||
constraint->position += (position - constraint->position) * alpha;
|
||||
spPathConstraintPositionTimeline *self = (spPathConstraintPositionTimeline *) timeline;
|
||||
spPathConstraint *constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||
if (constraint->active) constraint->position = spCurveTimeline1_getAbsoluteValue(SUPER(self), time, alpha, blend, constraint->position, constraint->data->position);
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
@ -2577,40 +2500,14 @@ static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
||||
void _spPathConstraintSpacingTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
float spacing;
|
||||
spPathConstraint *constraint;
|
||||
spPathConstraintSpacingTimeline *self = (spPathConstraintSpacingTimeline *) timeline;
|
||||
float *frames;
|
||||
spPathConstraintSpacingTimeline *self = (spPathConstraintSpacingTimeline *) timeline;
|
||||
spPathConstraint *constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||
if (constraint->active) constraint->spacing = spCurveTimeline1_getAbsoluteValue(SUPER(self), time, alpha, blend, constraint->spacing, constraint->data->spacing);
|
||||
|
||||
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||
if (!constraint->active) return;
|
||||
|
||||
frames = self->super.super.frames->items;
|
||||
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
constraint->spacing = constraint->data->spacing;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
constraint->spacing += (constraint->data->spacing - constraint->spacing) * alpha;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
spacing = spCurveTimeline1_getCurveValue(SUPER(self), time);
|
||||
|
||||
if (blend == SP_MIX_BLEND_SETUP)
|
||||
constraint->spacing = constraint->data->spacing + (spacing - constraint->data->spacing) * alpha;
|
||||
else
|
||||
constraint->spacing += (spacing - constraint->spacing) * alpha;
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
}
|
||||
|
||||
spPathConstraintSpacingTimeline *
|
||||
@ -2740,3 +2637,226 @@ void spPathConstraintMixTimeline_setFrame(spPathConstraintMixTimeline *self, int
|
||||
frames[frame + PATHCONSTRAINTMIX_X] = mixX;
|
||||
frames[frame + PATHCONSTRAINTMIX_Y] = mixY;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
int/*bool*/ _spPhysicsConstraintTimeline_global(spPhysicsConstraintData *data, spTimelineType type) {
|
||||
switch(type) {
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA:
|
||||
return data->inertiaGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH:
|
||||
return data->strengthGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING:
|
||||
return data->dampingGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MASS:
|
||||
return data->massGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_WIND:
|
||||
return data->windGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY:
|
||||
return data->gravityGlobal;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MIX:
|
||||
return data->mixGlobal;
|
||||
default:
|
||||
// should never happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void _spPhysicsConstraintTimeline_set(spPhysicsConstraint *constraint, spTimelineType type, float value) {
|
||||
switch(type) {
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA:
|
||||
constraint->inertia = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH:
|
||||
constraint->strength = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING:
|
||||
constraint->damping = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MASS:
|
||||
constraint->massInverse = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_WIND:
|
||||
constraint->wind = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY:
|
||||
constraint->gravity = value;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MIX:
|
||||
constraint->mix = value;
|
||||
break;
|
||||
default:
|
||||
// should never happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float _spPhysicsConstraintTimeline_get(spPhysicsConstraint *constraint, spTimelineType type) {
|
||||
switch(type) {
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA:
|
||||
return constraint->inertia;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH:
|
||||
return constraint->strength;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING:
|
||||
return constraint->damping;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MASS:
|
||||
return constraint->massInverse;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_WIND:
|
||||
return constraint->wind;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY:
|
||||
return constraint->gravity;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MIX:
|
||||
return constraint->mix;
|
||||
default:
|
||||
// should never happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float _spPhysicsConstraintTimeline_setup(spPhysicsConstraint *constraint, spTimelineType type) {
|
||||
switch(type) {
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA:
|
||||
return constraint->data->inertia;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH:
|
||||
return constraint->data->strength;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING:
|
||||
return constraint->data->damping;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MASS:
|
||||
return constraint->data->massInverse;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_WIND:
|
||||
return constraint->data->wind;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY:
|
||||
return constraint->data->gravity;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MIX:
|
||||
return constraint->data->mix;
|
||||
default:
|
||||
// should never happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void _spPhysicsConstraintTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spPhysicsConstraintTimeline *self = SUB_CAST(spPhysicsConstraintTimeline, timeline);
|
||||
spTimelineType type = self->super.super.type;
|
||||
float *frames = self->super.super.frames->items;
|
||||
if (self->physicsConstraintIndex == -1) {
|
||||
float value = time >= frames[0] ? spCurveTimeline1_getCurveValue(SUPER(self), time) : 0;
|
||||
|
||||
spPhysicsConstraint **physicsConstraints = skeleton->physicsConstraints;
|
||||
for (int i = 0; i < skeleton->physicsConstraintsCount; i++) {
|
||||
spPhysicsConstraint *constraint = physicsConstraints[i];
|
||||
if (constraint->active && _spPhysicsConstraintTimeline_global(constraint->data, type))
|
||||
_spPhysicsConstraintTimeline_set(constraint, type,spCurveTimeline1_getAbsoluteValue2(SUPER(self), time, alpha, blend, _spPhysicsConstraintTimeline_get(constraint, type), _spPhysicsConstraintTimeline_setup(constraint, type), value));
|
||||
}
|
||||
} else {
|
||||
spPhysicsConstraint *constraint = skeleton->physicsConstraints[self->physicsConstraintIndex];
|
||||
if (constraint->active) _spPhysicsConstraintTimeline_set(constraint, type, spCurveTimeline1_getAbsoluteValue(SUPER(self), time, alpha, blend, _spPhysicsConstraintTimeline_get(constraint, type), _spPhysicsConstraintTimeline_setup(constraint, type)));
|
||||
}
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(direction);
|
||||
}
|
||||
|
||||
spPhysicsConstraintTimeline *
|
||||
spPhysicsConstraintTimeline_create(int frameCount, int bezierCount, int physicsConstraintIndex, spTimelineType type) {
|
||||
spPhysicsConstraintTimeline *timeline = NEW(spPhysicsConstraintTimeline);
|
||||
spPropertyId ids[1];
|
||||
spPropertyId id;
|
||||
switch(type) {
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_INERTIA:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_INERTIA;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_STRENGTH:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_STRENGTH;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_DAMPING:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_DAMPING;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MASS:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_MASS;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_WIND:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_WIND;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_GRAVITY:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_GRAVITY;
|
||||
break;
|
||||
case SP_TIMELINE_PHYSICSCONSTRAINT_MIX:
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_MIX;
|
||||
break;
|
||||
default:
|
||||
// should never happen
|
||||
id = SP_PROPERTY_PHYSICSCONSTRAINT_INERTIA;
|
||||
}
|
||||
ids[0] = ((spPropertyId) id << 32) | physicsConstraintIndex;
|
||||
_spCurveTimeline_init(SUPER(timeline), frameCount, CURVE1_ENTRIES, bezierCount, ids, 1, type,
|
||||
_spCurveTimeline_dispose, _spPhysicsConstraintTimeline_apply, _spCurveTimeline_setBezier);
|
||||
timeline->physicsConstraintIndex = physicsConstraintIndex;
|
||||
return timeline;
|
||||
}
|
||||
|
||||
void spPhysicsConstraintTimeline_setFrame(spPhysicsConstraintTimeline *self, int frame, float time, float value) {
|
||||
spCurveTimeline1_setFrame(SUPER(self), frame, time, value);
|
||||
}
|
||||
|
||||
/**/
|
||||
void _spPhysicsConstraintResetTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||
spMixDirection direction) {
|
||||
spPhysicsConstraintResetTimeline *self = (spPhysicsConstraintResetTimeline *)timeline;
|
||||
spPhysicsConstraint *constraint = NULL;
|
||||
if (self->physicsConstraintIndex != -1) {
|
||||
constraint = skeleton->physicsConstraints[self->physicsConstraintIndex];
|
||||
if (!constraint->active) return;
|
||||
}
|
||||
|
||||
float *frames = SUPER(self)->frames->items;
|
||||
if (lastTime > time) {// Apply after lastTime for looped animations.
|
||||
_spPhysicsConstraintResetTimeline_apply(SUPER(self), skeleton, lastTime, INT_MAX, NULL, 0, alpha, blend, direction);
|
||||
lastTime = -1;
|
||||
} else if (lastTime >= frames[SUPER(self)->frameCount - 1])// Last time is after last frame.
|
||||
return;
|
||||
if (time < frames[0]) return;
|
||||
|
||||
if (lastTime < frames[0] || time >= frames[search(self->super.frames, lastTime) + 1]) {
|
||||
if (constraint != NULL)
|
||||
spPhysicsConstraint_reset(constraint);
|
||||
else {
|
||||
spPhysicsConstraint **physicsConstraints = skeleton->physicsConstraints;
|
||||
for (int i = 0; i < skeleton->physicsConstraintsCount; i++) {
|
||||
constraint = physicsConstraints[i];
|
||||
if (constraint->active) spPhysicsConstraint_reset(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED(lastTime);
|
||||
UNUSED(firedEvents);
|
||||
UNUSED(eventsCount);
|
||||
UNUSED(alpha);
|
||||
UNUSED(direction);
|
||||
}
|
||||
|
||||
void _spPhysicsConstraintResetTimeline_dispose(spTimeline *timeline) {
|
||||
// no-op, spTimeline_dispose disposes frames.
|
||||
UNUSED(timeline);
|
||||
}
|
||||
|
||||
spPhysicsConstraintResetTimeline *spPhysicsConstraintResetTimeline_create(int framesCount, int physicsConstraintIndex) {
|
||||
spPhysicsConstraintResetTimeline *self = NEW(spPhysicsConstraintResetTimeline);
|
||||
spPropertyId ids[1];
|
||||
ids[0] = (spPropertyId) SP_PROPERTY_PHYSICSCONSTRAINT_RESET << 32;
|
||||
_spTimeline_init(SUPER(self), framesCount, 1, ids, 1, SP_TIMELINE_PHYSICSCONSTRAINT_RESET, _spPhysicsConstraintResetTimeline_dispose,
|
||||
_spPhysicsConstraintResetTimeline_apply, 0);
|
||||
|
||||
self->physicsConstraintIndex = physicsConstraintIndex;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void spPhysicsResetTimeline_setFrame(spPhysicsConstraintResetTimeline *self, int frame, float time) {
|
||||
self->super.frames->items[frame] = time;
|
||||
}
|
||||
|
||||
@ -390,18 +390,19 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
|
||||
if (internal->animationsChanged) _spAnimationState_animationsChanged(self);
|
||||
|
||||
for (i = 0, n = self->tracksCount; i < n; i++) {
|
||||
float mix;
|
||||
float alpha;
|
||||
current = self->tracks[i];
|
||||
if (!current || current->delay > 0) continue;
|
||||
applied = -1;
|
||||
blend = i == 0 ? SP_MIX_BLEND_FIRST : current->mixBlend;
|
||||
|
||||
/* Apply mixing from entries first. */
|
||||
mix = current->alpha;
|
||||
alpha = current->alpha;
|
||||
if (current->mixingFrom)
|
||||
mix *= _spAnimationState_applyMixingFrom(self, current, skeleton, blend);
|
||||
alpha *= _spAnimationState_applyMixingFrom(self, current, skeleton, blend);
|
||||
else if (current->trackTime >= current->trackEnd && current->next == 0)
|
||||
mix = 0;
|
||||
alpha = 0;
|
||||
int/*bool*/ attachments = alpha >= current->alphaAttachmentThreshold;
|
||||
|
||||
/* Apply current entry. */
|
||||
animationLast = current->animationLast;
|
||||
@ -414,14 +415,14 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
|
||||
applyEvents = NULL;
|
||||
}
|
||||
timelines = current->animation->timelines->items;
|
||||
if ((i == 0 && mix == 1) || blend == SP_MIX_BLEND_ADD) {
|
||||
if ((i == 0 && alpha == 1) || blend == SP_MIX_BLEND_ADD) {
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, blend, -1);
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, blend, attachments);
|
||||
} else {
|
||||
spTimeline_apply(timelines[ii], skeleton, animationLast, applyTime, applyEvents,
|
||||
&internal->eventsCount, mix, blend, SP_MIX_DIRECTION_IN);
|
||||
&internal->eventsCount, alpha, blend, SP_MIX_DIRECTION_IN);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -436,13 +437,13 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
|
||||
timeline = timelines[ii];
|
||||
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
||||
if (!shortestRotation && timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, mix, timelineBlend,
|
||||
timelinesRotation, ii << 1, firstFrame);
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, alpha, timelineBlend,
|
||||
timelinesRotation, ii << 1, firstFrame);
|
||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, -1);
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, attachments);
|
||||
else
|
||||
spTimeline_apply(timeline, skeleton, animationLast, applyTime, applyEvents, &internal->eventsCount,
|
||||
mix, timelineBlend, SP_MIX_DIRECTION_IN);
|
||||
alpha, timelineBlend, SP_MIX_DIRECTION_IN);
|
||||
}
|
||||
}
|
||||
_spAnimationState_queueEvents(self, current, animationTime);
|
||||
@ -500,8 +501,8 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
|
||||
if (blend != SP_MIX_BLEND_FIRST) blend = from->mixBlend;
|
||||
}
|
||||
|
||||
attachments = mix < from->attachmentThreshold;
|
||||
drawOrder = mix < from->drawOrderThreshold;
|
||||
attachments = mix < from->mixAttachmentThreshold;
|
||||
drawOrder = mix < from->mixDrawOrderThreshold;
|
||||
timelineCount = from->animation->timelines->size;
|
||||
timelines = from->animation->timelines->items;
|
||||
alphaHold = from->alpha * to->interruptAlpha;
|
||||
@ -566,7 +567,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
|
||||
timelinesRotation, i << 1, firstFrame);
|
||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend,
|
||||
attachments);
|
||||
attachments && alpha >= from->alphaAttachmentThreshold);
|
||||
else {
|
||||
if (drawOrder && timeline->type == SP_TIMELINE_DRAWORDER &&
|
||||
timelineBlend == SP_MIX_BLEND_SETUP)
|
||||
@ -664,8 +665,8 @@ void _spAnimationState_applyRotateTimeline(spAnimationState *self, spTimeline *t
|
||||
|
||||
/* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */
|
||||
diff = r2 - r1;
|
||||
diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360;
|
||||
if (diff == 0) {
|
||||
diff -= CEIL(diff / 360 - 0.5) * 360;
|
||||
if (diff == 0) {
|
||||
total = timelinesRotation[i];
|
||||
} else {
|
||||
float lastTotal, lastDiff, loops;
|
||||
@ -714,10 +715,16 @@ void _spAnimationState_queueEvents(spAnimationState *self, spTrackEntry *entry,
|
||||
}
|
||||
|
||||
/* Queue complete if completed a loop iteration or the animation. */
|
||||
if (entry->loop)
|
||||
complete = duration == 0 || (trackLastWrapped > FMOD(entry->trackTime, duration));
|
||||
else
|
||||
complete = (animationTime >= animationEnd && entry->animationLast < animationEnd);
|
||||
if (entry->loop) {
|
||||
if (duration == 0)
|
||||
complete = -1;
|
||||
else {
|
||||
int cycles = (int) (entry->trackTime / duration);
|
||||
complete = cycles > 0 && cycles > (int) (entry->trackLast / duration);
|
||||
}
|
||||
} else {
|
||||
complete = (animationTime >= animationEnd && entry->animationLast < animationEnd);
|
||||
}
|
||||
if (complete) _spEventQueue_complete(internal->queue, entry);
|
||||
|
||||
/* Queue events after complete. */
|
||||
@ -910,8 +917,9 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation
|
||||
entry->next = 0;
|
||||
|
||||
entry->eventThreshold = 0;
|
||||
entry->attachmentThreshold = 0;
|
||||
entry->drawOrderThreshold = 0;
|
||||
entry->mixAttachmentThreshold = 0;
|
||||
entry->alphaAttachmentThreshold = 0;
|
||||
entry->mixDrawOrderThreshold = 0;
|
||||
|
||||
entry->animationStart = 0;
|
||||
entry->animationEnd = animation->duration;
|
||||
@ -1051,6 +1059,16 @@ float spTrackEntry_getTrackComplete(spTrackEntry *entry) {
|
||||
return entry->trackTime; /* Next update. */
|
||||
}
|
||||
|
||||
void spTrackEntry_setMixDuration(spTrackEntry *entry, float mixDuration, float delay) {
|
||||
entry->mixDuration = mixDuration;
|
||||
if (entry->previous && delay <= 0) delay += spTrackEntry_getTrackComplete(entry) - mixDuration;
|
||||
entry->delay = delay;
|
||||
}
|
||||
|
||||
int spTrackEntry_wasApplied(spTrackEntry *entry) {
|
||||
return entry->nextTrackLast != -1;
|
||||
}
|
||||
|
||||
void _spTrackEntry_computeHold(spTrackEntry *entry, spAnimationState *state) {
|
||||
spTrackEntry *to;
|
||||
spTimeline **timelines;
|
||||
|
||||
@ -209,6 +209,13 @@ void spDebug_printTimeline(spTimeline *timeline) {
|
||||
spSequenceTimeline *t = (spSequenceTimeline *) timeline;
|
||||
_spDebug_printTimelineBase(&t->super);
|
||||
}
|
||||
case SP_TIMELINE_INHERIT: {
|
||||
spInheritTimeline *t = (spInheritTimeline *) timeline;
|
||||
_spDebug_printTimelineBase(&t->super);
|
||||
}
|
||||
default: {
|
||||
_spDebug_printTimelineBase(timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -71,6 +71,14 @@ void spIkConstraint_update(spIkConstraint *self) {
|
||||
}
|
||||
}
|
||||
|
||||
void spIkConstraint_setToSetupPose(spIkConstraint *self) {
|
||||
self->bendDirection = self->data->bendDirection;
|
||||
self->compress = self->data->compress;
|
||||
self->stretch = self->data->stretch;
|
||||
self->softness = self->data->softness;
|
||||
self->mix = self->data->mix;
|
||||
}
|
||||
|
||||
void spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch,
|
||||
int /*boolean*/ uniform, float alpha) {
|
||||
spBone *p = bone->parent;
|
||||
|
||||
@ -33,11 +33,11 @@
|
||||
spIkConstraintData *spIkConstraintData_create(const char *name) {
|
||||
spIkConstraintData *self = NEW(spIkConstraintData);
|
||||
MALLOC_STR(self->name, name);
|
||||
self->bendDirection = 1;
|
||||
self->bendDirection = 0;
|
||||
self->compress = 0;
|
||||
self->stretch = 0;
|
||||
self->uniform = 0;
|
||||
self->mix = 1;
|
||||
self->mix = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@ -117,13 +117,9 @@ void spPathConstraint_update(spPathConstraint *self) {
|
||||
for (i = 0, n = spacesCount - 1; i < n; i++) {
|
||||
spBone *bone = bones[i];
|
||||
setupLength = bone->data->length;
|
||||
if (setupLength < EPSILON)
|
||||
lengths[i] = 0;
|
||||
else {
|
||||
x = setupLength * bone->a;
|
||||
y = setupLength * bone->c;
|
||||
lengths[i] = SQRT(x * x + y * y);
|
||||
}
|
||||
x = setupLength * bone->a;
|
||||
y = setupLength * bone->c;
|
||||
lengths[i] = SQRT(x * x + y * y);
|
||||
}
|
||||
}
|
||||
for (i = 1, n = spacesCount; i < n; i++) spaces[i] = spacing;
|
||||
@ -225,6 +221,15 @@ void spPathConstraint_update(spPathConstraint *self) {
|
||||
}
|
||||
}
|
||||
|
||||
void spPathConstraint_setToSetupPose(spPathConstraint *self) {
|
||||
spPathConstraintData *data = self->data;
|
||||
self->position = data->position;
|
||||
self->spacing = data->spacing;
|
||||
self->mixRotate = data->mixRotate;
|
||||
self->mixX = data->mixX;
|
||||
self->mixY = data->mixY;
|
||||
}
|
||||
|
||||
static void _addBeforePosition(float p, float *temp, int i, float *out, int o) {
|
||||
float x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = ATAN2(dy, dx);
|
||||
out[o] = x1 + p * COS(r);
|
||||
|
||||
@ -58,10 +58,8 @@ void spPointAttachment_computeWorldPosition(spPointAttachment *self, spBone *bon
|
||||
}
|
||||
|
||||
float spPointAttachment_computeWorldRotation(spPointAttachment *self, spBone *bone) {
|
||||
float cosine, sine, x, y;
|
||||
cosine = COS_DEG(self->rotation);
|
||||
sine = SIN_DEG(self->rotation);
|
||||
x = cosine * bone->a + sine * bone->b;
|
||||
y = cosine * bone->c + sine * bone->d;
|
||||
return ATAN2(y, x) * RAD_DEG;
|
||||
float r = self->rotation * DEG_RAD, cosine = COS(r), sine = SIN(r);
|
||||
float x = cosine * bone->a + sine * bone->b;
|
||||
float y = cosine * bone->c + sine * bone->d;
|
||||
return ATAN2DEG(y, x);
|
||||
}
|
||||
|
||||
@ -60,6 +60,11 @@ spSkeleton *spSkeleton_create(spSkeletonData *data) {
|
||||
_spSkeleton *internal = NEW(_spSkeleton);
|
||||
spSkeleton *self = SUPER(internal);
|
||||
self->data = data;
|
||||
self->skin = NULL;
|
||||
spColor_setFromFloats(&self->color, 1, 1, 1, 1);
|
||||
self->scaleX = 1;
|
||||
self->scaleY = 1;
|
||||
self->time = 0;
|
||||
|
||||
self->bonesCount = self->data->bonesCount;
|
||||
self->bones = MALLOC(spBone *, self->bonesCount);
|
||||
@ -116,6 +121,12 @@ spSkeleton *spSkeleton_create(spSkeletonData *data) {
|
||||
for (i = 0; i < self->data->pathConstraintsCount; i++)
|
||||
self->pathConstraints[i] = spPathConstraint_create(self->data->pathConstraints[i], self);
|
||||
|
||||
self->physicsConstraintsCount = data->physicsConstraintsCount;
|
||||
self->physicsConstraints = MALLOC(spPhysicsConstraint *, self->physicsConstraintsCount);
|
||||
for (i = 0; i < self->data->physicsConstraintsCount; i++)
|
||||
self->physicsConstraints[i] = spPhysicsConstraint_create(self->data->physicsConstraints[i], self);
|
||||
|
||||
|
||||
spColor_setFromFloats(&self->color, 1, 1, 1, 1);
|
||||
|
||||
self->scaleX = 1;
|
||||
@ -156,6 +167,10 @@ void spSkeleton_dispose(spSkeleton *self) {
|
||||
spPathConstraint_dispose(self->pathConstraints[i]);
|
||||
FREE(self->pathConstraints);
|
||||
|
||||
for (i = 0; i < self->physicsConstraintsCount; i++)
|
||||
spPhysicsConstraint_dispose(self->physicsConstraints[i]);
|
||||
FREE(self->physicsConstraints);
|
||||
|
||||
FREE(self->drawOrder);
|
||||
FREE(self);
|
||||
}
|
||||
@ -324,17 +339,35 @@ static void _sortTransformConstraint(_spSkeleton *const internal, spTransformCon
|
||||
constrained[i]->sorted = 1;
|
||||
}
|
||||
|
||||
static void _sortPhysicsConstraint(_spSkeleton *const internal, spPhysicsConstraint *constraint) {
|
||||
spBone *bone = constraint->bone;
|
||||
constraint->active = constraint->bone->active && (!constraint->data->skinRequired || (internal->super.skin != 0 &&
|
||||
spPhysicsConstraintDataArray_contains(
|
||||
internal->super.skin->physicsConstraints,
|
||||
constraint->data)));
|
||||
if (!constraint->active)
|
||||
return;
|
||||
|
||||
_sortBone(internal, bone);
|
||||
_addToUpdateCache(internal, SP_UPDATE_PHYSICS_CONSTRAINT, constraint);
|
||||
|
||||
_sortReset(bone->children, bone->childrenCount);
|
||||
bone->sorted = -1;
|
||||
}
|
||||
|
||||
void spSkeleton_updateCache(spSkeleton *self) {
|
||||
int i, ii;
|
||||
spBone **bones;
|
||||
spIkConstraint **ikConstraints;
|
||||
spPathConstraint **pathConstraints;
|
||||
spTransformConstraint **transformConstraints;
|
||||
int ikCount, transformCount, pathCount, constraintCount;
|
||||
spPhysicsConstraint **physicsConstraints;
|
||||
int ikCount, transformCount, pathCount, physicsCount, constraintCount;
|
||||
_spSkeleton *internal = SUB_CAST(_spSkeleton, self);
|
||||
|
||||
internal->updateCacheCapacity =
|
||||
self->bonesCount + self->ikConstraintsCount + self->transformConstraintsCount + self->pathConstraintsCount;
|
||||
self->bonesCount + self->ikConstraintsCount + self->transformConstraintsCount + self->pathConstraintsCount +
|
||||
self->physicsConstraintsCount;
|
||||
FREE(internal->updateCache);
|
||||
internal->updateCache = MALLOC(_spUpdate, internal->updateCacheCapacity);
|
||||
internal->updateCacheCount = 0;
|
||||
@ -362,10 +395,12 @@ void spSkeleton_updateCache(spSkeleton *self) {
|
||||
ikConstraints = self->ikConstraints;
|
||||
transformConstraints = self->transformConstraints;
|
||||
pathConstraints = self->pathConstraints;
|
||||
physicsConstraints = self->physicsConstraints;
|
||||
ikCount = self->ikConstraintsCount;
|
||||
transformCount = self->transformConstraintsCount;
|
||||
pathCount = self->pathConstraintsCount;
|
||||
constraintCount = ikCount + transformCount + pathCount;
|
||||
physicsCount = self->physicsConstraintsCount;
|
||||
constraintCount = ikCount + transformCount + pathCount + physicsCount;
|
||||
|
||||
i = 0;
|
||||
continue_outer:
|
||||
@ -396,6 +431,15 @@ continue_outer:
|
||||
goto continue_outer;
|
||||
}
|
||||
}
|
||||
|
||||
for (ii = 0; ii < physicsCount; ii++) {
|
||||
spPhysicsConstraint *physicsConstraint = physicsConstraints[ii];
|
||||
if (physicsConstraint->data->order == i) {
|
||||
_sortPhysicsConstraint(internal, physicsConstraint);
|
||||
i++;
|
||||
goto continue_outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < self->bonesCount; ++i)
|
||||
@ -495,33 +539,19 @@ void spSkeleton_setBonesToSetupPose(const spSkeleton *self) {
|
||||
spBone_setToSetupPose(self->bones[i]);
|
||||
|
||||
for (i = 0; i < self->ikConstraintsCount; ++i) {
|
||||
spIkConstraint *ikConstraint = self->ikConstraints[i];
|
||||
ikConstraint->bendDirection = ikConstraint->data->bendDirection;
|
||||
ikConstraint->compress = ikConstraint->data->compress;
|
||||
ikConstraint->stretch = ikConstraint->data->stretch;
|
||||
ikConstraint->softness = ikConstraint->data->softness;
|
||||
ikConstraint->mix = ikConstraint->data->mix;
|
||||
spIkConstraint_setToSetupPose(self->ikConstraints[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < self->transformConstraintsCount; ++i) {
|
||||
spTransformConstraint *constraint = self->transformConstraints[i];
|
||||
spTransformConstraintData *data = constraint->data;
|
||||
constraint->mixRotate = data->mixRotate;
|
||||
constraint->mixX = data->mixX;
|
||||
constraint->mixY = data->mixY;
|
||||
constraint->mixScaleX = data->mixScaleX;
|
||||
constraint->mixScaleY = data->mixScaleY;
|
||||
constraint->mixShearY = data->mixShearY;
|
||||
spTransformConstraint_setToSetupPose(self->transformConstraints[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < self->pathConstraintsCount; ++i) {
|
||||
spPathConstraint *constraint = self->pathConstraints[i];
|
||||
spPathConstraintData *data = constraint->data;
|
||||
constraint->position = data->position;
|
||||
constraint->spacing = data->spacing;
|
||||
constraint->mixRotate = data->mixRotate;
|
||||
constraint->mixX = data->mixX;
|
||||
constraint->mixY = data->mixY;
|
||||
spPathConstraint_setToSetupPose(self->pathConstraints[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < self->physicsConstraintsCount; ++i) {
|
||||
spPhysicsConstraint_setToSetupPose(self->physicsConstraints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,3 +675,15 @@ spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, co
|
||||
if (strcmp(self->physicsConstraints[i]->data->name, constraintName) == 0) return self->physicsConstraints[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spSkeleton_physicsTranslate(spSkeleton *self, float x, float y) {
|
||||
for (int i = 0; i < (int) self->physicsConstraintsCount; i++) {
|
||||
spPhysicsConstraint_translate(self->physicsConstraints[i], x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void spSkeleton_physicsRotate(spSkeleton *self, float x, float y, float degrees) {
|
||||
for (int i = 0; i < (int) self->physicsConstraintsCount; i++) {
|
||||
spPhysicsConstraint_rotate(self->physicsConstraints[i], x, y, degrees);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ _SP_ARRAY_IMPLEMENT_TYPE(spTransformConstraintDataArray, spTransformConstraintDa
|
||||
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spPathConstraintDataArray, spPathConstraintData *)
|
||||
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spPhysicsConstraintDataArray, spPhysicsConstraintData *)
|
||||
|
||||
_Entry *_Entry_create(int slotIndex, const char *name, spAttachment *attachment) {
|
||||
_Entry *self = NEW(_Entry);
|
||||
self->slotIndex = slotIndex;
|
||||
@ -72,6 +74,7 @@ spSkin *spSkin_create(const char *name) {
|
||||
self->ikConstraints = spIkConstraintDataArray_create(4);
|
||||
self->transformConstraints = spTransformConstraintDataArray_create(4);
|
||||
self->pathConstraints = spPathConstraintDataArray_create(4);
|
||||
self->physicsConstraints = spPhysicsConstraintDataArray_create(4);
|
||||
spColor_setFromFloats(&self->color, 0.99607843f, 0.61960787f, 0.30980393f, 1);
|
||||
return self;
|
||||
}
|
||||
@ -104,6 +107,7 @@ void spSkin_dispose(spSkin *self) {
|
||||
spIkConstraintDataArray_dispose(self->ikConstraints);
|
||||
spTransformConstraintDataArray_dispose(self->transformConstraints);
|
||||
spPathConstraintDataArray_dispose(self->pathConstraints);
|
||||
spPhysicsConstraintDataArray_dispose(self->physicsConstraints);
|
||||
FREE(self->name);
|
||||
FREE(self);
|
||||
}
|
||||
@ -198,6 +202,11 @@ void spSkin_addSkin(spSkin *self, const spSkin *other) {
|
||||
spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < other->physicsConstraints->size; i++) {
|
||||
if (!spPhysicsConstraintDataArray_contains(self->physicsConstraints, other->physicsConstraints->items[i]))
|
||||
spPhysicsConstraintDataArray_add(self->physicsConstraints, other->physicsConstraints->items[i]);
|
||||
}
|
||||
|
||||
entry = spSkin_getAttachments(other);
|
||||
while (entry) {
|
||||
spSkin_setAttachment(self, entry->slotIndex, entry->name, entry->attachment);
|
||||
@ -229,6 +238,11 @@ void spSkin_copySkin(spSkin *self, const spSkin *other) {
|
||||
spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < other->physicsConstraints->size; i++) {
|
||||
if (!spPhysicsConstraintDataArray_contains(self->physicsConstraints, other->physicsConstraints->items[i]))
|
||||
spPhysicsConstraintDataArray_add(self->physicsConstraints, other->physicsConstraints->items[i]);
|
||||
}
|
||||
|
||||
entry = spSkin_getAttachments(other);
|
||||
while (entry) {
|
||||
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
|
||||
@ -279,4 +293,5 @@ void spSkin_clear(spSkin *self) {
|
||||
spIkConstraintDataArray_clear(self->ikConstraints);
|
||||
spTransformConstraintDataArray_clear(self->transformConstraints);
|
||||
spPathConstraintDataArray_clear(self->pathConstraints);
|
||||
spPhysicsConstraintDataArray_clear(self->physicsConstraints);
|
||||
}
|
||||
|
||||
@ -193,8 +193,8 @@ void _spTransformConstraint_applyAbsoluteLocal(spTransformConstraint *self) {
|
||||
rotation = bone->arotation;
|
||||
if (mixRotate != 0) {
|
||||
r = target->arotation - rotation + self->data->offsetRotation;
|
||||
r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360;
|
||||
rotation += r * mixRotate;
|
||||
r -= CEIL(r / 360 - 0.5) * 360;
|
||||
rotation += r * mixRotate;
|
||||
}
|
||||
|
||||
x = bone->ax, y = bone->ay;
|
||||
@ -210,8 +210,8 @@ void _spTransformConstraint_applyAbsoluteLocal(spTransformConstraint *self) {
|
||||
shearY = bone->ashearY;
|
||||
if (mixShearY != 0) {
|
||||
r = target->ashearY - shearY + self->data->offsetShearY;
|
||||
r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360;
|
||||
shearY += r * mixShearY;
|
||||
r -= CEIL(r / 360 - 0.5) * 360;
|
||||
shearY += r * mixShearY;
|
||||
}
|
||||
|
||||
spBone_updateWorldTransformWith(bone, x, y, rotation, scaleX, scaleY, bone->ashearX, shearY);
|
||||
@ -257,3 +257,13 @@ void spTransformConstraint_update(spTransformConstraint *self) {
|
||||
_spTransformConstraint_applyAbsoluteWorld(self);
|
||||
}
|
||||
}
|
||||
|
||||
void spTransformConstraint_setToSetupPose(spTransformConstraint *self) {
|
||||
spTransformConstraintData *data = self->data;
|
||||
self->mixRotate = data->mixRotate;
|
||||
self->mixX = data->mixX;
|
||||
self->mixY = data->mixY;
|
||||
self->mixScaleX = data->mixScaleX;
|
||||
self->mixScaleY = data->mixScaleY;
|
||||
self->mixShearY = data->mixShearY;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user