[c][cpp] Fix all warnings on Clang, more physics constraints porting

This commit is contained in:
Mario Zechner 2024-01-03 12:52:10 +01:00
parent a190bc8899
commit 8c79c7c1de
49 changed files with 637 additions and 386 deletions

View File

@ -149,7 +149,7 @@ SP_API float spTrackEntry_getTrackComplete(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*/
SP_API void spAnimationState_disposeStatics(); SP_API void spAnimationState_disposeStatics(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -110,7 +110,7 @@ struct spAtlasRegion {
spAtlasRegion *next; spAtlasRegion *next;
}; };
SP_API spAtlasRegion *spAtlasRegion_create(); SP_API spAtlasRegion *spAtlasRegion_create(void);
SP_API void spAtlasRegion_dispose(spAtlasRegion *self); SP_API void spAtlasRegion_dispose(spAtlasRegion *self);

View File

@ -58,7 +58,7 @@ struct spBone {
SP_API void spBone_setYDown(int/*bool*/yDown); SP_API void spBone_setYDown(int/*bool*/yDown);
SP_API int/*bool*/spBone_isYDown(); SP_API int/*bool*/spBone_isYDown(void);
/* @param parent May be 0. */ /* @param parent May be 0. */
SP_API spBone *spBone_create(spBoneData *data, struct spSkeleton *skeleton, spBone *parent); SP_API spBone *spBone_create(spBoneData *data, struct spSkeleton *skeleton, spBone *parent);

View File

@ -41,7 +41,7 @@ typedef struct spColor {
} spColor; } spColor;
/* @param attachmentName May be 0 for no setup pose attachment. */ /* @param attachmentName May be 0 for no setup pose attachment. */
SP_API spColor *spColor_create(); SP_API spColor *spColor_create(void);
SP_API void spColor_dispose(spColor *self); SP_API void spColor_dispose(spColor *self);

View File

@ -62,7 +62,7 @@ typedef struct spSkeletonBounds {
float minX, minY, maxX, maxY; float minX, minY, maxX, maxY;
} spSkeletonBounds; } spSkeletonBounds;
SP_API spSkeletonBounds *spSkeletonBounds_create(); SP_API spSkeletonBounds *spSkeletonBounds_create(void);
SP_API void spSkeletonBounds_dispose(spSkeletonBounds *self); SP_API void spSkeletonBounds_dispose(spSkeletonBounds *self);

View File

@ -52,7 +52,7 @@ typedef struct spSkeletonClipping {
spArrayFloatArray *clippingPolygons; spArrayFloatArray *clippingPolygons;
} spSkeletonClipping; } spSkeletonClipping;
SP_API spSkeletonClipping *spSkeletonClipping_create(); SP_API spSkeletonClipping *spSkeletonClipping_create(void);
SP_API int spSkeletonClipping_clipStart(spSkeletonClipping *self, spSlot *slot, spClippingAttachment *clip); SP_API int spSkeletonClipping_clipStart(spSkeletonClipping *self, spSlot *slot, spClippingAttachment *clip);

View File

@ -81,7 +81,7 @@ typedef struct spSkeletonData {
spPathConstraintData **pathConstraints; spPathConstraintData **pathConstraints;
} spSkeletonData; } spSkeletonData;
SP_API spSkeletonData *spSkeletonData_create(); SP_API spSkeletonData *spSkeletonData_create(void);
SP_API void spSkeletonData_dispose(spSkeletonData *self); SP_API void spSkeletonData_dispose(spSkeletonData *self);

View File

@ -49,7 +49,7 @@ typedef struct spTriangulator {
spArrayShortArray *polygonIndicesPool; spArrayShortArray *polygonIndicesPool;
} spTriangulator; } spTriangulator;
SP_API spTriangulator *spTriangulator_create(); SP_API spTriangulator *spTriangulator_create(void);
SP_API spShortArray *spTriangulator_triangulate(spTriangulator *self, spFloatArray *verticesArray); SP_API spShortArray *spTriangulator_triangulate(spTriangulator *self, spFloatArray *verticesArray);

View File

@ -175,7 +175,7 @@ void *_spRealloc(void *ptr, size_t size);
void _spFree(void *ptr); void _spFree(void *ptr);
float _spRandom(); float _spRandom(void);
SP_API void _spSetMalloc(void *(*_malloc)(size_t size)); SP_API void _spSetMalloc(void *(*_malloc)(size_t size));
@ -185,7 +185,7 @@ SP_API void _spSetRealloc(void *(*_realloc)(void *ptr, size_t size));
SP_API void _spSetFree(void (*_free)(void *ptr)); SP_API void _spSetFree(void (*_free)(void *ptr));
SP_API void _spSetRandom(float (*_random)()); SP_API void _spSetRandom(float (*_random)(void));
char *_spReadFile(const char *path, int *length); char *_spReadFile(const char *path, int *length);

View File

@ -44,7 +44,7 @@ _SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry *)
static spAnimation *SP_EMPTY_ANIMATION = 0; static spAnimation *SP_EMPTY_ANIMATION = 0;
void spAnimationState_disposeStatics() { void spAnimationState_disposeStatics(void) {
if (SP_EMPTY_ANIMATION) spAnimation_dispose(SP_EMPTY_ANIMATION); if (SP_EMPTY_ANIMATION) spAnimation_dispose(SP_EMPTY_ANIMATION);
SP_EMPTY_ANIMATION = 0; SP_EMPTY_ANIMATION = 0;
} }

View File

