Meshes, FFD and skinning for spine-c.

Untested since rendering hasn't yet been done for a runtime that extends spine-c.
This commit is contained in:
NathanSweet 2014-04-28 17:52:01 +02:00
parent 5623631026
commit b1f851a246
13 changed files with 528 additions and 31 deletions

View File

@ -44,7 +44,7 @@ typedef enum {
typedef struct spAttachment spAttachment;
struct spAttachment {
const char* const name;
spAttachmentType type;
const spAttachmentType type;
const void* const vtable;
};

View File

@ -0,0 +1,88 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef SPINE_MESHATTACHMENT_H_
#define SPINE_MESHATTACHMENT_H_
#include <spine/Attachment.h>
#include <spine/Atlas.h>
#include <spine/Slot.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct spMeshAttachment spMeshAttachment;
struct spMeshAttachment {
spAttachment super;
const char* path;
int verticesCount;
float* vertices;
int uvsCount;
float* regionUVs;
float* uvs;
int trianglesCount;
int* triangles;
float r, g, b, a;
void* rendererObject;
int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate;
/* Nonessential. */
int hullLength;
int edgesCount;
int* edges;
float width, height;
};
spMeshAttachment* spMeshAttachment_create (const char* name);
void spMeshAttachment_updateUVs (spMeshAttachment* self);
void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, float x, float y, spSlot* bone, float* worldVertices);
#ifdef SPINE_SHORT_NAMES
typedef spMeshAttachment MeshAttachment;
#define MeshAttachment_create(...) spMeshAttachment_create(__VA_ARGS__)
#define MeshAttachment_updateUVs(...) spMeshAttachment_updateUVs(__VA_ARGS__)
#define MeshAttachment_computeWorldVertices(...) spMeshAttachment_computeWorldVertices(__VA_ARGS__)
#endif
#ifdef __cplusplus
}
#endif
#endif /* SPINE_MESHATTACHMENT_H_ */

View File

@ -46,6 +46,7 @@ typedef enum {
typedef struct spRegionAttachment spRegionAttachment;
struct spRegionAttachment {
spAttachment super;
const char* path;
float x, y, scaleX, scaleY, rotation, width, height;
float r, g, b, a;

View File

@ -0,0 +1,90 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef SPINE_SKINNEDMESHATTACHMENT_H_
#define SPINE_SKINNEDMESHATTACHMENT_H_
#include <spine/Attachment.h>
#include <spine/Slot.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct spSkinnedMeshAttachment spSkinnedMeshAttachment;
struct spSkinnedMeshAttachment {
spAttachment super;
const char* path;
int bonesCount;
int* bones;
int weightsCount;
float* weights;
int trianglesCount;
int* triangles;
int uvsCount;
float* regionUVs;
float* uvs;
float r, g, b, a;
void* rendererObject;
int regionOffsetX, regionOffsetY; /* Pixels stripped from the bottom left, unrotated. */
int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate;
/* Nonessential. */
int hullLength;
int edgesCount;
int* edges;
float width, height;
};
spSkinnedMeshAttachment* spSkinnedMeshAttachment_create (const char* name);
void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self);
void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self, float x, float y, spSlot* bone, float* worldVertices);
#ifdef SPINE_SHORT_NAMES
typedef spSkinnedMeshAttachment SkinnedMeshAttachment;
#define SkinnedMeshAttachment_create(...) spSkinnedMeshAttachment_create(__VA_ARGS__)
#define SkinnedMeshAttachment_updateUVs(...) spSkinnedMeshAttachment_updateUVs(__VA_ARGS__)
#define SkinnedMeshAttachment_computeWorldVertices(...) spSkinnedMeshAttachment_computeWorldVertices(__VA_ARGS__)
#endif
#ifdef __cplusplus
}
#endif
#endif /* SPINE_SKINNEDMESHATTACHMENT_H_ */

View File

@ -47,6 +47,9 @@ typedef struct spSlot {
spBone* const bone;
float r, g, b, a;
spAttachment* const attachment;
int attachmentVerticesCount;
float* attachmentVertices;
} spSlot;
spSlot* spSlot_create (spSlotData* data, struct spSkeleton* skeleton, spBone* bone);

View File

