|
@@ -68,10 +68,21 @@ namespace Spine {
|
|
|
public const int PATH_SPACING = 1;
|
|
|
public const int PATH_MIX = 2;
|
|
|
|
|
|
+ public const int PHYSICS_INERTIA = 0;
|
|
|
+ public const int PHYSICS_STRENGTH = 1;
|
|
|
+ public const int PHYSICS_DAMPING = 2;
|
|
|
+ public const int PHYSICS_MASS = 4;
|
|
|
+ public const int PHYSICS_WIND = 5;
|
|
|
+ public const int PHYSICS_GRAVITY = 6;
|
|
|
+ public const int PHYSICS_MIX = 7;
|
|
|
+ public const int PHYSICS_RESET = 8;
|
|
|
+
|
|
|
public const int CURVE_LINEAR = 0;
|
|
|
public const int CURVE_STEPPED = 1;
|
|
|
public const int CURVE_BEZIER = 2;
|
|
|
|
|
|
+ private readonly List<LinkedMesh> linkedMeshes = new List<LinkedMesh>();
|
|
|
+
|
|
|
public SkeletonBinary (AttachmentLoader attachmentLoader)
|
|
|
: base(attachmentLoader) {
|
|
|
}
|
|
@@ -177,7 +188,11 @@ namespace Spine {
|
|
|
data.Length = input.ReadFloat() * scale;
|
|
|
data.transformMode = TransformModeValues[input.ReadInt(true)];
|
|
|
data.skinRequired = input.ReadBoolean();
|
|
|
- if (nonessential) input.ReadInt(); // Skip bone color.
|
|
|
+ if (nonessential) { // discard non-essential data
|
|
|
+ input.ReadInt(); // Color.rgba8888ToColor(data.color, input.readInt());
|
|
|
+ input.ReadString(); // data.icon = input.readString();
|
|
|
+ input.ReadBoolean(); // data.visible = input.readBoolean();
|
|
|
+ }
|
|
|
bones[i] = data;
|
|
|
}
|
|
|
|
|
@@ -203,6 +218,7 @@ namespace Spine {
|
|
|
|
|
|
slotData.attachmentName = input.ReadStringRef();
|
|
|
slotData.blendMode = (BlendMode)input.ReadInt(true);
|
|
|
+ if (nonessential) input.ReadBoolean(); // if (nonessential) data.visible = input.readBoolean();
|
|
|
slots[i] = slotData;
|
|
|
}
|
|
|
|
|
@@ -211,17 +227,18 @@ namespace Spine {
|
|
|
for (int i = 0, nn; i < n; i++) {
|
|
|
IkConstraintData data = new IkConstraintData(input.ReadString());
|
|
|
data.order = input.ReadInt(true);
|
|
|
- data.skinRequired = input.ReadBoolean();
|
|
|
BoneData[] constraintBones = data.bones.Resize(nn = input.ReadInt(true)).Items;
|
|
|
for (int ii = 0; ii < nn; ii++)
|
|
|
constraintBones[ii] = bones[input.ReadInt(true)];
|
|
|
data.target = bones[input.ReadInt(true)];
|
|
|
data.mix = input.ReadFloat();
|
|
|
data.softness = input.ReadFloat() * scale;
|
|
|
- data.bendDirection = input.ReadSByte();
|
|
|
- data.compress = input.ReadBoolean();
|
|
|
- data.stretch = input.ReadBoolean();
|
|
|
- data.uniform = input.ReadBoolean();
|
|
|
+ int flags = input.Read();
|
|
|
+ data.skinRequired = (flags & 1) != 0;
|
|
|
+ data.bendDirection = (flags & 2) != 0 ? 1 : -1;
|
|
|
+ data.compress = (flags & 4) != 0;
|
|
|
+ data.stretch = (flags & 8) != 0;
|
|
|
+ data.uniform = (flags & 16) != 0;
|
|
|
o[i] = data;
|
|
|
}
|
|
|
|
|
@@ -230,13 +247,14 @@ namespace Spine {
|
|
|
for (int i = 0, nn; i < n; i++) {
|
|
|
TransformConstraintData data = new TransformConstraintData(input.ReadString());
|
|
|
data.order = input.ReadInt(true);
|
|
|
- data.skinRequired = input.ReadBoolean();
|
|
|
BoneData[] constraintBones = data.bones.Resize(nn = input.ReadInt(true)).Items;
|
|
|
for (int ii = 0; ii < nn; ii++)
|
|
|
constraintBones[ii] = bones[input.ReadInt(true)];
|
|
|
data.target = bones[input.ReadInt(true)];
|
|
|
- data.local = input.ReadBoolean();
|
|
|
- data.relative = input.ReadBoolean();
|
|
|
+ int flags = input.Read();
|
|
|
+ data.skinRequired = (flags & 1) != 0;
|
|
|
+ data.local = (flags & 2) != 0;
|
|
|
+ data.relative = (flags & 4) != 0;
|
|
|
data.offsetRotation = input.ReadFloat();
|
|
|
data.offsetX = input.ReadFloat() * scale;
|
|
|
data.offsetY = input.ReadFloat() * scale;
|
|
@@ -258,7 +276,7 @@ namespace Spine {
|
|
|
PathConstraintData data = new PathConstraintData(input.ReadString());
|
|
|
data.order = input.ReadInt(true);
|
|
|
data.skinRequired = input.ReadBoolean();
|
|
|
- Object[] constraintBones = data.bones.Resize(nn = input.ReadInt(true)).Items;
|
|
|
+ BoneData[] constraintBones = data.bones.Resize(nn = input.ReadInt(true)).Items;
|
|
|
for (int ii = 0; ii < nn; ii++)
|
|
|
constraintBones[ii] = bones[input.ReadInt(true)];
|
|
|
data.target = slots[input.ReadInt(true)];
|
|
@@ -276,6 +294,38 @@ namespace Spine {
|
|
|
o[i] = data;
|
|
|
}
|
|
|
|
|
|
+ // Physics constraints.
|
|
|
+ o = skeletonData.physicsConstraints.Resize(n = input.ReadInt(true)).Items;
|
|
|
+ for (int i = 0; i < n; i++) {
|
|
|
+ PhysicsConstraintData data = new PhysicsConstraintData(input.ReadString());
|
|
|
+ data.order = input.ReadInt(true);
|
|
|
+ data.bone = bones[input.ReadInt(true)];
|
|
|
+ int flags = input.Read();
|
|
|
+ data.skinRequired = (flags & 1) != 0;
|
|
|
+ if ((flags & 2) != 0) data.x = input.ReadFloat();
|
|
|
+ if ((flags & 4) != 0) data.y = input.ReadFloat();
|
|
|
+ if ((flags & 8) != 0) data.rotate = input.ReadFloat();
|
|
|
+ if ((flags & 16) != 0) data.scaleX = input.ReadFloat();
|
|
|
+ if ((flags & 32) != 0) data.shearX = input.ReadFloat();
|
|
|
+ data.step = 1f / input.ReadByte();
|
|
|
+ data.inertia = input.ReadFloat();
|
|
|
+ data.strength = input.ReadFloat();
|
|
|
+ data.damping = input.ReadFloat();
|
|
|
+ data.massInverse = input.ReadFloat();
|
|
|
+ data.wind = input.ReadFloat();
|
|
|
+ data.gravity = input.ReadFloat();
|
|
|
+ data.mix = input.ReadFloat();
|
|
|
+ flags = input.Read();
|
|
|
+ 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;
|
|
|
+ o[i] = data;
|
|
|
+ }
|
|
|
+
|
|
|
// Default skin.
|
|
|
Skin defaultSkin = ReadSkin(input, skeletonData, true, nonessential);
|
|
|
if (defaultSkin != null) {
|
|
@@ -295,8 +345,7 @@ namespace Spine {
|
|
|
n = linkedMeshes.Count;
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
LinkedMesh linkedMesh = linkedMeshes[i];
|
|
|
- Skin skin = linkedMesh.skin == null ? skeletonData.DefaultSkin : skeletonData.FindSkin(linkedMesh.skin);
|
|
|
- if (skin == null) throw new Exception("Skin not found: " + linkedMesh.skin);
|
|
|
+ Skin skin = skeletonData.skins.Items[linkedMesh.skinIndex];
|
|
|
Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent);
|
|
|
if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent);
|
|
|
linkedMesh.mesh.TimelineAttachment = linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh;
|
|
@@ -308,7 +357,7 @@ namespace Spine {
|
|
|
// Events.
|
|
|
o = skeletonData.events.Resize(n = input.ReadInt(true)).Items;
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
- EventData data = new EventData(input.ReadStringRef());
|
|
|
+ EventData data = new EventData(input.ReadString());
|
|
|
data.Int = input.ReadInt(false);
|
|
|
data.Float = input.ReadFloat();
|
|
|
data.String = input.ReadString();
|
|
@@ -339,7 +388,10 @@ namespace Spine {
|
|
|
if (slotCount == 0) return null;
|
|
|
skin = new Skin("default");
|
|
|
} else {
|
|
|
- skin = new Skin(input.ReadStringRef());
|
|
|
+ skin = new Skin(input.ReadString());
|
|
|
+
|
|
|
+ if (nonessential) input.ReadInt(); // discard, Color.rgba8888ToColor(skin.color, input.readInt());
|
|
|
+
|
|
|
Object[] bones = skin.bones.Resize(input.ReadInt(true)).Items;
|
|
|
BoneData[] bonesItems = skeletonData.bones.Items;
|
|
|
for (int i = 0, n = skin.bones.Count; i < n; i++)
|
|
@@ -354,6 +406,9 @@ namespace Spine {
|
|
|
PathConstraintData[] pathConstraintsItems = skeletonData.pathConstraints.Items;
|
|
|
for (int i = 0, n = input.ReadInt(true); i < n; i++)
|
|
|
skin.constraints.Add(pathConstraintsItems[input.ReadInt(true)]);
|
|
|
+ PhysicsConstraintData[] physicsConstraintsItems = skeletonData.physicsConstraints.Items;
|
|
|
+ for (int i = 0, n = input.ReadInt(true); i < n; i++)
|
|
|
+ skin.constraints.Add(physicsConstraintsItems[input.ReadInt(true)]);
|
|
|
skin.constraints.TrimExcess();
|
|
|
|
|
|
slotCount = input.ReadInt(true);
|
|
@@ -373,12 +428,14 @@ namespace Spine {
|
|
|
String attachmentName, bool nonessential) {
|
|
|
float scale = this.scale;
|
|
|
|
|
|
- String name = input.ReadStringRef();
|
|
|
- if (name == null) name = attachmentName;
|
|
|
+ int flags = input.ReadByte();
|
|
|
+ string name = (flags & 8) != 0 ? input.ReadStringRef() : attachmentName;
|
|
|
|
|
|
- switch ((AttachmentType)input.ReadByte()) {
|
|
|
+ switch ((AttachmentType)(flags & 0b111)) {
|
|
|
case AttachmentType.Region: {
|
|
|
- String path = input.ReadStringRef();
|
|
|
+ string path = (flags & 16) != 0 ? input.ReadStringRef() : null;
|
|
|
+ uint color = (flags & 32) != 0 ? (uint)input.ReadInt() : 0xffffffff;
|
|
|
+ Sequence sequence = (flags & 64) != 0 ? ReadSequence(input) : null;
|
|
|
float rotation = input.ReadFloat();
|
|
|
float x = input.ReadFloat();
|
|
|
float y = input.ReadFloat();
|
|
@@ -386,8 +443,6 @@ namespace Spine {
|
|
|
float scaleY = input.ReadFloat();
|
|
|
float width = input.ReadFloat();
|
|
|
float height = input.ReadFloat();
|
|
|
- int color = input.ReadInt();
|
|
|
- Sequence sequence = ReadSequence(input);
|
|
|
|
|
|
if (path == null) path = name;
|
|
|
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path, sequence);
|
|
@@ -409,36 +464,34 @@ namespace Spine {
|
|
|
return region;
|
|
|
}
|
|
|
case AttachmentType.Boundingbox: {
|
|
|
- int vertexCount = input.ReadInt(true);
|
|
|
- Vertices vertices = ReadVertices(input, vertexCount);
|
|
|
- if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; // Avoid unused local warning.
|
|
|
+ Vertices vertices = ReadVertices(input, (flags & 16) != 0);
|
|
|
+ if (nonessential) input.ReadInt(); // discard, int color = nonessential ? input.readInt() : 0;
|
|
|
|
|
|
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
|
|
|
if (box == null) return null;
|
|
|
- box.worldVerticesLength = vertexCount << 1;
|
|
|
+ box.worldVerticesLength = vertices.length;
|
|
|
box.vertices = vertices.vertices;
|
|
|
box.bones = vertices.bones;
|
|
|
// skipped porting: if (nonessential) Color.rgba8888ToColor(box.getColor(), color);
|
|
|
return box;
|
|
|
}
|
|
|
case AttachmentType.Mesh: {
|
|
|
- String path = input.ReadStringRef();
|
|
|
- int color = input.ReadInt();
|
|
|
- int vertexCount = input.ReadInt(true);
|
|
|
- float[] uvs = ReadFloatArray(input, vertexCount << 1, 1);
|
|
|
- int[] triangles = ReadShortArray(input);
|
|
|
- Vertices vertices = ReadVertices(input, vertexCount);
|
|
|
+ string path = (flags & 16) != 0 ? input.ReadStringRef() : name;
|
|
|
+ uint color = (flags & 32) != 0 ? (uint)input.ReadInt() : 0xffffffff;
|
|
|
+ Sequence sequence = (flags & 64) != 0 ? ReadSequence(input) : null;
|
|
|
int hullLength = input.ReadInt(true);
|
|
|
- Sequence sequence = ReadSequence(input);
|
|
|
+ Vertices vertices = ReadVertices(input, (flags & 128) != 0);
|
|
|
+ float[] uvs = ReadFloatArray(input, vertices.length, 1);
|
|
|
+ int[] triangles = ReadShortArray(input, (vertices.length - hullLength - 2) * 3);
|
|
|
+
|
|
|
int[] edges = null;
|
|
|
float width = 0, height = 0;
|
|
|
if (nonessential) {
|
|
|
- edges = ReadShortArray(input);
|
|
|
+ edges = ReadShortArray(input, input.ReadInt(true));
|
|
|
width = input.ReadFloat();
|
|
|
height = input.ReadFloat();
|
|
|
}
|
|
|
|
|
|
- if (path == null) path = name;
|
|
|
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path, sequence);
|
|
|
if (mesh == null) return null;
|
|
|
mesh.Path = path;
|
|
@@ -448,7 +501,7 @@ namespace Spine {
|
|
|
mesh.a = ((color & 0x000000ff)) / 255f;
|
|
|
mesh.bones = vertices.bones;
|
|
|
mesh.vertices = vertices.vertices;
|
|
|
- mesh.WorldVerticesLength = vertexCount << 1;
|
|
|
+ mesh.WorldVerticesLength = vertices.length;
|
|
|
mesh.triangles = triangles;
|
|
|
mesh.regionUVs = uvs;
|
|
|
if (sequence == null) mesh.UpdateRegion();
|
|
@@ -462,19 +515,18 @@ namespace Spine {
|
|
|
return mesh;
|
|
|
}
|
|
|
case AttachmentType.Linkedmesh: {
|
|
|
- String path = input.ReadStringRef();
|
|
|
- int color = input.ReadInt();
|
|
|
- String skinName = input.ReadStringRef();
|
|
|
- String parent = input.ReadStringRef();
|
|
|
- bool inheritTimelines = input.ReadBoolean();
|
|
|
- Sequence sequence = ReadSequence(input);
|
|
|
+ String path = (flags & 16) != 0 ? input.ReadStringRef() : name;
|
|
|
+ uint color = (flags & 32) != 0 ? (uint)input.ReadInt() : 0xffffffff;
|
|
|
+ Sequence sequence = (flags & 64) != 0 ? ReadSequence(input) : null;
|
|
|
+ bool inheritTimelines = (flags & 128) != 0;
|
|
|
+ int skinIndex = input.ReadInt(true);
|
|
|
+ string parent = input.ReadStringRef();
|
|
|
float width = 0, height = 0;
|
|
|
if (nonessential) {
|
|
|
width = input.ReadFloat();
|
|
|
height = input.ReadFloat();
|
|
|
}
|
|
|
|
|
|
- if (path == null) path = name;
|
|
|
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path, sequence);
|
|
|
if (mesh == null) return null;
|
|
|
mesh.Path = path;
|
|
@@ -487,15 +539,14 @@ namespace Spine {
|
|
|
mesh.Width = width * scale;
|
|
|
mesh.Height = height * scale;
|
|
|
}
|
|
|
- linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritTimelines));
|
|
|
+ linkedMeshes.Add(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines));
|
|
|
return mesh;
|
|
|
}
|
|
|
case AttachmentType.Path: {
|
|
|
- bool closed = input.ReadBoolean();
|
|
|
- bool constantSpeed = input.ReadBoolean();
|
|
|
- int vertexCount = input.ReadInt(true);
|
|
|
- Vertices vertices = ReadVertices(input, vertexCount);
|
|
|
- float[] lengths = new float[vertexCount / 3];
|
|
|
+ bool closed = (flags & 16) != 0;
|
|
|
+ bool constantSpeed = (flags & 32) != 0;
|
|
|
+ Vertices vertices = ReadVertices(input, (flags & 64) != 0);
|
|
|
+ float[] lengths = new float[vertices.length / 6];
|
|
|
for (int i = 0, n = lengths.Length; i < n; i++)
|
|
|
lengths[i] = input.ReadFloat() * scale;
|
|
|
if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0;
|
|
@@ -504,7 +555,7 @@ namespace Spine {
|
|
|
if (path == null) return null;
|
|
|
path.closed = closed;
|
|
|
path.constantSpeed = constantSpeed;
|
|
|
- path.worldVerticesLength = vertexCount << 1;
|
|
|
+ path.worldVerticesLength = vertices.length;
|
|
|
path.vertices = vertices.vertices;
|
|
|
path.bones = vertices.bones;
|
|
|
path.lengths = lengths;
|
|
@@ -527,14 +578,13 @@ namespace Spine {
|
|
|
}
|
|
|
case AttachmentType.Clipping: {
|
|
|
int endSlotIndex = input.ReadInt(true);
|
|
|
- int vertexCount = input.ReadInt(true);
|
|
|
- Vertices vertices = ReadVertices(input, vertexCount);
|
|
|
+ Vertices vertices = ReadVertices(input, (flags & 16) != 0);
|
|
|
if (nonessential) input.ReadInt();
|
|
|
|
|
|
ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name);
|
|
|
if (clip == null) return null;
|
|
|
clip.EndSlot = skeletonData.slots.Items[endSlotIndex];
|
|
|
- clip.worldVerticesLength = vertexCount << 1;
|
|
|
+ clip.worldVerticesLength = vertices.length;
|
|
|
clip.vertices = vertices.vertices;
|
|
|
clip.bones = vertices.bones;
|
|
|
// skipped porting: if (nonessential) Color.rgba8888ToColor(clip.getColor(), color);
|
|
@@ -545,7 +595,6 @@ namespace Spine {
|
|
|
}
|
|
|
|
|
|
private Sequence ReadSequence (SkeletonInput input) {
|
|
|
- if (!input.ReadBoolean()) return null;
|
|
|
Sequence sequence = new Sequence(input.ReadInt(true));
|
|
|
sequence.Start = input.ReadInt(true);
|
|
|
sequence.Digits = input.ReadInt(true);
|
|
@@ -553,16 +602,17 @@ namespace Spine {
|
|
|
return sequence;
|
|
|
}
|
|
|
|
|
|
- private Vertices ReadVertices (SkeletonInput input, int vertexCount) {
|
|
|
+ private Vertices ReadVertices (SkeletonInput input, bool weighted) {
|
|
|
float scale = this.scale;
|
|
|
- int verticesLength = vertexCount << 1;
|
|
|
+ int vertexCount = input.ReadInt(true);
|
|
|
Vertices vertices = new Vertices();
|
|
|
- if (!input.ReadBoolean()) {
|
|
|
- vertices.vertices = ReadFloatArray(input, verticesLength, scale);
|
|
|
+ vertices.length = vertexCount << 1;
|
|
|
+ if (!weighted) {
|
|
|
+ vertices.vertices = ReadFloatArray(input, vertices.length, scale);
|
|
|
return vertices;
|
|
|
}
|
|
|
- ExposedList<float> weights = new ExposedList<float>(verticesLength * 3 * 3);
|
|
|
- ExposedList<int> bonesArray = new ExposedList<int>(verticesLength * 3);
|
|
|
+ ExposedList<float> weights = new ExposedList<float>(vertices.length * 3 * 3);
|
|
|
+ ExposedList<int> bonesArray = new ExposedList<int>(vertices.length * 3);
|
|
|
for (int i = 0; i < vertexCount; i++) {
|
|
|
int boneCount = input.ReadInt(true);
|
|
|
bonesArray.Add(boneCount);
|
|
@@ -591,11 +641,10 @@ namespace Spine {
|
|
|
return array;
|
|
|
}
|
|
|
|
|
|
- private int[] ReadShortArray (SkeletonInput input) {
|
|
|
- int n = input.ReadInt(true);
|
|
|
+ private int[] ReadShortArray (SkeletonInput input, int n) {
|
|
|
int[] array = new int[n];
|
|
|
for (int i = 0; i < n; i++)
|
|
|
- array[i] = (input.ReadByte() << 8) | input.ReadByte();
|
|
|
+ array[i] = input.ReadInt(true);
|
|
|
return array;
|
|
|
}
|
|
|
|
|
@@ -783,34 +832,34 @@ namespace Spine {
|
|
|
int type = input.ReadByte(), frameCount = input.ReadInt(true), bezierCount = input.ReadInt(true);
|
|
|
switch (type) {
|
|
|
case BONE_ROTATE:
|
|
|
- timelines.Add(ReadTimeline(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new RotateTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_TRANSLATE:
|
|
|
- timelines.Add(ReadTimeline(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale));
|
|
|
+ ReadTimeline(input, timelines, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale);
|
|
|
break;
|
|
|
case BONE_TRANSLATEX:
|
|
|
- timelines.Add(ReadTimeline(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale));
|
|
|
+ ReadTimeline(input, timelines, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale);
|
|
|
break;
|
|
|
case BONE_TRANSLATEY:
|
|
|
- timelines.Add(ReadTimeline(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale));
|
|
|
+ ReadTimeline(input, timelines, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale);
|
|
|
break;
|
|
|
case BONE_SCALE:
|
|
|
- timelines.Add(ReadTimeline(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_SCALEX:
|
|
|
- timelines.Add(ReadTimeline(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_SCALEY:
|
|
|
- timelines.Add(ReadTimeline(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_SHEAR:
|
|
|
- timelines.Add(ReadTimeline(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ShearTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_SHEARX:
|
|
|
- timelines.Add(ReadTimeline(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
case BONE_SHEARY:
|
|
|
- timelines.Add(ReadTimeline(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1));
|
|
|
+ ReadTimeline(input, timelines, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -822,7 +871,8 @@ namespace Spine {
|
|
|
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount, input.ReadInt(true), index);
|
|
|
float time = input.ReadFloat(), mix = input.ReadFloat(), softness = input.ReadFloat() * scale;
|
|
|
for (int frame = 0, bezier = 0; ; frame++) {
|
|
|
- timeline.SetFrame(frame, time, mix, softness, input.ReadSByte(), input.ReadBoolean(), input.ReadBoolean());
|
|
|
+ int flags = input.Read();
|
|
|
+ timeline.SetFrame(frame, time, mix, softness, input.ReadByte(), (flags & 1) != 0, (flags & 2) != 0);
|
|
|
if (frame == frameLast) break;
|
|
|
float time2 = input.ReadFloat(), mix2 = input.ReadFloat(), softness2 = input.ReadFloat() * scale;
|
|
|
switch (input.ReadByte()) {
|
|
@@ -881,20 +931,18 @@ namespace Spine {
|
|
|
int index = input.ReadInt(true);
|
|
|
PathConstraintData data = skeletonData.pathConstraints.Items[index];
|
|
|
for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
|
|
|
- switch (input.ReadByte()) {
|
|
|
+ int type = input.ReadByte(), frameCount = input.ReadInt(true), bezierCount = input.ReadInt(true);
|
|
|
+ switch (type) {
|
|
|
case PATH_POSITION:
|
|
|
- timelines
|
|
|
- .Add(ReadTimeline(input, new PathConstraintPositionTimeline(input.ReadInt(true), input.ReadInt(true), index),
|
|
|
- data.positionMode == PositionMode.Fixed ? scale : 1));
|
|
|
+ ReadTimeline(input, timelines, new PathConstraintPositionTimeline(frameCount, bezierCount, index),
|
|
|
+ data.positionMode == PositionMode.Fixed ? scale : 1);
|
|
|
break;
|
|
|
case PATH_SPACING:
|
|
|
- timelines
|
|
|
- .Add(ReadTimeline(input, new PathConstraintSpacingTimeline(input.ReadInt(true), input.ReadInt(true), index),
|
|
|
- data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
|
|
|
+ ReadTimeline(input, timelines, new PathConstraintSpacingTimeline(frameCount, bezierCount, index),
|
|
|
+ data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1);
|
|
|
break;
|
|
|
case PATH_MIX:
|
|
|
- PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(input.ReadInt(true), input.ReadInt(true),
|
|
|
- index);
|
|
|
+ PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount, bezierCount, index);
|
|
|
float time = input.ReadFloat(), mixRotate = input.ReadFloat(), mixX = input.ReadFloat(), mixY = input.ReadFloat();
|
|
|
for (int frame = 0, bezier = 0, frameLast = timeline.FrameCount - 1; ; frame++) {
|
|
|
timeline.SetFrame(frame, time, mixRotate, mixX, mixY);
|
|
@@ -922,6 +970,45 @@ namespace Spine {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Physics timelines.
|
|
|
+ for (int i = 0, n = input.ReadInt(true); i < n; i++) {
|
|
|
+ int index = input.ReadInt(true) - 1;
|
|
|
+ for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
|
|
|
+ int type = input.ReadByte(), frameCount = input.ReadInt(true);
|
|
|
+ if (type == PHYSICS_RESET) {
|
|
|
+ PhysicsConstraintResetTimeline timeline = new PhysicsConstraintResetTimeline(frameCount, index);
|
|
|
+ for (int frame = 0; frame < frameCount; frame++)
|
|
|
+ timeline.SetFrame(frame, input.ReadFloat());
|
|
|
+ timelines.Add(timeline);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int bezierCount = input.ReadInt(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);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// Attachment timelines.
|
|
|
for (int i = 0, n = input.ReadInt(true); i < n; i++) {
|
|
|
Skin skin = skeletonData.skins.Items[input.ReadInt(true)];
|
|
@@ -1038,7 +1125,8 @@ namespace Spine {
|
|
|
Event e = new Event(time, eventData);
|
|
|
e.intValue = input.ReadInt(false);
|
|
|
e.floatValue = input.ReadFloat();
|
|
|
- e.stringValue = input.ReadBoolean() ? input.ReadString() : eventData.String;
|
|
|
+ e.stringValue = input.ReadString();
|
|
|
+ if (e.stringValue == null) e.stringValue = eventData.String;
|
|
|
if (e.Data.AudioPath != null) {
|
|
|
e.volume = input.ReadFloat();
|
|
|
e.balance = input.ReadFloat();
|
|
@@ -1056,7 +1144,7 @@ namespace Spine {
|
|
|
}
|
|
|
|
|
|
/// <exception cref="IOException">Throws IOException when a read operation fails.</exception>
|
|
|
- private Timeline ReadTimeline (SkeletonInput input, CurveTimeline1 timeline, float scale) {
|
|
|
+ private void ReadTimeline (SkeletonInput input, ExposedList<Timeline> timelines, CurveTimeline1 timeline, float scale) {
|
|
|
float time = input.ReadFloat(), value = input.ReadFloat() * scale;
|
|
|
for (int frame = 0, bezier = 0, frameLast = timeline.FrameCount - 1; ; frame++) {
|
|
|
timeline.SetFrame(frame, time, value);
|
|
@@ -1073,11 +1161,11 @@ namespace Spine {
|
|
|
time = time2;
|
|
|
value = value2;
|
|
|
}
|
|
|
- return timeline;
|
|
|
+ timelines.Add(timeline);
|
|
|
}
|
|
|
|
|
|
/// <exception cref="IOException">Throws IOException when a read operation fails.</exception>
|
|
|
- private Timeline ReadTimeline (SkeletonInput input, CurveTimeline2 timeline, float scale) {
|
|
|
+ private void ReadTimeline (SkeletonInput input, ExposedList<Timeline> timelines, CurveTimeline2 timeline, float scale) {
|
|
|
float time = input.ReadFloat(), value1 = input.ReadFloat() * scale, value2 = input.ReadFloat() * scale;
|
|
|
for (int frame = 0, bezier = 0, frameLast = timeline.FrameCount - 1; ; frame++) {
|
|
|
timeline.SetFrame(frame, time, value1, value2);
|
|
@@ -1096,7 +1184,7 @@ namespace Spine {
|
|
|
value1 = nvalue1;
|
|
|
value2 = nvalue2;
|
|
|
}
|
|
|
- return timeline;
|
|
|
+ timelines.Add(timeline);
|
|
|
}
|
|
|
|
|
|
/// <exception cref="IOException">Throws IOException when a read operation fails.</exception>
|
|
@@ -1107,6 +1195,7 @@ namespace Spine {
|
|
|
}
|
|
|
|
|
|
internal class Vertices {
|
|
|
+ public int length;
|
|
|
public int[] bones;
|
|
|
public float[] vertices;
|
|
|
}
|
|
@@ -1202,7 +1291,7 @@ namespace Spine {
|
|
|
return System.Text.Encoding.UTF8.GetString(buffer, 0, byteCount);
|
|
|
}
|
|
|
|
|
|
- ///<return>May be null.</return>
|
|
|
+ /// <return>May be null.</return>
|
|
|
public String ReadStringRef () {
|
|
|
int index = ReadInt(true);
|
|
|
return index == 0 ? null : strings[index - 1];
|
|
@@ -1257,5 +1346,20 @@ namespace Spine {
|
|
|
throw new ArgumentException("Stream does not contain valid binary Skeleton Data.");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private class LinkedMesh {
|
|
|
+ internal string parent;
|
|
|
+ internal int skinIndex, slotIndex;
|
|
|
+ internal MeshAttachment mesh;
|
|
|
+ internal bool inheritTimelines;
|
|
|
+
|
|
|
+ public LinkedMesh (MeshAttachment mesh, int skinIndex, int slotIndex, string parent, bool inheritTimelines) {
|
|
|
+ this.mesh = mesh;
|
|
|
+ this.skinIndex = skinIndex;
|
|
|
+ this.slotIndex = slotIndex;
|
|
|
+ this.parent = parent;
|
|
|
+ this.inheritTimelines = inheritTimelines;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|