@ -115,7 +115,7 @@ void spAtlasPage_dispose(spAtlasPage *self) {
/**/ /**/
spAtlasRegion *spAtlasRegion_create() { spAtlasRegion *spAtlasRegion_create(void) {
spAtlasRegion *region = NEW(spAtlasRegion); spAtlasRegion *region = NEW(spAtlasRegion);
region->keyValues = spKeyValueArray_create(2); region->keyValues = spKeyValueArray_create(2);
return region; return region;

View File

@ -96,6 +96,6 @@ void _spAttachmentLoader_setError(spAttachmentLoader *self, const char *error1,
void _spAttachmentLoader_setUnknownTypeError(spAttachmentLoader *self, spAttachmentType type) { void _spAttachmentLoader_setUnknownTypeError(spAttachmentLoader *self, spAttachmentType type) {
char buffer[16]; char buffer[16];
sprintf(buffer, "%d", type); snprintf(buffer, 16,"%d", type);
_spAttachmentLoader_setError(self, "Unknown attachment type: ", buffer); _spAttachmentLoader_setError(self, "Unknown attachment type: ", buffer);
} }

View File

@ -37,7 +37,7 @@ void spBone_setYDown(int value) {
yDown = value; yDown = value;
} }
int spBone_isYDown() { int spBone_isYDown(void) {
return yDown; return yDown;
} }
@ -261,26 +261,31 @@ void spBone_updateAppliedTransform(spBone *self) {
break; break;
} }
case SP_TRANSFORMMODE_NOSCALE: case SP_TRANSFORMMODE_NOSCALE:
case SP_TRANSFORMMODE_NOSCALEORREFLECTION: case SP_TRANSFORMMODE_NOSCALEORREFLECTION: {
cosine = COS_DEG(self->rotation), sine = SIN_DEG(self->rotation); cosine = COS_DEG(self->rotation), sine = SIN_DEG(self->rotation);
pa = (pa * cosine + pb * sine) / self->skeleton->scaleX; pa = (pa * cosine + pb * sine) / self->skeleton->scaleX;
pc = (pc * cosine + pd * sine) / self->skeleton->scaleY; pc = (pc * cosine + pd * sine) / self->skeleton->scaleY;
s = SQRT(pa * pa + pc * pc); s = SQRT(pa * pa + pc * pc);
if (s > 0.00001f) s = 1 / s; if (s > 0.00001f) s = 1 / s;
pa *= s; pa *= s;
pc *= s; pc *= s;
s = SQRT(pa * pa + pc * pc); s = SQRT(pa * pa + pc * pc);
if (self->data->transformMode == SP_TRANSFORMMODE_NOSCALE && if (self->data->transformMode == SP_TRANSFORMMODE_NOSCALE &&
pid < 0 != (self->skeleton->scaleX < 0 != self->skeleton->scaleY < 0)) pid < 0 != (self->skeleton->scaleX < 0 != self->skeleton->scaleY < 0))
s = -s; s = -s;
r = PI / 2 + ATAN2(pc, pa); r = PI / 2 + ATAN2(pc, pa);
pb = COS(r) * s; pb = COS(r) * s;
pd = SIN(r) * s; pd = SIN(r) * s;
pid = 1 / (pa * pd - pb * pc); pid = 1 / (pa * pd - pb * pc);
ia = pd * pid; ia = pd * pid;
ib = pb * pid; ib = pb * pid;
ic = pc * pid; ic = pc * pid;
id = pa * pid; id = pa * pid;
break;
}
case SP_TRANSFORMMODE_ONLYTRANSLATION:
case SP_TRANSFORMMODE_NORMAL:
break;
} }
ra = ia * self->a - ib * self->c; ra = ia * self->a - ib * self->c;
rb = ia * self->b - ib * self->d; rb = ia * self->b - ib * self->d;

View File

@ -30,7 +30,7 @@
#include <spine/Color.h> #include <spine/Color.h>
#include <spine/extension.h> #include <spine/extension.h>
spColor *spColor_create() { spColor *spColor_create(void) {
return MALLOC(spColor, 1); return MALLOC(spColor, 1);
} }

View File

@ -122,7 +122,6 @@ static const char *parse_number(Json *item, const char *num) {
if (*ptr == 'e' || *ptr == 'E') { if (*ptr == 'e' || *ptr == 'E') {
double exponent = 0; double exponent = 0;
int expNegative = 0; int expNegative = 0;
int n = 0;
++ptr; ++ptr;
if (*ptr == '-') { if (*ptr == '-') {
@ -135,7 +134,6 @@ static const char *parse_number(Json *item, const char *num) {
while (*ptr >= '0' && *ptr <= '9') { while (*ptr >= '0' && *ptr <= '9') {
exponent = (exponent * 10.0) + (*ptr - '0'); exponent = (exponent * 10.0) + (*ptr - '0');
++ptr; ++ptr;
++n;
} }
if (expNegative) if (expNegative)

View File

@ -102,7 +102,7 @@ static char *string_append(char *str, const char *b) {
static char *string_append_int(char *str, int value) { static char *string_append_int(char *str, int value) {
char intStr[20]; char intStr[20];
sprintf(intStr, "%i", value); snprintf(intStr, 20, "%i", value);
return string_append(str, intStr); return string_append(str, intStr);
} }

View File

@ -1325,7 +1325,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
skeletonData = spSkeletonData_create(); skeletonData = spSkeletonData_create();
lowHash = readInt(input); lowHash = readInt(input);
highHash = readInt(input); highHash = readInt(input);
sprintf(buffer, "%x%x", highHash, lowHash); snprintf(buffer, 32, "%x%x", highHash, lowHash);
buffer[31] = 0; buffer[31] = 0;
MALLOC_STR(skeletonData->hash, buffer); MALLOC_STR(skeletonData->hash, buffer);
@ -1336,7 +1336,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
} else { } else {
if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) { if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) {
char errorMsg[255]; char errorMsg[255];
sprintf(errorMsg, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING); snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING);
_spSkeletonBinary_setError(self, errorMsg, NULL); _spSkeletonBinary_setError(self, errorMsg, NULL);
return NULL; return NULL;
} }

View File

@ -89,7 +89,7 @@ typedef struct {
int capacity; int capacity;
} _spSkeletonBounds; } _spSkeletonBounds;
spSkeletonBounds *spSkeletonBounds_create() { spSkeletonBounds *spSkeletonBounds_create(void) {
return SUPER(NEW(_spSkeletonBounds)); return SUPER(NEW(_spSkeletonBounds));
} }

View File

@ -30,7 +30,7 @@
#include <spine/SkeletonClipping.h> #include <spine/SkeletonClipping.h>
#include <spine/extension.h> #include <spine/extension.h>
spSkeletonClipping *spSkeletonClipping_create() { spSkeletonClipping *spSkeletonClipping_create(void) {
spSkeletonClipping *clipping = CALLOC(spSkeletonClipping, 1); spSkeletonClipping *clipping = CALLOC(spSkeletonClipping, 1);
clipping->triangulator = spTriangulator_create(); clipping->triangulator = spTriangulator_create();

View File

@ -31,7 +31,7 @@
#include <spine/extension.h> #include <spine/extension.h>
#include <string.h> #include <string.h>
spSkeletonData *spSkeletonData_create() { spSkeletonData *spSkeletonData_create(void) {
return NEW(spSkeletonData); return NEW(spSkeletonData);
} }

View File

@ -988,7 +988,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", "0")); MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", "0"));
if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) { if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) {
char errorMsg[255]; char errorMsg[255];
sprintf(errorMsg, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING); snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING);
_spSkeletonJson_setError(self, 0, errorMsg, NULL); _spSkeletonJson_setError(self, 0, errorMsg, NULL);
return NULL; return NULL;
} }

