Merge branch '3.6' into 3.7-beta

This commit is contained in:
badlogic 2017-07-31 10:11:41 +02:00
commit cae990f66a
7 changed files with 121 additions and 99 deletions

View File

@ -282,8 +282,10 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
color.a *= nodeColor.a * _skeleton->color.a * slot->color.a * 255; color.a *= nodeColor.a * _skeleton->color.a * slot->color.a * 255;
// skip rendering if the color of this attachment is 0 // skip rendering if the color of this attachment is 0
if (color.a == 0) if (color.a == 0){
spSkeletonClipping_clipEnd(_clipper, slot);
continue; continue;
}
float multiplier = _premultipliedAlpha ? color.a : 255; float multiplier = _premultipliedAlpha ? color.a : 255;
color.r *= nodeColor.r * _skeleton->color.r * slot->color.r * multiplier; color.r *= nodeColor.r * _skeleton->color.r * slot->color.r * multiplier;
color.g *= nodeColor.g * _skeleton->color.g * slot->color.g * multiplier; color.g *= nodeColor.g * _skeleton->color.g * slot->color.g * multiplier;
@ -313,8 +315,10 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
spSkeletonClipping_clipTriangles(_clipper, (float*)&triangles.verts[0].vertices, triangles.vertCount * sizeof(cocos2d::V3F_C4B_T2F) / 4, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoords, 6); spSkeletonClipping_clipTriangles(_clipper, (float*)&triangles.verts[0].vertices, triangles.vertCount * sizeof(cocos2d::V3F_C4B_T2F) / 4, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoords, 6);
batch->deallocateVertices(triangles.vertCount); batch->deallocateVertices(triangles.vertCount);
if (_clipper->clippedTriangles->size == 0) if (_clipper->clippedTriangles->size == 0){
spSkeletonClipping_clipEnd(_clipper, slot);
continue; continue;
}
triangles.vertCount = _clipper->clippedVertices->size >> 1; triangles.vertCount = _clipper->clippedVertices->size >> 1;
triangles.verts = batch->allocateVertices(triangles.vertCount); triangles.verts = batch->allocateVertices(triangles.vertCount);
@ -397,8 +401,10 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t
spSkeletonClipping_clipTriangles(_clipper, (float*)&trianglesTwoColor.verts[0].position, trianglesTwoColor.vertCount * sizeof(V3F_C4B_C4B_T2F) / 4, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoords, 7); spSkeletonClipping_clipTriangles(_clipper, (float*)&trianglesTwoColor.verts[0].position, trianglesTwoColor.vertCount * sizeof(V3F_C4B_C4B_T2F) / 4, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoords, 7);
twoColorBatch->deallocateVertices(trianglesTwoColor.vertCount); twoColorBatch->deallocateVertices(trianglesTwoColor.vertCount);
if (_clipper->clippedTriangles->size == 0) if (_clipper->clippedTriangles->size == 0){
spSkeletonClipping_clipEnd(_clipper, slot);
continue; continue;
}
trianglesTwoColor.vertCount = _clipper->clippedVertices->size >> 1; trianglesTwoColor.vertCount = _clipper->clippedVertices->size >> 1;
trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount); trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount);

View File

