[c][cpp] Expose colors on bones, attachments. Closes #1823

This commit is contained in:
Mario Zechner 2021-06-14 14:50:07 +02:00
parent 06ac2ca28a
commit 3af35555a9
20 changed files with 136 additions and 42 deletions

View File

@ -31,6 +31,7 @@
#define SPINE_BONEDATA_H_
#include <spine/dll.h>
#include <spine/Color.h>
#ifdef __cplusplus
extern "C" {
@ -53,6 +54,7 @@ struct spBoneData {
float x, y, rotation, scaleX, scaleY, shearX, shearY;
spTransformMode transformMode;
int/*bool*/ skinRequired;
spColor color;
};
SP_API spBoneData *spBoneData_create(int index, const char *name, spBoneData *parent);

View File

@ -42,6 +42,7 @@ extern "C" {
typedef struct spBoundingBoxAttachment {
spVertexAttachment super;
spColor color;
} spBoundingBoxAttachment;
SP_API spBoundingBoxAttachment *spBoundingBoxAttachment_create(const char *name);

View File

@ -43,6 +43,7 @@ extern "C" {
typedef struct spClippingAttachment {
spVertexAttachment super;
spSlotData *endSlot;
spColor color;
} spClippingAttachment;
SP_API void _spClippingAttachment_dispose(spAttachment *self);

View File

@ -45,6 +45,7 @@ typedef struct spPathAttachment {
int lengthsLength;
float *lengths;
int/*bool*/ closed, constantSpeed;
spColor color;
} spPathAttachment;
SP_API spPathAttachment *spPathAttachment_create(const char *name);

View File

@ -48,6 +48,9 @@ typedef struct spSkeletonData {
const char *version;
const char *hash;
float x, y, width, height;
float fps;
const char *imagesPath;
const char *audioPath;
int stringsCount;
char **strings;

View File

@ -1002,7 +1002,10 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
int vertexCount = readVarint(input, 1);
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
if (nonessential) readInt(input); /* Skip color. */
if (nonessential) {
spBoundingBoxAttachment *bbox = SUB_CAST(spBoundingBoxAttachment, attachment);
readColor(input, &bbox->color.r, &bbox->color.g, &bbox->color.b, &bbox->color.a);
}
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
return attachment;
}
@ -1079,7 +1082,9 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
for (i = 0; i < path->lengthsLength; ++i) {
path->lengths[i] = readFloat(input) * self->scale;
}
if (nonessential) readInt(input); /* Skip color. */
if (nonessential) {
readColor(input, &path->color.r, &path->color.g, &path->color.b, &path->color.a);
}
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
return attachment;
}
@ -1102,7 +1107,9 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
spClippingAttachment *clip = SUB_CAST(spClippingAttachment, attachment);
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
if (nonessential) readInt(input); /* Skip color. */
if (nonessential) {
readColor(input, &clip->color.r, &clip->color.g, &clip->color.b, &clip->color.a);
}
clip->endSlot = skeletonData->slots[endSlotIndex];
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
return attachment;
@ -1201,10 +1208,17 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
nonessential = readBoolean(input);
if (nonessential) {
/* Skip images path & fps */
readFloat(input);
FREE(readString(input));
FREE(readString(input));
skeletonData->fps = readFloat(input);
skeletonData->imagesPath = readString(input);
if (!strlen(skeletonData->imagesPath)) {
FREE(skeletonData->imagesPath);
skeletonData->imagesPath = 0;
}
skeletonData->audioPath = readString(input);
if (!strlen(skeletonData->audioPath)) {
FREE(skeletonData->audioPath);
skeletonData->audioPath = 0;
}
}
skeletonData->stringsCount = n = readVarint(input, 1);
@ -1251,7 +1265,9 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
break;
}
data->skinRequired = readBoolean(input);
if (nonessential) readInt(input); /* Skip bone color. */
if (nonessential) {
readColor(input, &data->color.r, &data->color.g, &data->color.b, &data->color.a);
}
skeletonData->bones[i] = data;
}

View File

@ -76,6 +76,8 @@ void spSkeletonData_dispose(spSkeletonData *self) {
FREE(self->hash);
FREE(self->version);
FREE(self->imagesPath);
FREE(self->audioPath);
FREE(self);
}

View File

