mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[cpp] Fix SkeletinBinary, fix memory leaks
This commit is contained in:
parent
ff4cfbaa05
commit
2dc7335b4e
@ -37,6 +37,8 @@ namespace spine {
|
|||||||
/// The interface for all constraints.
|
/// The interface for all constraints.
|
||||||
class SP_API ConstraintData : public SpineObject {
|
class SP_API ConstraintData : public SpineObject {
|
||||||
|
|
||||||
|
friend class SkeletonBinary;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -42,12 +42,16 @@ namespace spine {
|
|||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
LinkedMesh(MeshAttachment *mesh, const int skinIndex, size_t slotIndex, const String &parent,
|
||||||
bool inheritTimeline);
|
bool inheritTimeline);
|
||||||
|
|
||||||
|
LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
||||||
|
bool inheritTimeline);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MeshAttachment *_mesh;
|
MeshAttachment *_mesh;
|
||||||
String _skin;
|
int _skinIndex;
|
||||||
|
String _skin;
|
||||||
size_t _slotIndex;
|
size_t _slotIndex;
|
||||||
String _parent;
|
String _parent;
|
||||||
bool _inheritTimeline;
|
bool _inheritTimeline;
|
||||||
|
|||||||
@ -75,6 +75,7 @@ namespace spine {
|
|||||||
static const int BONE_SHEAR = 7;
|
static const int BONE_SHEAR = 7;
|
||||||
static const int BONE_SHEARX = 8;
|
static const int BONE_SHEARX = 8;
|
||||||
static const int BONE_SHEARY = 9;
|
static const int BONE_SHEARY = 9;
|
||||||
|
static const int BONE_INHERIT = 10;
|
||||||
|
|
||||||
static const int SLOT_ATTACHMENT = 0;
|
static const int SLOT_ATTACHMENT = 0;
|
||||||
static const int SLOT_RGBA = 1;
|
static const int SLOT_RGBA = 1;
|
||||||
@ -90,6 +91,15 @@ namespace spine {
|
|||||||
static const int PATH_SPACING = 1;
|
static const int PATH_SPACING = 1;
|
||||||
static const int PATH_MIX = 2;
|
static const int PATH_MIX = 2;
|
||||||
|
|
||||||
|
static const int PHYSICS_INERTIA = 0;
|
||||||
|
static const int PHYSICS_STRENGTH = 1;
|
||||||
|
static const int PHYSICS_DAMPING = 2;
|
||||||
|
static const int PHYSICS_MASS = 4;
|
||||||
|
static const int PHYSICS_WIND = 5;
|
||||||
|
static const int PHYSICS_GRAVITY = 6;
|
||||||
|
static const int PHYSICS_MIX = 7;
|
||||||
|
static const int PHYSICS_RESET = 8;
|
||||||
|
|
||||||
static const int CURVE_LINEAR = 0;
|
static const int CURVE_LINEAR = 0;
|
||||||
static const int CURVE_STEPPED = 1;
|
static const int CURVE_STEPPED = 1;
|
||||||
static const int CURVE_BEZIER = 2;
|
static const int CURVE_BEZIER = 2;
|
||||||
@ -147,11 +157,11 @@ namespace spine {
|
|||||||
Attachment *readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
|
Attachment *readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
|
||||||
SkeletonData *skeletonData, bool nonessential);
|
SkeletonData *skeletonData, bool nonessential);
|
||||||
|
|
||||||
void readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, int vertexCount);
|
int readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, bool weighted);
|
||||||
|
|
||||||
void readFloatArray(DataInput *input, int n, float scale, Vector<float> &array);
|
void readFloatArray(DataInput *input, int n, float scale, Vector<float> &array);
|
||||||
|
|
||||||
void readShortArray(DataInput *input, Vector<unsigned short> &array);
|
void readShortArray(DataInput *input, Vector<unsigned short> &array, int n);
|
||||||
|
|
||||||
Animation *readAnimation(const String &name, DataInput *input, SkeletonData *skeletonData);
|
Animation *readAnimation(const String &name, DataInput *input, SkeletonData *skeletonData);
|
||||||
|
|
||||||
@ -159,9 +169,9 @@ namespace spine {
|
|||||||
setBezier(DataInput *input, CurveTimeline *timeline, int bezier, int frame, int value, float time1, float time2,
|
setBezier(DataInput *input, CurveTimeline *timeline, int bezier, int frame, int value, float time1, float time2,
|
||||||
float value1, float value2, float scale);
|
float value1, float value2, float scale);
|
||||||
|
|
||||||
Timeline *readTimeline(DataInput *input, CurveTimeline1 *timeline, float scale);
|
void readTimeline(DataInput *input, Vector<Timeline*> &timelines, CurveTimeline1 *timeline, float scale);
|
||||||
|
|
||||||
Timeline *readTimeline2(DataInput *input, CurveTimeline2 *timeline, float scale);
|
void readTimeline2(DataInput *input, Vector<Timeline*> &timelines, CurveTimeline2 *timeline, float scale);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -195,7 +195,7 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String substring(int startIndex, int length) const {
|
String substring(int startIndex, int length) const {
|
||||||
if (startIndex < 0 || startIndex >= _length || length < 0 || startIndex + length > _length) {
|
if (startIndex < 0 || startIndex >= (int)_length || length < 0 || startIndex + length > (int)_length) {
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
char* subStr = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
|
char* subStr = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
|
||||||
@ -205,7 +205,7 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String substring(int startIndex) const {
|
String substring(int startIndex) const {
|
||||||
if (startIndex < 0 || startIndex >= _length) {
|
if (startIndex < 0 || startIndex >= (int)_length) {
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
int length = _length - startIndex;
|
int length = _length - startIndex;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress
|
|||||||
float rotationIK = -bone._ashearX - bone._arotation;
|
float rotationIK = -bone._ashearX - bone._arotation;
|
||||||
float tx = 0, ty = 0;
|
float tx = 0, ty = 0;
|
||||||
|
|
||||||
switch (bone._data.getInherit()) {
|
switch (bone._inherit) {
|
||||||
case Inherit_OnlyTranslation:
|
case Inherit_OnlyTranslation:
|
||||||
tx = (targetX - bone._worldX) * MathUtil::sign(bone.getSkeleton().getScaleX());
|
tx = (targetX - bone._worldX) * MathUtil::sign(bone.getSkeleton().getScaleX());
|
||||||
ty = (targetY - bone._worldY) * MathUtil::sign(bone.getSkeleton().getScaleY());
|
ty = (targetY - bone._worldY) * MathUtil::sign(bone.getSkeleton().getScaleY());
|
||||||
@ -77,7 +77,7 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress
|
|||||||
float sx = bone._ascaleX;
|
float sx = bone._ascaleX;
|
||||||
float sy = bone._ascaleY;
|
float sy = bone._ascaleY;
|
||||||
if (compress || stretch) {
|
if (compress || stretch) {
|
||||||
switch (bone._data.getInherit()) {
|
switch (bone._inherit) {
|
||||||
case Inherit_NoScale:
|
case Inherit_NoScale:
|
||||||
case Inherit_NoScaleOrReflection:
|
case Inherit_NoScaleOrReflection:
|
||||||
tx = targetX - bone._worldX;
|
tx = targetX - bone._worldX;
|
||||||
@ -109,7 +109,8 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY
|
|||||||
Bone *pp = parent.getParent();
|
Bone *pp = parent.getParent();
|
||||||
float tx, ty, dx, dy, dd, l1, l2, a1, a2, r, td, sd, p;
|
float tx, ty, dx, dy, dd, l1, l2, a1, a2, r, td, sd, p;
|
||||||
float id, x, y;
|
float id, x, y;
|
||||||
px = parent._ax;
|
if (parent._inherit != Inherit_Normal || child._inherit != Inherit_Normal) return;
|
||||||
|
px = parent._ax;
|
||||||
py = parent._ay;
|
py = parent._ay;
|
||||||
psx = parent._ascaleX;
|
psx = parent._ascaleX;
|
||||||
psy = parent._ascaleY;
|
psy = parent._ascaleY;
|
||||||
|
|||||||
@ -37,11 +37,11 @@ RTTI_IMPL(IkConstraintData, ConstraintData)
|
|||||||
|
|
||||||
IkConstraintData::IkConstraintData(const String &name) : ConstraintData(name),
|
IkConstraintData::IkConstraintData(const String &name) : ConstraintData(name),
|
||||||
_target(NULL),
|
_target(NULL),
|
||||||
_bendDirection(1),
|
_bendDirection(0),
|
||||||
_compress(false),
|
_compress(false),
|
||||||
_stretch(false),
|
_stretch(false),
|
||||||
_uniform(false),
|
_uniform(false),
|
||||||
_mix(1),
|
_mix(0),
|
||||||
_softness(0) {
|
_softness(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,10 +33,20 @@
|
|||||||
|
|
||||||
using namespace spine;
|
using namespace spine;
|
||||||
|
|
||||||
LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
LinkedMesh::LinkedMesh(MeshAttachment *mesh, const int skinIndex, size_t slotIndex, const String &parent,
|
||||||
bool inheritTimeline) : _mesh(mesh),
|
bool inheritTimeline) : _mesh(mesh),
|
||||||
_skin(skin),
|
_skinIndex(skinIndex),
|
||||||
_slotIndex(slotIndex),
|
_skin(""),
|
||||||
_parent(parent),
|
_slotIndex(slotIndex),
|
||||||
_inheritTimeline(inheritTimeline) {
|
_parent(parent),
|
||||||
|
_inheritTimeline(inheritTimeline) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedMesh::LinkedMesh(MeshAttachment *mesh, const String &skin, size_t slotIndex, const String &parent,
|
||||||
|
bool inheritTimeline) : _mesh(mesh),
|
||||||
|
_skinIndex(-1),
|
||||||
|
_skin(skin),
|
||||||
|
_slotIndex(slotIndex),
|
||||||
|
_parent(parent),
|
||||||
|
_inheritTimeline(inheritTimeline) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,6 +136,7 @@ Skeleton::~Skeleton() {
|
|||||||
ContainerUtil::cleanUpVectorOfPointers(_ikConstraints);
|
ContainerUtil::cleanUpVectorOfPointers(_ikConstraints);
|
||||||
ContainerUtil::cleanUpVectorOfPointers(_transformConstraints);
|
ContainerUtil::cleanUpVectorOfPointers(_transformConstraints);
|
||||||
ContainerUtil::cleanUpVectorOfPointers(_pathConstraints);
|
ContainerUtil::cleanUpVectorOfPointers(_pathConstraints);
|
||||||
|
ContainerUtil::cleanUpVectorOfPointers(_physicsConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::updateCache() {
|
void Skeleton::updateCache() {
|
||||||
@ -195,7 +196,7 @@ continue_outer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t ii = 0; ii < pathCount; ++ii) {
|
for (size_t ii = 0; ii < physicsCount; ++ii) {
|
||||||
PhysicsConstraint *constraint = _physicsConstraints[ii];
|
PhysicsConstraint *constraint = _physicsConstraints[ii];
|
||||||
if (constraint->getData().getOrder() == i) {
|
if (constraint->getData().getOrder() == i) {
|
||||||
sortPhysicsConstraint(constraint);
|
sortPhysicsConstraint(constraint);
|
||||||
@ -222,7 +223,9 @@ void Skeleton::printUpdateCache() {
|
|||||||
printf("ik constraint %s\n", ((IkConstraint *) updatable)->getData().getName().buffer());
|
printf("ik constraint %s\n", ((IkConstraint *) updatable)->getData().getName().buffer());
|
||||||
} else if (updatable->getRTTI().isExactly(PathConstraint::rtti)) {
|
} else if (updatable->getRTTI().isExactly(PathConstraint::rtti)) {
|
||||||
printf("path constraint %s\n", ((PathConstraint *) updatable)->getData().getName().buffer());
|
printf("path constraint %s\n", ((PathConstraint *) updatable)->getData().getName().buffer());
|
||||||
}
|
} else if (updatable->getRTTI().isExactly(PhysicsConstraint::rtti)) {
|
||||||
|
printf("physics constraint %s\n", ((PhysicsConstraint *) updatable)->getData().getName().buffer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,12 +53,15 @@
|
|||||||
#include <spine/EventTimeline.h>
|
#include <spine/EventTimeline.h>
|
||||||
#include <spine/IkConstraintData.h>
|
#include <spine/IkConstraintData.h>
|
||||||
#include <spine/IkConstraintTimeline.h>
|
#include <spine/IkConstraintTimeline.h>
|
||||||
|
#include <spine/InheritTimeline.h>
|
||||||
#include <spine/MeshAttachment.h>
|
#include <spine/MeshAttachment.h>
|
||||||
#include <spine/PathAttachment.h>
|
#include <spine/PathAttachment.h>
|
||||||
#include <spine/PathConstraintData.h>
|
#include <spine/PathConstraintData.h>
|
||||||
#include <spine/PathConstraintMixTimeline.h>
|
#include <spine/PathConstraintMixTimeline.h>
|
||||||
#include <spine/PathConstraintPositionTimeline.h>
|
#include <spine/PathConstraintPositionTimeline.h>
|
||||||
#include <spine/PathConstraintSpacingTimeline.h>
|
#include <spine/PathConstraintSpacingTimeline.h>
|
||||||
|
#include <spine/PhysicsConstraintData.h>
|
||||||
|
#include <spine/PhysicsConstraintTimeline.h>
|
||||||
#include <spine/PointAttachment.h>
|
#include <spine/PointAttachment.h>
|
||||||
#include <spine/RegionAttachment.h>
|
#include <spine/RegionAttachment.h>
|
||||||
#include <spine/RotateTimeline.h>
|
#include <spine/RotateTimeline.h>
|
||||||
@ -129,6 +132,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
skeletonData->_y = readFloat(input);
|
skeletonData->_y = readFloat(input);
|
||||||
skeletonData->_width = readFloat(input);
|
skeletonData->_width = readFloat(input);
|
||||||
skeletonData->_height = readFloat(input);
|
skeletonData->_height = readFloat(input);
|
||||||
|
skeletonData->_referenceScale = readFloat(input) * this->_scale;
|
||||||
|
|
||||||
nonessential = readBoolean(input);
|
nonessential = readBoolean(input);
|
||||||
|
|
||||||
@ -161,6 +165,8 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
data->_skinRequired = readBoolean(input);
|
data->_skinRequired = readBoolean(input);
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
readColor(input, data->getColor());
|
readColor(input, data->getColor());
|
||||||
|
data->_icon.own(readString(input));
|
||||||
|
data->_visible = readBoolean(input);
|
||||||
}
|
}
|
||||||
skeletonData->_bones[i] = data;
|
skeletonData->_bones[i] = data;
|
||||||
}
|
}
|
||||||
@ -169,9 +175,17 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
int slotsCount = readVarint(input, true);
|
int slotsCount = readVarint(input, true);
|
||||||
skeletonData->_slots.setSize(slotsCount, 0);
|
skeletonData->_slots.setSize(slotsCount, 0);
|
||||||
for (int i = 0; i < slotsCount; ++i) {
|
for (int i = 0; i < slotsCount; ++i) {
|
||||||
const char *slotName = readString(input);
|
String slotName = String(readString(input), true);
|
||||||
|
String pathName = "";
|
||||||
|
if (nonessential) {
|
||||||
|
int slash = slotName.lastIndexOf('/');
|
||||||
|
if (slash != -1) {
|
||||||
|
pathName = slotName.substring(0, slash);
|
||||||
|
slotName = slotName.substring(slash + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
BoneData *boneData = skeletonData->_bones[readVarint(input, true)];
|
BoneData *boneData = skeletonData->_bones[readVarint(input, true)];
|
||||||
SlotData *slotData = new (__FILE__, __LINE__) SlotData(i, String(slotName, true), *boneData);
|
SlotData *slotData = new (__FILE__, __LINE__) SlotData(i, slotName, *boneData);
|
||||||
|
|
||||||
readColor(input, slotData->getColor());
|
readColor(input, slotData->getColor());
|
||||||
unsigned char a = readByte(input);
|
unsigned char a = readByte(input);
|
||||||
@ -184,6 +198,10 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
}
|
}
|
||||||
slotData->_attachmentName = readStringRef(input, skeletonData);
|
slotData->_attachmentName = readStringRef(input, skeletonData);
|
||||||
slotData->_blendMode = static_cast<BlendMode>(readVarint(input, true));
|
slotData->_blendMode = static_cast<BlendMode>(readVarint(input, true));
|
||||||
|
if (nonessential) {
|
||||||
|
slotData->_visible = readBoolean(input);
|
||||||
|
slotData->_path = pathName;
|
||||||
|
}
|
||||||
skeletonData->_slots[i] = slotData;
|
skeletonData->_slots[i] = slotData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,18 +212,20 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
const char *name = readString(input);
|
const char *name = readString(input);
|
||||||
IkConstraintData *data = new (__FILE__, __LINE__) IkConstraintData(String(name, true));
|
IkConstraintData *data = new (__FILE__, __LINE__) IkConstraintData(String(name, true));
|
||||||
data->setOrder(readVarint(input, true));
|
data->setOrder(readVarint(input, true));
|
||||||
data->setSkinRequired(readBoolean(input));
|
|
||||||
int bonesCount = readVarint(input, true);
|
int bonesCount = readVarint(input, true);
|
||||||
data->_bones.setSize(bonesCount, 0);
|
data->_bones.setSize(bonesCount, 0);
|
||||||
for (int ii = 0; ii < bonesCount; ++ii)
|
for (int ii = 0; ii < bonesCount; ++ii)
|
||||||
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
||||||
data->_target = skeletonData->_bones[readVarint(input, true)];
|
data->_target = skeletonData->_bones[readVarint(input, true)];
|
||||||
data->_mix = readFloat(input);
|
int flags = readByte(input);
|
||||||
data->_softness = readFloat(input) * _scale;
|
data->_skinRequired = (flags & 1) != 0;
|
||||||
data->_bendDirection = readSByte(input);
|
data->_bendDirection = (flags & 2) != 0 ? 1 : -1;
|
||||||
data->_compress = readBoolean(input);
|
data->_compress = (flags & 4) != 0;
|
||||||
data->_stretch = readBoolean(input);
|
data->_stretch = (flags & 8) != 0;
|
||||||
data->_uniform = readBoolean(input);
|
data->_uniform = (flags & 16) != 0;
|
||||||
|
if ((flags & 32) != 0) data->_mix = (flags & 64) != 0 ? readFloat(input) : 1;
|
||||||
|
if ((flags & 128) != 0) data->_softness = readFloat(input) * _scale;
|
||||||
|
|
||||||
skeletonData->_ikConstraints[i] = data;
|
skeletonData->_ikConstraints[i] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,27 +236,30 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
const char *name = readString(input);
|
const char *name = readString(input);
|
||||||
TransformConstraintData *data = new (__FILE__, __LINE__) TransformConstraintData(String(name, true));
|
TransformConstraintData *data = new (__FILE__, __LINE__) TransformConstraintData(String(name, true));
|
||||||
data->setOrder(readVarint(input, true));
|
data->setOrder(readVarint(input, true));
|
||||||
data->setSkinRequired(readBoolean(input));
|
|
||||||
int bonesCount = readVarint(input, true);
|
int bonesCount = readVarint(input, true);
|
||||||
data->_bones.setSize(bonesCount, 0);
|
data->_bones.setSize(bonesCount, 0);
|
||||||
for (int ii = 0; ii < bonesCount; ++ii)
|
for (int ii = 0; ii < bonesCount; ++ii)
|
||||||
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
||||||
data->_target = skeletonData->_bones[readVarint(input, true)];
|
data->_target = skeletonData->_bones[readVarint(input, true)];
|
||||||
data->_local = readBoolean(input);
|
int flags = readByte(input);
|
||||||
data->_relative = readBoolean(input);
|
data->_skinRequired = (flags & 1) != 0;
|
||||||
data->_offsetRotation = readFloat(input);
|
data->_local = (flags & 2) != 0;
|
||||||
data->_offsetX = readFloat(input) * _scale;
|
data->_relative = (flags & 4) != 0;
|
||||||
data->_offsetY = readFloat(input) * _scale;
|
if ((flags & 8) != 0) data->_offsetRotation = readFloat(input);
|
||||||
data->_offsetScaleX = readFloat(input);
|
if ((flags & 16) != 0) data->_offsetX =readFloat(input) * _scale;
|
||||||
data->_offsetScaleY = readFloat(input);
|
if ((flags & 32) != 0) data->_offsetY = readFloat(input) * _scale;
|
||||||
data->_offsetShearY = readFloat(input);
|
if ((flags & 64) != 0) data->_offsetScaleX = readFloat(input);
|
||||||
data->_mixRotate = readFloat(input);
|
if ((flags & 128) != 0) data->_offsetScaleY = readFloat(input);
|
||||||
data->_mixX = readFloat(input);
|
flags = readByte(input);
|
||||||
data->_mixY = readFloat(input);
|
if ((flags & 1) != 0) data->_offsetShearY = readFloat(input);
|
||||||
data->_mixScaleX = readFloat(input);
|
if ((flags & 2) != 0) data->_mixRotate = readFloat(input);
|
||||||
data->_mixScaleY = readFloat(input);
|
if ((flags & 4) != 0) data->_mixX = readFloat(input);
|
||||||
data->_mixShearY = readFloat(input);
|
if ((flags & 8) != 0) data->_mixY = readFloat(input);
|
||||||
skeletonData->_transformConstraints[i] = data;
|
if ((flags & 16) != 0) data->_mixScaleX = readFloat(input);
|
||||||
|
if ((flags & 32) != 0) data->_mixScaleY = readFloat(input);
|
||||||
|
if ((flags & 64) != 0) data->_mixShearY = readFloat(input);
|
||||||
|
|
||||||
|
skeletonData->_transformConstraints[i] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Path constraints */
|
/* Path constraints */
|
||||||
@ -252,10 +275,11 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
for (int ii = 0; ii < bonesCount; ++ii)
|
for (int ii = 0; ii < bonesCount; ++ii)
|
||||||
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
data->_bones[ii] = skeletonData->_bones[readVarint(input, true)];
|
||||||
data->_target = skeletonData->_slots[readVarint(input, true)];
|
data->_target = skeletonData->_slots[readVarint(input, true)];
|
||||||
data->_positionMode = static_cast<PositionMode>(readVarint(input, true));
|
int flags = readByte(input);
|
||||||
data->_spacingMode = static_cast<SpacingMode>(readVarint(input, true));
|
data->_positionMode = (PositionMode)(flags & 1);
|
||||||
data->_rotateMode = static_cast<RotateMode>(readVarint(input, true));
|
data->_spacingMode = (SpacingMode)((flags >> 1) & 3);
|
||||||
data->_offsetRotation = readFloat(input);
|
data->_rotateMode = (RotateMode)((flags >> 3) & 3);
|
||||||
|
if ((flags & 128) != 0) data->_offsetRotation = readFloat(input);
|
||||||
data->_position = readFloat(input);
|
data->_position = readFloat(input);
|
||||||
if (data->_positionMode == PositionMode_Fixed) data->_position *= _scale;
|
if (data->_positionMode == PositionMode_Fixed) data->_position *= _scale;
|
||||||
data->_spacing = readFloat(input);
|
data->_spacing = readFloat(input);
|
||||||
@ -267,6 +291,41 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
skeletonData->_pathConstraints[i] = data;
|
skeletonData->_pathConstraints[i] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Physics constraints.
|
||||||
|
int physicsConstraintsCount = readVarint(input, true);
|
||||||
|
skeletonData->_physicsConstraints.setSize(physicsConstraintsCount, 0);
|
||||||
|
for (int i = 0; i < physicsConstraintsCount; i++) {
|
||||||
|
const char *name = readString(input);
|
||||||
|
PhysicsConstraintData *data = new (__FILE__, __LINE__) PhysicsConstraintData(String(name, true));
|
||||||
|
data->_order = readVarint(input, true);
|
||||||
|
data->_bone = skeletonData->_bones[readVarint(input, true)];
|
||||||
|
int flags = readByte(input);
|
||||||
|
data->_skinRequired = (flags & 1) != 0;
|
||||||
|
if ((flags & 2) != 0) data->_x = readFloat(input);
|
||||||
|
if ((flags & 4) != 0) data->_y = readFloat(input);
|
||||||
|
if ((flags & 8) != 0) data->_rotate = readFloat(input);
|
||||||
|
if ((flags & 16) != 0) data->_scaleX = readFloat(input);
|
||||||
|
if ((flags & 32) != 0) data->_shearX = readFloat(input);
|
||||||
|
data->_limit = ((flags & 64) != 0 ? readFloat(input) : 5000) * _scale;
|
||||||
|
data->_step = 1.f / readByte(input);
|
||||||
|
data->_inertia = readFloat(input);
|
||||||
|
data->_strength = readFloat(input);
|
||||||
|
data->_damping = readFloat(input);
|
||||||
|
data->_massInverse = (flags & 128) != 0 ? readFloat(input) : 1;
|
||||||
|
data->_wind = readFloat(input);
|
||||||
|
data->_gravity = readFloat(input);
|
||||||
|
flags = readByte(input);
|
||||||
|
if ((flags & 1) != 0) data->_inertiaGlobal = true;
|
||||||
|
if ((flags & 2) != 0) data->_strengthGlobal = true;
|
||||||
|
if ((flags & 4) != 0) data->_dampingGlobal = true;
|
||||||
|
if ((flags & 8) != 0) data->_massGlobal = true;
|
||||||
|
if ((flags & 16) != 0) data->_windGlobal = true;
|
||||||
|
if ((flags & 32) != 0) data->_gravityGlobal = true;
|
||||||
|
if ((flags & 64) != 0) data->_mixGlobal = true;
|
||||||
|
data->_mix = (flags & 128) != 0 ? readFloat(input) : 1;
|
||||||
|
skeletonData->_physicsConstraints[i] = data;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default skin. */
|
/* Default skin. */
|
||||||
Skin *defaultSkin = readSkin(input, true, skeletonData, nonessential);
|
Skin *defaultSkin = readSkin(input, true, skeletonData, nonessential);
|
||||||
if (defaultSkin) {
|
if (defaultSkin) {
|
||||||
@ -289,13 +348,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
/* Linked meshes. */
|
/* Linked meshes. */
|
||||||
for (int i = 0, n = (int) _linkedMeshes.size(); i < n; ++i) {
|
for (int i = 0, n = (int) _linkedMeshes.size(); i < n; ++i) {
|
||||||
LinkedMesh *linkedMesh = _linkedMeshes[i];
|
LinkedMesh *linkedMesh = _linkedMeshes[i];
|
||||||
Skin *skin = linkedMesh->_skin.length() == 0 ? skeletonData->getDefaultSkin() : skeletonData->findSkin(linkedMesh->_skin);
|
Skin *skin = skeletonData->_skins[linkedMesh->_skinIndex];
|
||||||
if (skin == NULL) {
|
|
||||||
delete input;
|
|
||||||
delete skeletonData;
|
|
||||||
setError("Skin not found: ", linkedMesh->_skin.buffer());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Attachment *parent = skin->getAttachment(linkedMesh->_slotIndex, linkedMesh->_parent);
|
Attachment *parent = skin->getAttachment(linkedMesh->_slotIndex, linkedMesh->_parent);
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
delete input;
|
delete input;
|
||||||
@ -316,8 +369,8 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
|
|||||||
int eventsCount = readVarint(input, true);
|
int eventsCount = readVarint(input, true);
|
||||||
skeletonData->_events.setSize(eventsCount, 0);
|
skeletonData->_events.setSize(eventsCount, 0);
|
||||||
for (int i = 0; i < eventsCount; ++i) {
|
for (int i = 0; i < eventsCount; ++i) {
|
||||||
const char *name = readStringRef(input, skeletonData);
|
const char *name = readString(input);
|
||||||
EventData *eventData = new (__FILE__, __LINE__) EventData(String(name));
|
EventData *eventData = new (__FILE__, __LINE__) EventData(String(name, true));
|
||||||
eventData->_intValue = readVarint(input, false);
|
eventData->_intValue = readVarint(input, false);
|
||||||
eventData->_floatValue = readFloat(input);
|
eventData->_floatValue = readFloat(input);
|
||||||
eventData->_stringValue.own(readString(input));
|
eventData->_stringValue.own(readString(input));
|
||||||
@ -452,7 +505,10 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
|
|||||||
if (slotCount == 0) return NULL;
|
if (slotCount == 0) return NULL;
|
||||||
skin = new (__FILE__, __LINE__) Skin("default");
|
skin = new (__FILE__, __LINE__) Skin("default");
|
||||||
} else {
|
} else {
|
||||||
skin = new (__FILE__, __LINE__) Skin(readStringRef(input, skeletonData));
|
skin = new (__FILE__, __LINE__) Skin(String(readString(input), true));
|
||||||
|
|
||||||
|
if (nonessential) readColor(input, skin->getColor());
|
||||||
|
|
||||||
for (int i = 0, n = readVarint(input, true); i < n; i++) {
|
for (int i = 0, n = readVarint(input, true); i < n; i++) {
|
||||||
int boneIndex = readVarint(input, true);
|
int boneIndex = readVarint(input, true);
|
||||||
if (boneIndex >= (int) skeletonData->_bones.size()) return NULL;
|
if (boneIndex >= (int) skeletonData->_bones.size()) return NULL;
|
||||||
@ -476,6 +532,12 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
|
|||||||
if (pathIndex >= (int) skeletonData->_pathConstraints.size()) return NULL;
|
if (pathIndex >= (int) skeletonData->_pathConstraints.size()) return NULL;
|
||||||
skin->getConstraints().add(skeletonData->_pathConstraints[pathIndex]);
|
skin->getConstraints().add(skeletonData->_pathConstraints[pathIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0, n = readVarint(input, true); i < n; i++) {
|
||||||
|
int physicsIndex = readVarint(input, true);
|
||||||
|
if (physicsIndex >= (int) skeletonData->_physicsConstraints.size()) return NULL;
|
||||||
|
skin->getConstraints().add(skeletonData->_physicsConstraints[physicsIndex]);
|
||||||
|
}
|
||||||
slotCount = readVarint(input, true);
|
slotCount = readVarint(input, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +558,6 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sequence *SkeletonBinary::readSequence(DataInput *input) {
|
Sequence *SkeletonBinary::readSequence(DataInput *input) {
|
||||||
if (!readBoolean(input)) return NULL;
|
|
||||||
Sequence *sequence = new (__FILE__, __LINE__) Sequence(readVarint(input, true));
|
Sequence *sequence = new (__FILE__, __LINE__) Sequence(readVarint(input, true));
|
||||||
sequence->_start = readVarint(input, true);
|
sequence->_start = readVarint(input, true);
|
||||||
sequence->_digits = readVarint(input, true);
|
sequence->_digits = readVarint(input, true);
|
||||||
@ -506,24 +567,23 @@ Sequence *SkeletonBinary::readSequence(DataInput *input) {
|
|||||||
|
|
||||||
Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
|
Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slotIndex, const String &attachmentName,
|
||||||
SkeletonData *skeletonData, bool nonessential) {
|
SkeletonData *skeletonData, bool nonessential) {
|
||||||
String name(readStringRef(input, skeletonData));
|
|
||||||
if (name.isEmpty()) name = attachmentName;
|
|
||||||
|
|
||||||
AttachmentType type = static_cast<AttachmentType>(readByte(input));
|
int flags = readByte(input);
|
||||||
|
String name = (flags & 8) != 0 ? readStringRef(input, skeletonData) : attachmentName;
|
||||||
|
AttachmentType type = static_cast<AttachmentType>(flags & 0x7);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AttachmentType_Region: {
|
case AttachmentType_Region: {
|
||||||
String path(readStringRef(input, skeletonData));
|
String path = (flags & 16) != 0 ? readStringRef(input, skeletonData) : name;
|
||||||
if (path.isEmpty()) path = name;
|
Color color(1, 1, 1, 1);
|
||||||
float rotation = readFloat(input);
|
if ((flags & 32) != 0) readColor(input, color);
|
||||||
|
Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr;
|
||||||
|
float rotation = (flags & 128) != 0 ? readFloat(input) : 0;
|
||||||
float x = readFloat(input) * _scale;
|
float x = readFloat(input) * _scale;
|
||||||
float y = readFloat(input) * _scale;
|
float y = readFloat(input) * _scale;
|
||||||
float scaleX = readFloat(input);
|
float scaleX = readFloat(input);
|
||||||
float scaleY = readFloat(input);
|
float scaleY = readFloat(input);
|
||||||
float width = readFloat(input) * _scale;
|
float width = readFloat(input) * _scale;
|
||||||
float height = 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);
|
RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path), sequence);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
setError("Error reading attachment: ", name.buffer());
|
setError("Error reading attachment: ", name.buffer());
|
||||||
@ -544,14 +604,13 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
case AttachmentType_Boundingbox: {
|
case AttachmentType_Boundingbox: {
|
||||||
int vertexCount = readVarint(input, true);
|
|
||||||
BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
|
||||||
if (!box) {
|
if (!box) {
|
||||||
setError("Error reading attachment: ", name.buffer());
|
setError("Error reading attachment: ", name.buffer());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
readVertices(input, box->getVertices(), box->getBones(), vertexCount);
|
readVertices(input, box->getVertices(), box->getBones(), (flags & 16) != 0);
|
||||||
box->setWorldVerticesLength(vertexCount << 1);
|
box->setWorldVerticesLength(box->getVertices().size());
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
readColor(input, box->getColor());
|
readColor(input, box->getColor());
|
||||||
}
|
}
|
||||||
@ -559,31 +618,28 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
case AttachmentType_Mesh: {
|
case AttachmentType_Mesh: {
|
||||||
Color color;
|
|
||||||
int vertexCount;
|
|
||||||
Vector<float> uvs;
|
Vector<float> uvs;
|
||||||
Vector<unsigned short> triangles;
|
Vector<unsigned short> triangles;
|
||||||
Vector<float> vertices;
|
Vector<float> vertices;
|
||||||
Vector<int> bones;
|
Vector<int> bones;
|
||||||
int hullLength;
|
int hullLength;
|
||||||
Sequence *sequence;
|
|
||||||
float width = 0;
|
float width = 0;
|
||||||
float height = 0;
|
float height = 0;
|
||||||
Vector<unsigned short> edges;
|
Vector<unsigned short> edges;
|
||||||
|
|
||||||
String path(readStringRef(input, skeletonData));
|
String path = (flags & 16) != 0 ? readStringRef(input, skeletonData) : name;
|
||||||
if (path.isEmpty()) path = name;
|
Color color(1, 1, 1, 1);
|
||||||
readColor(input, color);
|
if ((flags & 32) != 0) readColor(input, color);
|
||||||
vertexCount = readVarint(input, true);
|
Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr;
|
||||||
readFloatArray(input, vertexCount << 1, 1, uvs);
|
hullLength = readVarint(input, true);
|
||||||
readShortArray(input, triangles);
|
int verticesLength = readVertices(input, vertices, bones, (flags & 128) != 0);
|
||||||
readVertices(input, vertices, bones, vertexCount);
|
readFloatArray(input, verticesLength, 1, uvs);
|
||||||
hullLength = readVarint(input, true) << 1;
|
readShortArray(input, triangles, (verticesLength - hullLength - 2) * 3);
|
||||||
sequence = readSequence(input);
|
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
readShortArray(input, edges);
|
readShortArray(input, edges, readVarint(input, true));
|
||||||
width = readFloat(input) * _scale;
|
width = readFloat(input);
|
||||||
height = readFloat(input) * _scale;
|
height = readFloat(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path), sequence);
|
MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path), sequence);
|
||||||
@ -595,7 +651,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
mesh->_color.set(color);
|
mesh->_color.set(color);
|
||||||
mesh->_bones.addAll(bones);
|
mesh->_bones.addAll(bones);
|
||||||
mesh->_vertices.addAll(vertices);
|
mesh->_vertices.addAll(vertices);
|
||||||
mesh->setWorldVerticesLength(vertexCount << 1);
|
mesh->setWorldVerticesLength(verticesLength);
|
||||||
mesh->_triangles.addAll(triangles);
|
mesh->_triangles.addAll(triangles);
|
||||||
mesh->_regionUVs.addAll(uvs);
|
mesh->_regionUVs.addAll(uvs);
|
||||||
if (sequence == NULL) mesh->updateRegion();
|
if (sequence == NULL) mesh->updateRegion();
|
||||||
@ -610,16 +666,14 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
case AttachmentType_Linkedmesh: {
|
case AttachmentType_Linkedmesh: {
|
||||||
String path(readStringRef(input, skeletonData));
|
String path = (flags & 16) != 0 ? readStringRef(input, skeletonData) : name;
|
||||||
if (path.isEmpty()) path = name;
|
Color color(1, 1, 1, 1);
|
||||||
|
if ((flags & 32) != 0) readColor(input, color);
|
||||||
Color color;
|
Sequence *sequence = (flags & 64) != 0 ? readSequence(input) : nullptr;
|
||||||
float width = 0, height = 0;
|
bool inheritTimelines = (flags & 128) != 0;
|
||||||
readColor(input, color);
|
int skinIndex = readVarint(input, true);
|
||||||
String skinName(readStringRef(input, skeletonData));
|
|
||||||
String parent(readStringRef(input, skeletonData));
|
String parent(readStringRef(input, skeletonData));
|
||||||
bool inheritTimelines = readBoolean(input);
|
float width = 0, height = 0;
|
||||||
Sequence *sequence = readSequence(input);
|
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
width = readFloat(input) * _scale;
|
width = readFloat(input) * _scale;
|
||||||
height = readFloat(input) * _scale;
|
height = readFloat(input) * _scale;
|
||||||
@ -638,7 +692,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
mesh->_height = height;
|
mesh->_height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedMesh *linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, String(skinName), slotIndex,
|
LinkedMesh *linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, skinIndex, slotIndex,
|
||||||
String(parent), inheritTimelines);
|
String(parent), inheritTimelines);
|
||||||
_linkedMeshes.add(linkedMesh);
|
_linkedMeshes.add(linkedMesh);
|
||||||
return mesh;
|
return mesh;
|
||||||
@ -649,12 +703,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
setError("Error reading attachment: ", name.buffer());
|
setError("Error reading attachment: ", name.buffer());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
path->_closed = readBoolean(input);
|
path->_closed = (flags & 16) != 0;
|
||||||
path->_constantSpeed = readBoolean(input);
|
path->_constantSpeed = (flags & 32) != 0;
|
||||||
int vertexCount = readVarint(input, true);
|
int verticesLength = readVertices(input, path->getVertices(), path->getBones(), (flags & 64) != 0);
|
||||||
readVertices(input, path->getVertices(), path->getBones(), vertexCount);
|
path->setWorldVerticesLength(verticesLength);
|
||||||
path->setWorldVerticesLength(vertexCount << 1);
|
int lengthsLength = verticesLength / 6;
|
||||||
int lengthsLength = vertexCount / 3;
|
|
||||||
path->_lengths.setSize(lengthsLength, 0);
|
path->_lengths.setSize(lengthsLength, 0);
|
||||||
for (int i = 0; i < lengthsLength; ++i) {
|
for (int i = 0; i < lengthsLength; ++i) {
|
||||||
path->_lengths[i] = readFloat(input) * _scale;
|
path->_lengths[i] = readFloat(input) * _scale;
|
||||||
@ -683,14 +736,13 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
}
|
}
|
||||||
case AttachmentType_Clipping: {
|
case AttachmentType_Clipping: {
|
||||||
int endSlotIndex = readVarint(input, true);
|
int endSlotIndex = readVarint(input, true);
|
||||||
int vertexCount = readVarint(input, true);
|
|
||||||
ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
|
||||||
if (!clip) {
|
if (!clip) {
|
||||||
setError("Error reading attachment: ", name.buffer());
|
setError("Error reading attachment: ", name.buffer());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
readVertices(input, clip->getVertices(), clip->getBones(), vertexCount);
|
int verticesLength = readVertices(input, clip->getVertices(), clip->getBones(), (flags & 16) != 0);
|
||||||
clip->setWorldVerticesLength(vertexCount << 1);
|
clip->setWorldVerticesLength(verticesLength);
|
||||||
clip->_endSlot = skeletonData->_slots[endSlotIndex];
|
clip->_endSlot = skeletonData->_slots[endSlotIndex];
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
readColor(input, clip->getColor());
|
readColor(input, clip->getColor());
|
||||||
@ -702,18 +754,16 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, int vertexCount) {
|
int SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vector<int> &bones, bool weighted) {
|
||||||
float scale = _scale;
|
float scale = _scale;
|
||||||
|
int vertexCount = readVarint(input, true);
|
||||||
int verticesLength = vertexCount << 1;
|
int verticesLength = vertexCount << 1;
|
||||||
|
if (!weighted) {
|
||||||
if (!readBoolean(input)) {
|
readFloatArray(input, verticesLength, scale, vertices);
|
||||||
readFloatArray(input, verticesLength, scale, vertices);
|
return verticesLength;
|
||||||
return;
|
}
|
||||||
}
|
vertices.ensureCapacity(verticesLength * 3 * 3);
|
||||||
|
bones.ensureCapacity(verticesLength * 3);
|
||||||
vertices.ensureCapacity(verticesLength * 3 * 3);
|
|
||||||
bones.ensureCapacity(verticesLength * 3);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; ++i) {
|
for (int i = 0; i < vertexCount; ++i) {
|
||||||
int boneCount = readVarint(input, true);
|
int boneCount = readVarint(input, true);
|
||||||
bones.add(boneCount);
|
bones.add(boneCount);
|
||||||
@ -724,6 +774,7 @@ void SkeletonBinary::readVertices(DataInput *input, Vector<float> &vertices, Vec
|
|||||||
vertices.add(readFloat(input));
|
vertices.add(readFloat(input));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return verticesLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBinary::readFloatArray(DataInput *input, int n, float scale, Vector<float> &array) {
|
void SkeletonBinary::readFloatArray(DataInput *input, int n, float scale, Vector<float> &array) {
|
||||||
@ -741,14 +792,10 @@ void SkeletonBinary::readFloatArray(DataInput *input, int n, float scale, Vector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBinary::readShortArray(DataInput *input, Vector<unsigned short> &array) {
|
void SkeletonBinary::readShortArray(DataInput *input, Vector<unsigned short> &array, int n) {
|
||||||
int n = readVarint(input, true);
|
|
||||||
array.setSize(n, 0);
|
array.setSize(n, 0);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
int i;
|
array[i] = (short)readVarint(input, true);
|
||||||
for (i = 0; i < n; ++i) {
|
|
||||||
array[i] = readByte(input) << 8;
|
|
||||||
array[i] |= readByte(input);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,7 +809,7 @@ void SkeletonBinary::setBezier(DataInput *input, CurveTimeline *timeline, int be
|
|||||||
timeline->setBezier(bezier, frame, value, time1, value1, cx1, cy1 * scale, cx2, cy2 * scale, time2, value2);
|
timeline->setBezier(bezier, frame, value, time1, value1, cx1, cy1 * scale, cx2, cy2 * scale, time2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline *SkeletonBinary::readTimeline(DataInput *input, CurveTimeline1 *timeline, float scale) {
|
void SkeletonBinary::readTimeline(DataInput *input, Vector<Timeline*> &timelines, CurveTimeline1 *timeline, float scale) {
|
||||||
float time = readFloat(input);
|
float time = readFloat(input);
|
||||||
float value = readFloat(input) * scale;
|
float value = readFloat(input) * scale;
|
||||||
for (int frame = 0, bezier = 0, frameLast = (int) timeline->getFrameCount() - 1;; frame++) {
|
for (int frame = 0, bezier = 0, frameLast = (int) timeline->getFrameCount() - 1;; frame++) {
|
||||||
@ -780,10 +827,10 @@ Timeline *SkeletonBinary::readTimeline(DataInput *input, CurveTimeline1 *timelin
|
|||||||
time = time2;
|
time = time2;
|
||||||
value = value2;
|
value = value2;
|
||||||
}
|
}
|
||||||
return timeline;
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline *SkeletonBinary::readTimeline2(DataInput *input, CurveTimeline2 *timeline, float scale) {
|
void SkeletonBinary::readTimeline2(DataInput *input, Vector<Timeline*> &timelines, CurveTimeline2 *timeline, float scale) {
|
||||||
float time = readFloat(input);
|
float time = readFloat(input);
|
||||||
float value1 = readFloat(input) * scale;
|
float value1 = readFloat(input) * scale;
|
||||||
float value2 = readFloat(input) * scale;
|
float value2 = readFloat(input) * scale;
|
||||||
@ -805,7 +852,7 @@ Timeline *SkeletonBinary::readTimeline2(DataInput *input, CurveTimeline2 *timeli
|
|||||||
value1 = nvalue1;
|
value1 = nvalue1;
|
||||||
value2 = nvalue2;
|
value2 = nvalue2;
|
||||||
}
|
}
|
||||||
return timeline;
|
timelines.add(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, SkeletonData *skeletonData) {
|
Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, SkeletonData *skeletonData) {
|
||||||
@ -1039,50 +1086,59 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
||||||
unsigned char timelineType = readByte(input);
|
unsigned char timelineType = readByte(input);
|
||||||
int frameCount = readVarint(input, true);
|
int frameCount = readVarint(input, true);
|
||||||
int bezierCount = readVarint(input, true);
|
if (timelineType == BONE_INHERIT) {
|
||||||
Timeline *timeline = NULL;
|
InheritTimeline *timeline = new (__FILE__, __LINE__) InheritTimeline(frameCount, boneIndex);
|
||||||
|
for (int frame = 0; frame < frameCount; frame++) {
|
||||||
|
float time = readFloat(input);
|
||||||
|
Inherit inherit = (Inherit)readByte(input);
|
||||||
|
timeline->setFrame(frame, time, inherit);
|
||||||
|
}
|
||||||
|
timelines.add(timeline);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int bezierCount = readVarint(input, true);
|
||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case BONE_ROTATE:
|
case BONE_ROTATE:
|
||||||
timeline = readTimeline(input,
|
readTimeline(input, timelines,
|
||||||
new (__FILE__, __LINE__) RotateTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) RotateTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_TRANSLATE:
|
case BONE_TRANSLATE:
|
||||||
timeline = readTimeline2(input, new (__FILE__, __LINE__) TranslateTimeline(frameCount, bezierCount, boneIndex), scale);
|
readTimeline2(input, timelines,new (__FILE__, __LINE__) TranslateTimeline(frameCount, bezierCount, boneIndex), scale);
|
||||||
break;
|
break;
|
||||||
case BONE_TRANSLATEX:
|
case BONE_TRANSLATEX:
|
||||||
timeline = readTimeline(input, new (__FILE__, __LINE__) TranslateXTimeline(frameCount, bezierCount, boneIndex), scale);
|
readTimeline(input, timelines, new (__FILE__, __LINE__) TranslateXTimeline(frameCount, bezierCount, boneIndex), scale);
|
||||||
break;
|
break;
|
||||||
case BONE_TRANSLATEY:
|
case BONE_TRANSLATEY:
|
||||||
timeline = readTimeline(input, new (__FILE__, __LINE__) TranslateYTimeline(frameCount, bezierCount, boneIndex), scale);
|
readTimeline(input, timelines, new (__FILE__, __LINE__) TranslateYTimeline(frameCount, bezierCount, boneIndex), scale);
|
||||||
break;
|
break;
|
||||||
case BONE_SCALE:
|
case BONE_SCALE:
|
||||||
timeline = readTimeline2(input,
|
readTimeline2(input, timelines,
|
||||||
new (__FILE__, __LINE__) ScaleTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ScaleTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_SCALEX:
|
case BONE_SCALEX:
|
||||||
timeline = readTimeline(input,
|
readTimeline(input, timelines,
|
||||||
new (__FILE__, __LINE__) ScaleXTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ScaleXTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_SCALEY:
|
case BONE_SCALEY:
|
||||||
timeline = readTimeline(input,
|
readTimeline(input, timelines,
|
||||||
new (__FILE__, __LINE__) ScaleYTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ScaleYTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_SHEAR:
|
case BONE_SHEAR:
|
||||||
timeline = readTimeline2(input,
|
readTimeline2(input, timelines,
|
||||||
new (__FILE__, __LINE__) ShearTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ShearTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_SHEARX:
|
case BONE_SHEARX:
|
||||||
timeline = readTimeline(input,
|
readTimeline(input, timelines,
|
||||||
new (__FILE__, __LINE__) ShearXTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ShearXTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
case BONE_SHEARY:
|
case BONE_SHEARY:
|
||||||
timeline = readTimeline(input,
|
readTimeline(input, timelines,
|
||||||
new (__FILE__, __LINE__) ShearYTimeline(frameCount, bezierCount, boneIndex),
|
new (__FILE__, __LINE__) ShearYTimeline(frameCount, bezierCount, boneIndex),
|
||||||
1);
|
1);
|
||||||
break;
|
break;
|
||||||
@ -1092,7 +1148,6 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timelines.add(timeline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,25 +1158,20 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
int frameLast = frameCount - 1;
|
int frameLast = frameCount - 1;
|
||||||
int bezierCount = readVarint(input, true);
|
int bezierCount = readVarint(input, true);
|
||||||
IkConstraintTimeline *timeline = new (__FILE__, __LINE__) IkConstraintTimeline(frameCount, bezierCount, index);
|
IkConstraintTimeline *timeline = new (__FILE__, __LINE__) IkConstraintTimeline(frameCount, bezierCount, index);
|
||||||
float time = readFloat(input);
|
int flags = readByte(input);
|
||||||
float mix = readFloat(input);
|
float time = readFloat(input), mix = (flags & 1) != 0 ? ((flags & 2) != 0 ? readFloat(input) : 1) : 0;
|
||||||
float softness = readFloat(input) * scale;
|
float softness = (flags & 4) != 0 ? readFloat(input) * scale : 0;
|
||||||
for (int frame = 0, bezier = 0;; frame++) {
|
for (int frame = 0, bezier = 0;; frame++) {
|
||||||
int bendDirection = readSByte(input);
|
timeline->setFrame(frame, time, mix, softness, (flags & 8) != 0 ? 1 : -1, (flags & 16) != 0, (flags & 32) != 0);
|
||||||
bool compress = readBoolean(input);
|
|
||||||
bool stretch = readBoolean(input);
|
|
||||||
timeline->setFrame(frame, time, mix, softness, bendDirection, compress, stretch);
|
|
||||||
if (frame == frameLast) break;
|
if (frame == frameLast) break;
|
||||||
float time2 = readFloat(input);
|
flags = readByte(input);
|
||||||
float mix2 = readFloat(input);
|
float time2 = readFloat(input), mix2 = (flags & 1) != 0 ? ((flags & 2) != 0 ? readFloat(input) : 1) : 0;
|
||||||
float softness2 = readFloat(input) * scale;
|
float softness2 = (flags & 4) != 0 ? readFloat(input) * scale : 0;
|
||||||
switch (readSByte(input)) {
|
if ((flags & 64) != 0)
|
||||||
case CURVE_STEPPED:
|
timeline->setStepped(frame);
|
||||||
timeline->setStepped(frame);
|
else if ((flags & 128) != 0) {
|
||||||
break;
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
|
||||||
case CURVE_BEZIER:
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
|
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);
|
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
mix = mix2;
|
mix = mix2;
|
||||||
@ -1182,26 +1232,24 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
int index = readVarint(input, true);
|
int index = readVarint(input, true);
|
||||||
PathConstraintData *data = skeletonData->_pathConstraints[index];
|
PathConstraintData *data = skeletonData->_pathConstraints[index];
|
||||||
for (int ii = 0, nn = readVarint(input, true); ii < nn; ii++) {
|
for (int ii = 0, nn = readVarint(input, true); ii < nn; ii++) {
|
||||||
int type = readSByte(input);
|
int type = readByte(input);
|
||||||
int frameCount = readVarint(input, true);
|
int frameCount = readVarint(input, true);
|
||||||
int bezierCount = readVarint(input, true);
|
int bezierCount = readVarint(input, true);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PATH_POSITION: {
|
case PATH_POSITION: {
|
||||||
timelines
|
readTimeline(input, timelines, new PathConstraintPositionTimeline(frameCount, bezierCount, index),
|
||||||
.add(readTimeline(input, new PathConstraintPositionTimeline(frameCount, bezierCount, index),
|
data->_positionMode == PositionMode_Fixed ? scale : 1);
|
||||||
data->_positionMode == PositionMode_Fixed ? scale : 1));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PATH_SPACING: {
|
case PATH_SPACING: {
|
||||||
timelines
|
readTimeline(input, timelines,
|
||||||
.add(readTimeline(input,
|
|
||||||
new PathConstraintSpacingTimeline(frameCount,
|
new PathConstraintSpacingTimeline(frameCount,
|
||||||
bezierCount,
|
bezierCount,
|
||||||
index),
|
index),
|
||||||
data->_spacingMode == SpacingMode_Length ||
|
data->_spacingMode == SpacingMode_Length ||
|
||||||
data->_spacingMode == SpacingMode_Fixed
|
data->_spacingMode == SpacingMode_Fixed
|
||||||
? scale
|
? scale
|
||||||
: 1));
|
: 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PATH_MIX:
|
case PATH_MIX:
|
||||||
@ -1236,7 +1284,46 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deform timelines.
|
// Physics timelines.
|
||||||
|
for (int i = 0, n = readVarint(input, true); i < n; i++) {
|
||||||
|
int index = readVarint(input, true) - 1;
|
||||||
|
for (int ii = 0, nn = readVarint(input, true); ii < nn; ii++) {
|
||||||
|
int type = readByte(input);
|
||||||
|
int frameCount = readVarint(input, true);
|
||||||
|
if (type == PHYSICS_RESET) {
|
||||||
|
PhysicsConstraintResetTimeline *timeline = new (__FILE__, __LINE__) PhysicsConstraintResetTimeline(frameCount, index);
|
||||||
|
for (int frame = 0; frame < frameCount; frame++)
|
||||||
|
timeline->setFrame(frame, readFloat(input));
|
||||||
|
timelines.add(timeline);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int bezierCount = readVarint(input, true);
|
||||||
|
switch (type) {
|
||||||
|
case PHYSICS_INERTIA:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_STRENGTH:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintStrengthTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_DAMPING:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintDampingTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_MASS:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintMassTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_WIND:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_GRAVITY:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
break;
|
||||||
|
case PHYSICS_MIX:
|
||||||
|
readTimeline(input, timelines, new PhysicsConstraintMixTimeline(frameCount, bezierCount, index), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attachment timelines.
|
||||||
for (int i = 0, n = readVarint(input, true); i < n; ++i) {
|
for (int i = 0, n = readVarint(input, true); i < n; ++i) {
|
||||||
Skin *skin = skeletonData->_skins[readVarint(input, true)];
|
Skin *skin = skeletonData->_skins[readVarint(input, true)];
|
||||||
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
|
||||||
@ -1379,10 +1466,13 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
|
|||||||
|
|
||||||
event->_intValue = readVarint(input, false);
|
event->_intValue = readVarint(input, false);
|
||||||
event->_floatValue = readFloat(input);
|
event->_floatValue = readFloat(input);
|
||||||
bool freeString = readBoolean(input);
|
const char *event_stringValue = readString(input);
|
||||||
const char *event_stringValue = freeString ? readString(input) : eventData->_stringValue.buffer();
|
if (event_stringValue == nullptr) {
|
||||||
event->_stringValue = String(event_stringValue);
|
event->_stringValue = eventData->_stringValue;
|
||||||
if (freeString) SpineExtension::free(event_stringValue, __FILE__, __LINE__);
|
} else {
|
||||||
|
event->_stringValue = String(event_stringValue);
|
||||||
|
SpineExtension::free(event_stringValue, __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
if (!eventData->_audioPath.isEmpty()) {
|
if (!eventData->_audioPath.isEmpty()) {
|
||||||
event->_volume = readFloat(input);
|
event->_volume = readFloat(input);
|
||||||
|
|||||||
@ -58,6 +58,7 @@
|
|||||||
#include <spine/PathConstraintMixTimeline.h>
|
#include <spine/PathConstraintMixTimeline.h>
|
||||||
#include <spine/PathConstraintPositionTimeline.h>
|
#include <spine/PathConstraintPositionTimeline.h>
|
||||||
#include <spine/PathConstraintSpacingTimeline.h>
|
#include <spine/PathConstraintSpacingTimeline.h>
|
||||||
|
#include <spine/PhysicsConstraintData.h>
|
||||||
#include <spine/PointAttachment.h>
|
#include <spine/PointAttachment.h>
|
||||||
#include <spine/RegionAttachment.h>
|
#include <spine/RegionAttachment.h>
|
||||||
#include <spine/RotateTimeline.h>
|
#include <spine/RotateTimeline.h>
|
||||||
@ -133,7 +134,7 @@ SkeletonData *SkeletonJson::readSkeletonDataFile(const String &path) {
|
|||||||
SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
|
SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
|
||||||
int i, ii;
|
int i, ii;
|
||||||
SkeletonData *skeletonData;
|
SkeletonData *skeletonData;
|
||||||
Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events;
|
Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *physics, *slots, *skins, *animations, *events;
|
||||||
|
|
||||||
_error = "";
|
_error = "";
|
||||||
_linkedMeshes.clear();
|
_linkedMeshes.clear();
|
||||||
@ -455,6 +456,54 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Physics constraints */
|
||||||
|
physics = Json::getItem(root, "physics");
|
||||||
|
if (physics) {
|
||||||
|
Json *constraintMap;
|
||||||
|
skeletonData->_physicsConstraints.ensureCapacity(physics->_size);
|
||||||
|
skeletonData->_physicsConstraints.setSize(physics->_size, 0);
|
||||||
|
for (constraintMap = physics->_child, i = 0; constraintMap; constraintMap = constraintMap->_next, ++i) {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
PhysicsConstraintData *data = new (__FILE__, __LINE__) PhysicsConstraintData(
|
||||||
|
Json::getString(constraintMap, "name", 0));
|
||||||
|
data->setOrder(Json::getInt(constraintMap, "order", 0));
|
||||||
|
data->setSkinRequired(Json::getBoolean(constraintMap, "skin", false));
|
||||||
|
|
||||||
|
name = Json::getString(constraintMap, "bone", 0);
|
||||||
|
data->_bone = skeletonData->findBone(name);
|
||||||
|
if (!data->_bone) {
|
||||||
|
delete skeletonData;
|
||||||
|
setError(root, "Physics bone not found: ", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->_x = Json::getFloat(constraintMap, "x", 0);
|
||||||
|
data->_y = Json::getFloat(constraintMap, "y", 0);
|
||||||
|
data->_rotate = Json::getFloat(constraintMap, "rotate", 0);
|
||||||
|
data->_scaleX = Json::getFloat(constraintMap, "scaleX", 0);
|
||||||
|
data->_shearX = Json::getFloat(constraintMap, "shearX", 0);
|
||||||
|
data->_limit = Json::getFloat(constraintMap, "limit", 5000) * _scale;
|
||||||
|
data->_step = 1.0f / Json::getInt(constraintMap, "fps", 60);
|
||||||
|
data->_inertia = Json::getFloat(constraintMap, "inertia", 1);
|
||||||
|
data->_strength = Json::getFloat(constraintMap, "strength", 100);
|
||||||
|
data->_damping = Json::getFloat(constraintMap, "damping", 1);
|
||||||
|
data->_massInverse = 1 / Json::getFloat(constraintMap, "mass", 1);
|
||||||
|
data->_wind = Json::getFloat(constraintMap, "wind", 0);
|
||||||
|
data->_gravity = Json::getFloat(constraintMap, "gravity", 0);
|
||||||
|
data->_mix = Json::getFloat(constraintMap, "mix", 1);
|
||||||
|
data->_inertiaGlobal = Json::getBoolean(constraintMap, "inertiaGlobal", false);
|
||||||
|
data->_strengthGlobal = Json::getBoolean(constraintMap, "strengthGlobal", false);
|
||||||
|
data->_dampingGlobal = Json::getBoolean(constraintMap, "dampingGlobal", false);
|
||||||
|
data->_massGlobal = Json::getBoolean(constraintMap, "massGlobal", false);
|
||||||
|
data->_windGlobal = Json::getBoolean(constraintMap, "windGlobal", false);
|
||||||
|
data->_gravityGlobal = Json::getBoolean(constraintMap, "gravityGlobal", false);
|
||||||
|
data->_mixGlobal = Json::getBoolean(constraintMap, "mixGlobal", false);
|
||||||
|
|
||||||
|
skeletonData->_physicsConstraints[i] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Skins. */
|
/* Skins. */
|
||||||
skins = Json::getItem(root, "skins");
|
skins = Json::getItem(root, "skins");
|
||||||
if (skins) {
|
if (skins) {
|
||||||
@ -520,6 +569,19 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = Json::getItem(skinMap, "physics");
|
||||||
|
if (item) {
|
||||||
|
for (item = item->_child; item; item = item->_next) {
|
||||||
|
PhysicsConstraintData *data = skeletonData->findPhysicsConstraint(item->_valueString);
|
||||||
|
if (!data) {
|
||||||
|
delete skeletonData;
|
||||||
|
setError(root, String("Skin physics constraint not found: "), item->_valueString);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
skin->getConstraints().add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
skeletonData->_skins[skinsIndex++] = skin;
|
skeletonData->_skins[skinsIndex++] = skin;
|
||||||
if (strcmp(Json::getString(skinMap, "name", ""), "default") == 0) {
|
if (strcmp(Json::getString(skinMap, "name", ""), "default") == 0) {
|
||||||
skeletonData->_defaultSkin = skin;
|
skeletonData->_defaultSkin = skin;
|
||||||
|
|||||||
@ -611,6 +611,40 @@ void mixAndMatch(SkeletonData *skeletonData, Atlas *atlas) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void celestialCircus(SkeletonData *skeletonData, Atlas *atlas) {
|
||||||
|
SP_UNUSED(atlas);
|
||||||
|
|
||||||
|
SkeletonDrawable drawable(skeletonData);
|
||||||
|
drawable.timeScale = 1;
|
||||||
|
drawable.setUsePremultipliedAlpha(true);
|
||||||
|
|
||||||
|
Skeleton *skeleton = drawable.skeleton;
|
||||||
|
skeleton->setPosition(320, 480);
|
||||||
|
skeleton->updateWorldTransform(Physics_Update);
|
||||||
|
|
||||||
|
drawable.state->setAnimation(0, "swing", true);
|
||||||
|
|
||||||
|
sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - celestial circus");
|
||||||
|
window.setFramerateLimit(60);
|
||||||
|
sf::Event event;
|
||||||
|
sf::Clock deltaClock;
|
||||||
|
|
||||||
|
while (window.isOpen()) {
|
||||||
|
while (window.pollEvent(event)) {
|
||||||
|
if (event.type == sf::Event::Closed) window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
float delta = deltaClock.getElapsedTime().asSeconds();
|
||||||
|
deltaClock.restart();
|
||||||
|
|
||||||
|
drawable.update(delta);
|
||||||
|
|
||||||
|
window.clear();
|
||||||
|
window.draw(drawable);
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for debugging purposes during runtime development
|
* Used for debugging purposes during runtime development
|
||||||
*/
|
*/
|
||||||
@ -636,11 +670,11 @@ DebugExtension dbgExtension(SpineExtension::getInstance());
|
|||||||
int main() {
|
int main() {
|
||||||
SpineExtension::setInstance(&dbgExtension);
|
SpineExtension::setInstance(&dbgExtension);
|
||||||
|
|
||||||
|
testcase(ikDemo, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
|
||||||
|
testcase(celestialCircus, "data/celestial-circus-pro.json", "data/celestial-circus-pro.skel", "data/celestial-circus-pma.atlas", 0.2f);
|
||||||
testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
|
testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
|
||||||
testcase(dragon, "data/dragon-ess.json", "data/dragon-ess.skel", "data/dragon-pma.atlas", 0.6f);
|
testcase(dragon, "data/dragon-ess.json", "data/dragon-ess.skel", "data/dragon-pma.atlas", 0.6f);
|
||||||
testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
|
|
||||||
testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl-pma.atlas", 0.5f);
|
testcase(owl, "data/owl-pro.json", "data/owl-pro.skel", "data/owl-pma.atlas", 0.5f);
|
||||||
testcase(ikDemo, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
|
|
||||||
testcase(mixAndMatch, "data/mix-and-match-pro.json", "data/mix-and-match-pro.skel", "data/mix-and-match-pma.atlas", 0.5f);
|
testcase(mixAndMatch, "data/mix-and-match-pro.json", "data/mix-and-match-pro.skel", "data/mix-and-match-pma.atlas", 0.5f);
|
||||||
testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin-pma.atlas", 0.5f);
|
testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin-pma.atlas", 0.5f);
|
||||||
testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
|
testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
|
||||||
|
|||||||
@ -79,6 +79,7 @@ namespace spine {
|
|||||||
void SkeletonDrawable::update(float deltaTime, Physics physics) {
|
void SkeletonDrawable::update(float deltaTime, Physics physics) {
|
||||||
state->update(deltaTime * timeScale);
|
state->update(deltaTime * timeScale);
|
||||||
state->apply(*skeleton);
|
state->apply(*skeleton);
|
||||||
|
skeleton->update(deltaTime * timeScale);
|
||||||
skeleton->updateWorldTransform(physics);
|
skeleton->updateWorldTransform(physics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user