@ -34,21 +34,21 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class AnimationState { public class AnimationState {
static readonly Animation EmptyAnimation = new Animation("<empty>", new ExposedList<Timeline>(), 0); static readonly Animation EmptyAnimation = new Animation("<empty>", new ExposedList<Timeline>(), 0);
internal const int SUBSEQUENT = 0, FIRST = 1, DIP = 2, DIP_MIX = 3; internal const int Subsequent = 0, First = 1, Dip = 2, DipMix = 3;
private AnimationStateData data; private AnimationStateData data;
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
private readonly HashSet<int> propertyIDs = new HashSet<int>();
private readonly ExposedList<Event> events = new ExposedList<Event>();
private readonly EventQueue queue;
Pool<TrackEntry> trackEntryPool = new Pool<TrackEntry>();
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
private readonly ExposedList<Event> events = new ExposedList<Event>();
private readonly EventQueue queue; // Initialized by constructor.
private readonly HashSet<int> propertyIDs = new HashSet<int>();
private readonly ExposedList<TrackEntry> mixingTo = new ExposedList<TrackEntry>(); private readonly ExposedList<TrackEntry> mixingTo = new ExposedList<TrackEntry>();
private bool animationsChanged; private bool animationsChanged;
private float timeScale = 1; private float timeScale = 1;
Pool<TrackEntry> trackEntryPool = new Pool<TrackEntry>();
public AnimationStateData Data { get { return data; } } public AnimationStateData Data { get { return data; } }
/// <summary>A list of tracks that have animations, which may contain nulls.</summary> /// <summary>A list of tracks that have animations, which may contain nulls.</summary>
public ExposedList<TrackEntry> Tracks { get { return tracks; } } public ExposedList<TrackEntry> Tracks { get { return tracks; } }
@ -63,11 +63,11 @@ namespace Spine {
public AnimationState (AnimationStateData data) { public AnimationState (AnimationStateData data) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
this.data = data; this.data = data;
this.queue = new EventQueue(this, HandleAnimationsChanged, trackEntryPool); this.queue = new EventQueue(
} this,
delegate { this.animationsChanged = true; },
void HandleAnimationsChanged () { trackEntryPool
this.animationsChanged = true; );
} }
/// <summary> /// <summary>
@ -155,7 +155,6 @@ namespace Spine {
return false; return false;
} }
/// <summary> /// <summary>
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the /// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
/// animation state can be applied to multiple skeletons to pose them identically.</summary> /// animation state can be applied to multiple skeletons to pose them identically.</summary>
@ -197,7 +196,7 @@ namespace Spine {
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
Timeline timeline = timelinesItems[ii]; Timeline timeline = timelinesItems[ii];
MixPose pose = timelineData[ii] >= FIRST ? MixPose.Setup : currentPose; MixPose pose = timelineData[ii] >= AnimationState.First ? MixPose.Setup : currentPose;
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
if (rotateTimeline != null) if (rotateTimeline != null)
ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame); ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
@ -246,17 +245,17 @@ namespace Spine {
for (int i = 0; i < timelineCount; i++) { for (int i = 0; i < timelineCount; i++) {
Timeline timeline = timelinesItems[i]; Timeline timeline = timelinesItems[i];
switch (timelineData[i]) { switch (timelineData[i]) {
case SUBSEQUENT: case Subsequent:
if (!attachments && timeline is AttachmentTimeline) continue; if (!attachments && timeline is AttachmentTimeline) continue;
if (!drawOrder && timeline is DrawOrderTimeline) continue; if (!drawOrder && timeline is DrawOrderTimeline) continue;
pose = currentPose; pose = currentPose;
alpha = alphaMix; alpha = alphaMix;
break; break;
case FIRST: case First:
pose = MixPose.Setup; pose = MixPose.Setup;
alpha = alphaMix; alpha = alphaMix;
break; break;
case DIP: case Dip:
pose = MixPose.Setup; pose = MixPose.Setup;
alpha = alphaDip; alpha = alphaDip;
break; break;
@ -421,6 +420,7 @@ namespace Spine {
queue.Drain(); queue.Drain();
} }
/// <summary>Sets the active TrackEntry for a given track number.</summary>
private void SetCurrent (int index, TrackEntry current, bool interrupt) { private void SetCurrent (int index, TrackEntry current, bool interrupt) {
TrackEntry from = ExpandToIndex(index); TrackEntry from = ExpandToIndex(index);
tracks.Items[index] = current; tracks.Items[index] = current;
@ -437,12 +437,12 @@ namespace Spine {
from.timelinesRotation.Clear(); // Reset rotation for mixing out, in case entry was mixed in. from.timelinesRotation.Clear(); // Reset rotation for mixing out, in case entry was mixed in.
} }
queue.Start(current); queue.Start(current); // triggers AnimationsChanged
} }
/// <summary>Sets an animation by name. <seealso cref="SetAnimation(int, Animation, bool)" /></summary> /// <summary>Sets an animation by name. <seealso cref="SetAnimation(int, Animation, bool)" /></summary>
public TrackEntry SetAnimation (int trackIndex, String animationName, bool loop) { public TrackEntry SetAnimation (int trackIndex, string animationName, bool loop) {
Animation animation = data.skeletonData.FindAnimation(animationName); Animation animation = data.skeletonData.FindAnimation(animationName);
if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName"); if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName");
return SetAnimation(trackIndex, animation, loop); return SetAnimation(trackIndex, animation, loop);
@ -480,7 +480,7 @@ namespace Spine {
/// <summary>Queues an animation by name.</summary> /// <summary>Queues an animation by name.</summary>
/// <seealso cref="AddAnimation(int, Animation, bool, float)" /> /// <seealso cref="AddAnimation(int, Animation, bool, float)" />
public TrackEntry AddAnimation (int trackIndex, String animationName, bool loop, float delay) { public TrackEntry AddAnimation (int trackIndex, string animationName, bool loop, float delay) {
Animation animation = data.skeletonData.FindAnimation(animationName); Animation animation = data.skeletonData.FindAnimation(animationName);
if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName"); if (animation == null) throw new ArgumentException("Animation not found: " + animationName, "animationName");
return AddAnimation(trackIndex, animation, loop, delay); return AddAnimation(trackIndex, animation, loop, delay);
@ -570,6 +570,7 @@ namespace Spine {
return null; return null;
} }
/// <summary>Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.</summary>
/// <param name="last">May be null.</param> /// <param name="last">May be null.</param>
private TrackEntry NewTrackEntry (int trackIndex, Animation animation, bool loop, TrackEntry last) { private TrackEntry NewTrackEntry (int trackIndex, Animation animation, bool loop, TrackEntry last) {
TrackEntry entry = trackEntryPool.Obtain(); // Pooling TrackEntry entry = trackEntryPool.Obtain(); // Pooling
@ -589,7 +590,7 @@ namespace Spine {
entry.delay = 0; entry.delay = 0;
entry.trackTime = 0; entry.trackTime = 0;
entry.trackLast = -1; entry.trackLast = -1;
entry.nextTrackLast = -1; entry.nextTrackLast = -1; // nextTrackLast == -1 signifies a TrackEntry that wasn't applied yet.
entry.trackEnd = float.MaxValue; // loop ? float.MaxValue : animation.Duration; entry.trackEnd = float.MaxValue; // loop ? float.MaxValue : animation.Duration;
entry.timeScale = 1; entry.timeScale = 1;
@ -600,6 +601,7 @@ namespace Spine {
return entry; return entry;
} }
/// <summary>Dispose all track entries queued after the given TrackEntry.</summary>
private void DisposeNext (TrackEntry entry) { private void DisposeNext (TrackEntry entry) {
TrackEntry next = entry.next; TrackEntry next = entry.next;
while (next != null) { while (next != null) {
@ -628,7 +630,7 @@ namespace Spine {
return (trackIndex >= tracks.Count) ? null : tracks.Items[trackIndex]; return (trackIndex >= tracks.Count) ? null : tracks.Items[trackIndex];
} }
override public String ToString () { override public string ToString () {
var buffer = new System.Text.StringBuilder(); var buffer = new System.Text.StringBuilder();
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry entry = tracks.Items[i]; TrackEntry entry = tracks.Items[i];
@ -680,11 +682,12 @@ namespace Spine {
Event = null; Event = null;
} }
/// <summary>Sets the timeline data.</summary>
/// <param name="to">May be null.</param> /// <param name="to">May be null.</param>
internal TrackEntry SetTimelineData (TrackEntry to, ExposedList<TrackEntry> mixingToArray, HashSet<int> propertyIDs) { internal TrackEntry SetTimelineData (TrackEntry to, ExposedList<TrackEntry> mixingToArray, HashSet<int> propertyIDs) {
if (to != null) mixingToArray.Add(to); if (to != null) mixingToArray.Add(to);
var lastEntry = mixingFrom != null ? mixingFrom.SetTimelineData(this, mixingToArray, propertyIDs) : this; var lastEntry = mixingFrom != null ? mixingFrom.SetTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null) mixingToArray.RemoveAt(mixingToArray.Count - 1); // mixingToArray.pop(); if (to != null) mixingToArray.Pop();
var mixingTo = mixingToArray.Items; var mixingTo = mixingToArray.Items;
int mixingToLast = mixingToArray.Count - 1; int mixingToLast = mixingToArray.Count - 1;
@ -698,21 +701,19 @@ namespace Spine {
for (int i = 0; i < timelinesCount; i++) { for (int i = 0; i < timelinesCount; i++) {
int id = timelines[i].PropertyId; int id = timelines[i].PropertyId;
if (!propertyIDs.Add(id)) { if (!propertyIDs.Add(id)) {
timelineDataItems[i] = AnimationState.SUBSEQUENT; timelineDataItems[i] = AnimationState.Subsequent;
} else if (to == null || !to.HasTimeline(id)) { } else if (to == null || !to.HasTimeline(id)) {
timelineDataItems[i] = AnimationState.FIRST; timelineDataItems[i] = AnimationState.First;
} else { } else {
for (int ii = mixingToLast; ii >= 0; ii--) { for (int ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii]; var entry = mixingTo[ii];
if (!entry.HasTimeline(id)) { if (entry.mixDuration > 0 && !entry.HasTimeline(id)) {
if (entry.mixDuration > 0) { timelineDataItems[i] = AnimationState.DipMix;
timelineDataItems[i] = AnimationState.DIP_MIX;
timelineDipMixItems[i] = entry; timelineDipMixItems[i] = entry;
goto outer; // continue outer; goto outer; // continue outer;
} }
} }
} timelineDataItems[i] = AnimationState.Dip;
timelineDataItems[i] = AnimationState.DIP;
} }
outer: {} outer: {}
} }
@ -886,20 +887,20 @@ namespace Spine {
timelinesRotation.Clear(); timelinesRotation.Clear();
} }
override public String ToString () { override public string ToString () {
return animation == null ? "<none>" : animation.name; return animation == null ? "<none>" : animation.name;
} }
} }
class EventQueue { class EventQueue {
private readonly List<EventQueueEntry> eventQueueEntries = new List<EventQueueEntry>(); private readonly List<EventQueueEntry> eventQueueEntries = new List<EventQueueEntry>();
public bool drainDisabled; internal bool drainDisabled;
private readonly AnimationState state; private readonly AnimationState state;
private readonly Pool<TrackEntry> trackEntryPool; private readonly Pool<TrackEntry> trackEntryPool;
public event Action AnimationsChanged; internal event Action AnimationsChanged;
public EventQueue (AnimationState state, Action HandleAnimationsChanged, Pool<TrackEntry> trackEntryPool) { internal EventQueue (AnimationState state, Action HandleAnimationsChanged, Pool<TrackEntry> trackEntryPool) {
this.state = state; this.state = state;
this.AnimationsChanged += HandleAnimationsChanged; this.AnimationsChanged += HandleAnimationsChanged;
this.trackEntryPool = trackEntryPool; this.trackEntryPool = trackEntryPool;
@ -921,33 +922,34 @@ namespace Spine {
Start, Interrupt, End, Dispose, Complete, Event Start, Interrupt, End, Dispose, Complete, Event
} }
public void Start (TrackEntry entry) { internal void Start (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Start, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.Start, entry));
if (AnimationsChanged != null) AnimationsChanged(); if (AnimationsChanged != null) AnimationsChanged();
} }
public void Interrupt (TrackEntry entry) { internal void Interrupt (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Interrupt, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.Interrupt, entry));
} }
public void End (TrackEntry entry) { internal void End (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.End, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.End, entry));
if (AnimationsChanged != null) AnimationsChanged(); if (AnimationsChanged != null) AnimationsChanged();
} }
public void Dispose (TrackEntry entry) { internal void Dispose (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Dispose, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.Dispose, entry));
} }
public void Complete (TrackEntry entry) { internal void Complete (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Complete, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.Complete, entry));
} }
public void Event (TrackEntry entry, Event e) { internal void Event (TrackEntry entry, Event e) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Event, entry, e)); eventQueueEntries.Add(new EventQueueEntry(EventType.Event, entry, e));
} }
public void Drain () { /// <summary>Raises all events in the queue and drains the queue.</summary>
internal void Drain () {
if (drainDisabled) return; if (drainDisabled) return;
drainDisabled = true; drainDisabled = true;
@ -992,7 +994,7 @@ namespace Spine {
drainDisabled = false; drainDisabled = false;
} }
public void Clear () { internal void Clear () {
eventQueueEntries.Clear(); eventQueueEntries.Clear();
} }
} }