@ -902,16 +902,15 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (skeleton) {
MALLOC_STR(skeletonData->hash, Json_getString(skeleton, "hash", 0));
MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", 0));
if (strcmp(skeletonData->version, "3.8.75") == 0) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root,
"Unsupported skeleton data, please export with a newer version of Spine.", "");
return 0;
}
skeletonData->x = Json_getFloat(skeleton, "x", 0);
skeletonData->y = Json_getFloat(skeleton, "y", 0);
skeletonData->width = Json_getFloat(skeleton, "width", 0);
skeletonData->height = Json_getFloat(skeleton, "height", 0);
skeletonData->fps = Json_getFloat(skeleton, "fps", 30);
skeletonData->imagesPath = Json_getString(skeleton, "images", 0);
if (skeletonData->imagesPath) skeletonData->imagesPath = strdup(skeletonData->imagesPath);
skeletonData->audioPath = Json_getString(skeleton, "audio", 0);
if (skeletonData->audioPath) skeletonData->audioPath = strdup(skeletonData->audioPath);
}
/* Bones. */
@ -920,6 +919,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
for (boneMap = bones->child, i = 0; boneMap; boneMap = boneMap->next, ++i) {
spBoneData *data;
const char *transformMode;
const char *color;
spBoneData *parent = 0;
const char *parentName = Json_getString(boneMap, "parent", 0);
@ -952,6 +952,9 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
data->skinRequired = Json_getInt(boneMap, "skin", 0) ? 1 : 0;
color = Json_getString(boneMap, "color", 0);
if (color) toColor2(&data->color, color, -1);
skeletonData->bones[i] = data;
skeletonData->bonesCount++;
}
@ -1370,6 +1373,14 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
int vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_readVertices(self, attachmentMap, SUPER(box), vertexCount);
box->super.verticesCount = vertexCount;
color = Json_getString(attachmentMap, "color", 0);
if (color) {
spColor_setFromFloats(&box->color,
toColor(color, 0),
toColor(color, 1),
toColor(color, 2),
toColor(color, 3));
}
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break;
}
@ -1387,6 +1398,14 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
curves = Json_getItem(attachmentMap, "lengths");
for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii)
pathAttachment->lengths[ii] = curves->valueFloat * self->scale;
color = Json_getString(attachmentMap, "color", 0);
if (color) {
spColor_setFromFloats(&pathAttachment->color,
toColor(color, 0),
toColor(color, 1),
toColor(color, 2),
toColor(color, 3));
}
break;
}
case SP_ATTACHMENT_POINT: {
@ -1415,6 +1434,14 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
}
vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_readVertices(self, attachmentMap, SUPER(clip), vertexCount);
color = Json_getString(attachmentMap, "color", 0);
if (color) {
spColor_setFromFloats(&clip->color,
toColor(color, 0),
toColor(color, 1),
toColor(color, 2),
toColor(color, 3));
}
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break;
}

View File