View File

@ -31,7 +31,7 @@
#include <spine/extension.h> #include <spine/extension.h>
#include <stdio.h> #include <stdio.h>
spTriangulator *spTriangulator_create() { spTriangulator *spTriangulator_create(void) {
spTriangulator *triangulator = CALLOC(spTriangulator, 1); spTriangulator *triangulator = CALLOC(spTriangulator, 1);
triangulator->convexPolygons = spArrayFloatArray_create(16); triangulator->convexPolygons = spArrayFloatArray_create(16);

View File

@ -30,7 +30,7 @@
#include <spine/extension.h> #include <spine/extension.h>
#include <stdio.h> #include <stdio.h>
float _spInternalRandom() { float _spInternalRandom(void) {
return rand() / (float) RAND_MAX; return rand() / (float) RAND_MAX;
} }
@ -42,7 +42,7 @@ static void *(*debugMallocFunc)(size_t size, const char *file, int line) = NULL;
static void (*freeFunc)(void *ptr) = free; static void (*freeFunc)(void *ptr) = free;
static float (*randomFunc)() = _spInternalRandom; static float (*randomFunc)(void) = _spInternalRandom;
void *_spMalloc(size_t size, const char *file, int line) { void *_spMalloc(size_t size, const char *file, int line) {
if (debugMallocFunc) if (debugMallocFunc)
@ -65,7 +65,7 @@ void _spFree(void *ptr) {
freeFunc(ptr); freeFunc(ptr);
} }
float _spRandom() { float _spRandom(void) {
return randomFunc(); return randomFunc();
} }
@ -85,7 +85,7 @@ void _spSetFree(void (*free)(void *ptr)) {
freeFunc = free; freeFunc = free;
} }
void _spSetRandom(float (*random)()) { void _spSetRandom(float (*random)(void)) {
randomFunc = random; randomFunc = random;
} }

View File

@ -76,6 +76,14 @@ namespace spine {
float getCurveValue(float time); float getCurveValue(float time);
float getRelativeValue(float time, float alpha, MixBlend blend, float current, float setup);
float getAbsoluteValue(float time, float alpha, MixBlend blend, float current, float setup);
float getAbsoluteValue (float time, float alpha, MixBlend blend, float current, float setup, float value);
float getScaleValue (float time, float alpha, MixBlend blend, MixDirection direction, float current, float setup);
protected: protected:
static const int ENTRIES = 2; static const int ENTRIES = 2;
static const int VALUE = 1; static const int VALUE = 1;

View File

@ -51,12 +51,12 @@ namespace spine {
/// Sets the time, mix and bend direction of the specified keyframe. /// Sets the time, mix and bend direction of the specified keyframe.
void setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch); void setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
int getIkConstraintIndex() { return _ikConstraintIndex; } int getIkConstraintIndex() { return _constraintIndex; }
void setIkConstraintIndex(int inValue) { _ikConstraintIndex = inValue; } void setIkConstraintIndex(int inValue) { _constraintIndex = inValue; }
private: private:
int _ikConstraintIndex; int _constraintIndex;
static const int ENTRIES = 6; static const int ENTRIES = 6;
static const int MIX = 1; static const int MIX = 1;

View File

@ -33,7 +33,6 @@
#include <spine/CurveTimeline.h> #include <spine/CurveTimeline.h>
namespace spine { namespace spine {
#define SP_PATHCONSTRAINTMIXTIMELINE_ENTRIES 5
class SP_API PathConstraintMixTimeline : public CurveTimeline { class SP_API PathConstraintMixTimeline : public CurveTimeline {
friend class SkeletonBinary; friend class SkeletonBinary;
@ -52,12 +51,12 @@ namespace spine {
/// Sets the time and mixes of the specified keyframe. /// Sets the time and mixes of the specified keyframe.
void setFrame(int frameIndex, float time, float mixRotate, float mixX, float mixY); void setFrame(int frameIndex, float time, float mixRotate, float mixX, float mixY);
int getPathConstraintIndex() { return _pathConstraintIndex; } int getPathConstraintIndex() { return _constraintIndex; }
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; } void setPathConstraintIndex(int inValue) { _constraintIndex = inValue; }
private: private:
int _pathConstraintIndex; int _constraintIndex;
static const int ENTRIES = 4; static const int ENTRIES = 4;
static const int ROTATE = 1; static const int ROTATE = 1;

View File

@ -52,12 +52,12 @@ namespace spine {
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend, apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
MixDirection direction); MixDirection direction);
int getPathConstraintIndex() { return _pathConstraintIndex; } int getPathConstraintIndex() { return _constraintIndex; }
void setPathConstraintIndex(int inValue) { _pathConstraintIndex = inValue; } void setPathConstraintIndex(int inValue) { _constraintIndex = inValue; }
protected: protected:
int _pathConstraintIndex; int _constraintIndex;
}; };
} }

View File

@ -33,16 +33,16 @@
namespace spine { namespace spine {
enum Physics { enum Physics {
/** Physics are not updated or applied. */ /** Physics are not updated or applied. */
none, Physics_None,
/** Physics are reset to the current pose. */ /** Physics are reset to the current pose. */
reset, Physics_Reset,
/** Physics are updated and the pose from physics is applied. */ /** Physics are updated and the pose from physics is applied. */
update, Physics_Update,
/** Physics are not updated but the pose from physics is applied. */ /** Physics are not updated but the pose from physics is applied. */
pose Physics_Pose
}; };
} }

View File

@ -45,6 +45,24 @@ namespace spine {
friend class Skeleton; friend class Skeleton;
friend class PhysicsConstraintTimeline;
friend class PhysicsConstraintInertiaTimeline;
friend class PhysicsConstraintStrengthTimeline;
friend class PhysicsConstraintDampingTimeline;
friend class PhysicsConstraintMassTimeline;
friend class PhysicsConstraintWindTimeline;
friend class PhysicsConstraintGravityTimeline;
friend class PhysicsConstraintMixTimeline;
friend class PhysicsConstraintResetTimeline;
RTTI_DECL RTTI_DECL
public: public:

View File

@ -0,0 +1,288 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated July 28, 2023. Replaces all prior versions.
*
* Copyright (c) 2013-2023, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software or
* otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
* SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef Spine_PhysicsConstraintTimeline_h
#define Spine_PhysicsConstraintTimeline_h
#include <spine/CurveTimeline.h>
#include <spine/PhysicsConstraint.h>
#include <spine/PhysicsConstraintData.h>
namespace spine {
class SP_API PhysicsConstraintTimeline : public CurveTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex, Property property);
virtual void
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
MixDirection direction);
int getPhysicsConstraintIndex() { return _constraintIndex; }
void setPhysicsConstraintIndex(int inValue) { _constraintIndex = inValue; }
protected:
virtual float setup(PhysicsConstraint *constraint) = 0;
virtual float get(PhysicsConstraint *constraint) = 0;
virtual void set(PhysicsConstraint *constraint, float value) = 0;
virtual bool global(PhysicsConstraintData &constraintData) = 0;
private:
int _constraintIndex;
};
class SP_API PhysicsConstraintInertiaTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintInertiaTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintInertia) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getInertia();
}
float get(PhysicsConstraint *constraint) {
return constraint->_inertia;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_inertia = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isInertiaGlobal();
}
};
class SP_API PhysicsConstraintStrengthTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintStrengthTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintStrength) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getStrength();
}
float get(PhysicsConstraint *constraint) {
return constraint->_strength;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_strength = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isStrengthGlobal();
}
};
class SP_API PhysicsConstraintDampingTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintDampingTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintDamping) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getDamping();
}
float get(PhysicsConstraint *constraint) {
return constraint->_damping;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_damping = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isDampingGlobal();
}
};
class SP_API PhysicsConstraintMassTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintMassTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMass) {};
protected:
float setup(PhysicsConstraint *constraint) {
return 1 / constraint->_data.getMassInverse();
}
float get(PhysicsConstraint *constraint) {
return 1 / constraint->_massInverse;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_massInverse = 1 / value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isMassGlobal();
}
};
class SP_API PhysicsConstraintWindTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintWindTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getWind();
}
float get(PhysicsConstraint *constraint) {
return constraint->_wind;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_wind = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isWindGlobal();
}
};
class SP_API PhysicsConstraintGravityTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintGravityTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getGravity();
}
float get(PhysicsConstraint *constraint) {
return constraint->_gravity;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_gravity = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isGravityGlobal();
}
};
class SP_API PhysicsConstraintMixTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintMixTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex): PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMix) {};
protected:
float setup(PhysicsConstraint *constraint) {
return constraint->_data.getMix();
}
float get(PhysicsConstraint *constraint) {
return constraint->_mix;
}
void set(PhysicsConstraint *constraint, float value) {
constraint->_mix = value;
}
bool global(PhysicsConstraintData &constraintData) {
return constraintData.isMixGlobal();
}
};
class SP_API PhysicsConstraintResetTimeline : public Timeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintResetTimeline(size_t frameCount, int physicsConstraintIndex): Timeline(frameCount, 1), _constraintIndex(physicsConstraintIndex) {
PropertyId ids[] = {((PropertyId)Property_PhysicsConstraintReset) << 32};
setPropertyIds(ids, 1);
}
virtual void
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
MixDirection direction);
void setFrame(int frame, float time) {
_frames[frame] = time;
}
private:
int _constraintIndex;
};
}
#endif /* Spine_PhysicsConstraintTimeline_h */

