mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
Added Animation.
OOP in C is a cold, dark place.
This commit is contained in:
parent
de53ad3f4f
commit
40835845be
@ -1,14 +1,16 @@
|
||||
#include "SfmlRegionAttachment.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void _RegionAttachment_init (RegionAttachment* attachment, const char* name);
|
||||
|
||||
void SfmlRegionAttachment_dispose (Attachment* attachment) {
|
||||
SfmlRegionAttachment* this = (SfmlRegionAttachment*)attachment;
|
||||
RegionAttachment_dispose(&this->super);
|
||||
/* SfmlRegionAttachment* this = (SfmlRegionAttachment*)attachment; */
|
||||
/* dispose something */
|
||||
}
|
||||
|
||||
SfmlRegionAttachment* SfmlRegionAttachment_create (const char* name) {
|
||||
SfmlRegionAttachment* this = calloc(1, sizeof(SfmlRegionAttachment));
|
||||
RegionAttachment_init(&this->super, name);
|
||||
_RegionAttachment_init(&this->super, name);
|
||||
((Attachment*)this)->_dispose = SfmlRegionAttachment_dispose;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
#include "SfmlSkeleton.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void _Skeleton_init (Skeleton* this, SkeletonData* data);
|
||||
|
||||
void SfmlSkeleton_dispose (Skeleton* skeleton) {
|
||||
/* SfmlSkeleton* this = (SfmlSkeleton*)skeleton; */
|
||||
}
|
||||
|
||||
Skeleton* Skeleton_create (SkeletonData* data) {
|
||||
SfmlSkeleton* this = calloc(1, sizeof(SfmlSkeleton));
|
||||
Skeleton_init(&this->super, data);
|
||||
_Skeleton_init(&this->super, data);
|
||||
this->super._dispose = SfmlSkeleton_dispose;
|
||||
return &this->super;
|
||||
}
|
||||
|
||||
403
spine-c/src/spine/Animation.c
Normal file
403
spine-c/src/spine/Animation.c
Normal file
@ -0,0 +1,403 @@
|
||||
#include <spine/Animation.h>
|
||||
#include <spine/util.h>
|
||||
|
||||
Animation* Animation_create () {
|
||||
Animation* this = calloc(1, sizeof(Animation));
|
||||
return this;
|
||||
}
|
||||
|
||||
void Animation_dispose (Animation* this) {
|
||||
int i;
|
||||
for (i = 0; i < this->timelineCount; ++i)
|
||||
Timeline_dispose(this->timelines[i]);
|
||||
FREE(this->timelines)
|
||||
FREE(this)
|
||||
}
|
||||
|
||||
void Animation_apply (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop) {
|
||||
}
|
||||
|
||||
void Animation_mix (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop, float alpha) {
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
void Timeline_dispose (Timeline* this) {
|
||||
this->_dispose(this);
|
||||
}
|
||||
|
||||
void Timeline_apply (const Timeline *this, Skeleton* skeleton, float time, float alpha) {
|
||||
this->_apply(this, skeleton, time, alpha);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const float CURVE_LINEAR = 0;
|
||||
static const float CURVE_STEPPED = -1;
|
||||
static const int CURVE_SEGMENTS = 10;
|
||||
|
||||
void _CurveTimeline_init (CurveTimeline* this, int frameCount) {
|
||||
this->curves = calloc(1, sizeof(float) * (frameCount - 1) * 6);
|
||||
}
|
||||
|
||||
void _CurveTimeline_deinit (CurveTimeline* this) {
|
||||
FREE(this->curves)
|
||||
}
|
||||
|
||||
void CurveTimeline_setLinear (CurveTimeline* this, int frameIndex) {
|
||||
this->curves[frameIndex * 6] = CURVE_LINEAR;
|
||||
}
|
||||
|
||||
void CurveTimeline_setStepped (CurveTimeline* this, int frameIndex) {
|
||||
this->curves[frameIndex * 6] = CURVE_STEPPED;
|
||||
}
|
||||
|
||||
void CurveTimeline_setCurve (CurveTimeline* this, int frameIndex, float cx1, float cy1, float cx2, float cy2) {
|
||||
float subdiv_step = 1.0f / CURVE_SEGMENTS;
|
||||
float subdiv_step2 = subdiv_step * subdiv_step;
|
||||
float subdiv_step3 = subdiv_step2 * subdiv_step;
|
||||
float pre1 = 3 * subdiv_step;
|
||||
float pre2 = 3 * subdiv_step2;
|
||||
float pre4 = 6 * subdiv_step2;
|
||||
float pre5 = 6 * subdiv_step3;
|
||||
float tmp1x = -cx1 * 2 + cx2;
|
||||
float tmp1y = -cy1 * 2 + cy2;
|
||||
float tmp2x = (cx1 - cx2) * 3 + 1;
|
||||
float tmp2y = (cy1 - cy2) * 3 + 1;
|
||||
int i = frameIndex * 6;
|
||||
this->curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
|
||||
this->curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
|
||||
this->curves[i + 2] = tmp1x * pre4 + tmp2x * pre5;
|
||||
this->curves[i + 3] = tmp1y * pre4 + tmp2y * pre5;
|
||||
this->curves[i + 4] = tmp2x * pre5;
|
||||
this->curves[i + 5] = tmp2y * pre5;
|
||||
}
|
||||
|
||||
float CurveTimeline_getCurvePercent (CurveTimeline* this, int frameIndex, float percent) {
|
||||
int curveIndex = frameIndex * 6;
|
||||
float dfx = this->curves[curveIndex];
|
||||
if (dfx == CURVE_LINEAR) return percent;
|
||||
if (dfx == CURVE_STEPPED) return 0;
|
||||
float dfy = this->curves[curveIndex + 1];
|
||||
float ddfx = this->curves[curveIndex + 2];
|
||||
float ddfy = this->curves[curveIndex + 3];
|
||||
float dddfx = this->curves[curveIndex + 4];
|
||||
float dddfy = this->curves[curveIndex + 5];
|
||||
float x = dfx, y = dfy;
|
||||
int i = CURVE_SEGMENTS - 2;
|
||||
while (1) {
|
||||
if (x >= percent) {
|
||||
float lastX = x - dfx;
|
||||
float lastY = y - dfy;
|
||||
return lastY + (y - lastY) * (percent - lastX) / (x - lastX);
|
||||
}
|
||||
if (i == 0) break;
|
||||
i--;
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
x += dfx;
|
||||
y += dfy;
|
||||
}
|
||||
return y + (1 - y) * (percent - x) / (1 - x); /* Last point is 1,1. */
|
||||
}
|
||||
|
||||
/** @param target After the first and before the last entry. */
|
||||
static int binarySearch (float *values, int valuesLength, float target, int step) {
|
||||
int low = 0;
|
||||
int high = valuesLength / step - 2;
|
||||
if (high == 0) return step;
|
||||
int current = high >> 1;
|
||||
while (1) {
|
||||
if (values[(current + 1) * step] <= target)
|
||||
low = current + 1;
|
||||
else
|
||||
high = current;
|
||||
if (low == high) return (low + 1) * step;
|
||||
current = (low + high) >> 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*static int linearSearch (float *values, int valuesLength, float target, int step) {
|
||||
int i, last = valuesLength - step;
|
||||
for (i = 0; i <= last; i += step) {
|
||||
if (values[i] <= target) continue;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
/**/
|
||||
|
||||
void _BaseTimeline_dispose (Timeline* timeline) {
|
||||
struct BaseTimeline* this = (struct BaseTimeline*)timeline;
|
||||
_CurveTimeline_deinit(&this->super);
|
||||
FREE(this->frames);
|
||||
FREE(this);
|
||||
}
|
||||
|
||||
struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) {
|
||||
struct BaseTimeline* this = calloc(1, sizeof(struct BaseTimeline));
|
||||
((Timeline*)this)->_dispose = _BaseTimeline_dispose;
|
||||
|
||||
CAST(int, this->frameCount) = frameCount;
|
||||
CAST(float*, this->frames) = calloc(1, sizeof(float) * frameCount * frameSize);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const int ROTATE_LAST_FRAME_TIME = -2;
|
||||
static const int ROTATE_FRAME_VALUE = 1;
|
||||
|
||||
void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
|
||||
RotateTimeline* this = (RotateTimeline*)timeline;
|
||||
|
||||
if (time < this->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[this->boneIndex];
|
||||
|
||||
if (time >= this->frames[this->frameCount - 2]) { /* Time is after last frame. */
|
||||
float amount = bone->data->rotation + this->frames[this->frameCount - 1] - bone->rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone->rotation += amount * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(this->frames, this->frameCount, time, 2);
|
||||
float lastFrameValue = this->frames[frameIndex - 1];
|
||||
float frameTime = this->frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime);
|
||||
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
float amount = this->frames[frameIndex + ROTATE_FRAME_VALUE] - lastFrameValue;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
amount = bone->data->rotation + (lastFrameValue + amount * percent) - bone->rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone->rotation += amount * alpha;
|
||||
}
|
||||
|
||||
RotateTimeline* RotateTimeline_create (int frameCount) {
|
||||
RotateTimeline* this = _BaseTimeline_create(frameCount, 2);
|
||||
((Timeline*)this)->_apply = _RotateTimeline_apply;
|
||||
_CurveTimeline_init(&this->super, frameCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
void RotateTimeline_setFrame (RotateTimeline* this, int frameIndex, float time, float angle) {
|
||||
frameIndex *= 2;
|
||||
this->frames[frameIndex] = time;
|
||||
this->frames[frameIndex + 1] = angle;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const int TRANSLATE_LAST_FRAME_TIME = -3;
|
||||
static const int TRANSLATE_FRAME_X = 1;
|
||||
static const int TRANSLATE_FRAME_Y = 2;
|
||||
|
||||
void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
|
||||
TranslateTimeline* this = (TranslateTimeline*)timeline;
|
||||
|
||||
if (time < this->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[this->boneIndex];
|
||||
|
||||
if (time >= this->frames[this->frameCount - 3]) { /* Time is after last frame. */
|
||||
bone->x += (bone->data->x + this->frames[this->frameCount - 2] - bone->x) * alpha;
|
||||
bone->y += (bone->data->y + this->frames[this->frameCount - 1] - bone->y) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(this->frames, this->frameCount, time, 3);
|
||||
float lastFrameX = this->frames[frameIndex - 2];
|
||||
float lastFrameY = this->frames[frameIndex - 1];
|
||||
float frameTime = this->frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime);
|
||||
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
bone->x += (bone->data->x + lastFrameX + (this->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent - bone->x)
|
||||
* alpha;
|
||||
bone->y += (bone->data->y + lastFrameY + (this->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent - bone->y)
|
||||
* alpha;
|
||||
}
|
||||
|
||||
TranslateTimeline* TranslateTimeline_create (int frameCount) {
|
||||
TranslateTimeline* this = _BaseTimeline_create(frameCount, 3);
|
||||
((Timeline*)this)->_apply = _TranslateTimeline_apply;
|
||||
_CurveTimeline_init(&this->super, frameCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
void TranslateTimeline_setFrame (TranslateTimeline* this, int frameIndex, float time, float x, float y) {
|
||||
frameIndex *= 3;
|
||||
this->frames[frameIndex] = time;
|
||||
this->frames[frameIndex + 1] = x;
|
||||
this->frames[frameIndex + 2] = y;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
|
||||
ScaleTimeline* this = (ScaleTimeline*)timeline;
|
||||
|
||||
if (time < this->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Bone *bone = skeleton->bones[this->boneIndex];
|
||||
if (time >= this->frames[this->frameCount - 3]) { /* Time is after last frame. */
|
||||
bone->scaleX += (bone->data->scaleX - 1 + this->frames[this->frameCount - 2] - bone->scaleX) * alpha;
|
||||
bone->scaleY += (bone->data->scaleY - 1 + this->frames[this->frameCount - 1] - bone->scaleY) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(this->frames, this->frameCount, time, 3);
|
||||
float lastFrameX = this->frames[frameIndex - 2];
|
||||
float lastFrameY = this->frames[frameIndex - 1];
|
||||
float frameTime = this->frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + TRANSLATE_LAST_FRAME_TIME] - frameTime);
|
||||
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
bone->scaleX += (bone->data->scaleX - 1 + lastFrameX + (this->frames[frameIndex + TRANSLATE_FRAME_X] - lastFrameX) * percent
|
||||
- bone->scaleX) * alpha;
|
||||
bone->scaleY += (bone->data->scaleY - 1 + lastFrameY + (this->frames[frameIndex + TRANSLATE_FRAME_Y] - lastFrameY) * percent
|
||||
- bone->scaleY) * alpha;
|
||||
}
|
||||
|
||||
ScaleTimeline* ScaleTimeline_create (int frameCount) {
|
||||
ScaleTimeline* this = _BaseTimeline_create(frameCount, 3);
|
||||
((Timeline*)this)->_apply = _ScaleTimeline_apply;
|
||||
_CurveTimeline_init(&this->super, frameCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
void ScaleTimeline_setFrame (ScaleTimeline* this, int frameIndex, float time, float x, float y) {
|
||||
TranslateTimeline_setFrame(this, frameIndex, time, x, y);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static const int COLOR_LAST_FRAME_TIME = -5;
|
||||
static const int COLOR_FRAME_R = 1;
|
||||
static const int COLOR_FRAME_G = 2;
|
||||
static const int COLOR_FRAME_B = 3;
|
||||
static const int COLOR_FRAME_A = 4;
|
||||
|
||||
void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
|
||||
ColorTimeline* this = (ColorTimeline*)timeline;
|
||||
|
||||
if (time < this->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
Slot *slot = skeleton->slots[this->slotIndex];
|
||||
|
||||
if (time >= this->frames[this->frameCount - 5]) { /* Time is after last frame. */
|
||||
int i = this->frameCount - 1;
|
||||
slot->r = this->frames[i - 3];
|
||||
slot->g = this->frames[i - 2];
|
||||
slot->b = this->frames[i - 1];
|
||||
slot->a = this->frames[i];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpolate between the last frame and the current frame. */
|
||||
int frameIndex = binarySearch(this->frames, this->frameCount, time, 5);
|
||||
float lastFrameR = this->frames[frameIndex - 4];
|
||||
float lastFrameG = this->frames[frameIndex - 3];
|
||||
float lastFrameB = this->frames[frameIndex - 2];
|
||||
float lastFrameA = this->frames[frameIndex - 1];
|
||||
float frameTime = this->frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (this->frames[frameIndex + COLOR_LAST_FRAME_TIME] - frameTime);
|
||||
percent = CurveTimeline_getCurvePercent(&this->super, frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
float r = lastFrameR + (this->frames[frameIndex + COLOR_FRAME_R] - lastFrameR) * percent;
|
||||
float g = lastFrameG + (this->frames[frameIndex + COLOR_FRAME_G] - lastFrameG) * percent;
|
||||
float b = lastFrameB + (this->frames[frameIndex + COLOR_FRAME_B] - lastFrameB) * percent;
|
||||
float a = lastFrameA + (this->frames[frameIndex + COLOR_FRAME_A] - lastFrameA) * percent;
|
||||
if (alpha < 1) {
|
||||
slot->r += (r - slot->r) * alpha;
|
||||
slot->g += (g - slot->g) * alpha;
|
||||
slot->b += (b - slot->b) * alpha;
|
||||
slot->a += (a - slot->a) * alpha;
|
||||
} else {
|
||||
slot->r = r;
|
||||
slot->g = g;
|
||||
slot->b = b;
|
||||
slot->a = a;
|
||||
}
|
||||
}
|
||||
|
||||
ColorTimeline* ColorTimeline_create (int frameCount) {
|
||||
ColorTimeline* this = (ColorTimeline*)_BaseTimeline_create(frameCount, 5);
|
||||
((Timeline*)this)->_apply = _ColorTimeline_apply;
|
||||
_CurveTimeline_init(&this->super, frameCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
void ColorTimeline_setFrame (ColorTimeline* this, int frameIndex, float time, float r, float g, float b, float a) {
|
||||
frameIndex *= 5;
|
||||
this->frames[frameIndex] = time;
|
||||
this->frames[frameIndex + 1] = r;
|
||||
this->frames[frameIndex + 2] = g;
|
||||
this->frames[frameIndex + 3] = b;
|
||||
this->frames[frameIndex + 4] = a;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
void _AttachmentTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha) {
|
||||
AttachmentTimeline* this = (AttachmentTimeline*)timeline;
|
||||
|
||||
if (time < this->frames[0]) return; /* Time is before first frame. */
|
||||
|
||||
int frameIndex;
|
||||
if (time >= this->frames[this->frameCount - 1]) /* Time is after last frame. */
|
||||
frameIndex = this->frameCount - 1;
|
||||
else
|
||||
frameIndex = binarySearch(this->frames, this->frameCount, time, 1) - 1;
|
||||
|
||||
const char* attachmentName = this->attachmentNames[frameIndex];
|
||||
Slot_setAttachment(skeleton->slots[this->slotIndex],
|
||||
attachmentName ? Skeleton_getAttachmentForSlotIndex(skeleton, this->slotIndex, attachmentName) : 0);
|
||||
}
|
||||
|
||||
void _AttachmentTimeline_dispose (Timeline* timeline) {
|
||||
AttachmentTimeline* this = (AttachmentTimeline*)timeline;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < this->frameCount; ++i)
|
||||
FREE(this->attachmentNames[i])
|
||||
FREE(this->attachmentNames)
|
||||
|
||||
_BaseTimeline_dispose(timeline);
|
||||
}
|
||||
|
||||
AttachmentTimeline* AttachmentTimeline_create (int frameCount) {
|
||||
AttachmentTimeline* this = (AttachmentTimeline*)_BaseTimeline_create(frameCount, 1);
|
||||
((Timeline*)this)->_dispose = _AttachmentTimeline_dispose;
|
||||
((Timeline*)this)->_apply = _AttachmentTimeline_apply;
|
||||
CAST(char*, this->attachmentNames) = calloc(1, sizeof(char*) * frameCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
void AttachmentTimeline_setFrame (AttachmentTimeline* this, int frameIndex, float time, const char* attachmentName) {
|
||||
this->frames[frameIndex] = time;
|
||||
FREE(this->attachmentNames[frameIndex])
|
||||
if (attachmentName)
|
||||
MALLOC_STR(this->attachmentNames[frameIndex], attachmentName)
|
||||
else
|
||||
this->attachmentNames[frameIndex] = 0;
|
||||
}
|
||||
114
spine-c/src/spine/Animation.h
Normal file
114
spine-c/src/spine/Animation.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef SPINE_ANIMATION_H_
|
||||
#define SPINE_ANIMATION_H_
|
||||
|
||||
#include <spine/Skeleton.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace spine {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct Timeline Timeline;
|
||||
|
||||
typedef struct {
|
||||
int timelineCount;
|
||||
Timeline** timelines;
|
||||
|
||||
float duration;
|
||||
} Animation;
|
||||
|
||||
Animation* Animation_create ();
|
||||
void Animation_dispose (Animation* animation);
|
||||
|
||||
void Animation_apply (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop);
|
||||
void Animation_mix (const Animation* animation, Skeleton* skeleton, float time, int/*bool*/loop, float alpha);
|
||||
|
||||
/**/
|
||||
|
||||
struct Timeline {
|
||||
void (*_apply) (const Timeline* timeline, Skeleton* skeleton, float time, float alpha);
|
||||
void (*_dispose) (Timeline* timeline);
|
||||
};
|
||||
|
||||
void Timeline_dispose (Timeline* timeline);
|
||||
void Timeline_apply (const Timeline* timeline, Skeleton* skeleton, float time, float alpha);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
Timeline super;
|
||||
float* curves; /* dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... */
|
||||
} CurveTimeline;
|
||||
|
||||
void CurveTimeline_setLinear (CurveTimeline* timeline, int frameIndex);
|
||||
void CurveTimeline_setStepped (CurveTimeline* timeline, int frameIndex);
|
||||
|
||||
/** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
||||
* cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
||||
* the difference between the keyframe's values. */
|
||||
void CurveTimeline_setCurve (CurveTimeline* timeline, int frameIndex, float cx1, float cy1, float cx2, float cy2);
|
||||
float CurveTimeline_getCurvePercent (CurveTimeline* timeline, int frameIndex, float percent);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline {
|
||||
CurveTimeline super;
|
||||
int const frameCount;
|
||||
float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
|
||||
int boneIndex;
|
||||
} RotateTimeline;
|
||||
|
||||
RotateTimeline* RotateTimeline_create (int frameCount);
|
||||
|
||||
void RotateTimeline_setFrame (RotateTimeline* timeline, int frameIndex, float time, float angle);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline TranslateTimeline;
|
||||
|
||||
TranslateTimeline* TranslateTimeline_create (int frameCount);
|
||||
|
||||
void TranslateTimeline_setFrame (TranslateTimeline* timeline, int frameIndex, float time, float x, float y);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct BaseTimeline ScaleTimeline;
|
||||
|
||||
ScaleTimeline* ScaleTimeline_create (int frameCount);
|
||||
|
||||
void ScaleTimeline_setFrame (ScaleTimeline* timeline, int frameIndex, float time, float x, float y);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
CurveTimeline super;
|
||||
int const frameCount;
|
||||
float* const frames; /* time, r, g, b, a, ... */
|
||||
int slotIndex;
|
||||
} ColorTimeline;
|
||||
|
||||
ColorTimeline* ColorTimeline_create (int frameCount);
|
||||
|
||||
void ColorTimeline_setFrame (ColorTimeline* timeline, int frameIndex, float time, float r, float g, float b, float a);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
Timeline super;
|
||||
int const frameCount;
|
||||
float* const frames; /* time, ... */
|
||||
int slotIndex;
|
||||
const char** const attachmentNames;
|
||||
} AttachmentTimeline;
|
||||
|
||||
AttachmentTimeline* AttachmentTimeline_create (int frameCount);
|
||||
|
||||
/** @param attachmentName May be 0. */
|
||||
void AttachmentTimeline_setFrame (AttachmentTimeline* timeline, int frameIndex, float time, const char* attachmentName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SPINE_ANIMATION_H_ */
|
||||
@ -7,6 +7,12 @@ AtlasPage* AtlasPage_create () {
|
||||
return this;
|
||||
}
|
||||
|
||||
void AtlasPage_dispose (AtlasPage* this) {
|
||||
if (this->next) AtlasPage_dispose(this->next);
|
||||
FREE(this->name);
|
||||
FREE(this);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
AtlasRegion* AtlasRegion_create () {
|
||||
@ -14,6 +20,14 @@ AtlasRegion* AtlasRegion_create () {
|
||||
return this;
|
||||
}
|
||||
|
||||
void AtlasRegion_dispose (AtlasRegion* this) {
|
||||
if (this->next) AtlasRegion_dispose(this->next);
|
||||
FREE(this->name);
|
||||
FREE(this->splits);
|
||||
FREE(this->pads);
|
||||
FREE(this);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
@ -80,7 +94,7 @@ static int readTuple (Str tuple[]) {
|
||||
readLine(0, &str);
|
||||
if (!beginPast(&str, ':')) return 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < 3; ++i) {
|
||||
tuple[i].begin = str.begin;
|
||||
if (!beginPast(&str, ',')) {
|
||||
if (i == 0) return 0;
|
||||
@ -224,9 +238,16 @@ Atlas* Atlas_readAtlasFile (const char* path) {
|
||||
}
|
||||
|
||||
void Atlas_dispose (Atlas* this) {
|
||||
if (this->pages) AtlasPage_dispose(this->pages);
|
||||
if (this->regions) AtlasRegion_dispose(this->regions);
|
||||
FREE(this)
|
||||
}
|
||||
|
||||
AtlasRegion* Atlas_findRegion (Atlas* atlas, const char* name) {
|
||||
AtlasRegion* Atlas_findRegion (const Atlas* this, const char* name) {
|
||||
AtlasRegion* region = this->regions;
|
||||
while (region) {
|
||||
if (strcmp(region->name, name) == 0) return region;
|
||||
region = region->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ Atlas* Atlas_readAtlas (const char* data);
|
||||
Atlas* Atlas_readAtlasFile (const char* path);
|
||||
void Atlas_dispose (Atlas* atlas);
|
||||
|
||||
AtlasRegion* Atlas_findRegion (Atlas* atlas, const char* name);
|
||||
AtlasRegion* Atlas_findRegion (const Atlas* atlas, const char* name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ typedef enum {
|
||||
typedef struct Attachment Attachment;
|
||||
struct Attachment {
|
||||
const char* const name;
|
||||
|
||||
void (*_dispose) (Attachment* attachment);
|
||||
};
|
||||
|
||||
|
||||
@ -44,12 +44,12 @@ void Bone_updateWorldTransform (Bone* this, int flipX, int flipY) {
|
||||
CAST(float, this->worldRotation) = this->rotation;
|
||||
}
|
||||
float radians = (float)(this->worldRotation * 3.1415926535897932385 / 180);
|
||||
float cos = cosf(radians);
|
||||
float sin = sinf(radians);
|
||||
CAST(float, this->m00) = cos * this->worldScaleX;
|
||||
CAST(float, this->m10) = sin * this->worldScaleX;
|
||||
CAST(float, this->m01) = -sin * this->worldScaleY;
|
||||
CAST(float, this->m11) = cos * this->worldScaleY;
|
||||
float cosine = cos(radians);
|
||||
float sine = sin(radians);
|
||||
CAST(float, this->m00) = cosine * this->worldScaleX;
|
||||
CAST(float, this->m10) = sine * this->worldScaleX;
|
||||
CAST(float, this->m01) = -sine * this->worldScaleY;
|
||||
CAST(float, this->m11) = cosine * this->worldScaleY;
|
||||
if (flipX) {
|
||||
CAST(float, this->m00) = -this->m00;
|
||||
CAST(float, this->m01) = -this->m01;
|
||||
|
||||
@ -2,16 +2,12 @@
|
||||
#include <math.h>
|
||||
#include <spine/util.h>
|
||||
|
||||
void RegionAttachment_init (RegionAttachment* this, const char* name) {
|
||||
void _RegionAttachment_init (RegionAttachment* this, const char* name) {
|
||||
Attachment_init(&this->super, name);
|
||||
this->scaleX = 1;
|
||||
this->scaleY = 1;
|
||||
}
|
||||
|
||||
void RegionAttachment_dispose (RegionAttachment* this) {
|
||||
Attachment_dispose(&this->super);
|
||||
}
|
||||
|
||||
void RegionAttachment_updateOffset (RegionAttachment* this) {
|
||||
float localX2 = this->width / 2;
|
||||
float localY2 = this->height / 2;
|
||||
|
||||
@ -15,9 +15,6 @@ struct RegionAttachment {
|
||||
float offset[8];
|
||||
};
|
||||
|
||||
void RegionAttachment_init (RegionAttachment* attachment, const char* name);
|
||||
void RegionAttachment_dispose (RegionAttachment* attachment);
|
||||
|
||||
void RegionAttachment_updateOffset (RegionAttachment* attachment);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/util.h>
|
||||
|
||||
void Skeleton_init (Skeleton* this, SkeletonData* data) {
|
||||
void _Skeleton_init (Skeleton* this, SkeletonData* data) {
|
||||
CAST(SkeletonData*, this->data) = data;
|
||||
|
||||
this->boneCount = this->data->boneCount;
|
||||
@ -51,9 +51,9 @@ void Skeleton_dispose (Skeleton* this) {
|
||||
Bone_dispose(this->bones[i]);
|
||||
FREE(this->bones)
|
||||
|
||||
FREE(this->slots)
|
||||
for (i = 0; i < this->slotCount; ++i)
|
||||
Slot_dispose(this->slots[i]);
|
||||
FREE(this->slots)
|
||||
|
||||
FREE(this->drawOrder)
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ struct Skeleton {
|
||||
void (*_dispose) (Skeleton* skeleton);
|
||||
};
|
||||
|
||||
void Skeleton_init (Skeleton* skeleton, SkeletonData* data);
|
||||
void Skeleton_dispose (Skeleton* skeleton);
|
||||
|
||||
void Skeleton_updateWorldTransform (const Skeleton* skeleton);
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#include <spine/Skin.h>
|
||||
#include <spine/util.h>
|
||||
|
||||
SkinEntry* SkinEntry_create (int slotIndex, const char* name, Attachment* attachment) {
|
||||
SkinEntry* entry = calloc(1, sizeof(SkinEntry));
|
||||
entry->slotIndex = slotIndex;
|
||||
MALLOC_STR(entry->name, name)
|
||||
entry->attachment = attachment;
|
||||
return entry;
|
||||
SkinEntry* _SkinEntry_create (int slotIndex, const char* name, Attachment* attachment) {
|
||||
SkinEntry* this = calloc(1, sizeof(SkinEntry));
|
||||
this->slotIndex = slotIndex;
|
||||
MALLOC_STR(this->name, name)
|
||||
this->attachment = attachment;
|
||||
return this;
|
||||
}
|
||||
|
||||
void SkinEntry_dispose (SkinEntry* entry) {
|
||||
if (entry->next) SkinEntry_dispose((SkinEntry*)entry->next);
|
||||
Attachment_dispose(entry->attachment);
|
||||
FREE(entry->name)
|
||||
FREE(entry)
|
||||
void _SkinEntry_dispose (SkinEntry* this) {
|
||||
if (this->next) _SkinEntry_dispose((SkinEntry*)this->next);
|
||||
Attachment_dispose(this->attachment);
|
||||
FREE(this->name)
|
||||
FREE(this)
|
||||
}
|
||||
|
||||
/**/
|
||||
@ -25,13 +25,13 @@ Skin* Skin_create (const char* name) {
|
||||
}
|
||||
|
||||
void Skin_dispose (Skin* this) {
|
||||
SkinEntry_dispose((SkinEntry*)this->entries);
|
||||
_SkinEntry_dispose((SkinEntry*)this->entries);
|
||||
FREE(this->name)
|
||||
FREE(this)
|
||||
}
|
||||
|
||||
void Skin_addAttachment (Skin* this, int slotIndex, const char* name, Attachment* attachment) {
|
||||
SkinEntry* newEntry = SkinEntry_create(slotIndex, name, attachment);
|
||||
SkinEntry* newEntry = _SkinEntry_create(slotIndex, name, attachment);
|
||||
SkinEntry* entry = (SkinEntry*)this->entries;
|
||||
if (!entry)
|
||||
entry = newEntry;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user