mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
spine-c updated to v3.1.
This commit is contained in:
parent
ca0372c415
commit
421789e6f7
@ -12,7 +12,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-c works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-c works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-c supports all Spine features.
|
spine-c supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,12 @@ extern "C" {
|
|||||||
struct spAttachmentLoader;
|
struct spAttachmentLoader;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SP_ATTACHMENT_REGION, SP_ATTACHMENT_BOUNDING_BOX, SP_ATTACHMENT_MESH, SP_ATTACHMENT_WEIGHTED_MESH
|
SP_ATTACHMENT_REGION,
|
||||||
|
SP_ATTACHMENT_BOUNDING_BOX,
|
||||||
|
SP_ATTACHMENT_MESH,
|
||||||
|
SP_ATTACHMENT_WEIGHTED_MESH,
|
||||||
|
SP_ATTACHMENT_LINKED_MESH,
|
||||||
|
SP_ATTACHMENT_WEIGHTED_LINKED_MESH
|
||||||
} spAttachmentType;
|
} spAttachmentType;
|
||||||
|
|
||||||
typedef struct spAttachment {
|
typedef struct spAttachment {
|
||||||
@ -65,6 +70,8 @@ typedef spAttachmentType AttachmentType;
|
|||||||
#define ATTACHMENT_BOUNDING_BOX SP_ATTACHMENT_BOUNDING_BOX
|
#define ATTACHMENT_BOUNDING_BOX SP_ATTACHMENT_BOUNDING_BOX
|
||||||
#define ATTACHMENT_MESH SP_ATTACHMENT_MESH
|
#define ATTACHMENT_MESH SP_ATTACHMENT_MESH
|
||||||
#define ATTACHMENT_WEIGHTED_MESH SP_ATTACHMENT_WEIGHTED_MESH
|
#define ATTACHMENT_WEIGHTED_MESH SP_ATTACHMENT_WEIGHTED_MESH
|
||||||
|
#define ATTACHMENT_LINKED_MESH SP_ATTACHMENT_LINKED_MESH
|
||||||
|
#define ATTACHMENT_WEIGHTED_LINKED_MESH SP_ATTACHMENT_WEIGHTED_LINKED_MESH
|
||||||
typedef spAttachment Attachment;
|
typedef spAttachment Attachment;
|
||||||
#define Attachment_dispose(...) spAttachment_dispose(__VA_ARGS__)
|
#define Attachment_dispose(...) spAttachment_dispose(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -40,7 +40,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct spMeshAttachment {
|
typedef struct spMeshAttachment spMeshAttachment;
|
||||||
|
struct spMeshAttachment {
|
||||||
spAttachment super;
|
spAttachment super;
|
||||||
const char* path;
|
const char* path;
|
||||||
|
|
||||||
@ -54,6 +55,9 @@ typedef struct spMeshAttachment {
|
|||||||
int trianglesCount;
|
int trianglesCount;
|
||||||
unsigned short* triangles;
|
unsigned short* triangles;
|
||||||
|
|
||||||
|
spMeshAttachment* const parentMesh;
|
||||||
|
int/*bool*/inheritFFD;
|
||||||
|
|
||||||
float r, g, b, a;
|
float r, g, b, a;
|
||||||
|
|
||||||
void* rendererObject;
|
void* rendererObject;
|
||||||
@ -67,17 +71,19 @@ typedef struct spMeshAttachment {
|
|||||||
int edgesCount;
|
int edgesCount;
|
||||||
int* edges;
|
int* edges;
|
||||||
float width, height;
|
float width, height;
|
||||||
} spMeshAttachment;
|
};
|
||||||
|
|
||||||
spMeshAttachment* spMeshAttachment_create (const char* name);
|
spMeshAttachment* spMeshAttachment_create (const char* name);
|
||||||
void spMeshAttachment_updateUVs (spMeshAttachment* self);
|
void spMeshAttachment_updateUVs (spMeshAttachment* self);
|
||||||
void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot, float* worldVertices);
|
void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot, float* worldVertices);
|
||||||
|
void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh);
|
||||||
|
|
||||||
#ifdef SPINE_SHORT_NAMES
|
#ifdef SPINE_SHORT_NAMES
|
||||||
typedef spMeshAttachment MeshAttachment;
|
typedef spMeshAttachment MeshAttachment;
|
||||||
#define MeshAttachment_create(...) spMeshAttachment_create(__VA_ARGS__)
|
#define MeshAttachment_create(...) spMeshAttachment_create(__VA_ARGS__)
|
||||||
#define MeshAttachment_updateUVs(...) spMeshAttachment_updateUVs(__VA_ARGS__)
|
#define MeshAttachment_updateUVs(...) spMeshAttachment_updateUVs(__VA_ARGS__)
|
||||||
#define MeshAttachment_computeWorldVertices(...) spMeshAttachment_computeWorldVertices(__VA_ARGS__)
|
#define MeshAttachment_computeWorldVertices(...) spMeshAttachment_computeWorldVertices(__VA_ARGS__)
|
||||||
|
#define MeshAttachment_setParentMesh(...) spMeshAttachment_setParentMesh(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -39,7 +39,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct spWeightedMeshAttachment {
|
typedef struct spWeightedMeshAttachment spWeightedMeshAttachment;
|
||||||
|
struct spWeightedMeshAttachment {
|
||||||
spAttachment super;
|
spAttachment super;
|
||||||
const char* path;
|
const char* path;
|
||||||
|
|
||||||
@ -57,6 +58,9 @@ typedef struct spWeightedMeshAttachment {
|
|||||||
float* uvs;
|
float* uvs;
|
||||||
int hullLength;
|
int hullLength;
|
||||||
|
|
||||||
|
spWeightedMeshAttachment* const parentMesh;
|
||||||
|
int/*bool*/inheritFFD;
|
||||||
|
|
||||||
float r, g, b, a;
|
float r, g, b, a;
|
||||||
|
|
||||||
void* rendererObject;
|
void* rendererObject;
|
||||||
@ -70,17 +74,19 @@ typedef struct spWeightedMeshAttachment {
|
|||||||
int edgesCount;
|
int edgesCount;
|
||||||
int* edges;
|
int* edges;
|
||||||
float width, height;
|
float width, height;
|
||||||
} spWeightedMeshAttachment;
|
};
|
||||||
|
|
||||||
spWeightedMeshAttachment* spWeightedMeshAttachment_create (const char* name);
|
spWeightedMeshAttachment* spWeightedMeshAttachment_create (const char* name);
|
||||||
void spWeightedMeshAttachment_updateUVs (spWeightedMeshAttachment* self);
|
void spWeightedMeshAttachment_updateUVs (spWeightedMeshAttachment* self);
|
||||||
void spWeightedMeshAttachment_computeWorldVertices (spWeightedMeshAttachment* self, spSlot* slot, float* worldVertices);
|
void spWeightedMeshAttachment_computeWorldVertices (spWeightedMeshAttachment* self, spSlot* slot, float* worldVertices);
|
||||||
|
void spWeightedMeshAttachment_setParentMesh (spWeightedMeshAttachment* self, spWeightedMeshAttachment* parentMesh);
|
||||||
|
|
||||||
#ifdef SPINE_SHORT_NAMES
|
#ifdef SPINE_SHORT_NAMES
|
||||||
typedef spWeightedMeshAttachment WeightedMeshAttachment;
|
typedef spWeightedMeshAttachment WeightedMeshAttachment;
|
||||||
#define WeightedMeshAttachment_create(...) spWeightedMeshAttachment_create(__VA_ARGS__)
|
#define WeightedMeshAttachment_create(...) spWeightedMeshAttachment_create(__VA_ARGS__)
|
||||||
#define WeightedMeshAttachment_updateUVs(...) spWeightedMeshAttachment_updateUVs(__VA_ARGS__)
|
#define WeightedMeshAttachment_updateUVs(...) spWeightedMeshAttachment_updateUVs(__VA_ARGS__)
|
||||||
#define WeightedMeshAttachment_computeWorldVertices(...) spWeightedMeshAttachment_computeWorldVertices(__VA_ARGS__)
|
#define WeightedMeshAttachment_computeWorldVertices(...) spWeightedMeshAttachment_computeWorldVertices(__VA_ARGS__)
|
||||||
|
#define WeightedMeshAttachment_setParentMesh(...) spWeightedMeshAttachment_setParentMesh(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -683,7 +683,24 @@ void _spFFDTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, flo
|
|||||||
spFFDTimeline* self = (spFFDTimeline*)timeline;
|
spFFDTimeline* self = (spFFDTimeline*)timeline;
|
||||||
|
|
||||||
spSlot *slot = skeleton->slots[self->slotIndex];
|
spSlot *slot = skeleton->slots[self->slotIndex];
|
||||||
if (slot->attachment != self->attachment) return;
|
|
||||||
|
if (slot->attachment != self->attachment) {
|
||||||
|
if (!slot->attachment) return;
|
||||||
|
switch (slot->attachment->type) {
|
||||||
|
case SP_ATTACHMENT_MESH: {
|
||||||
|
spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, slot->attachment);
|
||||||
|
if (!mesh->inheritFFD || mesh->parentMesh != (void*)self->attachment) return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SP_ATTACHMENT_WEIGHTED_MESH: {
|
||||||
|
spWeightedMeshAttachment* mesh = SUB_CAST(spWeightedMeshAttachment, slot->attachment);
|
||||||
|
if (!mesh->inheritFFD || mesh->parentMesh != (void*)self->attachment) return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (time < self->frames[0]) return; /* Time is before first frame. */
|
if (time < self->frames[0]) return; /* Time is before first frame. */
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,8 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
|
|||||||
attachment->regionOriginalHeight = region->originalHeight;
|
attachment->regionOriginalHeight = region->originalHeight;
|
||||||
return SUPER(attachment);
|
return SUPER(attachment);
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_MESH: {
|
case SP_ATTACHMENT_MESH:
|
||||||
|
case SP_ATTACHMENT_LINKED_MESH: {
|
||||||
spMeshAttachment* attachment;
|
spMeshAttachment* attachment;
|
||||||
spAtlasRegion* region = spAtlas_findRegion(self->atlas, path);
|
spAtlasRegion* region = spAtlas_findRegion(self->atlas, path);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
@ -76,7 +77,8 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
|
|||||||
attachment->regionOriginalHeight = region->originalHeight;
|
attachment->regionOriginalHeight = region->originalHeight;
|
||||||
return SUPER(attachment);
|
return SUPER(attachment);
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_WEIGHTED_MESH: {
|
case SP_ATTACHMENT_WEIGHTED_MESH:
|
||||||
|
case SP_ATTACHMENT_WEIGHTED_LINKED_MESH: {
|
||||||
spWeightedMeshAttachment* attachment;
|
spWeightedMeshAttachment* attachment;
|
||||||
spAtlasRegion* region = spAtlas_findRegion(self->atlas, path);
|
spAtlasRegion* region = spAtlas_findRegion(self->atlas, path);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
|
|||||||
@ -108,7 +108,8 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
|
|||||||
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
||||||
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
||||||
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
||||||
} else if (self->data->inheritRotation) { /* No scale inheritance. */
|
} else {
|
||||||
|
if (self->data->inheritRotation) { /* No scale inheritance. */
|
||||||
pa = 1;
|
pa = 1;
|
||||||
pb = 0;
|
pb = 0;
|
||||||
pc = 0;
|
pc = 0;
|
||||||
@ -130,14 +131,6 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
|
|||||||
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
||||||
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
||||||
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
||||||
if (self->skeleton->flipX) {
|
|
||||||
CONST_CAST(float, self->a) = -self->a;
|
|
||||||
CONST_CAST(float, self->b) = -self->b;
|
|
||||||
}
|
|
||||||
if (self->skeleton->flipY != yDown) {
|
|
||||||
CONST_CAST(float, self->c) = -self->c;
|
|
||||||
CONST_CAST(float, self->d) = -self->d;
|
|
||||||
}
|
|
||||||
} else if (self->data->inheritScale) { /* No rotation inheritance. */
|
} else if (self->data->inheritScale) { /* No rotation inheritance. */
|
||||||
pa = 1;
|
pa = 1;
|
||||||
pb = 0;
|
pb = 0;
|
||||||
@ -177,6 +170,12 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
|
|||||||
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
||||||
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
||||||
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
||||||
|
} else {
|
||||||
|
CONST_CAST(float, self->a) = la;
|
||||||
|
CONST_CAST(float, self->b) = lb;
|
||||||
|
CONST_CAST(float, self->c) = lc;
|
||||||
|
CONST_CAST(float, self->d) = ld;
|
||||||
|
}
|
||||||
if (self->skeleton->flipX) {
|
if (self->skeleton->flipX) {
|
||||||
CONST_CAST(float, self->a) = -self->a;
|
CONST_CAST(float, self->a) = -self->a;
|
||||||
CONST_CAST(float, self->b) = -self->b;
|
CONST_CAST(float, self->b) = -self->b;
|
||||||
@ -185,11 +184,6 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
|
|||||||
CONST_CAST(float, self->c) = -self->c;
|
CONST_CAST(float, self->c) = -self->c;
|
||||||
CONST_CAST(float, self->d) = -self->d;
|
CONST_CAST(float, self->d) = -self->d;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
CONST_CAST(float, self->a) = la;
|
|
||||||
CONST_CAST(float, self->b) = lb;
|
|
||||||
CONST_CAST(float, self->c) = lc;
|
|
||||||
CONST_CAST(float, self->d) = ld;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -80,47 +80,54 @@ void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float al
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, float alpha) {
|
void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, float alpha) {
|
||||||
float px = parent->x, py = parent->y, psx = parent->scaleX, psy = parent->scaleY, csx = child->scaleX, cy = child->y;
|
float px = parent->x, py = parent->y, psx = parent->scaleX, psy = parent->scaleY;
|
||||||
int offset1, offset2, sign2;
|
float cx = child->x, cy = child->y, csx = child->appliedScaleX, cwx = child->worldX, cwy = child->worldY;
|
||||||
|
int o1, o2, s2, u;
|
||||||
spBone* pp = parent->parent;
|
spBone* pp = parent->parent;
|
||||||
float tx, ty, dx, dy, l1, l2, a1, a2, psd, r;
|
float tx, ty, dx, dy, l1, l2, a1, a2, r;
|
||||||
if (alpha == 0) return;
|
if (alpha == 0) return;
|
||||||
if (psx < 0) {
|
if (psx < 0) {
|
||||||
psx = -psx;
|
psx = -psx;
|
||||||
offset1 = 180;
|
o1 = 180;
|
||||||
sign2 = -1;
|
s2 = -1;
|
||||||
} else {
|
} else {
|
||||||
offset1 = 0;
|
o1 = 0;
|
||||||
sign2 = 1;
|
s2 = 1;
|
||||||
}
|
}
|
||||||
if (psy < 0) {
|
if (psy < 0) {
|
||||||
psy = -psy;
|
psy = -psy;
|
||||||
sign2 = -sign2;
|
s2 = -s2;
|
||||||
|
}
|
||||||
|
u = psx - psy;
|
||||||
|
u = u < 0 ? -u : u <= 0.0001f;
|
||||||
|
if (!u && cy != 0) {
|
||||||
|
cwx = parent->a * cx + parent->worldX;
|
||||||
|
cwy = parent->c * cx + parent->worldY;
|
||||||
|
cy = 0;
|
||||||
}
|
}
|
||||||
if (csx < 0) {
|
if (csx < 0) {
|
||||||
csx = -csx;
|
csx = -csx;
|
||||||
offset2 = 180;
|
o2 = 180;
|
||||||
} else
|
} else
|
||||||
offset2 = 0;
|
o2 = 0;
|
||||||
if (!pp) {
|
if (!pp) {
|
||||||
tx = targetX - px;
|
tx = targetX - px;
|
||||||
ty = targetY - py;
|
ty = targetY - py;
|
||||||
dx = child->worldX - px;
|
dx = cwx - px;
|
||||||
dy = child->worldY - py;
|
dy = cwy - py;
|
||||||
} else {
|
} else {
|
||||||
float a = pp->a, b = pp->b, c = pp->c, d = pp->d, invDet = 1 / (a * d - b * c);
|
float a = pp->a, b = pp->b, c = pp->c, d = pp->d, invDet = 1 / (a * d - b * c);
|
||||||
float wx = pp->worldX, wy = pp->worldY, x = targetX - wx, y = targetY - wy;
|
float wx = pp->worldX, wy = pp->worldY, x = targetX - wx, y = targetY - wy;
|
||||||
tx = (x * d - y * b) * invDet - px;
|
tx = (x * d - y * b) * invDet - px;
|
||||||
ty = (y * a - x * c) * invDet - py;
|
ty = (y * a - x * c) * invDet - py;
|
||||||
x = child->worldX - wx;
|
x = cwx - wx;
|
||||||
y = child->worldY - wy;
|
y = cwy - wy;
|
||||||
dx = (x * d - y * b) * invDet - px;
|
dx = (x * d - y * b) * invDet - px;
|
||||||
dy = (y * a - x * c) * invDet - py;
|
dy = (y * a - x * c) * invDet - py;
|
||||||
}
|
}
|
||||||
l1 = SQRT(dx * dx + dy * dy);
|
l1 = SQRT(dx * dx + dy * dy);
|
||||||
l2 = child->data->length * csx;
|
l2 = child->data->length * csx;
|
||||||
psd = psx - psy;
|
if (u) {
|
||||||
if (psd < 0 ? -psd : psd <= 0.0001f) {
|
|
||||||
float cos, a, o;
|
float cos, a, o;
|
||||||
l2 *= psx;
|
l2 *= psx;
|
||||||
cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||||
@ -138,7 +145,6 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
|
|||||||
float minAngle = 0, minDist = FLT_MAX, minX = 0, minY = 0;
|
float minAngle = 0, minDist = FLT_MAX, minX = 0, minY = 0;
|
||||||
float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
|
float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
|
||||||
float x = l1 + a, dist = x * x, angle, y;
|
float x = l1 + a, dist = x * x, angle, y;
|
||||||
cy = 0;
|
|
||||||
if (d >= 0) {
|
if (d >= 0) {
|
||||||
float q = SQRT(d), r0, r1, ar0, ar1;;
|
float q = SQRT(d), r0, r1, ar0, ar1;;
|
||||||
if (c1 < 0) q = -q;
|
if (c1 < 0) q = -q;
|
||||||
@ -192,16 +198,16 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
outer: {
|
outer: {
|
||||||
float offset = ATAN2(cy, child->x) * sign2;
|
float offset = ATAN2(cy, child->x) * s2;
|
||||||
a1 = (a1 - offset) * RAD_DEG + offset1;
|
a1 = (a1 - offset) * RAD_DEG + o1;
|
||||||
a2 = (a2 + offset) * RAD_DEG * sign2 + offset2;
|
a2 = (a2 + offset) * RAD_DEG * s2 + o2;
|
||||||
if (a1 > 180) a1 -= 360;
|
if (a1 > 180) a1 -= 360;
|
||||||
else if (a1 < -180) a1 += 360;
|
else if (a1 < -180) a1 += 360;
|
||||||
if (a2 > 180) a2 -= 360;
|
if (a2 > 180) a2 -= 360;
|
||||||
else if (a2 < -180) a2 += 360;
|
else if (a2 < -180) a2 += 360;
|
||||||
r = parent->rotation;
|
r = parent->rotation;
|
||||||
spBone_updateWorldTransformWith(parent, parent->x, parent->y, r + (a1 - r) * alpha, parent->scaleX, parent->scaleY);
|
spBone_updateWorldTransformWith(parent, px, py, r + (a1 - r) * alpha, parent->appliedScaleX, parent->appliedScaleY);
|
||||||
r = child->rotation;
|
r = child->rotation;
|
||||||
spBone_updateWorldTransformWith(child, child->x, cy, r + (a2 - r) * alpha, child->scaleX, child->scaleY);
|
spBone_updateWorldTransformWith(child, cx, cy, r + (a2 - r) * alpha, child->appliedScaleX, child->appliedScaleY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,11 +36,13 @@ void _spMeshAttachment_dispose (spAttachment* attachment) {
|
|||||||
spMeshAttachment* self = SUB_CAST(spMeshAttachment, attachment);
|
spMeshAttachment* self = SUB_CAST(spMeshAttachment, attachment);
|
||||||
_spAttachment_deinit(attachment);
|
_spAttachment_deinit(attachment);
|
||||||
FREE(self->path);
|
FREE(self->path);
|
||||||
|
FREE(self->uvs);
|
||||||
|
if (!self->parentMesh) {
|
||||||
FREE(self->vertices);
|
FREE(self->vertices);
|
||||||
FREE(self->regionUVs);
|
FREE(self->regionUVs);
|
||||||
FREE(self->uvs);
|
|
||||||
FREE(self->triangles);
|
FREE(self->triangles);
|
||||||
FREE(self->edges);
|
FREE(self->edges);
|
||||||
|
}
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,3 +86,23 @@ void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot
|
|||||||
worldVertices[i + 1] = vx * bone->c + vy * bone->d + y;
|
worldVertices[i + 1] = vx * bone->c + vy * bone->d + y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh) {
|
||||||
|
CONST_CAST(spMeshAttachment*, self->parentMesh) = parentMesh;
|
||||||
|
if (parentMesh) {
|
||||||
|
self->vertices = parentMesh->vertices;
|
||||||
|
self->regionUVs = parentMesh->regionUVs;
|
||||||
|
self->verticesCount = parentMesh->verticesCount;
|
||||||
|
|
||||||
|
self->triangles = parentMesh->triangles;
|
||||||
|
self->trianglesCount = parentMesh->trianglesCount;
|
||||||
|
|
||||||
|
self->hullLength = parentMesh->hullLength;
|
||||||
|
|
||||||
|
self->edges = parentMesh->edges;
|
||||||
|
self->edgesCount = parentMesh->edgesCount;
|
||||||
|
|
||||||
|
self->width = parentMesh->width;
|
||||||
|
self->height = parentMesh->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -37,12 +37,16 @@ typedef enum {
|
|||||||
SP_UPDATE_BONE, SP_UPDATE_IK_CONSTRAINT, SP_UPDATE_TRANSFORM_CONSTRAINT
|
SP_UPDATE_BONE, SP_UPDATE_IK_CONSTRAINT, SP_UPDATE_TRANSFORM_CONSTRAINT
|
||||||
} _spUpdateType;
|
} _spUpdateType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
_spUpdateType type;
|
||||||
|
void* object;
|
||||||
|
} _spUpdate;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spSkeleton super;
|
spSkeleton super;
|
||||||
|
|
||||||
int updateCacheCount;
|
int updateCacheCount;
|
||||||
void** updateCache;
|
_spUpdate* updateCache;
|
||||||
_spUpdateType* updateCacheType;
|
|
||||||
} _spSkeleton;
|
} _spSkeleton;
|
||||||
|
|
||||||
spSkeleton* spSkeleton_create (spSkeletonData* data) {
|
spSkeleton* spSkeleton_create (spSkeletonData* data) {
|
||||||
@ -115,7 +119,6 @@ void spSkeleton_dispose (spSkeleton* self) {
|
|||||||
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
||||||
|
|
||||||
FREE(internal->updateCache);
|
FREE(internal->updateCache);
|
||||||
FREE(internal->updateCacheType);
|
|
||||||
|
|
||||||
for (i = 0; i < self->bonesCount; ++i)
|
for (i = 0; i < self->bonesCount; ++i)
|
||||||
spBone_dispose(self->bones[i]);
|
spBone_dispose(self->bones[i]);
|
||||||
@ -139,24 +142,25 @@ void spSkeleton_dispose (spSkeleton* self) {
|
|||||||
|
|
||||||
void spSkeleton_updateCache (const spSkeleton* self) {
|
void spSkeleton_updateCache (const spSkeleton* self) {
|
||||||
int i, ii;
|
int i, ii;
|
||||||
|
_spUpdate* update;
|
||||||
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
||||||
|
int capacity = self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount;
|
||||||
|
|
||||||
FREE(internal->updateCache);
|
FREE(internal->updateCache);
|
||||||
FREE(internal->updateCacheType);
|
internal->updateCache = MALLOC(_spUpdate, capacity);
|
||||||
int capacity = self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount;
|
|
||||||
internal->updateCache = MALLOC(void*, capacity);
|
|
||||||
internal->updateCacheType = MALLOC(_spUpdateType, capacity);
|
|
||||||
internal->updateCacheCount = 0;
|
internal->updateCacheCount = 0;
|
||||||
|
|
||||||
for (i = 0; i < self->bonesCount; ++i) {
|
for (i = 0; i < self->bonesCount; ++i) {
|
||||||
spBone* bone = self->bones[i];
|
spBone* bone = self->bones[i];
|
||||||
internal->updateCache[internal->updateCacheCount] = bone;
|
update = internal->updateCache + internal->updateCacheCount++;
|
||||||
internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_BONE;
|
update->type = SP_UPDATE_BONE;
|
||||||
|
update->object = bone;
|
||||||
for (ii = 0; ii < self->ikConstraintsCount; ++ii) {
|
for (ii = 0; ii < self->ikConstraintsCount; ++ii) {
|
||||||
spIkConstraint* ikConstraint = self->ikConstraints[ii];
|
spIkConstraint* ikConstraint = self->ikConstraints[ii];
|
||||||
if (bone == ikConstraint->bones[ikConstraint->bonesCount - 1]) {
|
if (bone == ikConstraint->bones[ikConstraint->bonesCount - 1]) {
|
||||||
internal->updateCache[internal->updateCacheCount] = ikConstraint;
|
update = internal->updateCache + internal->updateCacheCount++;
|
||||||
internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_IK_CONSTRAINT;
|
update->type = SP_UPDATE_IK_CONSTRAINT;
|
||||||
|
update->object = ikConstraint;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,17 +169,14 @@ void spSkeleton_updateCache (const spSkeleton* self) {
|
|||||||
for (i = 0; i < self->transformConstraintsCount; ++i) {
|
for (i = 0; i < self->transformConstraintsCount; ++i) {
|
||||||
spTransformConstraint* transformConstraint = self->transformConstraints[i];
|
spTransformConstraint* transformConstraint = self->transformConstraints[i];
|
||||||
for (ii = internal->updateCacheCount - 1; ii >= 0; --ii) {
|
for (ii = internal->updateCacheCount - 1; ii >= 0; --ii) {
|
||||||
void* updatable = internal->updateCache[ii];
|
void* object = internal->updateCache[ii].object;
|
||||||
if (updatable == transformConstraint->bone || updatable == transformConstraint->target) {
|
if (object == transformConstraint->bone || object == transformConstraint->target) {
|
||||||
int insertIndex = ii + 1;
|
int insertIndex = ii + 1;
|
||||||
int moveCount = (capacity-2) - insertIndex;
|
update = internal->updateCache + insertIndex;
|
||||||
if (moveCount > 0) {
|
memmove(update + 1, update, (internal->updateCacheCount - insertIndex) * sizeof(_spUpdate));
|
||||||
memmove(internal->updateCache + (insertIndex + 1), internal->updateCache + insertIndex, moveCount * sizeof(void*));
|
update->type = SP_UPDATE_TRANSFORM_CONSTRAINT;
|
||||||
memmove(internal->updateCacheType + (insertIndex + 1), internal->updateCacheType + insertIndex, moveCount * sizeof(_spUpdateType));
|
update->object = transformConstraint;
|
||||||
}
|
|
||||||
internal->updateCacheCount++;
|
internal->updateCacheCount++;
|
||||||
internal->updateCache[insertIndex] = transformConstraint;
|
|
||||||
internal->updateCacheType[insertIndex] = SP_UPDATE_TRANSFORM_CONSTRAINT;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,15 +188,16 @@ void spSkeleton_updateWorldTransform (const spSkeleton* self) {
|
|||||||
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
_spSkeleton* internal = SUB_CAST(_spSkeleton, self);
|
||||||
|
|
||||||
for (i = 0; i < internal->updateCacheCount; ++i) {
|
for (i = 0; i < internal->updateCacheCount; ++i) {
|
||||||
switch (internal->updateCacheType[i]) {
|
_spUpdate* update = internal->updateCache + i;
|
||||||
|
switch (update->type) {
|
||||||
case SP_UPDATE_BONE:
|
case SP_UPDATE_BONE:
|
||||||
spBone_updateWorldTransform((spBone*)internal->updateCache[i]);
|
spBone_updateWorldTransform((spBone*)update->object);
|
||||||
break;
|
break;
|
||||||
case SP_UPDATE_IK_CONSTRAINT:
|
case SP_UPDATE_IK_CONSTRAINT:
|
||||||
spIkConstraint_apply((spIkConstraint*)internal->updateCache[i]);
|
spIkConstraint_apply((spIkConstraint*)update->object);
|
||||||
break;
|
break;
|
||||||
case SP_UPDATE_TRANSFORM_CONSTRAINT:
|
case SP_UPDATE_TRANSFORM_CONSTRAINT:
|
||||||
spTransformConstraint_apply((spTransformConstraint*)internal->updateCache[i]);
|
spTransformConstraint_apply((spTransformConstraint*)update->object);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,20 @@
|
|||||||
#include <spine/extension.h>
|
#include <spine/extension.h>
|
||||||
#include <spine/AtlasAttachmentLoader.h>
|
#include <spine/AtlasAttachmentLoader.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* parent;
|
||||||
|
const char* skin;
|
||||||
|
int slotIndex;
|
||||||
|
spAttachment* mesh;
|
||||||
|
} _spLinkedMesh;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spSkeletonJson super;
|
spSkeletonJson super;
|
||||||
int ownsLoader;
|
int ownsLoader;
|
||||||
|
|
||||||
|
int linkedMeshCount;
|
||||||
|
int linkedMeshCapacity;
|
||||||
|
_spLinkedMesh* linkedMeshes;
|
||||||
} _spSkeletonJson;
|
} _spSkeletonJson;
|
||||||
|
|
||||||
spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader) {
|
spSkeletonJson* spSkeletonJson_createWithLoader (spAttachmentLoader* attachmentLoader) {
|
||||||
@ -56,7 +67,9 @@ spSkeletonJson* spSkeletonJson_create (spAtlas* atlas) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spSkeletonJson_dispose (spSkeletonJson* self) {
|
void spSkeletonJson_dispose (spSkeletonJson* self) {
|
||||||
if (SUB_CAST(_spSkeletonJson, self)->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader);
|
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
|
||||||
|
if (internal->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader);
|
||||||
|
FREE(internal->linkedMeshes);
|
||||||
FREE(self->error);
|
FREE(self->error);
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
@ -103,6 +116,28 @@ static void readCurve (spCurveTimeline* timeline, int frameIndex, Json* frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spAttachment* mesh, const char* skin, int slotIndex,
|
||||||
|
const char* parent) {
|
||||||
|
_spLinkedMesh* linkedMesh;
|
||||||
|
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
|
||||||
|
|
||||||
|
if (internal->linkedMeshCount == internal->linkedMeshCapacity) {
|
||||||
|
_spLinkedMesh* linkedMeshes;
|
||||||
|
internal->linkedMeshCapacity *= 2;
|
||||||
|
if (internal->linkedMeshCapacity < 8) internal->linkedMeshCapacity = 8;
|
||||||
|
linkedMeshes = MALLOC(_spLinkedMesh, internal->linkedMeshCapacity);
|
||||||
|
memcpy(linkedMeshes, internal->linkedMeshes, internal->linkedMeshCount);
|
||||||
|
FREE(internal->linkedMeshes);
|
||||||
|
internal->linkedMeshes = linkedMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
linkedMesh = internal->linkedMeshes + internal->linkedMeshCount++;
|
||||||
|
linkedMesh->mesh = mesh;
|
||||||
|
linkedMesh->skin = skin;
|
||||||
|
linkedMesh->slotIndex = slotIndex;
|
||||||
|
linkedMesh->parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* root, spSkeletonData *skeletonData) {
|
static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* root, spSkeletonData *skeletonData) {
|
||||||
int i;
|
int i;
|
||||||
spAnimation* animation;
|
spAnimation* animation;
|
||||||
@ -132,7 +167,6 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
|
|
||||||
animation = spAnimation_create(root->name, timelinesCount);
|
animation = spAnimation_create(root->name, timelinesCount);
|
||||||
animation->timelinesCount = 0;
|
animation->timelinesCount = 0;
|
||||||
skeletonData->animations[skeletonData->animationsCount++] = animation;
|
|
||||||
|
|
||||||
/* Slot timelines. */
|
/* Slot timelines. */
|
||||||
for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next) {
|
for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next) {
|
||||||
@ -409,9 +443,11 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
spSkeletonData* skeletonData;
|
spSkeletonData* skeletonData;
|
||||||
Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *slots, *skins, *animations, *events;
|
Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *slots, *skins, *animations, *events;
|
||||||
char* oldLocale;
|
char* oldLocale;
|
||||||
|
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
|
||||||
|
|
||||||
FREE(self->error);
|
FREE(self->error);
|
||||||
CONST_CAST(char*, self->error) = 0;
|
CONST_CAST(char*, self->error) = 0;
|
||||||
|
internal->linkedMeshCount = 0;
|
||||||
|
|
||||||
oldLocale = setlocale(LC_NUMERIC, "C");
|
oldLocale = setlocale(LC_NUMERIC, "C");
|
||||||
root = Json_create(json);
|
root = Json_create(json);
|
||||||
@ -584,13 +620,12 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
skins = Json_getItem(root, "skins");
|
skins = Json_getItem(root, "skins");
|
||||||
if (skins) {
|
if (skins) {
|
||||||
Json *slotMap;
|
Json *slotMap;
|
||||||
skeletonData->skinsCount = skins->size;
|
|
||||||
skeletonData->skins = MALLOC(spSkin*, skins->size);
|
skeletonData->skins = MALLOC(spSkin*, skins->size);
|
||||||
for (slotMap = skins->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
for (slotMap = skins->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
||||||
Json *attachmentsMap;
|
Json *attachmentsMap;
|
||||||
spSkin *skin = spSkin_create(slotMap->name);
|
spSkin *skin = spSkin_create(slotMap->name);
|
||||||
|
|
||||||
skeletonData->skins[i] = skin;
|
skeletonData->skins[skeletonData->skinsCount++] = skin;
|
||||||
if (strcmp(slotMap->name, "default") == 0) skeletonData->defaultSkin = skin;
|
if (strcmp(slotMap->name, "default") == 0) skeletonData->defaultSkin = skin;
|
||||||
|
|
||||||
for (attachmentsMap = slotMap->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
|
for (attachmentsMap = slotMap->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
|
||||||
@ -614,6 +649,10 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
type = SP_ATTACHMENT_MESH;
|
type = SP_ATTACHMENT_MESH;
|
||||||
else if (strcmp(typeString, "weightedmesh") == 0 || strcmp(typeString, "skinnedmesh") == 0)
|
else if (strcmp(typeString, "weightedmesh") == 0 || strcmp(typeString, "skinnedmesh") == 0)
|
||||||
type = SP_ATTACHMENT_WEIGHTED_MESH;
|
type = SP_ATTACHMENT_WEIGHTED_MESH;
|
||||||
|
else if (strcmp(typeString, "linkedmesh") == 0)
|
||||||
|
type = SP_ATTACHMENT_LINKED_MESH;
|
||||||
|
else if (strcmp(typeString, "weightedlinkedmesh") == 0)
|
||||||
|
type = SP_ATTACHMENT_WEIGHTED_LINKED_MESH;
|
||||||
else if (strcmp(typeString, "boundingbox") == 0)
|
else if (strcmp(typeString, "boundingbox") == 0)
|
||||||
type = SP_ATTACHMENT_BOUNDING_BOX;
|
type = SP_ATTACHMENT_BOUNDING_BOX;
|
||||||
else {
|
else {
|
||||||
@ -655,11 +694,25 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
spRegionAttachment_updateOffset(region);
|
spRegionAttachment_updateOffset(region);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_MESH: {
|
case SP_ATTACHMENT_MESH:
|
||||||
|
case SP_ATTACHMENT_LINKED_MESH: {
|
||||||
spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, attachment);
|
spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, attachment);
|
||||||
|
|
||||||
MALLOC_STR(mesh->path, path);
|
MALLOC_STR(mesh->path, path);
|
||||||
|
|
||||||
|
color = Json_getString(attachmentMap, "color", 0);
|
||||||
|
if (color) {
|
||||||
|
mesh->r = toColor(color, 0);
|
||||||
|
mesh->g = toColor(color, 1);
|
||||||
|
mesh->b = toColor(color, 2);
|
||||||
|
mesh->a = toColor(color, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
||||||
|
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
|
||||||
|
|
||||||
|
entry = Json_getItem(attachmentMap, "parent");
|
||||||
|
if (!entry) {
|
||||||
entry = Json_getItem(attachmentMap, "vertices");
|
entry = Json_getItem(attachmentMap, "vertices");
|
||||||
mesh->verticesCount = entry->size;
|
mesh->verticesCount = entry->size;
|
||||||
mesh->vertices = MALLOC(float, entry->size);
|
mesh->vertices = MALLOC(float, entry->size);
|
||||||
@ -679,14 +732,6 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
|
|
||||||
spMeshAttachment_updateUVs(mesh);
|
spMeshAttachment_updateUVs(mesh);
|
||||||
|
|
||||||
color = Json_getString(attachmentMap, "color", 0);
|
|
||||||
if (color) {
|
|
||||||
mesh->r = toColor(color, 0);
|
|
||||||
mesh->g = toColor(color, 1);
|
|
||||||
mesh->b = toColor(color, 2);
|
|
||||||
mesh->a = toColor(color, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
|
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
|
||||||
|
|
||||||
entry = Json_getItem(attachmentMap, "edges");
|
entry = Json_getItem(attachmentMap, "edges");
|
||||||
@ -696,18 +741,34 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
|
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
|
||||||
mesh->edges[i] = entry->valueInt;
|
mesh->edges[i] = entry->valueInt;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
mesh->inheritFFD = Json_getInt(attachmentMap, "ffd", 1);
|
||||||
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
|
_spSkeletonJson_addLinkedMesh(self, attachment, Json_getString(attachmentMap, "skin", 0), slotIndex,
|
||||||
|
entry->valueString);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_WEIGHTED_MESH: {
|
case SP_ATTACHMENT_WEIGHTED_MESH:
|
||||||
|
case SP_ATTACHMENT_WEIGHTED_LINKED_MESH: {
|
||||||
spWeightedMeshAttachment* mesh = SUB_CAST(spWeightedMeshAttachment, attachment);
|
spWeightedMeshAttachment* mesh = SUB_CAST(spWeightedMeshAttachment, attachment);
|
||||||
int verticesCount, b, w, nn;
|
int verticesCount, b, w, nn;
|
||||||
float* vertices;
|
float* vertices;
|
||||||
|
|
||||||
MALLOC_STR(mesh->path, path);
|
MALLOC_STR(mesh->path, path);
|
||||||
|
|
||||||
|
color = Json_getString(attachmentMap, "color", 0);
|
||||||
|
if (color) {
|
||||||
|
mesh->r = toColor(color, 0);
|
||||||
|
mesh->g = toColor(color, 1);
|
||||||
|
mesh->b = toColor(color, 2);
|
||||||
|
mesh->a = toColor(color, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
||||||
|
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
|
||||||
|
|
||||||
|
entry = Json_getItem(attachmentMap, "parent");
|
||||||
|
if (!entry) {
|
||||||
entry = Json_getItem(attachmentMap, "uvs");
|
entry = Json_getItem(attachmentMap, "uvs");
|
||||||
mesh->uvsCount = entry->size;
|
mesh->uvsCount = entry->size;
|
||||||
mesh->regionUVs = MALLOC(float, entry->size);
|
mesh->regionUVs = MALLOC(float, entry->size);
|
||||||
@ -750,14 +811,6 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
|
|
||||||
spWeightedMeshAttachment_updateUVs(mesh);
|
spWeightedMeshAttachment_updateUVs(mesh);
|
||||||
|
|
||||||
color = Json_getString(attachmentMap, "color", 0);
|
|
||||||
if (color) {
|
|
||||||
mesh->r = toColor(color, 0);
|
|
||||||
mesh->g = toColor(color, 1);
|
|
||||||
mesh->b = toColor(color, 2);
|
|
||||||
mesh->a = toColor(color, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
|
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
|
||||||
|
|
||||||
entry = Json_getItem(attachmentMap, "edges");
|
entry = Json_getItem(attachmentMap, "edges");
|
||||||
@ -767,9 +820,11 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
|
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
|
||||||
mesh->edges[i] = entry->valueInt;
|
mesh->edges[i] = entry->valueInt;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
mesh->inheritFFD = Json_getInt(attachmentMap, "ffd", 1);
|
||||||
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
|
_spSkeletonJson_addLinkedMesh(self, attachment, Json_getString(attachmentMap, "skin", 0), slotIndex,
|
||||||
|
entry->valueString);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_BOUNDING_BOX: {
|
case SP_ATTACHMENT_BOUNDING_BOX: {
|
||||||
@ -791,6 +846,33 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Linked meshes. */
|
||||||
|
for (i = 0; i < internal->linkedMeshCount; i++) {
|
||||||
|
spAttachment* parent;
|
||||||
|
_spLinkedMesh* linkedMesh = internal->linkedMeshes + i;
|
||||||
|
spSkin* skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
|
||||||
|
if (!skin) {
|
||||||
|
spSkeletonData_dispose(skeletonData);
|
||||||
|
_spSkeletonJson_setError(self, 0, "Skin not found: ", linkedMesh->skin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
|
||||||
|
if (!skin) {
|
||||||
|
spSkeletonData_dispose(skeletonData);
|
||||||
|
_spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (linkedMesh->mesh->type == SP_ATTACHMENT_MESH) {
|
||||||
|
spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, linkedMesh->mesh);
|
||||||
|
spMeshAttachment_setParentMesh(mesh, SUB_CAST(spMeshAttachment, parent));
|
||||||
|
spMeshAttachment_updateUVs(mesh);
|
||||||
|
} else {
|
||||||
|
spWeightedMeshAttachment* mesh = SUB_CAST(spWeightedMeshAttachment, linkedMesh->mesh);
|
||||||
|
spWeightedMeshAttachment_setParentMesh(mesh, SUB_CAST(spWeightedMeshAttachment, parent));
|
||||||
|
spWeightedMeshAttachment_updateUVs(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Events. */
|
/* Events. */
|
||||||
events = Json_getItem(root, "events");
|
events = Json_getItem(root, "events");
|
||||||
if (events) {
|
if (events) {
|
||||||
@ -813,8 +895,14 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
if (animations) {
|
if (animations) {
|
||||||
Json *animationMap;
|
Json *animationMap;
|
||||||
skeletonData->animations = MALLOC(spAnimation*, animations->size);
|
skeletonData->animations = MALLOC(spAnimation*, animations->size);
|
||||||
for (animationMap = animations->child; animationMap; animationMap = animationMap->next)
|
for (animationMap = animations->child; animationMap; animationMap = animationMap->next) {
|
||||||
_spSkeletonJson_readAnimation(self, animationMap, skeletonData);
|
spAnimation* animation = _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
|
||||||
|
if (!animation) {
|
||||||
|
spSkeletonData_dispose(skeletonData);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
skeletonData->animations[skeletonData->animationsCount++] = animation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Json_dispose(root);
|
Json_dispose(root);
|
||||||
|
|||||||
@ -36,12 +36,14 @@ void _spWeightedMeshAttachment_dispose (spAttachment* attachment) {
|
|||||||
spWeightedMeshAttachment* self = SUB_CAST(spWeightedMeshAttachment, attachment);
|
spWeightedMeshAttachment* self = SUB_CAST(spWeightedMeshAttachment, attachment);
|
||||||
_spAttachment_deinit(attachment);
|
_spAttachment_deinit(attachment);
|
||||||
FREE(self->path);
|
FREE(self->path);
|
||||||
|
FREE(self->uvs);
|
||||||
|
if (!self->parentMesh) {
|
||||||
|
FREE(self->regionUVs);
|
||||||
FREE(self->bones);
|
FREE(self->bones);
|
||||||
FREE(self->weights);
|
FREE(self->weights);
|
||||||
FREE(self->regionUVs);
|
|
||||||
FREE(self->uvs);
|
|
||||||
FREE(self->triangles);
|
FREE(self->triangles);
|
||||||
FREE(self->edges);
|
FREE(self->edges);
|
||||||
|
}
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,3 +110,28 @@ void spWeightedMeshAttachment_computeWorldVertices (spWeightedMeshAttachment* se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spWeightedMeshAttachment_setParentMesh (spWeightedMeshAttachment* self, spWeightedMeshAttachment* parentMesh) {
|
||||||
|
CONST_CAST(spWeightedMeshAttachment*, self->parentMesh) = parentMesh;
|
||||||
|
if (parentMesh) {
|
||||||
|
self->bones = parentMesh->bones;
|
||||||
|
self->bonesCount = parentMesh->bonesCount;
|
||||||
|
|
||||||
|
self->weights = parentMesh->weights;
|
||||||
|
self->weightsCount = parentMesh->weightsCount;
|
||||||
|
|
||||||
|
self->regionUVs = parentMesh->regionUVs;
|
||||||
|
self->uvsCount = parentMesh->uvsCount;
|
||||||
|
|
||||||
|
self->triangles = parentMesh->triangles;
|
||||||
|
self->trianglesCount = parentMesh->trianglesCount;
|
||||||
|
|
||||||
|
self->hullLength = parentMesh->hullLength;
|
||||||
|
|
||||||
|
self->edges = parentMesh->edges;
|
||||||
|
self->edgesCount = parentMesh->edgesCount;
|
||||||
|
|
||||||
|
self->width = parentMesh->width;
|
||||||
|
self->height = parentMesh->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-cocos2d-iphone v2 works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-cocos2d-iphone v2 works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-cocos2d-iphone v2 supports all Spine features.
|
spine-cocos2d-iphone v2 supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-cocos2d-iphone v3 works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-cocos2d-iphone v3 works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-cocos2d-iphone v3 supports all Spine features.
|
spine-cocos2d-iphone v3 supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-cocos2dx v2 works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-cocos2dx v2 works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-cocos2dx v2 supports all Spine features.
|
spine-cocos2dx v2 supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-cocos2dx v3 works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-cocos2dx v3 works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-cocos2dx v3 supports all Spine features.
|
spine-cocos2dx v3 supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ The Spine Runtimes are developed with the intent to be used with data exported f
|
|||||||
|
|
||||||
## Spine version
|
## Spine version
|
||||||
|
|
||||||
spine-sfml works with data exported from the latest version of Spine, except linked meshes are [not yet supported](https://trello.com/c/bERJAFEq/73-update-runtimes-to-support-v3-1-linked-meshes).
|
spine-sfml works with data exported from the latest version of Spine.
|
||||||
|
|
||||||
spine-sfml supports all Spine features.
|
spine-sfml supports all Spine features.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user