View File

@ -52,7 +52,15 @@ namespace spine {
Property_PathConstraintPosition = 1 << 16, Property_PathConstraintPosition = 1 << 16,
Property_PathConstraintSpacing = 1 << 17, Property_PathConstraintSpacing = 1 << 17,
Property_PathConstraintMix = 1 << 18, Property_PathConstraintMix = 1 << 18,
Property_Sequence = 1 << 19 Property_PhysicsConstraintInertia = 1 << 19,
Property_PhysicsConstraintStrength = 1 << 20,
Property_PhysicsConstraintDamping = 1 << 21,
Property_PhysicsConstraintMass = 1 << 22,
Property_PhysicsConstraintWind = 1 << 23,
Property_PhysicsConstraintGravity = 1 << 24,
Property_PhysicsConstraintMix = 1 << 25,
Property_PhysicsConstraintReset = 1 << 26,
Property_Sequence = 1 << 27
}; };
} }

View File

@ -77,7 +77,7 @@ namespace spine {
protected: protected:
void setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount); void setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount);
Vector <PropertyId> _propertyIds; Vector <PropertyId> _propertyIds;
Vector<float> _frames; Vector<float> _frames;
size_t _frameEntries; size_t _frameEntries;
}; };

View File

@ -51,12 +51,12 @@ namespace spine {
void setFrame(size_t frameIndex, float time, float mixRotate, float mixX, float mixY, float mixScaleX, void setFrame(size_t frameIndex, float time, float mixRotate, float mixX, float mixY, float mixScaleX,
float mixScaleY, float mixShearY); float mixScaleY, float mixShearY);
int getTransformConstraintIndex() { return _transformConstraintIndex; } int getTransformConstraintIndex() { return _constraintIndex; }
void setTransformConstraintIndex(int inValue) { _transformConstraintIndex = inValue; } void setTransformConstraintIndex(int inValue) { _constraintIndex = inValue; }
private: private:
int _transformConstraintIndex; int _constraintIndex;
static const int ENTRIES = 7; static const int ENTRIES = 7;
static const int ROTATE = 1; static const int ROTATE = 1;

View File

@ -132,6 +132,109 @@ float CurveTimeline1::getCurveValue(float time) {
return getBezierValue(time, i, CurveTimeline1::VALUE, curveType - CurveTimeline1::BEZIER); return getBezierValue(time, i, CurveTimeline1::VALUE, curveType - CurveTimeline1::BEZIER);
} }
float CurveTimeline1::getRelativeValue(float time, float alpha, MixBlend blend, float current, float setup) {
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
return setup;
case MixBlend_First:
return current + (setup - current) * alpha;
default:
return current;
}
}
float value = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
return setup + value * alpha;
case MixBlend_First:
case MixBlend_Replace:
value += setup - current;
break;
case MixBlend_Add:
break;
}
return current + value * alpha;
}
float CurveTimeline1::getAbsoluteValue(float time, float alpha, MixBlend blend, float current, float setup) {
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
return setup;
case MixBlend_First:
return current + (setup - current) * alpha;
default:
return current;
}
}
float value = getCurveValue(time);
if (blend == MixBlend_Setup) return setup + (value - setup) * alpha;
return current + (value - current) * alpha;
}
float CurveTimeline1::getAbsoluteValue(float time, float alpha, MixBlend blend, float current, float setup, float value) {
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
return setup;
case MixBlend_First:
return current + (setup - current) * alpha;
default:
return current;
}
}
if (blend == MixBlend_Setup) return setup + (value - setup) * alpha;
return current + (value - current) * alpha;
}
float CurveTimeline1::getScaleValue(float time, float alpha, MixBlend blend, MixDirection direction, float current,
float setup) {
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
return setup;
case MixBlend_First:
return current + (setup - current) * alpha;
default:
return current;
}
}
float value = getCurveValue(time) * setup;
if (alpha == 1) {
if (blend == MixBlend_Add) return current + value - setup;
return value;
}
// Mixing out uses sign of setup or current pose, else use sign of key.
if (direction == MixDirection_Out) {
switch (blend) {
case MixBlend_Setup:
return setup + (MathUtil::abs(value) * MathUtil::sign(setup) - setup) * alpha;
case MixBlend_First:
case MixBlend_Replace:
return current + (MathUtil::abs(value) * MathUtil::sign(current) - current) * alpha;
default:
break;
}
} else {
float s;
switch (blend) {
case MixBlend_Setup:
s = MathUtil::abs(setup) * MathUtil::sign(value);
return s + (value - s) * alpha;
case MixBlend_First:
case MixBlend_Replace:
s = MathUtil::abs(current) * MathUtil::sign(value);
return s + (value - s) * alpha;
default:
break;
}
}
return current + (value - setup) * alpha;
}
RTTI_IMPL(CurveTimeline2, CurveTimeline) RTTI_IMPL(CurveTimeline2, CurveTimeline)
CurveTimeline2::CurveTimeline2(size_t frameCount, size_t bezierCount) : CurveTimeline(frameCount, CurveTimeline2::CurveTimeline2(size_t frameCount, size_t bezierCount) : CurveTimeline(frameCount,

View File

@ -44,7 +44,7 @@ using namespace spine;
RTTI_IMPL(IkConstraintTimeline, CurveTimeline) RTTI_IMPL(IkConstraintTimeline, CurveTimeline)
IkConstraintTimeline::IkConstraintTimeline(size_t frameCount, size_t bezierCount, int ikConstraintIndex) IkConstraintTimeline::IkConstraintTimeline(size_t frameCount, size_t bezierCount, int ikConstraintIndex)
: CurveTimeline(frameCount, IkConstraintTimeline::ENTRIES, bezierCount), _ikConstraintIndex(ikConstraintIndex) { : CurveTimeline(frameCount, IkConstraintTimeline::ENTRIES, bezierCount), _constraintIndex(ikConstraintIndex) {
PropertyId ids[] = {((PropertyId) Property_IkConstraint << 32) | ikConstraintIndex}; PropertyId ids[] = {((PropertyId) Property_IkConstraint << 32) | ikConstraintIndex};
setPropertyIds(ids, 1); setPropertyIds(ids, 1);
} }
@ -54,7 +54,7 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time,
SP_UNUSED(lastTime); SP_UNUSED(lastTime);
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
IkConstraint *constraintP = skeleton._ikConstraints[_ikConstraintIndex]; IkConstraint *constraintP = skeleton._ikConstraints[_constraintIndex];
IkConstraint &constraint = *constraintP; IkConstraint &constraint = *constraintP;
if (!constraint.isActive()) return; if (!constraint.isActive()) return;

View File

@ -45,7 +45,7 @@ RTTI_IMPL(PathConstraintMixTimeline, CurveTimeline)
PathConstraintMixTimeline::PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex) PathConstraintMixTimeline::PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int pathConstraintIndex)
: CurveTimeline(frameCount, PathConstraintMixTimeline::ENTRIES, bezierCount), : CurveTimeline(frameCount, PathConstraintMixTimeline::ENTRIES, bezierCount),
_pathConstraintIndex(pathConstraintIndex) { _constraintIndex(pathConstraintIndex) {
PropertyId ids[] = {((PropertyId) Property_PathConstraintMix << 32) | pathConstraintIndex}; PropertyId ids[] = {((PropertyId) Property_PathConstraintMix << 32) | pathConstraintIndex};
setPropertyIds(ids, 1); setPropertyIds(ids, 1);
} }
@ -56,7 +56,7 @@ void PathConstraintMixTimeline::apply(Skeleton &skeleton, float lastTime, float
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
SP_UNUSED(direction); SP_UNUSED(direction);
PathConstraint *constraintP = skeleton._pathConstraints[_pathConstraintIndex]; PathConstraint *constraintP = skeleton._pathConstraints[_constraintIndex];
PathConstraint &constraint = *constraintP; PathConstraint &constraint = *constraintP;
if (!constraint.isActive()) return; if (!constraint.isActive()) return;

View File

@ -46,7 +46,7 @@ RTTI_IMPL(PathConstraintPositionTimeline, CurveTimeline1)
PathConstraintPositionTimeline::PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount, PathConstraintPositionTimeline::PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount,
int pathConstraintIndex) : CurveTimeline1(frameCount, int pathConstraintIndex) : CurveTimeline1(frameCount,
bezierCount), bezierCount),
_pathConstraintIndex( _constraintIndex(
pathConstraintIndex) { pathConstraintIndex) {
PropertyId ids[] = {((PropertyId) Property_PathConstraintPosition << 32) | pathConstraintIndex}; PropertyId ids[] = {((PropertyId) Property_PathConstraintPosition << 32) | pathConstraintIndex};
setPropertyIds(ids, 1); setPropertyIds(ids, 1);
@ -61,27 +61,6 @@ void PathConstraintPositionTimeline::apply(Skeleton &skeleton, float lastTime, f
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
SP_UNUSED(direction); SP_UNUSED(direction);
PathConstraint *constraintP = skeleton._pathConstraints[_pathConstraintIndex]; PathConstraint *constraint = skeleton._pathConstraints[_constraintIndex];
PathConstraint &constraint = *constraintP; if (constraint->_active) constraint->_position = getAbsoluteValue(time, alpha, blend, constraint->_position, constraint->_data._position);
if (!constraint.isActive()) return;
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
constraint._position = constraint._data._position;
return;
case MixBlend_First:
constraint._position += (constraint._data._position - constraint._position) * alpha;
return;
default:
return;
}
}
float position = getCurveValue(time);
if (blend == MixBlend_Setup)
constraint._position = constraint._data._position + (position - constraint._data._position) * alpha;
else
constraint._position += (position - constraint._position) * alpha;
} }

