[cpp] Sequence and SequenceTimeline support in SkeletonBinary.

This commit is contained in:
Mario Zechner 2021-12-16 17:14:52 +01:00
parent 2c8f68bd29
commit 9fda6dcd3b
6 changed files with 186 additions and 108 deletions

View File

@ -43,14 +43,14 @@ namespace spine {
public:
LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
bool inheritDeform);
bool inheritTimeline);
private:
MeshAttachment *_mesh;
String _skin;
size_t _slotIndex;
String _parent;
bool _inheritDeform;
bool _inheritTimeline;
};
}

View File

@ -39,12 +39,16 @@ namespace spine {
class Attachment;
class SP_API Sequence : public SpineObject {
class SkeletonBinary;
class SkeletonJson;
class SP_API Sequence : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
public:
explicit Sequence();
Sequence(int id, const Vector<TextureRegion *> &regions, int start, int digits, int setupIndex);
Sequence(int count);
~Sequence();

View File

@ -61,6 +61,8 @@ namespace spine {
class CurveTimeline2;
class Sequence;
class SP_API SkeletonBinary : public SpineObject {
public:
static const int BONE_ROTATE = 0;
@ -81,6 +83,9 @@ namespace spine {
static const int SLOT_RGB2 = 4;
static const int SLOT_ALPHA = 5;
static const int ATTACHMENT_DEFORM = 0;
static const int ATTACHMENT_SEQUENCE = 1;
static const int PATH_POSITION = 0;
static const int PATH_SPACING = 1;
static const int PATH_MIX = 2;
@ -137,10 +142,12 @@ namespace spine {
Skin *readSkin(DataInput *input, bool defaultSkin, SkeletonData *skeletonData, bool nonessential);
Sequence *readSequence(DataInput *input);
Attachment *readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
SkeletonData *skeletonData, bool nonessential);
void readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount);
void readVertices(DataInput *input, Vector<float> &vertices, Vector<size_t> &bones, int vertexCount);
void readFloatArray(DataInput *input, int n, float scale, Vector<float> &array);

View File

@ -38,9 +38,9 @@
using namespace spine;
LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
bool inheritDeform) : _mesh(mesh),
bool inheritTimeline) : _mesh(mesh),
_skin(skin),
_slotIndex(slotIndex),
_parent(parent),
_inheritDeform(inheritDeform) {
_inheritTimeline(inheritTimeline) {
}

View File

@ -35,11 +35,12 @@
using namespace spine;
Sequence::Sequence() : _id(Sequence::getNextID()),
Sequence::Sequence(int count) : _id(Sequence::getNextID()),
_regions(),
_start(0),
_digits(0),
_setupIndex(0) {
_regions.setSize(count, NULL);
}
Sequence::~Sequence() {

View File

@ -72,6 +72,7 @@
#include <spine/TransformConstraintData.h>
#include <spine/TransformConstraintTimeline.h>
#include <spine/TranslateTimeline.h>
#include "spine/SequenceTimeline.h"
using namespace spine;
@ -298,10 +299,10 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
setError("Parent mesh not found: ", linkedMesh->_parent.buffer());
return NULL;
}
linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritDeform ? static_cast<VertexAttachment *>(parent)
linkedMesh->_mesh->_timelineAttachment = linkedMesh->_inheritTimeline ? static_cast<VertexAttachment *>(parent)
: linkedMesh->_mesh;
linkedMesh->_mesh->setParentMesh(static_cast<MeshAttachment *>(parent));
linkedMesh->_mesh->updateRegion();
if (linkedMesh->_mesh->_region) linkedMesh->_mesh->updateRegion();
_attachmentLoader->configureAttachment(linkedMesh->_mesh);
}
ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes);
@ -478,6 +479,15 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
return skin;
}
Sequence *SkeletonBinary::readSequence(DataInput *input) {
if (!readBoolean(input)) return NULL;
Sequence *sequence = new (__FILE__, __LINE__) Sequence(readVarint(input, true));
sequence->_start = readVarint(input, true);
sequence->_digits = readVarint(input, true);
sequence->_setupIndex = readVarint(input, true);
return sequence;
}
Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
SkeletonData *skeletonData, bool nonessential) {
String name(readStringRef(input, skeletonData));
@ -488,21 +498,32 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
case AttachmentType_Region: {
String path(readStringRef(input, skeletonData));
if (path.isEmpty()) path = name;
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
float rotation = readFloat(input);
float x = readFloat(input) * _scale;
float y = readFloat(input) * _scale;
float scaleX = readFloat(input);
float scaleY = readFloat(input);
float width = readFloat(input) * _scale;
float height = readFloat(input) * _scale;
Color color;
readColor(input, color);
Sequence *sequence = readSequence(input);
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path), sequence);
if (!region) {
setError("Error reading attachment: ", name.buffer());
return nullptr;
}
region->_path = path;
region->_rotation = readFloat(input);
region->_x = readFloat(input) * _scale;
region->_y = readFloat(input) * _scale;
region->_scaleX = readFloat(input);
region->_scaleY = readFloat(input);
region->_width = readFloat(input) * _scale;
region->_height = readFloat(input) * _scale;
readColor(input, region->getColor());
region->updateRegion();
region->_rotation = rotation;
region->_x = x;
region->_y = y;
region->_scaleX = scaleX;
region->_scaleY = scaleY;
region->_width = width;
region->_height = height;
region->getColor().set(color);
region->_sequence = sequence;
if (sequence == NULL) region->updateRegion();
_attachmentLoader->configureAttachment(region);
return region;
}
@ -513,7 +534,8 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
setError("Error reading attachment: ", name.buffer());
return nullptr;
}
readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
readVertices(input, box->getVertices(), box->getBones(), vertexCount);
box->setWorldVerticesLength(vertexCount << 1);
if (nonessential) {
readColor(input, box->getColor());
}
@ -521,31 +543,51 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
return box;
}
case AttachmentType_Mesh: {
Color color;
int vertexCount;
MeshAttachment *mesh;
Vector<float> uvs;
Vector<unsigned short> triangles;
Vector<float> vertices;
Vector<size_t> bones;
int hullLength;
Sequence *sequence;
float width = 0;
float height = 0;
Vector<unsigned short> edges;
String path(readStringRef(input, skeletonData));
if (path.isEmpty()) path = name;
readColor(input, color);
vertexCount = readVarint(input, true);
readFloatArray(input, vertexCount << 1, 1, uvs);
readShortArray(input, triangles);
readVertices(input, vertices, bones, vertexCount);
hullLength = readVarint(input, true) << 1;
sequence = readSequence(input);
if (nonessential) {
readShortArray(input, edges);
width = readFloat(input) * _scale;
height = readFloat(input) * _scale;
}
mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path), sequence);
if (!mesh) {
setError("Error reading attachment: ", name.buffer());
return nullptr;
}
mesh->_path = path;
readColor(input, mesh->getColor());
vertexCount = readVarint(input, true);
readFloatArray(input, vertexCount << 1, 1, mesh->getRegionUVs());
readShortArray(input, mesh->getTriangles());
readVertices(input, static_cast<VertexAttachment *>(mesh), vertexCount);
mesh->updateRegion();
mesh->_hullLength = readVarint(input, true) << 1;
mesh->_color.set(color);
mesh->_vertices.addAll(vertices);
mesh->setWorldVerticesLength(vertexCount << 1);
mesh->_triangles.addAll(triangles);
mesh->_regionUVs.addAll(uvs);
if (sequence == NULL) mesh->updateRegion();
mesh->_hullLength = hullLength;
mesh->_sequence = sequence;
if (nonessential) {
readShortArray(input, mesh->getEdges());
mesh->_width = readFloat(input) * _scale;
mesh->_height = readFloat(input) * _scale;
} else {
mesh->_width = 0;
mesh->_height = 0;
mesh->_edges.addAll(edges);
mesh->_width = width;
mesh->_height = height;
}
_attachmentLoader->configureAttachment(mesh);
return mesh;
@ -554,23 +596,33 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
String path(readStringRef(input, skeletonData));
if (path.isEmpty()) path = name;
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
Color color;
float width, height;
readColor(input, color);
String skinName(readStringRef(input, skeletonData));
String parent(readStringRef(input, skeletonData));
bool inheritTimelines = readBoolean(input);
Sequence *sequence = readSequence(input);
if (nonessential) {
width = readFloat(input) * _scale;
height = readFloat(input) * _scale;
}
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path), sequence);
if (!mesh) {
setError("Error reading attachment: ", name.buffer());
return nullptr;
}
mesh->_path = path;
readColor(input, mesh->getColor());
String skinName(readStringRef(input, skeletonData));
String parent(readStringRef(input, skeletonData));
bool inheritDeform = readBoolean(input);
mesh->_color.set(color);
mesh->_sequence = sequence;
if (nonessential) {
mesh->_width = readFloat(input) * _scale;
mesh->_height = readFloat(input) * _scale;
mesh->_width = width;
mesh->_height = height;
}
LinkedMesh *linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, String(skinName), slotIndex,
String(parent), inheritDeform);
String(parent), inheritTimelines);
_linkedMeshes.add(linkedMesh);
return mesh;
}
@ -583,7 +635,8 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
path->_closed = readBoolean(input);
path->_constantSpeed = readBoolean(input);
int vertexCount = readVarint(input, true);
readVertices(input, static_cast<VertexAttachment *>(path), vertexCount);
readVertices(input, path->getVertices(), path->getBones(), vertexCount);
path->setWorldVerticesLength(vertexCount << 1);
int lengthsLength = vertexCount / 3;
path->_lengths.setSize(lengthsLength, 0);
for (int i = 0; i < lengthsLength; ++i) {
@ -619,7 +672,8 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
setError("Error reading attachment: ", name.buffer());
return nullptr;
}
readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
readVertices(input, clip->getVertices(), clip->getBones(), vertexCount);
clip->setWorldVerticesLength(vertexCount << 1);
clip->_endSlot = skeletonData->_slots[endSlotIndex];
if (nonessential) {
readColor(input, clip->getColor());
@ -631,18 +685,15 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
return nullptr;
}
void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {
void SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vector<size_t> &bones, int vertexCount) {
float scale = _scale;
int verticesLength = vertexCount << 1;
attachment->setWorldVerticesLength(vertexCount << 1);
if (!readBoolean(input)) {
readFloatArray(input, verticesLength, scale, attachment->getVertices());
readFloatArray(input, verticesLength, scale, vertices);
return;
}
Vector<float> &vertices = attachment->getVertices();
Vector<size_t> &bones = attachment->getBones();
vertices.ensureCapacity(verticesLength * 3 * 3);
bones.ensureCapacity(verticesLength * 3);
@ -1176,21 +1227,22 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
for (int iii = 0, nnn = readVarint(input, true); iii < nnn; iii++) {
const char *attachmentName = readStringRef(input, skeletonData);
Attachment *baseAttachment = skin->getAttachment(slotIndex, String(attachmentName));
if (!baseAttachment) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError("Attachment not found: ", attachmentName);
return NULL;
}
VertexAttachment *attachment = static_cast<VertexAttachment *>(baseAttachment);
unsigned int timelineType = readByte(input);
int frameCount = readVarint(input, true);
int frameLast = frameCount - 1;
switch (timelineType) {
case ATTACHMENT_DEFORM: {
bool weighted = attachment->_bones.size() > 0;
Vector<float> &vertices = attachment->_vertices;
int deformLength = weighted ? vertices.size() / 3 * 2 : vertices.size();
int frameCount = readVarint(input, true);
int frameLast = frameCount - 1;
int bezierCount = readVarint(input, true);
DeformTimeline *timeline = new (__FILE__, __LINE__) DeformTimeline(frameCount, bezierCount, slotIndex,
attachment);
@ -1239,6 +1291,20 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
}
timelines.add(timeline);
break;
}
case ATTACHMENT_SEQUENCE: {
SequenceTimeline *timeline = new (__FILE__, __LINE__) SequenceTimeline(frameCount, slotIndex, attachment);
for (int frame = 0; frame < frameCount; frame++) {
float time = readFloat(input);
int modeAndIndex = readInt(input);
float delay = readFloat(input);
timeline->setFrame(frame, time, (spine::SequenceMode)(modeAndIndex & 0xf), modeAndIndex >> 4, delay);
}
timelines.add(timeline);
break;
}
}
}
}
}