@ -33,6 +33,7 @@
#include <spine/TransformMode.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Color.h>
namespace spine {
class SP_API BoneData : public SpineObject {
@ -122,6 +123,8 @@ namespace spine {
void setSkinRequired(bool inValue);
Color &getColor();
private:
const int _index;
const String _name;
@ -130,6 +133,7 @@ namespace spine {
float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY;
TransformMode _transformMode;
bool _skinRequired;
Color _color;
};
}

View File

@ -31,6 +31,7 @@
#define Spine_BoundingBoxAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
#include <spine/SpineObject.h>
namespace spine {
@ -38,9 +39,14 @@ namespace spine {
class SP_API BoundingBoxAttachment : public VertexAttachment {
RTTI_DECL
public:
explicit BoundingBoxAttachment(const String &name);
Color &getColor();
virtual Attachment *copy();
private:
Color _color;
};
}

View File

@ -31,6 +31,7 @@
#define Spine_ClippingAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
namespace spine {
class SlotData;
@ -51,10 +52,13 @@ namespace spine {
void setEndSlot(SlotData *inValue);
Color &getColor();
virtual Attachment *copy();
private:
SlotData *_endSlot;
Color _color;
};
}

View File

@ -31,6 +31,7 @@
#define Spine_PathAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
namespace spine {
class SP_API PathAttachment : public VertexAttachment {
@ -54,12 +55,15 @@ namespace spine {
void setConstantSpeed(bool inValue);
Color &getColor();
virtual Attachment *copy();
private:
Vector<float> _lengths;
bool _closed;
bool _constantSpeed;
Color _color;
};
}

View File

@ -31,6 +31,7 @@
#define Spine_PointAttachment_h
#include <spine/Attachment.h>
#include <spine/Color.h>
namespace spine {
class Bone;
@ -67,10 +68,13 @@ namespace spine {
void setRotation(float inValue);
Color &getColor();
virtual Attachment *copy();
private:
float _x, _y, _rotation;
Color _color;
};
}

View File

@ -50,7 +50,8 @@ BoneData::BoneData(int index, const String &name, BoneData *parent) :
_shearX(0),
_shearY(0),
_transformMode(TransformMode_Normal),
_skinRequired(false) {
_skinRequired(false),
_color() {
assert(index >= 0);
assert(_name.length() > 0);
}
@ -146,3 +147,7 @@ bool BoneData::isSkinRequired() {
void BoneData::setSkinRequired(bool inValue) {
_skinRequired = inValue;
}
Color &BoneData::getColor() {
return _color;
}

View File

@ -37,7 +37,11 @@ using namespace spine;
RTTI_IMPL(BoundingBoxAttachment, VertexAttachment)
BoundingBoxAttachment::BoundingBoxAttachment(const String &name) : VertexAttachment(name) {
BoundingBoxAttachment::BoundingBoxAttachment(const String &name) : VertexAttachment(name), _color() {
}
Color &BoundingBoxAttachment::getColor() {
return _color;
}
Attachment *BoundingBoxAttachment::copy() {

View File

@ -39,7 +39,7 @@ using namespace spine;
RTTI_IMPL(ClippingAttachment, VertexAttachment)
ClippingAttachment::ClippingAttachment(const String &name) : VertexAttachment(name), _endSlot(NULL) {
ClippingAttachment::ClippingAttachment(const String &name) : VertexAttachment(name), _endSlot(NULL), _color() {
}
SlotData *ClippingAttachment::getEndSlot() {
@ -50,6 +50,10 @@ void ClippingAttachment::setEndSlot(SlotData *inValue) {
_endSlot = inValue;
}
Color &ClippingAttachment::getColor() {
return _color;
}
Attachment *ClippingAttachment::copy() {
ClippingAttachment *copy = new(__FILE__, __LINE__) ClippingAttachment(getName());
copyTo(copy);

View File

@ -37,7 +37,7 @@ using namespace spine;
RTTI_IMPL(PathAttachment, VertexAttachment)
PathAttachment::PathAttachment(const String &name) : VertexAttachment(name), _closed(false), _constantSpeed(false) {
PathAttachment::PathAttachment(const String &name) : VertexAttachment(name), _closed(false), _constantSpeed(false), _color() {
}
Vector<float> &PathAttachment::getLengths() {
@ -60,6 +60,10 @@ void PathAttachment::setConstantSpeed(bool inValue) {
_constantSpeed = inValue;
}
Color &PathAttachment::getColor() {
return _color;
}
Attachment *PathAttachment::copy() {
PathAttachment *copy = new(__FILE__, __LINE__) PathAttachment(getName());
copyTo(copy);

View File

@ -41,7 +41,7 @@ using namespace spine;
RTTI_IMPL(PointAttachment, Attachment)
PointAttachment::PointAttachment(const String &name) : Attachment(name), _x(0), _y(0), _rotation(0) {
PointAttachment::PointAttachment(const String &name) : Attachment(name), _x(0), _y(0), _rotation(0), _color() {
}
void PointAttachment::computeWorldPosition(Bone &bone, float &ox, float &oy) {
@ -81,6 +81,10 @@ void PointAttachment::setRotation(float inValue) {
_rotation = inValue;
}
Color &PointAttachment::getColor() {
return _color;
}
Attachment *PointAttachment::copy() {
PointAttachment *copy = new(__FILE__, __LINE__) PointAttachment(getName());
copy->_x = _x;

View File

@ -127,7 +127,6 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
nonessential = readBoolean(input);
if (nonessential) {
/* Skip images path, audio path & fps */
skeletonData->_fps = readFloat(input);
skeletonData->_imagesPath.own(readString(input));
skeletonData->_audioPath.own(readString(input));
@ -154,7 +153,9 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
data->_length = readFloat(input) * _scale;
data->_transformMode = static_cast<TransformMode>(readVarint(input, true));
data->_skinRequired = readBoolean(input);
if (nonessential) readInt(input); /* Skip bone color. */
if (nonessential) {
readColor(input, data->getColor());
}
skeletonData->_bones[i] = data;
}
@ -315,7 +316,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
eventData->_intValue = readVarint(input, false);
eventData->_floatValue = readFloat(input);
eventData->_stringValue.own(readString(input));
eventData->_audioPath.own(readString(input)); // skip audio path
eventData->_audioPath.own(readString(input));
if (!eventData->_audioPath.isEmpty()) {
eventData->_volume = readFloat(input);
eventData->_balance = readFloat(input);
@ -515,8 +516,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
}
readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
if (nonessential) {
/* Skip color. */
readInt(input);
readColor(input, box->getColor());
}
_attachmentLoader->configureAttachment(box);
return box;
@ -591,8 +591,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
path->_lengths[i] = readFloat(input) * _scale;
}
if (nonessential) {
/* Skip color. */
readInt(input);
readColor(input, path->getColor());
}
_attachmentLoader->configureAttachment(path);
return path;
@ -608,8 +607,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
point->_y = readFloat(input) * _scale;
if (nonessential) {
/* Skip color. */
readInt(input);
readColor(input, point->getColor());
}
_attachmentLoader->configureAttachment(point);
return point;
@ -625,8 +623,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
clip->_endSlot = skeletonData->_slots[endSlotIndex];
if (nonessential) {
/* Skip color. */
readInt(input);
readColor(input, clip->getColor());
}
_attachmentLoader->configureAttachment(clip);
return clip;

View File

@ -205,6 +205,9 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
data->_transformMode = TransformMode_NoScaleOrReflection;
data->_skinRequired = Json::getBoolean(boneMap, "skin", false);
const char* color = Json::getString(boneMap, "color", NULL);
if (color) toColor(data->getColor(), color, true);
skeletonData->_bones[i] = data;
bonesCount++;
}
@ -548,12 +551,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
region->_height = Json::getFloat(attachmentMap, "height", 32) * _scale;
color = Json::getString(attachmentMap, "color", 0);
if (color) {
region->getColor().r = toColor(color, 0);
region->getColor().g = toColor(color, 1);
region->getColor().b = toColor(color, 2);
region->getColor().a = toColor(color, 3);
}
if (color) toColor(region->getColor(), color, true);
region->updateOffset();
_attachmentLoader->configureAttachment(region);
@ -573,12 +571,7 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
mesh->_path = attachmentPath;
color = Json::getString(attachmentMap, "color", 0);
if (color) {
mesh->getColor().r = toColor(color, 0);
mesh->getColor().g = toColor(color, 1);
mesh->getColor().b = toColor(color, 2);
mesh->getColor().a = toColor(color, 3);
}
if (color) toColor(mesh->getColor(), color, true);
mesh->_width = Json::getFloat(attachmentMap, "width", 32) * _scale;
mesh->_height = Json::getFloat(attachmentMap, "height", 32) * _scale;
@ -633,6 +626,8 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
int vertexCount = Json::getInt(attachmentMap, "vertexCount", 0) << 1;
readVertices(attachmentMap, box, vertexCount);
color = Json::getString(attachmentMap, "color", NULL);
if (color) toColor(box->getColor(), color, true);
_attachmentLoader->configureAttachment(attachment);
break;
}
@ -654,6 +649,8 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
curves = Json::getItem(attachmentMap, "lengths");
for (curves = curves->_child, ii = 0; curves; curves = curves->_next, ++ii)
pathAttatchment->_lengths[ii] = curves->_valueFloat * _scale;
color = Json::getString(attachmentMap, "color", NULL);
if (color) toColor(pathAttatchment->getColor(), color, true);
_attachmentLoader->configureAttachment(attachment);
break;
}
@ -665,6 +662,8 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
point->_x = Json::getFloat(attachmentMap, "x", 0) * _scale;
point->_y = Json::getFloat(attachmentMap, "y", 0) * _scale;
point->_rotation = Json::getFloat(attachmentMap, "rotation", 0);
color = Json::getString(attachmentMap, "color", NULL);
if (color) toColor(point->getColor(), color, true);
_attachmentLoader->configureAttachment(attachment);
break;
}
@ -678,6 +677,8 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
if (end) clip->_endSlot = skeletonData->findSlot(end);
vertexCount = Json::getInt(attachmentMap, "vertexCount", 0) << 1;
readVertices(attachmentMap, clip, vertexCount);
color = Json::getString(attachmentMap, "color", NULL);
if (color) toColor(clip->getColor(), color, true);
_attachmentLoader->configureAttachment(attachment);
break;
}