View File

@ -58,27 +58,7 @@ void PathConstraintSpacingTimeline::apply(Skeleton &skeleton, float lastTime, fl
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
SP_UNUSED(direction); SP_UNUSED(direction);
PathConstraint *constraintP = skeleton._pathConstraints[_pathConstraintIndex]; PathConstraint *constraint = skeleton._pathConstraints[_pathConstraintIndex];
PathConstraint &constraint = *constraintP; if (constraint->_active)
if (!constraint.isActive()) return; constraint->_spacing = getAbsoluteValue(time, alpha, blend, constraint->_spacing, constraint->_data._spacing);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
constraint._spacing = constraint._data._spacing;
return;
case MixBlend_First:
constraint._spacing += (constraint._data._spacing - constraint._spacing) * alpha;
return;
default:
return;
}
}
float spacing = getCurveValue(time);
if (blend == MixBlend_Setup)
constraint._spacing = constraint._data._spacing + (spacing - constraint._data._spacing) * alpha;
else
constraint._spacing += (spacing - constraint._spacing) * alpha;
} }

View File

@ -318,12 +318,12 @@ void PhysicsConstraint::update(Physics physics) {
float l = bone->_data.getLength(); float l = bone->_data.getLength();
switch (physics) { switch (physics) {
case Physics::none: case Physics::Physics_None:
return; return;
case Physics::reset: case Physics::Physics_Reset:
reset(); reset();
// Fall through. // Fall through.
case Physics::update: { case Physics::Physics_Update: {
_remaining += MathUtil::max(_skeleton.getTime() - _lastTime, 0.0f); _remaining += MathUtil::max(_skeleton.getTime() - _lastTime, 0.0f);
_lastTime = _skeleton.getTime(); _lastTime = _skeleton.getTime();
@ -416,7 +416,7 @@ void PhysicsConstraint::update(Physics physics) {
_cy = bone->_worldY; _cy = bone->_worldY;
break; break;
} }
case Physics::pose: { case Physics::Physics_Pose: {
if (x) bone->_worldX += _xOffset * mix * _data._x; if (x) bone->_worldX += _xOffset * mix * _data._x;
if (y) bone->_worldY += _yOffset * mix * _data._y; if (y) bone->_worldY += _yOffset * mix * _data._y;
break; break;
@ -458,7 +458,7 @@ void PhysicsConstraint::update(Physics physics) {
bone->_a *= s; bone->_a *= s;
bone->_c *= s; bone->_c *= s;
} }
if (physics != Physics::pose) { if (physics != Physics::Physics_Pose) {
_tx = l * bone->_a; _tx = l * bone->_a;
_ty = l * bone->_c; _ty = l * bone->_c;
} }

View File

@ -0,0 +1,102 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated July 28, 2023. Replaces all prior versions.
*
* Copyright (c) 2013-2023, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software or
* otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
* SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/PhysicsConstraintTimeline.h>
#include <spine/Event.h>
#include <spine/Skeleton.h>
#include <spine/Animation.h>
#include <spine/Property.h>
#include <spine/Slot.h>
#include <spine/SlotData.h>
#include <spine/PhysicsConstraint.h>
#include <cfloat>
using namespace spine;
RTTI_IMPL(PhysicsConstraintTimeline, CurveTimeline)
RTTI_IMPL(PhysicsConstraintInertiaTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintStrengthTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintDampingTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintMassTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintWindTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintGravityTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintMixTimeline, PhysicsConstraintTimeline)
RTTI_IMPL(PhysicsConstraintResetTimeline, Timeline)
PhysicsConstraintTimeline::PhysicsConstraintTimeline(size_t frameCount, size_t bezierCount,
int constraintIndex, Property property) : CurveTimeline1(frameCount, bezierCount),
_constraintIndex(constraintIndex) {
PropertyId ids[] = {((PropertyId) property << 32) | constraintIndex};
setPropertyIds(ids, 1);
}
void PhysicsConstraintTimeline::apply(Skeleton &skeleton, float, float time, Vector<Event *> *,
float alpha, MixBlend blend, MixDirection) {
if (_constraintIndex == -1) {
float value = time >= _frames[0] ?getCurveValue(time) : 0;
Vector<PhysicsConstraint*> &physicsConstraints = skeleton.getPhysicsConstraints();
for (size_t i = 0; i < physicsConstraints.size(); i++) {
PhysicsConstraint *constraint = physicsConstraints[i];
if (constraint->_active && global(constraint->_data))
set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint), value));
}
} else {
PhysicsConstraint *constraint = skeleton.getPhysicsConstraints()[_constraintIndex];
if (constraint->_active) set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint)));
}
}
void PhysicsConstraintResetTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *, float alpha, MixBlend blend, MixDirection direction) {
PhysicsConstraint *constraint = nullptr;
if (_constraintIndex != -1) {
constraint = skeleton.getPhysicsConstraints()[_constraintIndex];
if (!constraint->_active) return;
}
if (lastTime > time) { // Apply after lastTime for looped animations.
apply(skeleton, lastTime, FLT_MAX, nullptr, alpha, blend, direction);
lastTime = -1;
} else if (lastTime >= _frames[_frames.size() - 1]) // Last time is after last frame.
return;
if (time < _frames[0]) return;
if (lastTime < _frames[0] || time >= _frames[Animation::search(_frames, lastTime) + 1]) {
if (constraint != nullptr)
constraint->reset();
else {
Vector<PhysicsConstraint *> &physicsConstraints = skeleton.getPhysicsConstraints();
for (size_t i = 0; i < physicsConstraints.size(); i++) {
if (constraint->_active) constraint->reset();
}
}
}
}

