mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +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_TRANSLATE,
|
||||||
SP_TIMELINE_DEFORM,
|
SP_TIMELINE_DEFORM,
|
||||||
SP_TIMELINE_SEQUENCE,
|
SP_TIMELINE_SEQUENCE,
|
||||||
|
SP_TIMELINE_INHERIT,
|
||||||
SP_TIMELINE_IKCONSTRAINT,
|
SP_TIMELINE_IKCONSTRAINT,
|
||||||
SP_TIMELINE_PATHCONSTRAINTMIX,
|
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_RGB2,
|
||||||
SP_TIMELINE_RGBA2,
|
SP_TIMELINE_RGBA2,
|
||||||
SP_TIMELINE_RGBA,
|
SP_TIMELINE_RGBA,
|
||||||
@ -122,19 +131,28 @@ typedef enum {
|
|||||||
SP_PROPERTY_SCALEY = 1 << 4,
|
SP_PROPERTY_SCALEY = 1 << 4,
|
||||||
SP_PROPERTY_SHEARX = 1 << 5,
|
SP_PROPERTY_SHEARX = 1 << 5,
|
||||||
SP_PROPERTY_SHEARY = 1 << 6,
|
SP_PROPERTY_SHEARY = 1 << 6,
|
||||||
SP_PROPERTY_RGB = 1 << 7,
|
SP_PROPERTY_INHERIT = 1 << 7,
|
||||||
SP_PROPERTY_ALPHA = 1 << 8,
|
SP_PROPERTY_RGB = 1 << 8,
|
||||||
SP_PROPERTY_RGB2 = 1 << 9,
|
SP_PROPERTY_ALPHA = 1 << 9,
|
||||||
SP_PROPERTY_ATTACHMENT = 1 << 10,
|
SP_PROPERTY_RGB2 = 1 << 10,
|
||||||
SP_PROPERTY_DEFORM = 1 << 11,
|
SP_PROPERTY_ATTACHMENT = 1 << 11,
|
||||||
SP_PROPERTY_EVENT = 1 << 12,
|
SP_PROPERTY_DEFORM = 1 << 12,
|
||||||
SP_PROPERTY_DRAWORDER = 1 << 13,
|
SP_PROPERTY_EVENT = 1 << 13,
|
||||||
SP_PROPERTY_IKCONSTRAINT = 1 << 14,
|
SP_PROPERTY_DRAWORDER = 1 << 14,
|
||||||
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 15,
|
SP_PROPERTY_IKCONSTRAINT = 1 << 15,
|
||||||
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 16,
|
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 16,
|
||||||
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 17,
|
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 17,
|
||||||
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18,
|
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 18,
|
||||||
SP_PROPERTY_SEQUENCE = 1 << 19
|
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;
|
} spProperty;
|
||||||
|
|
||||||
#define SP_MAX_PROPERTY_IDS 3
|
#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_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;
|
typedef struct spCurveTimeline spCurveTimeline2;
|
||||||
|
|
||||||
SP_API void spCurveTimeline2_setFrame(spCurveTimeline1 *self, int frame, float time, float value1, float value2);
|
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);
|
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 {
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -69,7 +69,7 @@ struct spTrackEntry {
|
|||||||
int /*boolean*/ holdPrevious;
|
int /*boolean*/ holdPrevious;
|
||||||
int /*boolean*/ reverse;
|
int /*boolean*/ reverse;
|
||||||
int /*boolean*/ shortestRotation;
|
int /*boolean*/ shortestRotation;
|
||||||
float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
float eventThreshold, mixAttachmentThreshold, alphaAttachmentThreshold, mixDrawOrderThreshold;
|
||||||
float animationStart, animationEnd, animationLast, nextAnimationLast;
|
float animationStart, animationEnd, animationLast, nextAnimationLast;
|
||||||
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
|
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
|
||||||
float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha;
|
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 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);
|
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*/
|
/** 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_update(spIkConstraint *self);
|
||||||
|
|
||||||
|
SP_API void spIkConstraint_setToSetupPose(spIkConstraint *self);
|
||||||
|
|
||||||
SP_API void
|
SP_API void
|
||||||
spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch,
|
spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch,
|
||||||
int /*boolean*/ uniform, float alpha);
|
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_update(spPathConstraint *self);
|
||||||
|
|
||||||
|
SP_API void spPathConstraint_setToSetupPose(spPathConstraint *self);
|
||||||
|
|
||||||
SP_API float *spPathConstraint_computeWorldPositions(spPathConstraint *self, spPathAttachment *path, int spacesCount,
|
SP_API float *spPathConstraint_computeWorldPositions(spPathConstraint *self, spPathAttachment *path, int spacesCount,
|
||||||
int/*bool*/ tangents);
|
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. */
|
/* Returns 0 if the physics constraint was not found. */
|
||||||
SP_API spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, const char *constraintName);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
#include <spine/IkConstraintData.h>
|
#include <spine/IkConstraintData.h>
|
||||||
#include <spine/TransformConstraintData.h>
|
#include <spine/TransformConstraintData.h>
|
||||||
#include <spine/PathConstraintData.h>
|
#include <spine/PathConstraintData.h>
|
||||||
|
#include <spine/PhysicsConstraintData.h>
|
||||||
#include <spine/Array.h>
|
#include <spine/Array.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -54,6 +55,8 @@ _SP_ARRAY_DECLARE_TYPE(spTransformConstraintDataArray, spTransformConstraintData
|
|||||||
|
|
||||||
_SP_ARRAY_DECLARE_TYPE(spPathConstraintDataArray, spPathConstraintData*)
|
_SP_ARRAY_DECLARE_TYPE(spPathConstraintDataArray, spPathConstraintData*)
|
||||||
|
|
||||||
|
_SP_ARRAY_DECLARE_TYPE(spPhysicsConstraintDataArray, spPhysicsConstraintData*)
|
||||||
|
|
||||||
typedef struct spSkin {
|
typedef struct spSkin {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
@ -61,6 +64,7 @@ typedef struct spSkin {
|
|||||||
spIkConstraintDataArray *ikConstraints;
|
spIkConstraintDataArray *ikConstraints;
|
||||||
spTransformConstraintDataArray *transformConstraints;
|
spTransformConstraintDataArray *transformConstraints;
|
||||||
spPathConstraintDataArray *pathConstraints;
|
spPathConstraintDataArray *pathConstraints;
|
||||||
|
spPhysicsConstraintDataArray *physicsConstraints;
|
||||||
spColor color;
|
spColor color;
|
||||||
} spSkin;
|
} spSkin;
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,8 @@ SP_API void spTransformConstraint_dispose(spTransformConstraint *self);
|
|||||||
|
|
||||||
SP_API void spTransformConstraint_update(spTransformConstraint *self);
|
SP_API void spTransformConstraint_update(spTransformConstraint *self);
|
||||||
|
|
||||||
|
SP_API void spTransformConstraint_setToSetupPose(spTransformConstraint *self);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -298,6 +298,110 @@ float spCurveTimeline1_getCurveValue(spCurveTimeline1 *self, float time) {
|
|||||||
return _spCurveTimeline_getBezierValue(self, time, i, CURVE1_VALUE, curveType - CURVE_BEZIER);
|
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_ENTRIES 3
|
||||||
#define CURVE2_VALUE1 1
|
#define CURVE2_VALUE1 1
|
||||||
#define CURVE2_VALUE2 2
|
#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,
|
void _spRotateTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents,
|
||||||
int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
||||||
spBone *bone;
|
|
||||||
float r;
|
|
||||||
spRotateTimeline *self = SUB_CAST(spRotateTimeline, timeline);
|
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];
|
UNUSED(lastTime);
|
||||||
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(firedEvents);
|
UNUSED(firedEvents);
|
||||||
UNUSED(eventsCount);
|
UNUSED(eventsCount);
|
||||||
UNUSED(direction);
|
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,
|
void _spScaleXTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
spBone *bone;
|
|
||||||
float x;
|
|
||||||
|
|
||||||
spScaleXTimeline *self = SUB_CAST(spScaleXTimeline, timeline);
|
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) bone->scaleX = spCurveTimeline1_getScaleValue(SUPER(self), time, alpha, blend, direction, bone->scaleX, bone->data->scaleX);
|
||||||
if (!bone->active) return;
|
|
||||||
|
|
||||||
if (time < frames[0]) {
|
UNUSED(lastTime);
|
||||||
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(firedEvents);
|
UNUSED(firedEvents);
|
||||||
UNUSED(eventsCount);
|
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,
|
void _spScaleYTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
spBone *bone;
|
|
||||||
float y;
|
|
||||||
|
|
||||||
spScaleYTimeline *self = SUB_CAST(spScaleYTimeline, timeline);
|
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) bone->scaleY = spCurveTimeline1_getScaleValue(SUPER(self), time, alpha, blend, direction, bone->scaleX, bone->data->scaleY);
|
||||||
if (!bone->active) return;
|
|
||||||
|
|
||||||
if (time < frames[0]) {
|
UNUSED(lastTime);
|
||||||
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(firedEvents);
|
UNUSED(firedEvents);
|
||||||
UNUSED(eventsCount);
|
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,
|
void _spShearXTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
spBone *bone;
|
|
||||||
float x;
|
|
||||||
|
|
||||||
spShearXTimeline *self = SUB_CAST(spShearXTimeline, timeline);
|
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) bone->shearX = spCurveTimeline1_getRelativeValue(SUPER(self), time, alpha, blend, bone->shearX, bone->data->shearX);
|
||||||
if (!bone->active) return;
|
|
||||||
|
|
||||||
if (time < frames[0]) {
|
UNUSED(lastTime);
|
||||||
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(firedEvents);
|
UNUSED(firedEvents);
|
||||||
UNUSED(eventsCount);
|
UNUSED(eventsCount);
|
||||||
UNUSED(direction);
|
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,
|
void _spShearYTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
spBone *bone;
|
|
||||||
float y;
|
|
||||||
|
|
||||||
spShearYTimeline *self = SUB_CAST(spShearYTimeline, timeline);
|
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) bone->shearY = spCurveTimeline1_getRelativeValue(SUPER(self), time, alpha, blend, bone->shearY, bone->data->shearY);
|
||||||
if (!bone->active) return;
|
|
||||||
|
|
||||||
if (time < frames[0]) {
|
UNUSED(lastTime);
|
||||||
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(firedEvents);
|
UNUSED(firedEvents);
|
||||||
UNUSED(eventsCount);
|
UNUSED(eventsCount);
|
||||||
UNUSED(direction);
|
UNUSED(direction);
|
||||||
@ -2053,7 +1955,7 @@ void _spSequenceTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float
|
|||||||
count = sequence->regions->size;
|
count = sequence->regions->size;
|
||||||
mode = modeAndIndex & 0xf;
|
mode = modeAndIndex & 0xf;
|
||||||
if (mode != SP_SEQUENCE_MODE_HOLD) {
|
if (mode != SP_SEQUENCE_MODE_HOLD) {
|
||||||
index += (int) (((time - before) / delay + 0.00001));
|
index += (int) (((time - before) / delay + 0.0001));
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SP_SEQUENCE_MODE_ONCE:
|
case SP_SEQUENCE_MODE_ONCE:
|
||||||
index = MIN(count - 1, index);
|
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;
|
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,
|
void _spPathConstraintPositionTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
float position;
|
spPathConstraintPositionTimeline *self = (spPathConstraintPositionTimeline *) timeline;
|
||||||
spPathConstraint *constraint;
|
spPathConstraint *constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||||
spPathConstraintPositionTimeline *self = (spPathConstraintPositionTimeline *) timeline;
|
if (constraint->active) constraint->position = spCurveTimeline1_getAbsoluteValue(SUPER(self), time, alpha, blend, constraint->position, constraint->data->position);
|
||||||
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;
|
|
||||||
|
|
||||||
UNUSED(lastTime);
|
UNUSED(lastTime);
|
||||||
UNUSED(firedEvents);
|
UNUSED(firedEvents);
|
||||||
@ -2577,40 +2500,14 @@ static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
|||||||
void _spPathConstraintSpacingTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
void _spPathConstraintSpacingTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time,
|
||||||
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend,
|
||||||
spMixDirection direction) {
|
spMixDirection direction) {
|
||||||
float spacing;
|
spPathConstraintSpacingTimeline *self = (spPathConstraintSpacingTimeline *) timeline;
|
||||||
spPathConstraint *constraint;
|
spPathConstraint *constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
||||||
spPathConstraintSpacingTimeline *self = (spPathConstraintSpacingTimeline *) timeline;
|
if (constraint->active) constraint->spacing = spCurveTimeline1_getAbsoluteValue(SUPER(self), time, alpha, blend, constraint->spacing, constraint->data->spacing);
|
||||||
float *frames;
|
|
||||||
|
|
||||||
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
|
UNUSED(lastTime);
|
||||||
if (!constraint->active) return;
|
UNUSED(firedEvents);
|
||||||
|
UNUSED(eventsCount);
|
||||||
frames = self->super.super.frames->items;
|
UNUSED(direction);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spPathConstraintSpacingTimeline *
|
spPathConstraintSpacingTimeline *
|
||||||
@ -2740,3 +2637,226 @@ void spPathConstraintMixTimeline_setFrame(spPathConstraintMixTimeline *self, int
|
|||||||
frames[frame + PATHCONSTRAINTMIX_X] = mixX;
|
frames[frame + PATHCONSTRAINTMIX_X] = mixX;
|
||||||
frames[frame + PATHCONSTRAINTMIX_Y] = mixY;
|
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);
|
if (internal->animationsChanged) _spAnimationState_animationsChanged(self);
|
||||||
|
|
||||||
for (i = 0, n = self->tracksCount; i < n; i++) {
|
for (i = 0, n = self->tracksCount; i < n; i++) {
|
||||||
float mix;
|
float alpha;
|
||||||
current = self->tracks[i];
|
current = self->tracks[i];
|
||||||
if (!current || current->delay > 0) continue;
|
if (!current || current->delay > 0) continue;
|
||||||
applied = -1;
|
applied = -1;
|
||||||
blend = i == 0 ? SP_MIX_BLEND_FIRST : current->mixBlend;
|
blend = i == 0 ? SP_MIX_BLEND_FIRST : current->mixBlend;
|
||||||
|
|
||||||
/* Apply mixing from entries first. */
|
/* Apply mixing from entries first. */
|
||||||
mix = current->alpha;
|
alpha = current->alpha;
|
||||||
if (current->mixingFrom)
|
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)
|
else if (current->trackTime >= current->trackEnd && current->next == 0)
|
||||||
mix = 0;
|
alpha = 0;
|
||||||
|
int/*bool*/ attachments = alpha >= current->alphaAttachmentThreshold;
|
||||||
|
|
||||||
/* Apply current entry. */
|
/* Apply current entry. */
|
||||||
animationLast = current->animationLast;
|
animationLast = current->animationLast;
|
||||||
@ -414,14 +415,14 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
|
|||||||
applyEvents = NULL;
|
applyEvents = NULL;
|
||||||
}
|
}
|
||||||
timelines = current->animation->timelines->items;
|
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++) {
|
for (ii = 0; ii < timelineCount; ii++) {
|
||||||
timeline = timelines[ii];
|
timeline = timelines[ii];
|
||||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, blend, -1);
|
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, blend, attachments);
|
||||||
} else {
|
} else {
|
||||||
spTimeline_apply(timelines[ii], skeleton, animationLast, applyTime, applyEvents,
|
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 {
|
} else {
|
||||||
@ -436,13 +437,13 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
|
|||||||
timeline = timelines[ii];
|
timeline = timelines[ii];
|
||||||
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
||||||
if (!shortestRotation && timeline->type == SP_TIMELINE_ROTATE)
|
if (!shortestRotation && timeline->type == SP_TIMELINE_ROTATE)
|
||||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, mix, timelineBlend,
|
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, alpha, timelineBlend,
|
||||||
timelinesRotation, ii << 1, firstFrame);
|
timelinesRotation, ii << 1, firstFrame);
|
||||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, -1);
|
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, attachments);
|
||||||
else
|
else
|
||||||
spTimeline_apply(timeline, skeleton, animationLast, applyTime, applyEvents, &internal->eventsCount,
|
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);
|
_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;
|
if (blend != SP_MIX_BLEND_FIRST) blend = from->mixBlend;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachments = mix < from->attachmentThreshold;
|
attachments = mix < from->mixAttachmentThreshold;
|
||||||
drawOrder = mix < from->drawOrderThreshold;
|
drawOrder = mix < from->mixDrawOrderThreshold;
|
||||||
timelineCount = from->animation->timelines->size;
|
timelineCount = from->animation->timelines->size;
|
||||||
timelines = from->animation->timelines->items;
|
timelines = from->animation->timelines->items;
|
||||||
alphaHold = from->alpha * to->interruptAlpha;
|
alphaHold = from->alpha * to->interruptAlpha;
|
||||||
@ -566,7 +567,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
|
|||||||
timelinesRotation, i << 1, firstFrame);
|
timelinesRotation, i << 1, firstFrame);
|
||||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend,
|
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend,
|
||||||
attachments);
|
attachments && alpha >= from->alphaAttachmentThreshold);
|
||||||
else {
|
else {
|
||||||
if (drawOrder && timeline->type == SP_TIMELINE_DRAWORDER &&
|
if (drawOrder && timeline->type == SP_TIMELINE_DRAWORDER &&
|
||||||
timelineBlend == SP_MIX_BLEND_SETUP)
|
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. */
|
/* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */
|
||||||
diff = r2 - r1;
|
diff = r2 - r1;
|
||||||
diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360;
|
diff -= CEIL(diff / 360 - 0.5) * 360;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
total = timelinesRotation[i];
|
total = timelinesRotation[i];
|
||||||
} else {
|
} else {
|
||||||
float lastTotal, lastDiff, loops;
|
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. */
|
/* Queue complete if completed a loop iteration or the animation. */
|
||||||
if (entry->loop)
|
if (entry->loop) {
|
||||||
complete = duration == 0 || (trackLastWrapped > FMOD(entry->trackTime, duration));
|
if (duration == 0)
|
||||||
else
|
complete = -1;
|
||||||
complete = (animationTime >= animationEnd && entry->animationLast < animationEnd);
|
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);
|
if (complete) _spEventQueue_complete(internal->queue, entry);
|
||||||
|
|
||||||
/* Queue events after complete. */
|
/* Queue events after complete. */
|
||||||
@ -910,8 +917,9 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation
|
|||||||
entry->next = 0;
|
entry->next = 0;
|
||||||
|
|
||||||
entry->eventThreshold = 0;
|
entry->eventThreshold = 0;
|
||||||
entry->attachmentThreshold = 0;
|
entry->mixAttachmentThreshold = 0;
|
||||||
entry->drawOrderThreshold = 0;
|
entry->alphaAttachmentThreshold = 0;
|
||||||
|
entry->mixDrawOrderThreshold = 0;
|
||||||
|
|
||||||
entry->animationStart = 0;
|
entry->animationStart = 0;
|
||||||
entry->animationEnd = animation->duration;
|
entry->animationEnd = animation->duration;
|
||||||
@ -1051,6 +1059,16 @@ float spTrackEntry_getTrackComplete(spTrackEntry *entry) {
|
|||||||
return entry->trackTime; /* Next update. */
|
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) {
|
void _spTrackEntry_computeHold(spTrackEntry *entry, spAnimationState *state) {
|
||||||
spTrackEntry *to;
|
spTrackEntry *to;
|
||||||
spTimeline **timelines;
|
spTimeline **timelines;
|
||||||
|
|||||||
@ -209,6 +209,13 @@ void spDebug_printTimeline(spTimeline *timeline) {
|
|||||||
spSequenceTimeline *t = (spSequenceTimeline *) timeline;
|
spSequenceTimeline *t = (spSequenceTimeline *) timeline;
|
||||||
_spDebug_printTimelineBase(&t->super);
|
_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,
|
void spIkConstraint_apply1(spBone *bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch,
|
||||||
int /*boolean*/ uniform, float alpha) {
|
int /*boolean*/ uniform, float alpha) {
|
||||||
spBone *p = bone->parent;
|
spBone *p = bone->parent;
|
||||||
|
|||||||
@ -33,11 +33,11 @@
|
|||||||
spIkConstraintData *spIkConstraintData_create(const char *name) {
|
spIkConstraintData *spIkConstraintData_create(const char *name) {
|
||||||
spIkConstraintData *self = NEW(spIkConstraintData);
|
spIkConstraintData *self = NEW(spIkConstraintData);
|
||||||
MALLOC_STR(self->name, name);
|
MALLOC_STR(self->name, name);
|
||||||
self->bendDirection = 1;
|
self->bendDirection = 0;
|
||||||
self->compress = 0;
|
self->compress = 0;
|
||||||
self->stretch = 0;
|
self->stretch = 0;
|
||||||
self->uniform = 0;
|
self->uniform = 0;
|
||||||
self->mix = 1;
|
self->mix = 0;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,13 +117,9 @@ void spPathConstraint_update(spPathConstraint *self) {
|
|||||||
for (i = 0, n = spacesCount - 1; i < n; i++) {
|
for (i = 0, n = spacesCount - 1; i < n; i++) {
|
||||||
spBone *bone = bones[i];
|
spBone *bone = bones[i];
|
||||||
setupLength = bone->data->length;
|
setupLength = bone->data->length;
|
||||||
if (setupLength < EPSILON)
|
x = setupLength * bone->a;
|
||||||
lengths[i] = 0;
|
y = setupLength * bone->c;
|
||||||
else {
|
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;
|
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) {
|
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);
|
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);
|
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 spPointAttachment_computeWorldRotation(spPointAttachment *self, spBone *bone) {
|
||||||
float cosine, sine, x, y;
|
float r = self->rotation * DEG_RAD, cosine = COS(r), sine = SIN(r);
|
||||||
cosine = COS_DEG(self->rotation);
|
float x = cosine * bone->a + sine * bone->b;
|
||||||
sine = SIN_DEG(self->rotation);
|
float y = cosine * bone->c + sine * bone->d;
|
||||||
x = cosine * bone->a + sine * bone->b;
|
return ATAN2DEG(y, x);
|
||||||
y = cosine * bone->c + sine * bone->d;
|
|
||||||
return ATAN2(y, x) * RAD_DEG;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,11 @@ spSkeleton *spSkeleton_create(spSkeletonData *data) {
|
|||||||
_spSkeleton *internal = NEW(_spSkeleton);
|
_spSkeleton *internal = NEW(_spSkeleton);
|
||||||
spSkeleton *self = SUPER(internal);
|
spSkeleton *self = SUPER(internal);
|
||||||
self->data = data;
|
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->bonesCount = self->data->bonesCount;
|
||||||
self->bones = MALLOC(spBone *, self->bonesCount);
|
self->bones = MALLOC(spBone *, self->bonesCount);
|
||||||
@ -116,6 +121,12 @@ spSkeleton *spSkeleton_create(spSkeletonData *data) {
|
|||||||
for (i = 0; i < self->data->pathConstraintsCount; i++)
|
for (i = 0; i < self->data->pathConstraintsCount; i++)
|
||||||
self->pathConstraints[i] = spPathConstraint_create(self->data->pathConstraints[i], self);
|
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);
|
spColor_setFromFloats(&self->color, 1, 1, 1, 1);
|
||||||
|
|
||||||
self->scaleX = 1;
|
self->scaleX = 1;
|
||||||
@ -156,6 +167,10 @@ void spSkeleton_dispose(spSkeleton *self) {
|
|||||||
spPathConstraint_dispose(self->pathConstraints[i]);
|
spPathConstraint_dispose(self->pathConstraints[i]);
|
||||||
FREE(self->pathConstraints);
|
FREE(self->pathConstraints);
|
||||||
|
|
||||||
|
for (i = 0; i < self->physicsConstraintsCount; i++)
|
||||||
|
spPhysicsConstraint_dispose(self->physicsConstraints[i]);
|
||||||
|
FREE(self->physicsConstraints);
|
||||||
|
|
||||||
FREE(self->drawOrder);
|
FREE(self->drawOrder);
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
@ -324,17 +339,35 @@ static void _sortTransformConstraint(_spSkeleton *const internal, spTransformCon
|
|||||||
constrained[i]->sorted = 1;
|
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) {
|
void spSkeleton_updateCache(spSkeleton *self) {
|
||||||
int i, ii;
|
int i, ii;
|
||||||
spBone **bones;
|
spBone **bones;
|
||||||
spIkConstraint **ikConstraints;
|
spIkConstraint **ikConstraints;
|
||||||
spPathConstraint **pathConstraints;
|
spPathConstraint **pathConstraints;
|
||||||
spTransformConstraint **transformConstraints;
|
spTransformConstraint **transformConstraints;
|
||||||
int ikCount, transformCount, pathCount, constraintCount;
|
spPhysicsConstraint **physicsConstraints;
|
||||||
|
int ikCount, transformCount, pathCount, physicsCount, constraintCount;
|
||||||
_spSkeleton *internal = SUB_CAST(_spSkeleton, self);
|
_spSkeleton *internal = SUB_CAST(_spSkeleton, self);
|
||||||
|
|
||||||
internal->updateCacheCapacity =
|
internal->updateCacheCapacity =
|
||||||
self->bonesCount + self->ikConstraintsCount + self->transformConstraintsCount + self->pathConstraintsCount;
|
self->bonesCount + self->ikConstraintsCount + self->transformConstraintsCount + self->pathConstraintsCount +
|
||||||
|
self->physicsConstraintsCount;
|
||||||
FREE(internal->updateCache);
|
FREE(internal->updateCache);
|
||||||
internal->updateCache = MALLOC(_spUpdate, internal->updateCacheCapacity);
|
internal->updateCache = MALLOC(_spUpdate, internal->updateCacheCapacity);
|
||||||
internal->updateCacheCount = 0;
|
internal->updateCacheCount = 0;
|
||||||
@ -362,10 +395,12 @@ void spSkeleton_updateCache(spSkeleton *self) {
|
|||||||
ikConstraints = self->ikConstraints;
|
ikConstraints = self->ikConstraints;
|
||||||
transformConstraints = self->transformConstraints;
|
transformConstraints = self->transformConstraints;
|
||||||
pathConstraints = self->pathConstraints;
|
pathConstraints = self->pathConstraints;
|
||||||
|
physicsConstraints = self->physicsConstraints;
|
||||||
ikCount = self->ikConstraintsCount;
|
ikCount = self->ikConstraintsCount;
|
||||||
transformCount = self->transformConstraintsCount;
|
transformCount = self->transformConstraintsCount;
|
||||||
pathCount = self->pathConstraintsCount;
|
pathCount = self->pathConstraintsCount;
|
||||||
constraintCount = ikCount + transformCount + pathCount;
|
physicsCount = self->physicsConstraintsCount;
|
||||||
|
constraintCount = ikCount + transformCount + pathCount + physicsCount;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
continue_outer:
|
continue_outer:
|
||||||
@ -396,6 +431,15 @@ continue_outer:
|
|||||||
goto 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)
|
for (i = 0; i < self->bonesCount; ++i)
|
||||||
@ -495,33 +539,19 @@ void spSkeleton_setBonesToSetupPose(const spSkeleton *self) {
|
|||||||
spBone_setToSetupPose(self->bones[i]);
|
spBone_setToSetupPose(self->bones[i]);
|
||||||
|
|
||||||
for (i = 0; i < self->ikConstraintsCount; ++i) {
|
for (i = 0; i < self->ikConstraintsCount; ++i) {
|
||||||
spIkConstraint *ikConstraint = self->ikConstraints[i];
|
spIkConstraint_setToSetupPose(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < self->transformConstraintsCount; ++i) {
|
for (i = 0; i < self->transformConstraintsCount; ++i) {
|
||||||
spTransformConstraint *constraint = self->transformConstraints[i];
|
spTransformConstraint_setToSetupPose(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < self->pathConstraintsCount; ++i) {
|
for (i = 0; i < self->pathConstraintsCount; ++i) {
|
||||||
spPathConstraint *constraint = self->pathConstraints[i];
|
spPathConstraint_setToSetupPose(self->pathConstraints[i]);
|
||||||
spPathConstraintData *data = constraint->data;
|
}
|
||||||
constraint->position = data->position;
|
|
||||||
constraint->spacing = data->spacing;
|
for (i = 0; i < self->physicsConstraintsCount; ++i) {
|
||||||
constraint->mixRotate = data->mixRotate;
|
spPhysicsConstraint_setToSetupPose(self->physicsConstraints[i]);
|
||||||
constraint->mixX = data->mixX;
|
|
||||||
constraint->mixY = data->mixY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,3 +675,15 @@ spPhysicsConstraint *spSkeleton_findPhysicsConstraint(const spSkeleton *self, co
|
|||||||
if (strcmp(self->physicsConstraints[i]->data->name, constraintName) == 0) return self->physicsConstraints[i];
|
if (strcmp(self->physicsConstraints[i]->data->name, constraintName) == 0) return self->physicsConstraints[i];
|
||||||
return 0;
|
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(spPathConstraintDataArray, spPathConstraintData *)
|
||||||
|
|
||||||
|
_SP_ARRAY_IMPLEMENT_TYPE(spPhysicsConstraintDataArray, spPhysicsConstraintData *)
|
||||||
|
|
||||||
_Entry *_Entry_create(int slotIndex, const char *name, spAttachment *attachment) {
|
_Entry *_Entry_create(int slotIndex, const char *name, spAttachment *attachment) {
|
||||||
_Entry *self = NEW(_Entry);
|
_Entry *self = NEW(_Entry);
|
||||||
self->slotIndex = slotIndex;
|
self->slotIndex = slotIndex;
|
||||||
@ -72,6 +74,7 @@ spSkin *spSkin_create(const char *name) {
|
|||||||
self->ikConstraints = spIkConstraintDataArray_create(4);
|
self->ikConstraints = spIkConstraintDataArray_create(4);
|
||||||
self->transformConstraints = spTransformConstraintDataArray_create(4);
|
self->transformConstraints = spTransformConstraintDataArray_create(4);
|
||||||
self->pathConstraints = spPathConstraintDataArray_create(4);
|
self->pathConstraints = spPathConstraintDataArray_create(4);
|
||||||
|
self->physicsConstraints = spPhysicsConstraintDataArray_create(4);
|
||||||
spColor_setFromFloats(&self->color, 0.99607843f, 0.61960787f, 0.30980393f, 1);
|
spColor_setFromFloats(&self->color, 0.99607843f, 0.61960787f, 0.30980393f, 1);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -104,6 +107,7 @@ void spSkin_dispose(spSkin *self) {
|
|||||||
spIkConstraintDataArray_dispose(self->ikConstraints);
|
spIkConstraintDataArray_dispose(self->ikConstraints);
|
||||||
spTransformConstraintDataArray_dispose(self->transformConstraints);
|
spTransformConstraintDataArray_dispose(self->transformConstraints);
|
||||||
spPathConstraintDataArray_dispose(self->pathConstraints);
|
spPathConstraintDataArray_dispose(self->pathConstraints);
|
||||||
|
spPhysicsConstraintDataArray_dispose(self->physicsConstraints);
|
||||||
FREE(self->name);
|
FREE(self->name);
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
@ -198,6 +202,11 @@ void spSkin_addSkin(spSkin *self, const spSkin *other) {
|
|||||||
spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
|
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);
|
entry = spSkin_getAttachments(other);
|
||||||
while (entry) {
|
while (entry) {
|
||||||
spSkin_setAttachment(self, entry->slotIndex, entry->name, entry->attachment);
|
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]);
|
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);
|
entry = spSkin_getAttachments(other);
|
||||||
while (entry) {
|
while (entry) {
|
||||||
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
|
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
|
||||||
@ -279,4 +293,5 @@ void spSkin_clear(spSkin *self) {
|
|||||||
spIkConstraintDataArray_clear(self->ikConstraints);
|
spIkConstraintDataArray_clear(self->ikConstraints);
|
||||||
spTransformConstraintDataArray_clear(self->transformConstraints);
|
spTransformConstraintDataArray_clear(self->transformConstraints);
|
||||||
spPathConstraintDataArray_clear(self->pathConstraints);
|
spPathConstraintDataArray_clear(self->pathConstraints);
|
||||||
|
spPhysicsConstraintDataArray_clear(self->physicsConstraints);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -193,8 +193,8 @@ void _spTransformConstraint_applyAbsoluteLocal(spTransformConstraint *self) {
|
|||||||
rotation = bone->arotation;
|
rotation = bone->arotation;
|
||||||
if (mixRotate != 0) {
|
if (mixRotate != 0) {
|
||||||
r = target->arotation - rotation + self->data->offsetRotation;
|
r = target->arotation - rotation + self->data->offsetRotation;
|
||||||
r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360;
|
r -= CEIL(r / 360 - 0.5) * 360;
|
||||||
rotation += r * mixRotate;
|
rotation += r * mixRotate;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = bone->ax, y = bone->ay;
|
x = bone->ax, y = bone->ay;
|
||||||
@ -210,8 +210,8 @@ void _spTransformConstraint_applyAbsoluteLocal(spTransformConstraint *self) {
|
|||||||
shearY = bone->ashearY;
|
shearY = bone->ashearY;
|
||||||
if (mixShearY != 0) {
|
if (mixShearY != 0) {
|
||||||
r = target->ashearY - shearY + self->data->offsetShearY;
|
r = target->ashearY - shearY + self->data->offsetShearY;
|
||||||
r -= (16384 - (int) (16384.499999999996 - r / 360)) * 360;
|
r -= CEIL(r / 360 - 0.5) * 360;
|
||||||
shearY += r * mixShearY;
|
shearY += r * mixShearY;
|
||||||
}
|
}
|
||||||
|
|
||||||
spBone_updateWorldTransformWith(bone, x, y, rotation, scaleX, scaleY, bone->ashearX, shearY);
|
spBone_updateWorldTransformWith(bone, x, y, rotation, scaleX, scaleY, bone->ashearX, shearY);
|
||||||
@ -257,3 +257,13 @@ void spTransformConstraint_update(spTransformConstraint *self) {
|
|||||||
_spTransformConstraint_applyAbsoluteWorld(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