Merge branch '3.7-beta' into 3.7-beta-cpp

This commit is contained in:
badlogic 2018-09-10 16:16:43 +02:00
commit 939cecdd0f
56 changed files with 1387 additions and 744 deletions

View File

@ -38,8 +38,8 @@ package spine.animation {
public class AnimationState {
public static var SUBSEQUENT : int = 0;
public static var FIRST : int = 1;
public static var DIP : int = 2;
public static var DIP_MIX : int = 3;
public static var HOLD : int = 2;
public static var HOLD_MIX : int = 3;
internal static var emptyAnimation : Animation = new Animation("<empty>", new Vector.<Timeline>(), 0);
public var data : AnimationStateData;
public var tracks : Vector.<TrackEntry> = new Vector.<TrackEntry>();
@ -112,6 +112,7 @@ package spine.animation {
// End mixing from entries once all have completed.
var from : TrackEntry = current.mixingFrom;
current.mixingFrom = null;
if (from != null) from.mixingTo = null;
while (from != null) {
queue.end(from);
from = from.mixingFrom;
@ -138,6 +139,7 @@ package spine.animation {
// Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
queue.end(from);
}
@ -174,11 +176,11 @@ package spine.animation {
var timelineCount : int = current.animation.timelines.length;
var timelines : Vector.<Timeline> = current.animation.timelines;
var ii : int = 0;
if (mix == 1 || blend == MixBlend.add) {
if (i == 0 && (mix == 1 || blend == MixBlend.add)) {
for (ii = 0; ii < timelineCount; ii++)
Timeline(timelines[ii]).apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.In);
} else {
var timelineData : Vector.<int> = current.timelineData;
var timelineMode : Vector.<int> = current.timelineMode;
var firstFrame : Boolean = current.timelinesRotation.length == 0;
if (firstFrame) current.timelinesRotation.length = timelineCount << 1;
@ -186,7 +188,7 @@ package spine.animation {
for (ii = 0; ii < timelineCount; ii++) {
var timeline : Timeline = timelines[ii];
var timelineBlend : MixBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
var timelineBlend : MixBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
if (timeline is RotateTimeline) {
applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
} else
@ -222,15 +224,15 @@ package spine.animation {
var animationLast : Number = from.animationLast, animationTime : Number = from.getAnimationTime();
var timelineCount : int = from.animation.timelines.length;
var timelines : Vector.<Timeline> = from.animation.timelines;
var alphaDip : Number = from.alpha * to.interruptAlpha;
var alphaMix : Number = alphaDip * (1 - mix);
var alphaHold : Number = from.alpha * to.interruptAlpha;
var alphaMix : Number = alphaHold * (1 - mix);
var i : int = 0;
if (blend == MixBlend.add) {
for (i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.Out);
} else {
var timelineData : Vector.<int> = from.timelineData;
var timelineDipMix : Vector.<TrackEntry> = from.timelineDipMix;
var timelineMode : Vector.<int> = from.timelineMode;
var timelineHoldMix : Vector.<TrackEntry> = from.timelineHoldMix;
var firstFrame : Boolean = from.timelinesRotation.length == 0;
if (firstFrame) from.timelinesRotation.length = timelineCount << 1;
@ -241,7 +243,7 @@ package spine.animation {
var timeline : Timeline = timelines[i];
var timelineBlend: MixBlend;
var alpha : Number = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case SUBSEQUENT:
if (!attachments && timeline is AttachmentTimeline) continue;
if (!drawOrder && timeline is DrawOrderTimeline) continue;
@ -252,14 +254,14 @@ package spine.animation {
timelineBlend = MixBlend.setup;
alpha = alphaMix;
break;
case DIP:
case HOLD:
timelineBlend = MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = MixBlend.setup;
var dipMix : TrackEntry = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix : TrackEntry = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -399,6 +401,7 @@ package spine.animation {
if (from == null) break;
queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
@ -414,6 +417,7 @@ package spine.animation {
if (from != null) {
if (interrupt) queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
// Store the interrupted mix percentage.
@ -529,6 +533,7 @@ package spine.animation {
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
@ -565,14 +570,69 @@ package spine.animation {
private function _animationsChanged() : void {
animationsChanged = false;
var propertyIDs : Dictionary = this.propertyIDs = new Dictionary();
var mixingTo : Vector.<TrackEntry> = this.mixingTo;
propertyIDs = new Dictionary();
for (var i : int = 0, n : int = tracks.length; i < n; i++) {
var entry : TrackEntry = tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null) continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingTo == null || entry.mixBlend != MixBlend.add) setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
}
private function setTimelineModes (entry: TrackEntry) {
var to: TrackEntry = entry.mixingTo;
var timelines : Vector.<Timeline> = entry.animation.timelines;
var timelinesCount : int = entry.animation.timelines.length;
var timelineMode : Vector.<int> = entry.timelineMode;
timelineMode.length = timelinesCount;
var timelineHoldMix : Vector.<TrackEntry> = entry.timelineHoldMix;
timelineHoldMix.length = 0;
var propertyIDs: Dictionary = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i : int = 0; i < timelinesCount; i++) {
propertyIDs[timelines[i].getPropertyId().toString()] = true;
timelineMode[i] = HOLD;
}
return;
}
outer:
for (var i : int = 0; i < timelinesCount; i++) {
var intId : int = timelines[i].getPropertyId();
var id : String = intId.toString();
var contained: Object = propertyIDs[id];
propertyIDs[id] = true;
if (contained != null) {
timelineMode[i] = AnimationState.SUBSEQUENT;
} else if (to == null || !hasTimeline(to, intId)) {
timelineMode[i] = AnimationState.FIRST;
} else {
for (var next : TrackEntry = to.mixingTo; next != null; next = next.mixingTo) {
if (hasTimeline(next, intId)) continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineHoldMix[i] = entry;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
}
private static function hasTimeline (entry: TrackEntry, id : int) : Boolean {
var timelines : Vector.<Timeline> = entry.animation.timelines;
for (var i : int = 0, n : int = entry.animation.timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id) return true;
return false;
}
public function getCurrent(trackIndex : int) : TrackEntry {
if (trackIndex >= tracks.length) return null;

View File

@ -34,7 +34,7 @@ package spine.animation {
public class TrackEntry implements Poolable {
public var animation : Animation;
public var next : TrackEntry, mixingFrom : TrackEntry;
public var next : TrackEntry, mixingFrom : TrackEntry, mixingTo: TrackEntry;
public var onStart : Listeners = new Listeners();
public var onInterrupt : Listeners = new Listeners();
public var onEnd : Listeners = new Listeners();
@ -42,14 +42,14 @@ package spine.animation {
public var onComplete : Listeners = new Listeners();
public var onEvent : Listeners = new Listeners();
public var trackIndex : int;
public var loop : Boolean;
public var loop : Boolean, holdPrevious: Boolean;
public var eventThreshold : Number, attachmentThreshold : Number, drawOrderThreshold : Number;
public var animationStart : Number, animationEnd : Number, animationLast : Number, nextAnimationLast : Number;
public var delay : Number, trackTime : Number, trackLast : Number, nextTrackLast : Number, trackEnd : Number, timeScale : Number;
public var alpha : Number, mixTime : Number, mixDuration : Number, interruptAlpha : Number, totalAlpha : Number = 0;
public var mixBlend: MixBlend = MixBlend.replace;
public var timelineData : Vector.<int> = new Vector.<int>();
public var timelineDipMix : Vector.<TrackEntry> = new Vector.<TrackEntry>();
public var timelineMode : Vector.<int> = new Vector.<int>();
public var timelineHoldMix : Vector.<TrackEntry> = new Vector.<TrackEntry>();
public var timelinesRotation : Vector.<Number> = new Vector.<Number>();
public function TrackEntry() {
@ -67,6 +67,7 @@ package spine.animation {
public function reset() : void {
next = null;
mixingFrom = null;
mixingTo = null;
animation = null;
onStart.listeners.length = 0;
onInterrupt.listeners.length = 0;
@ -74,60 +75,10 @@ package spine.animation {
onDispose.listeners.length = 0;
onComplete.listeners.length = 0;
onEvent.listeners.length = 0;
timelineData.length = 0;
timelineDipMix.length = 0;
timelineMode.length = 0;
timelineHoldMix.length = 0;
timelinesRotation.length = 0;
}
public function setTimelineData (to: TrackEntry, mixingToArray : Vector.<TrackEntry>, propertyIDs : Dictionary) : TrackEntry {
if (to != null) mixingToArray.push(to);
var lastEntry : TrackEntry = mixingFrom != null ? mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null) mixingToArray.pop();
var mixingTo : Vector.<TrackEntry> = mixingToArray;
var mixingToLast : int = mixingToArray.length - 1;
var timelines : Vector.<Timeline> = animation.timelines;
var timelinesCount : int = animation.timelines.length;
var timelineData : Vector.<int> = this.timelineData;
timelineData.length = timelinesCount;
this.timelineDipMix.length = 0;
var timelineDipMix : Vector.<TrackEntry> = this.timelineDipMix;
timelineDipMix.length = timelinesCount;
outer:
for (var i : int = 0; i < timelinesCount; i++) {
var intId : int = timelines[i].getPropertyId();
var id : String = intId.toString();
var contained: Object = propertyIDs[id];
propertyIDs[id] = true;
if (contained != null) {
timelineData[i] = AnimationState.SUBSEQUENT;
} else if (to == null || !to.hasTimeline(intId)) {
timelineData[i] = AnimationState.FIRST;
} else {
for (var ii : int = mixingToLast; ii >= 0; ii--) {
var entry : TrackEntry = mixingTo[ii];
if (!entry.hasTimeline(intId)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
break;
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
}
private function hasTimeline (id : int) : Boolean {
var timelines : Vector.<Timeline> = animation.timelines;
for (var i : int = 0, n : int = animation.timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id) return true;
return false;
}
}
public function resetRotationDirection() : void {
timelinesRotation.length = 0;

View File

@ -36,7 +36,7 @@ namespace Spine {
static readonly Animation EmptyAnimation = new Animation("<empty>", new ExposedList<Timeline>(), 0);
internal const int Subsequent = 0, First = 1, Hold = 2, HoldMix = 3;
private AnimationStateData data;
protected AnimationStateData data;
private readonly Pool<TrackEntry> trackEntryPool = new Pool<TrackEntry>();
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
@ -49,6 +49,7 @@ namespace Spine {
private float timeScale = 1;
public AnimationStateData Data { get { return data; } }
/// <summary>A list of tracks that have animations, which may contain nulls.</summary>
public ExposedList<TrackEntry> Tracks { get { return tracks; } }
public float TimeScale { get { return timeScale; } set { timeScale = value; } }
@ -70,7 +71,7 @@ namespace Spine {
}
/// <summary>
/// Increments the track entry times, setting queued animations as current if needed</summary>
/// Increments the track entry trackTimes, setting queued animations as current if needed</summary>
/// <param name="delta">delta time</param>
public void Update (float delta) {
delta *= timeScale;
@ -109,7 +110,6 @@ namespace Spine {
} else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
// Clear the track when there is no next entry, the track end time is reached, and there is no mixingFrom.
tracksItems[i] = null;
queue.End(current);
DisposeNext(current);
continue;
@ -166,7 +166,6 @@ namespace Spine {
if (animationsChanged) AnimationsChanged();
var events = this.events;
bool applied = false;
var tracksItems = tracks.Items;
for (int i = 0, m = tracks.Count; i < m; i++) {
@ -174,6 +173,7 @@ namespace Spine {
if (current == null || current.delay > 0) continue;
applied = true;
// Track 0 animations aren't for layering, so do not show the previously applied animations before the first key.
MixBlend blend = i == 0 ? MixBlend.First : current.mixBlend;
// Apply mixing from entries first.
@ -242,7 +242,7 @@ namespace Spine {
if (blend == MixBlend.Add) {
for (int i = 0; i < timelineCount; i++)
(timelinesItems[i]).Apply(skeleton, animationLast, animationTime, eventBuffer, alphaMix, blend, MixDirection.Out);
timelinesItems[i].Apply(skeleton, animationLast, animationTime, eventBuffer, alphaMix, blend, MixDirection.Out);
} else {
var timelineMode = from.timelineMode.Items;
var timelineHoldMix = from.timelineHoldMix.Items;
@ -258,10 +258,8 @@ namespace Spine {
float alpha;
switch (timelineMode[i]) {
case AnimationState.Subsequent:
if (!attachments && timeline is AttachmentTimeline)
continue;
if (!drawOrder && timeline is DrawOrderTimeline)
continue;
if (!attachments && timeline is AttachmentTimeline) continue;
if (!drawOrder && timeline is DrawOrderTimeline) continue;
timelineBlend = blend;
alpha = alphaMix;
break;
@ -446,7 +444,7 @@ namespace Spine {
if (from != null) {
if (interrupt) queue.Interrupt(from);
current.mixingFrom = from;
current.mixingTo = current;
from.mixingTo = current;
current.mixTime = 0;
// Store interrupted mix percentage.
@ -640,7 +638,7 @@ namespace Spine {
private void AnimationsChanged () {
animationsChanged = false;
this.propertyIDs.Clear();
propertyIDs.Clear();
var tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) {
@ -659,7 +657,7 @@ namespace Spine {
}
private void SetTimelineModes (TrackEntry entry) {
var to = entry.mixingTo;
TrackEntry to = entry.mixingTo;
var timelines = entry.animation.timelines.Items;
int timelinesCount = entry.animation.timelines.Count;
var timelineMode = entry.timelineMode.Resize(timelinesCount).Items; //timelineMode.setSize(timelinesCount);
@ -694,7 +692,7 @@ namespace Spine {
}
timelineMode[i] = AnimationState.Hold;
}
continue_outer: {}
continue_outer: {}
}
}
@ -750,6 +748,7 @@ namespace Spine {
public void Reset () {
next = null;
mixingFrom = null;
mixingTo = null;
animation = null;
timelineMode.Clear();
timelineHoldMix.Clear();
@ -763,13 +762,6 @@ namespace Spine {
Event = null;
}
bool HasTimeline (int id) {
var timelines = animation.timelines.Items;
for (int i = 0, n = animation.timelines.Count; i < n; i++)
if (timelines[i].PropertyId == id) return true;
return false;
}
/// <summary>The index of the track where this entry is either current or queued.</summary>
public int TrackIndex { get { return trackIndex; } }

View File

@ -283,8 +283,12 @@ namespace Spine {
public TextureFilter magFilter;
public TextureWrap uWrap;
public TextureWrap vWrap;
public Object rendererObject;
public object rendererObject;
public int width, height;
public AtlasPage Clone () {
return MemberwiseClone() as AtlasPage;
}
}
public class AtlasRegion {
@ -298,6 +302,10 @@ namespace Spine {
public bool rotate;
public int[] splits;
public int[] pads;
public AtlasRegion Clone () {
return MemberwiseClone() as AtlasRegion;
}
}
public interface TextureLoader {

View File

@ -45,6 +45,6 @@ namespace Spine {
}
public interface IHasRendererObject {
object RendererObject { get; }
object RendererObject { get; set; }
}
}

View File

@ -202,6 +202,20 @@ public class Animation {
twoColor
}
static public interface BoneTimeline extends Timeline {
public void setBoneIndex (int index);
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
public int getBoneIndex ();
}
static public interface SlotTimeline extends Timeline {
public void setSlotIndex (int index);
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
public int getSlotIndex ();
}
/** The base class for timelines that use interpolation between key frame values. */
abstract static public class CurveTimeline implements Timeline {
static public final float LINEAR = 0, STEPPED = 1, BEZIER = 2;
@ -290,7 +304,7 @@ public class Animation {
}
/** Changes a bone's local {@link Bone#getRotation()}. */
static public class RotateTimeline extends CurveTimeline {
static public class RotateTimeline extends CurveTimeline implements BoneTimeline {
static public final int ENTRIES = 2;
static final int PREV_TIME = -2, PREV_ROTATION = -1;
static final int ROTATION = 1;
@ -386,7 +400,7 @@ public class Animation {
}
/** Changes a bone's local {@link Bone#getX()} and {@link Bone#getY()}. */
static public class TranslateTimeline extends CurveTimeline {
static public class TranslateTimeline extends CurveTimeline implements BoneTimeline {
static public final int ENTRIES = 3;
static final int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
static final int X = 1, Y = 2;
@ -641,7 +655,7 @@ public class Animation {
}
/** Changes a slot's {@link Slot#getColor()}. */
static public class ColorTimeline extends CurveTimeline {
static public class ColorTimeline extends CurveTimeline implements SlotTimeline {
static public final int ENTRIES = 5;
static private final int PREV_TIME = -5, PREV_R = -4, PREV_G = -3, PREV_B = -2, PREV_A = -1;
static private final int R = 1, G = 2, B = 3, A = 4;
@ -735,7 +749,7 @@ public class Animation {
}
/** Changes a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
static public class TwoColorTimeline extends CurveTimeline {
static public class TwoColorTimeline extends CurveTimeline implements SlotTimeline {
static public final int ENTRIES = 8;
static private final int PREV_TIME = -8, PREV_R = -7, PREV_G = -6, PREV_B = -5, PREV_A = -4;
static private final int PREV_R2 = -3, PREV_G2 = -2, PREV_B2 = -1;
@ -849,7 +863,7 @@ public class Animation {
}
/** Changes a slot's {@link Slot#getAttachment()}. */
static public class AttachmentTimeline implements Timeline {
static public class AttachmentTimeline implements SlotTimeline {
int slotIndex;
final float[] frames; // time, ...
final String[] attachmentNames;
@ -925,7 +939,7 @@ public class Animation {
}
/** Changes a slot's {@link Slot#getAttachmentVertices()} to deform a {@link VertexAttachment}. */
static public class DeformTimeline extends CurveTimeline {
static public class DeformTimeline extends CurveTimeline implements SlotTimeline {
int slotIndex;
VertexAttachment attachment;
private final float[] frames; // time, ...

View File

@ -69,6 +69,7 @@ package spine.examples {
var skeletonData : SkeletonData = json.readSkeletonData(new SpineboyJson());
var stateData : AnimationStateData = new AnimationStateData(skeletonData);
stateData.setMixByName("walk", "run", 0.4);
stateData.setMixByName("run", "jump", 0.4);
stateData.setMixByName("jump", "run", 0.4);
stateData.setMixByName("jump", "jump", 0.4);

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;
@ -7266,8 +7279,8 @@ var spine;
break;
}
var listeners = _this.listeners;
for (var i_16 = 0; i_16 < listeners.length; i_16++) {
listeners[i_16].down(_this.currTouch.x, _this.currTouch.y);
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].down(_this.currTouch.x, _this.currTouch.y);
}
console.log("Start " + _this.currTouch.x + ", " + _this.currTouch.y);
_this.lastX = _this.currTouch.x;
@ -7276,29 +7289,6 @@ var spine;
ev.preventDefault();
}, false);
element.addEventListener("touchend", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
@ -7321,6 +7311,29 @@ var spine;
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchmove", function (ev) {
if (_this.currTouch == null)
return;
@ -7332,8 +7345,8 @@ var spine;
var x = touch.clientX - rect.left;
var y = touch.clientY - rect.top;
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].dragged(x, y);
for (var i_20 = 0; i_20 < listeners.length; i_20++) {
listeners[i_20].dragged(x, y);
}
console.log("Drag " + x + ", " + y);
_this.lastX = _this.currTouch.x = x;
@ -9183,11 +9196,11 @@ var spine;
var nn = clip.worldVerticesLength;
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
for (var i_20 = 0, n_2 = world.length; i_20 < n_2; i_20 += 2) {
var x = world[i_20];
var y = world[i_20 + 1];
var x2 = world[(i_20 + 2) % world.length];
var y2 = world[(i_20 + 3) % world.length];
for (var i_21 = 0, n_2 = world.length; i_21 < n_2; i_21 += 2) {
var x = world[i_21];
var y = world[i_21 + 1];
var x2 = world[(i_21 + 2) % world.length];
var y2 = world[(i_21 + 3) % world.length];
shapes.line(x, y, x2, y2);
}
}

File diff suppressed because one or more lines are too long

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;

File diff suppressed because one or more lines are too long

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;

File diff suppressed because one or more lines are too long

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;

File diff suppressed because one or more lines are too long

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;
@ -7000,8 +7013,8 @@ var spine;
break;
}
var listeners = _this.listeners;
for (var i_16 = 0; i_16 < listeners.length; i_16++) {
listeners[i_16].down(_this.currTouch.x, _this.currTouch.y);
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].down(_this.currTouch.x, _this.currTouch.y);
}
console.log("Start " + _this.currTouch.x + ", " + _this.currTouch.y);
_this.lastX = _this.currTouch.x;
@ -7010,29 +7023,6 @@ var spine;
ev.preventDefault();
}, false);
element.addEventListener("touchend", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
@ -7055,6 +7045,29 @@ var spine;
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchmove", function (ev) {
if (_this.currTouch == null)
return;
@ -7066,8 +7079,8 @@ var spine;
var x = touch.clientX - rect.left;
var y = touch.clientY - rect.top;
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].dragged(x, y);
for (var i_20 = 0; i_20 < listeners.length; i_20++) {
listeners[i_20].dragged(x, y);
}
console.log("Drag " + x + ", " + y);
_this.lastX = _this.currTouch.x = x;
@ -8917,11 +8930,11 @@ var spine;
var nn = clip.worldVerticesLength;
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
for (var i_20 = 0, n_2 = world.length; i_20 < n_2; i_20 += 2) {
var x = world[i_20];
var y = world[i_20 + 1];
var x2 = world[(i_20 + 2) % world.length];
var y2 = world[(i_20 + 3) % world.length];
for (var i_21 = 0, n_2 = world.length; i_21 < n_2; i_21 += 2) {
var x = world[i_21];
var y = world[i_21 + 1];
var x2 = world[(i_21 + 2) % world.length];
var y2 = world[(i_21 + 3) % world.length];
shapes.line(x, y, x2, y2);
}
}

File diff suppressed because one or more lines are too long

View File

@ -244,15 +244,14 @@ declare module spine {
static emptyAnimation: Animation;
static SUBSEQUENT: number;
static FIRST: number;
static DIP: number;
static DIP_MIX: number;
static HOLD: number;
static HOLD_MIX: number;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
mixingTo: TrackEntry[];
animationsChanged: boolean;
timeScale: number;
trackEntryPool: Pool<TrackEntry>;
@ -277,6 +276,8 @@ declare module spine {
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
disposeNext(entry: TrackEntry): void;
_animationsChanged(): void;
setTimelineModes(entry: TrackEntry): void;
hasTimeline(entry: TrackEntry, id: number): boolean;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
@ -287,9 +288,11 @@ declare module spine {
animation: Animation;
next: TrackEntry;
mixingFrom: TrackEntry;
mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number;
attachmentThreshold: number;
drawOrderThreshold: number;
@ -309,12 +312,10 @@ declare module spine {
interruptAlpha: number;
totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[];
timelineDipMix: TrackEntry[];
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
hasTimeline(id: number): boolean;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;

View File

@ -1303,7 +1303,6 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@ -1350,6 +1349,8 @@ var spine;
if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
var from = current.mixingFrom;
current.mixingFrom = null;
if (from != null)
from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -1369,6 +1370,8 @@ var spine;
if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null)
from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -1400,19 +1403,19 @@ var spine;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1 || blend == spine.MixBlend.add) {
if (i == 0 && (mix == 1 || blend == spine.MixBlend.add)) {
for (var ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection["in"]);
}
else {
var timelineData = current.timelineData;
var timelineMode = current.timelineMode;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
var timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
var timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup;
if (timeline instanceof spine.RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
}
@ -1452,14 +1455,14 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
var alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == spine.MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out);
}
else {
var timelineData = from.timelineData;
var timelineDipMix = from.timelineDipMix;
var timelineMode = from.timelineMode;
var timelineHoldMix = from.timelineHoldMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -1469,7 +1472,7 @@ var spine;
var timeline = timelines[i];
var timelineBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
@ -1482,14 +1485,14 @@ var spine;
timelineBlend = spine.MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = spine.MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = spine.MixBlend.setup;
var dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
var holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -1619,6 +1622,7 @@ var spine;
break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
this.tracks[current.trackIndex] = null;
@ -1631,6 +1635,7 @@ var spine;
if (interrupt)
this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
@ -1740,6 +1745,7 @@ var spine;
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
entry.drawOrderThreshold = 0;
@ -1769,15 +1775,63 @@ var spine;
};
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
propertyIDs.clear();
var mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != spine.MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null)
continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add)
this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null);
}
};
AnimationState.prototype.setTimelineModes = function (entry) {
var to = entry.mixingTo;
var timelines = entry.animation.timelines;
var timelinesCount = entry.animation.timelines.length;
var timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
var propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (var i_16 = 0; i_16 < timelinesCount; i_16++) {
propertyIDs.add(timelines[i_16].getPropertyId());
timelineMode[i_16] = AnimationState.HOLD;
}
return;
}
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (var next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id))
continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
};
AnimationState.prototype.hasTimeline = function (entry, id) {
var timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@ -1802,69 +1856,28 @@ var spine;
AnimationState.emptyAnimation = new spine.Animation("<empty>", [], 0);
AnimationState.SUBSEQUENT = 0;
AnimationState.FIRST = 1;
AnimationState.DIP = 2;
AnimationState.DIP_MIX = 3;
AnimationState.HOLD = 2;
AnimationState.HOLD_MIX = 3;
return AnimationState;
}());
spine.AnimationState = AnimationState;
var TrackEntry = (function () {
function TrackEntry() {
this.mixBlend = spine.MixBlend.replace;
this.timelineData = new Array();
this.timelineDipMix = new Array();
this.timelineMode = new Array();
this.timelineHoldMix = new Array();
this.timelinesRotation = new Array();
}
TrackEntry.prototype.reset = function () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
};
TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
if (to != null)
mixingToArray.push(to);
var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null)
mixingToArray.pop();
var mixingTo = mixingToArray;
var mixingToLast = mixingToArray.length - 1;
var timelines = this.animation.timelines;
var timelinesCount = this.animation.timelines.length;
var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer: for (var i = 0; i < timelinesCount; i++) {
var id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
var entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
};
TrackEntry.prototype.hasTimeline = function (id) {
var timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id)
return true;
return false;
};
TrackEntry.prototype.getAnimationTime = function () {
if (this.loop) {
var duration = this.animationEnd - this.animationStart;
@ -7000,8 +7013,8 @@ var spine;
break;
}
var listeners = _this.listeners;
for (var i_16 = 0; i_16 < listeners.length; i_16++) {
listeners[i_16].down(_this.currTouch.x, _this.currTouch.y);
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].down(_this.currTouch.x, _this.currTouch.y);
}
console.log("Start " + _this.currTouch.x + ", " + _this.currTouch.y);
_this.lastX = _this.currTouch.x;
@ -7010,29 +7023,6 @@ var spine;
ev.preventDefault();
}, false);
element.addEventListener("touchend", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_17 = 0; i_17 < listeners.length; i_17++) {
listeners[i_17].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
@ -7055,6 +7045,29 @@ var spine;
}
ev.preventDefault();
}, false);
element.addEventListener("touchcancel", function (ev) {
var touches = ev.changedTouches;
for (var i = 0; i < touches.length; i++) {
var touch = touches[i];
if (_this.currTouch.identifier === touch.identifier) {
var rect = element.getBoundingClientRect();
var x = _this.currTouch.x = touch.clientX - rect.left;
var y = _this.currTouch.y = touch.clientY - rect.top;
_this.touchesPool.free(_this.currTouch);
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].up(x, y);
}
console.log("End " + x + ", " + y);
_this.lastX = x;
_this.lastY = y;
_this.buttonDown = false;
_this.currTouch = null;
break;
}
}
ev.preventDefault();
}, false);
element.addEventListener("touchmove", function (ev) {
if (_this.currTouch == null)
return;
@ -7066,8 +7079,8 @@ var spine;
var x = touch.clientX - rect.left;
var y = touch.clientY - rect.top;
var listeners = _this.listeners;
for (var i_19 = 0; i_19 < listeners.length; i_19++) {
listeners[i_19].dragged(x, y);
for (var i_20 = 0; i_20 < listeners.length; i_20++) {
listeners[i_20].dragged(x, y);
}
console.log("Drag " + x + ", " + y);
_this.lastX = _this.currTouch.x = x;
@ -8917,11 +8930,11 @@ var spine;
var nn = clip.worldVerticesLength;
var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
for (var i_20 = 0, n_2 = world.length; i_20 < n_2; i_20 += 2) {
var x = world[i_20];
var y = world[i_20 + 1];
var x2 = world[(i_20 + 2) % world.length];
var y2 = world[(i_20 + 3) % world.length];
for (var i_21 = 0, n_2 = world.length; i_21 < n_2; i_21 += 2) {
var x = world[i_21];
var y = world[i_21 + 1];
var x2 = world[(i_21 + 2) % world.length];
var y2 = world[(i_21 + 3) % world.length];
shapes.line(x, y, x2, y2);
}
}

File diff suppressed because one or more lines are too long

View File

@ -33,8 +33,8 @@ module spine {
static emptyAnimation = new Animation("<empty>", [], 0);
static SUBSEQUENT = 0;
static FIRST = 1;
static DIP = 2;
static DIP_MIX = 3;
static HOLD = 2;
static HOLD_MIX = 3;
data: AnimationStateData;
tracks = new Array<TrackEntry>();
@ -42,7 +42,6 @@ module spine {
listeners = new Array<AnimationStateListener2>();
queue = new EventQueue(this);
propertyIDs = new IntSet();
mixingTo = new Array<TrackEntry>();
animationsChanged = false;
timeScale = 1;
@ -96,6 +95,7 @@ module spine {
// End mixing from entries once all have completed.
let from = current.mixingFrom;
current.mixingFrom = null;
if (from != null) from.mixingTo = null;
while (from != null) {
this.queue.end(from);
from = from.mixingFrom;
@ -122,6 +122,7 @@ module spine {
// Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).
if (from.totalAlpha == 0 || to.mixDuration == 0) {
to.mixingFrom = from.mixingFrom;
if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
to.interruptAlpha = from.interruptAlpha;
this.queue.end(from);
}
@ -158,11 +159,11 @@ module spine {
let animationLast = current.animationLast, animationTime = current.getAnimationTime();
let timelineCount = current.animation.timelines.length;
let timelines = current.animation.timelines;
if (mix == 1 || blend == MixBlend.add) {
if (i == 0 && (mix == 1 || blend == MixBlend.add)) {
for (let ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.in);
} else {
let timelineData = current.timelineData;
let timelineMode = current.timelineMode;
let firstFrame = current.timelinesRotation.length == 0;
if (firstFrame) Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
@ -170,7 +171,7 @@ module spine {
for (let ii = 0; ii < timelineCount; ii++) {
let timeline = timelines[ii];
let timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
let timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
if (timeline instanceof RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
} else {
@ -209,13 +210,13 @@ module spine {
let animationLast = from.animationLast, animationTime = from.getAnimationTime();
let timelineCount = from.animation.timelines.length;
let timelines = from.animation.timelines;
let alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
if (blend == MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.out);
} else {
let timelineData = from.timelineData;
let timelineDipMix = from.timelineDipMix;
let timelineMode = from.timelineMode;
let timelineHoldMix = from.timelineHoldMix;
let firstFrame = from.timelinesRotation.length == 0;
if (firstFrame) Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
@ -226,7 +227,7 @@ module spine {
let timeline = timelines[i];
var timelineBlend: MixBlend;
var alpha = 0;
switch (timelineData[i]) {
switch (timelineMode[i]) {
case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof AttachmentTimeline) continue;
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
@ -237,14 +238,14 @@ module spine {
timelineBlend = MixBlend.setup;
alpha = alphaMix;
break;
case AnimationState.DIP:
case AnimationState.HOLD:
timelineBlend = MixBlend.setup;
alpha = alphaDip;
alpha = alphaHold;
break;
default:
timelineBlend = MixBlend.setup;
let dipMix = timelineDipMix[i];
alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
let holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break;
}
from.totalAlpha += alpha;
@ -388,6 +389,7 @@ module spine {
if (from == null) break;
this.queue.end(from);
entry.mixingFrom = null;
entry.mixingTo = null;
entry = from;
}
@ -403,6 +405,7 @@ module spine {
if (from != null) {
if (interrupt) this.queue.interrupt(from);
current.mixingFrom = from;
from.mixingTo = current;
current.mixTime = 0;
// Store the interrupted mix percentage.
@ -520,6 +523,7 @@ module spine {
entry.trackIndex = trackIndex;
entry.animation = animation;
entry.loop = loop;
entry.holdPrevious = false;
entry.eventThreshold = 0;
entry.attachmentThreshold = 0;
@ -556,17 +560,67 @@ module spine {
_animationsChanged () {
this.animationsChanged = false;
let propertyIDs = this.propertyIDs;
propertyIDs.clear();
let mixingTo = this.mixingTo;
this.propertyIDs.clear();
for (var i = 0, n = this.tracks.length; i < n; i++) {
let entry = this.tracks[i];
if (entry != null && (i == 0 || entry.mixBlend != MixBlend.add))
entry.setTimelineData(null, mixingTo, propertyIDs);
if (entry == null) continue;
while (entry.mixingFrom != null)
entry = entry.mixingFrom;
do {
if (entry.mixingFrom == null || entry.mixBlend != MixBlend.add) this.setTimelineModes(entry);
entry = entry.mixingTo;
} while (entry != null)
}
}
setTimelineModes (entry: TrackEntry) {
let to = entry.mixingTo;
let timelines = entry.animation.timelines;
let timelinesCount = entry.animation.timelines.length;
let timelineMode = Utils.setArraySize(entry.timelineMode, timelinesCount);
entry.timelineHoldMix.length = 0;
let timelineDipMix = Utils.setArraySize(entry.timelineHoldMix, timelinesCount);
let propertyIDs = this.propertyIDs;
if (to != null && to.holdPrevious) {
for (let i = 0; i < timelinesCount; i++) {
propertyIDs.add(timelines[i].getPropertyId());
timelineMode[i] = AnimationState.HOLD;
}
return;
}
outer:
for (var i = 0; i < timelinesCount; i++) {
let id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || !this.hasTimeline(to, id))
timelineMode[i] = AnimationState.FIRST;
else {
for (let next = to.mixingTo; next != null; next = next.mixingTo) {
if (this.hasTimeline(next, id)) continue;
if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next;
continue outer;
}
break;
}
timelineMode[i] = AnimationState.HOLD;
}
}
}
hasTimeline (entry: TrackEntry, id: number) : boolean {
let timelines = entry.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id) return true;
return false;
}
getCurrent (trackIndex: number) {
if (trackIndex >= this.tracks.length) return null;
return this.tracks[trackIndex];
@ -594,73 +648,31 @@ module spine {
export class TrackEntry {
animation: Animation;
next: TrackEntry; mixingFrom: TrackEntry;
next: TrackEntry; mixingFrom: TrackEntry; mixingTo: TrackEntry;
listener: AnimationStateListener2;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
eventThreshold: number; attachmentThreshold: number; drawOrderThreshold: number;
animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number;
delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number;
alpha: number; mixTime: number; mixDuration: number; interruptAlpha: number; totalAlpha: number;
mixBlend = MixBlend.replace;
timelineData = new Array<number>();
timelineDipMix = new Array<TrackEntry>();
timelineMode = new Array<number>();
timelineHoldMix = new Array<TrackEntry>();
timelinesRotation = new Array<number>();
reset () {
this.next = null;
this.mixingFrom = null;
this.mixingTo = null;
this.animation = null;
this.listener = null;
this.timelineData.length = 0;
this.timelineDipMix.length = 0;
this.timelineMode.length = 0;
this.timelineHoldMix.length = 0;
this.timelinesRotation.length = 0;
}
setTimelineData (to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet) : TrackEntry {
if (to != null) mixingToArray.push(to);
let lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
if (to != null) mixingToArray.pop();
let mixingTo = mixingToArray;
let mixingToLast = mixingToArray.length - 1;
let timelines = this.animation.timelines;
let timelinesCount = this.animation.timelines.length;
let timelineData = Utils.setArraySize(this.timelineData, timelinesCount);
this.timelineDipMix.length = 0;
let timelineDipMix = Utils.setArraySize(this.timelineDipMix, timelinesCount);
outer:
for (var i = 0; i < timelinesCount; i++) {
let id = timelines[i].getPropertyId();
if (!propertyIDs.add(id))
timelineData[i] = AnimationState.SUBSEQUENT;
else if (to == null || !to.hasTimeline(id))
timelineData[i] = AnimationState.FIRST;
else {
for (var ii = mixingToLast; ii >= 0; ii--) {
let entry = mixingTo[ii];
if (!entry.hasTimeline(id)) {
if (entry.mixDuration > 0) {
timelineData[i] = AnimationState.DIP_MIX;
timelineDipMix[i] = entry;
continue outer;
}
}
}
timelineData[i] = AnimationState.DIP;
}
}
return lastEntry;
}
hasTimeline (id: number) : boolean {
let timelines = this.animation.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
if (timelines[i].getPropertyId() == id) return true;
return false;
}
getAnimationTime () {
if (this.loop) {
let duration = this.animationEnd - this.animationStart;

View File

@ -26,6 +26,7 @@ function load () {
var skeletonJson = new spine.SkeletonJson(new spine.AtlasAttachmentLoader(atlas));
var skeletonData = skeletonJson.readSkeletonData(assetManager.get("spineboy-ess.json"));
var animationStateData = new spine.AnimationStateData(skeletonData);
animationStateData.defaultMix = 0.3;
skeleton = new spine.Skeleton(skeletonData);
animationState = new spine.AnimationState(animationStateData);
@ -38,6 +39,8 @@ function load () {
renderer.camera.zoom = size.x > size.y ? size.x / canvas.width : size.y / canvas.height;
animationState.setAnimation(0, "walk", true);
animationState.addAnimation(0, "run", true, 1);
animationState.addAnimation(0, "jump", true, 3);
requestAnimationFrame(render);
} else {

View File

@ -0,0 +1,113 @@
<html>
<script src="../../build/spine-webgl.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<style>
* { margin: 0; padding: 0; }
body, html { height: 100% }
canvas { position: absolute; width: 100% ;height: 100%; }
</style>
<body>
<div id="label" style="position: absolute; top: 0; left: 0; color: #fff; z-index: 10"></div>
<canvas id="canvas" style="background: red;"></canvas>
</body>
<script>
var FILE = "spineboy-ess";
var ANIMATION = "idle";
var SCALE = 0.5;
var canvas, context, gl, renderer, input, assetManager;
var skeletons = [];
var timeKeeper;
var label = document.getElementById("label");
var updateMean = new spine.WindowedMean();
var renderMean = new spine.WindowedMean();
function init() {
canvas = document.getElementById("canvas");
canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight;
context = new spine.webgl.ManagedWebGLRenderingContext(canvas, { alpha: false });
gl = context.gl;
renderer = new spine.webgl.SceneRenderer(canvas, context);
assetManager = new spine.webgl.AssetManager(context, "../example/assets/");
input = new spine.webgl.Input(canvas);
assetManager.loadTextureAtlas(FILE.replace("-pro", "").replace("-ess", "") + ".atlas");
assetManager.loadText(FILE + ".json");
timeKeeper = new spine.TimeKeeper();
requestAnimationFrame(load);
}
alert("blah");
var run = true;
function switchAnimation() {
var skel = skeletons[0];
skel.state.setAnimation(0, run ? "run" : "idle", true);
run = !run;
setTimeout(switchAnimation, 300);
}
function load() {
timeKeeper.update();
if (assetManager.isLoadingComplete()) {
var atlas = assetManager.get(FILE.replace("-pro", "").replace("-ess", "") + ".atlas");
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
var skeletonJson = new spine.SkeletonJson(atlasLoader);
skeletonJson.scale = SCALE;
var skeletonData = skeletonJson.readSkeletonData(JSON.parse(assetManager.get(FILE + ".json")));
skeleton = new spine.Skeleton(skeletonData);
var stateData = new spine.AnimationStateData(skeleton.data);
state = new spine.AnimationState(stateData);
stateData.defaultMix = 0;
state.setAnimation(0, ANIMATION, true);
skeletons.push({ skeleton: skeleton, state: state });
setTimeout(switchAnimation, 300);
requestAnimationFrame(render);
} else {
requestAnimationFrame(load);
}
}
function render() {
var start = Date.now()
timeKeeper.update();
var delta = timeKeeper.delta;
for (var i = 0; i < skeletons.length; i++) {
var state = skeletons[i].state;
var skeleton = skeletons[i].skeleton;
state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
}
updateMean.addValue(Date.now() - start);
start = Date.now();
gl.clearColor(0.2, 0.2, 0.2, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.resize(spine.webgl.ResizeMode.Fit);
renderer.begin();
for (var i = 0; i < skeletons.length; i++) {
var skeleton = skeletons[i].skeleton;
renderer.drawSkeleton(skeleton, false);
}
renderer.end();
requestAnimationFrame(render)
renderMean.addValue(Date.now() - start);
label.innerHTML = ("Update time: " + Number(updateMean.getMean()).toFixed(2) + " ms\n" +
"Render time: " + Number(renderMean.getMean()).toFixed(2) + " ms\n");
}
init();
</script>
</html>

View File

@ -51,6 +51,7 @@ namespace Spine.Unity.Editor {
internal static bool showAttachments = false;
SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
SerializedProperty blendModeMaterials;
#if SPINE_TK2D
SerializedProperty spriteCollection;
#endif
@ -100,6 +101,8 @@ namespace Spine.Unity.Editor {
duration = serializedObject.FindProperty("duration");
defaultMix = serializedObject.FindProperty("defaultMix");
blendModeMaterials = serializedObject.FindProperty("blendModeMaterials");
#if SPINE_SKELETON_MECANIM
controller = serializedObject.FindProperty("controller");
#endif
@ -315,6 +318,8 @@ namespace Spine.Unity.Editor {
if (atlasAssets.arraySize == 0)
EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
EditorGUILayout.PropertyField(blendModeMaterials);
}
void HandleAtlasAssetsNulls () {

View File

@ -179,7 +179,7 @@ namespace Spine.Unity.Editor {
static void Initialize () {
Preferences.Load();
DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
var rootDir = new DirectoryInfo(Application.dataPath);
FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
editorGUIPath = editorPath + "/GUI";
@ -194,15 +194,27 @@ namespace Spine.Unity.Editor {
EditorApplication.hierarchyWindowItemOnGUI += HierarchyHandler.HandleDragAndDrop;
// Hierarchy Icons
#if UNITY_2017_2_OR_NEWER
#if UNITY_2017_2_OR_NEWER
EditorApplication.playModeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
EditorApplication.playModeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
#else
#else
EditorApplication.playmodeStateChanged -= HierarchyHandler.IconsOnPlaymodeStateChanged;
EditorApplication.playmodeStateChanged += HierarchyHandler.IconsOnPlaymodeStateChanged;
HierarchyHandler.IconsOnPlaymodeStateChanged();
#endif
#endif
// Data Refresh Edit Mode.
// This prevents deserialized SkeletonData from persisting from play mode to edit mode.
#if UNITY_2017_2_OR_NEWER
EditorApplication.playModeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged;
EditorApplication.playModeStateChanged += DataReloadHandler.OnPlaymodeStateChanged;
DataReloadHandler.OnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
#else
EditorApplication.playmodeStateChanged -= DataReloadHandler.OnPlaymodeStateChanged;
EditorApplication.playmodeStateChanged += DataReloadHandler.OnPlaymodeStateChanged;
DataReloadHandler.OnPlaymodeStateChanged();
#endif
initialized = true;
}
@ -214,11 +226,11 @@ namespace Spine.Unity.Editor {
#endregion
public static class Preferences {
#if SPINE_TK2D
#if SPINE_TK2D
const float DEFAULT_DEFAULT_SCALE = 1f;
#else
#else
const float DEFAULT_DEFAULT_SCALE = 0.01f;
#endif
#endif
const string DEFAULT_SCALE_KEY = "SPINE_DEFAULT_SCALE";
public static float defaultScale = DEFAULT_DEFAULT_SCALE;
@ -268,11 +280,11 @@ namespace Spine.Unity.Editor {
showHierarchyIcons = EditorGUILayout.Toggle(new GUIContent("Show Hierarchy Icons", "Show relevant icons on GameObjects with Spine Components on them. Disable this if you have large, complex scenes."), showHierarchyIcons);
if (EditorGUI.EndChangeCheck()) {
EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
#if UNITY_2017_2_OR_NEWER
#if UNITY_2017_2_OR_NEWER
HierarchyHandler.IconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
#else
#else
HierarchyHandler.IconsOnPlaymodeStateChanged();
#endif
#endif
}
EditorGUILayout.Separator();
@ -333,6 +345,38 @@ namespace Spine.Unity.Editor {
}
}
public static class DataReloadHandler {
#if UNITY_2017_2_OR_NEWER
internal static void OnPlaymodeStateChanged (PlayModeStateChange stateChange) {
#else
internal static void OnPlaymodeStateChanged () {
#endif
ReloadAllActiveSkeletons();
}
static void ReloadAllActiveSkeletons () {
var skeletonDataAssetsToReload = new HashSet<SkeletonDataAsset>();
var activeSkeletonRenderers = GameObject.FindObjectsOfType<SkeletonRenderer>();
foreach (var sr in activeSkeletonRenderers) {
var skeletonDataAsset = sr.skeletonDataAsset;
if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset);
}
var activeSkeletonGraphics = GameObject.FindObjectsOfType<SkeletonGraphic>();
foreach (var sg in activeSkeletonGraphics) {
var skeletonDataAsset = sg.skeletonDataAsset;
if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset);
}
foreach (var sda in skeletonDataAssetsToReload)
sda.Clear();
foreach (var sr in activeSkeletonRenderers) sr.Initialize(true);
foreach (var sg in activeSkeletonGraphics) sg.Initialize(true);
}
}
public static class AssetUtility {
public const string SkeletonDataSuffix = "_SkeletonData";
public const string AtlasSuffix = "_Atlas";

View File

@ -0,0 +1,120 @@
/******************************************************************************
* Spine Runtimes Software License v2.5
*
* Copyright (c) 2013-2016, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable, and
* non-transferable license to use, install, execute, and perform the Spine
* Runtimes software and derivative works solely for personal or internal
* use. Without the written permission of Esoteric Software (see Section 2 of
* the Spine Software License Agreement), you may not (a) modify, translate,
* adapt, or develop new applications using the Spine Runtimes or otherwise
* create derivative works or improvements of the Spine Runtimes or (b) remove,
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
* or other intellectual property or proprietary rights notices on or in the
* Software, including any copy thereof. Redistributions in binary or source
* form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine;
using Spine.Unity;
namespace Spine.Unity {
[CreateAssetMenu(menuName = "Spine/Blend Mode Materials Asset", order = 200)]
public class BlendModeMaterialsAsset : SkeletonDataModifierAsset {
public Material multiplyMaterialTemplate;
public Material screenMaterialTemplate;
public Material additiveMaterialTemplate;
public bool applyAdditiveMaterial;
public override void Apply (SkeletonData skeletonData) {
ApplyMaterials(skeletonData, multiplyMaterialTemplate, screenMaterialTemplate, additiveMaterialTemplate, applyAdditiveMaterial);
}
public static void ApplyMaterials (SkeletonData skeletonData, Material multiplyTemplate, Material screenTemplate, Material additiveTemplate, bool includeAdditiveSlots) {
if (skeletonData == null) throw new ArgumentNullException("skeletonData");
var atlasPageMaterialCache = new Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage>();
var attachmentBuffer = new List<Attachment>();
var slotsItems = skeletonData.Slots.Items;
for (int i = 0, slotCount = skeletonData.Slots.Count; i < slotCount; i++) {
var slot = slotsItems[i];
if (slot.blendMode == BlendMode.Normal) continue;
if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue;
attachmentBuffer.Clear();
foreach (var skin in skeletonData.Skins)
skin.FindAttachmentsForSlot(i, attachmentBuffer);
Material templateMaterial = null;
switch (slot.blendMode) {
case BlendMode.Multiply:
templateMaterial = multiplyTemplate;
break;
case BlendMode.Screen:
templateMaterial = screenTemplate;
break;
case BlendMode.Additive:
templateMaterial = additiveTemplate;
break;
}
if (templateMaterial == null) continue;
foreach (var attachment in attachmentBuffer) {
var renderableAttachment = attachment as IHasRendererObject;
if (renderableAttachment != null) {
renderableAttachment.RendererObject = AtlasRegionCloneWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial, atlasPageMaterialCache);
}
}
}
//atlasPageMaterialCache.Clear();
//attachmentBuffer.Clear();
}
static AtlasRegion AtlasRegionCloneWithMaterial (AtlasRegion originalRegion, Material materialTemplate, Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage> cache) {
var newRegion = originalRegion.Clone();
newRegion.page = GetAtlasPageWithMaterial(originalRegion.page, materialTemplate, cache);
return newRegion;
}
static AtlasPage GetAtlasPageWithMaterial (AtlasPage originalPage, Material materialTemplate, Dictionary<KeyValuePair<AtlasPage, Material>, AtlasPage> cache) {
if (originalPage == null) throw new ArgumentNullException("originalPage");
AtlasPage newPage = null;
var key = new KeyValuePair<AtlasPage, Material>(originalPage, materialTemplate);
cache.TryGetValue(key, out newPage);
if (newPage == null) {
newPage = originalPage.Clone();
var originalMaterial = originalPage.rendererObject as Material;
newPage.rendererObject = new Material(materialTemplate) {
name = originalMaterial.name + " " + materialTemplate.name,
mainTexture = originalMaterial.mainTexture
};
cache.Add(key, newPage);
}
return newPage;
}
}
}

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 12b0b98acbcda44468a7ae4e35000abe
timeCreated: 1536404384
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences:
- multiplyMaterialTemplate: {fileID: 2100000, guid: 53bf0ab317d032d418cf1252d68f51df,
type: 2}
- screenMaterialTemplate: {fileID: 2100000, guid: 73f0f46d3177c614baf0fa48d646a9be,
type: 2}
- additiveMaterialTemplate: {fileID: 2100000, guid: 4deba332d47209e4780b3c5fcf0e3745,
type: 2}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -29,8 +29,10 @@
*****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Spine;
namespace Spine.Unity {
@ -39,6 +41,7 @@ namespace Spine.Unity {
public class SkeletonDataAsset : ScriptableObject {
#region Inspector
public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0];
#if SPINE_TK2D
public tk2dSpriteCollectionData spriteCollection;
public float scale = 1f;
@ -46,6 +49,10 @@ namespace Spine.Unity {
public float scale = 0.01f;
#endif
public TextAsset skeletonJSON;
[Tooltip("Use SkeletonDataModifierAssets to apply changes to the SkeletonData after being loaded, such as apply blend mode Materials to Attachments under slots with special blend modes.")]
public List<SkeletonDataModifierAsset> skeletonDataModifiers = new List<SkeletonDataModifierAsset>();
[SpineAnimation(includeNone: false)]
public string[] fromAnimation = new string[0];
[SpineAnimation(includeNone: false)]
@ -87,6 +94,7 @@ namespace Spine.Unity {
}
#endregion
/// <summary>Clears the loaded SkeletonData and AnimationStateData. Use this to force a reload for the next time GetSkeletonData is called.</summary>
public void Clear () {
skeletonData = null;
stateData = null;
@ -161,6 +169,12 @@ namespace Spine.Unity {
}
if (skeletonDataModifiers != null) {
foreach (var m in skeletonDataModifiers) {
if (m != null) m.Apply(loadedSkeletonData);
}
}
this.InitializeWithData(loadedSkeletonData);
return skeletonData;
@ -218,6 +232,7 @@ namespace Spine.Unity {
GetSkeletonData(false);
return stateData;
}
}
}

View File

@ -0,0 +1,40 @@
/******************************************************************************
* Spine Runtimes Software License v2.5
*
* Copyright (c) 2013-2016, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable, and
* non-transferable license to use, install, execute, and perform the Spine
* Runtimes software and derivative works solely for personal or internal
* use. Without the written permission of Esoteric Software (see Section 2 of
* the Spine Software License Agreement), you may not (a) modify, translate,
* adapt, or develop new applications using the Spine Runtimes or otherwise
* create derivative works or improvements of the Spine Runtimes or (b) remove,
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
* or other intellectual property or proprietary rights notices on or in the
* Software, including any copy thereof. Redistributions in binary or source
* form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Spine.Unity {
/// <summary>Can be stored by SkeletonDataAsset to automatically apply modifications to loaded SkeletonData.</summary>
public abstract class SkeletonDataModifierAsset : ScriptableObject {
public abstract void Apply (SkeletonData skeletonData);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 79a44aba1f342f440965874280b4c318
timeCreated: 1536412736
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -69,7 +69,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// <summary>Sets the region (image) of a RegionAttachment</summary>
public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
if (region == null) throw new System.ArgumentNullException("region");
if (region == null) throw new System.ArgumentNullException("region");
// (AtlasAttachmentLoader.cs)
attachment.RendererObject = region;
@ -86,7 +86,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// <summary>Sets the region (image) of a MeshAttachment</summary>
public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
if (region == null) throw new System.ArgumentNullException("region");
if (region == null) throw new System.ArgumentNullException("region");
// (AtlasAttachmentLoader.cs)
attachment.RendererObject = region;
@ -395,7 +395,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, but mapped to a new single texture using the same material.</summary>
/// <param name="sourceAttachments">The list of attachments to be repacked.</param>
/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
///
///
/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) {
if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
@ -413,7 +413,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
int newRegionIndex = 0;
for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
var originalAttachment = sourceAttachments[i];
if (IsRenderable(originalAttachment)) {
var newAttachment = originalAttachment.GetClone(true);
var region = newAttachment.GetRegion();
@ -524,7 +524,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, newAttachment);
} else {
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true));
}
}
}
// Fill a new texture with the collected attachment textures.
@ -657,7 +657,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down)</summary>
static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) {
if (includeRotate && region.rotate)
return new Rect(region.x, region.y, region.height, region.width);
return new Rect(region.x, region.y, region.height, region.width);
else
return new Rect(region.x, region.y, region.width, region.height);
}
@ -684,7 +684,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// <summary>
/// Creates a new Spine AtlasRegion according to a Unity UV Rect (x-right, y-up, uv-normalized).</summary>
static AtlasRegion UVRectToAtlasRegion (Rect uvRect, string name, AtlasPage page, float offsetX, float offsetY, bool rotate) {
static AtlasRegion UVRectToAtlasRegion (Rect uvRect, string name, AtlasPage page, float offsetX, float offsetY, bool rotate) {
var tr = UVRectToTextureRect(uvRect, page.width, page.height);
var rr = tr.SpineUnityFlipRect(page.height);
@ -875,7 +875,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
public static Attachment GetClone (this Attachment o, bool cloneMeshesAsLinked) {
var regionAttachment = o as RegionAttachment;
if (regionAttachment != null)
return regionAttachment.GetClone();
return regionAttachment.GetClone();
var meshAttachment = o as MeshAttachment;
if (meshAttachment != null)

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: baf1d09e18b500d41a714f6207ddda2d
folderAsset: yes
timeCreated: 1536402197
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 22c0225612a65ee4fb15bad49f644762
timeCreated: 1536404361
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4deba332d47209e4780b3c5fcf0e3745
timeCreated: 1496447909
licenseType: Free
NativeFormatImporter:
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,106 @@
// Spine/Skeleton PMA Screen
// - single color multiply tint
// - unlit
// - Premultiplied alpha Multiply blending
// - No depth, no backface culling, no fog.
// - ShadowCaster pass
Shader "Spine/Blend Modes/Skeleton PMA Additive" {
Properties {
_Color ("Tint Color", Color) = (1,1,1,1)
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
[Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
}
SubShader {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
LOD 100
Fog { Mode Off }
Cull Off
ZWrite Off
Blend One One
Lighting Off
Pass {
CGPROGRAM
#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _Color;
struct VertexInput {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};
VertexOutput vert (VertexInput v) {
VertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.vertexColor = v.vertexColor * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
return o;
}
float4 frag (VertexOutput i) : COLOR {
float4 texColor = tex2D(_MainTex, i.uv);
#if defined(_STRAIGHT_ALPHA_INPUT)
texColor.rgb *= texColor.a;
#endif
return (texColor * i.vertexColor);
}
ENDCG
}
Pass {
Name "Caster"
Tags { "LightMode"="ShadowCaster" }
Offset 1, 1
ZWrite On
ZTest LEqual
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
V2F_SHADOW_CASTER;
float2 uv : TEXCOORD1;
};
uniform float4 _MainTex_ST;
v2f vert (appdata_base v) {
v2f o;
TRANSFER_SHADOW_CASTER(o)
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
uniform sampler2D _MainTex;
uniform fixed _Cutoff;
float4 frag (v2f i) : COLOR {
fixed4 texcol = tex2D(_MainTex, i.uv);
clip(texcol.a - _Cutoff);
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 53efa1d97f5d9f74285d4330cda14e36
timeCreated: 1496446742
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,13 +1,11 @@
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Spine/Skeleton PMA Multiply
// Spine/Skeleton PMA Multiply
// - single color multiply tint
// - unlit
// - Premultiplied alpha Multiply blending
// - No depth, no backface culling, no fog.
// - ShadowCaster pass
Shader "Spine/Skeleton PMA Multiply" {
Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
Properties {
_Color ("Tint Color", Color) = (1,1,1,1)
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}

View File

@ -1,11 +1,11 @@
// Spine/Skeleton PMA Multiply
// Spine/Skeleton PMA Screen
// - single color multiply tint
// - unlit
// - Premultiplied alpha Multiply blending
// - No depth, no backface culling, no fog.
// - ShadowCaster pass
Shader "Spine/Skeleton PMA Screen" {
Shader "Spine/Blend Modes/Skeleton PMA Screen" {
Properties {
_Color ("Tint Color", Color) = (1,1,1,1)
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}

View File

@ -98,6 +98,27 @@ namespace Spine.Unity {
}
#endregion
#region Skeleton
/// <summary>Sets the Skeleton's local scale using a UnityEngine.Vector2. If only individual components need to be set, set Skeleton.ScaleX or Skeleton.ScaleY.</summary>
public static void SetLocalScale (this Skeleton skeleton, Vector2 scale) {
skeleton.scaleX = scale.x;
skeleton.scaleY = scale.y;
}
/// <summary>Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix.</summary>
public static Matrix4x4 GetMatrix4x4 (this Bone bone) {
return new Matrix4x4 {
m00 = bone.a,
m01 = bone.b,
m03 = bone.worldX,
m10 = bone.c,
m11 = bone.d,
m13 = bone.worldY,
m33 = 1
};
}
#endregion
#region Bone
/// <summary>Sets the bone's (local) X and Y according to a Vector2</summary>
public static void SetPosition (this Bone bone, Vector2 position) {
@ -149,13 +170,9 @@ namespace Spine.Unity {
return new Quaternion(0, 0, Mathf.Sin(halfRotation), Mathf.Cos(halfRotation));
}
/// <summary>Gets the internal bone matrix as a Unity bonespace-to-skeletonspace transformation matrix.</summary>
public static Matrix4x4 GetMatrix4x4 (this Bone bone) {
return new Matrix4x4 {
m00 = bone.a, m01 = bone.b, m03 = bone.worldX,
m10 = bone.c, m11 = bone.d, m13 = bone.worldY,
m33 = 1
};
/// <summary>Returns the Skeleton's local scale as a UnityEngine.Vector2. If only individual components are needed, use Skeleton.ScaleX or Skeleton.ScaleY.</summary>
public static Vector2 GetLocalScale (this Skeleton skeleton) {
return new Vector2(skeleton.scaleX, skeleton.scaleY);
}
/// <summary>Calculates a 2x2 Transformation Matrix that can convert a skeleton-space position to a bone-local position.</summary>

View File

@ -103,6 +103,7 @@ namespace Spine.Unity {
int floatCount = floats.Length;
Bounds bounds = new Bounds();
bounds.center = new Vector3(floats[0], floats[1], 0);
for (int i = 2; i < floatCount; i += 2)
bounds.Encapsulate(new Vector3(floats[i], floats[i + 1], 0));
@ -122,14 +123,7 @@ namespace Spine.Unity {
void Update () {
var skeleton = skeletonRenderer.skeleton;
if (boneRoot != null && skeleton != null) {
Vector3 flipScale = Vector3.one;
if (skeleton.scaleX < 0)
flipScale.x = -1;
if (skeleton.scaleY < 0)
flipScale.y = -1;
boneRoot.localScale = flipScale;
boneRoot.localScale = new Vector3(skeleton.scaleX, skeleton.scaleY, 1f);
}
}