View File

@ -55,30 +55,5 @@ void RotateTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
SP_UNUSED(direction); SP_UNUSED(direction);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->isActive()) bone->_rotation = getRelativeValue(time, alpha, blend, bone->_rotation, bone->getData()._rotation);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_rotation = bone->_data._rotation;
return;
case MixBlend_First:
bone->_rotation += (bone->_data._rotation - bone->_rotation) * alpha;
default: {
}
}
return;
}
float r = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
bone->_rotation = bone->_data._rotation + r * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
r += bone->_data._rotation - bone->_rotation;
case MixBlend_Add:
bone->_rotation += r * alpha;
}
} }

View File

@ -170,60 +170,7 @@ void ScaleXTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_scaleX = getScaleValue(time, alpha, blend, direction, bone->_scaleX, bone->_data._scaleX);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_scaleX = bone->_data._scaleX;
return;
case MixBlend_First:
bone->_scaleX += (bone->_data._scaleX - bone->_scaleX) * alpha;
default: {
}
}
return;
}
float x = getCurveValue(time) * bone->_data._scaleX;
if (alpha == 1) {
if (blend == MixBlend_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 == MixDirection_Out) {
switch (blend) {
case MixBlend_Setup:
bx = bone->_data._scaleX;
bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bx = bone->_scaleX;
bone->_scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha;
break;
case MixBlend_Add:
bone->_scaleX += (x - bone->_data._scaleX) * alpha;
}
} else {
switch (blend) {
case MixBlend_Setup:
bx = MathUtil::abs(bone->_data._scaleX) * MathUtil::sign(x);
bone->_scaleX = bx + (x - bx) * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bx = MathUtil::abs(bone->_scaleX) * MathUtil::sign(x);
bone->_scaleX = bx + (x - bx) * alpha;
break;
case MixBlend_Add:
bone->_scaleX += (x - bone->_data._scaleX) * alpha;
}
}
}
} }
RTTI_IMPL(ScaleYTimeline, CurveTimeline1) RTTI_IMPL(ScaleYTimeline, CurveTimeline1)
@ -243,58 +190,5 @@ void ScaleYTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_scaleY = getScaleValue(time, alpha, blend, direction, bone->_scaleX, bone->_data._scaleY);
}
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_scaleY = bone->_data._scaleY;
return;
case MixBlend_First:
bone->_scaleY += (bone->_data._scaleY - bone->_scaleY) * alpha;
default: {
}
}
return;
}
float y = getCurveValue(time) * bone->_data._scaleY;
if (alpha == 1) {
if (blend == MixBlend_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 == MixDirection_Out) {
switch (blend) {
case MixBlend_Setup:
by = bone->_data._scaleY;
bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
by = bone->_scaleY;
bone->_scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha;
break;
case MixBlend_Add:
bone->_scaleY += (y - bone->_data._scaleY) * alpha;
}
} else {
switch (blend) {
case MixBlend_Setup:
by = MathUtil::abs(bone->_data._scaleY) * MathUtil::sign(y);
bone->_scaleY = by + (y - by) * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
by = MathUtil::abs(bone->_scaleY) * MathUtil::sign(y);
bone->_scaleY = by + (y - by) * alpha;
break;
case MixBlend_Add:
bone->_scaleY += (y - bone->_data._scaleY) * alpha;
}
}
}
}

