mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[csharp][unity] Port of commit 3789ec0: Make sequence rendering thread-safe. See #2989.
This commit is contained in:
parent
25942f2519
commit
73a50ef12d
@ -331,6 +331,7 @@
|
||||
- Attachment `ComputeWorldVertices()` methods now take an additional `skeleton` parameter
|
||||
- Renamed timeline constraint index methods to use unified `ConstraintIndex` property
|
||||
- Reorganized timeline class hierarchy with new base classes
|
||||
- Removed `AtlasAttachmentLoader` method `AtlasRegion FindRegion(string name)` from public interface. Added `protected AtlasRegion FindRegion(string name, string path)` instead which may be overridden instead when deriving your own subclass.
|
||||
|
||||
### Unity
|
||||
|
||||
|
||||
@ -1881,12 +1881,12 @@ namespace Spine {
|
||||
private const int MODE = 1, DELAY = 2;
|
||||
|
||||
readonly int slotIndex;
|
||||
readonly IHasTextureRegion attachment;
|
||||
readonly IHasSequence attachment;
|
||||
|
||||
public SequenceTimeline (int frameCount, int slotIndex, Attachment attachment)
|
||||
: base(frameCount, (int)Property.Sequence + "|" + slotIndex + "|" + ((IHasTextureRegion)attachment).Sequence.Id) {
|
||||
: base(frameCount, (int)Property.Sequence + "|" + slotIndex + "|" + ((IHasSequence)attachment).Sequence.Id) {
|
||||
this.slotIndex = slotIndex;
|
||||
this.attachment = (IHasTextureRegion)attachment;
|
||||
this.attachment = (IHasSequence)attachment;
|
||||
}
|
||||
|
||||
public override int FrameEntries {
|
||||
@ -1927,8 +1927,6 @@ namespace Spine {
|
||||
if ((vertexAttachment == null)
|
||||
|| vertexAttachment.TimelineAttachment != attachment) return;
|
||||
}
|
||||
Sequence sequence = ((IHasTextureRegion)slotAttachment).Sequence;
|
||||
if (sequence == null) return;
|
||||
|
||||
if (direction == MixDirection.Out) {
|
||||
if (blend == MixBlend.Setup) pose.SequenceIndex = -1;
|
||||
@ -1946,7 +1944,7 @@ namespace Spine {
|
||||
int modeAndIndex = (int)frames[i + MODE];
|
||||
float delay = frames[i + DELAY];
|
||||
|
||||
int index = modeAndIndex >> 4, count = sequence.Regions.Length;
|
||||
int index = modeAndIndex >> 4, count = (((IHasSequence)slotAttachment).Sequence).Regions.Length;
|
||||
SequenceMode mode = (SequenceMode)(modeAndIndex & 0xf);
|
||||
if (mode != SequenceMode.Hold) {
|
||||
index += (int)((time - before) / delay + 0.0001f);
|
||||
|
||||
@ -49,40 +49,32 @@ namespace Spine {
|
||||
this.allowMissingRegions = allowMissingRegions;
|
||||
}
|
||||
|
||||
private void LoadSequence (string name, string basePath, Sequence sequence) {
|
||||
protected void FindRegions (string name, string basePath, Sequence sequence) {
|
||||
TextureRegion[] regions = sequence.Regions;
|
||||
for (int i = 0, n = regions.Length; i < n; i++) {
|
||||
string path = sequence.GetPath(basePath, i);
|
||||
regions[i] = FindRegion(path);
|
||||
if (regions[i] == null && !allowMissingRegions)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
|
||||
regions[i] = FindRegion(name, sequence.GetPath(basePath, i));
|
||||
}
|
||||
}
|
||||
|
||||
protected AtlasRegion FindRegion (string name, string path) {
|
||||
for (int i = 0; i < atlasArray.Length; i++) {
|
||||
AtlasRegion region = atlasArray[i].FindRegion(path);
|
||||
if (region != null)
|
||||
return region;
|
||||
}
|
||||
if (!allowMissingRegions)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (attachment: {1})", path, name));
|
||||
return null;
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
var attachment = new RegionAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(name, path, sequence);
|
||||
else {
|
||||
AtlasRegion region = FindRegion(path);
|
||||
if (region == null && !allowMissingRegions)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
|
||||
attachment.Region = region;
|
||||
}
|
||||
return attachment;
|
||||
FindRegions(name, path, sequence);
|
||||
return new RegionAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
var attachment = new MeshAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(name, path, sequence);
|
||||
else {
|
||||
AtlasRegion region = FindRegion(path);
|
||||
if (region == null && !allowMissingRegions)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
|
||||
attachment.Region = region;
|
||||
}
|
||||
return attachment;
|
||||
FindRegions(name, path, sequence);
|
||||
return new MeshAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
|
||||
@ -100,17 +92,5 @@ namespace Spine {
|
||||
public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
|
||||
return new ClippingAttachment(name);
|
||||
}
|
||||
|
||||
public AtlasRegion FindRegion (string name) {
|
||||
AtlasRegion region;
|
||||
|
||||
for (int i = 0; i < atlasArray.Length; i++) {
|
||||
region = atlasArray[i].FindRegion(name);
|
||||
if (region != null)
|
||||
return region;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,25 +36,12 @@ namespace Spine {
|
||||
using Color32F = UnityEngine.Color;
|
||||
#endif
|
||||
|
||||
public interface IHasTextureRegion {
|
||||
/// <summary>The name used to find the <see cref="Region"/></summary>
|
||||
public interface IHasSequence {
|
||||
string Path { get; set; }
|
||||
/// <summary>
|
||||
/// Sets the region used to draw the attachment. After setting the region or if the region's properties are changed,
|
||||
/// <see cref="UpdateRegion()"/> must be called.
|
||||
/// </summary>
|
||||
TextureRegion Region { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates any values the attachment calculates using the <see cref="Region"/>. Must be called after setting the
|
||||
/// <see cref="Region"/> or if the region's properties are changed.
|
||||
/// </summary>
|
||||
void UpdateRegion ();
|
||||
|
||||
Color32F GetColor ();
|
||||
void SetColor (Color32F color);
|
||||
void SetColor (float r, float g, float b, float a);
|
||||
|
||||
Sequence Sequence { get; set; }
|
||||
Sequence Sequence { get; }
|
||||
void UpdateSequence ();
|
||||
}
|
||||
}
|
||||
@ -39,32 +39,25 @@ namespace Spine {
|
||||
#endif
|
||||
|
||||
/// <summary>Attachment that displays a texture region using a mesh.</summary>
|
||||
public class MeshAttachment : VertexAttachment, IHasTextureRegion {
|
||||
internal TextureRegion region;
|
||||
internal string path;
|
||||
internal float[] regionUVs, uvs;
|
||||
public class MeshAttachment : VertexAttachment, IHasSequence {
|
||||
internal readonly Sequence sequence;
|
||||
internal float[] regionUVs;
|
||||
internal int[] triangles;
|
||||
internal int hullLength;
|
||||
internal string path;
|
||||
// Color is a struct, set to protected to prevent
|
||||
// Color color = slot.color; color.a = 0.5;
|
||||
// modifying just a copy of the struct instead of the original
|
||||
// object as in reference implementation.
|
||||
protected Color32F color = new Color32F(1, 1, 1, 1);
|
||||
internal int hullLength;
|
||||
private MeshAttachment parentMesh;
|
||||
private Sequence sequence;
|
||||
|
||||
public TextureRegion Region {
|
||||
get { return region; }
|
||||
set {
|
||||
if (value == null) throw new ArgumentNullException("region", "region cannot be null.");
|
||||
region = value;
|
||||
}
|
||||
}
|
||||
public int HullLength { get { return hullLength; } set { hullLength = value; } }
|
||||
|
||||
/// <summary>The UV pair for each vertex, normalized within the texture region.</summary>
|
||||
public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } }
|
||||
/// <summary>The UV pair for each vertex, normalized within the entire texture.
|
||||
/// <seealso cref="MeshAttachment.UpdateRegion"/></summary>
|
||||
public float[] UVs { get { return uvs; } set { uvs = value; } }
|
||||
public int[] Triangles { get { return triangles; } set { triangles = value; } }
|
||||
|
||||
public Color32F GetColor () {
|
||||
@ -80,7 +73,7 @@ namespace Spine {
|
||||
}
|
||||
|
||||
public string Path { get { return path; } set { path = value; } }
|
||||
public Sequence Sequence { get { return sequence; } set { sequence = value; } }
|
||||
public Sequence Sequence { get { return sequence; } }
|
||||
|
||||
public MeshAttachment ParentMesh {
|
||||
get { return parentMesh; }
|
||||
@ -101,12 +94,18 @@ namespace Spine {
|
||||
}
|
||||
|
||||
// Nonessential.
|
||||
/// <summary>
|
||||
/// Vertex index pairs describing edges for controlling triangulation, or be null if nonessential data was not exported. Mesh
|
||||
/// triangles never cross edges. Triangulation is not performed at runtime.
|
||||
/// </summary>
|
||||
public int[] Edges { get; set; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
|
||||
public MeshAttachment (string name)
|
||||
public MeshAttachment (string name, Sequence sequence)
|
||||
: base(name) {
|
||||
if (sequence == null) throw new ArgumentException("sequence cannot be null.", "sequence");
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor. Use <see cref="NewLinkedMesh"/> if the other mesh is a linked mesh.</summary>
|
||||
@ -115,21 +114,17 @@ namespace Spine {
|
||||
|
||||
if (parentMesh != null) throw new ArgumentException("Use newLinkedMesh to copy a linked mesh.");
|
||||
|
||||
region = other.region;
|
||||
path = other.path;
|
||||
color = other.color;
|
||||
|
||||
regionUVs = new float[other.regionUVs.Length];
|
||||
Array.Copy(other.regionUVs, 0, regionUVs, 0, regionUVs.Length);
|
||||
|
||||
uvs = new float[other.uvs.Length];
|
||||
Array.Copy(other.uvs, 0, uvs, 0, uvs.Length);
|
||||
|
||||
triangles = new int[other.triangles.Length];
|
||||
Array.Copy(other.triangles, 0, triangles, 0, triangles.Length);
|
||||
|
||||
hullLength = other.hullLength;
|
||||
sequence = other.sequence == null ? null : new Sequence(other.sequence);
|
||||
sequence = new Sequence(other.sequence);
|
||||
|
||||
// Nonessential.
|
||||
if (other.Edges != null) {
|
||||
@ -140,58 +135,81 @@ namespace Spine {
|
||||
Height = other.Height;
|
||||
}
|
||||
|
||||
public void UpdateSequence () {
|
||||
sequence.Update(this);
|
||||
}
|
||||
|
||||
public void UpdateRegion () {
|
||||
float[] regionUVs = this.regionUVs;
|
||||
if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length];
|
||||
float[] uvs = this.uvs;
|
||||
/// <summary>Returns a new mesh with this mesh set as the <see cref="ParentMesh"/>.
|
||||
public MeshAttachment NewLinkedMesh () {
|
||||
var mesh = new MeshAttachment(Name, new Sequence(sequence));
|
||||
|
||||
mesh.timelineAttachment = timelineAttachment;
|
||||
mesh.path = path;
|
||||
mesh.color = color;
|
||||
mesh.ParentMesh = parentMesh != null ? parentMesh : this;
|
||||
mesh.UpdateSequence();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return parentMesh != null ? NewLinkedMesh() : new MeshAttachment(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes <see cref="Sequence.GetUVs(int)">UVs</see> for a mesh attachment.
|
||||
/// </summary>
|
||||
/// <param name="uvs">Output array for the computed UVs, same length as regionUVs.</param>
|
||||
internal static void ComputeUVs (TextureRegion region, float[] regionUVs, float[] uvs) {
|
||||
int n = uvs.Length;
|
||||
float u, v, width, height;
|
||||
|
||||
if (region is AtlasRegion) {
|
||||
u = this.region.u;
|
||||
v = this.region.v;
|
||||
AtlasRegion region = (AtlasRegion)this.region;
|
||||
// Note: difference from reference implementation.
|
||||
// Covers rotation since region.width and height are already setup accordingly.
|
||||
float textureWidth = this.region.width / (region.u2 - region.u);
|
||||
float textureHeight = this.region.height / (region.v2 - region.v);
|
||||
switch (region.degrees) {
|
||||
case 90:
|
||||
u -= (region.originalHeight - region.offsetY - region.packedWidth) / textureWidth;
|
||||
v -= (region.originalWidth - region.offsetX - region.packedHeight) / textureHeight;
|
||||
width = region.originalHeight / textureWidth;
|
||||
height = region.originalWidth / textureHeight;
|
||||
AtlasRegion r = region as AtlasRegion;
|
||||
if (r != null) {
|
||||
u = r.u;
|
||||
v = r.v;
|
||||
float textureWidth = region.width / (region.u2 - region.u);
|
||||
float textureHeight = region.height / (region.v2 - region.v);
|
||||
switch (r.degrees) {
|
||||
case 90: {
|
||||
u -= (r.originalHeight - r.offsetY - r.packedWidth) / textureWidth;
|
||||
v -= (r.originalWidth - r.offsetX - r.packedHeight) / textureHeight;
|
||||
width = r.originalHeight / textureWidth;
|
||||
height = r.originalWidth / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i]) * height;
|
||||
}
|
||||
return;
|
||||
case 180:
|
||||
u -= (region.originalWidth - region.offsetX - region.packedWidth) / textureWidth;
|
||||
v -= region.offsetY / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
}
|
||||
case 180: {
|
||||
u -= (r.originalWidth - r.offsetX - r.packedWidth) / textureWidth;
|
||||
v -= r.offsetY / textureHeight;
|
||||
width = r.originalWidth / textureWidth;
|
||||
height = r.originalHeight / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + (1 - regionUVs[i]) * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
|
||||
}
|
||||
return;
|
||||
case 270:
|
||||
u -= region.offsetY / textureWidth;
|
||||
v -= region.offsetX / textureHeight;
|
||||
width = region.originalHeight / textureWidth;
|
||||
height = region.originalWidth / textureHeight;
|
||||
}
|
||||
case 270: {
|
||||
u -= r.offsetY / textureWidth;
|
||||
v -= r.offsetX / textureHeight;
|
||||
width = r.originalHeight / textureWidth;
|
||||
height = r.originalWidth / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + (1 - regionUVs[i + 1]) * width;
|
||||
uvs[i + 1] = v + regionUVs[i] * height;
|
||||
}
|
||||
return;
|
||||
}
|
||||
u -= region.offsetX / textureWidth;
|
||||
v -= (region.originalHeight - region.offsetY - region.packedHeight) / textureHeight;
|
||||
width = region.originalWidth / textureWidth;
|
||||
height = region.originalHeight / textureHeight;
|
||||
default: {
|
||||
u -= r.offsetX / textureWidth;
|
||||
v -= (r.originalHeight - r.offsetY - r.packedHeight) / textureHeight;
|
||||
width = r.originalWidth / textureWidth;
|
||||
height = r.originalHeight / textureHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (region == null) {
|
||||
u = v = 0;
|
||||
width = height = 1;
|
||||
@ -206,29 +224,5 @@ namespace Spine {
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>If the attachment has a <see cref="Sequence"/>, the region may be changed.</summary>
|
||||
override public void ComputeWorldVertices (Skeleton skeleton, Slot slot, int start, int count, float[] worldVertices, int offset,
|
||||
int stride = 2) {
|
||||
if (sequence != null) sequence.Apply(slot.AppliedPose, this);
|
||||
base.ComputeWorldVertices(skeleton, slot, start, count, worldVertices, offset, stride);
|
||||
}
|
||||
|
||||
/// <summary>Returns a new mesh with this mesh set as the <see cref="ParentMesh"/>.
|
||||
public MeshAttachment NewLinkedMesh () {
|
||||
var mesh = new MeshAttachment(Name);
|
||||
|
||||
mesh.timelineAttachment = timelineAttachment;
|
||||
mesh.region = region;
|
||||
mesh.path = path;
|
||||
mesh.color = color;
|
||||
mesh.ParentMesh = parentMesh != null ? parentMesh : this;
|
||||
if (mesh.Region != null) mesh.UpdateRegion();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return parentMesh != null ? NewLinkedMesh() : new MeshAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,21 +39,19 @@ namespace Spine {
|
||||
#endif
|
||||
|
||||
/// <summary>Attachment that displays a texture region.</summary>
|
||||
public class RegionAttachment : Attachment, IHasTextureRegion {
|
||||
public class RegionAttachment : Attachment, IHasSequence {
|
||||
public const int BLX = 0, BLY = 1;
|
||||
public const int ULX = 2, ULY = 3;
|
||||
public const int URX = 4, URY = 5;
|
||||
public const int BRX = 6, BRY = 7;
|
||||
|
||||
internal TextureRegion region;
|
||||
internal readonly Sequence sequence;
|
||||
internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
|
||||
internal float[] offset = new float[8], uvs = new float[8];
|
||||
// Color is a struct, set to protected to prevent
|
||||
// Color color = slot.color; color.a = 0.5;
|
||||
// modifying just a copy of the struct instead of the original
|
||||
// object as in reference implementation.
|
||||
protected Color32F color = new Color32F(1, 1, 1, 1);
|
||||
internal Sequence sequence;
|
||||
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
@ -76,22 +74,17 @@ namespace Spine {
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
public TextureRegion Region { get { return region; } set { region = value; } }
|
||||
public Sequence Sequence { get { return sequence; } }
|
||||
|
||||
/// <summary>For each of the 4 vertices, a pair of <c>x,y</c> values that is the local position of the vertex.</summary>
|
||||
/// <seealso cref="UpdateRegion"/>
|
||||
public float[] Offset { get { return offset; } }
|
||||
public float[] UVs { get { return uvs; } }
|
||||
public Sequence Sequence { get { return sequence; } set { sequence = value; } }
|
||||
|
||||
public RegionAttachment (string name)
|
||||
public RegionAttachment (string name, Sequence sequence)
|
||||
: base(name) {
|
||||
if (sequence == null) throw new ArgumentException("sequence cannot be null.", "sequence");
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
public RegionAttachment (RegionAttachment other)
|
||||
: base(other) {
|
||||
region = other.region;
|
||||
Path = other.Path;
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
@ -100,41 +93,94 @@ namespace Spine {
|
||||
rotation = other.rotation;
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
Array.Copy(other.uvs, 0, uvs, 0, 8);
|
||||
Array.Copy(other.offset, 0, offset, 0, 8);
|
||||
color = other.color;
|
||||
sequence = other.sequence == null ? null : new Sequence(other.sequence);
|
||||
sequence = new Sequence(other.sequence);
|
||||
}
|
||||
|
||||
/// <summary>Calculates the <see cref="Offset"/> and <see cref="UVs"/> using the region and the attachment's transform. Must be called if the
|
||||
/// region, the region's properties, or the transform are changed.</summary>
|
||||
public void UpdateRegion () {
|
||||
float width = Width, height = Height;
|
||||
float localX2 = width / 2;
|
||||
float localY2 = height / 2;
|
||||
float localX = -localX2;
|
||||
float localY = -localY2;
|
||||
/// <summary><para>
|
||||
/// Transforms the attachment's four vertices to world coordinates. If the attachment has a <see cref="Sequence"/> the region may
|
||||
/// be changed.</para>
|
||||
/// <para>
|
||||
/// See <see href='https://esotericsoftware.com/spine-runtime-skeletons#World-transforms'>World transforms</a> in the Spine
|
||||
/// Runtimes Guide.</para></summary>
|
||||
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to offset + 8.</param>
|
||||
/// <param name="vertexOffsets">The vertex <see cref="Sequence.GetOffsets(int)">offsets</see>.</param>
|
||||
/// <param name="offset">The worldVertices index to begin writing values.</param>
|
||||
/// <param name="stride">The number of worldVertices entries between the value pairs written.</param>
|
||||
public void ComputeWorldVertices (Slot slot, float[] vertexOffsets, float[] worldVertices, int offset, int stride = 2) {
|
||||
BonePose bone = slot.Bone.AppliedPose;
|
||||
float bwx = bone.worldX, bwy = bone.worldY;
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
|
||||
// Vertex order is different from RegionAttachment.java
|
||||
float offsetX = vertexOffsets[BRX]; // 0
|
||||
float offsetY = vertexOffsets[BRY]; // 1
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[BLX]; // 2
|
||||
offsetY = vertexOffsets[BLY]; // 3
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[ULX]; // 4
|
||||
offsetY = vertexOffsets[ULY]; // 5
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[URX]; // 6
|
||||
offsetY = vertexOffsets[URY]; // 7
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
//offset += stride;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the vertex <see cref="Sequence.GetOffsets(int)">offsets</see> for the specified slot pose.
|
||||
/// </summary>
|
||||
public float[] GetOffsets (SlotPose pose) {
|
||||
return sequence.GetOffsets(sequence.ResolveIndex(pose));
|
||||
}
|
||||
|
||||
public void UpdateSequence () {
|
||||
sequence.Update(this);
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new RegionAttachment(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes <see cref="Sequence.GetUVs(int)">UVs</see> and <see cref="Sequence.GetOffsets(int)">offsets</see> for a region attachment.
|
||||
/// </summary>
|
||||
/// <param name="uvs">Output array for the computed UVs, length of 8.</param>
|
||||
/// <param name="offset">Output array for the computed vertex offsets, length of 8.</param>
|
||||
internal static void ComputeUVs (TextureRegion region, float x, float y, float scaleX, float scaleY, float rotation, float width,
|
||||
float height, float[] offset, float[] uvs) {
|
||||
float localX2 = width / 2, localY2 = height / 2;
|
||||
float localX = -localX2, localY = -localY2;
|
||||
bool rotated = false;
|
||||
if (region is AtlasRegion) {
|
||||
AtlasRegion region = (AtlasRegion)this.region;
|
||||
localX += region.offsetX / region.originalWidth * width;
|
||||
localY += region.offsetY / region.originalHeight * height;
|
||||
if (region.degrees == 90) {
|
||||
AtlasRegion r = region as AtlasRegion;
|
||||
if (r != null) {
|
||||
localX += r.offsetX / r.originalWidth * width;
|
||||
localY += r.offsetY / r.originalHeight * height;
|
||||
if (r.degrees == 90) {
|
||||
rotated = true;
|
||||
localX2 -= (region.originalWidth - region.offsetX - region.packedHeight) / region.originalWidth * width;
|
||||
localY2 -= (region.originalHeight - region.offsetY - region.packedWidth) / region.originalHeight * height;
|
||||
localX2 -= (r.originalWidth - r.offsetX - r.packedHeight) / r.originalWidth * width;
|
||||
localY2 -= (r.originalHeight - r.offsetY - r.packedWidth) / r.originalHeight * height;
|
||||
} else {
|
||||
localX2 -= (region.originalWidth - region.offsetX - region.packedWidth) / region.originalWidth * width;
|
||||
localY2 -= (region.originalHeight - region.offsetY - region.packedHeight) / region.originalHeight * height;
|
||||
localX2 -= (r.originalWidth - r.offsetX - r.packedWidth) / r.originalWidth * width;
|
||||
localY2 -= (r.originalHeight - r.offsetY - r.packedHeight) / r.originalHeight * height;
|
||||
}
|
||||
}
|
||||
float scaleX = ScaleX, scaleY = ScaleY;
|
||||
localX *= scaleX;
|
||||
localY *= scaleY;
|
||||
localX2 *= scaleX;
|
||||
localY2 *= scaleY;
|
||||
float r = Rotation * MathUtils.DegRad, cos = (float)Math.Cos(r), sin = (float)Math.Sin(r);
|
||||
float x = X, y = Y;
|
||||
float rot = rotation * MathUtils.DegRad, cos = (float)Math.Cos(rot), sin = (float)Math.Sin(rot);
|
||||
float localXCos = localX * cos + x;
|
||||
float localXSin = localX * sin;
|
||||
float localYCos = localY * cos + y;
|
||||
@ -143,7 +189,6 @@ namespace Spine {
|
||||
float localX2Sin = localX2 * sin;
|
||||
float localY2Cos = localY2 * cos + y;
|
||||
float localY2Sin = localY2 * sin;
|
||||
float[] offset = this.offset;
|
||||
offset[BLX] = localXCos - localYSin;
|
||||
offset[BLY] = localYCos + localXSin;
|
||||
offset[ULX] = localXCos - localY2Sin;
|
||||
@ -152,8 +197,6 @@ namespace Spine {
|
||||
offset[URY] = localY2Cos + localX2Sin;
|
||||
offset[BRX] = localX2Cos - localYSin;
|
||||
offset[BRY] = localYCos + localX2Sin;
|
||||
|
||||
float[] uvs = this.uvs;
|
||||
if (region == null) {
|
||||
uvs[BLX] = 0;
|
||||
uvs[BLY] = 0;
|
||||
@ -163,71 +206,23 @@ namespace Spine {
|
||||
uvs[URY] = 1;
|
||||
uvs[BRX] = 1;
|
||||
uvs[BRY] = 0;
|
||||
} else if (rotated) {
|
||||
uvs[BLX] = region.u2;
|
||||
uvs[BLY] = region.v;
|
||||
uvs[ULX] = region.u2;
|
||||
uvs[ULY] = region.v2;
|
||||
uvs[URX] = region.u;
|
||||
uvs[URY] = region.v2;
|
||||
uvs[BRX] = region.u;
|
||||
uvs[BRY] = region.v;
|
||||
} else {
|
||||
uvs[BLX] = region.u2;
|
||||
uvs[BLY] = region.v2;
|
||||
uvs[ULX] = region.u;
|
||||
uvs[ULY] = region.v2;
|
||||
uvs[URX] = region.u;
|
||||
uvs[URY] = region.v;
|
||||
uvs[BRX] = region.u2;
|
||||
uvs[BRY] = region.v;
|
||||
if (rotated) {
|
||||
uvs[BLY] = region.v;
|
||||
uvs[ULX] = region.u2;
|
||||
uvs[URY] = region.v2;
|
||||
uvs[BRX] = region.u;
|
||||
} else {
|
||||
uvs[BLY] = region.v2;
|
||||
uvs[ULX] = region.u;
|
||||
uvs[URY] = region.v;
|
||||
uvs[BRX] = region.u2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the attachment's four vertices to world coordinates. If the attachment has a <see cref="Sequence"/> the region may
|
||||
/// be changed.</summary>
|
||||
/// <param name="bone">The parent bone.</param>
|
||||
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to offset + 8.</param>
|
||||
/// <param name="offset">The worldVertices index to begin writing values.</param>
|
||||
/// <param name="stride">The number of worldVertices entries between the value pairs written.</param>
|
||||
public void ComputeWorldVertices (Slot slot, float[] worldVertices, int offset, int stride = 2) {
|
||||
if (sequence != null) sequence.Apply(slot.AppliedPose, this);
|
||||
|
||||
float[] vertexOffset = this.offset;
|
||||
BonePose bone = slot.Bone.AppliedPose;
|
||||
float bwx = bone.worldX, bwy = bone.worldY;
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
float offsetX, offsetY;
|
||||
|
||||
// Vertex order is different from RegionAttachment.java
|
||||
offsetX = vertexOffset[BRX]; // 0
|
||||
offsetY = vertexOffset[BRY]; // 1
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[BLX]; // 2
|
||||
offsetY = vertexOffset[BLY]; // 3
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[ULX]; // 4
|
||||
offsetY = vertexOffset[ULY]; // 5
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[URX]; // 6
|
||||
offsetY = vertexOffset[URY]; // 7
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
//offset += stride;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new RegionAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,12 +31,18 @@ using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>
|
||||
/// Holds texture regions, UVs, and vertex offsets for rendering a region or mesh attachment. <see cref="Regions"/> must
|
||||
/// be populated and <see cref="Update(IHasSequence)"/> called before use.
|
||||
/// </summary>
|
||||
public class Sequence {
|
||||
static int nextID = 0;
|
||||
static readonly Object nextIdLock = new Object();
|
||||
|
||||
internal readonly int id;
|
||||
internal readonly TextureRegion[] regions;
|
||||
internal readonly bool pathSuffix;
|
||||
internal float[][] uvs, offsets;
|
||||
internal int start, digits, setupIndex;
|
||||
|
||||
public int Start { get { return start; } set { start = value; } }
|
||||
@ -44,14 +50,16 @@ namespace Spine {
|
||||
/// <summary>The index of the region to show for the setup pose.</summary>
|
||||
public int SetupIndex { get { return setupIndex; } set { setupIndex = value; } }
|
||||
public TextureRegion[] Regions { get { return regions; } }
|
||||
public bool PathSuffix { get { return pathSuffix; } }
|
||||
/// <summary>Returns a unique ID for this attachment.</summary>
|
||||
public int Id { get { return id; } }
|
||||
|
||||
public Sequence (int count) {
|
||||
public Sequence (int count, bool pathSuffix) {
|
||||
lock (Sequence.nextIdLock) {
|
||||
id = Sequence.nextID++;
|
||||
}
|
||||
regions = new TextureRegion[count];
|
||||
this.pathSuffix = pathSuffix;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
@ -59,26 +67,82 @@ namespace Spine {
|
||||
lock (Sequence.nextIdLock) {
|
||||
id = Sequence.nextID++;
|
||||
}
|
||||
regions = new TextureRegion[other.regions.Length];
|
||||
Array.Copy(other.regions, 0, regions, 0, regions.Length);
|
||||
int regionCount = other.regions.Length;
|
||||
regions = new TextureRegion[regionCount];
|
||||
Array.Copy(other.regions, 0, regions, 0, regionCount);
|
||||
|
||||
start = other.start;
|
||||
digits = other.digits;
|
||||
setupIndex = other.setupIndex;
|
||||
}
|
||||
pathSuffix = other.pathSuffix;
|
||||
|
||||
public void Apply (SlotPose slot, IHasTextureRegion attachment) {
|
||||
int index = slot.SequenceIndex;
|
||||
if (index == -1) index = setupIndex;
|
||||
if (index >= regions.Length) index = regions.Length - 1;
|
||||
TextureRegion region = regions[index];
|
||||
if (attachment.Region != region) {
|
||||
attachment.Region = region;
|
||||
attachment.UpdateRegion();
|
||||
if (other.uvs != null) {
|
||||
int length = other.uvs[0].Length;
|
||||
uvs = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[length];
|
||||
Array.Copy(other.uvs[i], 0, uvs[i], 0, length);
|
||||
}
|
||||
}
|
||||
if (other.offsets != null) {
|
||||
offsets = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
offsets[i] = new float[8];
|
||||
Array.Copy(other.offsets[i], 0, offsets[i], 0, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update (IHasSequence attachment) {
|
||||
int regionCount = regions.Length;
|
||||
RegionAttachment region = attachment as RegionAttachment;
|
||||
if (region != null) {
|
||||
uvs = new float[regionCount][];
|
||||
offsets = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[8];
|
||||
offsets[i] = new float[8];
|
||||
RegionAttachment.ComputeUVs(regions[i], region.x, region.y, region.scaleX, region.scaleY, region.rotation,
|
||||
region.width, region.height, offsets[i], uvs[i]);
|
||||
}
|
||||
} else {
|
||||
MeshAttachment mesh = attachment as MeshAttachment;
|
||||
if (mesh != null) {
|
||||
float[] regionUVs = mesh.regionUVs;
|
||||
uvs = new float[regionCount][];
|
||||
offsets = null;
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[regionUVs.Length];
|
||||
MeshAttachment.ComputeUVs(regions[i], regionUVs, uvs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ResolveIndex (SlotPose pose) {
|
||||
int index = pose.SequenceIndex;
|
||||
if (index == -1) index = setupIndex;
|
||||
if (index >= regions.Length) index = regions.Length - 1;
|
||||
return index;
|
||||
}
|
||||
|
||||
public TextureRegion GetRegion (int index) {
|
||||
return regions[index];
|
||||
}
|
||||
|
||||
public float[] GetUVs (int index) {
|
||||
return uvs[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns vertex offsets from the center of a <see cref="RegionAttachment"/>. Invalid to call for a <see cref="MeshAttachment"/>.
|
||||
/// </summary>
|
||||
public float[] GetOffsets (int index) {
|
||||
return offsets[index];
|
||||
}
|
||||
|
||||
public string GetPath (string basePath, int index) {
|
||||
if (!pathSuffix) return basePath;
|
||||
var buffer = new StringBuilder(basePath.Length + digits);
|
||||
buffer.Append(basePath);
|
||||
string frame = (start + index).ToString();
|
||||
|
||||
@ -459,7 +459,7 @@ namespace Spine {
|
||||
verticesLength = 8;
|
||||
vertices = temp;
|
||||
if (vertices.Length < 8) vertices = temp = new float[8];
|
||||
region.ComputeWorldVertices(slot, vertices, 0, 2);
|
||||
region.ComputeWorldVertices(slot, region.GetOffsets(slot.applied), vertices, 0, 2);
|
||||
triangles = quadTriangles;
|
||||
} else {
|
||||
MeshAttachment mesh = attachment as MeshAttachment;
|
||||
|
||||
@ -461,7 +461,7 @@ namespace Spine {
|
||||
if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent);
|
||||
linkedMesh.mesh.TimelineAttachment = linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh;
|
||||
linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
|
||||
if (linkedMesh.mesh.Region != null) linkedMesh.mesh.UpdateRegion();
|
||||
linkedMesh.mesh.UpdateSequence();
|
||||
}
|
||||
linkedMeshes.Clear();
|
||||
|
||||
@ -546,7 +546,7 @@ namespace Spine {
|
||||
case AttachmentType.Region: {
|
||||
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;
|
||||
Sequence sequence = ReadSequence(input, (flags & 64) != 0);
|
||||
float rotation = (flags & 128) != 0 ? input.ReadFloat() : 0;
|
||||
float x = input.ReadFloat();
|
||||
float y = input.ReadFloat();
|
||||
@ -567,8 +567,7 @@ namespace Spine {
|
||||
region.width = width * scale;
|
||||
region.height = height * scale;
|
||||
region.SetColor(color.RGBA8888ToColor());
|
||||
region.sequence = sequence;
|
||||
if (region.Region != null) region.UpdateRegion();
|
||||
region.UpdateSequence();
|
||||
return region;
|
||||
}
|
||||
case AttachmentType.Boundingbox: {
|
||||
@ -586,7 +585,7 @@ namespace Spine {
|
||||
case AttachmentType.Mesh: {
|
||||
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;
|
||||
Sequence sequence = ReadSequence(input, (flags & 64) != 0);
|
||||
int hullLength = input.ReadInt(true);
|
||||
Vertices vertices = ReadVertices(input, (flags & 128) != 0);
|
||||
float[] uvs = ReadFloatArray(input, vertices.length, 1);
|
||||
@ -604,25 +603,24 @@ namespace Spine {
|
||||
if (mesh == null) return null;
|
||||
mesh.Path = path;
|
||||
mesh.SetColor(color.RGBA8888ToColor());
|
||||
mesh.HullLength = hullLength << 1;
|
||||
mesh.bones = vertices.bones;
|
||||
mesh.vertices = vertices.vertices;
|
||||
mesh.WorldVerticesLength = vertices.length;
|
||||
mesh.triangles = triangles;
|
||||
mesh.regionUVs = uvs;
|
||||
if (mesh.Region != null) mesh.UpdateRegion();
|
||||
mesh.HullLength = hullLength << 1;
|
||||
mesh.Sequence = sequence;
|
||||
mesh.triangles = triangles;
|
||||
if (nonessential) {
|
||||
mesh.Edges = edges;
|
||||
mesh.Width = width * scale;
|
||||
mesh.Height = height * scale;
|
||||
}
|
||||
mesh.UpdateSequence();
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType.Linkedmesh: {
|
||||
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;
|
||||
Sequence sequence = ReadSequence(input, (flags & 64) != 0);
|
||||
bool inheritTimelines = (flags & 128) != 0;
|
||||
int skinIndex = input.ReadInt(true);
|
||||
string parent = input.ReadStringRef();
|
||||
@ -636,7 +634,6 @@ namespace Spine {
|
||||
if (mesh == null) return null;
|
||||
mesh.Path = path;
|
||||
mesh.SetColor(color.RGBA8888ToColor());
|
||||
mesh.Sequence = sequence;
|
||||
if (nonessential) {
|
||||
mesh.Width = width * scale;
|
||||
mesh.Height = height * scale;
|
||||
@ -696,8 +693,9 @@ namespace Spine {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Sequence ReadSequence (SkeletonInput input) {
|
||||
var sequence = new Sequence(input.ReadInt(true));
|
||||
private Sequence ReadSequence (SkeletonInput input, bool hasPathSuffix) {
|
||||
if (!hasPathSuffix) return new Sequence(1, false);
|
||||
var sequence = new Sequence(input.ReadInt(true), true);
|
||||
sequence.Start = input.ReadInt(true);
|
||||
sequence.Digits = input.ReadInt(true);
|
||||
sequence.SetupIndex = input.ReadInt(true);
|
||||
|
||||
@ -494,7 +494,7 @@ namespace Spine {
|
||||
if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent);
|
||||
linkedMesh.mesh.TimelineAttachment = linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh;
|
||||
linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
|
||||
if (linkedMesh.mesh.Region != null) linkedMesh.mesh.UpdateRegion();
|
||||
linkedMesh.mesh.UpdateSequence();
|
||||
}
|
||||
linkedMeshes.Clear();
|
||||
|
||||
@ -596,14 +596,13 @@ namespace Spine {
|
||||
region.rotation = GetFloat(map, "rotation", 0);
|
||||
region.width = GetFloat(map, "width") * scale;
|
||||
region.height = GetFloat(map, "height") * scale;
|
||||
region.sequence = sequence;
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
string color = (string)map["color"];
|
||||
region.SetColor(ToColor32(color, 8));
|
||||
}
|
||||
|
||||
if (region.Region != null) region.UpdateRegion();
|
||||
region.UpdateSequence();
|
||||
return region;
|
||||
}
|
||||
case AttachmentType.Boundingbox:
|
||||
@ -628,7 +627,6 @@ namespace Spine {
|
||||
|
||||
mesh.Width = GetFloat(map, "width", 0) * scale;
|
||||
mesh.Height = GetFloat(map, "height", 0) * scale;
|
||||
mesh.Sequence = sequence;
|
||||
|
||||
string parent = GetString(map, "parent", null);
|
||||
if (parent != null) {
|
||||
@ -640,10 +638,10 @@ namespace Spine {
|
||||
ReadVertices(map, mesh, uvs.Length);
|
||||
mesh.triangles = GetIntArray(map, "triangles");
|
||||
mesh.regionUVs = uvs;
|
||||
if (mesh.Region != null) mesh.UpdateRegion();
|
||||
|
||||
|
||||
if (map.ContainsKey("hull")) mesh.HullLength = GetInt(map, "hull", 0) << 1;
|
||||
if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
|
||||
mesh.UpdateSequence();
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType.Path: {
|
||||
@ -693,8 +691,8 @@ namespace Spine {
|
||||
|
||||
public static Sequence ReadSequence (object sequenceJson) {
|
||||
Dictionary<string, object> map = sequenceJson as Dictionary<string, Object>;
|
||||
if (map == null) return null;
|
||||
var sequence = new Sequence(GetInt(map, "count"));
|
||||
if (map == null) return new Sequence(1, false);
|
||||
var sequence = new Sequence(GetInt(map, "count"), true);
|
||||
sequence.start = GetInt(map, "start", 1);
|
||||
sequence.digits = GetInt(map, "digits", 0);
|
||||
sequence.setupIndex = GetInt(map, "setup", 0);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "com.esotericsoftware.spine.spine-csharp",
|
||||
"displayName": "spine-csharp Runtime",
|
||||
"description": "This plugin provides the spine-csharp core runtime.",
|
||||
"version": "4.3.12",
|
||||
"version": "4.3.13",
|
||||
"unity": "2018.3",
|
||||
"author": {
|
||||
"name": "Esoteric Software",
|
||||
|
||||
@ -300,24 +300,14 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
RegionAttachment regionAttachment = new RegionAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(path, sequence);
|
||||
else {
|
||||
requirementList.Add(path);
|
||||
AssignDummyRegion(regionAttachment);
|
||||
}
|
||||
RegionAttachment regionAttachment = new RegionAttachment(name, sequence);
|
||||
LoadSequence(path, sequence);
|
||||
return regionAttachment;
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
MeshAttachment meshAttachment = new MeshAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(path, sequence);
|
||||
else {
|
||||
requirementList.Add(path);
|
||||
AssignDummyRegion(meshAttachment);
|
||||
}
|
||||
MeshAttachment meshAttachment = new MeshAttachment(name, sequence);
|
||||
LoadSequence(path, sequence);
|
||||
return meshAttachment;
|
||||
}
|
||||
|
||||
@ -344,10 +334,6 @@ namespace Spine.Unity.Editor {
|
||||
requirementList.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssignDummyRegion (IHasTextureRegion attachment) {
|
||||
attachment.Region = new AtlasRegion();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@ -520,8 +520,10 @@ namespace Spine.Unity.Editor {
|
||||
bone.AppliedPose.UpdateWorldTransform(skeleton);
|
||||
|
||||
float[] floatVerts = new float[8];
|
||||
attachment.ComputeWorldVertices(slot, floatVerts, 0);
|
||||
Vector2[] uvs = ExtractUV(attachment.UVs);
|
||||
Sequence sequence = attachment.Sequence;
|
||||
int sequenceIndex = 0;
|
||||
attachment.ComputeWorldVertices(slot, sequence.GetOffsets(sequenceIndex), floatVerts, 0);
|
||||
Vector2[] uvs = ExtractUV(sequence.GetUVs(sequenceIndex));
|
||||
Vector3[] verts = ExtractVerts(floatVerts);
|
||||
|
||||
//unrotate verts now that they're centered
|
||||
@ -559,7 +561,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
float[] floatVerts = new float[attachment.WorldVerticesLength];
|
||||
attachment.ComputeWorldVertices(skeleton, slot, floatVerts);
|
||||
Vector2[] uvs = ExtractUV(attachment.UVs);
|
||||
|
||||
Sequence sequence = attachment.Sequence;
|
||||
int sequenceIndex = 0;
|
||||
Vector2[] uvs = ExtractUV(sequence.GetUVs(sequenceIndex));
|
||||
Vector3[] verts = ExtractVerts(floatVerts);
|
||||
|
||||
int[] triangles = attachment.Triangles;
|
||||
@ -624,7 +629,10 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
float[] floatVerts = new float[attachment.WorldVerticesLength];
|
||||
attachment.ComputeWorldVertices(skeleton, skeleton.Slots.Items[slotIndex], floatVerts);
|
||||
Vector2[] uvs = ExtractUV(attachment.UVs);
|
||||
|
||||
Sequence sequence = attachment.Sequence;
|
||||
int sequenceIndex = 0;
|
||||
Vector2[] uvs = ExtractUV(sequence.GetUVs(sequenceIndex));
|
||||
Vector3[] verts = ExtractVerts(floatVerts);
|
||||
|
||||
int[] triangles = attachment.Triangles;
|
||||
|
||||
@ -88,7 +88,7 @@ namespace Spine.Unity {
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
|
||||
foreach (Skin.SkinEntry entry in skinEntries) {
|
||||
if (entry.Attachment is IHasTextureRegion) {
|
||||
if (entry.Attachment is IHasSequence) {
|
||||
requiresBlendModeMaterials = true;
|
||||
return true;
|
||||
}
|
||||
@ -165,22 +165,15 @@ namespace Spine.Unity {
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
|
||||
foreach (Skin.SkinEntry entry in skinEntries) {
|
||||
IHasTextureRegion renderableAttachment = entry.Attachment as IHasTextureRegion;
|
||||
IHasSequence renderableAttachment = entry.Attachment as IHasSequence;
|
||||
if (renderableAttachment != null) {
|
||||
AtlasRegion originalRegion = (AtlasRegion)renderableAttachment.Region;
|
||||
if (originalRegion != null) {
|
||||
anyCreationFailed |= createForRegionFunc(
|
||||
ref replacementMaterials, ref anyReplacementMaterialsChanged,
|
||||
originalRegion, materialTemplate, materialSuffix, skeletonDataAsset);
|
||||
} else {
|
||||
Sequence sequence = renderableAttachment.Sequence;
|
||||
if (sequence != null && sequence.Regions != null) {
|
||||
for (int i = 0, count = sequence.Regions.Length; i < count; ++i) {
|
||||
originalRegion = (AtlasRegion)sequence.Regions[i];
|
||||
anyCreationFailed |= createForRegionFunc(
|
||||
ref replacementMaterials, ref anyReplacementMaterialsChanged,
|
||||
originalRegion, materialTemplate, materialSuffix, skeletonDataAsset);
|
||||
}
|
||||
Sequence sequence = renderableAttachment.Sequence;
|
||||
if (sequence != null && sequence.Regions != null) {
|
||||
for (int i = 0, count = sequence.Regions.Length; i < count; ++i) {
|
||||
AtlasRegion originalRegion = (AtlasRegion)sequence.Regions[i];
|
||||
anyCreationFailed |= createForRegionFunc(
|
||||
ref replacementMaterials, ref anyReplacementMaterialsChanged,
|
||||
originalRegion, materialTemplate, materialSuffix, skeletonDataAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,20 +261,12 @@ namespace Spine.Unity {
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
|
||||
foreach (Skin.SkinEntry entry in skinEntries) {
|
||||
IHasTextureRegion renderableAttachment = entry.Attachment as IHasTextureRegion;
|
||||
IHasSequence renderableAttachment = entry.Attachment as IHasSequence;
|
||||
if (renderableAttachment != null) {
|
||||
if (renderableAttachment.Sequence != null) {
|
||||
TextureRegion[] regions = renderableAttachment.Sequence.Regions;
|
||||
for (int i = 0; i < regions.Length; ++i) {
|
||||
regions[i] = CloneAtlasRegionWithMaterial(
|
||||
(AtlasRegion)regions[i], replacementMaterials);
|
||||
}
|
||||
if (regions.Length > 0) {
|
||||
renderableAttachment.Region = regions[0];
|
||||
}
|
||||
} else if (renderableAttachment.Region != null) {
|
||||
renderableAttachment.Region = CloneAtlasRegionWithMaterial(
|
||||
(AtlasRegion)renderableAttachment.Region, replacementMaterials);
|
||||
TextureRegion[] regions = renderableAttachment.Sequence.Regions;
|
||||
for (int i = 0; i < regions.Length; ++i) {
|
||||
regions[i] = CloneAtlasRegionWithMaterial(
|
||||
(AtlasRegion)regions[i], replacementMaterials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,16 +57,12 @@ namespace Spine.Unity {
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
RegionAttachment attachment = new RegionAttachment(name) {
|
||||
Region = EmptyRegion
|
||||
};
|
||||
RegionAttachment attachment = new RegionAttachment(name, new Sequence(1, false));
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
|
||||
MeshAttachment attachment = new MeshAttachment(name) {
|
||||
Region = EmptyRegion
|
||||
};
|
||||
MeshAttachment attachment = new MeshAttachment(name, new Sequence(1, false));
|
||||
return attachment;
|
||||
}
|
||||
|
||||
|
||||
@ -254,15 +254,17 @@ namespace Spine.Unity {
|
||||
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null) {
|
||||
if (regionAttachment.Sequence != null) regionAttachment.Sequence.Apply(slot.AppliedPose, regionAttachment);
|
||||
rendererObject = regionAttachment.Region;
|
||||
Sequence sequence = regionAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slot.AppliedPose);
|
||||
rendererObject = sequence.GetRegion(sequenceIndex);
|
||||
attachmentVertexCount = 4;
|
||||
attachmentTriangleCount = 6;
|
||||
} else {
|
||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null) {
|
||||
if (meshAttachment.Sequence != null) meshAttachment.Sequence.Apply(slot.AppliedPose, meshAttachment);
|
||||
rendererObject = meshAttachment.Region;
|
||||
Sequence sequence = meshAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slot.AppliedPose);
|
||||
rendererObject = sequence.GetRegion(sequenceIndex);
|
||||
attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
|
||||
attachmentTriangleCount = meshAttachment.Triangles.Length;
|
||||
} else {
|
||||
@ -323,10 +325,11 @@ namespace Spine.Unity {
|
||||
#endif
|
||||
) continue;
|
||||
Attachment attachment = slot.AppliedPose.Attachment;
|
||||
IHasTextureRegion rendererAttachment = attachment as IHasTextureRegion;
|
||||
IHasSequence rendererAttachment = attachment as IHasSequence;
|
||||
if (rendererAttachment != null) {
|
||||
if (rendererAttachment.Sequence != null) rendererAttachment.Sequence.Apply(slot.AppliedPose, rendererAttachment);
|
||||
AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.Region;
|
||||
Sequence sequence = rendererAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slot.AppliedPose);
|
||||
AtlasRegion atlasRegion = (AtlasRegion)sequence.GetRegion(sequenceIndex);
|
||||
Material material = (Material)atlasRegion.page.rendererObject;
|
||||
if (lastRendererMaterial != material) {
|
||||
if (lastRendererMaterial != null)
|
||||
@ -399,8 +402,9 @@ namespace Spine.Unity {
|
||||
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null) {
|
||||
if (regionAttachment.Sequence != null) regionAttachment.Sequence.Apply(slot.AppliedPose, regionAttachment);
|
||||
region = regionAttachment.Region;
|
||||
Sequence sequence = regionAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slot.AppliedPose);
|
||||
region = sequence.GetRegion(sequenceIndex);
|
||||
#if SPINE_TRIANGLECHECK
|
||||
attachmentVertexCount = 4;
|
||||
attachmentTriangleCount = 6;
|
||||
@ -408,8 +412,9 @@ namespace Spine.Unity {
|
||||
} else {
|
||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null) {
|
||||
if (meshAttachment.Sequence != null) meshAttachment.Sequence.Apply(slot.AppliedPose, meshAttachment);
|
||||
region = meshAttachment.Region;
|
||||
Sequence sequence = meshAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slot.AppliedPose);
|
||||
region = sequence.GetRegion(sequenceIndex);
|
||||
#if SPINE_TRIANGLECHECK
|
||||
attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
|
||||
attachmentTriangleCount = meshAttachment.Triangles.Length;
|
||||
@ -620,8 +625,10 @@ namespace Spine.Unity {
|
||||
// Identify and prepare values.
|
||||
RegionAttachment region = attachment as RegionAttachment;
|
||||
if (region != null) {
|
||||
region.ComputeWorldVertices(slot, workingVerts, 0);
|
||||
uvs = region.UVs;
|
||||
Sequence sequence = region.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slotPose);
|
||||
region.ComputeWorldVertices(slot, sequence.GetOffsets(sequenceIndex), workingVerts, 0);
|
||||
uvs = sequence.GetUVs(sequenceIndex);
|
||||
attachmentTriangleIndices = regionTriangles;
|
||||
regionC = region.GetColor();
|
||||
attachmentVertexCount = 4;
|
||||
@ -634,8 +641,10 @@ namespace Spine.Unity {
|
||||
workingVerts = new float[meshVerticesLength];
|
||||
this.tempVerts = workingVerts;
|
||||
}
|
||||
mesh.ComputeWorldVertices(skeleton, slot, 0, meshVerticesLength, workingVerts, 0); //meshAttachment.ComputeWorldVertices(slot, tempVerts);
|
||||
uvs = mesh.UVs;
|
||||
Sequence sequence = mesh.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slotPose);
|
||||
mesh.ComputeWorldVertices(skeleton, slot, 0, meshVerticesLength, workingVerts, 0);
|
||||
uvs = sequence.GetUVs(sequenceIndex);
|
||||
attachmentTriangleIndices = mesh.Triangles;
|
||||
regionC = mesh.GetColor();
|
||||
attachmentVertexCount = meshVerticesLength >> 1; // meshVertexCount / 2;
|
||||
@ -942,7 +951,10 @@ namespace Spine.Unity {
|
||||
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null) {
|
||||
regionAttachment.ComputeWorldVertices(slot, tempVerts, 0);
|
||||
Sequence sequence = regionAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slotPose);
|
||||
regionAttachment.ComputeWorldVertices(slot, sequence.GetOffsets(sequenceIndex), tempVerts, 0);
|
||||
|
||||
Color regionC = regionAttachment.GetColor();
|
||||
Color combinedC = skeletonC * slotC * regionC;
|
||||
|
||||
@ -978,7 +990,7 @@ namespace Spine.Unity {
|
||||
|
||||
cbi[vertexIndex] = color; cbi[vertexIndex + 1] = color; cbi[vertexIndex + 2] = color; cbi[vertexIndex + 3] = color;
|
||||
|
||||
float[] regionUVs = regionAttachment.UVs;
|
||||
float[] regionUVs = sequence.GetUVs(sequenceIndex);
|
||||
ubi[vertexIndex] = new Vector2(regionUVs[RegionAttachment.BLX], regionUVs[RegionAttachment.BLY]);
|
||||
ubi[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.BRX], regionUVs[RegionAttachment.BRY]);
|
||||
ubi[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.ULX], regionUVs[RegionAttachment.ULY]);
|
||||
@ -1032,7 +1044,9 @@ namespace Spine.Unity {
|
||||
color.b = (byte)(combinedC.b * 255);
|
||||
}
|
||||
|
||||
float[] attachmentUVs = meshAttachment.UVs;
|
||||
Sequence sequence = meshAttachment.Sequence;
|
||||
int sequenceIndex = sequence.ResolveIndex(slotPose);
|
||||
float[] attachmentUVs = sequence.GetUVs(sequenceIndex);
|
||||
|
||||
// Potential first attachment bounds initialization. See conditions in RegionAttachment logic.
|
||||
if (vertexIndex == 0) {
|
||||
|
||||
@ -134,31 +134,13 @@ namespace Spine.Unity.TK2D {
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, String name, String path, Sequence sequence) {
|
||||
RegionAttachment attachment = new RegionAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(name, path, sequence);
|
||||
else {
|
||||
AtlasRegion region = ProcessSpriteDefinition(path);
|
||||
if (region == null)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
|
||||
attachment.Region = region;
|
||||
attachment.Path = path;
|
||||
}
|
||||
return attachment;
|
||||
LoadSequence(name, path, sequence);
|
||||
return new RegionAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, String name, String path, Sequence sequence) {
|
||||
MeshAttachment attachment = new MeshAttachment(name);
|
||||
if (sequence != null)
|
||||
LoadSequence(name, path, sequence);
|
||||
else {
|
||||
AtlasRegion region = ProcessSpriteDefinition(path);
|
||||
if (region == null)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
|
||||
attachment.Region = region;
|
||||
attachment.Path = path;
|
||||
}
|
||||
return attachment;
|
||||
LoadSequence(name, path, sequence);
|
||||
return new MeshAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
|
||||
|
||||
@ -77,10 +77,12 @@ namespace Spine.Unity {
|
||||
if (templateMaterial == null) continue;
|
||||
|
||||
foreach (Skin.SkinEntry entry in entryBuffer) {
|
||||
IHasTextureRegion renderableAttachment = entry.Attachment as IHasTextureRegion;
|
||||
if (renderableAttachment != null) {
|
||||
renderableAttachment.Region = materialCache.CloneAtlasRegionWithMaterial(
|
||||
(AtlasRegion)renderableAttachment.Region, templateMaterial);
|
||||
IHasSequence renderableAttachment = entry.Attachment as IHasSequence;
|
||||
if (renderableAttachment == null) continue;
|
||||
TextureRegion[] regions = renderableAttachment.Sequence.Regions;
|
||||
for (int i = 0; i < regions.Length; ++i) {
|
||||
regions[i] = materialCache.CloneAtlasRegionWithMaterial(
|
||||
(AtlasRegion)regions[i], templateMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,7 +498,8 @@ namespace Spine.Unity.AttachmentTools {
|
||||
}
|
||||
originalRegions.Clear();
|
||||
|
||||
if (!object.ReferenceEquals(sourceAttachments, outputAttachments)) {
|
||||
bool isInPlaceOperation = object.ReferenceEquals(sourceAttachments, outputAttachments);
|
||||
if (!isInPlaceOperation) {
|
||||
outputAttachments.Clear();
|
||||
outputAttachments.AddRange(sourceAttachments);
|
||||
}
|
||||
@ -507,40 +508,22 @@ namespace Spine.Unity.AttachmentTools {
|
||||
for (int attachmentIndex = 0, n = sourceAttachments.Count; attachmentIndex < n; attachmentIndex++) {
|
||||
Attachment originalAttachment = sourceAttachments[attachmentIndex];
|
||||
|
||||
if (originalAttachment is IHasTextureRegion) {
|
||||
MeshAttachment originalMeshAttachment = originalAttachment as MeshAttachment;
|
||||
IHasTextureRegion originalTextureAttachment = (IHasTextureRegion)originalAttachment;
|
||||
|
||||
Attachment newAttachment = (originalTextureAttachment.Sequence != null) ? originalAttachment :
|
||||
(originalMeshAttachment != null) ? originalMeshAttachment.NewLinkedMesh() :
|
||||
originalAttachment.Copy();
|
||||
IHasTextureRegion newTextureAttachment = (IHasTextureRegion)newAttachment;
|
||||
AtlasRegion region = newTextureAttachment.Region as AtlasRegion;
|
||||
if (region == null && originalTextureAttachment.Sequence != null)
|
||||
region = (AtlasRegion)originalTextureAttachment.Sequence.Regions[0];
|
||||
|
||||
if (originalAttachment is IHasSequence) {
|
||||
IHasSequence originalTextureAttachment = (IHasSequence)originalAttachment;
|
||||
Attachment newAttachment = originalAttachment.Copy();
|
||||
AtlasRegion firstRegion = (AtlasRegion)originalTextureAttachment.Sequence.Regions[0];
|
||||
int existingIndex;
|
||||
if (existingRegions.TryGetValue(region, out existingIndex)) {
|
||||
if (existingRegions.TryGetValue(firstRegion, out existingIndex)) {
|
||||
regionIndices.Add(existingIndex);
|
||||
} else {
|
||||
existingRegions.Add(region, newRegionIndex);
|
||||
existingRegions.Add(firstRegion, newRegionIndex);
|
||||
Sequence originalSequence = originalTextureAttachment.Sequence;
|
||||
if (originalSequence != null) {
|
||||
newTextureAttachment.Sequence = new Sequence(originalSequence);
|
||||
for (int i = 0, regionCount = originalSequence.Regions.Length; i < regionCount; ++i) {
|
||||
AtlasRegion sequenceRegion = (AtlasRegion)originalSequence.Regions[i];
|
||||
AddRegionTexturesToPack(numTextureParamsToRepack, sequenceRegion,
|
||||
settings.textureFormat, settings.mipmaps, settings.additionalTextureFormats,
|
||||
settings.additionalTexturePropertyIDsToCopy, settings.additionalTextureIsLinear);
|
||||
originalRegions.Add(sequenceRegion);
|
||||
regionIndices.Add(newRegionIndex);
|
||||
newRegionIndex++;
|
||||
}
|
||||
} else {
|
||||
AddRegionTexturesToPack(numTextureParamsToRepack, region,
|
||||
for (int i = 0, regionCount = originalSequence.Regions.Length; i < regionCount; ++i) {
|
||||
AtlasRegion sequenceRegion = (AtlasRegion)originalSequence.Regions[i];
|
||||
AddRegionTexturesToPack(numTextureParamsToRepack, sequenceRegion,
|
||||
settings.textureFormat, settings.mipmaps, settings.additionalTextureFormats,
|
||||
settings.additionalTexturePropertyIDsToCopy, settings.additionalTextureIsLinear);
|
||||
originalRegions.Add(region);
|
||||
originalRegions.Add(sequenceRegion);
|
||||
regionIndices.Add(newRegionIndex);
|
||||
newRegionIndex++;
|
||||
}
|
||||
@ -616,32 +599,24 @@ namespace Spine.Unity.AttachmentTools {
|
||||
|
||||
// Map the cloned attachments to the repacked atlas.
|
||||
for (int attachmentIndex = 0, repackedIndex = 0, n = outputAttachments.Count;
|
||||
attachmentIndex < n;
|
||||
++attachmentIndex, ++repackedIndex) {
|
||||
attachmentIndex < n; ++attachmentIndex, ++repackedIndex) {
|
||||
|
||||
Attachment attachment = outputAttachments[attachmentIndex];
|
||||
IHasTextureRegion textureAttachment = attachment as IHasTextureRegion;
|
||||
IHasSequence textureAttachment = attachment as IHasSequence;
|
||||
if (textureAttachment != null) {
|
||||
if (textureAttachment.Sequence != null) {
|
||||
TextureRegion[] regions = textureAttachment.Sequence.Regions;
|
||||
for (int r = 0, regionCount = regions.Length; r < regionCount; ++r) {
|
||||
TextureRegion originalRegion = regions[r];
|
||||
TextureRegion repackedRegion = repackedRegions[regionIndices[repackedIndex++]];
|
||||
TextureRegion[] regions = textureAttachment.Sequence.Regions;
|
||||
for (int r = 0, regionCount = regions.Length; r < regionCount; ++r) {
|
||||
TextureRegion originalRegion = regions[r];
|
||||
TextureRegion repackedRegion = repackedRegions[regionIndices[repackedIndex++]];
|
||||
if (enableBlendModes) {
|
||||
AssignBlendMode(ref repackedRegion, originalRegion, normalShader, ref blendModePages,
|
||||
additiveMaterialSource, multiplyMaterialSource, screenMaterialSource);
|
||||
regions[r] = repackedRegion;
|
||||
}
|
||||
textureAttachment.Region = regions[0];
|
||||
--repackedIndex;
|
||||
} else {
|
||||
TextureRegion originalRegion = textureAttachment.Region;
|
||||
TextureRegion repackedRegion = repackedRegions[regionIndices[repackedIndex]];
|
||||
if (enableBlendModes)
|
||||
AssignBlendMode(ref repackedRegion, originalRegion, normalShader, ref blendModePages,
|
||||
additiveMaterialSource, multiplyMaterialSource, screenMaterialSource);
|
||||
textureAttachment.Region = repackedRegion;
|
||||
regions[r] = repackedRegion;
|
||||
}
|
||||
textureAttachment.UpdateRegion();
|
||||
--repackedIndex;
|
||||
|
||||
textureAttachment.UpdateSequence();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1075,7 +1050,7 @@ namespace Spine.Unity.AttachmentTools {
|
||||
}
|
||||
|
||||
static bool IsRenderable (Attachment a) {
|
||||
return a is IHasTextureRegion;
|
||||
return a is IHasSequence;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -74,9 +74,10 @@ namespace Spine.Unity.AttachmentTools {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
|
||||
// (AtlasAttachmentLoader.cs)
|
||||
RegionAttachment attachment = new RegionAttachment(attachmentName);
|
||||
Sequence sequence = new Sequence(1, false);
|
||||
sequence.Regions[0] = region;
|
||||
RegionAttachment attachment = new RegionAttachment(attachmentName, sequence);
|
||||
|
||||
attachment.Region = region;
|
||||
attachment.Path = region.name;
|
||||
attachment.ScaleX = 1;
|
||||
attachment.ScaleY = 1;
|
||||
@ -84,15 +85,11 @@ namespace Spine.Unity.AttachmentTools {
|
||||
attachment.SetColor(Color.white);
|
||||
|
||||
// pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation.
|
||||
TextureRegion textreRegion = attachment.Region;
|
||||
AtlasRegion atlasRegion = textreRegion as AtlasRegion;
|
||||
float originalWidth = atlasRegion != null ? atlasRegion.originalWidth : textreRegion.width;
|
||||
float originalHeight = atlasRegion != null ? atlasRegion.originalHeight : textreRegion.height;
|
||||
attachment.Width = originalWidth * scale;
|
||||
attachment.Height = originalHeight * scale;
|
||||
attachment.Width = region.originalWidth * scale;
|
||||
attachment.Height = region.originalHeight * scale;
|
||||
|
||||
attachment.SetColor(Color.white);
|
||||
attachment.UpdateRegion();
|
||||
attachment.UpdateSequence();
|
||||
return attachment;
|
||||
}
|
||||
|
||||
@ -166,8 +163,10 @@ namespace Spine.Unity.AttachmentTools {
|
||||
float scale = 1f / sprite.pixelsPerUnit;
|
||||
if (useOriginalRegionScale) {
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null)
|
||||
scale = regionAttachment.Width / regionAttachment.Region.OriginalWidth;
|
||||
if (regionAttachment != null) {
|
||||
var firstRegion = regionAttachment.Sequence.GetRegion(0);
|
||||
scale = regionAttachment.Width / firstRegion.OriginalWidth;
|
||||
}
|
||||
}
|
||||
attachment.SetRegion(atlasRegion, useOriginalRegionSize, scale);
|
||||
}
|
||||
@ -181,17 +180,18 @@ namespace Spine.Unity.AttachmentTools {
|
||||
public static void SetRegion (this Attachment attachment, AtlasRegion atlasRegion, bool useOriginalRegionSize = false, float scale = 0.01f) {
|
||||
RegionAttachment regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null) {
|
||||
regionAttachment.Region = atlasRegion;
|
||||
|
||||
regionAttachment.Sequence.Regions[0] = atlasRegion;
|
||||
if (!useOriginalRegionSize) {
|
||||
regionAttachment.Width = atlasRegion.width * scale;
|
||||
regionAttachment.Height = atlasRegion.height * scale;
|
||||
}
|
||||
regionAttachment.UpdateRegion();
|
||||
regionAttachment.UpdateSequence();
|
||||
} else {
|
||||
MeshAttachment meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null) {
|
||||
meshAttachment.Region = atlasRegion;
|
||||
meshAttachment.UpdateRegion();
|
||||
meshAttachment.Sequence.Regions[0] = atlasRegion;
|
||||
meshAttachment.UpdateSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,9 +229,10 @@ namespace Spine.Unity {
|
||||
#region Attachments
|
||||
public static Material GetMaterial (this Attachment a) {
|
||||
object rendererObject = null;
|
||||
IHasTextureRegion renderableAttachment = a as IHasTextureRegion;
|
||||
if (renderableAttachment != null)
|
||||
rendererObject = renderableAttachment.Region;
|
||||
IHasSequence renderableAttachment = a as IHasSequence;
|
||||
if (renderableAttachment != null) {
|
||||
rendererObject = renderableAttachment.Sequence.Regions[0];
|
||||
}
|
||||
|
||||
if (rendererObject == null)
|
||||
return null;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "com.esotericsoftware.spine.spine-unity",
|
||||
"displayName": "spine-unity Runtime",
|
||||
"description": "This plugin provides the spine-unity runtime core and examples. Spine Examples can be installed via the Samples tab.",
|
||||
"version": "4.3.53",
|
||||
"version": "4.3.54",
|
||||
"unity": "2018.3",
|
||||
"author": {
|
||||
"name": "Esoteric Software",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user