View File

@ -43,11 +43,21 @@ using Windows.Storage;
#endif #endif
namespace Spine { namespace Spine {
public class Atlas { public class Atlas : IEnumerable<AtlasRegion> {
readonly List<AtlasPage> pages = new List<AtlasPage>(); readonly List<AtlasPage> pages = new List<AtlasPage>();
List<AtlasRegion> regions = new List<AtlasRegion>(); List<AtlasRegion> regions = new List<AtlasRegion>();
TextureLoader textureLoader; TextureLoader textureLoader;
#region IEnumerable implementation
public IEnumerator<AtlasRegion> GetEnumerator () {
return regions.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () {
return regions.GetEnumerator();
}
#endregion
#if !(IS_UNITY) #if !(IS_UNITY)
#if WINDOWS_STOREAPP #if WINDOWS_STOREAPP
private async Task ReadFile(string path, TextureLoader textureLoader) { private async Task ReadFile(string path, TextureLoader textureLoader) {
@ -99,7 +109,7 @@ namespace Spine {
} }
private void Load (TextReader reader, string imagesDir, TextureLoader textureLoader) { private void Load (TextReader reader, string imagesDir, TextureLoader textureLoader) {
if (textureLoader == null) throw new ArgumentNullException("textureLoader cannot be null."); if (textureLoader == null) throw new ArgumentNullException("textureLoader", "textureLoader cannot be null.");
this.textureLoader = textureLoader; this.textureLoader = textureLoader;
string[] tuple = new string[4]; string[] tuple = new string[4];
@ -168,11 +178,11 @@ namespace Spine {
region.height = Math.Abs(height); region.height = Math.Abs(height);
if (ReadTuple(reader, tuple) == 4) { // split is optional if (ReadTuple(reader, tuple) == 4) { // split is optional
region.splits = new int[] {int.Parse(tuple[0]), int.Parse(tuple[1]), region.splits = new [] {int.Parse(tuple[0]), int.Parse(tuple[1]),
int.Parse(tuple[2]), int.Parse(tuple[3])}; int.Parse(tuple[2]), int.Parse(tuple[3])};
if (ReadTuple(reader, tuple) == 4) { // pad is optional, but only present with splits if (ReadTuple(reader, tuple) == 4) { // pad is optional, but only present with splits
region.pads = new int[] {int.Parse(tuple[0]), int.Parse(tuple[1]), region.pads = new [] {int.Parse(tuple[0]), int.Parse(tuple[1]),
int.Parse(tuple[2]), int.Parse(tuple[3])}; int.Parse(tuple[2]), int.Parse(tuple[3])};
ReadTuple(reader, tuple); ReadTuple(reader, tuple);

View File

@ -104,14 +104,14 @@ namespace Spine {
} }
} }
private void CheckRange (int idx, int count) { private void CheckRange (int index, int count) {
if (idx < 0) if (index < 0)
throw new ArgumentOutOfRangeException("index"); throw new ArgumentOutOfRangeException("index");
if (count < 0) if (count < 0)
throw new ArgumentOutOfRangeException("count"); throw new ArgumentOutOfRangeException("count");
if ((uint)idx + (uint)count > (uint)Count) if ((uint)index + (uint)count > (uint)Count)
throw new ArgumentException("index and count exceed length of list"); throw new ArgumentException("index and count exceed length of list");
} }
@ -450,6 +450,21 @@ namespace Spine {
version++; version++;
} }
// Spine Added Method
// Based on Stack<T>.Pop(); https://referencesource.microsoft.com/#mscorlib/system/collections/stack.cs
/// <summary>Pops the last item of the list. If the list is empty, Pop throws an InvalidOperationException.</summary>
public T Pop () {
if (Count == 0)
throw new InvalidOperationException("List is empty. Nothing to pop.");
int i = Count - 1;
T item = Items[i];
Items[i] = default(T);
Count--;
version++;
return item;
}
public void RemoveRange (int index, int count) { public void RemoveRange (int index, int count) {
CheckRange(index, count); CheckRange(index, count);
if (count > 0) { if (count > 0) {

View File

@ -50,7 +50,6 @@ package spine.starling {
public function StarlingAtlasAttachmentLoader(atlas : TextureAtlas) { public function StarlingAtlasAttachmentLoader(atlas : TextureAtlas) {
this.atlas = atlas; this.atlas = atlas;
Bone.yDown = true; Bone.yDown = true;
} }
@ -59,11 +58,11 @@ package spine.starling {
} }
public function newRegionAttachment(skin : Skin, name : String, path : String) : RegionAttachment { public function newRegionAttachment(skin : Skin, name : String, path : String) : RegionAttachment {
var texture : Texture = getTexture(path); var texture : SubTexture = getTexture(path) as SubTexture;
if (texture == null) if (texture == null)
throw new Error("Region not found in Starling atlas: " + path + " (region attachment: " + name + ")"); throw new Error("Region not found in Starling atlas: " + path + " (region attachment: " + name + ")");
var attachment : RegionAttachment = new RegionAttachment(name); var attachment : RegionAttachment = new RegionAttachment(name);
var rotated : Boolean = atlas.getRotation(path); var rotated : Boolean = texture.rotated;
attachment.rendererObject = new Image(Texture.fromTexture(texture)); // Discard frame. attachment.rendererObject = new Image(Texture.fromTexture(texture)); // Discard frame.
var frame : Rectangle = texture.frame; var frame : Rectangle = texture.frame;
attachment.regionOffsetX = frame ? -frame.x : 0; attachment.regionOffsetX = frame ? -frame.x : 0;
@ -79,59 +78,44 @@ package spine.starling {
tmp = attachment.regionWidth; tmp = attachment.regionWidth;
attachment.regionWidth = attachment.regionHeight; attachment.regionWidth = attachment.regionHeight;
attachment.regionHeight = tmp; attachment.regionHeight = tmp;
}
if (!rotated) {
attachment["regionU"] = 0;
attachment["regionV"] = 0;
attachment["regionU2"] = 1;
attachment["regionV2"] = 1;
} else {
attachment["regionU2"] = 0; attachment["regionU2"] = 0;
attachment["regionV2"] = 1; attachment["regionV2"] = 1;
attachment["regionU"] = 1; attachment["regionU"] = 1;
attachment["regionV"] = 0; attachment["regionV"] = 0;
}else{
attachment["regionU"] = 0;
attachment["regionV"] = 0;
attachment["regionU2"] = 1;
attachment["regionV2"] = 1;
} }
attachment.setUVs(attachment["regionU"], attachment["regionV"], attachment["regionU2"], attachment["regionV2"], atlas.getRotation(path)); attachment.setUVs(attachment["regionU"], attachment["regionV"], attachment["regionU2"], attachment["regionV2"], rotated);
return attachment; return attachment;
} }
public function newMeshAttachment(skin : Skin, name : String, path : String) : MeshAttachment { public function newMeshAttachment(skin : Skin, name : String, path : String) : MeshAttachment {
var texture : Texture = getTexture(path); var texture : SubTexture = getTexture(path) as SubTexture;
if (texture == null) if (texture == null)
throw new Error("Region not found in Starling atlas: " + path + " (mesh attachment: " + name + ")"); throw new Error("Region not found in Starling atlas: " + path + " (mesh attachment: " + name + ")");
var rotated : Boolean = atlas.getRotation(path); var rotated : Boolean = texture.rotated;
var attachment : MeshAttachment = new MeshAttachment(name); var attachment : MeshAttachment = new MeshAttachment(name);
attachment.regionRotate = rotated; attachment.regionRotate = rotated;
attachment.rendererObject = new Image(Texture.fromTexture(texture)); // Discard frame. attachment.rendererObject = new Image(Texture.fromTexture(texture)); // Discard frame.
var subTexture : SubTexture = texture as SubTexture;
if (subTexture) { var root : Texture = texture.root;
var root : Texture = subTexture.root;
var rectRegion : Rectangle = atlas.getRegion(path); var rectRegion : Rectangle = atlas.getRegion(path);
if (!rotated) { if (!rotated) {
attachment.regionU = rectRegion.x / root.width; attachment.regionU = rectRegion.x / root.width;
attachment.regionV = rectRegion.y / root.height; attachment.regionV = rectRegion.y / root.height;
attachment.regionU2 = (rectRegion.x + subTexture.width) / root.width; attachment.regionU2 = (rectRegion.x + texture.width) / root.width;
attachment.regionV2 = (rectRegion.y + subTexture.height) / root.height; attachment.regionV2 = (rectRegion.y + texture.height) / root.height;
} else { } else {
attachment.regionU2 = rectRegion.x / root.width; attachment.regionU2 = rectRegion.x / root.width;
attachment.regionV2 = rectRegion.y / root.height; attachment.regionV2 = rectRegion.y / root.height;
attachment.regionU = (rectRegion.x + subTexture.height) / root.width; attachment.regionU = (rectRegion.x + texture.height) / root.width;
attachment.regionV = (rectRegion.y + subTexture.width) / root.height; attachment.regionV = (rectRegion.y + texture.width) / root.height;
} }
attachment.rendererObject = new Image(root); attachment.rendererObject = new Image(root);
} else {
if (!rotated) {
attachment.regionU = 0;
attachment.regionV = 1;
attachment.regionU2 = 1;
attachment.regionV2 = 0;
} else {
attachment.regionU2 = 0;
attachment.regionV2 = 1;
attachment.regionU = 1;
attachment.regionV = 0;
}
}
var frame : Rectangle = texture.frame; var frame : Rectangle = texture.frame;
attachment.regionOffsetX = frame ? -frame.x : 0; attachment.regionOffsetX = frame ? -frame.x : 0;
attachment.regionOffsetY = frame ? -frame.y : 0; attachment.regionOffsetY = frame ? -frame.y : 0;

View File

@ -75,7 +75,12 @@ namespace Spine.Unity {
public void Update () { public void Update () {
if (!valid) return; if (!valid) return;
#if UNITY_EDITOR
if (Application.isPlaying)
translator.Apply(skeleton); translator.Apply(skeleton);
#else
translator.Apply(skeleton);
#endif
// UpdateWorldTransform and Bone Callbacks // UpdateWorldTransform and Bone Callbacks
{ {