View File

@ -136,33 +136,7 @@ void ShearXTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
SP_UNUSED(direction); SP_UNUSED(direction);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_shearX = getRelativeValue(time, alpha, blend, bone->_shearX, bone->_data._shearX);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_shearX = bone->_data._shearX;
return;
case MixBlend_First:
bone->_shearX += (bone->_data._shearX - bone->_shearX) * alpha;
default: {
}
}
return;
}
float x = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
bone->_shearX = bone->_data._shearX + x * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bone->_shearX += (bone->_data._shearX + x - bone->_shearX) * alpha;
break;
case MixBlend_Add:
bone->_shearX += x * alpha;
}
} }
RTTI_IMPL(ShearYTimeline, CurveTimeline1) RTTI_IMPL(ShearYTimeline, CurveTimeline1)
@ -184,31 +158,5 @@ void ShearYTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
SP_UNUSED(direction); SP_UNUSED(direction);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_shearY = getRelativeValue(time, alpha, blend, bone->_shearX, bone->_data._shearY);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_shearY = bone->_data._shearY;
return;
case MixBlend_First:
bone->_shearY += (bone->_data._shearY - bone->_shearY) * alpha;
default: {
}
}
return;
}
float y = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
bone->_shearY = bone->_data._shearY + y * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bone->_shearY += (bone->_data._shearY + y - bone->_shearY) * alpha;
break;
case MixBlend_Add:
bone->_shearY += y * alpha;
}
} }

View File

@ -70,5 +70,4 @@ namespace spine {
float Timeline::getDuration() { float Timeline::getDuration() {
return _frames[_frames.size() - getFrameEntries()]; return _frames[_frames.size() - getFrameEntries()];
} }
}// namespace spine }// namespace spine

View File

@ -47,7 +47,7 @@ TransformConstraintTimeline::TransformConstraintTimeline(size_t frameCount, size
int transformConstraintIndex) : CurveTimeline(frameCount, int transformConstraintIndex) : CurveTimeline(frameCount,
TransformConstraintTimeline::ENTRIES, TransformConstraintTimeline::ENTRIES,
bezierCount), bezierCount),
_transformConstraintIndex( _constraintIndex(
transformConstraintIndex) { transformConstraintIndex) {
PropertyId ids[] = {((PropertyId) Property_TransformConstraint << 32) | transformConstraintIndex}; PropertyId ids[] = {((PropertyId) Property_TransformConstraint << 32) | transformConstraintIndex};
setPropertyIds(ids, 1); setPropertyIds(ids, 1);
@ -59,7 +59,7 @@ void TransformConstraintTimeline::apply(Skeleton &skeleton, float lastTime, floa
SP_UNUSED(pEvents); SP_UNUSED(pEvents);
SP_UNUSED(direction); SP_UNUSED(direction);
TransformConstraint *constraintP = skeleton._transformConstraints[_transformConstraintIndex]; TransformConstraint *constraintP = skeleton._transformConstraints[_constraintIndex];
TransformConstraint &constraint = *constraintP; TransformConstraint &constraint = *constraintP;
if (!constraint.isActive()) return; if (!constraint.isActive()) return;

View File

@ -136,33 +136,7 @@ void TranslateXTimeline::apply(Skeleton &skeleton, float lastTime, float time, V
SP_UNUSED(direction); SP_UNUSED(direction);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_x = getRelativeValue(time, alpha, blend, bone->_x, bone->_data._x);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_x = bone->_data._x;
return;
case MixBlend_First:
bone->_x += (bone->_data._x - bone->_x) * alpha;
default: {
}
}
return;
}
float x = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
bone->_x = bone->_data._x + x * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bone->_x += (bone->_data._x + x - bone->_x) * alpha;
break;
case MixBlend_Add:
bone->_x += x * alpha;
}
} }
RTTI_IMPL(TranslateYTimeline, CurveTimeline1) RTTI_IMPL(TranslateYTimeline, CurveTimeline1)
@ -184,31 +158,5 @@ void TranslateYTimeline::apply(Skeleton &skeleton, float lastTime, float time, V
SP_UNUSED(direction); SP_UNUSED(direction);
Bone *bone = skeleton._bones[_boneIndex]; Bone *bone = skeleton._bones[_boneIndex];
if (!bone->_active) return; if (bone->_active) bone->_y = getRelativeValue(time, alpha, blend, bone->_y, bone->_data._y);
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
bone->_y = bone->_data._y;
return;
case MixBlend_First:
bone->_y += (bone->_data._y - bone->_y) * alpha;
default: {
}
}
return;
}
float y = getCurveValue(time);
switch (blend) {
case MixBlend_Setup:
bone->_y = bone->_data._y + y * alpha;
break;
case MixBlend_First:
case MixBlend_Replace:
bone->_y += (bone->_data._y + y - bone->_y) * alpha;
break;
case MixBlend_Add:
bone->_y += y * alpha;
}
} }

