diff --git a/spine-c/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c index eea293778..6b8feba80 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/spine-c/src/spine/SkeletonBinary.c @@ -262,10 +262,12 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con unsigned char timelineType = readByte(input); int frameCount = readVarint(input, 1); switch (timelineType) { - case SLOT_ATTACHMENT: { + case SLOT_ATTACHMENT: + { spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount); timeline->slotIndex = slotIndex; - for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { float time = readFloat(input); const char* attachmentName = readString(input); /* TODO Avoid copying of attachmentName inside */ diff --git a/spine-cpp/spine-cpp/include/spine/Animation.h b/spine-cpp/spine-cpp/include/spine/Animation.h index 8015c57ea..9f0ca70ef 100644 --- a/spine-cpp/spine-cpp/include/spine/Animation.h +++ b/spine-cpp/spine-cpp/include/spine/Animation.h @@ -68,6 +68,8 @@ namespace Spine public: Animation(std::string name, Vector& timelines, float duration); + ~Animation(); + /// Applies all the animation's timelines to the specified skeleton. /// See also Timeline::apply(Skeleton&, float, float, Vector, float, MixPose, MixDirection) void apply(Skeleton& skeleton, float lastTime, float time, bool loop, Vector* pEvents, float alpha, MixPose pose, MixDirection direction); diff --git a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h index 91484b2b6..6fca8296c 100644 --- a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h @@ -46,6 +46,9 @@ namespace Spine class AttachmentTimeline : public Timeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/ColorTimeline.h b/spine-cpp/spine-cpp/include/spine/ColorTimeline.h index 53a33ddd4..740743134 100644 --- a/spine-cpp/spine-cpp/include/spine/ColorTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ColorTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class ColorTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/DeformTimeline.h b/spine-cpp/spine-cpp/include/spine/DeformTimeline.h index a23eaca83..b601ca9f9 100644 --- a/spine-cpp/spine-cpp/include/spine/DeformTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/DeformTimeline.h @@ -39,6 +39,9 @@ namespace Spine class DeformTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h b/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h index 29226dd88..4d1adc00c 100644 --- a/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class DrawOrderTimeline : public Timeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/Event.h b/spine-cpp/spine-cpp/include/spine/Event.h index 1f4688d4c..7c7330744 100644 --- a/spine-cpp/spine-cpp/include/spine/Event.h +++ b/spine-cpp/spine-cpp/include/spine/Event.h @@ -40,6 +40,8 @@ namespace Spine /// Stores the current pose values for an Event. class Event { + friend class SkeletonBinary; + friend class SkeletonJson; friend class AnimationState; public: diff --git a/spine-cpp/spine-cpp/include/spine/EventTimeline.h b/spine-cpp/spine-cpp/include/spine/EventTimeline.h index c2f880080..30e761b66 100644 --- a/spine-cpp/spine-cpp/include/spine/EventTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/EventTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class EventTimeline : public Timeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h index 3cd4235d9..295bd1d9c 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class IkConstraintTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h index 72598ab69..c2cce00e9 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class PathConstraintMixTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h index 2fc8af6a2..b5fe6916b 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class PathConstraintPositionTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h b/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h index 65392639c..68aad43c9 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class PathConstraintSpacingTimeline : public PathConstraintPositionTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h index c14031d98..aed7eb822 100644 --- a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h @@ -37,6 +37,8 @@ namespace Spine { class RotateTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; friend class AnimationState; RTTI_DECL; diff --git a/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h b/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h index 81409a50a..a0788fe1c 100644 --- a/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ScaleTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class ScaleTimeline : public TranslateTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/ShearTimeline.h b/spine-cpp/spine-cpp/include/spine/ShearTimeline.h index ae83d7cef..d3b46ac70 100644 --- a/spine-cpp/spine-cpp/include/spine/ShearTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/ShearTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class ShearTimeline : public TranslateTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h index 1d29d3af6..725ba5edb 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h @@ -46,6 +46,7 @@ namespace Spine class Attachment; class VertexAttachment; class Animation; + class CurveTimeline; class SkeletonBinary { @@ -128,6 +129,8 @@ namespace Spine Vector readShortArray(DataInput *input); Animation* readAnimation(const char* name, DataInput* input, SkeletonData *skeletonData); + + void readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline); }; } diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h index c001e82b1..2324234cb 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class TransformConstraintTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h b/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h index 37fd21a9e..424125ebb 100644 --- a/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/TranslateTimeline.h @@ -40,6 +40,9 @@ namespace Spine { class TranslateTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h b/spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h index fd3f55fd4..266eba418 100644 --- a/spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h @@ -37,6 +37,9 @@ namespace Spine { class TwoColorTimeline : public CurveTimeline { + friend class SkeletonBinary; + friend class SkeletonJson; + RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h index 3529c5cf3..56c057674 100644 --- a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h @@ -42,6 +42,8 @@ namespace Spine /// An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices. class VertexAttachment : public Attachment { + friend class SkeletonBinary; + friend class SkeletonJson; friend class DeformTimeline; RTTI_DECL; diff --git a/spine-cpp/spine-cpp/src/spine/Animation.cpp b/spine-cpp/spine-cpp/src/spine/Animation.cpp index ac140cbf9..d494c4154 100644 --- a/spine-cpp/spine-cpp/src/spine/Animation.cpp +++ b/spine-cpp/spine-cpp/src/spine/Animation.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include /* fmod */ @@ -47,6 +49,11 @@ namespace Spine assert(_name.length() > 0); } + Animation::~Animation() + { + ContainerUtil::cleanUpVectorOfPointers(_timelines); + } + void Animation::apply(Skeleton& skeleton, float lastTime, float time, bool loop, Vector* pEvents, float alpha, MixPose pose, MixDirection direction) { if (loop && _duration != 0) diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index 918904e45..34c92bacc 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -57,6 +57,24 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace Spine { @@ -351,7 +369,7 @@ namespace Spine } /* Linked meshes. */ - for (int i = 0, n = static_cast(_linkedMeshes.size()); i < n; i++) + for (int i = 0, n = static_cast(_linkedMeshes.size()); i < n; ++i) { LinkedMesh* linkedMesh = _linkedMeshes[i]; Skin* skin = linkedMesh->_skin.length() == 0 ? skeletonData->getDefaultSkin() : skeletonData->findSkin(linkedMesh->_skin); @@ -386,7 +404,9 @@ namespace Spine FREE(name); eventData->_intValue = readVarint(input, 0); eventData->_floatValue = readFloat(input); - eventData->_stringValue = readString(input); + const char* eventData_stringValue = readString(input); + eventData->_stringValue = std::string(eventData_stringValue); + FREE(eventData_stringValue); skeletonData->_events[i] = eventData; } @@ -695,6 +715,9 @@ namespace Spine FREE(name); } + FREE(skinName); + FREE(parent); + return mesh; } case AttachmentType_Path: @@ -847,395 +870,459 @@ namespace Spine Animation* SkeletonBinary::readAnimation(const char* name, DataInput* input, SkeletonData *skeletonData) { -// var timelines = new ExposedList(); -// float scale = Scale; -// float duration = 0; -// -// // Slot timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// int slotIndex = ReadVarint(input, true); -// for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) -// { -// int timelineType = input.ReadByte(); -// int frameCount = ReadVarint(input, true); -// switch (timelineType) -// { -// case SLOT_ATTACHMENT: -// { -// AttachmentTimeline timeline = new AttachmentTimeline(frameCount); -// timeline.slotIndex = slotIndex; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[frameCount - 1]); -// break; -// } -// case SLOT_COLOR: -// { -// ColorTimeline timeline = new ColorTimeline(frameCount); -// timeline.slotIndex = slotIndex; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)\ -// { -// float time = ReadFloat(input); -// int color = ReadInt(input); -// float r = ((color & 0xff000000) >> 24) / 255f; -// float g = ((color & 0x00ff0000) >> 16) / 255f; -// float b = ((color & 0x0000ff00) >> 8) / 255f; -// float a = ((color & 0x000000ff)) / 255f; -// timeline.SetFrame(frameIndex, time, r, g, b, a); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); -// break; -// } -// case SLOT_TWO_COLOR: -// { -// TwoColorTimeline timeline = new TwoColorTimeline(frameCount); -// timeline.slotIndex = slotIndex; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// float time = ReadFloat(input); -// int color = ReadInt(input); -// float r = ((color & 0xff000000) >> 24) / 255f; -// float g = ((color & 0x00ff0000) >> 16) / 255f; -// float b = ((color & 0x0000ff00) >> 8) / 255f; -// float a = ((color & 0x000000ff)) / 255f; -// int color2 = ReadInt(input); // 0x00rrggbb -// float r2 = ((color2 & 0x00ff0000) >> 16) / 255f; -// float g2 = ((color2 & 0x0000ff00) >> 8) / 255f; -// float b2 = ((color2 & 0x000000ff)) / 255f; -// -// timeline.SetFrame(frameIndex, time, r, g, b, a, r2, g2, b2); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TwoColorTimeline.ENTRIES]); -// break; -// } -// } -// } -// } -// -// // Bone timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// int boneIndex = ReadVarint(input, true); -// for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) -// { -// int timelineType = input.ReadByte(); -// int frameCount = ReadVarint(input, true); -// switch (timelineType) -// { -// case BONE_ROTATE: -// { -// RotateTimeline timeline = new RotateTimeline(frameCount); -// timeline.boneIndex = boneIndex; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); -// break; -// } -// case BONE_TRANSLATE: -// case BONE_SCALE: -// case BONE_SHEAR: -// { -// TranslateTimeline timeline; -// float timelineScale = 1; -// if (timelineType == BONE_SCALE) -// { -// timeline = new ScaleTimeline(frameCount); -// } -// else if (timelineType == BONE_SHEAR) -// { -// timeline = new ShearTimeline(frameCount); -// } -// else -// { -// timeline = new TranslateTimeline(frameCount); -// timelineScale = scale; -// } -// timeline.boneIndex = boneIndex; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) -// * timelineScale); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); -// break; -// } -// } -// } -// } -// -// // IK timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// int index = ReadVarint(input, true); -// int frameCount = ReadVarint(input, true); -// IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); -// timeline.ikConstraintIndex = index; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]); -// } -// -// // Transform constraint timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// int index = ReadVarint(input, true); -// int frameCount = ReadVarint(input, true); -// TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); -// timeline.transformConstraintIndex = index; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); -// } -// -// // Path constraint timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// int index = ReadVarint(input, true); -// PathConstraintData data = skeletonData.pathConstraints.Items[index]; -// for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) -// { -// int timelineType = ReadSByte(input); -// int frameCount = ReadVarint(input, true); -// switch(timelineType) -// { -// case PATH_POSITION: -// case PATH_SPACING: -// { -// PathConstraintPositionTimeline timeline; -// float timelineScale = 1; -// if (timelineType == PATH_SPACING) -// { -// timeline = new PathConstraintSpacingTimeline(frameCount); -// if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) -// { -// timelineScale = scale; -// } -// } -// else -// { -// timeline = new PathConstraintPositionTimeline(frameCount); -// if (data.positionMode == PositionMode.Fixed) -// { -// timelineScale = scale; -// } -// } -// timeline.pathConstraintIndex = index; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); -// break; -// } -// case PATH_MIX: -// { -// PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); -// timeline.pathConstraintIndex = index; -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input)); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); -// break; -// } -// } -// } -// } -// -// // Deform timelines. -// for (int i = 0, n = ReadVarint(input, true); i < n; i++) -// { -// Skin skin = skeletonData.skins.Items[ReadVarint(input, true)]; -// for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) -// { -// int slotIndex = ReadVarint(input, true); -// for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++) -// { -// VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input)); -// bool weighted = attachment.bones != null; -// float[] vertices = attachment.vertices; -// int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; -// -// int frameCount = ReadVarint(input, true); -// DeformTimeline timeline = new DeformTimeline(frameCount); -// timeline.slotIndex = slotIndex; -// timeline.attachment = attachment; -// -// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) -// { -// float time = ReadFloat(input); -// float[] deform; -// int end = ReadVarint(input, true); -// if (end == 0) -// { -// deform = weighted ? new float[deformLength] : vertices; -// } -// else -// { -// deform = new float[deformLength]; -// int start = ReadVarint(input, true); -// end += start; -// if (scale == 1) -// { -// for (int v = start; v < end; v++) -// { -// deform[v] = ReadFloat(input); -// } -// } -// else -// { -// for (int v = start; v < end; v++) -// { -// deform[v] = ReadFloat(input) * scale; -// } -// } -// -// if (!weighted) -// { -// for (int v = 0, vn = deform.Length; v < vn; v++) -// { -// deform[v] += vertices[v]; -// } -// } -// } -// -// timeline.SetFrame(frameIndex, time, deform); -// if (frameIndex < frameCount - 1) -// { -// ReadCurve(input, frameIndex, timeline); -// } -// } -// -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[frameCount - 1]); -// } -// } -// } -// -// // Draw order timeline. -// int drawOrderCount = ReadVarint(input, true); -// if (drawOrderCount > 0) -// { -// DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); -// int slotCount = skeletonData.slots.Count; -// for (int i = 0; i < drawOrderCount; i++) -// { -// float time = ReadFloat(input); -// int offsetCount = ReadVarint(input, true); -// int[] drawOrder = new int[slotCount]; -// for (int ii = slotCount - 1; ii >= 0; ii--) -// { -// drawOrder[ii] = -1; -// } -// int[] unchanged = new int[slotCount - offsetCount]; -// int originalIndex = 0, unchangedIndex = 0; -// for (int ii = 0; ii < offsetCount; ii++) -// { -// int slotIndex = ReadVarint(input, true); -// // Collect unchanged items. -// while (originalIndex != slotIndex) -// { -// unchanged[unchangedIndex++] = originalIndex++; -// } -// // Set changed items. -// drawOrder[originalIndex + ReadVarint(input, true)] = originalIndex++; -// } -// -// // Collect remaining unchanged items. -// while (originalIndex < slotCount) -// { -// unchanged[unchangedIndex++] = originalIndex++; -// } -// -// // Fill in unchanged items. -// for (int ii = slotCount - 1; ii >= 0; ii--) -// { -// if (drawOrder[ii] == -1) -// { -// drawOrder[ii] = unchanged[--unchangedIndex]; -// } -// } -// timeline.SetFrame(i, time, drawOrder); -// } -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); -// } -// -// // Event timeline. -// int eventCount = ReadVarint(input, true); -// if (eventCount > 0) -// { -// EventTimeline timeline = new EventTimeline(eventCount); -// for (int i = 0; i < eventCount; i++) -// { -// float time = ReadFloat(input); -// EventData eventData = skeletonData.events.Items[ReadVarint(input, true)]; -// Event e = new Event(time, eventData); -// e.Int = ReadVarint(input, false); -// e.Float = ReadFloat(input); -// e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; -// timeline.SetFrame(i, e); -// } -// -// timelines.Add(timeline); -// duration = Math.Max(duration, timeline.frames[eventCount - 1]); -// } -// -// timelines.TrimExcess(); -// + Vector timelines; + float scale = _scale; + float duration = 0; + + // Slot timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + int slotIndex = readVarint(input, true); + for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) + { + unsigned char timelineType = readByte(input); + int frameCount = readVarint(input, true); + switch (timelineType) + { + case SLOT_ATTACHMENT: + { + AttachmentTimeline* timeline = NEW(AttachmentTimeline); + new(timeline) AttachmentTimeline(frameCount); + timeline->_slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + const char* attachmentName = readString(input); + timeline->setFrame(frameIndex, readFloat(input), std::string(attachmentName)); + FREE(attachmentName); + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[frameCount - 1]); + break; + } + case SLOT_COLOR: + { + ColorTimeline* timeline = NEW(ColorTimeline); + new(timeline) ColorTimeline(frameCount); + timeline->_slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + float time = readFloat(input); + int color = readInt(input); + float r = ((color & 0xff000000) >> 24) / 255.0f; + float g = ((color & 0x00ff0000) >> 16) / 255.0f; + float b = ((color & 0x0000ff00) >> 8) / 255.0f; + float a = ((color & 0x000000ff)) / 255.0f; + timeline->setFrame(frameIndex, time, r, g, b, a); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * ColorTimeline::ENTRIES]); + break; + } + case SLOT_TWO_COLOR: + { + TwoColorTimeline* timeline = NEW(TwoColorTimeline); + new(timeline) TwoColorTimeline(frameCount); + timeline->_slotIndex = slotIndex; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + float time = readFloat(input); + int color = readInt(input); + float r = ((color & 0xff000000) >> 24) / 255.0f; + float g = ((color & 0x00ff0000) >> 16) / 255.0f; + float b = ((color & 0x0000ff00) >> 8) / 255.0f; + float a = ((color & 0x000000ff)) / 255.0f; + int color2 = readInt(input); // 0x00rrggbb + float r2 = ((color2 & 0x00ff0000) >> 16) / 255.0f; + float g2 = ((color2 & 0x0000ff00) >> 8) / 255.0f; + float b2 = ((color2 & 0x000000ff)) / 255.0f; + + timeline->setFrame(frameIndex, time, r, g, b, a, r2, g2, b2); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * TwoColorTimeline::ENTRIES]); + break; + } + } + } + } + + // Bone timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + int boneIndex = readVarint(input, true); + for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) + { + unsigned char timelineType = readByte(input); + int frameCount = readVarint(input, true); + switch (timelineType) + { + case BONE_ROTATE: + { + RotateTimeline* timeline = NEW(RotateTimeline); + new(timeline) RotateTimeline(frameCount); + timeline->_boneIndex = boneIndex; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input)); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * RotateTimeline::ENTRIES]); + break; + } + case BONE_TRANSLATE: + case BONE_SCALE: + case BONE_SHEAR: + { + TranslateTimeline* timeline; + float timelineScale = 1; + if (timelineType == BONE_SCALE) + { + timeline = NEW(ScaleTimeline); + new(timeline) ScaleTimeline(frameCount); + } + else if (timelineType == BONE_SHEAR) + { + timeline = NEW(ShearTimeline); + new(timeline) ShearTimeline(frameCount); + } + else + { + timeline = NEW(TranslateTimeline); + new(timeline) TranslateTimeline(frameCount); + timelineScale = scale; + } + timeline->_boneIndex = boneIndex; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input) * timelineScale, readFloat(input) * timelineScale); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * TranslateTimeline::ENTRIES]); + break; + } + } + } + } + + // IK timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + int index = readVarint(input, true); + int frameCount = readVarint(input, true); + IkConstraintTimeline* timeline = NEW(IkConstraintTimeline); + new(timeline) IkConstraintTimeline(frameCount); + timeline->_ikConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readSByte(input)); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * IkConstraintTimeline::ENTRIES]); + } + + // Transform constraint timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + int index = readVarint(input, true); + int frameCount = readVarint(input, true); + TransformConstraintTimeline* timeline = NEW(TransformConstraintTimeline); + new(timeline) TransformConstraintTimeline(frameCount); + timeline->_transformConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readFloat(input), readFloat(input), readFloat(input)); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * TransformConstraintTimeline::ENTRIES]); + } + + // Path constraint timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + int index = readVarint(input, true); + PathConstraintData* data = skeletonData->_pathConstraints[index]; + for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) + { + int timelineType = readSByte(input); + int frameCount = readVarint(input, true); + switch(timelineType) + { + case PATH_POSITION: + case PATH_SPACING: + { + PathConstraintPositionTimeline* timeline; + float timelineScale = 1; + if (timelineType == PATH_SPACING) + { + timeline = NEW(PathConstraintSpacingTimeline); + new(timeline) PathConstraintSpacingTimeline(frameCount); + + if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed) + { + timelineScale = scale; + } + } + else + { + timeline = NEW(PathConstraintPositionTimeline); + new(timeline) PathConstraintPositionTimeline(frameCount); + + if (data->_positionMode == PositionMode_Fixed) + { + timelineScale = scale; + } + } + timeline->_pathConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input) * timelineScale); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * PathConstraintPositionTimeline::ENTRIES]); + break; + } + case PATH_MIX: + { + PathConstraintMixTimeline* timeline = NEW(PathConstraintMixTimeline); + new(timeline) PathConstraintMixTimeline(frameCount); + + timeline->_pathConstraintIndex = index; + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readFloat(input)); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[(frameCount - 1) * PathConstraintMixTimeline::ENTRIES]); + break; + } + } + } + } + + // Deform timelines. + for (int i = 0, n = readVarint(input, true); i < n; ++i) + { + Skin* skin = skeletonData->_skins[readVarint(input, true)]; + for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) + { + int slotIndex = readVarint(input, true); + for (int iii = 0, nnn = readVarint(input, true); iii < nnn; iii++) + { + const char* vertexAttachmentName = readString(input); + VertexAttachment* attachment = static_cast(skin->getAttachment(slotIndex, std::string(vertexAttachmentName))); + FREE(vertexAttachmentName); + bool weighted = attachment->_bones.size() > 0; + Vector& vertices = attachment->_vertices; + int deformLength = weighted ? static_cast(vertices.size()) / 3 * 2 : static_cast(vertices.size()); + + int frameCount = readVarint(input, true); + + DeformTimeline* timeline = NEW(DeformTimeline); + new(timeline) DeformTimeline(frameCount); + + timeline->_slotIndex = slotIndex; + timeline->_attachment = attachment; + + for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) + { + float time = readFloat(input); + Vector deform; + int end = readVarint(input, true); + if (end == 0) + { + if (weighted) + { + deform.reserve(deformLength); + } + else + { + deform = vertices; + } + } + else + { + deform.reserve(deformLength); + int start = readVarint(input, true); + end += start; + if (scale == 1) + { + for (int v = start; v < end; ++v) + { + deform[v] = readFloat(input); + } + } + else + { + for (int v = start; v < end; ++v) + { + deform[v] = readFloat(input) * scale; + } + } + + if (!weighted) + { + for (int v = 0, vn = static_cast(deform.size()); v < vn; ++v) + { + deform[v] += vertices[v]; + } + } + } + + timeline->setFrame(frameIndex, time, deform); + if (frameIndex < frameCount - 1) + { + readCurve(input, frameIndex, timeline); + } + } + + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[frameCount - 1]); + } + } + } + + // Draw order timeline. + int drawOrderCount = readVarint(input, true); + if (drawOrderCount > 0) + { + DrawOrderTimeline* timeline = NEW(DrawOrderTimeline); + new(timeline) DrawOrderTimeline(drawOrderCount); + + int slotCount = static_cast(skeletonData->_slots.size()); + for (int i = 0; i < drawOrderCount; ++i) + { + float time = readFloat(input); + int offsetCount = readVarint(input, true); + + Vector drawOrder; + drawOrder.reserve(slotCount); + for (int ii = slotCount - 1; ii >= 0; --ii) + { + drawOrder[ii] = -1; + } + + Vector unchanged; + unchanged.reserve(slotCount - offsetCount); + int originalIndex = 0, unchangedIndex = 0; + for (int ii = 0; ii < offsetCount; ++ii) + { + int slotIndex = readVarint(input, true); + // Collect unchanged items. + while (originalIndex != slotIndex) + { + unchanged[unchangedIndex++] = originalIndex++; + } + // Set changed items. + int index = originalIndex; + drawOrder[index + readVarint(input, true)] = originalIndex++; + } + + // Collect remaining unchanged items. + while (originalIndex < slotCount) + { + unchanged[unchangedIndex++] = originalIndex++; + } + + // Fill in unchanged items. + for (int ii = slotCount - 1; ii >= 0; --ii) + { + if (drawOrder[ii] == -1) + { + drawOrder[ii] = unchanged[--unchangedIndex]; + } + } + timeline->setFrame(i, time, drawOrder); + } + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[drawOrderCount - 1]); + } + + // Event timeline. + int eventCount = readVarint(input, true); + if (eventCount > 0) + { + EventTimeline* timeline = NEW(EventTimeline); + new(timeline) EventTimeline(eventCount); + + for (int i = 0; i < eventCount; ++i) + { + float time = readFloat(input); + EventData* eventData = skeletonData->_events[readVarint(input, true)]; + Event* event = NEW(Event); + new(event) Event(time, *eventData); + + event->_intValue = readVarint(input, false); + event->_floatValue = readFloat(input); + bool freeString = readBoolean(input); + const char* event_stringValue = freeString ? readString(input) : eventData->_stringValue.c_str(); + event->_stringValue = std::string(event_stringValue); + if (freeString) + { + FREE(event_stringValue); + } + timeline->setFrame(i, event); + } + + timelines.push_back(timeline); + duration = MAX(duration, timeline->_frames[eventCount - 1]); + } + Animation* ret = NEW(Animation); -// new (ret) Animation(std::string(name), timelines, duration); + new (ret) Animation(std::string(name), timelines, duration); return ret; } + + void SkeletonBinary::readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline) + { + switch (readByte(input)) + { + case CURVE_STEPPED: + { + timeline->setStepped(frameIndex); + break; + } + case CURVE_BEZIER: + { + float cx1 = readFloat(input); + float cy1 = readFloat(input); + float cx2 = readFloat(input); + float cy2 = readFloat(input); + timeline->setCurve(frameIndex, cx1, cy1, cx2, cy2); + break; + } + } + } }