mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 09:16:01 +08:00
[cpp] Sequence and SequenceTimeline support in SkeletonBinary.
This commit is contained in:
parent
2c8f68bd29
commit
9fda6dcd3b
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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 *> ®ions, int start, int digits, int setupIndex);
|
||||
Sequence(int count);
|
||||
|
||||
~Sequence();
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -38,9 +38,9 @@
|
||||
using namespace spine;
|
||||
|
||||
LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
||||
bool inheritDeform) : _mesh(mesh),
|
||||
_skin(skin),
|
||||
_slotIndex(slotIndex),
|
||||
_parent(parent),
|
||||
_inheritDeform(inheritDeform) {
|
||||
bool inheritTimeline) : _mesh(mesh),
|
||||
_skin(skin),
|
||||
_slotIndex(slotIndex),
|
||||
_parent(parent),
|
||||
_inheritTimeline(inheritTimeline) {
|
||||
}
|
||||
|
||||
@ -35,11 +35,12 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
Sequence::Sequence() : _id(Sequence::getNextID()),
|
||||
_regions(),
|
||||
_start(0),
|
||||
_digits(0),
|
||||
_setupIndex(0) {
|
||||
Sequence::Sequence(int count) : _id(Sequence::getNextID()),
|
||||
_regions(),
|
||||
_start(0),
|
||||
_digits(0),
|
||||
_setupIndex(0) {
|
||||
_regions.setSize(count, NULL);
|
||||
}
|
||||
|
||||
Sequence::~Sequence() {
|
||||
|
||||
@ -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;
|
||||
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,69 +1227,84 @@ 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);
|
||||
|
||||
bool weighted = attachment->_bones.size() > 0;
|
||||
Vector<float> &vertices = attachment->_vertices;
|
||||
int deformLength = weighted ? vertices.size() / 3 * 2 : vertices.size();
|
||||
|
||||
unsigned int timelineType = readByte(input);
|
||||
int frameCount = readVarint(input, true);
|
||||
int frameLast = frameCount - 1;
|
||||
int bezierCount = readVarint(input, true);
|
||||
DeformTimeline *timeline = new (__FILE__, __LINE__) DeformTimeline(frameCount, bezierCount, slotIndex,
|
||||
attachment);
|
||||
|
||||
float time = readFloat(input);
|
||||
for (int frame = 0, bezier = 0;; ++frame) {
|
||||
Vector<float> deform;
|
||||
size_t end = (size_t) readVarint(input, true);
|
||||
if (end == 0) {
|
||||
if (weighted) {
|
||||
deform.setSize(deformLength, 0);
|
||||
for (int iiii = 0; iiii < deformLength; ++iiii)
|
||||
deform[iiii] = 0;
|
||||
} else {
|
||||
deform.clearAndAddAll(vertices);
|
||||
}
|
||||
} else {
|
||||
deform.setSize(deformLength, 0);
|
||||
size_t start = (size_t) readVarint(input, true);
|
||||
end += start;
|
||||
if (scale == 1) {
|
||||
for (size_t v = start; v < end; ++v)
|
||||
deform[v] = readFloat(input);
|
||||
} else {
|
||||
for (size_t v = start; v < end; ++v)
|
||||
deform[v] = readFloat(input) * scale;
|
||||
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 bezierCount = readVarint(input, true);
|
||||
DeformTimeline *timeline = new (__FILE__, __LINE__) DeformTimeline(frameCount, bezierCount, slotIndex,
|
||||
attachment);
|
||||
|
||||
float time = readFloat(input);
|
||||
for (int frame = 0, bezier = 0;; ++frame) {
|
||||
Vector<float> deform;
|
||||
size_t end = (size_t) readVarint(input, true);
|
||||
if (end == 0) {
|
||||
if (weighted) {
|
||||
deform.setSize(deformLength, 0);
|
||||
for (int iiii = 0; iiii < deformLength; ++iiii)
|
||||
deform[iiii] = 0;
|
||||
} else {
|
||||
deform.clearAndAddAll(vertices);
|
||||
}
|
||||
} else {
|
||||
deform.setSize(deformLength, 0);
|
||||
size_t start = (size_t) readVarint(input, true);
|
||||
end += start;
|
||||
if (scale == 1) {
|
||||
for (size_t v = start; v < end; ++v)
|
||||
deform[v] = readFloat(input);
|
||||
} else {
|
||||
for (size_t v = start; v < end; ++v)
|
||||
deform[v] = readFloat(input) * scale;
|
||||
}
|
||||
|
||||
if (!weighted) {
|
||||
for (size_t v = 0, vn = deform.size(); v < vn; ++v)
|
||||
deform[v] += vertices[v];
|
||||
}
|
||||
}
|
||||
|
||||
timeline->setFrame(frame, time, deform);
|
||||
if (frame == frameLast) break;
|
||||
float time2 = readFloat(input);
|
||||
switch (readSByte(input)) {
|
||||
case CURVE_STEPPED:
|
||||
timeline->setStepped(frame);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
|
||||
}
|
||||
time = time2;
|
||||
}
|
||||
|
||||
if (!weighted) {
|
||||
for (size_t v = 0, vn = deform.size(); v < vn; ++v)
|
||||
deform[v] += vertices[v];
|
||||
}
|
||||
timelines.add(timeline);
|
||||
break;
|
||||
}
|
||||
|
||||
timeline->setFrame(frame, time, deform);
|
||||
if (frame == frameLast) break;
|
||||
float time2 = readFloat(input);
|
||||
switch (readSByte(input)) {
|
||||
case CURVE_STEPPED:
|
||||
timeline->setStepped(frame);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
|
||||
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;
|
||||
}
|
||||
time = time2;
|
||||
}
|
||||
|
||||
timelines.add(timeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user