View File

@ -124,7 +124,7 @@ void spineboy(SkeletonData *skeletonData, Atlas *atlas) {
skeleton->setToSetupPose(); skeleton->setToSetupPose();
skeleton->setPosition(320, 590); skeleton->setPosition(320, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
Slot *headSlot = skeleton->findSlot("head"); Slot *headSlot = skeleton->findSlot("head");
@ -227,7 +227,7 @@ void ikDemo(SkeletonData *skeletonData, Atlas *atlas) {
// Calculate final world transform with the // Calculate final world transform with the
// crosshair bone set to the mouse cursor // crosshair bone set to the mouse cursor
// position. // position.
drawable.skeleton->updateWorldTransform(Physics::update); drawable.skeleton->updateWorldTransform(Physics_Update);
window.clear(); window.clear();
window.draw(drawable); window.draw(drawable);
@ -246,7 +246,7 @@ void goblins(SkeletonData *skeletonData, Atlas *atlas) {
skeleton->setSkin("goblingirl"); skeleton->setSkin("goblingirl");
skeleton->setSlotsToSetupPose(); skeleton->setSlotsToSetupPose();
skeleton->setPosition(320, 590); skeleton->setPosition(320, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "walk", true); drawable.state->setAnimation(0, "walk", true);
@ -281,7 +281,7 @@ void raptor(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 590); skeleton->setPosition(320, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "walk", true); drawable.state->setAnimation(0, "walk", true);
drawable.state->addAnimation(1, "gun-grab", false, 2); drawable.state->addAnimation(1, "gun-grab", false, 2);
@ -314,7 +314,7 @@ void tank(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(500, 590); skeleton->setPosition(500, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "drive", true); drawable.state->setAnimation(0, "drive", true);
@ -345,7 +345,7 @@ void vine(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 590); skeleton->setPosition(320, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "grow", true); drawable.state->setAnimation(0, "grow", true);
@ -378,7 +378,7 @@ void stretchyman(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(100, 590); skeleton->setPosition(100, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "sneak", true); drawable.state->setAnimation(0, "sneak", true);
@ -411,7 +411,7 @@ void stretchymanStrechyIk(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable->skeleton; Skeleton *skeleton = drawable->skeleton;
skeleton->setPosition(100, 590); skeleton->setPosition(100, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable->state->setAnimation(0, "sneak", true); drawable->state->setAnimation(0, "sneak", true);
@ -445,7 +445,7 @@ void coin(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 320); skeleton->setPosition(320, 320);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "animation", true); drawable.state->setAnimation(0, "animation", true);
@ -479,7 +479,7 @@ void dragon(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 320); skeleton->setPosition(320, 320);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "flying", true); drawable.state->setAnimation(0, "flying", true);
@ -513,7 +513,7 @@ void owl(SkeletonData *skeletonData, Atlas *atlas) {
Skeleton *skeleton = drawable.skeleton; Skeleton *skeleton = drawable.skeleton;
skeleton->setPosition(320, 400); skeleton->setPosition(320, 400);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "idle", true); drawable.state->setAnimation(0, "idle", true);
drawable.state->setAnimation(1, "blink", true); drawable.state->setAnimation(1, "blink", true);
@ -588,7 +588,7 @@ void mixAndMatch(SkeletonData *skeletonData, Atlas *atlas) {
skeleton->setSlotsToSetupPose(); skeleton->setSlotsToSetupPose();
skeleton->setPosition(320, 590); skeleton->setPosition(320, 590);
skeleton->updateWorldTransform(Physics::update); skeleton->updateWorldTransform(Physics_Update);
drawable.state->setAnimation(0, "dance", true); drawable.state->setAnimation(0, "dance", true);
@ -626,7 +626,7 @@ void test(SkeletonData *skeletonData, Atlas *atlas) {
for (int i = 0; i < 1; i++) { for (int i = 0; i < 1; i++) {
animationState.update(d); animationState.update(d);
animationState.apply(skeleton); animationState.apply(skeleton);
skeleton.updateWorldTransform(Physics::update); skeleton.updateWorldTransform(Physics_Update);
d += 0.1f; d += 0.1f;
} }
} }

View File

@ -104,8 +104,7 @@ int main(void) {
AnimationStateData stateData(skeletonData); AnimationStateData stateData(skeletonData);
SkeletonDrawable drawable(skeletonData, &stateData); SkeletonDrawable drawable(skeletonData, &stateData);
drawable.skeleton->getRootBone()->update(Physics::update); drawable.skeleton->updateWorldTransform(Physics_Update);
drawable.skeleton->updateWorldTransform(Physics::update);
drawable.skeleton->setPosition(320, 960); drawable.skeleton->setPosition(320, 960);
if (animation.length() > 0) drawable.state->setAnimation(0, animation, true); if (animation.length() > 0) drawable.state->setAnimation(0, animation, true);
if (skin.length() > 0) drawable.skeleton->setSkin(skin); if (skin.length() > 0) drawable.skeleton->setSkin(skin);

View File

@ -52,7 +52,7 @@ namespace spine {
~SkeletonDrawable(); ~SkeletonDrawable();
void update(float deltaTime, Physics physics = Physics::update); void update(float deltaTime, Physics physics = Physics_Update);
virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const; virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;