@ -40,7 +40,7 @@ extern "C" {
typedef struct {
const char* const name;
const spBoneData* const boneData;
const char* const attachmentName;
const char* attachmentName;
float r, g, b, a;
int/*bool*/additiveBlending;
} spSlotData;

View File

@ -28,13 +28,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/Animation.h>
#include <spine/AnimationState.h>
#include <spine/AnimationStateData.h>
#include <spine/Event.h>
#include <spine/extension.h>
#include <spine/Skeleton.h>
#include <spine/SkeletonData.h>
#include <string.h>
spTrackEntry* _spTrackEntry_create () {

View File

@ -43,7 +43,7 @@ void _spAttachment_init (spAttachment* self, const char* name, spAttachmentType
VTABLE(spAttachment, self) ->dispose = dispose;
MALLOC_STR(self->name, name);
self->type = type;
CONST_CAST(spAttachmentType, self->type) = type;
}
void _spAttachment_deinit (spAttachment* self) {

View File

@ -0,0 +1,87 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/MeshAttachment.h>
#include <spine/extension.h>
void _spMeshAttachment_dispose (spAttachment* attachment) {
spMeshAttachment* self = SUB_CAST(spMeshAttachment, attachment);
_spAttachment_deinit(attachment);
FREE(self->path);
FREE(self->vertices);
FREE(self->regionUVs);
FREE(self->uvs);
FREE(self->triangles);
FREE(self->edges);
FREE(self);
}
spMeshAttachment* spMeshAttachment_create (const char* name) {
spMeshAttachment* self = NEW(spMeshAttachment);
self->r = 1;
self->g = 1;
self->b = 1;
self->a = 1;
_spAttachment_init(SUPER(self), name, SP_ATTACHMENT_MESH, _spMeshAttachment_dispose);
return self;
}
void spMeshAttachment_updateUVs (spMeshAttachment* self) {
int i;
float width = self->regionU2 - self->regionU, height = self->regionV2 - self->regionV;
FREE(self->uvs);
self->uvs = MALLOC(float, self->uvsCount);
if (self->regionRotate) {
for (i = 0; i < self->uvsCount; i += 2) {
self->uvs[i] = self->regionU + self->regionUVs[i + 1] * width;
self->uvs[i + 1] = self->regionV + height - self->regionUVs[i] * height;
}
} else {
for (i = 0; i < self->uvsCount; i += 2) {
self->uvs[i] = self->regionU + self->regionUVs[i] * width;
self->uvs[i + 1] = self->regionV + self->regionUVs[i + 1] * height;
}
}
}
void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, float x, float y, spSlot* slot, float* worldVertices) {
int i;
float* vertices = self->vertices;
spBone* bone = slot->bone;
x += bone->worldX;
y += bone->worldY;
if (slot->attachmentVerticesCount == self->verticesCount) vertices = slot->attachmentVertices;
for (i = 0; i < self->verticesCount; i += 2) {
float vx = vertices[i];
float vy = vertices[i + 1];
worldVertices[i] = vx * bone->m00 + vy * bone->m01 + x;
worldVertices[i + 1] = vx * bone->m10 + vy * bone->m11 + y;
}
}

View File

@ -33,9 +33,7 @@
void _spRegionAttachment_dispose (spAttachment* attachment) {
spRegionAttachment* self = SUB_CAST(spRegionAttachment, attachment);
_spAttachment_deinit(attachment);
FREE(self);
}

View File

@ -33,6 +33,8 @@
#include "Json.h"
#include <spine/extension.h>
#include <spine/RegionAttachment.h>
#include <spine/MeshAttachment.h>
#include <spine/SkinnedMeshAttachment.h>
#include <spine/AtlasAttachmentLoader.h>
typedef struct {
@ -414,13 +416,19 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spAttachment* attachment;
const char* skinAttachmentName = attachmentMap->name;
const char* attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
const char* path = Json_getString(attachmentMap, "path", 0);
const char* path = Json_getString(attachmentMap, "path", attachmentName);
const char* color;
int i;
Json* entry;
const char* typeString = Json_getString(attachmentMap, "type", "region");
spAttachmentType type;
if (strcmp(typeString, "region") == 0)
type = SP_ATTACHMENT_REGION;
else if (strcmp(typeString, "mesh") == 0)
type = SP_ATTACHMENT_MESH;
else if (strcmp(typeString, "skinnedmesh") == 0)
type = SP_ATTACHMENT_SKINNED_MESH;
else if (strcmp(typeString, "boundingbox") == 0)
type = SP_ATTACHMENT_BOUNDING_BOX;
else {
@ -441,35 +449,152 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
switch (attachment->type) {
case SP_ATTACHMENT_REGION: {
spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;
regionAttachment->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
regionAttachment->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
regionAttachment->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
regionAttachment->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
regionAttachment->rotation = Json_getFloat(attachmentMap, "rotation", 0);
regionAttachment->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
regionAttachment->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
spRegionAttachment* region = (spRegionAttachment*)attachment;
if (path) MALLOC_STR(region->path, path);
region->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
region->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
region->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
region->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
region->rotation = Json_getFloat(attachmentMap, "rotation", 0);
region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
color = Json_getString(attachmentMap, "color", 0);
if (color) {
regionAttachment->r = toColor(color, 0);
regionAttachment->g = toColor(color, 1);
regionAttachment->b = toColor(color, 2);
regionAttachment->a = toColor(color, 3);
region->r = toColor(color, 0);
region->g = toColor(color, 1);
region->b = toColor(color, 2);
region->a = toColor(color, 3);
}
spRegionAttachment_updateOffset(regionAttachment);
spRegionAttachment_updateOffset(region);
break;
}
case SP_ATTACHMENT_MESH: {
spMeshAttachment* mesh = (spMeshAttachment*)attachment;
MALLOC_STR(mesh->path, path);
entry = Json_getItem(attachmentMap, "vertices");
mesh->verticesCount = entry->size;
mesh->vertices = MALLOC(float, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->vertices[i] = entry->valueFloat * self->scale;
entry = Json_getItem(attachmentMap, "triangles");
mesh->trianglesCount = entry->size;
mesh->triangles = MALLOC(int, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->triangles[i] = entry->valueInt;
entry = Json_getItem(attachmentMap, "uvs");
mesh->uvsCount = entry->size;
mesh->regionUVs = MALLOC(float, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->regionUVs[i] = entry->valueFloat;
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_getFloat(attachmentMap, "hull", 0);
entry = Json_getItem(attachmentMap, "edges");
if (entry) {
mesh->edgesCount = entry->size;
mesh->edges = MALLOC(int, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->edges[i] = entry->valueInt;
}
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
break;
}
case SP_ATTACHMENT_SKINNED_MESH: {
spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)attachment;
int verticesCount, b, w, nn;
float* vertices;
MALLOC_STR(mesh->path, path);
entry = Json_getItem(attachmentMap, "uvs");
mesh->uvsCount = entry->size;
mesh->regionUVs = MALLOC(float, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->regionUVs[i] = entry->valueFloat;
entry = Json_getItem(attachmentMap, "vertices");
verticesCount = entry->size;
vertices = MALLOC(float, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
vertices[i] = entry->valueFloat;
for (i = 0; i < verticesCount;) {
int boneCount = (int)vertices[i++];
mesh->bonesCount += boneCount + 1;
mesh->weightsCount += boneCount * 3;
}
mesh->bones = MALLOC(int, mesh->bonesCount);
mesh->weights = MALLOC(float, mesh->weightsCount);
for (i = 0, b = 0, w = 0; i < verticesCount;) {
int boneCount = (int)vertices[i++];
mesh->bones[b++] = boneCount;
for (nn = i + boneCount * 4; i < nn;) {
mesh->bones[b++] = (int)vertices[i];
mesh->weights[w++] = vertices[i + 1] * self->scale;
mesh->weights[w++] = vertices[i + 2] * self->scale;
mesh->weights[w++] = vertices[i + 3];
i += 4;
}
}
FREE(vertices);
entry = Json_getItem(attachmentMap, "triangles");
mesh->trianglesCount = entry->size;
mesh->triangles = MALLOC(int, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->triangles[i] = entry->valueInt;
spSkinnedMeshAttachment_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_getFloat(attachmentMap, "hull", 0);
entry = Json_getItem(attachmentMap, "edges");
if (entry) {
mesh->edgesCount = entry->size;
mesh->edges = MALLOC(int, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
mesh->edges[i] = entry->valueInt;
}
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
break;
}
case SP_ATTACHMENT_BOUNDING_BOX: {
spBoundingBoxAttachment* box = (spBoundingBoxAttachment*)attachment;
Json* verticesArray = Json_getItem(attachmentMap, "vertices");
Json* vertex;
int i;
box->verticesCount = verticesArray->size;
box->vertices = MALLOC(float, verticesArray->size);
for (vertex = verticesArray->child, i = 0; vertex; vertex = vertex->next, ++i)
box->vertices[i] = vertex->valueFloat * self->scale;
entry = Json_getItem(attachmentMap, "vertices");
box->verticesCount = entry->size;
box->vertices = MALLOC(float, entry->size);
for (entry = entry->child, i = 0; entry; entry = entry->next, ++i)
box->vertices[i] = entry->valueFloat * self->scale;
break;
}
}

View File

@ -0,0 +1,109 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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 THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <spine/SkinnedMeshAttachment.h>
#include <spine/extension.h>
void _spSkinnedMeshAttachment_dispose (spAttachment* attachment) {
spSkinnedMeshAttachment* self = SUB_CAST(spSkinnedMeshAttachment, attachment);
_spAttachment_deinit(attachment);
FREE(self->path);
FREE(self->bones);
FREE(self->weights);
FREE(self->regionUVs);
FREE(self->uvs);
FREE(self->triangles);
FREE(self->edges);
FREE(self);
}
spSkinnedMeshAttachment* spSkinnedMeshAttachment_create (const char* name) {
spSkinnedMeshAttachment* self = NEW(spSkinnedMeshAttachment);
self->r = 1;
self->g = 1;
self->b = 1;
self->a = 1;
_spAttachment_init(SUPER(self), name, SP_ATTACHMENT_SKINNED_MESH, _spSkinnedMeshAttachment_dispose);
return self;
}
void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self) {
int i;
float width = self->regionU2 - self->regionU, height = self->regionV2 - self->regionV;
FREE(self->uvs);
self->uvs = MALLOC(float, self->uvsCount);
if (self->regionRotate) {
for (i = 0; i < self->uvsCount; i += 2) {
self->uvs[i] = self->regionU + self->regionUVs[i + 1] * width;
self->uvs[i + 1] = self->regionV + height - self->regionUVs[i] * height;
}
} else {
for (i = 0; i < self->uvsCount; i += 2) {
self->uvs[i] = self->regionU + self->regionUVs[i] * width;
self->uvs[i + 1] = self->regionV + self->regionUVs[i + 1] * height;
}
}
}
void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self, float x, float y, spSlot* slot,
float* worldVertices) {
int w = 0, v = 0, b = 0, f = 0;
spBone** skeletonBones = slot->skeleton->bones;
if (slot->attachmentVerticesCount == 0) {
for (; v < self->bonesCount; w += 2) {
float wx = 0, wy = 0;
int nn = self->bones[v] + v;
v++;
for (; v <= nn; v++, b += 3) {
spBone* bone = skeletonBones[self->bones[v]];
float vx = self->weights[b], vy = self->weights[b + 1], weight = self->weights[b + 2];
wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight;
wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight;
}
worldVertices[w] = wx + x;
worldVertices[w + 1] = wy + y;
}
} else {
float* ffd = slot->attachmentVertices;
for (; v < self->bonesCount; w += 2) {
float wx = 0, wy = 0;
int nn = self->bones[v] + v;
v++;
for (; v <= nn; v++, b += 3, f += 2) {
spBone* bone = skeletonBones[self->bones[v]];
float vx = self->weights[b] + ffd[f], vy = self->weights[b + 1] + ffd[f + 1], weight = self->weights[b + 2];
wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight;
wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight;
}
worldVertices[w] = wx + x;
worldVertices[w + 1] = wy + y;
}
}
}

View File

@ -47,6 +47,7 @@ spSlot* spSlot_create (spSlotData* data, spSkeleton* skeleton, spBone* bone) {
}
void spSlot_dispose (spSlot* self) {
FREE(self->attachmentVertices);
FREE(self);
}